diff --git a/research/SConscript b/research/SConscript index 4df559f6a..5e4b2d481 100644 --- a/research/SConscript +++ b/research/SConscript @@ -4,7 +4,7 @@ ## Things defined here usuall won't be installed ## -Import('env core support_lib') +Import('env envGtk core support_lib') @@ -12,9 +12,14 @@ envR = env.Clone() envR.Append(CPPPATH='research') # envR.Append(CCFLAGS=' -O3 ') +envRGtk = envGtk.Clone() +envRGtk.Append(CPPPATH='research') + # build additional test and administrative tools.... experiments = [ envR.Program('try', ['try.cpp'] + core) #### to try out some feature... - , envR.Program('clang-static-init', ['clang-static-init-1.cpp', 'clang-static-init-2.cpp']) + , envR.Program('clang-static-init', ['clang-static-init-1.cpp', 'clang-static-init-2.cpp']) + + , envRGtk.Program('gtk-canvas-experiment', ['gtk-canvas-experiment.cpp', 'gtk-canvas-main.cpp'] + core) ] # diff --git a/research/gtk-canvas-experiment.cpp b/research/gtk-canvas-experiment.cpp new file mode 100644 index 000000000..272ffe9ef --- /dev/null +++ b/research/gtk-canvas-experiment.cpp @@ -0,0 +1,375 @@ +/* + GtkCanvasExperiment - Explore capabilities of the GTK canvas widget + + Copyright (C) Lumiera.org + 2016, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +/** @file gtk-canvas-experiment.cpp + ** Implementation of gtk canvas experiments. + ** + ** @todo as of 10/2016 this is WIP-WIP-WIP : canvas widgets experiment + ** @todo as of 10/2018 we start to build a new timeline widget, connected to the UI-Bus + ** @see timeline-widget.hpp + ** + */ + + +#include "gtk-canvas-experiment.hpp" + +//#include "gui/workspace/workspace-window.hpp" +#include "lib/format-string.hpp" +#include "lib/format-cout.hpp" + +//#include "lib/util.hpp" +#include +#include +#include + + + +using util::_Fmt; +//using std::shared_ptr; +//using std::weak_ptr; +//using util::contains; +using Gtk::Widget; +using sigc::mem_fun; +using sigc::ptr_fun; +using std::string; +using std::rand; +using std::max; + + +namespace gui { +namespace panel { + + + + TimelinePanel::TimelinePanel () + : Box{} + , twoParts_(Gtk::ORIENTATION_VERTICAL) + , buttons_() + , frame_("Gtk::Layout Experiments") + , scroller_() + , canvas_() + { + twoParts_.pack_start(buttons_, Gtk::PACK_SHRINK); + twoParts_.pack_start(frame_); + + buttons_.set_layout(Gtk::BUTTONBOX_START); + + // buttons to trigger experiments + button_1_.set_label("_place"); + button_1_.set_use_underline(); + button_1_.set_tooltip_markup("Experiment 1:\nplace new child widget\nat random position on the canvas"); + button_1_.signal_clicked().connect( + mem_fun(*this, &TimelinePanel::experiment_1)); + buttons_.add(button_1_); + + button_2_.set_label("_move"); + button_2_.set_use_underline(); + button_2_.set_tooltip_markup("Experiment 2:\nmove all child widgets randomly"); + button_2_.signal_clicked().connect( + mem_fun(*this, &TimelinePanel::experiment_2)); + buttons_.add(button_2_); + + button_3_.set_label("a_lign"); + button_3_.set_use_underline(); + button_3_.set_tooltip_markup("Experiment 3:\nalign all child widgets in a row\nwith silight random vertical offset"); + button_3_.signal_clicked().connect( + mem_fun(*this, &TimelinePanel::experiment_3)); + buttons_.add(button_3_); + + button_4_.set_label("_grow"); + button_4_.set_use_underline(); + button_4_.set_tooltip_markup("Experiment 4:\nextend arbitrary child widget's text"); + button_4_.signal_clicked().connect( + mem_fun(*this, &TimelinePanel::experiment_4)); + buttons_.add(button_4_); + + button_5_.set_label("_kill"); + button_5_.set_use_underline(); + button_5_.set_tooltip_markup("Experiment 5:\nkill arbitrary child widget"); + button_5_.signal_clicked().connect( + mem_fun(*this, &TimelinePanel::experiment_5)); + buttons_.add(button_5_); + + toggleDraw_.set_label("draw"); + toggleDraw_.signal_clicked().connect( + [this]() { + canvas_.enableDraw (this->toggleDraw_.get_active()); + }); + buttons_.add(toggleDraw_); + //(End)buttons... + + frame_.add(scroller_); + frame_.set_border_width(5); + + scroller_.set_shadow_type(Gtk::SHADOW_NONE); + scroller_.set_border_width(10); + scroller_.add(canvas_); + + canvas_.adjustSize(); + + // show everything.... + this->add(twoParts_); + this->show_all(); + } + + const char* + TimelinePanel::getTitle() + { + return _("Timeline"); + } + + const gchar* + TimelinePanel::getStockID() + { + return "panel_timeline"; + } + + + + void + TimelinePanel::experiment_1() + { + frame_.set_label("Experiment 1... PLACE"); + + ChildEx* chld = makeChld(); + childz_.push_back(chld); + uint x = rand() % 1000; + uint y = rand() % 500; + canvas_.put(*chld, x, y); + chld->show(); + canvas_.adjustSize(); + } + + + void + TimelinePanel::experiment_2() + { + frame_.set_label("Experiment 2... MOVE"); + for (Widget* chld : childz_) + { + uint x = canvas_.child_property_x(*chld); + uint y = canvas_.child_property_y(*chld); + int deltaX = -20 + rand() % 41; + int deltaY = -15 + rand() % 31; + x = uint(max (0, int(x) + deltaX)); + y = uint(max (0, int(y) + deltaY)); + + canvas_.move (*chld, x,y); + } + canvas_.adjustSize(); + } + + + void + TimelinePanel::experiment_3() + { + frame_.set_label("Experiment 3... ALIGN"); + uint pos=0; + for (Widget* chld : childz_) + { + uint y = rand() % 30; + canvas_.move (*chld, pos, y); + + int width = chld->get_allocated_width(); + pos += 0.6 * width; + } + canvas_.adjustSize(); + } + + + void + TimelinePanel::experiment_4() + { + frame_.set_label("Experiment 4... GROW"); + uint selector = rand() % childz_.size(); + ChildEx& toGrow = *childz_[selector]; + toGrow.set_label ("***"+toGrow.get_label()+"***"); + } + + + void + TimelinePanel::experiment_5() + { + frame_.set_label("Experiment 5... KILL"); + uint killPos = rand() % childz_.size(); + ChildV::iterator killThat(&childz_[killPos]); + ChildEx* victim = *killThat; + childz_.erase (killThat); + canvas_.remove (*victim); + delete victim; + } + + + void + Canvas::enableDraw (bool yes) + { + shallDraw_ = yes; + + // force redrawing of the visible area... + auto win = get_window(); + if (win) + { + int w = get_allocation().get_width(); + int h = get_allocation().get_height(); + Gdk::Rectangle rect{0, 0, w, h}; + win->invalidate_rect(rect, false); + } + } + + + + void + Canvas::adjustSize() + { + recalcExtension_ = true; + } + + void + Canvas::determineExtension() + { + if (not recalcExtension_) return; + + uint extH=20, extV=20; + Gtk::Container::ForeachSlot callback + = [&](Gtk::Widget& chld) + { + auto alloc = chld.get_allocation(); + uint x = alloc.get_x(); + uint y = alloc.get_y(); + x += alloc.get_width(); + y += alloc.get_height(); + extH = max (extH, x); + extV = max (extV, y); + }; + foreach(callback); + recalcExtension_ = false; + set_size (extH, extV); + } + + + bool + Canvas::on_draw(Cairo::RefPtr const& cox) + { + if (shallDraw_) + { + uint extH, extV; + determineExtension(); + get_size (extH, extV); + + auto adjH = get_hadjustment(); + auto adjV = get_vadjustment(); + double offH = adjH->get_value(); + double offV = adjV->get_value(); + + cox->save(); + cox->translate(-offH, -offV); + + // draw red diagonal line + cox->set_source_rgb(0.8, 0.0, 0.0); + cox->set_line_width (10.0); + cox->move_to(0, 0); + cox->line_to(extH, extV); + cox->stroke(); + cox->restore(); + + // cause child widgets to be redrawn + bool event_is_handled = Gtk::Layout::on_draw(cox); + + // any drawing which follows happens on top of child widgets... + cox->save(); + cox->translate(-offH, -offV); + + cox->set_source_rgb(0.2, 0.4, 0.9); + cox->set_line_width (2.0); + cox->rectangle(0,0, extH, extV); + cox->stroke(); + cox->restore(); + + return event_is_handled; + } + else + return Gtk::Layout::on_draw(cox); + } + + + /* === Support for Investigation === */ + + namespace { + _Fmt childID("Chld-%02d"); + + int instanceCnt = 0; + } + + + uint ChildEx::childNo = 0; + + + ChildEx::ChildEx() + : Gtk::Button(string (childID % childNo++)) + { + ++instanceCnt; + } + + + void + ChildEx::on_clicked() + { + cout << "|=="< 0) + cout << " ↯↯ still "< + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +/** @file gtk-canvas-experiment.hpp + ** A custom widget using a canvas to draw and to place widgets. + ** + ** ## planned design 2/2017 + ** The architecture of the UI is in a state of transition right now, working towards the goal + ** of interconnected layers and an operative session and engine. Within the new control structure + ** about to be built, there is an UI top-level circle of managing entities to handle global concerns + ** and actions. The ctrl::InteractionDirector incorporates the role of _model root_ and thus manages + ** a collection of timelines. The timeline panel exposes this collection and allows to view and + ** interact with one of the given timelines. The build-up of the timeline display and thus the + ** initiative to expose a timeline comes from the interaction director -- but as usual with + ** graphical user interfaces, any user interaction after this point is handled autonomously + ** by the gui::timeline::TimelineWidget and gui::timeline::TimelineController + ** + ** @todo as of 10/2016 this is WIP-WIP-WIP : canvas widgets experiment + ** @todo as of 10/2018 we start to build a new timeline widget, connected to the UI-Bus + */ + + +#ifndef RESEARCH_GTK_CANVAS_EXPERIMENT_H +#define RESEARCH_GTK_CANVAS_EXPERIMENT_H + +#include "gui/gtk-base.hpp" + +//#include +#include + + + +namespace gui { +namespace model{ + class Sequence; + } +namespace panel { + +//using std::shared_ptr; + + /** + * "experimental" child widget for investigation of Gtk::Layout + */ + class ChildEx + : public Gtk::Button + { + static uint childNo; + + public: + ChildEx(); + ~ChildEx(); + + private: + void on_clicked() override; + }; + + void __verifyDeadChildren(); + + + + /** + * "experimental" custom canvas, based on Gtk::Layout. + * In addition this customised widget supports direct drawing + */ + class Canvas + : public Gtk::Layout + { + bool shallDraw_; + bool recalcExtension_ = false; + + public: + void enableDraw (bool); + void adjustSize(); + + private: + virtual bool on_draw (Cairo::RefPtr const&) override; + + void determineExtension(); + }; + + + + /** + * Dockable panel to hold timeline widget(s). + * @todo build the actual implementation, after finishing the investigation + * + * ## Investigation of gtk::GtkLayout + * As of 10/2016, we start this task with an exploration of GTK behaviour + * + * \par Plan of investigation + * 1. place some simple widgets (Buttons) ✔ + * 2. learn how to draw ✔ + * 3. place a huge number of widgets, to scrutinise scrolling and performance + * 4. place widgets overlapping and irregularly, beyond the scrollable area ✔ + * 5. bind signals to those widgets, to verify event dispatching ✔ + * 6. bind some further signal(s) to the ~GtkLayout container + * 7. hide and re-show a partially and a totally overlapped widget + * 8. find a way to move a widget ✔ and delete arbitrary widgets ✔ + * 9. expand an existing widget (text change) ✔ + * 10. build a custom "clip" widget + * 11. retrofit all preceding tests to use this "clip" widget + */ + class TimelinePanel + : public Gtk::Box + { + public: + /** + * @param panel_manager The owner panel manager widget. + * @param dock_item The GdlDockItem that will host this panel. + */ + TimelinePanel(); + + + static const char* getTitle(); + static const gchar* getStockID(); + + + private: + Gtk::Box twoParts_; + Gtk::ButtonBox buttons_; + Gtk::Button button_1_; + Gtk::Button button_2_; + Gtk::Button button_3_; + Gtk::Button button_4_; + Gtk::Button button_5_; + Gtk::CheckButton toggleDraw_; + Gtk::Frame frame_; + Gtk::ScrolledWindow scroller_; + Canvas canvas_; + + ChildEx* makeChld(); + + using ChildV = std::vector; + ChildV childz_; + + void experiment_1(); + void experiment_2(); + void experiment_3(); + void experiment_4(); + void experiment_5(); + }; + + +}}// namespace gui::panel +#endif /*RESEARCH_GTK_CANVAS_EXPERIMENT_H*/ diff --git a/research/gtk-canvas-main.cpp b/research/gtk-canvas-main.cpp new file mode 100644 index 000000000..db0dce685 --- /dev/null +++ b/research/gtk-canvas-main.cpp @@ -0,0 +1,44 @@ +/* + gtk-canvas-main.cpp - demo application to explore the abilities of Gtk::Canvas + + Copyright (C) Lumiera.org + 2018, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +/** @file gtk-canvas-main.cpp + ** Simple GTK Application frame to explore canvas handling. + */ + + +#include "gui/gtk-base.hpp" +#include "gtk-canvas-experiment.hpp" +#include "lib/error.hpp" + + +namespace { +} + + + +int +main (int argc, const char* argv[]) +{ + NOTICE (main, "*** GTK-Canvas Experiment ***"); + + return 0; +} diff --git a/src/SConscript b/src/SConscript index b21a72d23..34cccabb0 100644 --- a/src/SConscript +++ b/src/SConscript @@ -38,13 +38,12 @@ plugins = [] # currently none # the Lumiera GTK GUI envGtk = env.Clone() envGtk.mergeConf(['gtkmm-3.0','sigc++-2.0','gthread-2.0','cairomm-1.0','gdl','xv','x11','xext','sm']) -envGtk.Append(LIBS=core) -guimodule = envGtk.LumieraPlugin('gtk_gui', srcSubtree('gui'), install=True) +guimodule = envGtk.LumieraPlugin('gtk_gui', srcSubtree('gui') + core, install=True) gui = ( guimodule + icons + [env.GuiResource(f) for f in env.Glob('gui/*.css')] ) -Export('lumiera core core_lib app_lib backend_lib support_lib plugins guimodule gui') +Export('lumiera core core_lib app_lib backend_lib support_lib plugins envGtk guimodule gui') diff --git a/src/common/option.cpp b/src/common/option.cpp index ce59d986b..268bfa63b 100644 --- a/src/common/option.cpp +++ b/src/common/option.cpp @@ -56,7 +56,7 @@ namespace lumiera { * @todo describe the actual options */ Option::Option (lib::Cmdline& cmdline) - : syntax("Lumiera, the non linear video editor. Supported parameters"), + : syntax("Lumiera, the non linear video editor.\nSupported parameters"), parameters() { syntax.add_options() @@ -64,7 +64,7 @@ namespace lumiera { ("session,f", op::value(), "session file to load (UNIMPLEMENTED)") ("script,s", op::value(), - "execute the given LUA script (UNIMPLEMENTED)") + "execute the given script (UNIMPLEMENTED)") ("headless", op::bool_switch(), "start without GUI") ("port,p", op::value(), diff --git a/src/gui/panel/timeline-panel.cpp b/src/gui/panel/timeline-panel.cpp index 698e8b344..462148208 100644 --- a/src/gui/panel/timeline-panel.cpp +++ b/src/gui/panel/timeline-panel.cpp @@ -25,7 +25,7 @@ ** Implementation of the dockable panel to hold the main timeline display. ** ** @todo as of 10/2016 this is WIP-WIP-WIP : canvas widgets experiment - ** @todo build a new timeline widget, connected to the UI-Bus + ** @todo as of 10/2018 we start to build a new timeline widget, connected to the UI-Bus ** @see timeline-widget.hpp ** */ @@ -54,8 +54,6 @@ using Gtk::Widget; using sigc::mem_fun; using sigc::ptr_fun; using std::string; -using std::cout; -using std::endl; using std::rand; using std::max; diff --git a/src/gui/panel/timeline-panel.hpp b/src/gui/panel/timeline-panel.hpp index df1fdc366..e93bdddcf 100644 --- a/src/gui/panel/timeline-panel.hpp +++ b/src/gui/panel/timeline-panel.hpp @@ -36,7 +36,7 @@ ** by the gui::timeline::TimelineWidget and gui::timeline::TimelineController ** ** @todo as of 10/2016 this is WIP-WIP-WIP : canvas widgets experiment - ** @todo build a new timeline widget, connected to the UI-Bus + ** @todo as of 10/2018 we start to build a new timeline widget, connected to the UI-Bus */ diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 7f9f9ecc6..30f3dc6c2 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -5774,8 +5774,9 @@ - + + @@ -5864,7 +5865,7 @@ - + @@ -5885,7 +5886,7 @@ - + @@ -6007,7 +6008,8 @@ - + + @@ -6024,8 +6026,9 @@ - - + + + @@ -6037,7 +6040,7 @@ - + @@ -6096,7 +6099,7 @@ - + @@ -6163,7 +6166,8 @@ - + + @@ -6316,7 +6320,7 @@ - + @@ -6378,15 +6382,16 @@ - + + - + @@ -6417,7 +6422,7 @@ - + @@ -6468,8 +6473,10 @@ - + + + @@ -6491,7 +6498,7 @@ - + @@ -6515,7 +6522,7 @@ - + @@ -6700,7 +6707,7 @@ - + @@ -6788,9 +6795,9 @@ - + - + @@ -7201,7 +7208,7 @@ - + @@ -7613,7 +7620,7 @@ - + @@ -7676,7 +7683,7 @@ - + @@ -8262,7 +8269,7 @@ - + @@ -12207,7 +12214,7 @@ - + @@ -15943,7 +15950,7 @@ - + @@ -16144,7 +16151,7 @@ - + @@ -16336,8 +16343,8 @@ - - + + @@ -16448,7 +16455,7 @@ - + @@ -16697,8 +16704,9 @@ - + + @@ -17005,7 +17013,8 @@ - + + @@ -17090,7 +17099,7 @@ - + @@ -18578,7 +18587,7 @@ - + @@ -18889,7 +18898,7 @@ - + @@ -18922,9 +18931,9 @@ - - - + + + @@ -19011,7 +19020,7 @@ - + @@ -19431,7 +19440,7 @@ - + @@ -19910,14 +19919,14 @@ - - - + + + - + @@ -20079,7 +20088,7 @@ - + @@ -20280,7 +20289,7 @@ - + @@ -26278,7 +26287,7 @@ - + @@ -26326,7 +26335,7 @@ - + @@ -26342,7 +26351,7 @@ - + @@ -26444,7 +26453,7 @@ - + @@ -26603,7 +26612,7 @@ - + @@ -26627,7 +26636,7 @@ - + @@ -27190,7 +27199,7 @@ - + @@ -27313,7 +27322,7 @@ - + @@ -27375,7 +27384,7 @@ - + @@ -27400,7 +27409,7 @@ - + @@ -27503,7 +27512,7 @@ - + @@ -27579,7 +27588,7 @@ - + @@ -27598,6 +27607,7 @@ + @@ -27614,7 +27624,7 @@ - + @@ -27629,10 +27639,11 @@ + - + @@ -27654,6 +27665,10 @@ + + + + @@ -27792,7 +27807,7 @@ - + @@ -27801,7 +27816,7 @@ - + @@ -27810,7 +27825,7 @@ - + @@ -27821,7 +27836,7 @@ - + @@ -27839,7 +27854,7 @@ - + @@ -27849,7 +27864,7 @@ - + @@ -27922,7 +27937,7 @@ - + @@ -27986,7 +28001,7 @@ - + @@ -28154,7 +28169,7 @@ - + @@ -28292,7 +28307,7 @@ - + @@ -28563,8 +28578,8 @@ - - + + @@ -28665,7 +28680,7 @@ - + @@ -28833,7 +28848,7 @@ - + @@ -29030,7 +29045,7 @@ - + @@ -29256,7 +29271,7 @@ - + @@ -29376,13 +29391,13 @@ - + - + @@ -29525,7 +29540,7 @@ - + @@ -29545,11 +29560,11 @@ - - + + - + @@ -29571,7 +29586,7 @@ - + @@ -29625,7 +29640,7 @@ - + @@ -29700,7 +29715,7 @@ - + @@ -29767,7 +29782,7 @@ - + @@ -29815,7 +29830,7 @@ - + @@ -29881,7 +29896,7 @@ - + @@ -30055,7 +30070,7 @@ - + @@ -30187,7 +30202,7 @@ - + @@ -30357,7 +30372,7 @@ - + @@ -30387,12 +30402,12 @@ - - + + - + @@ -30587,7 +30602,7 @@ - + @@ -30774,7 +30789,7 @@ - + @@ -30793,7 +30808,7 @@ - + @@ -30803,14 +30818,14 @@ - + - + @@ -30818,7 +30833,7 @@ - + @@ -30992,7 +31007,7 @@ - + @@ -31174,7 +31189,7 @@ - + @@ -31867,10 +31882,10 @@ - + - + @@ -32026,7 +32041,8 @@ - + + @@ -32061,8 +32077,9 @@ - - + + + @@ -32119,7 +32136,7 @@ - + @@ -32193,7 +32210,7 @@ - + @@ -32231,8 +32248,31 @@ - - + + + + + + +

+ seit längerer Zeit ein Thema, +

+

+ für das ich verschiedene Lösungen ausprobiere +

+
    +
  • + IterExplorer : erster Anlauf, etwas schief +
  • +
  • + TreeExplorer : Pipeline-Builder, vielversprechend +
  • +
+ + +
+ + @@ -32274,7 +32314,7 @@ - + @@ -32455,7 +32495,7 @@ - + @@ -34584,8 +34624,8 @@ - - + + @@ -34593,27 +34633,45 @@ - - + + + + - + + + + + + +

+ Frühjahr 2018 komplett überarbeitet. +

+

+ Lösung scheint nun "rund" zu sein +

+ + +
+ - + + - + - + @@ -34638,7 +34696,7 @@ - + @@ -34699,8 +34757,9 @@ - - + + + @@ -34714,7 +34773,7 @@ - + @@ -34852,7 +34911,7 @@ - + @@ -34907,7 +34966,7 @@ - + @@ -35423,7 +35482,7 @@ - + @@ -36040,7 +36099,7 @@ - + @@ -36115,7 +36174,7 @@ - + @@ -36223,7 +36282,7 @@ - + @@ -36321,7 +36380,7 @@ - + @@ -36900,7 +36959,7 @@ - + @@ -37181,7 +37240,7 @@ - + @@ -37265,7 +37324,8 @@ - + + @@ -37510,8 +37570,8 @@ - - + + @@ -37594,7 +37654,7 @@ - + @@ -37793,7 +37853,7 @@ - + @@ -37850,7 +37910,7 @@ - + @@ -38004,7 +38064,7 @@ - + @@ -38080,8 +38140,8 @@ - - + + @@ -38093,7 +38153,7 @@ - +