From b1edfcc646bcbce9fef2bed8b5843fb50250ca60 Mon Sep 17 00:00:00 2001 From: Botanic Date: Thu, 6 Jun 2013 02:56:48 -0700 Subject: [PATCH 01/10] bad eol --- .../client/client_config_qt/CMakeLists.txt | 114 ++-- .../client_config_qt/client_config_dialog.cpp | 518 ++++++++--------- .../client_config_qt/client_config_dialog.h | 134 ++--- .../tools/client/client_config_qt/config.cpp | 508 ++++++++--------- .../tools/client/client_config_qt/config.h | 240 ++++---- .../display_settings_advanced_widget.cpp | 172 +++--- .../display_settings_advanced_widget.h | 82 +-- .../display_settings_details_widget.cpp | 534 +++++++++--------- .../display_settings_details_widget.h | 242 ++++---- .../display_settings_widget.cpp | 454 +++++++-------- .../display_settings_widget.h | 144 ++--- .../general_settings_widget.cpp | 242 ++++---- .../general_settings_widget.h | 132 ++--- .../tools/client/client_config_qt/main.cpp | 72 +-- .../sound_settings_widget.cpp | 196 +++---- .../client_config_qt/sound_settings_widget.h | 100 ++-- .../client_config_qt/sys_info_d3d_widget.cpp | 82 +-- .../client_config_qt/sys_info_d3d_widget.h | 78 +-- .../sys_info_opengl_widget.cpp | 84 +-- .../client_config_qt/sys_info_opengl_widget.h | 76 +-- .../client_config_qt/sys_info_widget.cpp | 92 +-- .../client/client_config_qt/sys_info_widget.h | 76 +-- .../tools/client/client_config_qt/system.cpp | 360 ++++++------ .../tools/client/client_config_qt/system.h | 224 ++++---- .../client/client_config_qt/widget_base.h | 122 ++-- 25 files changed, 2539 insertions(+), 2539 deletions(-) diff --git a/code/ryzom/tools/client/client_config_qt/CMakeLists.txt b/code/ryzom/tools/client/client_config_qt/CMakeLists.txt index c69bb6aed..87c5d7b05 100644 --- a/code/ryzom/tools/client/client_config_qt/CMakeLists.txt +++ b/code/ryzom/tools/client/client_config_qt/CMakeLists.txt @@ -1,57 +1,57 @@ -INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ${QT_INCLUDES} ) - -FILE( GLOB SRC *.cpp *.h ) - -SET( CLIENT_CONFIG_HDR - client_config_dialog.h - display_settings_advanced_widget.h - display_settings_details_widget.h - display_settings_widget.h - general_settings_widget.h - sound_settings_widget.h - sys_info_d3d_widget.h - sys_info_opengl_widget.h - sys_info_widget.h - widget_base.h -) - -SET( CLIENT_CONFIG_UIS - client_config_dialog.ui - display_settings_advanced_widget.ui - display_settings_details_widget.ui - display_settings_widget.ui - general_settings_widget.ui - sound_settings_widget.ui - sys_info_d3d_widget.ui - sys_info_opengl_widget.ui - sys_info_widget.ui -) - -SET( CLIENT_CONFIG_TRANS - translations/ryzom_configuration_en.ts - translations/ryzom_configuration_hu.ts -) - -CONFIGURE_FILE( translations/translations.qrc ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc COPYONLY ) -SET( CLIENT_CONFIG_RCS resources.qrc ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc ) -SET( QT_USE_QTGUI TRUE ) -SET( QT_USE_QTOPENGL TRUE ) -SET( QT_USE_QTCORE TRUE ) -QT4_ADD_TRANSLATION( CLIENT_CONFIG_QM ${CLIENT_CONFIG_TRANS} ) -QT4_ADD_RESOURCES( CLIENT_CONFIG_RC_SRCS ${CLIENT_CONFIG_RCS} ) -QT4_WRAP_CPP( CLIENT_CONFIG_MOC_SRC ${CLIENT_CONFIG_HDR} ) -QT4_WRAP_UI( CLIENT_CONFIG_UI_HDRS ${CLIENT_CONFIG_UIS} ) -SOURCE_GROUP( "Resources" FILES ${CLIENT_CONFIG_RCS} ) -SOURCE_GROUP( "Forms" FILES ${CLIENT_CONFIG_UIS} ) -SOURCE_GROUP( "Generated Files" FILES ${CLIENT_CONFIG_UI_HDRS} ${CLIENT_CONFIG_MOC_SRC} ) -SOURCE_GROUP( "Translation Files" FILES ${CLIENT_CONFIG_TRANS} ) -ADD_DEFINITIONS( ${QT_DEFINITIONS} ) -ADD_EXECUTABLE( ryzom_configuration_qt WIN32 MACOSX_BUNDLE ${SRC} ${CLIENT_CONFIG_MOC_SRC} ${CLIENT_CONFIG_UI_HDRS} ${CLIENT_CONFIG_RC_SRCS} ${CLIENT_CONFIG_TRANS} ) -NL_DEFAULT_PROPS( ryzom_configuration_qt "Ryzom, Tools: Ryzom Configuration Qt" ) -NL_ADD_RUNTIME_FLAGS( ryzom_configuration_qt ) -NL_ADD_LIB_SUFFIX( ryzom_configuration_qt ) -TARGET_LINK_LIBRARIES( ryzom_configuration_qt nelmisc nel3d ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${OPENGL_gl_LIBRARY} ) -INSTALL( TARGETS ryzom_configuration_qt RUNTIME DESTINATION games COMPONENT client BUNDLE DESTINATION /Applications ) - +INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${QT_INCLUDES} ) + +FILE( GLOB SRC *.cpp *.h ) + +SET( CLIENT_CONFIG_HDR + client_config_dialog.h + display_settings_advanced_widget.h + display_settings_details_widget.h + display_settings_widget.h + general_settings_widget.h + sound_settings_widget.h + sys_info_d3d_widget.h + sys_info_opengl_widget.h + sys_info_widget.h + widget_base.h +) + +SET( CLIENT_CONFIG_UIS + client_config_dialog.ui + display_settings_advanced_widget.ui + display_settings_details_widget.ui + display_settings_widget.ui + general_settings_widget.ui + sound_settings_widget.ui + sys_info_d3d_widget.ui + sys_info_opengl_widget.ui + sys_info_widget.ui +) + +SET( CLIENT_CONFIG_TRANS + translations/ryzom_configuration_en.ts + translations/ryzom_configuration_hu.ts +) + +CONFIGURE_FILE( translations/translations.qrc ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc COPYONLY ) +SET( CLIENT_CONFIG_RCS resources.qrc ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc ) +SET( QT_USE_QTGUI TRUE ) +SET( QT_USE_QTOPENGL TRUE ) +SET( QT_USE_QTCORE TRUE ) +QT4_ADD_TRANSLATION( CLIENT_CONFIG_QM ${CLIENT_CONFIG_TRANS} ) +QT4_ADD_RESOURCES( CLIENT_CONFIG_RC_SRCS ${CLIENT_CONFIG_RCS} ) +QT4_WRAP_CPP( CLIENT_CONFIG_MOC_SRC ${CLIENT_CONFIG_HDR} ) +QT4_WRAP_UI( CLIENT_CONFIG_UI_HDRS ${CLIENT_CONFIG_UIS} ) +SOURCE_GROUP( "Resources" FILES ${CLIENT_CONFIG_RCS} ) +SOURCE_GROUP( "Forms" FILES ${CLIENT_CONFIG_UIS} ) +SOURCE_GROUP( "Generated Files" FILES ${CLIENT_CONFIG_UI_HDRS} ${CLIENT_CONFIG_MOC_SRC} ) +SOURCE_GROUP( "Translation Files" FILES ${CLIENT_CONFIG_TRANS} ) +ADD_DEFINITIONS( ${QT_DEFINITIONS} ) +ADD_EXECUTABLE( ryzom_configuration_qt WIN32 MACOSX_BUNDLE ${SRC} ${CLIENT_CONFIG_MOC_SRC} ${CLIENT_CONFIG_UI_HDRS} ${CLIENT_CONFIG_RC_SRCS} ${CLIENT_CONFIG_TRANS} ) +NL_DEFAULT_PROPS( ryzom_configuration_qt "Ryzom, Tools: Ryzom Configuration Qt" ) +NL_ADD_RUNTIME_FLAGS( ryzom_configuration_qt ) +NL_ADD_LIB_SUFFIX( ryzom_configuration_qt ) +TARGET_LINK_LIBRARIES( ryzom_configuration_qt nelmisc nel3d ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${OPENGL_gl_LIBRARY} ) +INSTALL( TARGETS ryzom_configuration_qt RUNTIME DESTINATION games COMPONENT client BUNDLE DESTINATION /Applications ) + diff --git a/code/ryzom/tools/client/client_config_qt/client_config_dialog.cpp b/code/ryzom/tools/client/client_config_qt/client_config_dialog.cpp index 2f1e2225f..5c6801152 100644 --- a/code/ryzom/tools/client/client_config_qt/client_config_dialog.cpp +++ b/code/ryzom/tools/client/client_config_qt/client_config_dialog.cpp @@ -1,259 +1,259 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "client_config_dialog.h" - -#include "general_settings_widget.h" -#include "display_settings_widget.h" -#include "display_settings_details_widget.h" -#include "display_settings_advanced_widget.h" -#include "sound_settings_widget.h" -#include "sys_info_widget.h" -#include "sys_info_opengl_widget.h" -#include "sys_info_d3d_widget.h" - -#include "system.h" - -#include - -CClientConfigDialog::CClientConfigDialog( QWidget *parent ) : - QDialog( parent ) -{ - setupUi( this ); - connect( buttonBox->button( QDialogButtonBox::Cancel ), SIGNAL( clicked() ), this, SLOT( close() ) ); - connect( buttonBox->button( QDialogButtonBox::Ok ), SIGNAL( clicked() ), this, SLOT( onClickOK() ) ); - connect( applyButton, SIGNAL( clicked() ), this, SLOT( onClickApply() ) ); - connect( defaultButton, SIGNAL( clicked() ), this, SLOT( onClickDefault() ) ); - connect( playButton, SIGNAL( clicked() ), this, SLOT( onClickPlay() ) ); - connect( treeWidget, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ), - this, SLOT( onClickCategory( QTreeWidgetItem * ) ) ); - - // General - QTreeWidgetItem *item = treeWidget->topLevelItem( 0 ); - item->setData( 0, Qt::UserRole, 0 ); - - // Display - item = treeWidget->topLevelItem( 1 ); - item->setData( 0, Qt::UserRole, 1 ); - - // Display details - item = treeWidget->topLevelItem( 1 )->child( 0 ); - item->setData( 0, Qt::UserRole, 2 ); - - // Display advanced - item = treeWidget->topLevelItem( 1 )->child( 1 ); - item->setData( 0, Qt::UserRole, 3 ); - - // Sound - item = treeWidget->topLevelItem( 2 ); - item->setData( 0, Qt::UserRole, 4 ); - - // System information - item = treeWidget->topLevelItem( 3 ); - item->setData( 0, Qt::UserRole, 5 ); - - // OpenGL info - item = treeWidget->topLevelItem( 3 )->child( 0 ); - item->setData( 0, Qt::UserRole, 6 ); - - // Direct3D info - item = treeWidget->topLevelItem( 3 )->child( 1 ); - item->setData( 0, Qt::UserRole, 7 ); - - - CategoryStackedWidget->addWidget( new CGeneralSettingsWidget( CategoryStackedWidget ) ); - CategoryStackedWidget->addWidget( new CDisplaySettingsWidget( CategoryStackedWidget ) ); - CategoryStackedWidget->addWidget( new CDisplaySettingsDetailsWidget( CategoryStackedWidget ) ); - CategoryStackedWidget->addWidget( new CDisplaySettingsAdvancedWidget( CategoryStackedWidget ) ); - CategoryStackedWidget->addWidget( new CSoundSettingsWidget( CategoryStackedWidget ) ); - CategoryStackedWidget->addWidget( new CSysInfoWidget( CategoryStackedWidget ) ); - CategoryStackedWidget->addWidget( new CSysInfoOpenGLWidget( CategoryStackedWidget ) ); - CategoryStackedWidget->addWidget( new CSysInfoD3DWidget( CategoryStackedWidget ) ); - - for( sint32 i = 0; i < CategoryStackedWidget->count(); i++ ) - { - QWidget *w = CategoryStackedWidget->widget( i ); - - // The sysinfo pages are not derived from CWidgetBase, so they don't have this signal! - if( qobject_cast< CWidgetBase * >( w ) == NULL ) - continue; - - connect( w, SIGNAL( changed() ), this, SLOT( onSomethingChanged() ) ); - } - - applyButton->setEnabled( false ); -} - -CClientConfigDialog::~CClientConfigDialog() -{ -} - -void CClientConfigDialog::closeEvent( QCloseEvent *event ) -{ - if( isOKToQuit() ) - event->accept(); - else - event->ignore(); -} - -void CClientConfigDialog::changeEvent( QEvent *event ) -{ - if( event->type() == QEvent::LanguageChange ) - { - int pageIndex = CategoryStackedWidget->currentIndex(); - // Signals that are emitted on index change need to be disconnected, since retranslation cleans the widget - disconnect( treeWidget, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ), - this, SLOT( onClickCategory( QTreeWidgetItem * ) ) ); - - retranslateUi( this ); - - connect( treeWidget, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ), - this, SLOT( onClickCategory( QTreeWidgetItem * ) ) ); - - CategoryStackedWidget->setCurrentIndex( pageIndex ); - } - - QDialog::changeEvent( event ); -} - -void CClientConfigDialog::onClickOK() -{ - saveChanges(); - // Since we use the apply button's enabled state to check for unsaved changes on quit, we disable it - applyButton->setEnabled( false ); - close(); -} - -void CClientConfigDialog::onClickApply() -{ - saveChanges(); - applyButton->setEnabled( false ); -} - -void CClientConfigDialog::onClickDefault() -{ - CSystem::GetInstance().config.revertToDefault(); - CSystem::GetInstance().config.save(); - reloadPages(); - applyButton->setEnabled( false ); -} - -void CClientConfigDialog::onClickPlay() -{ - bool started = false; - -#ifdef WIN32 - started = QProcess::startDetached( "ryzom_client_r.exe" ); - if( !started ) - QProcess::startDetached( "ryzom_client_rd.exe" ); - if( !started ) - QProcess::startDetached( "ryzom_client_d.exe" ); -#else - started = QProcess::startDetached( "./ryzom_client_r" ); - if( !started ) - QProcess::startDetached( "./ryzom_client_rd" ); - if( !started ) - QProcess::startDetached( "./ryzom_client_d" ); -#endif - - onClickOK(); -} - -void CClientConfigDialog::onClickCategory( QTreeWidgetItem *item ) -{ - if( item == NULL ) - return; - - static const char *iconNames[] = - { - ":/resources/general_icon.bmp", - ":/resources/display_icon.bmp", - ":/resources/display_properties_icon.bmp", - ":/resources/display_config_icon.bmp", - ":/resources/sound_icon.bmp", - ":/resources/general_icon.bmp", - ":/resources/card_icon.bmp", - ":/resources/card_icon.bmp" - }; - - sint32 index = item->data( 0, Qt::UserRole ).toInt(); - - if( ( index < 0 ) || ( index > 7 ) ) - return; - - CategoryStackedWidget->setCurrentIndex( index ); - categoryLabel->setText( item->text( 0 ) ); - topleftIcon->setPixmap( QPixmap( QString::fromUtf8( iconNames[ index ] ) ) ); -} - -void CClientConfigDialog::onSomethingChanged() -{ - applyButton->setEnabled( true ); -} - -void CClientConfigDialog::saveChanges() -{ - // First we tell the pages to save their changes into the cached config file - for( sint32 i = 0; i < CategoryStackedWidget->count(); i++ ) - { - QWidget *w = CategoryStackedWidget->widget( i ); - CWidgetBase *wb = qobject_cast< CWidgetBase * >( w ); - - // The system information pages are not derived from CWidgetBase, so they can't save! - if( wb == NULL ) - continue; - - wb->save(); - } - - // Then we write the cache to the disk - CSystem::GetInstance().config.save(); -} - -void CClientConfigDialog::reloadPages() -{ - for( sint32 i = 0; i < CategoryStackedWidget->count(); i++ ) - { - QWidget *w = CategoryStackedWidget->widget( i ); - CWidgetBase *wb = qobject_cast< CWidgetBase * >( w ); - - // The system information pages are not derived from CWidgetBase, so they can't load! - if( wb == NULL ) - continue; - - wb->load(); - } -} - -bool CClientConfigDialog::isOKToQuit() -{ - // If the apply button is enabled we have unsaved changes - if( applyButton->isEnabled() ) - { - sint32 r = QMessageBox::warning( - this, - tr( "Ryzom configuration" ), - tr( "Are you sure you want to quit without saving the configuration?" ), - QMessageBox::Yes | QMessageBox::No - ); - - if( r == QMessageBox::No ) - return false; - } - - return true; -} - +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "client_config_dialog.h" + +#include "general_settings_widget.h" +#include "display_settings_widget.h" +#include "display_settings_details_widget.h" +#include "display_settings_advanced_widget.h" +#include "sound_settings_widget.h" +#include "sys_info_widget.h" +#include "sys_info_opengl_widget.h" +#include "sys_info_d3d_widget.h" + +#include "system.h" + +#include + +CClientConfigDialog::CClientConfigDialog( QWidget *parent ) : + QDialog( parent ) +{ + setupUi( this ); + connect( buttonBox->button( QDialogButtonBox::Cancel ), SIGNAL( clicked() ), this, SLOT( close() ) ); + connect( buttonBox->button( QDialogButtonBox::Ok ), SIGNAL( clicked() ), this, SLOT( onClickOK() ) ); + connect( applyButton, SIGNAL( clicked() ), this, SLOT( onClickApply() ) ); + connect( defaultButton, SIGNAL( clicked() ), this, SLOT( onClickDefault() ) ); + connect( playButton, SIGNAL( clicked() ), this, SLOT( onClickPlay() ) ); + connect( treeWidget, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ), + this, SLOT( onClickCategory( QTreeWidgetItem * ) ) ); + + // General + QTreeWidgetItem *item = treeWidget->topLevelItem( 0 ); + item->setData( 0, Qt::UserRole, 0 ); + + // Display + item = treeWidget->topLevelItem( 1 ); + item->setData( 0, Qt::UserRole, 1 ); + + // Display details + item = treeWidget->topLevelItem( 1 )->child( 0 ); + item->setData( 0, Qt::UserRole, 2 ); + + // Display advanced + item = treeWidget->topLevelItem( 1 )->child( 1 ); + item->setData( 0, Qt::UserRole, 3 ); + + // Sound + item = treeWidget->topLevelItem( 2 ); + item->setData( 0, Qt::UserRole, 4 ); + + // System information + item = treeWidget->topLevelItem( 3 ); + item->setData( 0, Qt::UserRole, 5 ); + + // OpenGL info + item = treeWidget->topLevelItem( 3 )->child( 0 ); + item->setData( 0, Qt::UserRole, 6 ); + + // Direct3D info + item = treeWidget->topLevelItem( 3 )->child( 1 ); + item->setData( 0, Qt::UserRole, 7 ); + + + CategoryStackedWidget->addWidget( new CGeneralSettingsWidget( CategoryStackedWidget ) ); + CategoryStackedWidget->addWidget( new CDisplaySettingsWidget( CategoryStackedWidget ) ); + CategoryStackedWidget->addWidget( new CDisplaySettingsDetailsWidget( CategoryStackedWidget ) ); + CategoryStackedWidget->addWidget( new CDisplaySettingsAdvancedWidget( CategoryStackedWidget ) ); + CategoryStackedWidget->addWidget( new CSoundSettingsWidget( CategoryStackedWidget ) ); + CategoryStackedWidget->addWidget( new CSysInfoWidget( CategoryStackedWidget ) ); + CategoryStackedWidget->addWidget( new CSysInfoOpenGLWidget( CategoryStackedWidget ) ); + CategoryStackedWidget->addWidget( new CSysInfoD3DWidget( CategoryStackedWidget ) ); + + for( sint32 i = 0; i < CategoryStackedWidget->count(); i++ ) + { + QWidget *w = CategoryStackedWidget->widget( i ); + + // The sysinfo pages are not derived from CWidgetBase, so they don't have this signal! + if( qobject_cast< CWidgetBase * >( w ) == NULL ) + continue; + + connect( w, SIGNAL( changed() ), this, SLOT( onSomethingChanged() ) ); + } + + applyButton->setEnabled( false ); +} + +CClientConfigDialog::~CClientConfigDialog() +{ +} + +void CClientConfigDialog::closeEvent( QCloseEvent *event ) +{ + if( isOKToQuit() ) + event->accept(); + else + event->ignore(); +} + +void CClientConfigDialog::changeEvent( QEvent *event ) +{ + if( event->type() == QEvent::LanguageChange ) + { + int pageIndex = CategoryStackedWidget->currentIndex(); + // Signals that are emitted on index change need to be disconnected, since retranslation cleans the widget + disconnect( treeWidget, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ), + this, SLOT( onClickCategory( QTreeWidgetItem * ) ) ); + + retranslateUi( this ); + + connect( treeWidget, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ), + this, SLOT( onClickCategory( QTreeWidgetItem * ) ) ); + + CategoryStackedWidget->setCurrentIndex( pageIndex ); + } + + QDialog::changeEvent( event ); +} + +void CClientConfigDialog::onClickOK() +{ + saveChanges(); + // Since we use the apply button's enabled state to check for unsaved changes on quit, we disable it + applyButton->setEnabled( false ); + close(); +} + +void CClientConfigDialog::onClickApply() +{ + saveChanges(); + applyButton->setEnabled( false ); +} + +void CClientConfigDialog::onClickDefault() +{ + CSystem::GetInstance().config.revertToDefault(); + CSystem::GetInstance().config.save(); + reloadPages(); + applyButton->setEnabled( false ); +} + +void CClientConfigDialog::onClickPlay() +{ + bool started = false; + +#ifdef WIN32 + started = QProcess::startDetached( "ryzom_client_r.exe" ); + if( !started ) + QProcess::startDetached( "ryzom_client_rd.exe" ); + if( !started ) + QProcess::startDetached( "ryzom_client_d.exe" ); +#else + started = QProcess::startDetached( "./ryzom_client_r" ); + if( !started ) + QProcess::startDetached( "./ryzom_client_rd" ); + if( !started ) + QProcess::startDetached( "./ryzom_client_d" ); +#endif + + onClickOK(); +} + +void CClientConfigDialog::onClickCategory( QTreeWidgetItem *item ) +{ + if( item == NULL ) + return; + + static const char *iconNames[] = + { + ":/resources/general_icon.bmp", + ":/resources/display_icon.bmp", + ":/resources/display_properties_icon.bmp", + ":/resources/display_config_icon.bmp", + ":/resources/sound_icon.bmp", + ":/resources/general_icon.bmp", + ":/resources/card_icon.bmp", + ":/resources/card_icon.bmp" + }; + + sint32 index = item->data( 0, Qt::UserRole ).toInt(); + + if( ( index < 0 ) || ( index > 7 ) ) + return; + + CategoryStackedWidget->setCurrentIndex( index ); + categoryLabel->setText( item->text( 0 ) ); + topleftIcon->setPixmap( QPixmap( QString::fromUtf8( iconNames[ index ] ) ) ); +} + +void CClientConfigDialog::onSomethingChanged() +{ + applyButton->setEnabled( true ); +} + +void CClientConfigDialog::saveChanges() +{ + // First we tell the pages to save their changes into the cached config file + for( sint32 i = 0; i < CategoryStackedWidget->count(); i++ ) + { + QWidget *w = CategoryStackedWidget->widget( i ); + CWidgetBase *wb = qobject_cast< CWidgetBase * >( w ); + + // The system information pages are not derived from CWidgetBase, so they can't save! + if( wb == NULL ) + continue; + + wb->save(); + } + + // Then we write the cache to the disk + CSystem::GetInstance().config.save(); +} + +void CClientConfigDialog::reloadPages() +{ + for( sint32 i = 0; i < CategoryStackedWidget->count(); i++ ) + { + QWidget *w = CategoryStackedWidget->widget( i ); + CWidgetBase *wb = qobject_cast< CWidgetBase * >( w ); + + // The system information pages are not derived from CWidgetBase, so they can't load! + if( wb == NULL ) + continue; + + wb->load(); + } +} + +bool CClientConfigDialog::isOKToQuit() +{ + // If the apply button is enabled we have unsaved changes + if( applyButton->isEnabled() ) + { + sint32 r = QMessageBox::warning( + this, + tr( "Ryzom configuration" ), + tr( "Are you sure you want to quit without saving the configuration?" ), + QMessageBox::Yes | QMessageBox::No + ); + + if( r == QMessageBox::No ) + return false; + } + + return true; +} + diff --git a/code/ryzom/tools/client/client_config_qt/client_config_dialog.h b/code/ryzom/tools/client/client_config_qt/client_config_dialog.h index f4902b3f3..d9855afc0 100644 --- a/code/ryzom/tools/client/client_config_qt/client_config_dialog.h +++ b/code/ryzom/tools/client/client_config_qt/client_config_dialog.h @@ -1,67 +1,67 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef CLIENT_CONFIG_DIALOG_H -#define CLIENT_CONFIG_DIALOG_H - -#include "ui_client_config_dialog.h" - -/** - @brief The main dialog of the configuration tool - @details Sets up and controls the configuration pages, sets up navigation, - sets up the ok, cancel, apply, etc buttons. -*/ -class CClientConfigDialog : public QDialog, public Ui::client_config_dialog -{ - Q_OBJECT - -public: - CClientConfigDialog( QWidget *parent = NULL ); - ~CClientConfigDialog(); - -protected: - void closeEvent( QCloseEvent *event ); - void changeEvent( QEvent *event ); - -private slots: - //////////////////////////// Main dialog buttons ///////////////////// - void onClickOK(); - void onClickApply(); - void onClickDefault(); - void onClickPlay(); - ////////////////////////////////////////////////////////////////////// - void onClickCategory( QTreeWidgetItem *item ); - void onSomethingChanged(); - -private: - /** - @brief Tells the config pages to save their changes into the config file - */ - void saveChanges(); - - /** - @brief Reloads the pages' contents from the config file. - */ - void reloadPages(); - - /** - @brief Checks if it's OK to quit the application, may query the user - @return Returns true if it's OK to quit, returns false otherwise. - */ - bool isOKToQuit(); -}; - -#endif // CLIENT_CONFIG_DIALOG_H +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CLIENT_CONFIG_DIALOG_H +#define CLIENT_CONFIG_DIALOG_H + +#include "ui_client_config_dialog.h" + +/** + @brief The main dialog of the configuration tool + @details Sets up and controls the configuration pages, sets up navigation, + sets up the ok, cancel, apply, etc buttons. +*/ +class CClientConfigDialog : public QDialog, public Ui::client_config_dialog +{ + Q_OBJECT + +public: + CClientConfigDialog( QWidget *parent = NULL ); + ~CClientConfigDialog(); + +protected: + void closeEvent( QCloseEvent *event ); + void changeEvent( QEvent *event ); + +private slots: + //////////////////////////// Main dialog buttons ///////////////////// + void onClickOK(); + void onClickApply(); + void onClickDefault(); + void onClickPlay(); + ////////////////////////////////////////////////////////////////////// + void onClickCategory( QTreeWidgetItem *item ); + void onSomethingChanged(); + +private: + /** + @brief Tells the config pages to save their changes into the config file + */ + void saveChanges(); + + /** + @brief Reloads the pages' contents from the config file. + */ + void reloadPages(); + + /** + @brief Checks if it's OK to quit the application, may query the user + @return Returns true if it's OK to quit, returns false otherwise. + */ + bool isOKToQuit(); +}; + +#endif // CLIENT_CONFIG_DIALOG_H diff --git a/code/ryzom/tools/client/client_config_qt/config.cpp b/code/ryzom/tools/client/client_config_qt/config.cpp index f215a87ff..93a757b27 100644 --- a/code/ryzom/tools/client/client_config_qt/config.cpp +++ b/code/ryzom/tools/client/client_config_qt/config.cpp @@ -1,255 +1,255 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "Config.h" - -CConfig::CConfig() -{ -} - -CConfig::~CConfig() -{ -} - -bool CConfig::load( const char *fileName ) -{ - try - { - cf.load( fileName ); - - std::string def = getString( "RootConfigFilename" ); - if( def.compare( "" ) != 0 ) - dcf.load( def ); - } - catch( NLMISC::Exception &e ) - { - nlwarning( "%s", e.what() ); - return false; - } - - return true; -} - -bool CConfig::reload() -{ - try - { - cf.clear(); - cf.reparse(); - } - catch( NLMISC::Exception &e ) - { - nlwarning( "%s", e.what() ); - return false; - } - return true; -} - -void CConfig::revertToDefault() -{ - // If there's no default config, all we can do is revert the current changes - if( !dcf.loaded() ) - { - reload(); - return; - } - - // If there is a default config, we can however revert to the default! - // Code taken from the original config tool - uint32 count = cf.getNumVar(); - uint32 i = 0; - for( i = 0; i < count; i++ ) - { - NLMISC::CConfigFile::CVar *dst = cf.getVar( i ); - - // Comment from the original - // Temp: avoid changing this variable (debug: binded to the actual texture set installed) - if( dst->Name.compare( "HDTextureInstalled" ) == 0 ) - continue; - - NLMISC::CConfigFile::CVar *src = dcf.getVarPtr( dst->Name ); - if( ( src != NULL ) && !dst->Root && - ( ( src->Type == NLMISC::CConfigFile::CVar::T_INT ) && ( dst->Type == NLMISC::CConfigFile::CVar::T_INT ) || - ( src->Type == NLMISC::CConfigFile::CVar::T_REAL ) && ( dst->Type == NLMISC::CConfigFile::CVar::T_INT ) || - ( src->Type == NLMISC::CConfigFile::CVar::T_INT ) && ( dst->Type == NLMISC::CConfigFile::CVar::T_REAL ) || - ( src->Type == NLMISC::CConfigFile::CVar::T_REAL ) && ( dst->Type == NLMISC::CConfigFile::CVar::T_REAL ) || - ( src->Type == NLMISC::CConfigFile::CVar::T_STRING ) && ( dst->Type == NLMISC::CConfigFile::CVar::T_STRING ) ) ) - { - - if( src->Type == NLMISC::CConfigFile::CVar::T_INT ) - { - setInt( src->Name.c_str(), src->asInt() ); - } - else if( src->Type == NLMISC::CConfigFile::CVar::T_REAL ) - { - setFloat( src->Name.c_str(), src->asFloat() ); - } - else if( src->Type == NLMISC::CConfigFile::CVar::T_STRING ) - { - setString( src->Name.c_str(), src->asString() ); - } - } - } -} - -bool CConfig::save() -{ - try - { - cf.save(); - } - catch( NLMISC::Exception &e ) - { - nlwarning( "%s", e.what() ); - return false; - } - return true; -} - -bool CConfig::getBool( const char *key ) -{ - NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); - - if( var != NULL ) - { - return var->asBool(); - } - else - { - nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); - return false; - } -} - -sint32 CConfig::getInt( const char *key ) -{ - NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); - - if( var != NULL ) - { - return var->asInt(); - } - else - { - nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); - return 0; - } -} - -float CConfig::getFloat( const char *key ) -{ - NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); - - if( var != NULL ) - { - return var->asFloat(); - } - else - { - nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); - return 0.0f; - } -} - -std::string CConfig::getString( const char *key ) -{ - NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); - - if( var != NULL ) - { - return var->asString(); - } - else - { - nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); - return ""; - } -} - -void CConfig::setBool( const char *key, bool value ) -{ - NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); - - if( var != NULL ) - { - if( var->Type == NLMISC::CConfigFile::CVar::T_BOOL ) - { - if( value ) - var->setAsString( "true" ); - else - var->setAsString( "false" ); - } - else - { - nlwarning( "Key %s in %s is not a boolean.", key, cf.getFilename().c_str() ); - } - } - else - { - nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); - } -} - -void CConfig::setInt(const char *key, sint32 value) -{ - NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); - - if( var != NULL ) - { - if( var->Type == NLMISC::CConfigFile::CVar::T_INT ) - var->setAsInt( value ); - else - nlwarning( "Key %s in %s is not an integer.", key, cf.getFilename().c_str() ); - } - else - { - nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); - } -} - -void CConfig::setFloat( const char *key, float value ) -{ - NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); - - if( var != NULL ) - { - if( var->Type == NLMISC::CConfigFile::CVar::T_REAL ) - var->setAsFloat( value ); - else - nlwarning( "Key %s in %s is not a float.", key, cf.getFilename().c_str() ); - } - else - { - nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); - } -} - -void CConfig::setString( const char *key, std::string &value ) -{ - NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); - - if( var != NULL ) - { - if( var->Type == NLMISC::CConfigFile::CVar::T_STRING ) - var->setAsString( value ); - else - nlwarning( "Key %s in %s is not a string.", key, cf.getFilename().c_str() ); - } - else - { - nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); - } +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "Config.h" + +CConfig::CConfig() +{ +} + +CConfig::~CConfig() +{ +} + +bool CConfig::load( const char *fileName ) +{ + try + { + cf.load( fileName ); + + std::string def = getString( "RootConfigFilename" ); + if( def.compare( "" ) != 0 ) + dcf.load( def ); + } + catch( NLMISC::Exception &e ) + { + nlwarning( "%s", e.what() ); + return false; + } + + return true; +} + +bool CConfig::reload() +{ + try + { + cf.clear(); + cf.reparse(); + } + catch( NLMISC::Exception &e ) + { + nlwarning( "%s", e.what() ); + return false; + } + return true; +} + +void CConfig::revertToDefault() +{ + // If there's no default config, all we can do is revert the current changes + if( !dcf.loaded() ) + { + reload(); + return; + } + + // If there is a default config, we can however revert to the default! + // Code taken from the original config tool + uint32 count = cf.getNumVar(); + uint32 i = 0; + for( i = 0; i < count; i++ ) + { + NLMISC::CConfigFile::CVar *dst = cf.getVar( i ); + + // Comment from the original + // Temp: avoid changing this variable (debug: binded to the actual texture set installed) + if( dst->Name.compare( "HDTextureInstalled" ) == 0 ) + continue; + + NLMISC::CConfigFile::CVar *src = dcf.getVarPtr( dst->Name ); + if( ( src != NULL ) && !dst->Root && + ( ( src->Type == NLMISC::CConfigFile::CVar::T_INT ) && ( dst->Type == NLMISC::CConfigFile::CVar::T_INT ) || + ( src->Type == NLMISC::CConfigFile::CVar::T_REAL ) && ( dst->Type == NLMISC::CConfigFile::CVar::T_INT ) || + ( src->Type == NLMISC::CConfigFile::CVar::T_INT ) && ( dst->Type == NLMISC::CConfigFile::CVar::T_REAL ) || + ( src->Type == NLMISC::CConfigFile::CVar::T_REAL ) && ( dst->Type == NLMISC::CConfigFile::CVar::T_REAL ) || + ( src->Type == NLMISC::CConfigFile::CVar::T_STRING ) && ( dst->Type == NLMISC::CConfigFile::CVar::T_STRING ) ) ) + { + + if( src->Type == NLMISC::CConfigFile::CVar::T_INT ) + { + setInt( src->Name.c_str(), src->asInt() ); + } + else if( src->Type == NLMISC::CConfigFile::CVar::T_REAL ) + { + setFloat( src->Name.c_str(), src->asFloat() ); + } + else if( src->Type == NLMISC::CConfigFile::CVar::T_STRING ) + { + setString( src->Name.c_str(), src->asString() ); + } + } + } +} + +bool CConfig::save() +{ + try + { + cf.save(); + } + catch( NLMISC::Exception &e ) + { + nlwarning( "%s", e.what() ); + return false; + } + return true; +} + +bool CConfig::getBool( const char *key ) +{ + NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); + + if( var != NULL ) + { + return var->asBool(); + } + else + { + nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); + return false; + } +} + +sint32 CConfig::getInt( const char *key ) +{ + NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); + + if( var != NULL ) + { + return var->asInt(); + } + else + { + nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); + return 0; + } +} + +float CConfig::getFloat( const char *key ) +{ + NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); + + if( var != NULL ) + { + return var->asFloat(); + } + else + { + nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); + return 0.0f; + } +} + +std::string CConfig::getString( const char *key ) +{ + NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); + + if( var != NULL ) + { + return var->asString(); + } + else + { + nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); + return ""; + } +} + +void CConfig::setBool( const char *key, bool value ) +{ + NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); + + if( var != NULL ) + { + if( var->Type == NLMISC::CConfigFile::CVar::T_BOOL ) + { + if( value ) + var->setAsString( "true" ); + else + var->setAsString( "false" ); + } + else + { + nlwarning( "Key %s in %s is not a boolean.", key, cf.getFilename().c_str() ); + } + } + else + { + nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); + } +} + +void CConfig::setInt(const char *key, sint32 value) +{ + NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); + + if( var != NULL ) + { + if( var->Type == NLMISC::CConfigFile::CVar::T_INT ) + var->setAsInt( value ); + else + nlwarning( "Key %s in %s is not an integer.", key, cf.getFilename().c_str() ); + } + else + { + nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); + } +} + +void CConfig::setFloat( const char *key, float value ) +{ + NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); + + if( var != NULL ) + { + if( var->Type == NLMISC::CConfigFile::CVar::T_REAL ) + var->setAsFloat( value ); + else + nlwarning( "Key %s in %s is not a float.", key, cf.getFilename().c_str() ); + } + else + { + nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); + } +} + +void CConfig::setString( const char *key, std::string &value ) +{ + NLMISC::CConfigFile::CVar *var = cf.getVarPtr( key ); + + if( var != NULL ) + { + if( var->Type == NLMISC::CConfigFile::CVar::T_STRING ) + var->setAsString( value ); + else + nlwarning( "Key %s in %s is not a string.", key, cf.getFilename().c_str() ); + } + else + { + nlwarning( "Couldn't find key %s in %s.", key, cf.getFilename().c_str() ); + } } \ No newline at end of file diff --git a/code/ryzom/tools/client/client_config_qt/config.h b/code/ryzom/tools/client/client_config_qt/config.h index 7749b41b1..df48e19e0 100644 --- a/code/ryzom/tools/client/client_config_qt/config.h +++ b/code/ryzom/tools/client/client_config_qt/config.h @@ -1,120 +1,120 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef CONFIG_H -#define CONFIG_H - -#include - -/** - @brief Wrapper for a Ryzom config file, allows setting and querying values. -*/ -class CConfig -{ -public: - CConfig(); - ~CConfig(); - - /** - @brief Loads a config file. - @param fileName - The file to load - @return Returns true on success, returns false on failure. - */ - bool load( const char *fileName ); - - /** - @brief Reloads the contents of the config file - @return Return true on success, returns false on failure. - */ - bool reload(); - - /** - @brief Reverts the config file to the default - @details Reverts the config file to the default if possible. - If there is no default config, it reverts the current changes only. - */ - void revertToDefault(); - - /** - @brief Saves the configuration to the config file. - @return Returns true on success, returns false on failure. - */ - bool save(); - - /** - @brief Queries the value for the specified key. - @param key - The key we are interested in - @return Returns the value as a bool, returns false if the key doesn't exist. - */ - bool getBool( const char *key ); - - /** - @brief Queries the value for the specified key. - @param key - The key we are interested in - @return Returns the value as an integer, returns 0 if the key doesn't exist. - */ - sint32 getInt( const char *key ); - - /** - @brief Queries the value for the specified key. - @param key - The key we are interested in - @return Returns the value as a float, returns 0.0f if the key doesn't exist. - */ - float getFloat( const char *key ); - - /** - @brief Queries the value for the specified key. - @param key - The key we are interested in - @return Returns the value as a std::string, returns an empty string if the key doesn't exist. - */ - std::string getString( const char *key ); - - /** - @brief Sets the specified key to the specified value. - @param key - the key we want to alter - @param value - the value we want to set - */ - void setBool( const char *key, bool value ); - - /** - @brief Sets the specified key to the specified value. - @param key - the key we want to alter - @param value - the value we want to set - */ - void setInt( const char *key, sint32 value ); - - /** - @brief Sets the specified key to the specified value. - @param key - the key we want to alter - @param value - the value we want to set - */ - void setFloat( const char *key, float value ); - - /** - @brief Sets the specified key to the specified value. - @param key - the key we want to alter - @param value - the value we want to set - */ - void setString( const char *key, std::string &value ); - -private: - // config file - NLMISC::CConfigFile cf; - // default config file - NLMISC::CConfigFile dcf; -}; - -#endif +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CONFIG_H +#define CONFIG_H + +#include + +/** + @brief Wrapper for a Ryzom config file, allows setting and querying values. +*/ +class CConfig +{ +public: + CConfig(); + ~CConfig(); + + /** + @brief Loads a config file. + @param fileName - The file to load + @return Returns true on success, returns false on failure. + */ + bool load( const char *fileName ); + + /** + @brief Reloads the contents of the config file + @return Return true on success, returns false on failure. + */ + bool reload(); + + /** + @brief Reverts the config file to the default + @details Reverts the config file to the default if possible. + If there is no default config, it reverts the current changes only. + */ + void revertToDefault(); + + /** + @brief Saves the configuration to the config file. + @return Returns true on success, returns false on failure. + */ + bool save(); + + /** + @brief Queries the value for the specified key. + @param key - The key we are interested in + @return Returns the value as a bool, returns false if the key doesn't exist. + */ + bool getBool( const char *key ); + + /** + @brief Queries the value for the specified key. + @param key - The key we are interested in + @return Returns the value as an integer, returns 0 if the key doesn't exist. + */ + sint32 getInt( const char *key ); + + /** + @brief Queries the value for the specified key. + @param key - The key we are interested in + @return Returns the value as a float, returns 0.0f if the key doesn't exist. + */ + float getFloat( const char *key ); + + /** + @brief Queries the value for the specified key. + @param key - The key we are interested in + @return Returns the value as a std::string, returns an empty string if the key doesn't exist. + */ + std::string getString( const char *key ); + + /** + @brief Sets the specified key to the specified value. + @param key - the key we want to alter + @param value - the value we want to set + */ + void setBool( const char *key, bool value ); + + /** + @brief Sets the specified key to the specified value. + @param key - the key we want to alter + @param value - the value we want to set + */ + void setInt( const char *key, sint32 value ); + + /** + @brief Sets the specified key to the specified value. + @param key - the key we want to alter + @param value - the value we want to set + */ + void setFloat( const char *key, float value ); + + /** + @brief Sets the specified key to the specified value. + @param key - the key we want to alter + @param value - the value we want to set + */ + void setString( const char *key, std::string &value ); + +private: + // config file + NLMISC::CConfigFile cf; + // default config file + NLMISC::CConfigFile dcf; +}; + +#endif diff --git a/code/ryzom/tools/client/client_config_qt/display_settings_advanced_widget.cpp b/code/ryzom/tools/client/client_config_qt/display_settings_advanced_widget.cpp index 7f324f40c..211a4911b 100644 --- a/code/ryzom/tools/client/client_config_qt/display_settings_advanced_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/display_settings_advanced_widget.cpp @@ -1,86 +1,86 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "display_settings_advanced_widget.h" -#include "system.h" - -CDisplaySettingsAdvancedWidget::CDisplaySettingsAdvancedWidget( QWidget *parent ) : - CWidgetBase( parent ) -{ - setupUi( this ); - load(); - - connect( texcompressionCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); - connect( vertexshaderCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); - connect( verticesagpCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); - connect( pixelshadersCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); -} - -CDisplaySettingsAdvancedWidget::~CDisplaySettingsAdvancedWidget() -{ -} - -void CDisplaySettingsAdvancedWidget::load() -{ - CSystem &s = CSystem::GetInstance(); - - if( s.config.getInt( "ForceDXTC" ) == 1 ) - texcompressionCheckBox->setChecked( true ); - - if( s.config.getInt( "DisableVtxProgram" ) == 1 ) - vertexshaderCheckBox->setChecked( true ); - - if( s.config.getInt( "DisableVtxAGP" ) == 1 ) - verticesagpCheckBox->setChecked( true ); - - if( s.config.getInt( "DisableTextureShdr" ) == 1 ) - pixelshadersCheckBox->setChecked( true ); -} - -void CDisplaySettingsAdvancedWidget::save() -{ - CSystem &s = CSystem::GetInstance(); - - if( texcompressionCheckBox->isChecked() ) - s.config.setInt( "ForceDXTC", 1 ); - else - s.config.setInt( "ForceDXTC", 0 ); - - if( vertexshaderCheckBox->isChecked() ) - s.config.setInt( "DisableVtxProgram", 1 ); - else - s.config.setInt( "DisableVtxProgram", 0 ); - - if( verticesagpCheckBox->isChecked() ) - s.config.setInt( "DisableVtxAGP", 1 ); - else - s.config.setInt( "DisableVtxAGP", 0 ); - - if( pixelshadersCheckBox->isChecked() ) - s.config.setInt( "DisableTextureShdr", 1 ); - else - s.config.setInt( "DisableTextureShdr", 0 ); -} - -void CDisplaySettingsAdvancedWidget::changeEvent( QEvent *event ) -{ - if( event->type() == QEvent::LanguageChange ) - { - retranslateUi( this ); - } - - QWidget::changeEvent( event ); -} +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "display_settings_advanced_widget.h" +#include "system.h" + +CDisplaySettingsAdvancedWidget::CDisplaySettingsAdvancedWidget( QWidget *parent ) : + CWidgetBase( parent ) +{ + setupUi( this ); + load(); + + connect( texcompressionCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); + connect( vertexshaderCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); + connect( verticesagpCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); + connect( pixelshadersCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); +} + +CDisplaySettingsAdvancedWidget::~CDisplaySettingsAdvancedWidget() +{ +} + +void CDisplaySettingsAdvancedWidget::load() +{ + CSystem &s = CSystem::GetInstance(); + + if( s.config.getInt( "ForceDXTC" ) == 1 ) + texcompressionCheckBox->setChecked( true ); + + if( s.config.getInt( "DisableVtxProgram" ) == 1 ) + vertexshaderCheckBox->setChecked( true ); + + if( s.config.getInt( "DisableVtxAGP" ) == 1 ) + verticesagpCheckBox->setChecked( true ); + + if( s.config.getInt( "DisableTextureShdr" ) == 1 ) + pixelshadersCheckBox->setChecked( true ); +} + +void CDisplaySettingsAdvancedWidget::save() +{ + CSystem &s = CSystem::GetInstance(); + + if( texcompressionCheckBox->isChecked() ) + s.config.setInt( "ForceDXTC", 1 ); + else + s.config.setInt( "ForceDXTC", 0 ); + + if( vertexshaderCheckBox->isChecked() ) + s.config.setInt( "DisableVtxProgram", 1 ); + else + s.config.setInt( "DisableVtxProgram", 0 ); + + if( verticesagpCheckBox->isChecked() ) + s.config.setInt( "DisableVtxAGP", 1 ); + else + s.config.setInt( "DisableVtxAGP", 0 ); + + if( pixelshadersCheckBox->isChecked() ) + s.config.setInt( "DisableTextureShdr", 1 ); + else + s.config.setInt( "DisableTextureShdr", 0 ); +} + +void CDisplaySettingsAdvancedWidget::changeEvent( QEvent *event ) +{ + if( event->type() == QEvent::LanguageChange ) + { + retranslateUi( this ); + } + + QWidget::changeEvent( event ); +} diff --git a/code/ryzom/tools/client/client_config_qt/display_settings_advanced_widget.h b/code/ryzom/tools/client/client_config_qt/display_settings_advanced_widget.h index 92ca1775a..3f956f626 100644 --- a/code/ryzom/tools/client/client_config_qt/display_settings_advanced_widget.h +++ b/code/ryzom/tools/client/client_config_qt/display_settings_advanced_widget.h @@ -1,41 +1,41 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef DISPLAYSETTINGSADVANCEDWIDGET_H -#define DISPLAYSETTINGSADVANCEDWIDGET_H - -#include "ui_display_settings_advanced_widget.h" -#include "widget_base.h" - -/** - @brief The advanced display settings page of the configuration tool -*/ -class CDisplaySettingsAdvancedWidget : public CWidgetBase, public Ui::display_settings_advanced_widget -{ - Q_OBJECT -public: - CDisplaySettingsAdvancedWidget( QWidget *parent ); - ~CDisplaySettingsAdvancedWidget(); - - void load(); - void save(); - -protected: - void changeEvent( QEvent *event ); - -}; - -#endif // DISPLAYSETTINGSADVANCEDWIDGET_H +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef DISPLAYSETTINGSADVANCEDWIDGET_H +#define DISPLAYSETTINGSADVANCEDWIDGET_H + +#include "ui_display_settings_advanced_widget.h" +#include "widget_base.h" + +/** + @brief The advanced display settings page of the configuration tool +*/ +class CDisplaySettingsAdvancedWidget : public CWidgetBase, public Ui::display_settings_advanced_widget +{ + Q_OBJECT +public: + CDisplaySettingsAdvancedWidget( QWidget *parent ); + ~CDisplaySettingsAdvancedWidget(); + + void load(); + void save(); + +protected: + void changeEvent( QEvent *event ); + +}; + +#endif // DISPLAYSETTINGSADVANCEDWIDGET_H diff --git a/code/ryzom/tools/client/client_config_qt/display_settings_details_widget.cpp b/code/ryzom/tools/client/client_config_qt/display_settings_details_widget.cpp index fdc47d2bd..aeddcf628 100644 --- a/code/ryzom/tools/client/client_config_qt/display_settings_details_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/display_settings_details_widget.cpp @@ -1,268 +1,268 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "system.h" -#include "display_settings_details_widget.h" - -CDisplaySettingsDetailsWidget::CDisplaySettingsDetailsWidget( QWidget *parent ) : - CWidgetBase( parent ) -{ - setupUi( this ); - connect( landscapeSlider, SIGNAL( valueChanged( int ) ), this, SLOT( onLandscapeSliderChange( int ) ) ); - connect( charactersSlider, SIGNAL( valueChanged( int ) ), this, SLOT( onCharactersSliderChange( int ) ) ); - connect( fxSlider, SIGNAL( valueChanged( int ) ), this, SLOT( onFXSliderChange( int ) ) ); - connect( texturesSlider, SIGNAL( valueChanged( int ) ), this, SLOT( onTexturesSliderChange( int ) ) ); - load(); -} - -CDisplaySettingsDetailsWidget::~CDisplaySettingsDetailsWidget() -{ -} - -void CDisplaySettingsDetailsWidget::load() -{ - CSystem &s = CSystem::GetInstance(); - - landscapeSlider->setValue( getQuality( qualityToLandscapeThreshold, s.config.getFloat( "LandscapeThreshold" ) ) ); - landscapeSlider->setValue( std::min( landscapeSlider->value(), getQuality( qualityToZFar, s.config.getFloat( "Vision" ) ) ) ); - landscapeSlider->setValue( std::min( landscapeSlider->value(), getQuality( qualityToLandscapeTileNear, s.config.getFloat( "LandscapeTileNear" ) ) ) ); - landscapeSlider->setValue( std::min( landscapeSlider->value(), getQuality( qualityToMicrovegetDensity, s.config.getFloat( "MicroVegetDensity" ) ) ) ); - - charactersSlider->setValue( getQuality( qualityToSkinNbMaxPoly, s.config.getInt( "SkinNbMaxPoly" ) ) ); - charactersSlider->setValue( std::min( charactersSlider->value(), getQuality( qualityToNbMaxSkeletonNotCLod, s.config.getInt( "NbMaxSkeletonNotCLod" ) ) ) ); - charactersSlider->setValue( std::min( charactersSlider->value(), getQuality( qualityToCharacterFarClip, s.config.getFloat( "CharacterFarClip" ) ) ) ); - - fxSlider->setValue( getQuality( qualityToFxNbMaxPoly, s.config.getInt( "FxNbMaxPoly" ) ) ); - - int hdTextureInstalled = s.config.getInt( "HDTextureInstalled" ); - if( hdTextureInstalled == 1 ) - texturesSlider->setMaximum( QUALITY_NORMAL ); - else - texturesSlider->setMaximum( QUALITY_MEDIUM ); - - // Comment taken from the original config tool: - // NB: if the player changes its client.cfg, mixing HDEntityTexture=1 and DivideTextureSizeBy2=1, it will - // result to a low quality! - if( s.config.getInt( "DivideTextureSizeBy2" ) ) - texturesSlider->setValue( QUALITY_LOW ); - else if( s.config.getInt( "HDEntityTexture" ) && ( hdTextureInstalled == 1 ) ) - texturesSlider->setValue( QUALITY_NORMAL ); - else - texturesSlider->setValue( QUALITY_MEDIUM ); -} - -void CDisplaySettingsDetailsWidget::save() -{ - CSystem &s = CSystem::GetInstance(); - - s.config.setFloat( "Vision", qualityToZFar[ landscapeSlider->value() ] ); - s.config.setFloat( "LandscapeTileNear", qualityToLandscapeTileNear[ landscapeSlider->value() ] ); - s.config.setFloat( "LandscapeThreshold", qualityToLandscapeThreshold[ landscapeSlider->value() ] ); - - if( landscapeSlider->value() > QUALITY_LOW ) - s.config.setInt( "MicroVeget", 1 ); - else - s.config.setInt( "MicroVeget", 0 ); - - s.config.setFloat( "MicroVegetDensity", qualityToMicrovegetDensity[ landscapeSlider->value() ] ); - - - s.config.setInt( "SkinNbMaxPoly", qualityToSkinNbMaxPoly[ charactersSlider->value() ] ); - s.config.setInt( "NbMaxSkeletonNotCLod", qualityToNbMaxSkeletonNotCLod[ charactersSlider->value() ] ); - s.config.setFloat( "CharacterFarClip", qualityToCharacterFarClip[ charactersSlider->value() ] ); - - - s.config.setInt( "FxNbMaxPoly", qualityToFxNbMaxPoly[ fxSlider->value() ] ); - if( fxSlider->value() > QUALITY_LOW ) - { - s.config.setInt( "Shadows", 1 ); - s.config.setInt( "Bloom", 1 ); - s.config.setInt( "SquareBloom", 1 ); - } - else - { - s.config.setInt( "Shadows", 0 ); - s.config.setInt( "Bloom", 0 ); - s.config.setInt( "SquareBloom", 0 ); - } - - - if( texturesSlider->value() == QUALITY_NORMAL ) - s.config.setInt( "HDEntityTexture", 1 ); - else if( texturesSlider->value() == QUALITY_LOW ) - s.config.setInt( "DivideTextureSizeBy2", 1 ); -} - -void CDisplaySettingsDetailsWidget::changeEvent( QEvent *event ) -{ - if( event->type() == QEvent::LanguageChange ) - { - retranslateUi( this ); - - landscapeLabel->setText( getQualityString( landscapeSlider->value() ) ); - characterLabel->setText( getQualityString( charactersSlider->value() ) ); - fxLabel->setText( getQualityString( fxSlider->value() ) ); - textureLabel->setText( getTextureQualityString( texturesSlider->value() ) ); - } - QWidget::changeEvent( event ); -} - - -void CDisplaySettingsDetailsWidget::onLandscapeSliderChange( int value ) -{ - if( ( value < 0 ) || ( value > 3 ) ) - return; - - landscapeLabel->setText( getQualityString( value ) ); - emit changed(); -} - -void CDisplaySettingsDetailsWidget::onCharactersSliderChange( int value ) -{ - if( ( value < 0 ) || ( value > 3 ) ) - return; - - characterLabel->setText( getQualityString( value ) ); - emit changed(); -} - -void CDisplaySettingsDetailsWidget::onFXSliderChange( int value ) -{ - if( ( value < 0 ) || ( value > 3 ) ) - return; - - fxLabel->setText( getQualityString( value ) ); - emit changed(); -} - -void CDisplaySettingsDetailsWidget::onTexturesSliderChange( int value ) -{ - if( ( value < 0 ) || ( value > 3 ) ) - return; - - textureLabel->setText( getTextureQualityString( value ) ); - emit changed(); -} - -const float CDisplaySettingsDetailsWidget::qualityToZFar[ QUALITY_STEP ] = -{ - 200.0f, - 400.0f, - 500.0f, - 800.0f -}; - -const float CDisplaySettingsDetailsWidget::qualityToLandscapeTileNear[ QUALITY_STEP ] = -{ - 20.0f, - 100.0f, - 150.0f, - 200.0f -}; - -const float CDisplaySettingsDetailsWidget::qualityToLandscapeThreshold[ QUALITY_STEP ] = -{ - 100.0f, - 1000.0f, - 2000.0f, - 3000.0f -}; - - -const float CDisplaySettingsDetailsWidget::qualityToMicrovegetDensity[ QUALITY_STEP ] = -{ - 10.0f, - 30.0f, - 80.0f, - 100.0f -}; - - -const sint32 CDisplaySettingsDetailsWidget::qualityToSkinNbMaxPoly[ QUALITY_STEP ] = -{ - 10000, - 70000, - 100000, - 200000 -}; - -const sint32 CDisplaySettingsDetailsWidget::qualityToNbMaxSkeletonNotCLod[ QUALITY_STEP ] = -{ - 10, - 50, - 125, - 255 -}; - -const float CDisplaySettingsDetailsWidget::qualityToCharacterFarClip[ QUALITY_STEP ] = -{ - 50.0f, - 100.0f, - 200.0f, - 500.0f -}; - -const sint32 CDisplaySettingsDetailsWidget::qualityToFxNbMaxPoly[ QUALITY_STEP ] = -{ - 2000, - 10000, - 20000, - 50000 -}; - -QString CDisplaySettingsDetailsWidget::getQualityString( uint32 quality ) -{ - switch( quality ) - { - case QUALITY_LOW: - return tr( "Low" ); - break; - case QUALITY_MEDIUM: - return tr( "Medium" ); - break; - case QUALITY_NORMAL: - return tr( "Normal" ); - break; - case QUALITY_HIGH: - return tr( "High" ); - break; - default: - return ""; - break; - } -} - -QString CDisplaySettingsDetailsWidget::getTextureQualityString( uint32 quality ) -{ - switch( quality ) - { - case TEXQUALITY_LOW: - return tr( "Low (32 MB)" ); - break; - - case TEXQUALITY_NORMAL: - return tr( "Normal (64 MB)" ); - break; - - case TEXQUALITY_HIGH: - return tr( "High (128 MB)" ); - break; - - default: - return ""; - break; - } +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "system.h" +#include "display_settings_details_widget.h" + +CDisplaySettingsDetailsWidget::CDisplaySettingsDetailsWidget( QWidget *parent ) : + CWidgetBase( parent ) +{ + setupUi( this ); + connect( landscapeSlider, SIGNAL( valueChanged( int ) ), this, SLOT( onLandscapeSliderChange( int ) ) ); + connect( charactersSlider, SIGNAL( valueChanged( int ) ), this, SLOT( onCharactersSliderChange( int ) ) ); + connect( fxSlider, SIGNAL( valueChanged( int ) ), this, SLOT( onFXSliderChange( int ) ) ); + connect( texturesSlider, SIGNAL( valueChanged( int ) ), this, SLOT( onTexturesSliderChange( int ) ) ); + load(); +} + +CDisplaySettingsDetailsWidget::~CDisplaySettingsDetailsWidget() +{ +} + +void CDisplaySettingsDetailsWidget::load() +{ + CSystem &s = CSystem::GetInstance(); + + landscapeSlider->setValue( getQuality( qualityToLandscapeThreshold, s.config.getFloat( "LandscapeThreshold" ) ) ); + landscapeSlider->setValue( std::min( landscapeSlider->value(), getQuality( qualityToZFar, s.config.getFloat( "Vision" ) ) ) ); + landscapeSlider->setValue( std::min( landscapeSlider->value(), getQuality( qualityToLandscapeTileNear, s.config.getFloat( "LandscapeTileNear" ) ) ) ); + landscapeSlider->setValue( std::min( landscapeSlider->value(), getQuality( qualityToMicrovegetDensity, s.config.getFloat( "MicroVegetDensity" ) ) ) ); + + charactersSlider->setValue( getQuality( qualityToSkinNbMaxPoly, s.config.getInt( "SkinNbMaxPoly" ) ) ); + charactersSlider->setValue( std::min( charactersSlider->value(), getQuality( qualityToNbMaxSkeletonNotCLod, s.config.getInt( "NbMaxSkeletonNotCLod" ) ) ) ); + charactersSlider->setValue( std::min( charactersSlider->value(), getQuality( qualityToCharacterFarClip, s.config.getFloat( "CharacterFarClip" ) ) ) ); + + fxSlider->setValue( getQuality( qualityToFxNbMaxPoly, s.config.getInt( "FxNbMaxPoly" ) ) ); + + int hdTextureInstalled = s.config.getInt( "HDTextureInstalled" ); + if( hdTextureInstalled == 1 ) + texturesSlider->setMaximum( QUALITY_NORMAL ); + else + texturesSlider->setMaximum( QUALITY_MEDIUM ); + + // Comment taken from the original config tool: + // NB: if the player changes its client.cfg, mixing HDEntityTexture=1 and DivideTextureSizeBy2=1, it will + // result to a low quality! + if( s.config.getInt( "DivideTextureSizeBy2" ) ) + texturesSlider->setValue( QUALITY_LOW ); + else if( s.config.getInt( "HDEntityTexture" ) && ( hdTextureInstalled == 1 ) ) + texturesSlider->setValue( QUALITY_NORMAL ); + else + texturesSlider->setValue( QUALITY_MEDIUM ); +} + +void CDisplaySettingsDetailsWidget::save() +{ + CSystem &s = CSystem::GetInstance(); + + s.config.setFloat( "Vision", qualityToZFar[ landscapeSlider->value() ] ); + s.config.setFloat( "LandscapeTileNear", qualityToLandscapeTileNear[ landscapeSlider->value() ] ); + s.config.setFloat( "LandscapeThreshold", qualityToLandscapeThreshold[ landscapeSlider->value() ] ); + + if( landscapeSlider->value() > QUALITY_LOW ) + s.config.setInt( "MicroVeget", 1 ); + else + s.config.setInt( "MicroVeget", 0 ); + + s.config.setFloat( "MicroVegetDensity", qualityToMicrovegetDensity[ landscapeSlider->value() ] ); + + + s.config.setInt( "SkinNbMaxPoly", qualityToSkinNbMaxPoly[ charactersSlider->value() ] ); + s.config.setInt( "NbMaxSkeletonNotCLod", qualityToNbMaxSkeletonNotCLod[ charactersSlider->value() ] ); + s.config.setFloat( "CharacterFarClip", qualityToCharacterFarClip[ charactersSlider->value() ] ); + + + s.config.setInt( "FxNbMaxPoly", qualityToFxNbMaxPoly[ fxSlider->value() ] ); + if( fxSlider->value() > QUALITY_LOW ) + { + s.config.setInt( "Shadows", 1 ); + s.config.setInt( "Bloom", 1 ); + s.config.setInt( "SquareBloom", 1 ); + } + else + { + s.config.setInt( "Shadows", 0 ); + s.config.setInt( "Bloom", 0 ); + s.config.setInt( "SquareBloom", 0 ); + } + + + if( texturesSlider->value() == QUALITY_NORMAL ) + s.config.setInt( "HDEntityTexture", 1 ); + else if( texturesSlider->value() == QUALITY_LOW ) + s.config.setInt( "DivideTextureSizeBy2", 1 ); +} + +void CDisplaySettingsDetailsWidget::changeEvent( QEvent *event ) +{ + if( event->type() == QEvent::LanguageChange ) + { + retranslateUi( this ); + + landscapeLabel->setText( getQualityString( landscapeSlider->value() ) ); + characterLabel->setText( getQualityString( charactersSlider->value() ) ); + fxLabel->setText( getQualityString( fxSlider->value() ) ); + textureLabel->setText( getTextureQualityString( texturesSlider->value() ) ); + } + QWidget::changeEvent( event ); +} + + +void CDisplaySettingsDetailsWidget::onLandscapeSliderChange( int value ) +{ + if( ( value < 0 ) || ( value > 3 ) ) + return; + + landscapeLabel->setText( getQualityString( value ) ); + emit changed(); +} + +void CDisplaySettingsDetailsWidget::onCharactersSliderChange( int value ) +{ + if( ( value < 0 ) || ( value > 3 ) ) + return; + + characterLabel->setText( getQualityString( value ) ); + emit changed(); +} + +void CDisplaySettingsDetailsWidget::onFXSliderChange( int value ) +{ + if( ( value < 0 ) || ( value > 3 ) ) + return; + + fxLabel->setText( getQualityString( value ) ); + emit changed(); +} + +void CDisplaySettingsDetailsWidget::onTexturesSliderChange( int value ) +{ + if( ( value < 0 ) || ( value > 3 ) ) + return; + + textureLabel->setText( getTextureQualityString( value ) ); + emit changed(); +} + +const float CDisplaySettingsDetailsWidget::qualityToZFar[ QUALITY_STEP ] = +{ + 200.0f, + 400.0f, + 500.0f, + 800.0f +}; + +const float CDisplaySettingsDetailsWidget::qualityToLandscapeTileNear[ QUALITY_STEP ] = +{ + 20.0f, + 100.0f, + 150.0f, + 200.0f +}; + +const float CDisplaySettingsDetailsWidget::qualityToLandscapeThreshold[ QUALITY_STEP ] = +{ + 100.0f, + 1000.0f, + 2000.0f, + 3000.0f +}; + + +const float CDisplaySettingsDetailsWidget::qualityToMicrovegetDensity[ QUALITY_STEP ] = +{ + 10.0f, + 30.0f, + 80.0f, + 100.0f +}; + + +const sint32 CDisplaySettingsDetailsWidget::qualityToSkinNbMaxPoly[ QUALITY_STEP ] = +{ + 10000, + 70000, + 100000, + 200000 +}; + +const sint32 CDisplaySettingsDetailsWidget::qualityToNbMaxSkeletonNotCLod[ QUALITY_STEP ] = +{ + 10, + 50, + 125, + 255 +}; + +const float CDisplaySettingsDetailsWidget::qualityToCharacterFarClip[ QUALITY_STEP ] = +{ + 50.0f, + 100.0f, + 200.0f, + 500.0f +}; + +const sint32 CDisplaySettingsDetailsWidget::qualityToFxNbMaxPoly[ QUALITY_STEP ] = +{ + 2000, + 10000, + 20000, + 50000 +}; + +QString CDisplaySettingsDetailsWidget::getQualityString( uint32 quality ) +{ + switch( quality ) + { + case QUALITY_LOW: + return tr( "Low" ); + break; + case QUALITY_MEDIUM: + return tr( "Medium" ); + break; + case QUALITY_NORMAL: + return tr( "Normal" ); + break; + case QUALITY_HIGH: + return tr( "High" ); + break; + default: + return ""; + break; + } +} + +QString CDisplaySettingsDetailsWidget::getTextureQualityString( uint32 quality ) +{ + switch( quality ) + { + case TEXQUALITY_LOW: + return tr( "Low (32 MB)" ); + break; + + case TEXQUALITY_NORMAL: + return tr( "Normal (64 MB)" ); + break; + + case TEXQUALITY_HIGH: + return tr( "High (128 MB)" ); + break; + + default: + return ""; + break; + } } \ No newline at end of file diff --git a/code/ryzom/tools/client/client_config_qt/display_settings_details_widget.h b/code/ryzom/tools/client/client_config_qt/display_settings_details_widget.h index 535c3710c..001189432 100644 --- a/code/ryzom/tools/client/client_config_qt/display_settings_details_widget.h +++ b/code/ryzom/tools/client/client_config_qt/display_settings_details_widget.h @@ -1,121 +1,121 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef DISPLAYSETTINGSDETAILSWIDGET_H -#define DISPLAYSETTINGSDETAILSWIDGET_H - -#include "ui_display_settings_details_widget.h" -#include "widget_base.h" -#include - -enum -{ - QUALITY_LOW = 0, - QUALITY_MEDIUM = 1, - QUALITY_NORMAL = 2, - QUALITY_HIGH = 3, - QUALITY_STEP = 4 -}; - -enum -{ - TEXQUALITY_LOW = 0, - TEXQUALITY_NORMAL = 1, - TEXQUALITY_HIGH = 2 -}; - -/** - @brief The display details page of the configuration tool -*/ -class CDisplaySettingsDetailsWidget : public CWidgetBase, public Ui::display_settings_details_widget -{ - Q_OBJECT -public: - CDisplaySettingsDetailsWidget( QWidget *parent = NULL ); - ~CDisplaySettingsDetailsWidget(); - - void load(); - void save(); - -protected: - void changeEvent( QEvent *event ); - -private slots: - void onLandscapeSliderChange( int value ); - void onCharactersSliderChange( int value ); - void onFXSliderChange( int value ); - void onTexturesSliderChange( int value ); - -private: - /** - @brief Looks up and returns the "quality" ( see the enums on the top), that belongs to the specified value. - @param table - The lookup table you want to use. - @param value - The value that we want to look up. - @return Returns the "quality" that best fits the specified value. - */ - template< typename T > - int getQuality( const T *table, T value ) - { - if( table[ 0 ] < table[ QUALITY_STEP - 1 ] ) - { - uint32 i = 0; - while( ( i < QUALITY_STEP ) && ( table[ i ] < value ) ) - i++; - return i; - } - else - { - uint32 i = 0; - while( ( i < QUALITY_STEP ) && ( table[ i ] > value ) ) - i++; - return i; - } - } - - - /** - @brief Retrieves the string that belongs to the specified quality. - @param quality - The quality value - @return Returns a string describing the quality value, Returns an empty string if an invalid value is specified. - */ - static QString getQualityString( uint32 quality ); - - - /** - @brief Retrieves the string that belongs to the specified texture quality. - @param quality - The texture quality value - @return Returns a string describing the texture quality, Returns an empty string if an invalid value is specified. - */ - static QString getTextureQualityString( uint32 quality ); - - - ///////////////////////// Landscape values /////////////////////// - static const float qualityToZFar[ QUALITY_STEP ]; - static const float qualityToLandscapeTileNear[ QUALITY_STEP ]; - static const float qualityToLandscapeThreshold[ QUALITY_STEP ]; - static const float qualityToMicrovegetDensity[ QUALITY_STEP ]; - - //////////////////////// Character values //////////////////////// - static const sint32 qualityToSkinNbMaxPoly[ QUALITY_STEP ]; - static const sint32 qualityToNbMaxSkeletonNotCLod[ QUALITY_STEP ]; - static const float qualityToCharacterFarClip[ QUALITY_STEP ]; - - /////////////////////// FX values //////////////////////////////// - static const sint32 qualityToFxNbMaxPoly[ QUALITY_STEP ]; - -}; - -#endif // DISPLAYSETTINGSDETAILSWIDGET_H +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef DISPLAYSETTINGSDETAILSWIDGET_H +#define DISPLAYSETTINGSDETAILSWIDGET_H + +#include "ui_display_settings_details_widget.h" +#include "widget_base.h" +#include + +enum +{ + QUALITY_LOW = 0, + QUALITY_MEDIUM = 1, + QUALITY_NORMAL = 2, + QUALITY_HIGH = 3, + QUALITY_STEP = 4 +}; + +enum +{ + TEXQUALITY_LOW = 0, + TEXQUALITY_NORMAL = 1, + TEXQUALITY_HIGH = 2 +}; + +/** + @brief The display details page of the configuration tool +*/ +class CDisplaySettingsDetailsWidget : public CWidgetBase, public Ui::display_settings_details_widget +{ + Q_OBJECT +public: + CDisplaySettingsDetailsWidget( QWidget *parent = NULL ); + ~CDisplaySettingsDetailsWidget(); + + void load(); + void save(); + +protected: + void changeEvent( QEvent *event ); + +private slots: + void onLandscapeSliderChange( int value ); + void onCharactersSliderChange( int value ); + void onFXSliderChange( int value ); + void onTexturesSliderChange( int value ); + +private: + /** + @brief Looks up and returns the "quality" ( see the enums on the top), that belongs to the specified value. + @param table - The lookup table you want to use. + @param value - The value that we want to look up. + @return Returns the "quality" that best fits the specified value. + */ + template< typename T > + int getQuality( const T *table, T value ) + { + if( table[ 0 ] < table[ QUALITY_STEP - 1 ] ) + { + uint32 i = 0; + while( ( i < QUALITY_STEP ) && ( table[ i ] < value ) ) + i++; + return i; + } + else + { + uint32 i = 0; + while( ( i < QUALITY_STEP ) && ( table[ i ] > value ) ) + i++; + return i; + } + } + + + /** + @brief Retrieves the string that belongs to the specified quality. + @param quality - The quality value + @return Returns a string describing the quality value, Returns an empty string if an invalid value is specified. + */ + static QString getQualityString( uint32 quality ); + + + /** + @brief Retrieves the string that belongs to the specified texture quality. + @param quality - The texture quality value + @return Returns a string describing the texture quality, Returns an empty string if an invalid value is specified. + */ + static QString getTextureQualityString( uint32 quality ); + + + ///////////////////////// Landscape values /////////////////////// + static const float qualityToZFar[ QUALITY_STEP ]; + static const float qualityToLandscapeTileNear[ QUALITY_STEP ]; + static const float qualityToLandscapeThreshold[ QUALITY_STEP ]; + static const float qualityToMicrovegetDensity[ QUALITY_STEP ]; + + //////////////////////// Character values //////////////////////// + static const sint32 qualityToSkinNbMaxPoly[ QUALITY_STEP ]; + static const sint32 qualityToNbMaxSkeletonNotCLod[ QUALITY_STEP ]; + static const float qualityToCharacterFarClip[ QUALITY_STEP ]; + + /////////////////////// FX values //////////////////////////////// + static const sint32 qualityToFxNbMaxPoly[ QUALITY_STEP ]; + +}; + +#endif // DISPLAYSETTINGSDETAILSWIDGET_H diff --git a/code/ryzom/tools/client/client_config_qt/display_settings_widget.cpp b/code/ryzom/tools/client/client_config_qt/display_settings_widget.cpp index 89ed62783..f6775a0b7 100644 --- a/code/ryzom/tools/client/client_config_qt/display_settings_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/display_settings_widget.cpp @@ -1,227 +1,227 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include -#include -#include "display_settings_widget.h" -#include "system.h" -#include - -CDisplaySettingsWidget::CDisplaySettingsWidget( QWidget *parent ) : - CWidgetBase( parent ) -{ - setupUi( this ); - widthLineEdit->setValidator( new QRegExpValidator( QRegExp( "[0-9]{1,6}" ), widthLineEdit ) ); - heightLineEdit->setValidator( new QRegExpValidator( QRegExp( "[0-9]{1,6}" ), heightLineEdit ) ); - xpositionLineEdit->setValidator( new QRegExpValidator( QRegExp( "[0-9]{1,6}" ), xpositionLineEdit ) ); - ypositionLineEdit->setValidator( new QRegExpValidator( QRegExp( "[0-9]{1,6}" ), ypositionLineEdit ) ); - load(); - - connect( autoRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); - connect( openglRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); - connect( direct3dRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); - connect( fullscreenRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); - connect( windowedRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); - connect( widthLineEdit, SIGNAL( textChanged( const QString & ) ), this, SLOT( onSomethingChanged() ) ); - connect( heightLineEdit, SIGNAL( textChanged( const QString & ) ), this, SLOT( onSomethingChanged() ) ); - connect( xpositionLineEdit, SIGNAL( textChanged( const QString & ) ), this, SLOT( onSomethingChanged() ) ); - connect( ypositionLineEdit, SIGNAL( textChanged( const QString & ) ), this, SLOT( onSomethingChanged() ) ); - connect( videomodeComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onSomethingChanged() ) ); - connect( autoRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( updateVideoModes() ) ); - connect( openglRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( updateVideoModes() ) ); - connect( direct3dRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( updateVideoModes() ) ); -} - -CDisplaySettingsWidget::~CDisplaySettingsWidget() -{ -} - -void CDisplaySettingsWidget::load() -{ - CSystem &s = CSystem::GetInstance(); - - std::string driver = s.config.getString( "Driver3D" ); - switch( getDriverFromConfigString( driver ) ) - { - case DRV_AUTO: - autoRadioButton->setChecked( true ); - break; - case DRV_OPENGL: - openglRadioButton->setChecked( true ); - break; - case DRV_DIRECT3D: - direct3dRadioButton->setChecked( true ); - break; - } - - updateVideoModes(); - - - CVideoMode mode; - mode.widht = s.config.getInt( "Width" ); - mode.height = s.config.getInt( "Height" ); - mode.depth = s.config.getInt( "Depth" ); - mode.frequency = s.config.getInt( "Frequency" ); - - if( s.config.getInt( "FullScreen" ) == 1 ) - { - fullscreenRadioButton->setChecked( true ); - videomodeComboBox->setCurrentIndex( findVideoModeIndex( &mode ) ); - } - else - { - windowedRadioButton->setChecked( true ); - } - - widthLineEdit->setText( QString( "%1" ).arg( mode.widht ) ); - heightLineEdit->setText( QString( "%1" ).arg( mode.height ) ); - xpositionLineEdit->setText( QString( "%1" ).arg( s.config.getInt( "PositionX" ) ) ); - ypositionLineEdit->setText( QString( "%1" ).arg( s.config.getInt( "PositionY" ) ) ); - -} - -void CDisplaySettingsWidget::save() -{ - CSystem &s = CSystem::GetInstance(); - - if( openglRadioButton->isChecked() ) - s.config.setString( "Driver3D", std::string( "OpenGL" ) ); - else if( direct3dRadioButton->isChecked() ) - s.config.setString( "Driver3D", std::string( "Direct3D" ) ); - else - s.config.setString( "Driver3D", std::string( "Auto" ) ); - - if( fullscreenRadioButton->isChecked() ) - { - s.config.setInt( "FullScreen", 1 ); - - sint32 index = videomodeComboBox->currentIndex(); - CVideoMode mode; - - // OpenGL should be available everywhere! - if( direct3dRadioButton->isChecked() ) - mode = s.d3dInfo.modes[ index ]; - else - mode = s.openglInfo.modes[ index ]; - - s.config.setInt( "Width", mode.widht ); - s.config.setInt( "Height", mode.height ); - s.config.setInt( "Depth", mode.depth ); - s.config.setInt( "Frequency", mode.frequency ); - - } - else - { - s.config.setInt( "FullScreen", 0 ); - s.config.setInt( "Width", widthLineEdit->text().toInt() ); - s.config.setInt( "Height", heightLineEdit->text().toInt() ); - } - - s.config.setInt( "PositionX", xpositionLineEdit->text().toInt() ); - s.config.setInt( "PositionY", ypositionLineEdit->text().toInt() ); -} - -void CDisplaySettingsWidget::changeEvent( QEvent *event ) -{ - if( event->type() == QEvent::LanguageChange ) - { - disconnect( videomodeComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onSomethingChanged() ) ); - retranslateUi( this ); - connect( videomodeComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onSomethingChanged() ) ); - } - QWidget::changeEvent( event ); -} - -void CDisplaySettingsWidget::updateVideoModes() -{ - CSystem &s = CSystem::GetInstance(); - - videomodeComboBox->clear(); - - if( direct3dRadioButton->isChecked() ) - { - for( std::vector< CVideoMode >::iterator itr = s.d3dInfo.modes.begin(); itr != s.d3dInfo.modes.end(); ++itr ) - { - std::stringstream ss; - ss << itr->widht << "x" << itr->height << " " << itr->depth << " bit @" << itr->frequency; - videomodeComboBox->addItem( ss.str().c_str() ); - } - } - else - { - // OpenGL should be available everywhere! - for( std::vector< CVideoMode >::iterator itr = s.openglInfo.modes.begin(); itr != s.openglInfo.modes.end(); ++itr ) - { - std::stringstream ss; - ss << itr->widht << "x" << itr->height << " " << itr->depth << " bit @" << itr->frequency; - videomodeComboBox->addItem( ss.str().c_str() ); - } - } -} - -uint32 CDisplaySettingsWidget::findVideoModeIndex( CVideoMode *mode ) -{ - ////////////////////////////////////////////////////////////////////////////////// - // WARNING: - // This part relies on that the video mode combo box is filled as the following: - // - //| --------------------------------------| - //| Selected driver | Modes | - //| --------------------------------------| - //| Auto | OpenGL modes | - //| OpenGL | OpenGL modes | - //| Direct3D | Direct3d modes | - //| --------------------------------------| - // - // - ////////////////////////////////////////////////////////////////////////////////// - - CVideoMode &m = *mode; - CSystem &s = CSystem::GetInstance(); - - if( direct3dRadioButton->isChecked() ) - { - for( uint32 i = 0; i < s.d3dInfo.modes.size(); i++ ) - if( s.d3dInfo.modes[ i ] == m ) - return i; - } - else - { - // Again OpenGL should be available everywhere! - for( uint32 i = 0; i < s.openglInfo.modes.size(); i++ ) - if( s.openglInfo.modes[ i ] == m ) - return i; - } - - return 0; -} - -E3DDriver CDisplaySettingsWidget::getDriverFromConfigString(std::string &str) const -{ - if( str.compare( "0" ) == 0 ) - return DRV_AUTO; - if( str.compare( "1" ) == 0 ) - return DRV_OPENGL; - if( str.compare( "2" ) == 0 ) - return DRV_DIRECT3D; - if( str.compare( "OpenGL" ) == 0 ) - return DRV_OPENGL; - if( str.compare( "Direct3D" ) == 0) - return DRV_DIRECT3D; - - - return DRV_AUTO; -} +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include +#include +#include "display_settings_widget.h" +#include "system.h" +#include + +CDisplaySettingsWidget::CDisplaySettingsWidget( QWidget *parent ) : + CWidgetBase( parent ) +{ + setupUi( this ); + widthLineEdit->setValidator( new QRegExpValidator( QRegExp( "[0-9]{1,6}" ), widthLineEdit ) ); + heightLineEdit->setValidator( new QRegExpValidator( QRegExp( "[0-9]{1,6}" ), heightLineEdit ) ); + xpositionLineEdit->setValidator( new QRegExpValidator( QRegExp( "[0-9]{1,6}" ), xpositionLineEdit ) ); + ypositionLineEdit->setValidator( new QRegExpValidator( QRegExp( "[0-9]{1,6}" ), ypositionLineEdit ) ); + load(); + + connect( autoRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); + connect( openglRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); + connect( direct3dRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); + connect( fullscreenRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); + connect( windowedRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); + connect( widthLineEdit, SIGNAL( textChanged( const QString & ) ), this, SLOT( onSomethingChanged() ) ); + connect( heightLineEdit, SIGNAL( textChanged( const QString & ) ), this, SLOT( onSomethingChanged() ) ); + connect( xpositionLineEdit, SIGNAL( textChanged( const QString & ) ), this, SLOT( onSomethingChanged() ) ); + connect( ypositionLineEdit, SIGNAL( textChanged( const QString & ) ), this, SLOT( onSomethingChanged() ) ); + connect( videomodeComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onSomethingChanged() ) ); + connect( autoRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( updateVideoModes() ) ); + connect( openglRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( updateVideoModes() ) ); + connect( direct3dRadioButton, SIGNAL( clicked( bool ) ), this, SLOT( updateVideoModes() ) ); +} + +CDisplaySettingsWidget::~CDisplaySettingsWidget() +{ +} + +void CDisplaySettingsWidget::load() +{ + CSystem &s = CSystem::GetInstance(); + + std::string driver = s.config.getString( "Driver3D" ); + switch( getDriverFromConfigString( driver ) ) + { + case DRV_AUTO: + autoRadioButton->setChecked( true ); + break; + case DRV_OPENGL: + openglRadioButton->setChecked( true ); + break; + case DRV_DIRECT3D: + direct3dRadioButton->setChecked( true ); + break; + } + + updateVideoModes(); + + + CVideoMode mode; + mode.widht = s.config.getInt( "Width" ); + mode.height = s.config.getInt( "Height" ); + mode.depth = s.config.getInt( "Depth" ); + mode.frequency = s.config.getInt( "Frequency" ); + + if( s.config.getInt( "FullScreen" ) == 1 ) + { + fullscreenRadioButton->setChecked( true ); + videomodeComboBox->setCurrentIndex( findVideoModeIndex( &mode ) ); + } + else + { + windowedRadioButton->setChecked( true ); + } + + widthLineEdit->setText( QString( "%1" ).arg( mode.widht ) ); + heightLineEdit->setText( QString( "%1" ).arg( mode.height ) ); + xpositionLineEdit->setText( QString( "%1" ).arg( s.config.getInt( "PositionX" ) ) ); + ypositionLineEdit->setText( QString( "%1" ).arg( s.config.getInt( "PositionY" ) ) ); + +} + +void CDisplaySettingsWidget::save() +{ + CSystem &s = CSystem::GetInstance(); + + if( openglRadioButton->isChecked() ) + s.config.setString( "Driver3D", std::string( "OpenGL" ) ); + else if( direct3dRadioButton->isChecked() ) + s.config.setString( "Driver3D", std::string( "Direct3D" ) ); + else + s.config.setString( "Driver3D", std::string( "Auto" ) ); + + if( fullscreenRadioButton->isChecked() ) + { + s.config.setInt( "FullScreen", 1 ); + + sint32 index = videomodeComboBox->currentIndex(); + CVideoMode mode; + + // OpenGL should be available everywhere! + if( direct3dRadioButton->isChecked() ) + mode = s.d3dInfo.modes[ index ]; + else + mode = s.openglInfo.modes[ index ]; + + s.config.setInt( "Width", mode.widht ); + s.config.setInt( "Height", mode.height ); + s.config.setInt( "Depth", mode.depth ); + s.config.setInt( "Frequency", mode.frequency ); + + } + else + { + s.config.setInt( "FullScreen", 0 ); + s.config.setInt( "Width", widthLineEdit->text().toInt() ); + s.config.setInt( "Height", heightLineEdit->text().toInt() ); + } + + s.config.setInt( "PositionX", xpositionLineEdit->text().toInt() ); + s.config.setInt( "PositionY", ypositionLineEdit->text().toInt() ); +} + +void CDisplaySettingsWidget::changeEvent( QEvent *event ) +{ + if( event->type() == QEvent::LanguageChange ) + { + disconnect( videomodeComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onSomethingChanged() ) ); + retranslateUi( this ); + connect( videomodeComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onSomethingChanged() ) ); + } + QWidget::changeEvent( event ); +} + +void CDisplaySettingsWidget::updateVideoModes() +{ + CSystem &s = CSystem::GetInstance(); + + videomodeComboBox->clear(); + + if( direct3dRadioButton->isChecked() ) + { + for( std::vector< CVideoMode >::iterator itr = s.d3dInfo.modes.begin(); itr != s.d3dInfo.modes.end(); ++itr ) + { + std::stringstream ss; + ss << itr->widht << "x" << itr->height << " " << itr->depth << " bit @" << itr->frequency; + videomodeComboBox->addItem( ss.str().c_str() ); + } + } + else + { + // OpenGL should be available everywhere! + for( std::vector< CVideoMode >::iterator itr = s.openglInfo.modes.begin(); itr != s.openglInfo.modes.end(); ++itr ) + { + std::stringstream ss; + ss << itr->widht << "x" << itr->height << " " << itr->depth << " bit @" << itr->frequency; + videomodeComboBox->addItem( ss.str().c_str() ); + } + } +} + +uint32 CDisplaySettingsWidget::findVideoModeIndex( CVideoMode *mode ) +{ + ////////////////////////////////////////////////////////////////////////////////// + // WARNING: + // This part relies on that the video mode combo box is filled as the following: + // + //| --------------------------------------| + //| Selected driver | Modes | + //| --------------------------------------| + //| Auto | OpenGL modes | + //| OpenGL | OpenGL modes | + //| Direct3D | Direct3d modes | + //| --------------------------------------| + // + // + ////////////////////////////////////////////////////////////////////////////////// + + CVideoMode &m = *mode; + CSystem &s = CSystem::GetInstance(); + + if( direct3dRadioButton->isChecked() ) + { + for( uint32 i = 0; i < s.d3dInfo.modes.size(); i++ ) + if( s.d3dInfo.modes[ i ] == m ) + return i; + } + else + { + // Again OpenGL should be available everywhere! + for( uint32 i = 0; i < s.openglInfo.modes.size(); i++ ) + if( s.openglInfo.modes[ i ] == m ) + return i; + } + + return 0; +} + +E3DDriver CDisplaySettingsWidget::getDriverFromConfigString(std::string &str) const +{ + if( str.compare( "0" ) == 0 ) + return DRV_AUTO; + if( str.compare( "1" ) == 0 ) + return DRV_OPENGL; + if( str.compare( "2" ) == 0 ) + return DRV_DIRECT3D; + if( str.compare( "OpenGL" ) == 0 ) + return DRV_OPENGL; + if( str.compare( "Direct3D" ) == 0) + return DRV_DIRECT3D; + + + return DRV_AUTO; +} diff --git a/code/ryzom/tools/client/client_config_qt/display_settings_widget.h b/code/ryzom/tools/client/client_config_qt/display_settings_widget.h index 5da578bbf..f67ec8b15 100644 --- a/code/ryzom/tools/client/client_config_qt/display_settings_widget.h +++ b/code/ryzom/tools/client/client_config_qt/display_settings_widget.h @@ -1,72 +1,72 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef DISPLAYSETTINGSWIDGET_H -#define DISPLAYSETTINGSWIDGET_H - -#include "ui_display_settings_widget.h" -#include "widget_base.h" -#include - -struct CVideoMode; - -enum E3DDriver -{ - DRV_AUTO, - DRV_OPENGL, - DRV_DIRECT3D -}; - -/** - @brief The display settings page of the configuration tool -*/ -class CDisplaySettingsWidget : public CWidgetBase, public Ui::display_settings_widget -{ - Q_OBJECT -public: - CDisplaySettingsWidget( QWidget *parent = NULL ); - ~CDisplaySettingsWidget(); - - void load(); - void save(); - -protected: - void changeEvent( QEvent *event ); - -private slots: - /** - @brief Updates the video modes combo box, based on the current driver selection. - */ - void updateVideoModes(); - -private: - /** - @brief Finds the proper index for the video mode combobox - @param mode - the video mode read from config - @return Returns the proper video mode index if found, returns 0 otherwise. - */ - uint32 findVideoModeIndex( CVideoMode *mode ); - - - /** - @brief Retrieves the driver type from the config string. - @param str - Reference to the driver string. - @return Returns the driver type on success, rReturns E3DDriver::DRV_AUTO otherwise. - */ - E3DDriver getDriverFromConfigString( std::string &str ) const; -}; - -#endif // DISPLAYSETTINGSWIDGET_H +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef DISPLAYSETTINGSWIDGET_H +#define DISPLAYSETTINGSWIDGET_H + +#include "ui_display_settings_widget.h" +#include "widget_base.h" +#include + +struct CVideoMode; + +enum E3DDriver +{ + DRV_AUTO, + DRV_OPENGL, + DRV_DIRECT3D +}; + +/** + @brief The display settings page of the configuration tool +*/ +class CDisplaySettingsWidget : public CWidgetBase, public Ui::display_settings_widget +{ + Q_OBJECT +public: + CDisplaySettingsWidget( QWidget *parent = NULL ); + ~CDisplaySettingsWidget(); + + void load(); + void save(); + +protected: + void changeEvent( QEvent *event ); + +private slots: + /** + @brief Updates the video modes combo box, based on the current driver selection. + */ + void updateVideoModes(); + +private: + /** + @brief Finds the proper index for the video mode combobox + @param mode - the video mode read from config + @return Returns the proper video mode index if found, returns 0 otherwise. + */ + uint32 findVideoModeIndex( CVideoMode *mode ); + + + /** + @brief Retrieves the driver type from the config string. + @param str - Reference to the driver string. + @return Returns the driver type on success, rReturns E3DDriver::DRV_AUTO otherwise. + */ + E3DDriver getDriverFromConfigString( std::string &str ) const; +}; + +#endif // DISPLAYSETTINGSWIDGET_H diff --git a/code/ryzom/tools/client/client_config_qt/general_settings_widget.cpp b/code/ryzom/tools/client/client_config_qt/general_settings_widget.cpp index 357bd45d4..fcb85dec2 100644 --- a/code/ryzom/tools/client/client_config_qt/general_settings_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/general_settings_widget.cpp @@ -1,121 +1,121 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "general_settings_widget.h" -#include "system.h" -#include - -const QString CGeneralSettingsWidget::languageCodes[ NUM_LANGUAGE_CODES ] = -{ - "en", - "fr", - "de", - "hu" -}; - -CGeneralSettingsWidget::CGeneralSettingsWidget( QWidget *parent ) : - CWidgetBase( parent ) -{ - currentTranslator = NULL; - setupUi( this ); - load(); - - connect( languageComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onLanguageChanged() ) ); - connect( saveConfigOnQuitCheckBox, SIGNAL( stateChanged( int ) ), this, SLOT( onSomethingChanged() ) ); - connect( lowPriorityProcessCheckBox, SIGNAL( stateChanged( int ) ), this, SLOT( onSomethingChanged() ) ); -} - -CGeneralSettingsWidget::~CGeneralSettingsWidget() -{ -} - -void CGeneralSettingsWidget::load() -{ - CSystem &s = CSystem::GetInstance(); - - sint32 cbIndex = getIndexForLanguageCode( QString( s.config.getString( "LanguageCode" ).c_str() ) ); - if( cbIndex != -1 ){ - languageComboBox->setCurrentIndex( cbIndex ); - onLanguageChanged(); - } - - if( s.config.getInt( "SaveConfig" ) ) - saveConfigOnQuitCheckBox->setChecked( true ); - - if( s.config.getInt( "ProcessPriority" ) == -1 ) - lowPriorityProcessCheckBox->setChecked( true ); - else - lowPriorityProcessCheckBox->setChecked( false ); -} - -void CGeneralSettingsWidget::save() -{ - CSystem &s = CSystem::GetInstance(); - - s.config.setString( "LanguageCode", std::string( languageCodes[ languageComboBox->currentIndex() ].toUtf8() ) ); - - if( saveConfigOnQuitCheckBox->isChecked() ) - s.config.setInt( "SaveConfig", 1 ); - else - s.config.setInt( "SaveConfig", 0 ); - - if( lowPriorityProcessCheckBox->isChecked() ) - s.config.setInt( "ProcessPriority", -1 ); - else - s.config.setInt( "ProcessPriority", 0 ); -} - -void CGeneralSettingsWidget::onLanguageChanged() -{ - sint32 i = languageComboBox->currentIndex(); - - if( currentTranslator != NULL ) - { - qApp->removeTranslator( currentTranslator ); - delete currentTranslator; - currentTranslator = NULL; - } - - currentTranslator = new QTranslator(); - if( currentTranslator->load( QString( ":/translations/ryzom_configuration_%1" ).arg( languageCodes[ i ] ) ) ) - qApp->installTranslator( currentTranslator ); - - emit changed(); -} - -void CGeneralSettingsWidget::changeEvent( QEvent *event ) -{ - if( event->type() == QEvent::LanguageChange ) - { - sint32 i = languageComboBox->currentIndex(); - // Signals that are emitted on index change need to be disconnected, since retranslation cleans the widget - disconnect( languageComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onLanguageChanged() ) ); - retranslateUi( this ); - languageComboBox->setCurrentIndex( i ); - connect( languageComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onLanguageChanged() ) ); - } - - QWidget::changeEvent( event ); -} - -int CGeneralSettingsWidget::getIndexForLanguageCode( QString &languageCode ) -{ - for( sint32 i = 0; i < NUM_LANGUAGE_CODES; i++ ) - if( languageCode.compare( languageCodes[ i ] ) == 0 ) - return i; - - return -1; -} +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "general_settings_widget.h" +#include "system.h" +#include + +const QString CGeneralSettingsWidget::languageCodes[ NUM_LANGUAGE_CODES ] = +{ + "en", + "fr", + "de", + "hu" +}; + +CGeneralSettingsWidget::CGeneralSettingsWidget( QWidget *parent ) : + CWidgetBase( parent ) +{ + currentTranslator = NULL; + setupUi( this ); + load(); + + connect( languageComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onLanguageChanged() ) ); + connect( saveConfigOnQuitCheckBox, SIGNAL( stateChanged( int ) ), this, SLOT( onSomethingChanged() ) ); + connect( lowPriorityProcessCheckBox, SIGNAL( stateChanged( int ) ), this, SLOT( onSomethingChanged() ) ); +} + +CGeneralSettingsWidget::~CGeneralSettingsWidget() +{ +} + +void CGeneralSettingsWidget::load() +{ + CSystem &s = CSystem::GetInstance(); + + sint32 cbIndex = getIndexForLanguageCode( QString( s.config.getString( "LanguageCode" ).c_str() ) ); + if( cbIndex != -1 ){ + languageComboBox->setCurrentIndex( cbIndex ); + onLanguageChanged(); + } + + if( s.config.getInt( "SaveConfig" ) ) + saveConfigOnQuitCheckBox->setChecked( true ); + + if( s.config.getInt( "ProcessPriority" ) == -1 ) + lowPriorityProcessCheckBox->setChecked( true ); + else + lowPriorityProcessCheckBox->setChecked( false ); +} + +void CGeneralSettingsWidget::save() +{ + CSystem &s = CSystem::GetInstance(); + + s.config.setString( "LanguageCode", std::string( languageCodes[ languageComboBox->currentIndex() ].toUtf8() ) ); + + if( saveConfigOnQuitCheckBox->isChecked() ) + s.config.setInt( "SaveConfig", 1 ); + else + s.config.setInt( "SaveConfig", 0 ); + + if( lowPriorityProcessCheckBox->isChecked() ) + s.config.setInt( "ProcessPriority", -1 ); + else + s.config.setInt( "ProcessPriority", 0 ); +} + +void CGeneralSettingsWidget::onLanguageChanged() +{ + sint32 i = languageComboBox->currentIndex(); + + if( currentTranslator != NULL ) + { + qApp->removeTranslator( currentTranslator ); + delete currentTranslator; + currentTranslator = NULL; + } + + currentTranslator = new QTranslator(); + if( currentTranslator->load( QString( ":/translations/ryzom_configuration_%1" ).arg( languageCodes[ i ] ) ) ) + qApp->installTranslator( currentTranslator ); + + emit changed(); +} + +void CGeneralSettingsWidget::changeEvent( QEvent *event ) +{ + if( event->type() == QEvent::LanguageChange ) + { + sint32 i = languageComboBox->currentIndex(); + // Signals that are emitted on index change need to be disconnected, since retranslation cleans the widget + disconnect( languageComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onLanguageChanged() ) ); + retranslateUi( this ); + languageComboBox->setCurrentIndex( i ); + connect( languageComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onLanguageChanged() ) ); + } + + QWidget::changeEvent( event ); +} + +int CGeneralSettingsWidget::getIndexForLanguageCode( QString &languageCode ) +{ + for( sint32 i = 0; i < NUM_LANGUAGE_CODES; i++ ) + if( languageCode.compare( languageCodes[ i ] ) == 0 ) + return i; + + return -1; +} diff --git a/code/ryzom/tools/client/client_config_qt/general_settings_widget.h b/code/ryzom/tools/client/client_config_qt/general_settings_widget.h index dd6e41752..c8d530ea5 100644 --- a/code/ryzom/tools/client/client_config_qt/general_settings_widget.h +++ b/code/ryzom/tools/client/client_config_qt/general_settings_widget.h @@ -1,66 +1,66 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef GENERALSETTINGWIDGET_H -#define GENERALSETTINGWIDGET_H - -#include "ui_general_settings_widget.h" -#include "widget_base.h" -#include - -class QTranslator; - -enum -{ - NUM_LANGUAGE_CODES = 4 -}; - -/** - @brief The general settings page of the configuration tool -*/ -class CGeneralSettingsWidget : public CWidgetBase, public Ui::general_settings_widget -{ - Q_OBJECT - -public: - CGeneralSettingsWidget( QWidget *parent = NULL ); - ~CGeneralSettingsWidget(); - - void load(); - void save(); - -private slots: - void onLanguageChanged(); - -protected: - void changeEvent( QEvent *event ); - -private: - /** - @brief Retrieves the language combobox index for the language code provided. - @param languageCode - Reference to the language code, we are trying to find. - @return Returns the index on success, returns -1 if the language code cannot be found. - */ - sint32 getIndexForLanguageCode( QString &languageCode ); - - // Contains the language codes used in the config file - // They are in the same order as the options in languageComboBox - static const QString languageCodes[ NUM_LANGUAGE_CODES ]; - - QTranslator *currentTranslator; -}; - -#endif // GENERALSETTINGWIDGET_H +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef GENERALSETTINGWIDGET_H +#define GENERALSETTINGWIDGET_H + +#include "ui_general_settings_widget.h" +#include "widget_base.h" +#include + +class QTranslator; + +enum +{ + NUM_LANGUAGE_CODES = 4 +}; + +/** + @brief The general settings page of the configuration tool +*/ +class CGeneralSettingsWidget : public CWidgetBase, public Ui::general_settings_widget +{ + Q_OBJECT + +public: + CGeneralSettingsWidget( QWidget *parent = NULL ); + ~CGeneralSettingsWidget(); + + void load(); + void save(); + +private slots: + void onLanguageChanged(); + +protected: + void changeEvent( QEvent *event ); + +private: + /** + @brief Retrieves the language combobox index for the language code provided. + @param languageCode - Reference to the language code, we are trying to find. + @return Returns the index on success, returns -1 if the language code cannot be found. + */ + sint32 getIndexForLanguageCode( QString &languageCode ); + + // Contains the language codes used in the config file + // They are in the same order as the options in languageComboBox + static const QString languageCodes[ NUM_LANGUAGE_CODES ]; + + QTranslator *currentTranslator; +}; + +#endif // GENERALSETTINGWIDGET_H diff --git a/code/ryzom/tools/client/client_config_qt/main.cpp b/code/ryzom/tools/client/client_config_qt/main.cpp index f643005bc..758598e92 100644 --- a/code/ryzom/tools/client/client_config_qt/main.cpp +++ b/code/ryzom/tools/client/client_config_qt/main.cpp @@ -1,36 +1,36 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include -#include "client_config_dialog.h" -#include "system.h" - -int main( sint32 argc, char **argv ) -{ - QApplication app( argc, argv ); - QPixmap pixmap( ":/resources/splash_screen.bmp" ); - QSplashScreen splash( pixmap ); - - splash.show(); - - CSystem::GetInstance().config.load( "client.cfg" ); - - CClientConfigDialog d; - d.show(); - splash.finish( &d ); - - return app.exec(); -} +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include +#include "client_config_dialog.h" +#include "system.h" + +int main( sint32 argc, char **argv ) +{ + QApplication app( argc, argv ); + QPixmap pixmap( ":/resources/splash_screen.bmp" ); + QSplashScreen splash( pixmap ); + + splash.show(); + + CSystem::GetInstance().config.load( "client.cfg" ); + + CClientConfigDialog d; + d.show(); + splash.finish( &d ); + + return app.exec(); +} diff --git a/code/ryzom/tools/client/client_config_qt/sound_settings_widget.cpp b/code/ryzom/tools/client/client_config_qt/sound_settings_widget.cpp index 1b7dc5248..5436ac2b4 100644 --- a/code/ryzom/tools/client/client_config_qt/sound_settings_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/sound_settings_widget.cpp @@ -1,99 +1,99 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "sound_settings_widget.h" -#include "system.h" - -CSoundSettingsWidget::CSoundSettingsWidget( QWidget *parent ) : - CWidgetBase( parent ) -{ - setupUi( this ); - load(); - - connect( tracksSlider, SIGNAL( valueChanged( int ) ), this, SLOT( onTracksSliderChange() ) ); - connect( soundCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); - connect( eaxCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); - connect( softwareCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); - connect( fmodCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); -} - -CSoundSettingsWidget::~CSoundSettingsWidget() -{ -} - -void CSoundSettingsWidget::onTracksSliderChange() -{ - updateTracksLabel(); - emit changed(); -} - -void CSoundSettingsWidget::load() -{ - CSystem &s = CSystem::GetInstance(); - - if( s.config.getInt( "SoundOn" ) == 1 ) - soundCheckBox->setChecked( true ); - - if( s.config.getInt( "UseEax" ) == 1 ) - eaxCheckBox->setChecked( true ); - - if( s.config.getInt( "SoundForceSoftwareBuffer" ) == 1 ) - softwareCheckBox->setChecked( true ); - - sint32 tracks = s.config.getInt( "MaxTrack" ); - if( tracks < 4 ) - tracks = 4; - if( tracks > 32 ) - tracks = 32; - tracksSlider->setValue( tracks / 4 ); - - if( s.config.getString( "DriverSound" ).compare( "FMod" ) == 0 ) - fmodCheckBox->setChecked( true ); -} - -void CSoundSettingsWidget::save() -{ - CSystem &s = CSystem::GetInstance(); - - if( soundCheckBox->isChecked() ) - s.config.setInt( "SoundOn", 1 ); - - if( eaxCheckBox->isChecked() ) - s.config.setInt( "UseEax", 1 ); - - if( softwareCheckBox->isChecked() ) - s.config.setInt( "SoundForceSoftwareBuffer", 1 ); - - s.config.setInt( "MaxTrack", tracksSlider->value() * 4 ); - - if( fmodCheckBox->isChecked() ) - s.config.setString( "DriverSound", std::string( "FMod" ) ); -} - -void CSoundSettingsWidget::changeEvent( QEvent *event ) -{ - if( event->type() == QEvent::LanguageChange ) - { - retranslateUi( this ); - updateTracksLabel(); - } - QWidget::changeEvent( event ); -} - -void CSoundSettingsWidget::updateTracksLabel() -{ - tracksLabel->setText( tr( "%1 tracks" ).arg( tracksSlider->value() * 4 ) ); +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "sound_settings_widget.h" +#include "system.h" + +CSoundSettingsWidget::CSoundSettingsWidget( QWidget *parent ) : + CWidgetBase( parent ) +{ + setupUi( this ); + load(); + + connect( tracksSlider, SIGNAL( valueChanged( int ) ), this, SLOT( onTracksSliderChange() ) ); + connect( soundCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); + connect( eaxCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); + connect( softwareCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); + connect( fmodCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onSomethingChanged() ) ); +} + +CSoundSettingsWidget::~CSoundSettingsWidget() +{ +} + +void CSoundSettingsWidget::onTracksSliderChange() +{ + updateTracksLabel(); + emit changed(); +} + +void CSoundSettingsWidget::load() +{ + CSystem &s = CSystem::GetInstance(); + + if( s.config.getInt( "SoundOn" ) == 1 ) + soundCheckBox->setChecked( true ); + + if( s.config.getInt( "UseEax" ) == 1 ) + eaxCheckBox->setChecked( true ); + + if( s.config.getInt( "SoundForceSoftwareBuffer" ) == 1 ) + softwareCheckBox->setChecked( true ); + + sint32 tracks = s.config.getInt( "MaxTrack" ); + if( tracks < 4 ) + tracks = 4; + if( tracks > 32 ) + tracks = 32; + tracksSlider->setValue( tracks / 4 ); + + if( s.config.getString( "DriverSound" ).compare( "FMod" ) == 0 ) + fmodCheckBox->setChecked( true ); +} + +void CSoundSettingsWidget::save() +{ + CSystem &s = CSystem::GetInstance(); + + if( soundCheckBox->isChecked() ) + s.config.setInt( "SoundOn", 1 ); + + if( eaxCheckBox->isChecked() ) + s.config.setInt( "UseEax", 1 ); + + if( softwareCheckBox->isChecked() ) + s.config.setInt( "SoundForceSoftwareBuffer", 1 ); + + s.config.setInt( "MaxTrack", tracksSlider->value() * 4 ); + + if( fmodCheckBox->isChecked() ) + s.config.setString( "DriverSound", std::string( "FMod" ) ); +} + +void CSoundSettingsWidget::changeEvent( QEvent *event ) +{ + if( event->type() == QEvent::LanguageChange ) + { + retranslateUi( this ); + updateTracksLabel(); + } + QWidget::changeEvent( event ); +} + +void CSoundSettingsWidget::updateTracksLabel() +{ + tracksLabel->setText( tr( "%1 tracks" ).arg( tracksSlider->value() * 4 ) ); } \ No newline at end of file diff --git a/code/ryzom/tools/client/client_config_qt/sound_settings_widget.h b/code/ryzom/tools/client/client_config_qt/sound_settings_widget.h index f1a54114b..d98a89d82 100644 --- a/code/ryzom/tools/client/client_config_qt/sound_settings_widget.h +++ b/code/ryzom/tools/client/client_config_qt/sound_settings_widget.h @@ -1,50 +1,50 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef SOUNDSETTINGSWIDGET_H -#define SOUNDSETTINGSWIDGET_H - -#include "ui_sound_settings_widget.h" -#include "widget_base.h" -#include - -/** - @brief The sound settings page of the configuration tool -*/ -class CSoundSettingsWidget : public CWidgetBase, public Ui::sound_settings_widget -{ - Q_OBJECT -public: - CSoundSettingsWidget( QWidget *parent = NULL ); - ~CSoundSettingsWidget(); - - void load(); - void save(); - -protected: - void changeEvent( QEvent *event ); - -private slots: - void onTracksSliderChange(); - -private: - /** - @brief Updates the text on the tracks label. - */ - void updateTracksLabel(); -}; - -#endif // SOUNDSETTINGSWIDGET_H +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef SOUNDSETTINGSWIDGET_H +#define SOUNDSETTINGSWIDGET_H + +#include "ui_sound_settings_widget.h" +#include "widget_base.h" +#include + +/** + @brief The sound settings page of the configuration tool +*/ +class CSoundSettingsWidget : public CWidgetBase, public Ui::sound_settings_widget +{ + Q_OBJECT +public: + CSoundSettingsWidget( QWidget *parent = NULL ); + ~CSoundSettingsWidget(); + + void load(); + void save(); + +protected: + void changeEvent( QEvent *event ); + +private slots: + void onTracksSliderChange(); + +private: + /** + @brief Updates the text on the tracks label. + */ + void updateTracksLabel(); +}; + +#endif // SOUNDSETTINGSWIDGET_H diff --git a/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.cpp b/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.cpp index 2852a98dd..894ea07ac 100644 --- a/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.cpp @@ -1,41 +1,41 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "sys_info_d3d_widget.h" -#include "system.h" - -CSysInfoD3DWidget::CSysInfoD3DWidget( QWidget *parent ) : - QWidget( parent ) -{ - setupUi( this ); - - descriptionLabel->setText( CSystem::GetInstance().d3dInfo.device.c_str() ); - driverLabel->setText( CSystem::GetInstance().d3dInfo.driver.c_str() ); - versionLabel->setText( CSystem::GetInstance().d3dInfo.driverVersion.c_str() ); -} - -CSysInfoD3DWidget::~CSysInfoD3DWidget() -{ -} - -void CSysInfoD3DWidget::changeEvent( QEvent *event ) -{ - if( event->type() == QEvent::LanguageChange ) - { - retranslateUi( this ); - } - QWidget::changeEvent( event ); -} +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "sys_info_d3d_widget.h" +#include "system.h" + +CSysInfoD3DWidget::CSysInfoD3DWidget( QWidget *parent ) : + QWidget( parent ) +{ + setupUi( this ); + + descriptionLabel->setText( CSystem::GetInstance().d3dInfo.device.c_str() ); + driverLabel->setText( CSystem::GetInstance().d3dInfo.driver.c_str() ); + versionLabel->setText( CSystem::GetInstance().d3dInfo.driverVersion.c_str() ); +} + +CSysInfoD3DWidget::~CSysInfoD3DWidget() +{ +} + +void CSysInfoD3DWidget::changeEvent( QEvent *event ) +{ + if( event->type() == QEvent::LanguageChange ) + { + retranslateUi( this ); + } + QWidget::changeEvent( event ); +} diff --git a/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.h b/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.h index 64d13a6a4..6f79782ae 100644 --- a/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.h +++ b/code/ryzom/tools/client/client_config_qt/sys_info_d3d_widget.h @@ -1,39 +1,39 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef SYSINFOD3DWIDGET_H -#define SYSINFOD3DWIDGET_H - -#include "ui_sys_Info_d3d_widget.h" - - -/** - @brief The Direct3D information page of the configuration tool -*/ -class CSysInfoD3DWidget : public QWidget, public Ui::sys_info_d3d_widget -{ - Q_OBJECT -public: - CSysInfoD3DWidget( QWidget *parent = NULL ); - ~CSysInfoD3DWidget(); - -protected: - void changeEvent( QEvent *event ); - -}; - - -#endif // SYSINFOD3DWIDGET_H +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef SYSINFOD3DWIDGET_H +#define SYSINFOD3DWIDGET_H + +#include "ui_sys_Info_d3d_widget.h" + + +/** + @brief The Direct3D information page of the configuration tool +*/ +class CSysInfoD3DWidget : public QWidget, public Ui::sys_info_d3d_widget +{ + Q_OBJECT +public: + CSysInfoD3DWidget( QWidget *parent = NULL ); + ~CSysInfoD3DWidget(); + +protected: + void changeEvent( QEvent *event ); + +}; + + +#endif // SYSINFOD3DWIDGET_H diff --git a/code/ryzom/tools/client/client_config_qt/sys_info_opengl_widget.cpp b/code/ryzom/tools/client/client_config_qt/sys_info_opengl_widget.cpp index 9792bbdbc..0665025be 100644 --- a/code/ryzom/tools/client/client_config_qt/sys_info_opengl_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/sys_info_opengl_widget.cpp @@ -1,42 +1,42 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "sys_info_opengl_widget.h" -#include "system.h" - -CSysInfoOpenGLWidget::CSysInfoOpenGLWidget( QWidget *parent ) : - QWidget( parent ) -{ - setupUi( this ); - vendorLabel->setText( CSystem::GetInstance().openglInfo.vendor.c_str() ); - rendererLabel->setText( CSystem::GetInstance().openglInfo.renderer.c_str() ); - versionLabel->setText( CSystem::GetInstance().openglInfo.driverVersion.c_str() ); - extensionsBox->setPlainText( CSystem::GetInstance().openglInfo.extensions.c_str() ); - -} - -CSysInfoOpenGLWidget::~CSysInfoOpenGLWidget() -{ -} - -void CSysInfoOpenGLWidget::changeEvent( QEvent *event ) -{ - if( event->type() == QEvent::LanguageChange ) - { - retranslateUi( this ); - } - QWidget::changeEvent( event ); -} +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "sys_info_opengl_widget.h" +#include "system.h" + +CSysInfoOpenGLWidget::CSysInfoOpenGLWidget( QWidget *parent ) : + QWidget( parent ) +{ + setupUi( this ); + vendorLabel->setText( CSystem::GetInstance().openglInfo.vendor.c_str() ); + rendererLabel->setText( CSystem::GetInstance().openglInfo.renderer.c_str() ); + versionLabel->setText( CSystem::GetInstance().openglInfo.driverVersion.c_str() ); + extensionsBox->setPlainText( CSystem::GetInstance().openglInfo.extensions.c_str() ); + +} + +CSysInfoOpenGLWidget::~CSysInfoOpenGLWidget() +{ +} + +void CSysInfoOpenGLWidget::changeEvent( QEvent *event ) +{ + if( event->type() == QEvent::LanguageChange ) + { + retranslateUi( this ); + } + QWidget::changeEvent( event ); +} diff --git a/code/ryzom/tools/client/client_config_qt/sys_info_opengl_widget.h b/code/ryzom/tools/client/client_config_qt/sys_info_opengl_widget.h index 6f40db7d7..f1d396f51 100644 --- a/code/ryzom/tools/client/client_config_qt/sys_info_opengl_widget.h +++ b/code/ryzom/tools/client/client_config_qt/sys_info_opengl_widget.h @@ -1,38 +1,38 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef SYSINFOOPENGLWIDGET_H -#define SYSINFOOPENGLWIDGET_H - -#include "ui_sys_info_opengl_widget.h" - - -/** - @brief The OpenGL information page of the configuration tool -*/ -class CSysInfoOpenGLWidget : public QWidget, public Ui::sys_info_opengl_widget -{ - Q_OBJECT -public: - CSysInfoOpenGLWidget( QWidget *parent = NULL ); - ~CSysInfoOpenGLWidget(); - -protected: - void changeEvent( QEvent *event ); - -}; - -#endif // SYSINFOOPENGLWIDGET_H +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef SYSINFOOPENGLWIDGET_H +#define SYSINFOOPENGLWIDGET_H + +#include "ui_sys_info_opengl_widget.h" + + +/** + @brief The OpenGL information page of the configuration tool +*/ +class CSysInfoOpenGLWidget : public QWidget, public Ui::sys_info_opengl_widget +{ + Q_OBJECT +public: + CSysInfoOpenGLWidget( QWidget *parent = NULL ); + ~CSysInfoOpenGLWidget(); + +protected: + void changeEvent( QEvent *event ); + +}; + +#endif // SYSINFOOPENGLWIDGET_H diff --git a/code/ryzom/tools/client/client_config_qt/sys_info_widget.cpp b/code/ryzom/tools/client/client_config_qt/sys_info_widget.cpp index 58845fd38..26d52ddb8 100644 --- a/code/ryzom/tools/client/client_config_qt/sys_info_widget.cpp +++ b/code/ryzom/tools/client/client_config_qt/sys_info_widget.cpp @@ -1,46 +1,46 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "sys_info_widget.h" -#include "system.h" - -CSysInfoWidget::CSysInfoWidget( QWidget *parent ) : - QWidget( parent ) -{ - setupUi( this ); - - osLabel->setText( CSystem::GetInstance().sysInfo.osName.c_str() ); - cpuLabel->setText( CSystem::GetInstance().sysInfo.cpuName.c_str() ); - - ramLabel->setText( - QString().setNum( CSystem::GetInstance().sysInfo.totalRAM ).append( " Mb" ) ); - - gfxcardLabel->setText( CSystem::GetInstance().sysInfo.videoDevice.c_str() ); - gfxdriverLabel->setText( CSystem::GetInstance().sysInfo.videoDriverVersion.c_str() ); -} - -CSysInfoWidget::~CSysInfoWidget() -{ -} - -void CSysInfoWidget::changeEvent( QEvent *event ) -{ - if( event->type() == QEvent::LanguageChange ) - { - retranslateUi( this ); - } - QWidget::changeEvent( event ); -} +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "sys_info_widget.h" +#include "system.h" + +CSysInfoWidget::CSysInfoWidget( QWidget *parent ) : + QWidget( parent ) +{ + setupUi( this ); + + osLabel->setText( CSystem::GetInstance().sysInfo.osName.c_str() ); + cpuLabel->setText( CSystem::GetInstance().sysInfo.cpuName.c_str() ); + + ramLabel->setText( + QString().setNum( CSystem::GetInstance().sysInfo.totalRAM ).append( " Mb" ) ); + + gfxcardLabel->setText( CSystem::GetInstance().sysInfo.videoDevice.c_str() ); + gfxdriverLabel->setText( CSystem::GetInstance().sysInfo.videoDriverVersion.c_str() ); +} + +CSysInfoWidget::~CSysInfoWidget() +{ +} + +void CSysInfoWidget::changeEvent( QEvent *event ) +{ + if( event->type() == QEvent::LanguageChange ) + { + retranslateUi( this ); + } + QWidget::changeEvent( event ); +} diff --git a/code/ryzom/tools/client/client_config_qt/sys_info_widget.h b/code/ryzom/tools/client/client_config_qt/sys_info_widget.h index 8bb885aee..d266c119d 100644 --- a/code/ryzom/tools/client/client_config_qt/sys_info_widget.h +++ b/code/ryzom/tools/client/client_config_qt/sys_info_widget.h @@ -1,38 +1,38 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef SYSINFOWIDGET_H -#define SYSINFOWIDGET_H - -#include "ui_sys_info_widget.h" - - -/** - @brief The system information page of the configuration tool -*/ -class CSysInfoWidget : public QWidget, public Ui::sys_info_widget -{ - Q_OBJECT -public: - CSysInfoWidget( QWidget *parent = NULL ); - ~CSysInfoWidget(); - -protected: - void changeEvent( QEvent *event ); - -}; - -#endif // SYSINFOWIDGET_H +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef SYSINFOWIDGET_H +#define SYSINFOWIDGET_H + +#include "ui_sys_info_widget.h" + + +/** + @brief The system information page of the configuration tool +*/ +class CSysInfoWidget : public QWidget, public Ui::sys_info_widget +{ + Q_OBJECT +public: + CSysInfoWidget( QWidget *parent = NULL ); + ~CSysInfoWidget(); + +protected: + void changeEvent( QEvent *event ); + +}; + +#endif // SYSINFOWIDGET_H diff --git a/code/ryzom/tools/client/client_config_qt/system.cpp b/code/ryzom/tools/client/client_config_qt/system.cpp index 1bb50e845..c4c93f76d 100644 --- a/code/ryzom/tools/client/client_config_qt/system.cpp +++ b/code/ryzom/tools/client/client_config_qt/system.cpp @@ -1,181 +1,181 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "system.h" -#include -#include -#include -#include - -CSystem *CSystem::instance = NULL; - -CSystem::CSystem() -{ - GatherSysInfo(); -#ifdef WIN32 - GatherD3DInfo(); -#endif - GatherOpenGLInfo(); -} - -CSystem::~CSystem() -{ - instance = 0; -} - - -void CSystem::GatherSysInfo() -{ - std::string device; - uint64 driver; - - if( NLMISC::CSystemInfo::getVideoInfo( device, driver ) ) - { - sysInfo.videoDevice = device; - - ////////////////////////////////////////////////////////////// - // FIXME - // This is taken from the original configuration tool, and - // it generates the same *wrong* version number - ////////////////////////////////////////////////////////////// - uint32 version = static_cast< uint32 >( driver & 0xffff ); - std::stringstream ss; - - ss << ( version / 1000 % 10 ); - ss << "."; - ss << ( version / 100 % 10 ); - ss << "."; - ss << ( version / 10 % 10 ); - ss << "."; - ss << ( version % 10 ); - - sysInfo.videoDriverVersion = ss.str(); - ////////////////////////////////////////////////////////////// - } - else - { - sysInfo.videoDevice = "video card"; - sysInfo.videoDriverVersion = "0.0.0.0"; - } - - sysInfo.osName = NLMISC::CSystemInfo::getOS(); - sysInfo.cpuName = NLMISC::CSystemInfo::getProc(); - sysInfo.totalRAM = NLMISC::CSystemInfo::totalPhysicalMemory(); - sysInfo.totalRAM /= ( 1024 * 1024 ); -} - -#ifdef WIN32 -void CSystem::GatherD3DInfo() -{ - NL3D::IDriver *driver = NULL; - try - { - driver = NL3D::CDRU::createD3DDriver(); - - NL3D::IDriver::CAdapter adapter; - - if( driver->getAdapter( 0xffffffff, adapter ) ) - { - d3dInfo.device = adapter.Description; - d3dInfo.driver = adapter.Driver; - - sint64 ver = adapter.DriverVersion; - std::stringstream ss; - ss << static_cast< uint16 >( ver >> 48 ); - ss << "."; - ss << static_cast< uint16 >( ver >> 32 ); - ss << "."; - ss << static_cast< uint16 >( ver >> 16 ); - ss << "."; - ss << static_cast< uint16 >( ver & 0xFFFF ); - d3dInfo.driverVersion = ss.str(); - } - - GetVideoModes( d3dInfo.modes, driver ); - - driver->release(); - } - - catch( NLMISC::Exception &e ) - { - nlwarning( e.what() ); - } -} -#endif - -void CSystem::GatherOpenGLInfo() -{ - QGLWidget *gl = new QGLWidget(); - - gl->makeCurrent(); - - const char *s = NULL; - s = reinterpret_cast< const char * >( glGetString( GL_VENDOR ) ); - if( s != NULL ) - openglInfo.vendor.assign( s ); - - s = reinterpret_cast< const char * >( glGetString( GL_RENDERER ) ); - if( s != NULL ) - openglInfo.renderer.assign( s ); - - s = reinterpret_cast< const char * >( glGetString( GL_VERSION ) ); - if( s != NULL ) - openglInfo.driverVersion.assign( s ); - - s = reinterpret_cast< const char * >( glGetString( GL_EXTENSIONS ) ); - if( s != NULL ) - { - openglInfo.extensions.assign( s ); - for( std::string::iterator itr = openglInfo.extensions.begin(); itr != openglInfo.extensions.end(); ++itr ) - if( *itr == ' ' ) - *itr = '\n'; - } - - delete gl; - - NL3D::IDriver *driver = NULL; - try - { - driver = NL3D::CDRU::createGlDriver(); - GetVideoModes( openglInfo.modes, driver ); - driver->release(); - } - - catch( NLMISC::Exception &e ) - { - nlwarning( e.what() ); - } -} - -void CSystem::GetVideoModes( std::vector< CVideoMode > &dst, NL3D::IDriver *driver ) const -{ - std::vector< NL3D::GfxMode > modes; - driver->getModes( modes ); - - for( std::vector< NL3D::GfxMode >::iterator itr = modes.begin(); itr != modes.end(); ++itr ) - { - if( ( itr->Width >= 800 ) && ( itr->Height >= 600 ) && ( itr->Depth == 32 ) && ( itr->Frequency >= 60 ) ) - { - CVideoMode mode; - mode.depth = itr->Depth; - mode.widht = itr->Width; - mode.height = itr->Height; - mode.frequency = itr->Frequency; - - dst.push_back( mode ); - } - } +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "system.h" +#include +#include +#include +#include + +CSystem *CSystem::instance = NULL; + +CSystem::CSystem() +{ + GatherSysInfo(); +#ifdef WIN32 + GatherD3DInfo(); +#endif + GatherOpenGLInfo(); +} + +CSystem::~CSystem() +{ + instance = 0; +} + + +void CSystem::GatherSysInfo() +{ + std::string device; + uint64 driver; + + if( NLMISC::CSystemInfo::getVideoInfo( device, driver ) ) + { + sysInfo.videoDevice = device; + + ////////////////////////////////////////////////////////////// + // FIXME + // This is taken from the original configuration tool, and + // it generates the same *wrong* version number + ////////////////////////////////////////////////////////////// + uint32 version = static_cast< uint32 >( driver & 0xffff ); + std::stringstream ss; + + ss << ( version / 1000 % 10 ); + ss << "."; + ss << ( version / 100 % 10 ); + ss << "."; + ss << ( version / 10 % 10 ); + ss << "."; + ss << ( version % 10 ); + + sysInfo.videoDriverVersion = ss.str(); + ////////////////////////////////////////////////////////////// + } + else + { + sysInfo.videoDevice = "video card"; + sysInfo.videoDriverVersion = "0.0.0.0"; + } + + sysInfo.osName = NLMISC::CSystemInfo::getOS(); + sysInfo.cpuName = NLMISC::CSystemInfo::getProc(); + sysInfo.totalRAM = NLMISC::CSystemInfo::totalPhysicalMemory(); + sysInfo.totalRAM /= ( 1024 * 1024 ); +} + +#ifdef WIN32 +void CSystem::GatherD3DInfo() +{ + NL3D::IDriver *driver = NULL; + try + { + driver = NL3D::CDRU::createD3DDriver(); + + NL3D::IDriver::CAdapter adapter; + + if( driver->getAdapter( 0xffffffff, adapter ) ) + { + d3dInfo.device = adapter.Description; + d3dInfo.driver = adapter.Driver; + + sint64 ver = adapter.DriverVersion; + std::stringstream ss; + ss << static_cast< uint16 >( ver >> 48 ); + ss << "."; + ss << static_cast< uint16 >( ver >> 32 ); + ss << "."; + ss << static_cast< uint16 >( ver >> 16 ); + ss << "."; + ss << static_cast< uint16 >( ver & 0xFFFF ); + d3dInfo.driverVersion = ss.str(); + } + + GetVideoModes( d3dInfo.modes, driver ); + + driver->release(); + } + + catch( NLMISC::Exception &e ) + { + nlwarning( e.what() ); + } +} +#endif + +void CSystem::GatherOpenGLInfo() +{ + QGLWidget *gl = new QGLWidget(); + + gl->makeCurrent(); + + const char *s = NULL; + s = reinterpret_cast< const char * >( glGetString( GL_VENDOR ) ); + if( s != NULL ) + openglInfo.vendor.assign( s ); + + s = reinterpret_cast< const char * >( glGetString( GL_RENDERER ) ); + if( s != NULL ) + openglInfo.renderer.assign( s ); + + s = reinterpret_cast< const char * >( glGetString( GL_VERSION ) ); + if( s != NULL ) + openglInfo.driverVersion.assign( s ); + + s = reinterpret_cast< const char * >( glGetString( GL_EXTENSIONS ) ); + if( s != NULL ) + { + openglInfo.extensions.assign( s ); + for( std::string::iterator itr = openglInfo.extensions.begin(); itr != openglInfo.extensions.end(); ++itr ) + if( *itr == ' ' ) + *itr = '\n'; + } + + delete gl; + + NL3D::IDriver *driver = NULL; + try + { + driver = NL3D::CDRU::createGlDriver(); + GetVideoModes( openglInfo.modes, driver ); + driver->release(); + } + + catch( NLMISC::Exception &e ) + { + nlwarning( e.what() ); + } +} + +void CSystem::GetVideoModes( std::vector< CVideoMode > &dst, NL3D::IDriver *driver ) const +{ + std::vector< NL3D::GfxMode > modes; + driver->getModes( modes ); + + for( std::vector< NL3D::GfxMode >::iterator itr = modes.begin(); itr != modes.end(); ++itr ) + { + if( ( itr->Width >= 800 ) && ( itr->Height >= 600 ) && ( itr->Depth == 32 ) && ( itr->Frequency >= 60 ) ) + { + CVideoMode mode; + mode.depth = itr->Depth; + mode.widht = itr->Width; + mode.height = itr->Height; + mode.frequency = itr->Frequency; + + dst.push_back( mode ); + } + } } \ No newline at end of file diff --git a/code/ryzom/tools/client/client_config_qt/system.h b/code/ryzom/tools/client/client_config_qt/system.h index fceb6cdd3..bcb5f90bf 100644 --- a/code/ryzom/tools/client/client_config_qt/system.h +++ b/code/ryzom/tools/client/client_config_qt/system.h @@ -1,112 +1,112 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef SYSTEM_H -#define SYSTEM_H - -#include -#include "config.h" - -namespace NL3D -{ -class IDriver; -} - -struct CVideoMode -{ - unsigned int widht; - unsigned int height; - unsigned int depth; - unsigned int frequency; - - CVideoMode() - { - widht = 0; - height = 0; - depth = 0; - frequency = 0; - } - - bool operator==( CVideoMode &o ) - { - if( ( o.widht == widht ) && ( o.height == height ) && ( o.depth == depth ) && ( o.frequency == frequency ) ) - return true; - else - return false; - } -}; - -/** - @brief Singleton class that holds the system information, configs, etc -*/ -class CSystem -{ -public: - CSystem(); - ~CSystem(); - - static CSystem &GetInstance() - { - if( instance == 0 ) - { - instance = new CSystem; - } - return *instance; - } - - struct CSysInfo - { - std::string videoDevice; - std::string videoDriverVersion; - std::string osName; - std::string cpuName; - uint64 totalRAM; - } sysInfo; - -#ifdef WIN32 - struct CD3DInfo - { - std::string device; - std::string driver; - std::string driverVersion; - std::vector< CVideoMode > modes; - } d3dInfo; -#endif - - struct COpenGLInfo - { - std::string vendor; - std::string renderer; - std::string driverVersion; - std::string extensions; - std::vector< CVideoMode > modes; - } openglInfo; - - CConfig config; - -private: - void GatherSysInfo(); -#ifdef WIN32 - void GatherD3DInfo(); -#endif - void GatherOpenGLInfo(); - - void GetVideoModes( std::vector< CVideoMode > &dst, NL3D::IDriver *driver ) const; - - static CSystem *instance; -}; - -#endif // SYSTEM_H +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef SYSTEM_H +#define SYSTEM_H + +#include +#include "config.h" + +namespace NL3D +{ +class IDriver; +} + +struct CVideoMode +{ + unsigned int widht; + unsigned int height; + unsigned int depth; + unsigned int frequency; + + CVideoMode() + { + widht = 0; + height = 0; + depth = 0; + frequency = 0; + } + + bool operator==( CVideoMode &o ) + { + if( ( o.widht == widht ) && ( o.height == height ) && ( o.depth == depth ) && ( o.frequency == frequency ) ) + return true; + else + return false; + } +}; + +/** + @brief Singleton class that holds the system information, configs, etc +*/ +class CSystem +{ +public: + CSystem(); + ~CSystem(); + + static CSystem &GetInstance() + { + if( instance == 0 ) + { + instance = new CSystem; + } + return *instance; + } + + struct CSysInfo + { + std::string videoDevice; + std::string videoDriverVersion; + std::string osName; + std::string cpuName; + uint64 totalRAM; + } sysInfo; + +#ifdef WIN32 + struct CD3DInfo + { + std::string device; + std::string driver; + std::string driverVersion; + std::vector< CVideoMode > modes; + } d3dInfo; +#endif + + struct COpenGLInfo + { + std::string vendor; + std::string renderer; + std::string driverVersion; + std::string extensions; + std::vector< CVideoMode > modes; + } openglInfo; + + CConfig config; + +private: + void GatherSysInfo(); +#ifdef WIN32 + void GatherD3DInfo(); +#endif + void GatherOpenGLInfo(); + + void GetVideoModes( std::vector< CVideoMode > &dst, NL3D::IDriver *driver ) const; + + static CSystem *instance; +}; + +#endif // SYSTEM_H diff --git a/code/ryzom/tools/client/client_config_qt/widget_base.h b/code/ryzom/tools/client/client_config_qt/widget_base.h index 1cc30c0c3..d9948aeac 100644 --- a/code/ryzom/tools/client/client_config_qt/widget_base.h +++ b/code/ryzom/tools/client/client_config_qt/widget_base.h @@ -1,61 +1,61 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef WIDGETBASE_H -#define WIDGETBASE_H - -#include - -/** - @brief Base class for the config tool's settings page widgets. -*/ -class CWidgetBase : public QWidget -{ - Q_OBJECT - -public: - CWidgetBase( QWidget *parent = NULL ) : QWidget( parent ) {} - ~CWidgetBase() {} - - /** - @brief Tells the widget to load it's values from the config. - */ - virtual void load() = 0; - - /** - @brief Tells the widget to save it's values into the config. - */ - virtual void save() = 0; - -signals: - /** - @brief Emitted when the user changes a setting. - */ - void changed(); - - -private slots: - /** - @brief Triggered when something changes in the widget, emits the Changed() signal. - */ - void onSomethingChanged() - { - emit changed(); - } -}; - - -#endif +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef WIDGETBASE_H +#define WIDGETBASE_H + +#include + +/** + @brief Base class for the config tool's settings page widgets. +*/ +class CWidgetBase : public QWidget +{ + Q_OBJECT + +public: + CWidgetBase( QWidget *parent = NULL ) : QWidget( parent ) {} + ~CWidgetBase() {} + + /** + @brief Tells the widget to load it's values from the config. + */ + virtual void load() = 0; + + /** + @brief Tells the widget to save it's values into the config. + */ + virtual void save() = 0; + +signals: + /** + @brief Emitted when the user changes a setting. + */ + void changed(); + + +private slots: + /** + @brief Triggered when something changes in the widget, emits the Changed() signal. + */ + void onSomethingChanged() + { + emit changed(); + } +}; + + +#endif From a5350025540fed706d916a7db74b16ad63fb4e0d Mon Sep 17 00:00:00 2001 From: Botanic Date: Wed, 5 Jun 2013 19:59:53 -0700 Subject: [PATCH 02/10] why the hell make the faster values for "debug only" waiting it so 1990's --- code/ryzom/tools/server/admin/functions_tool_main.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/ryzom/tools/server/admin/functions_tool_main.php b/code/ryzom/tools/server/admin/functions_tool_main.php index 9ab2a5b9e..cb541a83e 100644 --- a/code/ryzom/tools/server/admin/functions_tool_main.php +++ b/code/ryzom/tools/server/admin/functions_tool_main.php @@ -1,12 +1,12 @@ 'Every 5 secs', 'secs' => 5, ), array('desc' => 'Every 30 secs', 'secs' => 30, - ),*/ + ), array('desc' => 'Every 1 min.', 'secs' => 60, ), From 0fc3b07a12a7a43534335fcf0e51fb03ac1b8399 Mon Sep 17 00:00:00 2001 From: Botanic Date: Wed, 5 Jun 2013 19:43:10 -0700 Subject: [PATCH 03/10] fixed warning --- code/ryzom/tools/server/admin/tool_preferences.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/tools/server/admin/tool_preferences.php b/code/ryzom/tools/server/admin/tool_preferences.php index 88e8d289c..85204d005 100644 --- a/code/ryzom/tools/server/admin/tool_preferences.php +++ b/code/ryzom/tools/server/admin/tool_preferences.php @@ -9,7 +9,7 @@ $tpl->assign("tool_v_login", $nel_user['user_name']); $tpl->assign("tool_v_user_id", $nel_user['user_id']); $tpl->assign("tool_v_menu", $nel_user['user_menu_style']); - $tpl->assign("tool_v_application", $nel_user['user_default_application_id']); + $tpl->assign("tool_v_application", isset($nel_user['user_default_application_id'])); if (isset($NELTOOL['POST_VARS']['tool_form_user_id'])) { From 7e64c718c41b09c193d902555cfa34509e7db64e Mon Sep 17 00:00:00 2001 From: Botanic Date: Wed, 5 Jun 2013 19:27:06 -0700 Subject: [PATCH 04/10] fixed warning --- code/ryzom/tools/server/admin/functions_mysql.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/tools/server/admin/functions_mysql.php b/code/ryzom/tools/server/admin/functions_mysql.php index 9ce5ec3de..6778bbeff 100644 --- a/code/ryzom/tools/server/admin/functions_mysql.php +++ b/code/ryzom/tools/server/admin/functions_mysql.php @@ -114,7 +114,7 @@ class sql_db } else { - return ( $transaction == END_TRANSACTION ) ? true : false; + return ( $transaction == 'END_TRANSACTION' ) ? true : false; } } From 914c5ad303e1c016e58d43de3a4dbe55335c5c8b Mon Sep 17 00:00:00 2001 From: Botanic Date: Wed, 5 Jun 2013 19:19:09 -0700 Subject: [PATCH 05/10] no reason to make people change the logs path every time --- code/ryzom/tools/server/www/login/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/tools/server/www/login/config.php b/code/ryzom/tools/server/www/login/config.php index 50cdcc748..80f89f32b 100644 --- a/code/ryzom/tools/server/www/login/config.php +++ b/code/ryzom/tools/server/www/login/config.php @@ -2,7 +2,7 @@ // This file contains all variables needed by other php scripts -$LogRelativePath = './'; +$LogRelativePath = 'logs/'; // ---------------------------------------------------------------------------------------- // Variables for nel database access From 503f5d348e3f3cd188a770d5a3735b3b5bd1063d Mon Sep 17 00:00:00 2001 From: Botanic Date: Wed, 5 Jun 2013 19:14:53 -0700 Subject: [PATCH 06/10] Fixed warnings and logout --- code/ryzom/tools/server/admin/common.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/code/ryzom/tools/server/admin/common.php b/code/ryzom/tools/server/admin/common.php index de49cfe4a..644ebba32 100644 --- a/code/ryzom/tools/server/admin/common.php +++ b/code/ryzom/tools/server/admin/common.php @@ -69,7 +69,7 @@ { $nel_user = null; nt_auth_stop_session(); - nt_common_redirect('index.php'); + nt_common_redirect(''); exit(); } elseif (isset($NELTOOL['SESSION_VARS']['nelid']) && !empty($NELTOOL['SESSION_VARS']['nelid'])) @@ -138,9 +138,12 @@ if (isset($nel_user['new_login'])) { $default_user_application_id = 0; - if ($nel_user['user_default_application_id'] > 0) $default_user_application_id = $nel_user['user_default_application_id']; - elseif ($nel_user['group_default_application_id'] > 0) $default_user_application_id = $nel_user['group_default_application_id']; - + if (isset( $nel_user['user_default_application_id']) &&($nel_user['user_default_application_id'] > 0)) { + $default_user_application_id = $nel_user['user_default_application_id']; + }elseif (isset( $nel_user['group_default_application_id']) &&($nel_user['group_default_application_id'] > 0)) { + $default_user_application_id = $nel_user['group_default_application_id']; + } + if ($default_user_application_id > 0) { nt_common_add_debug("default application : user:". $nel_user['user_default_application_id'] ." group:". $nel_user['group_default_application_id']); From 1055925bac1a5e38e7a137fb999cd0d5e8dfb976 Mon Sep 17 00:00:00 2001 From: Botanic Date: Wed, 5 Jun 2013 19:14:49 -0700 Subject: [PATCH 07/10] No reason to hardcode the path --- code/ryzom/tools/server/admin/config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/ryzom/tools/server/admin/config.php b/code/ryzom/tools/server/admin/config.php index 4d4c223a4..530adcb43 100644 --- a/code/ryzom/tools/server/admin/config.php +++ b/code/ryzom/tools/server/admin/config.php @@ -9,8 +9,8 @@ define('NELTOOL_DBNAME','nel_tool'); // site paths definitions - define('NELTOOL_SITEBASE','http://open.ryzom.com/'); - define('NELTOOL_SYSTEMBASE','/home/nevrax/hg/code/ryzom/tools/server/admin/'); + define('NELTOOL_SITEBASE',$_SERVER['PHP_SELF']); + define('NELTOOL_SYSTEMBASE',dirname( dirname(__FILE__) ) . '/admin/'); define('NELTOOL_LOGBASE', NELTOOL_SYSTEMBASE .'/logs/'); define('NELTOOL_IMGBASE', NELTOOL_SYSTEMBASE .'/imgs/'); From c5f75ec268adf7d61878c12ea01ede1369139e72 Mon Sep 17 00:00:00 2001 From: Botanic Date: Thu, 6 Jun 2013 01:28:12 -0700 Subject: [PATCH 08/10] fixed thanks kervala --- code/ryzom/tools/server/admin/tool_preferences.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/tools/server/admin/tool_preferences.php b/code/ryzom/tools/server/admin/tool_preferences.php index 85204d005..045034067 100644 --- a/code/ryzom/tools/server/admin/tool_preferences.php +++ b/code/ryzom/tools/server/admin/tool_preferences.php @@ -9,7 +9,7 @@ $tpl->assign("tool_v_login", $nel_user['user_name']); $tpl->assign("tool_v_user_id", $nel_user['user_id']); $tpl->assign("tool_v_menu", $nel_user['user_menu_style']); - $tpl->assign("tool_v_application", isset($nel_user['user_default_application_id'])); + $tpl->assign("tool_v_application", isset($nel_user['user_default_application_id']) ? $nel_user['user_default_application_id']:'') ; if (isset($NELTOOL['POST_VARS']['tool_form_user_id'])) { From 260315d1efb48ef1da779a8fe196f747247309ba Mon Sep 17 00:00:00 2001 From: Quitta Date: Sun, 16 Jun 2013 00:13:13 +0200 Subject: [PATCH 10/10] Basic template integration with css --HG-- branch : quitta-gsoc-2013 --- .../ryzom_ams/ams_lib/autoload/helpers.php | 11 +- .../ryzom_ams/www/html/css/charisma-app.css | 2 +- .../ryzom_ams/www/html/img/mainlogo.png | Bin 0 -> 46148 bytes .../ryzom_ams/www/html/img/ryzomlogo.psd | Bin 0 -> 203524 bytes .../ryzom_ams/www/html/img/ryzomtop.png | Bin 0 -> 52089 bytes .../server/ryzom_ams/www/html/index_old.php | 4 +- .../server/ryzom_ams/www/html/js/charisma.js | 2 +- .../tools/server/ryzom_ams/www/html/login.php | 10 +- .../ryzom_ams/www/html/templates/home.tpl | 19 ++ .../ryzom_ams/www/html/templates/layout.tpl | 234 ++++++++++++++ .../www/html/templates/layout_admin.tpl | 15 + .../www/html/templates/layout_user.tpl | 11 + .../ryzom_ams/www/html/templates/register.tpl | 115 +++++++ ...9837d8190f2360e006686ab6.file.home.tpl.php | 297 ++++++++++++++++++ ...631573af77d92f4505c948.file.layout.tpl.php | 256 +++++++++++++++ ...edfb34ea50aafba8.file.layout_admin.tpl.php | 274 ++++++++++++++++ ...3573b506c58aad0b1a410.extends.home.tpl.php | 293 +++++++++++++++++ ...8ac67558b081fc2e7cbb8.extends.home.tpl.php | 297 ++++++++++++++++++ 18 files changed, 1831 insertions(+), 9 deletions(-) create mode 100644 code/ryzom/tools/server/ryzom_ams/www/html/img/mainlogo.png create mode 100644 code/ryzom/tools/server/ryzom_ams/www/html/img/ryzomlogo.psd create mode 100755 code/ryzom/tools/server/ryzom_ams/www/html/img/ryzomtop.png create mode 100644 code/ryzom/tools/server/ryzom_ams/www/html/templates/home.tpl create mode 100644 code/ryzom/tools/server/ryzom_ams/www/html/templates/layout.tpl create mode 100644 code/ryzom/tools/server/ryzom_ams/www/html/templates/layout_admin.tpl create mode 100644 code/ryzom/tools/server/ryzom_ams/www/html/templates/layout_user.tpl create mode 100644 code/ryzom/tools/server/ryzom_ams/www/html/templates/register.tpl create mode 100644 code/ryzom/tools/server/ryzom_ams/www/html/templates_c/149a5753c6489e4c9837d8190f2360e006686ab6.file.home.tpl.php create mode 100644 code/ryzom/tools/server/ryzom_ams/www/html/templates_c/82fdcb43de00a568e1631573af77d92f4505c948.file.layout.tpl.php create mode 100644 code/ryzom/tools/server/ryzom_ams/www/html/templates_c/9ae80e874700913f7c626d25edfb34ea50aafba8.file.layout_admin.tpl.php create mode 100644 code/ryzom/tools/server/ryzom_ams/www/html/templates_c/e046ca36f637970ade33573b506c58aad0b1a410.extends.home.tpl.php create mode 100644 code/ryzom/tools/server/ryzom_ams/www/html/templates_c/ec9cd121cf7179810948ac67558b081fc2e7cbb8.extends.home.tpl.php diff --git a/code/ryzom/tools/server/ryzom_ams/ams_lib/autoload/helpers.php b/code/ryzom/tools/server/ryzom_ams/ams_lib/autoload/helpers.php index 56715943b..09cec04e9 100644 --- a/code/ryzom/tools/server/ryzom_ams/ams_lib/autoload/helpers.php +++ b/code/ryzom/tools/server/ryzom_ams/ams_lib/autoload/helpers.php @@ -10,14 +10,14 @@ class Helpers{ $smarty = new Smarty; // turn smarty debugging on/off - $smarty -> debugging = true; + $smarty -> debugging = false; // caching must be disabled for multi-language support $smarty -> caching = false; $smarty -> cache_lifetime = 120; helpers :: create_folders (); - if ( !helpers :: check_if_game_client () or $forcelibrender = true ){ + if ( helpers :: check_if_game_client () or $forcelibrender = false ){ $smarty -> template_dir = $AMS_LIB . '/ingame_templates/'; $smarty -> setConfigDir( $AMS_LIB . '/configs' ); }else{ @@ -44,7 +44,12 @@ class Helpers{ foreach ( $variables[$template] as $key => $value ){ $smarty -> assign( $key, $value ); } - $smarty -> display( $template . '.tpl' ); + if($vars['permission'] == 1){ + $inherited = "layout_admin.tpl"; + }else{ + $inherited = "layout_user.tpl"; + } + $smarty -> display( 'extends:' . $inherited .'|home.tpl' ); } public function create_folders(){ diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/css/charisma-app.css b/code/ryzom/tools/server/ryzom_ams/www/html/css/charisma-app.css index 7b6ae40fa..1684e5fd9 100644 --- a/code/ryzom/tools/server/ryzom_ams/www/html/css/charisma-app.css +++ b/code/ryzom/tools/server/ryzom_ams/www/html/css/charisma-app.css @@ -452,7 +452,7 @@ background: #DEDEDE; } .login-header{ padding-top:30px; -height:120px; +height:190px; } .pull-left{ float:left !important; diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/img/mainlogo.png b/code/ryzom/tools/server/ryzom_ams/www/html/img/mainlogo.png new file mode 100644 index 0000000000000000000000000000000000000000..06d01c71675296f39dd6d577eaff7e4802b211d4 GIT binary patch literal 46148 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

#2oDSALo+LQ!!7 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ℜc`kMVQc-`>BVdMJKfmn+IuGj>|4QFkM)-~w@1T=?lKC>}*u6EASlz7j6xS#b zdKh1DPn>b{Vmv1&=fPaHk!S}IjAVw_Ee(gUBf16oh_rY{6qJol(CybX|taYsAg4_-@GIsSAa-8cWV*1h6) z3P-*b$ zXJ-Ojm_<(a@0r)9%)4prYFQYVR>+IScylpR*<^iujQx$W}QWAL^nLb1c;a zoOE7`7@f{LL1YT6&0sdMB%GO;nCG-LwB8MV&915X*v6w-J;!TIG;nn3?EyPJZ_Cp* zZ!7I36)MqJdKcA@hK2BL0<9h5)4mMfEsgvQ8n1dI7EEW5yodol9m?Src6zyHgRxEE zv>>W+8H|Nt)~ev^0!21A$S4}18qWcjzI!|GQAcWaz}amLV3vHIel#24YRi|w{Gnr} zy5|Or&hSyxlJ7j#@It>2J6{~FV!|O|4*zRe(lyK`tjG=>I|*N&$dLv8P0=ko7aWI4049e|B6Z-e>-|5M-qFtVutI^ogX1pa#MR;M>6;J5T z7;14mzR#9soJ3!~C=>4fW|hB}C>bC|6oN~G!KO9MG{pR;!NBh>x!21&lmqjqZ+nY|nYtg01U`;M)lp_C$nv9FC6dgW<+(C=TlQs*Xl~Bl_ z(m9_Vs{r_zgT@<^1rux-g9&z z1R7W9t|eU$DhHlwV6-y_LWA$?9AvVxPrE-Fb#*i%npgek%K?=ode!@URh{hBjxU6^ zrB34N-&#}0-gf%R-QoEd5?xUtH7~C=7k${r9~$En%xJorb-vU|g$f@O1_7~L(B1g? zDVYipp7BG$k-LwUo(&loM@?{5TqZL47MVU3K*X_FdB@i#LCxfQwv+qbVa_ftvOUOm zB3yw%b(~6k1St?bZBh&k-o1^?@H_>% z7_WI6*ts%$(0V%=a3uXQ8W(PWXTH`unB0Gs4dF3jG*I(feY-$Vk`>bfRvhFH%^zG_ zh@xhcZ+B#WG{K|gTvO)HpTF=(e%TP4aCb`CJ<*JgI|^j3!NZ*Ro<2bVq=1mJDY=Xh zo&+@OM_-ibx!WtZUzJgb4pObyhxZuEQiWuQ`aiVviE$z`N~5|xD^DaS^o-r90!^s* zpBhb3;onrt?3wDjtz?mrWR~=oIGw$sl9C^ZSlZx*E~r{akc0s;=^8kWciNg)y%)c^ zTnVZD#We=090B>1Nxc**WLO=oX|82^UQ%UxCQ^KcY6cl=FJk%OVHG{YSe!jC(3Hy; z=C|j;f|Afb2?H<9a(8^-Ps86X+YI zTx&&)s=;|ydnaO-^sm3f2F6Z^S5LjK=IzGfyBH_A0EYn3b16e8c|{4wlrymIH@=E? zOo8Ub91^xR{QC7G24dd^zz7_EVAguzV`pW=_PX@~e<{aG`oGyVsykld%STy%nWHzf z*KUQ@Tz1p&*}t>YZ;yCag)rA#Q)aB}#%oMme0C`4bzmU zP7|`HznA=(te?2;Lt1WbW>txRfM40@P(GSu8yguoc7S%nbOk1J>JKq^zf8cgg*VO1PAcPCsjx)su7 ziF9>TVUY0<^k7w;D)bo`m|dHAN>dB;Fvt_JtAmlcg-m*6g@eqhQc)isTQH`Am8?jl8CR6 z*6G|tS|zFOxZ;I$Q9m$MEav*%TUgXHju)g&aO4mpa*dXV#pePH?2k)VZQu{|QP_vN#dQL0w2NyXGr zbdt2KQC}6qrCxGQV~5!%JPMcluJ<<|>#O;y{Y)?`%ME3Ad+Y!q_V&RSIIg~@=YelI0GeP4;(r>i@~fIQ|N9t|H%7#4=$dYz?>E7!M_%nkJf-K zp;J5$xlP3oPL=CxUV$KO&seDlZVN?eVdAvuC?0J{=M=;6kTU-hxxW|ze0m4u{cmMb!5_iG(x$k?IIk#QVVKo1D z9tDJBW@C%wJLo|F0QJcvEvb;BF&gxr-jju?ynI>U245(nUhQm-6S`_0qkd~_zd0xs zP2QzD$$UL-K3r|CMyaxk*#-j*iu?;8^IHVwuAO`JD={ONp;FGslq2wmjO9?6dy5N$pi z__4yVA2;7 zxgKHb@>SQ@fABLm-wFrL@8|vGnR28hr+YHsaN2#de1}N{h4-Nz7G|yGN-toHi(92D zL+t*0$!Js#D+X7MK*EDdO}S#)H%zM#dU$wfgq6lC4|!+>aJj)st%F{V6(8R645#j` zGw8%LMJ(R6WEqT_?s2{~$Jc99dsYynNNcbSd}Sa&B0fI8bIFBQuGZRp2A1|2vr`Y) z2JzD&g0?}3%JIL9pDe8K^jlVwdQExaN^U+HwWY2)sb3<}+=IW|=``;XJ`K@ldG>EP zkA|nzQHALK3!{r6!Thgrv67)W4%U((CQ-6JyWNmt@?ciV!op&)w^zc&?%_+C_@!Zs z8=av)2KyWB7ut!p z+}rw@6w5k`5*Q*%I@M^`qc)TgGKFdT`-ylSI)79X`t#?twA`>)iOb}alwLhkrjBk0 z_Q`y$&{orfP1*>u&=t3f3cW%uC1trQ07H+7CO;o8o28PjPfsNT|M+5`Z?glk|4q&s z@t!HAaRrKnK*UNux@o#FI6pE(fyw{-mnaP9V~0Cfob#wM8T4kfqgD6ZB6!i`5DLB_oL?Dw~66^H5Omh&K%7>b`4dyTn zuxf(GVgt6p=`Wop41=c>{O!R_fDA4S#YNIP^P5tlVh(bkZPPRdI((pvoG!}mE&c9L z1%3u5w%~9xlLlSm#=$1O^VeeV} zWTh8XQ>a;_Cpyw=TA%B%D%b{V6*)3yhY!)n67)HqS?>#bye}>sxf#HC-D^=l#J>zP zB_gE`^3CkTF@G)&iq3;5NlRkf(YjZ1)dyje(z)MDc_9#GDz}Rku4+B8NEzwdJzAwI zjHAco{l($3o<)BjhT#Wq`pP+>j1puvjGmwW4Xk=@U~Ea)3fNri5@QOz<5};$MJtP# z-~UxdRiPQv5ngI318eq>XfSTZ#9NDc&J2T@IJ47d6w5S2KYpcCLg z&4y#j3H5F#_k0xjG+q4_=J8G!umwC_oSpxbfT`v-@PJAMQQH0jb435GG0_un3Utix zoO9c*G^Db!FcQNe>m+G5g`tH!g&`V9`e)`zl;7b%YI#WNK-}yj00|`at?Q_c+8GEq zu61Aa1w74Hd3?uX@`>H)sq??_ z^#{Yg8d5azH8=}P0f;PWwj=&$HL`KZQfQKil{E%Ls~n>gMb7hi`C1(Fy`9^KBp6g?q?QBK?dT&M*xo+^qg+XV3IXDVeKsLT4((3WCp+zq=i1fR)k!BNCAbfdjJaS-@a*jD z1atw@_7QmPZ~)R}g+)yI?mV z^@Y$GmbP__pC#nw3{Woz@r#Xsr=t{|WbE~-9j}8#*HMD<596O#%D4LW43QL3$UAX9 zC{Py$N@;zxC*l~+{EIPLFc z8?gMuEvD?yvpJ8I|I`zcF_pUj?)eNPU?+(w+aRLlUe1j zrOILB5@3V(TcyWCssCvY?t*j?FcaefENk;(o%NIh0G-FcT82bYZa#ldZ~F0eSF7@4 z*V*1q_G7-m;1vTSqw4i>zD<%|h4Hau=_4|L+?oci?hJB%5Nh@6|A*h_nZ;J#vo!&+ zLfxHeUR|z^1xVhH#p(8W6}3E?cKUg)Z<)v&rRw{0aG)DHr=$STb~fGj72rNCM#WNz zIk*4`du)wj`)$f9?*I;5@<<`m0MLpC{DL78%)@4EF=-h_% z&cv^3VPGc#HKj3!6$`e0C`9rjsk`lBnD*1tb)%sBVG8;ha#`%Uw5_de^Gil;3ipFh z?sa*HLeT!P*xm>3Jq!R_Ms$B9B9wr{}79g71za2f@TG6a|;A0OV7tn<*(S z4`%z&aOt-FK)9?Kj!%7x%@&|&%b5Y(wNi^kuY1o4sa%0^N00TSIAyR~aJVxwNQWj4 z8P=0A8frqMk&w7?R*MEhP6zwwVNyx8}7Tk<~uYfc4%1NJ0@goL;xgqBe;(VTmi z-hf;}otlV3W!i?DWRCE4u+LkFeD>h1#y)xR&Q_B$jAdLgivyP=DD1%?!5mk zxvPMI?}>ZE>6iI-{6+Q)YPZ3QWtFljO00fiy!a5-q8e8-#J^isoNy-rQ zqrV>otlY?O0R(0K76F)db%mWu;K|8)UR-^0e=gxLy8wgL<&ze(m7#e0!F&RYsTV)> zHfU%v56?VZL$H_{rVaV<`S|9)V-RH=I#zNwSF*S8T1D!ZkwPC63)j6FmsF8A9t(!eiR(cy~)2QlL8OnQvpaQ8eO zu+WS~zE-$;VpqtNR^s)^t_D=*SMoz%A@s!!w)z2R=kx94=Foe@RUft-GZigWas~~< z_r_I;NnjU(N%KJO&ZTMJ-DL`|!%7yoq^!Vr&rGRxuG+Mo*ZbgWmkkH~z=71b4E^U( z2)Jw__YXh7v`5&#orRV471)+r^Oj`%7@w5wqV+Gg8#j$wXqNO0Dj#FiWJ*A8S(m~T z*I%=ZZY<-CFbq#%bl|aFX}@)gU{sf2862P)ok@fj!m+l`XsKh8$FBaCS3(Yuj#+UT z-*N6AJywN(oj>g9{TBXq)rFl*@l%rel)>;XcBkV5)&KVxPUnB{uMMT8D=O!wql1BL zxwkU$#dd94KBmL8U}Ma5(y3F&lq(faVUUA}^QximS$}M^>j7f(YP7rzEpnia2N(LA zD*Q3Zbr`M{0;JeWv#9~2Gq6L3T(8aj$TxYU5uMlKQCau?5G<=~?)=w_#sry#9w1K41#9K4fOin3%T@s?$=pe8w6F;s2Yo4hbu2YWT9W?+P*c{*td;^kC zQ!*e~sS%p%>dP z)&FVWerk0Y#74?n?jB#~;|=TYgHuD44{Q=T19)VOM|ZLXz~Im8RV|$q>q~uhOx+K% z;+gItCqe2x|MQ<0nh5xx-vD6YQ$=0fKconjLHi%IQ8NdZ!FN|j_aJFBxVlvD!AA6j z4s5DBy=#x6QAaLqJR-Uuk-Of3op+0|tWe z+8nHnHS0NSwJcW7p4~<5yuPP;BZFR@tXe(mB4|FjnHxDIr!e@%PxkVz_Ki%f$z_@c z_|B^+(^xCW=)rX9`8Zf=K;gexE2Ey?Y#Zn-W3B?1`2CvE4nI5Yp;sjb{h&FXTO|`Y z$2+R$$?yIYyc`SxJa}F^R7z?U!ngOyk2m9XrHuDAgbQ##guwzRSDE72OaTBwX*4;p{WE#ojL?`aJXIYN%i!Erj`MRS9HN7Ab0N)QJji!&C z+#NM%TK>+M2iZ~&7`}r~ew`%76n|I<6s!l+|ARoj(BbMe*hH?nAO6TP=o033yKC^$ zK3x`u`SN+PeebkEV9#o%2?NZr_Bp}!mb{i4towjfP||UebTg|Le<*+G`bqL+Q@4vg zx9Q_HXRVfX=&Ue@H4YC|=3Nd^AN&vtcbW`KuQb(+-froL^uphHYhr~c(D7=|Z8Eg0 zi|_WLG@gF-)(BBa7xj0E5ru9{@O}5ue@qyw^%Xn^TfdK51n-y0{^fyv26_h}@X9ik z-W%l{GJHKqS;Ug-w+1@+U&ts90pv4arRI$IYK5VD#-g5WrEHw6vLOC~d_lLxm;*S!CMZ?MTnaz3Y zAfV_!biyHtF-tO)8cGXK0}Sm|roi8|&c}@=y9HnIx~d1GO^j#yJ#Tz33b31Tqs9Rg zQk41r7TJvPbRKB}ehWsEk~3wz@4yni*WNzYg1bP;qShX=o-V;oJ)an)H43<$sfYZ2 z_!_+3SnyVXD3<|nkwJLsi1X#XUT^sQ^6w0nWY5#{)6%*sOH%%hf*=b)-)ME5olpR3 zUNZ31F2Bi_{@VHC$X2pjYCsugVpcI!#U77KSfHTmt}Ej0?SH(=mKr+B{emqs+HC6LVwWx_qfO1FTDjt$` z7d?<`k`0_zv^2ETC$b`7b4MDFU6lDMi&LlIr6?{6RXP@iVaf2J`CMAQO^KVxJm5>7 z(h*=s)R)1)k$0PbA7S$1diD8lTYoeKIk4fweHFTsmCvVBQc*Ju`!_7l;qZPxl#yW= z9w5CXCV+T_#Sj@T7LF&c`M-$my(%lUb(%m7UASqtD8?KaqbeDp(bcb|z zmxOc)NM1rfL0Y=r;d$2guJ!%#vRo{@_nb2`d-m+TXU^WgpODh#5(6?(Vq$Rt3%}hI z=8V)O?b$JNR!aR*WT<(U;q88tR);fPfUFSP$5-asY*fs7&#xkEm-i*ST}!cSYS|<6 z{cq7fN=^V@saat!Xuq0g=l0c^L5Dqwxkx$fb{LpLJ4W9}Td4@i#C1IyVH8`n4nL&` z5p(PfL4T#H*s~qg6<`04ALLl2_|zShoe14uRgvf<89tFt;Wm9S2=qZJY?3y~6C$Xb zDQT}5viF(r68{J$cR4ElhZ>uWNze0p@3IiB0?RlOcU9pgi$DB}VnRbu&)<@nqFF}u zUWW*tmp**)b0R>&&Vk`nV^fh;iVyfnty-EqpU58rS_!(1s|5!@U(IRADP{l#h#0V) zalgt3qSOtvBA&ivVo_fc#(sH!NkAAd9HB&czZnw?k8T>w_bpQWJz2t_Z1rcApZs@A zowY`6dU(Xi`@c(d+MZt1fDqy)!>Gu6_g^X>D*5b4#v66@>IycOuN$4$uTXo-lQAH} zr6*mioy^>V`1=Xx@_lYRpp)##!EITX4D}h%@}Xfce4OM;Xbbj80nE4S*`DKY!H_Qm zGpbrj5L#1Ixn-2{=nz^Wx`bX`7-T-T^$1qTeZSh{dsAaSV>JtFy7(K|N_MtZ?Ai^^ zp3_Br^>mS`tL3iuRg!x&OZ7ALfo68_85dF>ci6$v%a!r-Ef11{xj-G+cCR zmAf7lAd#!Ib&CBP;_tewNf)WO$Dd666A+0Pb?A**d1H1rb2ho|e~C|f%CVV9b+{yG zuchLkGEv6DH3;a^Cj9ta=1w7Vk9;~&szu&x`F`68fY{>2Ej`$Q%8Z9%TyA#v#9|48 zag_J{D&Sk}Ci!Dz{Md=M>7DN`T=yKmytOMXomYV_WyK5jh=D=zU_;C{H*m3?mN`jO zsR8@1=p^R>=<)=W)1d@jkCNgWlZi~=7nanKB73jfP_aK>rsnm&V81`v!vY_-)d|km z+N>wDu(CPu16NZwEy4v~ts4{zAZ^b{JkU+*kCVFZyQ;Hx{&y622*Ok&af{!R>)@Tk ztM_+dSaI61F>bIqdLCAE0jfbO4*j)CggdC{PK%3mjr+wRfT*KJW1os|&-&o7z?LE5 z?f`!TLZc6WXO>Ttk##jO+4ma>BBvp$sV( zEh7>-?{{Fjxt={^R)Hpye_cDLnXb^SvA7b`GTej0ihy6baqHB9L^w+tSo5$8hJ_DI-qZiw#K9Dnr% zB@j$Jl{IfF{rJwpjJ4CrCC_6F6x?t2XXdz&lWy-HXf8v<^UayqLs^fE+AyfGTzt66 zibb#k&K!6YaqR9gDEoL5->$XlAMgVCqaX6ZvETjQ1!vH{5iLgqd3KZ85RP!O;{ydm z3n25m$g)Iud36ISt55Ygwd6whV$t=sE7o_r0=|XHY2u!{|7^9ze7qm+)8{hI6uJR3 znHyEAsZPz8?-nlint_Johv{u5s%y1N2u;_yp>2 z-e!cFRKky(0!n_o*}8FzO%&+0YZ&)DTya0V1yD3J9sZ*!JRlr;t)#33_I!9SKcmn# z)PFcXcRL(#Mz>Sgx?UQosiX_#Yu{GaKSI0BaT#~sG6PdB5@4@7x0Awad%|olR!`%; zN7cj-UqTTOftQ$^7@ZD2=lv@E=nd7<_#H(nFAUv7@3Jm0J%EqKt5|I8834JS%BlPd zmAWLG2OW;2y(ovag9Xqf!4JtJM01R+FeJo@q17pFLF|u!~)vnS;@@w~$vtiqcUImo5%$dQpwS+rw zNp0070=^&w4$@%w6+RUdx>5`Eo^`ma!&~n;L_BYGz8CI+YQ46C+VJ!ol1B|718a9y z6t0^jKOXv*7o8vGZFB{|&bl5kVBZnSOGxbIqF(=yd-@u9jgAW}S+n=k{ECP-uS>iS zjlLIWiyVj=M6Ouyh9>?<{L!E<#G)+BWrxDHzk|^IE_x~rHX%wiPHy=2Q6DPJ!;3)7 zKPkd2<~Eakk#|CMh6ol zNOn1{wtGr}IvM*v3Fb7q^IJ)ko2?fIP$rwX0OyVs;NG3xaVT~6FF>RVHr6@qpd=&% zKC^c=d%)0P6tn8Sf)d%!E6-b2qFkO&?Ukbj)hJR@5C(I#ZmR4rv|;p9+sKHT_X2!J zTc&tg_!{_815uz4O-uZP5vH z`VAx**~yX5k;nEVv!VUNEdD#^SrTDL9#?uQ=K@HoLm?#bLGQPJDMEDK?_LhYhCY*D z#g5^Z0jb_)cnPfExnjRojfgmQ0M>I*Q!ovd(!Y`+IaZ-zst&JpC86utym7;}d&~LS z!wa}9qry;(Jt}u4&_AdjHSXzNefOW@@)pQ~>JOy>gtg4_Luo6k?TKWu=o>#c5{SD` z#ev~g*E4vtdAhl|85jHIBLj1^`QObL9t>jk<~rTTZFenZ%XyQS1rFkoFF;z*veWDH zL-(=yP@}4FMoLzc^<-FE(XQnW*<}4z>=;IMxU@GN@}-4>|3!D8hu4P7`I7f}N_qi zXIz_E54Bh2(Tw-+$F^_u((Gh|f^?GlX;86~R6zVO1Z+j!c(%xrqV0Q)lz+7rT}i#- z2}I+ECxbn*KkN3Ix?zS6e zL*?5j6OGB59?+hzUQ$6N%ogm#qgfOO6$`UhLYB&(qaraHrTZA&64*vF z(RijHi^6bnx%+@@Ol^rTP}NmCs(LfpUKoSlHPA)&XU^0cKBREi$3poNjyZNmOk$ z@Pg}*)x-cE#-O|2mbw$S4@$4qs?IxGm#2xIC7^>N!kc_R$oe`Ahh{ZoQ~0&L2U379 zairzlS;_?1QHT8MCnh2`1I`1)0SXFt${^EK?Tn(fQPO#%PZgwxwC~zR&&zFQ2s`Jk znAM1t|E6sxSU(M>0IKJ79&wnIWoaa3RNjh}t0z4u^ zMxmZ8-OP#RbX3XvIA(W#5Ee1NUp6|d>ghAymyOnJxT*a(c+o!`9Cru z8^rEXBB?L~HNDJ#kYcFJX`yPiLZ+zSiJ|SGo!=fmgdcIzb=f7CfQu~3_8XL-}>8c?AHN+I^0NAF%rj;o)VlqQS`>d zyJvi@^3h+D_)Qu9d*4-Q@x^yBgQwf`#_YGY^K&_!r)EnFb$u zr&>mWH+21@X#$aRM`3%s*$}Ua8=<1!cu6!-6KdBomL1F zZSkiTQZJPB^uDVoN3ExzbZ*CDl@N&DKTN#@amkU;W$&g4*e|?`i~R zG5nHH0&2mw>67Zys8?0<<{+B+nRvSYp~VSU<2uM+_A=_1C1O$2FNr@AD=R6=sNAv% ze1(G2zYkMF@MQ_JzK=DAW-m@*_#jTv(tDDyfH^m@(Vf-d)RJKnn;7~s%PUWz5`u^T z-bsjtp(m9pv!Ea^k86$~In{l|bE3k3Uq)(?l? z18(gluYbmSEA9P=jbjModN}X~sjT{M>o?hT?Xr+3iz=_*P=;17LHU}rqamEJ7Nth`kl%X{%T(x4?N7MtZqLdTk_gpoJn}Lw5V?zD$PgO4dg4ex*p@} zaHi}Svs_1v006ijDtki8wkw^PN=R>42Te8JWT37Mo$ib;aLk$f=>#Rhkm|#wCY;wK z9DY+~4XSM&+Bn~{hsG*8RSK;>(?>tf(nE#-Y>o@0?Q@iARvo~xXpr%Vi*VGug4V=2ks%uTc~rUJM_KUvst<$n!~y&U6qO15ayju)(1Qyw z?Oy}DZTv6hTwPL@(-shxk%^H=4~}W;Qhj|o?@~d=iOt!c7;)#8HT*H!wIpFtWKeXI z+iCeorR$P%um1AOGB9ztT>_tYgGs?>_YGWmK_%kToKV2Q ziZZ48Bse!F$@t!R4FY-hv&oSLJg>p=PhLL-_JLH+#!CeEKz{0P1D{`*`XTt;nvxxm zPtxeBkOvn2`FPs2)s*=ng{Q^tRM+6`+kKxbDR1my?|2VolgiSx37Cxb%3CpDrP(8A z$vdK;OJal3@lPIk@WVlosRH7;c~frEFZi3nOg2UsiziE} zf)WyUJ_Q$1&j_MvM4m=(<`O=!Q$j`#!tMN0(PI)Yzb6k6IaISGkUAq2m;fRfiQxw! zK`aWs(sw^oG^(&E_}FsG>+4U~gTt+=ZcTLq*2^F&Kb9?Kw&Gu>NoaEMAw3B;ZB8n> zzVjp8CiwzxRI)A1?0C44m{srvFuNPuORejZfk@T5_8)mt^ApZVU>V=`EUgTtNPdir zb|VCvUIIz(Lxvf%Qx`*WtV-8^zn?$~;O*Kr05E2tw%WMWrp6a^WjH5W^%#A(%0jyH_kexVx9ukhF z2J{yAUDu%oPydqlSxC|p-V2i&z1&QsRL?9>ZVccW9(TpmP0Sl^z-?}Xf=ujjPmqiy z3m5ZJp4%wP_bk?(9GT6Fl|X?!_tyz?stV6tnD%NV&mlhd#?)>mVe~`6^6v&cK1cZ3 z}c4ANzh0 zM=+C%SmbN51s%R|m4=9ms$eZwK4^16LZv4)osE5gGz~Oq?7!c^$o`4&d}ItMofZ`M z%>F#1kTuXM9Ee{7a?n0!es-{=sr_qbOU70q;Sj7REU+Yck5C6`4J`680Yp65qO!^{ zyi$BEujfToetD0|erbX2XV`{)#>@B3Z-Tk)t>CHdAEm{Gel1|jHsH1sIMPG-i0 z`wKZ{*fbdKM3j?JgT^`jM2fpA!Sau4=X_ilWT278C1bM$6BYg_I~{r{#*i*J z4iihg10370%YPZHlfj`h=Wy=CIN-Vvc*G6nPDIHF&CS$aN$;KSi&9B?{JwQdYVK9~ zMCGs>w6f%W%VzvqNsmoODiVy)J*i-;G)3O+vq^BViYRmqU>Xba4f#e*q46yA8tb*O>KtZSyO>&L_WXSec`#)AK0Py;8}lbt+g!xr#qHR3U`U z7Nj-2Lx`Ley#=HGmN;+6O^Rslyz!f7ZMSLVscr%Qa0X`bek6X4s<{({DgAj75mri} zxtl76PC#nRhN{e}loIFBCs}{d(Rr&wi0X;BI9gIN?+V^?*vu>G+OiHSy}lT7`Ps2o z@#FG%Qw+d;v)iw9QUR$s^N6ADXjPQ1_G(wHVy2I26$!Tg$G)|IGaaO{orn4o!SY5{ zgrVm^GrfcmkyiD!^hyy8yk8))Yr%?u7_CE*q_6md;B#0);aB643nH5as@C}<;)lLn zaH%seBF%b?e9%?g%Fj9YxKB?p1X*seUq1>AjbKc#5e+8UGEh&K5%bl^>d9^t*;lXq zqaIn7=NuK4l-eItwQNhFX_jDkf+`{o@x-EBKR#!Wt8R)@jJJDs491$0B6PD>&|1{! z$s%{5u`z>}Ei>C=$EUSKO8eDXzs{STPX4hLSpMkmNi2IY&~3t<<971_@2(mc7HP1* zC$7w~8?{V%Ir3=y4wwJ%so8}FgW37`YnAmm2lVNrwl|mfLUj#Pz(Eh70~`*1${!q< zMHaTi2=wt6I17d$+w1;ZF53FEUO#qV=$P2C{t3M2N}Vq7=` zMXM9KH8-})On-L#a&?<6I2(3m3AK)wB@J&DM}UOkQ1I;nTbx0~dB|5w{5(yT>p~oI zm?iAR&ORw;6r#G|BdpJ08-4~ebc`QxR)ivmDRFm0Prd7w-3fI{29tDX6UGGzW_PLHC@fgk$& z+*GA&BuEfhVHu3U7PPhW^cZp%jqZ%TM-cvl5@m|{K6&&?LEJKW)1ny9*@tD^z$q6G z^Rs97Af;ke@9Ghq;W#MZ6}g?TAJcK)Lh=ZOL&4Rp@tklO?~Frn;In!)F;n6)qVtdt zb`f<;FxE{jtDVs#s+INn9)RGqJ89G|CGYj&9-BjPV6=Q1U6G|P3`t72?sckHfSR30(`-56^q2>WfW zK>~AO4N`ZXO9vF9nPV%bf}@!!(lEx5~pZ?@!4)+x38 z)zxRND;!D+zgK51DL&SF&Idnh@+q|huSH07#_HFcVh*B*Xszx+~Ub91mW}* z36baHmI_32)y2)j{jfX7m?wWS4p4^0&W4K;eq*@wX9J(ahe^~JOx88Yi z*ffDCHR1p<#1JpMplKYpZl7r1nfPq(YMIG=I(D`a+;*Wuqc39BIjNFGQ1^tVq*PQ; zk_S&06r0zcjYS#E?n2R!5z)eXKg#EmQd0(vWTF<0e40Mt)k)6#Bu5{Z6`8#D!P^Rp z`1&@6CVy*8h&BRobip6zZoZNM5F(KY&v&Zh#4H8-I7&u0(x_0|!Ng`~XU`r_aFYSO za5h45hDKN$f~%!pR#g`BNCD^R&0p74-_-Xv6P~-bMq5Ij66cogf20awxzybTkw4V@ z!lc;wC#^T+B({ye_`JvaqkDKY6@K$9p_7&`{!Gefq0w#8cf4i_vIvs5RA0Y--J>t% zjX@ru&WIUi+RcsmqKDSOpe_1%3ewuzy8YL=72a@HU9)bw>q6&t1|D=T{@lSjdGkQ= zc;bQ@WWxEd=eyG^y_kbc`t35JZP;45$R-d-n?s?q@OS=uMUIcZvf{ro+1%Vh0BSq_ zu`vGeCHoX~es-MvAHmZnQ=ZqDMz*Q2Z7jZqX+gey5lC2|tqy}13Sd9k1XX>(xqHn% zB^1Wg*YrMsQdx5)nbQ|9N?{4XKw{dN{=7Ip@xg2$2Y(~0*Vo%t_s{*`Qkl05MxqE6UeX@MyWKI8ixmzD~z;Cx#Oq|Sc0(c<8)6Ts< zX~V8F*8?hdLCyN)yXRHBnx_XV7ZX@Ro z?oNk);}eq9SVr_!AFh)X>Vg?wuPTH7xNk4b!n>}vmqAHRC+3sjaD;#Ljg4W788L<# zH}j4*oz^EQU>Xo*n~u+oABf)6Vn%P4r&*FUXL9~TK@Z2K?yd4Wt3nkO74^ef#5HQ z2prPsvQREN8>+_Csh)gG#E{QGN=6nq_AIxc9rK}m(>UYdQmxCUHGsPpc6 zuM!ZG`$`B3&SB?JNar*(K#R!l##;`Hm%*@)rjxYel)iSqr&OMij+Q_*vZnU(@;Vw9 zJ6r}^Rk+xY#mU7>QPmJ3A$}gUGJYB%M%5r4gFui&(CpYBtZYb1fd!CmHs{*gZ3{=w zEuTrIjeZg5VVZ1v7)(j+AcNr~nL@&3^fY+!slr&4zH_m6!|ykC&bw~HyBsN-MJ7GK zLE0uT1oL8m$E*RA#W9q;-Ng*(oST~yp50|=5=`C_rMysn_WobGV~x+&dvQ%D3c)kv ztZ*)POcNAqUi&}p(aXHyIc;-Jdf`$B=VEFY=e(hjL~iZn{ViNxXf4t_rf+OuAn z?_6{tYeIE21uX4GtJmamG9mE2V78*;KZ7*s4`&B$*?@hd6KRbQl4;?Y%zRG06HO&n ze2!-3=Z66Mw_ZLK*;-i^zhWiXb%5f$k8uY29rp@3tu)9|gq!`;=_KQh8wO7u)1Bcr zNqHumBo7F?0O>*oCn`Vm+gdlR=tLIZc$TPy({XQTx|aAozmGCIPHl(o12 z*#OhNS^pO9P8Q}|-OwN)^Hnq*aHvV9ZrsWUHIO}jBVIB1@YcPKdoCBD-t+g1Chh#*MO z2uNW@(!h;X`sxHbB5vg}kOS|NgGt7-yMDOmACC6*^@)7ru0$Y3z(q0<4=u_>?T%Pp zUOt0Dp;h(^t!}b_gm`s#r<6_!zc&u8cZx-MCZPKmfOSHU6!A6II0C*O3$OYSwyiGB zF3ioHXXUYEBcNHa*=Yok_AB8te@f`PV$@)a*eEP5Ep2M5uWvuuotqaQ(JF@wx@f%! z)xj(+4KgLIX7^U}9A}-s+86njX_cf9H`D>^<;UV?$54!4a}`~G-$JVx-_U$CiR;zc zHsyOf{Sy#Y-8dR_O}SXV`|HDq|0hsjf)7GlqtoM$H-wlbvb@=85YX0(o&FmAwCgks>6+GQn#S~`!v{`^byw|pcJ$?fg~yTz~=E? zDzCmPi&ng_Vg}X&`;Xg8iYORwIh3WF46#m<$W!4}HjD8_4D-QBm=o}8rZ?$~Jw2?&wQ&&}o* zH=|*W&=N;7P@*$%6!p|%3P)$BY4z5!Q(~h&^+n<4r+V3WM+`v6C2k(`FgX*I?zjTh z4^L@X!GJ)bXeJsM6PZxJB2(yVJwQ*?*nYAIYoHLc|251uoNG%yFgS=8DQ{}=?7RM8 zd-vSd3;hfXwE6}5El+@tjs@z90fS$x9C~RfJ^oV$Tr?A#BjW4pYkVZ%yTJSVPW`~C z?kH(mC&Q$zB_&abcPZP#0Zvx05!6XE%6+yYUsFS92A%uk8KKQ92T%P?O@X>WXVcPl zBLrq=&xf}XS&nXi#=R*aq+dtd_$2JAf;v*WChSnEO8R8YgZhdZ=k`i6B$&?Us-F&I zZ#_`L933AFMKdL1ujr3EWRK(f6gL<>?^Cb`F-(9WXpBVeft<8T+?p?oiKWM*e+P>W%JKV5KW!03y1sV~Xkbu-ShMm6hB+N7iMh?31cs(f= zEiS15B18Vr)Kquh_oMw!$H$*)oLF4NNHJG6paOY&UUD<_)$AjtGyLX|c*rz_AL2E) z`OAekfZLpaFGe+eY?}zBXYjave(SyG>9Qw^LsMIGd3k$td3$?xefuaB@C5ni(p;_j z{Mz2`?Z55|13VmSYevuY6u}Wrlzr;-gQD);Q)tzQ-k=8nJm)NTfgG82zBm{ zHvCWJH40DC$F+$uIz>lOZTizLl2}dLbWg-_hOB~D9D-G9W#So+5T&5*@0AqjvjW(Q zaASaa4B*D->hqJ&(#O4GOI2n|EBy2LuXNYWN|R82M>x7>X+MZXv7J#dh$W&O6mX7N z5iCm&d$T2v;cO;CD%d6}r8KWCDXTVs!+EztnY=lD4pZ;&>cTQ)Izx?24{UxH;H3N!Mja<}jhR8hjZ$!ii zmK!YFcz*Inb9v>xXJvgmW;}~blBHapMxQwk?0ElOoaCD;iOxL^F^csUUNJOh3Eb7h zL_#Xhr&<{m0s0&$idZ8f&d<*m_TJ^kZlL-r3Fs!0LAt3ZS`I;XCi8JYt`1nC&hf(N z7}U~q<+hwy6K^GE4D_|N>l!;dJyg!f3As1|$E?EhSW^2ioWHY@r4_0qZn>ta?(Q8M zXv24AMO{o1SkRn=GeL9TYnI}Yi2hxi3(RK->axHXneQg($Fy50E4~GHf%`K)zd@N&Y}SIaH&f4sjp~LmFY88 zWoPO?zb!xinct+^C8aw~S>5MsU=lT0{*w@P*bGp5Yv=I)uOt>=7Q!A{Sk>UEx47KWr5p1Z6F87S+Hx4#rUyXp=g@pu()p%PcK)9ug{XsOFc zfQ|{L9ynVy0+4I#s`D-5S*xq7n(hMwqWp$k$R=oWx6?FCk9s!4sUu4FDx)uG-DHJ< zV_oDRRlKRKwA;A46(sb_Z=GxzS^BW-Y3+~XaG@>Razt$8c>@246a#Z-DHdbp#$o!ur@a%Y{$I4}63oJ>rd z*0#H&Ot?J+2%j3xxOH$b4AGXqlUHN3cBt4#M0JwJEJ>dw?+B;U zMu<4>}``)MnVGwHDf@I~3-&9IUpnK1zmflY;j4_d$dCV% z*?qQUU2Ldm?7bkMq7((}8YLP{tWgt9EU`pQEYT#! z7NgjWUFlVd^j>F}8D`e+UK=dQ`=0kZe&0FQ_4@(GF<<8;me}>+1W8d@BSK_7#Q%5&XQ#jAtIH)0LP$^pwOVOs7OaN z((xTQ>h=u`@SYzY5$Ye+-+#%Hkl+A+M#XV?SYR)a)m}>$hDU`*E(~AN*YSPPCc=Fk zS!+IMoya;v{YU!$snsj}m%M9sSY#9BfbdX9WT45t|K4OIdiz8K`A3CEObibX=|70+ z#P*Z74Yl=|;A}f3I4m%HMPy%w@VCP6W!CpyR?ratsG$DNy`5Zo_IB^-)$XwDEUtem{XvCl>dJV<-@Z73##z* z`_IY<4gD8=`1yGc2@hDtY|M8^|7FX91HA_i9W>a($;)Yo*ATa%&Q4CAgPom*3~_Vu z8aix{mxqs&DAm8$`@2k#=NlFo(t^Q#AU(!BcT+Ev~J}5FgWEty<{UJk77k5Xe-uP>(`eF7z zt4{mRRX@!BXVv#LCxrz^^>=Qf_K)O$)*1u0mIn<9UJw+CI&SU`&Tby~dgANl;Oy?~ z;OyawFVZ|+9o$@cg_qy)5&R&v%CA?-h&499y(}{XH&!f*0QE%|Btz> zpq0V@g&nY*f3*Xa>itRZ%Ak;`LxRyyBAISo-67%*EKb8+`{cXe>>?d9HEyh2YNPR@;2XECMm>VkAPr^Yg_ z4y=}kc!f@(FQnj#6jx8T-r^Pd#67f$EA;Q-0_$K`l*iSJT|H3}S4PVPw!*HAiVJLr zT~QZTu`Vpg)yWmP?26Xn+L+=Y-g~mE7ut!dSjNi@_a4qH-2>K!D{Rsgos6Y>iFLg^ zSzRwrR>sSdmGSZt%Xm47_YBQTMDy}u6um@DFV+$aBJK{bTL;*>gS&%=gQtU+14QHG zg0 zD%@;c&Eonf34B!HX6tGe*GEa(YP!B4tn*-kw~6*Cg3{mO`2M-lZuSu6~9$ zHo3R|#dk0}i+RT4RlE$?K!{kYTzoV#oEYIB7P-VfA}B0im6#)GA?CEh)rd?a5yYQ_ zkw~%x|075c?gPlGCX5QPB+w}p?+6Lx8Zm6dXZGG`3ck2BN`yVWeb<)|eKHC9jv~SMhCug$ zq$hDf{@eG0#llUO57O|Su!!+t_P?*x)JRq^Y*|PM{xODSc*Qm>Fmmj?MFDtf0v;a_ z<%B1(=@Y}3*oK6MEx@z*H#%s3)Q8W5qryX*p7Gi;A>$V;Y|0m#CX2+own34TLqkw&pHu7H< z6+S#DEGPo+xdtMEOkA}jsHw1iV_}xUa(qJ<*y7*+Hva-%PM$b)>O_!g5-t<|-&6b| z7X1ALWt4B^h>3oq=i!B52B`Zs`EP~w7KTTx9uyM1;H{)g z8kryQHW@W_0)yuJFAIsnt={sWh^T*4eDd4mzZW-{w?KT?=>y@KHR2B*{w@Pm$e8dj zCTqQ@@FioHMMVaEXgK;IFrNd%8p!VN;r@%|%b4K{qjA4^d2rAQ+{feI zK4e*FFz%VRwG0jNM`x5Unb}7L1uVpUZ`>P3OdRin`@XO$!v!DQ&->s$3Kod6#3y{o zDp4o4T?4w=;>|!$+Yv!4LV}{AdVYdmAn=a}wDk!OUE&{x@vD(%R*RVb%R6pja^vMc zW`0oaKix9jHs;ri6LrQ}J$;|{zUKS1@Z<2;7}M`2V`%2hIAR9S-Az<_EDjCdhU&tSmTe0n{B97%cvDLvYyN-eUX!;s3JQ z2MFx8(XMf0aY9Qh=ky|`FD!{r_LN9042UrEd*pEM^fp>=GGRS$O8bIFyT?89#p~ZL z{4PB5k-_4yKzznev<+AmvAnT}g#D9Zj5Z;bq!npLI+Cs!pPh*Z=|cvRp=2Z(i}-CC znT?2TAqhqFwt}oB(PT5(M!q87kOSlhIf38xI8S~fSID2_HhDmvke4KZq>(I=M@mQ~ zkrOo{4IR#iv*22B?YT}|56+qM<4$wG za@V-q+#~K4m%?RpMO-zf;sxH2x8!a3&b%Y<$q(X3@e}!3`~rR{znb5~@8rMbkMrmF z%lvKr37^1c@g;nnKm-H9O6VZ;6g&kVVXQD+m@h;Kp9))reZq0!yzqzcP>2(ag~mG+Q&OMRtNr3<7h zq?@Jtq^G2pr1zx>(mbhLCX-poy2w0aBV^NLi)3qL+hvDk7i70&uVimzbvimat#o?m z^wSxuei!|I`V;jR=|}5-tAAeqzJ9uXje&uIoq?CZ zID=q=4F=yD{9^EzLAHU?(A==Qp^xEA!)1m$4SzJeWtd`EV`OC1*=V5AbfYMvokpjP z?i#%|syDVU?q%$29B91W_@MD+<5=Tz6FrkoCWB07o2)k3XL8Zxg-NNYo@r-OA5(wR zPfZV+UNcQHtuwPQb21xi7HYQL?2OqXvqEzn^Umf&%>&Ihng3vZ*ZhrzVA0XS$0ERD zqs0k}`xbeYGRrQOzLtwDw^{yd`P{Oyg?S6t7L!}7Y;mx~jTTu}f>mcLU#k$ST~@zY zC0eOk+O!2>*$lT?V)LENU7ON& zR_zA1Th#9Bb~oD)b{NrNS%+gCo_A2& zb+Mad_nF-VyNr(d9X&hF@A!4cI~^UlV_)eo%VNn*h$g3OXn$_ zw{*VJxv-0M7vC!$GaH040BoUa@D2EwTEkv>-Vn7ZWeBSZd=^$ zxM|!y+#}r2yBB%bd(8DXG_H0cF(`Oq+Wx))_eWwrSx|9j`IG^yP{9eK8yRD z=~LLZOW&ZrC;GnWXV=fa-?4sK{cZct?SHg?)_@KJ{0AH#kTbC3z`%j01{MtJHfYhH zbA!qU_Z}QE_|jm7kGIb{pIbwOA;X7k9rApr`Ory24-9=h%x>6%VP}U`4tE>AX85fU z(h;LZ>>iQiYvUW>d)l{hq{qm0Bkzqe95rFofl)c5yN`|-{f8g#H_~sfU;3C%W5UK< z8B50cj@>&p=S$-xN6aeMMoAX7LQ&0<6;^zCFDY= zZs^?5YhmVLi^J}Pw+mkx{%T2&C7YLIE%jdd&C<$XU0EYXa8XS=(W4^xEuogVr7Ul>2nv zr+3zOT)%03-iF~Deu~zQUL5`Gv)-TW`K)&1l#PFEve~p@)0@wSe|~ne@#culNn84C zIr4?%i{LMwf9dk&cVB9^25x=4t@pNl+Zwh9Y=6ANX~(xa=+5~&pYL+t_5D|}ufo1c z+&y6TPkYSvtlslxuixIwU)z4Y_3PSi=6v&LpXE3CN)2Gk0J+td9e|Fi~qH{CPz5IE|&sWd)Jb&zh z)rD=pkYASlQvB=OUlV^D_1m3`o)^#m-s$&4mn<%Az06%+b-D7&!Yf%@D{Y0T=Fx?4+bmEK-(`^}v>chc@oy&HdT+`Z@b zN8SJH!LSE+9}apL^H;yW{(R*9=-Ok?$5)=XKe_zW?dhdwZqF_~cYl8Qg~yAlFTGy= z@v85uo3R68Z^sRZdl2s%|0H2d!mGqdiOESbld_TnlM7QqQmRsyr>fI7q)XGcW|(H| zd)@Z+@yu?S7qZ;5Ze$P1ews5OC+$tZo08nf+=jeO`9}Hs3fdQ(E_5#ZvuIe+%i_(=@V)80zZk z>ggKl=^2_C=o^@|FflYVX<=<)(Za&Q+RRY=Yx>vt@Xsq}WME)qY-DO|Y-(w2Y;4Ic z#+Hp$%>Fw7^cFGG1v^It&W`YAoM6V$46F#~(|gEXGffF6;RIg7OLb(rQo+y#nP!5dgSnG*&^Uh!yQR_2GRxh^ejVJ=zQy?4 z^ITjbK6~Y((`nCy%IvCuNH?qFzisS1Wbeelp?7|Wa&H+sDJQ7<;-+?2x+fj|b*Y+NJFKs^Ds|UO;k1&2A(e4~HQi8Dqx zzHUd3tcl)Y^mOHxPb1e?&MNAjVfjtVzUhyD`epCpkhDPamp+m|9)_fqUD|a)wQtsR zi`E7G7oSghS>#}}YVl~B?W@+D(_YuajJfhkyQ7nLutVmnOXWe|?Ax~?aJpjAg0v^= zQp2>Vb1Tz4Vs(4U$;@hlbdNRBD_)*D64$SjN7-Mejtd#(D_+f&J|B<};L-1K`^A-~ zV*4(CsF`T%^x&&eGIeN&-#*=&zCN~(VtU34IVB!*Y8JlUJUXnEIVBkm;Xi7_YhvoX zM=qG{=iVp4*Mwj0Y4yi|H34^LU1~8|({9p$6K&eY4zef@NGp>M&>qYD{{CdejhtT; zHg(q$VuE`bw^=uNhG9?baIOBH!>;?nY<8ZnjP(urK31>S7L!PmKM!9&cq2xh+VAJO zY6C-6)bArC8)j?PrH%S@V;f2~+Mf+Qac0tlMNbybxGK!p9=23c9=^aUbLb4;k-qkO zCeW9no@}3Kx2$iNK}qq*3oC!#-e%^5>+$n5a-;jCm3?JXz9PRzs}qKO3N&qEI!tRB z=$)hr;qJd!$kkk4p__5ZzTFP_)L~Cof8TGE!I!`9Y`cDh=A1^cM$>tHM{WAPNudu; z?@Rh&(ZbVr?;ja@B=u)XRBk~t(@L%-OzTiu?mFPnub;aty87mz^!r4s%MZe$inBV# z_D^zu@j89a!O_12&a}>4T)s73Ykd3W9gp=>5>hD9y%hTEx3&8pUiz$cqM{+uDJD_X zbL!XEY7dl$@M*0L4(Sn3@1LJ1#Kfo{%ZDcIopyP@)s#-J_s3+IK0NUJ$-0}AJo6o7 zz3=xMWtoe&AC8JlpX;GIc;iUbi1ME%1hqI4<^0gI%CYl}7urO{v4n-cJxJTxX5F%l zN25$@$`rp`iCmsU$q|Q9Zpz7*j!w2#cKE6w%-QD8QR{lf9A8XHzfPUg<8}|^J3Lp* zzoq1d8#AX;a#Ff)Lb;*sFMFS7hF_&*%Chh&F$>3CnVf8+KG=4w@|p1k?SYX-Ay0Q* z%uT-4CEn3j&ol6kqoEL+y zv`)PAIxZ$|ztVcm!8vuQcOG8XI@x=iw(8S9cJ1nCMj3NouHN9DIOC!=?c$<2i!bd6 zxRtC9sf%b`Xy5z(>?6OI)wPPT**a^`<}2ENhCx?zP~RJRkZX!oXG ziTz|e3~Ua4RoBNMbkZLWzYX9bcWvNDK6zODJoxwYvRAd!{f~OjC|!Ik=D5Z&PC<#= zqS%}J=8P)(ZF%28pADkK>&*2(#&9Vr&laD(x!|;ThoVpONvS@O0{EE11f{Noem#=s-nQD_?ItIu9kbF+phP^ ztkZX!=9l6S1DCA%QJSy3}2dl z_(pr_spHl;3vGYd?^)b7BzXDFvI`L-7v|2`v1|Y0>5p$5En9HvuMqbu1}j1{%6`?# z!?cT)G5IeyuRmd(8e$?FJ?&_;8Dk`2=-xmeY2Mz2VZn-ARzR$SF_ zDfHU0;-&VnPHF$cX1}KISy#Tdf5w=Kbou&m_O892Jd8|Nm&{!=BwQ!M<=0EsDt?Yn zt4O&Sv;N28#FM)c7M?trzjf%rnLZ_L40S>x+s{s#{=_3h?h#)%AZuTAk#(=AYnz^= zR~sBQFDx4{^!kd6iWW1EoK5gF`7O2hu=3WPK{`>lRijtLWN7!+#E$Q?dY@B=va}iL z^By|iYCXE8>(%~OT$Gn7=@ZZ+MdjXAb1C=RWpkIOCxzu3*Y{cXvm!>*T6)8=`!DMj zJ;~iuFmcp@1)$31FGHYDGne)2VeJ| zUz|C=-;Q-N=3c7S3k-=onQ-m7T+{Q5?KXzQ?pf>UT%GaGKG#2u9B})3jroM&#JqNg zrv(lEZQaSA$&RmJ9tx28KKvGyl_etxe@oaLmQl++&kdBv&xBWrA~9qc#1OdGDeADR&uFHc%G z?@F;l@bcrrtg^V8Z{@2)R@9GuWjE*F*zP{Pn^~+URUs5vsin4vxwvksZKTZqybla^ZNBB+? z`n3^)+sygNZpHO$8S2b~%B^p#QW`%D+6_uc$uHyYbGnA`6W2aWN2eC@wJ!A5uE z)UMZ+scC^ruL{a>=DvPDv6W-%yH+ng^oo+9w;fZa4k&!_tYUzoF4X?(t>}{784)=n@^yT>Ld!w&zK>)>sQ;MG2Y5wRv~Hi0j%^ z27xZ;ByKOYMVScBS-fY_^Uf{7;gw2=*JB{{M&HI3?_dOTBx$dpo(= z;)hGc9~}h*5sq^2+jf+Hi_bkjD!jdCzo;wz$v7-?;f}+~{|9_O)jIV$GWhx&&F`;H$r9#5q#eNfmCwgL7OUsHS;|M+X#h+{1x zgN9A`aDRjhi|`Hmx7%iKYl#>rC2pDZdT_QgLjlOY-)wtZOI*qv7WubbHPDWDyNSm@ z$gs#^5pQX;4Y{}IqkY0YXd~lme7Lxks4G^(MU=rY@u_X-{0Qthh`RrP=O*5{1v3e^ zU zR;jsdM8f#(DDKA(@5v-Jw310`*k`OIjgk_93!7m6+mg~5?Y}B00{!c~lvuyjA)_Is zRd6s7#Fp)uiTO{5wu0LYz^Bowq98dxNHGlG1(0MYzHGcs$|Cx zWbz=lg0jT_kezPx=YLiL(Ug5Iir41<&2nhAhvxp!><2#H4>XTW|Fh!~Lu>X$&AzDF z7k#`hYVJ49{pQ1d(>yjck4?=!q1h*V=o6alq1hh(|6mUoo7#~M#0o3m);Q7JLj0V^ zj?7px9;=Zv$t*GzpBcDk8%s;ce6k34vv9(BI+=pcBr+L!qscgwpCp!_jkC`)a6b|0 zji=wk7WrzK=A)WY7 zKzZU2QU|P&+F~cF8$KOzXGiSuW!J_}N76}rV*lBvGwFg)4MC!Qdl_s0Ylz*-5B_&**nEs4N zIif%KNNF0CmK-0fOSpojbisJyrTQc)D1PiGX-s=b1WwQIS}c{+?CijC#bUu&LOH(2 z$%YqHNSGkwOT@%DBJg?v*-xoNxvd4yl_Aldvzp>RXXexiV@C}iGH5_wZx2^zM~7~m zJKDBwWo2n@W@@ajBjIX6!m9s}vSIunGp+{5p}G!M4QoBrXJG%n-fmsYU>qE0WYwy5 zo3=LX+S_)p>!{bMbC<5&y7zGC*{jk~hvBs|<2VKATkOz2qQb?_JV2$g7H!+x*_(Fh z=HTe$?BeQ%le13UTk+t5a-5xyVweGF^z-&`bMD!xrBn_&fePAA+n}nK*H%}Ql@#XX zWTvMk#l3ub|Ign}AKABgp`VMH3dhOL7gPSE0Z4G&OBGNBYSb0K8mJ{k1D~a)XS~kL z%FcO{o0q4TUr<<7TvA$AUS3(DQ&wDd^izxX75(5hv zDO9ii!YCbxnV+L5q5K_F#+p}oHI+WMAY`zL0g`Zr$9KPfhYESV0;J7NRcmM!GKvXj z{tP17s>{`5KZ@fg*C$gQ)ps3vj+1>>LOJc!S~OhPSWP8(Z;#(oL$fKL*qT#A5X zqC&opz$x*dcZ4Bw&n-&`*S8)``Oy>&r>LxZDv`<(P>i#vmC(b7svCYKPh2F)sUsv{c0`P2cr zcoMpVS4AlrI}O6ryHX1{Eg^HOX%6LIwB#B9ZGW$jN^aJ6}ho@vZP8+C_#=<}o?6x>iJm zl1-iXI*7UbhT?qap%ofUW{JRxz5sTtDxqXcEo-#F-FWofK^)imh1g~&%L{(C+*cgl23`akS}x+sF2qr3 zQb&$VP?u8vo+%8J>s=*>)wF>$)>hG6%4sG+7@Tx18vLy_hxf$<&g^qdAr&+MJO?Z3 zSSTWAwXa~j0y;{B7LLM+d?({|e*zcNu~!(5_AW(x&7Lq={;HwaUOzcZX|D-i1{!)B z3n*9Mh}O2trL>%qAVAs|0CK4a$$cA3rOM%icvQ01nlU9C-$83r+5&f&x|Z_lx(XRO zVQGb23qdJIu%>rN0*P}L@LN1@e5?SSSr4`-w9RBRxEqF*giJ^Oh^QqEgnU&_B`?1_ z{zrZhm7LSzgdJ%83|Rkg70wJsfegP_MfEgke;imb!*7sFciKtPxl8wm1~ll5E~f=K z*C6}5z70%>Q;&m`TBnKB>IYO2PB;v5n?!P7lvCLb!s~Zgnpr}nwQhuT$_CVZ zGf0-xISt;@+kt4CbPbiMAAK>rEo(XqLii5s)%H^pZV39Ypq|9RsdEEs3Mv1{0@f?E zhXl(gx0kQRL4&j+%6-SxG5$6{tlOBOIG|&Z)zEST<4{SsK5}rl5*y;vw0O7q&~S4( zBjg5Aa|fjju)#~<>x>?k5A)wvfI5(&Lxo5srvs>r)PTx4L8P*pQDL(0oKQ-o7j>}n z`3!75FcWnyIS9U9+iHk(q4MRjZjxHD&r29fWlmseYy)~!jdw2Uw@-us|1<Hb8yo7QO%z(o0 z1dS}aBCx-6Zw;qXa+KJ%d3|xu#G12^b zHy{p@v*zQbTM?i?nLGBxfo~%I+s)nNjGog*Z zoJSq3yv`YbvV%~@Lu^v>TY&tgV^eYbM z*UxGxhy?@Ju`(Z~B*F$a!CJ)v_L&)A`RGzAJT&Jw0yW1TrwKSt?;P6u${OwEwn7j| z*01q$9boU_G`#VB1`GWu2no)Ej}u`RG{IUY0QNf`HQT4c2xi;o0(ArHHoht}bsm~( z@(|TeN?sGLT~-m57TDvEMw*DJ90*?{I}gy^B4}U}sNEaf%x3CCv+nI~YA44TlB=Kr z7X@;?*qFU41D*DJfNF*j(j6lcWV{!SnX@m(%x1C# z*Jk(7!YhVwG~`pTUFVjL?okIXk249|7=zQ5qppz>Blsk7=kHFm4r>xdCzpfMZx?{w zAs5)c>jJw|F|dm|+vSSbH?95z`OEqkC%%w_)JzQ?4cFztpf0DG!?FI+p_d8f&>#EYQolJJ*TmXZXMhDy_p|71PH+-{o8b^xt(v z^wH%YcfWxNJivf2XUzpjHfwmV5)pbGi&j|Y66MVq+{XA+-E(*YWFqWEkXS(_Uvk8| zUO@$|U%PBTKQ$GhebcB!bG8?ov~b*N)E65p+1J3L(X{qZu88`VF&eCM4X72}{YBKZ zgxiG%rQ47-a>UtfO`ZZYvt1)-I+bKkH{v)1vu%^%4aBB;RWnc$4yWI>0+do(0#kYc zn1%MM8Kz_*4puSq4>Z0H%%g(rcVJfb5-~@mQ$EWc(jbYTVf`y>K-xoB zTtR0*3MT=X)!`cv6332=ZUOT8NChBg6K+2sHG@P*zck9NWBRfB3m&1c8^r0OV2C6T zBdcfza#sNI2LYJU{?`WD0RJ-p`VRp}^>sOwl;E(^8rax$5pWCuv+S6ueh$DCE7nGX z-&C}Q@_$*dnT1Uz9Mw?P#v_1y)!{D@vf2@&apyu9t`?A&brE|5GD3v>B$e`?^Wc_6 zD_p7-z{jW=BAE^YZj}POxlD}bfcKzVhKTpZ4tSCyZyJNNp;`cM6T!x%Qm)($B5cGe zf|tLkqzDybOfdW8OdkX73!v#-0ou>b6(U-kC3=&e2A)~&3EbY*;QdEQJ+pe&VQZOR z(!d5MYz70c(w+nhTwxX1e)VhDNOg=r#m8oar-w zCbbel;kLMa`_a_rtznd6Q`4-_=7kE1;Y2y2f{$B1KS1um!+43!kQo`A0FdA$i!n{NOhLVzc^t2pX5ZVDkTMX}tgr;J|Y8ek6=V0t% z;aj*!2&1F$HOKG5sES`u!sJ)=tVdJxnV(r#N9!q9hSRS2>OB0ygx82AZzF(j z7|}9SO*NR0`he;6;IFhB(AmhdT|~z?F4@bG9>rzw&Td9GsvxsQ^p-&HoXgPp{Svq| zGDHK~Cp@hl!JBE2-yM*ZJe@E%fQM#nR5=2USW@6R=$G)8mREabS zI)R1``X^ZiVfC&AiQ9%E34}OO@ImZzAg5J&`#|EpVKhj*ZUYhyMIwnELJ863O#>(5 zg*_6D%AauvrDdnVhTNM>Rxv@Pv_vp738AIJ3nXlEP%5RBNFo3v_JIVq5^PlTvwsa& z^u%NnXk^(yu>uw(R0u)37vWqv!AWd{eW;w#4kUV&gTy60vP2~DmoWkbt2nscr)(j} z{3VK&b`fa=VczyFnG;IdVuB;wv6`!aM|ouqvy;9BaTyE<2hbhh$^SoDd!J&W{F zz|dFoSe4^3gDSxoG#-W}Qu zJT=`~PIYqId!^q9?Sa7(qwbz+3?*D)4`>E!t1D6{-Az72CoOgssSU3MwOhtSI4x2; z!j^}6S3)3~(V)klWSvDM7XskJ26t&}Tg!*wt9H1_PPm_&20PI5{B}#UR8o9)b_W;> z*R@C_xs@+Pq}Dzn1#?D?ugOy=^_&3lQoz{Jhd@e{2IORf@C*{7IcJ560#4DvOsUxSj8M(VUIE*7`cC* z-av)qmOhBx1?_x+jg7qJ*gzD_l>EIRPhwr8Yw&zyGU{RuAD0qX7!{AUV~o{(W8t3E%%vaV_XuWL!CUXz!QnmxV7` z8X2{G)fWdYJTGLi%^1rBgqo>X^ui(vZ@LT4V>yojdy10DePJyoLkPr5yQ3NKB3wpm zu^H$OdRKKE4~&r_rZ@!S%IE>NuOpar9@dwao<}V2GqZ;3WbPkgAoSdjET^xjkY?Sv z3JX6Oz7lvy%uTS4!Cx@NxIQ7>k?DjZQEJd3KWkZrx!+1878s8Ji%ter3lUxHo;|)Tdau8Z85|W+=q3jN9 zl4kTX+(!LmwyMdseGN)GEMAsTovJhA%ym3=zR}Q3Dobkv$J+j3J~h?eUD3C#fdEnP zf}zcTl@B4(`Tz-=baX2bX)dXTF9yk{W+2(O9&|3kRU_ZvHty@(uz1RKdkva--fRhu zb7cWZjNztYs{1(9M(7mvl7b}n4Wz~Mj>);yp#JsE)BAVtK6vJKrmBDnst_5EelVk+ zS;!aQoYUV?OSv5^q8_USjnbYXy-sh+Ff(TJym56<+RM(MM*Pv^s$F}P7g1U2`fftY zdH1jY%_0S?IQGrJ`ffvnE*3msRzER(Oj+0}zv&(X9a=xOMgfPq5w?Z}hNaA3unC^P zNf)zd;Zh5?n$y&qsfz0_X^t>QV;OA6)(P8q`w0A@xeM#B@BxpUL8#KCWu zu$3mbZ-nC9tB&<3qPMsP3~FXGbFyPo;rLE1Phbr}CA&1qMAzrXI!u<-gR$Pp@$FAw ziy&pFz?kBe%h|kcgS64~d;W@dKIbx?TD|~u?GVV8@Ea?rO3U3e!x}s<8F5!zMx~eG zM~tpPy;lv*zRtt17RqkTGS?aKLoI4OF~RabXS}NF5wd%VR?`PdnivQdb5+POTV4QF z<#&{e>q_LX1_Pt8CN3^MULB{2SH;m-;Z^KOO9g4q5zD#1W)@W`8`Nr*QmLpeE6jNv zd-E_}rYELHiX=8gT{-atolFw)f|?koEoU_MN-;?mu|=*P};|pFDl`?8S?h zuVUjK4`<8Yk|BR#7pZKe1;_f2%UyYVL%b08Di}-6x*YF#L`CU$0w(g)U&P7dwQ(d? z`%3ogLCmH7T_IOvh|9>rvW2;+nVG3+ixzTA-ojK;Og?Qi;J^X>`}gy5>Cwr? z8o$m&m?8wzB1;`pyynAkPUj0DXx+yPTJnZQM#jck6RoM%Olz*O;0-y<#IfzwW=r)8 zDqQa)u&$wNuCQ#d6f6u0T&+ZR#N~VTaxg#)Eov+^7BX`aL#%Xy28@o=={_%N+5Axk z+&T7=j?oNknJCeNLRzOYmIqwH>UjJ@a}MKHE^~{z#vGS~iah5Ff5B_F@Ml=PR?D+W zSxg!q(GI_Vz!Bpaen|SCe_SrB=&3W!8*4j>=<&Af&9c<6g7!Edm~- zQpuC3j-0p|h(5ncgCRqs8g&BA=(0J#64NSa#;2XI9hAk|VLtI}X%-cV&yKgu#+Dv@ zj`>q9rCOokurBulY`Xgwh1HnS3RxSw^6A)h>lu1BLyL}@d2(JiolLO`KT1QjsFB=> zJ4yth$JT;cEMf?6w)EiBh>px=NW}4HrK%eE{Ftjgg=aW z4m%3vSOF3Ww>wHwh?QX8W#F`ht3Kbn<%=)3ZCSZsy5GRw?M)=fjaBXQS=Fkk0(THq zd+sQz$C{{6vd2YoP%NMufP78aY#H}0@_X$pR$&EBDBtfPJ&b(3uP!}<0vUc%gw@F3 zRop<)ktz@O*F7TU>$K0;YHqso+yiJhg(;mdXCgT6##&w;73$88G&&}hl=Z4FUeSW% z4!~WbhzzgrIqfOM7LCyG$5e|S$W=m7o1@sR^>yU99ZXFUr@f>MyJUaOZ+(*7A_knL z+Zg|q+Yg<+G8+X6haZEJ@Xp_$h!DTb4!XVzUGY74y{JV8p3g-S36Z$$D@S(L=e?w7 z$bDuEE!Gt%!NNQq`G|6f#C3lKN|YWQW_%7m00yVy@n=1iB#jVw5)JV~`%<@WD^Wy! zb6%VCi-y^Pb`?DpB7I=_I*~LVSyja+LY83kSCwjo%_e z8NqQ|K_)f}50A9CN}jRidS6GG;!q>FiD-fiF22X++)RYgk5~1QT_-OX&z7r7Q6|P) zz@Q(EH}wR*OLP{-`O=>zx8`o*g-?th{ceEk>J3nl0%gjPWWO#w11NaCftQLieh|qH8H5Cfg-CWvB z{{af|(tZ~ZpgkNe#q>RzV5!h(*zt0#6IEP|a5Z{F5{V#jKZFrXQns!o2R9sz-(nM_ z&Ra9FKvf;H+S~LgNk)Rp{tCeS?j<1ViY9Nsl-<&&sZ=U|uyJT>;U!5Wg5i)O*N(8oB4G}kU(fJAYcV&tJ;9&= zrO+ev+&9H1P+9h+4Srosc=oe$5;M1uUrKAKUSK!>roA+X|F1* zli=3bDEf*>Ob2X!*6@-V)Mnf|ylVE4-nOPX7@+Hjp2VPauMrEsxR5BvV%S}Ot4x%C zj-Tlpvh9`j8MV;VWIelbXv@mrX}*1(dvvk4wP|f-Vr^sB#lhKQ$dtvO?ml%ZwF+@V z&6zP~8K{b1_~Wd6_axn;y6WoEqWm{m8L6_gtlXlqYD5ge>m43CX(;vx#@lM_zW9b1 zY*I^VE(O@~DM)@mq`Z|+^quNE*!`4fUViSOpNQl;L~86Dd@{A+0nJC}-Zi{M98zP5 zRMKYXx~qAQu%RJUJl#3kntO%x>qMs4(Qm`0Z0&P+Mrr<)6@4u5&T2HdLS(wOLnDqo zt%!wlmKNXoa$G09$H=%ybOkeq@vDA#SlEz^bst$x!nrkLx*9$}-g%AzOgW}99VxbK1JwE zd9cvBOvXW_ z2}pM(jyOQ%E#|opyJ&J5s*tiDDbmx`Nx)DMjRv>kOxw8)8|NRsX7ldvPnGVif(Vjs!xeb;;|cB#0{0II%R`Os-d)Cm&4oh zLbARmswq_|6)H}tDphJ!QZ=Q8TiP_95qd#n4u`6#roO&hsjaV3VriE03DdFR&3Jl6 zbafZyQ?*=CU$0PB*VidkDuHSbwq|FE^oX9d5%`x$`DBDsk~9Qiy04)`J)57Yh8=}b zpqgBvZmg!EFTL4mBb=xD>CcP5{CwueAC4UQ_M6>1wr>7x{hAdKVT*$1PMb7-?C9YG zy_~w(w8F-pgdh9Uk?)m9BJzF~vT`n4+~!-MCz*I`6`L2GNYwLF@oR>eO$iDN4q0LnwQ|k+&o+L(8Bxi$&(-Lu%D^v{qRs$kApE+FK7D z@>Cg83)i`dY8%ulP6efD*kY}MucyyJVqYk=VS7$I3_A$C@Xa zr!Ag6e~xH9E+Hu;Eh96xw7R}FakneRa%-I<^5oRiGIW>aY8+B$8mwnnI?_t?B-Ou4#31BuXTWlcjZCs$+5 zN25}pd}I5yt8l(c=O;x{QX-d_pp93?39riT7!?s?Kh>M2(^vU8eO0I}k`)%@zmY%1 zJO-5cL#2;YPaB>!JlDRUFX<~9tBq@jmnEd;D~b==g9GzN)oE`VFP_}0sI024re`pL z;LV;=MZKV)*RTY{w|lKsDm3y22vrMKC>Wq%KvOML)oLawh;&kwqO`nBQ%)B=;*K`nzaOULHF{ zR#dDl!6AkcNpWFyb~kpiNa&oC_(c6w^GpL)v@dmE#l~W4mXMIBO`^%Nl;q^>`ixl( zq@{O7VfLH6e5Q%=ib^np17@{K1vJ7hr09^ms$ndqkNy-)sKJD)PA$iT0jy}N8>%E& zsQptPG2EoOx?&A$LK!K?R!XI&%A$tSw0$#rTbr2}8@1>@{L45>VMt149pfhyhx(SO zlbhHPVyn+cN{E5^v%1^@@l0GvsisV)ysWIWq=@2p5T-fXD;_t19ql{K&^QCePhwJX za!N{Ssy0oMTB3>;G{j^*%`3o>o-!~b@}sSj$m{4?rX%MXbV(jJhryfkz zzzft2!DLnPTTK#|46Cb8;A87|lo0(-X+bfwebm!b5THxSOO^51UWAqgRz253OY{RR zwPadqRFcS3#%mma%z8sNXo$fWb#>#JMv)~oG;>yhwVx5HdX-$LqcLm)EShTTuviY| z&?-_%E9)RdZJDN2TOt&fE3o?^?UpWolb5H>rvJ974D@3fVE#-FOu-ZqlT?&7JThk-Nu3Mgo;-bu@b5Vl zU4kaIbsW@`l*FvAiJ{EK6P?8kv$RBCI7+M7DNS)~VmbmtYiX^jj#p?Wqbr#`$G}Bv zB-K?_m0(52th}_Ov_WJ^Q;b<=p^#5cNicUZzo*L4=3=&(Zwz1cmbEhaup<_bTU^9| zi)CdcPtRdDfM49u#F#vRQ_TZgP8C(6mN0fSdKh%qa?M{NTaxaXNl!$sI=^`N@)h$A zu?bmOnQ4iM$zThn2OkZtvT;ror0X*~Xo;j-k-8R^SEmr<^qdq1Z*ZH|sB489ddCoq z`NBWcNUN)A>QopVu)Uxx(v)b5wME)OOpWt}ywWOnFvWjOv$by!(}FEo6IH6YW!yPE z`N=aj0AU0ISK7GtiTN3sc~#2twA4nfvPAz6uL%!PM)zUKQ&>;s@>&csysCaMj#CU& zC{#7PTsu`m%(!o9RW)2TrL}J!|N6te%`0@mmqtb|+jzH5Rj4h1(dE%x$(wAtA5(Yh z=?!@}+WRIKhkG%+u&$4eQc|Dihz*Xe8MFb;k1D10iaK>cH!P9{sFEeH#l*zA1U{{* zZv`=yUZADS3`N#zYMKm%J`kC6>X4H9R2*CzH5MNqmzUhxu8U{Ljr#mF)~&L0Fs$Z_ z&JPgEie4CrS|N&8G{_}&wNM&c)7ww0)EI{7eIxMKE>m5lqN;@NX7;f+lVD;`a9(FK z&1=Zl=E3yd&>Ts2W^s`Nm}{3>nU(W5?pSD2p_zgGDW4im10n~i)TvjF2PyAVdlnW;Jy}ZGHV<*o#9+y{d|@p);{^H3xf4Ip6rU zV%z$>ZBAuFuJ(;Khi1#NGBaPNYrljsa(iedlA6p>pP3_6R!oobxrFfH$|w!mLK#jGC;G`Nq1U?r#X+ zGM?5b^+moa%8Ka)8FnSsYLfZXloU-eNs=dX>YyrO%palUP3mH!juK8;SKb?GYLrUF_|evC5XUL%;khMtZ|ck818D_c zN#|g#zQ@5CrqzgEq_$aQ7$mgdhh%8ewP`|nnr1b45{@^#eycA7v4=5zmC#MugrCx& zmMaaJ{nb?Acz#h?Z69#8Ta`?~6HTg5mZT(AUB^zVeybF91@j$n(@a%rglBxc!bjxG z=wa@2w$#kVVmNti3SX3Jqa=pMFzUhYh)O~&I12?0&=85_G_4c0BnEet^gJ9lx0`bCmzY-kr>uCm44o#FJtBJvAbqzRT!5a$>5IZAk=IgZ+MDsJc zpZ9{X)HD#Mrll4$p7gz|tIEU}skT;A*C6NU3RshCrMfZL)>dn(gv#1_A8c&2N>P?H zlnN!KG@uZHvVQx_;`EI4^t80pRP+Y~Uz}#Kl9+F!ng8TQTf)OPW)XgxR;>m*CZc{S z%fU}kL0);T9n>zpRGmb?QA3g%97)i=hP_bJ4q7SdNMs4Ibv;LeM1BnK7QBRqU}1$g z2xp|1Fn(mZFB!xb4}j$AQoO!s)lD`Ab&#D^=1lrT}^dWMR_Uo zQ;?tgMhnj)SUxUG(kA0g8KB8h(=sy3GTYS>L$jw^F?-86)b&@R}1X28{j^hIMS92WmWaq;*qpWsK-12qb)}l z6tG<^`<#3Yq)Oj50~4=?S#UqNbU`iA=`U9_S)K-#haK5^UQQ1+vK3PtD=LZwO9(2mvMLx` zLJ+3P8q7Qqn#<`DbnQrrp`eN)o}^9D>IFo;h9R`5u&|&YKR;Lg!h*3S-L6W){H39> z5ezl8<`&*&u@H`GF#0triUmtdQ`$0)ew9I5cPi8>7*jRqN#LrusIVX}_f1Y#S$aFL zKo=~=Edd8p@g(}r9d_5d6e}iQBTZAUA4YQTo>^lf)&5OxS8J=D9_3 zu~#jkb+w4eH7o$3moY8U*T13t{}_7@Fv+TF@B38f>NL}n^9*4I2M`7jP>?vFWI=-k_1r!0YO9%K@gN6Q6x&vox7{MtE)OzcXd~F<(zY_bI$($YoF?##@FwC-se8b zWt^%y|FidAd#$zC`t5|`i^DRI7tTV+!%jmTo|{{fLxfTDB}(B+2RY z6;3Eq*olpN(J;x$h7>$}(=t2eU!b<2NSS&bx6A3URbC+f^RDWYrDj>l=Tlu2Ez6Q~ z3p|?tVNg|qcPbVd(07)LAFK%bJUffYM{|#Re6d)W57qq?YAErNiv7GK=+3C75nn85 zV!`DBulVwLvX>;`wWesO1kKtv@@CrbFjCz7P?+YZ{S$uNa_zeky*R$0c-SYW8q%3G zdlScS8+D(tB-x1=<{uv_F3fIC>QTO-`AczXTApSYuobgteZwGNIzwA5mSESwxamH` z?peZ+K_r4A9V}@)Sw2Zo_*u@z=dB;_HG;*QsF0P{GT~H{y)S>kE%EJ0J<0ZuqQl!ouaPG{p zhio`YV{&{GUthrhW&({Hc0Oy+u^ESKZ)eRAC|g!JX+Cm!^sx9E_GJ?ucHgj6go)=l z6N+IQv0CGiuzVqx*!*!3o-L2D$d|_atCB?R!KrGVD@2Yiqe-#9sEWc~N9R*@eYDEF zG$);bnBD21$C-_fU>H@6AFs*M3RYGdh7k7FbO`FPdSd2j292v-(fFLQj+CrMGFiwU4Ri1lMhQZA9IIHRfOVD2D(g3f z9iIJyD{cC);>P;ppCh5E6j!Q#hEX7Z-3+G?@NKKX?FC^^^@~_am`&W6DAUwwpTjWH z7Cl?LK7jh(a-*%TQg$|zN{`o*h#XK7)*qQq@wk`5s0EiCo6Iig+&_}VZn9{e@^756 zWsetxwKM*y=?#>Du~Z%%N;v1og`&-Ln*9j|UGq=GQc`&>%B1^p#T=Qb`Ast5lOHFg zZB6gjyqM!O$tkBGr_?oajMc{%DiYtd8PW^M9Q#>LSaEPXIWH0ul?GCtV>WmovzqDX z$jYFgZtcvp&A=Wb9#;m_l0?qVSf;0^%0ESo zeA-%ADUB_M_EDO7exJM4!5d;$H@+>C z#p2782d^2?wgrCjJ_C$IDh`VVGz(v;d;(`71$qFf}-ATuYgp+0em4 z(-+xU#oeOR4NfGmx-o30*K!gbtR+!)Y!V)j$xO)J7QTWo5xgnhzSN?9jZsuegQmRP zM%ldn#J|OG-T+4$x%h-G9!<0G|1_e~_a-FVmDxiDTAC?7V%j?yax3!*IUyv4HKD3$ z1v;|tW3ggFj!Ve1riweQ=w8o_n;>IoXmCK^-!Jt^z0FXdnMa$;g!9#iE`r=ePk^eIi? z`eKlB4W-CH6{ipNL1OWSSTvn^^*g8nSZ;_<&tQN=43IpfndFPCVNXX0hfK1K%`v+K zi=uW(m*oWQ{d86$28$t0I9ff~DzqGt8iyDIiIMuNea$_QUkgniI{Nejd!y=X$T^0- z$4xfBg)33gPZ%E=O^eG%%5rEkoB@wZ`U#pqOS4#xkU;~DkscmOUrSPSkdmkmOfA;{ z$25;bET3v}TpNof@}~!dhKtLV>8Yu#Sw+jI;lVOu!0F}n^s=&x&*i#WQ9pPm^CNAa z4Xfl!tU}YFp$P*Y2)VyR&wjJ8d}yX`U_eLD?(b;AvE>uxX#_LeL&Q3igWJU~nuL?e zF*0vnw<8qTj>hQ39G{}|k3Kw*yqliAQTqy`?Ep(fgx4Z0EE0yiJ30I+>GGh^*z#2j znby%!q{mI7Q9C^7&|{V8_Vc@^;Yv~@EzHSw%6zCj)w8pL_7>XMvq+q(*e|Te*10F; z0W~I5zOT7AdcCl1dZNFsA^Mh17LGhVXQzOyp8dmTa2lx{z_A z%oA*~I#50t=X%$%NCA&82Q@zVd6i92?{6JX^fkrK5l)E?=m!QGXbNS2D++u5Z*7)4 zwXown1P$dZ=a++Cym|P)&eRcj@|I6yBlT&IwS>jgXX{=er)L4J-&_5($%eu&r?EHH*Q}5J01ZB<8s!oU*`J9*>$iM7Ge(*?WD4;31NuJm7{V?R@TMFPAz%xSCcN(C$bBNbZ8+QHg_0$m zo}MhAsfUVb@{8U9nz8!;m2dmO`uQ<&qT|$bCl0ybM{UV8VsDLr&dP`4LfAb$`yNC>SIK z{r!EWxgA_X-TTS5?q=_6y?lf5|UkY7U)?>$A$GN=op{gEIb+P z(d!4;pk~OF+*uQv&MG?{JVKH}%gF|LxJN^K{!IRKsJON;Y@8nj645shI-XQ~yYbyc z@c?;|&X{A}uO&pPgF%!cID*;0jVf ztAQTGGHv!+Hi+n+%^GP9V`I_F*d|pG-uU?KruSsZ`q1Jf4fv_3Yx71|5RN$aTIXGb zu@uhsp~BovDi~B~2L=an7e@qb^A|;jOLD8QVPngd{Td(p8*2Qt%Z5wXns62+;E02H zo9hmhwe~w`xjl+eg_dsr-_bi}?d{j=p=DsowiOZ0Jrbmd{*^E&bsZ#RYApK_3N~7f z4v#8}LJ#w(?vCI@P81GkdSCLx9hsMb)f9H^E!=tLv2;PDJPhgL^XbJTC{>XEn< zm3}}TROLy^`86*R{B&>u9W0>nCu2KMTB-S`?58QU0v;A6U3m0vv(02aZ?eNK{KelT z_hvCJ(OZN)#wYvw`}Ga_0ljr>CA1tA3pm}9XXU&%2_^JEljB7=`?`IdlUN&kMC4vg zSMX89#3bfJ5iUx7L})@dpHzG|EG^iE{=@_5ThSyJ1Tl6-+@M!;+ip4kOj2ZFt|_-J9ua>KzCiFC6F| zR_1KKvwbNAn{Q$1$<9>^pP_-lGmTk&`y$L*J8tQR8dx2ualX!*O^<8-NK~>_O4`F_ zn+-SsCAh1i?2vUkhpE|b^nG6t4*A_L|L2-Z&pqYn!w>w{hNVjoF3gV>iDR&%hG9eL zlBl4$68Rz;E9MvcXmbr}0-3oHuLMkjjGeXTua z(>mdYp@BXOS3|$P&-XTEMs`(fR*A>DNPAjZNE+U^Df&rc4X$0gy|*9Q#9nPr*UZ;T zXs8Zt{qum0&` zoxrDJPj4?h$p9QygK@ZgNlehLH09k8C;5c{!)G+1AbTJtEL%5|aRzJt``0a-PUmEnF6r;6ku|O;7k)6$Gvv4NXaqwyYkoDITIR z{|h9$8{YEvkUF_X(=~3~gXCc=t+=qMBR*D=5|$~ieVZ&Ce|rhWou**jw)gh-bcJv` z%Q3FL&hDO`UcJFIW}b1xZQB;>({p(yBiDB$LP#t#DIf%8><5})&beny*ogA^V&-qS zGUv3C9g|YArPEWBPR};vmv4#nXu5~&-&S;eUUtm8D%{kWJ@&1#uxagt151beZ#`^1RP}Us z4LObwRFC=FrEa-P?riSp@gA>;l6#k+A4HEK8#a!Z%9o?WdfikG)e$nrs|t7WF4)Y& z^dJ5JXWCCx=zw5;W0)K(-Qk4kc*D~p^$YqkoV=!<$+3+%8uE8Zy(B97zbME$C_Fnp zIVqaiWUHcR#AI;yFT+6I9qGYP)p}UBy3dD9FOAg~MTEe}N0Hs9WjW!T+lFG5>oW3S z6W@VJkJ#PRG5h&4Vav!^XQ_LAulE#T{lH|GG689Tcxy}f>bRi2jp4|Fw6GBNYs6s1 z*$rr8U)d}Pt5#1$k(Zs{Bqk?Dy<@9Uczu9#q`#zx$Jf`?9sWI zbBmuJ)1`PB4$$sM^i>CHh`yS84c@~MSGCV#r_%QJ^aoBs;^*AL_*iWmRX3weBPO!J z!-><8GX8NGbEVc(>sEJ!Z=uKEqxGvC!u5G;51VbW+P4b_9*ADfSbr}bo^_YInmYU4 zJB7wq-0kJ=O+CSLgiVI=E^Z0x1A#!Md?Tuk;oRKA{Pg&8n1bP=WnEC%u=dh}sP`5( zzAo(5kTLA*UFJdM{P3*4HYg6ru*c2azL&HxN~7c5QjfN$d(eqUU9)n;V*(Culp#=R zq_sR?nb?S-IL13z>#25Yy4t;ul9ny4?P>S}%DzRrk7?L4x3944g+`(I-;PeXJKwdW zeX47Xu(8A0+0oh6C3SD<@t-MdHjcxGrWG;(lWiOs9Um|MTv&bU$xCw>5JwJgTZSOHOVe(r!vjcK(wjs|m2X`n2=TGmw!d(4 z;e2G|{e9`KL)!fh3&LLSM`i{(+dDeDyZb#S(2`LEkr^8{jUYU#+$^k`EO*~=NF!e8 z?T7)TP$ewW2+gdI2zxBOTwi9dsS%FbzBx!HqrvPx5M2;IikXHagE%A)GAPsZ1pcl? zp~Y!|K9L4$bYcU}`*wt;seaAGj7?nEfIe|K7SkT)QJC6Vx7elWFn6vZU3)AYj7`;5 z(Y}f?9k=c;oKPIvB542N{5sQhSZA;AG<4Wq`-LOqo-*`w^tlcf_81%8EzD>_t-(a) zHeuONE+s}kx?vv`8i4k8!%+-{N)V?Gv0J0U-s`UHuB05*O9bKBiZTV^wa@!m2EG4Z zjYz#6Vx1Wjhb4nN#2`?s?;E%7i$v1((JrpfJh-j^tMISH@W_a4YNddOwiNxC9o#_e zhC$dRvAf!(=`>hy#E0mwZ6pjIh`T_fZcyJhGJAkrsmKc?XVG#2( zD-%N7s^fk)Ud=jfVb@;5Mr&A}UAbs2j9}^v>Lb5Kw7YfGJybEu!_3e~j`l!*;ufT2 z{}AZJVkZk??L?WI`qa#*gpq8))6?JTbAN#DckPPy8Tg|x3FQUJ zwmV~&U5(y^SRQ%cd$8V(-@0>Ds>Q=~p-Y3+_fI%#`?ftduV1xn#Y%bAfonGHedyUY zzdVu^lPvOfEAV|~jrmLGA z5DdKYGZ4vEHhmQ`z;5#ON%H%Xx1;o1`{7(?kKA4AQg?(dBlYXoPJ5BVA?=tA{e8VX z-Tm(G2}=)e!Iy3wGqv+^?(FtoRTB1U0C(jO_aNQ0Sr7>oqV+yrwG~k?_Fd)lD-q(yTSz)z|pJFqoQ$%jfHzQHS|EV0L^5k^0L1nO<3sIX|fPeu7+C<0S>! zF^t2qfemQ~2aLfZpgx9Y09N_x046tvywhO& zZeG~`1h4)-1!q5KP`y#MQ(g+m5q}_FlU+|Ai>#Zj`9w6i7b4&tLU4015>KSEsM$x6 zS|e&I;$c6|k=@L--Wl<31ud*Mr|9KA1kB?IMpipKk$hw+patKX3XN2e8&&p=28@s? zaWMkvZT3mLKD5Rn;}-ZB-O?*o4Ect+Vp`Ng1NQ!95UhIArwG=xJO81fzWTQ94(qUy z^!9VTQm4v)J{s&=-nD(**;($Yb!$2-9jFC3;Kza9|I{4sZWZp8xn|1iBbkfF&g|!x zBe~n8+VS8ltDx8!3pykOCDaZ|J`}H_)(&a->YEzmBM0*4+cB=iq>>Yb|Vr*8u`%RB;Es`&0U?HQir&^%=aIJllq3uH}zM=xB$C_?KCI`B*>(a zLbX>yHGT6L*?@9JIa@*Lg>HH(k$&lfWiY$Te)wL|F(IQfT7rYgpt1pDoqDAivA{2i zrZI6;J8BB_p!lt^>4TIJ-WqJQ);MfToq@{#has=0)Xgv>_0B^{U(3-+BPK08=FZM) zhx#k;y(sJWNw6CpLAASv^{oorS`_xaCx8#m%i}g`%9cG&SUa6|Au$i9fE(b(aJ0yx zubr_3+kD$O9~ZT90tXwl1%Z^jO1Oah(_T~Y&DpakU|TceEM$isyZX2Tw(Y&ww+{Hh z)lUrOlGA1hr^FJ%0?FKf#hZBx0E-6gd&#kh329tAKI%5FMN#3N2BZwhA;r?OSvJ8= zzvzYIDsq=Dh*BU?Xu39up(AnS4$W6HZ|N{}+CO_cr0zTdivi!RvanCXJ2nzWhKL+# zxIB|nQ`P&>j?SpmgN7~~uA+{kA;T&iS5OB`<4L-IWmsxK92JCWJkrb9bTv1ZLUzen zb5)$ov5L~0iAp6Kb=qw1Xs%L>TBq|EQSG#)_yIx!_5L9z26Iw7IWe0!JS{BUyC*j} zHcqOBldlq^b$Q<`B?NmVIG>tMbKh#hBj}pHoa=(BLWibZKeIoU=#tmHop6|ny$pe% z$#!H#*mmIDAk9f`U|}NRAwXAfW}UF2yXwMOEftxRNLIWmnQj5>vq5{*b5WMAgld?O zHNQF_o(DJinq11|sd%fNH9TNOws6+w@ZjS2TM)Gf2qNYaOA=Lps>- z!=oN5>0%bml-IRAg}VHk!tqIL^K-#(V|+Akga*h_(o*yZS&T-Yb7EkfNPR#DnvGCY zZO78;ab1LFkJd*c?%^WlsHQvc4yrn}7kT@8dgR_s$~LGBlX=?WC|)55JIrE`s^&A1 zhH#|7f`3&V3Hzr#@UZ~PRB?JzqwO%H4zgzog6@DG77v6Vl?7V)SvI8xu^CE^ioNQP zaO@x;r={^0Q`g}otm?~I=VTko`m7pDx_3iTX!>4n#WOjc{HzgP`L6V+Y;5I@9VH96 zGHriv_|HueD(5r@3>3VQPw-ZJqQ4>FONMvB1~#fr`Ou$6y=*PqOh>@UL?q}r70;{r zaVQg%aUi*#pMCSnSKidXaz9oJTR)al0Xdw;OjKooP5RdlP_3ui{}FE)MP(9N0MU~r z;=0r`aW=aAkHr!e9hJ+s%qOBDQ+DN@B2Vr&(>Ch&#^k=EQSsFF9ICoeQbNsC-TR=4 zciHWp!d&%d1!3bps9Q#T39k?1XE`{^35Wb1|Md5fyAo7KTzPKl9NoF+oO|x2XEx@A zHO)s}bK8B7KlS7je}4S&NACOO&DULe?hg)H0k2Mb%4L;v#a+^Q)$?0^atZ>rrrV-Y z6mruMRXEg;l=JVMf&-{^2b^~DDW{%x`srt!@uM@(`tgs?J_ldD>w@#zvci%xCtymH z+C&_$VOj##>=E5nmx#P3^R_|}mRlfFOW%jxShMD`i!UgjFP+aWP+fNbBL027`6fQ=@aAP?#sCias zT=#HFj?q~_J^3zqiyje0>`Q1{#-9hn<=PiJL)7@K`r*YIi-3xv*43+9bpH}sv}gBA zxqzSkS`M4FE)*BbpP$=0D>NPTPN^0R;tQzoU-Ff_qOXDP^VlPFp;$%MU)UT(ZzU4o zx?4Z%==l7#!`={Dm)|fdWqq_&(n-G%u7<>rE*Py<+b?Xh3Jncsd{&YYwSed^A-hH` zAGCKihQevNGH}B(zw&+8M5o3^ZQ&zc7j$cWHX)`x9tnv?RRHHlReW2dTI;=hg;i*6 zI^~TRD<=ZeqRaZ1v4}fLoYuIe}3m78sg;RF!WSUNBdX9 zrVgWF9>ZLZ=0?}Y|3FdzEO>Dlz4ZRE)*%rV?SFzBWzT) z?SJ+i&wSK1!Yk5kGsdouUVr9+pPq5>DveF~!fg`+Uw-YmTlJiGiROoB6P`Q;ve$LFx*o8F!5azEUZN5|QKATwB`&39VL{%OKMQIzviH%0 z6)1EQ>^uj&UP0}yM$!UXub>OFonyQJhX^U7Dd!|CxC15G#*NQlwrj@G`4pF=IR zdMz;SFXC4a7yrgu^q8sq7w4-u(4wXi!G|U9Zge?AmGoPuHNTD)^Twt%o3qnWbV-eTeN3zxki0Ohggu1Eg$<*+4Gd~07Y z3I5IsP`hleyKT8SxB}GpGi|lo3v(!cbEHf9>({*rB*4;Dci76cLOPU?o>(RbCE*#y zD-ia&XEtpa9F|P#(Md~fR^%D%>DgF$?5=&^Mhkq)PJ?}+a~U-zjgu3OZ0h5SSHCX|2(9~mB*#2Hk26|+eoYNV=}CO52*G!n{G%OR zaCnBs#L2=$#8fe1abK)-_L8bABA|N9E5CEW=*?i6)8AvhnA7|9E?QXICHM=gMep z1To}HGT!k&+f|Lq)LTHRuQrO5p0-op?THipE{>HKK-(zUqre}LNd_zJAe`PQXiAS3Q`igb;?s*yt(LH1h{0gICbf_M=y<)}Bv4@8};A@k#R9aF_$v zg>~tMJ+XP5-Z$ktB!Byk`czh~9GUwL__)fj({n1mVzMelb1P z-QHQluZumU-X%R9G%)aF~j1aKeQ|@h}=&*mn8+P?Rd)*OhaAf5ZR2uvwqSYa_OJH<&=Gp>JAC3v|CPl;A?-|FCI;Tt zmZNWYWjqpfj0_AR;2pQ;G9R7U>=p#!cX%OV06(1i#{s|F)YZ|IM7nAfeM^sF+8y$m z+h4x-%H#H3-UP~XM%bWf*?7o>54<<(i?}EBz5SH`9(5OkubkBA#Fst5OhWU9A3r@B zbeXz4I&t8Ov{_Y#Rob(uZN;7k9e3HUpZ#Rm z9tzk-_1#^)uxNurli|YjLk9z5Mc)d8q1xku7bZjAi9RIaYu%x)&G_E-&R)Z$%>!@9 zX~sVN#&eI|bNkIdyW#4~FWl#nYi_*d&buFc`k$Zb$7j63fXgzf$8g~c1*egH23tD% z*|nRkc$2?lgF>rj?_E#meSw*wuJ#URm#VWvZeP*a)jteFKF5Q13Y;Qqm11U}$8H%n z4)%1mw|C$hyRqb&y8EXhsnG|IXqu@H4sHord%``RSVL|+F%s?eF4igIYik{>Q|J^s zRPA5O?W{w_1Z16!edGSP`R`}1o2q}hTUgq9z@<<1VKR*O)5qt!w8%De;%^IGnaSwaXnf{8NqRUDi7|VsUtb9!vM@zdaugSAX5u zye;h4vf;p!uYTa~@AsSSe(EN2+pU&KO5q_{HGy0I=n$R+KJ07k zZll<4#sJ3|g88)IpA)d)L;O!o^?#dzfx-DVj6?wc7lg601Er&fcQF9Bl=S}(rI3X4h*9`yCW&p1Um3&5N+aN8E)a!wY$ z3nb350OK45?9CCtxhP5fVpx;PXJ{Sm;j|p>VWK zH-W=Ai9c2C2H>>)HvmrKmUltp5hV${9;TYd-t6~I$0r~C`<*vme+dK|g30_2*qhsL zzUjIvfxS8V%u`SJ{-Fx?Mx#Fa&6l$OkX}^(V-fb|`M>@3FHijGKd?8~|MaGx0ef@H zZMWZX=Uu?w+>`#Tj#xT%=FKP*s{r8w&ncq$4f;W~oyXn$l;dvhzVCMratPm}zq|WJ zj=TBk%fQ{d@b|y|Ye{T)QuXb8?gdxWla=;7Qp-R%e(nDj9x$fOO|S)Mv{qcqgrnR zBf3ttxh8KGLFN#Vx1}bZl{08Lf$QK4gyOlfRGfM8a2yG(Z+xkyoCD0ar=!21P!Ksp z?*l5nrP+KbW zp;tt%$VlAEtSJe8O=rhs6mK(vxggw4xxDZTMNm2&mP|O*KA!3cX@nb-jL=1vZtyV=y zp=Mol+@dYNOu!o5kFpiiY}Z=>kbFS8PA)Z+<#}YyML^a>@okkWkOJN22e=c1Qg&(_ z{xonkOO7k%6e-k2E)_Y#pqxI4`gqm5%E%8>exCqBq=wC{ty4nglPkyp;mVCVuSVvl zUYJu@zobSZvpTMZRU}Mp;A+%|BXoxv%$y3V)MyStjm#MVfQr;%H5HUUvvi}_`3`5vaQWvC&Z_*F!}P%t&xoq5X?7egJl=tQzD zs}BwDBco)b9MB=83&+@fILAB-gdIf*85|M6$T2mi09_AdYR;)ag8_y{;)6o1aH=8* zVAKsvSRqZONTeFge)bw#UD0d;MN8%tp*776QjO+N@Wn}uf~jG3F&amF4v?BA^z0H= zhF*Zun?+0`g;AqDEIMa~9HBlodtk{Zjmb#dEaH(+Z%`~NUWW5Jv?eG6BV*~RSs9QT z)!htaI2llNg;7(3(Ii$0WE6Bo-qx3^g598Wc4?CAp9-ReMWy(P-93|d#zKJ&fKa0W zp$6>&*bg|L<|b0akn&YYpwnm%NtG4)0%*0oW1NKE$Z1BK845rNKXu(9uA> z7@9}x#)9AQ!E1kg=+4HQX!fm4HBl`s{wm2zE`X74%Q zlx%6Nw+iFjWzX2`_O07Np{XUPmr!Ya6}NG#h593yn-LjSt?V>KP>Y)$eZ4-SaEZ4=f)*J88j?UpT4}%(@ zqnks^96NJ8^Qv*`g~^BWpo&Z5j61-cX}XkQd1B^a_hq%Js0CVa0XY+-9vs>~m0gE$ z5;bAnPUQV*#_^4lb{jI!966%_at63Pm^AWB-fbugsz+D_Os?I$nSE$0P~FFNQ=R01 z#*aQti1}_N4KWxjzJ@e3GICa3oyW~&E0RP#;i6F*}Y+)NaOkGygz; ztupE8v8wPm)GW<`GppN1!vT^eB!2W^+^EOfn#_j%0?DwGkbdSn6(Pci4Jl!;4=J*DzINgSEQn8iDKb6V};XZ zE)WqI;PO?v4K|lSA9NKrmohgEQpqiPH12Xc6)SA861W7zgH?;;Ff3hK*LBp4A!bop zwYeU=1)woFYUUe*135&R(SS5lS0e!%0whqCgJys}V#ehQpc&P@OvG6t$v|O(PvgxI zXhw5bI$c+?bU{frSBum^Gevo+B-SblnHH=!5qh5Jc#Wd9%NZmu?IO(2A@`Rz`Y=tRs}?vCF`ca zFF}ht99(uir7E@ic$4To@zj(bM@N!;c|}-yz6Acm0$4!KG;$D;%z-jDF+@D8Xmask zfu~O`$YJ)1!jmBvwCrl-ehPIj#~FAs4ab(~{Ft1rysVbk^NN=44EpGl83q>sE4Dyd zK$3ywgB1Klx`g<4VDYG{8_X6kCBV+AV`T6SQ$(r&=Z2(cz$$_{rM@_Z8K%RTqOa0} zf)#LN&{I1rm{>(Wt2qz#0s9R2xnP=qW9h@VR2*Em+@s+I#JOJM#6Gle$ z8%80rEM;lW{ix26>B`YLB6&1WL$MeqcxcW;KrPiuJQ9kQ zPlCNUwd8k6F6NY6OF3kOGeVPjBFJc3I%wx3JzBUthB`f_z2I;YB8~=!130T3Npdm8 zjb;2t&HN}W)m#EJs$3K>I)Fc*y?jNA0Uq;HMxB{-o?jjV%0eUjU2@c1s2}4lAMG>J zM?lBuPOYY?KNtZvO$MhV8;NwNFg)Pet0PdH79!t1DqXGvpYp6bFH9WyZO;VlYN26 zF=~)wUEkGl0};DC-P_-L*2xyS{=iA!gIj%i&pF4m1i9sGxQ2C)Wv5P*t@5F6Ch z%?}&Qj3=R>W6E<5=8&ALf-nGBFiIT2qmD1AL27%Lc3Iqrg2AI$jL?eM30NH+^NHwJ z@;BuC@Suw{st-;=_j%=e~g|8NvA^3CUwsb&Z2#c1Z<{9=4~2d5M#Ak2@0i4!|*eSyITH zYh0m3+NZ1`g`ig`)CvkY1}ThHjB;UB+znGVM7S<+o*E;EcJnNd9w{;siP(W+656mB z!AJ=jqgKDb2n^f8ySq6t4Aq%bl%s)zi7`~2RbB1dJ$?wiV51_rC`ZN=N<6k+6!g$G zUq{ANFgr0l>+6p6p$W~GKc0{=F}q^}<#e3VqeJ=m<)>tFO6)QCgh0kr!_G_fi=ZE<%kUak|B~%F_s0tgZ!sj9Tih=&nJa429P`_bl*E25{6NIndD#f4Ta=- zlnE8H>>^hB#t7051#f#NN5wGe`&V8ZSE!UliiC>EdU2hHb3M>T@=sPeK}n+ERT;!` zrN%fahC;n{5`kj4HJ)G9@n~3F0L4%iPstn5W0XBUDMIQ?+rxcVjh}dy?XZXR%iWr#tP9Xh*6sF<4U*hD7GUjr(JQC&Ks+4+p)0xG5^ug7LVq?kgT!dCYQ z3cE=$#LlEl6g1LvKqZKsXWD7-0X2mGh%9J7|}t4c-&TSf+3Jtxvu2v!`* zdX_DygA1Ij&2wV7h2gQaBtcx3b7BAjq**^dcn*hTZ=MtH#Fd&N5|Lb6uz(YzLh3)X zQ81`lKO-U)%%rvQnW*DI1tDM5im?c$cXMJW4a+Atq{)>QW+P6_Ggvg-2Sb`T-;l#q zaCJ^h7St)^q_J8ghiGSW8f%iqPrH7)7!0piERJRdyAiC!+mQEAf~X=UXW|O#14+a~-<>D}kCxM7e#>$txIYryA9b;`6S$b;^D_%<5tFHga{cC^?EQlJ zrG&vWvY9}?Zad*(YIXvrk(0%^>M+rU@d?Rj>bgnBRCd?_f~D>dX+~Az zw3t@SOQ;8}Peg17)dn#-P-F7EB4D;N#q28ti&I+JdtsTp

Qv>tCUYwKcDjJN22Sp-UH_`6HixF|2fDoq6iist}WDyBL6(d^A zVKFNypr(QnDY#8oKI%fzg^mbQu)1e3eCt4Mzym)FPmr z91j{eE+!bl2BWz82!^PqR~@MV7o)zJAqQ9hzFx&{w+iYVew#e1M(;-+HCWjjg?;9% zAVzZ$>9d*ty29|ue*SyhD9IgX3L7@$fx;H`W@xEObc_d0Wk7O{s$vd^f9YtRT> z47X_Dm%`m*=Hh1yuSkzg?*dY{}pQ9(~n?eQX^ zVqoP`czzLS=D5O&af0A&GG*!cuMiH4nCs6!R`@Gt#q{J|b!V3*5lkYnVyZEW0Ejnk zrm$kr4U7Sx)2!ua*Dp|3dUrj{91Wj}YG8`83Sq8u+K6U89$3~6bfmV8S4ftd68nV}$l?X89 z_b2D~M$XCrn<6z1Sd3=9(LPkgi|3DiaR`^)yd)8G*bgp&^5oP^D8HlSsF-vG?;hE2 z!Y#=h6>~_?Je)E%k7R!+T$3dP7YUds{ah55Y!Ac$P*Y+e5a(EOY2KF$p|S(7&6!bP zF)tL&iyj|Mb8{A49!Ub;q^XM21D>v49|`40?qlc-TSUn~3x)_GP8(Z>CxeFzzsV1Sb`K5X zlO>>Hn$<6h1c9R!oLs@v9k}d4*)m;rkx(%YlsMRezkX_?GEVsxP%*fpf+hCiLjV^u zn6>V(r@kRz&W19Z0|^xa4f3!E4Qxa+I#R~Lxvt?o5p%aLLXK#0={BKaw1?+%DLxEx zycsbbIj@N{p<<3tkEEbuc5aLC*OY;DU{jdN?j%%9H9*l#oIlYr;`P==I33OsSTU{F zR_6DXQ5ZF5RF9^1(m;H>@f`q@7D1jufsAwAuNXob>}a%ya1%T;Rd|K7VxU99tu>2v zoCbn9X40IZ7z{iP5mWFeAdi+_ zLJ>sMF>#Bc0@K>486L|1f^>it!*Bz_Ldb$j-lS`*a1W9e_~;_!z*xWpRt)CV9G*Zn zGLsG^RO4f$M0>sjCL=YX$oP3&W0EIQ%tp=YxCeqVMu>5EHiBjdC^jX96!T1CP#(@2 zTMW6|ggq=av=ELojEs)B&72eyN9C&&Ub)zvzz=$S=n zdK&1=V?!n|ISj+26H~Kuu3+A~&%C51v=X?YDKkkTEGP899we~Qz)`8VfQD%W8m5-z zXqbwh4jq}Zkw0j_yN?4o_ME|3gfrZdLyF+e+~DxA(FhxC$ow8T!+XS8c}}!1rCwi! z%3-!9(b=edHaTQ8O2bv?8u!h!VI)+L^SQ2AXIt38*)WrStQPXQQB7G#6^sXt6jV>d z`y~Jz*~uI1$co|-XKHsk zQ84vR#E{24YBJcSHwwaE;)Bw#cGzgh;>cgSBLb3M&4!|v*=7YtFcBK0F3@{3Fjk^L z8d4jhC-QM>`C^_X#rK-Ix!Is&n(@q@Nn;#O9*3fi9f1i&j@eBa*t;v{8nm=0 zz!KHajH2oHzlAdaj)ci^2LL$_`T_Ig*qm#B;gsryg7CwbF+F%le;n<>dwra7jShe_ zF*IZfpD1iG&yXCNT6CKUny6+aLc&xOBn&MT%&%$+mzgE17LJ6uOkd+jn2MLC@$QK> zWgedk5EACh%+y$QT!Jn(0>D7>MKtQFPfr*{8l;&S5Mi+T?NeX?GxY5@a+72#T#1#m zr`0lq6;K`2=;!)Zk}CDm!L)2gVchI$u4#O1WY+y{;Y4wC4?+8Cs4p{k*nly5I)E_O zxBF8O`-DMn3;_r;U6-X8W$Ip&2nbUyusRS%ySE$8pqwnHD2b23Qiw1$v_KLOMq2O* zm5m!q!W4g3M?@HhYpgPX+vT87J7S!5?}r+qpJoS1-Qe8FTIz#-GdqF4Z-`^mc!k}5 z#s?mZW&`YzI8=eU2|Ld0I1VO(i&?D7cyU|IS4~I`6rNF^NXR&e7yj05h4U_JJgrht!6AtDt(LQmYfVmufmg8XB z_B-X)S04oq#%W%V$tS1HRwEot(I*ERBRN)?$HCk&%2+OmdAbY<1(9GdTL}iU{2MSB zK(f&t<&yw|xm*M&ky~L}{CNEw{4+A1x&d+6mj3ue1+o;Tgm%mr?g0x%+wg7}U4KTc zX*l>bp24uvLoCE`ONPYX6*Nw*?wIpu>RC3?pq!~5BBJ2&LHbbCd=6r`D z4p}+uqOfIjR68~j{Twiurc27mRgq1ig`gQVCjf)dsQyX)|6F@t?0(X|db2givvQnK zMPQwQq4-JI8m~=aZbPH6;#0t2T2>e$_0fi8&4_;p?dJ`ur(>|AH4L_< zFYv0GC>w3tT^_s^I9VXefDj}NsNxr3|7rQq*C%5&%R?Hys}E=U2b`S%eGNMaIgXgz zq&e3E8VrMGBz%zZLCl>hv)pHO8qDuz0eeqEw1|uXJY~e1RZtIr9t_9?gK0a!tEA4k zcVV-Yt=ieS3bA0cx}S%lmI^vm$wgt)TCBp-A8{b|!^|{bc4n=4BKavQtF#wa_=1+P z@YN&v$AA%eIEf)Gqvui6Zyi9G2Mo+%5i6E3+!X^+q9nb#KXxrv{lSij{_0=}`eM)G zgzBIxGJ|lIX>Z~BEVx`IX4@#7CxyAbdI3c;nP<#=p8|rpv0r34RWemWex`=fJ}D~E zIe$b32d44#e4IN^R9ua!dwVuJkAeAj#Xnn~lesg=X0(>6{HtKVXn%nlU_egMPMc!{ zfzdR5P@oD}ZkW~P{Etw3{%CRl`;BT4W2hMz2^>cHT8_?6!Wkou*FaUT?v34#seN^F z2$a?AkSYP*)7JZv`noiLL}=5r&3W^LfGN^xCEZYg$tkBBQyFm)1E!?HH8ROsLWD9A zxNl83@7|LDFtw=Hm&S?QI#-~YAA0Pn-2j-OLe7p-!y1ld*qj8m$V~BVl+$P%{+*lQ zqp8KMcT?yz)$D1+Q1WT4neASYWJKJ@KYr)(~Ba}pfV-z;2bAmh$FmTD-ms=|P2I;r7bS@iqE zj}swJ#K397>?IWfubV3gKn28LIlyqlh@@p!67w-6?Y*&rSWA2CR68O%YYwg5StAUL zZvTiMd!h{$4m!5hh@J9O59DrshuHASYjz z`ZawcE{=kED>?vgs>0*GDGvgsy?6M=LCHctBRQiJleBlv%_TSrhR((5m?2e4>r${c zrkg>6Y1AI|ccB02THzWdWeq8xxPX!Stq22O*y95W9+!^M6; z$a_PN5e??O)ac-Ff#*@2CY)<;dorpga@B$+7!wrRNkoHj)^I9GcNyeqI!e27FcDTv z)HTs<1Z5j|FzPcsaz4hQx_Tx~rgKKhDTtmTS}O=Pq4g(g#DdWt9s_z@c7oy#U`)iL z&|o4N>nsu^A<$qD79~c;ENU9hn}Ql!e^^jEGV8VpY4NL4nC`=F|XgE?Xz2U8MJc~a$t z=xW?WimwI^CL6E9Wa5~gALY^+F$x(fzG@wK0pcN$B7ng(tm?;|I$mDoj66}XPocro zLe|;bXHB?MWLLq$_q}=`EfaYXF>UH8PJ_`MXp~^OqeWcor;Qa;=V>rrr+pm3U6<8# zvr=@p9yO4ot-> zfdix2$AWq|oRLw9Ukk1q!ZkecNPO-nlz9OHbCtZSc5ZH$`tq|B2F$g$Kk(!;Pe1jS zC!c)mcfY>%`YU$*@LIrWO-dHH$%%dJtCfp=2G{m(+O0S!U_Cjdqvz{~?+GyuR9 z=w@Z*P6Qz$VSg(Fwn2~#7HuZu8c(w<(O=Y{zaT+>zWRbX`z05qh-v#zE|e~)oX^f< zyV$u6KR)dT3+R`(DpZq^YNVTjN*w#5Tlaf>8J0XI2NG*2E6al^$f8T=cd%>{DM?(Q zzFeYEUs_hLZf;PhFRT)e(O=8ctsqHVBFn0r`_gdKJ7r8c`c@=NqD5r9>3Fx57Gg4q z#>GY0m)pPY?QQ=TurE4bUsx%M6pI?aT|#a`m&h=YGhcKKXM9>_d0b~K#tO)9;%Y&B zmy~KKvg&T+%k^3N417KyUmDlkG{K4}bD%VvBGueY2fCUB2gmdud#Evzg^ken>;0rc)3kwdmo}k~~1XmnFn|iKEvb zpTyL!AVb6wt;uw@gc|F}XLl?RUrvhvt~P1ePQ;g6r{oMOwB}n*@Pu5h%uF||nH6+P z54rle!4QgtROra6G@#U@DxyGIS51t)cFk_&%isLny#ui;fqdC;+q9VCH!IUu^2fyG z&q)k*T4G~ATlWp(3%@#X#@PAM>wmrfhBFS@O?;Ud?dgmBmJ?roVF5al>Mn7FuEjS} zmV(kOI{HHMt^XJ1%Z;(_{^(P?nJ+V9+{rK7Xd?feD$?*pHQe?lGRvKN%mZIOunmSE z{U-2brWSSJ6u((HLPh}%{~R8m#%yu^k>bNdAP!*&B-8XtM+zW`r;ZCz3g z)4d|RS~VOiVMR5f7>xaQ;>)t%*s5W4emW6pW7otfNJNFnkIj??fr`q!b?R>7%aIq( z6JM4Id);lX1ZLrJ!7p-oVc`HIM@d>kq+0x9G3~`T8!o-G-vaHWZLfRmB`@4;>PDG! z`|{pKkK13U=&!58UVbr$E1L_j3{NhCy)^E1udU#Kn;@Ij(^izu){wSsbUIw=+V}$P zg=K@d`Xv)uM0?TgeV;80DkM?_W0SLXJ8E>`v&!~Hn>}9hEh4^Dab+W}p!o*zW!t?o z3CjSkGct`%*(!4t__YoGQs$F+;>(9DLnn#p+H>C^zT7n#pY9)k6EJ3}T1!M#2g_zu zA-=R;glq>+bt0nwC-BPVkuOWP+&&tg(ZhK#j>EyKS|o%*NXJgigi4+|`9-tlY1Hn< zwYc$UG5KZb#+!%ZGq_G-U>GzTYLw&uK}YXY)1=v%OLhM5w-yjESXnrnL_GrgTXdgHh>S(y+K zd^V4oOtXpfz+JoXFW5N~3Go~Fm)2EReigL$cXZ>E6E(Oc5}NmAQws$#CTH6F=EYm; z{Ff~Dh$JleV*X2O+nH~;Jcf=gy=iQ$#y?4Wm0oS4sJr`~bvZ{>vK%@bm?)nP{D@*iXLtO=f{;wj{fbk{TJXbUNH_Eh4Y@+ zgNxuV%^NR#ZEDWggE>~lhebmT&)hU(k7qrf{pJKfGzk52-utO?n64F!i1}9+qhA^i z`*o*dW~fhJM(UP6yA%h^V-V zIJ0d~-#;*73#Wp^FWq+9w-(SZ4|as}K?_cmtTu14^dIP#lYZY92w8^u2c*Fi!qnvh z`hLC18cN3OozMOZ;1^9D{Bq1q|C~-`{L>>~WK7TaO1W=>U)G)exG5fu6-{`>xSw);qt?``$aFks?!`KK%aw z=kIysxifRld*1E5=bZPR^SzCo!;>Rz6;Iyr)%ODZ;>tq5{ORYm{qp?C^ib=mnmW1V z&^#C)Tm=2{iCyO>2GI?oWrD*euM}dnXFK}FCq~)>hj#sB(?{Qx5B_q=y6fKl-Y@^? zzn*L8ofz+Fu0IK6CE27iZ4q_vg=)-*W>%pSN#!1Cd=y?cnMR)1S# z^|6DG-GAE;!Aki0KYsq|FWvH;e<|7W@4KIQuC6&eJU%wq*?jtBRTV98$Gf1Rdv5I5 z0szb!_v=6XP~FJ*g)@=?PoC@#xT>qH%5~Kzf#hoI?2%0cx>}lA@9e%F>J7J?J5y7w z54QlWCP)seJ~TPouq_`0X7wxocFXf!lf!NG=ph8Klm*oU4@NMmQ(OTSRhdrTU~;f}`^T1mzPxkOt`p(0@xHb*K?(_9@xWS9X5ds?|HROledb?X zwg~d&%^xdyDsW+RVh9i&sz{ycUPZ~WD%S+hwDpXR_niFMt?#|clZW@>x#GQbY-&2s!sCmM$eblo@omAk4y}QtDnB(vv0q`y@2;}<*KXR`hl-+ zee72?P?ueCLw((ydjG;Yzec8M?Va8IdbD!YK)B&IPi(v8{Y&s(E?@u7jW>OB^SzHe zdFVHl3hYXPndDpLZ+`yYyZ*iCYaj8x8@w0SQoNT-9lV#TUU})7)hjN7_i~MKEyyVq zz()Fcod%ud6#t*$)oQdE=YZU5()Y zTV6Dd^IpTNTB)=t;!7K!Pw@FXRJ*8Wf%-NLg*Kxbif0YMmg%O(he2xj2k=@x#s41% z{l&(6c^Akoe+_2KUxM}Wmt6fhuXpg-#(Q}mC@=5k^&bA-XKYlwmya8tHNFVm%e#%Y zfcEmI;Kcm@0q^B+mcx4~P`sBkC#ItOEk=DQT=A^|_Ls{6q%?~#`T2i>fAPE)_!o;) z7;;K>HWlYQdmaqT8xOvC^p}T94?OvVz`zK|iUR}l)h{Rv%=;F>z)bDU{0=ZM|GX>= z%)i($Fe^8l$t3JO>2lC*R@qXPa#%3mw6S2e2o}tL+;i^&7R=AGSTNiFeXD~7vr4dF z=0@enzzh!uj$EDHYwjEpnVlLR>CZvIc!7dR$|-e@0Ls>1*UvA82IB<{W}d`>9D%SB z$+#RGl{FgT|U<_W0_mtewpu59Pt;sPqnY=d<=btc^aS~;`r z%=vZF`}HYv!_(2^0xV42-kB?F6FE~L(#$3tSQy;EhK2FC9?F2AV!(VV6`^5H3WHHn z5Mw)i79GZl2+oR}Bu;buKgM|(n`Z|gCc&*uqaz)Pw|QEpD?o?2@?*(iS-{!P=Czmd zJoP?d!^8O8d#3<*jw`N>JlNUbhI)pFF%^U^j3yj>n3^b0%w;zuQ#|FHUDiCO`=FOy zxtukPaxVKhwhg74LOp-lU?HuK1^~Z$(<~cG?J_VT+Pa?8PDRw;JzGQ zn8a;ujF_&mFuP`~j#$VYjt{J5zvd3wlK2dOm}%NOlEOnM#dJ7 zrZ`7HayT)ZYXbowv-C`CjpCD^`7VyXL`gpw2QLUer7sqgT;706+MeYnVfktt*>$()-4;o z9gvmop)6KRYSK9|r4o_v<4D2{INDpL!0-SP)5eOiz?o7xjCl^Uk@yoV64aOlijf^A z*7!={NtlvDyPiCx7|TM~99GP{N;4mFx23>}S@mN%x?|T$N91IxcXm2$gT;8>H+!y; z+sg=(HP4meYwW$x6Gl!w4hvY!nvW-8Pfq`k2;!7gN&qjsoGkbN7)l8nE5>s>$DTl? z!Y1If&T-TxA}1#-4vu;zXC0)N_%L`8q^AmPfg}*RGXfOj11N@pVjN*?s2DaKV3~O= zGb~Ust5+Sj#7XQ!*u)JB9AXxy+y!T&@`mA7p0mIWe@B{h>s6S>k%c|rim#%HsVPB< zDd04;$ilXMy13iQBE<+IiGvhl8^y=LHnyFMYg^N)nUvzISQFmy(ae633VfGWr3ZNq z$jB-?U8zO_A3~90ydcF`Y}RsT6e;H0wm@?sR|=$<)qhG(mcXgUax8)%2tXkD*ibRP zw{&-~H_tj(-~g>yt*>q8>9AcLakUQ=Ts3;UEn#rWPlWT|Q9#57r~7_dkx*08_n zL&+p(*yf`#1SWIsPET-mER};+8JQNim@C{5XR;@=a`ITy?i^eUus2`?C|(Sx^jIg# z(V$tui@D@G_Jg9GlQ?oxU66ci#2D`%b#_Vu=gkYSF`;2Wj7iOQ=>~m0B_n}dV%p4X zW*3Mtt}XQRdB!VuS^;C;7Xt#poe;p70sv!>g}7Td*IV;T0Aq?*I)E`T9xF?ZRx-&x zc4RAJjPDB;kMQ8Wz3fX}jlReMPfbrH``&IN#t6C!olr4jZsuq%a?OR@T{B?DtnnRo z@QLIk3jq}G7DOKh3Fq~puEukMe5?@G#Ok););HRiF{655Q7t56jbNum(^v|%RZM0L3z^C`QdjvVA5abvj1F|A{RU~W5opGRJrmYnsk(`MBAo~Ie8BTO~Lc<*Z$GEGgz?7iJ^}VU&tS2(J2tCGq zUH6PU??z6lCc9mk%>+AuV=#~0gjgX{7+t4ZQ=AEBA05CkQELst2-?cb)Wpo3LdT># z4Wvng6QHq01v=)EtJC$d%quRb89GNA6bq4DmVrp%ed5NdpJm3f(g3i6 zG^s3hj7|mwU`@hJ7CeT-WtlpjXW{a#0{GqVY~eA4VDEFLIML;~FeT72-VIYc4n|~I zo0Em!6VF1&5M0u0#WWoJl|z*yHhRpHiLeM13#U3g7y2Rq$oM{zl7osm4`gP|F;gbH z%-FLaG9%~J<78lE+N1D33L+D=jU#8{Eav0IJbmLGJU#$#<9IxyL1xY!7Ze%KRc)!M z@*HKdA^PJfC!ku8qthg^TXCK9tyPPs9&j6^Bg^?L+lJq^+ktq-0J_?E> zFf#O=`IIA#4I?ARgR{3YLB4ZfWONAiOr%aLjEwIm9Ac4&W)Pn)_`13;L>v^E2!{#m zgWh(;mWj+<7Da}K52P*=;|NNT2*U{mi!cL@%uLwe)M}E+Lq;fa>t;rvWPD8T^?)dc zx{)cJHkdiNQ#nAHaRI@!g;KbHX@QRLZk0Nzcr4+{Y*RoPOF&EH2CaaWcxL7WP{#Y} zrX<5Dw=lsh5fGNbKj;}lJDuEcV1v01*uCj5vsIiUANCEw%vgbpLdeAMs)#aIe@kXR z#81Uw(R0`$)lfeVrpAM>=^PHH33RJ*BEeSa9~@RlnfJ`6w0~pVR4fg8K^9bIlKV3v zj!qU>^4I`5x5#N`TOJ!!Cg$927RVBrbULUq_EDqJ;e?GUY6{{ zz{==?%$_gUlR9fA2P>ljWe?BmnQKlg&e*UrWBrhe^S2r<0o{R4ItweqSw-R$A_)*n z7Fp({DV`CaGI3Lo=X4E4#YiB_Bv?Ss%iIlQ88^r>;N`I(kTaT@sTGs6Hn2>>Vqb+d zthh1-;K~dTVA#|XUL}q!Q^bA;StcL9NW4zwoO4-Z8HGED&drM3ArG4wIKwzN|9))r z!Dx3!tYfV(CCO&@y^%2Zhc%&@##PWXB~CwB_mTP71Wlr5}tl8Z2}oU8#8@Ne5a+ zI#CYW0D=m=-JSU!0(~*X?MqH4TOF4|RBmE&laLkvxQ#6{X~{|;!W0bl$0_~zpMgUW`->eas*XQCCbi;6;pyO6CdPYF-J}N zGXE^tGE=>wbO*x{$J= zWzwOL9R6PC$fVOw95*T0GM?{{bCERx9g0xwosYzF=rU1|MC5@XVps;(siX>ayP(Ud zU>=YoK$j`_NMbHus?6wRBSRMOGP>u5qhgUPyiBak>bOiLgRrbn`g$#am$?jh8GFl+ z<9&$cn`3-?+Sg%RT~L-$*%Wcgu@`%UF3c*t%tP@uTRPidGEtKh%@o52JEnk_0f8!; z)X2mN2%yumu`Iq!3d?A0omT7>@MY{s?un)aTjteZ%S_s^Q+iTO&pwWfhNc}* z1hJd(cdwl53Q5*NgM|v$-#_WYSI49r%bF%o?(AZ}l!Ns|7tNm5lB z6vTj_q{anX#`V=qEOiA~TEMQ*bG7TTOK2nqEt3Y;QPd&^%wYrxvi(*iED;$4x5y&5Of&Vh}<42X$; z(gBy5&qH28X>v$4+|f0w;4(vPwuqtB_TaSO=V%T|m<22}3oes-MW!O6YgVTxORUX- z%UC*N7qw6gV2g|cE+Y`rI-+?avvkH;tFw)}9Gn*%9s# zcp2M@!mT8P=B!W_UMBS_3wRkT7l73%28jUzKk$meUx3(VFILr(Xh&8o0xx63cE~Km zJ3A8>e3?tPvjVYsu{R7_Oj9%L=_J_M_%hv>I6=n2nYD)9Q5#>zBEzBRAR;4~L}q<9 zzKq**h|`o;>yRL)rkqnp?d?g$m$}f^el_#j&I@VqWo9%bnM>ovGn_f~eOeNT%!gl{ zREQa(vJHx*y?Y?B05M|+DLcD^t`U^|hd|7b)Yi$C=HaYaAZFa_d#0_vmD&?!A3c*j z8KXR{;||13r0a5qQxaF=tIQ!KTkJs0%sJ@^JBy{M^&G^EXityq*}fWLH}lH2gh0$B zNQ=EjCR06%F*9H%y|cMJ#hCGtkx)Ue1gcbEW^#j%2FL!{1(+E{48p4%g(E4C&iZ(V zAfDnH%qoEmpH-NdwVN~IuELMFR!16^tTtB?lnf9UdI2?9Wy`43WHzKFvOqJWlk9r| zGKaE(W-h-qlXX<>i*iWNYFpWw;8>-ZWbUgH_6pKWWZWJzYzc8Sg&n=J1qrX>#zI<< zX0kEb8Gj~hq?uK|rxX`W$^eHF-H(j~YHP2N^I~D1N^N{CAzN}C zI6nzoF$ZUcT-R%mq(3b1V(4fSW&)4qHLC(L}!%E080j1|A`4c67&z~181y$zRhjF3dHN}>rSu~A0hW|ADW=ZN({pA9z? z=B%I|;8UoCGpFZra5Lht1P_Zf5fH50@W_dgAp<=la5Dv;Pj-kRVmYJuwkDfNd|&1) z(Cz6;S4;qBu-EV?`-tb+MXHE1EB|bySELX_^d(j^7C6%#^I=2K#$Q6>?^x%RWQQF%TXpd*)1iBnLT@6++g|ZjA}t zpusilslO}zF;l6i6kpu0RR=KT=#&3Im52dC`SVn zbEe>}eJygXI$aYDt~@#U4dV~mnt9r%N-<$$&P2MALYF0W2b@;S8FsJ@4fOR~h}oDk zea(7sPR?%0(ev7=1>@Ooy}=-*F7SzGwwHrTV+rCEFw&O#rU(q1~%-82=x&g zcIL#4KGniWS2EWT*qJ!X0l{wRw1Ay)Uv_%PYFdjGY~+?xJdODmIoKKL8L8RV*fY|x z=-e>E+oOaIh8H^13OiHN9+16Jsan^ZjXKk>b9zxf*)w+RyN4arnTdG}V2uifh@j5+ z-rU*5p@FI3ifMpnIOr?vgF7;Jn*h&P_9HnoSh3O>n{U1;K1wf;8EEg64Lma`=j3hW z%aQV$uBtVHPvI%p&+}Nxg0Ix!XJEXqcU%&Am&jmZ$J@5?GYUKd^RhWB4fCG^h{pYR zvcm$rx(5_%g)H(8^rs!znaQ|vFRx%-7WhThHfUXJijE>-B3y<75ng zospwQa*WI#F64;2!p_vRRiD(2Z9F%-t~M&*Iq#12+Y2f;^8mr0@eU4*JJ>Um?3~5~ z?8+vW?iq+E_ROD;oH{ubTy^qH-v(pzH2Xe9kW*)(f<5DUBH1b1cZWwT9ta?4dn3~_ z--C~iwxnXuL^;$ifm(&&%vocXV$b*r4@%Aq8dQ)W4jKI-c|m>1&2&a!bi6|Yiaz6c$LusmVdOT4$Wb5@zY!aKX1sP1 zNt)WOF&-YvO44Yf&%}FrIN3HLJI+Th)nJ4#i5%@6QP5}Bd_AVU_>>|pSR6;H8_S{3 zWZ_PnIp(CG&yb#_vWg)%4^54;Pbm5fl317|BU>En+_m%UHSm5Y1|BHT*F1&E#sdOp z)CQo5$_-9U&8$)-$s|kxXg)VygD8Pc|7zEvemTAF1LUE3(8iyc>6Z1M)VqxS4AP4| zt7&f?Yyp2})ko$Uvd|Iim*n_=4u59EIe{XxAzGTa0R9Ycmm-A>EPBSd@%)V9&mc&e zy_zD3x30b}Ca^6lK@d=<5>O+HBV?J~E`^^-${iX|X@*wkAT2sAfuH%;$?C~qVfFB% zt~J%2z_%bqU3;euK7$lP>EX*67#tB~pl)lL6Y!ape?5B6@hOpk)2#oJ1)l-pQzDTq zLQmJ&h1VNDPRp4s05=>F0Bq^C!Dmzo9@B^vG<~W*_630BZsPfq;!~MHd33Gf8qJIX zK;r?~ld&7G0>#jtF^ZF1=$I1#8n64|kt*pbGV)z}z9q=%mUB^TQQ7?RH!GeKxzV^<&r8uJ?JEvAs$8`5J#*R!J7CNmN2hCSxnJz zK@~>awtol!8jtVU?&_)F>XUV#ZoIYsj2z)Yo|@j{;Lp6q^Gt$-h_lkLU0q$|d}kl{ zGrm`y43gDMIL}n3<(6afB+^;* z6)2)fO5tbDHU}780&NYz&y3Zvb(kO-9Qrx=H_xXM7r1*MYecfTp;aPSOH=F@cT$uL z>0?)OAP@wIrm3}q8w_vA%C;tZ2oTtyI5;%!Z}P}1^+wtD;2E747@Dhrp-If_`D4TQ zP^>#A7`R3~-ERO|=hmq}gkz%xQ-VS>Rhu|w`E#aA&;EnZ)_fa zCpYkRj8@B`?^M83eY#r_XxyugrL5kyIe9>&=obWGENg?7`ffZG!dO)DL zf4Cy8n`W=_2L?f)5mV`ITkT++A8vFIXyymGaVvqBiE%yxjr*r*4q0RXFSVo4`Gg|S zJTnlG5iQQP_Z5MbbD+>XFj8glyuAzuET_KDdB3*}cXB2q-O3K3=2bQTW8>+5L89^e zcp{*O**SO_9Lhq`BuG)|G{6on&AkFeI)nrSsaO8Q4ub`)OhXLrpo#1!r&lK zG&L=>n+dL#UZtoyXA?ltcyAT(PmVcrNGpYb;yEmuD_+q!!7YO9z|hisZt#p?(Y&SS zY|T6;57-G`J$|=gxJ&!!t{n0WOn)950X=ax(VS_@qMw|ppS_10$G1$g?K>GrRl7#B zNHj6&ueli6e7-vj63yyMt9pXWA+Sv#5U(z%7~R6n^YLi)l_!TkYFt&)eyfD-*R3v((ko@S(wHdN zEm<6zDd$*vylO>d?ZEqt!l(NEvFg_ZMsGA;bE5EQ0XL>Y<+r6wTSD>U6*xsIKp2*gft zkUl3!5&(fHv>{+L?spH=r%#?>eKsw%3I)vpZ!^Qecj(T98^!kG>l?nz#0xvPEhLleKmKDAvFRLBv^U zN8I4pwy;mS%H!{PnwtoWtZOP}tkA0+^PFQ4J=NL?9!=~shOu!tI8}AM ze;6#K*F8JgQD4c^TC1yT`fo5^+j!m)DSPO*DJgg~u?0LDWJ-=(SgWq;n849Om)5qKpM}V47JM+ zuEtEm3VSMDGXo%v@4Du5MA{^~_&pV^6^cl6?IkBC*=nPc0~t;+YE$^l#tq5(*BaiR z^_`fm+E5uB6hxX^%Dcx0+RvP<2=;+Ua}L2cKA-_jFYWOf`Im%C9p zM4H5GPf8GJk~oOW&g_EQ8nWdvs)++hRKyzv9y|Ji>4NE2$v7g8Q>6&FC7NVnBjI552cNb^Gg zX{N_Gbbcv}pmII`j>Fe(4N(mrMQnTA)V8^pCQ+@5}u}!RAURybGy3qo_TEJEc z#eBj3<3Q4QdV3|}q!~SJPa4$7bv3g^f=P3#VZuUf8t?M8RmQsVGl5#LBXSOeKBUych&0R9gU-kNAqM~W!gT5a$@K< zksCakK0sci({gkUSOw0w3~v-Xnvn`Mc;)F%@My06+riqU;?4;k4M4DxShI!;N7#s; z#iRMV$A&YpafZIs*a~hzL? z^UOVKcz)ksG>x6*>6SJyR;JNM%xs)dJesZ+$+-#uPyLAC(G;w!89alfEx?(`+SK)& ziH^f<%yo3IdC+cozmm8;-)KkkSw=iR~_j(QCS&dB=J;q_<^H&-6uv* zE){uN;b`QkAF>xFJz6k6zko)wwKbEP90Lk4rKyq>OV7k$dVpuj^ri)kX3bl=r^wBA zcB)S&TGGwlrq-CC(G-A2Gjt9JxMo+2!d7R_`6QA?L8S3)oI1-P00ZEi(_;cjbLr<} z=Ne@$U}G%J2qw*4qnH(tkBXKm2a#r|h0ZRBEpomoUE%f*0jA`6d;95%WK|Rqhjs`e z&6g+aS*1?FaN?$x*5S6Rj8CTkNV2n~vQc4-L#LT@x7&y`->OPxrW2gHPmQF&A^?YA zz-56(v*IJO!$`*zM7C=dw6{%9KXJpQfIVEg@fWe4=J{5^(o-zJ#u)*laTmoJlY+A| zEKoF;uK49_g99VcaHerqplJSMv=X=(SCx#Rm9;%tD4GU|Od?gH!hL*j3!p<^8?EMO zR)P~{nQGU_t-#T2p(@=gXiqJHG-=^U_5w!}(LEESvhhtxd;$kGvhO2n7}nQ*@>la7 zAPQtK1))G>14n3J#s;KG40Y*!$^=ivdu2y&Y!N8U1Hs5lduy~k)5ZY@&~}<40!icZ z9h%9)?ev`kk!J06wUcalR4LC~Xca`7CkB}V%PiDWRWW+2K+>$ZWj1Jw7pw3b@A!Fv zOkp1!Vlfb5IZ-#Lcr=H*L_7&T4wMjRZYjm1A$_6gVGH1y%(!nZhez{%!J~qKs4?*5A|5U;sdc0 zo)8$C*H_NBoR=lSxii!MtuQnv!z|`3FrKVxPi0F$VQ30gzR*>L!K{k7-&^6Y?NA(= z1A~=JkfMsC)YvIFG;i&yuX4naV{45ZO>b=*RU8_*iH^~%@t8e!kM#t`O!}Ja?^z`ntj)HbG2v`Yv?#rVd=jKA3H(bbDHW zby|}plg8>-Jr(OduZy{uK+xPUaau56Iav&!ta_@(H`x$0qk+oGii&x^g%9>^7YLft zvAXJ$5zVB8Y6XJkr$e$Pb%qEL2VfoU)G7o`d_Y`qd^{p9n97HsiHtJgNsh+Z83huz z13{CTBdN&Ew}F+q+-JSjbpeE+3-ZJ{qbuFx>+K#>3>x=4MhDW|nB)-=?Sowo0?lL# zsg4VRKy#(%>9JY{OGyhj>t{}2RyNlv0*&XbEe!}1^Cv6Zf!@yx0?mD6{b%N|rl)%3 z7lJ_Z`N0~QTwH_a;d*K#Zq|glV_#7Ono)hC+02A*d?F?YH1EnH(9EUS+-_rx14HZ} z&`gaaNEZUdVy7A9DJ)jce0Q9i49p#5^TuFY5NNztRL*yHrOAz0JPtMD0MI1*TbiZ? zfX4l)*>f@tSgC0N70e2HYXajBDgce=t+fdrMwuS=jSS6>e+u}SSAFo=p*gn1vT=%+ zy_aKRbU-0!J~2l66M)*x8>fi-shE~d*{gH8N`r=45 z9*}506LWxQGN1JQ!w2)BXi@?l!@a2Kd?=bJdc9`V1=dX-Ihg?Z<`Nlw7d&9XJ{*%4RqLQvu8)1;t4#scn^X};YE{^EePZO|7I(3?o7{9j&|#iL10k4{2JQagnc(Zz5y{-*NdFLdnzj^@%U zzjw}>;YPZ%`#=`CghYs?tdse0G>Mrp($qi}Q)1P`)Lcr?XnweWMl(=x;`o{Kibiwm z`Luw?$lZCJ2pFURZIU(~&FV|8zxlsT4g#jgUadroXC4a{&DbI=nqA#5o~RuD3RpB( z-`bQMXBVRG0~r`}6UsFx)hkCuS-o`YVfR-$WwQTzqX7iso=j zW&b@(plEEUmX&aUk~qL9VH*a<nm=-& zXuh8*=g`JLCTZ~ea-%&1x+qXI@xfJX?NU#+e-4Wl3r9yr=kl;2?W*Qkc2G7Bv6!SbbWA*ipr7r?RvqFGqVtru$S#6&7j;>yw zchj2^P?^Da^w=UGnwFvYgKx|M(OmMnABUnG+|gq@ZJkLTp_=F_yb$h*#H%-Dv1r=a z5jZ$kK`wt%<5`k|rO z0#7F0zM`$QeK_8;>%A*}!MXC)D~hLL1ATqny{UW{nze8Ear5Z;$|@FG^^Gk&AE?dM z+7@rkH2Zp@Q@>ikqL~^P9O#`${8t_p%_Y|rHw>SvsAS4^>U>Mfj7)^vC!(houxMmg z>|k;c7R{R1-daC$zJjS<@bvknX+dv3-yiLEP-s?zLKDUFhb9)G(5$-pyEVg2et%_E z@bu)_m8=pvrYBzd?gH}66hV3f#0LnHjlNnOuTB z^OfK9wpWzDSP?vRIzbwWM=>zXB7+;K3Wg@S_J2N$Ju}UqFh<{B_`~Y1hVtk9C!MsgC72fE1XrC5RMoUk zjGo8?pGl1jjSTaclr2|GfMakM$B=uCRagDvv*B|u96KI3$vinuCW86$$(1BYFH8;j z^U!C~3oz%Y3zMTKbNDkq>PU_A z@X>*(#rQKTe1EaU-+tz$7b*m2Fii@4jVuv?))+gr`-^W{fS*Z@0zt*?o<;C8g;#&( z3BbNzIx$b>R3K$nu5BBcx^T4QeGBk2^Zgy2-Q9!9rSLN)FSMVpK2aH`b`tcPHPuyt zhVJpAWnRnlHYHl*z8tUxqn_r4P^U42e2scz$fTWSEj-fD1!9Ie`gJZpc zJ)7Q{hd?tn+t+-a0~g)V#EVN2Xnxai;atF9k*U_l2E?Vce0a$E7~8^XzC}LzTaxYQB2B>Pn$?5`>bG(ZSZL zU+nntrjIPepLyGRzWk#{esj8ObfoKCE%-2+$!ca>%VPYQ&+cs=8*Do1uc+*TNw!S@z7M|GDK~fAHOJ-29c#UH!$cfBV*d`^jB9pZ-nF`Ov`Va9`+L zT@}Ky3bKL)r!LHnmfdnq8wYak%$zg?dFH{Ip%HT3(C!5pBCvjJ`tNnaKeW2pR2`UH_3u~8}w(*(8$TMp|p7~99tiL&k1}aCYW-Bulmft#& z@Ea9L-ZTD8MXFNZXbMj@4^06*gX3n5tr-K%kxN$p@t1a-#2K1vr1nhJh04jwjDJN% zP20%W`MvqzGnc>OufFwIuy<^r?Nqg28LF&mtBh1$QsF=051iwNs(U{AG60$#$J<9n zyPNB)kB;)Dq29sK zfl%fC+duR6D?AGbG;dl30?o~LKKjd(EnP#h(GLKckfL=r>Z323T0)&Yx*lKE8#-0C zck9>x{^bZXfA{Hclx*Mq-#;(&GgyKu+i<$Rw#Hv}@QEFF{mWNB{68VkT()NQ${YgC zhrnrh4~Q)9bzK93OeKgh$BbVaNn^<9GcFi?uGfJka}MOI3r52A5#vhdb(L`~oAZmp z>5Q>+Kieyci|fNhGY04{2j#1nVeCw2TsyDZ1saWSU2*Zw%uaTVY}_`H&bSX2uj|ZK zi5cxi+%Uq)jB(@BhH+CWV}v1dP(CNvjLiGpyTGF{)^W9I#&F$m5NME{YrCDYQlE00 z5*eeM`g@%E^^`8>`*Pk7YW?+6f7UQ=j%18tYHLZSc6mHwYU-fH4o|EtE=CAqt zKy_jpyNKk2Q-R05ZYM&@F--Z57!w`2_o)33-oW>iE)c$HC7tn=7jJO5-WT^IV8oh?qb78W;}b0 zwL7V>lScROzLAO>MIYsq+7ruoKxZ#j?}1RR!4zDCQ-39(}ly!odyvZ=`hM{_! zeTu9@_M43BXQbhEh!A#o$2FAhCXrL9JDiJus#n|Y!vljduDj8Jd!5bqwhRvxb#GF( zCxmV3(Gw!3!G0H`crN4GsQ;~-#$vgy;plvV@=l=GBVG-4^);B;0HfYmBKlBXmu8o_}FAha}uAS>F;kw+|G(w<-JbeW6 z(o^o{lLYG`g4L#t`Ik3gIqGkN*4>NbpzeBOkNrRVhl#iSx?T&SOM#t%A-_{|Mkc3rV5 zpTVb);7OFUM-|-eCW{jVE@P7ryn%N17)1zq6T)tqkv^fa?;)s*4))ORY1$x*sP-;@ zxws++p6iHPF1D*jv0)78-9vW^qu#8v;_@4bgt)>U$a~ncBfh;6kAM$bQk3hWH|cO- z+>NB`ZB6mNYom(FP%9x4i;FdNfVkV(K(HvkaY4+xRm}B>N$X`slkYW{ENRC&nQ=h;O;Ed=cF$N3c9;$3ixhG#n87CbXnb5AEasmT>^1qZZj455^ z>ydGt$XJd$FOrddH0y{+C;eZDIBvK$>?9oCZ4WV6=0?OT|6Rl@p3G#lk2-z|WXWPb zWi&#&*+1 z7QCCfI~Ur)f5oY04S3XvB0|Y@;cmkB&C)rfchaBWS)5VkL*o5_y()|et#?3^a z^~G!RE*ByY+M}nr>#tizR>mQQvW**JM#dI*BjRqbJzSKca^(vxa!U9YM)qj@*(eOS zwyh;_-Bc{`aT)2QXUg28fXOt0CZ}#ygO5JGR;F^kb(zebVhFK42%X}+gnKCZZY(ce zUyL6xIwUhbWw_YN$V6*_=F9ZsGB!*|JZDIA?bQDyhR|2=(Zv=g*fU$EH;E3IhlvEz zy!7)489){p9n5Q~&(|A`yBQQ2pqG(YhD+3xla#_?q+vR!K~%yT6K|OtFm~y9gQPO5 zQ)wAdB*IEJWwgnxXFkNAYdu4|uqk8kVu55lCSbYOt3XgJLLeq5j6241PAqdz>AD+@ z^^m0CQh{XT-^1iZrUvSVc2^PmOdwJDj6Fk>d2TTxZQ>y{@Zc$C-pw1emJvx-P2&7Q zuvo@y*G)2T-y}0G4`CV&=8Gkf5qmP)A$Sbu8x1!zUWV@cn zmn;@-11ek(cgz@A6e0kk$q*+KByKk6i_R7Tj}eAt7LEBHtg4_P zS(R-dfE~PnC?m$$15+{~MfWg*)ozw~&-!J=Q*XrXc%!&Ks{!ZD%O_oE)ZfgKqX>_e zaF~-(ShW{HvRGS?5_&9eikP;_q$yV%POrly3}9RAm7UJ8HV`6Zwc}wGxzv_Mm>*@4 zy@-yjA-dc8gfJB)XkTwTo&hoAM#6193k~H=#$wU{HiefN)^(k(9*I>H#zZXEWc|rN zQC|$Hg=-dKx;osmiQQ7HN>iD_gBtqQLO@qJ`p#W*ew17TxFxksY+`bwh`Ao;o@S{>bZVTF*7vRb<)RKQ%g-k^v+_O7MU$(TIdV1j6#O%dgcYX zZWJ2Iz0_UG8)L8jwjOw}jXH@U4s%zT0C9uNILcXxua{G~(v-@5+9^;XvhT;Fj0!1YSkHLkb0{>gaAc$@JDy#5e$ z;5DhtUFPk)I!x)m>4?j0Oov<#nNLRw%tuR0>l)3Oh+!JX^~(f5-_F&u=B`L{q|huW zEqyk$j}jTv{ZMIhI^;cGT4I{rxw^4PC}Kd@qT;?($Q6LD%Y4oXxg5H6Pz#tsH^9|# zrE9mb&zz08&64BuAy+9Bv$gUm29hDycJrCsZ^~&i%{*kL_;Nc}b&DuQVAQCKhFtrW zp_rk{Ly3^BlATJP*zqpx z#^0Px)Cw7mNi#-Ex6}GVrs#?*gNrDo=lF}7asCoekZU87Hq%rPT63nD44WAHk`!{8 zDAXuTo8HpEb0)2%wWWDlQw2&(0CiF|5t)ZjoJPbx?uc1}{!5#&Oeu6Srfc7G>5%() zDFv2(*j}0rd7gXJv^mA-rDh~zrbC6aXqu&^sL9ia9|&j9#Y7}wOjH}tD$gZCg||x; z+>6@HrQ3y6#>|u&3spVlL#59`2o4Yv7D@wrdbV^QN|R4@ATrcxBVP0N(o&qZu#uvV zJ{JmkL(Tl4l^%K)R-aW?7tvQ8!&(5=3|RLbH(@Ag8lr{c%H{TSr~ttb2+u4Cz+^(%D40zz-{T_@S$3ec72bEl(*+;$lYk#{-v^Ld$5b;Zf}GoQIw+`GoRGH z`H&HaV@1=n^?`ca$IXY(iWm}wG$Tl}C?tDf2IfOPxTpE0`j}JQX-ke%pRzpM=>lR&LMg*C}W5mN@w4A$XzP((+O}#oCD{@^;GRx!Z=Q8-f=>^QF&iZ zc%`<`qeOTiNW`Vz%B63g@ck?e!;sRlIVg#Syjaw{J))AECCy0QC`FJQ&n?Z0OMMkv zIdH6xXC>Ry_PxwU&G0xZ~;l0T?n6C(jvM=+xyV)aXPbfVVsMI z=-OTfDdCj%91`?O=^3RDrA>ln$os6w!Fzy)QKy=d?~P|MkbE!Z#e;D-dK2LhJ`Ey_ zC>h4-`E^L}kdz24YDc9<5<5uK+2|960m{M~{HptGhbz9>C#5X2V4pIs(j`oHNi#bj z7gML8NWsADC46j`QG2_|jRa*xC6QS6tg2gd(kz;1oYofeK8Yr^Epa96xs1X!;)wjx zD`APjTLwnaccW+;t>=_(LPl2^jgAv2M59@$c`uaeI5{EIgKNTr4^LLbic6Ku+5*^~8bKordekBeNRavWl_7r(uzBxe$Nw1-*>;z-FCG^)2g4P`jifsZBu%PsPl;0&n$X^cZmb=;3=nHvN=Z0d{M2^j{6ZQ zmo_tS^K#XC@JEQmal@h_n;5FacnBcwc!Z{0TOhzlM{VgJ@+JaWrhA8|IKP4A_3X}= zTQF}aG)-8lo zgh1gwb#-)Niy7(*W(rg@MMq#`In8XrKrHZHm^nJj>&7J=l-0G29!x@PtK6e{^_#p4o2CgZ_Ytxk zc*T~o`Io7u0BfVTBkITEI$OnCcbHL#O60-`w_I$3@(6{VK#L5MJ7hFDLIt(An?OMO zs=4LV#C%A`(4wc{XNfmDO2%CGpeW&)E`ToRr>1zq6RNb*n7{Cd25jM6gHw@_rFJoG z*}Y5rlHOIQalzcd@V@eh9V8Zi*eX5w31V8(mM`Tme2N%>O7r@TN~_{a%)Vb8EKh;7 zSRnG5JDy7V3!ivdh$)n=W^UP0&OlSPW5-rxBiu525xu3mx^^(67e2B>CB29ubx?u? zA|2VGU3MvdC=o_HM|PCJA0yb-9i_BKxDwf1B91oaF-xR54`Mitqb47p@DGnLxzNJ$ z8jjQFN$L6L^)Ka*GnmdXge5R`5(CEgoH0|lmV6V*{gS4X40hs3hPY4>g`<3&G81q( z&(#8nd47Q{VagPrE7cMSh%=^W(=41QpP@;EO-*)F%z+%Oa>|q}DRa-f-_3m5E_94a zB^26fhH`|2wflFVW^XyhH~W>^F}%J6R^5+mG2636b4l>uV=_JIGF#F;uAS!7$pZ87 z!-vndm@`R|>DBsWf}ii?>X^AJ*_o63vwel&}CwpA?na|{Y zQ%=J)v(rrR<$YY8T|_YgqsG~2kL$oP6f;!Wndou7lt*!v?@DN;UJ1Sg!SE7-F7t4- z#~mh_o?|1+q7Zy3-h&IwCrPC19|`azj;Mbm)9pG&3(0gY@1*seCQrVQE0XC+lIcm3 z>Ac7JOF%)cjie^ilR}GRx)e|M7zaqEbBRKY!z9xW*S}=aN?KbYna)qBU0O;f4XP%R zB-44f)IRPcqXmi%W0}LyAkF$lo{MPcD^ zJ)e#pK7i8X(^;#>b5S2v! zI({pyXfj>AP=3BI-BW;I2!v-A)Wc*_r19<)&fR8?GS4tG4~WdZmv+)2TC5&lH4XAG zvkY2ARjv~8_b?iFoA;fK_xOZT?m|4IpkCF16|<`JiYjp|*W%D42JG#WLk;X}0`?fM=U zDeuhFkh_IsI<260WYP9u7t7t*0!yMOM>*sd7f2nL?=kA*SkX?VCr#Ajt~Pg~6)_|V z2_r~Y6q3C#>*srXa8L6~^)aWq)0P~kLcMJ6=&{v>dt)k_b;5>yaX4G)J`{0Q89%^R zs=J*CiZS47rU(C_6LYQYSIZSu5pY2b+PPfyJ4vRCx@k%)SJVDkieU+H4$%Ymluh>D z;R!7nC`VL5Y z$7mRal$OmwNwmj{Ma?@SD!Ew_M)DRZg5-Fvc3=^g`YN_^;8-6~lhRA?v^zZg!Y)sn zo@1toUYW0D&2Jv=p)DaJQipA+@qe$_SUSUJKB9AMRWU?&}nujPYJK9tBPa)6G^ zyGPt>sT1%uoIDN}kfd2Vs7d(bk`~b|+CG4Ws|jh+g>fz-qU$~hHo__GIV9AR-R9w) zOa%DWdraiuy`F|qr<#-Rjbj){z8CZ2!MGc}iSP)Y1`$S-4CD0tvq-R0O4KiEN2Ny+ zJ4j=7`b1$pW#J8e)qT*bhi?u@DU#_2lyQ|#lIh`|%o6Gp6e$>(y@ZeZWYoUTPNu_% zN+J>cn5tWJ5*E!fPHT&KpG1?|mbeo3Tt?vP zt5DU_qE)S>+$I@t3=vquo9IirTu#&czyM$ufFnoK_%oVDQf4NOsvvIMiOG2PP;PM> zA^^cOO?#p0@$9Ll)mGph8oaI6flp?sw?GDlxnsfb#7O3 zn6X2{lXxk^ti)XDEcYdQGKWc~+r%729_#6uQ-bJ8Srv;*hp;J%29L}Jz4w|yb2Bis zyUk?KxL#x5^gXUC_#L#VflQwH*R?vNr9B0r6qe1gXJm_PInq@f^^q5ZugL6tv zq!FnQnzgH~ng=zRzIi6-RXKjY%0fKJ2ycef3i7Rd)OKH(dzrFCx(DIX(Uscb_o1ut zATzn5BM811fl;Tc=w3BGS~EA7#chUc^Zt&y+C3e#lj%X%UiB+<&z1PqUZHP7->k4D z=O?lAMg3~G@*;jk1@(x7Df?X8JhN*w;kEN8BQF1I}-Ykun4U$Zsej07q;#3 z2K`A4-y99PH_QJT(B~ZG>?Q_^hb?7xGtRqPHM&_esscU81w$E*A>M1;i-IJK=T#L& zmO)x5ni5{cew+D1t1aiHK1LY`MuR@QVi7H^`(#{3Nd7aAM1ron)Y;331H1L=L0cGj zWz=MRnRlpMR4Ff@6q4yqPe3U1!TF%)USj@y(7*wWBlE$+7Z8d7BSYyD&DcZRLD+dR zry6C2WI8laiwBYyA65#~F=ddpDZ#(3+2u4-pqe44k3%e@ncFbXW;-OJnS*o>m-%4I ziD3)@=t4U&+#-hD8?fmtuN#+iP%?TldN2vGt#YsGHE8lKY?>yt++~|-%5C2E!u-qB zQ-HNmT$%c@bjG{HTX&mLTQ@ih)h;qY*-N1((IUg-ZW&F=P^Q}3O(39s)!cGwVm>5e zXwgCVS>lb3k}=o4C`x#y3!n@7sVScDq$=%5ELd2k0b4lN;8etRZJXM~v}N}$@k@GF zp~eMsH^ckNGCN2t{&1J{xJqZiRzx~pq9Lwe!f-74ut6sdy}BoL`=w|3d3 z{Gmh`@s#b}41bJZckMnxdxR^IO~)5)&SP$t<~)euG>)2le8N9G!sJ2=%WIfqI_#%| zB-8mz1xcm{Nv89i6(pG+B$-b0B-8a9lIhMbX-dgpCyr!@3z19@M)|18bV$iSmL)OI zFR&#{ag$%%KS_xM#2HhxX%B&()byE{a{|XgLIA~W=F1!)GeY+nK_W7RY94}OUm3kA9ORHwhJAj(q;MZ4S~lIb}%vMdV0 z7vo)$OplXH*T1+4?wOggizP#J{a05M_VP%WRz4(&&2@~Oe<@-%28 zUh|Gahj7}$CW`KTv8&7572*f2^l%xhmMN=?=qu;2Rtp;>)A3tU#c@rhix+Lo``kzA74wOEMi1(Q1kKdkBp)1UAIG zm_x-EF2q9$YE>OrF{?_is1nCwRV2JDXmNkM%S&OB>0LhMqyZ_!Na}}9@x8Gwcheo{ z-)-&<(SO9J;5d}PQEmTfqE-myTlx(M%k*&gP%TKiOk|Prjyw&yn?ytSm&&5;!7i4& zqY0KoQI2xRFD{VUKi_54#<8NEOplwW$6aMUj8?>uC?td+AyG*7!mOR|^1(gLFV)AK z>P}m7oC@_CwN{s{F5DYa*{l;b?2AL$O826O236F4zEa&ijG!0;u4cOMA38DD+J2Q> zQ569f)S#WqRr@f>bWt}=Y2_-~Z=e{K5a$p*7?d$Y4yChyyvu#aPAelg3pG_@E%rg} zSi-2HH19Z}-Ke}TC%jTy@C6ZG2oiDWw{q#*FMOBLFbpXzn}d>Q7fW7Jy_SYir<#-RjWP@*--~(i zVBC$~M0kWxg9sx^hH-j+0}?zeB?v5e?WpufVh3rgPM;{Or7XO`ueuL<_3+JpDMd1U zzcQ}UNisdum03caf+7V2vzPF3uZ-IF+R1bnQAs4CvktX8tve)|XPnj+^FE0twJmWa z@*&G8TqBOiFTE0$7`$a*6n!^|rqMc`kS^&o$b1#5T3WQKwUpa9@){zrgg4Qbbh(_S z`GEnzE&xZ4rtxPqjik&>992QwxI^b|T^`CUZbJkhxXeoDIusMzP(+3Sy2&93h$D)U z_cAB6g+QDXL40o)I?ku-Xc#przkHPVN-9{Y%iIy6Z6_2>zsQIq$#l7r`3y};GMy{w zD76TP_6IcbOba!3Toq=1{Rl{4@2(%@`BaxZ!0v>GfwU`_=jnf_SP zX6>jIa6dziGvI^KfO$9`@EtD7vCNa6%zc5toKh2ML@I>l-n6Zn2b^Sjz^iinewBrI za$jUKtez-RZE3sD&%I1pBHaUU>F7#r@%zx#cz~H)(P0FC41rOnt7y9#AFY|2kH&39 z*yjBmb+v0c;6WHP?s`o9%Dxi6dQ9k>&^J%mlJk?;`J#TcOL-B$qJnzFGdu@IJVPAw zC}%;^IR{bGEpZ5p?|Ob44kX2;8g78XbACqq#$zPYe~YKVvnIY5IX&hOT6C9L6eyiX zBoUtxVIO#gW*_5sV*Tb_IHKso7DaUUSRjze(!99K9i7%LCxW|i4xYqi8u`~q?#sG? z8c#HYMlP;PD&Y75lIidpaP+wiecnbTr=z1km{$EP)u(j8Y@5Y_)tOER7CCH^WOeDa~_1VTQ5%gMV4i}1!{ zB-3qGOnU6M?9^zBIKL&74ozPOQ#DqPsM#~bu#C({F(Ot%C2oTHpw#6a<|rOa-|d1a6y zI*CSApa-~MD8n(tdyVZVNWyqtRZ-+oNDD<%!mHSCGhb-6<-F9#Cp@~{Nki7V?QUE=BkhUqozpdHjG*h6O zDLM)p%W38|3`8fK?$>_l(#J0+I z)oZ}yUD!0q76sf#Nv7i!w>>}qGW8T-Z4`G@{a9RQn|SLkGivJwXQA3fCMb_lXdhZ+ znA|0!$x)Q4_U1_U3EEf9EvF{tLo$XIJp(^WywOoI=Gu;;gy(2Lj@Z&qP4R?%s&7`BH(xXNVD~ zG_UWdv?{*D><84r@)SsmB-5ptXOe-!eJ=|!h0@i`+jgB`pm~1Ru5HLhxMlQ`?6x+` zkY4!ME|v5miqt^~5{Ptkmv-5u{Gmh`@f_VnG99AsZMzQB9^p!4)A2={BbmO7<~)eu zG>)2ld_qqo)AL(cUc+(vJSn{Z$#njB@F9aK$#lNsk%4?BnNIU0)AbvY>CP`{O37d+ zj%0`nkxUPeOb=)>9a1uoWl7BQ3v8+J#OK)7M2Q5%8B?@r7EYAU(4;2Q1HYz&@7pCu zb;SXWnuAavnU3TVJc#5NF&yX!XfmDB_!)lvKwi0L=p2X5j$9e3TSS?o=0J|t3CfU6 zUsPuMe8A0o+AegAN}DOP%?#xV32P7RLe1V27~kwyYRB;U&9LfzjAVMY=t43bXl(wy z>u*2wu}^%h2ux1?xr`P6!|OWZO~!S`o56co&($9qe+1(2IpaB_#ppD;jD9eOdyNre zz?d>-d376;TzB!E{NKml0KbkKQDdIR8$^w1ejn!BR-@KvG)@^cidEbMUT~AqrnQ7# zj}g+(eb65@;;t30)h@4*G~&jLF$m7_G~Z58r_#8^_=@o*%cdoaCU-J=HiR)I^m99T@ZE$_p^;zR1il6)*;{(R~x&E;63FEWIKO0}; z|MwYxZd`Bt1?b9u$8Uday!C(3&Htpk<$t#|y54xbagA}U@ml^bH|mX_p^H<1@pPlt zUNmh7Z3yY7(fG6xK_e4rqlfYh##yvkqnd4|{CRBDL+N(t zg}4?Ci)Dt5gsafC28~A0=os}UpfZZ3>Wr6+O~w~^?KKX<(IdufX!J`tjeg(t_seMX zGsZ{J+~1(Jjp+1)eENj(dE=Yd<_moH$Djqh16}^Vr_ndyrImQs)BH7|uYR=G%`2p` zj`DdBEnGl1;=!F<^`q$#^f`kE$MDlBKJ}oj^Sn-Bn;PDm(cn40>!vQxnBxCtzU`o{ z?V~GQt6T+mx%7fw$44hA??)3~MjwyC&*OON@2=7JqP_R?`l$No=ZtR{|A-^lg6iwn~+B2`8@sZ)AXBLdHu8TZS9F)aDMr$@fonB zK1zA1@kL($sQvUa)c!QzeaiS4K5~Hq&YpuQ3+H3E#zT{2$bEkQ6;MMWUW1o+!ZDA?GOVXyNEtPFU zkvsCA+retIc&hsLMvigx0hE}K$g2d#cxh(wa>co&JZBH&4_@HK=;Arhcx)N%3MH2J z<@ewUarRilK!&qNh0m14zN)(7!taHAI-kmk`4Wk9Z%5s*pnT#oFJtLv)eph9m&9+))c-UGkl-fOn~6wf=UTOWABTmmzYToRH^SyH@ukCw(b@sFUxJ z(svJexIh$US?m_ZvnkxQn6ul*0ut-Nr$+eiS>Wk|hhKDm{p`heeS zEh|`pc0%DuER_||3Pr;L!+ojOx!3B!Fhk!)X=5P&`uA`8^@fqL>5VY@+A$XQdx*AO zq0!#uIbL3hE|$;@?P10;e6JKd_5_{Nh*%B7O5^<`c~BBxtlO0EpkL$yPTRJ5!?;3J zx1bQ8oSI+rNGt%%s_p*F>%DmB@Yv+^+_K4+?*$pczv}Ml?|u5D`|*Rjx2|37xOl$( z^r_Zk&4&**)>lrJ$L@X zg)=9bU;DUv`3cZp*M@iw%!CPgH_N zRdpbNZqQ8Jtn>01?#dHINg;)1&?zCMNdtp~(ZixJ`rOe0QOfXA%Sp~)uz466eoXU> zCd+Hwey%yS$pt2Ii7=wo-;3wag_f-~M2KE~TAGn&{{aN8#45hFzG>dJx`Od+(s-rz zc^1YZJ@`BgK16eY%W5AnSMCHu;Z(XjLOK~g%~RPjL97aLKG4Z?5Gc^GoRsB|G6NYN zOK9SJ^s_u>p0rjU79tYl#N#<2LNB#6Uc%By`3x>n;ILCKMc5zzQkPj@2hlNG&8=vb zLc>=B{QXd6-YL_G$sB4v(6<%)K;o31J*~>H7l5T>Qup29RDM>R6X!uOy9i?JWws)& z{&LOa$pmg6+L9Q{ot%oBWo9mbAu>749EH9Fjmr$YcxPi4Wr`IE;{a+@K#=_JhAIpOLaS zQjpg%e!5@8zEG)@uD5yDH`YNfn_JVYrz>`L_}-Dr+yQ7ZYc1&Xz)uS{#JIgCQY1YG zmxzvKsvX7|VOE-xfQ~JeE-f#Er+sbB2-en(Pc}C;?Ah%`Jb(o&B0f8)(nwk1_aaeZ zNrYkMGM|#xH0x-UpUsrz#R@Oy_Bsx1@IEO4?1hAn#l@I58sYud@?0kw8&fHe=wdh_ zH1Ut{s1z$gm(~x=pVibfU%7ts#_5Lgb1R&~@N&5nVQe0k7$)7~Q2~V93c}@hcQ+88 zn@hR81@coVR2Bwn?T()xnTLS@g1Y(AIFYgzulGE7_} z)VW+tMyOpihbqBfxG!0m3djhFIh2KqA}m}S+KENVGcriEuRNh(1SPm^pMOs(d<)S` zWNwx%hjhJLl*H3>Ie)=Cwd7ccU^1h{if_P$kdAuY-ij>Yqs zVT6)Jq%aFXD^L}_};}6+zW0YSyob{2+t`F2Xm{S6_6E~{4_Stph*6X zBL7|{j+6B$W8Ah_tTvmIw+%Apt`Oo8#YDlM2?wo)9$}~9ihMSo)}*)|?S<8|r#MTY zzZ^8kfh`5eGLUsM%#v`XJjB2;!eUKZX(t#wJ=|NmOFs!MX!vT?M3ETBC#2cxQJ%{R zxi|o>A4=m`K=I_+yb+elfKa>YGBvX>-+NszV)BrH$QbB>#gULWbxDC(oU8V(%*@V$ zO>Lgbjz(Jkm*B<&u{v350iji4KMaWVTZ})s&tsT`sZ_cMF%?S0TtuJUh2v4sv@+WsG*c5LyiVD>9nmS)+i|~E9>PSr1BqEsNz+%PGur%4B zAk~RYR*-lT(Ens%5hV5SIm>IHwly1#8$e3jgBAiRGc1C*(t02#WvcyXY} z{?%hxYo~!Hgrp|HhdVGU!{tJnC3NvvB9(_2R5`x{K4%6tZeq~Yxr4Ft1T?B;z1O&% zIk}9pxPX%db<*Nt5P*j9f%M5yE?`muWH!f-EJC0527!DlGiKH_E0Nc?BYeO4AXjt= zUkGO}!H9}uQ8w18pnRVl+1i*Prt$?uLSSSoe=vHst?pPZY&IzvZF1~^dxqBu@oTR+ zpFG7W6lW3YwE1j#7?VX4E6-%|2~C<+IT`=e>l-{4N3h^L>74%d!L|0IhYmL%K5}X# zl?PKQ%oGgkTBn^~ewA_^OtPJj15&>|$|~T%BxxF$tb`74Wg2}E+;EEy{0v;WG@fJ_wb7L|j@qtw7#?!ni%FAchIAtg^K~cs854l-ju5=nHNuiN!A9IJ_-ygTps9 zaF{dxhX|reX0xA$F^e?Wnw@Mu23xMSV}IRM$9Re3v&z=*oM~hU8nMX{C0b49;Pw(C zTi;^mhmq&>b#g0yS1{&%WXy1)0e-)SK^Ot9)}QC8Tv49o_CUFbSU8re2qHkKZ4Dv= zYq@a>)a}V5&QiLlA@@Uq0ox8C9#6}d0T4^*c$Vo6G>J^eKrN``vt~Za!@IMRT|SefY8~p$`b{k zkx+nt^M$~RS6ZbF)8?kMQM8`kPzw!~IN$&B9uF6kN)a%Z)}?ZhDp3Zw|LmM&4kk=_ z5b}g|wxRZ!T1EahY_lfkqXc0W9r@j~kf_dLiB^s^Tbj!$fdm(nA*F&{iV025Y#336 zM>J7hYX!~Jm$#cP83hU(LX$0oc*TGcz1+9Z{BO%F9iN9*zkMKDcD1^X*rMTyft0t6 zfwdk6Y^xT9bnd-uCY?;gBB33BD2Wt+>xQr75h^5b(PuZbo9nT@n+d*`9orNl^v&kfGa-@@L z>ADU$fL3rWr$c&WHr3ruHfq&@h-vv5jr_n*xuSPwIXa?)icV17?yg_Uy7fd z#{CB`^CX&EQ&vtH9c(kizkY<%uEs+gS$RO~&(F6pFE5)pDIxEGzugou5^mC&O_A9% za3962#S{fgG;@9Mb|zA;5Y3lI@`$$Tvol=C{w$MDCE~G2I0*H5JuWA!af5{8;&ceJ zDvR|6-z+hix3@#qLt={WJ3Grr4JmnEF)WY7oGzQ;rzw?(3O_UWmkQaCoFZ5(A%duz zJj0=PDJdc)2g0^FAj~z{MHDD^@v-o}P%Qgt2&=EwwX9#x3DmrC%ZIs?YjAiZNSp7D z2MbfN)&>>&t3=oLaZ|BR7E}uhXL5k3**HM!laGNh8IM7OyC7}CgI>(@Ll!qIjZlKO z*}P@3Ih?!!`~;=R%5QZo`3Z6zJ!phsIcH;5s)x>-tot~FeQQ11-J(08WosRGC)hayJIinjQ#|tYNXMODFjBWd-A{zVI5RA;uvibi2Jt z8KbwBsuvJOQX@GJq7#SOR?VP6Xiq^1=kEWRmpy%8ZsGvwbUGZi`1~2DQ2X*`b`_%D zuXryxMK))8?;`zfD*(RI0iV}((J z#N6*s%QJEN08b^c@{p3+M4Z2T2u8ur21;3o*5sgqMj_7+-{<`xko#lpe9De`p&d!T zL`u}b||vvPM@UJm9l75^8;p(Dlvb#E+2gtBlmphc8K@?SB9FXoUTP=HGYCM=n92dOaR%5 z(UNsr_~J>9f6)DvM53fXPirn(MeCxmDDV0vic%2pQjO(QXP!puoN z$ZtY<%6E!c`qM~0DWgSkG^UC0&Owl$vFP7^nv4{{(wuaV)mq#;Tb6B#`y0VInxCKC z?~T)(SDX)&3de1?vFqRE_^+jd?j%W7R_ZQRWGeiyS=MZzTB7j(1GSp5#<6?BmUGRp zv%&!P=hi^btjsrM;Nfs8S%KbS8b>Xs@+|V5k9jVI37Cj0vwa5{1wXnWqkjBt&W5Qf zUrL}O5unDZl#E#jyR%=F-rtQb zLYN4$rg1UqQUc}jTITy>DksVL0ig!%*O3*Jvf0nlRl)EsXxKBUn3=f=$|{?QWDnnvf;p z*6*{`L8-}YRkG7{@t^-sW_1*t4(Tcy6V1(3xsVRqxSZMkBA@=BoVmA7T^6HVc+@NF zy61`XJ%_d|eSoILNVI7k8P;x6R2)k2lX?-$mi>I_B6rY4Ls$T0Ld<}euWOBKxrQxd z5cZlpL1q?i)sdPVNd2@idm|Q>TB9uO;}1-FZxyH`a}7 zYpdCV_DofDQ$f8cH2iOtkX@dZvVkHePx2ZE@AwG=*!%vxDfFr#j5 z#fKc%$A8J%r=tk^yGlk4g)$|6Y(B%^cQx?nyJjt=SwKIXI-C9hJb$%v-oU@d!IvqhC!1#f9680MzxIT2o;^ZoP3nY>z|lwK}& zur+B_vm)#G!_6j1F1wL_6|l^!$zZ((!ct2Ur!5xvQ*0PX*y+-Uv6>8l{h8?qgR6t# zkU8V7P_4B3hm}mr=Jw(2ioD?3v?R;@6slL}aq`9x(3wSm@kE@pp)s-9H!;4W8^ zFxm0I9xZ<7LE5RnRPKF*u%oz8np-TsM>4fUUe;VsOZW+k7)qi_gMlRf`k;#;WbMc1 zRf}#nLyX2j1gLZY&v9-vyjoIHXU{zMxylErNOEwRq#3nD7Q)!Kms+P6- zp}#g`TwPgNURqqB{mGf>X>sbe6X9cPb7vwG(=$~2+VIv&cfN~nD2X2xyRf5F%Fj)3 z9>EG#!Z7!QvfIsYB;;k7V~;%NAUj8-rYK85_dI{VY1vImRYYFGR{rg$*LSd0ghU_v zC4@4{eMjylk^3{gXY+u(DS{#n5aw63tBO8B4#QD_+AVYzc_p9Ln+JGQh>=h2q(dwy z?Pvp$v@%ckqlU1EZP)3^$%*l?(NSqc8veI>--+edH(Z9%vGIw?$&JmU*xSjjQk7Oo z-;w`0lk3MAAG?TvAv-s#@UYi@D6h=%)s^MtrKLr-ph}b%MF`(}ukLX&_rmN!wIt&o z&tt!+ph6xj-3dfv59*dA{EESCotp}-twVhx)W=q}%RX6wTH)ZfcSAIBGvAWnm^4I$F5Jbw_s zyA!L(?vTfH*tWgy1~FG1GRwBS3uJmc+*-6mNJ?JZ=j4ts$3)~$MQ>*p$HoXPQ8ZGO znT61$w&ePo9aOjH=TXX^6=!tQ6We2L%#Tg%Y^}?-whM=CQ4vUE&sTbrTxUK+sYM*M zYBg`!BuE;u-nNX>t}wdf$bUZ^XtEqxTN+gW1-^X3dAvNaMGMSAK^2z=Qxz{Rb2n-V zcB{pd?0vx5VXJLP){8PZrzS^tt`rRtAT6epGMU80ujFlzFjlj)CXv%vNX40gO%WoU z|5Nwm$fz)aS2{=7sAf1^XY}%Y{his>xBE<}W+4n}wzDtpU}Mm7fO``@$*c9adHW2( zDUl9sE{_6CeB^`SK&`FHF{6N)h;|M!{*Tv&!t2UnvamAs@+<$ta>@nOShu$}#UtyS zpPhH1j$ZIHQ?T1nM|V+|3jrV6GX=HG~E zsOT~Q(R}*_^9b0P`Dr^$ROiTg{Zr50ap2w&mdm6YuE92m9t;>;r@i{@!=4&i7!;z5>#sZ%j>jUs< zG-syb2e%pDCp0)+CS`f(@ru6vo|q$SvstzwP2q|(>}`D+H&^9bQn-H1ceQY-$U{9vS@kSrlgc82LlKi zFWP;{@+jh%21#W=D1ZS9r^X&#Z%8!M|Xy0K$BC6>K%#ig>*K7 zhq8Vz^L>E&n@!!!gAy>|8Q8Ak&SF@v8yiA7{Gdtx(Ki+Ws>QXVgB>2j7@YLPD~Sif&3dvj0#J^I)HEF)f~}2@5vGxGuc|yrp!iq+@XoS^@?Fc$ z_WyiB!eX4#A%e8Bf^an(z5j%)PF9sTOrAi-6tDE}@KUx@k+D-+s9=(u+MQ@6t)MjQ zpgS%Ww&1w4j8=*;XrTtRCcyI6_z+SPBOe+z2R`fSu@NvJTXNRr;7ZTVg|-Nn-y129&yXiT2peOF&P9Gzt%p$kM_)Z*R1qT|K$!5zfVHW?>Y)uw zO0;)VmW4=#8!3g1Yh{RVap2O8PmCuj{n%Hy`CWS3iZ^5J=+TS(UgP99UPZX}(sTx~ z5c`Tn*nr}cvdC^`Q#cJyVBj(y4h+e-hFmw^Trq48kCMj5S51deDb~%Okbp~c{R|GO z0E$qpF2wIWhm~fkee=7j5=K-*e$}CM0`(tveVS z$rB=kk0oLI=!)JT$*@#o<7`5mBz@`JRe}TCEVQWvROArCJ5}ij{Kq5aBJ=wYDIk@i ztnPM+P>~;nK5VcyUAE&}Pfx^2jJ58{1qs1&5Ta-f>%OlKrFI)EB5|WXp@` zS{HV-q$bNU86c^O4XgAX)wvM@_D@~kib$FYnj+)f^jeyQ!&|PEw~CSvzfF#Y&J1&w zGp(C!o?tAU6Hs#f9wp9-jh4cIkiMj4n3qRV7JC7t)%ZHI4>xZVDj|%GH2S9 zVyo{;Yp%coZPTVYNZO4nh|~`JX-N&10zq^%sP?VRUU{nclo^ zpO*vot`8a=9ol++g+F>NVRGx-){Ui^k>9-f{KA1X1*Bnkcm$>;2cwzkY?VKRa%lT( z(gu5#V4#vm>-F$6lR^IeiS?MpBe>2S`ga?Ca$0Od-n?Cobv?S z_#$UTT7jZ~Qk^lbI;ix&+MGe)ATL{p8^gl}y|;NfUTz&395NV&$EIc%R(`X-9W)(z z7o?nS?ctv4tI2>4~v# zYo2G2qvvQ#W;f_8FJzjRWo(bXup6Y&qOmLz&{D(lLJQYlbm^sG4vc|AChX~Dt9=`b z%gf>lU*4+#oSU7pjb4HoFSPm%P$8H?hKfei&WZ#f{Pq3s(pdFVjicbBmMmu4zcDw& z*hHxu_X(ajR64Nn>RkH3+`?dPh!6d0*in^e8(-Ed21>f4RqkB2-WBG$l_MOxJ%kO3 z4_21xjicfY|0^l-`PUIF+fFY9Q03l@Kg&z=j)hYQ2Oio~u*{8S#*mYaln(jY#(4K* zt6mt^7wl&7r_#IYJPCd&wqm(<~WO1q|NU_f@!6z?Sx6QbR;yA9~ZE;EE}G3RHXUU{tX0J ztzpz%ffcCMUzu855El6YpD&x6CHFoZD#w{*U8uqb(-I8AP|<+ecW{G1{q>zU2~;h1 z;|Z3UvzuE-I0~N5ik;D6AmT$=ed*w+t=#|l=eGVlF#VOmQyDrrwWybUNkLUunq?1I zm@kdgWbOoa5vDw;%Ge_L_+Qzt9`EHa8#=tTn5VaALL6ss z@?}HLdtY>=B9YyGuVl=^Y1`S5lEDUj&RKxKzlcld7^w_j+OcAg?b z#Jc(iNyAj^=$s5t%f7p`GbT+66L{l%Z13pEr03HZ7i+dBWrQ=E4JfQ@7Fts?I2{Xo zWxxlQH{!X|3tuDEY)=n?5(d7Ys9(MHs9VN(Z8(gwwHzb~Au0qbri01qRE=}zkFJrZ z{=I(J+3%vqzwxh+5B3iX@}b|2+N+Ys<`xuyv?7_Fox|cUci8^fa(3uw?L!M1W>F!) zjY2@0^tXOY3gY~}t)p%%%OAc%Rl@W`9nQ{7t=OuPuv=?FG#b2Z*II$k-;XUb%d<71&3C+6d!m3cUHVMx@&LRSVa$`;x& zv9nr$NWmORU)*epf0~|bhM(IUAB$uQ%z_c=?gl5dTAb>SWzeF0!4k@%3NNDaMMG z$8G{RHRgJJOQf?-I%%hNbA3XbmZsPw2h_b|Ba5508OE*k0X;!onK+FK(UZra>A5*J zyN|LEieO_4TlE5F>6r=mI&mnkFB;TL85`Lv*zDh&pYtIxlj}VMbYg5|Zlf_#9!S-K zIn**XAPuJU`v#WAn={h(_1fAi1IB;l_V`icII{RXSlMKku>v$+orsvWJsHVq3#68`B`A3hu+Zm5 zY)|iJxb|xQI#Or270rmfGARQ;z2ri=hD=7*FMO$Cdb19P>+al@`0GoKK4~zi-`j7$ z`b5G>0LPn-1AkL~@ZR}B*0?_NR>{DPV>ip`%Tu?8Vq47mks~B#=T2AMvj~#mK+C)& z1bs5_|HhO5=HFGYq!Hcd*ofujtt9{G`Wx>Q z9I-s1Ne-jo!)uVk{cp{K1~!z@YX-d4Zj!@qPp&yo;vy-)QbtFH4MT9e+2z*fc^pY^ zT$t@A3(yS?x$0LD;EKfGMK|A!N%?Bq1jS9ca7q(;X=OQixBubm#1?jxnd4)W!Xhsk z5A`L*<+i$4DITNkZ4uk!|8+`;2i%s8r75L4IkWBz=eQ7a(UQ|*5o^7hXE_~dlc)SD z=7C(4fF+O5dk??FOG*)VZvTNv?@UhiT70Gyc0RtcT^)hf)0`h&A7*2GTstx5cz!?0 zOI_6|ib*rmY>H3nCdOwx6={g#oBP&+DEeKkvm}b2AK$Q|=tWs@{XUU z`~rkf=J5wZkvQIa!7<4aoUjS{TsSIVnaCtbP$bgJNsm6-4n(3wR1^oaQ8k;@DI;TI;UkRkWZK#-x|FL zuh@Utxhn(9ou{w3p1;oyZ*NY|kO)R)5lDk-7mg<5dAgflnfe9?vwC4jH((q%nZuTy z$p0}|=^p;E41z<~*G@252DGV!!nrTblY|8mK!rID89=VcwaWw@RhOZ+DUJ|->*yEgEUXqq21HH7XP2}KK~pSII2@r%${YKG}@{0@cA)7pE&IqR6N4K^3Yj=zCT~% zS%zrjIiMdLlm;~Y&RPqy7#6QKP7R3q6o5OfcH?ak0RKB@m0ypgz=&+d$`n{}ZXONR zkRu5n1z+Zy78+mwFp#4*0b9#0` znAgm@4Oejj^Yf>X86=np1-hB(nMg%A&2=MffNjVOalLkM%upVlqQu0FrTt>0Gc?^~X;J=$W?#4ZKfy*v%)r1=M$+f5z8zyud ziQN51zCfA>9#nqj5KWh=deba~Jt*NVbnejFaWW3~ES44z=A7m&aL}86zHUjyCoj}j zR3C0RdZ4o!q z)tJU6V++Gx(9_!vEH6X^KJCze=io9SE;H4Ip=QFH1>W^9?;kbYOEW3Eda38Pnfh$G0>hha{~awRyjzw5mW3G8B>Agl;qYirp{uOeV^!Z-mn;s4NwlN_eg z4R2D(7d0I|9`n+g$&+*IT+aAr3(jrf)tH4kdybZgIVxOJK~#+x#kKv_s+jWjn z1Ja}4D1lm0>&lvOJKbdRHLi#r924@z{O|kxDen2Kx+j|Hue;>tu{<`y1o_PpygYMl zAcxm?C0m1m2XT5%@Ng0VN^W-SNm#i>+Rkm|w_|rry%C{T9lJb|*fcX! zep6?R4xi1-VXJJpW;kbGUJSqd98sA0YNGROW}lp??pCz`?uAM;7NCCA^Z15{$?tRaF#kh_cxEi|Gue zGQD_GT-YhV?uCt6lNM3llG#UL-sRX~Bh}0Fx{!L}7T)O;vf2zEdVp$l84F)LYEPN- z2e#7uqfVUQ#|b9+yrR5Ehb=n1k?FF#)=m&wop|?PC7QBSNcfLe@+x)X*&yC6W_;)K zx`rdCE?w!k%r5OYce3SBLuFOXkp&pECUUl+GG8H9N>%ylJqItuS@LE}Kng$vQU5-l zH_Vbxs_q7IBS-7<)kRg=YTUJ^u|I`aFZ9(c!Br`zX|a-G!LGv|YN6O^kLkJZJiH8m|=*cK^e(qiMynD?-l=IUpMYs6}?N?lo1B~_MGR#jHj z9p9AAm9xEZY(|D6wCf)Tq<7T82woBRdDgQzH-aP!Q*nHD)#UI7af$>eP~IH+U=5)yHsvZ(p&2B=Y`?A3n+=x(*t)a zzu4i~kejR^g*ql`K`4gp_4;FYA?0D!r7b3R3Gi~&KnuF-bX$4p`GJL3Z(eR)f3bwh zLSJ9Is%0R~Ri-=iXB@BWmdZcs4so_|^2mx9vS7uUcxq-m!CCs;{rRygP!8fZj%_Tz#i6Wk-2V zM~`k9=*MtXElZMF)v;*jdqSVu2m0SkFEwS@3W|xhdU|G5OD!1Q9liV!yji~3BANL! z#(yTQwKlH^J6l^gJZ<)^<$g$a`Q|r7qt8KhF;YEW2m5>oq+GHw| z6D9m1xbUE%{+=;w<0Yx4o}Ops2V-%rHQnjxF-m5wzNe`><3ubfmItxa(vNbKYV3h% zR*iSsdD)B3E%YpK)tlHdS9QH+W@VV|GZ^ML4z{a0$MK#1j>ta}SC2QZ<@_e)z>0E$ zK$2frE%o{{Y~kRERUp#k9DN-P)xT`M_Dnw~AH*=N&*+~$ymq>&y6)_ATYj6Xf`G1i zFoqTg6HWSzS=G}=BiwzwJi^X#!K`Y>N&hmjacTT@pZ!!Ha`4@cK#+|_KSs07havuw9lkzh(8>cpQ|=H@@CcRE{w}u@BFUcarH|P_0`>Rp;thv z2?HPR#JIX%V_e3@EdRN<+|pvqd5pVfz3FT?CM@O-_m}$oX>L4rWEKM$eP;-&zMiyM zZEQ;Y$q>3;=gg|6R0eA7lI<{qhtaoX#~<|BEGE=(x`{_%J$I?Q6V!sKuCdtr?decij-n zwMV|TdLdKw#MAp?xu(8u1iN4AOkXGN+ub)Ne~)HY>h?Z*(VlC9eSMg*x|Y5SU+BW` z8+%iD+y)J?8$+b06ow=z@X?kFG}(AnR7F-;)PswA#$R_42Gt#tB!em@Pz|Dmr-XobcuWxmdV8}eQJ$;;)OXd;`DAV23108FYFvl=}kJxv}Ge>xh7w{7Z=~7%zmPy=b32M>3gbc4H=xa>}~8B z$GxBRJm|(t9QbL5nKd&#O}%hAe4wSL2fjwP)YI603y;+p@dwBfv;G;z`|Q>ocsA|3 z$)!$Jh*yWO?p}&JqINBw1F#zKBnDy%Mo_39ccfHPmM^%=yej>zthsEd<#_E2 zG>f=pgjeaCl+oxz*T%jJaq$2ZOqkp;KN63wW7Lf2Tus zdU#`Wpxp={#ztQFrh%n9$1~7oi|NluBn9bVfbUutjiP8A2X-K`-X2V1XiIl%f%7}? zrn*}b!hC%XT{iA^&$VaF#WQVzo0X>?;8!HQ-VQjH_5oQQVRH#w45pGi0R0^jL<$IL zAO$(dvrs$U(byZr)S^d|Ht{Gtf2Lj5MNx-lLzaZLW8?cfjXem_1l!>|G#_A=w-(xA z#4tgKK0~_DLPCYFz=7vt0Do!{7&Z;;PXs`>Y)Um^8W-VP-GedCpFIQqnRdos6MlV% z&0%gzo3*#}xs8^jj6T(51bQ6kBx?wnbu^vjN8@rCx;%tk=zTo`jHjnXp8hmDP1 z`7_KG=($Pbm_CCUqUqS!y^W09*eK(sL2IFDc~Z0l3l^kWLN9IYgN_aP*Ytx9KVWDu zF0`M#g|C`+$Dc|9ziz>wF$~;N7RX!oO%GBV8zEnHPwxXrSq~pabD2Bf!papTLeuob z!c9tybsJ{O?Vb)KO!%$#*?sdZ_(APB+MPn6(53w8qG#w_h~HyAk<7^I@OK&_h6-;( z%E8bX1mA%_&qXY#Rm3F+Pyq%ISNDVKzspSvzXKD;gNwR>SY*TKlJ;b7D%E! znESne4aNRB!E52dyGT0nSIBp%1;JjH`cezz4cTKtsyg6WDXCLC`X~>@jp+gsy0+z* ziNZ`t%jojj%9ju7@MnVl`i8lVglBAOURo`Pod#R<8i5&KksR%cy$kj&-!LSr0YamZ z7g0WpubT40bCiKuouA#Tl5 z9aT3~Kf1Rf?Vt$)CATwx3stukNZQCIF$(H=2?@xSDMysoT|yz!zV1TSijgB}!F_4= zXvRB#O31RTV0t84MaZ4Ft!Ad3Osq&AUklxW0x$(CJ>1A!5$g{ggs4k8dS@rDw)eox zYF=Mo!iaUxzFs(12kFAXQcVfU;Jz0s0VQLX=PEqIvu6p|RZvlyqC8wy5GGRVOm|Zc z1r^x6Y_vUnG(xgAN4sF=J)oBv(b&w_F;+MlRMxn1LlP4WRknCck-{Bi5q9<@4BEB@ z9&C~fs?I)0uJ9c)@UD9}NYdAc45PD$88k0j=ug^CIS(;t?;&b-;^(FyAG?6BtpGw7 zyd?XSFX-v)?aUiAoqa7YnL+pH4j*WGnU*goT$q0(U-)Faqcd&L+`Bf3`|B=z<<1PZ zN(N2qMzASiP~9Vm;Rf`;4g7xhLE4uscwoYyX$rnO4*4=*xiE%aC#l}X<{N^1N&8b~ zP(Qj;izi^Dyt5}~Q1#Sm`nGQ>gQm1pxtojzs0f3$2jU{pTo^;ABN9&Bpaqiuz~Ul& znx4*J6UN$Co08$;$t^Ea?}|&7v!?a=oeL>Q>$7o^R_DXzCA}=I)&Fk zd*hj`SXFJCtbX{E#ipk@1G0{@fk*#7!s_dc88o%26lAWt@r)*=@*Pa;*$w=zR-To8 zGIaVAX&5Q)pEa$%PI)jetwvlxpS<%3ML>L&P3>v>LK`Z>_Yg72M4-JN+C=Y3s9*K6 z6@MpFzISyA&(Zaq9$b1U3$N}4o?mn$i`9$kr_GHJ&T32W5UZq+JiU~})>@-Nw4`_q^_^9a1UuNEhNwZXp34}T&F z=sGEykO-hfSyE5iLw`x8#fDnM!VL%N76r*~v_h`U4n?jnTVy$wyOgQ-Be|+uK`@4A z-Y|@uq{(uxbD`xa=?`7K@8N6f@MqC%(bH)sJ-f{F(g2|rY! zEaPIp!tyJFrU9wi+O9s_R%L>;b&$5=exBlis%8gnvUuTO$LmMsxT~hM_A$PcC{X|8 zIX@}*FjgkbPDw?F9cL#nn9AGuIo-bP>HW7;8#q8p$G zkj?a6F!a~43mB*25fYBpW(Q^j*@})Pfb1*@j%?U{jdUU1=Fc0pv5xS*Y*q|gd+*BJ z{mvvF-xvOprWh_R*S2*+oj)!2RIO-GJ;EJIYCFlf|9GS{AXOixj;fQ+%#2+y+{0Z} z&5tl(QpZMX-cSb7prX~>)7gZP$ReK~g>x?gKn(!?=n;QO;<8ZXNJIjJcMmqD4eBQP z7eDlNrW9rO;TxL%KOSwci5YM@u(J;`B`>WbNCObI4p9y!0vjt|XoHA;WXp&f?N4#< zdsk*A4wBz({dUsOlrpGs*`Jr44gm-^OdE6r{>S6!x`zPM*N7!~XHU|gYQ>sR)&5j4 z6nFM9w$pNf(Ch@8vJ@ZR-sCUIrRAmUGT~n2M*&v%g^WSdwm@GH!ZV#c8AHj-rbYOm zT8gtj5>5$)y*rO^5Qt)GK{}8VdY*#v8UIlLguu&xBJ6C8A?y_2yF4>}kHWaF_36aK zCBQ%(O3!DC>ZrP)jEP!EkWd5Av9|2~hWqw4wCg`O&GVdj~ox;ylF#C9Pj$gX>aT zU)G?;qyD@xA#FmSov3|;@%+d#<$R_40?ermWh=FV9;`r@AOKWEj?g~fN^ zMe>lfeK3s_WgS!)+DnD-Th|)KVoEx7I?AE|gTU@j(VD?@F}yVWUpOPfx{{xfF`hYtQb`VjIFloeF?uNci^c&6V;iJ$bPc zBk6>l%OH2q$NEcN7JprT*s#@cud@xvDe^r%k{iM?+hLtSKf31k>IPdXJ7(gKu)IX@ zE<)_u-#VQ4;Fz#i2%T>CF`Rayme`NEES}4i$f9)EUOJe6Q!o0TYs|h z{8*$5yD5+IhWC1|_-)u3O-e6o#zpLl()EwfU3sk*7e75B;$jgS(|G^EuxHA&;~i_S zIQ7OYenmNK-mtIfHG13y`C8)*oVL!%S3jiTWen<`+Is@dAkm}w$a}E$iFKcU`m>t) zyGx0u6|lWXxA~l^*RZ(ax`%5EL;Zs^646jJoE_e8 z&=1dU`P~y&>#EPbvS#{uac22yWt;wyR9<>x)SAdVt$dP<%XhiS_oSyzmS3CMn9&am zG90lH4cw3&{*aE~j4nBR*5S_@s@i(jqj(?i7vbq^)h&a8sBLj!)o9#~X9ue9V+&2W z)iu7?(_MA&#ky(E&_AFjy(V#7=R+JY9$U6~tz$P2RWy9|W-EaMzQ0IqeSNg@be}71 zTbQ0hzc6z=^`_=CUsxX0RlG+$f9{Vb1}v6&Aj=MA<+HyZ4-WJXj4oNduC>=!8Y>TU zd_Ct(q6gcra^C5OEfw|m7yW_lx$#LHHCo(C#GX~%a0li4b>N+@p_6}XA9vYi^#hPo z66X$oNp~|$t=YVemHvCJwdDuSKkQ$yMzVNU?yrTUd+EEIC#tGXKACs=ZA)XrqjVg4 z-j?>bBeCTs3rGIo42Kaq#$s zn_s>hnOog3TODq{*Rj2^GB?@RbK}g>hVt5$&z?_jdEKV@u_6614);tt9Sd8F#rve&URGB8*K0ABrni|6zY4o@wc?AVaCtY8oAiyP-#4<9_xSXWa~ zRo`^z=<(B69=#Y_Tz7cfR^$8_^oxV|c>iT&$`lQ}Y-~Y~4EX`=I2z#j_E6=eF{gW7 zGpX+%u;^8T1FZia2KA%U^UFqz8k>%E7^ToV#cAI%F3wCC2K)O5aMvNIde6}4sy{N{ zR(02ktzQxk`o2s4{xjvR&r3JGHjEsHu($9s2g99(0X8TOsQUX@KgYKMeqA=Q=nAgf zs608DqE>4yyp^kCb2sCk^=2Fv)8njEULPBLPmkY>uDbn8x2unS7qG|| zweSxG*PF9djW@=uUi<3g5JouY)jI~?AL#GvAD*}P>_cZOTb_H_R^jvLsF>dBZL6&B z=v#Mtww5Oixb47TRPP%65ZCk#jxBDx9aDD?R9zemqFDzGtp#r>e3G%g>1e2IzHiuY zdTkpE6S$5p1Q`DyAK?AG@BRLvi6xWMZ8qFKSbqE)Q+lm%b&7u?hF8A6P+!$>`RSy| z>2=~=rRgz)ez0Ha6Z+YJfUh58^ zirQ1xzZqTGa#6=H+t#LW8Ap|H4iRk<78aJ*Hn-4^#_h4LPxszBRaaSmp=Z{YpDWxY z!2eS*W}kj}zwJ=XA1fP=wqL#1{d{n2d=jS!XQy%Wa`0K#?T%B2>OQS#YQ6b<+7_24 z3zs_hZ?iZqwlx0cn};_qwzr)+ajfNd>*+J?*fIUKf6C~Lq~S^wX|??SUuCQL4<(0x zKVF9055IiU`|{b7FF*S!UIx6f_!GPgRkzpkjOWo=T>J}!40Jxmk8__T(vR2}v|wZC zKqpH92PRNj_yG@t4m=E15918Y{haut?#Jv4y4CtyU};F>eNtTd1J(tcFuQxmjlR6h zN`L$RkZYj~Tnk?z8xkcnrrBmV^Y#CjV}bYla^U&1uY0;4-o2%;6`TRb0?{DURk6yw zRn;{hOW5UD(Bw~d-A&zLcck0eJ3ru9xOuI! zQGkt>@B)p(4yWA_dNLD5L6d)nJ^@{8AqAGp<%WR-iQAvx z9gv+}-h}Ba+7sYL)Mj=sx_{!lKU)63!<&$1rMt8V94&UG93XI!2~u9lX$6HbK}U=U z)BqHS(H;xwa9))cLDdolU&7$PGAK{DAA;AM=_jTHEtnEONrE$q8H>i2Bc6nPBbRu9 z8Y!W*P&_VBU+ZYrUi}VBg4=@EN`*CQcF8vWpfu6k-nQVC3~GC3v-zc6nuI9M=7GB- z1~BiTFonHz1!^Pg= zM@TKRRS||pxHx*ezDK8!c5yiz%=wWcE-L&8C(+<0swion3=4*ijiPRaA0Y`~3O|DS z^Ik4VBD9pti$FzvQmNgw4umo?Jwhqy5#l*?m??BP!m%)%KV=y;Ec;Ih5&}%ib4|PC z2tiU@)}q~ZMTs2Yy<|l?p`fGIzY^O1pq3clXb=K;caXLw zWd-gf1)@j&!dn`I6C+R^j;Rp?g4$lsaO%{Wf@4V$|G{4K0kn~(iAxP|L21Qvx(wfC zKlnH7h{dk-aD3a;%CcjzdE!#4a9kHwNg;$>e**Hnrm!C%&f^$0{w2LB^ar12rF>o^ z%Jc{7*Edk_K&0aDr(9D{AAHuNL*8F6}`=J{=D_A^38f+s_y0vV80c z_R9Dm*BmoDSE-4<($m$n z{_Yyi#jD@49w1P0aqaq_upWRGNCHG0PYM+KeX)SddQif0hs_yZ;H^IQ7LaD%Wj%z zU_0=!0><|WT@TS|_u@W{Q(loq{+h16+W;=cmL0a|^L#mdp0LOXdGnc_eLiUXu3n2_+B z!1dJ^m@=d1cn-uf-!mLE5yOFc8tzr@L5|bcH~_D8Q6o*f_>!!QMS%~hmFJ{}bjae` z{0|5Y;;c*p!gMMo^BZVaS~;5h*|Rnkv}xDaxWaI77u``6gQX$nkuzy|v_Nt2@!5Hw zvCx7TISi#RVQP!|A={+>r4&ucQk5vNN8$>_!KZoPLn1CGUpgcze8`zVueua~SUY*dQWA`!e8)(0MfYy}?(DxL#Dtp!M`3*48B-<+qzzK$fl+12W zJlu&_%Ix-xO$5wrKe!D_z->T%@S#L_1iY03w?Ka5Ew{ncj#25!E2Cs~HJYgxxD9@w zLM@y@V}aU$5Ec?lV0yAkZGf}u{9S4T^~^~w;!Pg{hSw9EI!8jGHqfG}X|#ZD|66qN zgy8?4+91u|lSCn>H2)9D#0Hw)2LcqBCUo8uks9m?S3uD;7b#jRq3nA?gYlqpE*r?` z{Jql=rG~y`AT-D-%45(wlfEZ3pw*z9tx$?7$aDt9pfivV&7_1TDf1cVz)69A=?W%# zzXdOCxi}FT=s;*7`F=0xHxp+OZTw(pb56jYH=+I;}oq3+>}ECRI%HV?w5 z!$|oqok0N{jg#IyQ`b?6ZIJKp91U$yyV(LX=2FW|;)|~ia%3-X!AQK2tL%~)2v`kJ z0)|R9F#r&ifd*6t;HD@BQ;sx8Tn3~rqE7)RjG_cV)sdE|41NtNgNza)8y2q1{8>fT909qD>EMmc#0)GL|6Ke~BLhh3Kc`}zJ8y5IWYMwKOznrTa-BugGdd5|^GcABy*S(0fdsg!KW)?|qUKmY_uZ~_5>06`EW z=6S}M`d@pW142_)R#$d(M@Lsh6-f&?XRo#QUVH87|Bz=_m$$GKizI533|`P$+*zR; zV3a%-W%Qcgea~v_m5(0gAZf^3BJweG`x043*aAdX7-o=^LrWZ5P;Wu-&{%%27)Ip-1}*pvpam=v z3w87_LKkRohN8a*jjX;m6 z40h36mC3*xV_jIAkU%a%MyU}Cu!Y4MA@)L;XnIGP0}Di`jMI<}=7f)`tlSxoF9!wH zy>xjfDyX;uZ|w=oD8;HM99QsH179IAhheBO-V~WOa4Zt9?!xJzTvsJ5E-L|P`2{9g z&rp5oBEuCJKE6-PMl#NXRLy>d*W2&zmHa`XB~hI*_8oM=ak(I}hbGxo{GUMyYp4QU z4Q-L2D9{Xt!thHO1*C!l3KRE_$D`FLQbIQjeE=aTHqGv;XG!-J z*WwyV!sxG($|?9YI0e+lv^vA>KUEZ6dEEz2L6;~mivf9g8)^db)?6|<%Qyu{ud|45 z)Fd%o!(^-hD!5Yy(SX*O$rUuPK@%F*`45tHJRa(mZ#k&I2%H1D2NX|<%%)`8)A`yz z?VhY7slruAsFCbP-4UlCw+0VyZ=QT4D-2W6HhqFgz^b!al1ip|yI$GA6oAyJwn^Bh zX&tXhpWY!%f$XmbUS>@V3L>f|bWRKqra+HmTf$^ULVlqLCV(Fsn1b)BY$Y8nlcm!6 zfQ=e@u# zcJT?;x$&4DJYjogP!piaC?&;yB1z4;piwZ1;UaLP?ldJ zp+l_>F`p_iNP!-Z0=cokqtx3Fa0{hc15!|jlsj81LSDqwnaR#pKnf_s5s{Y5z_lqV zrNHoeNH}X&zQUVmD(TB(F3hA7QJaiXP+FzVO}(34A;k42V>ZVq1)EQ~L^ZmoAS_JX zuvnXthjnHWoVoM!{$v#wvjyFGo_@Ro>Sysbj?!N*bg9t3a<{8o+?ES^&$WHUI^3 zWJ3m>c()4WGkO3DXvRe&p#sQ?!ubUHZ~7Iw*xCWd6FGtE6#IL)oNGiDOylCuK_{rM zZqzGXR*J=A1)480Izg#IqamBVZY0Wb6P=(2oq5EdCNcxG{#J{OPLNpg(;8VoI%O+r zU6srw#K!xhIMx8MuA2NKo2q+v;BSvb0!N8!XV1j@6z$P(ps!E|?RlB?#2nYlwSdWmk%fV&kpZ*U;3#8N} zF-K6agoA90zyx*q$4cdY4g-V<(wr6mk}>6qN+tLj^guLbzI+0E$zV<;a3fvP^0!tT zfo-A^r~=K@j!AozvNr{@IKM22PDuF@* z(A=5KV5a2g7l}%c5AifDB=7s*0)ThW?48$d6?ih0N&q!Z`6m)F30PEDLtZi&kBSW@ z0j-$wWfeZN<~9fSSpd;wO`4LsRs`h34+u)|0%dbW(u3i5>9NT~8BoCF_hnGW3`#Ig zG*Vj9;}y&@AqFMb4k!U+^fy{FCZh_nPnAmWGOcm5IFE-j{ZUk~>~CEXiAo^I{$Efe z3=5zVC?vjvc|2c^$3;nvN+8HT#rQ)|f|AMfUSTmDvU|chfc;4K_mdh_Cj8GoJo)eCWS512PD6^ zr1*^9H0CI%TpW1%tta(U$dm;~+KLs%Z-Q^B%iP&S|h^<~o1fG{B`AwjiN zoc>2w`NaH0Z)u8vcW!qu1}MSz$P)PQNy`_QHVG!jLToj!eACaybp{L#yIB zl}fPno6oUG+X$C(t-Y>*O3;@;BBfG=U}r^%HBku^S^^C~-9%gxeTr74KgC@YH8gD` z@gO;AT!KOcIT)5`a)xrH0VXIeG_>lSP60ASe{0LXIrII+l%0+fxLiRfcCPFdmIw$$ z=^k5IjMr2!0oMLrK;1>;%K#I|RHP-`%^?LXX+c*}xdfYUUxf68+G-Jv>LxL66%;xi zg)T}tZ(FXM|GXJXP=Icz>@O`D7c;E>T7}mFX)IBYIxSRf)(jvB07+l~k^l?HVycE^ zRzpsBRbvw5JW#QlCUG&zSs(vLd+x;irQ7S!&;c*jwdNuwfiFROe=4kqk_gTupa}(( zJ)#krm;|+D5*p`Xx1@~cDj(oXf=#fg$onBJ(3-IPEfDF7nkAu;+H%Fx|K3C;5Fih} zRQ5?rde-~4S>F*ks1}g{Ga#6SC7hbZB}k;ibQvqIdPO4>>`r*e9#T}QjQ^EAcf@yk zavA5I$e#EQpAeZq^kYn>3L;XAocgUoWP)0r!bmK#mRct=K_YFkadZFu~?~=S1kqQQdG$ly%4q5tqOiIH+V` zikLR0=<=2dCI|r0>vZPFw>$Ftf}OEhZpu{Y{6hj0JSr}$i8(bjL|Ot9)Dx%~fEI$v z;RON{K-U!&gIL4J9#hWvV9PZU!EXhafC7YA`Xv`|NmnXKHGiTh029QK8(;#b-!6=c zfIu6ZRRR;V%f+3TnIk>LK+lvcl!!5@aS4FiDL2654KP8_lN#Sv>2pUdvNBOI(oJx?bp+>M3 zfh~%-+@KPy&pI;W+b8ln+z0Z6ks)4m<#oTTY!wcyC4dOxlRGe$l=Rl(Y9WF%RTx47 zInE{cU3s?24oDUH+%3mdE&(-YZ1AxCf}h1A#fcsz%<6)Vi%fe;5mRDzw!DMxnvMaRtg-ihNy2N2i@ z(K8jI5^TD4NhIVEb^i2AY`q8gc*;kRTrY{7O7K>NNuje^Azixhxz#2r0odzG>aSVV zAQfKEd;e}J(ok8)z#mNXy>X;a?BWyDMTeO)piyN z8CF4ZvV&$8h_I=wMkRPPJCT7^9$(Lc3mH2Dd%NcHDwUwVM)S2KE8KPhWvVs>{DBH# z3ATjx*R(Ng67f+P*G*Yq`Mx0s%FaCD3ri!u!Hp>2noJ0HY*_ z)G$iJ5`a&vDs;#(DGuU0!x9*QC8(lcvbt@wiRSvqsHHtBmtaqJTyzx2+w3c&=dTY% z?eat`&gglgoJ%lST#aD7D*zjM~Qf}?|YqG4(IFxJvrCr>J{DlR2nLRFz$ zB*%|3f#+BG>{~R`%I>6_TZGOqu6Nk-y2BcmKmk9!F%5&XReHH+{DkbMZ#OAXPpvss zE&)P>4@H5xqO*;_7;&7Y=)mx)-72h_*NpoaI!4BqYeB=*ukP@;=TS?Wq%$V3Txkb&;w6p`K)i zZY-_)fKds4di{nHZy3eeZfg06aA+wm`+m)|sCmG5xtzt`XHW^qMkwz>cGcOA0EY3N z8+pcDM?y=jQBFun1E#+}5R>4rA}6+@dzF*|nk=(V4jKcI7-tfgKKmw&NR)?g=~QZ0 zwktB@p#E!cu0P~Z0$~Lq=@mYtP?AZm_j(sr05(G9zA+!5QBFjw){U*}z8oMad;PVW zI1TuBY*v6bBH%11mkCNBdbQ-4NL3gJoU@6YfD)WO`uc&rdv^WvV^9KEX_quJDNNUQ zaVP=i8@wX1&YLnN%MB<&IRjK(P63plimeYd@23guGKUh(dF|QpP4=akHwvBU$#L{) zOH?t5; zIuYoRr6Zn5Ljaq#YNyk-_C1gU4`_HWVc3P*Y{$K8XI=x6zyT8>BaE8d#4^#D8Q92? z1U1^VlTeW&7{Mx#puC<^)(A+Dp>Rc$RmE@cmcL{`0z+X}3PH2Ymi+X)=-wPcmf|$n zv!5^+!BpB;3%tOB8zrx9_iT-U2nGh@cCt)@WgguO2N7KUR>riLwH3SuRlXF1Wy;)< zx;9pjR6Jx(p-!7U>d5bmIHBuqcT7&>czeh4dNFiFGi@vN7#d?|=4R`=03y(1mPvNW zu!~Me)Rw!6L$LYYr;3ng9D-Vyc94}oJ1gy4h;s;x3x^8!@iKDv_QI}&yQeVbfQ1Ho z4w^BFVe*9Nk$vLQ3z(g;I0vm(Z+ce+dujLk(zfw&$x(-eF8yi)L?ErPp^(KQwCTkt zEhS3FXTs=DG)=(qX;rh@wYD>L`@^JJVw&C^R*NIPyVlFA4)#qzK%6n%>l%ol8lw&f zAvC168i?Qq2NB2tb)H7?YjHv7Q9%S>#q32iv3C37JRk&Tljz^ZaeMyoBJR&(90f#5 zSX8_~N^@1}>Btxm1cs@TIRrb=F4SdK=9j3-)YPfHv97VJYczEGsd^S0=t;T zKPnCieGmxdJl2{`vHi>u?<&0GM1yoV#@Wensl+-YuBKm+H91S|%C&MCTzMZ7gr)LT~fgdoYIy2+= zV9nNI(Ps}a`hdRwPEB6dC~rxs%c?CROti8i8nB4QsWad#6ubADH*pM7z;8wa(!KlhHZgxiQ6Sr|F1mGOz&lfU(pWo3zPx!6uEhnDz1Z8GS(i zyZdE%`6px+3pev~)Bfc{!t0;iR(|)*8q`FKV;$xt%Zb8?k#(zO3^xjFzp^L0GH*en5Q^9 z#$D+hKo9I$n`ZXS1`lxbKy6llbsfw)*VK6W5^hnqLJxTw!A-DUSS5hrY1bWgZUlesOC+Q_5+ z{DRjj5qF?kQZ(*>@pKTms*D8<1rhR413Vx=){(#iQX^;O*#bI|Gx_x=IAzSi1ODZy z+O!O{ZFzF@#JDH87Y7=a59G&S=$LQfO{@a_{(62|W@akW?JUn&SS9R$;cWys(N=?< zhUujSbs)8fX3Fc4iSW-agF29x_JKOE=Cp{`^4J#3;smD-?Cl#_`uC|!E(Gepf}2+- znTo~=(w{`sf#S+qN>oChHc_FUuSpl_QeqqQy69jf(<@1Zc4xEdRiq_KDW^?=_6+3XI`&T;;fBpfm z1A*Cw;j9@iE((MlD6h)vFUJZ>t$`irnN*ZQI$g{B=X6SZ4s`&WTU_s4l|UUhAc7vo za!d*ws1b&qm~dqdZBPfy$>|y_vst{@bTRgat^gG zW851r9RYN}aOvAH!jCv6SPhoUZjCw+bvHY~KIV*oI&gwh2i$XJ34SnHZK(r~QwJhb zPkN!+59$CNvqysZQmU?G8`Obe>;_>q9ZPussV3zUM5eMcUV$CVfs6pHj08!vVxr8L z1JIvWM>@?7pbt&D(}y{8pcTvkM|u`VsY247}ho>;;<9wyeo;Dg*O5Iqi z7Sah~RQ_ZwyV@-ZACAnORl-XUX?nq z;>FC`g?YnN>RV6;I!@bTYKwpy3=?4+r~{^Z=Mq*MpfqR?qidgQ*n#C0_zFoN;W);| zB&$Bju>*!r{;)bKBOb^$lVy2S#SZ+(WM>MLA&gs;>Y_uC4+@Wf9Z=u{ER11g3~LUV zs!|wMu>)^=fEK_34H4@rNQE)2u0!Ekj{Im%=G1`@-?(7Yt;NNvSMTxFROo;S(1A$Y zUGvH;aZ={n(0?oMGva_Dw=*{{&q%X|>GZeY4Vb{pVgUi-t<#2y;`_i2;6{8J^_loA-GiG2ai8}Lt?>thvIocLJf4g3$QyK`g6_-QO-7P~!* zzQkfra*q^c7OMwq(&?h2%)ZHq0|(6_VnIg0GM0b?r&3%Z+3T3hfdgH|B+KvU!hz^- z0ayE#r+5Q{wXg?!{VWq!7FykN#V;-rY{29`Qpas%ao#YSAliW8^BW~PNp|l`+kiF9+gejcRo1}Y zjGstbRHGqCPs8`3FNE`wC$W=6%b&FV2@&Y*_DoJ}f(?L9Tu%!r5jKk;`WmA}M0`#f z5aOZLEOuIdvbN9I5p zfd2aNaa20%0>+sYsKFCy;8J|7j;y6+4D6BgAx0W#U))z3XO@bfXBjOc%R?7I9g>GG zBq#?f+1qRr@jVof&_|}!6V{5T zVMA0Q@+4yo)KU;_7T2p#hklt>hVznGOkg)9lqiWpc4dhU9Ekw|o1_7O^9I_%8;FH5 zHZO`^!*WIg4vbd4oH8|2xJn9#6L7-Q z$kqh3X90BYq(snxc7hHRO9*~-hF8(8uYoeUx(X0SI0CoDan%5OA~_t5Yz?kS4eWrl zgt~_Q+oHIE9jL7$MMN%(ypr_k)Bl`x5jRSPwTit3S+l{K*{@*-_MpW=7@}+jXLKa; zegix3`^@B+qlB-R#sW?iJMf!ZXX6%zWYO$J(84KDiLe6!0ejLUk6whmP}gp72VzP& zrP@n0^Xejj2TTk+AQux#+(4_HdK$!NkD1nA#FaAk7)S}cHJlbWbf6W`fdufwbj{7Q z6kFNA4#aX^4_1~UgdH$m{W3M-lBZf}Dvr6h>}avK0R`iA_Hgb%8@L0Dv%r*<&7#F% zUq7I72R=+kW-1QBZX8Sffw%((|NgiWxE(CB{9LVDveh35*Sd*2fPGl9HJ{y<$<_fL z=+wXi6%mJ;>X3C;(uR~m-~lie2t1Ha))BN#>^KbgIXK;e12MJLx++ReOZP&SV+UI0 zGv-=wH6*S`K~tbS+Qc0YB3@5{xC7h49Vofk@T@L9$j%n*yJ7(#(|4bg_}iop$0ZCS zP^%ZQn^Dg6fI83)>cE~`u}Y~>&vx(wK)F8}q$^F-0UZ0mRv%rbvkps1mM92ZdIk$qVXL4CC(bcVdKHHj2Cu2$9NwU%)UVOc?w5!@_ z=<03)4IFv`zkU4h{@tB>j;Nr4gI(CP)*u5taV3WtZ#gSwHe=8!ZBPbY z=1VeqX&37iDCmG~A4=Eqsy&;`D&D#et9mnex67P;l5 z9_5iT?PaC@I9%XBerW+|wFVbxUwrGeX{C(Q9&{0+B`M%|Kzk}HOOH5Spo8NDl8RJF zN!S~pb!91ydp%X$r+W@sVAS*A(GRPiJ|8Wxg`ovb9GX=MIPgpDN{?Zrj>U_PR92F$ zPqGCd04^5OC|ZilXMyukS(zZ5cBh8lPQD#e0|7q}*dbk1{x7x*araKxI}&+!5e`Ri5pOm4@ehnGaQ-%m zd;4NPq(LEq+;{^F(O1e;#6J5WZW02mCX2bgT26Enq=OEd7vmr8k={;!}@# zNx#6^0`NVoL9y<_IOFNi*ztuL8YZy?;2kQH>s;eemTQ$zi?fFIq_G9yAN+Big*;*l zoc6;dey|1jFZ;n3a8^*8$06zelt)VN9tzm(5GqBBQx1{KZVjOiqqa;Ji7kLwYPv{l zfg$?ZcrrPAx)N%gIYn%NYxqy(y<6uIS5Dt&{z!+~5MhWdKn1Y$lOsy7kP4!<799-) zM(25zEr3^3ZQ@mU{|wjysEd~K#1?=jjOW1?(4J(umZJW}*#a=$aB=DsInv450;mfk zJVbSZpRfb(#m{FtfC~1M1L%=p3!oRb;8)W%Vhh}c6*I&ZAp0%nBC*iHa>#gbRQ4P% zGV4n~x`j}!%=%QwM7^248eeCovm$7w-yIUrc!rL1wg7qu`#inUaQkKmuH|e2SZ+A) z(H_I>_N#0G^aCSmnrcjUoUsMyw}ora<-2y?!~QeA(um&V9liem{Hq_jbq!v&9OQjj2_b^*(4D4AB(?xvuRf&BzZXhq7l+P6 z1`z+%c>9ahi->$i=jk0g;84^h`*h1~hydchqd!p(qE?50ry`=Lh&I$}P;?oNKaYQ) z4>-XV*mw`wPqs9|I@ki}9&OI^)bXfEP&=a711DOp(FY;*du@oZ1z;B0NNj;8UqK%w zQ;<&?oyT{aMnFWqpt1$##wqetq_V`yMGok|zLlj$4e4&^wo*?2Mp8u0jjmrCP-N5X8(`H@{ZdaWP?(1x=r|+o8KuLTYfK(?UoY((gEDGpvVx zhsU9H;9>%dXHO&_QdwE6M>kO)$@u~|3N~Xe_yXOMP1ncx0{l1l?)nwkrW;{=fg7^T zaPKI6$k@kH5u5P}M$SI`-3`9L8T>p6OXv&t7+-+CaO2#qzPioOclYQ$ESwMYEBCwa zmDv~6FV??cU%WYazOQUET={qs&o`a9krd1)C7a=-C)r)F>8_B=@Bn(D2mf7rk?|h* z0#^z)LwB;d9PDeb<&4S~=;;^OS56JfHvItj0yYy$s+_w~vq6s6@I$zt7n<^B{xoI{ ztb#zW&3FUuB8Qw&`2yW}n-P}$ncYS9!ClF2lywAr0WueFK6@MbK!^u0B&y>hp zPV!dYb+6aLyfyc4^A_g|+<<@k!52Wq>h|=q>PJ4~>K?}Vg&T%?c)|VffTkFOI`p z!Kgt^1hw~go4EZZs$X~SB>tT~e&r(%-ebD)j@fgUIgj`Pww8X4FYuh^My1yH0!>XH zO^%9COz`&HbD&(A|gDNPGcq4cc7OBmY>tJ2jkRJ&%mnk2LrKkNrg+ zF!j-ZLM}ipGEWUNzQA*R+G^vX`;0HZKIJ(HzxIGHK#sb1l=+eP0?+WP{v`MUcxS(D z{4MG%SNhz?hpGO+7r26-C&3q>>K*BRj4$vU@6wx;erT9A_ySM+xD{qSgD-%p#NAgG zeunWvT~C8AaBT-3VmP_y8h&VefhXVdT*nh%pa)fc1AGDeG!BC=Kn-`e7nxLd-$3IJ z6aFae8No-+?AXyuKhY#k!4)n2;0rv{`Ia*%rwz*P`jb5>U%+NUvu3f5nZqhzhPSb+cv>9iX7~@(btWVFqco75!^|--T(ui zc*P&{ICCl+iO7M7?#b@5P2WxbAAj8HEAh&{i(j5K1|_>?n?QXLQHG+liA=f=XPYp} zp@~Q~@CAC|qNien=hQHsedYY@#A_6HPu`vy>n_>!_}a65XTku42bOInGX6=gUB7|> zW`ywtZWL|0lb9FkP7MpT*1o&M7dS)KB$C}#8Xp@E`D1=LdJpxvhwvrrRWNJdOvPsC zouVHY!Yk))RBUbcx*1=9#@QzZ=r$Vm`UkMm#wr}fIY znVBzW7&o2#c53n*%+RAG&vsBNIVcR)fsOG6&?=gfg-}n`rt4Pu0%(B!#1}Xt+S*1q zU!cE&j>q@{12r#uOW0NO+wT=Ukc{Mj3D z=dj8b7_PHM*?8O^bD7%Th%bQt)`n04q(C1Mflb2{Hy;0EvHv7>?ki_hzChnFDr}&y zkN5&j^~;(&_yT<`c%;7n4C4zlyhv|sg^~A<_6-Oqe;*B6&0nXcni}Zo8xd`r@AdVa zy#9m5Ipw%Spw6Qh&iDd-ux%4;qeZIbH~cYY|G$wh zu=D7h@Wj2r_dgrNj_aedXtBCI@VtJszZZCc&u?0K|L?&Ipnr7S*!g9>jx}lD@V^-^ z&@;Ar{z_jj=7VgA?h$ZWN4B>*Y-3J;Hf4HrtW)I+VDJWs!S=$*Q8@)=nzWLB^GUwI zp8e=!x-*vroR6S$c8aZKs(mFFA9+jT3k=k4TW_4rMB?#eO@5j$fUek6!;wQ7R~fe0 zZLXDE(ssH*7Z|DAwsiln9*gClq6_pQq~F+c#Y$hMH_P<($>mIX@}oWbRk}cT-M0DU z#dX{YNSu0{E^vn0Wa~)Z$v3WBtyMfiv(>04#9mP9WsQsX1}1 zZj)_w9Oijx%wo1qEJicyj*EwP9e4~a@Xq~caovq83Ess}x$-1hV8`2|YZ152Y?a`g zB8~*TVzrnpPH!ZgSbEUc{Ulmo*TFC5Gr92m1mx7`7gj5UC(r^XUVYD*jLyMGX-u(I zaK8Dc^gR1?AeM=HN3OgHjly@Y+^P$~ zIps}P-A~~Kx<2!y;~t0E(qhfwY#3UN^*>n5qoc55aV3ha-!<>F<@Ug*ADrwt{QAND zd$5`Q`jKNNPxXEI{kYp7OC=)#_vDz_jF;d7R=aDZl)U{EVxaTvcs#XioT5|F!q}Qs zXEDp8e`gsRpPu&yLUj3!9X-KqT&8{!UG*=_PT4J^fEHNC#&BZAW^?*71=p#kC<8lB z-f0VFVqPcQ@?PgNumYV2EvAF;1+@X+qOVz2VUq$|Ua(DhLy1&q z?9$<969u}u&wn!!jA!Ct5==Xx;BS^j1+#1s@beY8-7z)qUyG+>e#`Z@c0WNB_@zb^ z*!T9Qx9oTiT^5gqR|4#uyFB-E+E85#tgJC<#&y5zyU*U)-}!u^z>co&WAA=^W$?Sv zaVMRbn{nY#<>+@`e-16t{X2GnC~)ifM1glyqQIMPzw`e8PZaobkprIhod3@d1-kwS zQJ{?z1xVgYfP!=$=ffW73Tz^-z&hk+NaIYBWn8*uANqd~Fks?<0lBV6p-5e{B-S7? z{BHsc3;;CnhrzF|UHOba15CM}g9i3>G0;HQ)1U#dU-^?j0|%c48t6In+5rL$Y?hYy zOeuA)mP!hM&?{tCF?*V61FtdKz?(!Hc=x^cH)sQwG}^#>z3*($20Dl~P)d;KQC`NG zx8G`#IFN)Q0jxqc6<>P_HXx9~Fys=^3V<8<`Z>6PHjW#p;N%)Uh7)o^jdT`KbSb-m z9B3ot05urs<3J-*fjso?wU}afa}hUs9)k`PT=JwiCAn~(WCr&b=6*vV)erH!a4c6A z%1zXP8rK5BxtwTh3xtu#x_X z_()Z(7;8=R0RhkeXg)&1oGL^IMOtM`N}~^8@d;Xk5CPB#1nnRY1e3U|1*IcE*!@*v z5Nw4$6Lb;iR4>Fmvtq6l`9`?`A!wB=U16VVx{ibN@*ED5LoEDnJW#iV9{LiKBlG(s zf(9YTq;UG1NgL(2LR_0`0ZWwzgg~l_9kK=?fVQbnM(e>jOIU_FgQN-sVejFtwMlaC zFV(VjC^mArKdIbORg~>b41yiKvt%H*k7Ed0T|F}0RAkn9D}*7~e0rir0);Rw2kk&o zpJ|0epavo^-us|1H7zjPaBTv%kr4VOZd(9%ucYA1%b5m;Af8kOxwdSm9B*(4pam!z z1rY{d)#CGS6l(htx||5>xbCO~!5Cwi!w5`(5#%a3vV{{-O?rPioFbmsfA~%qf?sW7 zdh|q>1Bc;YWiyN*Mp{)sc`vSH2u83OFoG;p&ZtkYF0T+tqO8FPjM1It85pTFDp2wK z26zu%epPJh#6H>&ZtU{o1nJT#3F!bf7?zB4CT(e3{VQIJO}~eAS6$wSK87Km%f{|&3f>b0O z(AGju(pUt>;;V((Y1{^baas*BP6lh74dX~+Xht#2DD0G@Kg(eO`Ee5%8oKS4z7E;7DXc&Tajv>Iwj*uAneJ%jk)stWgmbh5a%9u6*%0Hc8j#@ckNJYrv$Jz#=>lUfcw?Ubi314|OdpaBo;2n`=e<;x zG#~-gV(~v11vDVRM@+rm@`0@Ug>+~cBq>Fh|M)2&0V)jA2{`3VNAOK+8BQc2~6U_P!Wa0BmCm_*&2)shIKc8WE0@LgXT<~XR)&hE2V-v8H zgkmF#StrPZtg#7R=$%~0EjHN5h5Kc{KG|Rsq^KfcA>}iW&#ZR{4K{%!3oUGzr(kL% zd3)T!GZLIY6bj%AJq{Hd5+oiFVupejes;d;0ns6)Tm;4c%I;02Hgo62fff@#W1J!o3a zax#GlWP%j8Z(GAYbjey1nEz8E0?;NpwsR?e67@_aO&IDJp;&8Pt>U?aUTElv`opcRk;x@9dd zlS(!u)R&75MnO>%24!83XE~)NMgd?);)_&oM9d(|pynj+2BpCG{&?OGrBPu?@hkLL zjCT2D0u`75DnKX10D_VtgO^&60YdtI16PnD`W&~94U##s&;(ooz9!bH7%ARSaRqXv zMKzD4@3-VD8m>UVn2*aqkiK7vg6Il;+a%l-2#6?5JIg9oCE^vBz$=LH%P>l^m0k7A zLP%Y&@(O<8fkqF+&q@6rYRXJ(mu!r#$ttiQCL)qQbRA9lbipXLGiJ?~| zqtJvb$l$Il8OJgkjQWo=n zdh`KgzygrMX0GPe1uG9#XaSqC^7MvRpPbjA1^0JDKU~LO?RFLJN{>h!QnC zcQcBM+Y)$~)Swoi0ukY19!dK*zy%MoUgX|n9$l|M^C?s95xAg^$##Wu&<41GxMf^J zQ^~ex3LINdr)y|(j8hBRh+43YLg4bRe>1gsnyjofxCPA&4N6Wak1jQF3z!ZzDvlZ_ zj3eRY^>C!piBn0ruJTG{X&V)lYL3JK^9^VLOP@i<0W#54uQq`T@(eh^Y-3+xSOz`7 z1(@m~NH%c`^cAk_ugSr`l;q$7rgsJ(S2S>euqZ5TWxbhC!~_BtY=^)q1|FWRG0SNB zYAgy(-~#G)4b5vjmc;17D-cg--~tJ9v+~k*JQ(XKD(*0)kqa_1&3%fE^ys0)$Z{7_B^IcK zGIRk(J~Gl+sW#9Brh2K_NG0)NJSu}-Kx)~L%MKMac0tw4y-m@Dgi#@ZFB7|9JJyNPIPJ0X3El{sfnb3&c6MpzI~F=9j~u zfU$P$G-tCAWVbW257RGmmA;$v;w{W z14z%g2Uy)ij{It|2!Vps&ooIz)a7bCi%KI!#z2l$=}#`*DlgI^5DPhs)PRp+Sg$Et zBxqYURVP*@%B_@Gs^Efuh<8eq#<1a#^-6XJeA&Mq+YfNT2!;T*{<4<$ z=Y<*r7wAKKl&bg&$Rv>QM<-{!9QT9c8{7g3nh$4^wSFjW)fu}W%+}ZZ zOT;eV^~+bRF{6}y8|(t{$1>OjawCef_7ai5P}v2)2XTl}5*pUnY_y48fCP%IOew{- zLcXTL3tm(nzK@v{FB5BWOxj+7xPXsK+rJ2Sfod?8#MmWQDAATN*+M=Bc!3NN9#}~!merC6U_ywBL&_&OKr_A{UM#}GUa(EN#zN8j} z#8biWXY`~R{DLAWnsb{eTc>6G2EU+0Gkvv^8EX*KjO`~uURkFb6Vn|}({A0Z4H!x@XQYXy!l_%#p)3{-(Or}|$- z80=mmW+2)P65RHDuCReH*an0FwQA~VZ2dw)!DO#qAcnzik(dW985 z50!3Oh~s-Wl*2U`1}`rjRuJW2EPE`kU)lRxPyMLZe@NiXI!rY;l8Op!asmSbu%cjG?G947L?_6z3tA1^p&23t6}Qtu=je=KD|MR<6G1_YuON zP9h*GvkHwRT2&DSSTFnq%vzHOVIZL~a7|HCpqihXFRKg#()-8q2rZZKjVO~41H*vG zBC37u*-SClfEcvNryaRPW?vaKm|`_(6khWu*u0v}&P2ulln7*C1jvA9XhNc%G(ikP z*uh8!TdF&CV6{X@dD^h)XhIptP;a2xuBtc#Lu^NUqGnfc4$xpL>;ukV%e`{~4%(?{ zEtx`VtODm5bc5GZVr%LU0OvphgY>%JL$X5!+xD?6fCdp4SF&^#325-!zK40jXRtPh zCWp+6fCe>8Ux)(`kPkDUK~$dK%0y9_#;(&I`TYjafI5>{_$5!6ljTwje&Az}8keO8 z(7?WEr6Y}^Lti4E!Diwatf_M?B7!Io95Ti>fClLbDn^E6QB2`L1MI&9<{|f#wQb9R zX#izbUNI$=X&^IOXpe%;Mw1oyf2k$Vbtq8=1q7GZFArx(4H@l>0u3pM1C4!ZBPv|60--YEZEU7tQR$^0UGOA*7oAqRCw>ivD_H5 zX=19(s0Q#)08@KZjhuXm=56tKjz(^HcF8NKRD&{9oEru~#BVyNQVmRl1DJiIEs!KS zgPDc1pcMl~>k zYLJ5(80|%oNo|yr#y6-2DMtoY&3k(uoKLD&O>0zxS}4R=izMZPn$A&Ep0~ zg=F$u<;2b^AbOmpK@1A;`5IV*GVN-!MXJrrZ1d~o#R!a8W=x;crdS_`(BwjkMM3E)aV z)~E(YGM0?3%@X_c&RI(U9Dr6lZxN!?oM`}~qEhT7j6SMGWRiEjL`;JY061n<32~hK zw&^Sx-Ju540Bk%8Y)Cj^P$-yOJ~DnnBAGiVv#SO{`+s$VX~1lfnN29egcFM3sI9e5 zaUH2Wr-jHdQ#_VuR0G4!FBD`BXn&DyQJ&UPOIltkajJpw{<*jr-K*W2IpjS$w_xK9 zJ1_&N!CzFnk}(S6l>1Yb&1wpEK_#|ERD(894HiflUB>ZiWlU#I=-y*g13jn)a`f-W zEb=1-$^@etL_Lja!kCPDw&&k@Ce^^^LCuks?M#Gk0#%n#4A4&tYbHWaFs6LKs0K$c zDf5VxbK27x|!N9QYx&}3n<;dSP%v)ae#{&#%zz1lSaqyAA6(y)a@6p!| z?A^VSLk%{4G&B~4-hj66oGNSXq-J5Fvwh7B=fk9BHtc((3}!AURHF^c@CU^lKmujL}{7W#pD}0DBP- zk?bHF7v|?@(nK{dT=-!HpC(OUo!PJZfiVsKyDx5$EI#T_n+aj#9uxN?o;9ZY&!Z1& z-)^^rZi8uX53sF-DIWH_UAB(9UwqIFrU5L3aHfKK+(h-r85}7Dms8FP+wmiIg8)7+ zK@EO>VxhE}ki!Hu0IGz~=+LznN*ronEbL5-!(Vks!M9pspMY$Th7P~oU`>4luz~UI zsiYU{y;w$D+)UM+SrbK1A zo7e`w0NbFR|771-Y*%%qVIdG2p%uN@u0d=>!clo;^cSO#tPyYxsQTDJd)5gd?mFGz8dM?#g%OdybFRVW(g};o zHNdhv8d--L!{+K5*Wk-_D~+2qyNpJhX6Ndg~DfGeqllK;1rs> zgEPpcC)WsXV4OOUwlaBQ#nNH}p@Z=aetzk@Iu`L*CdCIf_o~V_D9g@Pwf1Bv*tU=O z?}BeIGe26hD3&%`1bhSg0^Y9JwlJMf;x^3GiEm&6-vCo3syG1xi!}x~z*+du2Q!MS zyfvN1UW_*4EVySQQySo)D>P%TK-FIXO(E55Q3k#Wn}sohHP;2ef#Iv``I)*~nOEjE zu}pEwS$LP@4RW|AB3MO>KEd$@zxfQ%z~*S{o?G!BmKER)%pn^R7}S~7TC=o{B;Eww zAXSA$KO2jIZZN)JeyqA?XX^)4xl~4T~(i5(Ge_8)Q|L;hMR9)Ugh_!PT`#b=dSvYoarCa>Bh~6O&e-6I8l^33LOj z>d3H4#5zFzF}#83W0l00H(=FN#N328m<%`saB5@(_Dz=P=L9&InTMRU(c)Ysz(MQV zlk0T4MPkz8Z4?Xu_X6U;Q0iQFig3Qp{74^pj{y$;@^|-3l!R!O%}!7G0*8dxF9L9I zGc;(sazxy!jaLNp}Av-qXu2|w#$S3X&O)wi>eid?1b>U3wj5586 z2XkBUGrG$y?OBY$M{sOb#u$8VRDg^4u1XaL{iN#xuFi*%o0cknfhLk4pto_qj~d|kp+he zI=Jx2_wRA|clmYY@Z4;}RxWUkNgqH5`Q=ceu7vuVKnL|S%xz7gUSG}Qh~-PQ)Z#a% zcD?NqORLK%Mmk8!{vTy#g$ zgTN&M9ef!1K^iTZH$RG8&_D+Vf3@?_rS||j@VS}|2ajZ-MxcY@iX47fjBII+&e)B*PP?QA>RPs#POsPN(4FpWRX_AKzxYf`x@w= zvp=R(Qy6>2B*Z^+MIs$wn;qvz%eiC>IX1BH;h(IgIqIOoy@2MxCxF7VValD~03DcI zUGvGAIZ=hTDAO39CZ_Wm>L9qlmais32qn}(>uGyr3N1pOQYL|N8xM^Ebzr!6HaaR> zD%3F^hAwHSgFt|2SDF)~QGJY~4osii2tFJgt(pa>i7!1;Q3rpO>`aV3>4h9a9bhY( zEjLSvms6Du(!o0(MaA3~tf@Z7`W6+`)^XuIlVG?Q2jxoE*<{-oZNw zRDZ>67+ElDw1emZE!k1c<9ekuVt5qYtI`e@Cr1Qx8AeBO%OA@VqVo5vU1^>avk47h zu@*crFK7oMm>q19kgpOZ^PnBP#c2oKW)sVa5k&zT{qNI2_&q)Uc_mS#!9dw5naSpbB z{)d7~6%KbzO&2)lpf@oJl7Y@l8vmn?&<5wgMS+j(t&bRfh`a&LL7VK}o3P+|X&u*N z6-#TpXM=Tsr=ZW;_#6&;_zT|U0{t!0i$d@@{Zb0>lKACa7eeCV2c5Sn(1FIt zE4jdVr&1H5^Eqgfb;Ijx4d&;Pd=8*))9c)_MSFmw|t1x)!>x&o{<)QOY z%y^2{Hlh`2tb?H-8A}09G+&K3^za6zb`K*H>Pu`&t)$bq+beU4^b_NcM;eMz=rRU>sBy z=BVChr*fa)BF4d(ACp-bC=!VKTSgbGoN>^4=3dZ@8kI+Ck6K3_IhGobgX@t|MNYe2yji@}`Q*Pt6DtfQkNBb7(;i0Oy$dkwn5SIKe9 zSP@H6CbQ4cpc{M`rD?l5WRaoZIbh44(G6`*H!u?3U|m`ge5S=nunBIES-?Wk zGJ_kuboI-mgN;y(TgPU1ZC1;u+o8e@0QK0n;DW8yN5Y7~y1HM58=Oh5O_k6JjF$Ky zha2pR*eNgiCE6|;FRN2*zWG+F2N~QTfpve9=C zn}h$Q(;x-lfz~%5Yx zKHT?i2nV9r>1h!+1PyW%-9VttAu?Kt>LTkLU?HOa))~2CD?f@K%_>cV0~xpYjJ0OQ zK{Y69j05ZlbBw)-Z)UZEAHN>+o*;8g;>FiGckUE+NjvMi6peN8Gg(P|zIQ)o9i08} z!}s1gc4&WB=bpnF>!7o~OYAH+(GD^RAyr{S=#D}&?tnN19nZoY6!=aKb~2+a5hc>H zF0GYSVucdjLPsUyDLMD201ql%y3Q`Cvt?J?E>IQzT+9P8iGv1Ples^Id5}e*Qny%I zFvtKzu~rAXVLRLI#>kXNiT~HJ2g8qJ4=QX69owN|vMrHSY8-p8m0=Gmat40G4h60m zMdfG_%YSG@@fRo^NG2iq{yg%*(eEEVymR$2@_}5&5mI6VB=UGsMiw~vU@IpdU|_{r z3-+Q|0lB7zcu1y-Pr?uOWxR89%c&;#!RymNtgW-cwV->~lkJJLBt8j05OWDBR=|@L zjA|V~COwyZ@M!+-5BGwfJfD5=3S%FfJTxokajKS1T+uK}T!W58T9n70!9J+xlX`56 zfSrovkIm_9NhI{a(LWh|FfRplXF2*{edOT}Q}ZhNpnq`CrJHBy12g*w1kYT@@Y^uZ z2QLGCaAZy*qySw?W4RpGrX_Na_!#@(z$ar70V>`&S6Q#>>ewb|uP2+q2ZMvd!K)m6 zaCXoq1&!vx2Ka!=Ft36Su8KjOgMknFR_;F>jj7;+`*M(%@{|i@b1?9M1HYO3HSmFu z!XagLnu`^a7WUfG!c*9T3pan5;CFgB_Ta51>;aj5m17Ugm7s1=#UAi?-@^!}JLeFB zx?YYwm>+-eaQ$tLJ!ll~fDh$A%diK%_{{}bv{xARKuG%i{P;UkVzxwwc#~>RqKLD9 z0{4Iyjd2fLWhy1-9%w})?!no5P(tWJKJ<#5-yE|A8>U|pbpy~bB@7IFQ;T~Lluy*EO!9Bo3 zTjn+H!7*5MmT?d8+f&?wdUVmZFfc&egTsGVrEA6d@tdFj`MC!$zXkeDD)#_Quw@Y3 zgF(mre~Ek0u;owV9-z_r(9#Dv_u%S%DX2FOa_#~BvB^Bxf0Vcfy@OKFaKE2(4^TMc zAjBJYNWnG~s4_4(hzd5$qk|Fm07XEfJ?p^%ebz=CjC*ju9&9^C+ynGIDY(Tq*bDA~ zr?&EO)BNCpQ~h|W z!H0if+=H{jDDH57Kj$7a-oUsA$EwsS8TTN#+1%g6J)quA+=E^z*b4jZA00%G*E0twaFt9q-9LNo;NUz;V8%N+_W%yl9Ymqf?umQQ>#7A!z2F}3 zUx<5v_S@<>b{~*|CWji~P-^nJe#Sj$@}=c!EoeN(xCcQKmE@GGigGgU0sF!wIiY*h zUkz@WKgPKS{XPVhvy6Li)>jW2ePTYg-N)LXNj# zx#6rwdknMNr*aR_jE$&isxjR$#yz0l=C4An_v%>>`_J@;34fqyaP-w3JNog{&>MQ% z6Zp@^@Xsg)9?2Zih~DHKz3%}0s~@~|6<#(UhIW;~qTr*A%%F$Fa~g@W|nt&+@zx zA^bYIhy8?u=Nb2a+&+I44u|v6BXwtYpcItQsoVoRnZ7~pFdjSZyMiaQ9kVTXJzp{I z0U3Y)cfoyRn~%5$s^h7&E%z}p<0rBs&GFzKz~gveid6*MMn!Kq#uO%l#64i|;UzU3 zOOhcx&vKm`M4+NjM^7N`0pbSL40*A&pK%Z73^n-+7-X1Nxd)FwoBNx%2PiYR2l%3{ zU*#T9t&z?pT)^5UxCfLXK^a*6jRe;5VwHP99msL+d2VJ#p!HFk=59WR=Neq6s0p;N z0v@G4NJB7f?ciN1AvL&AuMkuQ!9B1V!og4QIJ6GN zJ>X9yA5vLat4B9cAIZ4~Lj|kx6yqLPbr)3b0sRKwUB8UOBM%w(U`Vza?hyCDYP`Tw z5v%bsM$QZP8v?eL5AgE@ETJ#lVcY}y!qB-}7wT5Sg}X=Z$X3&r{oo$lDYGxAU#x$@ zzW9gnvlq%%!(~$Px0*f}iq%F>NLIrM;vQIam&s*#0KL$I|E|5rcn92r%LOZO51Pus zz9w09A86czPX+dsQ{Tu|{g>b#SWPIYa&D+*)eY@2JXraZ7n<^B{xoI{tU3o9j6;lj zK#xN@PfFT(s}YuvC;p7?BKzPja1X4;hu|KNxp?!@JEdlKF+Uqle1GYK61?@1gS>U& zn%m92McjjbgSR;MUcV!DEjn z?g6z2+%P6#au*qc`Xi%sAAE^7f2wj1E}%6M_kdeN+=Gor{;_s<>YE(vd1So)VS{_{ z*k9xU(*+t($OWiH=BaNO_u#ocZM8OW57?(XC*W7&9+0E%9A$na?!hzssy_kl0p9tk z)%Mo^+1-~wRatd^pYuF-;L3ObaTZ0Kb40VuN)xBd27R&F28-$~OO3o*mYSg?4w(s& z(I9DomT!q>;=p)uxTpxCfLBJD=Xtt3-*2Bwgi5Xd_kHWX{@?nROYU@@-yY6Bd+&43 z^PEkCB`i4g<4Ed1)IA8pt3T=!YGDQMk1Wg^o24tDCw9 z=t`=4K*kvff?et!?0*}mvcKPtc=@yL!R>VZR`J%l2e5om_rR!%MBM{2+{i$xdk`Ga z`9X~j^?uP1dFR`22huBiOdwRjLQ(giTjk@d8zVP{BkAz}v+jXW4RaR0PKYBqAbK@v zfnd5f?6mht-s4pFK=eS+<*?v7kUw1=L7YYhqwYaqu(j^N-{>864~#rq)IA6$=iXKA zBnNpT9*v>HgGJqgoyIVr^7Y~9dg_jA{w+owR6}(S4h2))1EKN@@o?@80?H8ZHWL4& zaiLTZiAaIgx(7y4_kcbe4z9O$b`;)p7lTmuz}VUmz{pFhNu-ldwi;0mCITCK`(hwe zbcc_)78nWau-%u=e?WfMKhl)&e!Wq`W!(oLH3AR-8;oia{&ubX6ovp3y&ALf-G}Oo z++Wl^h-@`#f<@hfod|fM?g7QePLO}n%ZB6VPix%+=$FE9#Lh;e9C(pl5W*XGA8Ise zk6Y^=P@IJ^b!AFRVegx8+yF#T0zSAShIOrb0PRrSgKoplwFHD6P1qL~FNRSVSNk6} zo!mGo(6lSe^0GrT4H35OuUmSuuBRlFIM79W{?1cL#m353as(XO( z)=~E$7>R%`lKckh9(4JT@r^$X?y#L5bq|6g(P81i!BqEvtP-pfEn)7cdl1Y3DTVG7 zbq_kVNEEGg4}!y6!GACXt*)1osiN*daCDo|_IPlx|NaxPXOj}Yqq+y{5#)61kI?O) zU-|`83J@A>t$WaocY{)`bq|8!lC_b+fw$4IvKg@+{K%2P9d!@DL)^dtY*br04hWbY0O4#a#=gy?lR_&fo2mS~JW zn^94!j_#~`fZ)v#yBz%E+DeK_ip$z70&cH+@U8)4jPKmrhC9eCxSd}zCYWrps)}Md z>mG#TJoQ6gl;6Zt<&EvXziVv6xlM4U&VqjbnGtU10-&~{9u+jMXmds$M*yQ?}&9~f=@L-XdmtJGoc^8b9?oJg4+C4R4cf8HLJd%YxM*BrVHDa1;pg$r6k0NJAZ0%Kdft9Y)tIg zEBR%`87G3*+)@2t^$)4#6}gwsn{c<$m7IoKsvp=@MsHfS{ao?QWN-sbHQ?6g-UMg7 zka4rD@M?6}roSnE5b&Sm!it+|=MvB2NtlZ%`Avo2t@s{~Ympg!rZ|*EeY`yAa%ujh z_?TFnf8U%?9{(`mCgS}2lG4I!@jnM`T=Vun)jlww_Q6-jE@YRMWT%`%VFGdgVj3Ri zyrcHPif_`&3a=!_#Im@Y_$iCrVC&NLMWF#>T6SHZ7qSL`}lRB~Nq zii?Sj%fm7J_klokbZq>Y3zyR}v+&p-ZNJlv8uZLA9{9=5NWEk-#zse@J)QlJx&>#` z%WJx=dT`9fTy`_<3=|Vr5?>pq#J0z@N4LbV*jBtMF-mM(9F;=QC8iZsq42?`+X^4N z=NFU+3ragn05$PRaY{^&*t6*+WvSnEEq&0lHUIe56>CDzy}idAH>ccAw5DDa}bUB|zku*pxUuu8591mzG;vkhJ%M?#dq+R;>Ra-dt36 z)0}c%Ton@=n+M4tO|)Z7f+;P#s3a@l+Yh_1f3RZB?!%@Vg=K|#<||Y>A~wbn4P8JV zmS|V-ooKq8nO9g^kQujs^UB-mA58tT{=s_zU;mnTHM@wOm`C}8%&X$r8#*5WH~(ec z$Q5@>e9Ur*)YDZ;}_ZCUq^8AYK|f|{&>I2`t9dT z=DG!c)G1kts&@Ne&VLe(zhDZNM(=B@#bbW*l|>pUTztKo$&zkqPBk9=Q#A+nl=uOB z9mhPm+mkQ7@Z3|29-BYMd&Yy)rcRkOaok-ahYcCjzmJ=%v);*}hgQYwK+5d_@A}!z zv!xk&UdtqD#6vB!J!j3F{=l@UlZWdWXPn!+_37KM|A2w+g9dvH89HqEh>@d4-!*1z z)i^By4%Bnr2qs*%wO1(_ihOvO1Y9>w&;ITnp2J7pHEzO0uSt{do^tnuQGFy{0x7u1 z%*NTapmG1yDU&CT8QM#In8h;oN~1CmM{bLQPRmP+ZsulP&$ya$$&_&7xA1R+Hod;U zOW(q{`j=XzNs;#1f(Rc~)`O)J)j=OpTNPLjS73RmT{-kRf_6G#_Zx#6rN_+0`cBfCj5{ZlC~OP2;YWapW{aDyDcY8hArj}B zj|q~uKUD`}@8+unWa z-~awN>}*56B4^zz@g~N{m4fHRrHp-0sz_xMV6dkdpIHy=5+96}dn<9u1=xKW8rA(? z2gG*9UIe!nd+|14d&U;|MN!v0DNFK(Mg^y4gYSCAHNW7%&eT4P=?;VMmq`Y+sU^(6)9 ziaubPJrCf0K8i#H8Va1r`+?;cm-qsE>Waa9l)AHDL6)D2xp60n{m>N6z>FE z<>RZNn5+GukF}`^xA;IET)nnfk-qE=+o=Mw-rs`5B`ixNj=?enkE`-*_ev5K*nS<@ z@^_aNRftBi`KcL4^sr~@8N)$lxT6rPp9jas>;%UP8cGy-m!rfgKt;E)P~nB+!0*8P zGKIYgOwU4KuIRwzUtU(!&2t!=Qq=-bDPB)K?GOuo)B6K>b}PnGYkehBpt8ya9Dcx? z=MwjWuj0A=gDw(dWGN%~(tU^&;3fX(S0N(eY zmdo2(lp2LSi-9nwr9okSpd{_W0h5-@<6jw`T`;VZIA6?NTY#)js!f~b_B zClzbMA>s9bpxf`dMbWgL4VcqkM*~w10bJevki@$Y&$qYwa8SoMonBj{NM~JO$=p33 zqidH`L$pCLgj;1?U!kx-GMT%gN)`4#I(sFaF@Tg%{(U$vjIFjX_H?@<7kxd)85d8k z0;N4_0NNgbXc0Q}9tf!d3vmtT-&F}Rxr5R2VGGC{l&xgmCo*Jm>cd*bdL^}i zj%3t}?pN)BWH$y`nELhROYeq0b!uUSaC3mp>!8~L)w@;wnV`l)vD(i8(skH4aD{X^%&BKE-(<%$O8ge z^?i||{tOXLeE^2^29U>96)5~!EASf~z;2fToTLY^ghkK_MNV{b!-jvyQYayWjx-chBDcxQpmoG{IzEhP{UQC?_Taeom_`C*#b{Q zKJJzTT%6+F!K;r2A1#YuIg1fl7B;b)jJ;H(sFpJ}tp$)dgYeUH`3jG<6NoQZ5g9s; z?~xIAp35O+LTY_H82sH1PKSL2vFj%j7N3Mi7UUg_EzE~ghDuc51M8ZbzLY!Kq4s=csD%-UeC+G`%%S~0Vc{8${3J^cg4d6;Ijk> zBJ-On73q5|xw%JL@pG;)(B7B8V7QI&ipPL>rKdoYe*og?9&9rjHco40?D0G>bFTn= ziU7$6^@;PG%n^-<$et=7Hk?;^GZ>q;t+sRKz zU*sxmfxui$nB+bk_f#r!?sOS}Q(_O+L)p1QpvQsm^U@wQG9B)g0@zcw0`^J3W(~B# zejLxlaRA&r0I+UX;BLucUKh}dtkB&3TOi+i|Bg zBVazQ1z|MbLw^}ro#|hV@EI=xc@~Z;^5z#dux?BZb_`M^Hqb^>f4?SXg^fYi+NoCT!5qSOse=1~m! ztxofPZUy>R{Wwy68OFU8=pPa1(x*VbIUHkr7|vnke^@zpyA1S-Q4{Nd9wEH~msEcb zV@~IQzGGr7&?A{vpg&RpdI@c$?xnU;HG_X2MqK8QzQ^KVI{qPLFEp+?)Xi;U5UOg% z%)tYTyO1|l;!$SKreZE6w=Wo&18fs>64>)H@#x5bu@bTy!1DJ2Ay`%g0XEYeX`FyP z;~*5G{R6O-qh12+TE=&Pqw53M2l!;}?`Q&Q78__q#dIm>8GFtv89Jl?HDC#5@2w$E z2>8jEZ2skjbX9VD* z0L=CffZQK|>2AcN?Qa+qXIyB`F(3<$YL=DBZvmM+_zaoqIO^0QaE6CoR7Y))kppt2 zfP6edk^Cj75`!Db3(s(aNj-|=vDh<6I{Kso??tO34+76P(hR&j58$c3&9mlgvvABd z3lv~aWGK91a>ZX*#qjf|z};y_SS@!t2ebfzru`jgKTpJLfv32l7Z+IIm>cc^?s$~S z;6JL4kmb{utwa0>*TI5183gFFc(jPOJ&t@&a|A*3u(p{-t8FYmcg$!7Xsj(jT`vIi zoD)C?z({$FtpN3bl&4DYr)^QE)R}IjP^9ZQuzJLfLva2zV6P$M0k$_nHedE6qQcJ_ zSjSp`1|s9(PDud0+DCxGaq*yFuzH~{ul|$OOt%uoUWWxW&#h$aJs{S33B-{oWF%Q; z;qVR~LKe5XDBJJY`bwGWz2-YM( zXCkYUiihoh*V_Q!uRRFN>-~T!eFMyvX#(>ZVD47!Dp&N?_d|I@M+|lErgSKbkX5FX_(xU>Th%h^kH3MwtOB#jmpoau&%9{&&mR8J{m zY!jYqto-a3sTV8wvQu1iw|lBa*9jaW=XHcN`T@ zwm(^~paA`DD||1&lSh|=RT$gM8@qQcKiuPXwp!ues9K4{h%%74;yMz~So69`h*cA+ zU_rmzpjRGhtHS2$Px4VRZ;V3KF64;;Ws3ZV^IUikP>Is4gDqX}4c$wdAw>E3Ql{$> zq9~{4+pq_kL8WXAQDINR!Ea^LTR^06D2Qk=K-qiH*Z3-;5o0H4Aj?rh66To;j@Rgd z1dRl{4WMzOA86c#v#t0xxs=&RPOtpS39BL-poWiOmB^qp;Si)@Dq9RgC4b6%kYYC8 z3mOA*iAH)KL1QUs1krNJY6wz!zvqoc66Cz&Cm@nN0R1a}4kE>)iWyc(n1*sc&@c}a zG{#nd#t|K(!9alkfgO!av|i+ViHMX97erpgT<%Nu!ZOw$wlBxJy@>TaP)T;)3@zpk z=DlJz(91s#*qmI_6i?|$#~lgmbH8v!STDjJR6;cTEGT~T(j zk1tl>Lp2hIlfyk|i09A8;^xhYO=xRX}GcKF&?Bf;X6Sf#n0jW#_?BBeB0(y#cNVOAW z3x_PnV-q=h=DT2IYy{Dw(dAfRz1#nKn<8K9H4|yPs@+%SG>4R250ohCA8a@qggl>Z z#3Tuxn}?}Db0g8@q5O9;_|+h~*Dg*`Qf+OIl`6U&Hj>9%2X4?K^@{W*`vP>!M!t=+ zZraa(I7tT=`zp?5kwWdITBgxB51s$v$yz)(5hP)LCYL@WaX4+sAsAz;m?GR%B<}1z zBo)rc!`Msc-xY%RXlMt%Gwzib z+<+uG?SLOyB_Vh}iS?M*>o76G{IzTp*myy(VeTu~z@X3_(~kS4(HLw@ z);JEEJxx;og1|QOxmrb=73^&*k6C{$MUgXm535GDXP(DZ@RpdS&>F`fC)gQ#AGBUZ z;P00K$8bysVowNSbzXv4Ai5#Zp`BK-VLLgX7U>LX2sw7Apjn@XQM<#YC2DDZ-v8AY zOB(V^S+yE7#%kH%!Vt2t;5+Uxh^5hz3zxnIwI#Kn3U9g!rZuyz8Y_kD@!x3?kcWU+ zs#_~AVz0x2Z`2^U2PKz_p!DXb>PkhMzG;%i;gO$et|_X8nC$N>RAeRQ2`8*wJHMKP z9KL!sjaBXt4>~U*VHj`?_fj@a1*Ll$1f{itk{WBkJZCV?*zA9X_h?!y<1&!ye*>hp zxm+q&wAB$$IBTbD&&yOanf>5n-RWpQ91t95nAYDGX3HemZoq@9@vYpnR7KN}k)@!z zyasL=L``}Soz_G|`C*%5B%f^zsMb%$A}b$x1B2}5R0%MkI*C%0({`VfD4KK22FOGG zE}5}Z0EJ1?xNF5YoWi#0#;Ne&ojdnL#ALNV=9afK61x0ZERP02cHU!K9egll*^l9@ zV^Ay`BPb5d!&>XhSoP*l)Wert8Ybw`+)u8VG`6Bx(PXR}DffCgKHHi-U~O`mxr7#& z+g93OIRpmw6OfPUXmh~nbGV`Q1+;)sh2h3G@;@LITY<1}kmh|dSHFo2LO#+{qO@9f z2*$Eg`(B}`hy5WIpod}ZCO6FEL`$++gGchd*lK;KnMk?+P)_?G>9b@K zjITmiSg*E@gE7Chz$i(sUKcAtiPw1_2O%zPtW;Xs`6+!9Q%S11ag>=Jl`#La{{vlp z%ufGBo}!6<-dX!#SRFVz?}!Z-?yv^KArn835o^8owICk8iNq0Wz^e+;IR!&7n?~N> zs<2R^qLx3P5{9iQmQ-veT$YnB?{jTreK>P{@z<>4>gF~SA!%-ItSK+by>ao+*30xgtmpnQ9ojz$l>_H1yKT%54>*i+kQ*u-hmr$6|>1NYzSHG1fP-Y&NAN9YaNsn}KPB;y00 z@Jp^@bMCcXlAXQ1gG0MxyHmTq-Pz(I*>OzOv47TYb4`tMLy@EIqg4TJ<6Pq^yV#NQ zRoTov8t>Tv0hpajt!ulB*2US;4vV5->J%>3j(XYeJ>U7Z`~v2X$aL+WP0Ga$<8Sr7 zPBK6Ed##eKs8U~d=G;V{(#C=FT(R;b@p*ZOOzoSc3(QPc_F0vUD^phv6rUWP#b!aS zqRLv`-?}Y$3iHGq7@_4Ckjf;chkl%!3wv7a!Eey@J(n6AaqzY3yx$Nmwiq!X^fOx& z7L>)<8r-qfZfTjH%w!*f!Nkpe$Y^HZ`AHUpKpKP<>L7O{{DpW8z{;*PDxe5LWN#cHU1w^|m}LjdICBR}|5^K99;wY{ zOpk`Xf>-3CK@NFX{a`+A3NxRerC(o+o2VQn&9^A+Aa-pizsy+3pTtbKHVVY>R0oTI zbCE}HDFm^+&7-AE5F6mVa&HnZYpF$;s?9wUzV;D!wV5#wqKH7W6fV>t=!JCBi^5#O zD-ZrXl;~NCy`|(X^zcYATL|atg;x_ik$l%S60T_LI8{3A(b;wQ^rv560LOPiGXpks^tU00V0%)J+|d^rLti=|-uOaRrCnnwU!vh&Fbf{ygB%TS zR6!2nRU0y%F$aSI?Ig1S>${|GXpGFr1Dq~I;xHby#hHvoCRkm?o_!@?sQJu8nCM9k zhA3PZWbhU5VIz{sfMs~N6c2*|#;P_O9GFiCzOV3y*W=#ALlAf%xDJ|F)b@ZeL@mSw z3ks7$h(8`N1K;C~h8P7Ih!kb;g0+y8K@hD23WR+LNgd+N^ah-g&Lez^kZCeKGCY4c zrllsRGzbo4sR;)LnHQ)hh9C|^kzg8ovM50iwUC~8Y z#R?fuBO(Gnd4UZB^D|@D+lz%@@x`054g}H!NWoeGS3<%WfK!2?;Ey#rFZwGlkrrVQ zNXFh@r&Q3S0R{-!sZ%?I@`V)RVJ3rqgLgBgt?tbdt5up{nZ8$`RXjeJTEYmt4iXbX-^oUOS;#PrA?%~p2N`2xyU zFblvAW+AfGTCE1caFPWN@WSS{=j3C6^(OMZH2-83f>9b(6(kt*pdP_ywYT`AN7nCk zi)}z-*p2>cyyHqj7v=0yQvoa0&# z7GnJ?q60i9aZjd&lTIiUNnVBs7>kF{L{&C2*RgYP0q`M;0iuA-5Eeif?)2Woe4rp| zZG~1qkm3eRAJz%M(3I;9Lb(W2s-Ta5tx-^MuY{%{)@yyy!ea&iLYN;e_7QUW)(9=r zC=Y?_6|We$Kx2AbNWB?#r)EwGuw$!89_mf$#AH`# zF#I~D3HeJJQn^){Dkkauao7}E(I|z3A$NejgEKZ$Sfh)q(oo3ilm^Rk9!TBA07mcs zpGpH6(2tNtPtrs&^Iy_1Ur00ee@_~$8+rx7O9faxJq%^xe?<~QrJ|691$09GYp)^W|Fp8M{StttK^-GV zbPVXgO)#(|GDN6_f^q;H=qpK0w5U}=;}xA_y|Vk>!FCS93C^8iOW`0q3=Uo1{^cN` zDPrB^-mPp{@`Y#e_G+^J>J9O{tY%6|7*EdqFCjtcP?myPjSBb2dWg!$fC$l@yfl<3 zylap~Bbs;WlY4`VI)Ks^hh`+%mPv_Y z-AaiNMWLxHG&Xi9wL&7V$Pg2GlF9@XO@>oa9(@g6>}9>CdjZJx(LjUGS3Hn#;6L|3 z6eH#+PTwkqhY*9@3p@%j;s-Gh{NerCEw)LXzyv9L?vz3{qdgKAFxgcM>WB)65k8Xy&dp8;tcp#1>pC-U=7C6Y)pgh-el(I|qu5?#YR zy0~*@HOQc3FmR_V%nU7Ha@N%z370ZnnykQ)57sPW7St&e*@CpxL>+}`O{Y|V!z{oLnIGjOovp#D zd(dTtKW}%3i(qDWx*5>>Ef-i5Y)maYux&wb=oPCG@wJy|IdLhjqDhMi$>N_^cPk-x z7qcn&7__IUKbG;VGbNM3tLyteXGJ#10nJkJn+I0UyhTnDW$>`T2}2hY*Gtg*K~M}<_aKO16>mEcVWJ)67Dj=5 z6bwZ$U&=PHaO_FU-dkZ-)Jo;Cm6PoEA#KBcQ2B?wIM%u8ZuK9Tte&_fD+_C$s+!a9 zPj&hU!v^;jMBXc7C6Zd~V_ce$1=CPB7&p%9D<4F}tX5Rl-@tBIvuN=HP_u9wuG*5m zcj;KW|G;nIM%?Oco^<;(L4<*&Y}`7ju8jV8&Oq%EtgkPs!#2h*_o=XWMJ@Kyl$K;` zX)eZ%Z5qpsU)RnZWOIV4Y{tBE0!3q`m_@cVqUjzc>+b#}m5v9}GwcQv=9f(F^W?#b3M~F;i_d)X&a5GJJc+4$3|YA2Y%Tm$^0HnPqG1qI zX(y~r#O7fhZi+65`Rd(;6Z_jr*RZS7d-9U)Q8y88&cD&OOf=rbR89|WN@}aaN}z3> zIXZOB67TVYoU~FQ)2VFxj-C5@z@fAT1n{_*u)j@we8yBR-hs*OjaYgfVyVqe`u*$8 ztKWEf-n5CMhkFhh(ATZ^0FU8!O`PKWrjASqw`fE)WI zx0xGaYn1(p%5uqnN{<}z{UCLZqd~abI-H-+AkL0u;SJVZ+8}4)A=^Z~cGmXulSu4LcRmLjnlITyL7^=I{@l!ps zk@a^iToaa9)Rv@ZYOfsp;L#Cw$sNB|F`eY(Idkcz{fRks>55H#Zv6M}`*`(ICv`L^ zVfM1az{&HLeiZzhF*UccrChOZZz{ch;Y8Txe?KzW-CjD=(K43}(%SbNJoet%3zxj% ow|2e%r`vaK-{QYvt=}8ZJwEg9k^P-?a!g0t|EXs*{yXUYF9W_AZU6uP literal 0 HcmV?d00001 diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/img/ryzomtop.png b/code/ryzom/tools/server/ryzom_ams/www/html/img/ryzomtop.png new file mode 100755 index 0000000000000000000000000000000000000000..bbed52f467246ae6b3159d8d2a01b039fa1c6edd GIT binary patch literal 52089 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 literal 0 HcmV?d00001 diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/index_old.php b/code/ryzom/tools/server/ryzom_ams/www/html/index_old.php index 9556f50c7..b8be452dd 100644 --- a/code/ryzom/tools/server/ryzom_ams/www/html/index_old.php +++ b/code/ryzom/tools/server/ryzom_ams/www/html/index_old.php @@ -16,5 +16,7 @@ $page = 'home'; if ( isset( $_GET["page"] ) ){ $page = $_GET["page"]; } +//temporary set permission to 1 which = admin mode +$return = array('permission' => 1); -helpers :: loadTemplate( 'register' , $return ); +helpers :: loadTemplate( 'home' , $return ); diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/js/charisma.js b/code/ryzom/tools/server/ryzom_ams/www/html/js/charisma.js index 579174176..6445ef69a 100644 --- a/code/ryzom/tools/server/ryzom_ams/www/html/js/charisma.js +++ b/code/ryzom/tools/server/ryzom_ams/www/html/js/charisma.js @@ -1,7 +1,7 @@ $(document).ready(function(){ //themes, change CSS with JS //default theme(CSS) is cerulean, change it if needed - var current_theme = $.cookie('current_theme')==null ? 'cerulean' :$.cookie('current_theme'); + var current_theme = $.cookie('current_theme')==null ? 'spacelab' :$.cookie('current_theme'); switch_theme(current_theme); $('#themes a[data-value="'+current_theme+'"]').find('i').addClass('icon-ok'); diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/login.php b/code/ryzom/tools/server/ryzom_ams/www/html/login.php index 63d46f3c8..d0f7f825c 100644 --- a/code/ryzom/tools/server/ryzom_ams/www/html/login.php +++ b/code/ryzom/tools/server/ryzom_ams/www/html/login.php @@ -4,7 +4,7 @@ include('header.php'); ?>

@@ -16,12 +16,12 @@ include('header.php'); ?>
- +
- +
@@ -35,6 +35,10 @@ include('header.php'); ?>

+
diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/templates/home.tpl b/code/ryzom/tools/server/ryzom_ams/www/html/templates/home.tpl new file mode 100644 index 000000000..357d05932 --- /dev/null +++ b/code/ryzom/tools/server/ryzom_ams/www/html/templates/home.tpl @@ -0,0 +1,19 @@ +{block name=content} +
+
+
+

Ryzom Account Management System

+
+ + +
+
+
+

Ryzom AMS

+

Welcome to the Ryzom Account Management System!

+
+
+
+
+{/block} + diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout.tpl b/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout.tpl new file mode 100644 index 000000000..0c1c3655b --- /dev/null +++ b/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout.tpl @@ -0,0 +1,234 @@ + + + + + + Ryzom Account Management System + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+ + + {block name=content}{/block} + +
+ +
+ +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout_admin.tpl b/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout_admin.tpl new file mode 100644 index 000000000..73cddd510 --- /dev/null +++ b/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout_admin.tpl @@ -0,0 +1,15 @@ +{extends file="layout.tpl"} +{block name=menu} + +
  • Dashboard
  • +
  • Settings
  • +
  • Logout
  • + +
  • UserList
  • +
  • BanList
  • + +
  • General Queue
  • +
  • Personal Queue
  • +
  • Ticket Archive
  • +{/block} + diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout_user.tpl b/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout_user.tpl new file mode 100644 index 000000000..81d2c7cc6 --- /dev/null +++ b/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout_user.tpl @@ -0,0 +1,11 @@ +{extends file="layout.tpl"} +{block name=menu} + +
  • Dashboard
  • +
  • Settings
  • +
  • Logout
  • + +
  • New Ticket
  • +
  • Ticket Queue
  • +{/block} + diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/templates/register.tpl b/code/ryzom/tools/server/ryzom_ams/www/html/templates/register.tpl new file mode 100644 index 000000000..17100d13d --- /dev/null +++ b/code/ryzom/tools/server/ryzom_ams/www/html/templates/register.tpl @@ -0,0 +1,115 @@ +{config_load file="ams_lib.conf" section="setup"} +
    + {$title} +
    + +
    + {$welcome_message} +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    {$username_tag} + + {if isset($Username)}{$Username}{/if}
    {$password_tag} + + {if isset($PASSWORD_ERROR) && $PASSWORD_ERROR eq "TRUE"}{$Password}{/if}
    {$cpassword_tag} + {if isset($CPASSWORD_ERROR) && $CPASSWORD_ERROR eq "TRUE"}{$ConfirmPass}{/if}
    {$email_tag} + + {if isset($EMAIL_ERROR) && $EMAIL_ERROR eq "TRUE"}{$Email}{/if}
    {$tac_tag}{$tac_message}
    + +
    + +
    + +
    + +
    + +
    + {$username_tooltip} +
    + + +
    + {$password_message} +
    + +
    + {$cpassword_message} +
    + +
    + {$email_message} +
    + +
    \ No newline at end of file diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/149a5753c6489e4c9837d8190f2360e006686ab6.file.home.tpl.php b/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/149a5753c6489e4c9837d8190f2360e006686ab6.file.home.tpl.php new file mode 100644 index 000000000..f60719246 --- /dev/null +++ b/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/149a5753c6489e4c9837d8190f2360e006686ab6.file.home.tpl.php @@ -0,0 +1,297 @@ + +decodeProperties(array ( + 'file_dependency' => + array ( + '149a5753c6489e4c9837d8190f2360e006686ab6' => + array ( + 0 => '/home/daan/ryzom/ryzomcore/code/ryzom/tools/server/ryzom_ams/www/html/templates/home.tpl', + 1 => 1371327630, + 2 => 'file', + ), + '9ae80e874700913f7c626d25edfb34ea50aafba8' => + array ( + 0 => '/home/daan/ryzom/ryzomcore/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout_admin.tpl', + 1 => 1371327397, + 2 => 'file', + ), + '82fdcb43de00a568e1631573af77d92f4505c948' => + array ( + 0 => '/home/daan/ryzom/ryzomcore/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout.tpl', + 1 => 1371326024, + 2 => 'file', + ), + ), + 'nocache_hash' => '182818190051bcbf3b50f736-14104775', + 'function' => + array ( + ), + 'version' => 'Smarty-3.1.13', + 'unifunc' => 'content_51bcbf3b574410_14327703', + 'has_nocache_code' => false, +),false); /*/%%SmartyHeaderCode%%*/?> + + + + + + Ryzom Account Management System + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + +
    + + + +
    +
    +
    +

    Ryzom Account Management System

    +
    + + +
    +
    +
    +

    Ryzom AMS

    +

    Welcome to the Ryzom Account Management System!

    +
    +
    +
    +
    + + +
    + +
    + +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/82fdcb43de00a568e1631573af77d92f4505c948.file.layout.tpl.php b/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/82fdcb43de00a568e1631573af77d92f4505c948.file.layout.tpl.php new file mode 100644 index 000000000..de4b7ef0f --- /dev/null +++ b/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/82fdcb43de00a568e1631573af77d92f4505c948.file.layout.tpl.php @@ -0,0 +1,256 @@ + +decodeProperties(array ( + 'file_dependency' => + array ( + '82fdcb43de00a568e1631573af77d92f4505c948' => + array ( + 0 => '/home/daan/ryzom/ryzomcore/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout.tpl', + 1 => 1371322463, + 2 => 'file', + ), + ), + 'nocache_hash' => '160017253151bca2b5a70430-40836818', + 'function' => + array ( + ), + 'version' => 'Smarty-3.1.13', + 'unifunc' => 'content_51bca2b5ab3437_35089772', + 'has_nocache_code' => false, +),false); /*/%%SmartyHeaderCode%%*/?> + + + + + + Ryzom Account Management System + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + +
    + + + + +
    + +
    + +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/9ae80e874700913f7c626d25edfb34ea50aafba8.file.layout_admin.tpl.php b/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/9ae80e874700913f7c626d25edfb34ea50aafba8.file.layout_admin.tpl.php new file mode 100644 index 000000000..837abc071 --- /dev/null +++ b/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/9ae80e874700913f7c626d25edfb34ea50aafba8.file.layout_admin.tpl.php @@ -0,0 +1,274 @@ + +decodeProperties(array ( + 'file_dependency' => + array ( + '9ae80e874700913f7c626d25edfb34ea50aafba8' => + array ( + 0 => '/home/daan/ryzom/ryzomcore/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout_admin.tpl', + 1 => 1371324061, + 2 => 'file', + ), + '82fdcb43de00a568e1631573af77d92f4505c948' => + array ( + 0 => '/home/daan/ryzom/ryzomcore/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout.tpl', + 1 => 1371322463, + 2 => 'file', + ), + ), + 'nocache_hash' => '33219468451bcbeabacc0d9-76997576', + 'function' => + array ( + ), + 'has_nocache_code' => false, + 'version' => 'Smarty-3.1.13', + 'unifunc' => 'content_51bcbeabb3c189_52163969', +),false); /*/%%SmartyHeaderCode%%*/?> + + + + + + Ryzom Account Management System + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + +
    + + + + +
    + +
    + +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/e046ca36f637970ade33573b506c58aad0b1a410.extends.home.tpl.php b/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/e046ca36f637970ade33573b506c58aad0b1a410.extends.home.tpl.php new file mode 100644 index 000000000..d449862eb --- /dev/null +++ b/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/e046ca36f637970ade33573b506c58aad0b1a410.extends.home.tpl.php @@ -0,0 +1,293 @@ + +decodeProperties(array ( + 'file_dependency' => + array ( + 'e046ca36f637970ade33573b506c58aad0b1a410' => + array ( + 0 => '/home/daan/ryzom/ryzomcore/code/ryzom/tools/server/ryzom_ams/www/html/templates/home.tpl', + 1 => 1371327917, + 2 => 'file', + ), + 'f877c777d98fc313c8d29f39b0859e2aa1879e2e' => + array ( + 0 => '/home/daan/ryzom/ryzomcore/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout_user.tpl', + 1 => 1371327403, + 2 => 'file', + ), + '82fdcb43de00a568e1631573af77d92f4505c948' => + array ( + 0 => '/home/daan/ryzom/ryzomcore/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout.tpl', + 1 => 1371326024, + 2 => 'file', + ), + ), + 'nocache_hash' => '37341928851bcce16930ba2-45846425', + 'function' => + array ( + ), + 'has_nocache_code' => false, + 'version' => 'Smarty-3.1.13', + 'unifunc' => 'content_51bcce1698f268_66900106', +),false); /*/%%SmartyHeaderCode%%*/?> + + + + + + Ryzom Account Management System + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + +
    + + + +
    +
    +
    +

    Ryzom Account Management System

    +
    + + +
    +
    +
    +

    Ryzom AMS

    +

    Welcome to the Ryzom Account Management System!

    +
    +
    +
    +
    + + +
    + +
    + +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/ec9cd121cf7179810948ac67558b081fc2e7cbb8.extends.home.tpl.php b/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/ec9cd121cf7179810948ac67558b081fc2e7cbb8.extends.home.tpl.php new file mode 100644 index 000000000..15dbfc198 --- /dev/null +++ b/code/ryzom/tools/server/ryzom_ams/www/html/templates_c/ec9cd121cf7179810948ac67558b081fc2e7cbb8.extends.home.tpl.php @@ -0,0 +1,297 @@ + +decodeProperties(array ( + 'file_dependency' => + array ( + 'ec9cd121cf7179810948ac67558b081fc2e7cbb8' => + array ( + 0 => '/home/daan/ryzom/ryzomcore/code/ryzom/tools/server/ryzom_ams/www/html/templates/home.tpl', + 1 => 1371329107, + 2 => 'file', + ), + '9ae80e874700913f7c626d25edfb34ea50aafba8' => + array ( + 0 => '/home/daan/ryzom/ryzomcore/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout_admin.tpl', + 1 => 1371327397, + 2 => 'file', + ), + '82fdcb43de00a568e1631573af77d92f4505c948' => + array ( + 0 => '/home/daan/ryzom/ryzomcore/code/ryzom/tools/server/ryzom_ams/www/html/templates/layout.tpl', + 1 => 1371329620, + 2 => 'file', + ), + ), + 'nocache_hash' => '188962902651bcce005d1445-21118150', + 'function' => + array ( + ), + 'version' => 'Smarty-3.1.13', + 'unifunc' => 'content_51bcce0062ca40_45088230', + 'has_nocache_code' => false, +),false); /*/%%SmartyHeaderCode%%*/?> + + + + + + Ryzom Account Management System + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + +
    + + + +
    +
    +
    +

    Ryzom Account Management System

    +
    + + +
    +
    +
    +

    Ryzom AMS

    +

    Welcome to the Ryzom Account Management System!

    +
    +
    +
    +
    + + +
    + +
    + +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file