diff --git a/Applications/mitkWorkbench/mitkWorkbench.cpp b/Applications/mitkWorkbench/mitkWorkbench.cpp index dfe2379342..36c3b32584 100644 --- a/Applications/mitkWorkbench/mitkWorkbench.cpp +++ b/Applications/mitkWorkbench/mitkWorkbench.cpp @@ -1,143 +1,150 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include +#include +#include #include #include class QtSafeApplication : public QtSingleApplication { public: QtSafeApplication(int& argc, char** argv) : QtSingleApplication(argc, argv) {} /** * Reimplement notify to catch unhandled exceptions and open an error message. * * @param receiver * @param event * @return */ bool notify(QObject* receiver, QEvent* event) { QString msg; try { return QApplication::notify(receiver, event); } catch (mitk::Exception& e) { msg = QString("MITK Exception:\n\n") + QString("Desciption: ") + QString(e.GetDescription()) + QString("\n\n") + QString("Filename: ") + QString(e.GetFile()) + QString("\n\n") + QString("Line: ") + QString::number(e.GetLine()); } catch (Poco::Exception& e) { msg = QString::fromStdString(e.displayText()); } catch (std::exception& e) { msg = e.what(); } catch (...) { msg = "Unknown exception"; } MITK_ERROR << "An error occurred: " << msg.toStdString(); QMessageBox msgBox; msgBox.setText("An error occurred. You should save all data and quit the program to prevent possible data loss."); msgBox.setDetailedText(msg); msgBox.setIcon(QMessageBox::Critical); msgBox.addButton(trUtf8("Exit immediately"), QMessageBox::YesRole); msgBox.addButton(trUtf8("Ignore"), QMessageBox::NoRole); int ret = msgBox.exec(); switch(ret) { case 0: MITK_ERROR << "The program was closed."; this->closeAllWindows(); break; case 1: MITK_ERROR << "The error was ignored by the user. The program may be in a corrupt state and don't behave like expected!"; break; } return false; } }; int main(int argc, char** argv) { // Create a QApplication instance first QtSafeApplication qSafeApp(argc, argv); qSafeApp.setApplicationName("mitkWorkbench"); qSafeApp.setOrganizationName("DKFZ"); // This function checks if an instance is already running // and either sends a message to it (containing the command // line arguments) or checks if a new instance was forced by // providing the BlueBerry.newInstance command line argument. // In the latter case, a path to a temporary directory for // the new application's storage directory is returned. QString storageDir = handleNewAppInstance(&qSafeApp, argc, argv, "BlueBerry.newInstance"); // These paths replace the .ini file and are tailored for installation // packages created with CPack. If a .ini file is presented, it will // overwrite the settings in MapConfiguration Poco::Path basePath(argv[0]); basePath.setFileName(""); Poco::Path provFile(basePath); provFile.setFileName("mitkWorkbench.provisioning"); Poco::Path extPath(basePath); extPath.pushDirectory("ExtBundles"); std::string pluginDirs = extPath.toString(); Poco::Util::MapConfiguration* extConfig(new Poco::Util::MapConfiguration()); if (!storageDir.isEmpty()) { extConfig->setString(berry::Platform::ARG_STORAGE_DIR, storageDir.toStdString()); } extConfig->setString(berry::Platform::ARG_PLUGIN_DIRS, pluginDirs); extConfig->setString(berry::Platform::ARG_PROVISIONING, provFile.toString()); extConfig->setString(berry::Platform::ARG_APPLICATION, "org.mitk.qt.extapplication"); // Preload the org.mitk.gui.qt.ext plug-in (and hence also QmitkExt) to speed // up a clean-cache start. This also works around bugs in older gcc and glibc implementations, // which have difficulties with multiple dynamic opening and closing of shared libraries with // many global static initializers. It also helps if dependent libraries have weird static // initialization methods and/or missing de-initialization code. extConfig->setString(berry::Platform::ARG_PRELOAD_LIBRARY, "liborg_mitk_gui_qt_ext,libCTKDICOMCore:0.1"); + // Seed the random number generator, once at startup. + QTime time = QTime::currentTime(); + qsrand((uint)time.msec()); + + // Run the workbench. return berry::Starter::Run(argc, argv, extConfig); } diff --git a/Modules/Qmitk/QmitkDataStorageComboBox.h b/Modules/Qmitk/QmitkDataStorageComboBox.h index 12be11db9c..7d65e3e0ba 100644 --- a/Modules/Qmitk/QmitkDataStorageComboBox.h +++ b/Modules/Qmitk/QmitkDataStorageComboBox.h @@ -1,241 +1,241 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkDataStorageComboBox_h #define QmitkDataStorageComboBox_h #include // Own Includes #include "mitkDataStorage.h" #include "mitkDataNode.h" #include "mitkWeakPointer.h" #include "mitkNodePredicateBase.h" // Toolkit Includes #include #include // Forward Declartions /// /// \class QmitkDataStorageComboBox /// \author Michael Mueller /// \version 4.0 /// \date 2009-02-09 /// \ingroup Widgets /// \brief Displays all or a subset (defined by a predicate) of nodes of the Data Storage. /// /// Dont forget that this class inherits from QComboBox and you can therefore use the whole API of QComboBox. /// class QMITK_EXPORT QmitkDataStorageComboBox : public QComboBox { //#CLASS-MACROS,FRIENDS Q_OBJECT //#CTORS/DTOR public: /// /// \brief Ctor for an empty combobox. Use setDataStorage and setPredicate afterwards. /// QmitkDataStorageComboBox(QWidget* parent = 0, bool _AutoSelectNewNodes=false); /// /// \brief Ctor for constructing QmitkDataStorageComboBox with given DataStorageComboBox and given _Predicate. /// QmitkDataStorageComboBox( mitk::DataStorage* _DataStorage, const mitk::NodePredicateBase* _Predicate, QWidget* parent = 0, bool _AutoSelectNewNodes=false); /// /// \brief Standard Dtor. Nothing to do here. /// ~QmitkDataStorageComboBox(); /// /// \brief Seaches for a given node and returns a valid index or -1 if the node was not found. /// - int Find( const mitk::DataNode* _DataNode ) const; + virtual int Find( const mitk::DataNode* _DataNode ) const; //#PUBLIC GETTER public: /// /// \brief Get the DataStorage this ComboBox listens to. /// mitk::DataStorage::Pointer GetDataStorage() const; /// /// \brief Return the predicate (may be NULL) that is responsible for the _DataNode selection of this ComboBox. /// const mitk::NodePredicateBase::ConstPointer GetPredicate() const; /// /// \brief Returns the _DataNode at Index index or 0 if the index is out of bounds. /// - mitk::DataNode::Pointer GetNode(int index) const; + virtual mitk::DataNode::Pointer GetNode(int index) const; /// /// \brief Returns the selected _DataNode or 0 if there is none. /// - mitk::DataNode::Pointer GetSelectedNode() const; + virtual mitk::DataNode::Pointer GetSelectedNode() const; /// /// \brief Returns all nodes that are stored in this combobox. /// mitk::DataStorage::SetOfObjects::ConstPointer GetNodes() const; /// /// Returns the AutoSelectNewItems. /// \see SetAutoSelectNewItems /// virtual bool GetAutoSelectNewItems(); //#PUBLIC SETTER public: /// /// \brief Set the DataStorage this ComboBox should listen to. /// /// If DataStorage is 0 nothing will be shown. If DataStorage is re-set the combobox will be resetted. void SetDataStorage(mitk::DataStorage* dataStorage); /// /// \brief Set the predicate for this ComboBox. (QmitkDataStorageComboBox is now owner of the predicate) /// /// If predicate is NULL all nodes will be selected. If predicate changes the whole combobox will be resetted. void SetPredicate(const mitk::NodePredicateBase* _Predicate); /// /// Adds a node to the ComboBox. Gets called everytime a DataStorage Add Event was thrown. /// virtual void AddNode(const mitk::DataNode* _DataNode); /// /// Removes a node from the ComboBox at a specified index (if the index exists). Gets called when a DataStorage Remove Event was thrown. /// virtual void RemoveNode(int index); /// /// Removes a node from the ComboBox. Gets called when a DataStorage Remove Event was thrown. /// virtual void RemoveNode(const mitk::DataNode* _DataNode); /// /// Set a _DataNode in the ComboBox at the specified index (if the index exists). /// Internally the method just calls RemoveNode(unsigned int) /// virtual void SetNode(int index, const mitk::DataNode* _DataNode); /// /// Replaces a _DataNode in the combobox by an _OtherDataNode. /// Internally the method just calls SetNode(unsigned int, mitk::DataNode*) /// virtual void SetNode(const mitk::DataNode* _DataNode, const mitk::DataNode* _OtherDataNode); /// /// Sets AutoSelectNewItems flag. If set to true new Nodes will be automatically selected. Default is false. /// virtual void SetAutoSelectNewItems(bool _AutoSelectNewItems); /// /// \brief Called when a node is deleted or the name property of the node was modified. Calls RemoveNode or SetNode then. /// virtual void OnDataNodeDeleteOrModified(const itk::Object *caller, const itk::EventObject &event); signals: /// /// \brief Throw a signal when the _DataNode selection changed. /// void OnSelectionChanged(const mitk::DataNode*); //#PROTECTED GETTER protected: /// /// \brief Checks if the given index is within the range of the m_Nodes vector. /// bool HasIndex(unsigned int index) const; //#PROTECTED SETTER protected slots: /// /// \brief Slot for signal when the user selects another item. /// void OnCurrentIndexChanged(int); //#PUBLIC SETTER public slots: /// /// \brief Slot for signal when user wants to set a node as current selected node. /// void SetSelectedNode(mitk::DataNode::Pointer item); protected: /// /// \brief Inserts a new node at the given index. If the index does not exist, the _DataNode is simply appended to the combobox. /// /// This function is used by AddNode() and SetNode() because they just to the same: /// 1. If node is replaced (that is when index exists), /// the itk::Event observer will be removed /// 2. Check Node against Predicate /// 3. Register for itk::Events on the node /// 4. Insert Node and show in combobox virtual void InsertNode(int index, const mitk::DataNode* _DataNode); /// /// \brief Init-function this class with the given dataStorage and _Predicate. This function is called by all ctors. /// void Init(); /// /// \brief Reset function whenever datastorage or predicate changes. /// - void Reset(); + virtual void Reset(); protected: //#PROTECTED MEMBER VARS /// /// Pointer to the DataStorage from which the nodes are selected (remember: in BlueBerry there /// might be more than one DataStorage). /// mitk::WeakPointer m_DataStorage; /// /// \brief Holds the predicate that is responsible for the _DataNode selection of this ComboBox. /// If the predicate is 0, every _DataNode will be selected. /// mitk::NodePredicateBase::ConstPointer m_Predicate; /// /// Holds all selected Nodes. Dont hold smart pointer as we are in a GUI class. /// std::vector m_Nodes; /// /// \brief Holds the tags of the node-modified observers. (must be updated everytime m_Nodes changes) /// std::vector m_NodesModifiedObserverTags; /// /// \brief Holds the tags of the node-modified observers. (must be updated everytime m_Nodes changes) /// std::vector m_NodesDeleteObserverTags; /// /// \brief Maps a a specific node to (Name-)property. This is needed because we have to find the assiociated node /// whenever the name property of a node changed. /// std::map m_PropertyToNode; /// /// \brief Event function guard. Each function which is called by an event mechanism /// first checks if this is true in order to avoid endless loops. bool m_BlockEvents; /// /// \brief If set to "true" new Nodes will be automatically selected. bool m_AutoSelectNewNodes; }; #endif // QmitkDataStorageComboBox_h diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake index 1cf526d180..e0f3b475c6 100644 --- a/Plugins/PluginList.cmake +++ b/Plugins/PluginList.cmake @@ -1,43 +1,44 @@ # Plug-ins must be ordered according to their dependencies set(MITK_EXT_PLUGINS org.mitk.core.services:ON org.mitk.gui.common:ON org.mitk.planarfigure:ON org.mitk.core.ext:OFF org.mitk.core.jobs:OFF org.mitk.diffusionimaging:OFF org.mitk.gui.qt.application:ON org.mitk.gui.qt.coreapplication:OFF org.mitk.gui.qt.ext:OFF org.mitk.gui.qt.extapplication:OFF org.mitk.gui.qt.common:ON org.mitk.gui.qt.stdmultiwidgeteditor:ON org.mitk.gui.qt.common.legacy:OFF + org.mitk.gui.qt.cli:OFF org.mitk.gui.qt.diffusionimagingapp:OFF org.mitk.gui.qt.datamanager:ON org.mitk.gui.qt.basicimageprocessing:OFF org.mitk.gui.qt.dicom:OFF org.mitk.gui.qt.diffusionimaging:OFF org.mitk.gui.qt.dtiatlasapp:OFF org.mitk.gui.qt.examples:OFF org.mitk.gui.qt.examplesopencv:OFF org.mitk.gui.qt.igtexamples:OFF org.mitk.gui.qt.igttracking:OFF org.mitk.gui.qt.imagecropper:OFF org.mitk.gui.qt.imagenavigator:ON org.mitk.gui.qt.materialeditor:OFF org.mitk.gui.qt.measurementtoolbox:OFF org.mitk.gui.qt.meshdecimation:OFF org.mitk.gui.qt.moviemaker:OFF org.mitk.gui.qt.pointsetinteraction:OFF org.mitk.gui.qt.python.console:OFF org.mitk.gui.qt.registration:OFF org.mitk.gui.qt.segmentation:OFF org.mitk.gui.qt.toftutorial:OFF org.mitk.gui.qt.tofutil:OFF org.mitk.gui.qt.ugvisualization:OFF org.mitk.gui.qt.ultrasound:OFF org.mitk.gui.qt.volumevisualization:OFF ) diff --git a/Plugins/org.mitk.gui.qt.cli/CMakeLists.txt b/Plugins/org.mitk.gui.qt.cli/CMakeLists.txt new file mode 100644 index 0000000000..a6ba14fe29 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/CMakeLists.txt @@ -0,0 +1,10 @@ +project(org_mitk_gui_qt_cli) + +set(QT_USE_QTUITOOLS 1) +include(${QT_USE_FILE}) + +MACRO_CREATE_MITK_CTK_PLUGIN( + EXPORT_DIRECTIVE CLI_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDENCIES CTK QmitkExt +) diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIF3D.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIF3D.png new file mode 100644 index 0000000000..badee5e53f Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIF3D.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIIcon.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIIcon.png new file mode 100644 index 0000000000..88f2710f8d Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIIcon.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIInitial.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIInitial.png new file mode 100644 index 0000000000..b728072ce6 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIInitial.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLINiftyReg.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLINiftyReg.png new file mode 100644 index 0000000000..3932227e3e Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLINiftyReg.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLINiftyRegRunning2.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLINiftyRegRunning2.png new file mode 100644 index 0000000000..9df12752c2 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLINiftyRegRunning2.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIPreferences.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIPreferences.png new file mode 100644 index 0000000000..35ab9f7ce8 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIPreferences.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIPreferencesAdditionalDirectories.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIPreferencesAdditionalDirectories.png new file mode 100644 index 0000000000..ed77784ee4 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIPreferencesAdditionalDirectories.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIPreferencesAdditionalModules.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIPreferencesAdditionalModules.png new file mode 100644 index 0000000000..e45e2afd58 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIPreferencesAdditionalModules.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIWithPrograms.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIWithPrograms.png new file mode 100644 index 0000000000..6ff8a032b9 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIWithPrograms.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..c4748f0fe8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/Manual.dox @@ -0,0 +1,170 @@ +/** +\bundlemainpage{org.mitk.gui.qt.cli} The Command Line Interface (CLI) View + +\image html CLIIcon.png "Icon of CLI" + +\li \ref CLIIntroduction +\li \ref CLIPreferences +\li \ref CLIUsage +\li \ref CLITechnicalNotes + +\section CLIPrefix Contribution + +This plugin was developed at the Centre For Medical Image Computing (CMIC), +part of University College London (UCL) and contributed back to the +MITK community with thanks. + +\section CLIIntroduction Introduction + +This view provides the facility to run third party command line programs, and load the data back +into the DataManager for +immediate visualisation. All that is required is that the command line application can be called +with an argument of --xml and respond with a valid XML description of the necessary parameters. +This view can then generate a Graphical User Interface (GUI) dynamically from the XML to enable the +user to interact with the command line application. This provides an easy to use, and potentially +very flexible way to integrate almost any third party, medical imaging, command line application. + +As a high level introduction, this view performs the following steps: + +\li The view searches for available programs to run, and for each valid module, stores the XML document describing +the interface, and populates a searchable list of available programs. +\li When a program is selected, the GUI is generated. +\li The user can then set the necessary parameters and run the program. +\li Multiple programs can be launched simultaneously, and where available on the host platform, +the user can pause, resume or cancel running jobs and see console output for each job. + +As a consequence of the very flexible nature of this plugin, these instructions can only describe how to launch +command line modules in a general sense. The examples shown have been constructed by downloading the latest version +of the NiftyReg package, available here, and described further +here. NiftyReg provides valid XML descriptors +to enable the integration of the NiftyReg affine (RegAladin) and and non-rigid (RegF3D) image registration algorithms, as well +as utility programs to resample an image, and calculate a Jacobian image. These same XML descriptors work within +Slicer and MITK based applications. + +\section CLIPreferences Preferences + +The first time that the CLI View is launched, it is advisable to set the user preferences for the view. Please refer +to Figure 1. + +\image html CLIPreferences.png "Figure 1. The CLI Preferences Page" + +Each of these preferences is now explained in some detail. + +\li show debug output: If checked will output more messages to the console for debugging purposes. +\li XML validation mode: The user may select a different mode for XML validation. If this is changed, the application will +need to be restarted. There are 3 modes available. If the user selects "strict" mode, the XML schema produced by the +command line application must exactly conform to +this definition. For "none", there will be no validation. For "weak" validation, the application will report errors, +but try to carry on and load as many modules as possible. The XML validation errors are available as tool-tips on +the tab widget when the module is launched. Many third party modules included with Slicer currently have +incorrect XML, and so the "weak" or "none" mode may assist in loading them. By default the "strict" mode is chosen +so that only valid modules are loaded. +\li max concurrent processes: Sets the maximum number of concurrent jobs that can be run via this interface. The default is 4. +When the maximum number is reached, the green "Run" button is disabled until a job finishes. + +The next four preferences are to control where the view will search for valid command line programs. By default these are off +as the searching process can take a long time and slow down the startup time of the GUI. The options provided are: + +\li scan home directory: Scan the users home directory. Most useful on unix systems where users can install their own software. +\li scan current directory: This is the current working directory. Most useful on unix systems where users launch the application from the console. +\li scan installation directory: This is the directory where the actual application is stored. +\li scan CTK_MODULE_LOAD_PATH: If the environment variable CTK_MODULE_LOAD_PATH points to a valid directory, this will also be scanned. + +In addition, for the first 3 of these options, the sub-directory "cli-modules" will also be scanned if it exists. +In most cases, the user will leave these options unchecked, as the user can also specify custom directories, and +even cherry-pick specific command line programs to load. Figure 2 shows a selection box that enables the user to +specify custom directories to scan, and Figure 3. shows a selection box that enables the user to select specific modules. + +\image html CLIPreferencesAdditionalDirectories.png "Figure 2. The User can specify specific directories to scan". +\image html CLIPreferencesAdditionalModules.png "Figure 3. The User can specify specific command line programs to load". + +These directory and file selection boxes enable directories or files to be added, removed and updated in a similar fashion. + +The user must make sure that the list of files selected in the "additional modules" section are not already contained within +the directories specified in the "additional module directories" section. + +In addition, the preferences page provides: + +\li temporary directory: Images stored in the DataManager are first written to a temporary folder as +Nifti images before being passed to each command line program. +This temporary directory will default to a platform specific temporary folder, but the user may select their preferred choice +of temporary workspace. + +\section CLIUsage Usage + +When the view is launched, a simple interface is presented, as shown in Figure 4. + +\image html CLIInitial.png "Figure 4. The initial interface, with no command line programs available." + +In this example, all the above check-box preferences were off, and the "additional module directories" +was empty, and the "additional modules" list was empty so no command line applications were found. +The "Search" box displays zero entries, and there is nothing to search. + +If the available search paths contain programs that are compatible (i.e. runnable) with this view, +the name of the programs are displayed in the "Search" box in a nested menu, shown in Figure 5. + +\image html CLIWithPrograms.png "Figure 5. When valid paths are set, and programs are discovered, the menu is recalculated to show available programs." + +When a program is selected, the relevant interface is displayed, by default as collapsed group boxes to save space. +Each section can be individually expanded if necessary to see the parameters. + +\image html CLINiftyReg.png "Figure 6. An example program, showing parameters for NiftyReg's program RegAladin." + +In this example, the parameters are displayed for NiftyReg +produced at UCL, and more specifically for the affine registration program called +RegAladin. The interface can contain a wide variety of controls. If a parameter for a command line program is an input image, +then the widget displayed is linked to the DataManager, so that as new images are loaded, the correct image can be easily +selected from the combo box. + +At this stage, multiple tabs can be opened, with one tab for each command line program. Figure 7 shows 2 tabs, +for the RegAladin and RegF3D programs. + +\image html CLIF3D.png "Figure 7. Multiple tabs can be opened, one for each command line program." + +The main view provides some simple controls: + +\li Green arrow: Launch (run) the command line executable of the currently selected tab. +\li Yellow undo arrow: Resets the GUI controls of the currently selected tab to default values, if and only if the original XML specified a default value. + +At this stage, nothing has been launched. When the user hits the green arrow button, a job is launched. +Each running job is shown as a new progress reporting widget under the main tabbed widget, as shown in Figure 8. + +\image html CLINiftyRegRunning2.png "Figure 8. Multiple programs can be run, each with individual controls and console output." + +The controls for each running job are: + +\li Blue pause button: If supported on the host platform, this button will be enabled and can be toggled off (pause) or on (resume). +\li Red square: If supported on the host platform, this button will kill the command line program. +\li Black cross: Will remove the progress reporting widget from the GUI. + +When the user hits the green arrow in the main view: + +\li The currently selected tab is designated the "current" job, and contains the "current" set of parameters. +\li A new progress reporting widget is created. +\li The current parameters are copied to the progress reporting widget. In Figure 8. a parameters section +is visible, and by default is collapsed, as they are simply for referring back to. +\li All the output for the command line program is shown in the console widget, with a separate console for each job. +\li Each new progress reporting widget is simply stacked vertically (newest is top-most), and it is up to the +user to delete them when they are finished. + +It is easy to run multiple jobs. The green button simply launches the job corresponding to the current tab repeatedly. +It is up to the user to make sure that any output file names are changed between successive invocations of the same command +line module to avoid overwritting output data. + +In addition, each set of parameters contains an "About" section containing details of the contributors, the licence and acknowledgements and also +a "Help" section containing a description and a link to any on-line documentation. + +These documentation features are provided by the developers of the third party plugin, and not by the host program. +If information is missing, the user must contact the third party developers. + +\section CLITechnicalNotes Technical Notes + +From a technical perspective, the Command Line Interface (CLI) View is a simple view, harnessing the power of the CTK +command line modules framework. For technical information see: + +\li The doxygen generated manual page. +\li The wiki page. + +and obviously the CTK code base. +*/ + diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.cli/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..f738796960 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/documentation/doxygen/modules.dox @@ -0,0 +1,18 @@ +/** + \defgroup org_mitk_gui_qt_cli org.mitk.gui.qt.cli + \ingroup MITKPlugins + + \brief This plugin, provided by University College London (UCL), written by Matt + Clarkson (m.clarkson@ucl.ac.uk) uses the CTK (http://www.commontk.org) Command + Line Modules library to run command line programs as an external process. + +*/ + +/** + \defgroup org_mitk_gui_qt_cli_internal Internal + \ingroup org_mitk_gui_qt_cli + + \brief This subcategory includes the internal classes of the org.mitk.gui.qt.cli plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.cli/files.cmake b/Plugins/org.mitk.gui.qt.cli/files.cmake new file mode 100644 index 0000000000..30935b9fc2 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/files.cmake @@ -0,0 +1,66 @@ +set(SRC_CPP_FILES + QmitkCmdLineModuleMenuComboBox.cpp +) + +set(INTERNAL_CPP_FILES + QmitkDataStorageComboBoxWithSelectNone.cpp + QmitkDirectoryListWidget.cpp + QmitkFileListWidget.cpp + QmitkCmdLineModuleGui.cpp + QmitkCmdLineModuleFactoryGui.cpp + QmitkUiLoader.cpp + org_mitk_gui_qt_cli_Activator.cpp + CommandLineModulesViewConstants.cpp + CommandLineModulesViewControls.cpp + CommandLineModulesPreferencesPage.cpp + CommandLineModulesView.cpp + QmitkCmdLineModuleProgressWidget.cpp +) + +set(UI_FILES + src/internal/QmitkPathListWidget.ui + src/internal/CommandLineModulesViewControls.ui + src/internal/QmitkCmdLineModuleProgressWidget.ui +) + +set(MOC_H_FILES + src/QmitkCmdLineModuleMenuComboBox.h + src/internal/QmitkDataStorageComboBoxWithSelectNone.h + src/internal/QmitkDirectoryListWidget.h + src/internal/QmitkFileListWidget.h + src/internal/QmitkCmdLineModuleGui.h + src/internal/QmitkUiLoader.h + src/internal/org_mitk_gui_qt_cli_Activator.h + src/internal/CommandLineModulesViewControls.h + src/internal/CommandLineModulesPreferencesPage.h + src/internal/CommandLineModulesView.h + src/internal/QmitkCmdLineModuleProgressWidget.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + resources/icon.xpm + resources/run.png + resources/stop.png + plugin.xml +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + resources/CommandLineModulesResources.qrc +) + +set(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) + diff --git a/Plugins/org.mitk.gui.qt.cli/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.cli/manifest_headers.cmake new file mode 100644 index 0000000000..7e78c50b34 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "CLI") +set(Plugin-Version "0.1") +set(Plugin-Vendor "CMIC, Centre For Medical Image Computing, UCL.") +set(Plugin-ContactAddress "http://cmic.cs.ucl.ac.uk/") +set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.cli/plugin.xml b/Plugins/org.mitk.gui.qt.cli/plugin.xml new file mode 100644 index 0000000000..2960fef46e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/plugin.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.cli/resources/CommandLineModulesResources.qrc b/Plugins/org.mitk.gui.qt.cli/resources/CommandLineModulesResources.qrc new file mode 100644 index 0000000000..09dca11a7a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/resources/CommandLineModulesResources.qrc @@ -0,0 +1,8 @@ + + + run.png + stop.png + undo.png + pause.png + + diff --git a/Plugins/org.mitk.gui.qt.cli/resources/icon.png b/Plugins/org.mitk.gui.qt.cli/resources/icon.png new file mode 100644 index 0000000000..32565f7217 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/resources/icon.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/resources/icon.xpm b/Plugins/org.mitk.gui.qt.cli/resources/icon.xpm new file mode 100644 index 0000000000..8ef9be444a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/resources/icon.xpm @@ -0,0 +1,2193 @@ +/* XPM */ +static char * icon_xpm[] = { +"278 287 1903 2", +" c None", +". c #B3B3B3", +"+ c #B4B4B4", +"@ c #B3B4B3", +"# c #B2B4B2", +"$ c #BABCBA", +"% c #C7C9C8", +"& c #D2D3D2", +"* c #D8DAD8", +"= c #DDDEDD", +"- c #DDDFDD", +"; c #DCDEDC", +"> c #D9DAD9", +", c #D4D5D4", +"' c #C9CBCA", +") c #BABDBB", +"! c #B3B5B4", +"~ c #B2B3B2", +"{ c #B2B2B2", +"] c #B5B7B6", +"^ c #C1C3C2", +"/ c #CED0CF", +"( c #D8D9D8", +"_ c #E0E1E0", +": c #E7E8E7", +"< c #EEEEEE", +"[ c #F1F1F1", +"} c #F0F1F1", +"| c #EEEFEF", +"1 c #E3E5E4", +"2 c #D6D8D7", +"3 c #C4C6C5", +"4 c #B4B5B4", +"5 c #B5B5B5", +"6 c #BBBEBC", +"7 c #C8CAC9", +"8 c #D3D6D5", +"9 c #E4E5E4", +"0 c #EBECEB", +"a c #F0F1F0", +"b c #EFF0EF", +"c c #E8EAE8", +"d c #E2E4E2", +"e c #DBDDDB", +"f c #D5D7D5", +"g c #CFD2D0", +"h c #CACECB", +"i c #C8CCC9", +"j c #C8CBC9", +"k c #CCCFCD", +"l c #D1D3D1", +"m c #D8DAD9", +"n c #E2E3E2", +"o c #EDEEED", +"p c #E0E2E0", +"q c #CBCECB", +"r c #B5B7B5", +"s c #B3B4B4", +"t c #B6B9B8", +"u c #C4C5C4", +"v c #D0D1D0", +"w c #D9DBDA", +"x c #E1E3E2", +"y c #E8E9E8", +"z c #E5E6E5", +"A c #DEE0DE", +"B c #D1D4D1", +"C c #C6C9C6", +"D c #C5C9C6", +"E c #C5C8C6", +"F c #C5C8C5", +"G c #CFD2CF", +"H c #C7CAC7", +"I c #B1B3B2", +"J c #BEC0BF", +"K c #CACCCA", +"L c #D5D7D6", +"M c #E5E7E5", +"N c #EBECEC", +"O c #E1E3E1", +"P c #DBDCDB", +"Q c #D4D7D4", +"R c #CED0CE", +"S c #C8CBC8", +"T c #D4D6D4", +"U c #B7B9B7", +"V c #B8BAB9", +"W c #D1D2D1", +"X c #DADCDB", +"Y c #E8EAE9", +"Z c #F1F2F1", +"` c #E4E6E5", +" . c #DDDFDE", +".. c #D7D9D7", +"+. c #CACDCA", +"@. c #C5C7C5", +"#. c #E3E4E3", +"$. c #C0C1C0", +"%. c #B6B6B6", +"&. c #CBCDCC", +"*. c #D6D9D7", +"=. c #DEE1DF", +"-. c #E6E7E6", +";. c #ECEDEC", +">. c #E7E8E8", +",. c #E0E2E1", +"'. c #CDD0CE", +"). c #C7CAC8", +"!. c #C4C7C5", +"~. c #D4D6D5", +"{. c #EFEFEF", +"]. c #E4E6E4", +"^. c #C3C5C3", +"/. c #B1B1B1", +"(. c #B9BAB9", +"_. c #C7C7C7", +":. c #E9EBE9", +"<. c #EAEBEA", +"[. c #D0D2D0", +"}. c #C9CCCA", +"|. c #C6C9C7", +"1. c #C4C7C4", +"2. c #CDCFCD", +"3. c #C2C4C2", +"4. c #B2B3B3", +"5. c #B5B6B6", +"6. c #C2C2C2", +"7. c #CECFCE", +"8. c #E6E8E6", +"9. c #D9DCDA", +"0. c #D3D6D4", +"a. c #CCD0CD", +"b. c #C9CCC9", +"c. c #BCBDBC", +"d. c #B3B5B3", +"e. c #BBBDBC", +"f. c #C8CAC8", +"g. c #EFF0F0", +"h. c #E2E4E3", +"i. c #DCDFDD", +"j. c #D6D9D6", +"k. c #C6CAC7", +"l. c #C4C6C4", +"m. c #C9CBC9", +"n. c #B6B7B6", +"o. c #C2C5C3", +"p. c #CED1CF", +"q. c #D9DBD9", +"r. c #EEEFEE", +"s. c #DFE1E0", +"t. c #D8DBD9", +"u. c #D2D5D2", +"v. c #CBCFCC", +"w. c #C7C9C7", +"x. c #CCCECC", +"y. c #CBCDCB", +"z. c #CDCECD", +"A. c #EEEEED", +"B. c #CDCECC", +"C. c #BCBEBD", +"D. c #CACBCA", +"E. c #D4D7D5", +"F. c #DEDFDE", +"G. c #EBEDEC", +"H. c #E9EAE9", +"I. c #D5D8D5", +"J. c #CCCFCC", +"K. c #D3D5D3", +"L. c #CFD1CF", +"M. c #C4C6C3", +"N. c #BBBDBB", +"O. c #B8B9B8", +"P. c #D0D2D1", +"Q. c #DADCDA", +"R. c #E5E6E6", +"S. c #DFE0DF", +"T. c #D2D4D2", +"U. c #CCCDCC", +"V. c #DADBDA", +"W. c #D5D6D5", +"X. c #C6C8C6", +"Y. c #C3C6C3", +"Z. c #B0B1B0", +"`. c #B2B4B3", +" + c #BFC0BF", +".+ c #EEF0EF", +"++ c #DBDDDC", +"@+ c #CED1CE", +"#+ c #A9AAA9", +"$+ c #A5A6A5", +"%+ c #B1B2B1", +"&+ c #C1C2C1", +"*+ c #CCCECB", +"=+ c #C5C7C4", +"-+ c #BBBCBB", +";+ c #B9BCBA", +">+ c #C5C7C6", +",+ c #E3E5E3", +"'+ c #EFF1F0", +")+ c #D1D4D2", +"!+ c #BFC1BF", +"~+ c #B6B8B6", +"{+ c #999999", +"]+ c #828382", +"^+ c #717372", +"/+ c #727473", +"(+ c #7E807F", +"_+ c #BCBEBC", +":+ c #DBDCDA", +"<+ c #DFE1DF", +"[+ c #D6D8D6", +"}+ c #B0B0B0", +"|+ c #AFAFAF", +"1+ c #CDCFCE", +"2+ c #D7D9D8", +"3+ c #E6E8E7", +"4+ c #E7E9E7", +"5+ c #DADDDB", +"6+ c #CDD1CE", +"7+ c #C7CBC8", +"8+ c #AFB1B0", +"9+ c #A0A2A0", +"0+ c #8B8E8C", +"a+ c #767877", +"b+ c #797B7A", +"c+ c #A2A3A2", +"d+ c #B1B1B0", +"e+ c #C7CAC9", +"f+ c #D3D5D4", +"g+ c #DDE0DE", +"h+ c #D7DAD8", +"i+ c #D0D4D1", +"j+ c #C3C5C4", +"k+ c #BEC0BE", +"l+ c #B4B7B4", +"m+ c #A8A9A8", +"n+ c #949795", +"o+ c #7F8180", +"p+ c #818281", +"q+ c #AEB0AF", +"r+ c #C9CAC9", +"s+ c #C3C5C2", +"t+ c #DEDFDD", +"u+ c #BEBFBD", +"v+ c #CFD0CF", +"w+ c #E7E9E8", +"x+ c #C0C3C1", +"y+ c #B9BBBA", +"z+ c #AEAFAE", +"A+ c #9DA09E", +"B+ c #888B89", +"C+ c #757776", +"D+ c #696B6A", +"E+ c #616261", +"F+ c #5D5F5E", +"G+ c #656766", +"H+ c #707271", +"I+ c #787A79", +"J+ c #959796", +"K+ c #CCCCCC", +"L+ c #C3C4C2", +"M+ c #D0D3D0", +"N+ c #C9CDCA", +"O+ c #C2C6C4", +"P+ c #BDBFBE", +"Q+ c #B3B6B4", +"R+ c #A5A7A6", +"S+ c #929492", +"T+ c #7C7E7D", +"U+ c #6E706F", +"V+ c #616362", +"W+ c #535453", +"X+ c #444544", +"Y+ c #363736", +"Z+ c #272727", +"`+ c #191919", +" @ c #121212", +".@ c #181818", +"+@ c #363737", +"@@ c #737574", +"#@ c #888A89", +"$@ c #E0E0E0", +"%@ c #B7B8B7", +"&@ c #ECEEED", +"*@ c #D9DCD9", +"=@ c #D2D6D3", +"-@ c #B9BBB9", +";@ c #ACADAD", +">@ c #9B9D9C", +",@ c #868987", +"'@ c #676968", +")@ c #595B5A", +"!@ c #4A4C4B", +"~@ c #3D3D3D", +"{@ c #2D2E2E", +"]@ c #202020", +"^@ c #131313", +"/@ c #141414", +"(@ c #424342", +"_@ c #A8A9A9", +":@ c #D6D7D5", +"<@ c #C7C8C6", +"[@ c #B4B6B5", +"}@ c #BEBFBE", +"|@ c #CACCCB", +"1@ c #D6D7D6", +"2@ c #D0D3D1", +"3@ c #BDBFBD", +"4@ c #A3A4A3", +"5@ c #909291", +"6@ c #5F6060", +"7@ c #515252", +"8@ c #434444", +"9@ c #343534", +"0@ c #252525", +"a@ c #171717", +"b@ c #373838", +"c@ c #A1A2A2", +"d@ c #D1D3D2", +"e@ c #E5E7E6", +"f@ c #D3D6D3", +"g@ c #C0C2C0", +"h@ c #B8BAB8", +"i@ c #AAACAB", +"j@ c #999A9A", +"k@ c #848685", +"l@ c #575958", +"m@ c #4A4B4A", +"n@ c #393A3A", +"o@ c #2C2C2C", +"p@ c #1E1E1E", +"q@ c #4B4C4B", +"r@ c #989999", +"s@ c #BABBBA", +"t@ c #DCDDDC", +"u@ c #C2C4C1", +"v@ c #BFC0BE", +"w@ c #B5B6B5", +"x@ c #C0C0C0", +"y@ c #D5D8D6", +"z@ c #B0B2B0", +"A@ c #A1A4A2", +"B@ c #8E918F", +"C@ c #777978", +"D@ c #6C6E6D", +"E@ c #5E605F", +"F@ c #4F5050", +"G@ c #404141", +"H@ c #323332", +"I@ c #242524", +"J@ c #151615", +"K@ c #2F2F2F", +"L@ c #454545", +"M@ c #5B5B5B", +"N@ c #727272", +"O@ c #878787", +"P@ c #989898", +"Q@ c #A0A0A0", +"R@ c #9C9C9C", +"S@ c #636363", +"T@ c #303030", +"U@ c #6D6F6E", +"V@ c #8F908F", +"W@ c #DCDCDC", +"X@ c #C2C3C1", +"Y@ c #A5A5A5", +"Z@ c #DCDEDD", +"`@ c #D2D5D3", +" # c #A9ABA9", +".# c #979997", +"+# c #818482", +"@# c #636564", +"## c #565756", +"$# c #474847", +"%# c #393939", +"&# c #2A2A2A", +"*# c #1C1C1C", +"=# c #262626", +"-# c #3C3C3C", +";# c #535353", +"># c #6A6A6A", +",# c #808080", +"'# c #969696", +")# c #A4A4A4", +"!# c #A3A3A3", +"~# c #A2A2A2", +"{# c #A1A1A1", +"]# c #9F9F9F", +"^# c #9E9E9E", +"/# c #717171", +"(# c #232323", +"_# c #484949", +":# c #868786", +"<# c #D7D8D7", +"[# c #A7A7A7", +"}# c #AEAEAE", +"|# c #C0C2C1", +"1# c #CDCECE", +"2# c #DBDEDC", +"3# c #CED2CF", +"4# c #C2C4C3", +"5# c #BABDBA", +"6# c #AFB0AF", +"7# c #A0A2A1", +"8# c #6A6C6B", +"9# c #5C5E5D", +"0# c #4D4F4E", +"a# c #3F4040", +"b# c #303131", +"c# c #222222", +"d# c #151515", +"e# c #1B1B1B", +"f# c #333333", +"g# c #4A4A4A", +"h# c #616161", +"i# c #777777", +"j# c #8E8E8E", +"k# c #A8A8A8", +"l# c #A6A6A6", +"m# c #9D9D9D", +"n# c #8F8F8F", +"o# c #2E2E2E", +"p# c #2E2F2F", +"q# c #A6A8A7", +"r# c #C7C7C6", +"s# c #C1C3C1", +"t# c #AAAAAA", +"u# c #BBBEBB", +"v# c #A7A9A7", +"w# c #959696", +"x# c #6F7170", +"y# c #636464", +"z# c #545555", +"A# c #454646", +"B# c #373837", +"C# c #292929", +"D# c #1A1A1A", +"E# c #282828", +"F# c #404040", +"G# c #595959", +"H# c #6F6F6F", +"I# c #858585", +"J# c #A9A9A9", +"K# c #9B9B9B", +"L# c #9A9A9A", +"M# c #7B7D7C", +"N# c #9FA09F", +"O# c #BFC0C0", +"P# c #C8C9C8", +"Q# c #B6B8B7", +"R# c #E0E3E1", +"S# c #C1C4C2", +"T# c #BABCBB", +"U# c #8A8A8A", +"V# c #5A5B5A", +"W# c #4C4D4C", +"X# c #3D3E3E", +"Y# c #2F302F", +"Z# c #363636", +"`# c #4F4F4F", +" $ c #676767", +".$ c #7D7D7D", +"+$ c #959595", +"@$ c #ACACAC", +"#$ c #ABABAB", +"$$ c #979797", +"%$ c #797979", +"&$ c #646665", +"*$ c #969796", +"=$ c #DCDDDB", +"-$ c #CBCCCA", +";$ c #C1C2C0", +">$ c #929292", +",$ c #E9EBEA", +"'$ c #BDC1BF", +")$ c #B4B6B4", +"!$ c #929493", +"~$ c #606261", +"{$ c #525453", +"]$ c #353535", +"^$ c #262727", +"/$ c #161616", +"($ c #5D5D5D", +"_$ c #757575", +":$ c #8D8D8D", +"<$ c #ADADAD", +"[$ c #949494", +"}$ c #383838", +"|$ c #4F504F", +"1$ c #747675", +"2$ c #8C8D8D", +"3$ c #AEAFAF", +"4$ c #ABAEAC", +"5$ c #9B9D9B", +"6$ c #858887", +"7$ c #676867", +"8$ c #595A59", +"9$ c #494B4A", +"0$ c #3B3C3C", +"a$ c #2D2D2D", +"b$ c #1F1F1F", +"c$ c #3B3B3B", +"d$ c #6B6B6B", +"e$ c #848484", +"f$ c #939393", +"g$ c #6C6C6C", +"h$ c #D3D4D3", +"i$ c #DEE0DF", +"j$ c #C3C7C3", +"k$ c #A2A4A3", +"l$ c #909191", +"m$ c #505251", +"n$ c #333434", +"o$ c #313131", +"p$ c #626262", +"q$ c #7B7B7B", +"r$ c #919191", +"s$ c #909090", +"t$ c #A4A6A5", +"u$ c #CACBCB", +"v$ c #C6C7C5", +"w$ c #B7BAB8", +"x$ c #999B9A", +"y$ c #838483", +"z$ c #575858", +"A$ c #3A3B3A", +"B$ c #2B2C2B", +"C$ c #1D1D1D", +"D$ c #7A7C7B", +"E$ c #9C9D9D", +"F$ c #DADAD9", +"G$ c #C8C9C7", +"H$ c #7C7C7C", +"I$ c #BCBFBC", +"J$ c #C6C8C7", +"K$ c #A1A3A1", +"L$ c #767977", +"M$ c #6B6D6C", +"N$ c #5E5F5E", +"O$ c #323232", +"P$ c #242424", +"Q$ c #343434", +"R$ c #4E4E4E", +"S$ c #686868", +"T$ c #818181", +"U$ c #B8B8B8", +"V$ c #B7B7B7", +"W$ c #434343", +"X$ c #939494", +"Y$ c #DCDCDB", +"Z$ c #CCCDCB", +"`$ c #BEC1BE", +" % c #A8ABAA", +".% c #808180", +"+% c #545655", +"@% c #464747", +"#% c #383939", +"$% c #292A2A", +"%% c #5E5E5E", +"&% c #BBBBBB", +"*% c #BABABA", +"=% c #B9B9B9", +"-% c #8C8C8C", +";% c #8B8B8B", +">% c #494A4A", +",% c #8A8B8A", +"'% c #B1B2B2", +")% c #D0D1CF", +"!% c #C0C1BF", +"~% c #A7A8A7", +"{% c #C2C6C3", +"]% c #AFB1AF", +"^% c #9FA19F", +"/% c #8A8D8B", +"(% c #6A6B6B", +"_% c #5B5D5C", +":% c #4D4E4D", +"<% c #3F403F", +"[% c #303130", +"}% c #212121", +"|% c #545454", +"1% c #6D6D6D", +"2% c #868686", +"3% c #BDBDBD", +"4% c #BCBCBC", +"5% c #898989", +"6% c #828383", +"7% c #AAABAA", +"8% c #D4D4D3", +"9% c #A2A4A2", +"0% c #C4C8C5", +"a% c #BFC2C0", +"b% c #A7A9A8", +"c% c #949695", +"d% c #7D7E7E", +"e% c #626463", +"f% c #535454", +"g% c #444545", +"h% c #272827", +"i% c #191A19", +"j% c #494949", +"k% c #BFBFBF", +"l% c #BEBEBE", +"m% c #888888", +"n% c #7D7F7E", +"o% c #A2A3A3", +"p% c #C6C7C7", +"q% c #D7D7D7", +"r% c #C6C7C6", +"s% c #C1C5C3", +"t% c #AEB0AE", +"u% c #9C9F9D", +"v% c #878A88", +"w% c #686A69", +"x% c #3D3E3D", +"y% c #3E3E3E", +"z% c #737373", +"A% c #C1C1C1", +"B% c #9A9B9A", +"C% c #BCBCBB", +"D% c #D1D5D2", +"E% c #A5A7A5", +"F% c #929392", +"G% c #7B7C7B", +"H% c #5F6160", +"I% c #515352", +"J% c #434544", +"K% c #252626", +"L% c #4D4D4D", +"M% c #838383", +"N% c #C4C4C4", +"O% c #C3C3C3", +"P% c #828282", +"Q% c #464646", +"R% c #B6B7B7", +"S% c #C0C0BF", +"T% c #B8BBB9", +"U% c #9B9C9C", +"V% c #858886", +"W% c #666767", +"X% c #585959", +"Y% c #3A3B3B", +"Z% c #2C2D2C", +"`% c #424242", +" & c #787878", +".& c #C5C5C5", +"+& c #C6C6C6", +"@& c #5C5C5C", +"#& c #878888", +"$& c #AFB0B0", +"%& c #D8D8D7", +"&& c #C0C0BE", +"*& c #A3A4A4", +"=& c #CBCECC", +"-& c #A3A5A4", +";& c #787979", +">& c #505150", +",& c #414242", +"'& c #525252", +")& c #CACACA", +"!& c #C9C9C9", +"~& c #C8C8C8", +"{& c #7F7F7F", +"]& c #808281", +"^& c #A5A5A4", +"/& c #B8BBBA", +"(& c #AAABAB", +"_& c #828482", +":& c #565857", +"<& c #484948", +"[& c #393A39", +"}& c #2A2B2B", +"|& c #1C1D1D", +"1& c #CBCBCB", +"2& c #7E7E7E", +"3& c #7C7D7D", +"4& c #A0A1A0", +"5& c #C2C3C3", +"6& c #B3B4B2", +"7& c #5D5E5D", +"8& c #4E504F", +"9& c #3A3A3A", +"0& c #575757", +"a& c #747474", +"b& c #CFCFCF", +"c& c #CECECE", +"d& c #CDCDCD", +"e& c #979898", +"f& c #B9BABA", +"g& c #DBDBDA", +"h& c #C9C9C7", +"i& c #BFBFBE", +"j& c #BDBDBC", +"k& c #9D9F9D", +"l& c #4B4B4B", +"m& c #D1D1D1", +"n& c #D0D0D0", +"o& c #7A7A7A", +"p& c #484848", +"q& c #8D8F8E", +"r& c #B4B5B5", +"s& c #B0B1B1", +"t& c #939593", +"u& c #5A5C5B", +"v& c #4C4D4D", +"w& c #3E3F3E", +"x& c #202120", +"y& c #D3D3D3", +"z& c #D2D2D2", +"A& c #3E3F3F", +"B& c #858786", +"C& c #ADAEAE", +"D& c #D6D6D5", +"E& c #D1D1D0", +"F& c #505050", +"G& c #6E6E6E", +"H& c #D6D6D6", +"I& c #D5D5D5", +"J& c #D4D4D4", +"K& c #767676", +"L& c #D5D5D4", +"M& c #C4C4C3", +"N& c #BFBFBD", +"O& c #444444", +"P& c #D8D8D8", +"Q& c #9E9F9E", +"R& c #BEBFBF", +"S& c #C6C6C5", +"T& c #373737", +"U& c #555555", +"V& c #DBDBDB", +"W& c #DADADA", +"X& c #D9D9D9", +"Y& c #959695", +"Z& c #B8B9B9", +"`& c #C9C9C8", +" * c #BEBEBD", +".* c #8C8E8D", +"+* c #DDDDDD", +"@* c #707070", +"#* c #4D4E4E", +"$* c #8B8C8B", +"%* c #CECECC", +"&* c #C1C1BF", +"** c #B2B5B2", +"=* c #DEDEDE", +"-* c #5A5A5A", +";* c #838584", +">* c #ABACAC", +",* c #D2D2D0", +"'* c #696969", +")* c #A4A5A4", +"!* c #BEBEBC", +"~* c #ACACAB", +"{* c #B1B3B1", +"]* c #B9B9B7", +"^* c #A6A8A8", +"/* c #929393", +"(* c #BEBDBC", +"_* c #747574", +":* c #666666", +"<* c #474848", +"[* c #CECECD", +"}* c #888988", +"|* c #656565", +"1* c #646464", +"2* c #585858", +"3* c #333433", +"4* c #818382", +"5* c #D2D2D1", +"6* c #C2C2C0", +"7* c #9C9D9C", +"8* c #D6D5D5", +"9* c #C4C3C3", +"0* c #606060", +"a* c #5F5F5F", +"b* c #999A99", +"c* c #BDBDBB", +"d* c #BBBBBA", +"e* c #8F9190", +"f* c #CACAC9", +"g* c #BDBCBB", +"h* c #868887", +"i* c #A6A7A6", +"j* c #A6A7A7", +"k* c #858685", +"l* c #C0C1C1", +"m* c #D7D6D5", +"n* c #C4C3C2", +"o* c #BCBCBA", +"p* c #B2B2B1", +"q* c #505250", +"r* c #5F605F", +"s* c #565656", +"t* c #D9D9D8", +"u* c #C7C6C5", +"v* c #BBBBB9", +"w* c #505151", +"x* c #CBCACA", +"y* c #BCBBBA", +"z* c #C3C6C4", +"A* c #9A9C9A", +"B* c #3C3D3C", +"C* c #D4D5D5", +"D* c #CFCFCE", +"E* c #A5A4A4", +"F* c #515151", +"G* c #D3D3D2", +"H* c #A9AAA8", +"I* c #9C9E9D", +"J* c #BDBEBE", +"K* c #A6AAA7", +"L* c #4C4C4C", +"M* c #777878", +"N* c #C7C6C6", +"O* c #BCBAB9", +"P* c #BCBABA", +"Q* c #8C8D8C", +"R* c #EAEAEA", +"S* c #CCCBCA", +"T* c #BBBAB9", +"U* c #717271", +"V* c #FCFCFC", +"W* c #FFFFFF", +"X* c #FEFEFE", +"Y* c #F4F4F4", +"Z* c #E7E7E7", +"`* c #D0D0CF", +" = c #C0BFBE", +".= c #575957", +"+= c #F5F5F5", +"@= c #F0F0F0", +"#= c #E3E3E3", +"$= c #2B2B2B", +"%= c #D4D3D2", +"&= c #C2C0BF", +"*= c #ABADAC", +"== c #EDEDED", +"-= c #F6F6F6", +";= c #414141", +">= c #9A9C9B", +",= c #D8D7D6", +"'= c #B8B7B6", +")= c #FDFDFD", +"!= c #E2E2E2", +"~= c #919292", +"{= c #C8C7C6", +"]= c #BBB9B9", +"^= c #F7F7F7", +"/= c #E9E9E9", +"(= c #454645", +"_= c #878988", +":= c #D7D6D6", +"<= c #CCCCCB", +"[= c #BBB9B8", +"}= c #E1E1E1", +"|= c #D1D0CF", +"1= c #E8E8E8", +"2= c #D4D3D3", +"3= c #C2C0C0", +"4= c #BAB9B8", +"5= c #AEAFAD", +"6= c #8F918F", +"7= c #F9F9F9", +"8= c #979998", +"9= c #D9D7D7", +"0= c #C5C3C2", +"a= c #B9B8B7", +"b= c #7C7D7A", +"c= c #F8F8F8", +"d= c #8E908F", +"e= c #C9C7C6", +"f= c #BAB8B8", +"g= c #CDCCCB", +"h= c #BAB8B7", +"i= c #727372", +"j= c #ECECEC", +"k= c #FAFAFA", +"l= c #D1D0D0", +"m= c #BFBEBD", +"n= c #A7A7A6", +"o= c #8E8F8E", +"p= c #9E9F9F", +"q= c #D5D4D4", +"r= c #C1C0C0", +"s= c #BDBEBD", +"t= c #A4A4A3", +"u= c #D8D7D7", +"v= c #B1B3B0", +"w= c #E5E5E5", +"x= c #8B8D8C", +"y= c #C9C8C7", +"z= c #B9B7B7", +"A= c #A5A6A4", +"B= c #E6E6E6", +"C= c #474747", +"D= c #D3D2D2", +"E= c #CECDCC", +"F= c #BEBCBB", +"G= c #A4A3A3", +"H= c #F3F3F3", +"I= c #B9B7B6", +"J= c #AAA9A8", +"K= c #C1BFBF", +"L= c #B4B3B2", +"M= c #707270", +"N= c #B7B8B8", +"O= c #C5C3C3", +"P= c #F2F2F2", +"Q= c #B0B2B1", +"R= c #CAC9C8", +"S= c #B9B6B6", +"T= c #848584", +"U= c #FBFBFB", +"V= c #343535", +"W= c #A9AAAA", +"X= c #B8B6B6", +"Y= c #A5A5A3", +"Z= c #3F3F3F", +"`= c #C5C6C5", +" - c #D3D1D1", +".- c #C0BEBD", +"+- c #B8B6B5", +"@- c #ADACAB", +"#- c #B6B7B4", +"$- c #ADAEAD", +"%- c #D7D5D5", +"&- c #B6B5B4", +"*- c #AAACAA", +"=- c #BABBB9", +"-- c #E4E4E4", +";- c #575857", +">- c #909190", +",- c #C6C4C4", +"'- c #9D9E9D", +")- c #C1C1C0", +"!- c #424343", +"~- c #B8B5B5", +"{- c #A7A8A8", +"]- c #CFCDCD", +"^- c #BDBBBA", +"/- c #9FA1A0", +"(- c #D3D2D1", +"_- c #BFBDBD", +":- c #B8B5B4", +"<- c #AFAEAE", +"[- c #656765", +"}- c #DFDFDF", +"|- c #969897", +"1- c #C3C0C0", +"2- c #B7B5B4", +"3- c #8D8E8E", +"4- c #C7C5C5", +"5- c #BAB7B7", +"6- c #B7B4B4", +"7- c #949493", +"8- c #CCCAC9", +"9- c #BCB9B8", +"0- c #A7A6A6", +"a- c #BABAB9", +"b- c #D0CECE", +"c- c #AFB0AE", +"d- c #9D9E9E", +"e- c #D4D2D2", +"f- c #B7B4B3", +"g- c #B1AFAF", +"h- c #949594", +"i- c #969695", +"j- c #D7D7D6", +"k- c #C8C5C5", +"l- c #B7B3B3", +"m- c #878785", +"n- c #828483", +"o- c #D2D1D1", +"p- c #CCCACA", +"q- c #BBB8B7", +"r- c #B6B3B3", +"s- c #A6A5A5", +"t- c #D1CFCE", +"u- c #BDBABA", +"v- c #A9A8A8", +"w- c #9B9C9B", +"x- c #BBBCBC", +"y- c #D5D3D3", +"z- c #C0BDBD", +"A- c #B4B2B2", +"B- c #919392", +"C- c #C3C1C1", +"D- c #B6B3B2", +"E- c #BCBDBB", +"F- c #A1A1A0", +"G- c #C8C6C6", +"H- c #B6B2B2", +"I- c #B3B3B1", +"J- c #313232", +"K- c #CDCBCB", +"L- c #BBB8B8", +"M- c #A9A9A8", +"N- c #1D1E1D", +"O- c #D1CFCF", +"P- c #B5B2B2", +"Q- c #ACAAAA", +"R- c #D6D4D4", +"S- c #90908E", +"T- c #C5C1C1", +"U- c #B8B4B4", +"V- c #B5B2B1", +"W- c #7D7D7B", +"X- c #C9C7C7", +"Y- c #B5B1B1", +"Z- c #AAA9A9", +"`- c #BDBAB9", +" ; c #AEACAC", +".; c #B6B6B4", +"+; c #ABAAAA", +"@; c #C5C2C2", +"#; c #B4B1B1", +"$; c #B3B2B2", +"%; c #ADADAC", +"&; c #B7B7B6", +"*; c #CAC7C7", +"=; c #B9B5B5", +"-; c #B4B0B0", +";; c #A3A2A1", +">; c #C9C8C8", +",; c #CFCCCC", +"'; c #BBB7B7", +"); c #B0AEAE", +"!; c #868685", +"~; c #C1BEBE", +"{; c #494A49", +"]; c #898B8A", +"^; c #C6C3C3", +"/; c #B4AFB0", +"(; c #B5B0B1", +"_; c #CBC8C8", +":; c #B4AFAF", +"<; c #919190", +"[; c #B3AFAF", +"}; c #A9A8A7", +"|; c #D4D1D2", +"1; c #BEBABB", +"2; c #B2AFAF", +"3; c #B1B0AF", +"4; c #C2BEBE", +"5; c #A8A7A5", +"6; c #C7C4C4", +"7; c #B3AEAF", +"8; c #9D9C9A", +"9; c #CBC9C9", +"0; c #B3AEAE", +"a; c #A5A3A3", +"b; c #8F8F8D", +"c; c #D0CDCD", +"d; c #AAA8A8", +"e; c #7F7F7D", +"f; c #D5D2D2", +"g; c #525352", +"h; c #D6D4D5", +"i; c #C3BFBF", +"j; c #B5B0B0", +"k; c #B2AEAE", +"l; c #898988", +"m; c #C8C4C4", +"n; c #B7B2B2", +"o; c #B2ADAE", +"p; c #9E9D9D", +"q; c #CDC9C9", +"r; c #B9B4B4", +"s; c #A7A5A6", +"t; c #B4B2B1", +"u; c #D1CECE", +"v; c #B2ADAD", +"w; c #ADAAAA", +"x; c #ACAAA9", +"y; c #B8B7B7", +"z; c #D5D2D3", +"A; c #A1A0A0", +"B; c #BDBBBB", +"C; c #C4C0C0", +"D; c #B0AFAF", +"E; c #C9C5C5", +"F; c #B2ACAD", +"G; c #B1ACAD", +"H; c #C7C8C7", +"I; c #CDCACA", +"J; c #6E6F6F", +"K; c #D2CFCF", +"L; c #B1ACAC", +"M; c #AFACAC", +"N; c #7F7E7E", +"O; c #D6D3D4", +"P; c #BFBBBB", +"Q; c #969595", +"R; c #464847", +"S; c #C4C1C1", +"T; c #B1ABAC", +"U; c #B6B4B3", +"V; c #A8A7A7", +"W; c #C9C6C6", +"X; c #A5A3A4", +"Y; c #AEADAC", +"Z; c #B5B4B3", +"`; c #A1A3A2", +" > c #C3C4C3", +".> c #CECBCB", +"+> c #AAA8A7", +"@> c #D3D0D0", +"#> c #BCB7B7", +"$> c #B0ABAC", +"%> c #B1ADAE", +"&> c #9C9B9B", +"*> c #C0BBBC", +"=> c #B3ADAE", +"-> c #B0ABAB", +";> c #918F8D", +">> c #C6C1C2", +",> c #B5AFB0", +"'> c #B0AAAB", +")> c #CDCCCC", +"!> c #B6B1B2", +"~> c #767675", +"{> c #ABA8A8", +"]> c #8F8E8E", +"^> c #D4D1D1", +"/> c #BCB7B8", +"(> c #B1ADAD", +"_> c #A2A1A1", +":> c #D5D3D4", +"<> c #C1BCBD", +"[> c #B0AAAA", +"}> c #B1ABAB", +"|> c #B1AFAE", +"1> c #3B3C3B", +"2> c #D2D0D1", +"3> c #C6C2C3", +"4> c #B0A9AA", +"5> c #AFA9AA", +"6> c #A8A7A8", +"7> c #AAA7A7", +"8> c #CBC7C8", +"9> c #B7B1B2", +"0> c #A1A09E", +"a> c #ADA9AA", +"b> c #989494", +"c> c #BCB8B8", +"d> c #898787", +"e> c #C2BDBE", +"f> c #AFA8A9", +"g> c #353635", +"h> c #D0CFCF", +"i> c #C7C3C4", +"j> c #B4AEAF", +"k> c #878686", +"l> c #CCC8C9", +"m> c #A7A4A5", +"n> c #9B9A9A", +"o> c #B9B3B4", +"p> c #AEA8A9", +"q> c #AEABAB", +"r> c #ABAAA9", +"s> c #BEB8B9", +"t> c #B1AAAB", +"u> c #ADA9A9", +"v> c #B6B4B4", +"w> c #D3D1D2", +"x> c #C3BEBF", +"y> c #AEA7A9", +"z> c #A5A2A2", +"A> c #2F3030", +"B> c #AEA7A8", +"C> c #9E9B9B", +"D> c #C2C3C2", +"E> c #B6B1B1", +"F> c #A8A5A6", +"G> c #939090", +"H> c #666867", +"I> c #B9B3B5", +"J> c #AFA8AA", +"K> c #616060", +"L> c #D4D2D3", +"M> c #BFB9BA", +"N> c #AFAAAA", +"O> c #7D7C7C", +"P> c #C4BFC0", +"Q> c #B2ABAC", +"R> c #ADA7A8", +"S> c #ADA6A8", +"T> c #AAA9AA", +"U> c #949393", +"V> c #C9C4C5", +"W> c #ADA6A7", +"X> c #B4B1B0", +"Y> c #CDC9CA", +"Z> c #B7B0B1", +"`> c #B2B0B0", +" , c #D2D0D0", +"., c #BAB4B6", +"+, c #A9A5A5", +"@, c #BFBABB", +"#, c #A39E9E", +"$, c #C5C0C1", +"%, c #ADA5A7", +"&, c #A9A7A7", +"*, c #989595", +"=, c #CAC5C6", +"-, c #B4ADAE", +";, c #ACA5A7", +">, c #A5A2A3", +",, c #CFCBCB", +"', c #ACA5A6", +"), c #ABA8A9", +"!, c #5B5C5C", +"~, c #BBB5B6", +"{, c #AEA6A8", +"], c #8C8B8B", +"^, c #A09F9F", +"/, c #ACA4A6", +"(, c #B0ACAC", +"_, c #CAC6C6", +":, c #A6A3A4", +"<, c #B7B5B5", +"[, c #D0CCCC", +"}, c #B7B0B2", +"|, c #ACA4A5", +"1, c #555756", +"2, c #BCB5B7", +"3, c #9E9A9A", +"4, c #B7B2B3", +"5, c #414241", +"6, c #C2BCBD", +"7, c #B0A8AA", +"8, c #ABA4A5", +"9, c #ABA3A5", +"0, c #CCCBCB", +"a, c #C7C2C2", +"b, c #B2AAAB", +"c, c #A6A4A4", +"d, c #696868", +"e, c #CCC7C8", +"f, c #848383", +"g, c #B8B1B2", +"h, c #ADA8A9", +"i, c #999898", +"j, c #BDB6B8", +"k, c #ABA3A4", +"l, c #ADA5A6", +"m, c #C3BDBE", +"n, c #ABA2A4", +"o, c #A8A8A7", +"p, c #ADA8A8", +"q, c #B5B1B2", +"r, c #C8C2C4", +"s, c #B2AAAC", +"t, c #AAA2A4", +"u, c #A4A2A3", +"v, c #A8A4A4", +"w, c #CDC8C8", +"x, c #B5ADAE", +"y, c #A9A5A6", +"z, c #A29E9E", +"A, c #D2CECF", +"B, c #B9B1B3", +"C, c #ACA3A5", +"D, c #9A9496", +"E, c #AAA2A3", +"F, c #AAA1A3", +"G, c #7B7A7A", +"H, c #BDB7B9", +"I, c #C4BEC0", +"J, c #9B999A", +"K, c #939191", +"L, c #BAB4B5", +"M, c #C9C3C4", +"N, c #979496", +"O, c #B5AEAF", +"P, c #A9A1A3", +"Q, c #D0CBCC", +"R, c #908F8F", +"S, c #AEAAAA", +"T, c #B1A8AA", +"U, c #D3CFD0", +"V, c #AAA6A6", +"W, c #B8B4B5", +"X, c #ADA4A6", +"Y, c #A9A1A2", +"Z, c #D7D3D4", +"`, c #787B7A", +" ' c #A4A0A0", +".' c #B6B2B3", +"+' c #B0ABAD", +"@' c #A9A0A2", +"#' c #BBB4B6", +"$' c #CBC6C7", +"%' c #656B69", +"&' c #8B8D8D", +"*' c #9F9999", +"=' c #767776", +"-' c #5C6260", +";' c #737776", +">' c #545353", +",' c #E8E6E6", +"'' c #ABA6A6", +")' c #656A68", +"!' c #A6A2A3", +"~' c #B7AFB1", +"{' c #E0DDDE", +"]' c #5F6664", +"^' c #8A8989", +"/' c #1F201F", +"(' c #5B5C5B", +"_' c #A9A4A5", +":' c #DAD6D7", +"<' c #C4BDBF", +"[' c #6A6E6D", +"}' c #9F9C9D", +"|' c #636463", +"1' c #A39E9F", +"2' c #F0EFEF", +"3' c #ABA5A6", +"4' c #2A2929", +"5' c #4F4D4D", +"6' c #757372", +"7' c #999496", +"8' c #CEC9CA", +"9' c #9EA0A0", +"0' c #403E3E", +"a' c #615E5F", +"b' c #7E7A7B", +"c' c #969192", +"d' c #A69EA0", +"e' c #B8B0B2", +"f' c #F2F0F1", +"g' c #A7A2A3", +"h' c #2F2E2E", +"i' c #525050", +"j' c #726F6F", +"k' c #8D8989", +"l' c #A09A9B", +"m' c #A9A2A3", +"n' c #ECEAEB", +"o' c #636967", +"p' c #A29D9D", +"q' c #1F1E1E", +"r' c #656263", +"s' c #827F80", +"t' c #989394", +"u' c #A6A0A1", +"v' c #AAA3A4", +"w' c #E1DEDF", +"x' c #A5A1A1", +"y' c #6E7271", +"z' c #343233", +"A' c #565454", +"B' c #767273", +"C' c #8F8A8C", +"D' c #A19B9C", +"E' c #C7C2C3", +"F' c #F1EFF0", +"G' c #B1A9AB", +"H' c #7B7F7D", +"I' c #686767", +"J' c #474546", +"K' c #696767", +"L' c #868283", +"M' c #9B9597", +"N' c #A8A1A3", +"O' c #A9A2A4", +"P' c #C2BBBD", +"Q' c #F6F5F5", +"R' c #777A78", +"S' c #757876", +"T' c #828080", +"U' c #373636", +"V' c #5B5858", +"W' c #7A7677", +"X' c #928D8E", +"Y' c #A49D9F", +"Z' c #C5BFC0", +"`' c #BAB3B5", +" ) c #5D6361", +".) c #4C4E4E", +"+) c #979595", +"@) c #272626", +"#) c #4D4B4C", +"$) c #6D6A6A", +"%) c #888384", +"&) c #9E9799", +"*) c #D1CCCD", +"=) c #F3F2F2", +"-) c #A7A5A5", +";) c #191818", +">) c #3C3C3B", +",) c #5E5D5D", +"') c #7D7979", +")) c #959091", +"!) c #A59EA0", +"~) c #E8E5E6", +"{) c #E9E6E7", +"]) c #B3ACAE", +"^) c #7E807E", +"/) c #595C5B", +"() c #ACA6A7", +"_) c #B3AFB0", +":) c #2D2C2C", +"<) c #504E4E", +"[) c #706D6D", +"}) c #8A8786", +"|) c #F7F6F6", +"1) c #CFCACB", +"2) c #AAA4A6", +"3) c #6C706E", +"4) c #606564", +"5) c #0A0B0B", +"6) c #A9A2A2", +"7) c #413F40", +"8) c #626060", +"9) c #807C7D", +"0) c #A7A1A1", +"a) c #B3ABAD", +"b) c #D5D0D1", +"c) c #DCD8D9", +"d) c #B4ADAF", +"e) c #929192", +"f) c #4A4E4D", +"g) c #A59F9F", +"h) c #313031", +"i) c #545152", +"j) c #737070", +"k) c #8E8B8B", +"l) c #A29C9D", +"m) c #AAA3A5", +"n) c #C3BCBE", +"o) c #EDEBEC", +"p) c #9B9999", +"q) c #626866", +"r) c #070707", +"s) c #434342", +"t) c #666364", +"u) c #848081", +"v) c #9A9596", +"w) c #B9B2B3", +"x) c #C6C0C1", +"y) c #F8F7F7", +"z) c #EFEDEE", +"A) c #DFDCDD", +"B) c #CDC8C9", +"C) c #A6A1A3", +"D) c #898A88", +"E) c #292C2B", +"F) c #343333", +"G) c #585556", +"H) c #787475", +"I) c #918C8D", +"J) c #A29C9E", +"K) c #ABA4A6", +"L) c #C0B9BB", +"M) c #CDC7C9", +"N) c #E7E5E5", +"O) c #F4F3F3", +"P) c #F5F3F4", +"Q) c #E8E6E7", +"R) c #9E9C9C", +"S) c #8F8D8E", +"T) c #464B49", +"U) c #000000", +"V) c #797878", +"W) c #252424", +"X) c #484647", +"Y) c #6B6868", +"Z) c #878283", +"`) c #9D9798", +" ! c #C7C1C2", +".! c #E2DFDF", +"+! c #EEEDED", +"@! c #F7F6F7", +"#! c #EEECED", +"$! c #D4D0D1", +"%! c #C7C1C3", +"&! c #A39FA0", +"*! c #979495", +"=! c #858584", +"-! c #515654", +";! c #050505", +">! c #918F8F", +",! c #393838", +"'! c #5D5A5A", +")! c #7C7879", +"!! c #948F90", +"~! c #A59FA0", +"{! c #C1BBBC", +"]! c #F5F4F4", +"^! c #B5AFB1", +"/! c #A7A3A3", +"(! c #9D9A9B", +"_! c #787A7A", +":! c #616462", +"~ c #858282", +",~ c #9C9798", +"'~ c #B9B2B4", +")~ c #E1DDDE", +"!~ c #EDECEC", +"~~ c #E2DFE0", +"{~ c #D5D1D2", +"]~ c #C8C2C3", +"^~ c #BDB8B8", +"/~ c #B0A9AB", +"(~ c #999696", +"_~ c #878886", +":~ c #5B615F", +"<~ c #4F5452", +"[~ c #373B3A", +"}~ c #161818", +"|~ c #353534", +"1~ c #5A5858", +"2~ c #7A7777", +"3~ c #938E8F", +"4~ c #A49E9F", +"5~ c #B3ACAD", +"6~ c #C0BABB", +"7~ c #DBD7D8", +"8~ c #DBD8D8", +"9~ c #B6B0B2", +"0~ c #A7A3A4", +"a~ c #9E9B9C", +"b~ c #7A7C7A", +"c~ c #5F6563", +"d~ c #535856", +"e~ c #484C4B", +"f~ c #3C403F", +"g~ c #2F3130", +"h~ c #1E201F", +"i~ c #252625", +"j~ c #4B4949", +"k~ c #888485", +"l~ c #9E9999", +"m~ c #AEA5A7", +"n~ c #BBB3B5", +"o~ c #EFEDED", +"p~ c #EEECEC", +"q~ c #BCB6B7", +"r~ c #979695", +"s~ c #6A6E6C", +"t~ c #585E5C", +"u~ c #4D5250", +"v~ c #424544", +"w~ c #343836", +"x~ c #262827", +"y~ c #060606", +"z~ c #C2BBBC", +"A~ c #888686", +"B~ c #3A3939", +"C~ c #5E5C5C", +"D~ c #7D797A", +"E~ c #969191", +"F~ c #A7A0A1", +"G~ c #B5ADAF", +"H~ c #DCD9D9", +"I~ c #E9E7E7", +"J~ c #F4F2F3", +"K~ c #E7E4E5", +"L~ c #B5AFAF", +"M~ c #A7A2A4", +"N~ c #9D9A9A", +"O~ c #8D8C8C", +"P~ c #5E6462", +"Q~ c #525856", +"R~ c #474B4A", +"S~ c #3A3E3C", +"T~ c #2C302F", +"U~ c #1D201E", +"V~ c #0C0E0E", +"W~ c #535252", +"X~ c #4E4C4D", +"Y~ c #6F6D6E", +"Z~ c #8B8788", +"`~ c #A09A9C", +" { c #AFA7A9", +".{ c #BCB5B6", +"+{ c #CAC4C5", +"@{ c #D7D2D3", +"#{ c #ECEBEB", +"${ c #DFDCDC", +"%{ c #BAB5B5", +"&{ c #A29E9F", +"*{ c #808282", +"={ c #676C6A", +"-{ c #575C5A", +";{ c #4C504F", +">{ c #3F4342", +",{ c #323634", +"'{ c #252826", +"){ c #030303", +"!{ c #CECACA", +"~{ c #5C5B5B", +"{{ c #403E3F", +"]{ c #625F60", +"^{ c #989395", +"/{ c #A8A2A3", +"({ c #B6AFB0", +"_{ c #F2F1F1", +":{ c #E5E2E3", +"<{ c #CBC5C6", +"[{ c #C0BABC", +"}{ c #A6A1A2", +"|{ c #747676", +"1{ c #5A605E", +"2{ c #444A48", +"3{ c #383C3B", +"4{ c #2B2E2D", +"5{ c #1C1E1E", +"6{ c #0B0B0B", +"7{ c #999697", +"8{ c #302F30", +"9{ c #545252", +"0{ c #737071", +"a{ c #8F8B8C", +"b{ c #BEB7B9", +"c{ c #B8B2B4", +"d{ c #ABA6A7", +"e{ c #949391", +"f{ c #636966", +"g{ c #565C5A", +"h{ c #4A4F4E", +"i{ c #3E4341", +"j{ c #313534", +"k{ c #232524", +"l{ c #131413", +"m{ c #010303", +"n{ c #D8D6D6", +"o{ c #B8B2B2", +"p{ c #A8A3A4", +"q{ c #928E8F", +"r{ c #7F7C7C", +"s{ c #838081", +"t{ c #A19D9D", +"u{ c #D2CECE", +"v{ c #B2ABAD", +"w{ c #A5A0A1", +"x{ c #999797", +"y{ c #707473", +"z{ c #4F5553", +"A{ c #444847", +"B{ c #373B39", +"C{ c #1A1B1B", +"D{ c #080A08", +"E{ c #DFDDDD", +"F{ c #BFB9BB", +"G{ c #B8B1B3", +"H{ c #918F90", +"I{ c #545957", +"J{ c #494E4C", +"K{ c #3C4140", +"L{ c #2F3332", +"M{ c #212322", +"N{ c #101212", +"O{ c #010101", +"P{ c #D5D1D1", +"Q{ c #AFA9AB", +"R{ c #A3A0A1", +"S{ c #989797", +"T{ c #595F5D", +"U{ c #4E5352", +"V{ c #434745", +"W{ c #353937", +"X{ c #272929", +"Y{ c #171A19", +"Z{ c #060707", +"`{ c #BBB5B7", +" ] c #DBD8D9", +".] c #E7E5E6", +"+] c #C2BDBD", +"@] c #B6B0B0", +"#] c #9F9B9B", +"$] c #777A79", +"%] c #3A3F3E", +"&] c #2D3130", +"*] c #202121", +"=] c #0F100F", +"-] c #AFA7A8", +";] c #C9C3C5", +">] c #E3E0E0", +",] c #F0EEEE", +"'] c #BBB6B7", +")] c #A3A09F", +"!] c #969494", +"~] c #818483", +"{] c #585D5B", +"]] c #414543", +"^] c #333635", +"/] c #040404", +"(] c #B1AEAE", +"_] c #EAE7E8", +":] c #F6F5F6", +"<] c #B3AEB0", +"[] c #9C9A9A", +"}] c #757877", +"|] c #525755", +"1] c #3A3D3C", +"2] c #2C2F2D", +"3] c #1D201F", +"4] c #0C0C0C", +"5] c #BEB9BA", +"6] c #BDB7B8", +"7] c #E4E1E2", +"8] c #ECEAEA", +"9] c #939292", +"0] c #818282", +"a] c #666B69", +"b] c #4B504F", +"c] c #3F4341", +"d] c #323635", +"e] c #242625", +"f] c #141514", +"g] c #C5C0C0", +"h] c #DEDBDC", +"i] c #D8D4D4", +"j] c #CBC5C7", +"k] c #9B9899", +"l] c #727674", +"m] c #444948", +"n] c #383B3A", +"o] c #2A2E2D", +"p] c #1B1C1C", +"q] c #0A0A0A", +"r] c #A19C9C", +"s] c #929191", +"t] c #646967", +"u] c #565B59", +"v] c #3D4241", +"w] c #303433", +"x] c #222424", +"y] c #111313", +"z] c #736E6E", +"A] c #F1F0F0", +"B] c #C3BEBE", +"C] c #D6D3D3", +"D] c #B1ABAD", +"E] c #A5A1A2", +"F] c #888788", +"G] c #4E5453", +"H] c #424746", +"I] c #191A1A", +"J] c #070808", +"K] c #444443", +"L] c #B2AFB0", +"M] c #DAD7D8", +"N] c #F4F3F4", +"O] c #9E9D9C", +"P] c #919090", +"Q] c #7B7E7D", +"R] c #484D4B", +"S] c #2F3230", +"T] c #202221", +"U] c #101010", +"V] c #4B4F4E", +"W] c #767777", +"X] c #E6E4E5", +"Y] c #DCD9DA", +"Z] c #C4BEBF", +"`] c #C8C3C4", +" ^ c #A4A1A2", +".^ c #979596", +"+^ c #595E5C", +"@^ c #4E5351", +"#^ c #424644", +"$^ c #272928", +"%^ c #181918", +"&^ c #9A9797", +"*^ c #E0DDDD", +"=^ c #EBE9EA", +"-^ c #8E8D8E", +";^ c #535857", +">^ c #3B3E3D", +",^ c #2D3030", +"'^ c #1E2020", +")^ c #0E0F0F", +"!^ c #272A28", +"~^ c #818080", +"{^ c #9A9697", +"]^ c #B7B3B4", +"^^ c #949292", +"/^ c #8A8788", +"(^ c #7F7E7F", +"_^ c #626765", +":^ c #575D5B", +"<^ c #4C514F", +"[^ c #404443", +"}^ c #252727", +"|^ c #151616", +"1^ c #363A38", +"2^ c #454948", +"3^ c #2B2F2D", +"4^ c #1C1F1D", +"5^ c #393D3C", +"6^ c #4A504E", +"7^ c #3E4342", +"8^ c #323533", +"9^ c #242525", +"0^ c #131414", +"a^ c #333735", +"b^ c #505553", +"c^ c #2A2D2D", +"d^ c #1A1C1B", +"e^ c #080A0A", +"f^ c #232624", +"g^ c #555A59", +"h^ c #3E4140", +"i^ c #111111", +"j^ c #464A49", +"k^ c #434746", +"l^ c #363938", +"m^ c #282B29", +"n^ c #1F2120", +"o^ c #4F5352", +"p^ c #2E3231", +"q^ c #0F1010", +"r^ c #1F2020", +"s^ c #4A4F4D", +"t^ c #555A58", +"u^ c #515655", +"v^ c #474C4B", +"w^ c #2D302F", +"x^ c #090A09", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" . . . . . . . . . ", +" + + @ # $ % & * = - ; > , ' ) ! ~ . . ", +" + . { ~ ] ^ / ( _ : < [ [ [ [ [ } } } } } | 1 2 3 4 5 . ", +" . . { @ 6 7 8 - 9 0 a [ [ [ b c d e f g h i j j k l m n o a b p q r 5 . ", +" . . { s t u v w x y | [ [ [ a 0 z A * B q C D D D E E E E E E E F F F F G _ b a p H I . . ", +" + . . 4 J K L A M N } [ [ [ | y O P Q R H C C C C D D D E E E E E E F F F F F F F F F F S ; b o T U . { ", +" + . @ # V 3 W X d Y b Z [ [ a 0 ` ...l +.C C C C C C C D D D E E E E E E F F F F F F F F F F F F F @.@.@.' #.a A $.+ . ", +" + . %.. ! $.&.*.=.-.;.Z Z Z Z < >.,.X T '.).C C C C C C C C C D D D E E E E E E E F F F F F F F F F F F F @.@.@.@.!.!.!.!.!.~.{.].^./.. ", +" { . @ ~ (._.& ; 1 :.a Z Z Z a <.1 - 2 [.}.|.|.|.C C C C C C C C C C D D D E E E E E E F F F F F F F F F F F F F @.@.@.!.!.!.!.!.!.1.1.1.1.2.0 -.3.{ . ", +" { . . 4.5.6.7.( p : o Z Z Z Z o 8.p 9.0.a.).|.|.|.|.|.|.C C C C C C C C C D D D E E E E E E F F F F F F F F F F F F F @.@.@.!.!.!.!.!.!.!.1.1.1.1.1.1.1.1.b.<.n c.. . ", +" . . . d.e.f., = 9 0 a Z Z Z g.:.h.i.j.g i k.k.k.|.|.|.|.|.|.C C C C C C C C C D D D D E E E E E E F F F F F F F F F F F F @.@.@.@.!.!.E |.|.|.F 1.1.1.1.1.1.1.1.l.l.l.l.m.0 > + . ", +" . . { + n.o.p.q.O y r.Z Z Z Z ;.-.s.t.u.v.k.k.k.k.k.k.|.|.|.|.|.|.C C C C C C C C C C D D D E E E E E E F F F F F F F F F F F F F @.@.@.!.!.!.!.!.E w.b.q x.y.m.C F 1.1.l.l.l.l.l.l.l.l.z.A.B.. { ", +" . . . ! C.D.E.F.M G.[ Z Z Z b H.d ; I.G i k.k.k.k.k.k.k.k.|.|.|.|.|.|.|.C C C C C C C C C D D D E E E E E E E F F F F F F F F F F F F @.@.@.!.!.!.!.!.!.!.1.1.F w.b.J.[.K.K.L.D.@.l.l.l.l.l.l.l.M.M.M.f : N.. ", +" { . { . O.l.P.Q.h.Y b Z Z Z [ G.R.S.* T.x.H H k.k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.C C C C C C C C C D D D D E E E E E E F F F F F F F F F F F F F @.@.@.!.!.!.!.!.!.1.1.1.1.1.1.1.F C S U.& ..V.W.x.X.l.l.M.M.M.Y.Y.Y.^.^.n T Z.{ ", +" + . { `.4 +y.2 s.-.;.Z Z Z Z .+c n ++f @+S H H H H H k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.C C C C C C C C C C D D D E E E E E E F F F F F F F F F F F F F @.@.@.!.!.!.!.!.!.1.1.1.1.1.1.1.1.1.3.c.~ #+$+%+&+v > - ..*+=+M.Y.Y.Y.^.^.^.^.^.m.y -+. ", +" . . . @ ;+>+B ; ,+:.'+Z Z Z } 0 ` A * )+y.).).H H H H H H k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.|.C C C C C C C C C D D D E E E E E E E F F F F F F F F F F F F @.@.@.!.!.!.!.!.!.!.1.1.1.1.1.l.!+~+#+{+]+^+^+^+^+^+^+^+/+(+_+:+<+[+b.^.^.^.^.^.^.^.^.^.^.e W { }+ ", +" . . |+{ 5.&+1+2+_ 3+o Z Z Z Z r.4+O 5+E.6+i 7+).).).H H H H H H k.k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.C C C C C C C C C C D D D E E E E E E F F F F F F F F F F F F F @.@.@.!.!.!.!.!.!.1.1.1.3.$ 8+9+0+a+^+^+^+^+^+^+^+^+^+^+^+^+^+^+/+b+c+F.S.[.@.^.^.^.^.^.^.^.^.^.w._ d+. ", +" . { @ 4 e.e+f+i.z <.a Z Z Z a <.].g+h+i+h 7+7+7+7+).).).H H H H H H H k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.C C C C C C C C C C D D D E E E E E E F F F F F F F F F F F F F @.@.@.!.!.!.!.!.!.j+k+l+m+n+o+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+/+p+q+n ( r+^.^.^.^.^.^.^.^.s+s+t+u+. ", +" . + { { n.^.v+w O w+r.Z Z Z Z o 3+,.Q.0.'.7+7+7+7+7+7+7+7+).).).H H H H H H k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.|.C C C C C C C C C D D D E E E E E E E F F F F F F F F F F F F @.@.@.@.!.!.!.x+y+z+A+B+C+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+D+E+F+G+H+^+^+^+^+^+I+J+K+F.2.l.^.^.^.s+s+s+L+L+L+L.R . { ", +" + . 4.4 C.' f A M G.} Z Z Z a :.,+- j.M+N+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H k.k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.C C C C C C C C C C D D D E E E E E E F F F F F F F F F F F F F @.@.X.O+P+Q+R+S+T+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+U+V+W+X+Y+Z+`+ @ @ @ @.@+@V+^+^+^+@@#@Z.$@& =+s+s+s+L+L+L+3.3.3.^.f /.. ", +" + . s { %@l.g X n Y .+Z Z Z Z &@8.,.*@=@a.7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H H k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.|.C C C C C C C C C D D D E E E E E E E F F F F F F F F F F F F @.&+-@;@>@,@@@^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+'@)@!@~@{@]@^@ @ @ @ @ @ @ @ @ @ @ @ @/@(@^+^+^+p+_@f+:@<@L+L+3.3.3.3.3.3.3.3.T . . ", +" . { @ [@}@|@1@=.-.;.Z Z Z Z b H.,+i.*.2@+.7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H k.k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.C C C C C C C C C D D D D E E E E E E F F F F F F F F F X.Y.3@# 4@5@b+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+U+6@7@8@9@0@a@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @b@^+^+T+c@u * f.3.3.3.3.3.3.3.3.3.3.y.~+. ", +" . + . s V >+d@++,+:.b Z Z Z Z ;.e@<+q.f@a.i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H k.k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.C C C C C C C C C C D D D E E E E E E F F F F F F F 1.g@h@i@j@k@@@^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+G+l@m@n@o@p@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @q@^+I+r@s@t@K 3.3.3.3.3.3.3.u@u@u@s+v@. {+ ", +" . + { ~ w@x@x...p 3+&@Z Z Z Z .+Y d ; y@g N+i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).).H H H H H H k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.|.C C C C C C C C C D D D E E E E E E E F F F F o._+z@A@B@C@^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+D@E@F@G@H@I@J@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @`+K@L@M@N@O@P@Q@R@O@S@T@ @ @ @ @ @ @.@U@C+V@w@W@R ^.3.3.3.u@u@u@X@X@X@X@X@+ Y@ ", +" + . . . y+w.T.Z@1 <.a Z Z Z } 0 ` =.t.`@v.i i i i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H k.k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.C C C C C C C C C C D D D E E E E E E F 1.g@~+ #.#+#^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+H+@###$#%#&#*# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @^@=#-#;#>#,#'#Y@Y@)#!#!#~#{#{#Q@]#^#^#/#(# @ @ @ @ @_#/+:#z+<#T.=+u@u@X@X@X@X@X@X@X@X@X@[#}# ", +" . { . ~ n.|#1#q.,.4+o Z Z Z Z r.w+x 2#I.3#N+i i i i i i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H H k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.C C C C C C C C C C D D D E E E E E 4#5#6#7#0+C+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+8#9#0#a#b#c#d# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @e#f#g#h#i#j#)#k#[#l#l#Y@)#!#!#~#{#{#Q@]#]#^#m#R@R@R@n#o# @ @ @ @p#^+o+q#7.:@r#X@X@X@X@X@X@X@X@s#s#s#t#. ", +" . + @ d.u#j 0.- ` 0 } Z Z Z a <.].A h+)+v.i i i i i i i i i i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).).H H H H H H k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.|.C C C C C C C C C D D D E E !.J ] v#w#(+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+x#y#z#A#B#C#D# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @d#E#F#G#H#I#m#t#J#J#J#k#[#l#l#Y@)#)#!#~#~#{#Q@]#]#^#m#m#R@R@R@K#L#{+n#(# @ @ @.@^+M#N#O#> P#X@X@X@X@X@s#s#s#s#s#s#Q#. ", +" %.4.h@f.* O y r.Z Z Z Z o : R#5+Q 6+i i i i i i i i i i i i i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H k.k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.C C C C C C C C C C D D S#T#z+A+U#@@^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+D+V#W#X#Y#]@/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @p@Z#`# $.$+$t#@$#$t#t#J#J#J#k#[#[#l#Y@)#)#!#~#~#{#Q@Q@]#^#m#m#R@R@R@K#L#L#{+P@$$$$%$^@ @ @ @&$C@*$(.=$-$L+s#s#s#s#s#s#s#s#s#;$ +. >$ ", +" ~ g@..,+r.Z Z '+,$1 .*.i+h i i i i i i i i i i i i i i i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H H k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.|.C C C C C C C C 1.'$)$$+!$M#^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+U+~${$X+]$^$.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @/$o@L@($_$:$)#|+}#<$<$@$#$#$t#J#J#J#k#[#[#l#Y@Y@)#!#~#~#{#Q@Q@]#^#^#m#R@R@R@K#L#L#{+P@P@$$'#+$+$[$}$ @ @ @|$1$2$s V.v+^.s#s#s#s#s#s#;$;$;$;$;$3$)# ", +" 4 y.=.r.Z H.p *.6+i i i i i i i i i i i i i i i i i i i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H k.k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.C C C C C F s#(.4$5$6$@@^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+7$8$9$0$a$b$^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @c#c$;#d$e$R@}+/.}+}+|+}#}#<$@$#$#$t#J#J#J#k#k#[#l#Y@Y@)#!#!#~#{#{#Q@]#^#^#m#R@R@R@K#K#L#{+P@P@$$'#'#+$[$[$f$>$g$ @ @ @0$/+k@;@W.h$l.s#s#;$;$;$;$;$;$;$;$;$c+|+ ", +" { l.i$} ,$5+a.i i i i i i i i i i i i i i i i i i i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H k.k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.C C C j$k+@ k$l$b+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+U@E@m$(@n$0@/$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @.@o$g#p$q$f$#$+ . . { /.}+}+|+}#}#<$@$@$#$t#J#J#J#k#k#[#l#l#Y@)#!#!#~#{#{#Q@]#]#^#m#R@R@R@K#K#L#{+{+P@$$'#'#+$[$[$f$>$>$r$s$U#d# @ @Z+^+(+t$u$[+v$;$;$;$;$;$;$;$;$;$;$;$<$. ", +" n.0.&@w+`@i i i i i i i i i i i i i i i i i i i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H H k.k.k.k.k.k.k.k.k.|.|.|.|.|.|.E s#w$i@x$y$^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+H+G+z$_#A$B$C$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @^@=#F#G#N@U#!#%.%.5 5 + . . { /./.}+|+}#}#<$@$@$#$t#t#J#J#k#k#[#l#l#Y@)#)#!#~#{#{#Q@]#]#^#m#m#R@R@K#K#L#{+{+P@$$$$'#+$+$[$f$>$>$r$s$s$n#n#n#&# @ @d#U+D$E$c.F$G$;$;$;$;$;$;$;$;$;$;$;$h@. H$ ", +" I$h+;.0.i i i i i i i i i i i i i i i i i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H k.k.k.k.k.k.k.k.k.k.|.|.J$j+C.%+K$n#L$^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+M$N$|$F#O$P$d# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @D#Q$R$S$T$L#. U$V$V$V$%.%.5 + + . { /./.}+|+|+}#<$<$@$#$t#t#J#J#J#k#[#[#l#Y@)#)#!#~#~#{#Q@Q@]#^#m#m#R@R@R@K#L#L#{+P@$$$$'#+$+$[$f$f$>$r$s$s$n#n#n#j#:$:$W$ @ @ @E@a+X$O.Y$Z$X@;$;$;$;$;$;$g@g@g@$.$.. [$ ", +" `$5+` v.i i i i i i i i i i i i i i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H H k.k.k.k.k.k.k.k.k.E |#~+ %.#.%^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+x#&$+%@%#%$%D# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @/@C#W$%%i#s$t#&%*%*%=%U$U$V$V$%.%.5 + + . { { /.}+|+|+}#<$<$@$#$#$t#J#J#J#k#[#[#l#Y@Y@)#!#~#~#{#Q@Q@]#^#^#m#R@R@R@K#L#L#{+P@P@$$'#+$+$[$f$f$>$r$r$s$n#n#n#j#:$:$-%;%;%M@ @ @ @>%@@,%'%> )%L+;$;$g@g@g@g@$.$.$.!%!%~%Y@ ", +" `$I.A i i i i i i i i i i i i i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).).H H H H H H k.k.k.k.k.k.D {%6 ]%^%/%C+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+(%_%:%<%[%}%d# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @p@}$|%1%2%~#=%3%3%4%&%*%*%=%U$U$V$V$V$%.5 + + . { { /.}+}+|+}#<$<$@$#$#$t#J#J#J#k#[#[#l#Y@Y@)#!#!#~#{#{#Q@]#^#^#m#R@R@R@K#K#L#{+P@P@$$'#'#+$[$[$f$>$r$r$s$n#n#n#j#j#:$-%;%;%U#5%5%_$ @ @ @Z#/+6%7%& 8%l.g@g@$.$.$.!%!%!%!%!%!%9%}+ ", +" O.3#i.i i i i i i i i i i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H k.k.k.k.0%a%r b%c%d%^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+U+e%f%g%+@h%i% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @/$o@j%S@.${+. x@x@k%l%3%3%4%&%&%*%=%=%U$V$V$V$%.5 5 + . . { /.}+}+|+}#}#<$@$@$#$t#J#J#J#k#k#[#l#l#Y@)#!#!#~#{#{#Q@]#]#^#m#R@R@R@K#K#L#{+{+P@$$'#'#+$[$[$f$>$>$r$s$n#n#n#j#j#:$-%-%;%U#5%5%m%O@O@I#.@ @ @}%^+n%o%p%q%r%$.!%!%!%!%!%!%!%!%!%!%6#. ", +" { i t.i i i i i i i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H H H H C s%T#t%u%v%@@^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+w%V#q@x%p#b$/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @}%y%G#z%j#J#k%6.6.A%x@x@k%l%l%3%4%&%&%*%=%=%U$V$V$V$%.5 5 + . . { /./.}+|+}#}#<$@$@$#$t#t#J#J#k#k#[#l#l#Y@)#)#!#~#{#{#Q@]#]#^#m#m#R@R@K#K#L#{+{+P@$$$$'#+$[$[$f$>$>$r$s$s$n#n#j#j#:$-%-%;%U#U#5%m%m%O@2%I#I#e$T@ @ @^@M$b+B%&%V.P#!%!%!%!%!%!%!%!%!%!%!%C%. ,# ", +" k.D%h i i i i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H H H H 1.`$)$E%F%G%^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+U+H%I%J%]$K%.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @a@O$L%S$M%]#=%N%N%N%O%O%6.A%x@x@k%l%l%3%4%4%&%*%=%=%U$V$V$V$%.%.5 + . . { /./.}+|+|+}#<$@$@$#$t#t#J#J#J#k#[#[#l#Y@)#)#!#~#~#{#Q@Q@]#^#m#m#R@R@R@K#L#L#{+P@$$$$'#+$+$[$f$f$>$r$s$s$n#n#n#j#:$:$-%;%U#U#5%m%m%O@2%2%I#e$M%M%P%Q% @ @ @8$C+5@R%P Z$;$!%!%!%!%!%!%!%!%!%S%S%{ P@ ", +" $ N+'.i i i i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).).H w.3.T%4$U%V%@@^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+W%X%>%Y%Z%p@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @=#`%($ &+$}+.&_.+&.&.&N%N%O%O%6.A%A%x@k%k%l%3%4%4%&%*%*%=%U$U$V$V$%.%.5 + + . { { /.}+|+|+}#<$<$@$#$#$t#J#J#J#k#[#[#l#Y@Y@)#!#~#~#{#Q@Q@]#^#^#m#R@R@R@K#L#L#{+P@P@$$'#+$+$[$f$f$>$r$r$s$n#n#n#j#:$:$-%;%;%U#5%m%m%O@2%2%I#e$e$M%P%P%P%T$@& @ @ @g%@@#&$&%&v L+!%!%!%!%!%S%S%S%S%&&&&*&[# ", +" 7+=&i i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+).).!.k+@ -&V@;&^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+D@E@>&,&f#0@/$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @D#Z#'&1%;%l#A%)&!&~&_._.+&.&.&N%N%N%O%6.A%A%x@k%k%l%3%3%4%&%*%*%=%U$U$V$V$V$%.5 + + . { { /.}+}+|+}#<$<$@$#$#$t#J#J#J#k#[#[#l#Y@Y@)#!#!#~#{#Q@Q@]#^#^#m#R@R@R@K#L#L#{+P@P@$$'#'#+$[$f$f$>$r$r$s$n#n#n#j#j#:$-%;%;%U#5%5%m%O@O@2%I#e$e$M%P%P%P%T$T$,#{&N@ @ @ @[%^+]&m+v+, u !%!%S%S%S%&&&&&&v@v@v@^&{ ", +" y+i i 7+7+7+7+7+7+7+7+7+7+7+7+7+7+7+E /&(&L#_&^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+H+&$:&<&[&}&|& @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @^@&#Q%p$T$R@V$1&K+1&)&)&!&~&~&_.+&.&.&N%N%N%O%6.6.A%x@k%k%l%3%3%4%&%&%*%=%U$U$V$V$V$%.5 5 + . { { /.}+}+|+}#}#<$@$@$#$t#J#J#J#k#k#[#l#l#Y@)#!#!#~#{#{#Q@]#]#^#m#R@R@R@K#K#L#{+{+P@$$'#'#+$[$[$f$>$>$r$s$n#n#n#j#j#:$-%-%;%U#5%5%m%O@O@2%I#I#e$M%P%P%P%T$T$,#{&{&2&.$H$C$ @ @*#^+3&4&5&%&+&S%&&&&&&v@v@v@v@v@v@v@6&. ", +" |.}.7+7+7+7+7+7+7+7+7+7+7+7+7+).C./%^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+^+8#7&8&<%o$(#d# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @C$9&0&a&r$@$~&b&c&d&d&K+1&1&)&!&~&~&_.+&+&.&N%N%N%O%6.6.A%x@x@k%l%l%3%4%&%&%*%=%=%U$V$V$V$%.5 5 + . . { /./.}+|+}#}#<$@$@$#$t#t#J#J#k#k#[#l#l#Y@)#)#!#~#{#{#Q@]#]#^#m#m#R@R@K#K#L#{+{+P@$$$$'#+$[$[$f$>$>$r$s$s$n#n#j#j#:$-%-%;%U#U#5%m%O@O@2%I#I#e$M%M%P%P%T$T$,#{&{&2&.$.$H$q$q$f# @ @ @7$I+e&f&g&h&S%v@v@v@v@v@v@v@v@v@i&j&. I# ", +" ~ 7+i 7+7+7+7+7+7+7+7+7+).).).).k&^+^+^+^+^+^+^+^+^+^+^+^+^+x#@#z#A#b@$%D# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @/@o#l&S$2%~#k%m&m&n&n&b&c&d&d&K+1&1&)&!&!&~&_.+&+&.&N%N%N%O%O%6.A%x@x@k%l%l%3%4%4%&%*%=%=%U$V$V$V$%.%.5 + . . { /./.}+|+|+}#<$@$@$#$t#t#J#J#J#k#[#l#l#Y@)#)#!#~#~#{#Q@]#]#^#m#m#R@R@R@K#L#L#{+P@$$$$'#+$+$[$f$f$>$r$s$s$n#n#n#j#:$:$-%;%U#U#5%m%m%O@2%2%I#e$M%M%P%P%P%T$,#,#{&2&.$.$H$q$q$o&%$%$p& @ @ @W+1$q&r&V.U.;$v@v@v@v@v@v@i&i&i&i&S%s&R@ ", +" C.7+7+7+7+7+7+7+7+).).).H H H t&^+^+^+^+^+^+^+^+D+u&v&w&Y#x&/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @}%y%@&q$$$5 n&y&z&m&m&m&n&n&b&c&c&d&K+1&1&)&!&!&~&_._.+&.&N%N%N%O%O%6.A%A%x@k%l%l%3%4%4%&%*%*%=%U$U$V$V$%.%.5 + + . { { /.}+|+|+}#<$<$@$#$#$t#J#J#J#k#[#[#l#Y@Y@)#!#~#~#{#Q@Q@]#^#^#m#R@R@R@K#L#L#{+P@P@$$'#+$+$[$f$f$>$r$r$s$n#n#n#j#:$:$-%;%;%U#5%m%m%O@2%2%I#e$e$M%P%P%P%T$,#,#{&2&2&.$H$q$q$o&%$%$ &i#i#@& @ @ @A&/+B&C&D&E&X@v@v@i&i&i&i&i&i&i&i&i&c+#$ ", +" E 7+7+7+7+).).).H H H H H H i@^+^+^+^+e%m@Z#Z+`+ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @a@O$F&G&-%J#_.H&I&J&J&y&z&z&m&m&m&n&b&c&c&d&K+K+1&)&)&!&~&_._.+&.&.&N%N%N%O%6.A%A%x@k%k%l%3%3%4%&%*%*%=%U$U$V$V$V$%.5 + + . { { /.}+}+|+}#<$<$@$#$#$t#J#J#J#k#[#[#l#Y@Y@)#!#!#~#{#Q@Q@]#^#^#m#R@R@R@K#L#L#{+P@P@$$'#'#+$[$f$f$>$r$r$s$n#n#n#j#:$:$-%;%;%U#5%5%m%O@2%2%I#e$e$M%P%P%P%T$T$,#{&2&2&.$H$H$q$o&o&%$ &i#i#K&_$_$H#^@ @ @}&^+o+R+U.L&M&i&i&i&i&i&i&i&i&N&N&N&m+. ", +" 7+).).).).H H H H H H k.k.!.@@^+^+9#}& @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @0@O&p$T$^#4%H&P&q%q%H&I&I&J&y&z&z&m&m&m&n&b&b&c&d&K+K+1&)&)&!&~&~&_.+&.&.&N%N%N%O%6.6.A%x@k%k%l%3%3%4%&%&%*%=%U$U$V$V$V$%.5 5 + . { { /.}+}+|+}#}#<$@$#$#$t#J#J#J#k#k#[#l#Y@Y@)#!#!#~#{#{#Q@]#]#^#m#R@R@R@K#K#L#{+{+P@$$'#'#+$[$[$f$>$>$r$s$n#n#n#j#j#:$-%-%;%U#5%5%m%O@O@2%I#I#e$M%P%P%P%T$T$,#{&{&2&.$H$H$q$o&o&%$ & &i#K&_$_$_$a&a&z%c# @ @/$H+D$Q&R&%&S&i&i&i&i&N&N&N&N&N&N&N&w@. ", +" k#).H H H H H H k.k.k.k.k.k.t%^+^+@%/@ @ @ @ @ @ @ @ @ @ @`+T&U&_$>$/.b&V&W&W&X&P&q%q%H&I&I&J&y&y&z&m&m&m&n&b&b&c&d&d&K+1&)&)&!&~&~&_.+&+&.&N%N%N%O%6.6.A%x@x@k%l%l%3%4%&%&%*%=%=%U$V$V$V$%.5 5 + . . { /./.}+|+}#}#<$@$@$#$t#t#J#J#k#k#[#l#l#Y@)#)#!#~#{#{#Q@]#]#^#m#m#R@R@K#K#L#{+{+P@$$$$'#+$[$[$f$>$>$r$s$s$n#n#j#j#:$-%-%;%U#U#5%m%O@O@2%I#I#e$M%M%P%P%T$T$,#{&{&2&.$.$H$q$o&o&%$ & &i#K&K&_$_$a&a&z%N@N@/#]$ @ @ @V+C@Y&Z&g&`&S%N&N&N&N&N&N&u+u+u+ *j&. ;% ", +" 6#H H H H k.k.k.k.k.k.k.k.k..*^+<& @ @ @ @ @ @ @ @F#K&Y@N%W@+*+*W@V&W&W&X&P&P&q%H&H&I&J&y&y&z&m&m&m&n&n&b&c&d&d&K+1&1&)&!&!&~&_.+&+&.&N%N%N%O%O%6.A%x@x@k%l%l%3%4%4%&%*%=%=%U$V$V$V$%.%.5 + . . { /./.}+|+|+}#<$@$@$#$t#t#J#J#J#k#[#l#l#Y@)#)#!#~#~#{#Q@]#]#^#m#m#R@R@R@K#L#{+{+P@$$$$'#+$+$[$f$>$>$r$s$s$n#n#n#j#:$-%-%;%U#U#5%m%m%O@2%2%I#e$M%M%P%P%P%T$,#,#{&2&.$.$H$q$q$o&%$%$ &i#K&K&_$_$_$a&z%z%N@/#@*@*H#j% @ @ @#*1$$*4.X&%*&*N&N&u+u+u+ * * * * * *$&]# ", +" **k.k.k.k.k.k.k.k.k.k.|.|.|.L$~$/@ @ @ @ @ @ @Q%. =*=*+*+*W@V&V&W&X&P&P&q%H&H&I&J&J&y&z&m&m&m&n&n&b&c&c&d&K+1&1&)&!&!&~&_._.+&.&N%N%N%O%O%6.A%A%x@k%l%l%3%4%4%&%*%*%=%U$V$V$V$%.%.5 + + . { /./.}+|+|+}#<$<$@$#$t#t#J#J#J#k#[#[#l#Y@Y@)#!#~#~#{#Q@Q@]#^#^#m#R@R@R@K#L#L#{+P@P@$$'#+$+$[$f$f$>$r$r$s$n#n#n#j#:$:$-%;%;%U#5%m%m%O@2%2%I#e$e$M%P%P%P%T$,#,#{&2&2&.$H$q$q$o&%$%$ &i#i#K&_$_$_$a&z%z%N@/#/#@*H#G&G&1%-* @ @ @%#/+;*>*8%,*X@u+u+ * * * * * * * * *o%}# ", +" ~ k.k.k.k.k.k.|.|.|.|.|.|.C ^+p# @ @ @ @ @^@ &W@+*+*W@V&V&W&X&X&P&q%H&H&I&J&J&y&z&z&m&m&n&n&b&c&c&d&K+K+1&)&!&!&~&_._.+&.&.&N%N%N%O%6.A%A%x@k%k%l%3%3%4%&%*%*%=%U$U$V$V$V$%.5 + + . { { /.}+}+|+}#<$<$@$#$#$t#J#J#J#k#[#[#l#Y@Y@)#!#!#~#{#Q@Q@]#^#^#m#R@R@R@K#L#L#{+P@P@$$'#'#+$[$f$f$>$r$r$s$n#n#n#j#:$:$-%;%;%U#5%5%m%O@2%2%I#e$e$M%P%P%P%T$,#,#{&2&2&.$H$H$q$o&%$%$ &i#i#K&_$_$_$a&a&z%N@/#/#@*H#H#G&1%1%g$d$'*d# @ @0@^+n%)*P#L&M& * * * * * * * *!*!*!*~*. ", +" {*k.k.|.|.|.|.|.|.|.C C C C /+/@ @ @ @ @ @2&+*W@W@V&W&X&X&P&q%q%H&I&I&J&y&z&z&m&m&m&n&b&b&c&d&K+K+1&)&)&!&~&~&_.+&.&.&N%N%N%O%6.6.A%x@k%k%l%3%3%4%&%&%*%=%U$U$V$V$V$%.5 5 + . { { /.}+}+|+}#}#<$@$#$#$t#J#J#J#k#k#[#l#Y@Y@)#!#!#~#{#{#Q@]#^#^#m#R@R@R@K#K#L#{+P@P@$$'#'#+$[$[$f$>$>$r$s$n#n#n#j#j#:$-%-%;%U#5%5%m%O@O@2%I#I#e$M%P%P%P%T$T$,#{&{&2&.$H$H$q$o&o&%$ & &i#K&_$_$_$a&a&z%N@N@/#@*H#H#G&1%1%g$d$d$>#'*S$=# @ @/@U+b+>@4%P&S& * * * *!*!*!*!*!*!*!*]*. _$ ", +" ^*|.|.|.|.|.C C C C C C C C H# @ @ @ @ @l&W@V&W&W&X&P&q%q%H&I&I&J&y&y&z&m&m&m&n&b&b&c&d&d&K+1&)&)&!&~&~&_.+&+&.&N%N%N%O%6.6.A%x@x@k%l%3%3%4%&%&%*%=%=%U$V$V$V$%.5 5 + . . { /./.}+|+}#}#<$@$@$#$t#t#J#J#k#k#[#l#l#Y@)#)#!#~#{#{#Q@]#]#^#m#m#R@R@K#K#L#{+{+P@$$$$'#+$[$[$f$>$>$r$s$s$n#n#j#j#:$-%-%;%U#U#5%m%O@O@2%I#I#e$M%M%P%P%T$T$,#{&{&2&.$.$H$q$o&o&%$ & &i#K&K&_$_$a&a&z%N@N@/#@*@*H#G&1%1%g$d$d$>#'*'*S$S$ $T& @ @ @_%a+/*%@W&!&N&!*!*!*!*!*!*!*!*!*(*(*. r$ ", +" [$|.C C C C C C C C C C D D _* @ @ @ @d#3%W&X&P&P&q%H&I&I&J&y&y&z&m&m&m&n&n&b&c&d&d&K+1&1&)&!&!&~&_.+&+&.&N%N%N%O%O%6.A%x@x@k%l%l%3%4%4%&%*%=%=%U$V$V$V$%.%.5 + . . { /./.}+|+|+}#<$@$@$#$t#t#J#J#J#k#[#l#l#Y@)#)#!#~#~#{#Q@]#]#^#m#m#R@R@R@K#L#{+{+P@$$$$'#+$+$[$f$>$>$r$s$s$n#n#n#j#:$-%-%;%U#U#5%m%m%O@2%I#I#e$M%M%P%P%P%T$,#{&{&2&.$.$H$q$q$o&%$%$ &i#K&K&_$_$_$a&z%z%N@/#@*@*H#G&G&1%g$g$d$>#'*'*S$S$S$ $:*:*p& @ @ @<*@@#@Z.%&[*&*!*!*!*!*!*(*(*(*j&j&j&k#!# ", +" C C C C C C C D D D E E E }* @ @ @ @g#P&P&q%H&H&I&J&J&y&z&m&m&m&n&n&b&c&c&d&K+1&1&)&!&!&~&_._.+&.&N%N%N%O%O%6.A%A%x@k%l%l%3%4%4%&%*%*%=%U$V$V$V$%.%.5 + + . { /./.}+|+|+}#<$<$@$#$t#t#J#J#J#k#[#[#l#Y@)#)#!#~#~#{#Q@Q@]#^#m#m#R@R@R@K#L#L#{+P@P@$$'#+$+$[$f$f$>$r$r$s$n#n#n#j#:$:$-%;%;%U#5%m%m%O@2%2%I#e$e$M%P%P%P%T$,#,#{&2&2&.$H$q$q$o&%$%$ &i#i#K&_$_$_$a&z%z%N@/#/#@*H#G&G&1%g$g$d$>#>#'*S$S$S$ $:*:*|*1*1*2* @ @ @3*^+4*#+E&5*6*!*!*(*(*(*j&j&j&j&j&j&)*/. ", +" X.C C C D D D E E E E E E 7* @ @ @ @m%H&H&I&J&J&y&z&z&m&m&n&n&b&c&c&d&K+K+1&)&!&!&~&_._.+&.&.&N%N%O%O%6.A%A%x@k%k%l%3%4%4%&%*%*%=%U$U$V$V$V$%.5 + + . { { /.}+}+|+}#<$<$@$#$#$t#J#J#J#k#[#[#l#Y@Y@)#!#!#~#{#Q@Q@]#^#^#m#R@R@R@K#L#L#{+P@P@$$'#'#+$[$f$f$>$r$r$s$n#n#n#j#:$:$-%;%;%U#5%5%m%O@2%2%I#e$e$M%P%P%P%T$,#,#{&2&2&.$H$H$q$o&%$%$ &i#i#K&_$_$_$a&z%z%N@/#/#@*H#H#G&1%g$g$d$>#>#'*S$S$S$ $ $:*|*1*1*S@p$p$h#`+ @ @b$^+T+c@u 8*9*(*j&j&j&j&j&j&j&j&j&j&6#. ", +" Y.D D E E E E E E F F F F z@ @ @ @ @k#I&J&y&z&z&m&m&m&n&b&b&c&d&K+K+1&)&)&!&~&~&_.+&.&.&N%N%N%O%6.6.A%x@k%k%l%3%3%4%&%&%*%=%U$U$V$V$V$%.5 5 + . { { /.}+}+|+}#}#<$@$#$#$t#J#J#J#k#k#[#l#Y@Y@)#!#!#~#{#{#Q@]#^#^#m#R@R@R@K#K#L#{+P@P@$$'#'#+$[$[$f$>$r$r$s$n#n#n#j#j#:$-%;%;%U#5%5%m%O@O@2%I#e$e$M%P%P%P%T$T$,#{&{&2&.$H$H$q$o&o&%$ & &i#K&_$_$_$a&a&z%N@N@/#@*H#H#G&1%1%g$d$d$>#'*S$S$S$ $ $:*|*|*1*S@p$p$h#0*0*a*E# @ @ @D+I+b*s@X&S&j&j&j&j&j&j&j&c*c*c*c*d*. q$ ", +" 3@E E E E E F F F F F F F !+ @ @ @ @U$y&z&m&m&m&n&b&b&c&d&d&K+1&)&)&!&~&~&_.+&+&.&N%N%N%O%6.6.A%x@x@k%l%3%3%4%&%&%*%=%=%U$V$V$V$%.5 5 + . . { /.}+}+|+}#}#<$@$@$#$t#J#J#J#k#k#[#l#l#Y@)#!#!#~#{#{#Q@]#]#^#m#m#R@R@K#K#L#{+{+P@$$$$'#+$[$[$f$>$>$r$s$s$n#n#j#j#:$-%-%;%U#U#5%m%O@O@2%I#I#e$M%M%P%P%T$T$,#{&{&2&.$.$H$q$o&o&%$ & &i#K&K&_$_$a&a&z%N@N@/#@*@*H#G&1%1%g$d$d$>#'*'*S$S$ $ $:*|*|*1*S@S@p$h#0*0*a*%%%%($T& @ @ @##C+e*w@F$f*i&j&j&c*c*c*c*c*c*c*g*(*/.+$ ", +" [@E F F F F F F F F F F F F ^@ @ @ @<$m&m&n&b&b&c&d&d&K+1&1&)&!&~&~&_.+&+&.&N%N%N%O%6.6.A%x@x@k%l%l%3%4%4%&%*%=%=%U$V$V$V$%.%.5 + . . { /./.}+|+|+}#<$@$@$#$t#t#J#J#J#k#[#l#l#Y@)#)#!#~#~#{#Q@]#]#^#m#m#R@R@R@K#L#{+{+P@$$$$'#+$+$[$f$>$>$r$s$s$n#n#n#j#:$-%-%;%U#U#5%m%m%O@2%I#I#e$M%M%P%P%P%T$,#{&{&2&.$.$H$q$q$o&%$ & &i#K&K&_$_$_$a&z%N@N@/#@*@*H#G&G&1%g$g$d$>#'*'*S$S$S$ $:*:*|*1*S@S@p$h#h#0*a*a*%%($@&@&M@Q% @ @ @(@/+h*3$1@c&&&c*c*c*c*c*g*g*g*g*g*g*)*Y@ ", +" i*F F F F F F F F F F @.@.X.b$ @ @ @R@n&b&c&c&d&K+1&1&)&!&!&~&_._.+&.&N%N%N%O%O%6.A%A%x@x@k%k%l%3%3%4%&%&%=%U$V$V$V$%.%.5 + + . { /./.}+|+|+}#<$<$@$#$t#t#J#J#J#k#[#[#l#Y@)#)#!#~#~#{#Q@Q@]#^#m#m#R@R@R@K#L#L#{+P@$$$$'#+$+$[$f$f$>$r$s$s$n#n#n#j#:$:$-%;%;%U#5%m%m%O@2%2%I#e$e$M%P%P%P%T$,#,#{&2&2&.$H$q$q$o&%$%$ &i#i#K&_$_$_$a&z%z%N@/#/#@*H#G&G&1%g$g$d$>#>#'*S$S$S$ $:*:*|*1*1*S@p$h#h#0*a*a*%%($($@&M@-*-*-*|% @ @ @{@^+o+q#c&5*6*c*g*g*g*g*g*g*g*g*g*g*j*{ ", +" k*F F F F F F F @.@.@.!.!.!.w& @ @ @M%c&d&K+K+1&)&!&!&~&_._.+&.&.&N%N%O%O%6.A%A%x@x@x@k%l%3%3%3%4%4%*%=%=%U$U$V$V$5 + + . { { /.}+|+|+}#<$<$@$#$#$t#J#J#J#k#[#[#l#Y@Y@)#!#!#~#{#Q@Q@]#^#^#m#R@R@R@K#L#L#{+P@P@$$'#'#+$[$f$f$>$r$r$s$n#n#n#j#:$:$-%;%;%U#5%5%m%O@2%2%I#e$e$M%P%P%P%T$,#,#{&2&2&.$H$H$q$o&%$%$ &i#i#K&_$_$_$a&z%z%N@/#/#@*H#H#G&1%g$g$d$>#>#'*S$S$S$ $:*:*|*1*1*S@p$p$h#0*a*a*%%($($@&M@M@-*-*G#G#2*0&e# @ @D#^+M#N#l*m*n*g*g*g*g*g*g*g*C%C%C%o*p*. ", +" q*F F F @.@.@.!.!.!.!.!.!.1.r* @ @ @d$K+1&)&)&!&~&~&_.+&.&.&N%N%N%O%6.6.A%x@k%k%k%l%l%l%3%3%3%4%&%&%*%*%*%U$V$%.5 + . . /.}+}+|+}#}#<$@$#$#$t#J#J#J#k#k#[#l#Y@Y@)#!#!#~#{#{#Q@]#^#^#m#R@R@R@K#K#L#{+P@P@$$'#'#+$[$[$f$>$r$r$s$n#n#n#j#j#:$-%;%;%U#5%5%m%O@O@2%I#e$e$M%P%P%P%T$T$,#{&2&2&.$H$H$q$o&o&%$ &i#i#K&_$_$_$a&a&z%N@N@/#@*H#H#G&1%1%g$d$d$>#'*S$S$S$ $ $:*|*|*1*S@p$p$h#0*0*a*%%%%($@&M@M@-*-*-*G#2*2*0&s*U&&# @ @ @&$C@*$(.t*u*(*g*g*g*C%C%C%o*o*o*o*v*. e$ ", +" @.@.!.!.!.!.!.!.!.1.1.1.1..% @ @ @;#)&!&~&~&_.+&+&.&N%N%N%O%6.6.A%x@x@k%l%3%l%3%4%3%4%4%3%4%4%4%4%&%*%*%U$V$%.5 . { { }+|+|+}#@$@$#$t#J#J#J#k#k#[#l#l#Y@)#!#!#~#{#{#Q@]#]#^#m#R@R@R@K#K#L#{+{+P@$$'#'#+$[$[$f$>$>$r$s$s$n#n#j#j#:$-%-%;%U#U#5%m%O@O@2%I#I#e$M%M%P%P%T$T$,#{&{&2&.$.$H$q$o&o&%$ & &i#K&K&_$_$a&a&z%N@N@/#@*@*H#G&1%1%g$d$d$>#'*'*S$S$ $ $:*|*|*1*S@S@p$h#0*0*a*%%%%($@&@&M@-*-*-*G#2*2*0&s*s*U&|%;#T& @ @ @w*1$2$s X&x* *C%C%o*o*o*o*o*o*o*y*y*/.{+ ", +" z*!.!.!.!.1.1.1.1.1.1.1.1.A* @ @ @-#~&_.+&+&.&N%N%N%O%6.6.A%x@x@k%l%l%3%4%&%4%&%&%4%4%4%3%l%3%3%3%4%&%*%=%V$V$5 . . /.}+}#}#<$#$#$t#J#J#k#[#l#l#Y@)#)#!#~#~#{#Q@]#]#^#m#m#R@R@R@K#L#{+{+P@$$$$'#+$+$[$f$>$>$r$s$s$n#n#n#j#:$-%-%;%U#U#5%m%m%O@2%I#I#e$M%M%P%P%P%T$,#{&{&2&.$.$H$q$q$o&%$ & &i#K&K&_$_$_$a&z%N@N@/#@*@*H#G&G&1%g$d$d$>#'*'*S$S$S$ $:*|*|*1*S@S@p$h#h#0*a*a*%%($@&@&M@-*-*-*G#G#2*0&s*s*U&|%|%;#'&'&W$ @ @ @B*/+k@;@C*D*&&o*o*o*o*o*y*y*y*y*y*y*E*t# ", +" a%1.1.1.1.1.1.1.1.1.1.l.l.6# @ @ @0@+&.&N%N%N%O%O%6.A%A%x@k%l%l%3%4%4%&%*%&%*%*%*%&%3%3%k%k%k%x@x@l%3%3%&%=%U$%.+ . { }+}#}#@$@$#$t#k#k#[#l#)#)#!#~#~#{#Q@Q@]#^#m#m#R@R@R@K#L#L#{+P@$$$$'#+$+$[$f$f$>$r$s$s$n#n#n#j#:$:$-%;%U#U#5%m%m%O@2%2%I#e$M%M%P%P%P%T$,#,#{&2&.$.$H$q$q$o&%$%$ &i#i#K&_$_$_$a&z%z%N@/#/#@*H#G&G&1%g$g$d$>#>#'*S$S$S$ $:*:*|*1*1*S@p$h#h#0*a*a*%%($($@&M@-*-*-*G#G#2*0&0&s*U&|%|%;#'&'&F*F&F&L%/@ @ @E#^+(+$+D.G*6*o*y*y*y*y*y*y*y*y*y*y*H*. ", +" U 1.1.1.1.1.1.l.l.l.l.l.l._+ @ @ @ @l%N%O%O%6.A%A%x@k%k%l%3%4%4%&%*%*%=%U$=%=%*%*%4%3%l%x@A%A%O%6.6.A%x@l%4%&%=%V$5 . /.}+|+<$@$#$J#k#[#l#Y@!#!#~#{#Q@]#^#^#m#R@R@R@K#L#L#{+P@P@$$'#'#+$[$f$f$>$r$r$s$n#n#n#j#:$:$-%;%;%U#5%5%m%O@2%2%I#e$e$M%P%P%P%T$,#,#{&2&2&.$H$H$q$o&%$%$ &i#i#K&_$_$_$a&z%z%N@/#/#@*H#H#G&1%g$g$d$>#>#'*S$S$S$ $:*:*|*1*1*S@p$p$h#0*a*a*%%($($@&M@M@-*-*G#G#2*0&0&s*U&U&|%;#'&'&F*F&F&`#R$R$L%p@ @ @d#x#D$I*J*m*n*y*y*y*y*y*y*y*y*y*y*y*4 . ", +" K*1.1.1.l.l.l.l.l.l.l.l.l.M. @ @ @ @l#6.A%A%x@k%k%l%3%3%4%&%*%*%=%U$U$V$V$U$U$U$*%&%3%k%A%O%N%+&_.+&+&N%O%A%k%4%*%=%V$5 . /.|+<$@$t#k#k#l#)#)#~#{#Q@]#^#m#R@R@K#K#L#{+P@P@$$'#'#+$[$[$f$>$r$r$s$n#n#n#j#j#:$-%;%;%U#5%5%m%O@O@2%I#e$e$M%P%P%P%T$T$,#{&2&2&.$H$H$q$o&o&%$ &i#i#K&_$_$_$a&a&z%N@/#/#@*H#H#G&1%1%g$d$>#>#'*S$S$S$ $ $:*|*|*1*S@p$p$h#0*0*a*%%%%($@&M@M@-*-*-*G#2*2*0&s*U&U&|%;#;#'&F*F*F&`#R$R$L%L%L%L*E# @ @ @E@M*X$O.t*N*g*y*y*y*y*y*y*y*y*y*O*P*. m% ", +" Q*l.l.l.l.l.l.l.l.l.M.M.M.Y.e# @ @ @n#x@x@k%l%3%3%4%&%&%*%=%=%U$V$V$V$%.%.%.V$V$*%&%l%x@~&R*V&c&1&1&1&)&~&+&N%6.x@l%&%=%V$5 { }+|+@$t#J#[#Y@)#!#{#]#]#^#m#m#K#L#L#P@$$'#'#+$[$[$f$>$>$r$s$n#n#n#j#j#:$-%-%;%U#5%5%m%O@O@2%I#I#e$M%M%P%P%T$T$,#{&{&2&.$.$H$q$o&o&%$ & &i#K&K&_$_$a&a&z%N@N@/#@*@*H#G&1%1%g$d$d$>#'*'*S$S$ $ $:*|*|*1*S@S@p$h#0*0*a*%%%%($@&@&M@-*-*-*G#2*2*0&s*s*U&|%;#;#'&F*F*F&`#`#R$L%L%L%L*l&l&p&C$ @ @ @!@@@,%~ P&S*(*y*y*y*y*y*O*O*O*T*T*y*@$m# ", +" U*l.l.l.l.l.M.M.M.Y.Y.Y.^.^.T& @ @ @i#l%l%3%4%&%&%*%=%=%U$V$V$V$%.5 5 + + + 5 %.=%&%l%A%.&V*W*X*Y*Z*V&n&b&d&1&~&+&N%A%l%4%=%%.5 { }+<$@$J#[#l#)#!#~#Q@^#m#R@L#{+{+$$'#+$[$f$>$>$r$s$s$n#n#n#j#:$-%-%;%U#U#5%m%m%O@2%I#I#e$M%M%P%P%P%T$,#{&{&2&.$.$H$q$q$o&%$ & &i#K&K&_$_$_$a&z%N@N@/#@*@*H#G&G&1%g$d$d$>#'*'*S$S$S$ $:*|*|*1*S@S@p$h#h#0*a*%%%%($@&@&M@-*-*-*G#2*2*0&s*s*U&|%|%;#'&F*F*F&`#`#R$L%L%L%L*L*l&W$Q$0@/$ @ @ @ @Y+/+6%i@& `* =y*y*O*O*O*T*T*T*T*T*T**&@$ ", +" .=l.M.M.M.Y.Y.Y.Y.^.^.^.^.^.-* @ @ @h#4%4%&%*%*%=%U$V$V$V$%.%.5 + + . { { . . 5 V$*%l%O%_.+=W*W*W*W*W*V*@=#=H&b&K+)&_.N%6.k%4%*%V$+ { }+<$@$t#k#Y@)#~#Q@^#m#K#{+P@$$+$+$f$>$s$s$n#n#n#j#:$:$-%;%U#U#5%m%m%O@2%2%I#e$M%M%P%P%P%T$,#,#{&2&.$.$H$q$q$o&%$%$ &i#K&K&_$_$_$a&z%z%N@/#@*@*H#G&G&1%g$g$d$>#>#'*S$S$S$ $:*:*|*1*1*S@p$h#h#0*a*a*%%($($@&M@-*-*-*G#G#2*0&0&s*U&|%|%;#'&'&F*F&F&`#R$L%L%L%L*L*j%c$$=e# @ @ @ @ @ @ @ @c#^+n%4@_.%=&=O*T*T*T*T*T*T*T*T*T*T**=. ", +" M.Y.Y.Y.^.^.^.^.^.^.^.^.^.q$ @ @ @g#*%*%=%U$U$V$V$%.%.5 + + . { { /.}+}+/./.. %.=%3%O%~&==W*W*W*W*W*W*W*W*W*-=R*W@b&1&!&+&O%A%l%&%U$%.. /.|+@$J#[#Y@~#Q@]#R@L#{+$$+$[$>$s$s$n#j#:$:$-%;%;%U#5%5%m%O@2%2%I#e$e$M%P%P%P%T$,#,#{&2&2&.$H$H$q$o&%$%$ &i#i#K&_$_$_$a&z%z%N@/#/#@*H#H#G&1%g$g$d$>#>#'*S$S$S$ $:*:*|*1*1*S@p$p$h#0*a*a*%%($($@&M@M@-*-*G#G#2*0&0&s*U&U&|%;#'&'&F*F&F&`#R$R$L%L%L*L*;=o$c#/@ @ @ @ @ @ @ @ @ @ @ @^@U@b+>=c.,=n*T*T*T*T*T*T*T*T*T*T*T*'=. ", +" 3.^.^.^.^.^.^.^.^.^.^.^.^.*$ @ @ @f#U$U$V$V$V$%.5 + + . { { /.}+}+|+}#}#|+}+/.5 U$3%6.~&Z*W*W*W*W*W*W*W*W*W*W*W*W*)=@=!=z&1&~&+&O%x@3%*%V$+ { }#@$J#l#Y@~#]#R@L#P@'#[$f$r$s$j#-%;%;%U#5%5%m%O@O@2%I#e$e$M%P%P%P%T$T$,#{&2&2&.$H$H$q$o&o&%$ &i#i#K&_$_$_$a&a&z%N@/#/#@*H#H#G&1%1%g$d$>#>#'*S$S$S$ $ $:*|*1*1*S@p$p$h#0*0*a*%%($($@&M@M@-*-*-*G#2*2*0&s*U&U&|%;#;#'&F*F*F&`#R$R$L%L%L%l&c$&#`+ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @8$C+~=R%t*{=y*T*T*T*T*T*T*T*T*T*]=P*. :$ ", +" _+^.^.^.^.^.^.^.^.^.^.^.^. # @ @ @p@V$V$%.5 5 + . . { /.}+}+|+}#}#<$@$<$<$}#|+. V$4%6._.=*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*^=/=W&1&~&N%A%l%4%U$5 . }+<$t#[#!#Q@m#K#P@'#f$r$n#:$;%5%5%m%O@O@2%I#I#e$M%P%P%P%T$T$,#{&{&2&.$H$H$q$o&o&%$ & &i#K&_$_$_$a&a&z%N@N@/#@*@*H#G&1%1%g$d$d$>#'*'*S$S$ $ $:*|*|*1*S@S@p$h#0*0*a*%%%%($@&@&M@-*-*-*G#2*2*0&s*s*U&|%;#;#'&F*F*F&`#`#R$L%L%L%Q%Q$0@d# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @(=@@_=$&:=<=(*T*T*T*T*T*]=]=]=[=[=[=#+{# ", +" {*^.^.^.^.^.^.^.^.s+s+s+L+O. @ @ @ @@$5 + . . { /./.}+|+}#}#<$@$@$#$t##$#$@$}#{ 5 *%k%.&I&W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*)=@=}=n&+&O%x@3%&%V$+ /.<$t#[#!#]#K#P@[$s$n#-%U#5%O@2%I#I#e$M%M%P%P%P%T$,#{&{&2&.$.$H$q$q$o&%$ & &i#K&K&_$_$_$a&z%N@N@/#@*@*H#G&G&1%g$d$d$>#'*'*S$S$S$ $:*|*|*1*S@S@p$h#h#0*a*%%%%($@&@&M@-*-*-*G#2*2*0&s*s*U&|%|%;#'&F*F*F&`#`#R$L%L%L%F#o#C$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @b#^+]&_@v+|= =T*]=]=]=[=[=[=[=[=[=[=)*}# ", +" Q&^.^.^.^.s+s+s+L+L+L+L+3.g@ @ @ @ @'#. { /./.}+|+|+}#<$<$@$#$t#t#J#J#t#t#t#<$|+{ V$4%6.1&W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*^=1=P&~&O%k%4%=%5 /.<$k#!#^#K#'#>$n#;%5%O@I#e$M%M%P%P%P%T$,#,#{&2&.$.$H$q$q$o&%$%$ &i#K&K&_$_$_$a&z%z%N@/#@*@*H#G&G&1%g$g$d$>#'*'*S$S$S$ $:*:*|*1*S@S@p$h#h#0*a*a*%%($($@&M@-*-*-*G#G#2*0&0&s*U&|%|%;#'&'&F*F&F&`#R$L%L%L*~@$=`+ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @|&^+3&7#5&2=3=]=[=[=[=[=[=[=4=4=4=4=5=. ", +" 6=^.s+s+s+L+L+L+3.3.3.3.3.^.a@ @ @ @T$/.}+|+|+}#<$<$@$#$#$t#J#J#J#k#[#[#[#k#t#@$|+. =%l%O%7=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*)=[ }=c&6.l%=%+ |+J#!#^#P@f$n#;%m%2%e$P%P%P%T$,#,#{&2&2&.$H$H$q$o&%$%$ &i#i#K&_$_$_$a&z%z%N@/#/#@*H#H#G&1%g$g$d$>#>#'*S$S$S$ $:*:*|*1*1*S@p$p$h#0*a*a*%%($($@&M@M@-*-*G#G#2*0&0&s*U&U&|%;#'&'&F*F&F&`#R$R$L%l&9&E#a@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @w%I+8=s@9=0=O*[=[=[=4=4=4=4=4=4=4=a=. i# ", +" b=L+L+L+3.3.3.3.3.3.3.3.3.3.a$ @ @ @d$|+}#<$<$@$#$#$t#J#J#J#k#[#[#l#Y@Y@Y@l#[#J#@$|++ =%l%@=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*c=1=J&k%%.|+J#~#K#+$s$;%O@I#M%T$T$,#{&2&2&.$H$H$q$o&o&%$ &i#i#K&_$_$_$a&a&z%N@/#/#@*H#H#G&1%1%g$d$>#>#'*S$S$S$ $ $:*|*1*1*S@p$p$h#0*0*a*%%($($@&M@M@-*-*-*G#2*0&0&s*U&U&|%;#;#'&F*F&F&`#R$R$L%j%}$0@d# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @f%C+d=r&t*e=y*4=4=4=4=4=4=4=4=f=f=]=+ >$ ", +" 1*3.3.3.3.3.3.3.3.3.3.3.3.u@'& @ @ @s*<$@$@$#$t#J#J#J#k#k#[#l#l#Y@)#!#!#!#!#Y@l#k#@$|+. U$#=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*X*< q%4%l#]#$$r$-%m%I#P%,#{&2&.$H$H$q$o&o&%$ & &i#K&_$_$_$a&a&z%N@N@/#@*H#H#G&1%1%g$d$d$>#'*S$S$S$ $ $:*|*|*1*S@S@p$h#0*0*a*%%%%($@&@&M@-*-*-*G#2*2*0&s*s*U&|%;#;#'&F*F*F&`#`#R$L%g#T&(#^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @<%/+B&C&L&g=(*4=4=4=4=4=f=f=f=h=h=h=i*)# ", +" 3.3.3.3.3.3.3.3.3.u@u@u@X@i= @ @ @;=#$t#t#J#J#k#k#[#l#l#Y@)#)#!#~#{#{#{#{#~#!#)#[#t#|+{ U$~&V&j=k=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*-=#$K#f$:$m%e$T$2&.$H$q$q$o&%$ & &i#K&K&_$_$_$a&z%N@N@/#@*@*H#G&G&1%g$d$d$>#'*'*S$S$S$ $:*|*|*1*S@S@p$h#h#0*a*%%%%($@&@&M@-*-*-*G#2*2*0&s*s*U&|%|%;#'&F*F*F&`#`#R$L%l&}$0@/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @}&^+o+j*K+l=m=4=f=f=f=h=h=h=h=h=h=h=n=/. ", +" 3.3.3.3.3.u@u@u@X@X@X@X@X@o= @ @ @o#J#J#J#k#[#l#l#Y@)#)#!#~#~#{#Q@Q@]#^#^#]#]#{#)#l#J#@$|+. %.*%4%)&V&R*7=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*4%m#+$:$O@M%{&H$H$o&%$%$ &i#K&K&_$_$_$a&z%z%N@/#@*@*H#G&G&1%g$g$d$>#'*'*S$S$S$ $:*:*|*1*S@S@p$h#h#0*a*a*%%($@&@&M@-*-*-*G#G#2*0&s*s*U&|%|%;#'&'&F*F&F&`#R$L%L*9&=#d# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @.@H+M#p=R&q=r=f=h=h=h=h=h=h=h=h=h=h=d+. ", +" s=u@u@u@u@X@X@X@X@X@X@X@X@t= @ @ @e#k#[#[#l#Y@Y@)#!#~#~#{#Q@Q@]#^#^#m#R@m#^#^#^#Q@{#!#l#k##$<$}+. 5 V$=%&%+&q%Z*-=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*1&^#+$:$2%P%2&q$o& &i#i#K&_$_$_$a&z%z%N@/#/#@*H#G&G&1%g$g$d$>#>#'*S$S$S$ $:*:*|*1*1*S@p$p$h#0*a*a*%%($($@&M@M@-*-*G#G#2*0&0&s*U&U&|%;#'&'&F*F&F&`#R$R$L%-#Z+d# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @e%C@J+Z&u=0=[=h=h=h=h=h=h=h=h=h=a=a=. {& ", +" v=X@X@X@X@X@X@X@X@X@s#s#s#@ @ @ @ @K#Y@Y@)#!#!#~#{#Q@Q@]#^#^#m#R@R@R@K#L#K#K#K#R@m#^#Q@{#!#Y@[#J##$<$|+}+. %.V$=%6.J&w=+=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*X&]#+$-%2%,#H$%$ &K&_$_$_$a&a&z%N@/#/#@*H#H#G&1%1%g$d$>#>#'*S$S$S$ $ $:*|*1*1*S@p$p$h#0*0*a*%%($($@&M@M@-*-*-*G#2*0&0&s*U&U&|%;#;#'&F*F&F&`#R$R$L%`%o@.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @0#1$x=4.u=y=O*h=h=h=h=h=a=a=a=z=z=f=}+P@ ", +" A=X@X@X@X@X@X@s#s#s#s#s#s#}@ @ @ @ @O@!#!#~#{#{#Q@]#]#^#m#R@R@R@K#K#L#{+{+P@P@P@{+{+{+K#K#m#^#Q@{#~#)#l#[#J##$<$}+{ 5 U$4%N%H&Z*Y*X*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*B=]#+$-%I#{&o&i#K&_$a&a&z%N@N@/#@*H#H#G&1%1%g$d$d$>#'*S$S$S$ $ $:*|*|*1*S@p$p$h#0*0*a*%%%%($@&M@M@-*-*-*G#2*2*0&s*s*U&|%;#;#'&F*F*F&`#`#R$L%C=f#*# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @A$/+;*>*D=E=F=h=a=a=a=a=z=z=z=z=z=z=G=[# ", +" *$X@X@s#s#s#s#s#s#s#s#s#s#X@/@ @ @ @z%{#{#Q@]#]#^#m#m#R@R@K#K#L#{+{+P@$$$$'#+$+$'#'#+$'#$$$$P@{+L#K#m#^#^#{#~#)#[#J#@$}+5 =%l%N%)&z&}=< c=X*W*W*W*W*W*W*W*W*W*W*W*W*H=^#f$U#M%.$%$i#_$z%N@N@/#@*@*H#G&G&1%g$d$d$>#'*'*S$S$S$ $:*|*|*1*S@S@p$h#h#0*a*%%%%($@&@&M@-*-*-*G#2*2*0&s*s*U&|%|%;#'&F*F*F&`#`#R$L%L*}$(#^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @0@^+n%)*!&E&m=a=z=z=z=z=z=z=I=I=I=I=J={ ", +" k*s#s#s#s#s#s#s#s#;$;$;$;$X@=# @ @ @a*]#]#^#m#m#R@R@R@K#L#{+{+P@$$$$'#+$+$[$f$f$f$>$>$f$f$f$[$[$[$+$'#'#$${+K#m#Q@~#l##$|++ *%x@_.c&I&V&}=B={.V*W*W*W*W*W*W*W*W*W*W*X*^#r$m%P%H$i#_$z%/#@*@*H#G&G&1%g$g$d$>#'*'*S$S$S$ $:*:*|*1*S@S@p$h#h#0*a*a*%%($@&@&M@-*-*-*G#G#2*0&s*s*U&|%|%;#'&'&F*F&`#`#R$L%L%F#E#/$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @d#U+D$>@c.q=K=z=z=z=z=I=I=I=I=I=I=I=L=. ", +" M=s#s#s#s#;$;$;$;$;$;$;$;$;$C= @ @ @L%^#m#R@R@R@K#L#L#{+P@P@$$'#+$+$[$f$f$>$r$r$s$n#s$s$s$n#s$s$s$s$r$r$>$[$'#P@K#^#~#[#@${ U$k%+&d&J&W&$@R*k=W*W*W*W*W*W*W*W*W*W*W*W*t#n#2%{&o&_$z%/#H#G&G&1%g$g$d$>#>#'*S$S$S$ $:*:*|*1*1*S@p$h#h#0*a*a*%%($($@&M@M@-*-*G#G#2*0&0&s*U&U&|%;#'&'&F*F&F&`#R$R$L%j%f#*# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @9#a+!$N=P&O=h=I=I=I=I=I=I=I=I=I=I=f=. e$ ", +" s*s#;$;$;$;$;$;$;$;$;$;$;$;$'* @ @ @9&R@R@K#L#L#{+P@P@$$'#'#+$[$f$f$>$r$r$s$n#n#n#j#:$:$:$-%-%-%-%:$:$j#n#r$f$+${+R@Q@l#@${ U$x@+&d&J&W@P=W*W*W*W*W*W*W*W*W*W*W*W*W*W*%.;%P%H$i#z%/#H#1%1%g$d$>#>#'*S$S$S$ $ $:*|*1*1*S@p$p$h#0*0*a*%%($($@&M@M@-*-*-*G#2*0&0&s*U&U&|%;#;#'&F*F&F&`#R$R$L%L%F#Z+/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @<&@@#@Q=:=R=O*I=I=I=I=I=I=I=I=S=S=S=C&K# ", +" ;$;$;$;$;$;$;$;$;$;$;$;$;$T= @ @ @E#K#L#{+{+P@$$'#'#+$[$[$f$>$>$r$s$n#n#n#j#j#:$-%-%;%U#5%U#5%5%;%;%-%j#s$>$+$L#^#!#J#|+5 4%6.!&n&w=V*W*W*W*W*W*W*W*W*W*W*W*W*W*W*U=<$2%2&%$a&@*H#1%d$d$>#'*S$S$S$ $ $:*|*|*1*S@p$p$h#0*0*a*%%%%($@&M@M@-*-*-*G#2*2*0&s*U&U&|%;#;#'&F*F*F&`#R$R$L%L%j%f#e# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @V=^+4*W=n&E=F=I=I=I=I=S=S=S=S=X=X=X=Y=#$ ", +" v@;$;$;$;$;$;$;$;$g@g@g@$.K# @ @ @a@{+P@$$$$'#+$[$[$f$>$>$r$s$s$n#n#j#j#:$-%-%;%U#U#5%m%m%m%m%m%U#;%-%n#r$+$P@m#~#[#}#+ *%A%_.H&+=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*w=Q@5%T$o&K&/#G&g$>#'*'*S$S$ $ $:*|*|*1*S@S@p$h#h#0*a*%%%%($@&@&M@-*-*-*G#2*2*0&s*s*U&|%|%;#'&F*F*F&`#`#R$L%L%L%Z==#/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @b$^+n%o%`= -.-I=S=S=S=X=X=X=+-+-+-+-@-. ", +" #-;$;$;$;$;$g@g@g@$.$.$.!%$- @ @ @ @;%'#+$+$[$f$>$>$r$s$s$n#n#n#j#:$-%-%;%U#U#5%m%m%O@O@2%O@m%m%;%-%n#>$'#{+^#!#k#<$+ *%x@)&/=X*W*W*W*W*W*W*W*W*W*W*W*W*W*W*k=N%f$;%M%H$i#N@G&d$>#S$S$S$ $:*:*|*1*S@S@p$h#h#0*a*a*%%($@&@&M@-*-*-*G#G#2*0&s*s*U&|%|%;#'&'&F*F&`#`#R$L%L%L%g#Z#C$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @8#b+x$&%%-3=X=X=X=+-+-+-+-+-+-+-+-&-. ", +" *-;$g@g@g@$.$.$.!%!%!%!%!%=- @ @ @ @ &[$f$f$>$r$r$s$n#n#n#j#:$:$-%;%;%U#5%m%m%O@2%2%2%2%O@O@m%;%:$s$>$$$K#]#Y@t#}+5 4%6.V&k=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*--l#f$U#e$H$K&z%G&d$'*'* $:*:*|*1*1*S@p$h#h#0*a*a*%%($($@&M@-*-*-*G#G#2*0&0&s*U&|%|%;#'&'&F*F&F&`#R$R$L%L%L*Q%o#a@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @;-C+>-] u=,-h=+-+-+-+-+-+-+-+-+-+-I=. U# ", +" '-g@$.$.$.!%!%!%!%!%!%!%!%)- @ @ @ @:*>$r$r$s$n#n#n#j#:$:$-%;%;%U#5%5%m%O@2%2%I#e$I#I#I#O@5%;%:$s$[$P@m#~#[#<$. =%l%b&P=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*7=O%{+r$5%P%H$i#/#H#g$'*S$:*|*1*1*S@p$p$h#0*0*a*%%($($@&M@M@-*-*-*G#2*0&0&s*U&U&|%;#;#'&F*F&F&`#R$R$L%L%L%L*F#=#^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @!-@@h*3$L&R=[=+-+-+-+-+-+-+-+-~-~-~-W=]# ", +" n#!%!%!%!%!%!%!%!%!%!%!%!%;$b$ @ @ @|%s$n#n#n#j#j#:$-%-%;%U#5%5%m%O@O@2%I#I#e$M%M%e$I#2%m%U#:$r$+$L#^#Y@t#}+%.4%.&w=X*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*!=l#+$j#O@,#o&K&/#G&d$S$:*:*1*S@p$p$h#0*0*a*%%%%($@&M@M@-*-*-*G#2*2*0&s*U&U&|%;#;#'&F*F*F&`#R$R$L%L%L%L*g#T&p@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @K@^+o+{-c&]-^-+-+-+-+-~-~-~-~-~-~-~-)#}# ", +" q$!%!%!%!%!%!%!%!%!%!%!%!%S%9& @ @ @W$n#j#j#:$-%-%;%U#U#5%m%O@O@2%I#I#e$M%M%P%P%P%e$I#O@U#:$s$+$K#Q@l#<$. =%k%P&7=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*^=x@{+r$U#e$2&%$a&/#1%'*S$:*1*S@p$h#0*0*a*%%%%($@&@&M@-*-*-*G#2*2*0&s*s*U&|%|%;#'&F*F*F&`#`#R$L%L%L%L*l&p&T@.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @D#^+3&/-A%(-_-+-~-~-~-~-~-~-~-~-~-:-<-. ", +" [-!%!%!%!%!%!%!%!%!%S%S%S%&&M@ @ @ @f#:$-%-%;%U#U#5%m%m%O@2%I#I#e$M%M%P%P%P%T$T$P%M%I#O@;%s$+$K#{#k#|+5 4%1&@=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*}-!#[$:$2%T$H$K&N@H#d$S$|*|*S@h#h#0*a*a*%%($@&@&M@-*-*-*G#G#2*0&s*s*U&|%|%;#'&'&F*F&`#`#R$L%L%L%L*L*l&L@o@d# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @&$I+|-f&%-1-S=~-~-~-~-~-:-:-:-:-2-2-. a& ", +" !%!%!%!%!%S%S%S%&&&&&&v@v@o& @ @ @(#;%;%U#5%m%m%O@2%2%I#e$e$M%P%P%P%T$,#,#,#,#T$M%I#m%j#f${+Q@k#}+U$6.#=X*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*-=4%$$s$5%M%2& &a&H#g$'* $1*p$p$0*a*a*%%($($@&M@-*-*-*G#G#2*0&0&s*U&U&U&|%;#;#'&F*F&`#R$L%L%L%L*L*l&g#`%C#/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @m$1$3-4 q%4-5-~-~-:-:-:-2-2-2-6-6-~-{ n# ", +" !%S%S%S%S%&&&&&&v@v@v@v@v@7- @ @ @d#O@5%m%O@2%2%I#e$e$M%P%P%P%T$,#,#{&2&2&2&2&,#P%I#U#s$$$^#l#|+V$y&c=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*V&Q@f$:$I#{&o&_$@*1%>#:*|*S@h#0*a*%%($($@&M@M@-*-*-*G#2*2*2*0&s*s*U&|%U&|%;#'&'&F*`#`#R$R$L%L*l&g#g#F#=#^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @~@/+k@$-y&8-9-:-2-2-2-6-6-6-6-6-6-6-0-~# ", +" a-&&&&&&v@v@v@v@v@v@v@v@v@~% @ @ @ @%$O@2%I#e$e$M%P%P%P%T$T$,#{&2&2&.$H$H$H$.${&P%2%-%>$L#~#@$k%j=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*Y*U$'#n#m%P%q$i#N@1%>#S$|*p$p$0*a*%%($@&M@M@-*-*M@-*G#G#2*0&0&0&0&s*s*U&U&U&|%|%;#'&F*F&F&R$L*L*l&j%-#(# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @C#^+(+$+D.b-^-2-6-6-6-6-6-6-6-6-6-6-n=}+ ", +" c-v@v@v@v@v@v@v@v@v@i&i&i&5 @ @ @ @'*I#e$M%M%P%P%T$T$,#{&{&2&.$.$H$q$o&o&q$q$2&T$2%:$[$^#t#P&)=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*X*q%^#>$;%e$2& &z%H#d$S$|*S@h#a*a*%%($($@&M@M@M@-*G#-*-*G#G#2*2*0&2*0&0&2*2*0&0&s*U&U&U&|%F*F*R$L%l&c$]@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @J@x#D$d-J*e-_-6-6-6-6-6-6-6-6-6-6-f-g-. ", +" 4@v@v@v@v@v@i&i&i&i&i&i&i& * @ @ @ @-*M%P%P%P%T$,#{&{&2&.$.$H$q$q$o&%$ & &%$o&.$,#2%j#'#]#3%W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*P=+ +$j#O@,#o&_$@*g$'*:*S@p$h#a*($($@&M@@&@&@&@&M@-*-*M@-*-*M@-*G#-*M@-*-*M@-*M@M@@&M@-*2*s*|%'&`#F#P$/$/@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @6@M*h-Z&:=1-~-6-6-6-6-6-f-f-f-f-f-2-. o& ", +" i-v@v@i&i&i&i&i&i&i&i&i&N&&*.@ @ @ @l&P%T$,#,#{&2&2&.$H$q$q$o&%$%$ &i#i#i#i#%$.$T$2%j#'#Q@/.W*W*W*W*W*W*W*W*W*W*W*W*W*W*X*J&R@s$5%P%H$K&/#1%># $|*p$0*0*a*%%($($($($%%($@&($($@&@&($@&($%%($%%%%a*a*a*h#h#p$p$p$h#0*%%M@2*g#o#C$D#.@/$/@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @q@@@,%~ j-k-5-6-6-f-f-f-f-f-f-l-l-l-z+[$ ", +" m-i&i&i&i&i&i&i&i&N&N&N&N&&&K@ @ @ @c$,#{&2&2&.$H$H$q$o&%$%$ &i#i#K&_$_$K&K&i#q${&e$:$'#Q@t#k=W*W*W*W*W*W*W*W*W*W*W*W*{.}+f$-%I#2&%$a&G&>#S$|*S@p$0*0*0*a*a*a*0*a*%%0*a*a*0*0*0*0*h#h#h#S@S@1*|*|* $'*'*>#>#d$d$'*S$|*G#y%o@Z+(#p@D#.@d#^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @B#/+n-i@o-p-q-f-f-f-f-l-l-l-r-r-r-r-s-l# ", +" N@i&i&i&i&N&N&N&N&N&N&u+u+u+F* @ @ @o@2&.$H$H$q$o&o&%$ &i#i#K&_$_$_$a&a&a&a&_$%$.$M%;%[$^#k#==W*W*W*W*W*W*W*W*W*W*)=b&P@j#O@T$o&_$@*g$S$:*1*p$h#h#0*0*h#h#h#p$p$p$p$S@S@1*|*|*|* $S$'*'*>#d$1%H#@*/#z%a&_$_$K&_$a&d$;#;=-#]$K@E#(#C$`+/$/@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @(#^+n%*&_.t-u-f-l-l-l-r-r-r-r-r-r-r-v-{ ", +" N&N&N&N&N&N&N&u+u+u+ * * */# @ @ @b$H$q$o&o&%$ & &i#K&K&_$_$a&a&z%N@N@/#N@a&K&q$,#m%s$L#)#$@W*W*W*W*W*W*W*W*W*==@$>$U#P%H$K&/#1%'*:*1*S@h#0*h#p$S@S@1*|*|* $ $ $S$'*>#d$g$1%G&H#/#/#z%_$i#i#o&q$H${&,#T$T$T$q$S$-*|%R$Q%Z=Z#o#=#]@e#.@d#^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @^@U@b+w-x-y-z-r-r-r-r-r-r-r-r-r-r-r-A-. ", +" N&N&N&u+u+u+ * * * * * * *;% @ @ @^@ &%$ & &i#K&K&_$_$_$a&z%N@N@/#@*@*H#@*N@a& &.$e$-%+$^#n&W*W*W*W*W*W*W*)=K+'#-%2%{& &N@G&>#:*1*h#0*0*p$h#p$1*:* $'*>#d$1%H#H#/#N@z%a&K&i# &o&H$2&,#T$P%e$2%O@5%;%-%:$;%q$G&g$S$p$-*s*S$Q%f#$=P$C$`+/$^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @)@a+B-R%:=C-6-r-r-r-r-r-r-r-r-D-D-2-. ,# ", +" E-u+ * * * * * * * * * *!*F- @ @ @ @>#i#K&K&_$_$_$a&z%z%N@/#/#@*H#G&G&1%1%H#/#_$o&,#O@n#$$4%W*W*W*W*W*W*/=[#n#m%T$q$_$H#d$ $S@0*0*a*a*h#p$1*:*'*d$1%@*z%_$i#%$o&H$.${&,#T$M%I#O@m%U#-%j#n#s$>$[$+$$$$$;%,#j#]#/.O%H&j=X*W*@*%#K@=#b$`+/$/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @A#@@#@$&8*G-S=r-r-r-r-r-D-D-D-H-H-H->*P@ ", +" I- * * * * * * *!*!*!*!*!*d+ @ @ @ @@&_$_$_$a&z%z%N@/#/#@*H#H#G&1%g$g$d$d$1%G&/#K&H$P%m%n#l#W*W*W*W*U=.&r$U#M%.$K&/#g$ $1*h#a*%%%%($%%h#S@:*>#G&/#_$%$H${&T$M%2%m%5%;%:$n#n#r$f$+$'#P@{+L#R@~#{ A%K+P&1=k=W*W*W*W*W*W*W*W*r$-#O$Z+]@D#a@/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @J-^+p+_@b&K-L-r-D-D-D-H-H-H-H-H-H-H-^&J# ", +" M- * * * *!*!*!*!*!*!*!*!*d* @ @ @ @L%a&a&z%N@/#/#@*H#H#G&1%1%g$d$>#>#'*'*>#1%H#z%i#q$T$O@j#)=W*W*#=^#5%M%2& &N@1%'*1*p$a*($M@M@@&@&%%p$|*>#H#a&%${&M%2%U#:$n#r$[$'#$${+L#K#m#]#@$&%)&W&Z*+=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*<$y%f#E#}%D#a@/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @N-^+T+7#O%O-u-H-H-H-H-H-H-H-H-H-H-P-Q-. ", +" m#!*!*!*!*!*!*!*!*!*!*(*(*i&/@ @ @ @F#N@N@/#@*@*H#G&1%1%g$d$d$>#'*'*S$S$S$'*>#d$H#/#_$o&2&T$< 7=V$M%T$.$ &a&G&>#:*S@0*($M@-*2*G#-*M@%%S@S$G&a&q$T$O@-%r$+$P@K#m#]#[#%..&y&!={.)=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*!&y%f#E#}%D#a@/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @w%I+8=s@R-z-l-H-H-H-H-H-P-P-P-P-P-P-. ", +" S-!*!*!*!*!*!*(*(*(*j&j&j& *Z+ @ @ @f#@*@*H#G&G&1%g$d$d$>#'*'*S$S$S$ $:*|*:*:*S$>#g$H#z%K& &5 U#o& &K&N@G&d$ $S@0*($-*G#0&s*s*0&2*-*%%1*>#/# &,#m%n#P@t#&%K+V&/=^=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*---#o$Z+]@D#a@/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @z#C+d=w@:=T-U-H-H-P-P-P-P-P-P-V-V-r-. O@ ", +" W-!*!*(*(*(*j&j&j&j&j&j&j&j&O& @ @ @Z+G&G&1%g$g$d$>#'*'*S$S$S$ $:*:*|*1*1*1*1*1*:* $>#g$G&H#/#@*@*G&g$># $1*h#%%@&G#0&U&U&|%;#U&s*-*%%1*d$z%T$_.V&{.)=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*V*c$o#=#p@`+/$/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @a#/+:#z+2=X-X=P-P-P-P-V-V-V-V-Y-Y-Y-Z-m# ", +" (*(*j&j&j&j&j&j&j&j&j&c*c*|* @ @ @e#g$g$d$>#>#'*S$S$S$ $:*:*|*1*1*S@p$p$p$h#p$S@S@|* $ $S$'*S$S$ $|*p$0*%%M@2*0&U&|%'&'&'&F*;#U&2*%%|*1%_$,#k=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*k=$@6.~#~@&#(#*#`+/$^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @o@^+o+q#K+K-L-P-V-V-V-Y-Y-Y-Y-Y-Y-Y-^&#$ ", +" j&j&j&j&j&j&j&j&c*c*c*c*c*P% @ @ @ @S$>#'*S$S$S$ $ $:*|*1*1*S@p$p$h#0*0*a*a*%%0*a*0*h#h#p$S@p$h#0*%%@&-*G#0&U&|%;#F*F&F&`#`#F*;#0&%%|*g$_${&/=W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*@=X&A%[#U#1%`#Q%y%]$a$=#b$D#.@d#^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @.@^+M#p= +|=`-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y- ;. ", +" j&j&j&j&c*c*c*c*c*c*g*g*g*{+ @ @ @ @M@S$S$ $ $:*|*|*1*S@S@p$h#0*0*a*%%%%($@&($@&@&($%%%%($($@&M@M@G#0&s*U&;#'&F*F&`#`#R$L%R$F&'&s*M@p$>#z%H$J&W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*W*7=#=d&%.m#I#d$0*($G#|%R$j%`%c$Q$a$Z+}%*#`+/$/@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @y#C@J+(.R-z-H-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-H-. ", +" .;c*c*c*c*c*c*g*g*g*g*g*g*+; @ @ @ @`# $:*|*|*1*S@S@p$h#h#0*a*%%%%($@&@&M@-*-*M@-*G#-*-*G#G#2*0&0&U&;#'&'&F&`#`#R$L%L%L%L*L*R$F&;#G#a*:*H#i#x@W*W*W*W*W*W*W*W*W*W*W*W*W*W*X*==q%x@[#s$i#S@0*($-*2*U&'&`#L*p&O&F#c$Z#o$$==#}%C$`+a@d#^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @8&1$2$@ %-@;l-Y-Y-Y-Y-Y-Y-Y-Y-#;#;#;$;-% ", +" %;c*c*g*g*g*g*g*g*g*g*g*g*&; @ @ @ @W$|*1*S@S@p$h#h#0*a*a*%%($@&@&M@-*-*-*G#G#2*0&2*0&s*U&U&|%;#;#'&F*F&`#R$L%L%L%L*L*l&g#l&L*R$F&U&-*h#'*/#[#W*W*W*W*W*W*W*W*c=B=c&. L#P%'*h#%%M@G#s*;#F*R$L*j%Q%O&;=Z=-#%#Z#f#K@$=Z+P$]@*#`+a@d#/@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @n@/+;**=z&*;=;Y-Y-Y-Y-#;#;#;-;-;-;-;0-Q@ ", +" ;;g*g*g*g*g*g*g*g*C%C%C%o* * @ @ @ @}$S@p$p$h#0*a*a*%%($($@&M@M@-*-*G#G#2*0&0&s*U&U&|%;#'&'&F*F&F&`#R$R$L%L%L*L*l&g#g#j%p&j%j%g#L%F*s*M@p$'*U#W*)=j=X&_.+ Q@;%a&S@@&-*2*U&'&`#L%g#p&L@`%F#y%c$%#T&Q$f#o$K@o@&#Z+=#(#]@C$D#`+a@d#/@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @=#^+(+)*>;,;';Y-#;#;#;-;-;-;-;-;-;-;0-}# ", +" i-g*g*g*g*C%C%C%o*o*o*o*o*!*]@ @ @ @a$h#0*0*a*%%($($@&M@M@-*-*-*G#2*0&0&s*U&U&|%;#;#'&F*F&F&`#R$R$L%L%L%L*l&g#g#j%p&p&C=Q%C=Q%p&g#L%F&U&-*a*'*P%/#/#z%a&z%H#M@F&L%l&j%Q%W$;=Z=~@9&}$Z#f#O$T@o#o@&#C#Z+=#0@(#}%b$p@*#D#`+a@/$d#/@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @d#U+D$E$c. -u--;-;-;-;-;-;-;-;-;-;-;);. ", +" !;g*C%C%C%o*o*o*o*o*o*y*y*y*}$ @ @ @c#a*%%%%($@&@&M@-*-*-*G#2*2*0&s*s*U&|%;#;#'&F*F*F&`#`#R$L%L%L%L*l&l&g#j%j%p&C=Q%Q%L@O&O&O&L@Q%p&l&`#;#0&M@a*p$S@|*|*2*Q%;=F#y%c$%#Z#Q$f#o$K@a$$=C#E#=#0@P$(#}%]@b$C$*#e#D#`+`+.@a@/$d#/@^@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @F+a+!$N=8*~;Y--;-;-;-;-;-;-;-;-;-;P-. K& ", +" o*o*o*o*o*o*o*y*y*y*y*y*y*-* @ @ @.@($@&@&M@-*-*-*G#2*2*0&s*s*U&|%|%;#'&F*F*F&`#`#R$L%L%L%L*l&l&g#j%j%p&C=C=Q%L@O&O&W$`%`%`%;=W$L@C=j%L*R$F*|%U&0&|%F#]$Q$f#O$T@o#o@&#E#Z+=#0@(#c#}%b$p@C$*#e#D#`+`+.@.@a@/$/$d#d#/@^@^@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @{;@@];Q=R-^;l--;-;-;-;-;-;-;-;/;/;(;}#>$ ", +" o*o*o*y*y*y*y*y*y*y*y*y*y* & @ @ @ @2*-*-*-*G#G#2*0&s*s*U&|%|%;#'&'&F*F&`#`#R$L%L%L%L*L*l&g#j%j%p&C=C=Q%L@L@O&W$W$`%;=F#F#F#F#;=;=`%L@Q%C=p&g#l&F#o@C#C#E#Z+=#0@P$c#}%]@b$C$*#e#D#D#`+`+.@a@a@/$/$d#d#/@/@/@^@^@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @]$^+6%W=n&_;=;-;-;-;-;/;/;/;/;/;/;:;E*)# ", +" y*y*y*y*y*y*y*y*y*y*y*y*y*<; @ @ @ @L%G#G#2*0&0&s*U&U&|%;#'&'&F*F&F&`#R$R$L%L%L*L*l&g#g#j%p&p&C=Q%L@L@O&W$W$`%;=;=F#F#Z=Z=y%y%Z=y%y%F#F#;=;=y%$=]@}%}%]@]@b$p@C$*#e#D#`+`+.@.@a@a@/$d#d#/@/@/@^@^@^@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @x&^+n%o%`=]-';/;/;/;/;/;/;/;:;:;:;[;};/. ", +" I=y*y*y*y*y*y*y*y*y*y*O*O*E* @ @ @ @`%0&0&s*U&U&|%;#;#'&F*F&F&`#R$R$L%L%L%L*l&g#g#j%p&p&C=Q%Q%L@O&W$W$`%;=;=F#F#F#Z=y%~@~@-#c$-#c$c$c$c$c$T@*#`+D#D#D#`+`+`+`+.@a@a@/$/$d#d#/@/@/@^@^@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @8#b+B%&%|;1;/;/;/;:;:;:;[;[;[;[;[;2;. ", +" 3;y*y*y*y*y*y*y*O*O*O*T*T*$; @ @ @ @%#U&U&|%;#;#'&F*F*F&`#`#R$L%L%L%L*l&l&g#j%j%p&C=Q%Q%L@O&O&W$`%`%;=F#F#F#Z=y%y%~@-#-#c$9&%#%#}$}$}$]$]@d#/$/$/$/$/$/$/$d#d#/@/@/@^@^@^@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @l@C+>-] 8*4;Y-:;:;[;[;[;[;[;[;[;[;#;. H$ ", +" 5;y*y*y*O*O*O*T*T*T*T*T*T*d* @ @ @ @K@|%;#'&F*F*F&`#`#R$L%L%L%L*l&l&g#j%j%p&C=C=Q%L@O&O&W$`%`%;=F#F#F#Z=y%y%~@-#-#c$9&9&%#}$T&T&Z#]$&#/$^@^@^@^@^@^@^@^@^@^@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @8@@@#&6#y-6;H-[;[;[;[;[;[;[;7;7;7;7;>*'# ", +" 8;O*O*O*T*T*T*T*T*T*T*T*T*j&.@ @ @ @=#'&F*F&`#`#R$L%L%L%L*L*l&g#j%j%p&C=C=Q%L@L@O&W$`%`%;=F#F#F#Z=Z=y%~@-#-#c$9&9&%#}$}$T&Z#Z#]$f#b$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @Y#^+]&m+[*9;~-[;[;[;[;7;7;7;7;7;7;0;a;[# ", +" b;T*T*T*T*T*T*T*T*T*T*T*T*d*K@ @ @ @C$F&`#R$R$L%L%L*L*l&g#g#j%p&p&C=Q%L@L@O&W$W$`%;=;=F#F#Z=Z=y%~@~@-#c$c$9&%#}$}$T&Z#Z#]$Q$Q$a$a@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @D#^+3&/-A%c;';7;7;7;7;7;7;0;0;0;0;0;d;{ ", +" e;T*T*T*T*T*T*T*T*T*T*T*]=]=R$ @ @ @/$R$L%L%L%L*l&g#g#j%p&p&C=Q%Q%L@O&W$W$`%;=;=F#F#F#Z=y%~@~@-#c$c$9&%#%#}$T&Z#Z#]$Q$Q$f#f#P$^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @G+I+e&f&f;1;/;7;7;0;0;0;0;0;0;0;0;-;. ", +" T*T*T*T*T*T*T*T*]=]=]=[=[=G& @ @ @ @j%L*l&l&g#j%p&p&C=Q%Q%L@O&O&W$`%;=;=F#F#F#Z=y%y%~@-#-#c$9&%#%#}$T&T&Z#]$]$Q$f#f#f#K@D# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @g;1$q&4 h;i;j;0;0;0;0;0;0;0;0;k;k;-;+ e$ ", +" T*T*T*T*]=]=]=[=[=[=[=[=[=l; @ @ @ @F#g#j%j%p&C=C=Q%L@O&O&W$`%`%;=F#F#F#Z=y%y%~@-#-#c$9&9&%#}$T&T&Z#]$]$Q$f#f#f#O$o$C#d# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @x%/+k@$-D=m;n;0;0;0;0;k;k;k;o;o;o;o;Z-K# ", +" z=]=]=]=[=[=[=[=[=[=4=4=4=p; @ @ @ @T&p&C=C=Q%L@L@O&W$`%`%;=F#F#F#Z=Z=y%~@-#-#c$9&9&%#}$}$T&Z#]$]$Q$f#f#f#O$O$o$T@}% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @$%^+o+R+)&q;r;k;k;k;k;o;o;o;o;o;o;o;s;t# ", +" t;[=[=[=[=[=4=4=4=4=4=4=4=%; @ @ @ @K@Q%L@L@O&W$W$`%;=;=F#F#Z=Z=y%~@~@-#c$c$9&%#}$}$T&Z#Z#]$Q$Q$f#f#O$O$o$T@T@o@`+ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @/$H+D$d-3%u;';o;o;o;o;o;o;o;o;o;v;v;w;. ", +" x;[=[=4=4=4=4=4=4=4=4=4=f=y; @ @ @ @Z+O&W$W$`%;=;=F#F#F#Z=y%~@~@-#c$c$9&%#%#}$T&Z#Z#]$Q$Q$f#f#f#O$o$T@T@K@o#Z+d# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @H%M*c%O.z;1;7;o;o;o;o;o;v;v;v;v;v;-;. ", +" A;4=4=4=4=4=4=4=f=f=f=f=h=B;d# @ @ @}%`%;=;=F#F#F#Z=y%y%~@-#c$c$9&%#%#}$T&T&Z#]$Q$Q$f#f#f#O$o$o$T@K@K@o#a$}%^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @v&@@$*4.q=C;(;o;v;v;v;v;v;v;v;v;v;0;D;U# ", +" i-4=4=4=4=f=f=f=h=h=h=h=h=O*E# @ @ @`+F#F#F#Z=y%y%~@-#-#c$9&9&%#}$T&T&Z#]$]$Q$f#f#f#O$o$o$T@K@K@o#a$a$$=D# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @b@/+;*>*m&E;n;v;v;v;v;v;v;v;F;F;F;G;Y@m# ", +" m%f=f=f=h=h=h=h=h=h=h=h=h=h=`% @ @ @/@Z=Z=y%~@-#-#c$9&9&%#}$}$T&Z#]$]$Q$f#f#f#O$O$o$T@K@K@o#a$a$o@$=Z+a@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @P$^+n%*&H;I;r;v;v;v;F;F;F;F;G;G;G;G;s;<$ ", +" h=h=h=h=h=h=h=h=h=h=h=h=a=1* @ @ @ @%#~@-#c$9&9&%#}$}$T&Z#Z#]$Q$Q$f#f#O$O$o$T@T@K@o#o#a$o@$=$=&#(#^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @^@J;b+w-4%K;';F;F;F;G;G;G;G;G;G;L;L;M;. ", +" h=h=h=h=h=h=h=h=h=a=a=a=z=N; @ @ @ @O$c$9&%#%#}$T&Z#Z#]$Q$Q$f#f#f#O$o$T@T@K@o#o#a$o@o@$=&#C#C#p@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @V#a+B-%@O;P;o;G;G;G;G;G;L;L;L;L;L;0;. /# ", +" h=h=h=h=h=a=a=a=z=z=z=z=z=Q; @ @ @ @o@%#}$T&T&Z#]$Q$Q$f#f#f#O$o$o$T@K@o#o#a$o@o@$=&#&#C#E#=#`+ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @R;@@#@Z.2=S;/;G;L;L;L;L;L;L;L;L;L;T;}#j# ", +" U;a=a=a=a=z=z=z=z=z=z=I=I=V; @ @ @ @=#T&Z#]$]$Q$f#f#f#O$o$o$T@K@K@o#a$a$o@$=&#&#C#E#E#Z+0@a@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @O$^+4*#+b&W;H-L;L;L;L;L;L;L;T;T;T;T;X;~# ", +" Y;z=z=z=z=z=z=I=I=I=I=I=I=Z; @ @ @ @]@]$Q$f#f#f#O$O$o$T@K@K@o#a$a$o@$=$=&#C#E#E#Z+=#=#c#/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @p@^+T+`; >.>r;L;L;L;T;T;T;T;T;T;T;T;+>|+ ", +" s-z=z=z=I=I=I=I=I=I=I=I=I=O* @ @ @ @e#f#f#O$O$o$T@T@K@o#a$a$o@$=$=&#C#C#E#Z+Z+=#=#0@b$^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @D+I+b*s@@>#>T;T;T;T;T;T;T;T;T;$>$>%>. ", +" &>I=I=I=I=I=I=I=I=I=I=I=I=P*}% @ @ @a@O$o$T@T@K@o#o#a$o@o@$=&#C#C#E#Z+Z+=#=#=#0@P$e# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @z#C+e*w@R-*>=>T;T;T;T;$>$>$>$>->->k;. %$ ", +" ;>I=I=I=I=I=I=I=I=S=S=S=X=z=T& @ @ @^@T@K@o#o#a$o@o@$=&#&#C#E#Z+Z+=#=#=#0@P$P$(#`+ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @G@/+h*3$D=>>,>T;$>$>$>->->->->->->'>Z->$ ", +" I=I=I=I=S=S=S=S=X=X=X=+-+-0& @ @ @ @$=a$a$o@$=&#&#C#E#E#Z+=#=#=#0@P$P$(#c#}%a@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @o@^+o+q#)>*;!>->->->->->->->'>'>'>'>E*Y@ ", +" I=S=S=S=X=X=X=+-+-+-+-+-+-~> @ @ @ @=#$=$=&#C#E#E#Z+=#=#=#0@0@P$(#c#c#}%b$d# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @`+^+M#N#O#,;U-->->->'>'>'>'>'>'>'>'>{>/. ", +" X=X=X=+-+-+-+-+-+-+-+-+-+-]> @ @ @ @}%C#C#E#Z+=#=#=#0@0@P$(#(#c#}%]@]@C$/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@#C@*$f&^>/>T;'>'>'>'>'>'>'>'>'>'>(>. ", +" 2-+-+-+-+-+-+-+-+-+-+-+-~-_> @ @ @ @C$Z+Z+=#=#=#0@P$(#(#c#}%}%]@b$b$e#^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @8&1$2$s :><>o;'>'>'>'>'>'>'>[>[>[>}>{ {& ", +" |>+-+-+-+-+-+-+-+-~-~-~-~-g- @ @ @ @`+=#=#0@P$P$(#c#}%}%]@b$b$p@C$D# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @1>/+k@;@2>3>/;'>'>'>'>[>[>[>4>4>4>5>6>P@ ", +" 7>+-+-+-+-~-~-~-~-~-~-~-~-z= @ @ @ @a@P$P$(#c#c#}%]@]@b$p@C$C$*#.@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @=#^+(+t$!&8>9>[>[>[>4>4>4>5>5>5>5>5>E*J# ", +" 0>+-~-~-~-~-~-~-~-~-~-:-:-9-D# @ @ @/@c#c#}%]@]@b$p@p@C$*#e#e#a@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @d#U+D$E$c.,;r;4>4>4>5>5>5>5>5>5>5>5>a>. ", +" b>~-~-~-~-~-~-:-:-:-:-2-2-'=T@ @ @ @ @]@]@b$p@p@C$*#*#e#D#`+/$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @N$M*X$O.f;c>'>5>5>5>5>5>5>5>5>5>5>G;. ", +" d>~-~-~-:-:-:-2-2-2-6-6-6-6-L* @ @ @ @C$p@C$*#*#e#D#D#`+`+d# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @m@@@,%'%2=e>F;5>5>5>5>5>5>5>5>5>5>f>8+e$ ", +" :-:-2-2-2-6-6-6-6-6-6-6-6-g$ @ @ @ @D#*#e#D#D#`+`+`+.@/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @g>/+6%7%h>i>j>5>5>5>5>5>5>5>f>f>f>f>0-K# ", +" 2-2-6-6-6-6-6-6-6-6-6-6-6-k> @ @ @ @.@D#`+`+`+.@a@a@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @x&^+n%4@+&l>!>5>5>5>f>f>f>f>f>f>f>f>m>#$ ", +" 6-6-6-6-6-6-6-6-6-6-6-f-f-n> @ @ @ @/$`+.@.@a@/$d#^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @^@M$b+B%&%u;o>f>f>f>f>f>f>f>f>f>p>p>q>. ", +" 2;6-6-6-6-6-6-f-f-f-f-f-f-r> @ @ @ @/@a@/$/$d#/@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @X%C+5@R%f;s>t>f>f>f>f>p>p>p>p>p>p>$>. ", +" u>6-6-6-f-f-f-f-f-f-l-l-l-v> @ @ @ @^@d#/@/@^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @X+@@#&6#w>x>F;f>p>p>p>p>p>p>p>p>p>y><$;% ", +" z>f-f-f-f-f-l-l-l-r-r-r-r-L-d# @ @ @ @^@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @A>^+]&m+)>m;j>p>p>p>p>p>p>p>y>y>y>B>E*^# ", +" C>f-f-l-l-l-r-r-r-r-r-r-r-S=C# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @e#^+3&4&D>l>E>p>p>p>y>y>y>B>B>B>B>B>F>}# ", +" G>l-r-r-r-r-r-r-r-r-r-r-r-r-;= @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @H>I+e&f&O-I>J>y>B>B>B>B>B>B>B>B>B>$>. ", +" r-r-r-r-r-r-r-r-r-r-D-D-D-K> @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @g;1$q&r&L>M>4>B>B>B>B>B>B>B>B>B>B>N>. z% ", +" r-r-r-r-r-r-r-D-D-D-H-H-H-O> @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @A&/+B&C&l=P>Q>B>B>B>B>B>B>B>R>R>R>S>T>s$ ", +" r-r-r-D-D-D-H-H-H-H-H-H-H-U> @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @$%^+o+j*)&V>j>B>B>B>R>R>R>S>S>S>W>W>G=~# ", +" X>D-H-H-H-H-H-H-H-H-H-H-P-E* @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @/$H+D$Q&R&Y>Z>R>R>R>S>S>S>W>W>W>W>W>7>/. ", +" q>H-H-H-H-H-H-H-P-P-P-P-P-`> @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @E+C@Y&Z& ,.,y>S>W>W>W>W>W>W>W>W>W>'>. ", +" +,H-H-H-H-P-P-P-P-P-P-V-V-z= @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @v&1$$*4.e-@,4>W>W>W>W>W>W>W>W>W>W>B>{ o& ", +" #,P-P-P-P-P-P-V-V-V-V-Y-Y-=;c# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @%#/+;*>*h>$,Q>W>W>W>W>W>W>W>W>W>W>%,&,f$ ", +" *,P-P-P-V-V-V-Y-Y-Y-Y-Y-Y-H-}$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @0@^+n%)*_.=,-,W>W>W>W>W>W>%,%,%,;,;,>,l# ", +" V-V-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-U& @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @/@J;b+>@c.,,Z>W>W>W>%,%,%,;,;,;,',',),{ ", +" Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-z% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @!,a+/*%@ -~,{,%,;,;,;,',',',',',',5>. ", +" Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-#;#;], @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @R;@@#@Z.w>*>5>;,',',',',',',',',',%,s&P% ", +" -;Y-Y-Y-Y-Y-Y-#;#;#;-;-;-;^, @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @3*^+4*#+[*T-Q>',',',',',',/,/,/,/,/,s;P@ ", +" (,Y-Y-Y-#;#;#;-;-;-;-;-;-; ; @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @b$^+T+`;O%_,-,',',',/,/,/,/,/,/,/,/,:,t# ", +" d;#;#;-;-;-;-;-;-;-;-;-;-;<, @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @D+b+b*s@[,},/,/,/,/,/,/,/,/,/,|,|,p>. ", +" z>-;-;-;-;-;-;-;-;-;-;-;-;S=D# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @1,C+e*w@ -2,{,/,/,/,/,|,|,|,|,|,|,R>. ", +" 3,-;-;-;-;-;-;-;-;-;-;-;/;4,o$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @5,/+h*3$2>6,7,|,|,|,|,|,|,|,8,8,8,9,@$O@ ", +" -;-;-;-;-;-;-;/;/;/;/;/;/;j% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @a$^+o+{-0,a,b,|,|,|,8,8,8,9,9,9,9,9,c,m# ", +" -;-;-;/;/;/;/;/;/;/;:;:;:;d, @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @`+^+M#/-$.e,-,8,8,8,9,9,9,9,9,9,9,9,m><$ ", +" /;/;/;/;/;/;:;:;:;[;[;[;[;f, @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @&$I+|-f&u;g,/,9,9,9,9,9,9,9,9,9,9,h,. ", +" /;/;:;:;:;:;[;[;[;[;[;[;[;i, @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @F@1$.*4 -j,W>9,9,9,9,9,9,9,k,k,k,l,+ H# ", +" v;:;[;[;[;[;[;[;[;[;[;7;7;&, @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @0$/+k@$-l=m,7,9,9,9,k,k,k,k,k,k,k,n,o,-% ", +" p,[;[;[;[;[;[;[;7;7;7;7;7;q, @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @h%^+(+$+>;r,s,k,k,k,k,k,k,n,n,n,t,t,u,Q@ ", +" v,[;[;[;7;7;7;7;7;7;0;0;0;S=/$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @d#x#D$I*J*w,x,k,k,n,n,n,n,t,t,t,t,t,y,|+ ", +" z,7;7;7;7;7;7;0;0;0;0;0;0;H-&# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @E@C@c%Z&A,B,C,n,t,t,t,t,t,t,t,t,t,4>. ", +" D,7;7;0;0;0;0;0;0;0;0;0;0;2;F# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @9$1$.*4 ,2,/,t,t,t,t,t,t,t,E,E,E,Z>{ K& ", +" 0;0;0;0;0;0;0;0;k;k;k;o;o;%% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @Z#@@_=Q=0,s>%,t,t,t,E,E,E,E,E,E,F,B,Y@r$ ", +" 0;0;0;0;k;k;k;k;o;o;o;o;o;G, @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @c#/+#&$&A%H,%,E,E,E,E,E,E,F,F,F,F,I,J,)# ", +" 0;k;k;k;o;o;o;o;o;o;o;o;o;K, @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @^@^+x=~ (.L,|,E,E,F,F,F,F,F,F,F,F,M,N,}+ ", +" G;o;o;o;o;o;o;o;o;o;v;v;v;z> @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @H+c%r&z+O,n,F,F,F,F,F,F,F,F,P,P,Q,R,. ", +" S,o;o;o;o;o;v;v;v;v;v;v;v;2; @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @^@a+4&s J#T,F,F,F,F,F,P,P,P,P,P,P,U,U#/..$ ", +" V,o;o;v;v;v;v;v;v;v;v;v;F;W, @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @p@x=7%7%v-X,F,F,P,P,P,P,P,P,Y,Y,k,Z,`,`;$$ ", +" 'v;v;v;v;v;v;v;F;F;F;F;G;.'c# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @`+L@I*_@*$+'P,P,P,P,P,Y,Y,Y,Y,@'@'#'$'%'&')# ", +" *'v;v;v;v;F;F;F;G;G;G;G;G;[;}$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @/@e#a$='/-|-o=%,P,P,Y,Y,Y,@'@'@'@'@'@'A,j,-';'#$ ", +" F;F;F;G;G;G;G;G;G;G;L;L;L;>' @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @/@e#o@g#/*V@4*R>Y,Y,@'@'@'@'@'@'@'@'@'@','''-')'{ ", +" G;G;G;G;G;G;L;L;L;L;L;L;L;/# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @^@`+}%o$z%;*D$!'@'@'@'@'@'@'@'@'@'@'@'@'~'{'U>-']'. ", +" G;G;L;L;L;L;L;L;L;L;L;L;T;^' @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @^@.@/'('C@o&_'@'@'@'@'@'@'@'@'@'@'@'@'@':'<'['-'-'/. ", +" L;L;L;L;L;L;L;L;T;T;T;T;T;}' @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @o@|'e$1'9,@'@'@'@'@'@'@'@'@'@'@'@'@'7,2'3'-'-'-'^* ", +" S,L;L;L;L;T;T;T;T;T;T;T;T;w; @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @4'5'6'7';,/,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@':'8':#-'-'-'9' ", +" ''T;T;T;T;T;T;T;T;T;$>$>$>r- @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @D#0'a'b'c'd'F,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'e'f'R>-'-'-'-'s$ ", +" g'T;T;T;T;T;T;$>$>$>->->->l-e# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @^@h'i'j'k'l'm'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'F,n'I,]&-'-'-'o'K& ", +" p'T;T;$>$>$>->->->->->->->/;o$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @q'`%r's't'u'v'Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'Z,w'x'-'-'-'-'y'l& ", +" $>$>->->->->->->'>'>'>'>T;j% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @d#z'A'B'C'D'v'P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'E'F'G'%'-'-'-'-'H' ", +" ->->->->'>'>'>'>'>'>'>'>'>I' @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @c#J'K'L'M'N'O'P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'P'Q'Z>R'-'-'-'-'-'S' ", +" ->'>'>'>'>'>'>'>'>'>'>'>'>T' @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @a@U'V'W'X'Y'9,F,F,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'Z'Q'`':#-'-'-'-'-' ).) ", +" '>'>'>'>'>'>'>'>'>'>[>[>[>+) @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@)#)$)%)&)t,n,F,F,F,F,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'*)=)B,5%-'-'-'-'-'-'[' ", +" 4>'>'>'>'>'>[>[>[>4>4>4>5>-) @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @;)>),)')))!)n,F,F,F,F,F,F,F,P,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'b,~){)])^)-'-'-'-'-'-'-'/) ", +" ()'>'>[>[>[>4>4>4>5>5>5>5>_) @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @:)<)[)})l'm'E,F,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'/,A,|)1)2)3)-'-'-'-'-'-'-'4)5) ", +" 6)[>4>4>4>5>5>5>5>5>5>5>5>4,/$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @*#7)8)9)t'0)8,E,E,E,E,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,Y,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'a)b)Q'c)d)e)-'-'-'-'-'-'-'-'-'f) ", +" g)4>5>5>5>5>5>5>5>5>5>5>5>/;&# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @^@h)i)j)k)l)m)t,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'G'n)b)o)f'U,-,p)q)-'-'-'-'-'-'-'-'-' )r) ", +" *'5>5>5>5>5>5>5>5>5>5>5>5>$>F# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @}%s)t)u)v)N'9,t,t,t,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'C,w)x)A,{'o)y)z)A)B)`'C)D) )-'-'-'-'-'-'-'-'-'-'-'E) ", +" 5>5>5>5>5>5>5>5>5>f>f>f>f>@& @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @/$F)G)H)I)J)K)t,t,t,t,t,t,E,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,Y,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'a)L)M):'N)O)P)Q)c)8'e>9>_'R)S)H+-'-'-'-'-'-'-'-'-'-'-'-'-'-'T)U) ", +" 5>5>5>5>5>f>f>f>f>f>f>f>f>V) @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @W)X)Y)Z)`)t,9,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'%,`' !b).!+!@!#!w'$!%!/>5>&!*!=!3)-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-!;! ", +" 5>5>f>f>f>f>f>f>f>f>f>p>p>>! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @`+,!'!)!!!~!/,n,n,n,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'F,-,{!1)c){)]!O)N):'e,6,^!/!(!:$_!:!-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'f>f>f>f>f>f>f>p>p>p>p>p>}! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @E#|!1!2!3!v'k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'4!5!M,6!7!8!@!9!0!a!x)2,b!}!c!]+d!-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'e!f!U) ", +" ()f>f>f>p>p>p>p>p>p>p>p>p>M; @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @`+g!h!i!j!k!|,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'n,l!m,m!n!o!|)p!q!r!$'s!=>C)J,$*t! )-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'u!5)U) ", +" O'p>p>p>p>p>p>p>p>p>y>y>y>4, @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @o#v!w!x!y!8,/,9,k,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'7,j,=,z!A!f'|)B!C!*)D!o>()E!e)o+%'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'F!G!H!U) ", +" I!p>p>p>p>p>y>y>y>B>B>B>B>j;(# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @p@J!K!L!M!N!/,9,9,9,9,9,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'9,e'Z'a!O!n'@!F'P!Z,=,Q!G;x'R!5%S!-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'T!U!U)U) ", +" 1'p>p>y>y>y>B>B>B>B>B>B>B>T;%# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @/@V!W!X!Y!J)K)9,9,9,9,9,9,9,9,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'b,Q!e,Z!`!=)Q' ~.~+~m,@~#~$~<;%~&~-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'*~=~U)U)U) ", +" y>B>B>B>B>B>B>B>B>B>B>B>B>p$ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @}%-~;~>~,~O'8,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,Y,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'@'/,'~x)U,)~!~y)z)~~{~]~^~/~ '(~_~y'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-':~<~[~}~U)U)U) ", +" B>B>B>B>B>B>B>B>B>B>R>R>R>c! @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @a@|~1~2~3~4~()8,9,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'@'@'@'5~6~B)7~~)P)P),'8~B)6,9~0~a~n#b~c~-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'d~e~f~g~h~r)U)U)U)U) ", +" t>B>B>B>B>B>B>R>R>R>S>S>S>o;}% @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @i~j~$)k~l~8,l,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,n,n,n,n,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'@'@'@'@'m~n~E'{~~~o~y)p~w'U, !q~h,}!r~T=s~-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'t~u~v~w~x~}~y~U)U)U)U)U)U)U)U) ", +" z~B>B>R>R>R>S>S>S>W>W>W>W>W>A~ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @`+B~C~D~E~F~l,|,|,|,|,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@'@'@'F,G~P'+~H~I~Q'J~K~Z!e,{!L~M~N~O~L$P~-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-':~Q~R~S~T~U~V~U)U)U)U)U)U)U)U)U)U)U)U) ", +" G-R>S>S>S>S>W>W>W>W>W>W>W>W>4>W~ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @4'X~Y~Z~`~K)/,|,|,|,|,|,|,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,Y,Y,Y,@'@'@'@'@' {.{+{@{7!2'@!#{${a!x)%{()&{U>*{={-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-{;{>{,{'{J@){U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" !{^!W>W>W>W>W>W>W>W>W>W>W>W>W>'>~{ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @D#{{]{9)^{/{%,/,/,/,|,|,|,|,|,|,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,Y,Y,Y,@'@'n,({<'*)C!B!|)_{:{z!<{[{])}{p),%|{P~-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'1{-!2{3{4{5{6{U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" U,W>W>W>W>W>W>W>W>W>W>W>W>%,%,{,7{o$ @ @ @ @ @ @ @/@8{9{0{a{l);,/,/,/,/,/,/,|,|,|,|,|,|,|,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,P,P,P,P,P,P,P,Y,Y,4>b{$'r!:{p!|)B!n!m!P>c{d{$~e{^)f{-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'g{h{i{j{k{l{m{U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" n{o{W>W>W>W>W>W>W>W>%,%,%,;,;,;,',W>p{q{r{s{a{t{()W>/,/,/,/,/,/,/,/,/,|,|,|,|,|,|,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,F,P,P,P,P,P,K)o{$,u{A)#{@!2'7!6!V>s>v{w{x{5%y{-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'1{z{A{B{E)C{D{U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" E{W>W>W>W>%,%,%,;,;,;,',',',',',',',',',',/,/,/,/,/,/,/,/,/,|,|,|,|,|,|,|,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,P,P,P,v{F{l>:'K~O)Q'{)c)1)m,G{_'}'H{D$&~-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'I{J{K{L{M{N{O{U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" m!e,%,%,;,;,;,;,',',',',',',',',',/,/,/,/,/,/,/,/,/,/,|,|,|,|,|,|,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,F,F,F,F,F,F,F,F,F,%,`'%!$!w'#!y)o~.!P{]~j,Q{R{S{:#3)-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'T{U{V{W{X{Y{Z{U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" `!`{;,',',',',',',',',',/,/,/,/,/,/,/,/,/,/,|,|,|,|,|,|,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,n,n,n,n,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,F,F,F,F,F,F,n,G~{!1) ],']!]!.]7~B)+]@]/{#]S)$]c~-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-':~],]y)!~{'U,E'']u>)]!]~]['-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'{]u~]]^]x~}~/]U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" (]+!5~',/,/,/,/,/,/,/,/,/,/,|,|,|,|,|,|,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,t,E,E,E,E,E,E,n,l!m,Q,.~_]:]=)`!Z!e,<><]M~[]],}]P~-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'F!|]T)1]2]3]4]U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" 5]+!({/,/,/,/,/,/,|,|,|,|,|,|,8,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,n,n,n,n,t,t,t,t,t,t,t,t,t,E,E,E,E,4>6]<{Z,7]f'|)8]O!a!>>~,d{E!9]0]a]-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'g{b]c]d]e]f]){U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" S=O)M>/,|,|,|,|,|,|,|,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,t,E,|,g,g]a!h]8]|)_{A!i]j]6~=>g'k]D)l]P~-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'1{-!m]n]o]p]q]U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" r]=)6!l,|,|,8,8,8,9,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,n,n,n,t,t,t,t,t,t,t,t,s,F{e,Z!`!=)-=o!n!*)Z'o>V,t{s](+t]-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'u]f)v]w]x]y]m{U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" z]h]A]B]8,9,9,9,9,9,9,9,9,9,9,9,9,k,k,k,k,k,k,k,n,n,n,t,t,t,t,%,`'>>U,{'!~y)2'7!C]V>5]D]E]x{F]H+-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'1{G]H]B{E)I]J]U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" K]L]!~n'E'/,9,9,9,9,9,9,9,k,k,k,k,k,k,n,n,n,t,t,d){!Y>M]~)N]]!I~H~1)x>@~y,O]P]Q]q)-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'I{R]f~S]T]U]O{U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" U)V]W]=;X]^=Y]Z]G'k,k,k,k,k,k,n,n,4!~,r,{~~~z)y)+!~~{~`]^~'> ^.^I#3)-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'+^@^#^W{$^%^y~U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" N{t~-'H+&^=,A!+=O)o!*^n!n!7]=^]!N].]M]Y>6,!>v,a~-^`,:!-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-':~;^R~>^,^'^)^U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" U)!^:~-'-'P~^+~^{^h,5]x>x>]^v,^^/^(^|{_^-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-':^<^[^^]}^|^/]U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" U)1^-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'F!|]2^G!3^4^6{U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" U)5^-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-{6^7^8^9^0^){U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" U)U)a^:~-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'1{b^A{n]c^d^e^U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" U)U)f^-{-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'g^f)h^w]M{i^O{U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" U)U)V~j^-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'1{<~k^l^m^I]r)U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" U)U)n^o^-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-';^e~f~p^T]q^U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" U)U)U)r^k^T{-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'t~u~v~w~x~}~y~U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" U)U)U)U)/]K%1]s^t^:~-'-'-'T{u^v^S~w^U~V~U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" U)U)U)U)U)U)U)O{x^x^Z{U)U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" U)U)U)U)U)U)U)U)U)U)U)U)U)U)U)U) ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/Plugins/org.mitk.gui.qt.cli/resources/pause.png b/Plugins/org.mitk.gui.qt.cli/resources/pause.png new file mode 100644 index 0000000000..a63d34e17e Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/resources/pause.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/resources/run.png b/Plugins/org.mitk.gui.qt.cli/resources/run.png new file mode 100644 index 0000000000..9bb19bfe36 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/resources/run.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/resources/stop.png b/Plugins/org.mitk.gui.qt.cli/resources/stop.png new file mode 100644 index 0000000000..5a9f49c1c6 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/resources/stop.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/resources/undo.png b/Plugins/org.mitk.gui.qt.cli/resources/undo.png new file mode 100644 index 0000000000..39986044ab Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/resources/undo.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/src/QmitkCmdLineModuleMenuComboBox.cpp b/Plugins/org.mitk.gui.qt.cli/src/QmitkCmdLineModuleMenuComboBox.cpp new file mode 100644 index 0000000000..f1dd6be7ed --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/QmitkCmdLineModuleMenuComboBox.cpp @@ -0,0 +1,190 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "QmitkCmdLineModuleMenuComboBox.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// ------------------------------------------------------------------------- +QmitkCmdLineModuleMenuComboBox::QmitkCmdLineModuleMenuComboBox(QWidget* parent) +: ctkMenuComboBox(parent) +, m_ModuleManager(NULL) +{ + qRegisterMetaType(); +} + + +// ------------------------------------------------------------------------- +QmitkCmdLineModuleMenuComboBox::~QmitkCmdLineModuleMenuComboBox() +{ + +} + + +// ------------------------------------------------------------------------- +void QmitkCmdLineModuleMenuComboBox::SetManager(ctkCmdLineModuleManager* manager) +{ + if (m_ModuleManager != NULL) + { + QObject::disconnect(manager, 0, this, 0); + } + + m_ModuleManager = manager; + + connect(m_ModuleManager, SIGNAL(moduleRegistered(const ctkCmdLineModuleReference&)), this, SLOT(OnModuleRegistered(const ctkCmdLineModuleReference&))); + connect(m_ModuleManager, SIGNAL(moduleUnregistered(const ctkCmdLineModuleReference&)), this, SLOT(OnModuleUnRegistered(const ctkCmdLineModuleReference&))); +} + + +// ------------------------------------------------------------------------- +ctkCmdLineModuleManager* QmitkCmdLineModuleMenuComboBox::GetManager() const +{ + return m_ModuleManager; +} + + +// ------------------------------------------------------------------------- +void QmitkCmdLineModuleMenuComboBox::OnModuleRegistered(const ctkCmdLineModuleReference&) +{ + this->RebuildMenu(); +} + + +// ------------------------------------------------------------------------- +void QmitkCmdLineModuleMenuComboBox::OnModuleUnRegistered(const ctkCmdLineModuleReference&) +{ + this->RebuildMenu(); +} + + +// ------------------------------------------------------------------------- +void QmitkCmdLineModuleMenuComboBox::AddName( + QList< QHash* >& listOfHashMaps, + const int& depth, + const QString& name, + QMenu* menu + ) +{ + if (depth >= listOfHashMaps.size()) + { + int need = depth - listOfHashMaps.size(); + for (int i = 0; i <= need; i++) + { + QHash *newHashMap = new QHash(); + listOfHashMaps.push_back(newHashMap); + } + } + listOfHashMaps[depth]->insert(name, menu); +} + + +// ------------------------------------------------------------------------- +void QmitkCmdLineModuleMenuComboBox::RebuildMenu() +{ + if (m_ModuleManager == NULL) + { + qDebug() << "QmitkCmdLineModuleMenuComboBox::RebuildMenu(): Module Manager is NULL? Surely a bug?"; + return; + } + + // Can't see another way to get a nested menu, without rebuilding the whole thing each time. + // :-( + + QMenu *menu = new QMenu(); + QStringList listOfModules; + + QList references = m_ModuleManager->moduleReferences(); + + // Get full names + for (int i = 0; i < references.size(); i++) + { + ctkCmdLineModuleReference reference = references[i]; + ctkCmdLineModuleDescription description = reference.description(); + QString title = description.title(); + QString category = description.category(); + QString fullName = category + "." + title; + listOfModules << fullName; + } + + // Sort list, so menu comes out in some sort of nice order. + listOfModules.sort(); + + // Temporary data structure to enable connecting menus together. + QList< QHash* > list; + + // Iterate through all modules. + foreach (QString fullName, listOfModules) + { + // Pointer to keep track of where we are in the menu tree. + QMenu *currentMenu = menu; + + // Get individual parts, as they correspond to menu levels. + QStringList nameParts = fullName.split(".", QString::SkipEmptyParts); + + // Iterate over each part, building up either a QMenu or QAction. + for (int i = 0; i < nameParts.size(); i++) + { + QString part = nameParts[i]; + + if (i != nameParts.size() - 1) + { + // Need to add a menu/submenu, not an action. + if (list.size() <= i || list[i] == NULL || !list[i]->contains(part)) + { + QMenu *newMenu = new QMenu(part); + currentMenu->addMenu(newMenu); + currentMenu = newMenu; + + // Add this newMenu pointer to temporary datastructure, + // so we know we have already created it. + this->AddName(list, i, part, newMenu); + } + else + { + currentMenu = list[i]->value(part); + } + } + else + { + // Leaf node, just add the action. + QAction *action = currentMenu->addAction(part); + + // We set the object name, so we can retrieve it later when we want to + // rebuild a new GUI depending on the name of the action. + // see QmitkCmdLineModuleProgressWidget. + action->setObjectName(fullName); + } + } + } + + // Clearup termporary data structure + for (int i = 0; i < list.size(); i++) + { + delete list[i]; + } + + // Set the constructed menu on the base class combo box. + this->setMenu(menu); +} + diff --git a/Plugins/org.mitk.gui.qt.cli/src/QmitkCmdLineModuleMenuComboBox.h b/Plugins/org.mitk.gui.qt.cli/src/QmitkCmdLineModuleMenuComboBox.h new file mode 100644 index 0000000000..8cd6546950 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/QmitkCmdLineModuleMenuComboBox.h @@ -0,0 +1,67 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QMITKCMDLINEMODULEMENUCOMBOBOX_H +#define QMITKCMDLINEMODULEMENUCOMBOBOX_H + +#include +#include +#include +#include +#include + +/** + * \class QmitkCmdLineModuleMenuComboBox + * \brief Subclass of ctkMenuComboBox to listen to ctkCmdLineModuleManager + * moduleRegistered and moduleUnregistered signals, and update the menu accordingly. + * \ingroup org_mitk_gui_qt_cli_internal + * \sa ctkMenuComboBox + */ +class QmitkCmdLineModuleMenuComboBox : public ctkMenuComboBox { + + Q_OBJECT + +public: + + QmitkCmdLineModuleMenuComboBox(QWidget* parent = 0); + virtual ~QmitkCmdLineModuleMenuComboBox(); + + /** + * \brief Inject the module manager, so that this widget can + * still easily be used via widget promotion in Qt Designer, + * as it will maintain the default constructor. + */ + void SetManager(ctkCmdLineModuleManager* manager); + + /** + * \brief Returns the ctkCmdLineModuleManager. + */ + ctkCmdLineModuleManager* GetManager() const; + +private slots: + + void OnModuleRegistered(const ctkCmdLineModuleReference&); + void OnModuleUnRegistered(const ctkCmdLineModuleReference&); + +private: + + void RebuildMenu(); + void AddName(QList< QHash* >& listOfHashMaps, const int& depth, const QString& name, QMenu* menu); + + ctkCmdLineModuleManager* m_ModuleManager; +}; + +#endif QMITKCMDLINEMODULEMENUCOMBOBOX_H + diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesPreferencesPage.cpp b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesPreferencesPage.cpp new file mode 100644 index 0000000000..fc0bb89003 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesPreferencesPage.cpp @@ -0,0 +1,194 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "CommandLineModulesPreferencesPage.h" +#include "CommandLineModulesViewConstants.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "QmitkDirectoryListWidget.h" +#include "QmitkFileListWidget.h" + +//----------------------------------------------------------------------------- +CommandLineModulesPreferencesPage::CommandLineModulesPreferencesPage() +: m_MainControl(0) +, m_TemporaryDirectory(0) +, m_ModulesDirectories(0) +, m_ModulesFiles(0) +, m_LoadFromHomeDir(0) +, m_LoadFromCurrentDir(0) +, m_LoadFromApplicationDir(0) +, m_LoadFromAutoLoadPathDir(0) +, m_ValidationMode(0) +, m_MaximumNumberProcesses(0) +, m_CLIPreferencesNode(0) +{ + +} + + +//----------------------------------------------------------------------------- +CommandLineModulesPreferencesPage::~CommandLineModulesPreferencesPage() +{ + +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesPreferencesPage::Init(berry::IWorkbench::Pointer ) +{ + +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesPreferencesPage::CreateQtControl(QWidget* parent) +{ + berry::IPreferencesService::Pointer prefService + = berry::Platform::GetServiceRegistry() + .GetServiceById(berry::IPreferencesService::ID); + + std::string id = "/" + CommandLineModulesViewConstants::VIEW_ID; + m_CLIPreferencesNode = prefService->GetSystemPreferences()->Node(id); + + m_MainControl = new QWidget(parent); + + m_TemporaryDirectory = new ctkDirectoryButton(m_MainControl); + m_TemporaryDirectory->setCaption("Select a directory for temporary files ... "); + m_ModulesDirectories = new QmitkDirectoryListWidget(m_MainControl); + m_ModulesDirectories->m_Label->setText("Select directories to scan:"); + m_ModulesFiles = new QmitkFileListWidget(m_MainControl); + m_ModulesFiles->m_Label->setText("Select additional executables:"); + m_DebugOutput = new QCheckBox(m_MainControl); + + m_LoadFromApplicationDir = new QCheckBox(m_MainControl); + m_LoadFromAutoLoadPathDir = new QCheckBox(m_MainControl); + m_LoadFromHomeDir = new QCheckBox(m_MainControl); + m_LoadFromCurrentDir = new QCheckBox(m_MainControl); + m_ValidationMode = new QComboBox(m_MainControl); + m_ValidationMode->addItem("strict", ctkCmdLineModuleManager::STRICT_VALIDATION); + m_ValidationMode->addItem("none", ctkCmdLineModuleManager::SKIP_VALIDATION); + m_ValidationMode->addItem("weak", ctkCmdLineModuleManager::WEAK_VALIDATION); + m_ValidationMode->setCurrentIndex(0); + m_MaximumNumberProcesses = new QSpinBox(m_MainControl); + m_MaximumNumberProcesses->setMinimum(1); + m_MaximumNumberProcesses->setMaximum(1000000); + + QFormLayout *formLayout = new QFormLayout; + formLayout->addRow("show debug output:", m_DebugOutput); + formLayout->addRow("XML validation mode:", m_ValidationMode); + formLayout->addRow("max. concurrent processes:", m_MaximumNumberProcesses); + formLayout->addRow("scan home directory:", m_LoadFromHomeDir); + formLayout->addRow("scan current directory:", m_LoadFromCurrentDir); + formLayout->addRow("scan installation directory:", m_LoadFromApplicationDir); + formLayout->addRow("scan CTK_MODULE_LOAD_PATH:", m_LoadFromAutoLoadPathDir); + formLayout->addRow("additional module directories:", m_ModulesDirectories); + formLayout->addRow("additional modules:", m_ModulesFiles); + formLayout->addRow("temporary directory:", m_TemporaryDirectory); + + m_MainControl->setLayout(formLayout); + + this->Update(); +} + + +//----------------------------------------------------------------------------- +QWidget* CommandLineModulesPreferencesPage::GetQtControl() const +{ + return m_MainControl; +} + + +//----------------------------------------------------------------------------- +std::string CommandLineModulesPreferencesPage::ConvertToStdString(const QStringList& list) +{ + std::string output; + for (int i = 0; i < list.count(); i++) + { + QString path = list[i] + ";"; + output += path.toStdString(); + } + return output; +} + +//----------------------------------------------------------------------------- +bool CommandLineModulesPreferencesPage::PerformOk() +{ + m_CLIPreferencesNode->Put(CommandLineModulesViewConstants::TEMPORARY_DIRECTORY_NODE_NAME, m_TemporaryDirectory->directory().toStdString()); + m_CLIPreferencesNode->PutBool(CommandLineModulesViewConstants::DEBUG_OUTPUT_NODE_NAME, m_DebugOutput->isChecked()); + m_CLIPreferencesNode->PutBool(CommandLineModulesViewConstants::LOAD_FROM_APPLICATION_DIR, m_LoadFromApplicationDir->isChecked()); + m_CLIPreferencesNode->PutBool(CommandLineModulesViewConstants::LOAD_FROM_HOME_DIR, m_LoadFromHomeDir->isChecked()); + m_CLIPreferencesNode->PutBool(CommandLineModulesViewConstants::LOAD_FROM_CURRENT_DIR, m_LoadFromCurrentDir->isChecked()); + m_CLIPreferencesNode->PutBool(CommandLineModulesViewConstants::LOAD_FROM_AUTO_LOAD_DIR, m_LoadFromAutoLoadPathDir->isChecked()); + + std::string paths = this->ConvertToStdString(m_ModulesDirectories->directories()); + m_CLIPreferencesNode->Put(CommandLineModulesViewConstants::MODULE_DIRECTORIES_NODE_NAME, paths); + + std::string modules = this->ConvertToStdString(m_ModulesFiles->files()); + m_CLIPreferencesNode->Put(CommandLineModulesViewConstants::MODULE_FILES_NODE_NAME, modules); + + int currentValidationMode = m_CLIPreferencesNode->GetInt(CommandLineModulesViewConstants::XML_VALIDATION_MODE, 0); + if (currentValidationMode != m_ValidationMode->currentIndex()) + { + QMessageBox msgBox; + msgBox.setText("Changing the XML validation mode will require a restart of the application."); + msgBox.exec(); + } + + m_CLIPreferencesNode->PutInt(CommandLineModulesViewConstants::XML_VALIDATION_MODE, m_ValidationMode->currentIndex()); + m_CLIPreferencesNode->PutInt(CommandLineModulesViewConstants::MAX_CONCURRENT, m_MaximumNumberProcesses->value()); + return true; +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesPreferencesPage::PerformCancel() +{ +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesPreferencesPage::Update() +{ + QString fallbackTmpDir = QDir::tempPath(); + m_TemporaryDirectory->setDirectory(QString::fromStdString(m_CLIPreferencesNode->Get(CommandLineModulesViewConstants::TEMPORARY_DIRECTORY_NODE_NAME, fallbackTmpDir.toStdString()))); + + m_DebugOutput->setChecked(m_CLIPreferencesNode->GetBool(CommandLineModulesViewConstants::DEBUG_OUTPUT_NODE_NAME, false)); + m_LoadFromApplicationDir->setChecked(m_CLIPreferencesNode->GetBool(CommandLineModulesViewConstants::LOAD_FROM_APPLICATION_DIR, false)); + m_LoadFromHomeDir->setChecked(m_CLIPreferencesNode->GetBool(CommandLineModulesViewConstants::LOAD_FROM_HOME_DIR, false)); + m_LoadFromCurrentDir->setChecked(m_CLIPreferencesNode->GetBool(CommandLineModulesViewConstants::LOAD_FROM_CURRENT_DIR, false)); + m_LoadFromAutoLoadPathDir->setChecked(m_CLIPreferencesNode->GetBool(CommandLineModulesViewConstants::LOAD_FROM_AUTO_LOAD_DIR, false)); + + QString paths = QString::fromStdString(m_CLIPreferencesNode->Get(CommandLineModulesViewConstants::MODULE_DIRECTORIES_NODE_NAME, "")); + QStringList directoryList = paths.split(";", QString::SkipEmptyParts); + m_ModulesDirectories->setDirectories(directoryList); + + QString files = QString::fromStdString(m_CLIPreferencesNode->Get(CommandLineModulesViewConstants::MODULE_FILES_NODE_NAME, "")); + QStringList fileList = files.split(";", QString::SkipEmptyParts); + m_ModulesFiles->setFiles(fileList); + + m_ValidationMode->setCurrentIndex(m_CLIPreferencesNode->GetInt(CommandLineModulesViewConstants::XML_VALIDATION_MODE, 0)); + m_MaximumNumberProcesses->setValue(m_CLIPreferencesNode->GetInt(CommandLineModulesViewConstants::MAX_CONCURRENT, 4)); +} diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesPreferencesPage.h b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesPreferencesPage.h new file mode 100644 index 0000000000..8f930f77e0 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesPreferencesPage.h @@ -0,0 +1,102 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef COMMANDLINEMODULESPREFERENCESPAGE_H +#define COMMANDLINEMODULESPREFERENCESPAGE_H + +#include "berryIQtPreferencePage.h" +#include "berryIPreferences.h" +#include + +class QWidget; +class QCheckBox; +class QComboBox; +class QSpinBox; +class QmitkDirectoryListWidget; +class QmitkFileListWidget; +class ctkDirectoryButton; + +/** + * \class CommandLineModulesPreferencesPage + * \brief Preference page for CommandLineModulesView + * \author Matt Clarkson (m.clarkson@ucl.ac.uk) + * \ingroup org_mitk_gui_qt_cli_internal + */ +class CommandLineModulesPreferencesPage : public QObject, public berry::IQtPreferencePage +{ + Q_OBJECT + Q_INTERFACES(berry::IPreferencePage) + +public: + CommandLineModulesPreferencesPage(); + ~CommandLineModulesPreferencesPage(); + + /** + * \brief Called by framework to initialise this preference page, but currently does nothing. + * \param workbench The workbench. + */ + void Init(berry::IWorkbench::Pointer workbench); + + /** + * \brief Called by framework to create the GUI, and connect signals and slots. + * \param widget The Qt widget that acts as parent to all GUI components, as this class itself is not derived from QWidget. + */ + void CreateQtControl(QWidget* widget); + + /** + * \brief Required by framework to get hold of the GUI. + * \return QWidget* the top most QWidget for the GUI. + */ + QWidget* GetQtControl() const; + + /** + * \see IPreferencePage::PerformOk + */ + virtual bool PerformOk(); + + /** + * \see IPreferencePage::PerformCancel + */ + virtual void PerformCancel(); + + /** + * \see IPreferencePage::Update + */ + virtual void Update(); + +public slots: + +protected: + + QWidget *m_MainControl; + QCheckBox *m_DebugOutput; + ctkDirectoryButton *m_TemporaryDirectory; + QmitkDirectoryListWidget *m_ModulesDirectories; + QmitkFileListWidget *m_ModulesFiles; + QCheckBox *m_LoadFromHomeDir; + QCheckBox *m_LoadFromCurrentDir; + QCheckBox *m_LoadFromApplicationDir; + QCheckBox *m_LoadFromAutoLoadPathDir; + QComboBox *m_ValidationMode; + QSpinBox *m_MaximumNumberProcesses; + + berry::IPreferences::Pointer m_CLIPreferencesNode; + +private: + + std::string ConvertToStdString(const QStringList& list); +}; + +#endif // COMMANDLINEMODULESPREFERENCESPAGE_H diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesView.cpp b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesView.cpp new file mode 100644 index 0000000000..31e8c70630 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesView.cpp @@ -0,0 +1,432 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +// Blueberry +#include +#include +#include + +// Qmitk +#include "CommandLineModulesView.h" +#include "CommandLineModulesViewConstants.h" +#include "CommandLineModulesViewControls.h" +#include "CommandLineModulesPreferencesPage.h" +#include "QmitkCmdLineModuleFactoryGui.h" +#include "QmitkCmdLineModuleGui.h" +#include "QmitkCmdLineModuleProgressWidget.h" + +// Qt +#include +#include +#include +#include +#include +#include +#include + +// CTK +#include +#include +#include +#include +#include +#include +#include + +//----------------------------------------------------------------------------- +CommandLineModulesView::CommandLineModulesView() +: m_Controls(NULL) +, m_Parent(NULL) +, m_Layout(NULL) +, m_ModuleManager(NULL) +, m_ModuleBackend(NULL) +, m_DirectoryWatcher(NULL) +, m_TemporaryDirectoryName("") +, m_MaximumConcurrentProcesses(4) +, m_CurrentlyRunningProcesses(0) +, m_DebugOutput(false) +{ +} + + +//----------------------------------------------------------------------------- +CommandLineModulesView::~CommandLineModulesView() +{ + if (m_ModuleManager != NULL) + { + delete m_ModuleManager; + } + + if (m_ModuleBackend != NULL) + { + delete m_ModuleBackend; + } + + if (m_DirectoryWatcher != NULL) + { + delete m_DirectoryWatcher; + } + + if (m_Layout != NULL) + { + delete m_Layout; + } + + for (int i = 0; i < m_ListOfModules.size(); i++) + { + delete m_ListOfModules[i]; + } +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesView::SetFocus() +{ + this->m_Controls->m_ComboBox->setFocus(); +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesView::CreateQtPartControl( QWidget *parent ) +{ + m_Parent = parent; + + if (!m_Controls) + { + // We create CommandLineModulesViewControls, which derives from the Qt generated class. + m_Controls = new CommandLineModulesViewControls(parent); + + // Create a layout to contain a display of QmitkCmdLineModuleProgressWidget. + m_Layout = new QVBoxLayout(m_Controls->m_RunningWidgets); + m_Layout->setContentsMargins(0,0,0,0); + m_Layout->setSpacing(0); + + // This must be done independent of other preferences, as we need it before + // we create the ctkCmdLineModuleManager to initialise the Cache. + this->RetrieveAndStoreTemporaryDirectoryPreferenceValues(); + this->RetrieveAndStoreValidationMode(); + + // Start to create the command line module infrastructure. + m_ModuleBackend = new ctkCmdLineModuleBackendLocalProcess(); + m_ModuleManager = new ctkCmdLineModuleManager(m_ValidationMode, m_TemporaryDirectoryName); + + // Set the main object, the ctkCmdLineModuleManager onto all the objects that need it. + m_Controls->m_ComboBox->SetManager(m_ModuleManager); + m_DirectoryWatcher = new ctkCmdLineModuleDirectoryWatcher(m_ModuleManager); + m_ModuleManager->registerBackend(m_ModuleBackend); + + // Setup the remaining preferences. + this->RetrieveAndStorePreferenceValues(); + + // Connect signals to slots after we have set up GUI. + connect(this->m_Controls->m_RunButton, SIGNAL(pressed()), this, SLOT(OnRunButtonPressed())); + connect(this->m_Controls->m_RestoreDefaults, SIGNAL(pressed()), this, SLOT(OnRestoreButtonPressed())); + connect(this->m_Controls->m_ComboBox, SIGNAL(actionChanged(QAction*)), this, SLOT(OnActionChanged(QAction*))); + connect(this->m_Controls->m_TabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(OnTabCloseRequested(int))); + + this->UpdateRunButtonEnabledStatus(); + } +} + + +//----------------------------------------------------------------------------- +berry::IBerryPreferences::Pointer CommandLineModulesView::RetrievePreferences() +{ + berry::IPreferencesService::Pointer prefService + = berry::Platform::GetServiceRegistry() + .GetServiceById(berry::IPreferencesService::ID); + + assert( prefService ); + + std::string id = "/" + CommandLineModulesViewConstants::VIEW_ID; + berry::IBerryPreferences::Pointer prefs + = (prefService->GetSystemPreferences()->Node(id)) + .Cast(); + + assert( prefs ); + + return prefs; +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesView::RetrieveAndStoreTemporaryDirectoryPreferenceValues() +{ + berry::IBerryPreferences::Pointer prefs = this->RetrievePreferences(); + + QString fallbackTmpDir = QDir::tempPath(); + m_TemporaryDirectoryName = QString::fromStdString( + prefs->Get(CommandLineModulesViewConstants::TEMPORARY_DIRECTORY_NODE_NAME, fallbackTmpDir.toStdString())); +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesView::RetrieveAndStoreValidationMode() +{ + berry::IBerryPreferences::Pointer prefs = this->RetrievePreferences(); + + int value = prefs->GetInt(CommandLineModulesViewConstants::XML_VALIDATION_MODE, 0); + if (value == 0) + { + m_ValidationMode = ctkCmdLineModuleManager::STRICT_VALIDATION; + } + else if (value == 1) + { + m_ValidationMode = ctkCmdLineModuleManager::SKIP_VALIDATION; + } + else + { + m_ValidationMode = ctkCmdLineModuleManager::WEAK_VALIDATION; + } +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesView::RetrieveAndStorePreferenceValues() +{ + berry::IBerryPreferences::Pointer prefs = this->RetrievePreferences(); + + m_MaximumConcurrentProcesses = prefs->GetInt(CommandLineModulesViewConstants::MAX_CONCURRENT, 4); + + // Get the flag for debug output, useful when parsing all the XML. + m_DebugOutput = prefs->GetBool(CommandLineModulesViewConstants::DEBUG_OUTPUT_NODE_NAME, false); + m_DirectoryWatcher->setDebug(m_DebugOutput); + + bool loadApplicationDir = prefs->GetBool(CommandLineModulesViewConstants::LOAD_FROM_APPLICATION_DIR, false); + bool loadHomeDir = prefs->GetBool(CommandLineModulesViewConstants::LOAD_FROM_HOME_DIR, false); + bool loadCurrentDir = prefs->GetBool(CommandLineModulesViewConstants::LOAD_FROM_CURRENT_DIR, false); + bool loadAutoLoadDir = prefs->GetBool(CommandLineModulesViewConstants::LOAD_FROM_AUTO_LOAD_DIR, false); + + // Get some default application paths. + + // Here we can use the preferences to set up the builder, + ctkCmdLineModuleDefaultPathBuilder builder; + builder.setLoadFromApplicationDir(loadApplicationDir); + builder.setLoadFromHomeDir(loadHomeDir); + builder.setLoadFromCurrentDir(loadCurrentDir); + builder.setLoadFromCtkModuleLoadPath(loadAutoLoadDir); + + // and then we ask the builder to set up the paths. + QStringList defaultPaths = builder.build(); + + // We get additional directory paths from preferences. + QString pathString = QString::fromStdString(prefs->Get(CommandLineModulesViewConstants::MODULE_DIRECTORIES_NODE_NAME, "")); + QStringList additionalPaths = pathString.split(";", QString::SkipEmptyParts); + + // Combine the sets of directory paths. + QStringList totalPaths; + totalPaths << defaultPaths; + totalPaths << additionalPaths; + + QString additionalModulesString = QString::fromStdString(prefs->Get(CommandLineModulesViewConstants::MODULE_FILES_NODE_NAME, "")); + QStringList additionalModules = additionalModulesString.split(";", QString::SkipEmptyParts); + + // OnPreferencesChanged can be called for each preference in a dialog box, so + // when you hit "OK", it is called repeatedly, whereas we want to only call these only once. + if (this->m_DirectoryWatcher->directories() != totalPaths) + { + m_DirectoryWatcher->setDirectories(totalPaths); + } + if (this->m_DirectoryWatcher->additionalModules() != additionalModules) + { + m_DirectoryWatcher->setAdditionalModules(additionalModules); + } +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesView::OnPreferencesChanged(const berry::IBerryPreferences* /*prefs*/) +{ + this->RetrieveAndStoreTemporaryDirectoryPreferenceValues(); + this->RetrieveAndStoreValidationMode(); + this->RetrieveAndStorePreferenceValues(); +} + + +//----------------------------------------------------------------------------- +ctkCmdLineModuleReference CommandLineModulesView::GetReferenceByFullName(QString fullName) +{ + ctkCmdLineModuleReference result; + + QList references = this->m_ModuleManager->moduleReferences(); + + ctkCmdLineModuleReference ref; + foreach(ref, references) + { + QString name = ref.description().categoryDotTitle(); + if (name == fullName) + { + result = ref; + } + } + + return result; +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesView::OnActionChanged(QAction* action) +{ + QString fullName = action->objectName(); + ctkCmdLineModuleReference ref = this->GetReferenceByFullName(fullName); + + // ref should never be invalid, as the menu was generated from each ctkCmdLineModuleReference. + // But just to be sure ... if invalid, don't do anything. + if (ref) + { + // Check if we already have the reference. + int tabIndex = -1; + for (int i = 0; i < m_ListOfModules.size(); i++) + { + ctkCmdLineModuleReference tabsReference = m_ListOfModules[i]->moduleReference(); + if (ref.location() == tabsReference.location()) + { + tabIndex = i; + break; + } + } + + // i.e. we found a matching tab, so just switch to it. + if (tabIndex != -1) + { + m_Controls->m_TabWidget->setCurrentIndex(tabIndex); + } + else // i.e. we did not find a matching tab + { + // In this case, we need to create a new tab, and give + // it a GUI for the user to setup the parameters with. + QmitkCmdLineModuleFactoryGui factory(this->GetDataStorage()); + ctkCmdLineModuleFrontend *frontEnd = factory.create(ref); + QmitkCmdLineModuleGui *theGui = dynamic_cast(frontEnd); + + // Add to list and tab wigdget + m_ListOfModules.push_back(frontEnd); + int tabIndex = m_Controls->m_TabWidget->addTab(theGui->getGui(), ref.description().title()); + m_Controls->m_TabWidget->setTabToolTip(tabIndex, ref.description().title() + ":" + ref.xmlValidationErrorString()); + } + } +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesView::OnTabCloseRequested(int tabNumber) +{ + + ctkCmdLineModuleFrontend *frontEnd = m_ListOfModules[tabNumber]; + + m_Controls->m_TabWidget->removeTab(tabNumber); + m_ListOfModules.removeAt(tabNumber); + + delete frontEnd; +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesView::AskUserToSelectAModule() const +{ + QMessageBox msgBox; + msgBox.setText("Please select a module!"); + msgBox.setIcon(QMessageBox::Warning); + msgBox.exec(); +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesView::OnRestoreButtonPressed() +{ + int tabNumber = m_Controls->m_TabWidget->currentIndex(); + if (tabNumber >= 0) + { + ctkCmdLineModuleFrontend *frontEnd = m_ListOfModules[tabNumber]; + frontEnd->resetValues(); + } + else + { + this->AskUserToSelectAModule(); + } +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesView::OnRunButtonPressed() +{ + int tabNumber = m_Controls->m_TabWidget->currentIndex(); + if (tabNumber >= 0) + { + // 1. Create a new QmitkCmdLineModuleProgressWidget to represent the running widget. + QmitkCmdLineModuleProgressWidget *widget = new QmitkCmdLineModuleProgressWidget(m_Controls->m_RunningWidgets); + widget->SetDataStorage(this->GetDataStorage()); + widget->SetManager(m_ModuleManager); + widget->SetTemporaryDirectory(m_TemporaryDirectoryName); + + // 2. Create a new front end. + QmitkCmdLineModuleFactoryGui factory(this->GetDataStorage()); + + ctkCmdLineModuleFrontend *frontEndOnCurrentTab = m_ListOfModules[tabNumber]; + QmitkCmdLineModuleGui *frontEndGuiOnCurrentTab = dynamic_cast(frontEndOnCurrentTab); + ctkCmdLineModuleReference currentTabFrontendReferences = frontEndGuiOnCurrentTab->moduleReference(); + + ctkCmdLineModuleFrontend *newFrontEnd = factory.create(currentTabFrontendReferences); + QmitkCmdLineModuleGui *newFrontEndGui = dynamic_cast(newFrontEnd); + widget->SetFrontend(newFrontEndGui); + m_Layout->insertWidget(0, widget); + + // 3. Copy parameters. This MUST come after widget->SetFrontEnd + newFrontEndGui->copyParameters(*frontEndGuiOnCurrentTab); + newFrontEndGui->setParameterContainerEnabled(false); + + // 4. Connect widget signals to here, to count how many jobs running. + connect(widget, SIGNAL(started()), this, SLOT(OnJobStarted())); + connect(widget, SIGNAL(finished()), this, SLOT(OnJobFinished())); + + // 5. GO. + widget->Run(); + } + else + { + this->AskUserToSelectAModule(); + } +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesView::UpdateRunButtonEnabledStatus() +{ + if (m_CurrentlyRunningProcesses >= m_MaximumConcurrentProcesses) + { + m_Controls->m_RunButton->setEnabled(false); + } + else + { + m_Controls->m_RunButton->setEnabled(true); + } +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesView::OnJobStarted() +{ + m_CurrentlyRunningProcesses++; + this->UpdateRunButtonEnabledStatus(); +} + + +//----------------------------------------------------------------------------- +void CommandLineModulesView::OnJobFinished() +{ + m_CurrentlyRunningProcesses--; + this->UpdateRunButtonEnabledStatus(); +} diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesView.h b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesView.h new file mode 100644 index 0000000000..bc97082e6a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesView.h @@ -0,0 +1,220 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef CommandLineModulesView_h +#define CommandLineModulesView_h + +#include +#include +#include +#include +#include +#include +#include + +class ctkCmdLineModuleBackendLocalProcess; +class ctkCmdLineModuleDirectoryWatcher; +class CommandLineModulesViewControls; +class QmitkCmdLineModuleProgressWidget; +class QAction; +class QVBoxLayout; + +namespace berry +{ + class IBerryPreferences; +} + +/*! + * \class CommandLineModulesView + * \brief Provides basic GUI interface to the CTK command line modules. + * \author Matt Clarkson (m.clarkson@ucl.ac.uk) + * \ingroup org_mitk_gui_qt_cli_internal + * \sa QmitkAbstractView + */ +class CommandLineModulesView : public QmitkAbstractView +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + +public: + + CommandLineModulesView(); + virtual ~CommandLineModulesView(); + + /** + * \brief Main method, called by framework to create the GUI at the right time. + * \param parent The parent QWidget, as this class itself is not a QWidget subclass. + */ + virtual void CreateQtPartControl(QWidget *parent); + + /** + * \brief Called by the framework to indicate that the preferences have changed. + * \param prefs not used, as we call RetrievePreferenceValues(). + */ + void OnPreferencesChanged(const berry::IBerryPreferences* prefs); + +protected Q_SLOTS: + + /** + * \brief Called when the ctkMenuComboBox has the menu selection changed, + * and causes the corresponding GUI to be displayed. + */ + void OnActionChanged(QAction*); + + /** + * \brief Slot that is called when the restore defaults button is pressed, + * to reset the current GUI form to the default values, if the XML specifies defaults. + */ + void OnRestoreButtonPressed(); + + /** + * \brief Slot that is called when the Run button is pressed to run the current module. + */ + void OnRunButtonPressed(); + +protected: + + /** + * \brief Called by framework to set the focus on the right widget + * when this view has focus, so currently, thats the ctkMenuCombo box. + */ + virtual void SetFocus(); + +private slots: + + /** + * \brief Called when the user clicks to close a tab, and removes the front end from m_ListOfModules + */ + void OnTabCloseRequested(int tabNumber); + + /** + * \brief Called from QmitkCmdLineModuleProgressWidget to indicate a job has started. + */ + void OnJobStarted(); + + /** + * \brief Called from QmitkCmdLineModuleProgressWidget to indicate a job has finished. + */ + void OnJobFinished(); + +private: + + /** + * \brief Called on startup and by OnPreferencesChanged to load all + * preferences except the temporary folder into member variables. + */ + void RetrieveAndStorePreferenceValues(); + + /** + * \brief Called on startup and by OnPreferencesChanged to load the temporary folder + * preference into member variable m_TemporaryDirectoryName. + */ + void RetrieveAndStoreTemporaryDirectoryPreferenceValues(); + + /** + * \brief Called on startup and by OnPreferencesChanged to set the validation mode, but will require a restart. + */ + void RetrieveAndStoreValidationMode(); + + /** + * \brief Called to get hold of the actual preferences node. + */ + berry::IBerryPreferences::Pointer RetrievePreferences(); + + /** + * \brief Search all modules for the one matching the given identifier. + * \param fullName The "fullName" is the . from the XML. + * \return ctkCmdLineModuleReference the reference corresponding to the fullName, or an invalid reference if non found. + */ + ctkCmdLineModuleReference GetReferenceByFullName(QString fullName); + + /** + * \brief Raises a message box asking the user to select a module first. + */ + void AskUserToSelectAModule() const; + + /** + * \brief Enables or Disables the Run Button. + */ + void UpdateRunButtonEnabledStatus(); + + /** + * \brief The GUI controls contain a reset and run button, and a QWidget container, and the GUI component + * for each command line module is added to the QWidget dynamically at run time. + */ + CommandLineModulesViewControls *m_Controls; + + /** + * \brief We store the parent, passed in via CommandLineModulesView::CreateQtPartControl, + * as this class itself is not a QWidget. + */ + QWidget *m_Parent; + + /** + * \brief We keep a local layout, and arrange a display of QmitkCmdLineModuleProgressWidget, + * where each QmitkCmdLineModuleProgressWidget represents a single running job. + */ + QVBoxLayout *m_Layout; + + /** + * \brief The manager is responsible for loading and instantiating command line modules. + */ + ctkCmdLineModuleManager *m_ModuleManager; + + /** + * \brief We are using a back-end that runs locally installed command line programs. + */ + ctkCmdLineModuleBackendLocalProcess *m_ModuleBackend; + + /** + * \brief The ctkCmdLineModuleDirectoryWatcher maintains the list of directories + * we are using to load modules, to provide automatic updates. + */ + ctkCmdLineModuleDirectoryWatcher *m_DirectoryWatcher; + + /** + * \brief We store a temporary folder name, accessible via user preferences. + */ + QString m_TemporaryDirectoryName; + + /** + * \brief We store the validation mode, accessisble via user preferences. + */ + ctkCmdLineModuleManager::ValidationMode m_ValidationMode; + + /** + * \brief We store the maximum number of concurrent processes, and disable the run button accordingly. + */ + int m_MaximumConcurrentProcesses; + + /** + * \brief Counts the number of currently running processes. + */ + int m_CurrentlyRunningProcesses; + + /** + * \brief Member variable, taken from preference page. + */ + bool m_DebugOutput; + + /** + * \brief We keep a list of front ends to match the m_TabWidget. + */ + QList<ctkCmdLineModuleFrontend*> m_ListOfModules; +}; + +#endif // CommandLineModulesView_h + diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewConstants.cpp b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewConstants.cpp new file mode 100644 index 0000000000..6eb516d861 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewConstants.cpp @@ -0,0 +1,28 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "CommandLineModulesViewConstants.h" + +const std::string CommandLineModulesViewConstants::VIEW_ID = "org.mitk.gui.qt.cli"; +const std::string CommandLineModulesViewConstants::TEMPORARY_DIRECTORY_NODE_NAME = "temporary directory"; +const std::string CommandLineModulesViewConstants::MODULE_DIRECTORIES_NODE_NAME = "module directories"; +const std::string CommandLineModulesViewConstants::MODULE_FILES_NODE_NAME = "module files"; +const std::string CommandLineModulesViewConstants::DEBUG_OUTPUT_NODE_NAME = "debug output"; +const std::string CommandLineModulesViewConstants::LOAD_FROM_APPLICATION_DIR = "load from application dir"; +const std::string CommandLineModulesViewConstants::LOAD_FROM_HOME_DIR = "load from home dir"; +const std::string CommandLineModulesViewConstants::LOAD_FROM_CURRENT_DIR = "load from current dir"; +const std::string CommandLineModulesViewConstants::LOAD_FROM_AUTO_LOAD_DIR = "load from auto-load dir"; +const std::string CommandLineModulesViewConstants::XML_VALIDATION_MODE = "xml validation mode"; +const std::string CommandLineModulesViewConstants::MAX_CONCURRENT = "max concurrent processes"; diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewConstants.h b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewConstants.h new file mode 100644 index 0000000000..af1821d52f --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewConstants.h @@ -0,0 +1,91 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef CommandLineModulesViewConstants_h +#define CommandLineModulesViewConstants_h + +#include <QString> +#include <string> + +/** + * \class CommandLineModulesViewConstants + * \brief Structure to define a namespace for constants used privately within this view. + * \author Matt Clarkson (m.clarkson@ucl.ac.uk) + * \ingroup org_mitk_gui_qt_cli_internal + */ +struct CommandLineModulesViewConstants +{ + /** + * \brief The name of the preferences node containing the temporary directory. + */ + static const std::string TEMPORARY_DIRECTORY_NODE_NAME; + + /** + * \brief The name of the preferences node containing the list of directories to scan. + */ + static const std::string MODULE_DIRECTORIES_NODE_NAME; + + /** + * \brief The name of the preferences node containing the additional files to add to the module list. + */ + static const std::string MODULE_FILES_NODE_NAME; + + /** + * \brief The name of the preferences node containing whether we are producing debug output. + */ + static const std::string DEBUG_OUTPUT_NODE_NAME; + + /** + * \brief The name of the preferences node containing a boolean describing whether + * we are loading modules from the application directory. + */ + static const std::string LOAD_FROM_APPLICATION_DIR; + + /** + * \brief The name of the preferences node containing a boolean describing whether + * we are loading modules from the users home directory. + */ + static const std::string LOAD_FROM_HOME_DIR; + + /** + * \brief The name of the preferences node containing a boolean describing whether + * we are loading modules from the applications current working directory. + */ + static const std::string LOAD_FROM_CURRENT_DIR; + + /** + * \brief The name of the preferences node containing a boolean describing whether + * we are loading modules from the directory specified in CTK_MODULE_LOAD_PATH. + */ + static const std::string LOAD_FROM_AUTO_LOAD_DIR; + + /** + * \brief The name of the preferences node containing the validation mode. + */ + static const std::string XML_VALIDATION_MODE; + + /** + * \brief The name of the preferences node containing the maximum number of concurrent processes. + */ + static const std::string MAX_CONCURRENT; + + /** + * \brief The View ID = org.mitk.gui.qt.cli, and should match that in plugin.xml. + */ + static const std::string VIEW_ID; + +}; + +#endif // CommandLineModulesViewConstants_h diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewControls.cpp b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewControls.cpp new file mode 100644 index 0000000000..ab5b38717d --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewControls.cpp @@ -0,0 +1,36 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "CommandLineModulesViewControls.h" +#include <QIcon> +#include <QSize> +#include <QHBoxLayout> + +//----------------------------------------------------------------------------- +CommandLineModulesViewControls::CommandLineModulesViewControls(QWidget *parent) +{ + this->setupUi(parent); + this->m_ChooseLabel->setVisible(false); + this->m_ComboBox->setToolTip("Choose a command line module"); + this->m_RunButton->setIcon(QIcon(":/CommandLineModulesResources/run.png")); + this->m_RestoreDefaults->setIcon(QIcon(":/CommandLineModulesResources/undo.png")); +} + + +//----------------------------------------------------------------------------- +CommandLineModulesViewControls::~CommandLineModulesViewControls() +{ + +} diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewControls.h b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewControls.h new file mode 100644 index 0000000000..052fe45ff8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewControls.h @@ -0,0 +1,46 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef CommandLineModulesViewControls_h +#define CommandLineModulesViewControls_h + +#include "ui_CommandLineModulesViewControls.h" + +class QHBoxLayout; + +/** + * \class CommandLineModulesViewControls + * \brief Class derived from Ui_CommandLineModulesViewControls to provide access to GUI widgets. + * \author Matt Clarkson (m.clarkson@ucl.ac.uk) + * \ingroup org_mitk_gui_qt_cli_internal + */ +class CommandLineModulesViewControls : public QWidget, public Ui_CommandLineModulesViewControls +{ + // this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) + Q_OBJECT + +public: + + CommandLineModulesViewControls(QWidget *parent = 0); + virtual ~CommandLineModulesViewControls(); + +protected: + +private: + +}; + +#endif // CommandLineModulesViewControls_h + diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewControls.ui b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewControls.ui new file mode 100644 index 0000000000..7d34e94cfd --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesViewControls.ui @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>CommandLineModulesViewControls</class> + <widget class="QWidget" name="CommandLineModulesViewControls"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>678</width> + <height>582</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="windowTitle"> + <string>QmitkTemplate</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="m_HorizontalLayout"> + <item> + <widget class="QLabel" name="m_ChooseLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string/> + </property> + <property name="text"> + <string>choose:</string> + </property> + </widget> + </item> + <item> + <widget class="QmitkCmdLineModuleMenuComboBox" name="m_ComboBox" native="true"/> + </item> + <item> + <widget class="QPushButton" name="m_RestoreDefaults"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>restore default parameters</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="m_RunButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>run the command line module</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <spacer name="m_HorizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QTabWidget" name="m_TabWidget"> + <property name="currentIndex"> + <number>-1</number> + </property> + <property name="tabsClosable"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QWidget" name="m_RunningWidgets" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>250</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <customwidgets> + <customwidget> + <class>QmitkCmdLineModuleMenuComboBox</class> + <extends>QWidget</extends> + <header>QmitkCmdLineModuleMenuComboBox.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources> + <include location="../../resources/CommandLineModulesResources.qrc"/> + </resources> + <connections/> +</ui> diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleFactoryGui.cpp b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleFactoryGui.cpp new file mode 100644 index 0000000000..e8afea274d --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleFactoryGui.cpp @@ -0,0 +1,47 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "QmitkCmdLineModuleFactoryGui.h" +#include "QmitkCmdLineModuleGui.h" + +//----------------------------------------------------------------------------- +struct QmitkCmdLineModuleFactoryGuiPrivate +{ + QmitkCmdLineModuleFactoryGuiPrivate(const mitk::DataStorage* dataStorage) + : m_DataStorage(dataStorage) + {} + + const mitk::DataStorage* m_DataStorage; +}; + +//----------------------------------------------------------------------------- +QmitkCmdLineModuleFactoryGui::QmitkCmdLineModuleFactoryGui(const mitk::DataStorage* dataStorage) + : d(new QmitkCmdLineModuleFactoryGuiPrivate(dataStorage)) +{ +} + + +//----------------------------------------------------------------------------- +QmitkCmdLineModuleFactoryGui::~QmitkCmdLineModuleFactoryGui() +{ +} + + +//----------------------------------------------------------------------------- +ctkCmdLineModuleFrontendQtGui* QmitkCmdLineModuleFactoryGui::create(const ctkCmdLineModuleReference& moduleRef) +{ + ctkCmdLineModuleFrontendQtGui* gui = new QmitkCmdLineModuleGui(d->m_DataStorage, moduleRef); + return gui; +} diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleFactoryGui.h b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleFactoryGui.h new file mode 100644 index 0000000000..6345c8a187 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleFactoryGui.h @@ -0,0 +1,54 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QmitkCmdLineModuleFactoryGui_h +#define QmitkCmdLineModuleFactoryGui_h + +#include <ctkCmdLineModuleFrontendFactoryQtGui.h> +#include <ctkCmdLineModuleReference.h> + +namespace mitk { + class DataStorage; +} +class QmitkCmdLineModuleFactoryGuiPrivate; + +/** + * \class QmitkCmdLineModuleFactoryGui + * \brief Derived from ctkCmdLineModuleFactory to instantiate QmitkCmdLineModuleGui front ends. + * \author Matt Clarkson (m.clarkson@ucl.ac.uk) + * \ingroup org_mitk_gui_qt_cli_internal + * \sa QmitkCmdLineModuleGui + * \sa ctkCmdLineModuleFrontendFactoryQtGui + */ +class QmitkCmdLineModuleFactoryGui + : public ctkCmdLineModuleFrontendFactoryQtGui +{ +public: + + QmitkCmdLineModuleFactoryGui(const mitk::DataStorage* dataStorage); + virtual ~QmitkCmdLineModuleFactoryGui(); + + /** + * \brief Simply creates QmitkCmdLineModuleGui which is an MITK specific Qt front end. + */ + ctkCmdLineModuleFrontendQtGui* create(const ctkCmdLineModuleReference& moduleRef); + +private: + + QScopedPointer<QmitkCmdLineModuleFactoryGuiPrivate> d; + +}; + +#endif // QmitkCmdLineModuleFactoryGui_h diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleGui.cpp b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleGui.cpp new file mode 100644 index 0000000000..29d61b2fdd --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleGui.cpp @@ -0,0 +1,273 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "QmitkCmdLineModuleGui.h" +#include "QmitkUiLoader.h" +#include <QVariant> +#include <QIODevice> +#include <QFile> +#include <QScopedPointer> +#include <QWidget> +#include <QTextBrowser> +#include <QVBoxLayout> +#include <QmitkCustomVariants.h> +#include <ctkCmdLineModuleXslTransform.h> +#include <ctkCmdLineModuleParameter.h> +#include <ctkCmdLineModuleDescription.h> +#include <ctkCollapsibleGroupBox.h> +#include "mitkDataStorage.h" + +//----------------------------------------------------------------------------- +struct QmitkCmdLineModuleGuiPrivate +{ + QmitkCmdLineModuleGuiPrivate(const mitk::DataStorage* dataStorage) + : m_DataStorage(dataStorage), m_Loader(NULL), m_Transform(NULL), m_TopLevelWidget(NULL) + { + } + const mitk::DataStorage* m_DataStorage; + mutable QScopedPointer<QUiLoader> m_Loader; + mutable QScopedPointer<ctkCmdLineModuleXslTransform> m_Transform; + mutable QScopedPointer<QWidget> m_TopLevelWidget; +}; + + +//----------------------------------------------------------------------------- +QmitkCmdLineModuleGui::QmitkCmdLineModuleGui(const mitk::DataStorage* dataStorage, const ctkCmdLineModuleReference& moduleRef) + : ctkCmdLineModuleFrontendQtGui(moduleRef) +, d(new QmitkCmdLineModuleGuiPrivate(dataStorage)) +{ + qRegisterMetaType<mitk::DataNode::Pointer>(); +} + + +//----------------------------------------------------------------------------- +QmitkCmdLineModuleGui::~QmitkCmdLineModuleGui() +{ +} + + +//----------------------------------------------------------------------------- +QUiLoader* QmitkCmdLineModuleGui::uiLoader() const +{ + // Here we are creating a QUiLoader locally, so when this method + // is called, it overrides the one in the base class, so the base + // class one is never constructed, and this one is constructed as + // a replacement. + if (d->m_Loader == NULL) + { + d->m_Loader.reset(new QmitkUiLoader(d->m_DataStorage)); + } + return d->m_Loader.data(); +} + + +//----------------------------------------------------------------------------- +ctkCmdLineModuleXslTransform* QmitkCmdLineModuleGui::xslTransform() const +{ + // This is a virtual getter, overriding the one in the base class. + // However, we want to use the transform in the base class, and just append to it. + // So we call the base class one, modify it by adding some stuff, and then return + // the pointer to the one in the base class. + ctkCmdLineModuleXslTransform *transform = ctkCmdLineModuleFrontendQtGui::xslTransform(); + if (transform != NULL) + { + transform->bindVariable("imageInputWidget", QVariant(QString("QmitkDataStorageComboBoxWithSelectNone"))); + transform->bindVariable("imageInputValueProperty", "currentValue"); + } + return transform; +} + + +//----------------------------------------------------------------------------- +QVariant QmitkCmdLineModuleGui::value(const QString ¶meter, int role) const +{ + if (role == UserRole) + { + ctkCmdLineModuleParameter param = this->moduleReference().description().parameter(parameter); + if (param.channel() == "input" && param.tag() == "image") + { + return this->customValue(parameter, "SelectedNode"); + } + return QVariant(); + } + return ctkCmdLineModuleFrontendQtGui::value(parameter, role); +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleGui::setValue(const QString& parameter, const QVariant& value, int role) +{ + if (role == UserRole) + { + ctkCmdLineModuleParameter param = this->moduleReference().description().parameter(parameter); + if (param.channel() == "input" && param.tag() == "image") + { + this->setCustomValue(parameter, value, "SelectedNode"); + } + else + { + ctkCmdLineModuleFrontendQtGui::setValue(parameter, value, role); + } + } + else + { + ctkCmdLineModuleFrontendQtGui::setValue(parameter, value, role); + } +} + +//----------------------------------------------------------------------------- +QWidget* QmitkCmdLineModuleGui::getGui() +{ + if (!d->m_TopLevelWidget) + { + // Construct additional widgets to contain full GUI. + QWidget *aboutBoxContainerWidget = new QWidget(); + + ctkCollapsibleGroupBox *aboutBox = new ctkCollapsibleGroupBox(aboutBoxContainerWidget); + aboutBox->setTitle("About"); + + QTextBrowser *aboutBrowser = new QTextBrowser(aboutBox); + aboutBrowser->setReadOnly(true); + aboutBrowser->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + aboutBrowser->setOpenExternalLinks(true); + aboutBrowser->setOpenLinks(true); + + QVBoxLayout *aboutLayout = new QVBoxLayout(aboutBox); + aboutLayout->addWidget(aboutBrowser); + + QVBoxLayout *aboutBoxContainerWidgetLayout = new QVBoxLayout(aboutBoxContainerWidget); + aboutBoxContainerWidgetLayout->addWidget(aboutBox); + + QWidget *helpBoxContainerWidget = new QWidget(); + + ctkCollapsibleGroupBox *helpBox = new ctkCollapsibleGroupBox(); + helpBox->setTitle("Help"); + + QTextBrowser *helpBrowser = new QTextBrowser(helpBox); + helpBrowser->setReadOnly(true); + helpBrowser->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + helpBrowser->setOpenExternalLinks(true); + helpBrowser->setOpenLinks(true); + + QVBoxLayout *helpLayout = new QVBoxLayout(helpBox); + helpLayout->addWidget(helpBrowser); + + QVBoxLayout *helpBoxContainerWidgetLayout = new QVBoxLayout(helpBoxContainerWidget); + helpBoxContainerWidgetLayout->addWidget(helpBox); + + QObject* guiHandle = this->guiHandle(); + QWidget* generatedGuiWidgets = qobject_cast<QWidget*>(guiHandle); + + QWidget *topLevelWidget = new QWidget(); + + QGridLayout *topLevelLayout = new QGridLayout(topLevelWidget); + topLevelLayout->setContentsMargins(0,0,0,0); + topLevelLayout->setSpacing(0); + topLevelLayout->addWidget(aboutBoxContainerWidget, 0, 0); + topLevelLayout->addWidget(helpBoxContainerWidget, 1, 0); + topLevelLayout->addWidget(generatedGuiWidgets, 2, 0); + + ctkCmdLineModuleDescription description = this->moduleReference().description(); + + QString helpString = ""; + + if (!description.title().isEmpty()) + { + QString titleHtml = "<h1>" + description.title() + "</h1>"; + helpString += titleHtml; + } + + if (!description.description().isEmpty()) + { + QString descriptionHtml = "<p>" + description.description() + "</p>"; + helpString += descriptionHtml; + } + + if (!description.documentationURL().isEmpty()) + { + QString docUrlHtml = "<p>For more information please see <a href=\"" + description.documentationURL() + + "\">" + description.documentationURL() + "</a></p>"; + helpString += docUrlHtml; + } + + QString aboutString = ""; + + if (!description.title().isEmpty()) + { + QString titleHtml = "<h1>" + description.title() + "</h1>"; + aboutString += titleHtml; + } + + if (!description.contributor().isEmpty()) + { + QString contributorHtml = "<h2>Contributed By</h2><p>" + description.contributor() + "</p>"; + aboutString += contributorHtml; + } + + if (!description.license().isEmpty()) + { + QString licenseHtml = "<h2>License</h2><p>" + description.license() + "</p>"; + aboutString += licenseHtml; + } + + if (!description.acknowledgements().isEmpty()) + { + QString acknowledgementsHtml = "<h2>Acknowledgements</h2><p>" + description.acknowledgements() + "</p>"; + aboutString += acknowledgementsHtml; + } + + helpBrowser->clear(); + helpBrowser->setHtml(helpString); + helpBox->setCollapsed(true); + + aboutBrowser->clear(); + aboutBrowser->setHtml(aboutString); + aboutBox->setCollapsed(true); + + d->m_TopLevelWidget.reset(topLevelWidget); + } + + return d->m_TopLevelWidget.data(); +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleGui::copyParameters(QmitkCmdLineModuleGui& another) +{ + + // This copies "display" parameter types. + // See ctkCmdLineModuleFrontend::DisplayRole + this->setValues(another.values()); + + // For custom types, we must manually copy the values. + // In our case, we copy image types manually, to pass across the mitk::DataNode pointer. + QList<ctkCmdLineModuleParameter> parameters = another.parameters("image", ctkCmdLineModuleFrontend::Input); + foreach (ctkCmdLineModuleParameter parameter, parameters) + { + QString parameterName = parameter.name(); + + QVariant tmp = another.value(parameterName, ctkCmdLineModuleFrontend::UserRole); + mitk::DataNode::Pointer node = tmp.value<mitk::DataNode::Pointer>(); + + if (node.IsNotNull()) + { + mitk::Image* image = dynamic_cast<mitk::Image*>(node->GetData()); + if (image != NULL) + { + this->setValue(parameterName, tmp, ctkCmdLineModuleFrontend::UserRole); + } + } + } +} diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleGui.h b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleGui.h new file mode 100644 index 0000000000..eddc50ad54 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleGui.h @@ -0,0 +1,117 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QmitkCmdLineModuleGui_h +#define QmitkCmdLineModuleGui_h + +#include <QBuffer> +#include <QUiLoader> + +#include <ctkCmdLineModuleReference.h> +#include <ctkCmdLineModuleFrontendQtGui.h> + +namespace mitk +{ + class DataStorage; +} +class QmitkCmdLineModuleGuiPrivate; +class QWidget; + +/** + * \class QmitkCmdLineModuleGui + * \brief Derived from ctkCmdLineModuleQtGui to implement an MITK specific command line module, + * that has access to the mitk::DataStorage, and also instantiates QmitkDataStorageComboBox + * for any "imageInputWidget" type, and also provides QmitkDataStorageComboBox.xsl to override + * the standard CTK xslt transformation. + * \author Matt Clarkson (m.clarkson@ucl.ac.uk) + * \ingroup org_mitk_gui_qt_cli_internal + * \sa QmitkCmdLineModuleFactoryGui + * \sa ctkCmdLineModuleFrontendQtGui + */ +class QmitkCmdLineModuleGui : public ctkCmdLineModuleFrontendQtGui +{ + Q_OBJECT + +public: + QmitkCmdLineModuleGui(const mitk::DataStorage* dataStorage, const ctkCmdLineModuleReference& moduleRef); + virtual ~QmitkCmdLineModuleGui(); + + /** + * \brief Returns the top level widget containing the whole GUI, and + * should be used in preference to ctkCmdLineModuleFrontend::guiHandle. + */ + QWidget* getGui(); + + /** + * \brief Copies the visible parameters from another QmitkCmdLineModuleGui; + * \param another a QmitkCmdLineModuleGui frontend. + */ + void copyParameters(QmitkCmdLineModuleGui& another); + + /** + * \brief A custom method to enable access to a mitk::DataNode::Pointer for input images. + * \param parameter The name of the parameter as specified in XML. + * \param role The role, \see ctkCmdLineModuleFrontend. + * \return QVariant + * + * If role==UserRole and the parameter specified by parameter name is an + * input image, will return a mitk::DataNode::Pointer wrapped in a QVariant. + * + * If role==UserRole and the parameter specified is not an input image, + * returns an Empty QVariant. + * + * For any other scenario, calls base class. + * + * \sa ctkCmdLineModuleFrontend::value + */ + virtual QVariant value(const QString ¶meter, int role) const; + + /** + * \brief A custom method to enable the setting of mitk::DataNode::Pointer for input images. + * \param parameter The name of the parameter as specified in XML. + * \param value QVariant containing a mitk::DataNode::Pointer + * \param role The role, \see ctkCmdLineModuleFrontend. + * + * If role==UserRole and the parameter specified by parameter name is an + * input image, will set the value for that parameter. + * + * + * For any other scenario, calls base class. + * + * \sa ctkCmdLineModuleFrontend::setValue + */ + virtual void setValue(const QString& parameter, const QVariant& value, int role = DisplayRole); + +protected: + + /** + * \brief Virtual getter. + * \see ctkCmdLineModuleFrontendQtGui::uiLoader() + */ + virtual QUiLoader* uiLoader() const; + + /** + * \brief Virtual getter. + * \see ctkCmdLineModuleFrontendQtGui::xslTransform() + */ + virtual ctkCmdLineModuleXslTransform* xslTransform() const; + +private: + + QScopedPointer<QmitkCmdLineModuleGuiPrivate> d; + +}; // end class + +#endif // QmitkCmdLineModuleGui_h diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleProgressWidget.cpp b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleProgressWidget.cpp new file mode 100644 index 0000000000..b8667b7a57 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleProgressWidget.cpp @@ -0,0 +1,513 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "QmitkCmdLineModuleProgressWidget.h" +#include "ui_QmitkCmdLineModuleProgressWidget.h" + +// Qt +#include <QFile> +#include <QVBoxLayout> +#include <QLayoutItem> +#include <QTextBrowser> +#include <QByteArray> + +// CTK +#include <ctkCmdLineModuleFuture.h> +#include <ctkCmdLineModuleFutureWatcher.h> +#include <ctkCmdLineModuleManager.h> +#include <ctkCmdLineModuleFrontend.h> +#include <ctkCmdLineModuleDescription.h> +#include <ctkCmdLineModuleParameter.h> +#include <ctkCollapsibleGroupBox.h> + +// MITK +#include <mitkIOUtil.h> +#include <mitkDataStorage.h> +#include <mitkDataNode.h> +#include <QmitkCommonFunctionality.h> +#include <QmitkCustomVariants.h> +#include "QmitkCmdLineModuleGui.h" + +//----------------------------------------------------------------------------- +QmitkCmdLineModuleProgressWidget::QmitkCmdLineModuleProgressWidget(QWidget *parent) + : QWidget(parent) +, m_ModuleManager(NULL) +, m_DataStorage(NULL) +, m_TemporaryDirectoryName("") +, m_UI(new Ui::QmitkCmdLineModuleProgressWidget) +, m_Layout(NULL) +, m_ModuleFrontEnd(NULL) +, m_FutureWatcher(NULL) +{ + m_UI->setupUi(this); + m_UI->m_RemoveButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_TitleBarCloseButton)); + + m_Layout = new QVBoxLayout(); + m_Layout->setContentsMargins(0,0,0,0); + m_Layout->setSpacing(0); + m_UI->m_ParametersGroupBox->setLayout(m_Layout); + + qRegisterMetaType<mitk::DataNode::Pointer>(); + qRegisterMetaType<ctkCmdLineModuleReference>(); + + connect(m_UI->m_RemoveButton, SIGNAL(clicked()), this, SLOT(OnRemoveButtonClicked())); + + // Due to Qt bug 12152, we cannot listen to the "paused" signal because it is + // not emitted directly when the QFuture is paused. Instead, it is emitted after + // resuming the future, after the "resume" signal has been emitted... we use + // a polling approach instead. + connect(&m_PollPauseTimer, SIGNAL(timeout()), SLOT(OnCheckModulePaused())); + m_PollPauseTimer.setInterval(300); + m_PollPauseTimer.start(); +} + + +//----------------------------------------------------------------------------- +QmitkCmdLineModuleProgressWidget::~QmitkCmdLineModuleProgressWidget() +{ + if (m_ModuleFrontEnd != NULL) + { + delete m_ModuleFrontEnd; + } + + this->ClearUpTemporaryFiles(); + + delete m_UI; +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::SetManager(ctkCmdLineModuleManager* manager) +{ + this->m_ModuleManager = manager; +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::SetDataStorage(mitk::DataStorage* dataStorage) +{ + this->m_DataStorage = dataStorage; +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::SetTemporaryDirectory(const QString& directoryName) +{ + this->m_TemporaryDirectoryName = directoryName; +} + + +//----------------------------------------------------------------------------- +QString QmitkCmdLineModuleProgressWidget::GetTitle() +{ + assert(m_ModuleFrontEnd); + + ctkCmdLineModuleReference reference = m_ModuleFrontEnd->moduleReference(); + ctkCmdLineModuleDescription description = reference.description(); + + return description.title(); +} + + +//----------------------------------------------------------------------------- +QString QmitkCmdLineModuleProgressWidget::GetFullName() const +{ + assert(m_ModuleFrontEnd); + + ctkCmdLineModuleReference reference = m_ModuleFrontEnd->moduleReference(); + ctkCmdLineModuleDescription description = reference.description(); + + return description.categoryDotTitle(); +} + + +//----------------------------------------------------------------------------- +bool QmitkCmdLineModuleProgressWidget::IsStarted() const +{ + bool isStarted = false; + if (m_FutureWatcher != NULL && m_FutureWatcher->isStarted()) + { + isStarted = true; + } + return isStarted; +} + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::OnCheckModulePaused() +{ + if (!this->IsStarted()) + { + return; + } + + if (this->m_FutureWatcher->future().isPaused()) + { + if (!m_UI->m_PauseButton->isChecked()) + { + m_UI->m_PauseButton->setChecked(true); + } + } + else + { + if (m_UI->m_PauseButton->isChecked()) + { + m_UI->m_PauseButton->setChecked(false); + } + } +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::OnPauseButtonToggled(bool toggled) +{ + this->m_FutureWatcher->setPaused(toggled); + + if (toggled) + { + this->m_UI->m_ProgressTitle->setText(this->GetTitle() + ": paused"); + } + else + { + this->m_UI->m_ProgressTitle->setText(this->GetTitle() + ": resumed"); + } +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::OnRemoveButtonClicked() +{ + this->deleteLater(); +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::OnModuleStarted() +{ + this->m_UI->m_ProgressBar->setMaximum(0); + + QString message = "started."; + this->PublishMessage(message); + + emit started(); +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::OnModuleCanceled() +{ + QString message = "cancelling."; + this->PublishMessage(message); + + this->m_UI->m_PauseButton->setEnabled(false); + this->m_UI->m_PauseButton->setChecked(false); + this->m_UI->m_CancelButton->setEnabled(false); + this->m_UI->m_RemoveButton->setEnabled(true); + + this->m_UI->m_ParametersGroupBox->setCollapsed(true); + this->m_UI->m_ConsoleGroupBox->setCollapsed(true); + this->m_UI->m_ProgressTitle->setText(this->GetTitle() + ": cancelled"); + + message = "cancelled."; + this->PublishMessage(message); +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::OnModuleFinished() +{ + this->m_UI->m_PauseButton->setEnabled(false); + this->m_UI->m_PauseButton->setChecked(false); + this->m_UI->m_CancelButton->setEnabled(false); + this->m_UI->m_RemoveButton->setEnabled(true); + + if (!this->m_FutureWatcher->isCanceled()) + { + QString message = "finishing."; + this->PublishMessage(message); + + // If no incremental results from stdout, try getting hold of the whole buffer and printing it. + if (m_OutputCount == 0) + { + message = "Output channel is:"; + this->PublishMessage(message); + this->PublishByteArray(this->m_FutureWatcher->readAllOutputData()); + } + + // If no incremental results from stderr, try getting hold of the whole buffer and printing it. + if (m_ErrorCount == 0) + { + message = "Error channel is:"; + this->PublishMessage(message); + this->PublishByteArray(this->m_FutureWatcher->readAllErrorData()); + } + + this->m_UI->m_ProgressTitle->setText(this->GetTitle() + ": finished"); + + this->LoadOutputData(); + this->ClearUpTemporaryFiles(); + + message = "finished."; + this->PublishMessage(message); + + } + + emit finished(); +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::OnModuleResumed() +{ + this->m_UI->m_PauseButton->setChecked(false); +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::OnModuleProgressRangeChanged(int progressMin, int progressMax) +{ + this->m_UI->m_ProgressBar->setMinimum(progressMin); + this->m_UI->m_ProgressBar->setMaximum(progressMax); +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::OnModuleProgressTextChanged(const QString& progressText) +{ + this->m_UI->m_Console->appendPlainText(progressText); +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::OnModuleProgressValueChanged(int progressValue) +{ + this->m_UI->m_ProgressBar->setValue(progressValue); +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::OnOutputDataReady() +{ + m_OutputCount++; + this->PublishByteArray(this->m_FutureWatcher->readPendingOutputData()); +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::OnErrorDataReady() +{ + m_ErrorCount++; + this->PublishByteArray(this->m_FutureWatcher->readPendingErrorData()); +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::PublishMessage(const QString& message) +{ + QString prefix = ""; // Can put additional prefix here if needed. + QString outputMessage = prefix + message; + + qDebug() << outputMessage; + this->m_UI->m_Console->appendPlainText(outputMessage); +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::PublishByteArray(const QByteArray& array) +{ + QString message = array.data(); + this->PublishMessage(message); +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::ClearUpTemporaryFiles() +{ + QString message; + QString fileName; + + foreach (fileName, m_TemporaryFileNames) + { + QFile file(fileName); + if (file.exists()) + { + message = QObject::tr("removing %1").arg(fileName); + this->PublishMessage(message); + + bool success = file.remove(); + + message = QObject::tr("removed %1, successfully=%2").arg(fileName).arg(success); + this->PublishMessage(message); + } + } +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::LoadOutputData() +{ + assert(m_DataStorage); + + std::vector<std::string> fileNames; + + QString fileName; + foreach (fileName, m_OutputDataToLoad) + { + QString message = QObject::tr("loading %1").arg(fileName); + this->PublishMessage(message); + + fileNames.push_back(fileName.toStdString()); + } + + if (fileNames.size() > 0) + { + int numberLoaded = mitk::IOUtil::LoadFiles(fileNames, *(m_DataStorage)); + + QString message = QObject::tr("loaded %1 files").arg(numberLoaded); + this->PublishMessage(message); + } +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::SetFrontend(QmitkCmdLineModuleGui* frontEnd) +{ + assert(frontEnd); + assert(m_ModuleManager); + assert(m_DataStorage); + + // We are assuming that this method is ONLY EVER CALLED ONCE. + assert(!m_ModuleFrontEnd); + + // Assign the frontEnd to the member variable. + m_ModuleFrontEnd = frontEnd; + + // We put the new GUI into the layout. + m_Layout->insertWidget(0, m_ModuleFrontEnd->getGui()); + + // And configure a few other niceties. + m_UI->m_ProgressTitle->setText(this->GetTitle()); + m_UI->m_ConsoleGroupBox->setCollapsed(true); // We basically call SetFrontend then Run + m_UI->m_ParametersGroupBox->setCollapsed(true); // so in practice the user will only want the progress bar. +} + + +//----------------------------------------------------------------------------- +void QmitkCmdLineModuleProgressWidget::Run() +{ + assert(m_ModuleManager); + assert(m_DataStorage); + assert(m_ModuleFrontEnd); + + m_OutputDataToLoad.clear(); + + ctkCmdLineModuleReference reference = m_ModuleFrontEnd->moduleReference(); + ctkCmdLineModuleDescription description = reference.description(); + + QString message = "Saving image data to temporary storage..."; + this->PublishMessage(message); + + // Sanity check we have actually specified some input: + QString parameterName; + QList<ctkCmdLineModuleParameter> parameters; + + // For each input image, write a temporary file as a Nifti image, + // and then save the full path name back on the parameter. + parameters = m_ModuleFrontEnd->parameters("image", ctkCmdLineModuleFrontend::Input); + foreach (ctkCmdLineModuleParameter parameter, parameters) + { + parameterName = parameter.name(); + + QVariant tmp = m_ModuleFrontEnd->value(parameterName, ctkCmdLineModuleFrontend::UserRole); + mitk::DataNode::Pointer node = tmp.value<mitk::DataNode::Pointer>(); + + if (node.IsNotNull()) + { + mitk::Image* image = dynamic_cast<mitk::Image*>(node->GetData()); + if (image != NULL) + { + QString name = QString::fromStdString(node->GetName()); + int pid = QCoreApplication::applicationPid(); + int randomInt = qrand() % 1000000; + + QString fileName = m_TemporaryDirectoryName + "/" + name + QString::number(pid) + "." + QString::number(randomInt) + ".nii"; + + message = "Saving " + fileName; + this->PublishMessage(message); + + std::string tmpFN = CommonFunctionality::SaveImage(image, fileName.toStdString().c_str()); + QString temporaryStorageFileName = QString::fromStdString(tmpFN); + + m_TemporaryFileNames.push_back(temporaryStorageFileName); + m_ModuleFrontEnd->setValue(parameterName, temporaryStorageFileName); + + message = "Saved " + temporaryStorageFileName; + this->PublishMessage(message); + } // end if image + } // end if node + } // end foreach input image + + // For each output image or file, store the filename, so we can auto-load it once the process finishes. + parameters = m_ModuleFrontEnd->parameters("image", ctkCmdLineModuleFrontend::Output); + parameters << m_ModuleFrontEnd->parameters("file", ctkCmdLineModuleFrontend::Output); + + foreach (ctkCmdLineModuleParameter parameter, parameters) + { + parameterName = parameter.name(); + QString outputFileName = m_ModuleFrontEnd->value(parameterName, ctkCmdLineModuleFrontend::DisplayRole).toString(); + + if (!outputFileName.isEmpty()) + { + m_OutputDataToLoad.push_back(outputFileName); + + message = "Registered " + outputFileName + " to auto load upon completion."; + this->PublishMessage(message); + } + } + + m_OutputCount = 0; + m_ErrorCount = 0; + + // Now we run stuff. + message = "starting."; + this->PublishMessage(message); + + if (m_FutureWatcher == NULL) + { + m_FutureWatcher = new ctkCmdLineModuleFutureWatcher(); + + connect(m_FutureWatcher, SIGNAL(started()), SLOT(OnModuleStarted())); + connect(m_FutureWatcher, SIGNAL(canceled()), SLOT(OnModuleCanceled())); + connect(m_FutureWatcher, SIGNAL(finished()), SLOT(OnModuleFinished())); + connect(m_FutureWatcher, SIGNAL(resumed()), SLOT(OnModuleResumed())); + connect(m_FutureWatcher, SIGNAL(progressRangeChanged(int,int)), SLOT(OnModuleProgressRangeChanged(int,int))); + connect(m_FutureWatcher, SIGNAL(progressTextChanged(QString)), SLOT(OnModuleProgressTextChanged(QString))); + connect(m_FutureWatcher, SIGNAL(progressValueChanged(int)), SLOT(OnModuleProgressValueChanged(int))); + connect(m_FutureWatcher, SIGNAL(outputDataReady()), SLOT(OnOutputDataReady())); + connect(m_FutureWatcher, SIGNAL(errorDataReady()), SLOT(OnErrorDataReady())); + + connect(m_UI->m_CancelButton, SIGNAL(clicked()), m_FutureWatcher, SLOT(cancel())); + connect(m_UI->m_PauseButton, SIGNAL(toggled(bool)), this, SLOT(OnPauseButtonToggled(bool))); + + } + ctkCmdLineModuleFuture future = m_ModuleManager->run(m_ModuleFrontEnd); + m_FutureWatcher->setFuture(future); + + m_UI->m_PauseButton->setEnabled(future.canPause()); + m_UI->m_CancelButton->setEnabled(future.canCancel()); + m_UI->m_RemoveButton->setEnabled(!future.isRunning()); + + // Give some immediate indication that we are running. + m_UI->m_ProgressTitle->setText(description.title() + ": running"); +} diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleProgressWidget.h b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleProgressWidget.h new file mode 100644 index 0000000000..800df91be1 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleProgressWidget.h @@ -0,0 +1,209 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QMITKCMDLINEMODULEPROGRESSWIDGET_H +#define QMITKCMDLINEMODULEPROGRESSWIDGET_H + +#include <QWidget> +#include <QTimer> + +class QVBoxLayout; +class QmitkCmdLineModuleGui; +class ctkCmdLineModuleManager; +class ctkCmdLineModuleFutureWatcher; + +namespace Ui { +class QmitkCmdLineModuleProgressWidget; +} + +namespace mitk { +class DataStorage; +} + +/** + * \class QmitkCmdLineModuleProgressWidget + * \brief Based on ctkCmdLineModuleExplorerProgressWidget, implements a progress widget + * with console output, and space for storing the GUI widgets. + * \author Matt Clarkson (m.clarkson@ucl.ac.uk) + * \ingroup org_mitk_gui_qt_cli_internal + * \sa ctkCmdLineModuleExplorerProgressWidget + */ +class QmitkCmdLineModuleProgressWidget : public QWidget +{ + Q_OBJECT + +public: + + QmitkCmdLineModuleProgressWidget(QWidget *parent = 0); + virtual ~QmitkCmdLineModuleProgressWidget(); + + /** + * \brief Sets the manager on this object, and must be called immediately + * after construction, before using the widget. + */ + void SetManager(ctkCmdLineModuleManager* manager); + + /** + * \brief Sets the DataStorage on this object, and must be called immediately + * after construction, before using the widget. + */ + void SetDataStorage(mitk::DataStorage* dataStorage); + + /** + * \brief Sets the Temporary Directory on this widget, and must be called + * immediately after construction, before using the widget. + */ + void SetTemporaryDirectory(const QString& directoryName); + + /** + * \brief Tells this widget, which module frontend it is running + * \param frontEnd our QmitkCmdLineModuleGui class derived from ctkCmdLineModuleFrontend + */ + void SetFrontend(QmitkCmdLineModuleGui* frontEnd); + + /** + * \brief Runs the module that this widget is currently referring to. + */ + void Run(); + +Q_SIGNALS: + + // These signals so that container classes such as CommandLineModuleView + // can keep track of how many modules are running simultaneously. + + void started(); // emmitted when the module is started. + void finished(); // emmitted when the module is completely finished. + +private Q_SLOTS: + + void OnCheckModulePaused(); + + void OnPauseButtonToggled(bool toggled); + void OnRemoveButtonClicked(); + + void OnModuleStarted(); + void OnModuleCanceled(); + void OnModuleFinished(); + void OnModuleResumed(); + void OnModuleProgressRangeChanged(int progressMin, int progressMax); + void OnModuleProgressTextChanged(const QString& progressText); + void OnModuleProgressValueChanged(int progressValue); + void OnOutputDataReady(); + void OnErrorDataReady(); + +private: + + /** + * \brief Simply returns true if this widget is considered as having been started. + */ + bool IsStarted() const; + + /** + * \brief Used to write output to the console widget, and also to qDebug(). + */ + void PublishMessage(const QString& message); + + /** + * \brief Used to write output to the console widget, and also to qDebug(). + */ + void PublishByteArray(const QByteArray& array); + + /** + * \brief Destroys any images listed in m_TemporaryFileNames. + */ + void ClearUpTemporaryFiles(); + + /** + * \brief Loads any data listed in m_OutputDataToLoad into the m_DataStorage. + */ + void LoadOutputData(); + + /** + * \brief Utility method to look up the title from the description. + */ + QString GetTitle(); + + /** + * \brief Returns <category>.<title>, derived from the ctkCmdLineModuleReference and + * hence from the ctkCmdLineModuleDescription. + */ + QString GetFullName() const; + + /** + * \brief This must be injected before the Widget is used. + */ + ctkCmdLineModuleManager *m_ModuleManager; + + /** + * \brief This must be injected before the Widget is used. + */ + mitk::DataStorage *m_DataStorage; + + /** + * \brief This must be injected before the Widget is used. + */ + QString m_TemporaryDirectoryName; + + /** + * \brief We instantiate the main widgets from this .ui file. + */ + Ui::QmitkCmdLineModuleProgressWidget *m_UI; + + /** + * \brief The m_ParametersGroupBox needs a layout. + */ + QVBoxLayout *m_Layout; + + /** + * \brief The QmitkCmdLineModuleGui is created by the QmitkCmdLineModuleFactoryGui outside + * of this class and injected into this class before being run. + */ + QmitkCmdLineModuleGui *m_ModuleFrontEnd; + + /** + * \brief Main object to keep track of a running command line module. + */ + ctkCmdLineModuleFutureWatcher *m_FutureWatcher; + + /** + * \brief Due to Qt bug 12152, we use a timer to correctly check for a paused module. + */ + QTimer m_PollPauseTimer; + + /** + * \brief We store a list of temporary file names that are saved to disk before + * launching a command line app, and then must be cleared up when the command line + * app successfully finishes. + */ + QStringList m_TemporaryFileNames; + + /** + * \brief We store a list of output images, so that on successful completion of + * the command line module, we automatically load the output data into the mitk::DataStorage. + */ + QStringList m_OutputDataToLoad; + + /** + * \brief We track how many times the OnOutputDataReady is called. + */ + int m_OutputCount; + + /** + * \brief We track how many times the OnErrorDataReady is called. + */ + int m_ErrorCount; +}; + +#endif // QMITKCMDLINEMODULEPROGRESSWIDGET_H diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleProgressWidget.ui b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleProgressWidget.ui new file mode 100644 index 0000000000..2cbf66be90 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkCmdLineModuleProgressWidget.ui @@ -0,0 +1,131 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>QmitkCmdLineModuleProgressWidget</class> + <widget class="QWidget" name="QmitkCmdLineModuleProgressWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>593</width> + <height>390</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QFrame" name="m_Frame"> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="m_ProgressTitle"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QProgressBar" name="m_ProgressBar"> + <property name="value"> + <number>0</number> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="m_PauseButton"> + <property name="text"> + <string>...</string> + </property> + <property name="icon"> + <iconset> + <normaloff>:/CommandLineModulesResources/pause.png</normaloff>:/CommandLineModulesResources/pause.png</iconset> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="autoRaise"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="m_CancelButton"> + <property name="text"> + <string>...</string> + </property> + <property name="icon"> + <iconset> + <normaloff>:/CommandLineModulesResources/stop.png</normaloff>:/CommandLineModulesResources/stop.png</iconset> + </property> + <property name="autoRaise"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="m_RemoveButton"> + <property name="text"> + <string>Remove</string> + </property> + <property name="autoRaise"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="ctkCollapsibleGroupBox" name="m_ParametersGroupBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Parameters</string> + </property> + </widget> + </item> + <item> + <widget class="ctkCollapsibleGroupBox" name="m_ConsoleGroupBox"> + <property name="title"> + <string>Console</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QPlainTextEdit" name="m_Console"/> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>ctkCollapsibleGroupBox</class> + <extends>QGroupBox</extends> + <header>ctkCollapsibleGroupBox.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkDataStorageComboBoxWithSelectNone.cpp b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkDataStorageComboBoxWithSelectNone.cpp new file mode 100644 index 0000000000..fd8f1c3bf2 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkDataStorageComboBoxWithSelectNone.cpp @@ -0,0 +1,189 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "QmitkDataStorageComboBoxWithSelectNone.h" +#include <QDebug> + +const QString QmitkDataStorageComboBoxWithSelectNone::ZERO_ENTRY_STRING = "please select"; + +//----------------------------------------------------------------------------- +QmitkDataStorageComboBoxWithSelectNone::QmitkDataStorageComboBoxWithSelectNone( + QWidget* parent, + bool autoSelectNewNodes ) +: QmitkDataStorageComboBox(parent, autoSelectNewNodes) +, m_CurrentPath("") +{ +} + + +//----------------------------------------------------------------------------- +QmitkDataStorageComboBoxWithSelectNone::QmitkDataStorageComboBoxWithSelectNone( + mitk::DataStorage* dataStorage, + const mitk::NodePredicateBase* predicate, + QWidget* parent, bool autoSelectNewNodes ) +: QmitkDataStorageComboBox(dataStorage, predicate, parent, autoSelectNewNodes) +{ +} + + +//----------------------------------------------------------------------------- +QmitkDataStorageComboBoxWithSelectNone::~QmitkDataStorageComboBoxWithSelectNone() +{ +} + + +//----------------------------------------------------------------------------- +int QmitkDataStorageComboBoxWithSelectNone::Find( const mitk::DataNode* dataNode ) const +{ + int index = QmitkDataStorageComboBox::Find(dataNode); + if (index != -1) + { + index += 1; + } + return index; +} + + +//----------------------------------------------------------------------------- +mitk::DataNode::Pointer QmitkDataStorageComboBoxWithSelectNone::GetNode( int index ) const +{ + mitk::DataNode::Pointer result = NULL; + + if (this->HasIndex(index)) + { + if (index != 0) + { + result = m_Nodes.at(index - 1); + } + } + return result; +} + + +//----------------------------------------------------------------------------- +mitk::DataNode::Pointer QmitkDataStorageComboBoxWithSelectNone::GetSelectedNode() const +{ + return this->GetNode(this->currentIndex()); +} + + +//----------------------------------------------------------------------------- +void QmitkDataStorageComboBoxWithSelectNone::SetSelectedNode(const mitk::DataNode::Pointer& node) +{ + int currentIndex = -1; + for (int i = 0; i < m_Nodes.size(); i++) + { + if (m_Nodes[i] == node.GetPointer()) + { + currentIndex = i; + break; + } + } + if (currentIndex == -1) + { + // didn't find it, so set the value to 0. + currentIndex = 0; + } + else + { + currentIndex += 1; // because the combo box contains "please select" at position zero. + } + this->setCurrentIndex(currentIndex); +} + +//----------------------------------------------------------------------------- +void QmitkDataStorageComboBoxWithSelectNone::RemoveNode( int index ) +{ + if(index > 0 && this->HasIndex(index)) + { + + // remove itk::Event observer + mitk::DataNode* dataNode = m_Nodes.at(index - 1); + + // get name property first + mitk::BaseProperty* nameProperty = dataNode->GetProperty("name"); + + // if prop exists remove modified listener + if(nameProperty) + { + nameProperty->RemoveObserver(m_NodesModifiedObserverTags[index-1]); + + // remove name property map + m_PropertyToNode.erase(dataNode); + } + + // then remove delete listener on the node itself + dataNode->RemoveObserver(m_NodesDeleteObserverTags[index-1]); + + // remove observer tags from lists + m_NodesModifiedObserverTags.erase(m_NodesModifiedObserverTags.begin()+index-1); + m_NodesDeleteObserverTags.erase(m_NodesDeleteObserverTags.begin()+index-1); + + // remove node name from combobox + this->removeItem(index); + + // remove node from node vector + m_Nodes.erase(m_Nodes.begin()+index-1); + } +} + + +//----------------------------------------------------------------------------- +void QmitkDataStorageComboBoxWithSelectNone::SetNode(int index, const mitk::DataNode* dataNode) +{ + if(index > 0 && this->HasIndex(index)) + { + QmitkDataStorageComboBox::InsertNode(index - 1, dataNode); + } +} + + +//----------------------------------------------------------------------------- +bool QmitkDataStorageComboBoxWithSelectNone::HasIndex(unsigned int index) const +{ + return (m_Nodes.size() > 0 && index <= m_Nodes.size()); +} + + +//----------------------------------------------------------------------------- +void QmitkDataStorageComboBoxWithSelectNone::InsertNode(int index, const mitk::DataNode* dataNode) +{ + if (index != 0) + { + QmitkDataStorageComboBox::InsertNode(index - 1, dataNode); + } +} + + +//----------------------------------------------------------------------------- +void QmitkDataStorageComboBoxWithSelectNone::Reset() +{ + QmitkDataStorageComboBox::Reset(); + this->insertItem(0, ZERO_ENTRY_STRING); +} + + +//----------------------------------------------------------------------------- +QString QmitkDataStorageComboBoxWithSelectNone::currentValue() const +{ + return m_CurrentPath; +} + + +//----------------------------------------------------------------------------- +void QmitkDataStorageComboBoxWithSelectNone::setCurrentValue(const QString& path) +{ + m_CurrentPath = path; +} diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkDataStorageComboBoxWithSelectNone.h b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkDataStorageComboBoxWithSelectNone.h new file mode 100644 index 0000000000..1b30456bc8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkDataStorageComboBoxWithSelectNone.h @@ -0,0 +1,146 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QmitkDataStorageComboBoxWithSelectNone_h +#define QmitkDataStorageComboBoxWithSelectNone_h + +#include <QmitkExports.h> +#include "QmitkDataStorageComboBox.h" +#include "QmitkCustomVariants.h" +#include "mitkDataNode.h" + +/** + * \class QmitkDataStorageComboBoxWithSelectNone + * \brief Displays all or a subset (defined by a predicate) of nodes of the Data Storage, + * and additionally, index 0 is always "please select", indicating no selection, and will + * hence always return a NULL mitk::DataNode* if asked for the node at index 0. + * + * In addition, to support the integration of CTK command line modules, the methods + * currentValue() and setCurrentValue() are provided. See also the .xsl file + * in org.mitk.gui.qt.cli/resources/QmitkDataStorageComboBox.xsl. + * + * \author Matt Clarkson (m.clarkson@ucl.ac.uk) + * \ingroup org_mitk_gui_qt_cli_internal + * \sa QmitkDataStorageComboBox + */ +class QmitkDataStorageComboBoxWithSelectNone : public QmitkDataStorageComboBox +{ + Q_OBJECT + Q_PROPERTY(mitk::DataNode::Pointer SelectedNode READ GetSelectedNode WRITE SetSelectedNode) + Q_PROPERTY(QString currentValue READ currentValue WRITE setCurrentValue) + + public: + /** + * \brief Calls base class constructor. + * \see QmitkDataStorageComboBox + */ + QmitkDataStorageComboBoxWithSelectNone(QWidget* parent = 0, bool autoSelectNewNodes=false); + + /** + * \brief Calls base class constructor. + * \see QmitkDataStorageComboBox + */ + QmitkDataStorageComboBoxWithSelectNone( mitk::DataStorage* _DataStorage, + const mitk::NodePredicateBase* predicate, + QWidget* parent = 0, + bool autoSelectNewNodes=false); + + /** + * \brief Nothing to do. + * \see QmitkDataStorageComboBox + */ + ~QmitkDataStorageComboBoxWithSelectNone(); + + /** + * \brief Stores the string that will be present on index 0, currently equal to "please select". + */ + static const QString ZERO_ENTRY_STRING; + + /** + * \brief Searches for a given node, returning the index if found. + * \param dataNode an mitk::DataNode, can be NULL. + * \return int -1 if not found, and compared to base class, will add 1 onto the retrieved index. + */ + virtual int Find( const mitk::DataNode* dataNode ) const; + + /** + * \brief Retrieves the node at a given index, where if index is zero, will always return NULL. + * \param index An integer between 0 and n = number of nodes. + * \return mitk::DataNode::Pointer NULL or a data node pointer. + */ + virtual mitk::DataNode::Pointer GetNode(int index) const; + + /** + * \brief Returns the selected DataNode or NULL if there is none, or the current index is zero. + */ + virtual mitk::DataNode::Pointer GetSelectedNode() const; + + /** + * \brief Sets the combo box to the index that contains the specified node, or 0 if the node cannot be found. + */ + virtual void SetSelectedNode(const mitk::DataNode::Pointer& node); + + /** + * \brief Removes a node from the ComboBox at a specified index (if the index exists). + * Gets called when a DataStorage Remove Event was thrown. + */ + virtual void RemoveNode(int index); + + /** + * \brief Set a DataNode in the ComboBox at the specified index (if the index exists). + * Internally the method just calls InsertNode(unsigned int) + */ + virtual void SetNode(int index, const mitk::DataNode* dataNode); + + /** + * \brief Get the current file path. + */ + virtual QString currentValue() const; + + /** + * \brief Set the current file path. + */ + virtual void setCurrentValue(const QString& path); + + protected: + + /** + * \brief Checks if the given index is within range. + */ + bool HasIndex(unsigned int index) const; + + /** + * \brief Inserts a new node at the given index, unless index is 0, which is silently ignored. + */ + virtual void InsertNode(int index, const mitk::DataNode* dataNode); + + /** + * \brief Reset function whenever datastorage or predicate changes. + */ + virtual void Reset(); + + private: + + /** + * \brief This should store the current file path of the current image. + * + * + * The reason is so that we can store and retrieve a temporary file name. + */ + QString m_CurrentPath; +}; + +#endif // QmitkDataStorageComboBoxWithSelectNone_h + diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkDirectoryListWidget.cpp b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkDirectoryListWidget.cpp new file mode 100644 index 0000000000..a275a4108c --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkDirectoryListWidget.cpp @@ -0,0 +1,51 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "QmitkDirectoryListWidget.h" + +#include <ctkPathListWidget.h> +#include <ctkPathListButtonsWidget.h> + +//----------------------------------------------------------------------------- +QmitkDirectoryListWidget::QmitkDirectoryListWidget(QWidget*) +{ + this->setupUi(this); + this->m_PathListWidget->setMode(ctkPathListWidget::DirectoriesOnly); + this->m_PathListWidget->setDirectoryOptions(ctkPathListWidget::Exists | ctkPathListWidget::Readable | ctkPathListWidget::Executable); + this->m_PathListButtonsWidget->init(this->m_PathListWidget); + this->m_PathListButtonsWidget->setOrientation(Qt::Vertical); + connect(this->m_PathListWidget, SIGNAL(pathsChanged(QStringList,QStringList)), this, SLOT(OnPathsChanged(QStringList, QStringList))); +} + + +//----------------------------------------------------------------------------- +void QmitkDirectoryListWidget::OnPathsChanged(const QStringList& before, const QStringList& after) +{ + emit pathsChanged(before, after); +} + + +//----------------------------------------------------------------------------- +QStringList QmitkDirectoryListWidget::directories(bool absolutePath) const +{ + return this->m_PathListWidget->directories(absolutePath); +} + + +//----------------------------------------------------------------------------- +void QmitkDirectoryListWidget::setDirectories(const QStringList& paths) +{ + this->m_PathListWidget->setPaths(paths); +} diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkDirectoryListWidget.h b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkDirectoryListWidget.h new file mode 100644 index 0000000000..3e9ca3532e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkDirectoryListWidget.h @@ -0,0 +1,58 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QMITKDIRECTORYLISTWIDGET_H +#define QMITKDIRECTORYLISTWIDGET_H + +#include "ui_QmitkPathListWidget.h" +#include <QWidget> + +/** + * \class QmitkDirectoryListWidget + * \brief Widget to contain a ctkPathListWidget and a ctkPathListButtonsWidget + * and provide simple directory access for readable, executable directories. + * \author Matt Clarkson (m.clarkson@ucl.ac.uk) + * \ingroup org_mitk_gui_qt_cli_internal + */ +class QmitkDirectoryListWidget : public QWidget, public Ui::QmitkPathListWidget +{ + Q_OBJECT + +public: + QmitkDirectoryListWidget(QWidget* parent=0); + + /** + * \brief Get all directory entries. + * \param absolutePath If <code>true</code>, resolve all entries to absolute paths. + * \return A list of all directory entries. + */ + QStringList directories(bool absolutePath = false) const; + + /** + * \brief Sets the list of directory entries. + * \param paths The new path list. + */ + void setDirectories(const QStringList& paths); + +Q_SIGNALS: + + void pathsChanged(const QStringList&, const QStringList&); + +private Q_SLOTS: + + void OnPathsChanged(const QStringList&, const QStringList&); +}; + +#endif // QMITKDIRECTORYLISTWIDGET_H diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkFileListWidget.cpp b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkFileListWidget.cpp new file mode 100644 index 0000000000..a1bf1bdec2 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkFileListWidget.cpp @@ -0,0 +1,51 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "QmitkFileListWidget.h" + +#include <ctkPathListWidget.h> +#include <ctkPathListButtonsWidget.h> + +//----------------------------------------------------------------------------- +QmitkFileListWidget::QmitkFileListWidget(QWidget*) +{ + this->setupUi(this); + this->m_PathListWidget->setMode(ctkPathListWidget::FilesOnly); + this->m_PathListWidget->setFileOptions(ctkPathListWidget::Exists | ctkPathListWidget::Readable | ctkPathListWidget::Executable); + this->m_PathListButtonsWidget->init(this->m_PathListWidget); + this->m_PathListButtonsWidget->setOrientation(Qt::Vertical); + connect(this->m_PathListWidget, SIGNAL(pathsChanged(QStringList,QStringList)), this, SLOT(OnPathsChanged(QStringList, QStringList))); +} + + +//----------------------------------------------------------------------------- +void QmitkFileListWidget::OnPathsChanged(const QStringList& before, const QStringList& after) +{ + emit pathsChanged(before, after); +} + + +//----------------------------------------------------------------------------- +QStringList QmitkFileListWidget::files(bool absolutePath) const +{ + return this->m_PathListWidget->files(absolutePath); +} + + +//----------------------------------------------------------------------------- +void QmitkFileListWidget::setFiles(const QStringList& paths) +{ + this->m_PathListWidget->setPaths(paths); +} diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkFileListWidget.h b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkFileListWidget.h new file mode 100644 index 0000000000..cc03e948d1 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkFileListWidget.h @@ -0,0 +1,58 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QMITKFILELISTWIDGET_H +#define QMITKFILELISTWIDGET_H + +#include "ui_QmitkPathListWidget.h" +#include <QWidget> + +/** + * \class QmitkFileListWidget + * \brief Widget to contain a ctkPathListWidget and a ctkPathListButtonsWidget + * and provide simple file access for readable, executable files. + * \author Matt Clarkson (m.clarkson@ucl.ac.uk) + * \ingroup org_mitk_gui_qt_cli_internal + */ +class QmitkFileListWidget : public QWidget, public Ui::QmitkPathListWidget +{ + Q_OBJECT + +public: + QmitkFileListWidget(QWidget* parent=0); + + /** + * \brief Get all file entries. + * \param absolutePath If <code>true</code>, resolve all entries to absolute paths. + * \return A list of all file entries. + */ + QStringList files(bool absolutePath = false) const; + + /** + * \brief Sets the list of file entries. + * \param paths The new path list. + */ + void setFiles(const QStringList& paths); + +Q_SIGNALS: + + void pathsChanged(const QStringList&, const QStringList&); + +private Q_SLOTS: + + void OnPathsChanged(const QStringList&, const QStringList&); +}; + +#endif // QMITKDIRECTORYLISTWIDGET_H diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkPathListWidget.ui b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkPathListWidget.ui new file mode 100644 index 0000000000..1c21a8441d --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkPathListWidget.ui @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>QmitkPathListWidget</class> + <widget class="QWidget" name="QmitkPathListWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>449</width> + <height>312</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="m_Label"> + <property name="text"> + <string>Enter Label Text</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="ctkPathListWidget" name="m_PathListWidget"> + <property name="textElideMode"> + <enum>Qt::ElideMiddle</enum> + </property> + </widget> + </item> + <item row="1" column="1"> + <layout class="QVBoxLayout" name="m_VerticalLayout"> + <item> + <widget class="ctkPathListButtonsWidget" name="m_PathListButtonsWidget" native="true"> + <property name="buttonsAutoRaise" stdset="0"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer name="m_VerticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>ctkPathListButtonsWidget</class> + <extends>QWidget</extends> + <header>ctkPathListButtonsWidget.h</header> + </customwidget> + <customwidget> + <class>ctkPathListWidget</class> + <extends>QListView</extends> + <header>ctkPathListWidget.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkUiLoader.cpp b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkUiLoader.cpp new file mode 100644 index 0000000000..a0a53212ac --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkUiLoader.cpp @@ -0,0 +1,64 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "QmitkUiLoader.h" +#include "QmitkDataStorageComboBoxWithSelectNone.h" +#include "mitkNodePredicateDataType.h" + +//----------------------------------------------------------------------------- +QmitkUiLoader::QmitkUiLoader(const mitk::DataStorage* dataStorage, QObject *parent) + : ctkCmdLineModuleQtUiLoader(parent) +, m_DataStorage(dataStorage) +{ + +} + + +//----------------------------------------------------------------------------- +QmitkUiLoader::~QmitkUiLoader() +{ + +} + + +//----------------------------------------------------------------------------- +QStringList QmitkUiLoader::availableWidgets () const +{ + QStringList availableWidgets = ctkCmdLineModuleQtUiLoader::availableWidgets(); + availableWidgets << "QmitkDataStorageComboBoxWithSelectNone"; + return availableWidgets; +} + + +//----------------------------------------------------------------------------- +QWidget* QmitkUiLoader::createWidget(const QString& className, QWidget* parent, const QString& name) +{ + QWidget* widget = NULL; + if (className == "QmitkDataStorageComboBoxWithSelectNone") + { + QmitkDataStorageComboBoxWithSelectNone* comboBox = new QmitkDataStorageComboBoxWithSelectNone(parent); + comboBox->setObjectName(name); + comboBox->SetAutoSelectNewItems(false); + comboBox->SetPredicate(mitk::NodePredicateDataType::New("Image")); + comboBox->SetDataStorage(const_cast<mitk::DataStorage*>(m_DataStorage)); + comboBox->setCurrentIndex(0); + widget = comboBox; + } + else + { + widget = ctkCmdLineModuleQtUiLoader::createWidget(className, parent, name); + } + return widget; +} diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkUiLoader.h b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkUiLoader.h new file mode 100644 index 0000000000..e4b67fe5b1 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/QmitkUiLoader.h @@ -0,0 +1,59 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QmitkUiLoader_h +#define QmitkUiLoader_h + +#include <ctkCmdLineModuleQtUiLoader.h> +#include <QStringList> +#include "mitkDataStorage.h" + +/** + * \class QmitkUiLoader + * \brief Derived from ctkCmdLineModuleQtGuiLoader to enable us to instantiate widgets from Qmitk at runtime, + * and currently we instatiate QmitkDataStorageComboBoxWithSelectNone, used for image input widgets. + * \author Matt Clarkson (m.clarkson@ucl.ac.uk) + * \ingroup org_mitk_gui_qt_cli_internal + * \sa ctkCmdLineModuleQtUiLoader + */ +class QmitkUiLoader : public ctkCmdLineModuleQtUiLoader +{ + + Q_OBJECT + +public: + QmitkUiLoader(const mitk::DataStorage* dataStorage, QObject *parent=0); + virtual ~QmitkUiLoader(); + + /** + * \brief Returns the list of available widgets in ctkCmdLineModuleQtGuiLoader and also QmitkDataStorageComboBoxWithSelectNone. + * \see ctkCmdLineModuleQtGuiLoader::availableWidgets() + */ + QStringList availableWidgets () const; + + /** + * \brief If className is QmitkDataStorageComboBox, instantiates QmitkDataStorageComboBoxWithSelectNone and + * otherwise delegates to base class. + * \see ctkCmdLineModuleQtGuiLoader::createWidget() + */ + virtual QWidget* createWidget(const QString & className, QWidget * parent = 0, const QString & name = QString() ); + +private: + + const mitk::DataStorage* m_DataStorage; + +}; // end class + +#endif // QmitkUiLoader_h diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/org_mitk_gui_qt_cli_Activator.cpp b/Plugins/org.mitk.gui.qt.cli/src/internal/org_mitk_gui_qt_cli_Activator.cpp new file mode 100644 index 0000000000..ef2c4318e5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/org_mitk_gui_qt_cli_Activator.cpp @@ -0,0 +1,39 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#include "org_mitk_gui_qt_cli_Activator.h" + +#include <QtPlugin> + +#include "CommandLineModulesView.h" +#include "CommandLineModulesPreferencesPage.h" + +namespace mitk { + +void org_mitk_gui_qt_cli_Activator::start(ctkPluginContext* context) +{ + BERRY_REGISTER_EXTENSION_CLASS(CommandLineModulesView, context) + BERRY_REGISTER_EXTENSION_CLASS(CommandLineModulesPreferencesPage, context) +} + +void org_mitk_gui_qt_cli_Activator::stop(ctkPluginContext* context) +{ + Q_UNUSED(context) +} + +} + +Q_EXPORT_PLUGIN2(org_mitk_gui_qt_cli, mitk::org_mitk_gui_qt_cli_Activator) diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/org_mitk_gui_qt_cli_Activator.h b/Plugins/org.mitk.gui.qt.cli/src/internal/org_mitk_gui_qt_cli_Activator.h new file mode 100644 index 0000000000..e7aa6f64f1 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/org_mitk_gui_qt_cli_Activator.h @@ -0,0 +1,45 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef org_mitk_gui_qt_cli_Activator_h +#define org_mitk_gui_qt_cli_Activator_h + +#include <ctkPluginActivator.h> + +namespace mitk { + +/** + * \class org_mitk_gui_qt_cli_Activator + * \brief Blueberry plugin activator for CommandLineModulesView. + * \author Matt Clarkson (m.clarkson@ucl.ac.uk) + * \ingroup org_mitk_gui_qt_cli_internal + */ +class org_mitk_gui_qt_cli_Activator : + public QObject, public ctkPluginActivator +{ + Q_OBJECT + Q_INTERFACES(ctkPluginActivator) + +public: + + void start(ctkPluginContext* context); + void stop(ctkPluginContext* context); + +}; // org_mitk_gui_qt_cli_Activator + +} + +#endif // org_mitk_gui_qt_cli_Activator_h