From 90ead023ec593bd3dba0ef8eb4e38f2299cfb783 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Fri, 6 Mar 2009 16:55:02 +0100 Subject: Implemented LinjaZax-like gesture in collidingmice example. --- examples/gestures/collidingmice/collidingmice.pro | 8 +- .../collidingmice/gesturerecognizerlinjazax.cpp | 189 +++++++++++++++++++++ .../collidingmice/gesturerecognizerlinjazax.h | 65 +++++++ examples/gestures/collidingmice/images/cheese.jpg | Bin 0 -> 3029 bytes examples/gestures/collidingmice/linjazaxgesture.h | 58 +++++++ examples/gestures/collidingmice/main.cpp | 19 ++- 6 files changed, 335 insertions(+), 4 deletions(-) create mode 100644 examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp create mode 100644 examples/gestures/collidingmice/gesturerecognizerlinjazax.h create mode 100644 examples/gestures/collidingmice/images/cheese.jpg create mode 100644 examples/gestures/collidingmice/linjazaxgesture.h diff --git a/examples/gestures/collidingmice/collidingmice.pro b/examples/gestures/collidingmice/collidingmice.pro index 5c7b42b..15164ce 100644 --- a/examples/gestures/collidingmice/collidingmice.pro +++ b/examples/gestures/collidingmice/collidingmice.pro @@ -1,8 +1,12 @@ HEADERS += \ - mouse.h + mouse.h \ + gesturerecognizerlinjazax.h \ + linjazaxgesture.h + SOURCES += \ main.cpp \ - mouse.cpp + mouse.cpp \ + gesturerecognizerlinjazax.cpp RESOURCES += \ mice.qrc diff --git a/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp b/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp new file mode 100644 index 0000000..4c57209 --- /dev/null +++ b/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp @@ -0,0 +1,189 @@ +#include "gesturerecognizerlinjazax.h" + +#include +#include + +static const int SIZE = 20; + +DirectionSimpleRecognizer::DirectionSimpleRecognizer() +{ +} + +Direction DirectionSimpleRecognizer::addPosition(const QPoint &pos) +{ + if (!directions.isEmpty()) { + const QPoint tmp = pos - directions.back().point; + if (tmp.manhattanLength() < 5) + return Direction(); + } + if (lastPoint.isNull()) { + lastPoint = pos; + return Direction(); + } + int dx = pos.x() - lastPoint.x(); + int dy = pos.y() - lastPoint.y(); + QString direction; + if (dx < 0) { + if (-1*dx >= SIZE/2) + direction = "4"; + } else { + if (dx >= SIZE/2) + direction = "6"; + } + if (dy < 0) { + if (-1*dy >= SIZE/2) + direction = "8"; + } else { + if (dy >= SIZE/2) + direction = "2"; + } + if (direction.isEmpty()) + return Direction(); + + lastPoint = pos; + directions.push_back(Direction(direction, pos)); + return Direction(direction, pos); +} + + +DirectionList DirectionSimpleRecognizer::getDirections() const +{ + return directions; +} + +void DirectionSimpleRecognizer::reset() +{ + directions.clear(); + lastPoint = QPoint(); +} + +/////////////////////////////////////////////////////////////////////////// + +GestureRecognizerLinjaZax::GestureRecognizerLinjaZax() + : QGestureRecognizer("LinjaZax"), mousePressed(false), gestureFinished(false), + zoomState(LinjaZaxGesture::NoZoom) +{ +} + +QGestureRecognizer::Result GestureRecognizerLinjaZax::recognize(const QList &inputEvents) +{ + // get all mouse events + QList events; + for(int i = 0; i < inputEvents.count(); ++i) { + QEvent *event = inputEvents.at(i); + switch (event->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + events.push_back(static_cast(event)); + default: + break; + } + } + + if (zoomState != LinjaZaxGesture::NoZoom && !lastDirections.isEmpty()) { + lastDirections = lastDirections.right(1); + zoomState = LinjaZaxGesture::NoZoom; + } + + QGestureRecognizer::Result result = QGestureRecognizer::NotGesture; + for(int i = 0; i < events.count(); ++i) { + QMouseEvent *event = events.at(i); + if (event->type() == QEvent::MouseButtonPress) { + if (!currentDirection.isEmpty()) { + result = QGestureRecognizer::NotGesture; + reset(); + break; + } + result = QGestureRecognizer::MaybeGesture; + mousePressed = true; + pressedPos = lastPos = currentPos = event->pos(); + } else if (event->type() == QEvent::MouseButtonRelease) { + if (mousePressed && !currentDirection.isEmpty()) { + result = QGestureRecognizer::GestureFinished; + gestureFinished = true; + currentPos = event->pos(); + internalReset(); + break; + } + result = QGestureRecognizer::NotGesture; + reset(); + break; + } else if (event->type() == QEvent::MouseMove) { + if (!mousePressed) + continue; + lastPos = currentPos; + currentPos = event->pos(); + QString direction = + simpleRecognizer.addPosition(event->pos()).direction; + if (currentDirection.isEmpty()) { + if (direction.isEmpty()) + result = QGestureRecognizer::MaybeGesture; + else + result = QGestureRecognizer::GestureStarted; + } else { + result = QGestureRecognizer::GestureStarted; + } + if (!direction.isEmpty()) { + if (currentDirection != direction) + lastDirections.append(direction); + currentDirection = direction; + if (lastDirections.length() > 5) + lastDirections.remove(0, 1); + if (lastDirections.contains("248")) + zoomState = LinjaZaxGesture::ZoomingIn; + else if (lastDirections.contains("268")) + zoomState = LinjaZaxGesture::ZoomingOut; + } + } + } + return result; +} + +static inline LinjaZaxGesture::DirectionType convertPanningDirection(const QString &direction) +{ + if (direction.length() == 1) { + if (direction == "4") + return LinjaZaxGesture::Left; + else if (direction == "6") + return LinjaZaxGesture::Right; + else if (direction == "8") + return LinjaZaxGesture::Up; + else if (direction == "2") + return LinjaZaxGesture::Down; + } + return LinjaZaxGesture::None; +} + +QGesture* GestureRecognizerLinjaZax::makeEvent() const +{ + LinjaZaxGesture::DirectionType dir = convertPanningDirection(currentDirection); + LinjaZaxGesture::DirectionType lastDir = convertPanningDirection(lastDirections.right(1)); + if (dir == LinjaZaxGesture::None) + return 0; + LinjaZaxGesture *g = + new LinjaZaxGesture("LinjaZax", pressedPos, lastPos, currentPos, + QRect(), pressedPos, QDateTime(), 0, + gestureFinished ? Qt::GestureFinished : Qt::GestureStarted); + g->lastDirection_ = lastDir; + g->direction_ = dir; + g->zoomState_ = zoomState; + + return g; +} + +void GestureRecognizerLinjaZax::reset() +{ + mousePressed = false; + lastDirections.clear(); + currentDirection.clear(); + gestureFinished = false; + simpleRecognizer.reset(); + zoomState = LinjaZaxGesture::NoZoom; +} + +void GestureRecognizerLinjaZax::internalReset() +{ + mousePressed = false; + simpleRecognizer.reset(); +} diff --git a/examples/gestures/collidingmice/gesturerecognizerlinjazax.h b/examples/gestures/collidingmice/gesturerecognizerlinjazax.h new file mode 100644 index 0000000..6579059 --- /dev/null +++ b/examples/gestures/collidingmice/gesturerecognizerlinjazax.h @@ -0,0 +1,65 @@ +#ifndef GESTURERECOGNIZERLINJAZAX_H +#define GESTURERECOGNIZERLINJAZAX_H + +#include +#include +#include +#include +#include + +#include "linjazaxgesture.h" + +struct Direction +{ + QString direction; + QPoint point; + + Direction(QString dir, const QPoint &pt) + : direction(dir), point(pt) { } + Direction() + : direction() { } + + inline bool isEmpty() const { return direction.isEmpty(); } + inline bool isNull() const { return direction.isEmpty(); } +}; +typedef QList DirectionList; + +class DirectionSimpleRecognizer +{ +public: + DirectionSimpleRecognizer(); + Direction addPosition(const QPoint &pos); + DirectionList getDirections() const; + void reset(); + +private: + QPoint lastPoint; + DirectionList directions; +}; + +class GestureRecognizerLinjaZax : public QGestureRecognizer +{ + Q_OBJECT +public: + GestureRecognizerLinjaZax(); + + QGestureRecognizer::Result recognize(const QList &inputEvents); + QGesture* makeEvent() const; + + void reset(); + +private: + void internalReset(); + + QPoint pressedPos; + QPoint lastPos; + QPoint currentPos; + bool mousePressed; + bool gestureFinished; + QString lastDirections; + QString currentDirection; + DirectionSimpleRecognizer simpleRecognizer; + LinjaZaxGesture::ZoomState zoomState; +}; + +#endif diff --git a/examples/gestures/collidingmice/images/cheese.jpg b/examples/gestures/collidingmice/images/cheese.jpg new file mode 100644 index 0000000..dea5795 Binary files /dev/null and b/examples/gestures/collidingmice/images/cheese.jpg differ diff --git a/examples/gestures/collidingmice/linjazaxgesture.h b/examples/gestures/collidingmice/linjazaxgesture.h new file mode 100644 index 0000000..9601675 --- /dev/null +++ b/examples/gestures/collidingmice/linjazaxgesture.h @@ -0,0 +1,58 @@ +#ifndef LINJAZAXGESTURE_H +#define LINJAZAXGESTURE_H + +#include + +class Q_GUI_EXPORT LinjaZaxGesture : public QGesture +{ +public: + enum DirectionType + { + None = 0, + LeftDown = 1, + DownLeft = LeftDown, + Down = 2, + RightDown = 3, + DownRight = RightDown, + Left = 4, + Right = 6, + LeftUp = 7, + UpLeft = LeftUp, + Up = 8, + RightUp = 9, + UpRight = RightUp + }; + + enum ZoomState + { + NoZoom, + ZoomingIn, + ZoomingOut + }; + +public: + explicit LinjaZaxGesture(const Qt::GestureType &type, Qt::GestureState state = Qt::GestureStarted) + : QGesture(type, state), lastDirection_(None), direction_(None), zoomState_(NoZoom) { } + LinjaZaxGesture(const Qt::GestureType &type, const QPoint &startPos, + const QPoint &lastPos, const QPoint &pos, const QRect &rect, + const QPoint &hotSpot, const QDateTime &startTime, + uint duration, Qt::GestureState state) + : QGesture(type, startPos, lastPos, pos, rect, hotSpot, startTime, duration, state) { } + ~LinjaZaxGesture() { } + + DirectionType lastDirection() const + { return lastDirection_; } + DirectionType direction() const + { return direction_; } + + ZoomState zoomState() const + { return zoomState_; } + +private: + DirectionType lastDirection_; + DirectionType direction_; + ZoomState zoomState_; + friend class GestureRecognizerLinjaZax; +}; + +#endif diff --git a/examples/gestures/collidingmice/main.cpp b/examples/gestures/collidingmice/main.cpp index 56e9f7f..9f50379 100644 --- a/examples/gestures/collidingmice/main.cpp +++ b/examples/gestures/collidingmice/main.cpp @@ -41,6 +41,9 @@ #include "mouse.h" +#include "gesturerecognizerlinjazax.h" +#include "linjazaxgesture.h" + #include #include @@ -53,14 +56,25 @@ public: PannableGraphicsView(QGraphicsScene *scene, QWidget *parent = 0) : QGraphicsView(scene, parent) { - grabGesture(Qt::Pan); + grabGesture("LinjaZax"); } protected: bool event(QEvent *event) { if (event->type() == QEvent::Gesture) { QGestureEvent *ge = static_cast(event); - if (const QPannableGesture *g = dynamic_cast(ge->gesture(Qt::Pan))) { + const LinjaZaxGesture *g = dynamic_cast(ge->gesture("LinjaZax")); + if (g) { + switch (g->zoomState()) { + case LinjaZaxGesture::ZoomingIn: + scale(1.5, 1.5); + break; + case LinjaZaxGesture::ZoomingOut: + scale(0.6, 0.6); + break; + default: + break; + }; QPoint pt = g->pos() - g->lastPos(); horizontalScrollBar()->setValue(horizontalScrollBar()->value() - pt.x()); verticalScrollBar()->setValue(verticalScrollBar()->value() - pt.y()); @@ -77,6 +91,7 @@ int main(int argc, char **argv) { QApplication app(argc, argv); QApplication::setAttribute(Qt::AA_EnableGestures); + app.addGestureRecognizer(new GestureRecognizerLinjaZax); qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); //! [0] -- cgit v0.12 _speedup'>core_8_4_win_speedup Tk is a free and open-source, cross-platform widget toolkit that provides a library of basic elements of GUI widgets for building a graphical user interface (GUI) in many programming languages.
summaryrefslogtreecommitdiffstats
blob: b8ab85f3a5d23e6d7d866f9d6aba9723f988ffce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
P6
256 256
255
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\[7 eOLjQLmSMoTMnSMlRMhPL_9 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\nSMtVMzYN~[N~[N\N\O\O]O]O]O]O\O\O}[NyYNtVM\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\G-wXN}[N]O^O_O`O`O`O`OaOaOaOaOaOaOaOaO`O_O^O\N\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\aMLyYN_OaPbPcPcPdPdPdPdPdPdPdPdPdPePePePePePdPcP_OpUM\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\wXN_OdPfPgQhQhQiQiQiQiQiQjQjQjQjQjQjQjQjQjQjQiQfP`O\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\NCJiQLbPhQkQmRnRoRoRoRoRoRoRoRoRpRpSqSqSrSrSrSqSoRjQ]O\KK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\fOLrUMcPlRqStSuTwTxTxTyTyTzTzUzUzUzUzUyTxTwTtSmRaOhPL\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\a0	cNLqUM\OfQpSwVzV|V}VVVǀVɂW̅[ՏewꪅĈgqTfQ{ZNYIK9\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\O1{G#JkRMqUMtVNiSv\dbzZvUuTsSqSnRjQeP^OrUMHh>!T4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\G-V5wE"~I#M%U+e7l:g2b*a(`(^(])^-]1S,qC$`9 R3G-\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\@)J/i>!pA"tD"wF$yH&xH&tE$wE#yG%}M+T4S5mE*Z7!K/B*;'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\aOoR{UǀVυX<(F-a: e<!h>!j@#k@$h>"d<!c=$hD-fF2[<)K0@);'5$˂VǀV|U_LKYIK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_OxTɂW֒k|X>f-^(Z'W&T&N>)F-J/b; g>#nD(jB&c<!b=%jH2_A/I0!<(8&5$JYS%8&;'?)E,<:HA=HE?IJAISFJYIKXIK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\nR}UܘqʊevUe,V&VC
@|>y<u:r9o7l6
j5
h4
g3
5$D,K/b; h>"wM1tK.e="a<#cA,U8&E-<(9&.!a0	b1	c1				

+3#@)46G<:HMCIXHK\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\U*vT~X{Yk+W&N$|>u:p8k5
f3
a0	_/	].	[-	I\*_(LkRMmSMmSMnSMnSMD,R3W5mA"|O0|P1j?"c<!a=%Y7"N1F,;'NCJNCJNDJODJODJODJh>!a: X/K%