From 4b477f8abc876bb5062fda0f791de604f27cedfd Mon Sep 17 00:00:00 2001 From: ptv Date: Mon, 27 Aug 2007 11:42:32 +0000 Subject: [PATCH] O-2.12 Renaming curves --- src/Plot2d/Makefile.in | 1 + src/Plot2d/Plot2d_SetupCurveDlg.cxx | 274 ++++++++++++++++---- src/Plot2d/Plot2d_SetupCurveDlg.h | 71 +++-- src/Plot2d/Plot2d_ViewWindow.cxx | 38 +++ src/Plot2d/Plot2d_ViewWindow.h | 4 +- src/Plot2d/resources/Plot2d_images.po | 3 + src/Plot2d/resources/Plot2d_msg_en.po | 18 ++ src/Plot2d/resources/plot2d_edit_legend.png | Bin 0 -> 537 bytes 8 files changed, 344 insertions(+), 65 deletions(-) create mode 100755 src/Plot2d/resources/plot2d_edit_legend.png diff --git a/src/Plot2d/Makefile.in b/src/Plot2d/Makefile.in index 647c1b84d..d25700d1a 100755 --- a/src/Plot2d/Makefile.in +++ b/src/Plot2d/Makefile.in @@ -72,6 +72,7 @@ plot2d_camera_dump.png \ plot2d_fitall.png \ plot2d_fitarea.png \ plot2d_glpan.png \ +plot2d_edit_legend.png \ plot2d_legend.png \ plot2d_linear.png \ plot2d_linear_y.png \ diff --git a/src/Plot2d/Plot2d_SetupCurveDlg.cxx b/src/Plot2d/Plot2d_SetupCurveDlg.cxx index 4873db496..862a8ded3 100644 --- a/src/Plot2d/Plot2d_SetupCurveDlg.cxx +++ b/src/Plot2d/Plot2d_SetupCurveDlg.cxx @@ -24,6 +24,7 @@ // $Header$ #include "Plot2d_SetupCurveDlg.h" +#include "Plot2d_ViewFrame.h" #include "SUIT_Tools.h" #include #include @@ -33,6 +34,8 @@ #include #include #include +#include +#include #ifndef WNT using namespace std; @@ -48,21 +51,69 @@ using namespace std; Constructor */ Plot2d_SetupCurveDlg::Plot2d_SetupCurveDlg( QWidget* parent ) - : QDialog( parent, "Plot2d_SetupCurveDlg", true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) +: QtxDialog( parent, "Plot2d_SetupCurveDlg", true, true, OK | Cancel, + WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ), + myCurrent( -1 ), + myCurveBox( 0 ) +{ + createControls( 0 ); +} + +/*! + Constructor +*/ +Plot2d_SetupCurveDlg::Plot2d_SetupCurveDlg( Plot2d_ViewFrame* vf, QWidget* parent ) +: QtxDialog( parent, "Plot2d_SetupCurveDlg", true, true, OK | Cancel, + WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ), + myCurrent( -1 ), + myCurveBox( 0 ) +{ + createControls( vf ); +} + +/*! + Destructor +*/ +Plot2d_SetupCurveDlg::~Plot2d_SetupCurveDlg() +{ +} + +/*! + createControls +*/ +void Plot2d_SetupCurveDlg::createControls( Plot2d_ViewFrame* vf ) { setCaption( tr("TLT_SETUP_CURVE") ); setSizeGripEnabled( TRUE ); - QGridLayout* topLayout = new QGridLayout( this ); - topLayout->setSpacing( SPACING_SIZE ); - topLayout->setMargin( MARGIN_SIZE ); - QGroupBox* TopGroup = new QGroupBox( this ); + QFrame* main = mainFrame(); + QVBoxLayout* layout = new QVBoxLayout( main, 0, 5 ); + QGroupBox* grp = new QGroupBox( 1, Qt::Vertical, "", main ); + grp->setFrameStyle( QFrame::NoFrame ); + grp->setInsideMargin( 0 ); + layout->addWidget( grp ); + + if ( vf ) + { + QGroupBox* crvGrp = new QGroupBox( 1, Qt::Horizontal, tr( "CURVES" ), grp ); + crvGrp->setInsideMargin( MARGIN_SIZE ); + myCurveBox = new QListBox( crvGrp ); + myCurveBox->setSelectionMode( QListBox::NoSelection ); + connect( myCurveBox, SIGNAL( currentChanged( QListBoxItem* ) ), this, SLOT( onCurveChanged() ) ); + } + + QGroupBox* TopGroup = new QGroupBox( 1, Qt::Horizontal, tr( "CURVE_PROPS" ), grp ); + TopGroup->setInsideMargin( MARGIN_SIZE ); + TopGroup->setColumnLayout( 0, Qt::Vertical ); TopGroup->layout()->setSpacing( 0 ); TopGroup->layout()->setMargin( 0 ); QGridLayout* TopGroupLayout = new QGridLayout( TopGroup->layout() ); TopGroupLayout->setAlignment( Qt::AlignTop ); TopGroupLayout->setSpacing( SPACING_SIZE ); TopGroupLayout->setMargin( MARGIN_SIZE ); + QLabel* nameLab = new QLabel( tr( "CURVE_NAME" ), TopGroup ); + myName = new QLineEdit( TopGroup ); + QLabel* aLineTypeLab = new QLabel( tr( "CURVE_LINE_TYPE_LAB" ), TopGroup ); myLineCombo = new QComboBox( false, TopGroup ); myLineCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); @@ -101,48 +152,63 @@ Plot2d_SetupCurveDlg::Plot2d_SetupCurveDlg( QWidget* parent ) myColorBtn = new QToolButton( TopGroup ); myColorBtn->setMinimumSize(25, 25); - TopGroupLayout->addWidget( aLineTypeLab, 0, 0 ); - TopGroupLayout->addMultiCellWidget( myLineCombo, 0, 0, 1, 2 ); - TopGroupLayout->addWidget( aLineWidthLab, 1, 0 ); - TopGroupLayout->addMultiCellWidget( myLineSpin, 1, 1, 1, 2 ); - TopGroupLayout->addWidget( aMarkerLab, 2, 0 ); - TopGroupLayout->addMultiCellWidget( myMarkerCombo, 2, 2, 1, 2 ); - TopGroupLayout->addWidget( aColorLab, 3, 0 ); - TopGroupLayout->addWidget( myColorBtn, 3, 1 ); - TopGroupLayout->setColStretch( 2, 5 ); - - QGroupBox* GroupButtons = new QGroupBox( this ); - GroupButtons->setColumnLayout( 0, Qt::Vertical ); - GroupButtons->layout()->setSpacing( 0 ); GroupButtons->layout()->setMargin( 0 ); - QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons->layout() ); - GroupButtonsLayout->setAlignment( Qt::AlignTop ); - GroupButtonsLayout->setSpacing( SPACING_SIZE ); GroupButtonsLayout->setMargin( MARGIN_SIZE ); - - myOkBtn = new QPushButton( tr( "BUT_OK" ), GroupButtons ); - myOkBtn->setAutoDefault( true ); myOkBtn->setDefault( true ); - myCancelBtn = new QPushButton( tr( "BUT_CANCEL" ) , GroupButtons ); - myCancelBtn->setAutoDefault( true ); - - GroupButtonsLayout->addWidget( myOkBtn ); - GroupButtonsLayout->addStretch(); - GroupButtonsLayout->addWidget( myCancelBtn ); + TopGroupLayout->addWidget( nameLab, 0, 0 ); + TopGroupLayout->addMultiCellWidget( myName, 0, 0, 1, 2 ); + TopGroupLayout->addWidget( aLineTypeLab, 1, 0 ); + TopGroupLayout->addMultiCellWidget( myLineCombo, 1, 1, 1, 2 ); + TopGroupLayout->addWidget( aLineWidthLab, 2, 0 ); + TopGroupLayout->addMultiCellWidget( myLineSpin, 2, 2, 1, 2 ); + TopGroupLayout->addWidget( aMarkerLab, 3, 0 ); + TopGroupLayout->addMultiCellWidget( myMarkerCombo, 3, 3, 1, 2 ); + TopGroupLayout->addWidget( aColorLab, 4, 0 ); + TopGroupLayout->addWidget( myColorBtn, 4, 1 ); + TopGroupLayout->setColStretch( 2, 6 ); + + setBorderEnabled( true, BottomArea ); + setButtonPosition( Left, OK ); + setButtonPosition( Right, Cancel ); + ((QPushButton*)(button( Cancel )))->setAutoDefault( true ); + connect( myName, SIGNAL( textChanged( const QString& ) ), this, SLOT( onNameChanged( const QString& ) ) ); connect( myColorBtn, SIGNAL( clicked() ), this, SLOT( onColorChanged() ) ); - connect( myOkBtn, SIGNAL( clicked() ), this, SLOT( accept() ) ); - connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( this, SIGNAL( dlgOk() ), this, SLOT( onOk() ) ) ; setColor( QColor( 0, 0, 0 ) ); - topLayout->addWidget( TopGroup, 0, 0 ); - topLayout->addWidget( GroupButtons, 1, 0 ); + SUIT_Tools::centerWidget( this, (QWidget*)parent() ); - SUIT_Tools::centerWidget( this, parent ); + if ( vf ) + init( vf ); } + /*! - Destructor + onOk */ -Plot2d_SetupCurveDlg::~Plot2d_SetupCurveDlg() +void Plot2d_SetupCurveDlg::onOk() { + if ( myCurrent != -1 ) + storeCurveProps( myCurrent ); } + + +/*! + Sets name of curve +*/ +void Plot2d_SetupCurveDlg::setName( const QString txt ) +{ + myName->setText( txt ); +} + +/*! + Returns name of curve +*/ +QString Plot2d_SetupCurveDlg::getName( const int id ) const +{ + if ( id == -1 ) + return myName->text(); + else + return myCurvesProps[ id ].name; +} + /*! Sets line style and width */ @@ -151,20 +217,29 @@ void Plot2d_SetupCurveDlg::setLine( const int line, const int width ) myLineCombo->setCurrentItem( line ); myLineSpin->setValue( width ); } + /*! Gets line style */ -int Plot2d_SetupCurveDlg::getLine() const +int Plot2d_SetupCurveDlg::getLine( const int id ) const { - return myLineCombo->currentItem(); + if ( id == -1 ) + return myLineCombo->currentItem(); + else + return myCurvesProps[ id ].line; } + /*! Gets line width */ -int Plot2d_SetupCurveDlg::getLineWidth() const +int Plot2d_SetupCurveDlg::getLineWidth( const int id ) const { - return myLineSpin->value(); + if ( id == -1 ) + return myLineSpin->value(); + else + return myCurvesProps[ id ].width; } + /*! Sets marker style */ @@ -172,13 +247,18 @@ void Plot2d_SetupCurveDlg::setMarker( const int marker ) { myMarkerCombo->setCurrentItem( marker ); } + /*! Gets marker style */ -int Plot2d_SetupCurveDlg::getMarker() const +int Plot2d_SetupCurveDlg::getMarker( const int id ) const { - return myMarkerCombo->currentItem(); + if ( id == -1 ) + return myMarkerCombo->currentItem(); + else + return myCurvesProps[ id ].marker; } + /*! Sets color */ @@ -193,13 +273,18 @@ void Plot2d_SetupCurveDlg::setColor( const QColor& color ) pal.setInactive( ci ); myColorBtn->setPalette( pal ); } + /*! Gets color */ -QColor Plot2d_SetupCurveDlg::getColor() const +QColor Plot2d_SetupCurveDlg::getColor( const int id ) const { - return myColorBtn->palette().active().button(); + if ( id == -1 ) + return myColorBtn->palette().active().button(); + else + return myCurvesProps[ id ].color; } + /*! button slot, invokes color selection dialog box */ @@ -211,7 +296,106 @@ void Plot2d_SetupCurveDlg::onColorChanged() } } +/*! + init dialog by several curves +*/ +void Plot2d_SetupCurveDlg::init( Plot2d_ViewFrame* vf ) +{ + if ( !vf || !myCurveBox ) + return; + + curveList lst; + if ( !vf->getCurves( lst ) ) + return; + curveList::const_iterator crvIt = lst.begin(); + for ( ; crvIt != lst.end(); ++crvIt ) + { + CurveProp newProp; + Plot2d_Curve* crv = *crvIt; + newProp.name = crv->getVerTitle(); + newProp.line = (int)crv->getLine(); + newProp.width = crv->getLineWidth(); + newProp.marker = (int)crv->getMarker(); + newProp.color = crv->getColor(); + myCurvesProps.insert( myCurvesProps.count(), newProp ); + // add curve to list box + myCurveBox->insertItem( newProp.name ); + } + setCurrentCurve( 0 ); +} +/*! + Sets current curve property +*/ +void Plot2d_SetupCurveDlg::setCurrentCurve( const int id ) +{ + if ( myCurrent == id ) return; + myCurveBox->setCurrentItem( id ); + //retrieveCurveProps( 0 ); + //myCurrent = id; +} +/*! + getNbCurves, return number of curves +*/ +int Plot2d_SetupCurveDlg::getNbCurves() const +{ + return myCurvesProps.count(); +} +/*! + slot, invokes when current curve changed +*/ +void Plot2d_SetupCurveDlg::onCurveChanged() +{ + int newId = myCurveBox->currentItem(); + if ( myCurrent == newId ) + return; + if ( myCurrent != -1 ) + storeCurveProps( myCurrent ); + myCurrent = newId; + retrieveCurveProps( newId ); +} + +/*! + slot, invokes when current curve name changed +*/ +void Plot2d_SetupCurveDlg::onNameChanged( const QString& txt ) +{ + if ( myCurveBox && myCurrent != -1 ) + myCurveBox->changeItem( txt, myCurrent ); +} + +/*! + storeCurveProps, stores curve properties +*/ +bool Plot2d_SetupCurveDlg::storeCurveProps( const int id ) +{ + if ( id < 0 || id > (int)myCurvesProps.count() - 1 ) + return false; + CurveProp& curProp = myCurvesProps[ id ]; + curProp.name = getName(); + curProp.line = getLine(); + curProp.width = getLineWidth(); + curProp.marker = getMarker(); + curProp.color = getColor(); + return true; +} + +/*! + retrieveCurveProps, retrievs curve properties +*/ +void Plot2d_SetupCurveDlg::retrieveCurveProps( const id ) +{ + if ( id < 0 || id > (int)myCurvesProps.count() - 1 ) + return; + const CurveProp& curProp = myCurvesProps[ id ]; + myName->blockSignals( true ); + myName->setText( curProp.name ); + myName->blockSignals( false ); + //setName( curProp.name ); + setLine( curProp.line, curProp.width ); + setMarker( curProp.marker ); + setColor( curProp.color ); +} diff --git a/src/Plot2d/Plot2d_SetupCurveDlg.h b/src/Plot2d/Plot2d_SetupCurveDlg.h index 84d530aa6..651493a65 100644 --- a/src/Plot2d/Plot2d_SetupCurveDlg.h +++ b/src/Plot2d/Plot2d_SetupCurveDlg.h @@ -25,48 +25,81 @@ #ifndef Plot2d_SetupCurveDlg_H #define Plot2d_SetupCurveDlg_H -#include "Plot2d.h" +#include + +#include -#include +#include "Plot2d.h" /*! \class Plot2d_SetupCurveDlg Dialog box for setup Plot2d curve */ +class QListBox; +class QLineEdit; class QPushButton; class QComboBox; class QSpinBox; class QToolButton; +class Plot2d_ViewFrame; -class PLOT2D_EXPORT Plot2d_SetupCurveDlg : public QDialog -{ +class PLOT2D_EXPORT Plot2d_SetupCurveDlg : public QtxDialog +{ Q_OBJECT public: Plot2d_SetupCurveDlg( QWidget* parent = 0 ); + Plot2d_SetupCurveDlg( Plot2d_ViewFrame* vf, QWidget* parent = 0 ); ~Plot2d_SetupCurveDlg(); public: - void setLine( const int line, const int width ); - int getLine() const; - int getLineWidth() const; - void setMarker( const int marker ); - int getMarker() const ; - void setColor( const QColor& color ); - QColor getColor() const; + void setCurrentCurve( const int ); + + void setName( const QString ); + QString getName( const int id = -1 ) const; + void setLine( const int line, const int width ); + int getLine( const int id = -1 ) const; + int getLineWidth( const int id = -1 ) const; + void setMarker( const int marker ); + int getMarker( const int id = -1 ) const; + void setColor( const QColor& color ); + QColor getColor( const int id = -1 ) const; + int getNbCurves() const; -protected slots: +private: + void createControls( Plot2d_ViewFrame* vf ); + void init( Plot2d_ViewFrame* vf ); + bool storeCurveProps( const int id = -1 ); + void retrieveCurveProps( const int id ); + +private slots: + void onCurveChanged(); void onColorChanged(); + void onNameChanged( const QString& ); + void onOk(); private: - QPushButton* myOkBtn; - QPushButton* myCancelBtn; - QComboBox* myLineCombo; - QSpinBox* myLineSpin; - QComboBox* myMarkerCombo; - QToolButton* myColorBtn; + + struct CurveProp + { + CurveProp() + { line = width = marker = -1; } + int line; + int width; + int marker; + QColor color; + QString name; + }; + + int myCurrent; + QListBox* myCurveBox; + QMap myCurvesProps; + QLineEdit* myName; + QComboBox* myLineCombo; + QSpinBox* myLineSpin; + QComboBox* myMarkerCombo; + QToolButton* myColorBtn; }; #endif // Plot2d_SetupCurveDlg_H - diff --git a/src/Plot2d/Plot2d_ViewWindow.cxx b/src/Plot2d/Plot2d_ViewWindow.cxx index e562e30dc..854bc97db 100755 --- a/src/Plot2d/Plot2d_ViewWindow.cxx +++ b/src/Plot2d/Plot2d_ViewWindow.cxx @@ -20,6 +20,7 @@ #include "Plot2d_ViewWindow.h" #include "Plot2d_ViewFrame.h" +#include "Plot2d_SetupCurveDlg.h" #include "SUIT_ViewManager.h" #include "SUIT_ResourceMgr.h" @@ -104,6 +105,8 @@ void Plot2d_ViewWindow::contextMenuPopup( QPopupMenu* thePopup ) // legend myActionsMap[ LegendId ]->addTo(thePopup); + // edit legend + myActionsMap[ EditLegendId ]->addTo(thePopup); // settings myActionsMap[ CurvSettingsId ]->addTo(thePopup); } @@ -240,6 +243,14 @@ void Plot2d_ViewWindow::createActions() aAction->setToggleAction(true); myActionsMap[ LegendId ] = aAction; + aAction = new QtxAction(tr("TOT_PLOT2D_EDIT_LEGEND"), + aResMgr->loadPixmap("Plot2d", tr("ICON_PLOT2D_EDIT_LEGEND")), + tr("MEN_PLOT2D_EDIT_LEGEND"), 0, this); + aAction->setStatusTip(tr("PRP_PLOT2D_EDIT_LEGEND")); + connect(aAction, SIGNAL(activated()), this, SLOT(onEditLegend())); + aAction->setToggleAction(true); + myActionsMap[ EditLegendId ] = aAction; + // Settings aAction = new QtxAction(tr( "TOT_PLOT2D_SETTINGS"), aResMgr->loadPixmap("Plot2d", tr("ICON_PLOT2D_SETTINGS")), @@ -322,6 +333,7 @@ void Plot2d_ViewWindow::createToolBar() onChangeVerMode(); myActionsMap[LegendId]->addTo(myToolBar); + myActionsMap[EditLegendId]->addTo(myToolBar); myActionsMap[CurvSettingsId]->addTo(myToolBar); myActionsMap[CloneId]->addTo(myToolBar); onChangeLegendMode(); @@ -463,6 +475,32 @@ void Plot2d_ViewWindow::onLegend() onChangeLegendMode(); } +/*! + SLOT: called if action "Edit legend" is activated +*/ +void Plot2d_ViewWindow::onEditLegend() +{ + Plot2d_SetupCurveDlg aDlg( myViewFrame, this ); + if ( aDlg.exec() != QDialog::Accepted ) + return; + curveList lst; + if ( !myViewFrame->getCurves( lst ) ) + return; + curveList::iterator crvIt = lst.begin(); + for ( int i = 0, nb = aDlg.getNbCurves(); crvIt != lst.end() && i < nb; ++crvIt, i++ ) + { + Plot2d_Curve* crv = *crvIt; + crv->setVerTitle( aDlg.getName( i ) ); + crv->setLine( (Plot2d_Curve::LineType)aDlg.getLine( i ), aDlg.getLineWidth( i ) ); + crv->setMarker( (Plot2d_Curve::MarkerType)aDlg.getMarker( i ) ); + crv->setColor( aDlg.getColor( i ) ); + myViewFrame->updateCurve( crv, false ); + } + if ( i ) + myViewFrame->Repaint(); + emit legendChanged(); +} + /*! SLOT: called if action "Change curve type" is activated */ diff --git a/src/Plot2d/Plot2d_ViewWindow.h b/src/Plot2d/Plot2d_ViewWindow.h index b8c3718d3..1b1db0636 100755 --- a/src/Plot2d/Plot2d_ViewWindow.h +++ b/src/Plot2d/Plot2d_ViewWindow.h @@ -74,16 +74,18 @@ public slots: void onViewHorMode(); void onViewVerMode(); void onLegend(); + void onEditLegend(); void onCurves(); void onDumpView(); signals: void cloneView(); + void legendChanged(); protected: enum { DumpId, FitAllId, FitRectId, ZoomId, PanId, GlobalPanId, HorId, - VerId, LegendId, CurvPointsId, CurvLinesId, CurvSplinesId, CurvSettingsId, CloneId, + VerId, LegendId, EditLegendId, CurvPointsId, CurvLinesId, CurvSplinesId, CurvSettingsId, CloneId, PModeXLinearId, PModeXLogarithmicId, PModeYLinearId, PModeYLogarithmicId }; typedef QMap ActionsMap; ActionsMap myActionsMap; diff --git a/src/Plot2d/resources/Plot2d_images.po b/src/Plot2d/resources/Plot2d_images.po index 59c109033..04f891999 100755 --- a/src/Plot2d/resources/Plot2d_images.po +++ b/src/Plot2d/resources/Plot2d_images.po @@ -63,6 +63,9 @@ msgstr "plot2d_log_y.png" msgid "ICON_PLOT2D_SHOW_LEGEND" msgstr "plot2d_legend.png" +msgid "ICON_PLOT2D_EDIT_LEGEND" +msgstr "plot2d_edit_legend.png" + msgid "ICON_PLOT2D_CURVES_POINTS" msgstr "plot2d_points.png" diff --git a/src/Plot2d/resources/Plot2d_msg_en.po b/src/Plot2d/resources/Plot2d_msg_en.po index e0d764da7..0df89850e 100755 --- a/src/Plot2d/resources/Plot2d_msg_en.po +++ b/src/Plot2d/resources/Plot2d_msg_en.po @@ -75,6 +75,15 @@ msgstr "Show &Legend" msgid "PRP_PLOT2D_SHOW_LEGEND" msgstr "Enables/disables legend" +msgid "TOT_PLOT2D_EDIT_LEGEND" +msgstr "Edit Legend" + +msgid "MEN_PLOT2D_EDIT_LEGEND" +msgstr "Edit &Legend" + +msgid "PRP_PLOT2D_EDIT_LEGEND" +msgstr "Edit curves legend" + msgid "TOT_PLOT2D_CURVES_POINTS" msgstr "Draw points" @@ -409,3 +418,12 @@ msgstr "PostScript files (*.ps)" msgid "Plot2d_ViewManager::PLOT2D_VIEW_TITLE" msgstr "Plot2d scene:%M - viewer:%V" + +msgid "CURVES" +msgstr "Curves" + +msgid "CURVE_PROPS" +msgstr "Properties" + +msgid "CURVE_NAME" +msgstr "Name" diff --git a/src/Plot2d/resources/plot2d_edit_legend.png b/src/Plot2d/resources/plot2d_edit_legend.png new file mode 100755 index 0000000000000000000000000000000000000000..393ad94a77e05a0184ac2772dabf838e43b18101 GIT binary patch literal 537 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VOS+@4BLl<6zM9{GlYxANWRD>fq`*}r;B4q#hj!+|Nq-F z?`)VjQE;7P2A^^V8;63}2A5>zu9fUEG7^Q7N%{Hw<~%7Uj+ILPXJ=tIXvp}lQ18~j zkaTd_%Y)7A|3yVaBxLzy4ix;Wudd#aYT)c}$iT3H;ZT+WM@_}=hxR9yDjY6c$+(l} zrhxzhhr%4TLku9HjVE&>b~D~gFaU~eXl#j5QqXBI_PMy1N5H}7gr497(S(LXCkC{|P=!4Lf;6ZiDP&QdMhf_TUuZ;gd;d ziEdKso5QzJl25?F;<92#7=u)UP^7~)+aN2KzSM|WEF21IBI1o-bRrm*ISMj+>9r_v zi z;yuGuqu0*Zz|bVkQ6y=`(5)h%rj`S=W>PSpT#AE!?tzzl-HbbmxHN1W@3C_jFu12& VPV6mb-vW$V22WQ%mvv4FO#sf1t^@!8 literal 0 HcmV?d00001 -- 2.39.2