diff --git a/src/common/notification-interface-proxy.cpp b/src/common/notification-interface-proxy.cpp
index e6d1160f1..d767bdb31 100644
--- a/src/common/notification-interface-proxy.cpp
+++ b/src/common/notification-interface-proxy.cpp
@@ -42,6 +42,7 @@ namespace gui {
namespace lumiera {
namespace facade {
using gui::ID;
+ using lib::diff::GenNode;
using lib::diff::MutationMessage;
@@ -65,6 +66,7 @@ namespace facade {
void displayInfo (Level level, string const& text) override { _i_.displayInfo (level, cStr(text)); }
void markError (ID uiElement, string const& text) override { _i_.markError(&uiElement, cStr(text)); }
void markNote (ID uiElement, string const& text) override { _i_.markNote (&uiElement, cStr(text)); }
+ void mark (ID uiElement, GenNode&& stateMark) override { _i_.mark (&uiElement, &stateMark); }
void mutate (ID uiElement, MutationMessage&& diff) override { _i_.mutate (&uiElement, &diff); }
void triggerGuiShutdown (string const& cause) override { _i_.triggerGuiShutdown (cStr(cause)); }
diff --git a/src/gui/ctrl/core-service.hpp b/src/gui/ctrl/core-service.hpp
index 8c23fc7b7..72b87e16d 100644
--- a/src/gui/ctrl/core-service.hpp
+++ b/src/gui/ctrl/core-service.hpp
@@ -39,6 +39,11 @@
** since both CoreService and Nexus are mutually interdependent from an
** operational perspective, since they exchange messages in both directions.
**
+ ** In fact, the CoreService even _holds and thus manages_ the Nexus as a
+ ** private member, while the latter controls and connects all nodes attached
+ ** to the bus at runtime, including CoreService. This crisscross arrangement
+ ** ensures sane start-up and shutdown of the whole UI-Bus compound.
+ **
** ## Bus connection and topology
** The CoreService plays a central role within the UI, since it represents
** _»the application core«_ from the UI layer's viewpoint. But it is not
@@ -103,6 +108,8 @@ namespace ctrl{
* handles those messages to be processed by centralised services:
* - commands need to be sent down to Proc-Layer
* - presentation state messages need to be recorded and acted upon.
+ * As an object, CoreService encases the heart of the UI-Bus, the
+ * \ref Nexus, and acts as "PImpl" for the gui::UiBus front-end.
*/
class CoreService
: public BusTerm
diff --git a/src/gui/ctrl/facade.hpp b/src/gui/ctrl/facade.hpp
index 6d6093d2d..ce4eafdf4 100644
--- a/src/gui/ctrl/facade.hpp
+++ b/src/gui/ctrl/facade.hpp
@@ -30,8 +30,8 @@
**
** @note GTK operates single threaded by design.
** For this reason, any call from other parts of the application need to be explicitly
- ** dispatched into the UI event loop. The external facade interfaces are defined in a way
- ** to ensure this constraint is met.
+ ** dispatched into the UI event loop. The external façade interfaces are constructed
+ ** appropriately to ensure this constraint is regarded.
**
** @see notification-service.hpp
** @see ui-manager.hpp
diff --git a/src/gui/ctrl/notification-hub.hpp b/src/gui/ctrl/notification-hub.hpp
index 96f64aa49..c380c29c7 100644
--- a/src/gui/ctrl/notification-hub.hpp
+++ b/src/gui/ctrl/notification-hub.hpp
@@ -120,7 +120,7 @@ namespace ctrl {
virtual bool
doMsg (string text) override
{
- getWidget().addMsg (text);
+ getWidget().addInfo (text);
return false; // logging is no persistent state
}
@@ -136,7 +136,6 @@ namespace ctrl {
doErr (string text) override
{
getWidget().addError (text);
- widget_->expand (true);
return false;
}
@@ -148,6 +147,17 @@ namespace ctrl {
return false; // not persistent (sticky)
}
+ /** adds special treatment for a state mark tagged as `"Warning"` */
+ virtual void
+ doMark (GenNode const& stateMark) override
+ {
+ if (stateMark.idi.getSym() == "Warning")
+ getWidget().addWarn (stateMark.data.get());
+ else
+ // forward to default handler
+ Controller::doMark (stateMark);
+ }
+
virtual void
doFlash() override
{
diff --git a/src/gui/dialog/test-control.hpp b/src/gui/dialog/test-control.hpp
index e9045c5cb..4a2796407 100644
--- a/src/gui/dialog/test-control.hpp
+++ b/src/gui/dialog/test-control.hpp
@@ -50,21 +50,12 @@
#include "lib/nocopy.hpp"
#include
-#include /////////TODO
+#include
-#if true /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1099 : WIP-WIP-WIP
-namespace proc {
- namespace asset {
- namespace meta {
- class ErrorLog;
-
- extern lib::idi::EntryID theErrorLog_ID;
-} } }
-#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1099 : WIP-WIP-WIP
namespace gui {
namespace dialog {
- using std::string; ////////////TODO
+ using std::string;
using std::forward;
using lib::diff::GenNode;
@@ -93,7 +84,7 @@ namespace dialog {
operator Gtk::Widget&() { return frame; }
void
- pack_start(Gtk::Widget& child, Gtk::PackOptions options = Gtk::PACK_EXPAND_WIDGET, guint padding = 0)
+ pack_start(Gtk::Widget& child, Gtk::PackOptions options =Gtk::PACK_EXPAND_WIDGET, guint padding =0)
{
box.pack_start (child, options, padding);
}
@@ -148,7 +139,7 @@ namespace dialog {
/**
- * A complex, tabbed-notebook style non-modal dialog window,
+ * A complex, tabbed-notebook-style non-modal dialog window,
* dedicated to development, diagnostics and experimentation.
* The TestControl can be launched from Lumiera's "Help" menu,
* offers an (passive, up-link) [UI-Bus connection](\ref ui-bus.hpp)
@@ -165,7 +156,7 @@ namespace dialog {
/**
* Ticket #1099 : perform a dummy round-trip to verify Proc-GUI integration.
- * This routine invokes the command 'xxx' down in Proc-Layer, passing the settings
+ * This routine invokes the command `test_meta_displayInfo` down in Proc-Layer, passing the settings
* from the radio buttons to select the flavour of feedback, and the text for feedback content.
* The expected behaviour is for the invoked command to send a feedback via UI-Bus towards
* the ErrorLogDisplay within the InfoboxPanel.
@@ -271,14 +262,6 @@ namespace dialog {
trig_4_.signal_clicked().connect(
[&]{ bus.act (model::commandMessage (proc::cmd::test_meta_markAction, getActionID(), getContent())); });
}
-
- void
- demoGuiRoundtrip (Bus bus, string placeholder)
- {
- TODO ("collect command arguments and then send the command message for #1099");
- ID errorLogID = proc::asset::meta::theErrorLog_ID;
- bus.mark (errorLogID, GenNode{"Message", placeholder});
- }
};
diff --git a/src/gui/model/controller.hpp b/src/gui/model/controller.hpp
index 802c47d44..a6df8f52d 100644
--- a/src/gui/model/controller.hpp
+++ b/src/gui/model/controller.hpp
@@ -100,6 +100,7 @@ namespace model {
UNIMPLEMENTED ("Controller doFlash");
}
+ protected:
/** default handler for all generic mark messages. Forwards to Tangible::doMark
* @todo is there any default implementation for special messages,
* which might be eligible as a base class implementation??
diff --git a/src/gui/notification-service.cpp b/src/gui/notification-service.cpp
index 73251c88d..529a60449 100644
--- a/src/gui/notification-service.cpp
+++ b/src/gui/notification-service.cpp
@@ -32,13 +32,20 @@
** lifespan of this service instance must exceed the running of the event loop,
** since otherwise the event loop might invoke a lambda bound to the `this`
** pointer of a NotificationService already decommissioned. The setup of the
- ** standard Lumiera UI top-level context ensures this is the case, since the
+ ** standard Lumiera UI top-level context ensures these requirements, since the
** UiManager::performMainLoop() maintains the NotificationService instance
** and also performs the blocking `gtk_main()` call. Consequently, any
** invocation added from other threads after leaving the GTK main loop
** but before closing the GuiNotification facade will just be enqueued,
** but then dropped on destruction of the UiDispatcher PImpl.
**
+ ** Beyond that dispatching functionality, the NotificationService
+ ** just serves as entry point to send messages through the [UI-Bus]
+ ** (\ref ui-bus.hpp) towards [UI elements](\ref tangible.hpp)
+ ** identified by EntryID. Even notifications and error messages
+ ** are handled this way, redirecting them toward a dedicated
+ ** [Log display](\ref error-log-display.hpp)
+ **
** @see ui-dispatcher.hpp
**
*/
@@ -53,6 +60,7 @@
#include "lib/diff/mutation-message.hpp"
#include "lib/diff/gen-node.hpp"
#include "include/logging.h"
+#include "lib/format-string.hpp"
#include "lib/depend.hpp"
#include "lib/util.hpp"
@@ -60,6 +68,7 @@ extern "C" {
#include "common/interface-descriptor.h"
}
+#include
#include
@@ -68,8 +77,11 @@ using lib::diff::TreeMutator;
using lib::diff::MutationMessage;
using gui::ctrl::UiDispatcher;
using gui::ctrl::BusTerm;
-using std::string;
using util::cStr;
+using util::_Fmt;
+
+using std::string;
+using std::move;
namespace gui {
@@ -84,19 +96,29 @@ namespace gui {
{
dispatch_->event ([=]()
{
- this->mark (uiElement, uiMessage);
+ ctrl::BusTerm::mark (uiElement, uiMessage);
});
}
- void
+ void
NotificationService::displayInfo (NotifyLevel severity, string const& text)
- {
- INFO (gui, "@GUI: display '%s' as notification message.", cStr(text));
- ID errorLogID = interact::Wizard::getErrorLogID();
- ////////////////////////TODO actually push the information to the GUI ///////////////////////////////////TICKET #1102 : build a message display box in the UI
- ////////////////////////////////////////////////TICKET #1047 : as a temporary solution, use the InfoBox panel...
- }
+ { ///////////////////////////////////TICKET #1102 : build a dedicated message display box in the UI
+ ID errorLogID = interact::Wizard::getErrorLogID(); ////////////////////////////////////TICKET #1047 : as a temporary solution, use the InfoBox panel...
+ switch (severity) {
+ case NOTE_ERROR:
+ markError (errorLogID, text);
+ break;
+ case NOTE_INFO:
+ markNote (errorLogID, text);
+ break;
+ case NOTE_WARN:
+ mark (errorLogID, GenNode{"Warning", text});
+ break;
+ default:
+ throw lumiera::error::Logic (_Fmt{"UI Notification with invalid severity %d encountered. "
+ "Given message text was '%s'"} % severity % text);
+ } }
void
@@ -107,18 +129,24 @@ namespace gui {
void
- NotificationService::markNote (ID uiElement, string const& text)
+ NotificationService::markNote (ID uiElement, string const& text)
{
dispatchMsg (uiElement, GenNode{"Message", text});
}
+ void
+ NotificationService::mark (ID uiElement, GenNode&& stateMarkMsg)
+ {
+ dispatchMsg (uiElement, move (stateMarkMsg));
+ }
+
+
void
NotificationService::mutate (ID uiElement, MutationMessage&& diff)
{
- dispatch_->event ([=]() //////////////////////////////////TODO care for error handling!!!
- {
- // apply and consume diff message stored within closure
+ dispatch_->event ([=]()
+ { // apply and consume diff message stored within closure
this->change (uiElement, move(unConst(diff)));
});
}
@@ -247,6 +275,14 @@ namespace gui {
_instance().markNote (*static_cast (element), text);
}
)
+ , LUMIERA_INTERFACE_INLINE (mark,
+ void, (const void* element, void* stateMark),
+ {
+ if (!_instance) lumiera_error_set (LUMIERA_ERROR_LIFECYCLE, "passing state mark");
+ else
+ _instance().mark (*static_cast (element), move(*reinterpret_cast (stateMark)));
+ }
+ )
, LUMIERA_INTERFACE_INLINE (mutate,
void, (const void* element, void* diff),
{
@@ -265,9 +301,7 @@ namespace gui {
)
);
-
-
- } // (END) facade implementation details
+ } //(END) facade implementation details
diff --git a/src/gui/notification-service.hpp b/src/gui/notification-service.hpp
index 20ea60c9f..b3390fa5c 100644
--- a/src/gui/notification-service.hpp
+++ b/src/gui/notification-service.hpp
@@ -27,11 +27,12 @@
** events within the lower layers, or as result of invoking commands on the session.
**
** This service is the implementation of a layer separation facade interface. Clients should use
- ** gui::GuiNotification#facade to access this service. This header defines the interface used
- ** to \em provide this service, not to access it.
- **
- ** @see gui::GuiFacade
- ** @see core-sevice.hpp starting this service
+ ** gui::GuiNotification#facade to access this service. This header here defines the interface
+ ** used to _provide_ this service, not to access it.
+ **
+ ** @see gui::GuiFacade launching the Lumiera UI
+ ** @see facade.hpp RAII holder to start this service and open the interface
+ ** @see gui::ctrl::UiManager::performMainLoop() exposes all UI façade interfaces
*/
@@ -100,10 +101,11 @@ namespace gui {
void displayInfo (NotifyLevel,string const& text) override;
void markError (ID uiElement, string const& text) override;
void markNote (ID uiElement, string const& text) override;
+ void mark (ID uiElement, GenNode&&) override;
void mutate (ID uiElement, MutationMessage&&) override;
void triggerGuiShutdown (string const& cause) override;
};
-
+
} // namespace gui
diff --git a/src/gui/widget/error-log-display.hpp b/src/gui/widget/error-log-display.hpp
index aba28a069..2d8361e46 100644
--- a/src/gui/widget/error-log-display.hpp
+++ b/src/gui/widget/error-log-display.hpp
@@ -152,9 +152,16 @@ namespace widget {
/** just add normal information message to buffer,
* without special markup and without expanding the widget */
void
- addMsg (string text)
+ addInfo (string text)
{
- showMsg (NOTE_INFO, text);
+ addEntry (text);
+ }
+
+ /** add an information message, formatted more prominent as warning */
+ void
+ addWarn (string text)
+ {
+ addEntry ("WARNING: "+text, TAG_WARN);
}
/** present an error notification prominently.
@@ -167,7 +174,10 @@ namespace widget {
void
addError (string text)
{
- showMsg (NOTE_ERROR, text);
+ errorMarks_.emplace_back(
+ addEntry ("ERROR: "+text, TAG_ERROR));
+ if (not expand.isExpanded())
+ expand (true);
}
void
@@ -202,7 +212,7 @@ namespace widget {
* [GTKmm tutorial]: https://developer.gnome.org/gtkmm-tutorial/stable/sec-textview-buffer.html.en#textview-marks
* [insert-mark]: https://developer.gnome.org/gtkmm/3.22/classGtk_1_1TextMark.html#details
*/
- auto
+ Mark
addEntry (string const& text, Literal markupTagName =nullptr)
{
auto buff = textLog_.get_buffer();
@@ -216,26 +226,6 @@ namespace widget {
textLog_.scroll_to (cursor);
return cursor;
}
-
- void
- showMsg (NotifyLevel severity, string const& text)
- {
- //////////////////////////////////////////////////TICKET #1102 : add formatting according to the error level
- switch (severity) {
- case NOTE_ERROR:
- errorMarks_.emplace_back(
- addEntry ("ERROR: "+text, TAG_ERROR));
- if (not expand.isExpanded())
- expand (true);
- break;
- case NOTE_WARN:
- addEntry ("WARN: "+text, TAG_WARN);
- break;
- default:
- addEntry (text);
- break;
- }
- }
};
diff --git a/src/include/gui-notification-facade.h b/src/include/gui-notification-facade.h
index 6babf13f7..2eca7f2bc 100644
--- a/src/include/gui-notification-facade.h
+++ b/src/include/gui-notification-facade.h
@@ -53,6 +53,7 @@
namespace gui {
using std::string;
+ using lib::diff::GenNode;
using lib::diff::MutationMessage;
using ID = lib::idi::BareEntryID const&;
@@ -69,7 +70,7 @@ namespace gui {
* from the lower layers into the Lumiera GUI. Typically, this happens
* asynchronously and triggered by events within the lower layers.
*
- * This is a layer separation facade interface. Clients should use
+ * This is a layer separation façade interface. Clients should use
* the embedded #facade factory, which yields a proxy routing any
* calls through the lumieraorg_GuiNotification interface
* @throws lumiera::error::State when interface is not opened
@@ -93,6 +94,9 @@ namespace gui {
/** attach an warning or state information element */
virtual void markNote (ID uiElement, string const& text) =0;
+ /** send a generic _state mark_ message to some element */
+ virtual void mark (ID uiElement, GenNode&& stateMark) =0;
+
/** push a diff message up into the user interface.
* @remark this is the intended way how to populate or
* manipulate the contents of the user interface from
@@ -131,6 +135,7 @@ LUMIERA_INTERFACE_DECLARE (lumieraorg_GuiNotification, 0,
LUMIERA_INTERFACE_SLOT (void, displayInfo, (uint, const char*)),
LUMIERA_INTERFACE_SLOT (void, markError, (const void*, const char*)), ////////////TICKET #1175 : need a way to pass EntryID
LUMIERA_INTERFACE_SLOT (void, markNote, (const void*, const char*)),
+ LUMIERA_INTERFACE_SLOT (void, mark, (const void*, void*)),
LUMIERA_INTERFACE_SLOT (void, mutate, (const void*, void*)),
LUMIERA_INTERFACE_SLOT (void, triggerGuiShutdown, (const char*)),
);
diff --git a/src/proc/cmd/meta-cmd.cpp b/src/proc/cmd/meta-cmd.cpp
index 2369fda9b..6bed40e8c 100644
--- a/src/proc/cmd/meta-cmd.cpp
+++ b/src/proc/cmd/meta-cmd.cpp
@@ -40,9 +40,10 @@
//#include "proc/mobject/session.hpp"
#include "include/gui-notification-facade.h"
#include "gui/interact/wizard.hpp" //////////////////////////////////////////////////////////////TICKET #1099 : include needed temporarily
-//#include "lib/symbol.hpp"
+#include "lib/diff/gen-node.hpp"
#include "lib/idi/entry-id.hpp"
#include "lib/format-string.hpp" //////////////////////////////////////////////////////////////TICKET #1099 : include needed temporarily
+//#include "lib/symbol.hpp"
#include
@@ -53,6 +54,7 @@ using gui::NOTE_WARN;
using gui::NOTE_ERROR;
using gui::NotifyLevel;
using gui::GuiNotification;
+using lib::diff::GenNode;
//using util::cStr;
using util::_Fmt; //////////////////////////////////////////////////////////////TICKET #1099 : include needed temporarily
using std::string;
@@ -209,7 +211,7 @@ COMMAND_DEFINITION (test_meta_markAction)
def.operation ([](string actionID, string message)
{
ID errorLogID = gui::interact::Wizard::getErrorLogID();
- UNIMPLEMENTED ("GuiNotification::facade().mark (errorLogID, actionID, message);");
+ GuiNotification::facade().mark (errorLogID, GenNode{actionID, message});
})
.captureUndo ([](string actionID, string message) -> string
{
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index 70f4b52e4..7336c44ce 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -213,9 +213,9 @@
-
+
-
+
@@ -329,7 +329,8 @@
-
+
+
@@ -373,6 +374,10 @@
+
+
+
+
@@ -417,7 +422,7 @@
-
+
@@ -515,9 +520,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ zwar sind die Fasaden offen, bevor die Main-Loop läuft,
+
+
+ jedoch werden genau durch diese Fasaden alle Aktionen per Dispatch
+
+
+ in die GTK-Loop übertragen. Und das kann nur in der Loop selber passieren.
+
+
+ Ein zu früher bzw. zu später Aufruf "fällt einfach hinten runter"
+
+
+
+
+
@@ -589,8 +621,8 @@
-
-
+
+
@@ -859,38 +891,38 @@
-
-
-
+
+
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
@@ -905,14 +937,14 @@
-
-
+
+
-
+
-
+
@@ -920,24 +952,24 @@
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
@@ -950,38 +982,38 @@
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
@@ -1002,34 +1034,34 @@
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -1081,7 +1113,7 @@
-
+
@@ -1135,15 +1167,15 @@
-
+
-
+
-
-
+
+
@@ -1155,7 +1187,7 @@
-
+
@@ -1167,7 +1199,7 @@
-
+
@@ -1180,34 +1212,34 @@
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
+
+
+
+
+
-
+
-
+
@@ -1221,16 +1253,16 @@
-
+
-
-
-
+
+
+
-
-
-
+
+
+
@@ -1243,9 +1275,9 @@
-
-
-
+
+
+
@@ -1257,7 +1289,7 @@
-
+
@@ -1275,7 +1307,7 @@
-
+
@@ -1287,31 +1319,31 @@
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -1330,7 +1362,7 @@
-
+
@@ -1344,29 +1376,55 @@
-
+
+
+
+
+
+
+
+
+
+
+ Habe nochmal alle Aufrufe im Einzelnen durchgeprüft
+
+
+ -
+ wenn schon das Einfügen des Funktors vor dem Dispatch wirft (out of memory),
dann bekommt der Aufrufer diese Exception, was typischerweise tödlich ist.
+
+ -
+ aber alles, was innerhalb dieses Funktors passiert, wird abgefangen und geloggt.
+
+
+
+ mehr erscheint mir nicht sinnvoll; behandeln kann man solche Fehler ohnehin nicht.
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -1384,9 +1442,9 @@
-
+
-
+
@@ -1419,46 +1477,46 @@
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -1466,13 +1524,13 @@
-
-
-
-
+
+
+
+
-
-
+
+
@@ -1485,13 +1543,13 @@
-
-
-
+
+
+
-
+
@@ -1499,7 +1557,7 @@
-
+
@@ -1515,6 +1573,9 @@
+
+
+
@@ -1607,11 +1668,11 @@
-
+
-
+
@@ -1699,26 +1760,26 @@
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
@@ -1728,22 +1789,22 @@
-
-
+
+
-
+
-
+
-
+
-
+
@@ -1756,25 +1817,24 @@
wäre es nicht sinnvoller, sie direkt auf das API zu heben?
-
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
@@ -1787,19 +1847,19 @@
-
+
-
+
-
+
@@ -1810,15 +1870,15 @@
-
+
-
-
-
+
+
+
-
+
@@ -1925,150 +1985,150 @@
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
@@ -2078,119 +2138,118 @@
YAGNI
-
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
@@ -2198,19 +2257,19 @@
-
+
-
+
-
+
-
+
-
+
@@ -2231,11 +2290,11 @@
-
+
-
+
-
+
@@ -2250,7 +2309,7 @@
-
+
@@ -2264,43 +2323,43 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -2489,12 +2548,12 @@
-
+
-
+
-
+
@@ -2510,7 +2569,7 @@
-
+
@@ -2521,23 +2580,23 @@
-
+
-
+
-
+
-
+
-
+
-
+
@@ -2558,57 +2617,57 @@
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -2625,27 +2684,27 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -2670,21 +2729,21 @@
-
+
-
+
-
+
-
+
-
+
-
+
@@ -2702,33 +2761,33 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -2741,131 +2800,138 @@
-
+
-
-
-
-
+
-
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
-
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-