From 7aa91a2cd4497f68ebf5b9dd85b5f2c791f738a1 Mon Sep 17 00:00:00 2001 From: Claudio Sacerdoti Coen Date: Fri, 1 Dec 2000 11:39:24 +0000 Subject: [PATCH] other files missing in 20001129 --- .../applications/browser/Makefile | 41 + .../applications/browser/README | 18 + .../applications/browser/TODO | 4 + .../applications/browser/editor.ml | 101 ++ .../applications/browser/file.ml | 13 + .../applications/browser/lexical.ml | 155 ++ .../applications/browser/list2.ml | 25 + .../applications/browser/shell.ml | 255 +++ .../applications/browser/text.ml | 16 + .../applications/browser/useunix.ml | 36 + .../applications/browser/widgets.ml | 34 + .../applications/radtest/CHANGES | 16 + .../applications/radtest/Makefile | 86 + .../applications/radtest/README | 24 + .../applications/radtest/aspectframe.xpm | 33 + .../applications/radtest/button.xpm | 33 + .../applications/radtest/checkbutton.xpm | 33 + .../applications/radtest/clist.xpm | 30 + .../applications/radtest/colorselection.xpm | 35 + .../applications/radtest/combo.xpm | 34 + .../applications/radtest/common.mli | 27 + .../applications/radtest/entry.xpm | 33 + .../applications/radtest/eventbox.xpm | 34 + .../applications/radtest/fixed.xpm | 31 + .../applications/radtest/frame.xpm | 33 + .../applications/radtest/gToolbar2.ml | 65 + .../applications/radtest/gTree2.ml | 78 + .../applications/radtest/gTree2.mli | 73 + .../applications/radtest/gtkTree2.ml | 82 + .../applications/radtest/gtktree2.c | 1385 +++++++++++++++++ .../applications/radtest/gtktree2.h | 139 ++ .../applications/radtest/gtktreeitem2.c | 1110 +++++++++++++ .../applications/radtest/gtktreeitem2.h | 91 ++ .../applications/radtest/handlebox.xpm | 34 + .../applications/radtest/hbox.xpm | 31 + .../applications/radtest/hbuttonbox.xpm | 33 + .../applications/radtest/hseparator.xpm | 31 + .../applications/radtest/label.xpm | 30 + .../applications/radtest/load_lexer.mll | 46 + .../applications/radtest/load_parser.mly | 56 + .../applications/radtest/main.ml | 393 +++++ .../applications/radtest/ml_gtk2.c | 124 ++ .../applications/radtest/notebook.xpm | 33 + .../applications/radtest/pixmap.xpm | 39 + .../applications/radtest/property.ml | 175 +++ .../applications/radtest/property.mli | 96 ++ .../applications/radtest/propwin.ml | 180 +++ .../applications/radtest/propwin.mli | 10 + .../applications/radtest/radiobutton.xpm | 33 + .../applications/radtest/scrolledwindow.xpm | 30 + .../applications/radtest/spinbutton.xpm | 33 + .../applications/radtest/statusbar.xpm | 34 + .../applications/radtest/tiBase.ml | 671 ++++++++ .../applications/radtest/tiBin.ml | 185 +++ .../applications/radtest/tiButton.ml | 372 +++++ .../applications/radtest/tiContainer.ml | 92 ++ .../applications/radtest/tiEdit.ml | 153 ++ .../applications/radtest/tiList.ml | 66 + .../applications/radtest/tiMisc.ml | 176 +++ .../applications/radtest/tiPack.ml | 300 ++++ .../applications/radtest/tiWidget.ml | 43 + .../applications/radtest/tiWindow.ml | 117 ++ .../applications/radtest/togglebutton.xpm | 33 + .../applications/radtest/toolbar.xpm | 33 + .../applications/radtest/tree_minus.xpm | 18 + .../applications/radtest/tree_plus.xpm | 18 + .../applications/radtest/utils.ml | 353 +++++ .../applications/radtest/vbox.xpm | 31 + .../applications/radtest/vbuttonbox.xpm | 33 + .../applications/radtest/viewport.xpm | 34 + .../applications/radtest/vseparator.xpm | 31 + .../applications/radtest/window.xpm | 38 + .../applications/unison/README | 10 + .../lablgtk_20001129-0.1.0/doc/formula.eps | 409 +++++ .../lablgtk_20001129-0.1.0/doc/lablgtk.mgp | 558 +++++++ .../examples/GL/morph3d.ml | 607 ++++++++ .../examples/GL/planet.ml | 125 ++ .../examples/GL/simple.ml | 33 + .../lablgtk_20001129-0.1.0/examples/README | 17 + .../examples/buttons.ml | 26 + .../lablgtk_20001129-0.1.0/examples/calc.ml | 114 ++ .../examples/calendar.ml | 21 + .../lablgtk_20001129-0.1.0/examples/clist.ml | 51 + .../lablgtk_20001129-0.1.0/examples/combo.ml | 23 + .../lablgtk_20001129-0.1.0/examples/csview.ml | 155 ++ .../examples/dcalendar.ml | 247 +++ .../examples/drawing.ml | 19 + .../lablgtk_20001129-0.1.0/examples/editor.ml | 101 ++ .../lablgtk_20001129-0.1.0/examples/entry.ml | 48 + .../lablgtk_20001129-0.1.0/examples/events.ml | 25 + .../examples/fifteen.ml | 97 ++ .../examples/fixed_editor.ml | 279 ++++ .../examples/fixpoint.ml | 30 + .../lablgtk_20001129-0.1.0/examples/hello.ml | 18 + .../lablgtk_20001129-0.1.0/examples/image.ml | 67 + .../examples/image256x256.rgb | 19 + .../examples/kaimono.ml | 130 ++ .../lablgtk_20001129-0.1.0/examples/label.ml | 48 + .../examples/lissajous.ml | 48 + .../examples/nihongo.ml | 31 + .../lablgtk_20001129-0.1.0/examples/pousse.ml | 199 +++ .../examples/progressbar.ml | 51 + .../examples/radiobuttons.ml | 39 + .../lablgtk_20001129-0.1.0/examples/rpn.ml | 129 ++ .../examples/scrolledwin.ml | 35 + .../lablgtk_20001129-0.1.0/examples/socket.ml | 16 + .../lablgtk_20001129-0.1.0/examples/test.xpm | 92 ++ .../examples/testdnd.ml | 510 ++++++ .../examples/testgtk.ml | 1140 ++++++++++++++ .../examples/testinput.ml | 43 + .../examples/tictactoe.ml | 113 ++ .../lablgtk_20001129-0.1.0/examples/tron.ml | 204 +++ .../examples/xmhtml/test.ml | 38 + 113 files changed, 14406 insertions(+) create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/Makefile create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/README create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/TODO create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/editor.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/file.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/lexical.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/list2.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/shell.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/text.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/useunix.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/widgets.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/CHANGES create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/Makefile create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/README create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/aspectframe.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/button.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/checkbutton.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/clist.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/colorselection.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/combo.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/common.mli create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/entry.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/eventbox.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/fixed.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/frame.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gToolbar2.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gTree2.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gTree2.mli create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtkTree2.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktree2.c create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktree2.h create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktreeitem2.c create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktreeitem2.h create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/handlebox.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/hbox.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/hbuttonbox.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/hseparator.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/label.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/load_lexer.mll create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/load_parser.mly create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/main.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/ml_gtk2.c create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/notebook.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/pixmap.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/property.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/property.mli create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/propwin.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/propwin.mli create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/radiobutton.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/scrolledwindow.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/spinbutton.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/statusbar.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiBase.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiBin.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiButton.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiContainer.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiEdit.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiList.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiMisc.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiPack.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiWidget.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiWindow.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/togglebutton.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/toolbar.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tree_minus.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tree_plus.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/utils.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/vbox.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/vbuttonbox.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/viewport.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/vseparator.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/window.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/unison/README create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/doc/formula.eps create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/doc/lablgtk.mgp create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/morph3d.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/planet.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/simple.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/README create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/buttons.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/calc.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/calendar.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/clist.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/combo.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/csview.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/dcalendar.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/drawing.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/editor.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/entry.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/events.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/fifteen.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/fixed_editor.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/fixpoint.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/hello.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/image.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/image256x256.rgb create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/kaimono.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/label.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/lissajous.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/nihongo.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/pousse.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/progressbar.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/radiobuttons.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/rpn.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/scrolledwin.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/socket.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/test.xpm create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/testdnd.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/testgtk.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/testinput.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/tictactoe.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/tron.ml create mode 100644 helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/xmhtml/test.ml diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/Makefile b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/Makefile new file mode 100644 index 000000000..8822e4738 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/Makefile @@ -0,0 +1,41 @@ +# $Id$ +# Makefile for lablgtk. + +all: browser + +CAMLC = ocamlc +CAMLOPT = ocamlopt +COMPILER = $(CAMLC) $(MLFLAGS) -labels -w s -c +LINKER = $(CAMLC) $(MLFLAGS) +COMPOPT = $(CAMLOPT) $(MLFLAGS) -labels -w s -c +LINKOPT = $(CAMLOPT) $(MLFLAGS) + +RANLIB = ranlib + +include ../../config.make + +MLFLAGS = -I ../.. -I ocaml-src/utils -I ocaml-src/parsing + +# Rules +.SUFFIXES: .ml .mli .cmo .cmi .cmx .c .o .var .h .opt .def +.ml.cmo: + $(COMPILER) $< +.mli.cmi: + $(COMPILER) $< +.ml.cmx: + $(COMPOPT) $< + +# Targets +MLOBJS = text.cmo file.cmo lexical.cmo shell.cmo editor.cmo + +browser: $(MLOBJS) + $(LINKER) -o $@ toplevellib.cma str.cma unix.cma \ + lablgtk.cma $(MLOBJS) + +clean: + rm -f *.cm* browser + +.depend: + ocamldep *.ml *.mli > .depend + +include .depend diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/README b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/README new file mode 100644 index 000000000..f2ed1ec2e --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/README @@ -0,0 +1,18 @@ + Browser: the beginning of a port of the OCamlBrowser + +Installation: + +* make a link from a directory where the O'Caml distribution is + compiled to ocaml-src + ln -s /path/to/ocaml-3.00 ocaml-src + (actually only the directory parsing needs to be compiled) + +* just type "make" + +Use: + +When you run browser, you just get a customized editor with lexical +coloring. Nothing very fancy. +In the file menu you can open a shell, running olabl as subprocess. + +Jacques Garrigue diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/TODO b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/TODO new file mode 100644 index 000000000..0c8bb5357 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/TODO @@ -0,0 +1,4 @@ +* lexical coloring (done) +* hyperlinks (call signal with position) +* keyboard popup +* protection diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/editor.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/editor.ml new file mode 100644 index 000000000..d4adbfbc7 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/editor.ml @@ -0,0 +1,101 @@ +(* $Id$ *) + +open GMain + +class editor ?packing ?show () = + let text = GEdit.text ~editable:true ?packing ?show () in +object (self) + inherit GObj.widget text#as_widget + + val mutable filename = None + + method text = text + + method load_file name = + try + let ic = open_in name in + filename <- Some name; + text#freeze (); + text#delete_text ~start:0 ~stop:text#length; + let buf = String.create 1024 and len = ref 0 in + while len := input ic ~buf ~pos:0 ~len:1024; !len > 0 do + if !len = 1024 then text#insert buf + else text#insert (String.sub buf ~pos:0 ~len:!len) + done; + text#set_point 0; + text#thaw (); + close_in ic + with _ -> () + + method open_file () = File.dialog ~title:"Open" ~callback:self#load_file () + + method save_file () = + File.dialog ~title:"Save" ?filename () ~callback: + begin fun name -> + try + if Sys.file_exists name then Sys.rename ~src:name ~dst:(name ^ "~"); + let oc = open_out name in + output_string oc (text#get_chars ~start:0 ~stop:text#length); + close_out oc + with _ -> prerr_endline "Save failed" + end +end + +open GdkKeysyms + +class editor_window ?(show=false) () = + let window = GWindow.window ~width:500 ~height:300 + ~title:"Program Editor" () in + let vbox = GPack.vbox ~packing:window#add () in + + let menubar = GMenu.menu_bar ~packing:vbox#pack () in + let factory = new GMenu.factory menubar in + let accel_group = factory#accel_group + and file_menu = factory#add_submenu "File" + and edit_menu = factory#add_submenu "Edit" + and comp_menu = factory#add_submenu "Compiler" in + + let hbox = GPack.hbox ~packing:vbox#add () in + let scrollbar = + GRange.scrollbar `VERTICAL ~packing:(hbox#pack ~from:`END) () + and editor = new editor ~packing:hbox#add () in +object (self) + inherit GObj.widget window#as_widget + + method window = window + method editor = editor + method show = window#show + + initializer + window#connect#destroy ~callback:Main.quit; + let factory = new GMenu.factory file_menu ~accel_group in + factory#add_item "Open..." ~key:_O ~callback:editor#open_file; + factory#add_item "Save..." ~key:_S ~callback:editor#save_file; + factory#add_item "Shell" + ~callback:(fun () -> Shell.f ~prog:"ocaml" ~title:"Objective Caml Shell"); + factory#add_separator (); + factory#add_item "Quit" ~key:_Q ~callback:window#destroy; + let factory = new GMenu.factory edit_menu ~accel_group in + factory#add_item "Copy" ~key:_C ~callback:editor#text#copy_clipboard; + factory#add_item "Cut" ~key:_X ~callback:editor#text#cut_clipboard; + factory#add_item "Paste" ~key:_V ~callback:editor#text#paste_clipboard; + factory#add_separator (); + factory#add_check_item "Word wrap" ~active:false + ~callback:editor#text#set_word_wrap; + factory#add_check_item "Read only" ~active:false + ~callback:(fun b -> editor#text#set_editable (not b)); + let factory = new GMenu.factory comp_menu ~accel_group in + factory#add_item "Lex" ~key:_L + ~callback:(fun () -> Lexical.tag editor#text); + window#add_accel_group accel_group; + editor#text#set_vadjustment scrollbar#adjustment; + if show then self#show () +end + +let _ = + Main.init (); + if Array.length Sys.argv >= 2 && Sys.argv.(1) = "-shell" then + Shell.f ~prog:"ocaml" ~title:"Objective Caml Shell" + else + ignore (new editor_window ~show:true ()); + Main.main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/file.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/file.ml new file mode 100644 index 000000000..e9c0cf34f --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/file.ml @@ -0,0 +1,13 @@ +(* $Id$ *) + +let dialog ~title ~callback ?filename () = + let sel = + GWindow.file_selection ~title ~modal:true ?filename () in + sel#cancel_button#connect#clicked ~callback:sel#destroy; + sel#ok_button#connect#clicked ~callback: + begin fun () -> + let name = sel#get_filename in + sel#destroy (); + callback name + end; + sel#show () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/lexical.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/lexical.ml new file mode 100644 index 000000000..9acb9c060 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/lexical.ml @@ -0,0 +1,155 @@ +(* $Id$ *) + +open Parser + +type tags = [`none|`control|`define|`structure|`char|`infix|`label|`uident] + +let colors : (tags * GDraw.color) list Lazy.t = + lazy + (List.map ~f:(fun (tag,col) -> tag, `COLOR (GDraw.color (`NAME col))) + [ `control, "blue"; + `define, "forestgreen"; + `structure, "purple"; + `char, "gray40"; + `infix, "indianred4"; + `label, "brown"; + `uident, "midnightblue"; + `none, "black" ]) + +let tag ?(start=0) ?stop:pend (tw : GEdit.text) = + let pend = Gaux.default tw#length ~opt:pend in + let colors = Lazy.force colors in + tw#freeze (); + let position = tw#position + and text = tw#get_chars ~start ~stop:pend in + let replace ~start:pstart ~stop:pend ~tag = + if pend > pstart then begin + tw#delete_text ~start:(start+pstart) ~stop:(start+pend); + tw#set_point (start+pstart); + tw#insert ~foreground:(List.assoc tag colors) + (String.sub text ~pos:pstart ~len:(pend-pstart)); + end + and next_lf = ref (-1) in + let colorize ~start:rstart ~stop:rend ~tag = + let rstart = ref rstart in + while !rstart < rend do + if !next_lf < !rstart then begin + try next_lf := String.index_from text !rstart '\n' + with Not_found -> next_lf := pend-start + end; + replace ~start:!rstart ~stop:(min !next_lf rend) ~tag; + rstart := !next_lf + 1 + done + in + let buffer = Lexing.from_string text + and last = ref (EOF, 0, 0) + and last_pos = ref 0 in + try + while true do + let token = Lexer.token buffer + and start = Lexing.lexeme_start buffer + and stop = Lexing.lexeme_end buffer in + let tag = + match token with + AMPERAMPER + | AMPERSAND + | BARBAR + | DO | DONE + | DOWNTO + | ELSE + | FOR + | IF + | LAZY + | MATCH + | OR + | THEN + | TO + | TRY + | WHEN + | WHILE + | WITH + -> `control + | AND + | AS + | BAR + | CLASS + | CONSTRAINT + | EXCEPTION + | EXTERNAL + | FUN + | FUNCTION + | FUNCTOR + | IN + | INHERIT + | INITIALIZER + | LET + | METHOD + | MODULE + | MUTABLE + | NEW + | OF + | PARSER + | PRIVATE + | REC + | TYPE + | VAL + | VIRTUAL + -> `define + | BEGIN + | END + | INCLUDE + | OBJECT + | OPEN + | SIG + | STRUCT + -> `structure + | CHAR _ + | STRING _ + -> `char + | BACKQUOTE + | INFIXOP1 _ + | INFIXOP2 _ + | INFIXOP3 _ + | INFIXOP4 _ + | PREFIXOP _ + | QUESTION2 + | SHARP + -> `infix + | LABEL _ + | OPTLABEL _ + | QUESTION + | TILDE + -> `label + | UIDENT _ -> `uident + | LIDENT _ -> + begin match !last with + (QUESTION | TILDE), _, _ -> `label + | _ -> `none + end + | COLON -> + begin match !last with + LIDENT _, lstart, lstop when lstop = start -> + colorize ~tag:`none ~start:!last_pos ~stop:lstart; + colorize ~tag:`label ~start:lstart ~stop; + last_pos := stop; + `none + | _ -> `none + end + | EOF -> raise End_of_file + | _ -> `none + in + if tag <> `none then begin + colorize ~tag:`none ~start:!last_pos ~stop:start; + colorize ~tag ~start ~stop; + last_pos := stop + end; + last := (token, start, stop) + done + with exn -> + colorize ~tag:`none ~start:!last_pos ~stop:(pend-start); + tw#thaw (); + tw#set_position position; + tw#set_point position; + match exn with + End_of_file | Lexer.Error _ -> () + | _ -> raise exn diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/list2.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/list2.ml new file mode 100644 index 000000000..0d7798a6a --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/list2.ml @@ -0,0 +1,25 @@ +(* $Id$ *) + +let rec cut l ~len = + if len <= 0 then [], l else + match l with + a::l -> + let l1, l2 = cut l ~len:(len-1) in + a::l1, l2 + | [] -> + invalid_arg "cut_list" + +let rec chop l ~len = + if l = [] then [] else + let l1, l2 = + try cut_list l ~len + with Invalid_argument _ -> l, [] + in + l1 :: chop l2 ~len + + +let rec iteri_aux ~f:f ~i = function + [] -> () + | a::l -> f ~i a; iteri_aux ~f:f ~i:(i+1) l + +let iteri = iteri_aux ~i:0 diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/shell.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/shell.ml new file mode 100644 index 000000000..fbe0f92a0 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/shell.ml @@ -0,0 +1,255 @@ +(* $Id$ *) + +open GdkKeysyms +open Printf + +(* Nice history class. May reuse *) + +class ['a] history () = object + val mutable history = ([] : 'a list) + val mutable count = 0 + method empty = history = [] + method add s = count <- 0; history <- s :: history + method previous = + let s = List.nth history count in + count <- (count + 1) mod List.length history; + s + method next = + let l = List.length history in + count <- (l + count - 1) mod l; + List.nth history ((l + count - 1) mod l) +end + +(* The shell class. Now encapsulated *) + +let protect f x = try f x with _ -> () + +class shell ~prog ~args ~env ?packing ?show () = + let (in2,out1) = Unix.pipe () + and (in1,out2) = Unix.pipe () + and (err1,err2) = Unix.pipe () in + let _ = List.iter ~f:Unix.set_nonblock [out1;in1;err1] in +object (self) + val textw = GEdit.text ~editable:true ?packing ?show () + val pid = Unix.create_process_env + ~prog ~args ~env ~stdin:in2 ~stdout:out2 ~stderr:err2 + val out = Unix.out_channel_of_descr out1 + val h = new history () + val mutable alive = true + val mutable reading = false + val mutable input_start = 0 + method text = textw + method alive = alive + method kill () = + textw#set_editable false; + if alive then begin + alive <- false; + protect close_out out; + List.iter ~f:(protect Unix.close) [in1; err1; in2; out2; err2]; + try + Unix.kill ~pid ~signal:Sys.sigkill; + Unix.waitpid pid ~mode:[]; () + with _ -> () + end + method interrupt () = + if alive then try + reading <- false; + Unix.kill ~pid ~signal:Sys.sigint + with Unix.Unix_error _ -> () + method send s = + if alive then try + output_string out s; + flush out + with Sys_error _ -> () + method private read ~fd ~len = + try + let buf = String.create len in + let len = Unix.read fd ~buf ~pos:0 ~len in + if len > 0 then begin + textw#set_position textw#length; + self#insert (String.sub buf ~pos:0 ~len); + input_start <- textw#position; + end; + len + with Unix.Unix_error _ -> 0 + method history (dir : [`next|`previous]) = + if not h#empty then begin + if reading then begin + textw#delete_text ~start:input_start ~stop:textw#position; + end else begin + reading <- true; + input_start <- textw#position + end; + self#insert (if dir = `previous then h#previous else h#next); + end + val mutable lexing = false + method private lex ~start ~stop:e = + if not lexing && start < e then begin + lexing <- true; + Lexical.tag textw ~start ~stop:e; + lexing <- false + end + method insert ?(lex=true) text = + let start = Text.line_start textw in + textw#insert text; + if lex then self#lex ~start ~stop:(Text.line_end textw) + method private keypress c = + if not reading & c > " " then begin + reading <- true; + input_start <- textw#position + end + method private return () = + if reading then reading <- false + else input_start <- textw#position; + textw#set_position (Text.line_end textw); + let s = textw#get_chars ~start:input_start ~stop:textw#position in + h#add s; + self#send s; + self#send "\n" + method private paste () = + if not reading then begin + reading <- true; + input_start <- textw#position; + end + initializer + textw#event#connect#key_press ~callback: + begin fun ev -> + if GdkEvent.Key.keyval ev = _Return && GdkEvent.Key.state ev = [] + then self#return () + else self#keypress (GdkEvent.Key.string ev); + false + end; + textw#connect#after#insert_text ~callback: + begin fun s ~pos -> + if not lexing then + self#lex ~start:(Text.line_start textw ~pos:(pos - String.length s)) + ~stop:(Text.line_end textw ~pos) + end; + textw#connect#after#delete_text ~callback: + begin fun ~start:pos ~stop -> + if not lexing then + self#lex ~start:(Text.line_start textw ~pos) + ~stop:(Text.line_end textw ~pos) + end; + textw#event#connect#button_press ~callback: + begin fun ev -> + if GdkEvent.Button.button ev = 2 then self#paste (); + false + end; + textw#connect#destroy ~callback:self#kill; + GMain.Timeout.add ~ms:100 ~callback: + begin fun () -> + if alive then begin + List.iter [err1;in1] + ~f:(fun fd -> while self#read ~fd ~len:1024 = 1024 do () done); + true + end else false + end; + () +end + +(* Specific use of shell, for LablBrowser *) + +let shells : (string * shell) list ref = ref [] + +(* Called before exiting *) +let kill_all () = + List.iter !shells ~f:(fun (_,sh) -> if sh#alive then sh#kill ()); + shells := [] +let _ = at_exit kill_all + +let get_all () = + let all = List.filter !shells ~f:(fun (_,sh) -> sh#alive) in + shells := all; + all + +let may_exec prog = + try Unix.access prog ~perm:[Unix.X_OK]; true + with Unix.Unix_error _ -> false + +let f ~prog ~title = + let progargs = + List.filter ~f:((<>) "") (Str.split ~sep:(Str.regexp " ") prog) in + if progargs = [] then () else + let prog = List.hd progargs in + let path = try Sys.getenv "PATH" with Not_found -> "/bin:/usr/bin" in + let exec_path = Str.split ~sep:(Str.regexp":") path in + let prog = + if not (Filename.is_implicit prog) then + if may_exec prog then prog else "" + else + List.fold_left exec_path ~init:"" ~f: + begin fun acc dir -> + if acc <> "" then acc else + let prog = Filename.concat dir prog in + if may_exec prog then prog else acc + end + in + if prog = "" then () else + let reg = Str.regexp "TERM=" in + let env = Array.map (Unix.environment ()) ~f: + begin fun s -> + if Str.string_match ~pat:reg s ~pos:0 then "TERM=dumb" else s + end in + let load_path = + List.flatten (List.map !Config.load_path ~f:(fun dir -> ["-I"; dir])) in + let args = Array.of_list (progargs @ load_path) in + let current_dir = ref (Unix.getcwd ()) in + + let tl = GWindow.window ~title ~width:500 ~height:300 () in + let vbox = GPack.vbox ~packing:tl#add () in + let menus = GMenu.menu_bar ~packing:vbox#pack () in + let f = new GMenu.factory menus in + let accel_group = f#accel_group in + let file_menu = f#add_submenu "File" + and history_menu = f#add_submenu "History" + and signal_menu = f#add_submenu "Signal" in + + let hbox = GPack.hbox ~packing:vbox#add () in + let sh = new shell ~prog ~env ~args ~packing:hbox#add () in + let sb = + GRange.scrollbar `VERTICAL ~adjustment:sh#text#vadjustment + ~packing:hbox#pack () + in + + let f = new GMenu.factory file_menu ~accel_group in + f#add_item "Use..." ~callback: + begin fun () -> + File.dialog ~title:"Use File" ~filename:(!current_dir ^ "/") () ~callback: + begin fun name -> + current_dir := Filename.dirname name; + if Filename.check_suffix name ".ml" then + let cmd = "#use \"" ^ name ^ "\";;\n" in + sh#insert cmd; + sh#send cmd + end + end; + f#add_item "Load..." ~callback: + begin fun () -> + File.dialog ~title:"Load File" ~filename:(!current_dir ^ "/") () ~callback: + begin fun name -> + current_dir := Filename.dirname name; + if Filename.check_suffix name ".cmo" or + Filename.check_suffix name ".cma" + then + let cmd = Printf.sprintf "#load \"%s\";;\n" name in + sh#insert cmd; + sh#send cmd + end + end; + f#add_item "Import path" ~callback: + begin fun () -> + List.iter (List.rev !Config.load_path) + ~f:(fun dir -> sh#send (sprintf "#directory \"%s\";;\n" dir)) + end; + f#add_item "Close" ~key:_W ~callback:tl#destroy; + + let h = new GMenu.factory history_menu ~accel_group ~accel_modi:[`MOD1] in + h#add_item "Previous" ~key:_P ~callback:(fun () -> sh#history `previous); + h#add_item "Next" ~key:_N ~callback:(fun () -> sh#history `next); + let s = new GMenu.factory signal_menu ~accel_group in + s#add_item "Interrupt" ~key:_G ~callback:sh#interrupt; + s#add_item "Kill" ~callback:sh#kill; + shells := (title, sh) :: !shells; + tl#add_accel_group accel_group; + tl#show () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/text.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/text.ml new file mode 100644 index 000000000..729f3105a --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/text.ml @@ -0,0 +1,16 @@ +(* $Id$ *) + +open GEdit + +let line_start ?pos (text : GEdit.text) = + let pos = Gaux.default text#position ~opt:pos in + if pos = 0 then 0 else + let start = max 0 (pos-256) in + let buffer = text#get_chars ~start ~stop:pos in + try start + String.rindex buffer '\n' with Not_found -> 0 + +let line_end ?pos (text : GEdit.text) = + let pos = Gaux.default text#position ~opt:pos in + if pos = text#length then text#length else + let buffer = text#get_chars ~start:pos ~stop:(min text#length (pos+256)) in + try pos + String.index buffer '\n' with Not_found -> text#length diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/useunix.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/useunix.ml new file mode 100644 index 000000000..c4860a8ca --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/useunix.ml @@ -0,0 +1,36 @@ +(* $Id$ *) + +open Unix + +let get_files_in_directory dir = + try + let dirh = opendir dir in + let rec get_them () = + try + let x = readdir dirh in + x :: get_them () + with + _ -> closedir dirh; [] + in + Sort.list ~order:(<) (get_them ()) + with Unix_error _ -> [] + +let is_directory name = + try + (stat name).st_kind = S_DIR + with _ -> false + +let get_directories_in_files ~path = + List.filter ~pred:(fun x -> is_directory (path ^ "/" ^ x)) + +(************************************************** Subshell call *) +let subshell ~cmd = + let rc = open_process_in ~cmd in + let rec it () = + try + let x = input_line rc in x :: it () + with _ -> [] + in + let answer = it () in + close_process_in rc; + answer diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/widgets.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/widgets.ml new file mode 100644 index 000000000..c27ca9fbb --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/browser/widgets.ml @@ -0,0 +1,34 @@ +(* $Id$ *) + +open GObj + +class multibox ~rows ~columns ?(row_view = rows) ?(col_view = columns) + ?packing ?show () = + let sw = + GBin.scrolled_window ~hpolicy:`AUTOMATIC ~vpolicy:`AUTOMATIC + ?show ?packing () in + let vp = GBin.viewport ~shadow_type:`NONE ~packing:sw#add in + let table = + GPack.table ~columns ~rows ~homogeneous:true ~packing:vp#add () in + let buttons = + Array.init ~len:columns + ~f:(fun left -> Array.init ~len:rows + ~f:(fun top -> GButton.button + ~packing:(table#attach ~top ~left ~expand:`BOTH))) + in + object (self) + inherit widget sw#as_widget + method cell ~col ~row = buttons.(col).(row) + initializer + let id = ref None in + id := Some + (sw#event#connect#expose ~after:true ~callback: + begin fun _ -> + may !id ~f:sw#connect#disconnect; + let height = table#misc#allocation.height * row_view / rows + and width = table#misc#allocation.width * col_view / columns in + vp#misc#set_size ~height ~width; + false + end); + table#focus#set_vadjustment vp#vadjustment + end diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/CHANGES b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/CHANGES new file mode 100644 index 000000000..e87fc0a9a --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/CHANGES @@ -0,0 +1,16 @@ +$Id$ + +2000.05.15 + * suppressed treew.ml; replaced by ti*.ml + * new widgets + * less known bugs (Hubert) +1999.10.28 + * re-objectified property.ml + * split it into common.mli/property.ml/propwin.ml + * undo is back + * restructure menu code in main.ml + +1999.10.27 + * simplified property.ml, and corrected treew.ml accordingly. + undo is temporarily disabled. + (Jacques) \ No newline at end of file diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/Makefile b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/Makefile new file mode 100644 index 000000000..175eca980 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/Makefile @@ -0,0 +1,86 @@ +# $Id$ +# Makefile for lablgtk. + +all: radtest + +CAMLC = ocamlc +CAMLOPT = ocamlopt +COMPILER = $(CAMLC) $(MLFLAGS) -c +LINKER = $(CAMLC) $(MLFLAGS) +COMPOPT = $(CAMLOPT) $(MLFLAGS) -c +LINKOPT = $(CAMLOPT) $(MLFLAGS) + +RANLIB = ranlib + +include ../../config.make + +MLFLAGS = -I ../.. -w s -labels + +ifdef DEBUG +CFLAGS = -g $(GTKCFLAGS) +MLFLAGS += -g +else +CFLAGS = -O -DGTK_NO_CHECK_CASTS -DGTK_DISABLE_COMPAT_H $(GTKCFLAGS) +endif + +ifdef USE_CC +CCOMPILER = $(CC) -c -I$(LIBDIR) $(CFLAGS) +else +CCOMPILER = ocamlc -c -ccopt "$(CFLAGS)" +endif + + +# Rules +.SUFFIXES: .ml .mli .cmo .cmi .cmx .c .o .var .h .opt .def +.c.o: + $(CCOMPILER) $< +.ml.cmo: + $(COMPILER) $< +.mli.cmi: + $(COMPILER) $< +.ml.cmx: + $(COMPOPT) $< + +# Targets +MLOBJS = utils.cmo property.cmo propwin.cmo \ + load_parser.cmo load_lexer.cmo tiBase.cmo tiContainer.cmo tiBin.cmo \ + tiButton.cmo tiEdit.cmo tiList.cmo tiMisc.cmo tiPack.cmo tiWindow.cmo \ + tiWidget.cmo main.cmo + +MLSRC = common.mli utils.ml property.mli property.ml propwin.mli \ + propwin.ml \ + load_parser.ml load_lexer.ml tiBase.ml tiContainer.ml tiBin.ml \ + tiButton.ml tiEdit.ml tiList.ml tiMisc.ml tiPack.ml tiWindow.ml \ + tiWidget.ml main.ml + +radtest: $(MLOBJS) libgtk2.a gtk2.cma + $(LINKER) -o $@ lablgtk.cma gtkInit.cmo -I . gtk2.cma \ + $(MLOBJS) + +radtestopt: $(MLOBJS:.cmo=.cmx) libgtk2.a gtk2.cmxa + $(LINKOPT) -o $@ lablgtk.cmxa gtkInit.cmx -I . gtk2.cmxa \ + $(MLOBJS:.cmo=.cmx) + +%.mli %.ml: %.mly + ocamlyacc $< + +%.ml: %.mll + ocamllex $< + +libgtk2.a: gtktree2.o gtktreeitem2.o ml_gtk2.o + ar rc $@ gtktree2.o gtktreeitem2.o ml_gtk2.o + $(RANLIB) $@ + +gtk2.cma: gtkTree2.cmo gTree2.cmo gToolbar2.cmo libgtk2.a + $(LINKER) -a -o $@ gtkTree2.cmo gTree2.cmo gToolbar2.cmo -cclib -lgtk2 + +gtk2.cmxa: gtkTree2.cmx gTree2.cmx gToolbar2.cmx libgtk2.a + $(LINKOPT) -a -o $@ gtkTree2.cmx gTree2.cmx gToolbar2.cmx -cclib -lgtk2 + +clean: + rm -f *.cm* *.o *.a radtest *_parser.ml *_parser.mli *_lexer.ml + +.depend: $(MLSRC) load_parser.ml load_lexer.ml + ocamldep $(MLSRC) load_parser.ml* load_lexer.ml* > .depend + +include .depend diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/README b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/README new file mode 100644 index 000000000..aedd81fff --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/README @@ -0,0 +1,24 @@ + Lablgtk RADTEST + +Author: Hubert Fauque, hubert.fauque@inria.fr + +This is an experimental R.A.D. for Lablgtk. +You can compile it simply by make. + + +When radtest starts a new empty project is open; +you can add new windows to this project by clicking on +the window icon at the top of the icons window; + +by clicking on an item in the tree window with the third button +you can add or remove widgets; +you can also drag widgets from the icons window and drop them +on the tree; + +when a widget is selected (click on it in the tree) you can +move it up or down (if its parent is a box) with CTRL-up_arrow +or CTRL-down_arrow; with up_arrow and down_arrow you select +the widget which is above or below the currently selected widget; + +Save the project by Project->Save, and load an already existing +project by Project->Open. diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/aspectframe.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/aspectframe.xpm new file mode 100644 index 000000000..66b9ca14d --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/aspectframe.xpm @@ -0,0 +1,33 @@ +/* XPM */ +static char *aspectframe_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 6 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray100", +"+ c None", +/* pixels */ +"+++++++++++++++++++++", +"+++++ + +++++++++++", +"+...X X X X......O+", +"+.OOX X X XOOOOO.O+", +"+.OXX X X XXXXXX.O+", +"+.OXXXXXXXXXXXXXXX.O+", +"+.OXXXXXXX.XXXXXXX.O+", +"+.OXXXXXX...XXXXXX.O+", +"+.OXXXXX.X.X.XXXXX.O+", +"+.OXXXXXXX.XXXXXXX.O+", +"+.OXX.XXXX.XXXX.XX.O+", +"+.OX.XXXXX.XXXXX.X.O+", +"+.O................O+", +"+.OX.XXXXX.XXXXX.X.O+", +"+.OXX.XXXX.XXXX.XX.O+", +"+.OXXXXX.X.X.XXXXX.O+", +"+.OXXXXXX...XXXXXX.O+", +"+.OXXXXXXX.XXXXXXX.O+", +"+..................O+", +"+OOOOOOOOOOOOOOOOOOO+", +"+++++++++++++++++++++" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/button.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/button.xpm new file mode 100644 index 000000000..62ebc3074 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/button.xpm @@ -0,0 +1,33 @@ +/* XPM */ +static char *button_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 6 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray100", +"+ c None", +/* pixels */ +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+OOOOOOOOOOOOOOOOOO +", +"+OXXXXXXXXXXXXXXXX. +", +"+OXXXXXXXXXXXXXXXX. +", +"+OXXX XXX XXX XX. +", +"+OXX XXX XX XX XXX. +", +"+OXX XXX XX X XXXX. +", +"+OXX XXX XX XXXXX. +", +"+OXX XXX XX X XXXX. +", +"+OXX XXX XX XX XXX. +", +"+OXXX XXX XXX XX. +", +"+OXXXXXXXXXXXXXXXX. +", +"+OXXXXXXXXXXXXXXXX. +", +"+OXXXXXXXXXXXXXXXX. +", +"+O................. +", +"+ +", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/checkbutton.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/checkbutton.xpm new file mode 100644 index 000000000..314ba97ce --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/checkbutton.xpm @@ -0,0 +1,33 @@ +/* XPM */ +static char *checkbutton_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 6 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray100", +"+ c None", +/* pixels */ +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++OOOOOOOOOOO+++++", +"+++++OXXXXXXXXX +++++", +"+++++OXXXXXXXX. +++++", +"+++++OXXXXXXXX. +++++", +"+++++OXXXXXXXX. +++++", +"+++++OXXXXXXXX. +++++", +"+++++OXXXXXXXX. +++++", +"+++++OXXXXXXXX. +++++", +"+++++OXXXXXXXX. +++++", +"+++++OX........ +++++", +"+++++O +++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/clist.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/clist.xpm new file mode 100644 index 000000000..2dd61e709 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/clist.xpm @@ -0,0 +1,30 @@ +/* XPM */ +static char *clist_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c Gray0", +". c Gray87", +"X c Gray100", +/* pixels */ +" ", +" ...... ...... ..... ", +" ...... ...... ..... ", +" ...... ...... ..... ", +" ", +" XXXXXX XXXXXX XXXXX ", +" XXXXXX XXXXXX XXXXX ", +" XXXXXX XXXXXX XXXXX ", +" ", +" XXXXXX XXXXXX XXXXX ", +" XXXXXX XXXXXX XXXXX ", +" XXXXXX XXXXXX XXXXX ", +" ", +" XXXXXX XXXXXX XXXXX ", +" XXXXXX XXXXXX XXXXX ", +" XXXXXX XXXXXX XXXXX ", +" ", +" XXXXXX XXXXXX XXXXX ", +" XXXXXX XXXXXX XXXXX ", +" XXXXXX XXXXXX XXXXX ", +" " +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/colorselection.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/colorselection.xpm new file mode 100644 index 000000000..0bb0914d0 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/colorselection.xpm @@ -0,0 +1,35 @@ +/* XPM */ +static char *colorselection_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 8 1", +" c Gray0", +". c #7b7b7b", +"X c Blue", +"o c Green", +"O c Red", +"+ c #b3cece", +"@ c Gray100", +"# c None", +/* pixels */ +"#####################", +"#####################", +"#####################", +"#####################", +"#####################", +"##................###", +"##.@@@@@@@@@@@@@@. ##", +"##.@@@@@@@@@@@@@@. ##", +"##.@@@@@@@@@@@@@@. ##", +"##.@@OOOoooXXX@@@. ##", +"##.@@OOOoooXXX@@@. ##", +"##.@@OOOoooXXX@@@. ##", +"##.@@OOOoooXXX@@@. ##", +"##.@@@@@@@@@@@@@@. ##", +"##.@@@@@@@@@@@@@@. ##", +"##.@@@@@@@@@@@@@@. ##", +"##................ ##", +"### ##", +"#####################", +"#####################", +"#####################" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/combo.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/combo.xpm new file mode 100644 index 000000000..3b4055b6d --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/combo.xpm @@ -0,0 +1,34 @@ +/* XPM */ +static char *combo_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 7 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray87", +"+ c Gray100", +"@ c None", +/* pixels */ +"@@@@@@@@@@@@@@@@@@@@@", +" ", +" +++++++++++++ OOOOO ", +" +++++++++++++ OOO ", +" +++++++++++++ O ", +" ", +" +++++++++++++ ++++++", +" +++++++++++++ XXXXX ", +" +.........+++ XX XX ", +" +++++++++++++ X X ", +" +++++++++++++ XXXXX ", +" +...........+ ", +" +++++++++++++ +++++ ", +" +++++++++++++ +XXXX ", +" +..........++ ..... ", +" +++++++++++++ +++++ ", +" +++++++++++++ XXXXX ", +" +...........+ X X ", +" +++++++++++++ XX XX ", +" +++++++++++++ XXXXX ", +" " +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/common.mli b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/common.mli new file mode 100644 index 000000000..7050f9f94 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/common.mli @@ -0,0 +1,27 @@ +(* $Id$ *) + +type range = + | String + | Int + | Float of float * float + | Enum of string list + | Enum_string of string list + | Adjust + | CList_titles + | File + +class type prop = + object + method name : string (* name of the property *) + method range : range (* range of its values *) + method get : string (* current value *) + method set : string -> unit (* change value *) + method modified : bool (* value differs from default *) + method code : string (* encoded value for the ml code *) + method save_code : string (* encoded value for saving *) + end + +class type tiwidget_base = object + method name : string + method proplist : (string * prop) list +end diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/entry.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/entry.xpm new file mode 100644 index 000000000..cb9004135 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/entry.xpm @@ -0,0 +1,33 @@ +/* XPM */ +static char *entry_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 6 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray100", +"+ c None", +/* pixels */ +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"....................O", +". XO", +". OOOOOOOOOOOOOOOOOXO", +". OOOOOOOOOOOOOOO OXO", +". OOOOOOOO OOOOOO OXO", +". OOOOOOOO OOOOOO OXO", +". OOO OO X OOO OXO", +". OO XOX O O. OO OXO", +". OOOOOO O OOO OO OXO", +". OOO O OOO OO OXO", +". OO XOO O OOO OO OXO", +". OO XOO O OO. OO OXO", +". OOO O OOO OXO", +". OOOOOOOOOOOOOOO OXO", +". OOOOOOOOOOOOOOOOOXO", +".XXXXXXXXXXXXXXXXXXXO", +"OOOOOOOOOOOOOOOOOOOOO", +"+++++++++++++++++++++", +"+++++++++++++++++++++" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/eventbox.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/eventbox.xpm new file mode 100644 index 000000000..73da445d2 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/eventbox.xpm @@ -0,0 +1,34 @@ +/* XPM */ +static char *eventbox_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 7 1", +" c Gray0", +". c #7b7b7b", +"X c Blue", +"o c #d6d6d6", +"O c #b3cece", +"+ c Gray100", +"@ c None", +/* pixels */ +"@@@@@@@@@@X+@@@@@@@@@", +"@@@@@@@@@XX+@@@@@@@@@", +"@@@@@@@@XX+@@@@@@@@@@", +"@@@@@@@XX+@@@@@@@@@@@", +"@@@@@@@@XX+@@@@@@@@@@", +"@@@@@@@@@XX+@@@@@@@@@", +"@@@@@@@@@@XX+@@@@@@@@", +"@@@++++++XX++++++ @@@", +"@@@+ooooXX+ooooo. @@@", +"@@@+oooXX+oooooo. @@@", +"@@@+ooooXX+ooooo. @@@", +"@@@+oooooXX+oooo. @@@", +"@@@+ooooooXX+ooo. @@@", +"@@@+oooooooooooo. @@@", +"@@@+oooooooooooo. @@@", +"@@@+oooooooooooo. @@@", +"@@@+............. @@@", +"@@@ @@@", +"@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@@@@@@@@@@@@" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/fixed.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/fixed.xpm new file mode 100644 index 000000000..2e0481572 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/fixed.xpm @@ -0,0 +1,31 @@ +/* XPM */ +static char *fixed_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 4 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c Gray100", +/* pixels */ +"oooooooooooooooooooo ", +"oXXXXXXXXXXXXXXXXXX. ", +"oXXXXXXXXXXXXXXXXXX. ", +"oXooooo XXXXXXXXXXX. ", +"oXoXXX. XXXXXXXXXXX. ", +"oXoXXX. XXXXooooo X. ", +"oXo.... XXXXoXXX. X. ", +"oX XXXXoXXX. X. ", +"oXXXXXXXXXXXo.... X. ", +"oXXXXXXXXXXX X. ", +"oXXXXXXXXXXXXXXXXXX. ", +"oXXXXooooo XXXXXXXX. ", +"oXXXXoXXX. XXXXXXXX. ", +"oXXXXoXXX. XXXXXXXX. ", +"oXXXXo.... XXXXXXXX. ", +"oXXXX XXXXXXXX. ", +"oXXXXXXXXXXXXXXXXXX. ", +"oXXXXXXXXXXXXXXXXXX. ", +"oXXXXXXXXXXXXXXXXXX. ", +"o................... ", +" " +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/frame.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/frame.xpm new file mode 100644 index 000000000..c8c8b5782 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/frame.xpm @@ -0,0 +1,33 @@ +/* XPM */ +static char *frame_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 6 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray100", +"+ c None", +/* pixels */ +"+++++++++++++++++++++", +"+++++ + +++++++++++", +"+...X X X X......O+", +"+.OOX X X XOOOOO.O+", +"+.OXX X X XXXXXX.O+", +"+.OXXXXXXXXXXXXXXX.O+", +"+.OXXXXXXXXXXXXXXX.O+", +"+.OXXXXXXXXXXXXXXX.O+", +"+.OXXXXXXXXXXXXXXX.O+", +"+.OXXXXXXXXXXXXXXX.O+", +"+.OXXXXXXXXXXXXXXX.O+", +"+.OXXXXXXXXXXXXXXX.O+", +"+.OXXXXXXXXXXXXXXX.O+", +"+.OXXXXXXXXXXXXXXX.O+", +"+.OXXXXXXXXXXXXXXX.O+", +"+.OXXXXXXXXXXXXXXX.O+", +"+.OXXXXXXXXXXXXXXX.O+", +"+.OXXXXXXXXXXXXXXX.O+", +"+..................O+", +"+OOOOOOOOOOOOOOOOOOO+", +"+++++++++++++++++++++" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gToolbar2.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gToolbar2.ml new file mode 100644 index 000000000..c2ad0a854 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gToolbar2.ml @@ -0,0 +1,65 @@ +(* $Id$ *) + +open Gaux +open Gtk +open GtkBase +open GtkButton +open GObj +open GContainer +open GButton + +module Toolbar2 = struct + external set_text : [>`toolbar] obj -> string -> int -> unit = + "ml_gtk_toolbar2_set_text" + external set_icon : [>`toolbar] obj -> [>`widget] obj -> int -> unit = + "ml_gtk_toolbar2_set_icon" +end + +class toolbar2 obj = object + inherit container_full (obj : Gtk.toolbar obj) + method insert_widget ?tooltip ?tooltip_private ?pos w = + Toolbar.insert_widget obj (as_widget w) ?tooltip ?tooltip_private ?pos + + method insert_button ?text ?tooltip ?tooltip_private ?icon + ?pos ?callback () = + let icon = may_map icon ~f:as_widget in + new button + (Toolbar.insert_button obj ~kind:`BUTTON ?icon ?text + ?tooltip ?tooltip_private ?pos ?callback ()) + + method insert_toggle_button ?text ?tooltip ?tooltip_private ?icon + ?pos ?callback () = + let icon = may_map icon ~f:as_widget in + new toggle_button + (ToggleButton.cast + (Toolbar.insert_button obj ~kind:`TOGGLEBUTTON ?icon ?text + ?tooltip ?tooltip_private ?pos ?callback ())) + + method insert_radio_button ?text ?tooltip ?tooltip_private ?icon + ?pos ?callback () = + let icon = may_map icon ~f:as_widget in + new radio_button + (RadioButton.cast + (Toolbar.insert_button obj ~kind:`RADIOBUTTON ?icon ?text + ?tooltip ?tooltip_private ?pos ?callback ())) + + method insert_space = Toolbar.insert_space obj + + method set_orientation = Toolbar.set_orientation obj + method set_style = Toolbar.set_style obj + method set_space_size = Toolbar.set_space_size obj + method set_space_style = Toolbar.set_space_style obj + method set_tooltips = Toolbar.set_tooltips obj + method set_button_relief = Toolbar.set_button_relief obj + method button_relief = Toolbar.get_button_relief obj + method set_text = Toolbar2.set_text obj + method set_icon (icon : widget) = Toolbar2.set_icon obj icon#as_widget +end + +let toolbar2 ?(orientation=`HORIZONTAL) ?style + ?space_size ?space_style ?tooltips ?button_relief + ?border_width ?width ?height ?packing ?show () = + let w = Toolbar.create orientation ?style () in + Toolbar.set w ?space_size ?space_style ?tooltips ?button_relief; + Container.set w ?border_width ?width ?height; + pack_return (new toolbar2 w) ~packing ~show diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gTree2.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gTree2.ml new file mode 100644 index 000000000..62c38ac57 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gTree2.ml @@ -0,0 +1,78 @@ +(* $Id$ *) + +open Gaux +open Gtk +open GtkBase +open GtkTree2 +open GObj +open GContainer + +class tree_item_signals obj = object + inherit item_signals obj + method expand = GtkSignal.connect obj ~sgn:TreeItem.Signals.expand ~after + method collapse = GtkSignal.connect obj ~sgn:TreeItem.Signals.collapse ~after +end + +class tree_item obj = object + inherit container obj + method event = new GObj.event_ops obj + method as_item : Gtk.tree_item obj = obj + method connect = new tree_item_signals obj + method set_subtree (w : tree) = TreeItem.set_subtree obj w#as_tree + method remove_subtree () = TreeItem.remove_subtree obj + method expand () = TreeItem.expand obj + method collapse () = TreeItem.collapse obj + method subtree = + try Some(new tree (TreeItem.subtree obj)) with Gpointer.Null -> None +end + +and tree_signals obj = object + inherit container_signals obj + method selection_changed = + GtkSignal.connect obj ~sgn:Tree.Signals.selection_changed ~after + method select_child ~callback = + GtkSignal.connect obj ~sgn:Tree.Signals.select_child ~after + ~callback:(fun w -> callback (new tree_item (TreeItem.cast w))) + method unselect_child ~callback = + GtkSignal.connect obj ~sgn:Tree.Signals.unselect_child ~after + ~callback:(fun w -> callback (new tree_item (TreeItem.cast w))) +end + +and tree obj = object (self) + inherit [tree_item] item_container obj + method event = new GObj.event_ops obj + method as_tree = Tree.coerce obj + method insert w ~pos = Tree.insert obj w#as_item ~pos + method connect = new tree_signals obj + method clear_items = Tree.clear_items obj + method select_item = Tree.select_item obj + method unselect_item = Tree.unselect_item obj + method child_position (w : tree_item) = Tree.child_position obj w#as_item + method remove_items items = + Tree.remove_items obj + (List.map ~f:(fun (t : tree_item) -> t#as_item) items) +(* method set_selection_mode = Tree.set_selection_mode obj + method set_view_mode = Tree.set_view_mode obj *) + method set_view_lines = Tree.set_view_lines obj + method selection = + List.map ~f:(fun w -> self#wrap (Widget.coerce w)) (Tree.selection obj) + method item_up ~pos = + Tree.item_up obj pos + method private wrap w = + new tree_item (TreeItem.cast w) +end + +let tree_item ?label ?border_width ?width ?height ?packing ?show () = + let w = TreeItem.create ?label () in + Container.set w ?border_width ?width ?height; + let self = new tree_item w in + may packing ~f:(fun f -> (f self : unit)); + if show <> Some false then self#misc#show (); + self + +let tree ?selection_mode ?view_mode ?view_lines + ?border_width ?width ?height ?packing ?show () = + let w = Tree.create () in + Tree.set w ?selection_mode ?view_mode ?view_lines; + Container.set w ?border_width ?width ?height; + pack_return (new tree w) ~packing ~show diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gTree2.mli b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gTree2.mli new file mode 100644 index 000000000..c288e157e --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gTree2.mli @@ -0,0 +1,73 @@ +(* $Id$ *) + +open Gtk +open GObj +open GContainer + +class tree_item_signals : 'a obj -> + object + inherit item_signals + constraint 'a = [>`treeitem|`container|`item|`widget] + val obj : 'a obj + method collapse : callback:(unit -> unit) -> GtkSignal.id + method expand : callback:(unit -> unit) -> GtkSignal.id + end + +class tree_item : Gtk.tree_item obj -> + object + inherit GContainer.container + val obj : Gtk.tree_item obj + method event : event_ops + method as_item : Gtk.tree_item obj + method collapse : unit -> unit + method connect : tree_item_signals + method expand : unit -> unit + method remove_subtree : unit -> unit + method set_subtree : tree -> unit + method subtree : tree option + end + +and tree_signals : Gtk.tree obj -> + object + inherit container_signals + val obj : Gtk.tree obj + method select_child : callback:(tree_item -> unit) -> GtkSignal.id + method selection_changed : callback:(unit -> unit) -> GtkSignal.id + method unselect_child : callback:(tree_item -> unit) -> GtkSignal.id + end + +and tree : Gtk.tree obj -> + object + inherit [tree_item] item_container + val obj : Gtk.tree obj + method event : event_ops + method as_tree : Gtk.tree obj + method child_position : tree_item -> int + method clear_items : start:int -> stop:int -> unit + method connect : tree_signals + method insert : tree_item -> pos:int -> unit + method item_up : pos:int -> unit + method remove_items : tree_item list -> unit + method select_item : pos:int -> unit + method selection : tree_item list +(* method set_selection_mode : Tags.selection_mode -> unit *) + method set_view_lines : bool -> unit +(* method set_view_mode : [`LINE|`ITEM] -> unit *) + method unselect_item : pos:int -> unit + method private wrap : Gtk.widget obj -> tree_item + end + +val tree_item : + ?label:string -> + ?border_width:int -> + ?width:int -> + ?height:int -> + ?packing:(tree_item -> unit) -> ?show:bool -> unit -> tree_item + +val tree : + ?selection_mode:Tags.selection_mode -> + ?view_mode:[`LINE|`ITEM] -> + ?view_lines:bool -> + ?border_width:int -> + ?width:int -> + ?height:int -> ?packing:(GObj.widget -> unit) -> ?show:bool -> unit -> tree diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtkTree2.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtkTree2.ml new file mode 100644 index 000000000..46d1e0220 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtkTree2.ml @@ -0,0 +1,82 @@ +(* $Id$ *) + +open Gaux +open Gtk +open Tags +open GtkBase + +module TreeItem = struct + let cast w : tree_item obj = + if Object.is_a w "GtkTreeItem" then Obj.magic w + else invalid_arg "Gtk.TreeItem.cast" + external create : unit -> tree_item obj = "ml_gtk_tree_item2_new" + external create_with_label : string -> tree_item obj + = "ml_gtk_tree_item2_new_with_label" + let create ?label () = + match label with None -> create () + | Some label -> create_with_label label + external set_subtree : [>`treeitem] obj -> [>`widget] obj -> unit + = "ml_gtk_tree_item2_set_subtree" + external remove_subtree : [>`treeitem] obj -> unit + = "ml_gtk_tree_item2_remove_subtree" + external expand : [>`treeitem] obj -> unit + = "ml_gtk_tree_item2_expand" + external collapse : [>`treeitem] obj -> unit + = "ml_gtk_tree_item2_collapse" + external subtree : [>`treeitem] obj -> tree obj + = "ml_GTK_TREE_ITEM2_SUBTREE" + let subtree t = try subtree t with Gpointer.Null -> raise Not_found + module Signals = struct + open GtkSignal + let expand : ([>`treeitem],_) t = + { name = "expand"; marshaller = marshal_unit } + let collapse : ([>`treeitem],_) t = + { name = "collapse"; marshaller = marshal_unit } + end +end + +module Tree = struct + let cast w : tree obj = + if Object.is_a w "GtkTree" then Obj.magic w + else invalid_arg "Gtk.Tree.cast" + external coerce : [>`tree] obj -> tree obj = "%identity" + external create : unit -> tree obj = "ml_gtk_tree2_new" + external insert : [>`tree] obj -> [>`treeitem] obj -> pos:int -> unit + = "ml_gtk_tree2_insert" + external remove_items : [>`tree] obj -> [>`treeitem] obj list -> unit + = "ml_gtk_tree2_remove_items" + external clear_items : [>`tree] obj -> start:int -> stop:int -> unit + = "ml_gtk_tree2_clear_items" + external select_item : [>`tree] obj -> pos:int -> unit + = "ml_gtk_tree2_select_item" + external unselect_item : [>`tree] obj -> pos:int -> unit + = "ml_gtk_tree2_unselect_item" + external child_position : [>`tree] obj -> [>`treeitem] obj -> int + = "ml_gtk_tree2_child_position" +(* external set_selection_mode : [>`tree] obj -> selection_mode -> unit + = "ml_gtk_tree2_set_selection_mode" + external set_view_mode : [>`tree] obj -> [`LINE|`ITEM] -> unit + = "ml_gtk_tree2_set_view_mode" +*) + external set_view_lines : [>`tree] obj -> bool -> unit + = "ml_gtk_tree2_set_view_lines" + external selection : [>`tree] obj -> tree_item obj list = + "ml_gtk_tree2_selection" + external item_up : [>`tree] obj -> int -> unit = + "ml_gtk_tree2_item_up" + + let set ?selection_mode ?view_mode ?view_lines w = + let may_set f = may ~f:(f w) in +(* may_set set_selection_mode selection_mode; + may_set set_view_mode view_mode; *) + may_set set_view_lines view_lines + module Signals = struct + open GtkSignal + let selection_changed : ([>`tree],_) t = + { name = "selection_changed"; marshaller = marshal_unit } + let select_child : ([>`tree],_) t = + { name = "select_child"; marshaller = Widget.Signals.marshal } + let unselect_child : ([>`tree],_) t = + { name = "unselect_child"; marshaller = Widget.Signals.marshal } + end +end diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktree2.c b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktree2.c new file mode 100644 index 000000000..db37a1f9d --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktree2.c @@ -0,0 +1,1385 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#include "gtktree2.h" +#include "gtktreeitem2.h" + +#include +#include +#include + +enum { + SELECTION_CHANGED, + SELECT_CHILD, + UNSELECT_CHILD, + LAST_SIGNAL +}; + +static void gtk_tree2_class_init (GtkTree2Class *klass); +static void gtk_tree2_init (GtkTree2 *tree); +static void gtk_tree2_destroy (GtkObject *object); +static void gtk_tree2_map (GtkWidget *widget); +static void gtk_tree2_unmap (GtkWidget *widget); +static void gtk_tree2_realize (GtkWidget *widget); +static void gtk_tree2_draw (GtkWidget *widget, + GdkRectangle *area); +static gint gtk_tree2_expose (GtkWidget *widget, + GdkEventExpose *event); +static gint gtk_tree2_motion_notify (GtkWidget *widget, + GdkEventMotion *event); +static gint gtk_tree2_button_press (GtkWidget *widget, + GdkEventButton *event); +static gint gtk_tree2_button_release (GtkWidget *widget, + GdkEventButton *event); +static void gtk_tree2_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static void gtk_tree2_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static void gtk_tree2_add (GtkContainer *container, + GtkWidget *widget); +static void gtk_tree2_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); + +static void gtk_real_tree2_select_child (GtkTree2 *tree, + GtkWidget *child); +static void gtk_real_tree2_unselect_child (GtkTree2 *tree, + GtkWidget *child); + +static GtkType gtk_tree2_child_type (GtkContainer *container); + +static GtkContainerClass *parent_class = NULL; +static guint tree_signals[LAST_SIGNAL] = { 0 }; + +GtkType +gtk_tree2_get_type (void) +{ + static GtkType tree_type = 0; + + if (!tree_type) + { + static const GtkTypeInfo tree_info = + { + "GtkTree2", + sizeof (GtkTree2), + sizeof (GtkTree2Class), + (GtkClassInitFunc) gtk_tree2_class_init, + (GtkObjectInitFunc) gtk_tree2_init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + tree_type = gtk_type_unique (gtk_container_get_type (), &tree_info); + } + + return tree_type; +} + +static void +gtk_tree2_class_init (GtkTree2Class *class) +{ + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + GtkContainerClass *container_class; + + object_class = (GtkObjectClass*) class; + widget_class = (GtkWidgetClass*) class; + container_class = (GtkContainerClass*) class; + + parent_class = gtk_type_class (gtk_container_get_type ()); + + tree_signals[SELECTION_CHANGED] = + gtk_signal_new ("selection_changed", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (GtkTree2Class, selection_changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + tree_signals[SELECT_CHILD] = + gtk_signal_new ("select_child", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (GtkTree2Class, select_child), + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, + GTK_TYPE_WIDGET); + tree_signals[UNSELECT_CHILD] = + gtk_signal_new ("unselect_child", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (GtkTree2Class, unselect_child), + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, + GTK_TYPE_WIDGET); + + gtk_object_class_add_signals (object_class, tree_signals, LAST_SIGNAL); + + object_class->destroy = gtk_tree2_destroy; + + widget_class->map = gtk_tree2_map; + widget_class->unmap = gtk_tree2_unmap; + widget_class->realize = gtk_tree2_realize; + widget_class->draw = gtk_tree2_draw; + widget_class->expose_event = gtk_tree2_expose; + widget_class->motion_notify_event = gtk_tree2_motion_notify; + widget_class->button_press_event = gtk_tree2_button_press; + widget_class->button_release_event = gtk_tree2_button_release; + widget_class->size_request = gtk_tree2_size_request; + widget_class->size_allocate = gtk_tree2_size_allocate; + + container_class->add = gtk_tree2_add; + container_class->remove = + (void (*)(GtkContainer *, GtkWidget *)) gtk_tree2_remove_item; + container_class->forall = gtk_tree2_forall; + container_class->child_type = gtk_tree2_child_type; + + class->selection_changed = NULL; + class->select_child = gtk_real_tree2_select_child; + class->unselect_child = gtk_real_tree2_unselect_child; +} + +static GtkType +gtk_tree2_child_type (GtkContainer *container) +{ + return GTK_TYPE_TREE_ITEM2; +} + +static void +gtk_tree2_init (GtkTree2 *tree) +{ + tree->children = NULL; + tree->root_tree = NULL; + tree->selection = NULL; + tree->tree_owner = NULL; + tree->selection_mode = GTK_SELECTION_SINGLE; + tree->indent_value = 9; + tree->current_indent = 0; + tree->level = 0; + tree->view_mode = GTK_TREE2_VIEW_LINE; + tree->view_line = 1; +} + +GtkWidget* +gtk_tree2_new (void) +{ + return GTK_WIDGET (gtk_type_new (gtk_tree2_get_type ())); +} + +void +gtk_tree2_append (GtkTree2 *tree, + GtkWidget *tree_item) +{ + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + gtk_tree2_insert (tree, tree_item, -1); +} + +void +gtk_tree2_prepend (GtkTree2 *tree, + GtkWidget *tree_item) +{ + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + gtk_tree2_insert (tree, tree_item, 0); +} + +void +gtk_tree2_insert (GtkTree2 *tree, + GtkWidget *tree_item, + gint position) +{ + gint nchildren; + + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + nchildren = g_list_length (tree->children); + + if ((position < 0) || (position > nchildren)) + position = nchildren; + + if (position == nchildren) + tree->children = g_list_append (tree->children, tree_item); + else + tree->children = g_list_insert (tree->children, tree_item, position); + + gtk_widget_set_parent (tree_item, GTK_WIDGET (tree)); + + if (GTK_WIDGET_REALIZED (tree_item->parent)) + gtk_widget_realize (tree_item); + + if (GTK_WIDGET_VISIBLE (tree_item->parent) && GTK_WIDGET_VISIBLE (tree_item)) + { + if (GTK_WIDGET_MAPPED (tree_item->parent)) + gtk_widget_map (tree_item); + + gtk_widget_queue_resize (tree_item); + } +} + +/* moves the pos child up in the tree */ +void +gtk_tree2_item_up (GtkTree2 *tree, + gint position) +{ + gint nchildren, i; + GList *children, *tmp; + + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + + children = (tree->children); + nchildren = g_list_length (tree->children); + + if ((position < 1) || (position >= nchildren)) + return; + + for (i=1; i < position; i++) + children = (children->next); + + tmp = children->next; + if (position == 1) + { + tree->children = children->next; + children->next->prev = NULL; + } + else + { + children->prev->next = children->next; + children->next->prev = children->prev; + } + children->next = tmp->next; + children->prev = tmp; + if (tmp->next) + tmp->next->prev = children; + tmp->next = children; + + if (GTK_WIDGET_VISIBLE (tree)) + { +/* if (GTK_WIDGET_VISIBLE (GTK_WIDGET(children->data))) + gtk_widget_queue_resize (GTK_WIDGET(children->data)); + if (GTK_WIDGET_VISIBLE (GTK_WIDGET(tmp->data))) + gtk_widget_queue_resize (GTK_WIDGET(tmp->data)); +*/ + gtk_widget_queue_resize (GTK_WIDGET(tree)); + } +} + +static void +gtk_tree2_add (GtkContainer *container, + GtkWidget *child) +{ + GtkTree2 *tree; + + g_return_if_fail (container != NULL); + g_return_if_fail (GTK_IS_TREE2 (container)); + g_return_if_fail (GTK_IS_TREE_ITEM2 (child)); + + tree = GTK_TREE2 (container); + + tree->children = g_list_append (tree->children, child); + + gtk_widget_set_parent (child, GTK_WIDGET (container)); + + if (GTK_WIDGET_REALIZED (child->parent)) + gtk_widget_realize (child); + + if (GTK_WIDGET_VISIBLE (child->parent) && GTK_WIDGET_VISIBLE (child)) + { + if (GTK_WIDGET_MAPPED (child->parent)) + gtk_widget_map (child); + + gtk_widget_queue_resize (child); + } + + if (!tree->selection && (tree->selection_mode == GTK_SELECTION_BROWSE)) + gtk_tree2_select_child (tree, child); +} + +static gint +gtk_tree2_button_press (GtkWidget *widget, + GdkEventButton *event) +{ + GtkTree2 *tree; + GtkWidget *item; + + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_TREE2 (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + tree = GTK_TREE2 (widget); + item = gtk_get_event_widget ((GdkEvent*) event); + + while (item && !GTK_IS_TREE_ITEM2 (item)) + item = item->parent; + + if (!item || (item->parent != widget)) + return FALSE; + + switch(event->button) + { + case 1: + gtk_tree2_select_child (tree, item); + break; + case 2: + if(GTK_TREE_ITEM2(item)->subtree) gtk_tree_item2_expand(GTK_TREE_ITEM2(item)); + break; + case 3: + if(GTK_TREE_ITEM2(item)->subtree) gtk_tree_item2_collapse(GTK_TREE_ITEM2(item)); + break; + } + + return TRUE; +} + +static gint +gtk_tree2_button_release (GtkWidget *widget, + GdkEventButton *event) +{ + GtkTree2 *tree; + GtkWidget *item; + + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_TREE2 (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + tree = GTK_TREE2 (widget); + item = gtk_get_event_widget ((GdkEvent*) event); + + return TRUE; +} + +gint +gtk_tree2_child_position (GtkTree2 *tree, + GtkWidget *child) +{ + GList *children; + gint pos; + + + g_return_val_if_fail (tree != NULL, -1); + g_return_val_if_fail (GTK_IS_TREE2 (tree), -1); + g_return_val_if_fail (child != NULL, -1); + + pos = 0; + children = tree->children; + + while (children) + { + if (child == GTK_WIDGET (children->data)) + return pos; + + pos += 1; + children = children->next; + } + + + return -1; +} + +void +gtk_tree2_clear_items (GtkTree2 *tree, + gint start, + gint end) +{ + GtkWidget *widget; + GList *clear_list; + GList *tmp_list; + guint nchildren; + guint index; + + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + + nchildren = g_list_length (tree->children); + + if (nchildren > 0) + { + if ((end < 0) || (end > nchildren)) + end = nchildren; + + if (start >= end) + return; + + tmp_list = g_list_nth (tree->children, start); + clear_list = NULL; + index = start; + while (tmp_list && index <= end) + { + widget = tmp_list->data; + tmp_list = tmp_list->next; + index++; + + clear_list = g_list_prepend (clear_list, widget); + } + + gtk_tree2_remove_items (tree, clear_list); + } +} + +static void +gtk_tree2_destroy (GtkObject *object) +{ + GtkTree2 *tree; + GtkWidget *child; + GList *children; + + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_TREE2 (object)); + + tree = GTK_TREE2 (object); + + children = tree->children; + while (children) + { + child = children->data; + children = children->next; + + gtk_widget_ref (child); + gtk_widget_unparent (child); + gtk_widget_destroy (child); + gtk_widget_unref (child); + } + + g_list_free (tree->children); + tree->children = NULL; + + if (tree->root_tree == tree) + { + GList *node; + for (node = tree->selection; node; node = node->next) + gtk_widget_unref ((GtkWidget *)node->data); + g_list_free (tree->selection); + tree->selection = NULL; + } + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +static void +gtk_tree2_draw (GtkWidget *widget, + GdkRectangle *area) +{ + GtkTree2 *tree; + GtkWidget *subtree; + GtkWidget *child; + GdkRectangle child_area; + GList *children; + + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE2 (widget)); + g_return_if_fail (area != NULL); + + if (GTK_WIDGET_DRAWABLE (widget)) + { + tree = GTK_TREE2 (widget); + + children = tree->children; + while (children) + { + child = children->data; + children = children->next; + + if (gtk_widget_intersect (child, area, &child_area)) + gtk_widget_draw (child, &child_area); + + if((subtree = GTK_TREE_ITEM2(child)->subtree) && + GTK_WIDGET_VISIBLE(subtree) && + gtk_widget_intersect (subtree, area, &child_area)) + gtk_widget_draw (subtree, &child_area); + } + } + +} + +static gint +gtk_tree2_expose (GtkWidget *widget, + GdkEventExpose *event) +{ + GtkTree2 *tree; + GtkWidget *child; + GdkEventExpose child_event; + GList *children; + + + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_TREE2 (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + if (GTK_WIDGET_DRAWABLE (widget)) + { + tree = GTK_TREE2 (widget); + + child_event = *event; + + children = tree->children; + while (children) + { + child = children->data; + children = children->next; + + if (GTK_WIDGET_NO_WINDOW (child) && + gtk_widget_intersect (child, &event->area, &child_event.area)) + gtk_widget_event (child, (GdkEvent*) &child_event); + } + } + + + return FALSE; +} + +static void +gtk_tree2_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) +{ + GtkTree2 *tree; + GtkWidget *child; + GList *children; + + + g_return_if_fail (container != NULL); + g_return_if_fail (GTK_IS_TREE2 (container)); + g_return_if_fail (callback != NULL); + + tree = GTK_TREE2 (container); + children = tree->children; + + while (children) + { + child = children->data; + children = children->next; + + (* callback) (child, callback_data); + + if (include_internals && GTK_TREE_ITEM2(child)->subtree) + (* callback) (GTK_TREE_ITEM2(child)->subtree, callback_data); + } +} + +static void +gtk_tree2_map (GtkWidget *widget) +{ + GtkTree2 *tree; + GtkWidget *child; + GList *children; + + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE2 (widget)); + + GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); + tree = GTK_TREE2 (widget); + + if(GTK_IS_TREE2(widget->parent)) + { + /* set root tree for this tree */ + tree->root_tree = GTK_TREE2(widget->parent)->root_tree; + + tree->level = GTK_TREE2(GTK_WIDGET(tree)->parent)->level+1; + tree->indent_value = GTK_TREE2(GTK_WIDGET(tree)->parent)->indent_value; + tree->current_indent = GTK_TREE2(GTK_WIDGET(tree)->parent)->current_indent + + tree->indent_value; + tree->view_mode = GTK_TREE2(GTK_WIDGET(tree)->parent)->view_mode; + tree->view_line = GTK_TREE2(GTK_WIDGET(tree)->parent)->view_line; + } + else + tree->root_tree = tree; + + children = tree->children; + while (children) + { + child = children->data; + children = children->next; + + if (GTK_WIDGET_VISIBLE (child) && + !GTK_WIDGET_MAPPED (child)) + gtk_widget_map (child); + + if (GTK_TREE_ITEM2 (child)->subtree) + { + child = GTK_WIDGET (GTK_TREE_ITEM2 (child)->subtree); + + if (GTK_WIDGET_VISIBLE (child) && !GTK_WIDGET_MAPPED (child)) + gtk_widget_map (child); + } + } + + gdk_window_show (widget->window); +} + +static gint +gtk_tree2_motion_notify (GtkWidget *widget, + GdkEventMotion *event) +{ + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_TREE2 (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + +#ifdef TREE_DEBUG + g_message("gtk_tree2_motion_notify\n"); +#endif /* TREE_DEBUG */ + + return FALSE; +} + +static void +gtk_tree2_realize (GtkWidget *widget) +{ + GdkWindowAttr attributes; + gint attributes_mask; + + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE2 (widget)); + + GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); + + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = widget->allocation.x; + attributes.y = widget->allocation.y; + attributes.width = widget->allocation.width; + attributes.height = widget->allocation.height; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.visual = gtk_widget_get_visual (widget); + attributes.colormap = gtk_widget_get_colormap (widget); + attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK; + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + + widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); + gdk_window_set_user_data (widget->window, widget); + + widget->style = gtk_style_attach (widget->style, widget->window); + gdk_window_set_background (widget->window, + &widget->style->base[GTK_STATE_NORMAL]); +} + +void +gtk_tree2_remove_item (GtkTree2 *container, + GtkWidget *widget) +{ + GList *item_list; + + g_return_if_fail (container != NULL); + g_return_if_fail (GTK_IS_TREE2 (container)); + g_return_if_fail (widget != NULL); + g_return_if_fail (container == GTK_TREE2 (widget->parent)); + + item_list = g_list_append (NULL, widget); + + gtk_tree2_remove_items (GTK_TREE2 (container), item_list); + + g_list_free (item_list); +} + +/* used by gtk_tree2_remove_items to make the function independant of + order in list of items to remove. + Sort item bu depth in tree */ +static gint +gtk_tree2_sort_item_by_depth(GtkWidget* a, GtkWidget* b) +{ + if((GTK_TREE2(a->parent)->level) < (GTK_TREE2(b->parent)->level)) + return 1; + if((GTK_TREE2(a->parent)->level) > (GTK_TREE2(b->parent)->level)) + return -1; + + return 0; +} + +void +gtk_tree2_remove_items (GtkTree2 *tree, + GList *items) +{ + GtkWidget *widget; + GList *selected_widgets; + GList *tmp_list; + GList *sorted_list; + GtkTree2 *real_tree; + GtkTree2 *root_tree; + + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + +#ifdef TREE_DEBUG + g_message("+ gtk_tree2_remove_items [ tree %#x items list %#x ]\n", (int)tree, (int)items); +#endif /* TREE_DEBUG */ + + /* We may not yet be mapped, so we actively have to find our + * root tree + */ + if (tree->root_tree) + root_tree = tree->root_tree; + else + { + GtkWidget *tmp = GTK_WIDGET (tree); + while (tmp->parent && GTK_IS_TREE2 (tmp->parent)) + tmp = tmp->parent; + + root_tree = GTK_TREE2 (tmp); + } + + tmp_list = items; + selected_widgets = NULL; + sorted_list = NULL; + widget = NULL; + +#ifdef TREE_DEBUG + g_message("* sort list by depth\n"); +#endif /* TREE_DEBUG */ + + while (tmp_list) + { + +#ifdef TREE_DEBUG + g_message ("* item [%#x] depth [%d]\n", + (int)tmp_list->data, + (int)GTK_TREE2(GTK_WIDGET(tmp_list->data)->parent)->level); +#endif /* TREE_DEBUG */ + + sorted_list = g_list_insert_sorted(sorted_list, + tmp_list->data, + (GCompareFunc)gtk_tree2_sort_item_by_depth); + tmp_list = g_list_next(tmp_list); + } + +#ifdef TREE_DEBUG + /* print sorted list */ + g_message("* sorted list result\n"); + tmp_list = sorted_list; + while(tmp_list) + { + g_message("* item [%#x] depth [%d]\n", + (int)tmp_list->data, + (int)GTK_TREE2(GTK_WIDGET(tmp_list->data)->parent)->level); + tmp_list = g_list_next(tmp_list); + } +#endif /* TREE_DEBUG */ + +#ifdef TREE_DEBUG + g_message("* scan sorted list\n"); +#endif /* TREE_DEBUG */ + + tmp_list = sorted_list; + while (tmp_list) + { + widget = tmp_list->data; + tmp_list = tmp_list->next; + +#ifdef TREE_DEBUG + g_message("* item [%#x] subtree [%#x]\n", + (int)widget, (int)GTK_TREE_ITEM2_SUBTREE(widget)); +#endif /* TREE_DEBUG */ + + /* get real owner of this widget */ + real_tree = GTK_TREE2(widget->parent); +#ifdef TREE_DEBUG + g_message("* subtree having this widget [%#x]\n", (int)real_tree); +#endif /* TREE_DEBUG */ + + + if (widget->state == GTK_STATE_SELECTED) + { + selected_widgets = g_list_prepend (selected_widgets, widget); +#ifdef TREE_DEBUG + g_message("* selected widget - adding it in selected list [%#x]\n", + (int)selected_widgets); +#endif /* TREE_DEBUG */ + } + + /* remove this item from its real parent */ +#ifdef TREE_DEBUG + g_message("* remove widget from its owner tree\n"); +#endif /* TREE_DEBUG */ + real_tree->children = g_list_remove (real_tree->children, widget); + + /* remove subtree associate at this item if it exist */ + if(GTK_TREE_ITEM2(widget)->subtree) + { +#ifdef TREE_DEBUG + g_message("* remove subtree associate at this item [%#x]\n", + (int) GTK_TREE_ITEM2(widget)->subtree); +#endif /* TREE_DEBUG */ + if (GTK_WIDGET_MAPPED (GTK_TREE_ITEM2(widget)->subtree)) + gtk_widget_unmap (GTK_TREE_ITEM2(widget)->subtree); + + gtk_widget_unparent (GTK_TREE_ITEM2(widget)->subtree); + GTK_TREE_ITEM2(widget)->subtree = NULL; + } + + /* really remove widget for this item */ +#ifdef TREE_DEBUG + g_message("* unmap and unparent widget [%#x]\n", (int)widget); +#endif /* TREE_DEBUG */ + if (GTK_WIDGET_MAPPED (widget)) + gtk_widget_unmap (widget); + + gtk_widget_unparent (widget); + + /* delete subtree if there is no children in it */ +/* HF supprime */ +/* if(real_tree->children == NULL && + real_tree != root_tree) + { +*/ +#ifdef TREE_DEBUG + g_message("* owner tree don't have children ... destroy it\n"); +#endif /* TREE_DEBUG */ +/* + gtk_tree_item2_remove_subtree(GTK_TREE_ITEM2(real_tree->tree_owner)); + } +*/ +#ifdef TREE_DEBUG + g_message("* next item in list\n"); +#endif /* TREE_DEBUG */ + } + + if (selected_widgets) + { +#ifdef TREE_DEBUG + g_message("* scan selected item list\n"); +#endif /* TREE_DEBUG */ + tmp_list = selected_widgets; + while (tmp_list) + { + widget = tmp_list->data; + tmp_list = tmp_list->next; + +#ifdef TREE_DEBUG + g_message("* widget [%#x] subtree [%#x]\n", + (int)widget, (int)GTK_TREE_ITEM2_SUBTREE(widget)); +#endif /* TREE_DEBUG */ + + /* remove widget of selection */ + root_tree->selection = g_list_remove (root_tree->selection, widget); + + /* unref it to authorize is destruction */ + gtk_widget_unref (widget); + } + + /* emit only one selection_changed signal */ + gtk_signal_emit (GTK_OBJECT (root_tree), + tree_signals[SELECTION_CHANGED]); + } + +#ifdef TREE_DEBUG + g_message("* free selected_widgets list\n"); +#endif /* TREE_DEBUG */ + g_list_free (selected_widgets); + g_list_free (sorted_list); + + if (root_tree->children && !root_tree->selection && + (root_tree->selection_mode == GTK_SELECTION_BROWSE)) + { +#ifdef TREE_DEBUG + g_message("* BROWSE mode, select another item\n"); +#endif /* TREE_DEBUG */ + widget = root_tree->children->data; + gtk_tree2_select_child (root_tree, widget); + } + + if (GTK_WIDGET_VISIBLE (root_tree)) + { +#ifdef TREE_DEBUG + g_message("* query queue resizing for root_tree\n"); +#endif /* TREE_DEBUG */ + gtk_widget_queue_resize (GTK_WIDGET (root_tree)); + } +} + +void +gtk_tree2_select_child (GtkTree2 *tree, + GtkWidget *tree_item) +{ + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + gtk_signal_emit (GTK_OBJECT (tree), tree_signals[SELECT_CHILD], tree_item); +} + +void +gtk_tree2_select_next_child (GtkTree2 *tree, + GtkWidget *tree_item, gboolean descend) +{ + GList *children; + + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + if (descend && GTK_TREE2(GTK_TREE_ITEM2(tree_item)->subtree)->children) + { + gtk_signal_emit (GTK_OBJECT (GTK_TREE_ITEM2(tree_item)->subtree), tree_signals[SELECT_CHILD], GTK_TREE2(GTK_TREE_ITEM2(tree_item)->subtree)->children->data); + return; + } + + children = tree->children; + while (children) + { + if (tree_item == GTK_WIDGET (children->data)) + break; + + children = children->next; + } + if (!children) return; + + if (children->next) + gtk_signal_emit (GTK_OBJECT (tree), tree_signals[SELECT_CHILD], children->next->data); + else if (tree != tree->root_tree) + { + children = GTK_TREE2(GTK_WIDGET(tree)->parent)->children; + gtk_tree2_select_next_child (GTK_TREE2(GTK_WIDGET(tree)->parent), tree->tree_owner, FALSE); + } + +} + +/* we know that tree is not the roor_tree and that + tree_items always have subtrees */ +void +gtk_tree2_select_prev_child (GtkTree2 *tree, + GtkWidget *tree_item) +{ + GList *children; + GtkTreeItem2 *tree_item2; + + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + + children = tree->children; + while (children) + { + if (tree_item == GTK_WIDGET (children->data)) + break; + + children = children->next; + } + if (!children) return; + + if (children = children->prev) + { + tree_item2 = GTK_TREE_ITEM2(children->data); + while (GTK_TREE2(tree_item2->subtree)->children) + { + children = GTK_TREE2(tree_item2->subtree)->children; + while (children->next) + children = children->next; + tree_item2 = GTK_TREE_ITEM2(children->data); + } + gtk_signal_emit (GTK_OBJECT (GTK_WIDGET(tree_item2)->parent), tree_signals[SELECT_CHILD], tree_item2); + } + else + { + gtk_signal_emit (GTK_OBJECT (GTK_WIDGET(tree)->parent), tree_signals[SELECT_CHILD], tree->tree_owner); + } + +} + +void +gtk_tree2_select_item (GtkTree2 *tree, + gint item) +{ + GList *tmp_list; + + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + + tmp_list = g_list_nth (tree->children, item); + if (tmp_list) + gtk_tree2_select_child (tree, GTK_WIDGET (tmp_list->data)); + +} + +static void +gtk_tree2_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkTree2 *tree; + GtkWidget *child, *subtree; + GtkAllocation child_allocation; + GList *children; + + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE2 (widget)); + g_return_if_fail (allocation != NULL); + + tree = GTK_TREE2 (widget); + + widget->allocation = *allocation; + if (GTK_WIDGET_REALIZED (widget)) + gdk_window_move_resize (widget->window, + allocation->x, allocation->y, + allocation->width, allocation->height); + + if (tree->children) + { + child_allocation.x = GTK_CONTAINER (tree)->border_width; + child_allocation.y = GTK_CONTAINER (tree)->border_width; + child_allocation.width = MAX (1, (gint)allocation->width - child_allocation.x * 2); + + children = tree->children; + + while (children) + { + child = children->data; + children = children->next; + + if (GTK_WIDGET_VISIBLE (child)) + { + GtkRequisition child_requisition; + gtk_widget_get_child_requisition (child, &child_requisition); + + child_allocation.height = child_requisition.height; + + gtk_widget_size_allocate (child, &child_allocation); + + child_allocation.y += child_allocation.height; + + if((subtree = GTK_TREE_ITEM2(child)->subtree)) + if(GTK_WIDGET_VISIBLE (subtree)) + { + child_allocation.height = subtree->requisition.height; + gtk_widget_size_allocate (subtree, &child_allocation); + child_allocation.y += child_allocation.height; + } + } + } + } + +} + +static void +gtk_tree2_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkTree2 *tree; + GtkWidget *child, *subtree; + GList *children; + GtkRequisition child_requisition; + + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE2 (widget)); + g_return_if_fail (requisition != NULL); + + tree = GTK_TREE2 (widget); + requisition->width = 0; + requisition->height = 0; + + children = tree->children; + while (children) + { + child = children->data; + children = children->next; + + if (GTK_WIDGET_VISIBLE (child)) + { + gtk_widget_size_request (child, &child_requisition); + + requisition->width = MAX (requisition->width, child_requisition.width); + requisition->height += child_requisition.height; + + if((subtree = GTK_TREE_ITEM2(child)->subtree) && + GTK_WIDGET_VISIBLE (subtree)) + { + gtk_widget_size_request (subtree, &child_requisition); + + requisition->width = MAX (requisition->width, + child_requisition.width); + + requisition->height += child_requisition.height; + } + } + } + + requisition->width += GTK_CONTAINER (tree)->border_width * 2; + requisition->height += GTK_CONTAINER (tree)->border_width * 2; + + requisition->width = MAX (requisition->width, 1); + requisition->height = MAX (requisition->height, 1); + +} + +static void +gtk_tree2_unmap (GtkWidget *widget) +{ + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE2 (widget)); + + GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); + gdk_window_hide (widget->window); + +} + +void +gtk_tree2_unselect_child (GtkTree2 *tree, + GtkWidget *tree_item) +{ + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + gtk_signal_emit (GTK_OBJECT (tree), tree_signals[UNSELECT_CHILD], tree_item); +} + +void +gtk_tree2_unselect_item (GtkTree2 *tree, + gint item) +{ + GList *tmp_list; + + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + + tmp_list = g_list_nth (tree->children, item); + if (tmp_list) + gtk_tree2_unselect_child (tree, GTK_WIDGET (tmp_list->data)); + +} + +static void +gtk_real_tree2_select_child (GtkTree2 *tree, + GtkWidget *child) +{ + GList *selection, *root_selection; + GList *tmp_list; + GtkWidget *tmp_item; + + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + g_return_if_fail (child != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (child)); + + root_selection = tree->root_tree->selection; + + switch (tree->root_tree->selection_mode) + { + case GTK_SELECTION_SINGLE: + + selection = root_selection; + + /* remove old selection list */ + while (selection) + { + tmp_item = selection->data; + + if (tmp_item != child) + { + gtk_tree_item2_deselect (GTK_TREE_ITEM2 (tmp_item)); + + tmp_list = selection; + selection = selection->next; + + root_selection = g_list_remove_link (root_selection, tmp_list); + gtk_widget_unref (tmp_item); + + g_list_free (tmp_list); + } + else + selection = selection->next; + } + + if (child->state == GTK_STATE_NORMAL) + { + gtk_tree_item2_select (GTK_TREE_ITEM2 (child)); + root_selection = g_list_prepend (root_selection, child); + gtk_widget_ref (child); + } + else if (child->state == GTK_STATE_SELECTED) + { + gtk_tree_item2_deselect (GTK_TREE_ITEM2 (child)); + root_selection = g_list_remove (root_selection, child); + gtk_widget_unref (child); + } + + tree->root_tree->selection = root_selection; + + gtk_signal_emit (GTK_OBJECT (tree->root_tree), + tree_signals[SELECTION_CHANGED]); + break; + + + case GTK_SELECTION_BROWSE: + selection = root_selection; + + while (selection) + { + tmp_item = selection->data; + + if (tmp_item != child) + { + gtk_tree_item2_deselect (GTK_TREE_ITEM2 (tmp_item)); + + tmp_list = selection; + selection = selection->next; + + root_selection = g_list_remove_link (root_selection, tmp_list); + gtk_widget_unref (tmp_item); + + g_list_free (tmp_list); + } + else + selection = selection->next; + } + + tree->root_tree->selection = root_selection; + + if (child->state == GTK_STATE_NORMAL) + { + gtk_tree_item2_select (GTK_TREE_ITEM2 (child)); + root_selection = g_list_prepend (root_selection, child); + gtk_widget_ref (child); + tree->root_tree->selection = root_selection; + gtk_signal_emit (GTK_OBJECT (tree->root_tree), + tree_signals[SELECTION_CHANGED]); + } + break; + + case GTK_SELECTION_MULTIPLE: + if (child->state == GTK_STATE_NORMAL) + { + gtk_tree_item2_select (GTK_TREE_ITEM2 (child)); + root_selection = g_list_prepend (root_selection, child); + gtk_widget_ref (child); + tree->root_tree->selection = root_selection; + gtk_signal_emit (GTK_OBJECT (tree->root_tree), + tree_signals[SELECTION_CHANGED]); + } + else if (child->state == GTK_STATE_SELECTED) + { + gtk_tree_item2_deselect (GTK_TREE_ITEM2 (child)); + root_selection = g_list_remove (root_selection, child); + gtk_widget_unref (child); + tree->root_tree->selection = root_selection; + gtk_signal_emit (GTK_OBJECT (tree->root_tree), + tree_signals[SELECTION_CHANGED]); + } + break; + + case GTK_SELECTION_EXTENDED: + break; + } +} + +static void +gtk_real_tree2_unselect_child (GtkTree2 *tree, + GtkWidget *child) +{ + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + g_return_if_fail (child != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (child)); + + switch (tree->selection_mode) + { + case GTK_SELECTION_SINGLE: + case GTK_SELECTION_MULTIPLE: + case GTK_SELECTION_BROWSE: + if (child->state == GTK_STATE_SELECTED) + { + GtkTree2* root_tree = GTK_TREE2_ROOT_TREE(tree); + gtk_tree_item2_deselect (GTK_TREE_ITEM2 (child)); + root_tree->selection = g_list_remove (root_tree->selection, child); + gtk_widget_unref (child); + gtk_signal_emit (GTK_OBJECT (tree->root_tree), + tree_signals[SELECTION_CHANGED]); + } + break; + + case GTK_SELECTION_EXTENDED: + break; + } +} + +void +gtk_tree2_set_selection_mode (GtkTree2 *tree, + GtkSelectionMode mode) +{ + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + + tree->selection_mode = mode; +} + +void +gtk_tree2_set_view_mode (GtkTree2 *tree, + GtkTree2ViewMode mode) +{ + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + + tree->view_mode = mode; +} + +void +gtk_tree2_set_view_lines (GtkTree2 *tree, + guint flag) +{ + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + + tree->view_line = flag; +} + +void +gtk_tree2_item_up_1 (GtkTree2 *tree, + guint pos) +{ + GList *tmp; + guint length; + gpointer data; + + g_return_if_fail (tree != NULL); + g_return_if_fail (GTK_IS_TREE2 (tree)); + + tmp = tree->children; + length = g_list_length (tmp); + if (pos <= 0 || pos >= length) { return; } + data = g_list_nth_data (tree->children, pos); + g_list_remove (tree->children, data); + tree->children = g_list_insert (tree->children, data, pos-1); +} diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktree2.h b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktree2.h new file mode 100644 index 000000000..291a1d1b3 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktree2.h @@ -0,0 +1,139 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __GTK_TREE2_H__ +#define __GTK_TREE2_H__ + +/* set this flag to enable tree debugging output */ +/* #define TREE_DEBUG */ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define GTK_TYPE_TREE2 (gtk_tree2_get_type ()) +#define GTK_TREE2(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_TREE2, GtkTree2)) +#define GTK_TREE2_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_TREE2, GtkTree2Class)) +#define GTK_IS_TREE2(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_TREE2)) +#define GTK_IS_TREE2_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TREE2)) + +#define GTK_IS_ROOT_TREE2(obj) ((GtkObject*) GTK_TREE2(obj)->root_tree == (GtkObject*)obj) +#define GTK_TREE2_ROOT_TREE(obj) (GTK_TREE2(obj)->root_tree ? GTK_TREE2(obj)->root_tree : GTK_TREE2(obj)) +#define GTK_TREE2_SELECTION(obj) (GTK_TREE2_ROOT_TREE(obj)->selection) + +typedef enum +{ + GTK_TREE2_VIEW_LINE, /* default view mode */ + GTK_TREE2_VIEW_ITEM +} GtkTree2ViewMode; + +typedef struct _GtkTree2 GtkTree2; +typedef struct _GtkTree2Class GtkTree2Class; + +struct _GtkTree2 +{ + GtkContainer container; + + GList *children; + + GtkTree2* root_tree; /* owner of selection list */ + GtkWidget* tree_owner; + GList *selection; + guint level; + guint indent_value; + guint current_indent; + guint selection_mode : 2; + guint view_mode : 1; + guint view_line : 1; +}; + +struct _GtkTree2Class +{ + GtkContainerClass parent_class; + + void (* selection_changed) (GtkTree2 *tree); + void (* select_child) (GtkTree2 *tree, + GtkWidget *child); + void (* unselect_child) (GtkTree2 *tree, + GtkWidget *child); +}; + + +GtkType gtk_tree2_get_type (void); +GtkWidget* gtk_tree2_new (void); +void gtk_tree2_append (GtkTree2 *tree, + GtkWidget *tree_item); +void gtk_tree2_prepend (GtkTree2 *tree, + GtkWidget *tree_item); +void gtk_tree2_insert (GtkTree2 *tree, + GtkWidget *tree_item, + gint position); +void gtk_tree2_remove_items (GtkTree2 *tree, + GList *items); +void gtk_tree2_clear_items (GtkTree2 *tree, + gint start, + gint end); +void gtk_tree2_select_item (GtkTree2 *tree, + gint item); +void gtk_tree2_unselect_item (GtkTree2 *tree, + gint item); +void gtk_tree2_select_child (GtkTree2 *tree, + GtkWidget *tree_item); +void gtk_tree2_unselect_child (GtkTree2 *tree, + GtkWidget *tree_item); +gint gtk_tree2_child_position (GtkTree2 *tree, + GtkWidget *child); +void gtk_tree2_set_selection_mode (GtkTree2 *tree, + GtkSelectionMode mode); +void gtk_tree2_set_view_mode (GtkTree2 *tree, + GtkTree2ViewMode mode); +void gtk_tree2_set_view_lines (GtkTree2 *tree, + guint flag); + +/* deprecated function, use gtk_container_remove instead. + */ +void gtk_tree2_remove_item (GtkTree2 *tree, + GtkWidget *child); +void gtk_tree2_item_up (GtkTree2 *tree, + gint position); + +void gtk_tree2_select_next_child (GtkTree2 *tree, + GtkWidget *tree_item, gboolean descend); + +void gtk_tree2_select_prev_child (GtkTree2 *tree, + GtkWidget *tree_item); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GTK_TREE2_H__ */ diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktreeitem2.c b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktreeitem2.c new file mode 100644 index 000000000..7e6f8116b --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktreeitem2.c @@ -0,0 +1,1110 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#include +#include "gtktree2.h" +#include "gtktreeitem2.h" +#include +#include +#include +#include + +#include "tree_plus.xpm" +#include "tree_minus.xpm" + +#define DEFAULT_DELTA 9 + +enum { + COLLAPSE_TREE, + EXPAND_TREE, + LAST_SIGNAL +}; + +typedef struct _GtkTree2Pixmaps GtkTree2Pixmaps; + +struct _GtkTree2Pixmaps { + gint refcount; + GdkColormap *colormap; + + GdkPixmap *pixmap_plus; + GdkPixmap *pixmap_minus; + GdkBitmap *mask_plus; + GdkBitmap *mask_minus; +}; + +static GList *pixmaps = NULL; + +static void gtk_tree_item2_class_init (GtkTreeItem2Class *klass); +static void gtk_tree_item2_init (GtkTreeItem2 *tree_item); +static void gtk_tree_item2_realize (GtkWidget *widget); +static void gtk_tree_item2_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static void gtk_tree_item2_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static void gtk_tree_item2_draw (GtkWidget *widget, + GdkRectangle *area); +static void gtk_tree_item2_draw_focus (GtkWidget *widget); +static void gtk_tree_item2_paint (GtkWidget *widget, + GdkRectangle *area); +static gint gtk_tree_item2_button_press (GtkWidget *widget, + GdkEventButton *event); +static gint gtk_tree_item2_expose (GtkWidget *widget, + GdkEventExpose *event); +static gint gtk_tree_item2_focus_in (GtkWidget *widget, + GdkEventFocus *event); +static gint gtk_tree_item2_focus_out (GtkWidget *widget, + GdkEventFocus *event); +static void gtk_tree_item2_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); + +static void gtk_real_tree_item2_select (GtkItem *item); +static void gtk_real_tree_item2_deselect (GtkItem *item); +static void gtk_real_tree_item2_toggle (GtkItem *item); +static void gtk_real_tree_item2_expand (GtkTreeItem2 *item); +static void gtk_real_tree_item2_collapse (GtkTreeItem2 *item); +static void gtk_real_tree_item2_expand (GtkTreeItem2 *item); +static void gtk_real_tree_item2_collapse (GtkTreeItem2 *item); +static void gtk_tree_item2_destroy (GtkObject *object); +static void gtk_tree_item2_subtree_button_click (GtkWidget *widget); +static void gtk_tree_item2_subtree_button_changed_state (GtkWidget *widget); + +static void gtk_tree_item2_map(GtkWidget*); +static void gtk_tree_item2_unmap(GtkWidget*); + +static void gtk_tree_item2_add_pixmaps (GtkTreeItem2 *tree_item); +static void gtk_tree_item2_remove_pixmaps (GtkTreeItem2 *tree_item); + +static GtkItemClass *parent_class = NULL; +static guint tree_item_signals[LAST_SIGNAL] = { 0 }; + +GtkType +gtk_tree_item2_get_type (void) +{ + static GtkType tree_item_type = 0; + + if (!tree_item_type) + { + static const GtkTypeInfo tree_item_info = + { + "GtkTreeItem", + sizeof (GtkTreeItem2), + sizeof (GtkTreeItem2Class), + (GtkClassInitFunc) gtk_tree_item2_class_init, + (GtkObjectInitFunc) gtk_tree_item2_init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + tree_item_type = gtk_type_unique (gtk_item_get_type (), &tree_item_info); + } + + return tree_item_type; +} + +static void +gtk_tree_item2_class_init (GtkTreeItem2Class *class) +{ + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + GtkContainerClass *container_class; + GtkItemClass *item_class; + + object_class = (GtkObjectClass*) class; + widget_class = (GtkWidgetClass*) class; + item_class = (GtkItemClass*) class; + container_class = (GtkContainerClass*) class; + + parent_class = gtk_type_class (gtk_item_get_type ()); + + tree_item_signals[EXPAND_TREE] = + gtk_signal_new ("expand", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (GtkTreeItem2Class, expand), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + tree_item_signals[COLLAPSE_TREE] = + gtk_signal_new ("collapse", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (GtkTreeItem2Class, collapse), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, tree_item_signals, LAST_SIGNAL); + + object_class->destroy = gtk_tree_item2_destroy; + + widget_class->realize = gtk_tree_item2_realize; + widget_class->size_request = gtk_tree_item2_size_request; + widget_class->size_allocate = gtk_tree_item2_size_allocate; + widget_class->draw = gtk_tree_item2_draw; + widget_class->draw_focus = gtk_tree_item2_draw_focus; + widget_class->button_press_event = gtk_tree_item2_button_press; + widget_class->expose_event = gtk_tree_item2_expose; + widget_class->focus_in_event = gtk_tree_item2_focus_in; + widget_class->focus_out_event = gtk_tree_item2_focus_out; + widget_class->map = gtk_tree_item2_map; + widget_class->unmap = gtk_tree_item2_unmap; + + container_class->forall = gtk_tree_item2_forall; + + item_class->select = gtk_real_tree_item2_select; + item_class->deselect = gtk_real_tree_item2_deselect; + item_class->toggle = gtk_real_tree_item2_toggle; + + class->expand = gtk_real_tree_item2_expand; + class->collapse = gtk_real_tree_item2_collapse; +} + +/* callback for event box mouse event */ +static void +gtk_tree_item2_subtree_button_click (GtkWidget *widget) +{ + GtkTreeItem2* item; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_EVENT_BOX (widget)); + + item = (GtkTreeItem2*) gtk_object_get_user_data (GTK_OBJECT (widget)); + if (!GTK_WIDGET_IS_SENSITIVE (item)) + return; + + if (item->expanded) + gtk_tree_item2_collapse (item); + else + gtk_tree_item2_expand (item); +} + +/* callback for event box state changed */ +static void +gtk_tree_item2_subtree_button_changed_state (GtkWidget *widget) +{ + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_EVENT_BOX (widget)); + + if (GTK_WIDGET_VISIBLE (widget)) + { + + if (widget->state == GTK_STATE_NORMAL) + gdk_window_set_background (widget->window, &widget->style->base[widget->state]); + else + gdk_window_set_background (widget->window, &widget->style->bg[widget->state]); + + if (GTK_WIDGET_DRAWABLE (widget)) + gdk_window_clear_area (widget->window, 0, 0, + widget->allocation.width, widget->allocation.height); + } +} + +static void +gtk_tree_item2_init (GtkTreeItem2 *tree_item) +{ + GtkWidget *eventbox, *pixmapwid; + + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + tree_item->expanded = FALSE; + tree_item->subtree = NULL; + GTK_WIDGET_SET_FLAGS (tree_item, GTK_CAN_FOCUS); + + /* create an event box containing one pixmaps */ + eventbox = gtk_event_box_new(); + gtk_widget_set_events (eventbox, GDK_BUTTON_PRESS_MASK); + gtk_signal_connect(GTK_OBJECT(eventbox), "state_changed", + (GtkSignalFunc)gtk_tree_item2_subtree_button_changed_state, + (gpointer)NULL); + gtk_signal_connect(GTK_OBJECT(eventbox), "realize", + (GtkSignalFunc)gtk_tree_item2_subtree_button_changed_state, + (gpointer)NULL); +/* HF inutile + gtk_signal_connect(GTK_OBJECT(eventbox), "button_press_event", + (GtkSignalFunc)gtk_tree_item2_subtree_button_click, + (gpointer)NULL); +*/ + gtk_object_set_user_data(GTK_OBJECT(eventbox), tree_item); + tree_item->pixmaps_box = eventbox; + + /* create pixmap for button '+' */ + pixmapwid = gtk_type_new (gtk_pixmap_get_type ()); + if (!tree_item->expanded) + gtk_container_add (GTK_CONTAINER (eventbox), pixmapwid); + gtk_widget_show (pixmapwid); + tree_item->plus_pix_widget = pixmapwid; + gtk_widget_ref (tree_item->plus_pix_widget); + gtk_object_sink (GTK_OBJECT (tree_item->plus_pix_widget)); + + /* create pixmap for button '-' */ + pixmapwid = gtk_type_new (gtk_pixmap_get_type ()); + if (tree_item->expanded) + gtk_container_add (GTK_CONTAINER (eventbox), pixmapwid); + gtk_widget_show (pixmapwid); + tree_item->minus_pix_widget = pixmapwid; + gtk_widget_ref (tree_item->minus_pix_widget); + gtk_object_sink (GTK_OBJECT (tree_item->minus_pix_widget)); + + gtk_widget_set_parent (eventbox, GTK_WIDGET (tree_item)); +} + + +GtkWidget* +gtk_tree_item2_new (void) +{ + GtkWidget *tree_item; + + tree_item = GTK_WIDGET (gtk_type_new (gtk_tree_item2_get_type ())); + + return tree_item; +} + +GtkWidget* +gtk_tree_item2_new_with_label (gchar *label) +{ + GtkWidget *tree_item; + GtkWidget *label_widget; + + tree_item = gtk_tree_item2_new (); + label_widget = gtk_label_new (label); + gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5); + + gtk_container_add (GTK_CONTAINER (tree_item), label_widget); + gtk_widget_show (label_widget); + + + return tree_item; +} + +void +gtk_tree_item2_set_subtree (GtkTreeItem2 *tree_item, + GtkWidget *subtree) +{ + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + g_return_if_fail (subtree != NULL); + g_return_if_fail (GTK_IS_TREE2 (subtree)); + + if (tree_item->subtree) + { + g_warning("there is already a subtree for this tree item\n"); + return; + } + + tree_item->subtree = subtree; + GTK_TREE2 (subtree)->tree_owner = GTK_WIDGET (tree_item); + + /* show subtree button */ + if (tree_item->pixmaps_box) + gtk_widget_show (tree_item->pixmaps_box); + + if (tree_item->expanded) + gtk_widget_show (subtree); + else + gtk_widget_hide (subtree); + + gtk_widget_set_parent (subtree, GTK_WIDGET (tree_item)->parent); + + if (GTK_WIDGET_REALIZED (subtree->parent)) + gtk_widget_realize (subtree); + + if (GTK_WIDGET_VISIBLE (subtree->parent) && GTK_WIDGET_VISIBLE (subtree)) + { + if (GTK_WIDGET_MAPPED (subtree->parent)) + gtk_widget_map (subtree); + + gtk_widget_queue_resize (subtree); + } +} + +void +gtk_tree_item2_select (GtkTreeItem2 *tree_item) +{ + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + gtk_item_select (GTK_ITEM (tree_item)); +} + +void +gtk_tree_item2_deselect (GtkTreeItem2 *tree_item) +{ + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + gtk_item_deselect (GTK_ITEM (tree_item)); +} + +void +gtk_tree_item2_expand (GtkTreeItem2 *tree_item) +{ + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + gtk_signal_emit (GTK_OBJECT (tree_item), tree_item_signals[EXPAND_TREE], NULL); +} + +void +gtk_tree_item2_collapse (GtkTreeItem2 *tree_item) +{ + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + gtk_signal_emit (GTK_OBJECT (tree_item), tree_item_signals[COLLAPSE_TREE], NULL); +} + +static void +gtk_tree_item2_add_pixmaps (GtkTreeItem2 *tree_item) +{ + GList *tmp_list; + GdkColormap *colormap; + GtkTree2Pixmaps *pixmap_node = NULL; + + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + if (tree_item->pixmaps) + return; + + colormap = gtk_widget_get_colormap (GTK_WIDGET (tree_item)); + + tmp_list = pixmaps; + while (tmp_list) + { + pixmap_node = (GtkTree2Pixmaps *)tmp_list->data; + + if (pixmap_node->colormap == colormap) + break; + + tmp_list = tmp_list->next; + } + + if (tmp_list) + { + pixmap_node->refcount++; + tree_item->pixmaps = tmp_list; + } + else + { + pixmap_node = g_new (GtkTree2Pixmaps, 1); + + pixmap_node->colormap = colormap; + gdk_colormap_ref (colormap); + + pixmap_node->refcount = 1; + + /* create pixmaps for plus icon */ + pixmap_node->pixmap_plus = + gdk_pixmap_create_from_xpm_d (GTK_WIDGET (tree_item)->window, + &pixmap_node->mask_plus, + NULL, + tree_plus); + + /* create pixmaps for minus icon */ + pixmap_node->pixmap_minus = + gdk_pixmap_create_from_xpm_d (GTK_WIDGET (tree_item)->window, + &pixmap_node->mask_minus, + NULL, + tree_minus); + + tree_item->pixmaps = pixmaps = g_list_prepend (pixmaps, pixmap_node); + } + + gtk_pixmap_set (GTK_PIXMAP (tree_item->plus_pix_widget), + pixmap_node->pixmap_plus, pixmap_node->mask_plus); + gtk_pixmap_set (GTK_PIXMAP (tree_item->minus_pix_widget), + pixmap_node->pixmap_minus, pixmap_node->mask_minus); +} + +static void +gtk_tree_item2_remove_pixmaps (GtkTreeItem2 *tree_item) +{ + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + if (tree_item->pixmaps) + { + GtkTree2Pixmaps *pixmap_node = (GtkTree2Pixmaps *)tree_item->pixmaps->data; + + g_assert (pixmap_node->refcount > 0); + + if (--pixmap_node->refcount == 0) + { + gdk_colormap_unref (pixmap_node->colormap); + gdk_pixmap_unref (pixmap_node->pixmap_plus); + gdk_bitmap_unref (pixmap_node->mask_plus); + gdk_pixmap_unref (pixmap_node->pixmap_minus); + gdk_bitmap_unref (pixmap_node->mask_minus); + + pixmaps = g_list_remove_link (pixmaps, tree_item->pixmaps); + g_list_free_1 (tree_item->pixmaps); + g_free (pixmap_node); + } + + tree_item->pixmaps = NULL; + } +} + +static void +gtk_tree_item2_realize (GtkWidget *widget) +{ + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (widget)); + + if (GTK_WIDGET_CLASS (parent_class)->realize) + (* GTK_WIDGET_CLASS (parent_class)->realize) (widget); + + gdk_window_set_background (widget->window, + &widget->style->base[GTK_STATE_NORMAL]); + + gtk_tree_item2_add_pixmaps (GTK_TREE_ITEM2 (widget)); +} + +static void +gtk_tree_item2_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkBin *bin; + GtkTreeItem2* item; + GtkRequisition child_requisition; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (widget)); + g_return_if_fail (requisition != NULL); + + bin = GTK_BIN (widget); + item = GTK_TREE_ITEM2(widget); + + requisition->width = (GTK_CONTAINER (widget)->border_width + + widget->style->klass->xthickness) * 2; + requisition->height = GTK_CONTAINER (widget)->border_width * 2; + + if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) + { + GtkRequisition pix_requisition; + + gtk_widget_size_request (bin->child, &child_requisition); + + requisition->width += child_requisition.width; + + gtk_widget_size_request (item->pixmaps_box, + &pix_requisition); + requisition->width += pix_requisition.width + DEFAULT_DELTA + + GTK_TREE2 (widget->parent)->current_indent; + + requisition->height += MAX (child_requisition.height, + pix_requisition.height); + } +} + +static void +gtk_tree_item2_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkBin *bin; + GtkTreeItem2* item; + GtkAllocation child_allocation; + guint border_width; + int temp; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (widget)); + g_return_if_fail (allocation != NULL); + + widget->allocation = *allocation; + if (GTK_WIDGET_REALIZED (widget)) + gdk_window_move_resize (widget->window, + allocation->x, allocation->y, + allocation->width, allocation->height); + + bin = GTK_BIN (widget); + item = GTK_TREE_ITEM2(widget); + + if (bin->child) + { + border_width = (GTK_CONTAINER (widget)->border_width + + widget->style->klass->xthickness); + + child_allocation.x = border_width + GTK_TREE2(widget->parent)->current_indent; + child_allocation.y = GTK_CONTAINER (widget)->border_width; + + child_allocation.width = item->pixmaps_box->requisition.width; + child_allocation.height = item->pixmaps_box->requisition.height; + + temp = allocation->height - child_allocation.height; + child_allocation.y += ( temp / 2 ) + ( temp % 2 ); + + gtk_widget_size_allocate (item->pixmaps_box, &child_allocation); + + child_allocation.y = GTK_CONTAINER (widget)->border_width; + child_allocation.height = MAX (1, (gint)allocation->height - child_allocation.y * 2); + child_allocation.x += item->pixmaps_box->requisition.width+DEFAULT_DELTA; + + child_allocation.width = + MAX (1, (gint)allocation->width - ((gint)child_allocation.x + border_width)); + + gtk_widget_size_allocate (bin->child, &child_allocation); + } +} + +static void +gtk_tree_item2_draw_lines (GtkWidget *widget) +{ + GtkTreeItem2* item; + GtkTree2* tree; + guint lx1, ly1, lx2, ly2; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (widget)); + + item = GTK_TREE_ITEM2(widget); + tree = GTK_TREE2(widget->parent); + + /* draw vertical line */ + lx1 = item->pixmaps_box->allocation.width; + lx1 = lx2 = ((lx1 / 2) + (lx1 % 2) + + GTK_CONTAINER (widget)->border_width + 1 + tree->current_indent); + ly1 = 0; + ly2 = widget->allocation.height; + + if (g_list_last (tree->children)->data == widget) + ly2 = (ly2 / 2) + (ly2 % 2); + + if (tree != tree->root_tree) + gdk_draw_line (widget->window, widget->style->black_gc, lx1, ly1, lx2, ly2); + + /* draw vertical line for subtree connecting */ + if(g_list_last(tree->children)->data != (gpointer)widget) + ly2 = (ly2 / 2) + (ly2 % 2); + + lx2 += DEFAULT_DELTA; + + if (item->subtree && item->expanded) + gdk_draw_line (widget->window, widget->style->black_gc, + lx2, ly2, lx2, widget->allocation.height); + + /* draw horizontal line */ + ly1 = ly2; + lx2 += 2; + + gdk_draw_line (widget->window, widget->style->black_gc, + lx1, ly1, lx2, ly2); + + lx2 -= DEFAULT_DELTA+2; + ly1 = 0; + ly2 = widget->allocation.height; + + if (tree != tree->root_tree) + { + item = GTK_TREE_ITEM2 (tree->tree_owner); + tree = GTK_TREE2 (GTK_WIDGET (tree)->parent); + while (tree != tree->root_tree) + { + lx1 = lx2 -= tree->indent_value; + + if (g_list_last (tree->children)->data != item) + gdk_draw_line (widget->window, widget->style->black_gc, lx1, ly1, lx2, ly2); + item = GTK_TREE_ITEM2 (tree->tree_owner); + tree = GTK_TREE2 (GTK_WIDGET (tree)->parent); + } + } +} + +static void +gtk_tree_item2_paint (GtkWidget *widget, + GdkRectangle *area) +{ + GtkBin *bin; + GdkRectangle child_area, item_area; + GtkTreeItem2* tree_item; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (widget)); + g_return_if_fail (area != NULL); + + if (GTK_WIDGET_DRAWABLE (widget)) + { + bin = GTK_BIN (widget); + tree_item = GTK_TREE_ITEM2(widget); + + if (widget->state == GTK_STATE_NORMAL) + { + gdk_window_set_back_pixmap (widget->window, NULL, TRUE); + gdk_window_clear_area (widget->window, area->x, area->y, area->width, area->height); + } + else + { + if (!GTK_WIDGET_IS_SENSITIVE (widget)) + gtk_paint_flat_box(widget->style, widget->window, + widget->state, GTK_STATE_INSENSITIVE, + area, widget, "treeitem", + 0, 0, -1, -1); + else + gtk_paint_flat_box(widget->style, widget->window, + widget->state, GTK_SHADOW_ETCHED_OUT, + area, widget, "treeitem", + 0, 0, -1, -1); + } + + /* draw left size of tree item */ + item_area.x = 0; + item_area.y = 0; + item_area.width = (tree_item->pixmaps_box->allocation.width + DEFAULT_DELTA + + GTK_TREE2 (widget->parent)->current_indent + 2); + item_area.height = widget->allocation.height; + + + if (gdk_rectangle_intersect(&item_area, area, &child_area)) + { + + gtk_tree_item2_draw_lines(widget); + + if (tree_item->pixmaps_box && + GTK_WIDGET_VISIBLE(tree_item->pixmaps_box) && + gtk_widget_intersect (tree_item->pixmaps_box, area, &child_area)) + gtk_widget_draw (tree_item->pixmaps_box, &child_area); + } + + if (GTK_WIDGET_HAS_FOCUS (widget)) + gtk_paint_focus (widget->style, widget->window, + NULL, widget, "treeitem", + 0, 0, + widget->allocation.width - 1, + widget->allocation.height - 1); + + } +} + +static void +gtk_tree_item2_draw (GtkWidget *widget, + GdkRectangle *area) +{ + GtkBin *bin; + GdkRectangle child_area; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (widget)); + g_return_if_fail (area != NULL); + + if (GTK_WIDGET_DRAWABLE (widget)) + { + bin = GTK_BIN (widget); + + gtk_tree_item2_paint (widget, area); + + if (bin->child && + gtk_widget_intersect (bin->child, area, &child_area)) + gtk_widget_draw (bin->child, &child_area); + + } +} + +static void +gtk_tree_item2_draw_focus (GtkWidget *widget) +{ + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (widget)); + + gtk_widget_draw(widget, NULL); +} + +static gint +gtk_tree_item2_button_press (GtkWidget *widget, + GdkEventButton *event) +{ +/* HF + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_TREE_ITEM2 (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + if (event->type == GDK_BUTTON_PRESS + && GTK_WIDGET_IS_SENSITIVE(widget) + && !GTK_WIDGET_HAS_FOCUS (widget)) + gtk_widget_grab_focus (widget); + + return FALSE; + +*/ +} + +static gint +gtk_tree_item2_expose (GtkWidget *widget, + GdkEventExpose *event) +{ + GdkEventExpose child_event; + GtkBin *bin; + + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_TREE_ITEM2 (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + if (GTK_WIDGET_DRAWABLE (widget)) + { + bin = GTK_BIN (widget); + + gtk_tree_item2_paint (widget, &event->area); + + child_event = *event; + if (bin->child && GTK_WIDGET_NO_WINDOW (bin->child) && + gtk_widget_intersect (bin->child, &event->area, &child_event.area)) + gtk_widget_event (bin->child, (GdkEvent*) &child_event); + } + + return FALSE; +} + +static gint +gtk_tree_item2_focus_in (GtkWidget *widget, + GdkEventFocus *event) +{ + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_TREE_ITEM2 (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); + gtk_widget_draw_focus (widget); + + + return FALSE; +} + +static gint +gtk_tree_item2_focus_out (GtkWidget *widget, + GdkEventFocus *event) +{ + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_TREE_ITEM2 (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); + gtk_widget_draw_focus (widget); + + + return FALSE; +} + +static void +gtk_real_tree_item2_select (GtkItem *item) +{ + GtkTreeItem2 *tree_item; + GtkWidget *widget; + + g_return_if_fail (item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (item)); + + tree_item = GTK_TREE_ITEM2 (item); + widget = GTK_WIDGET (item); + + gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_SELECTED); + + if (!widget->parent || GTK_TREE2 (widget->parent)->view_mode == GTK_TREE2_VIEW_LINE) + gtk_widget_set_state (GTK_TREE_ITEM2 (item)->pixmaps_box, GTK_STATE_SELECTED); +} + +static void +gtk_real_tree_item2_deselect (GtkItem *item) +{ + GtkTreeItem2 *tree_item; + GtkWidget *widget; + + g_return_if_fail (item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (item)); + + tree_item = GTK_TREE_ITEM2 (item); + widget = GTK_WIDGET (item); + + gtk_widget_set_state (widget, GTK_STATE_NORMAL); + + if (!widget->parent || GTK_TREE2 (widget->parent)->view_mode == GTK_TREE2_VIEW_LINE) + gtk_widget_set_state (tree_item->pixmaps_box, GTK_STATE_NORMAL); +} + +static void +gtk_real_tree_item2_toggle (GtkItem *item) +{ + g_return_if_fail (item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (item)); + + if(!GTK_WIDGET_IS_SENSITIVE(item)) + return; + + if (GTK_WIDGET (item)->parent && GTK_IS_TREE2 (GTK_WIDGET (item)->parent)) + gtk_tree2_select_child (GTK_TREE2 (GTK_WIDGET (item)->parent), + GTK_WIDGET (item)); + else + { + /* Should we really bother with this bit? A listitem not in a list? + * -Johannes Keukelaar + * yes, always be on the safe side! + * -timj + */ + if (GTK_WIDGET (item)->state == GTK_STATE_SELECTED) + gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_NORMAL); + else + gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_SELECTED); + } +} + +static void +gtk_real_tree_item2_expand (GtkTreeItem2 *tree_item) +{ + GtkTree2* tree; + + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + if (tree_item->subtree && !tree_item->expanded) + { + tree = GTK_TREE2 (GTK_WIDGET (tree_item)->parent); + + /* hide subtree widget */ + gtk_widget_show (tree_item->subtree); + + /* hide button '+' and show button '-' */ + if (tree_item->pixmaps_box) + { + gtk_container_remove (GTK_CONTAINER (tree_item->pixmaps_box), + tree_item->plus_pix_widget); + gtk_container_add (GTK_CONTAINER (tree_item->pixmaps_box), + tree_item->minus_pix_widget); + } + if (tree->root_tree) + gtk_widget_queue_resize (GTK_WIDGET (tree->root_tree)); + tree_item->expanded = TRUE; + } +} + +static void +gtk_real_tree_item2_collapse (GtkTreeItem2 *tree_item) +{ + GtkTree2* tree; + + g_return_if_fail (tree_item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (tree_item)); + + if (tree_item->subtree && tree_item->expanded) + { + tree = GTK_TREE2 (GTK_WIDGET (tree_item)->parent); + + /* hide subtree widget */ + gtk_widget_hide (tree_item->subtree); + + /* hide button '-' and show button '+' */ + if (tree_item->pixmaps_box) + { + gtk_container_remove (GTK_CONTAINER (tree_item->pixmaps_box), + tree_item->minus_pix_widget); + gtk_container_add (GTK_CONTAINER (tree_item->pixmaps_box), + tree_item->plus_pix_widget); + } + if (tree->root_tree) + gtk_widget_queue_resize (GTK_WIDGET (tree->root_tree)); + tree_item->expanded = FALSE; + } +} + +static void +gtk_tree_item2_destroy (GtkObject *object) +{ + GtkTreeItem2* item; + GtkWidget* child; + + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (object)); + +#ifdef TREE_DEBUG + g_message("+ gtk_tree_item2_destroy [object %#x]\n", (int)object); +#endif /* TREE_DEBUG */ + + item = GTK_TREE_ITEM2(object); + + /* free sub tree if it exist */ + child = item->subtree; + if (child) + { + gtk_widget_ref (child); + gtk_widget_unparent (child); + gtk_widget_destroy (child); + gtk_widget_unref (child); + item->subtree = NULL; + } + + /* free pixmaps box */ + child = item->pixmaps_box; + if (child) + { + gtk_widget_ref (child); + gtk_widget_unparent (child); + gtk_widget_destroy (child); + gtk_widget_unref (child); + item->pixmaps_box = NULL; + } + + + /* destroy plus pixmap */ + if (item->plus_pix_widget) + { + gtk_widget_destroy (item->plus_pix_widget); + gtk_widget_unref (item->plus_pix_widget); + item->plus_pix_widget = NULL; + } + + /* destroy minus pixmap */ + if (item->minus_pix_widget) + { + gtk_widget_destroy (item->minus_pix_widget); + gtk_widget_unref (item->minus_pix_widget); + item->minus_pix_widget = NULL; + } + + /* By removing the pixmaps here, and not in unrealize, we depend on + * the fact that a widget can never change colormap or visual. + */ + gtk_tree_item2_remove_pixmaps (item); + + GTK_OBJECT_CLASS (parent_class)->destroy (object); + +#ifdef TREE_DEBUG + g_message("- gtk_tree_item2_destroy\n"); +#endif /* TREE_DEBUG */ +} + +void +gtk_tree_item2_remove_subtree (GtkTreeItem2* item) +{ + g_return_if_fail (item != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2(item)); + g_return_if_fail (item->subtree != NULL); + + if (GTK_TREE2 (item->subtree)->children) + { + /* The following call will remove the children and call + * gtk_tree_item2_remove_subtree() again. So we are done. + */ + gtk_tree2_remove_items (GTK_TREE2 (item->subtree), + GTK_TREE2 (item->subtree)->children); + return; + } + + if (GTK_WIDGET_MAPPED (item->subtree)) + gtk_widget_unmap (item->subtree); + + gtk_widget_unparent (item->subtree); + + if (item->pixmaps_box) + gtk_widget_hide (item->pixmaps_box); + + item->subtree = NULL; + + if (item->expanded) + { + item->expanded = FALSE; + if (item->pixmaps_box) + { + gtk_container_remove (GTK_CONTAINER (item->pixmaps_box), + item->minus_pix_widget); + gtk_container_add (GTK_CONTAINER (item->pixmaps_box), + item->plus_pix_widget); + } + } +} + +static void +gtk_tree_item2_map (GtkWidget *widget) +{ + GtkBin *bin; + GtkTreeItem2* item; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (widget)); + + bin = GTK_BIN (widget); + item = GTK_TREE_ITEM2(widget); + + GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); + + if(item->pixmaps_box && + GTK_WIDGET_VISIBLE (item->pixmaps_box) && + !GTK_WIDGET_MAPPED (item->pixmaps_box)) + gtk_widget_map (item->pixmaps_box); + + if (bin->child && + GTK_WIDGET_VISIBLE (bin->child) && + !GTK_WIDGET_MAPPED (bin->child)) + gtk_widget_map (bin->child); + + gdk_window_show (widget->window); +} + +static void +gtk_tree_item2_unmap (GtkWidget *widget) +{ + GtkBin *bin; + GtkTreeItem2* item; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (widget)); + + GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); + bin = GTK_BIN (widget); + item = GTK_TREE_ITEM2(widget); + + gdk_window_hide (widget->window); + + if(item->pixmaps_box && + GTK_WIDGET_VISIBLE (item->pixmaps_box) && + GTK_WIDGET_MAPPED (item->pixmaps_box)) + gtk_widget_unmap (bin->child); + + if (bin->child && + GTK_WIDGET_VISIBLE (bin->child) && + GTK_WIDGET_MAPPED (bin->child)) + gtk_widget_unmap (bin->child); +} + +static void +gtk_tree_item2_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) +{ + GtkBin *bin; + GtkTreeItem2 *tree_item; + + g_return_if_fail (container != NULL); + g_return_if_fail (GTK_IS_TREE_ITEM2 (container)); + g_return_if_fail (callback != NULL); + + bin = GTK_BIN (container); + tree_item = GTK_TREE_ITEM2 (container); + + if (bin->child) + (* callback) (bin->child, callback_data); +/* if (include_internals && tree_item->subtree) + (* callback) (tree_item->subtree, callback_data); */ +} diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktreeitem2.h b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktreeitem2.h new file mode 100644 index 000000000..bbbb364ad --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/gtktreeitem2.h @@ -0,0 +1,91 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __GTK_TREE_ITEM2_H__ +#define __GTK_TREE_ITEM2_H__ + + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define GTK_TYPE_TREE_ITEM2 (gtk_tree_item2_get_type ()) +#define GTK_TREE_ITEM2(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_TREE_ITEM2, GtkTreeItem2)) +#define GTK_TREE_ITEM2_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_TREE_ITEM2, GtkTreeItem2Class)) +#define GTK_IS_TREE_ITEM2(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_TREE_ITEM2)) +#define GTK_IS_TREE_ITEM2_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TREE_ITEM2)) + +#define GTK_TREE_ITEM2_SUBTREE(obj) (GTK_TREE_ITEM2(obj)->subtree) + + +typedef struct _GtkTreeItem2 GtkTreeItem2; +typedef struct _GtkTreeItem2Class GtkTreeItem2Class; + +struct _GtkTreeItem2 +{ + GtkItem item; + + GtkWidget *subtree; + GtkWidget *pixmaps_box; + GtkWidget *plus_pix_widget, *minus_pix_widget; + + GList *pixmaps; /* pixmap node for this items color depth */ + + guint expanded : 1; +}; + +struct _GtkTreeItem2Class +{ + GtkItemClass parent_class; + + void (* expand) (GtkTreeItem2 *tree_item); + void (* collapse) (GtkTreeItem2 *tree_item); +}; + + +GtkType gtk_tree_item2_get_type (void); +GtkWidget* gtk_tree_item2_new (void); +GtkWidget* gtk_tree_item2_new_with_label (gchar *label); +void gtk_tree_item2_set_subtree (GtkTreeItem2 *tree_item, + GtkWidget *subtree); +void gtk_tree_item2_remove_subtree (GtkTreeItem2 *tree_item); +void gtk_tree_item2_select (GtkTreeItem2 *tree_item); +void gtk_tree_item2_deselect (GtkTreeItem2 *tree_item); +void gtk_tree_item2_expand (GtkTreeItem2 *tree_item); +void gtk_tree_item2_collapse (GtkTreeItem2 *tree_item); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GTK_TREE_ITEM2_H__ */ diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/handlebox.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/handlebox.xpm new file mode 100644 index 000000000..e4d792cbb --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/handlebox.xpm @@ -0,0 +1,34 @@ +/* XPM */ +static char *handlebox_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 7 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray87", +"+ c Gray100", +"@ c None", +/* pixels */ +"@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@@@@@@@@@@@@", +"@++++++++++++++++++ @", +"@+OOOO.XXXXXXXXXXX. @", +"@++OOO.XXXXXXXXXXX. @", +"@+O.+O.XXXXXXXXXXX. @", +"@+OOO..XXXXXXXXXXX. @", +"@++OOO.XXXXXXXXXXX. @", +"@+O.+O.XXXXXXXXXXX. @", +"@+OOO..XXXXXXXXXXX. @", +"@++OOO.XXXXXXXXXXX. @", +"@+O.+O.XXXXXXXXXXX. @", +"@+OOO..XXXXXXXXXXX. @", +"@+................. @", +"@ @", +"@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@@@@@@@@@@@@" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/hbox.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/hbox.xpm new file mode 100644 index 000000000..7363317b6 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/hbox.xpm @@ -0,0 +1,31 @@ +/* XPM */ +static char *hbox_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 4 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c Gray100", +/* pixels */ +"oooooo oooooo oooooo ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"oXXXX. oXXXX. oXXXX. ", +"o..... o..... o..... ", +" " +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/hbuttonbox.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/hbuttonbox.xpm new file mode 100644 index 000000000..77d73dc46 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/hbuttonbox.xpm @@ -0,0 +1,33 @@ +/* XPM */ +static char *hbuttonbox_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 6 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray100", +"+ c None", +/* pixels */ +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+OOOOO +OOOOO +OOOOO ", +"+OXXX. +OXXX. +OXXX. ", +"+OXXX. +OXXX. +OXXX. ", +"+O.... +O.... +O.... ", +"+ + + ", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/hseparator.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/hseparator.xpm new file mode 100644 index 000000000..41ad8aafc --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/hseparator.xpm @@ -0,0 +1,31 @@ +/* XPM */ +static char *hseparator_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 4 1", +" c #7b7b7b", +". c #b3cece", +"X c Gray100", +"o c None", +/* pixels */ +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"o o", +"oXXXXXXXXXXXXXXXXXXXo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/label.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/label.xpm new file mode 100644 index 000000000..013e13a96 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/label.xpm @@ -0,0 +1,30 @@ +/* XPM */ +static char *label_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c Gray0", +". c #b3cece", +"X c None", +/* pixels */ +"XXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXX XXXXXXXXX", +"XXXXXXXXX XXXXXXXXX", +"XXXXXXXXX XXXXXXXXX", +"XXXXXXXX XXXXXXXX", +"XXXXXXXX XXXXXXXX", +"XXXXXXXX XXXXXXX", +"XXXXXXX X XXXXXXX", +"XXXXXXX X XXXXXX", +"XXXXXX XX XXXXXX", +"XXXXXX XXXXX", +"XXXXX XXXXX", +"XXXXX XXXXX XXXXX", +"XXXX XXXXX XXXX", +"XXX XXXXX XXX", +"XXX XXX XXX", +"XXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXX", +"XXXXXXXXXXXXXXXXXXXXX" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/load_lexer.mll b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/load_lexer.mll new file mode 100644 index 000000000..46aa5acc2 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/load_lexer.mll @@ -0,0 +1,46 @@ +{ +open Load_parser +} + +rule token = parse + [ ' ' '\t' '\n']+ { token lexbuf } +| "" { WINDOW_END } +| "name" { NAME } +| '=' { EQUAL } +| '>' { SUP } + +| "<" ['A'-'Z' 'a'-'z' '0'-'9' '_']+ + { + let l = Lexing.lexeme lexbuf in + let s = String.sub l ~pos:1 ~len:(String.length l - 1) in + WIDGET_START s + } + +| "' + { + let l = Lexing.lexeme lexbuf in + let s = String.sub l ~pos:2 ~len:(String.length l - 3) in + WIDGET_END s + } + +| '"' [^ '"']* '"' + { + let l = Lexing.lexeme lexbuf in + let s = String.sub l ~pos:1 ~len:(String.length l - 2) in + IDENT s + } + +| '\'' [^ '\'']* '\'' + { + let l = Lexing.lexeme lexbuf in + let s = String.sub l ~pos:1 ~len:(String.length l - 2) in + IDENT s + } + +| ['A'-'Z' 'a'-'z' '0'-'9' '_' '.']+ + { + let s = Lexing.lexeme lexbuf in IDENT s + } + +| eof { EOF } diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/load_parser.mly b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/load_parser.mly new file mode 100644 index 000000000..09c7b7bf7 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/load_parser.mly @@ -0,0 +1,56 @@ +%{ +open Utils +%} + +%token EOF NAME EQUAL SUP WINDOW_START WINDOW_END +%token WIDGET_START WIDGET_END IDENT + +%type window_start +%type property widget_start +%type <(string * string) list> property_list +%type widget window +%type children window_list project + +%start project +%start window +%start widget + +%% + +project : window_list EOF { List.rev $1 } + +window_list : { [] } + | window_list window { $2 :: $1 } +; + +window : window_start property_list children WINDOW_END + { + Node (("window", $1, List.rev $2), $3) + } +; + +window_start : WINDOW_START NAME EQUAL IDENT SUP { $4 } +; + +children : { [] } + | children widget { $2 :: $1 } +; + +widget : widget_start property_list children WIDGET_END + { + let classe, name = $1 in + if classe <> $4 then raise Parsing.Parse_error; + Node ((classe, name, List.rev $2), $3) + } +; + +widget_start : WIDGET_START NAME EQUAL IDENT SUP { $1, $4 } +; + +property_list : { [] } + | property_list property { $2 :: $1 } +; + +property : IDENT EQUAL IDENT { $1, $3 } +; + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/main.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/main.ml new file mode 100644 index 000000000..cb150e086 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/main.ml @@ -0,0 +1,393 @@ +(* $Id$ *) + +open GdkKeysyms +open Gtk +open GObj + +open Utils +open TiBase + +let main_project_modify = ref false + +let main_window = GWindow.window ~title:"ZOOM" ~x:10 ~y:10 () +let main_vbox = GPack.vbox ~packing:main_window#add () +let main_menu = GMenu.menu_bar ~packing:(main_vbox#pack ~expand:false) () + +let can_copy = ref (fun _ -> assert false) +let can_paste = ref (fun _ -> assert false) + +class project () = + let project_box = GPack.vbox ~packing:main_vbox#pack () in + let project_tree = GTree2.tree ~packing:project_box#pack () in + object(self) + val mutable window_list = [] + +(* the selected window *) + val mutable selected = (None : window_and_tree option) + + method change_selected sel = + match selected with + | None -> + selected <- Some sel; + sel#project_tree_item#misc#set_state `SELECTED; + !can_copy true + | Some old_sel -> + if sel = old_sel then begin + selected <- None; + sel#project_tree_item#misc#set_state `NORMAL; + !can_copy false + end else begin + old_sel#project_tree_item#misc#set_state `NORMAL; + selected <- Some sel; + sel#project_tree_item#misc#set_state `SELECTED; + !can_copy true + end + + val mutable filename = "" + val mutable dirname = "" + + method set_filename f = + let dir, file = split_filename f ~ext:".rad" in + filename <- file; + dirname <- dir + + method get_filename () = + get_filename ~callback:self#set_filename ~dir:dirname () + + method dirname = dirname + +(* method set_dirname f = dirname <- f *) + + method add_window ~name ?tree:wt () = + let wt = match wt with + | None -> new window_and_tree ~name + | Some wt -> wt in + let tiwin = wt#tiwin and tw=wt#tree_window in + let project_tree_item = wt#project_tree_item in + project_tree#append project_tree_item; + let show = ref true in + project_tree_item#event#connect#button_press ~callback: + (fun ev -> + match GdkEvent.get_type ev with + | `BUTTON_PRESS -> + if GdkEvent.Button.button ev = 1 then begin + self#change_selected wt + end else + if GdkEvent.Button.button ev = 3 then begin + let menu = GMenu.menu () in + let name = wt#tiwin#name in + let mi_remove = GMenu.menu_item ~label:("delete " ^ name) + ~packing:menu#append () + and mi_copy = GMenu.menu_item ~label:("copy " ^ name) + ~packing:menu#append () + and mi_cut = GMenu.menu_item ~label:("cut " ^ name) + ~packing:menu#append () in + mi_remove#connect#activate + ~callback:(fun () -> self#delete_window wt); + mi_copy#connect#activate + ~callback:(fun () -> self#copy_wt wt); + mi_cut#connect#activate + ~callback:(fun () -> self#cut_wt wt); + menu#popup ~button:3 ~time:(GdkEvent.Button.time ev) + end; + GtkSignal.stop_emit (); + true + | `TWO_BUTTON_PRESS -> + if GdkEvent.Button.button ev = 1 then begin + if !show then begin + show := false; + tiwin#widget#misc#hide (); + tw#misc#hide () + end + else begin + show := true; + tiwin#widget#misc#show (); + tw#misc#show () + end + end; + true + | _ -> false); + tiwin#connect_event#delete ~callback: + (fun _ -> show := false; tiwin#widget#misc#hide (); true); + tw#event#connect#delete ~callback: + (fun _ -> show := false; tw#misc#hide (); true); + window_list <- wt :: window_list; + add_undo (Remove_window name); + main_window#misc#set_can_focus false; + main_window#misc#grab_focus () + + + method add_window_by_node + (Node ((classe, name, proplist), children)) = + if classe <> "window" + then failwith "add_window_by_node: class <> \"window\""; + let name = change_name name in (* for paste *) + let wt = new window_and_tree ~name in + let tiwin = wt#tiwin in + List.iter proplist ~f:(fun (n,v) -> tiwin#set_property n v); + begin match children with + | [] -> () + | [ ch ] -> tiwin#add_children_wo_undo ch; () + | _ -> failwith "add_window_by_node: more than one child" + end; + self#add_window ~name ~tree:wt () + + method delete_window (wt : window_and_tree) = + let tiwin = wt#tiwin in + project_tree#remove wt#project_tree_item; + tiwin#remove_me (); + wt#tree_window#destroy (); + window_list <- list_remove ~f:(fun w -> w = wt) window_list + + method delete_window_by_name ~name = + let wt = List.find window_list ~f:(fun wt -> wt#tiwin#name = name) in + self#delete_window wt + + method delete () = + List.iter window_list + ~f:(fun wt -> self#delete_window wt); + main_vbox#remove project_box#coerce; +(* remove after test *) + if !name_list <> [] then failwith "name_list not empty" + + method save_as () = if self#get_filename () then self#save () + + method save () = + if filename = "" then self#save_as () + else begin + let outch = open_out (dirname ^ filename ^ ".rad") in + let f = Format.formatter_of_out_channel outch in + List.iter window_list ~f:(fun wt -> wt#tiwin#save f); + close_out outch; + main_project_modify := false + end + + method copy_wt (wt : window_and_tree) = + wt#tiwin#copy (); + !can_paste true + + method cut_wt (wt : window_and_tree) = + self#copy_wt wt; + self#delete_window wt + + method copy () = + match selected with + | None -> failwith "main_project copy" + | Some sel -> self#copy_wt sel + + method cut () = + match selected with + | None -> failwith "main_project cut" + | Some sel -> self#cut_wt sel + + method paste () = + let lexbuf = Lexing.from_string !window_selection in + let node = Load_parser.window Load_lexer.token lexbuf in + self#add_window_by_node node + + method emit () = + let outc = open_out (dirname ^ filename ^ ".ml") in + let f = Format.formatter_of_out_channel outc in + List.iter window_list ~f:(fun wt -> wt#emit f); + Format.fprintf f "let main () =@\n"; +(* this is just for demo *) + List.iter window_list ~f: + begin fun wt -> + let name = wt#tiwin#name in + Format.fprintf f " let %s = new %s () in %s#show ();@\n" + name name name + end; + Format.fprintf f + " GMain.Main.main ()@\n@\nlet _ = main ()@\n"; + close_out outc + + end + + +let main_project = ref (new project ()) + +let load () = + let filename = ref "" in + get_filename ~callback:(fun f -> filename := f) ~dir:!main_project#dirname (); + if !filename <> "" then begin + !main_project#delete (); + main_project := new project (); + let inch = open_in !filename in + let lexbuf = Lexing.from_channel inch in + let project_list = Load_parser.project Load_lexer.token lexbuf in + close_in inch; + List.iter project_list + ~f:(fun node -> !main_project#add_window_by_node node); + !main_project#set_filename !filename + end + + +let interpret_undo = function + | Add (parent_name, node, pos) -> + let parent = Hashtbl.find widget_map parent_name in + parent#add_children node ~pos + | Remove child_name -> + let child = Hashtbl.find widget_map child_name in + child#remove_me () + | Property (property, value_string) -> + property#set value_string + | Add_window node -> !main_project#add_window_by_node node + | Remove_window name -> !main_project#delete_window_by_name ~name + +let undo () = + if !last_action_was_undo then begin + match !next_undo_info with + | hd :: tl -> interpret_undo hd; next_undo_info := tl + | [] -> message "no more undo info" + end + else begin + match !undo_info with + | hd :: tl -> interpret_undo hd; next_undo_info := tl + | [] -> message "no undo info" + end; + last_action_was_undo := true + + +let targets = [ { target = "STRING"; flags = []; info = 0} ] + +let xpm_window () = + let source_drag_data_get classe _ (data : selection_data) ~info ~time = + data#set ~typ:data#target ~format:0 ~data:classe in + let window = GWindow.window ~title:"icons" ~x:250 ~y:10 () in + window#misc#realize (); + let vbox = GPack.vbox ~packing:window#add () in + let table = GPack.table ~rows:1 ~columns:5 ~border_width:20 + ~packing:vbox#pack () in + let tooltips = GData.tooltips () in + let add_xpm ~file ~left ~top ~tip = + let gdk_pix = GDraw.pixmap_from_xpm ~file ~window () in + let ev = GBin.event_box ~packing:(table#attach ~left ~top) () in + let pix = GMisc.pixmap gdk_pix ~packing:ev#add () in + ev#event#connect#button_press ~callback: + (fun ev -> match GdkEvent.get_type ev with + | `BUTTON_PRESS -> + if GdkEvent.Button.button ev = 1 then begin + !main_project#add_window ~name:(make_new_name "window") () + end; + true + | _ -> false); + tooltips#set_tip ev#coerce ~text:tip + in + add_xpm ~file:"window.xpm" ~left:0 ~top:0 ~tip:"window"; + GMisc.separator `HORIZONTAL ~packing:vbox#pack (); + let table = GPack.table ~rows:6 ~columns:6 ~packing:vbox#pack + ~row_spacings:20 ~col_spacings:20 ~border_width:20 () in + let add_xpm file ~left ~top ~classe = + let gdk_pix = GDraw.pixmap_from_xpm ~file ~window () in + let ev = GBin.event_box ~packing:(table#attach ~left ~top) () in + let pix = GMisc.pixmap gdk_pix ~packing:ev#add () in + ev#drag#source_set ~modi:[`BUTTON1] targets ~actions:[`COPY]; + ev#drag#source_set_icon ~colormap:window#misc#style#colormap + gdk_pix; + ev#drag#connect#data_get ~callback:(source_drag_data_get classe); + tooltips#set_tip ev#coerce ~text:classe + in + + add_xpm "button.xpm" ~left:0 ~top:0 ~classe:"button"; + add_xpm "togglebutton.xpm" ~left:1 ~top:0 ~classe:"toggle_button"; + add_xpm "checkbutton.xpm" ~left:2 ~top:0 ~classe:"check_button"; + add_xpm "radiobutton.xpm" ~left:3 ~top:0 ~classe:"radio_button"; + add_xpm "toolbar.xpm" ~left:4 ~top:0 ~classe:"toolbar"; + add_xpm "hbox.xpm" ~left:0 ~top:1 ~classe:"hbox"; + add_xpm "vbox.xpm" ~left:1 ~top:1 ~classe:"vbox"; + add_xpm "hbuttonbox.xpm" ~left:2 ~top:1 ~classe:"hbutton_box"; + add_xpm "vbuttonbox.xpm" ~left:3 ~top:1 ~classe:"vbutton_box"; + add_xpm "fixed.xpm" ~left:4 ~top:1 ~classe:"fixed"; + add_xpm "frame.xpm" ~left:0 ~top:2 ~classe:"frame"; + add_xpm "aspectframe.xpm" ~left:1 ~top:2 ~classe:"aspect_frame"; + add_xpm "scrolledwindow.xpm" ~left:2 ~top:2 ~classe:"scrolled_window"; + add_xpm "eventbox.xpm" ~left:3 ~top:2 ~classe:"event_box"; + add_xpm "handlebox.xpm" ~left:4 ~top:2 ~classe:"handle_box"; + add_xpm "viewport.xpm" ~left:5 ~top:2 ~classe:"viewport"; + add_xpm "hseparator.xpm" ~left:0 ~top:3 ~classe:"hseparator"; + add_xpm "vseparator.xpm" ~left:1 ~top:3 ~classe:"vseparator"; + add_xpm "clist.xpm" ~left:2 ~top:3 ~classe:"clist"; + add_xpm "label.xpm" ~left:0 ~top:4 ~classe:"label"; + add_xpm "statusbar.xpm" ~left:1 ~top:4 ~classe:"statusbar"; + add_xpm "notebook.xpm" ~left:2 ~top:4 ~classe:"notebook"; + add_xpm "colorselection.xpm" ~left:3 ~top:4 ~classe:"color_selection"; + add_xpm "pixmap.xpm" ~left:4 ~top:4 ~classe:"pixmap"; + add_xpm "entry.xpm" ~left:0 ~top:5 ~classe:"entry"; + add_xpm "spinbutton.xpm" ~left:1 ~top:5 ~classe:"spin_button"; + add_xpm "combo.xpm" ~left:2 ~top:5 ~classe:"combo"; + + window#show (); + window + + +let main () = + let _ = GMain.Main.init () in + let prop_win = Propwin.init () in + let palette = xpm_window () in + main_window#show (); + main_window#connect#destroy ~callback:GMain.Main.quit; + + let mp = main_project in + let f = new GMenu.factory main_menu in + let accel_group = f#accel_group in + main_window#add_accel_group accel_group; + prop_win#add_accel_group accel_group; + palette#add_accel_group accel_group; + + let file_menu = new GMenu.factory (f#add_submenu "File") ~accel_group + and edit_menu = new GMenu.factory (f#add_submenu "Edit") ~accel_group + and view_menu = new GMenu.factory (f#add_submenu "View") ~accel_group + and project_menu = new GMenu.factory (f#add_submenu "Project") ~accel_group + in + + file_menu#add_item "Quit" ~key:_Q ~callback:GMain.Main.quit; + + project_menu#add_item "New" ~key:_N + ~callback:(fun () -> !mp#delete (); mp := new project ()); + project_menu#add_item "Open..." ~key:_O ~callback:load; + project_menu#add_item "Save" ~key:_S ~callback:(fun () -> !mp#save ()); + project_menu#add_item "Save as..." ~callback:(fun () -> !mp#save_as ()); + project_menu#add_separator (); + project_menu#add_item "Emit code" ~callback:(fun () -> !mp#emit ()); + + let copy_item = + edit_menu#add_item "Copy" ~key:_C ~callback:(fun () -> !mp#copy ()) + and cut_item = + edit_menu#add_item "Cut" ~key:_X ~callback:(fun () -> !mp#cut ()) + and paste_item = + edit_menu#add_item "Paste" ~key:_V ~callback:(fun () -> !mp#paste ()) + in + can_copy := + (fun b -> copy_item#misc#set_sensitive b; cut_item#misc#set_sensitive b); + can_paste := paste_item#misc#set_sensitive; + !can_copy false; !can_paste false; + edit_menu#add_item "Undo" ~key:_Z ~callback:undo; + + let palette_visible = ref true in + palette#event#connect#delete ~callback: + (fun _ -> palette_visible := false; palette#misc#hide (); true); + view_menu#add_item "Palette" + ~callback:(fun () -> + if !palette_visible then begin + palette#misc#hide (); + palette_visible := false + end else begin + palette#misc#show (); + palette_visible := true + end); + let prop_win_visible = ref true in + prop_win#event#connect#delete ~callback: + (fun _ -> prop_win_visible := false; prop_win#misc#hide (); true); + view_menu#add_item "Properties window" + ~callback:(fun () -> + if !prop_win_visible then begin + prop_win#misc#hide (); + prop_win_visible := false + end else begin + prop_win#misc#show (); + prop_win_visible := true + end); + + GMain.Main.main () + +let _ = main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/ml_gtk2.c b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/ml_gtk2.c new file mode 100644 index 000000000..49ce27bbe --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/ml_gtk2.c @@ -0,0 +1,124 @@ +/* $Id$ */ + +#include +#include +#include +#include +#include +#include + +#include "../../wrappers.h" +#include "../../ml_glib.h" +#include "../../ml_gdk.h" +#include "../../ml_gtk.h" +#include "../../gtk_tags.h" + +#include "gtktree2.h" +#include "gtktreeitem2.h" + +#include + +value Val_GtkObject_sink (GtkObject *); + +#define Val_GtkAny(w) Val_GtkObject((GtkObject*)w) +#define Val_GtkAny_sink(w) Val_GtkObject_sink((GtkObject*)w) + +#define GtkWidget_val(val) check_cast(GTK_WIDGET,val) + +/* gtkwidget.h */ + + +#define Val_GtkWidget Val_GtkAny +#define Val_GtkWidget_sink Val_GtkAny_sink + + +/* gtktreeitem2.h */ + +#define GtkTreeItem2_val(val) check_cast(GTK_TREE_ITEM2,val) +ML_0 (gtk_tree_item2_new, Val_GtkWidget_sink) +ML_1 (gtk_tree_item2_new_with_label, String_val, Val_GtkWidget_sink) +ML_2 (gtk_tree_item2_set_subtree, GtkTreeItem2_val, GtkWidget_val, Unit) +ML_1 (gtk_tree_item2_remove_subtree, GtkTreeItem2_val, Unit) +ML_1 (gtk_tree_item2_expand, GtkTreeItem2_val, Unit) +ML_1 (gtk_tree_item2_collapse, GtkTreeItem2_val, Unit) +ML_1 (GTK_TREE_ITEM2_SUBTREE, GtkTreeItem2_val, Val_GtkWidget) + +/* gtktree2.h */ + +#define GtkTree2_val(val) check_cast(GTK_TREE2,val) +ML_0 (gtk_tree2_new, Val_GtkWidget_sink) +ML_3 (gtk_tree2_insert, GtkTree2_val, GtkWidget_val, Int_val, Unit) +ML_3 (gtk_tree2_clear_items, GtkTree2_val, Int_val, Int_val, Unit) +ML_2 (gtk_tree2_select_item, GtkTree2_val, Int_val, Unit) +ML_2 (gtk_tree2_unselect_item, GtkTree2_val, Int_val, Unit) +ML_2 (gtk_tree2_select_child, GtkTree2_val, GtkWidget_val, Unit) +ML_2 (gtk_tree2_unselect_child, GtkTree2_val, GtkWidget_val, Unit) +ML_2 (gtk_tree2_child_position, GtkTree2_val, GtkWidget_val, Val_int) + +/* +ML_2 (gtk_tree2_set_selection_mode, GtkTree2_val, Selection_mode_val, Unit) +ML_2 (gtk_tree2_set_view_mode, GtkTree2_val, Tree_view_mode_val, Unit) +*/ + +ML_2 (gtk_tree2_set_view_lines, GtkTree2_val, Bool_val, Unit) +ML_2 (gtk_tree2_item_up, GtkTree2_val, Int_val, Unit) +ML_3 (gtk_tree2_select_next_child, GtkTree2_val, GtkWidget_val, Bool_val, Unit) +ML_2 (gtk_tree2_select_prev_child, GtkTree2_val, GtkWidget_val, Unit) + +static value val_gtkany (gpointer p) { return Val_GtkAny(p); } +value ml_gtk_tree2_selection (value tree) +{ + GList *selection = GTK_TREE2_SELECTION(GtkTree2_val(tree)); + return Val_GList(selection, val_gtkany); +} +static gpointer gtkobject_val (value val) { return GtkObject_val(val); } +value ml_gtk_tree2_remove_items (value tree, value items) +{ + GList *items_list = GList_val (items, gtkobject_val); + gtk_tree2_remove_items (GtkTree2_val(tree), items_list); + return Val_unit; +} + +value ml_gtk_tree2_children (value tree) +{ + GList *children = (GtkTree2_val(tree))->children; + return Val_GList(children, val_gtkany); +} + + + +#define GtkToolbar_val(val) check_cast(GTK_TOOLBAR,val) +/* sets the text of the label of a button; creates the label + if necessary */ +value ml_gtk_toolbar2_set_text (value toolbar, value text, value pos) +{ + GtkToolbar *t = GtkToolbar_val(toolbar); + GtkToolbarChild *ch = (GtkToolbarChild *)g_list_nth_data (t->children, Int_val(pos)); + GtkWidget *label = ch->label; + + if (label) + gtk_label_set_text (GTK_LABEL(label), String_val(text)); + else { + label = ch->label = gtk_label_new (String_val(text)); + gtk_box_pack_end (GTK_BOX (GTK_BIN(ch->widget)->child), label, FALSE, FALSE, 0); + if (t->style != GTK_TOOLBAR_ICONS) + gtk_widget_show (label); + } + + return Val_unit; +} + +value ml_gtk_toolbar2_set_icon (value toolbar, value icon, value pos) +{ + GtkToolbar *t = GtkToolbar_val(toolbar); + GtkToolbarChild * ch = + (GtkToolbarChild *)g_list_nth_data (t->children, Int_val(pos)); + GtkWidget *vbox = GTK_BIN(ch->widget)->child; + gtk_container_remove (GTK_CONTAINER(vbox), ch->icon); + ch->icon = GtkWidget_val(icon); + gtk_box_pack_end (GTK_BOX (vbox), ch->icon, FALSE, FALSE, 0); + if (t->style != GTK_TOOLBAR_TEXT) + gtk_widget_show (ch->icon); + + return Val_unit; +} diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/notebook.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/notebook.xpm new file mode 100644 index 000000000..77ac20d6c --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/notebook.xpm @@ -0,0 +1,33 @@ +/* XPM */ +static char *notebook_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 6 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray100", +"+ c None", +/* pixels */ +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+OOOOOO.OOOO.OOOO.+++", +"+OXXXXX.X.X..X.X..+++", +"+OXXXXX..X.X..X.X.+++", +"+OXXXXX.X.X..X.X..+++", +"+OXXXXX.OOOOOOOOOOO +", +"+OXXXXXXXXXXXXXXXX. +", +"+OXXXXXXXXXXXXXXXX. +", +"+OXXXXXXXXXXXXXXXX. +", +"+OXXXXXXXXXXXXXXXX. +", +"+OXXXXXXXXXXXXXXXX. +", +"+OXXXXXXXXXXXXXXXX. +", +"+OXXXXXXXXXXXXXXXX. +", +"+OXXXXXXXXXXXXXXXX. +", +"+O................. +", +"+ +", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/pixmap.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/pixmap.xpm new file mode 100644 index 000000000..d76a5ec81 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/pixmap.xpm @@ -0,0 +1,39 @@ +/* XPM */ +static char *pixmap_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 12 1", +" c Gray0", +". c #007b00", +"X c #7b7b7b", +"o c Blue", +"O c Green", +"+ c Cyan", +"@ c Yellow", +"# c #d6d6d6", +"$ c #b3cece", +"% c Gray87", +"& c Gray100", +"* c None", +/* pixels */ +"*********************", +"*********************", +"*********************", +"* ", +"* +++++%%%&+++++++++ ", +"* +&&&++%%++&+++XX++ ", +"* +++++++%+++++X@@X+ ", +"* ++&&++++XX+++X@@X+ ", +"* +++++++ XXX&++XX++ ", +"* &+++++XXXXXX++++&+ ", +"* +++++ +++++ ", +"* +++++ ###### +++++ ", +"* +++++ #o##o# +++++ ", +"* ..... ###### ..... ", +"* OOOOO ##oo## OOOOO ", +"* OOOOO ##oo## OOOOO ", +"* OOOOO OOOOO ", +"* OOOOOOOOOOOOOOOOOO ", +"* ", +"*********************", +"*********************" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/property.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/property.ml new file mode 100644 index 000000000..829e40b7c --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/property.ml @@ -0,0 +1,175 @@ +(* $Id$ *) + +open Gtk +open GObj +open GEdit +open GData +open GPack +open GMisc +open GWindow + +open Common +open Utils + +(* external id : 'a -> 'a = "%identity" *) + +class virtual vprop ~name ~init ~set = + object (self) + val mutable s : string = init + val name : string = name + method private virtual parse : string -> 'a + method get = s + method set s' = + if s' <> s then begin + let v = self#parse s' in + if (set v) then begin + add_undo (Property ((self :> prop), s)); + s <- s' + end + end + method modified = s <> init + method name = name + method code = s + method virtual range : range + method save_code = self#code + end + +let invalid_prop kind name s = + invalid_arg (Printf.sprintf "Property.%s(%s) <- %s" kind name s) + +class prop_enum ~values ~name ~init ~set = + object (self) + inherit vprop ~name ~init ~set + method private parse s = + try List.assoc s values + with Not_found -> invalid_prop "enum" name s + method range = Enum (List.map ~f:fst values) + end + +(* used for radio_button groups; there is nothing to do + in radtest when setting a radio_button group, only when writing + code or saving *) +class prop_enum_dyn ~values ~name ~init ~set = + object (self) + inherit vprop ~name ~init ~set + method private parse s = () + method range = Enum (values ()) + end + +let bool_values = + [ "true", true; "false", false ] + +let shadow_type_values : (string * Tags.shadow_type) list = + [ "NONE", `NONE; "IN", `IN; "OUT", `OUT; + "ETCHED_IN", `ETCHED_IN; "ETCHED_OUT", `ETCHED_OUT ] + +let policy_type_values : (string * Tags.policy_type) list = + [ "ALWAYS", `ALWAYS; "AUTOMATIC", `AUTOMATIC ] + +let orientation_values : (string * Tags.orientation) list = + [ "HORIZONTAL", `HORIZONTAL; "VERTICAL", `VERTICAL ] + +let toolbar_style_values : (string * Tags.toolbar_style) list = + [ "ICONS", `ICONS; "TEXT", `TEXT; "BOTH", `BOTH ] + +let toolbar_space_style_values : (string * [`EMPTY | `LINE]) list = + [ "EMPTY", `EMPTY; "LINE", `LINE ] + +let relief_style_values : (string * Tags.relief_style) list = + [ "NORMAL", `NORMAL; "HALF", `HALF; "NONE", `NONE ] + +let position_values : (string * Tags.position) list = + [ "LEFT", `LEFT; "RIGHT", `RIGHT; "TOP", `TOP; "BOTTOM", `BOTTOM ] + +let combo_use_arrows_values : (string * [ `NEVER | `DEFAULT | `ALWAYS ]) list = +[ "NEVER", `NEVER; "DEFAULT", `DEFAULT; "ALWAYS", `ALWAYS ] + +let spin_button_update_policy_values : + (string * Tags. spin_button_update_policy) list = + [ "ALWAYS", `ALWAYS; "IF_VALID", `IF_VALID ] + +let button_box_style_values : (string * Tags.button_box_style) list = + [ "DEFAULT_STYLE", `DEFAULT_STYLE; "SPREAD", `SPREAD; "EDGE", `EDGE; + "START", `START; "END", `END ] + +let update_type_values : (string * Tags.update_type) list = + [ "CONTINUOUS", `CONTINUOUS; "DISCONTINUOUS", `DISCONTINUOUS; + "DELAYED", `DELAYED ] + + +class prop_bool = prop_enum ~values:bool_values + +(* +class prop_variant ~values ~name ~init ~set : prop = + object + inherit prop_enum ~values ~name ~init ~set + method code = "`" ^ s + end +*) + +class prop_shadow = prop_enum ~values:shadow_type_values +class prop_policy = prop_enum ~values:policy_type_values +class prop_orientation = prop_enum ~values:orientation_values +class prop_toolbar_style = prop_enum ~values:toolbar_style_values +class prop_toolbar_space_style = prop_enum ~values:toolbar_space_style_values +class prop_relief_style = prop_enum ~values:relief_style_values +class prop_position = prop_enum ~values:position_values +class prop_combo_use_arrows = prop_enum ~values:combo_use_arrows_values +class prop_spin_button_update_policy = prop_enum + ~values:spin_button_update_policy_values +class prop_button_box_style = prop_enum ~values:button_box_style_values +class prop_update_type = prop_enum ~values:update_type_values + +class prop_int ~name ~init ~set : prop = + object + inherit vprop ~name ~init ~set + method private parse s = + try int_of_string s with _ -> invalid_prop "int" name s + method range = Int + end + +(* NB: float_of_string doesn't raise an exception in case of error *) +class prop_float ~name ~init ~min ~max ~set : prop = + object + inherit vprop ~name ~init ~set + method private parse s = + try float_of_string s with _ -> invalid_prop "float" name s + method code = + if String.contains s '.' || String.contains s 'e' then s + else s ^ ".0" + method range = Float(min,max) + end + +class prop_string ~name ~init ~set : prop = + object + inherit vprop ~name ~init ~set + method private parse s = s + method range = String + method code = "\"" ^ String.escaped s ^ "\"" + end + +class prop_adjustment ~name ~init ~set : prop = + object + inherit vprop ~name ~init ~set + method private parse = get5floats_from_string + method range = Adjust + end + +class prop_clist_titles ~name ~init ~set : prop = + object + inherit vprop ~name ~init ~set + method private parse = split_string ~sep:' ' + method range = CList_titles + method code = "[ \"" ^ + String.concat ~sep:"\"; \"" (split_string ~sep:' ' s) ^ "\" ]" + method save_code = "\"" ^ s ^ "\"" + end + +class prop_file ~name ~init ~set : prop = + object + inherit vprop ~name ~init ~set + method private parse s = s + method range = File + method code = "\"" ^ String.escaped s ^ "\"" + end + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/property.mli b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/property.mli new file mode 100644 index 000000000..ccf265077 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/property.mli @@ -0,0 +1,96 @@ +(* $Id$ *) + +open Gtk.Tags +open Common + +class virtual vprop : + name:string -> (* property's name *) + init:string -> (* default value *) + set:('a -> bool) -> + object + val name : string + val mutable s : string + method code : string (* encoded value *) + method get : string + method modified : bool + method name : string + method private virtual parse : string -> 'a + method virtual range : range + method save_code : string + method set : string -> unit + end + +class prop_int : + name:string -> init:string -> set:(int -> bool) -> prop + +class prop_float : + name:string -> + init:string -> min:float -> max:float -> set:(float -> bool) -> prop + +class prop_string : + name:string -> init:string -> set:(string -> bool) -> prop + +class prop_bool : + name:string -> init:string -> set:(bool -> bool) -> prop +(* +class prop_variant : + values:(string * 'a) list -> + name:string -> init:string -> set:('a -> bool) -> prop +*) +class prop_shadow : + name:string -> init:string -> set:(shadow_type -> bool) -> prop + +class prop_policy : + name:string -> init:string -> set:(policy_type -> bool) -> prop + +class prop_orientation : + name:string -> + init:string -> set:(Gtk.Tags.orientation -> bool) -> prop + +class prop_toolbar_style : + name:string -> + init:string -> set:(Gtk.Tags.toolbar_style -> bool) -> prop + +class prop_toolbar_space_style : + name:string -> init:string -> set:([ `EMPTY | `LINE] -> bool) -> prop + +class prop_relief_style : + name:string -> + init:string -> set:(Gtk.Tags.relief_style -> bool) -> prop + +class prop_position : + name:string -> + init:string -> set:(Gtk.Tags.position -> bool) -> prop + +class prop_combo_use_arrows : + name:string -> + init:string -> set:([ `NEVER | `DEFAULT | `ALWAYS] -> bool) -> prop + +class prop_spin_button_update_policy : + name:string -> + init:string -> set:(Gtk.Tags.spin_button_update_policy -> bool) -> prop + +class prop_button_box_style : + name:string -> + init:string -> set:(Gtk.Tags.button_box_style -> bool) -> prop + +class prop_update_type : + name:string -> + init:string -> set:(Gtk.Tags.update_type -> bool) -> prop + +class prop_enum_dyn : + values:(unit -> string list) -> name:string -> + init:string -> set:(unit -> bool) -> prop + +class prop_adjustment : + name:string -> init:string -> + set:(float * float * float * float * float -> bool) -> prop + +class prop_clist_titles : + name:string -> init:string -> + set:(string list -> bool) -> prop + +class prop_file : + name:string -> init:string -> set:(string -> bool) -> prop + + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/propwin.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/propwin.ml new file mode 100644 index 000000000..2f8b29151 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/propwin.ml @@ -0,0 +1,180 @@ +(* $Id$ *) + +open GObj + +open Common +open Utils + +class type tiwidget_base = object + method name : string + method proplist : (string * prop) list +end + +let prop_widget (prop : prop) = + match prop#range with + Enum l -> + let w = GEdit.combo ~popdown_strings:l ~use_arrows:`ALWAYS () in + w#entry#connect#changed ~callback:(fun () -> prop#set w#entry#text); + w#entry#set_editable false; + w#entry#set_text prop#get; + w#coerce + | String -> + let w = GEdit.entry ~text:prop#get () in + w#connect#activate ~callback:(fun () -> prop#set w#text); + w#coerce + | File -> + let w = GPack.hbox () in + let e = GEdit.entry ~text:prop#get ~editable:false ~packing:w#pack () in + let b = GButton.button ~label:"..." ~packing:w#pack () in + b#connect#clicked + ~callback:(fun () -> get_filename + ~callback:(fun name -> e#set_text name; prop#set name) (); ()); + w#coerce + | Int -> + let adjustment = + GData.adjustment ~value:(float_of_string prop#get) + ~lower:(-2.) ~upper:5000. ~step_incr:1. ~page_incr:10. ~page_size:0. () + in + let w = GEdit.spin_button ~rate:0.5 ~digits:0 ~adjustment () in + w#connect#activate + ~callback:(fun () -> prop#set (string_of_int w#value_as_int)); + w#coerce + | Float (lower, upper) -> +(* let adjustment = + GData.adjustment ~value:(float_of_string prop#get) + ~lower ~upper ~step_incr:((upper-.lower)/.100.) + ~page_incr:((upper-.lower)/.10.) ~page_size:0. () + in + let w = GEdit.spin_button ~rate:0.5 ~digits:2 ~adjustment () in + w#connect#activate + ~callback:(fun () -> prop#set (string_of_float w#value)); + w#coerce +*) + let w = entry_float ~init:(float_of_string prop#get) () in + w#connect#activate + ~callback:(fun () -> prop#set (string_of_float w#value)); + w#coerce +(* | Adjust -> + let wpop = GWindow.window ~title:"Adjustment values" () in + let vb = GPack.vbox ~packing:wpop#add() in + let hb1 = GPack.hbox ~packing:vb#pack () in + let l1 = GMisc.label ~text:"lower" ~packing:hb1#pack () in + let e1 = entry_float ~packing:hb1#pack + ~init:(float_of_string prop#get) ~set:prop#set in +*) + | CList_titles -> + let wpop = GWindow.window ~title:"titles of the columns" () in + let vb = GPack.vbox ~packing:wpop#add () in + let titles = split_string prop#get ~sep:' ' in + let n = List.length titles in + let rtitles = ref titles in + let rget = ref [] and rset = ref [] in + for i = 1 to n do + match !rtitles with + | hd::tl -> + let hb = GPack.hbox ~packing:vb#pack () in + let _ = GMisc.label ~text:("column" ^ (string_of_int i)) + ~packing:hb#pack () in + let e = GEdit.entry ~text:hd ~packing:hb#pack () in + rtitles := tl; + rget := (fun () -> e#text) :: !rget; + rset := e#set_text :: !rset; + | _ -> failwith "CList_titles: this cannot happen!!" + done; + rtitles := titles; + rget := List.rev !rget; + rset := List.rev !rset; + let hb = GPack.hbox ~packing:vb#pack () in + let ok = GButton.button ~label:"OK" ~packing:hb#pack () in + let cancel = GButton.button ~label:"Cancel" ~packing:hb#pack () in + ok#connect#pressed + ~callback:(fun () -> + let tit = List.map ~f:(fun f -> f ()) !rget in + prop#set (String.concat ~sep:" " tit); + rtitles := tit; + wpop#misc#hide ()); + cancel#connect#pressed + ~callback:(fun () -> + wpop#misc#hide (); + List.iter2 ~f:(fun f v -> f v) !rset !rtitles); + let e = GEdit.entry ~text:"double click here" ~editable:false () in + e#event#connect#button_press ~callback: + (fun ev -> + GdkEvent.get_type ev = `TWO_BUTTON_PRESS && + GdkEvent.Button.button ev = 1 && + begin + wpop#misc#show (); + GtkSignal.stop_emit (); + true + end); + e#coerce + +let prop_box list = + let vbox = GPack.vbox () in + List.iter list ~f: + begin fun (name, prop) -> + let hbox = + GPack.hbox ~homogeneous:true ~packing:(vbox#pack ~expand:false) () in + GMisc.label ~text:name ~packing:hbox#pack (); + hbox#pack ~fill:true (prop_widget prop); + GMisc.separator `HORIZONTAL ~packing:(vbox#pack ~expand:false) (); + () + end; + vbox + +class ['a] frozen lz = object + method get : 'a = Lazy.force lz +end + +let vbox = + new frozen (lazy (GWindow.window ~show:true ~title:"Properties" ())) + +let init () = vbox#get + +let widget_pool = Hashtbl.create 7 + +let boxref = ref None +let shown_widget = ref "" + +let show_prop_box vb = + Gaux.may !boxref ~f:vbox#get#remove; + vbox#get#add vb#coerce; + boxref := Some vb#coerce + +let show (w : #tiwidget_base) = + let name = w#name in + let vb = + try + Hashtbl.find widget_pool name + with Not_found -> + let vb = prop_box w#proplist in + Hashtbl.add widget_pool ~key:name ~data:vb; + vb + in + show_prop_box vb; + shown_widget := name + +let add (w : #tiwidget_base) = + let vb = prop_box w#proplist in + Hashtbl.add widget_pool ~key:w#name ~data:vb + + +let remove name = + Hashtbl.remove widget_pool name; + if !shown_widget = name then begin + shown_widget := ""; + show_prop_box (GMisc.label ~text:"No widget selected" ()) + end + +(* +let change_name oldname newname = + let vb = Hashtbl.find widget_pool oldname in + Hashtbl.remove widget_pool oldname; + Hashtbl.add widget_pool ~key:newname ~data:vb +*) + +let update (w : #tiwidget_base) show_modif = + let vb = prop_box w#proplist in + Hashtbl.remove widget_pool w#name; + Hashtbl.add widget_pool ~key:w#name ~data:vb; + if show_modif && !shown_widget = w#name then show_prop_box vb diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/propwin.mli b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/propwin.mli new file mode 100644 index 000000000..6636a4f6f --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/propwin.mli @@ -0,0 +1,10 @@ +(* $Id$ *) + +open Common + +val init : unit -> GWindow.window +val show : #tiwidget_base -> unit +val add : #tiwidget_base -> unit +val remove : string -> unit +(* val change_name : string -> string -> unit *) +val update : #tiwidget_base -> bool -> unit diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/radiobutton.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/radiobutton.xpm new file mode 100644 index 000000000..0f5fbbd45 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/radiobutton.xpm @@ -0,0 +1,33 @@ +/* XPM */ +static char *radiobutton_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 6 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray100", +"+ c None", +/* pixels */ +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"++++++++++.++++++++++", +"+++++++++...+++++++++", +"++++++++.. ..++++++++", +"+++++++.. X ..+++++++", +"++++++.. XXX ..++++++", +"+++++.. XXXXX ..+++++", +"++++++OOXXXXXOO++++++", +"+++++++OOXXXOO+++++++", +"++++++++OOXOO++++++++", +"+++++++++OOO+++++++++", +"++++++++++O++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/scrolledwindow.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/scrolledwindow.xpm new file mode 100644 index 000000000..44e59f610 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/scrolledwindow.xpm @@ -0,0 +1,30 @@ +/* XPM */ +static char *scrolledwindow_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c Gray0", +". c #d6d6d6", +"X c Gray100", +/* pixels */ +"XXXXXXXXXXXXXXXXXXXXX", +"X.............X..... ", +"X.............X.. .. ", +"X.............X. . ", +"X.............X..... ", +"X.............X ", +"X.............XXXXXX ", +"X.............XX.... ", +"X.............XX.... ", +"X.............XXXXXX ", +"X.............X..... ", +"X.............X. . ", +"X.............X.. .. ", +"X.............X..... ", +"XXXXXXXXXXXXXXX ", +"X.... XXX .... ......", +"X.. . X.. . .. ......", +"X. . X.. . . ......", +"X.. . X.. . .. ......", +"X.... X.. .... ......", +"X ......" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/spinbutton.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/spinbutton.xpm new file mode 100644 index 000000000..f3a313b19 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/spinbutton.xpm @@ -0,0 +1,33 @@ +/* XPM */ +static char *spinbutton_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 6 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray100", +"+ c None", +/* pixels */ +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+ +", +"+ OOOOOOOOOOO OOOOO +", +"+ OOOOOOOOOOO OX X. +", +"+ OOOOOOOOOOO O . +", +"+ OOOOOOOOOOO OOOOO +", +"+ OOOOOOOOOOO O . +", +"+ OOOOOOOOOOO OX X. +", +"+ OOOOOOOOOOO ..... +", +"+ +", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/statusbar.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/statusbar.xpm new file mode 100644 index 000000000..8576d88c6 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/statusbar.xpm @@ -0,0 +1,34 @@ +/* XPM */ +static char *statusbar_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 7 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray87", +"+ c Gray100", +"@ c None", +/* pixels */ +"@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@@@@@@@@@@@@", +"@@@+XX.@@@@@@@@@@@@@@", +"@@@+XX.@@@@@@@@@@@@@@", +"@@@+XX.@@@@@@@@@@@@@@", +"@@@+XX.@@@@@@@@@@@@@@", +"@@@+XX++++++++++++@@@", +"@@@+XXXXXXXXXXXXXX@@@", +"@@@+XXXXXXXXXXXXXX@@@", +"@@@+XX............@@@", +"@@@+XX.OOOOOOOOOOO@@@", +"@@@+XX.OOOOOOOOOOO@@@", +"@@@+XX.OOOOOOOOOOO@@@", +"@@@+XX++++++++++++@@@", +"@@@+XXXXXXXXXXXXXX@@@", +"@@@+XXXXXXXXXXXXXX@@@", +"@@@ @@@", +"@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@@@@@@@@@@@@" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiBase.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiBase.ml new file mode 100644 index 000000000..390749337 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiBase.ml @@ -0,0 +1,671 @@ +(* $Id$ *) + +open Gaux +open Gtk +open GObj +open GContainer + +open Utils +open Common +open Property + +(* possible children; used to make the menus *) +let widget_add_list = + [ "vbox"; "hbox"; "vbutton_box"; "hbutton_box"; "fixed"; + "frame"; "aspect_frame"; "handle_box"; "event_box"; + "hseparator"; "vseparator"; "statusbar"; "label"; "notebook"; + "color_selection"; + "button"; + "toggle_button"; "check_button"; "radio_button"; "scrolled_window"; + + "entry"; "spin_button"; "combo"; "clist"; "toolbar"] + + +(*********** selection ***********) + +let selection = ref "" +let window_selection = ref "" + + +(**************** signals class ***************) + +class tiwidget_signals ~signals = + let name_changed : string signal = signals in + object + val after = false + method after = {< after = true >} + method name_changed = name_changed#connect ~after + end + + +(************* class type ***************) +(* the ti classes encapsulate the corresponding gtk + widget which will be in the gtk-window and a tree item + labelled with the name of the widget which will be in the + tree-window. + all these classes have the same following interface *) + +class virtual tiwidget0 = object + method virtual widget : GObj.widget + method virtual connect_event : GObj.event_signals + method virtual parent : tiwidget0 option + method virtual set_parent : tiwidget0 -> unit + method virtual base : GObj.widget + method virtual tree_item : GTree2.tree_item + method virtual tree : GTree2.tree + method virtual children : (tiwidget0 * Gtk.Tags.pack_type) list + method virtual name : string + method virtual proplist : (string * prop) list + method virtual add_to_proplist : (string * prop) list -> unit + method virtual change_name_in_proplist : string -> string -> unit + method virtual set_property : string -> string -> unit + method virtual forall : callback:(tiwidget0 -> unit) -> unit + method virtual remove : tiwidget0 -> unit +(* method virtual add_child_with_name : string -> string -> pos:int -> tiwidget0 *) + method virtual add_children : ?pos:int -> yywidget_tree -> unit + method virtual add_children_wo_undo : ?pos:int -> yywidget_tree -> string + method virtual remove_me : unit -> unit + method virtual remove_me_without_undo : unit -> unit + method virtual emit_code : Format.formatter -> char list -> unit + method virtual emit_init_code : Format.formatter -> packing:string -> unit + method virtual emit_method_code : Format.formatter -> unit + method virtual emit_initializer_code : Format.formatter -> unit + method virtual save : Format.formatter -> unit + method virtual copy : unit -> unit + method virtual connect : tiwidget_signals + method virtual disconnect : GtkSignal.id -> bool + method virtual child_up : tiwidget0 -> unit + method virtual up : unit -> unit + method virtual child_down : tiwidget0 -> unit + method virtual down : unit -> unit + method virtual next : tiwidget0 + method virtual next_child : tiwidget0 -> tiwidget0 + method virtual last : tiwidget0 + method virtual prev : tiwidget0 + method virtual set_full_menu : bool -> unit +end + +class virtual window_and_tree0 = object + method virtual tiwin : tiwidget0 +(* method virtual tree_window : window *) + method virtual change_selected : tiwidget0 -> unit + method virtual remove_sel : tiwidget0 -> unit + method virtual add_param : char + method virtual remove_param : char -> unit +(* method virtual emit : unit -> unit *) +end + +(* forward declaration of function new_widget *) +let new_tiwidget : + (classe:string -> ?pos:int -> name:string ->parent_tree:GTree2.tree -> + ?insert_evbox:bool -> ?listprop:(string * string) list -> window_and_tree0 -> tiwidget0) ref = + ref (fun ~classe ?pos ~name ~parent_tree ?insert_evbox ?listprop w -> failwith "new_tiwidget") + + +let widget_map = Hashtbl.create 17 + +(* list of names of radio_buttons (for groups) *) +let radio_button_pool = ref [] + + +(************* window creation class *************) +(* an instance of this class is created for each window opened + in radtest. It contains the tree window and the gtk window (tiwin) *) + +class window_and_tree ~name = + let tree_window = GWindow.window ~show:true ~title:(name ^ "-Tree") () in + let vbox = GPack.vbox ~spacing:2 ~packing:tree_window#add () in + let root_tree = GTree2.tree ~packing:vbox#pack ~selection_mode:`EXTENDED () in + let project_tree_item = GTree2.tree_item () in + let label = GMisc.label ~text:name ~xalign:0. ~yalign:0.5 + ~packing:project_tree_item#add () in + + object(self) + + inherit window_and_tree0 + +(* the params of the window class; because the class clist needs a param + I suppose there will be no more than 26 clists in a single window *) + val param_list = Array.create 26 false + + method add_param = + let i = ref 0 in + while param_list.(!i) do incr i done; + param_list.(!i) <- true; + char_of_int (97 + !i) + + method remove_param c = + param_list.(int_of_char c - 97) <- false + + method private param_list = + let r = ref [] in + for i = 25 downto 0 do + if Array.unsafe_get param_list i then r := (char_of_int (i+97)) :: !r + done; + !r + +(* I use magic here because the real initialization is done + below in the initializer part. It can't be done here because + of the call to self *) + val mutable tiwin = (Obj.magic 0 : tiwidget0) + + method tiwin = tiwin + method tree_window = tree_window + + method project_tree_item = project_tree_item + +(* the selected item in this window *) + val mutable selected = (None : tiwidget0 option) + +(* what to do when a new item is selected. + this method is passed to all the tiwidgets (by the select_fun + parameter) and they will call it when they are clicked on; + she is also called when changing the selection the arrow keys + (see in the initializer part) *) + method change_selected sel = + match selected with + | None -> + selected <- Some sel; + sel#tree_item#misc#set_state `SELECTED; + sel#base#misc#set_state `SELECTED; + Propwin.show sel + | Some old_sel -> + if sel = old_sel then begin + selected <- None; + sel#base#misc#set_state `NORMAL; + sel#tree_item#misc#set_state `NORMAL + end else begin + old_sel#tree_item#misc#set_state `NORMAL; + old_sel#base#misc#set_state `NORMAL; + selected <- Some sel; + sel#tree_item#misc#set_state `SELECTED; + sel#base#misc#set_state `SELECTED; + Propwin.show sel + end + +(* the tiwidget tiw is being removed; if it was selected, + put the selection to None *) + method remove_sel tiw = + match selected with + | Some sel when sel = tiw -> selected <- None + | _ -> () + +(* emits the code corresponding to this window *) + method emit c = tiwin#emit_code c self#param_list; + + method delete () = + tiwin#remove_me_without_undo (); + tree_window#destroy (); + + initializer + tiwin <- !new_tiwidget ~classe:"window" ~name ~parent_tree:root_tree + (self : #window_and_tree0 :> window_and_tree0); + + tiwin#connect#name_changed ~callback: + (fun n -> label#set_text n; tree_window#set_title (n ^ "-Tree")); + + Propwin.show tiwin; + + tree_window#event#connect#key_press ~callback: + begin fun ev -> + let state = GdkEvent.Key.state ev in + let keyval = GdkEvent.Key.keyval ev in + if keyval = GdkKeysyms._Up then begin + match selected with + | None -> () + | Some t -> + if List.mem `CONTROL state then t#up () + else try + self#change_selected t#prev + with Not_found -> () + end + else if keyval = GdkKeysyms._Down then begin + match selected with + | None -> () + | Some t -> + if List.mem `CONTROL state then t#down () + else try + self#change_selected t#next + with Not_found -> () + end; + GtkSignal.stop_emit (); + true + end; + () + end + + + +(***************** class implementation *****************) +(* this is the base class of the ti hierarchy. + all these classes will inherit from tiwidget, but without + adding new methods. In this way all the classes have the + same interface and we can use them in lists, pass them to + functions without caring on the type. + All methods needed by any of the classes are defined in + tiwidget but if a method is not pertinent in tiwidget + it has for implementation: + failwith "" + the real implementation of the method is done in the + class (or classes) in which it is needed (or sometimes + in tiwidget anyway). + Additionally, to workaround some problem with recursive types + the type of the (public) methods of tiwidget is defined in + tiwidget0 of which tiwidget inherits. + The parent_tree parameter is the tree in which the + tiwidget#tree_item will be inserted at position :pos. +*) + +class virtual tiwidget ~name ~parent_tree:(parent_tree : GTree2.tree) ~pos + ~widget ?(insert_evbox=true) (parent_window : window_and_tree0) = +object(self) + + inherit tiwidget0 + inherit has_ml_signals + + val evbox = + if insert_evbox then + let ev = GBin.event_box () in ev#add widget#coerce; Some ev + else None + +(* used only for windows delete_event *) + method connect_event = failwith "tiwidget::connect_event" + + val widget = widget#coerce + method widget = widget + + val mutable parent = None + method set_parent p = parent <- Some p + method parent = parent + method private sure_parent = + match parent with + | None -> failwith "sure_parent" + | Some p -> p + + method base = + match evbox with + | None -> widget#coerce + | Some ev -> ev#coerce + +(* this is the name used in new_tiwidget for the creation + of an object of this class *) + val mutable classe = "" + + val tree_item = GTree2.tree_item () + method tree_item = tree_item + + val mutable stree = GTree2.tree () + method tree = stree + + val label = GMisc.label ~text:name ~xalign:0. ~yalign:0.5 () + + val mutable name : string = name + method name = name + +(* this is the complete name for the creation of the widget + in lablgtk e.g. GPack.vbox; used in emit_init_code *) + method private class_name = "" + + val mutable proplist : (string * prop) list = [] + method proplist = proplist + method private get_mandatory_props = [] + + method add_to_proplist plist = proplist <- proplist @ plist + +(* for children of a box *) + method change_name_in_proplist : string -> string -> unit = + fun _ _ -> () + method set_property name value_string = try + (List.assoc name proplist)#set value_string + with Not_found -> Printf.printf "Property not_found %s, %s\n" name value_string; + flush stdout + + method private get_property name = + (List.assoc name proplist)#get + + +(* the proplist with some items removed e.g. the expand... in a box + used for saving and emitting code *) + method private emit_clean_proplist = + List.fold_left ~f:(fun l p -> List.remove_assoc p l) + ~init:proplist + ([ "name"; "expand"; "fill"; "padding" ] @ self#get_mandatory_props) +(* method private emit_clean_proplist plist = + List.fold_left ~init:plist ~f: + (fun pl propname -> List.remove_assoc propname pl) + [ "name"; "expand"; "fill"; "padding" ] +*) + + method private save_clean_proplist = + List.fold_left ~f:(fun l p -> List.remove_assoc p l) + ~init:proplist ("name" :: self#get_mandatory_props) +(* method private save_clean_proplist = + List.remove_assoc "name" proplist *) + + val mutable children : (tiwidget0 * Gtk.Tags.pack_type) list = [] + method children = children + method forall = + fun ~callback -> List.iter (List.map children ~f:fst) ~f:callback + +(* encapsulate container#add and container#remove + they are here because they depend on the type of the widget: + e.g.: gtkbin->add scrolled_window->add_with_viewport box->pack *) + method private add = failwith (name ^ "::add") + method remove = failwith (name ^ "::remove") + + +(* removes self from his parent; + will be different for a window *) + method remove_me () = + let sref = ref "" in + self#save_to_string sref; + let pos = list_pos ~item:(self : #tiwidget0 :> tiwidget0) + (List.map self#sure_parent#children ~f:fst) in + let lexbuf = Lexing.from_string !sref in + let node = Load_parser.widget Load_lexer.token lexbuf in + add_undo (Add (self#sure_parent#name, node, pos)); + self#remove_me_without_undo () + + method remove_me_without_undo () = +(* it should be enough to only recursively remove the children from the + name_list and do the tip#remove and tip#tree#remove + only for self *) + self#forall ~callback:(fun tiw -> tiw#remove_me_without_undo ()); + parent_window#remove_sel (self : #tiwidget0 :> tiwidget0); + match parent with + | None -> failwith "remove without parent" + | Some (tip : #tiwidget0) -> + tip#tree#remove tree_item; + tip#remove (self : #tiwidget0 :> tiwidget0); + name_list := list_remove !name_list ~f:(fun n -> n=name); + Hashtbl.remove widget_map name; + Propwin.remove name + +(* used for undo *) + method private remove_child_by_name name () = + let child = fst (List.find children + ~f:(fun (ch, _) -> ch#name = name)) in + child#remove_me () + +(* for most widgets we make a child with new_tiwidget and then add it + to self; for toolbars we use toolbar#insert_button... *) + method private make_child = !new_tiwidget + +(* adds a child and shows his properties; + used when adding a child by the menu or DnD *) + method private add_child classe ?name ?(undo = true) ?(affich = true) ?(pos = -1) ?(listprop = []) () = + let name = match name with + | None -> make_new_name classe + | Some n -> n in + let child = self#make_child ~classe ~name ~parent_tree:stree parent_window ~pos ~listprop in + child#set_parent (self : #tiwidget0 :> tiwidget0); + self#add child ~pos; + if affich then Propwin.show child; + if undo then add_undo (Remove name); + child + + +(* adds the subtree saved in the Node *) + method add_children ?(pos = -1) node = + let child_name = self#add_children_wo_undo node ~pos in + add_undo (Remove child_name) + + method add_children_wo_undo ?(pos = -1) (Node (child, children)) = + let classe, name, property_list = child in + let rname = change_name name in + let tc = self#add_child classe ~name:rname ~undo:false ~affich:false ~pos ~listprop:property_list () in + List.iter (List.rev children) + ~f:(fun c -> tc#add_children_wo_undo c; ()); + List.iter property_list ~f:(fun (n,v) -> tc#set_property n v); + rname + +(* only a tiwindow can emit code *) + method emit_code = failwith "emit_code" + +(* some methods for emitting code *) +(* this one calculates the expand, fill and padding parameters + of a box child *) + method private get_packing packing = + let aux name = + let prop = List.assoc name proplist in + if prop#modified then " ~" ^ name ^ ":" ^ prop#code else "" + in + let efp = try + (aux "expand") ^ (aux "fill") ^ (aux "padding") + with Not_found -> "" in + if efp = "" then ("~packing:" ^ packing) + else ("~packing:(" ^ packing ^ efp ^ ")") + +(* this one emits the declaration code of the widget *) + method emit_init_code formatter ~packing = + Format.fprintf formatter "@ @[let %s =@ @[%s" + name self#class_name; + List.iter self#get_mandatory_props + ~f:begin fun name -> + Format.fprintf formatter "@ ~%s:%s" name + (List.assoc name proplist)#code + end; + let packing = self#get_packing packing in + if packing <> "" then Format.fprintf formatter "@ %s" packing; + self#emit_prop_code formatter; + Format.fprintf formatter "@ ()@ in@]@]" + +(* this one emits the properties which do not have their + default value; used by emit_init_code *) + method private emit_prop_code formatter = + let mandatory = self#get_mandatory_props in + List.iter self#emit_clean_proplist ~f: + begin fun (name, prop) -> + if List.mem name mandatory then () else + if prop#modified then + Format.fprintf formatter "@ ~%s:%s" prop#name prop#code + end + +(* this one emits the method returning this widget *) + method emit_method_code formatter = + Format.fprintf formatter "@ method %s = %s" name name; + +(* emits the code in the initializer part for this widget *) + method emit_initializer_code _ = () + +(* for saving the project to a file. Used also by copy and cut *) + method private save_start formatter = + Format.fprintf formatter "@\n@[<2><%s name=%s>" classe name; + List.iter + ~f:(fun p -> Format.fprintf formatter + "@\n%s=\"%s\"" p (List.assoc p proplist)#get) + self#get_mandatory_props + + + method private save_end formatter = + Format.fprintf formatter "@]@\n" classe + + method save formatter = + self#save_start formatter; + List.iter self#save_clean_proplist ~f: + (fun (name, prop) -> + if prop#modified then + Format.fprintf formatter "@\n%s=%s" name prop#save_code); + self#forall ~callback:(fun w -> w#save formatter); + self#save_end formatter + + + method private save_to_string string_ref = + let b = Buffer.create 80 in + let f = Format.formatter_of_buffer b in + self#save f; + Format.pp_print_flush f (); + string_ref := Buffer.contents b + + method private copy_to_sel selection = self#save_to_string selection + + method copy () = self#copy_to_sel selection + + method private cut () = + self#copy (); + self#remove_me () + + method private paste () = + let lexbuf = Lexing.from_string !selection in + let node = Load_parser.widget Load_lexer.token lexbuf in + self#add_children node + + +(* ML signal used when the name of the widget is changed *) + val name_changed : string signal = new signal + method connect = new tiwidget_signals ~signals:name_changed + method private call_name_changed = name_changed#call + + +(* this is necessary because gtk_tree#remove deletes the tree + when removing the last item *) +(* suppressed this in gtktree2 + method new_tree () = + stree <- GTree2.tree; + tree_item#set_subtree stree; + tree_item#expand () +*) + +(* when full_menu is true we use the menu else the restricted menu *) + val mutable full_menu = true + method set_full_menu b = full_menu <- b + +(* the menu for this widget + This menu is recalculated when one clicks on the 3rd button. + There is nothing to do e.g. when the name of the widget changes, + it will change in the menu the next time. *) + method private menu ~time = self#restricted_menu ~time + +(* the restricted menu for this widget + used for containers when they are full *) + method private restricted_menu ~time = + let menu = GMenu.menu () in + let mi_remove = GMenu.menu_item ~packing:menu#append ~label:"remove" () + and mi_cut = GMenu.menu_item ~packing:menu#append ~label:"Cut" () + and mi_copy = GMenu.menu_item ~packing:menu#append ~label:"Copy" () in + mi_remove#connect#activate ~callback:self#remove_me; + mi_copy#connect#activate ~callback:self#copy; + mi_cut#connect#activate ~callback:self#cut; + menu#popup ~button:3 ~time + +(* changes all that depends on the name *) + method private set_new_name new_name = + if test_unique new_name then begin + Hashtbl.remove widget_map name; + Hashtbl.add widget_map ~key:new_name + ~data:(self : #tiwidget0 :> tiwidget0); + if (classe = "radio_button") then begin + radio_button_pool := new_name :: + (list_remove !radio_button_pool ~f:(fun x -> x = name)); + List.iter + ~f:(fun x -> Propwin.update (Hashtbl.find widget_map x) false) + !radio_button_pool + end; + label#set_text new_name; + let old_name = name in + name <- new_name; +(* Propwin.change_name old_name new_name; *) + name_list := + new_name :: (list_remove !name_list ~f:(fun n -> n=old_name)); + begin match self#parent with + | None -> () + | Some p -> p#change_name_in_proplist old_name new_name + end; + self#call_name_changed new_name; + true + end + else begin + message_name (); + Propwin.update self true; + false + end + + +(* moves the present tiw up in his parents' children list *) +(* does something only when the parent is a box *) + method child_up = fun _ -> () + + method up () = match parent with + | None -> () + | Some t -> t#child_up (self : #tiwidget0 :> tiwidget0) + + method child_down = fun _ -> () + + method down () = match parent with + | None -> () + | Some t -> t#child_down (self : #tiwidget0 :> tiwidget0) + + +(* get the next tiwidget in the tree (used with Down arrow) *) + method next = + if children <> [] then fst (List.hd children) + else begin + match parent with + | None -> raise Not_found + | Some p -> p#next_child (self : #tiwidget0 :> tiwidget0) + end + + method next_child child = + let _, tl = cut_list ~item:child (List.map ~f:fst children) in + match tl with + | ch :: next :: _ -> next + | ch :: [] -> begin + match parent with + | None -> raise Not_found + | Some p -> p#next_child (self : #tiwidget0 :> tiwidget0) + end + | _ -> failwith "next_child" + +(* get the last child of the last child ... of our last child. + Used by prev. *) + method last = + if children = [] then (self : #tiwidget0 :> tiwidget0) + else (fst (List.hd (List.rev children)))#last + +(* get the previous tiwidget in the tree (used with Up arrow) *) + method prev = + match parent with + | None -> raise Not_found + | Some p -> + let hd, _ = cut_list ~item:(self : #tiwidget0 :> tiwidget0) + (List.map ~f:fst p#children) in + match hd with + | [] -> p + | h :: _ -> h#last + + initializer + Hashtbl.add widget_map ~key:name ~data:(self : #tiwidget0 :> tiwidget0); + name_list := name :: !name_list; + parent_tree#insert tree_item ~pos; + tree_item#set_subtree stree; + tree_item#add label#coerce; + tree_item#expand (); + + proplist <- proplist @ + [ "name", + new prop_string ~name:"name" ~init:name ~set:self#set_new_name; + "width", new prop_int ~name:"width" ~init:"-2" + ~set:(fun v -> widget#misc#set_geometry ~width:v (); true); + "height", new prop_int ~name:"height" ~init:"-2" + ~set:(fun v -> widget#misc#set_geometry ~height:v (); true) ]; + + self#add_signal name_changed; + + tree_item#event#connect#button_press ~callback: + (fun ev -> match GdkEvent.get_type ev with + | `BUTTON_PRESS -> + if GdkEvent.Button.button ev = 1 then begin + parent_window#change_selected + (self : #tiwidget0 :> tiwidget0); + end + else if GdkEvent.Button.button ev = 3 then begin + if full_menu + then self#menu ~time:(GdkEvent.Button.time ev) + else self#restricted_menu ~time:(GdkEvent.Button.time ev); + end; + GtkSignal.stop_emit (); + true + | _ -> false); + () +end + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiBin.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiBin.ml new file mode 100644 index 000000000..5ebcb3e2e --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiBin.ml @@ -0,0 +1,185 @@ +open Gtk + +open Utils +open Property + +open TiContainer + +class tiframe ~(widget : GBin.frame) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object + val frame = widget + inherit ticontainer ~name ~widget ~parent_tree ~pos + ~insert_evbox parent_window as container + + method private class_name = "GBin.frame" + + method private get_mandatory_props = [ "label" ] + + initializer + classe <- "frame"; + frame#set_label name; + proplist <- proplist @ + [ "label", + new prop_string ~name:"label" ~init:name ~set:(ftrue frame#set_label); + "label_xalign", + new prop_float ~name:"label_xalign" ~init:"0.0" ~min:0. ~max:1. + ~set:(fun x -> frame#set_label_align ~x (); true); + "shadow_type", + new prop_shadow ~name:"shadow_type" ~init:"ETCHED_IN" + ~set:(ftrue frame#set_shadow_type) ] +end + +let new_tiframe ~name ?(listprop = []) = + new tiframe ~widget:(GBin.frame ()) ~name + + + + +class tiaspect_frame ~(widget : GBin.aspect_frame) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object + val aspect_frame = widget + inherit tiframe ~name ~widget:(widget :> GBin.frame) ~parent_tree ~pos + ~insert_evbox parent_window + + method private class_name = "GBin.aspect_frame" + + initializer + classe <- "aspect_frame"; + frame#set_label name; + proplist <- proplist @ + [ "obey_child", + new prop_bool ~name:"obey_child" ~init:"true" + ~set:(ftrue aspect_frame#set_obey_child); + "ratio", + new prop_float ~name:"ratio" ~init:"1.0" ~min:0. ~max:1. + ~set:(ftrue aspect_frame#set_ratio) + ] +end + +let new_tiaspect_frame ~name ?(listprop = []) = + new tiaspect_frame ~widget:(GBin.aspect_frame ()) ~name + + + + +class tievent_box ~(widget : GBin.event_box) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object + val event_box = widget + inherit ticontainer ~name ~widget ~parent_tree ~pos + ~insert_evbox parent_window + + method private class_name = "GBin.event_box" + initializer + classe <- "event_box" +end + +let new_event_box ~name ?(listprop = []) = + new tievent_box ~widget:(GBin.event_box ()) ~name + + + + +class tihandle_box ~(widget : GBin.handle_box) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object + val handle_box = widget + inherit ticontainer ~name ~widget ~parent_tree ~pos + ~insert_evbox parent_window + + method private class_name = "GBin.handle_box" + + initializer + classe <- "handle_box"; + proplist <- proplist @ + [ "shadow_type", + new prop_shadow ~name:"shadow_type" ~init:"OUT" + ~set:(ftrue handle_box#set_shadow_type); + "handle_position", + new prop_position ~name:"handle_position" ~init:"LEFT" + ~set:(ftrue handle_box#set_handle_position); + "snap_edge", + new prop_position ~name:"snap_edge" ~init:"TOP" + ~set:(ftrue handle_box#set_snap_edge) + ] +end + +let new_handle_box ~name ?(listprop = []) = + new tihandle_box ~widget:(GBin.handle_box ()) ~name + + + + + +class tiviewport ~(widget : GBin.handle_box) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object + val viewport = widget + inherit ticontainer ~name ~widget ~parent_tree ~pos + ~insert_evbox parent_window + + method private class_name = "GBin.viewport" + + initializer + classe <- "viewport"; + proplist <- proplist @ + [ "shadow_type", + new prop_shadow ~name:"shadow_type" ~init:"OUT" + ~set:(ftrue viewport#set_shadow_type) + ] +end + +let new_viewport ~name ?(listprop = []) = + new tiviewport ~widget:(GBin.handle_box ()) ~name + + + + + +class tiscrolled_window ~(widget : GBin.scrolled_window) + ~name ~parent_tree ~pos ?(insert_evbox=true) parent_window = + object(self) + val scrolled_window = widget + inherit ticontainer ~name ~insert_evbox + ~parent_tree ~pos ~widget parent_window + + method private class_name = "GBin.scrolled_window" + method private name_of_add_method = "#add_with_viewport" + + method private add rw ~pos = + scrolled_window#add_with_viewport (rw#base); + children <- [ rw, `START]; + self#set_full_menu false; + tree_item#drag#dest_unset () + +(* we must remove the child from the viewport, + not from the scrolled_window; + it is not mandatory to remove the viewport + from the scrolled_window *) + method remove child = + let viewport = (new GContainer.container (GtkBase.Container.cast (List.hd scrolled_window#children)#as_widget)) in + viewport#remove child#base; +(* scrolled_window#remove (List.hd scrolled_window#children); *) + children <- [ ]; + self#set_full_menu true; + tree_item#drag#dest_set ~actions:[`COPY] + [ { target = "STRING"; flags = []; info = 0} ] + + + initializer + classe <- "scrolled_window"; + proplist <- proplist @ + [ "hscrollbar_policy", + new prop_policy ~name:"hscrollbar_policy" ~init:"ALWAYS" + ~set:(ftrue scrolled_window#set_hpolicy); + "vscrollbar_policy", + new prop_policy ~name:"vscrollbar_policy" ~init:"ALWAYS" + ~set:(ftrue scrolled_window#set_vpolicy) ] +end + +let new_tiscrolled_window ~name ?(listprop = []) = + new tiscrolled_window ~widget:(GBin.scrolled_window ()) ~name + + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiButton.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiButton.ml new file mode 100644 index 000000000..174c6ebff --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiButton.ml @@ -0,0 +1,372 @@ +open Utils +open Property + +open TiBase +open TiContainer + +(* the button inherits from widget because it can't accept + a child; + needs to add the border_width property *) +class tibutton ~(widget : #GButton.button) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object(self) + val button = widget + inherit tiwidget ~name ~widget ~parent_tree ~pos ~insert_evbox + parent_window as widget + + method private class_name = "GButton.button" + + method private get_mandatory_props = [ "label" ] + + initializer + classe <- "button"; + proplist <- proplist @ + [ "border_width", new prop_int ~name:"border_width" ~init:"0" + ~set:(ftrue button#set_border_width); + "label", + new prop_string ~name:"label" ~init:name ~set: + begin fun v -> + button#remove (List.hd button#children)#coerce; + GMisc.label ~text:v ~xalign:0.5 ~yalign:0.5 ~packing:button#add (); + true + end ] +end + +let new_tibutton ~name ?(listprop = []) = + let b = GButton.button ~label:name () in + b#event#connect#enter_notify + ~callback:(fun _ -> GtkSignal.stop_emit (); true); + b#event#connect#leave_notify + ~callback:(fun _ -> GtkSignal.stop_emit (); true); + new tibutton ~widget:b ~name + + +class ticheck_button ~(widget : #GButton.toggle_button) ~name + ~parent_tree ~pos ?(insert_evbox=true) parent_window = +object(self) + val button = widget + inherit tiwidget ~name ~widget ~insert_evbox + ~parent_tree ~pos parent_window as widget + + + method private class_name = "GButton.check_button" + + method private get_mandatory_props = [ "label" ] + + initializer + classe <- "check_button"; + proplist <- proplist @ + [ "border_width", new prop_int ~name:"border_width" ~init:"0" + ~set:(ftrue button#set_border_width); + "label", + new prop_string ~name:"label" ~init:name ~set: + begin fun v -> + button#remove (List.hd button#children)#coerce; + GMisc.label ~text:v ~xalign:0.5 ~yalign:0.5 ~packing:button#add (); + true + end + ] +end + +let new_ticheck_button ~name ?(listprop = []) = + new ticheck_button ~widget:(GButton.check_button ~label:name ()) ~name + + + +class titoggle_button ~(widget : #GButton.toggle_button) ~name + ~parent_tree ~pos ?(insert_evbox=true) parent_window = +object(self) + val button = widget + inherit tiwidget ~name ~widget ~insert_evbox + ~parent_tree ~pos parent_window as widget + + method private class_name = "GButton.toggle_button" + + method private get_mandatory_props = [ "label" ] + + initializer + classe <- "toggle_button"; + proplist <- proplist @ + [ "border width", new prop_int ~name:"border_width" ~init:"0" + ~set:(ftrue button#set_border_width); + "label", + new prop_string ~name:"label" ~init:name ~set: + begin fun v -> + button#remove (List.hd button#children)#coerce; + GMisc.label ~text:v ~xalign:0.5 ~yalign:0.5 ~packing:button#add (); + true + end ] +end + +let new_titoggle_button ~name ?(listprop = []) = + let b = GButton.toggle_button ~label:name () in +(* b#connect#event#enter_notify + ~callback:(fun _ -> GtkSignal.stop_emit ()); + b#connect#event#leave_notify + ~callback:(fun _ -> GtkSignal.stop_emit ()); +*) + new titoggle_button ~name ~widget:b + + +class tiradio_button ~(widget : #GButton.radio_button) ~name:nname + ~parent_tree ~pos ?(insert_evbox=true) parent_window = +object(self) + val button = widget + inherit tiwidget ~name:nname ~widget ~insert_evbox + ~parent_tree ~pos parent_window as widget + + val group_prop = + new prop_enum_dyn ~values:(fun () -> !radio_button_pool) ~name:"group" + ~set:(fun () -> true) ~init:nname + + + method private class_name = "GButton.radio_button" + + method remove_me_without_undo () = + radio_button_pool := list_remove !radio_button_pool + ~f:(fun x -> x = name); + widget#remove_me_without_undo () + + method private get_mandatory_props = [ "label" ] + + method private emit_clean_proplist = + List.remove_assoc "group" widget#emit_clean_proplist + + method emit_initializer_code formatter = + let groupname = group_prop#get in + if name <> groupname then + Format.fprintf formatter "@ %s#set_group %s#group;" name groupname + + initializer + classe <- "radio_button"; + radio_button_pool := name :: !radio_button_pool; + List.iter + ~f:(fun x -> Propwin.update (Hashtbl.find widget_map x) true) + (List.tl !radio_button_pool); + + proplist <- proplist @ + [ "border_width", new prop_int ~name:"border_width" ~init:"0" + ~set:(ftrue button#set_border_width); + "label", + new prop_string ~name:"label" ~init:name ~set: + begin fun v -> + button#remove (List.hd button#children)#coerce; + GMisc.label ~text:v ~xalign:0.5 ~yalign:0.5 ~packing:button#add (); + true + end ; + "group", group_prop + ] +end + +let new_tiradio_button ~name ?(listprop = []) = + let b = GButton.radio_button ~label:name () in + (* + b#event#connect#enter_notify + ~callback:(fun _ -> b#misc#stop_emit ~name:"enter_notify_event"; true); + b#event#connect#leave_notify + ~callback:(fun _ -> b#misc#stop_emit ~name:"leave_notify_event"; true); + *) + new tiradio_button ~name ~widget:b + + + + +class tibutton_toolbar ~(widget : #GButton.button) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window ~toolbar = +object(self) + val button = widget + inherit tibutton ~name ~widget ~parent_tree ~pos ~insert_evbox + parent_window as button + + method private get_mandatory_props = + [ "text"; "tooltip"; "tooltip_private" ] + + method emit_init_code formatter ~packing = + Format.fprintf formatter "@ @[let %s =@ @[%s#insert_button" + name toolbar#name; + List.iter self#get_mandatory_props ~f: + begin fun name -> + Format.fprintf formatter "@ ~%s:%s" name + (List.assoc name proplist)#code + end; + Format.fprintf formatter "@ ()@ in@]@]" + + initializer + proplist <- List.remove_assoc "label" proplist +end + + +class titoggle_button_toolbar ~(widget : #GButton.toggle_button) ~name + ~parent_tree ~pos ?(insert_evbox=true) parent_window ~toolbar = +object(self) + val button = widget + inherit titoggle_button ~name ~widget ~parent_tree ~pos ~insert_evbox + parent_window as button + + method private get_mandatory_props = + [ "text"; "tooltip"; "tooltip_private" ] + + method emit_init_code formatter ~packing = + Format.fprintf formatter + "@ @[let %s =@ @[%s#insert_toggle_button" + name toolbar#name; + List.iter self#get_mandatory_props ~f: + begin fun name -> + Format.fprintf formatter "@ ~%s:%s" name + (List.assoc name proplist)#code + end; + Format.fprintf formatter "@ ()@ in@]@]" + + initializer + proplist <- List.remove_assoc "label" proplist +end + + +class tiradio_button_toolbar ~(widget : #GButton.radio_button) ~name + ~parent_tree ~pos ?(insert_evbox=true) parent_window ~toolbar = +object(self) + val button = widget + inherit tiradio_button ~name ~widget ~parent_tree ~pos ~insert_evbox + parent_window as button + + method private get_mandatory_props = + [ "text"; "tooltip"; "tooltip_private" ] + + method emit_init_code formatter ~packing = + Format.fprintf formatter + "@ @[let %s =@ @[%s#insert_radio_button" + name toolbar#name; + List.iter self#get_mandatory_props ~f: + begin fun name -> + Format.fprintf formatter "@ ~%s:%s" name + (List.assoc name proplist)#code + end; + Format.fprintf formatter "@ ()@ in@]@]" + + initializer + proplist <- List.remove_assoc "label" proplist +end + + + + +class titoolbar ~(widget : GToolbar2.toolbar2) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object(self) + val toolbar = widget + inherit ticontainer ~name ~widget ~parent_tree ~pos + ~insert_evbox parent_window + + method private class_name = "GButton.toolbar" + + method private add child ~pos = + children <- children @ [child, `START] + + method private get_pos child = + let rec aux n = function + | [] -> failwith "toolbar::get_pos" + | (hd, _)::tl -> if hd = child then n else aux (n+1) tl in + aux 0 children + + method private make_child ~classe ?(pos = -1) ~name ~parent_tree + ?(insert_evbox = true) ?(listprop = []) parent_window = + match classe with + | "button" -> + let t = try List.assoc "text" listprop with Not_found -> "" in + let tt = try List.assoc "tooltip" listprop with Not_found -> "" in + let ptt = try List.assoc "tooltip_private" listprop + with Not_found -> "" in + let listp = List.fold_left ~f:(fun l p -> List.remove_assoc p l) + ~init:listprop + [ "text"; "tooltip"; "tooltip_private" ] in + let b = toolbar#insert_button ~text:t ~tooltip:tt + ~tooltip_private:ptt () in + let child = new tibutton_toolbar ~name ~widget:b ~pos:(-1) + ~insert_evbox:false ~parent_tree:stree parent_window ~toolbar:self in + let tp = new prop_string ~name:"text" ~init:t + ~set:(fun v -> + toolbar#set_text v (self#get_pos child); true) + and ttp = new prop_string ~name:"tooltip" ~init:tt + ~set:(fun _ -> true) + and pttp = new prop_string ~name:"tooltip_private" ~init:ptt + ~set:(fun _ -> true) in + child#add_to_proplist + [ "text", tp; "tooltip", ttp; "tooltip_private", pttp ]; + child + | "toggle_button" -> + let t = try List.assoc "text" listprop with Not_found -> "" in + let tt = try List.assoc "tooltip" listprop with Not_found -> "" in + let ptt = try List.assoc "tooltip_private" listprop + with Not_found -> "" in + let listp = List.fold_left ~f:(fun l p -> List.remove_assoc p l) + ~init:listprop + [ "text"; "tooltip"; "tooltip_private" ] in + let b = toolbar#insert_toggle_button ~text:t ~tooltip:tt + ~tooltip_private:ptt () in + let child = new titoggle_button_toolbar ~name ~widget:b ~pos:(-1) + ~insert_evbox:false ~parent_tree:stree parent_window ~toolbar:self in + let tp = new prop_string ~name:"text" ~init:t + ~set:(fun v -> toolbar#set_text v (self#get_pos child); true) + and ttp = new prop_string ~name:"tooltip" ~init:tt + ~set:(fun _ -> true) + and pttp = new prop_string ~name:"tooltip_private" ~init:ptt + ~set:(fun _ -> true) in + child#add_to_proplist + [ "text", tp; "tooltip", ttp; "tooltip_private", pttp ]; + child + | "radio_button" -> + let t = try List.assoc "text" listprop with Not_found -> "" in + let tt = try List.assoc "tooltip" listprop with Not_found -> "" in + let ptt = try List.assoc "tooltip_private" listprop + with Not_found -> "" in + let listp = List.fold_left ~f:(fun l p -> List.remove_assoc p l) + ~init:listprop + [ "text"; "tooltip"; "tooltip_private" ] in + let b = toolbar#insert_radio_button ~text:t ~tooltip:tt + ~tooltip_private:ptt () in + let child = new tiradio_button_toolbar ~name ~widget:b ~pos:(-1) + ~insert_evbox:false ~parent_tree:stree parent_window ~toolbar:self in + let tp = new prop_string ~name:"text" ~init:t + ~set:(fun v -> toolbar#set_text v (self#get_pos child); true) + and ttp = new prop_string ~name:"tooltip" ~init:tt + ~set:(fun _ -> true) + and pttp = new prop_string ~name:"tooltip_private" ~init:ptt + ~set:(fun _ -> true) in + child#add_to_proplist + [ "text", tp; "tooltip", ttp; "tooltip_private", pttp ]; + child + | _ -> failwith "toolbar" + + + + method remove child = + toolbar#remove (child#base); + children <- list_remove ~f:(fun (ch, _) -> ch = child) children; + + initializer + classe <- "toolbar"; + proplist <- proplist @ + [ "orientation", + new prop_orientation ~name:"orientation" ~init:"HORIZONTAL" + ~set:(ftrue toolbar#set_orientation); + "style", + new prop_toolbar_style ~name:"style" ~init:"BOTH" + ~set:(ftrue toolbar#set_style); + "space_size", + new prop_int ~name:"space_size" ~init:"5" + ~set:(ftrue toolbar#set_space_size); + "space_style", + new prop_toolbar_space_style ~name:"space_style" ~init:"EMPTY" + ~set:(ftrue toolbar#set_space_style); + "tooltips", + new prop_bool ~name:"tooltips" ~init:"true" + ~set:(ftrue toolbar#set_tooltips); + "button_relief", + new prop_relief_style ~name:"button_relief" ~init:"NORMAL" + ~set:(ftrue toolbar#set_button_relief) + ] +end + +let new_toolbar ~name ?(listprop = []) = + new titoolbar ~name ~widget:(GToolbar2.toolbar2 ()) + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiContainer.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiContainer.ml new file mode 100644 index 000000000..ddf04d31f --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiContainer.ml @@ -0,0 +1,92 @@ + +open Gtk +open GObj +open GContainer + +open Utils +open Property + +open TiBase + +(* for containers being able to have at least one child; + not for buttons (can't have children) *) + +class virtual ticontainer ~widget ~name + ?(insert_evbox=true) ~parent_tree ~pos parent_window = +object(self) + + val container = (widget : #container :> container) + + inherit tiwidget ~name ~widget ~insert_evbox + ~parent_tree ~pos parent_window as widget + +(* name of the add method: add for most bin widgets, + pack for boxes, add_with_viewport for scrolled windows... *) + method private name_of_add_method = "#add" + + method private add child ~pos = + container#add child#base; + children <- [child, `START]; + self#set_full_menu false; + tree_item#drag#dest_unset () + + method remove child = + container#remove child#base; + children <- []; + self#set_full_menu true; + tree_item#drag#dest_set ~actions:[`COPY] + [ { target = "STRING"; flags = []; info = 0} ] + + method private menu ~time = + let menu = GMenu.menu () and menu_add = GMenu.menu () in + List.iter + ~f:(fun n -> + let mi = GMenu.menu_item ~packing:menu_add#append ~label:n () + in mi#connect#activate + ~callback:(fun () -> self#add_child n ();()); ()) + widget_add_list; + let mi_add = GMenu.menu_item ~packing:menu#append + ~label:("add to " ^ name) () + and mi_remove = GMenu.menu_item ~packing:menu#append + ~label:("remove " ^ name) () + and mi_cut = GMenu.menu_item ~packing:menu#append ~label:"Cut" () + and mi_copy = GMenu.menu_item ~packing:menu#append ~label:"Copy" () + and mi_paste = GMenu.menu_item ~packing:menu#append ~label:"Paste" () in + mi_remove#connect#activate ~callback:self#remove_me; + mi_add#set_submenu menu_add; + mi_copy#connect#activate ~callback:self#copy; + mi_cut#connect#activate ~callback:self#cut; + if !selection <> "" + then begin mi_paste#connect#activate ~callback:self#paste; () end + else mi_paste#misc#set_sensitive false; + menu#popup ~button:3 ~time + + method emit_init_code c ~packing = + widget#emit_init_code c ~packing; + self#forall ~callback:(fun child -> child#emit_init_code c + ~packing:(name ^ self#name_of_add_method)) + + method emit_method_code c = + widget#emit_method_code c; + self#forall ~callback:(fun child -> child#emit_method_code c) + + method emit_initializer_code c = + widget#emit_initializer_code c; + self#forall ~callback:(fun child -> child#emit_initializer_code c) + + + initializer + proplist <- proplist @ + [ "border_width", new prop_int ~name:"border_width" ~init:"0" + ~set:(ftrue container#set_border_width) ]; + + tree_item#drag#dest_set ~actions:[`COPY] + [ { target = "STRING"; flags = []; info = 0} ]; + tree_item#drag#connect#data_received ~callback: + begin fun (context : drag_context) ~x ~y + (data : selection_data) ~info ~time -> + self#add_child data#data (); + context#finish ~success:true ~del:false ~time + end;() +end + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiEdit.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiEdit.ml new file mode 100644 index 000000000..4b0977bb6 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiEdit.ml @@ -0,0 +1,153 @@ +open Utils +open Property + +open TiBase + + + +class tientry ~(widget : GEdit.entry) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object + val entry = widget + inherit tiwidget ~name ~widget ~parent_tree ~pos + ~insert_evbox parent_window + + method private class_name = "GEdit.entry" + initializer + classe <- "entry"; + proplist <- proplist @ + [ "visibility", + new prop_bool ~name:"visibility" ~init:"true" + ~set:(ftrue entry#set_visibility); + "editable", + new prop_bool ~name:"editable" ~init:"true" + ~set:(ftrue entry#set_editable) + ] +end + +let new_tientry ~name ?(listprop = []) = + new tientry ~name ~widget:(GEdit.entry ()) + + +class tispin_button ~(widget : GEdit.spin_button) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object + val spin_button = widget + inherit tientry ~widget:(widget :> GEdit.entry) ~name ~parent_tree ~pos + ~insert_evbox parent_window + + method private class_name = "GEdit.spin_button" + initializer + classe <- "spin_button"; + proplist <- proplist @ + [ "digits", + new prop_int ~name:"digits" ~init:"0" + ~set:(ftrue spin_button#set_digits); + "update_policy", + new prop_spin_button_update_policy ~name:"update_policy" + ~init:"ALWAYS" + ~set:(ftrue spin_button#set_update_policy); + "numeric", + new prop_bool ~name:"numeric" ~init:"false" + ~set:(ftrue spin_button#set_numeric); + "wrap", + new prop_bool ~name:"wrap" ~init:"false" + ~set:(ftrue spin_button#set_wrap); + "shadow_type", + new prop_shadow ~name:"shadow_type" ~init:"NONE" + ~set:(ftrue spin_button#set_shadow_type); + "snap_to_ticks", + new prop_bool ~name:"snap_to_ticks" ~init:"false" + ~set:(ftrue spin_button#set_snap_to_ticks) + ] + +end + + +let get_adjustment () = + let rv = ref 0. and rl = ref 0. and ru = ref 100. and rsi = ref 1. + and rpi = ref 10. and rps = ref 10. in + let w = GWindow.window ~modal:true () in + let v = GPack.vbox ~packing:w#add () in + let l = GMisc.label ~text:"adjustment properties" ~packing:v#pack () in + let h1 = GPack.hbox ~packing:v#pack () in + let l1 = GMisc.label ~text:"value" ~packing:h1#pack () in + let e1 = GEdit.entry ~text:"0." ~packing:h1#pack () in + let h2 = GPack.hbox ~packing:v#pack () in + let l2 = GMisc.label ~text:"lower" ~packing:h2#pack () in + let e2 = GEdit.entry ~text:"0." ~packing:h2#pack () in + let h3 = GPack.hbox ~packing:v#pack () in + let l3 = GMisc.label ~text:"upper" ~packing:h3#pack () in + let e3 = GEdit.entry ~text:"100." ~packing:h3#pack () in + let h4 = GPack.hbox ~packing:v#pack () in + let l4 = GMisc.label ~text:"step_incr" ~packing:h4#pack () in + let e4 = GEdit.entry ~text:"1." ~packing:h4#pack () in + let h5 = GPack.hbox ~packing:v#pack () in + let l5 = GMisc.label ~text:"page_incr" ~packing:h5#pack () in + let e5 = GEdit.entry ~text:"10." ~packing:h5#pack () in + let h6 = GPack.hbox ~packing:v#pack () in + let l6 = GMisc.label ~text:"page_size" ~packing:h6#pack () in + let e6 = GEdit.entry ~text:"10." ~packing:h6#pack () in + let h7 = GPack.hbox ~packing:v#pack () in + let b1 = GButton.button ~label:"OK" ~packing:h7#pack () in + let b2 = GButton.button ~label:"Cancel" ~packing:h7#pack () in + w#show (); + b1#connect#clicked + ~callback:(fun () -> + begin + try rv := float_of_string e1#text with _ -> + try rv := float_of_int (int_of_string e1#text) with _ -> () end; + begin + try rl := float_of_string e2#text with _ -> + try rl := float_of_int (int_of_string e2#text) with _ -> () end; + begin + try ru := float_of_string e3#text with _ -> + try ru := float_of_int (int_of_string e3#text) with _ -> () end; + begin + try rsi := float_of_string e4#text with _ -> + try rsi := float_of_int (int_of_string e4#text) with _ -> () end; + begin + try rpi := float_of_string e5#text with _ -> + try rpi := float_of_int (int_of_string e5#text) with _ -> () end; + begin + try rps := float_of_string e6#text with _ -> + try rps := float_of_int (int_of_string e6#text) with _ -> () end; + w#destroy ()); + b2#connect#clicked ~callback:w#destroy; + w#connect#destroy ~callback:GMain.Main.quit; + GMain.Main.main (); + !rv, !rl, !ru, !rsi, !rpi, !rps + +let new_tispin_button ~name ?(listprop = []) = + let v, l, u, si, pi, ps = get_adjustment () in + new tispin_button ~name + ~widget:(GEdit.spin_button ~adjustment: + (GData.adjustment ~value:v ~lower:l ~upper:u + ~step_incr:si ~page_incr:pi ~page_size:ps ()) ()) + + + +class ticombo ~(widget : GEdit.combo) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object + val combo = widget + inherit tiwidget ~name ~widget ~parent_tree ~pos + ~insert_evbox parent_window + + method private class_name = "GEdit.combo" + initializer + classe <- "combo"; + proplist <- proplist @ + [ "use_arrows", + new prop_combo_use_arrows ~name:"use_arrows" ~init:"true" + ~set:(ftrue combo#set_use_arrows); + "case_sensitive", + new prop_bool ~name:"case_sensitive" ~init:"false" + ~set:(ftrue combo#set_case_sensitive) + ] +end + +let new_ticombo ~name ?(listprop = []) = + new ticombo ~name ~widget:(GEdit.combo ()) + + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiList.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiList.ml new file mode 100644 index 000000000..770e19b73 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiList.ml @@ -0,0 +1,66 @@ + +open Utils +open Property + +open TiBase + +class ticlist ~(widget : 'a GList.clist) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window ~columns ~titles = + object(self) + val clist = widget + inherit tiwidget ~name ~widget ~parent_tree ~pos + ~insert_evbox parent_window as widget + + val param = parent_window#add_param + + method private class_name = "GList.clist" + + method private get_mandatory_props = [ "columns" ] + + method remove_me_without_undo () = + parent_window#remove_param param; + widget#remove_me_without_undo () + + method emit_init_code formatter ~packing = + Format.fprintf formatter + "@ @[let (%s : '%c GList.clist) =@ @[GList.clist" + name param; + List.iter self#get_mandatory_props ~f: + begin fun name -> + Format.fprintf formatter "@ ~%s:%s" name + (List.assoc name proplist)#code + end; + let packing = self#get_packing packing in + if packing <> "" then Format.fprintf formatter "@ %s" packing; + self#emit_prop_code formatter; + Format.fprintf formatter "@ ()@ in@]@]" + + + initializer + classe <- "clist"; + proplist <- proplist @ + [ "columns", + new prop_int ~name:"columns" ~init:(string_of_int columns) + ~set:(fun _ -> true); + "titles", + new prop_clist_titles ~name:"titles" ~init:(String.concat ~sep:" " titles) + ~set:(fun v -> + let v = Array.of_list v in + for i = 0 to Array.length v - 1 do + clist#set_column i ~title:v.(i) + done; + true) + ] +end + +let new_clist ~name ?(listprop = []) = + let c, lp = match listprop with + | [] -> (get_a_number "number of columns" 3), [] + | ("columns", n)::tl -> (int_of_string n), tl + | _ -> failwith "new_clist" + in + let rtitles = ref [] in + for i = c downto 1 do rtitles := ("column" ^(string_of_int i)):: !rtitles done; + new ticlist ~name ~widget:(GList.clist ~columns:c ~titles: !rtitles ()) ~columns:c ~titles: !rtitles + + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiMisc.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiMisc.ml new file mode 100644 index 000000000..f4f435a54 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiMisc.ml @@ -0,0 +1,176 @@ + +open Utils +open Property + +open TiBase +open TiContainer + + +class tiseparator ~(dir : Gtk.Tags.orientation) ~(widget : GObj.widget_full) + ~name ~parent_tree ~pos ?(insert_evbox=true) parent_window = +object + val separator = widget + inherit tiwidget ~name ~widget ~parent_tree ~pos parent_window ~insert_evbox + + method private class_name = + match dir with `VERTICAL -> "GMisc.separator `VERTICAL" + | `HORIZONTAL -> "GMisc.separator `HORIZONTAL" + initializer + classe <- + (match dir with `VERTICAL -> "vseparator" | `HORIZONTAL -> "hseparator") + +end + +let new_tihseparator ~name ?(listprop = []) = + new tiseparator ~dir: `HORIZONTAL ~name + ~widget:(GMisc.separator `HORIZONTAL ()) +let new_tivseparator ~name ?(listprop = []) = + new tiseparator ~dir: `VERTICAL ~name + ~widget:(GMisc.separator `VERTICAL ()) + + + + +class tistatusbar ~(widget : GMisc.statusbar) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object(self) + val statusbar = widget + inherit ticontainer ~name ~widget ~insert_evbox + ~parent_tree ~pos parent_window as widget + + method private class_name = "GMisc.statusbar" + + initializer + classe <- "statusbar" +end + +let new_tistatusbar ~name ?(listprop = []) = + new tistatusbar ~widget:(GMisc.statusbar ()) ~name + + + +class timisc ~(widget : GMisc.misc) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object(self) + val misc = widget + inherit tiwidget ~name ~widget ~insert_evbox + ~parent_tree ~pos parent_window as widget + + method private class_name = failwith "timisc::class_name" + + initializer + proplist <- proplist @ + [ "x_alignment", + new prop_float ~name:"x alignment" ~init:"0.5" ~min:0. ~max:1. + ~set:(fun v -> misc#set_alignment ~x:v (); true); + "y_alignment", + new prop_float ~name:"y alignment" ~init:"0.5" ~min:0. ~max:1. + ~set:(fun v -> misc#set_alignment ~y:v (); true); + "x_padding", + new prop_int ~name:"x padding" ~init:"0.5" + ~set:(fun v -> misc#set_padding ~x:v (); true); + "y_padding", + new prop_int ~name:"y padding" ~init:"0.5" + ~set:(fun v -> misc#set_padding ~y:v (); true) + + ] +end + + +class tiarrow ~(widget : GMisc.arrow) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object(self) + val arrow = widget + inherit timisc ~name ~widget:(widget :> GMisc.misc) ~insert_evbox + ~parent_tree ~pos parent_window as widget + + method private class_name = "GMisc.arrow" + initializer + classe <- "arrow"; +end + + +(* TODO fenetre demandant kind et shadow +let new_tiarrow ~name = new tiarrow ~widget:(GMisc.arrow ()) ~name +*) + + +class tilabel ~(widget : GMisc.label) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object(self) + val labelw = widget + inherit timisc ~name ~widget:(widget :> GMisc.misc) ~insert_evbox + ~parent_tree ~pos parent_window as widget + + method private class_name = "GMisc.label" + + method private get_mandatory_props = [ "text" ] + + initializer + classe <- "label"; + proplist <- proplist @ + [ "text", + new prop_string ~name:"text" ~init:name ~set:(ftrue labelw#set_text); + "line_wrap", + new prop_bool ~name:"line_wrap" ~init:"true" + ~set:(ftrue labelw#set_line_wrap) + ] +end + +let new_tilabel ~name ?(listprop = []) = + new tilabel ~widget:(GMisc.label ~text:name ()) ~name + + + + + +class ticolor_selection ~(widget : GMisc.color_selection) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object(self) + val color_selection = widget + inherit tiwidget ~name ~widget ~insert_evbox + ~parent_tree ~pos parent_window as widget + + method private class_name = "GMisc.color_selection" + + initializer + classe <- "color_selection"; + proplist <- proplist @ + [ "use_opacity", + new prop_bool ~name:"use_opacity" ~init:"false" + ~set:(ftrue color_selection#set_opacity); + "update_policy", + new prop_update_type ~name:"update_policy" ~init:"CONTINUOUS" + ~set:(ftrue color_selection#set_update_policy) + ] +end + +let new_ticolor_selection ~name ?(listprop = []) = + new ticolor_selection ~widget:(GMisc.color_selection ()) ~name + + +class tipixmap ~(widget : GMisc.pixmap) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object(self) + val pixmap = widget + inherit timisc ~name ~widget:(widget :> GMisc.misc) ~insert_evbox + ~parent_tree ~pos parent_window as widget + + method private class_name = "GMisc.pixmap" + initializer + classe <- "pixmap"; + proplist <- proplist @ + [ "file", + new prop_file ~name:"file" ~init:"" + ~set:(fun v -> + pixmap#set_pixmap + (GDraw.pixmap_from_xpm ~window:parent_window#tiwin#widget + ~file:v ()); + true) + ] +end + +let new_tipixmap ~name ?(listprop = []) ~parent_tree ~pos ?(insert_evbox=true) (parent_window : window_and_tree0) = + new tipixmap ~widget:(GMisc.pixmap (GDraw.pixmap_from_xpm + ~window:parent_window#tiwin#widget ~file:"pixmap.xpm" ()) ()) ~name + ~parent_tree ~pos ~insert_evbox parent_window diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiPack.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiPack.ml new file mode 100644 index 000000000..291eec9d9 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiPack.ml @@ -0,0 +1,300 @@ + +open Utils +open Property + +open TiContainer + +class tibox ~(dir : Gtk.Tags.orientation) ~(widget : GPack.box) + ~name ~parent_tree ~pos ?(insert_evbox=true) parent_window = + let class_name = + match dir with `VERTICAL -> "GPack.vbox" | _ -> "GPack.hbox" in +object(self) + val box = widget + inherit ticontainer ~name ~widget ~parent_tree ~pos ~insert_evbox + parent_window as container + + method private class_name = class_name + + method private name_of_add_method = "#pack" + +(* removes the ::expand ::fill ::padding in the proplist of a box + assumes that these are the only properties with a :: in the name *) + method private save_clean_proplist = + List.filter container#save_clean_proplist + ~f:(fun (n,p) -> + try + let i = String.index n ':' in + i = String.length n || n.[i+1] <> ':' + with Not_found -> true) + + method private emit_clean_proplist = + List.filter container#emit_clean_proplist + ~f:(fun (n,p) -> + try + let i = String.index n ':' in + i = String.length n || n.[i+1] <> ':' + with Not_found -> true) + + method change_name_in_proplist oldn newn = + proplist <- List.fold_left ~init:proplist ~f: + (fun pl propname -> + change_property_name (oldn ^ propname) (newn ^ propname) pl) + [ "::expand"; "::fill"; "::padding" ]; + Propwin.update self false + + method child_up child = + let pos = list_pos ~item:child (List.map ~f:fst children) in + if pos > 0 then begin + box#reorder_child child#base ~pos:(pos-1); + children <- list_reorder_up children ~pos; + stree#item_up ~pos + end + + method child_down child = + let pos = list_pos ~item:child (List.map ~f:fst children) in + if pos < (List.length children - 1) then begin + box#reorder_child child#base ~pos:(pos+1); + children <- list_reorder_down children ~pos; + stree#item_up ~pos:(pos+1) + end + + method private add child ~pos = + box#pack child#base; + if pos < 0 then begin + children <- children @ [(child, `START)] + end + else begin + children <- list_insert ~item:(child, `START) children ~pos; + box#reorder_child child#base ~pos + end; + let n = child#name in + let expand = + new prop_bool ~name:"expand" ~init:"false" ~set: + begin fun v -> + box#set_child_packing (child#base) ~expand:v; + Propwin.update child false; + Propwin.update self false; true + end + and fill = + new prop_bool ~name:"fill" ~init:"true" ~set: + begin fun v -> + box#set_child_packing (child#base) ~fill:v; + Propwin.update child false; + Propwin.update self false; true + end + and padding = + new prop_int ~name:"padding" ~init:"0" ~set: + begin fun v -> + box#set_child_packing (child#base) ~padding:v; + Propwin.update child false; + Propwin.update self false; true + end + in + proplist <- proplist @ + [ (n ^ "::expand"), expand; + (n ^ "::fill"), fill; + (n ^ "::padding"), padding ]; + child#add_to_proplist + [ "expand", expand; "fill", fill; "padding", padding ]; + Propwin.update self true + + + method remove child = + box#remove (child#base); + children <- list_remove ~f:(fun (ch, _) -> ch = child) children; + let n = child#name in + proplist <- List.fold_left ~init:proplist + ~f:(fun acc n -> List.remove_assoc n acc) + [ (n ^ "::expand"); (n ^ "::fill"); (n ^ "::padding") ]; + Propwin.update self true + + initializer + classe <- (match dir with `VERTICAL -> "vbox" | _ -> "hbox"); + proplist <- proplist @ + [ "homogeneous", + new prop_bool ~name:"homogeneous" ~init:"false" + ~set:(ftrue box#set_homogeneous); + "spacing", + new prop_int ~name:"spacing" ~init:"0" + ~set:(ftrue box#set_spacing) + ] +end + +class tihbox = tibox ~dir:`HORIZONTAL +class tivbox = tibox ~dir:`VERTICAL + +let new_tihbox ~name ?(listprop = []) = new tihbox ~widget:(GPack.hbox ()) ~name +let new_tivbox ~name ?(listprop = []) = new tivbox ~widget:(GPack.vbox ()) ~name + + + + +class tibbox ~(dir : Gtk.Tags.orientation) ~(widget : GPack.button_box) + ~name ~parent_tree ~pos ?(insert_evbox=true) parent_window = + let class_name = + match dir with `VERTICAL -> "GPack.button_box `VERTICAL" + | _ -> "GPack.button_box `HORIZONTAL" in +object(self) + val bbox = widget + inherit tibox ~dir ~widget:(widget :> GPack.box) + ~name ~parent_tree ~pos ~insert_evbox parent_window + + method private class_name = class_name + +initializer + classe <- (match dir with `VERTICAL -> "vbutton_box" | _ -> "hbutton_box"); + proplist <- proplist @ + [ "layout", + new prop_button_box_style ~name:"layout" ~init:"DEFAULT_STYLE" + ~set:(ftrue bbox#set_layout); + "spacing", + new prop_int ~name:"spacing" + ~init:(match dir with `VERTICAL -> "10" | _ -> "30") +(* donne -1 (defaut) +(GtkPack.BBox.get_spacing bbox#as_button_box) *) + ~set:(fun v -> bbox#set_spacing v; + GtkBase.Widget.queue_resize bbox#as_widget; true); + "child_width", + new prop_int ~name:"child_width" ~init:"85" + ~set:(fun v -> + bbox#set_child_size ~width:v + ~height:(int_of_string (self#get_property "child_height")) (); + GtkBase.Widget.queue_resize bbox#as_widget; true); + "child_height", + new prop_int ~name:"child_height" ~init:"27" + ~set:(fun v -> + bbox#set_child_size ~height:v + ~width:(int_of_string (self#get_property "child_width")) (); + GtkBase.Widget.queue_resize bbox#as_widget; true); + "child_ipad_x", + new prop_int ~name:"child_ipad_x" ~init:"7" + ~set:(fun v -> + bbox#set_child_ipadding ~x:v + ~y:(int_of_string (self#get_property "child_ipad_y")) (); + GtkBase.Widget.queue_resize bbox#as_widget; true); + "child_ipad_y", + new prop_int ~name:"child_ipad_y" ~init:"0" + ~set:(fun v -> + bbox#set_child_ipadding ~y:v + ~x:(int_of_string (self#get_property "child_ipad_x")) (); + GtkBase.Widget.queue_resize bbox#as_widget; true); + ] +end + + +(* TODO: pour proplist/spacing il faudrait implementer + les fonctions get_spacing ... (voir dans gtkPack) *) + +class tihbutton_box = tibbox ~dir:`HORIZONTAL +class tivbutton_box = tibbox ~dir:`VERTICAL + +let new_tihbutton_box ~name ?(listprop = []) = + new tihbutton_box ~widget:(GPack.button_box `HORIZONTAL ()) ~name + +let new_tivbutton_box ~name ?(listprop = []) = + new tivbutton_box ~widget:(GPack.button_box `VERTICAL ()) ~name + + + + +let get_fixed_pos () = + let rx = ref 0 and ry = ref 0 in + let w = GWindow.window ~modal:true () in + let v = GPack.vbox ~packing:w#add () in + let l = GMisc.label ~text:"Enter position for child" ~packing:v#pack () in + let h1 = GPack.hbox ~packing:v#pack () in + let l1 = GMisc.label ~text:"x:" ~packing:h1#pack () in + let e1 = GEdit.entry ~text:"0" ~packing:h1#pack () in + let h2 = GPack.hbox ~packing:v#pack () in + let l2 = GMisc.label ~text:"y" ~packing:h2#pack () in + let e2 = GEdit.entry ~text:"0" ~packing:h2#pack () in + let h7 = GPack.hbox ~packing:v#pack () in + let b1 = GButton.button ~label:"OK" ~packing:h7#pack () in + let b2 = GButton.button ~label:"Cancel" ~packing:h7#pack () in + w#show (); + b1#connect#clicked + ~callback:(fun () -> + begin + try rx := int_of_string e1#text with _ -> () end; + begin + try ry := int_of_string e2#text with _ -> () end; + w#destroy ()); + b2#connect#clicked ~callback:w#destroy; + w#connect#destroy ~callback:GMain.Main.quit; + GMain.Main.main (); + !rx, !ry + + +class tifixed ~(widget : GPack.fixed) + ~name ~parent_tree ~pos ?(insert_evbox=true) parent_window = +object(self) + val fixed = widget + inherit ticontainer ~widget + ~name ~parent_tree ~pos ~insert_evbox parent_window + + method private class_name = "GPack.fixed" + + method private add child ~pos = + let x, y = get_fixed_pos () in + fixed#put child#base ~x ~y; + children <- children @ [(child, `START)] + initializer + classe <- "fixed" +end + +let new_tifixed ~name ?(listprop = []) = + new tifixed ~widget:(GPack.fixed ()) ~name + + + + + +class tinotebook ~(widget : GPack.notebook) ~name ~parent_tree ~pos + ?(insert_evbox=true) parent_window = +object(self) + val notebook = widget + inherit ticontainer ~name ~widget ~insert_evbox + ~parent_tree ~pos parent_window as widget + + method private class_name = "GPack.notebook" + + method private add child ~pos = + children <- children @ [child, `START]; + notebook#insert_page child#base ~pos; + child#add_to_proplist + [ "tab_label", + new prop_string ~name:"tab_label" ~init:"" + ~set:(fun v -> notebook#set_page + ~tab_label:((GMisc.label ~text:v())#coerce) child#base; true) + ] + + + initializer + classe <- "notebook"; + proplist <- proplist @ + [ "tab_pos", + new prop_position ~name:"tab_ pos" ~init:"TOP" + ~set:(ftrue notebook#set_tab_pos); + "show_tabs", + new prop_bool ~name:"show_tabs" ~init:"true" + ~set:(ftrue notebook#set_show_tabs); + "homogeneous_tabs", + new prop_bool ~name:"homogeneous_tabs" ~init:"true" + ~set:(ftrue notebook#set_homogeneous_tabs); + "show_border", + new prop_bool ~name:"show_border" ~init:"true" + ~set:(ftrue notebook#set_show_border); + "scrollable", + new prop_bool ~name:"scrollable" ~init:"false" + ~set:(ftrue notebook#set_scrollable); + "tab_border", + new prop_int ~name:"tab_border" ~init:"2" + ~set:(ftrue notebook#set_tab_border); + "popup_enable", + new prop_bool ~name:"popup_enable" ~init:"false" + ~set:(ftrue notebook#set_popup) + ] +end + +let new_tinotebook ~name ?(listprop = []) = + new tinotebook ~widget:(GPack.notebook ()) ~name diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiWidget.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiWidget.ml new file mode 100644 index 000000000..5a6e3ac01 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiWidget.ml @@ -0,0 +1,43 @@ + +let new_class_list (* : + (string * + (name:string -> ?listprop:string list -> + parent_tree:GTree2.tree -> pos:int -> + ?insert_evbox:bool -> + + TiBase.window_and_tree0 -> TiBase.tiwidget0)) list *) += [ + "window", TiWindow.new_tiwindow; + "hbox", TiPack.new_tihbox; + "vbox", TiPack.new_tivbox; + "hbutton_box", TiPack.new_tihbutton_box; + "vbutton_box", TiPack.new_tivbutton_box; + "fixed", TiPack.new_tifixed; + "notebook", TiPack.new_tinotebook; + "button", TiButton.new_tibutton; + "check_button", TiButton.new_ticheck_button; + "toggle_button", TiButton.new_titoggle_button; + "radio_button", TiButton.new_tiradio_button; + "toolbar", TiButton.new_toolbar; + "hseparator", TiMisc.new_tihseparator; + "vseparator", TiMisc.new_tivseparator; + "statusbar", TiMisc.new_tistatusbar; + "label", TiMisc.new_tilabel; + "color_selection", TiMisc.new_ticolor_selection; + "pixmap", TiMisc.new_tipixmap; + "frame", TiBin.new_tiframe; + "aspect_frame", TiBin.new_tiaspect_frame; + "handle_box", TiBin.new_handle_box; + "viewport", TiBin.new_viewport; + "event_box", TiBin.new_event_box; + "scrolled_window", TiBin.new_tiscrolled_window; + "entry", TiEdit.new_tientry; + "spin_button", TiEdit.new_tispin_button; + "combo", TiEdit.new_ticombo; + "clist", TiList.new_clist +] + +let _ = + TiBase.new_tiwidget := + (fun ~classe ?(pos = -1) ~name ~parent_tree ?insert_evbox ?(listprop = []) -> (List.assoc classe new_class_list) ~pos ~name ~parent_tree ?insert_evbox ~listprop) + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiWindow.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiWindow.ml new file mode 100644 index 000000000..b44b4d479 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tiWindow.ml @@ -0,0 +1,117 @@ + +open Utils +open Property + +open TiBase +open TiContainer + + +class tiwindow ~widget ~name ~parent_tree ~pos ?(insert_evbox=true) + parent_window = +object(self) + val window = widget + inherit ticontainer ~name ~widget + ~insert_evbox:false ~parent_tree ~pos parent_window as container + + method connect_event = window#event#connect + + method private class_name = "GWindow.window" + + method private get_mandatory_props = [ "title" ] + +(* method private save_clean_proplist = + List.remove_assoc "title" container#save_clean_proplist + + method private emit_clean_proplist plist = + List.remove_assoc "title" (container#emit_clean_proplist plist) +*) + method remove_me () = + let sref = ref "" in + self#save_to_string sref; + let lexbuf = Lexing.from_string !sref in + let node = Load_parser.window Load_lexer.token lexbuf in + add_undo (Add_window node); + self#remove_me_without_undo () + + method copy () = self#copy_to_sel window_selection + + method remove_me_without_undo () = + self#forall ~callback:(fun tiw -> tiw#remove_me_without_undo ()); + parent_window#remove_sel (self : #tiwidget0 :> tiwidget0); + name_list := list_remove !name_list ~f:(fun n -> n=name); + Hashtbl.remove widget_map name; + Propwin.remove name; + widget#destroy () + + method private get_packing packing = "" + + method emit_code f param_list = + let param_string = + match param_list with + | [] -> "" + | _ -> "['" ^ + (String.concat ~sep:", '" + (List.map ~f:(fun c -> (String.make 1 c)) param_list)) ^ + "] " in + Format.fprintf f "(* Code for %s *)@\n@\n@[class %s%s () =" + name param_string name; + self#emit_init_code f ~packing:""; + Format.fprintf f "@]@\n@[object (self)"; + self#emit_method_code f; + Format.fprintf f "@ method show () = %s#show ()" name; + Format.fprintf f "@ @[initializer"; + self#emit_initializer_code f; + Format.fprintf f "@ ()@]@]@ end@\n@\n" + +(* method private save_start formatter = + Format.fprintf formatter "@[<0>@\n@[<2>" name; + Format.fprintf formatter "@\ntitle=\"%s\"" + (List.assoc "title" proplist)#get +*) + method private save_end formatter = + Format.fprintf formatter "@]@\n@\n@]" + + method private menu ~time = + let menu = GMenu.menu () and menu_add = GMenu.menu () in + List.iter + ~f:(fun n -> + let mi = GMenu.menu_item ~packing:menu_add#append ~label:n () + in mi#connect#activate + ~callback:(fun () -> self#add_child n (); ()); ()) + widget_add_list; + let mi_add = GMenu.menu_item ~packing:menu#append ~label:("add to "^ name) () + and mi_paste = GMenu.menu_item ~packing:menu#append ~label:"Paste" () + in + mi_add#set_submenu menu_add; + if !selection <> "" + then begin mi_paste#connect#activate ~callback:self#paste; () end + else mi_paste#misc#set_sensitive false; + menu#popup ~button:3 ~time + + + initializer + classe <- "window"; + window#set_title name; + proplist <- proplist @ + [ "title", + new prop_string ~name:"title" ~init:name ~set:(ftrue window#set_title); + "allow_shrink", new prop_bool ~name:"allow_shrink" ~init:"false" + ~set:(ftrue window#set_allow_shrink); + "allow_grow", new prop_bool ~name:"allow_grow" ~init:"true" + ~set:(ftrue window#set_allow_grow); + "auto_shrink", new prop_bool ~name:"auto_shrink" ~init:"false" + ~set:(ftrue window#set_auto_shrink); + "x position", new prop_int ~name:"x" ~init:"-2" + ~set:(fun x -> window#misc#set_geometry ~x (); true); + "y position", new prop_int ~name:"y" ~init:"-2" + ~set:(fun y -> window#misc#set_geometry ~y (); true) ] +end + +let new_tiwindow ~name ?(listprop = []) = + let w = GWindow.window ~show:true () in + w#misc#set_can_focus false; + w#misc#set_can_default false; + new tiwindow ~widget:w ~name + + + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/togglebutton.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/togglebutton.xpm new file mode 100644 index 000000000..f29d76972 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/togglebutton.xpm @@ -0,0 +1,33 @@ +/* XPM */ +static char *togglebutton_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 6 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray100", +"+ c None", +/* pixels */ +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+..................O+", +"+. O+", +"+. XXXXXXXXXXXXXXXXO+", +"+. XXXXXXXXXXXXXXXXO+", +"+. XXX XXX XXX XXO+", +"+. XX XXX XX XX XXO+", +"+. XX XXX XX XX XXO+", +"+. XX XXX XX X X XXO+", +"+. XX XXX XX XX XXO+", +"+. XX XXX XX XX XXO+", +"+. XXX XXX XXX XXO+", +"+. XXXXXXXXXXXXXXXXO+", +"+. XXXXXXXXXXXXXXXXO+", +"+. XXXXXXXXXXXXXXXXO+", +"+OOOOOOOOOOOOOOOOOOO+", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/toolbar.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/toolbar.xpm new file mode 100644 index 000000000..d9a521716 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/toolbar.xpm @@ -0,0 +1,33 @@ +/* XPM */ +static char *toolbar_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 6 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray100", +"+ c None", +/* pixels */ +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+OOOOOOOOOOOOOOOOOOO ", +"+OXXXXXXXXXXXXXXXXX. ", +"+OXOOOO OOOO OOOO X. ", +"+OXOXXX OXXX OXXX X. ", +"+OXOXXX OXXX OXXX X. ", +"+OXO O O X. ", +"+OXXXXXXXXXXXXXXXXX. ", +"+O.................. ", +"+ ", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tree_minus.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tree_minus.xpm new file mode 100644 index 000000000..cce067910 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tree_minus.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char *tree_minus[] = { +/* width height num_colors chars_per_pixel */ +" 9 9 2 1", +/* colors */ +". c #000000", +"# c #f8fcf8", +/* pixels */ +".........", +".#######.", +".#######.", +".#######.", +".#.....#.", +".#######.", +".#######.", +".#######.", +"........." +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tree_plus.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tree_plus.xpm new file mode 100644 index 000000000..d0ba80ca2 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/tree_plus.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char *tree_plus[] = { +/* width height num_colors chars_per_pixel */ +" 9 9 2 1", +/* colors */ +". c #000000", +"# c #f8fcf8", +/* pixels */ +".........", +".#######.", +".###.###.", +".###.###.", +".#.....#.", +".###.###.", +".###.###.", +".#######.", +"........." +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/utils.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/utils.ml new file mode 100644 index 000000000..0b37975c7 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/utils.ml @@ -0,0 +1,353 @@ +(* $Id$ *) + +open GObj + +open Common + +external test_modifier : Gdk.Tags.modifier -> int -> bool + = "ml_test_GdkModifier_val" + + +(************* types *************) +(* used in the load_parser and for the selection *) + +(* widget: class * name * property list + where property = name * value_string *) +type yywidget = string * string * (string * string) list +type yywidget_tree = Node of yywidget * yywidget_tree list + + +(*********** some utility functions **************) +let rec list_remove ~f = function + | [] -> [] + | hd :: tl -> if f hd then tl else hd :: (list_remove ~f tl) + + +(* cut the list at the element elt; elt stays in tail; + hd stays in reverse order *) +let cut_list ~item l = + let rec aux h t = match t with + | hd :: tl -> if hd = item then h, t + else aux (hd :: h) tl + | [] -> failwith "cut_list" + in aux [] l + +let list_pos ~item l = + let rec aux pos = function + | [] -> raise Not_found + | hd :: tl -> if hd = item then pos else aux (pos+1) tl + in aux 0 l + +(* moves the pos element up; pos is >= 1; + the first element is numbered 0 *) +let rec list_reorder_up ~pos = function + | hd1 :: hd2 :: tl when pos = 1 -> hd2 :: hd1 :: tl + | hd :: tl when pos > 1 -> hd :: (list_reorder_up ~pos:(pos-1) tl) + | _ -> failwith "list_reorder" + +(* moves the pos element down; pos is < length of l - 1; + the first element is numbered 0 *) +let rec list_reorder_down ~pos = + list_reorder_up ~pos:(pos+1) + + +let rec list_insert ~item l ~pos = + if pos=0 then item :: l + else + match l with + | [] -> failwith "list_insert" + | hd :: tl -> hd :: (list_insert ~item tl ~pos:(pos-1)) + + +let rec change_property_name oldname newname = function + | (n, p) :: tl when oldname = n -> (newname, p) :: tl + | (n, p) :: tl -> (n, p) :: change_property_name oldname newname tl + | [] -> failwith "change_property_name: name not found" + + + +(* contains the list of names of widgets in the current project; + used to test if a name is already used; + a name is added to the list when a tiwrapper is created (in + the initilizer part of tiwrapper, + it is removed when the widget is removed from his parent, + in method remove_me of tiwrapper *) +let name_list = ref ([] : string list) + +let split name = + let l = String.length name in + let i = ref (l-1) in + while !i >= 0 && name.[!i] >= '0' && name.[!i] <= '9' do decr i done; + if !i = l-1 then + name, (-1) + else + (String.sub name ~pos:0 ~len:(!i+1)), + int_of_string (String.sub name ~pos:(!i+1) ~len:(l- !i-1)) + +let test_unique name = not (List.mem name !name_list) + +let make_new_name ?(index=1) base = + let index, name = + if index = -1 then ref 1, ref base + else ref index, ref (base ^ (string_of_int index)) in + while not (test_unique !name) do + incr index; + name := base ^ (string_of_int !index) + done; + !name + +let change_name name = + let base, index = split name in make_new_name base ~index + +let message s = + let w = GWindow.window ~show:true ~modal:true () in + let v = GPack.vbox ~packing:w#add () in + let l = GMisc.label ~text:s ~packing:v#add () in + let b = GButton. button ~label:"OK" ~packing:v#add () in + b#connect#clicked ~callback:w#destroy; + w#connect#destroy ~callback:GMain.Main.quit; + GMain.Main.main () + +let message_name () = message "name already in use\npick a new name" + +(* better: use a spin button *) +let get_a_number s default= + let res = ref default in + let w = GWindow.window ~show:true ~modal:true () in + let v = GPack.vbox ~packing:w#add () in + let l = GMisc.label ~text:s ~packing:v#add () in + let e = GEdit.entry ~text:(string_of_int default) ~packing:v#add () in + let b = GButton. button ~label:"OK" ~packing:v#add () in + b#connect#clicked ~callback:(fun () -> + begin try res := int_of_string e#text with Failure _ -> () end; + w#destroy ()); + w#connect#destroy ~callback:GMain.Main.quit; + GMain.Main.main (); + !res + + +(*************** file selection *****************) + +let get_filename ~callback:set_filename ?(dir="") () = + let res = ref false in + let file_selection = GWindow.file_selection ~modal:true () in + if dir <> "" then file_selection#set_filename dir; + file_selection#show (); + file_selection#ok_button#connect#clicked + ~callback:(fun () -> set_filename file_selection#get_filename; + res := true; + file_selection#destroy ()); + file_selection#cancel_button#connect#clicked + ~callback:file_selection#destroy; + file_selection#connect#destroy ~callback:GMain.Main.quit; + GMain.Main.main (); + !res + +(* returns the directory and the file name (without the extension) *) +let split_filename filename ~ext = + let lext = String.length ext in + let l = String.length filename in + let filename, l = + if (l > lext) && (String.sub filename ~pos:(l - lext) ~len:lext = ext) + then (String.sub filename ~pos:0 ~len:(l-lext)), l-lext + else filename, l in + let i = 1 + (String.rindex filename '/') in + String.sub filename ~pos:0 ~len:i, + String.sub filename ~pos:i ~len:(l-i) + + +(****************** ML signals *****************) +let signal_id = ref 0 + +let next_callback_id () : GtkSignal.id = + decr signal_id; Obj.magic (!signal_id : int) + +class ['a] signal = object + val mutable callbacks : (GtkSignal.id * ('a -> unit)) list = [] + method connect ~callback ~after = + let id = next_callback_id () in + callbacks <- + if after then callbacks @ [id,callback] else (id,callback)::callbacks; + id + method call arg = + List.iter callbacks ~f:(fun (_,f) -> f arg) + method disconnect id = + List.mem_assoc id callbacks && + (callbacks <- List.remove_assoc id callbacks; true) + method reset () = callbacks <- [] +end + +class type disconnector = + object + method disconnect : GtkSignal.id -> bool + method reset : unit -> unit + end + +class has_ml_signals = object + val mutable disconnectors = [] + method private add_signal (sgn : 'a signal) = + disconnectors <- (sgn :> disconnector) :: disconnectors + + method disconnect id = + List.exists disconnectors ~f:(fun d -> d#disconnect id) +end + + +(****************** undo information ********************) + +type undo_action = + | Add of string * yywidget_tree * int + | Remove of string + | Property of prop * string + | Add_window of yywidget_tree + | Remove_window of string + +let undo_info = ref ([] : undo_action list) +let next_undo_info = ref ([] : undo_action list) +let last_action_was_undo = ref false + +let add_undo f = + undo_info := f :: !undo_info; + last_action_was_undo := false + + +(**********************************************************) +let ftrue f = fun x -> f x; true + + +(**********************************************************) + +let toolbar_child_prop kind = + let rt = ref "" and rtt = ref "" and rptt = ref "" and ok = ref false in + let w = GWindow.window ~modal:true () in + let v = GPack.vbox ~packing:w#add () in + let h1 = GPack.hbox ~packing:v#pack () in + let h2 = GPack.hbox ~packing:v#pack () in + let h3 = GPack.hbox ~packing:v#pack () in + let h4 = GPack.hbox ~packing:v#pack () in + let l1 = GMisc.label ~text:"text" ~packing:h1#pack () in + let e1 = GEdit.entry ~packing:h1#pack () in + let l2 = GMisc.label ~text:"tooltip_text" ~packing:h2#pack () in + let e2 = GEdit.entry ~packing:h2#pack () in + let l3 = GMisc.label ~text:"private_text" ~packing:h3#pack () in + let e3 = GEdit.entry ~packing:h3#pack () in + let b1 = GButton.button ~label:"OK" ~packing:h4#pack () in + let b2 = GButton.button ~label:"Cancel" ~packing:h4#pack () in + w#show (); + b1#connect#clicked + ~callback:(fun () -> rt := e1#text; rtt := e2#text; + rptt := e3#text; ok := true; + w#destroy ()); + b2#connect#clicked ~callback:w#destroy; + w#connect#destroy ~callback:GMain.Main.quit; + GMain.Main.main (); + !ok, !rt, !rtt, !rptt + + + +(**********************************************************) + +let get5floats_from_string s = + try + let n1 = String.index s ' ' in + let f1 = float_of_string (String.sub s ~pos:0 ~len:(n1-1)) in + let n2 = String.index_from s (n1+1) ' ' in + let f2 = float_of_string (String.sub s ~pos:(n1+1) ~len:(n2-1)) in + let n3 = String.index_from s (n2+1) ' ' in + let f3 = float_of_string (String.sub s ~pos:(n2+1) ~len:(n3-1)) in + let n4 = String.index_from s (n3+1) ' ' in + let f4 = float_of_string (String.sub s ~pos:(n3+1) ~len:(n4-1)) in + let f5 = float_of_string (String.sub s ~pos:(n4+1) ~len: + ((String.length s) -1)) in + f1, f2, f3, f4, f5 + with _ -> failwith "get5floats_of_string" + + + +(**********************************************************) + +exception Float_of_string +let my_float_of_string s = + let l = String.length s in + if l=0 then raise Float_of_string; + let sign, d = match s.[0] with + | '+' -> 1, 1 + | '-' -> -1, 1 + | _ -> 1, 0 in + let m, p = + let p = + try + String.index s '.' + with Not_found -> l in + if p=d then 0, p + else + try int_of_string (String.sub s ~pos:d ~len:(p-d)), p + with Failure "int_of_string" -> raise Float_of_string + in + if p=l then float_of_int m + else begin + let f = ref 0. and r = ref 0.1 in + for i = p+1 to l-1 do + let k = (int_of_char s.[i]) - 48 in + if k > 9 || k < 0 then raise Float_of_string; + f := !f +. (float_of_int k) *. !r; + r := !r *. 0.1 + done; + !f +. (float_of_int m) + end + + + + +class entry_float obj ~init = let rv = ref init in +object + inherit GEdit.entry obj as entry + method value = + try + let v = my_float_of_string entry#text in + rv := v; + v + with Float_of_string -> + let pop = GWindow.window ~title:"error" ~modal:true () in + let vb = GPack.vbox ~packing:pop#add () in + let l = GMisc.label ~text:"value must be a float" ~packing:vb#pack () in + let b = GButton.button ~label:"OK" ~packing:vb#pack () in + b#connect#clicked ~callback:pop#destroy; + pop#event#connect#delete ~callback:(fun _ -> pop#destroy (); true); + pop#connect#destroy ~callback:GtkMain.Main.quit; + pop#show (); + GtkMain.Main.main (); + entry#set_text (string_of_float !rv); + !rv +end + + +let set_editable ?editable ?(width = -2) ?(height = -2) w = + Gaux.may editable ~f:(GtkEdit.Editable.set_editable w); + if width <> -2 || height <> -2 then GtkBase.Widget.set_usize w ~width ~height + + +let entry_float ~init ?max_length ?visibility ?editable + ?width ?height ?packing ?show () = + let w = GtkEdit.Entry.create ?max_length () in + GtkEdit.Entry.set w ~text:(string_of_float init) ?visibility; + set_editable w ?editable ?width ?height; + pack_return (new entry_float w ~init) ~packing ~show + + +(*************************************************************) + + +let split_string s ~sep = + let l = String.length s in + let r = ref [] in + let j = ref 0 in + for i = 0 to l-1 do + if String.unsafe_get s i = sep then begin + r := (String.sub s ~pos:!j ~len:(i - !j)) :: !r; + j := i + 1 + end + done; + List.rev ((String.sub s ~pos:!j ~len:(l - !j)) :: !r) + + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/vbox.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/vbox.xpm new file mode 100644 index 000000000..1c557b021 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/vbox.xpm @@ -0,0 +1,31 @@ +/* XPM */ +static char *vbox_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 4 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c Gray100", +/* pixels */ +"oooooooooooooooooooo ", +"oXXXXXXXXXXXXXXXXXX. ", +"oXXXXXXXXXXXXXXXXXX. ", +"oXXXXXXXXXXXXXXXXXX. ", +"oXXXXXXXXXXXXXXXXXX. ", +"o................... ", +" ", +"oooooooooooooooooooo ", +"oXXXXXXXXXXXXXXXXXX. ", +"oXXXXXXXXXXXXXXXXXX. ", +"oXXXXXXXXXXXXXXXXXX. ", +"oXXXXXXXXXXXXXXXXXX. ", +"o................... ", +" ", +"oooooooooooooooooooo ", +"oXXXXXXXXXXXXXXXXXX. ", +"oXXXXXXXXXXXXXXXXXX. ", +"oXXXXXXXXXXXXXXXXXX. ", +"oXXXXXXXXXXXXXXXXXX. ", +"o................... ", +" " +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/vbuttonbox.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/vbuttonbox.xpm new file mode 100644 index 000000000..0c2bc9598 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/vbuttonbox.xpm @@ -0,0 +1,33 @@ +/* XPM */ +static char *vbuttonbox_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 6 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray100", +"+ c None", +/* pixels */ +"+++++++++++++++++++++", +"+++++++++++++++++++++", +"++++++++OOOOO +++++++", +"++++++++OXXX. +++++++", +"++++++++OXXX. +++++++", +"++++++++O.... +++++++", +"++++++++ +++++++", +"+++++++++++++++++++++", +"++++++++OOOOO +++++++", +"++++++++OXXX. +++++++", +"++++++++OXXX. +++++++", +"++++++++O.... +++++++", +"++++++++ +++++++", +"+++++++++++++++++++++", +"++++++++OOOOO +++++++", +"++++++++OXXX. +++++++", +"++++++++OXXX. +++++++", +"++++++++O.... +++++++", +"++++++++ +++++++", +"+++++++++++++++++++++", +"+++++++++++++++++++++" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/viewport.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/viewport.xpm new file mode 100644 index 000000000..71e5e80cf --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/viewport.xpm @@ -0,0 +1,34 @@ +/* XPM */ +static char *viewport_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 7 1", +" c Gray0", +". c #7b7b7b", +"X c #d6d6d6", +"o c #b3cece", +"O c Gray87", +"+ c Gray100", +"@ c None", +/* pixels */ +"@@@@@@@@@@@@@@@@@@@@@", +"@...................@", +"@. +O@", +"@. XXXXXXXXXXXXXXX+O@", +"@. XXXXXXXXXXXXXXX+O@", +"@. XXXXXXXXXXXXXXX+O@", +"@. XXXXXXXXXXXXXXX+O@", +"@. XXXXXXXXXXXXXXX+O@", +"@. XXXXXXXXXXXXXXX+O@", +"@. XXXXXXXXXXXXXXX+O@", +"@. XXXXXXXXXXXXXXX+O@", +"@. XXXXXXXXXXXXXXX+O@", +"@. XXXXXXXXXXXXXXX+O@", +"@. XXXXXXXXXXXXXXX+O@", +"@. XXXXXXXXXXXXXXX+O@", +"@. XXXXXXXXXXXXXXX+O@", +"@. XXXXXXXXXXXXXXX+O@", +"@. XXXXXXXXXXXXXXX+O@", +"@.+++++++++++++++++O@", +"@.OOOOOOOOOOOOOOOOOO@", +"@@@@@@@@@@@@@@@@@@@@@" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/vseparator.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/vseparator.xpm new file mode 100644 index 000000000..3455f74d9 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/vseparator.xpm @@ -0,0 +1,31 @@ +/* XPM */ +static char *vseparator_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 4 1", +" c #7b7b7b", +". c #b3cece", +"X c Gray100", +"o c None", +/* pixels */ +"ooooooooooooooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"oooooooooo Xooooooooo", +"ooooooooooooooooooooo" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/window.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/window.xpm new file mode 100644 index 000000000..8407e2836 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/radtest/window.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char *window_xpm[] = { +/* columns rows colors chars-per-pixel */ +"21 21 11 1", +" c Gray0", +". c #00007b", +"X c #7b7b7b", +"o c Green", +"O c Cyan", +"+ c Red", +"@ c Yellow", +"# c #d6d6d6", +"$ c #b3cece", +"% c Gray100", +"& c None", +/* pixels */ +"&&&&&&&&&&&&&&&&&&&&&", +"&&&&&&&&&&&&&&&&&&&&&", +"&&&&&&&&&&&&&&&&&&&&&", +"XXXXXXXXXXXXXXXXXXXX&", +"X.+@...............X ", +"X.Oo.%%%.%%.....# #X ", +"XXXXXXXXXXXXXXXXXXXX ", +"X#%%%%%%%%%%%%%%%%%X ", +"X#%%%%%%%%%%%%%%%%%X ", +"X#%%%%%%%%%%%%%%%%%X ", +"X#%%%%%%%%%%%%%%%%%X ", +"X#%%%%%%%%%%%%%%%%%X ", +"X#%%%%%%%%%%%%%%%%%X ", +"X#%%%%%%%%%%%%%%%%%X ", +"X#%%%%%%%%%%%%%%%%%X ", +"X#%%%%%%%%%%%%%%%%%X ", +"X#%%%%%%%%%%%%%%%%%X ", +"XXXXXXXXXXXXXXXXXXXX ", +"& ", +"&&&&&&&&&&&&&&&&&&&&&", +"&&&&&&&&&&&&&&&&&&&&&" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/unison/README b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/unison/README new file mode 100644 index 000000000..e98697ada --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/applications/unison/README @@ -0,0 +1,10 @@ + A GUI for Unison + +As of version 2.6.1, unison works with LablGTK snapshots. +You may just compile it after having installed lablgtk. + + http://www.cis.upenn.edu/~bcpierce/unison/ + +Jacques Garrigue + +$Id$ diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/doc/formula.eps b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/doc/formula.eps new file mode 100644 index 000000000..31ddafc6f --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/doc/formula.eps @@ -0,0 +1,409 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Creator: dvipsk 5.78 p1.4c Copyright 1996-99 ASCII Corp.(www-ptex@ascii.co.jp) +%%dvipsk 5.78 Copyright 1998 Radical Eye Software (www.radicaleye.com) +%%Title: formula.dvi +%%BoundingBox: 71 318 395 524 +%%DocumentFonts: Symbol Times-Italic Times-Roman Helvetica +%%EndComments +%DVIPSCommandLine: dvips -E -o formula.eps formula +%DVIPSParameters: dpi=300, compressed +%DVIPSSource: TeX output 1999.08.19:0906 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N +/X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 +mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} +ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale +isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div +hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul +TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} +forall round exch round exch]setmatrix}N /@landscape{/isls true N}B +/@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B +/FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ +/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N +string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N +end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ +/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] +N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup +length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ +128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub +get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data +dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N +/rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup +/base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx +0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff +setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff +.1 sub]/id ch-image N /rw ch-width 7 add 8 idiv string N /rc 0 N /gp 0 N +/cp 0 N{rc 0 ne{rc 1 sub /rc X rw}{G}ifelse}imagemask restore}B /G{{id +gp get /gp gp 1 add N dup 18 mod S 18 idiv pl S get exec}loop}B /adv{cp +add /cp X}B /chg{rw cp id gp 4 index getinterval putinterval dup gp add +/gp X adv}B /nd{/cp 0 N rw exit}B /lsh{rw cp 2 copy get dup 0 eq{pop 1}{ +dup 255 eq{pop 254}{dup dup add 255 and S 1 and or}ifelse}ifelse put 1 +adv}B /rsh{rw cp 2 copy get dup 0 eq{pop 128}{dup 255 eq{pop 127}{dup 2 +idiv S 128 and or}ifelse}ifelse put 1 adv}B /clr{rw cp 2 index string +putinterval adv}B /set{rw cp fillstr 0 4 index getinterval putinterval +adv}B /fillstr 18 string 0 1 17{2 copy 255 put pop}for N /pl[{adv 1 chg} +{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{ +adv rsh nd}{1 add adv}{/rc X nd}{1 add set}{1 add clr}{adv 2 chg}{adv 2 +chg nd}{pop nd}]dup{bind pop}forall N /D{/cc X dup type /stringtype ne{] +}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup +length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ +cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin +0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul +add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict +/eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook +known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X +/IE 256 array N 2 string 0 1 255{IE S dup 360 add 36 4 index cvrs cvn +put}for pop 65781.76 div /vsize X 65781.76 div /hsize X}N /dir 0 def +/dyy{/dir 0 def}B /dyt{/dir 1 def}B /dty{/dir 2 def}B /dtt{/dir 3 def}B +/p{dir 2 eq{-90 rotate show 90 rotate}{dir 3 eq{-90 rotate show 90 +rotate}{show}ifelse}ifelse}B /RMat[1 0 0 -1 0 0]N /BDot 260 string N +/rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V{}B /RV statusdict +begin /product where{pop false[(Display)(NeXT)(LaserWriter 16/600)]{dup +length product length le{dup length product exch 0 exch getinterval eq{ +pop true exit}if}{pop}ifelse}forall}{false}ifelse end{{gsave TR -.1 .1 +TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR +-.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}} +ifelse B /QV{gsave newpath transform round exch round exch itransform +moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill +grestore}B /a{moveto}B /delta 0 N /tail{dup /delta X 0 rmoveto}B /M{S p +delta add tail}B /b{S p tail}B /c{-4 M}B /d{-3 M}B /e{-2 M}B /f{-1 M}B +/g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{4 M}B /w{0 rmoveto}B /l{p -4 w}B +/m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{ +p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS +restore}B end + +%%EndProcSet +%%BeginProcSet: 8r.enc +% @@psencodingfile@{ +% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", +% version = "0.6", +% date = "22 June 1996", +% filename = "8r.enc", +% email = "kb@@mail.tug.org", +% address = "135 Center Hill Rd. // Plymouth, MA 02360", +% codetable = "ISO/ASCII", +% checksum = "119 662 4424", +% docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." +% @} +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both ASCII and Windows. +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there down to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /.notdef /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + +%%EndProcSet +%%BeginProcSet: texps.pro +%! +TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 +index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics +exch def dict begin 0 1 255{exch dup type /integertype ne{pop pop 1 sub +dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} +ifelse}for Metrics /Metrics currentdict end def[2 index currentdict end +definefont 3 -1 roll makefont /setfont cvx]cvx def}def /ObliqueSlant{ +dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 +roll mul exch}def /ReEncodeFont{/Encoding exch def}def end + +%%EndProcSet +%%BeginProcSet: special.pro +%! +TeXDict begin /SDict 200 dict N SDict begin /@SpecialDefaults{/hs 612 N +/vs 792 N /ho 0 N /vo 0 N /hsc 1 N /vsc 1 N /ang 0 N /CLIP 0 N /rwiSeen +false N /rhiSeen false N /letter{}N /note{}N /a4{}N /legal{}N}B +/@scaleunit 100 N /@hscale{@scaleunit div /hsc X}B /@vscale{@scaleunit +div /vsc X}B /@hsize{/hs X /CLIP 1 N}B /@vsize{/vs X /CLIP 1 N}B /@clip{ +/CLIP 2 N}B /@hoffset{/ho X}B /@voffset{/vo X}B /@angle{/ang X}B /@rwi{ +10 div /rwi X /rwiSeen true N}B /@rhi{10 div /rhi X /rhiSeen true N}B +/@llx{/llx X}B /@lly{/lly X}B /@urx{/urx X}B /@ury{/ury X}B /magscale +true def end /@MacSetUp{userdict /md known{userdict /md get type +/dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup +length 20 add dict copy def}if end md begin /letter{}N /note{}N /legal{} +N /od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath +clippath mark{transform{itransform moveto}}{transform{itransform lineto} +}{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{ +itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{ +closepath}}pathforall newpath counttomark array astore /gc xdf pop ct 39 +0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}if}N +/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 +scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get +ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip +not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 +TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{noflips{TR +pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 +-1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg +TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg +sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr +0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add +2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N /cp +{pop pop showpage pm restore}N end}if}if}N /normalscale{Resolution 72 +div VResolution 72 div neg scale magscale{DVImag dup scale}if 0 setgray} +N /psfts{S 65781.76 div N}N /startTexFig{/psf$SavedState save N userdict +maxlength dict begin /magscale true def normalscale currentpoint TR +/psf$ury psfts /psf$urx psfts /psf$lly psfts /psf$llx psfts /psf$y psfts +/psf$x psfts currentpoint /psf$cy X /psf$cx X /psf$sx psf$x psf$urx +psf$llx sub div N /psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy +scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR +/showpage{}N /erasepage{}N /copypage{}N /p 3 def @MacSetUp}N /doclip{ +psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 +roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath +moveto}N /endTexFig{end psf$SavedState restore}N /@beginspecial{SDict +begin /SpecialSave save N gsave normalscale currentpoint TR +@SpecialDefaults count /ocount X /dcount countdictstack N}N /@setspecial +{CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto +closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx +sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR +}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse +CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury +lineto closepath clip}if /showpage{}N /erasepage{}N /copypage{}N newpath +}N /@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{ +end}repeat grestore SpecialSave restore end}N /@defspecial{SDict begin} +N /@fedspecial{end}B /li{lineto}B /rl{rlineto}B /rc{rcurveto}B /np{ +/SaveX currentpoint /SaveY X N 1 setlinecap newpath}N /st{stroke SaveX +SaveY moveto}N /fil{fill SaveX SaveY moveto}N /ellipse{/endangle X +/startangle X /yrad X /xrad X /savematrix matrix currentmatrix N TR xrad +yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end + +%%EndProcSet +%%BeginProcSet: color.pro +%! +TeXDict begin /setcmykcolor where{pop}{/setcmykcolor{dup 10 eq{pop +setrgbcolor}{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll +}repeat setrgbcolor pop}ifelse}B}ifelse /TeXcolorcmyk{setcmykcolor}def +/TeXcolorrgb{setrgbcolor}def /TeXcolorgrey{setgray}def /TeXcolorgray{ +setgray}def /TeXcolorhsb{sethsbcolor}def /currentcmykcolor where{pop}{ +/currentcmykcolor{currentrgbcolor 10}B}ifelse /DC{exch dup userdict exch +known{pop pop}{X}ifelse}B /GreenYellow{0.15 0 0.69 0 setcmykcolor}DC +/Yellow{0 0 1 0 setcmykcolor}DC /Goldenrod{0 0.10 0.84 0 setcmykcolor} +DC /Dandelion{0 0.29 0.84 0 setcmykcolor}DC /Apricot{0 0.32 0.52 0 +setcmykcolor}DC /Peach{0 0.50 0.70 0 setcmykcolor}DC /Melon{0 0.46 0.50 +0 setcmykcolor}DC /YellowOrange{0 0.42 1 0 setcmykcolor}DC /Orange{0 +0.61 0.87 0 setcmykcolor}DC /BurntOrange{0 0.51 1 0 setcmykcolor}DC +/Bittersweet{0 0.75 1 0.24 setcmykcolor}DC /RedOrange{0 0.77 0.87 0 +setcmykcolor}DC /Mahogany{0 0.85 0.87 0.35 setcmykcolor}DC /Maroon{0 +0.87 0.68 0.32 setcmykcolor}DC /BrickRed{0 0.89 0.94 0.28 setcmykcolor} +DC /Red{0 1 1 0 setcmykcolor}DC /OrangeRed{0 1 0.50 0 setcmykcolor}DC +/RubineRed{0 1 0.13 0 setcmykcolor}DC /WildStrawberry{0 0.96 0.39 0 +setcmykcolor}DC /Salmon{0 0.53 0.38 0 setcmykcolor}DC /CarnationPink{0 +0.63 0 0 setcmykcolor}DC /Magenta{0 1 0 0 setcmykcolor}DC /VioletRed{0 +0.81 0 0 setcmykcolor}DC /Rhodamine{0 0.82 0 0 setcmykcolor}DC /Mulberry +{0.34 0.90 0 0.02 setcmykcolor}DC /RedViolet{0.07 0.90 0 0.34 +setcmykcolor}DC /Fuchsia{0.47 0.91 0 0.08 setcmykcolor}DC /Lavender{0 +0.48 0 0 setcmykcolor}DC /Thistle{0.12 0.59 0 0 setcmykcolor}DC /Orchid{ +0.32 0.64 0 0 setcmykcolor}DC /DarkOrchid{0.40 0.80 0.20 0 setcmykcolor} +DC /Purple{0.45 0.86 0 0 setcmykcolor}DC /Plum{0.50 1 0 0 setcmykcolor} +DC /Violet{0.79 0.88 0 0 setcmykcolor}DC /RoyalPurple{0.75 0.90 0 0 +setcmykcolor}DC /BlueViolet{0.86 0.91 0 0.04 setcmykcolor}DC /Periwinkle +{0.57 0.55 0 0 setcmykcolor}DC /CadetBlue{0.62 0.57 0.23 0 setcmykcolor} +DC /CornflowerBlue{0.65 0.13 0 0 setcmykcolor}DC /MidnightBlue{0.98 0.13 +0 0.43 setcmykcolor}DC /NavyBlue{0.94 0.54 0 0 setcmykcolor}DC +/RoyalBlue{1 0.50 0 0 setcmykcolor}DC /Blue{1 1 0 0 setcmykcolor}DC +/Cerulean{0.94 0.11 0 0 setcmykcolor}DC /Cyan{1 0 0 0 setcmykcolor}DC +/ProcessBlue{0.96 0 0 0 setcmykcolor}DC /SkyBlue{0.62 0 0.12 0 +setcmykcolor}DC /Turquoise{0.85 0 0.20 0 setcmykcolor}DC /TealBlue{0.86 +0 0.34 0.02 setcmykcolor}DC /Aquamarine{0.82 0 0.30 0 setcmykcolor}DC +/BlueGreen{0.85 0 0.33 0 setcmykcolor}DC /Emerald{1 0 0.50 0 +setcmykcolor}DC /JungleGreen{0.99 0 0.52 0 setcmykcolor}DC /SeaGreen{ +0.69 0 0.50 0 setcmykcolor}DC /Green{1 0 1 0 setcmykcolor}DC +/ForestGreen{0.91 0 0.88 0.12 setcmykcolor}DC /PineGreen{0.92 0 0.59 +0.25 setcmykcolor}DC /LimeGreen{0.50 0 1 0 setcmykcolor}DC /YellowGreen{ +0.44 0 0.74 0 setcmykcolor}DC /SpringGreen{0.26 0 0.76 0 setcmykcolor} +DC /OliveGreen{0.64 0 0.95 0.40 setcmykcolor}DC /RawSienna{0 0.72 1 0.45 +setcmykcolor}DC /Sepia{0 0.83 1 0.70 setcmykcolor}DC /Brown{0 0.81 1 +0.60 setcmykcolor}DC /Tan{0.14 0.42 0.56 0 setcmykcolor}DC /Gray{0 0 0 +0.50 setcmykcolor}DC /Black{0 0 0 1 setcmykcolor}DC /White{0 0 0 0 +setcmykcolor}DC end + +%%EndProcSet +TeXDict begin 40258437 52099154 1000 300 300 (formula.dvi) +@start /Fa 134[ 41 5[ 41 3[ 46 46 1[ 18 6[ 46 15[ 60 +4[ 55 14[ 55 23[ 28 28 40[{ TeXBase1Encoding ReEncodeFont } 11 +82.6359 /Helvetica rf /Fb 205[ 34 34 49[{ + TeXBase1Encoding ReEncodeFont } 2 68.8667 /Times-Roman +rf /Fc 154[ 30 101[{ } 1 68.8667 /Symbol rf +%DVIPSBitmapFont: Fd cmr10 19.907 4 +/Fd 4 94 df<146014E0EB01C0EB0380EB0700130E5B133C13385B13F05B1201485AA248 +5AA348C7FCA25A121EA2123EA2123CA2127CA5127812F8B01278127CA5123CA2123EA212 +1EA2121F7EA26C7EA36C7EA26C7E12007F13707F133C131C7F7FEB0380EB01C0EB00E014 +60135278BD20> 40 D<7E7E7E12707E7E7E120F7E6C7E7F12017F6C7EA21378A37FA213 +3E131EA2131FA27FA21480A5130714C0B01480130FA51400A25BA2131EA2133E133CA25B +A35BA2485A5B12035B48C7FC5A120E5A5A5A5A5A5A12527BBD20> I 91 D 93 D E +%EndDVIPSBitmapFont +/Fe 197[ 23 58[{ TeXBase1Encoding ReEncodeFont } 1 82.6359 +/Times-Roman rf +%DVIPSBitmapFont: Ff cmsy10 19.907 4 +/Ff 4 106 df<0060161800F0163CA26C167C00781678007C16F8003C16F0A2003E1501 +001E16E0A2001F15036C16C06D140700071680A26D140F000316006D5C6CB612FEA36C5D +01F8C7127C01781478A2017C14F8013C5CA2013E1301011E5C011F13036D5CA2EC800701 +075CECC00F010391C7FCA26E5A0101131EECF03E0100133CA2ECF87CEC7878A2EC7CF8EC +3CF0143F6E5AA36E5AA26E5AA26EC8FC2E3A80B82F> 56 D<126012F0B3A7B8FC1780A3 +00F0CAFCB3A8126029397CB832> 96 D<14C0EB01E0A2130314C013071480A2130F1400 +A25B131E133E133CA2137C137813F85BA212015BA212035B12075BA2120F90C7FC5A121E +A2123E123CA2127C127812F85AA27E1278127C123CA2123E121EA2121F7E7F1207A27F12 +037F1201A27F1200A27F1378137C133CA2133E131E131F7FA214801307A214C0130314E0 +1301A2EB00C0135278BD20> 104 D<126012F0A27E1278127C123CA2123E121EA2121F7E +7F1207A27F12037F1201A27F1200A27F1378137C133CA2133E131E131F7FA214801307A2 +14C0130314E01301A2130314C013071480A2130F1400A25B131E133E133CA2137C137813 +F85BA212015BA212035B12075BA2120F90C7FC5A121EA2123E123CA2127C127812F85AA2 +126013527CBD20> I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fg cmmi10 19.907 1 +/Fg 1 59 df<121C123E127FEAFF80A3EA7F00123E121C0909798817> 58 +D E +%EndDVIPSBitmapFont +/Fh 158[ 41 31[ 50 65[{ TeXBase1Encoding ReEncodeFont } 2 +82.6359 /Times-Italic rf /Fi 139[ 36 50 13[ 36 101[{ } 3 +82.6359 /Symbol rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 300dpi +TeXDict begin + +%%EndSetup +0 0 bop Black Black 0 0.7 0 TeXcolorrgb Fh 567 883 a(A) p +Ff 636 883 a(`) p Fh 705 883 a(a) p Fe 765 883 a(:) p +0 0 1 TeXcolorrgb Fi 806 883 a(t) p Fb 842 900 a(1) p +0 0.7 0 TeXcolorrgb Fd 948 883 a(\() p 0 0 1 TeXcolorrgb +Fi(t) p Fb 1016 900 a(1) p 0 0.7 0 TeXcolorrgb Fe 1071 +883 a(:) p 0 0 1 TeXcolorrgb Fi 1112 883 a(t) p 0 0.7 0 +TeXcolorrgb Fe 1167 883 a(:) p 0 0 1 TeXcolorrgb Fi 1208 +883 a(t) p Fb 1244 900 a(2) p 0 0.7 0 TeXcolorrgb Fd +1281 883 a(\)) p 567 920 746 4 v Fh 704 995 a(A) p Ff +773 995 a(`) p Fd 842 995 a(\() p Fh(a) p Fe 934 995 +a(:) p 0 0 1 TeXcolorrgb Fi 975 995 a(t) p 0 0.7 0 TeXcolorrgb +Fd(\)) p Fe 1062 995 a(:) p 0 0 1 TeXcolorrgb Fi 1103 +995 a(t) p Fb 1139 1012 a(2) p 0 0.7 0 TeXcolorrgb Black +Fa 2 939 a(\(Ann\)) p 0 0.7 0 TeXcolorrgb Black 0 0.7 0 +TeXcolorrgb Fh 540 1208 a(A) p Ff 609 1208 a(`) p Fh +678 1208 a(a) p Fe 738 1208 a(:) p 0 0 1 TeXcolorrgb +Fi 779 1208 a(s) p Fb 829 1225 a(1) p 0 0.7 0 TeXcolorrgb +Fd 934 1208 a(\() p 0 0 1 TeXcolorrgb Fi(s) p Fb 1016 +1225 a(1) p 0 0.7 0 TeXcolorrgb Fe 1071 1208 a(:) p 0 0 1 +TeXcolorrgb Fi 1112 1208 a(s) p 0 0.7 0 TeXcolorrgb Fe +1180 1208 a(:) p 0 0 1 TeXcolorrgb Fi 1222 1208 a(s) p +Fb 1272 1225 a(2) p 0 0.7 0 TeXcolorrgb Fd 1308 1208 +a(\)) p 540 1245 801 4 v Fh 661 1321 a(A) p Ff 730 1321 +a(`) p Fd 799 1321 a([) p Fh(a) p Fe 881 1321 a(:) p +0 0 1 TeXcolorrgb Fi 923 1321 a(s) p 0 0.7 0 TeXcolorrgb +Fd 972 1321 a(]) p Fe 1014 1321 a(:) p 0 0 1 TeXcolorrgb +Fd 1055 1321 a([) p Fi(s) p Fb 1128 1338 a(2) p Fd 1164 +1321 a(]) p Fc 1187 1297 a(e) p 0 0.7 0 TeXcolorrgb Black +Fa 2 1264 a(\(P) l(oly\)) p 0 0.7 0 TeXcolorrgb Black +0 0.7 0 TeXcolorrgb Fh 704 1537 a(A) p Ff 773 1537 a(`) p +Fh 842 1537 a(a) p Fe 902 1537 a(:) p 0 0 1 TeXcolorrgb +Ff 943 1537 a(8) p Fi(e) p Fg(:) p Fd([) p Fi(s) p Fd(]) p +Fc 1145 1507 a(e) p 0 0.7 0 TeXcolorrgb 704 1573 472 +4 v Fh 764 1649 a(A) p Ff 833 1649 a(`) p 902 1649 a(h) p +Fh(a) p Ff(i) p Fe 1025 1649 a(:) p 0 0 1 TeXcolorrgb +Fi 1067 1649 a(s) p 0 0.7 0 TeXcolorrgb Black Fa 2 1592 +a(\(Use\)) p 0 0.7 0 TeXcolorrgb Black Black Black 90 rotate +dyy eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/doc/lablgtk.mgp b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/doc/lablgtk.mgp new file mode 100644 index 000000000..3eac79341 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/doc/lablgtk.mgp @@ -0,0 +1,558 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%deffont "code" xfont "itc avant garde gothic-demi-r", tfont "verdana.ttf" +%deffont "code-bold" xfont "terminal-bold-r", tfont "verdanab.ttf" +%deffont "sans" xfont "helvetica-medium-r", tfont "comic.ttf" +%deffont "sans-bold" xfont "helvetica-bold-r", tfont "comicbd.ttf" +%deffont "sansit" xfont "helvetica-medium-i", tfont "marlett.ttf" +%deffont "title" xfont "times-medium-r", tfont "times.ttf" +%deffont "title-bold" xfont "times-bold-r", tfont "timesbd.ttf" +%default 1 right, size 2, fore "white", bgrad +%default 1 vfont "goth", font "sans-bold", vgap 100 +%default 2 leftfill, size 8, vgap 60, prefix " ", font "sans" +%default 3 size 4, bar "beige", vgap 10 +%default 4 size 5, fore "white", vgap 20, prefix " " +%tab 1 size 5, vgap 40, prefix " ", icon box "green" 50 +%tab 2 size 5, vgap 40, prefix " ", icon arc "yellow" 50 +%tab 3 size 5, vgap 40, prefix " ", icon arc "white" 40 +%tab com1 size 4, prefix " " +%tab com2 size 4, prefix " " +%tab com3 size 4, prefix " " +%tab txt font "sans", size 5, fore "white", prefix " " +%tab vspace size 2 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +%nodefault +%size 9, font "title-bold" +%fore "beige", back "navyblue", vgap 20 +%center + + +A Type System in Action: + +the LablGTK Interface + + +%size 7, font "title" +Jacques Garrigue +Kyoto University +%size 6, font "code" +garrigue@kurims.kyoto-u.ac.jp + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +2 +Synopsis + + Objective Label introduction +%size 2 + + Why GTK+? + GTK+/LablGTK structure +%size 2 + + Low Level + Type encoding with variants + Labeled parameters +%size 2 + + High Level + Object-orientation + Optional arguments + Polymorphic methods +%size 2 + + Conclusion + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +3 +Objective Label + + Based on Objective Caml + ML syntax and type inference + Class-based object system + + Several extensions + Labeled and optional parameters + Polymorphic variants + Polymorphic methods + + Tools + Type-based browser + GUI and 3D graphics + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +4 +Labels and optionals + +%font "code", size 4, prefix " ", fore "yellow" +let rec map fun:f = function + [] -> [] + | x :: l -> f x :: map fun:f l +%fore "lightpink" +val map : fun:('a -> 'b) -> 'a list -> 'b list + +%pause, fore "yellow", font "code" +let f = map [1;2;3] +%fore "lightpink" +val f : fun:(int -> 'a) -> 'a list +%fore "yellow" +f fun:(fun x -> 2*x) +%fore "lightpink" +- : int list = [2; 3; 4] + +%pause, fore "yellow", font "code" +let f x ?incr:y [< 1 >] = x + y +%fore "lightpink" +val f : int -> ?incr:int -> int +%fore "yellow" +f 1 +%fore "lightpink" +- : int = 2 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +5 +Polymorphic variants + + +%font "code", size 4, prefix " ", fore "yellow" +[`on; `off] +%fore "lightpink" +- : [> off on] list = [`on; `off] + +%pause, fore "yellow", font "code" +`number 1;; +%fore "lightpink" +- : [> number(int)] = `number 1 + +%pause, fore "yellow", font "code" +let f = function `on -> 1 | `off -> 0 | `number n -> n +%fore "lightpink" +val f : [< number(int) off on] -> int + +%pause, fore "yellow", font "code" +type t = [on off number(int)] + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +6 +Polymorphic methods + +Not allowed in Objective Caml +%size 2 + +%font "code", size 4, prefix " ", fore "yellow" +class c = object method m x = x end +%fore "red" +Some type variables are unbound in this type: + class c : object method m : 'a -> 'a end +The method m has type 'a -> 'a where 'a is unbound + +%pause, font "sans", size 5, prefix " ", fore "white" +Need explicit annotation in O'Labl +%size 2 + +%font "code", size 4, prefix " ", fore "yellow" +class c = object + method m : 'a. 'a -> 'a = fun x -> x +end +%fore "lightpink" +class c : object method m : 'a -> 'a end +%fore "yellow" +let o = new c +%fore "lightpink" +val o : c = +%fore "yellow" +o#m 1, o#m true +%fore "lightpink" +- : int * bool = 1, true + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +7 +Why GTK+ ? + +Why use the GIMP Tool Kit? +%size 3 + + Widely used in free software + + Easy to interface + Written in C (QT uses C++) + Memory management + +Drawbacks +%size 3 + + Design lacks uniformity + Extensive use of dynamic typing + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +8 +GTK+ Structure + +Class hierarchy based on GtkObject +%size 2 + + Single inheritance +&com1 New widgets may redefine methods +%size 2 + + Dynamically checked +&com1 Casting necessay both up and down +%size 2 + + Developper-side hierarchy +&com1 Inheritance is not always meaningful to the user +%size 2 + +%size 5 +Signal-based callback mechanism +%size 2 + + May use multiple callbacks +%size 2 + + Signals are polymorphic + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +9 +LablGTK structure + +Typed at all levels + + Low-level interface +%size 2 + + C stub functions -- typechecked by C + + ML type declarations -- ML abstract types + + High-level interface +%size 2 + + ML class wrappers -- ML concrete types + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +10 +Low Level Interface + +Goals + + Strongly typed interface +&com1 heavy use of advanced typing techniques + + Very little ML code +&com1 C-stubs and external declarations + + Safe memory management +&com1 have the library cooperate with the GC + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +11 +Low level encoding (I) + + +How to represent widget subtyping in ML? + + Example: buttons' hierarchy +%size 2 + +%font "code", size 5, prefix " ", fore "yellow" +GtkObject + GtkWidget + GtkContainer + GtkButton + GtkToggleButton + GtkRadioButton + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +12 +Variants as set constraints + + +Variants can be seen as sets of possible values: + + [tag1 ... tagn] = {tag1,...,tagn} + + +Polymorphic variants introduce constraints + + $B&A(B[> tag1 ... tagn] $B"N(B $B&A(B $B"?(B {tag1,...,tagn} + $B&A(B[< tag1 ... tagn] $B"N(B $B&A(B $B">(B {tag1,...,tagn} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +13 +Encoding hierarchies + +Define an abstract type +&vspace +%font "code", fore "yellow", size 5 + type 'a obj + +&txt Use tags to represent properties +&vspace +%font "code", fore "yellow", size 5 + type t = [class1 ... classn] obj + +&txt Functions check properties +&vspace +%font "code", fore "yellow", size 5 + val f : [> class1 ... classn] obj -> ... +&txt + Subsumes Haskell type classes +&vspace + Allows multiple inheritance + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +14 +Low level encoding (II) + +Example: buttons' hierarchy +%size 2 + +%font "code", size 4, prefix " ", fore "yellow" +type 'a obj +type widget = [widget] obj +type container = [widget container] obj +type button = [widget container button] obj +type toggle_button = [widget ... togglebutton] obj +type radio_button = [widget ... radiobutton] obj +type state_type = [ NORMAL + ACTIVE PRELIGHT SELECTED INSENSITIVE ] +val set_state : [> widget] obj -> state_type -> unit +val children : [> container] obj -> [widget] obj list +val clicked : [> button] obj -> unit +val set_group : [> radiobutton] obj -> group -> unit + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +15 +Alternate encoding + +Use only standard ML features +%size 2 + +%font "code", size 4, prefix " ", fore "yellow", vgap 50 +type 'a obj +type 'a widget +... +type 'a radio +type state_type = NORMAL | ACTIVE | ... | INSENSITIVE +val set_state : 'a widget obj -> state_type -> unit +val children : + 'a container widget obj -> unit widget obj list +val clicked : 'a button container widget obj -> unit + +&txt Weaknesses + No multiple inheritance + Not very intuitive for the user + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +16 +Low level encoding (III) + +Use of labeled parameters +%size 2 + +%font "code", size 4, prefix " ", fore "yellow", vgap 50 +val adjustment_new : + value:float -> lower:float -> upper:float -> + step_incr:float -> page_incr:float -> + page_size:float -> adjustment obj + +&txt Signals +%size 2 + +%font "code", size 4, prefix " ", fore "yellow", vgap 50 +type ('a,'b) signal = + { name: string; marshaller: 'b -> GtkArgv.t -> unit } +val connect : 'a obj -> sig:('a,'b) signal -> + callback:'b -> ?after:bool -> id +val button_clicked : ([> button], unit -> unit) signal + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +17 +High-Level Interface + +Problems with GTK+ +%size 2 + + Name space is scattered +&com1 One has to know in which superclass a function is defined + Developper oriented design +&com1 There is no clear distinction between public and private definitions + +&txt LablGTK design +%size 2 + + OCaml classes to reunify name space + Omit developper-oriented methods + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +18 +High-level classes + +%font "code", size 4, prefix " ", fore "yellow" +class button : +%fore "lightgreen" + ?label:string -> +%fore "lightpink" + ?border_width:int -> + ?width:int -> + ?height:int -> +%fore "lightgray" + ?packing:(GButton.button -> unit) -> + ?show:bool -> +%fore "yellow" + object +%fore "lightgray" + method destroy : unit -> unit + method as_widget : Gtk.widget obj + method misc : GObj.widget_misc +%fore "lightpink" + method add : #is_widget -> unit + method set_border_width : int -> unit +%fore "lightgreen" + method clicked : unit -> unit + method connect : GButton.button_signals + method grab_default : unit -> unit +%fore "yellow" + end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +19 +High-level features + + Objective Caml classes +&com1 allow collecting methods from different modules + + Use optionals in class constructors +&com1 makes widget creation much easier + + Polymorphic methods +&com1 needed for container widgets +%size 2 + +%font "code", size 4, fore "yellow", vgap 50 + method add : 'a. (#is_widget as 'a) -> unit + +%fore "white", font "sans" + Polymorphic variants +&com1 for C-style enumeration types, avoid name-space dependancies + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +20 +Polymorphic methods (I) + + Instance of first-class polymorphism +%size 2 + + first-class polytypes cannot be inferred + they are propagated by the definition flow + + Technically +%size 2 + + use polymorphism to track available information + type system excludes derivations based on "guessed" information + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +21 +First class polymorphism + +%prefix " " +%image "formula.eps" 512x384 +%size 2 + +%prefix " ", size 5, fore "lightblue" + ($B&R(B1 : $B&R(B : $B&R(B2) $B"N(B $B&R(B1 = $B&H(B($B&Q(B1($B&R(B)) $B"J(B $B&R(B2 = $B&H(B($B&Q(B2($B&R(B)) +%fore "white" +where $B&H(B instantiates free variables, and $B&Q(B1,$B&Q(B2 rename free labels of $B&R(B. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +22 +Polymorphic methods (II) + +Definitions +%size 2 + +%font "code", size 4, prefix " ", fore "yellow", vgap 50 +type is_widget = < as_widget : widget obj > +type #is_widget = < as_widget : widget obj; .. > +type container = + < ... ; add : 'a. (#as_widget as 'a) -> unit; ... > + +%pause +&txt Propagation +%size 2 + +%font "code", size 4, prefix " ", fore "lightgreen", vgap 50 +fun (cont : container) -> cont#add widget + +%pause +let button = new button in button#add widget + +%pause, fore "red" +fun cont -> cont#add widget + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +23 +Programming example + +Hello World +%size 2 + +%font "code", size 4, prefix " ", fore "yellow" +open GMain + +let window = + new GWindow.window border_width: 10 + +let button = + new GButton.button + label: "Hello World" packing: window#add + +let _ = + window#connect#destroy callback: Main.quit; + button#connect#clicked callback: window#destroy; + window#show (); + Main.main () + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%page +24 +Conclusion + + Results +%size 2 + + Could build a strongly typed interface + + It is easier to use than the C API + + Makes effective use of extensions to the type system + + Comments +%size 2 + + Still difficulties with the Caml object system +&com2 class recursion, method type refinement, etc... diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/morph3d.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/morph3d.ml new file mode 100644 index 000000000..a08726e05 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/morph3d.ml @@ -0,0 +1,607 @@ +(* $Id$ *) + +(*- + * morph3d.c - Shows 3D morphing objects (TK Version) + * + * This program was inspired on a WindowsNT(R)'s screen saver. It was written + * from scratch and it was not based on any other source code. + * + * Porting it to xlock (the final objective of this code since the moment I + * decided to create it) was possible by comparing the original Mesa's gear + * demo with it's ported version, so thanks for Danny Sung for his indirect + * help (look at gear.c in xlock source tree). NOTE: At the moment this code + * was sent to Brian Paul for package inclusion, the XLock Version was not + * available. In fact, I'll wait it to appear on the next Mesa release (If you + * are reading this, it means THIS release) to send it for xlock package + * inclusion). It will probably there be a GLUT version too. + * + * Thanks goes also to Brian Paul for making it possible and inexpensive + * to use OpenGL at home. + * + * Since I'm not a native english speaker, my apologies for any gramatical + * mistake. + * + * My e-mail addresses are + * + * vianna@cat.cbpf.br + * and + * marcelo@venus.rdc.puc-rio.br + * + * Marcelo F. Vianna (Feb-13-1997) + *) + +(* +This document is VERY incomplete, but tries to describe the mathematics used +in the program. At this moment it just describes how the polyhedra are +generated. On futhurer versions, this document will be probabbly improved. + +Since I'm not a native english speaker, my apologies for any gramatical +mistake. + +Marcelo Fernandes Vianna +- Undergraduate in Computer Engeneering at Catholic Pontifical University +- of Rio de Janeiro (PUC-Rio) Brasil. +- e-mail: vianna@cat.cbpf.br or marcelo@venus.rdc.puc-rio.br +- Feb-13-1997 + +POLYHEDRA GENERATION + +For the purpose of this program it's not sufficient to know the polyhedra +vertexes coordinates. Since the morphing algorithm applies a nonlinear +transformation over the surfaces (faces) of the polyhedron, each face has +to be divided into smaller ones. The morphing algorithm needs to transform +each vertex of these smaller faces individually. It's a very time consoming +task. + +In order to reduce calculation overload, and since all the macro faces of +the polyhedron are transformed by the same way, the generation is made by +creating only one face of the polyhedron, morphing it and then rotating it +around the polyhedron center. + +What we need to know is the face radius of the polyhedron (the radius of +the inscribed sphere) and the angle between the center of two adjacent +faces using the center of the sphere as the angle's vertex. + +The face radius of the regular polyhedra are known values which I decided +to not waste my time calculating. Following is a table of face radius for +the regular polyhedra with edge length = 1: + + TETRAHEDRON : 1/(2*sqrt(2))/sqrt(3) + CUBE : 1/2 + OCTAHEDRON : 1/sqrt(6) + DODECAHEDRON : T^2 * sqrt((T+2)/5) / 2 -> where T=(sqrt(5)+1)/2 + ICOSAHEDRON : (3*sqrt(3)+sqrt(15))/12 + +I've not found any reference about the mentioned angles, so I needed to +calculate them, not a trivial task until I figured out how :) +Curiously these angles are the same for the tetrahedron and octahedron. +A way to obtain this value is inscribing the tetrahedron inside the cube +by matching their vertexes. So you'll notice that the remaining unmatched +vertexes are in the same straight line starting in the cube/tetrahedron +center and crossing the center of each tetrahedron's face. At this point +it's easy to obtain the bigger angle of the isosceles triangle formed by +the center of the cube and two opposite vertexes on the same cube face. +The edges of this triangle have the following lenghts: sqrt(2) for the base +and sqrt(3)/2 for the other two other edges. So the angle we want is: + +-----------------------------------------------------------+ + | 2*ARCSIN(sqrt(2)/sqrt(3)) = 109.47122063449069174 degrees | + +-----------------------------------------------------------+ +For the cube this angle is obvious, but just for formality it can be +easily obtained because we also know it's isosceles edge lenghts: +sqrt(2)/2 for the base and 1/2 for the other two edges. So the angle we +want is: + +-----------------------------------------------------------+ + | 2*ARCSIN((sqrt(2)/2)/1) = 90.000000000000000000 degrees | + +-----------------------------------------------------------+ +For the octahedron we use the same idea used for the tetrahedron, but now +we inscribe the cube inside the octahedron so that all cubes's vertexes +matches excatly the center of each octahedron's face. It's now clear that +this angle is the same of the thetrahedron one: + +-----------------------------------------------------------+ + | 2*ARCSIN(sqrt(2)/sqrt(3)) = 109.47122063449069174 degrees | + +-----------------------------------------------------------+ +For the dodecahedron it's a little bit harder because it's only relationship +with the cube is useless to us. So we need to solve the problem by another +way. The concept of Face radius also exists on 2D polygons with the name +Edge radius: + Edge Radius For Pentagon (ERp) + ERp = (1/2)/TAN(36 degrees) * VRp = 0.6881909602355867905 + (VRp is the pentagon's vertex radio). + Face Radius For Dodecahedron + FRd = T^2 * sqrt((T+2)/5) / 2 = 1.1135163644116068404 +Why we need ERp? Well, ERp and FRd segments forms a 90 degrees angle, +completing this triangle, the lesser angle is a half of the angle we are +looking for, so this angle is: + +-----------------------------------------------------------+ + | 2*ARCTAN(ERp/FRd) = 63.434948822922009981 degrees | + +-----------------------------------------------------------+ +For the icosahedron we can use the same method used for dodecahedron (well +the method used for dodecahedron may be used for all regular polyhedra) + Edge Radius For Triangle (this one is well known: 1/3 of the triangle height) + ERt = sin(60)/3 = sqrt(3)/6 = 0.2886751345948128655 + Face Radius For Icosahedron + FRi= (3*sqrt(3)+sqrt(15))/12 = 0.7557613140761707538 +So the angle is: + +-----------------------------------------------------------+ + | 2*ARCTAN(ERt/FRi) = 41.810314895778596167 degrees | + +-----------------------------------------------------------+ + +*) + + +let scale = 0.3 + +let vect_mul (x1,y1,z1) (x2,y2,z2) = + (y1 *. z2 -. z1 *. y2, z1 *. x2 -. x1 *. z2, x1 *. y2 -. y1 *. x2) + +let sqr a = a *. a + +(* Increasing this values produces better image quality, the price is speed. *) +(* Very low values produces erroneous/incorrect plotting *) +let tetradivisions = 23 +let cubedivisions = 20 +let octadivisions = 21 +let dodecadivisions = 10 +let icodivisions = 15 + +let tetraangle = 109.47122063449069174 +let cubeangle = 90.000000000000000000 +let octaangle = 109.47122063449069174 +let dodecaangle = 63.434948822922009981 +let icoangle = 41.810314895778596167 + +let pi = acos (-1.) +let sqrt2 = sqrt 2. +let sqrt3 = sqrt 3. +let sqrt5 = sqrt 5. +let sqrt6 = sqrt 6. +let sqrt15 = sqrt 15. +let cossec36_2 = 0.8506508083520399322 +let cosd x = cos (float x /. 180. *. pi) +let sind x = sin (float x /. 180. *. pi) +let cos72 = cosd 72 +let sin72 = sind 72 +let cos36 = cosd 36 +let sin36 = sind 36 + +(*************************************************************************) + +let front_shininess = 60.0 +let front_specular = 0.7, 0.7, 0.7, 1.0 +let ambient = 0.0, 0.0, 0.0, 1.0 +let diffuse = 1.0, 1.0, 1.0, 1.0 +let position0 = 1.0, 1.0, 1.0, 0.0 +let position1 = -1.0,-1.0, 1.0, 0.0 +let lmodel_ambient = 0.5, 0.5, 0.5, 1.0 +let lmodel_twoside = true + +let materialRed = 0.7, 0.0, 0.0, 1.0 +let materialGreen = 0.1, 0.5, 0.2, 1.0 +let materialBlue = 0.0, 0.0, 0.7, 1.0 +let materialCyan = 0.2, 0.5, 0.7, 1.0 +let materialYellow = 0.7, 0.7, 0.0, 1.0 +let materialMagenta = 0.6, 0.2, 0.5, 1.0 +let materialWhite = 0.7, 0.7, 0.7, 1.0 +let materialGray = 0.2, 0.2, 0.2, 1.0 +let all_gray = Array.create 20 materialGray + +let vertex ~xf ~yf ~zf ~ampvr2 = + let xa = xf +. 0.01 and yb = yf +. 0.01 in + let xf2 = sqr xf and yf2 = sqr yf in + let factor = 1. -. (xf2 +. yf2) *. ampvr2 + and factor1 = 1. -. (sqr xa +. yf2) *. ampvr2 + and factor2 = 1. -. (xf2 +. sqr yb) *. ampvr2 in + let vertx = factor *. xf and verty = factor *. yf + and vertz = factor *. zf in + let neiax = factor1 *. xa -. vertx and neiay = factor1 *. yf -. verty + and neiaz = factor1 *. zf -. vertz and neibx = factor2 *. xf -. vertx + and neiby = factor2 *. yb -. verty and neibz = factor2 *. zf -. vertz in + GlDraw.normal3 (vect_mul (neiax, neiay, neiaz) (neibx, neiby, neibz)); + GlDraw.vertex3 (vertx, verty, vertz) + +let triangle ~edge ~amp ~divisions ~z = + let divi = float divisions in + let vr = edge *. sqrt3 /. 3. in + let ampvr2 = amp /. sqr vr + and zf = edge *. z in + let ax = edge *. (0.5 /. divi) + and ay = edge *. (-0.5 *. sqrt3 /. divi) + and bx = edge *. (-0.5 /. divi) in + for ri = 1 to divisions do + GlDraw.begins `triangle_strip; + for ti = 0 to ri - 1 do + vertex ~zf ~ampvr2 + ~xf:(float (ri-ti) *. ax +. float ti *. bx) + ~yf:(vr +. float (ri-ti) *. ay +. float ti *. ay); + vertex ~zf ~ampvr2 + ~xf:(float (ri-ti-1) *. ax +. float ti *. bx) + ~yf:(vr +. float (ri-ti-1) *. ay +. float ti *. ay) + done; + vertex ~xf:(float ri *. bx) ~yf:(vr +. float ri *. ay) ~zf ~ampvr2; + GlDraw.ends () + done + +let square ~edge ~amp ~divisions ~z = + let divi = float divisions in + let zf = edge *. z + and ampvr2 = amp /. sqr (edge *. sqrt2 /. 2.) in + for yi = 0 to divisions - 1 do + let yf = edge *. (-0.5 +. float yi /. divi) in + let yf2 = sqr yf in + let y = yf +. 1.0 /. divi *. edge in + let y2 = sqr y in + GlDraw.begins `quad_strip; + for xi = 0 to divisions do + let xf = edge *. (-0.5 +. float xi /. divi) in + vertex ~xf ~yf:y ~zf ~ampvr2; + vertex ~xf ~yf ~zf ~ampvr2 + done; + GlDraw.ends () + done + +let pentagon ~edge ~amp ~divisions ~z = + let divi = float divisions in + let zf = edge *. z + and ampvr2 = amp /. sqr(edge *. cossec36_2) in + let x = + Array.init 6 + ~f:(fun fi -> -. cos (float fi *. 2. *. pi /. 5. +. pi /. 10.) + /. divi *. cossec36_2 *. edge) + and y = + Array.init 6 + ~f:(fun fi -> sin (float fi *. 2. *. pi /. 5. +. pi /. 10.) + /. divi *. cossec36_2 *. edge) + in + for ri = 1 to divisions do + for fi = 0 to 4 do + GlDraw.begins `triangle_strip; + for ti = 0 to ri-1 do + vertex ~zf ~ampvr2 + ~xf:(float(ri-ti) *. x.(fi) +. float ti *. x.(fi+1)) + ~yf:(float(ri-ti) *. y.(fi) +. float ti *. y.(fi+1)); + vertex ~zf ~ampvr2 + ~xf:(float(ri-ti-1) *. x.(fi) +. float ti *. x.(fi+1)) + ~yf:(float(ri-ti-1) *. y.(fi) +. float ti *. y.(fi+1)) + done; + vertex ~xf:(float ri *. x.(fi+1)) ~yf:(float ri *. y.(fi+1)) ~zf ~ampvr2; + GlDraw.ends () + done + done + +let call_list list color = + GlLight.material ~face:`both (`diffuse color); + GlList.call list + +let draw_tetra ~amp ~divisions ~color = + let list = GlList.create `compile in + triangle ~edge:2.0 ~amp ~divisions ~z:(0.5 /. sqrt6); + GlList.ends(); + + call_list list color.(0); + GlMat.push(); + GlMat.rotate ~angle:180.0 ~z:1.0 (); + GlMat.rotate ~angle:(-.tetraangle) ~x:1.0 (); + call_list list color.(1); + GlMat.pop(); + GlMat.push(); + GlMat.rotate ~angle:180.0 ~y:1.0 (); + GlMat.rotate ~angle:(-180.0 +. tetraangle) ~x:0.5 ~y:(sqrt3 /. 2.) (); + call_list list color.(2); + GlMat.pop(); + GlMat.rotate ~angle:180.0 ~y:1.0 (); + GlMat.rotate ~angle:(-180.0 +. tetraangle) ~x:0.5 ~y:(-.sqrt3 /. 2.) (); + call_list list color.(3); + + GlList.delete list + +let draw_cube ~amp ~divisions ~color = + let list = GlList.create `compile in + square ~edge:2.0 ~amp ~divisions ~z:0.5; + GlList.ends (); + + call_list list color.(0); + for i = 1 to 3 do + GlMat.rotate ~angle:cubeangle ~x:1.0 (); + call_list list color.(i) + done; + GlMat.rotate ~angle:cubeangle ~y:1.0 (); + call_list list color.(4); + GlMat.rotate ~angle:(2.0 *. cubeangle) ~y:1.0 (); + call_list list color.(5); + + GlList.delete list + +let draw_octa ~amp ~divisions ~color = + let list = GlList.create `compile in + triangle ~edge:2.0 ~amp ~divisions ~z:(1.0 /. sqrt6); + GlList.ends (); + + let do_list (i,y) = + GlMat.push(); + GlMat.rotate ~angle:180.0 ~y:1.0 (); + GlMat.rotate ~angle:(-.octaangle) ~x:0.5 ~y (); + call_list list color.(i); + GlMat.pop() + in + call_list list color.(0); + GlMat.push(); + GlMat.rotate ~angle:180.0 ~z:1.0 (); + GlMat.rotate ~angle:(-180.0 +. octaangle) ~x:1.0 (); + call_list list color.(1); + GlMat.pop(); + List.iter [2, sqrt3 /. 2.0; 3, -.sqrt3 /. 2.0] ~f:do_list; + GlMat.rotate ~angle:180.0 ~x:1.0 (); + GlLight.material ~face:`both (`diffuse color.(4)); + GlList.call list; + GlMat.push(); + GlMat.rotate ~angle:180.0 ~z:1.0 (); + GlMat.rotate ~angle:(-180.0 +. octaangle) ~x:1.0 (); + GlLight.material ~face:`both (`diffuse color.(5)); + GlList.call list; + GlMat.pop(); + List.iter [6, sqrt3 /. 2.0; 7, -.sqrt3 /. 2.0] ~f:do_list; + + GlList.delete list + +let draw_dodeca ~amp ~divisions ~color = + let tau = (sqrt5 +. 1.0) /. 2.0 in + let list = GlList.create `compile in + pentagon ~edge:2.0 ~amp ~divisions + ~z:(sqr(tau) *. sqrt ((tau+.2.0)/.5.0) /. 2.0); + GlList.ends (); + + let do_list (i,angle,x,y) = + GlMat.push(); + GlMat.rotate ~angle:angle ~x ~y (); + call_list list color.(i); + GlMat.pop(); + in + GlMat.push (); + call_list list color.(0); + GlMat.rotate ~angle:180.0 ~z:1.0 (); + List.iter ~f:do_list + [ 1, -.dodecaangle, 1.0, 0.0; + 2, -.dodecaangle, cos72, sin72; + 3, -.dodecaangle, cos72, -.sin72; + 4, dodecaangle, cos36, -.sin36; + 5, dodecaangle, cos36, sin36 ]; + GlMat.pop (); + GlMat.rotate ~angle:180.0 ~x:1.0 (); + call_list list color.(6); + GlMat.rotate ~angle:180.0 ~z:1.0 (); + List.iter ~f:do_list + [ 7, -.dodecaangle, 1.0, 0.0; + 8, -.dodecaangle, cos72, sin72; + 9, -.dodecaangle, cos72, -.sin72; + 10, dodecaangle, cos36, -.sin36 ]; + GlMat.rotate ~angle:dodecaangle ~x:cos36 ~y:sin36 (); + call_list list color.(11); + + GlList.delete list + +let draw_ico ~amp ~divisions ~color = + let list = GlList.create `compile in + triangle ~edge:1.5 ~amp ~divisions + ~z:((3.0 *. sqrt3 +. sqrt15) /. 12.0); + GlList.ends (); + + let do_list1 i = + GlMat.rotate ~angle:180.0 ~y:1.0 (); + GlMat.rotate ~angle:(-180.0 +. icoangle) ~x:0.5 ~y:(sqrt3/.2.0) (); + call_list list color.(i) + and do_list2 i = + GlMat.rotate ~angle:180.0 ~y:1.0 (); + GlMat.rotate ~angle:(-180.0 +. icoangle) ~x:0.5 ~y:(-.sqrt3/.2.0) (); + call_list list color.(i) + and do_list3 i = + GlMat.rotate ~angle:180.0 ~z:1.0 (); + GlMat.rotate ~angle:(-.icoangle) ~x:1.0 (); + call_list list color.(i) + in + GlMat.push (); + call_list list color.(0); + GlMat.push (); + do_list3 1; + GlMat.push (); + do_list1 2; + GlMat.pop (); + do_list2 3; + GlMat.pop (); + GlMat.push (); + do_list1 4; + GlMat.push (); + do_list1 5; + GlMat.pop(); + do_list3 6; + GlMat.pop (); + do_list2 7; + GlMat.push (); + do_list2 8; + GlMat.pop (); + do_list3 9; + GlMat.pop (); + GlMat.rotate ~angle:180.0 ~x:1.0 (); + call_list list color.(10); + GlMat.push (); + do_list3 11; + GlMat.push (); + do_list1 12; + GlMat.pop (); + do_list2 13; + GlMat.pop (); + GlMat.push (); + do_list1 14; + GlMat.push (); + do_list1 15; + GlMat.pop (); + do_list3 16; + GlMat.pop (); + do_list2 17; + GlMat.push (); + do_list2 18; + GlMat.pop (); + do_list3 19; + + GlList.delete list + +class view area = object (self) + val area : GlGtk.area = area + val mutable smooth = true + val mutable step = 0. + val mutable obj = 1 + val mutable draw_object = fun ~amp -> () + val mutable magnitude = 0. + + method width = area#misc#allocation.Gtk.width + method height = area#misc#allocation.Gtk.height + + method draw () = + let ratio = float self#height /. float self#width in + GlClear.clear [`color;`depth]; + GlMat.push(); + GlMat.translate ~z:(-10.0) (); + GlMat.scale ~x:(scale *. ratio) ~y:scale ~z:scale (); + GlMat.translate () + ~x:(2.5 *. ratio *. sin (step *. 1.11)) + ~y:(2.5 *. cos (step *. 1.25 *. 1.11)); + GlMat.rotate ~angle:(step *. 100.) ~x:1.0 (); + GlMat.rotate ~angle:(step *. 95.) ~y:1.0 (); + GlMat.rotate ~angle:(step *. 90.) ~z:1.0 (); + draw_object ~amp:((sin step +. 1.0/.3.0) *. (4.0/.5.0) *. magnitude); + GlMat.pop(); + Gl.flush(); + area#swap_buffers (); + step <- step +. 0.05 + + method reshape ~width ~height = + GlDraw.viewport ~x:0 ~y:0 ~w:width ~h:height; + GlMat.mode `projection; + GlMat.load_identity(); + GlMat.frustum ~x:(-1.0, 1.0) ~y:(-1.0, 1.0) ~z:(5.0, 15.0); + GlMat.mode `modelview + + method key sym = + begin match sym with + "1" -> obj <- 1 + | "2" -> obj <- 2 + | "3" -> obj <- 3 + | "4" -> obj <- 4 + | "5" -> obj <- 5 + | "\r" -> smooth <- not smooth + | "\027" -> area#misc#toplevel#destroy (); exit 0 + | _ -> () + end; + self#pinit + + method pinit = + begin match obj with + 1 -> + draw_object <- draw_tetra + ~divisions:tetradivisions + ~color:[|materialRed; materialGreen; + materialBlue; materialWhite|]; + magnitude <- 2.5 + | 2 -> + draw_object <- draw_cube + ~divisions:cubedivisions + ~color:[|materialRed; materialGreen; materialCyan; + materialMagenta; materialYellow; materialBlue|]; + magnitude <- 2.0 + | 3 -> + draw_object <- draw_octa + ~divisions:octadivisions + ~color:[|materialRed; materialGreen; materialBlue; + materialWhite; materialCyan; materialMagenta; + materialGray; materialYellow|]; + magnitude <- 2.5 + | 4 -> + draw_object <- draw_dodeca + ~divisions:dodecadivisions + ~color:[|materialRed; materialGreen; materialCyan; + materialBlue; materialMagenta; materialYellow; + materialGreen; materialCyan; materialRed; + materialMagenta; materialBlue; materialYellow|]; + magnitude <- 2.0 + | 5 -> + draw_object <- draw_ico + ~divisions:icodivisions + ~color:[|materialRed; materialGreen; materialBlue; + materialCyan; materialYellow; materialMagenta; + materialRed; materialGreen; materialBlue; + materialWhite; materialCyan; materialYellow; + materialMagenta; materialRed; materialGreen; + materialBlue; materialCyan; materialYellow; + materialMagenta; materialGray|]; + magnitude <- 3.5 + | _ -> () + end; + GlDraw.shade_model (if smooth then `smooth else `flat) + initializer + area#connect#display ~callback:self#draw; + area#connect#reshape ~callback:self#reshape; + () +end + +open GMain + +let main () = + List.iter ~f:print_string + [ "Morph 3D - Shows morphing platonic polyhedra\n"; + "Author: Marcelo Fernandes Vianna (vianna@cat.cbpf.br)\n"; + "Ported to LablGL by Jacques Garrigue\n\n"; + " [1] - Tetrahedron\n"; + " [2] - Hexahedron (Cube)\n"; + " [3] - Octahedron\n"; + " [4] - Dodecahedron\n"; + " [5] - Icosahedron\n"; + "[RETURN] - Toggle smooth/flat shading\n"; + " [ESC] - Quit\n" ]; + flush stdout; + + let window = + GWindow.window ~title:"Morph 3D - Shows morphing platonic polyhedra" () + in + window#connect#destroy ~callback:Main.quit; + window#set_resize_mode `IMMEDIATE; + + let area = GlGtk.area [`DEPTH_SIZE 1;`RGBA;`DOUBLEBUFFER] + ~width:640 ~height:480 ~packing:window#add () in + + let view = new view area in + + area#connect#realize ~callback: + begin fun () -> + view#pinit; + GlClear.depth 1.0; + GlClear.color (0.0, 0.0, 0.0); + GlDraw.color (1.0, 1.0, 1.0); + + GlClear.clear [`color;`depth]; + Gl.flush(); + + List.iter ~f:(GlLight.light ~num:0) + [`ambient ambient; `diffuse diffuse; `position position0]; + List.iter ~f:(GlLight.light ~num:1) + [`ambient ambient; `diffuse diffuse; `position position1]; + GlLight.light_model (`ambient lmodel_ambient); + GlLight.light_model (`two_side lmodel_twoside); + List.iter ~f:Gl.enable + [`lighting;`light0;`light1;`depth_test;`normalize]; + + GlLight.material ~face:`both (`shininess front_shininess); + GlLight.material ~face:`both (`specular front_specular); + + GlMisc.hint `fog `fastest; + GlMisc.hint `perspective_correction `fastest; + GlMisc.hint `polygon_smooth `fastest + end; + + window#event#connect#key_press + ~callback:(fun ev -> view#key (GdkEvent.Key.string ev); true); + + Timeout.add ~ms:20 + ~callback:(fun _ -> if area#misc#visible then view#draw (); true); + window#show (); + Main.main () + +let _ = main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/planet.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/planet.ml new file mode 100644 index 000000000..51f947c48 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/planet.ml @@ -0,0 +1,125 @@ +(* $Id$ *) + +class planet area = object (self) + val area : GlGtk.area = area + val mutable year = 0.0 + val mutable day = 0.0 + val mutable eye = 0.0 + val mutable time = 0.0 + + method tick new_time = + if time = 0. then time <- new_time else + let diff = new_time -. time in + time <- new_time; + day <- mod_float (day +. diff *. 200.) 360.0; + year <- mod_float (year +. diff *. 20.) 360.0 + method day_add () = + day <- mod_float (day +. 10.0) 360.0 + method day_subtract () = + day <- mod_float (day -. 10.0) 360.0 + method year_add () = + year <- mod_float (year +. 5.0) 360.0 + method year_subtract () = + year <- mod_float (year -. 5.0) 360.0 + method eye x = + eye <- x; self#display () + + method display () = + GlClear.clear [`color;`depth]; + + GlDraw.color (1.0, 1.0, 1.0); + GlMat.push(); + GlMat.rotate ~angle:eye ~x:1. (); +(* draw sun *) + GlLight.material ~face:`front (`specular (1.0,1.0,0.0,1.0)); + GlLight.material ~face:`front (`shininess 5.0); + GluQuadric.sphere ~radius:1.0 ~slices:32 ~stacks:32 (); +(* draw smaller planet *) + GlMat.rotate ~angle:year ~y:1.0 (); + GlMat.translate ~x:3.0 (); + GlMat.rotate ~angle:day ~y:1.0 (); + GlDraw.color (0.0, 1.0, 1.0); + GlDraw.shade_model `flat; + GlLight.material ~face:`front(`shininess 128.0); + GluQuadric.sphere ~radius:0.2 ~slices:10 ~stacks:10 (); + GlDraw.shade_model `smooth; + GlMat.pop (); + Gl.flush (); + area#swap_buffers () +end + +let myinit () = + let light_ambient = 0.5, 0.5, 0.5, 1.0 + and light_diffuse = 1.0, 0.8, 0.2, 1.0 + and light_specular = 1.0, 1.0, 1.0, 1.0 + (* light_position is NOT default value *) + and light_position = 1.0, 1.0, 1.0, 0.0 + in + List.iter ~f:(GlLight.light ~num:0) + [ `ambient light_ambient; `diffuse light_diffuse; + `specular light_specular; `position light_position ]; + GlFunc.depth_func `less; + List.iter ~f:Gl.enable [`lighting; `light0; `depth_test]; + GlDraw.shade_model `smooth + + +let my_reshape ~width:w ~height:h = + GlDraw.viewport ~x:0 ~y:0 ~w ~h; + GlMat.mode `projection; + GlMat.load_identity(); + GluMat.perspective ~fovy:60.0 ~aspect:(float w /. float h) ~z:(1.0,20.0); + GlMat.mode `modelview; + GlMat.load_identity(); + GlMat.translate ~z:(-5.0) () + +(* Main Loop + * Open window with initial window size, title bar, + * RGBA display mode, and handle input events. + *) +open GMain +open GdkKeysyms + +let main () = + let w = GWindow.window ~title:"Planet" () in + w#connect#destroy ~callback:(fun () -> Main.quit (); exit 0); + w#set_resize_mode `IMMEDIATE; + let hb = GPack.hbox ~packing:w#add () in + let area = GlGtk.area [`DOUBLEBUFFER;`RGBA;`DEPTH_SIZE 1] + ~width:700 ~height:500 ~packing:hb#add () in + area#event#add [`KEY_PRESS]; + + let planet = new planet area in + let adjustment = GData.adjustment ~value:0. ~lower:(-90.) ~upper:90. + ~step_incr:1. ~page_incr:5. ~page_size:5. () in + let scale = GRange.scale `VERTICAL ~adjustment ~draw_value:false + ~packing:hb#pack () in + adjustment#connect#value_changed + ~callback:(fun () -> planet#eye adjustment#value); + w#event#connect#key_press ~callback: + begin fun ev -> + let key = GdkEvent.Key.keyval ev in + if key = _Left then planet#year_subtract () else + if key = _Right then planet#year_add () else + if key = _Up then planet#day_add () else + if key = _Down then planet#day_subtract () else + if key = _Escape then w#destroy (); + planet#display (); + true + end; + + Timeout.add ~ms:20 ~callback: + begin fun () -> + planet#tick (Sys.time ()); planet#display (); true + end; + area#connect#display ~callback:planet#display; + area#connect#reshape ~callback:my_reshape; + + area#connect#realize ~callback: + begin fun () -> + myinit (); + my_reshape ~width:700 ~height:500 + end; + w#show (); + Main.main () + +let _ = Printexc.print main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/simple.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/simple.ml new file mode 100644 index 000000000..ea6ebde96 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/GL/simple.ml @@ -0,0 +1,33 @@ +(* $Id$ *) + +open GMain + +let main () = + let w = GWindow.window ~title:"LablGL/Gtk" () in + w#connect#destroy ~callback:Main.quit; + let area = + GlGtk.area [`RGBA;`DEPTH_SIZE 1] ~width:500 ~height:500 ~packing:w#add () in + area#connect#realize ~callback: + begin fun () -> + GlMat.mode `projection; + GlMat.load_identity (); + GlMat.ortho ~x:(-1.0,1.0) ~y:(-1.0,1.0) ~z:(-1.0,1.0); + end; + area#connect#display ~callback: + begin fun () -> + GlClear.color (0.0, 0.0, 0.0); + GlClear.clear [`color]; + GlDraw.color (1.0, 1.0, 1.0); + GlDraw.begins `polygon; + GlDraw.vertex ~x:(-0.5) ~y:(-0.5) (); + GlDraw.vertex ~x:(-0.5) ~y:(0.5) (); + GlDraw.vertex ~x:(0.5) ~y:(0.5) (); + GlDraw.vertex ~x:(0.5) ~y:(-0.5) (); + GlDraw.ends (); + Gl.flush () + end; + Timeout.add ~ms:10000 ~callback:(fun () -> w#destroy ();false); + w#show (); + Main.main () + +let _ = main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/README b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/README new file mode 100644 index 000000000..6cbb5b6e9 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/README @@ -0,0 +1,17 @@ +Since this library was written in commuting label mode, examples were +also written in this mode. +Still, the following examples also compile in classic mode without +any modification. + +* calendar.ml +* clist.ml +* drawing.ml +* entry.ml +* events.ml +* fifteen.ml +* hello.ml +* image.ml +* radiobuttons.ml +* rpn.ml +* scrolledwin.ml +* testinput.ml \ No newline at end of file diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/buttons.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/buttons.ml new file mode 100644 index 000000000..78eebb038 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/buttons.ml @@ -0,0 +1,26 @@ +(* $Id$ *) + +open GMain + +let xpm_label_box ~(window : #GContainer.container) + ~file ~text ?packing ?(show=true) () = + if not (Sys.file_exists file) then failwith (file ^ " does not exist"); + let box = GPack.hbox ~border_width: 2 ?packing ~show:false () in + let pixmap = GDraw.pixmap_from_xpm ~file ~window () in + GMisc.pixmap pixmap ~packing:(box#pack ~padding:3) (); + GMisc.label ~text ~packing:(box#pack ~padding:3) (); + if show then box#misc#show (); + new GObj.widget_full box#as_widget + +let main () = + let window = GWindow.window ~title:"Pixmap'd Buttons!" ~border_width:10 () in + window#connect#destroy ~callback:Main.quit; + let button = GButton.button ~packing:window#add () in + button#connect#clicked ~callback: + (fun () -> prerr_endline "Hello again - cool button was pressed"); + xpm_label_box ~window ~file:"test.xpm" ~text:"cool button" + ~packing:button#add (); + window#show (); + Main.main () + +let _ = main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/calc.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/calc.ml new file mode 100644 index 000000000..405d1bf87 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/calc.ml @@ -0,0 +1,114 @@ +(* $Id$ *) + +(* A simple calculator ported from LablTk to LablGtk *) + +let mem_string ~char s = + try + for i = 0 to String.length s -1 do + if s.[i] = char then raise Exit + done; false + with Exit -> true + +let ops = ['+',(+.); '-',(-.); '*',( *.); '/',(/.)] + +(* The abstract calculator class. Does not use Gtk *) + +class virtual calc = object (calc) + val mutable x = 0.0 + val mutable op = None + val mutable displaying = true + + method virtual set : string -> unit + method virtual get : string + method virtual quit : unit -> unit + method insert s = calc#set (calc#get ^ s) + method get_float = float_of_string (calc#get) + + initializer calc#set "0" + + method command s = + if s <> "" then match s.[0] with + '0'..'9' -> + if displaying then (calc#set ""; displaying <- false); + calc#insert s + | '.' -> + if displaying then + (calc#set "0."; displaying <- false) + else + if not (mem_string ~char:'.' calc#get) then calc#insert s + | '+'|'-'|'*'|'/' as c -> + displaying <- true; + begin match op with + None -> + x <- calc#get_float; + op <- Some (List.assoc c ops) + | Some f -> + x <- f x (calc#get_float); + op <- Some (List.assoc c ops); + calc#set (string_of_float x) + end + | '='|'\n'|'\r' -> + displaying <- true; + begin match op with + None -> () + | Some f -> + x <- f x (calc#get_float); + op <- None; + calc#set (string_of_float x) + end + | 'q' -> calc#quit () + | _ -> () +end + +(* Buttons for the calculator *) + +let m = + [|[|"7";"8";"9";"+"|]; + [|"4";"5";"6";"-"|]; + [|"1";"2";"3";"*"|]; + [|"0";".";"=";"/"|]|] + +(* The physical calculator. Inherits from the abstract one *) + +open GMain + +class calculator ?packing ?show () = + let table = GPack.table ~rows:5 ~columns:4 ~homogeneous:true ~show:false () in + object (calc) + inherit calc + + val label = + let frame = GBin.frame ~shadow_type:`IN () + ~packing:(table#attach ~left:0 ~top:0 ~right:4 ~expand:`BOTH) in + let evbox = GBin.event_box ~packing:frame#add () in + evbox#misc#set_style evbox#misc#style#copy; + evbox#misc#style#set_bg [`NORMAL,`WHITE]; + GMisc.label ~justify:`RIGHT ~xalign:0.95 ~packing:evbox#add () + val table = table + + method set = label#set_text + method get = label#text + method quit = Main.quit + + initializer + for i = 0 to 3 do for j = 0 to 3 do + let button = + GButton.button ~label:(" " ^ m.(i).(j) ^ " ") + ~packing:(table#attach ~top:(i+1) ~left:j ~expand:`BOTH) () in + button#connect#clicked ~callback:(fun () -> calc#command m.(i).(j)); + done done; + ignore (GObj.pack_return table ~packing ~show) + end + +(* Finally start everything *) + +let w = GWindow.window ~auto_shrink:true () + +let applet = new calculator ~packing: w#add () + +let _ = + w#connect#destroy ~callback: Main.quit; + w#event#connect#key_press + ~callback:(fun ev -> applet#command (GdkEvent.Key.string ev); true); + w#show (); + Main.main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/calendar.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/calendar.ml new file mode 100644 index 000000000..233c7449f --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/calendar.ml @@ -0,0 +1,21 @@ +(* $Id$ *) + +open GMain + +let main () = + let window = GWindow.window () in + window#connect#destroy ~callback:Main.quit; + + let calendar = GMisc.calendar ~packing:window#add () in + calendar#connect#day_selected ~callback: + begin fun () -> + let (year,month,day) = calendar#date in + Printf.printf "You selected %d/%d/%02d.\n" + day (month+1) (year mod 100); + flush stdout + end; + + window#show (); + Main.main () + +let _ = main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/clist.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/clist.ml new file mode 100644 index 000000000..f900f1781 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/clist.ml @@ -0,0 +1,51 @@ +(* $Id$ *) + +open GMain + +let main () = + let window = GWindow.window ~title:"CList example" ~width:300 ~height:150 () in + window#connect#destroy ~callback:Main.quit; + + let vbox = GPack.vbox ~border_width:5 ~packing:window#add () in + + let hbox = GPack.hbox ~packing:vbox#add () in + let sb = + GRange.scrollbar `VERTICAL ~packing:(hbox#pack ~from:`END) () in + let clist = + GList.clist ~titles:["Ingredients";"Amount"] ~shadow_type:`OUT + ~packing:hbox#add ~vadjustment:sb#adjustment () in + clist#connect#select_row ~callback: + begin fun ~row ~column ~event -> + let text = clist#cell_text row column in + Printf.printf "You selected row %d. More specifically you clicked in column %d, and the text in this cell is %s\n\n" row column text; + flush stdout + end; + + let hbox = GPack.hbox ~packing:vbox#pack () in + + let button_add = GButton.button ~label:"Add List" ~packing:hbox#add () in + button_add#connect#clicked ~callback: + begin fun () -> + List.iter ~f:(fun t -> ignore (clist#append t)) + [ ["Milk"; "3 Oz"]; + ["Water"; "6 l"]; + ["Carrots"; "2"]; + ["Snakes"; "55"] ] + end; + + let button_clear = GButton.button ~label:"Clear List" ~packing:hbox#add () in + button_clear#connect#clicked ~callback:clist#clear; + + let button_hide_show = + GButton.button ~label:"Hide/Show titles" ~packing:hbox#add () in + let flag = ref false in + button_hide_show#connect#clicked ~callback: + begin fun () -> + clist#set_titles_show !flag; + flag := not !flag + end; + + window#show (); + Main.main () + +let _ = main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/combo.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/combo.ml new file mode 100644 index 000000000..9aff1b320 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/combo.ml @@ -0,0 +1,23 @@ +(* $Id$ *) + +open GMain + +let make_arrow_label combo ~label ~string = + let item = GList.list_item () in (* no packing here, it blocks GTK *) + let hbox = GPack.hbox ~spacing:3 ~packing:item#add () in + GMisc.arrow ~kind:`RIGHT ~shadow:`OUT ~packing:hbox#pack (); + GMisc.label ~text:label ~packing:hbox#pack (); + combo#set_item_string item string; + combo#list#add item; + item + +let main () = + let window = GWindow.window ~border_width:10 () in + window#connect#destroy ~callback:Main.quit; + let combo = GEdit.combo ~packing:window#add () in + make_arrow_label combo ~label:"First item" ~string:"1st item"; + make_arrow_label combo ~label:"Second item" ~string:"2nd item"; + window#show (); + Main.main () + +let _ = main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/csview.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/csview.ml new file mode 100644 index 000000000..eaf8de18b --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/csview.ml @@ -0,0 +1,155 @@ +(* $Id$ *) + +(* A simple CSV data viewer *) + +type data = + { fields : string list; + titles : string list; + data : string list list } + +let mem_string ~char s = + try + for i = 0 to String.length s - 1 do + if s.[i] = char then raise Exit + done; + false + with Exit -> true + +let rec until ~chars ?(escapes="") ?(buf = Buffer.create 80) s = + match Stream.peek s with + Some c -> + if mem_string ~char:c escapes then begin + Stream.junk s; + Buffer.add_char buf (Stream.next s); + until ~chars ~escapes ~buf s + end else if mem_string ~char:c chars then + Buffer.contents buf + else begin + Buffer.add_char buf c; + Stream.junk s; + until ~chars ~escapes ~buf s + end + | None -> + if Buffer.length buf > 0 then raise (Stream.Error "until") + else raise Stream.Failure + +let rec ignores ?(chars = " \t") s = + match Stream.peek s with + Some c when mem_string ~char:c chars -> + Stream.junk s; ignores ~chars s + | _ -> () + +let parse_field = parser + [< ''"'; f = until ~chars:"\"" ~escapes:"\\"; ''"'; _ = ignores >] -> + for i = 0 to String.length f - 1 do + if f.[i] = '\031' then f.[i] <- '\n' + done; + f + | [< f = until ~chars:",\n\r" >] -> f + | [< >] -> "" + +let comma = parser [< '','; _ = ignores >] -> () + +let rec parse_list ~item ~sep = parser + [< i = item; s >] -> + begin match s with parser + [< _ = sep; l = parse_list ~item ~sep >] -> i :: l + | [< >] -> [i] + end + | [< >] -> [] + +let parse_one = parse_list ~item:parse_field ~sep:comma + +let lf = parser [< ''\n'|'\r'; _ = ignores ~chars:"\n\r"; _ = ignores >] -> () + +let parse_all = parse_list ~item:parse_one ~sep:lf + +let read_file file = + let ic = open_in file in + let s = Stream.of_channel ic in + let data = parse_all s in + close_in ic; + match data with + ("i"::fields) :: ("T"::titles) :: data -> + {fields=fields; titles=titles; data=List.map ~f:List.tl data} + | titles :: data -> + {fields=titles; titles=titles; data=data} + | _ -> failwith "Insufficient data" + +let print_string s = + Format.print_char '"'; + for i = 0 to String.length s - 1 do + match s.[i] with + '\'' -> Format.print_char '\'' + | '"' -> Format.print_string "\\\"" + | '\160'..'\255' as c -> Format.print_char c + | c -> Format.print_string (Char.escaped c) + done; + Format.print_char '"' + +(* +#install_printer print_string;; +*) + +open GMain + +let field_widths = + [ "i", 0; + "ATTR", 0; + "NAME", 17; + "NAPR", 8; + "TEL1", 14; + "ZIPC", 12; + "ADR1", 40; + "BRTH", 10; + "RMRK", 20; + "CHK1", 0; + "CHK2", 0; + "CHK3", 0; + "CHK4", 0; + "TIM1", 16; + "TIM2", 16; + "ALRM", 0; + "ATTM", 0; + ] + +let main argv = + if Array.length argv <> 2 then begin + prerr_endline "Usage: csview "; + exit 2 + end; + let data = read_file argv.(1) in + let w = GWindow.window () in + w#misc#realize (); + let style = w#misc#style in + let font = Gdk.Font.load_fontset "-schumacher-clean-medium-r-normal--13-*-*-*-c-60-*,-mnkaname-fixed-*--12-*" in + let w0 = Gdk.Font.char_width font '0' in + style#set_font font; + w#connect#destroy ~callback:Main.quit; + let sw = GBin.scrolled_window ~width:600 ~height:300 ~packing:w#add () in + let cl = GList.clist ~titles:data.titles ~packing:sw#add () in + List.fold_left data.fields ~init:0 ~f: + begin fun acc f -> + let width = try List.assoc f field_widths with Not_found -> -1 in + if width = 0 then + cl#set_column ~visibility:false acc + else begin + if width > 0 then cl#set_column ~width:(width * w0) acc + else cl#set_column ~auto_resize:true acc; + if f = "NAPR" || f = "TIM1" || f = "CLAS" then + cl#set_sort ~auto:true ~column:acc (); + try + let ali = GBin.alignment_cast (cl#column_widget acc) in + let lbl = GMisc.label_cast (List.hd ali#children) in + lbl#set_alignment ~x:0. () + with _ -> + prerr_endline ("No column widget for field " ^ f) + end; + succ acc + end; + List.iter data.data + ~f:(fun l -> if List.length l > 1 then ignore (cl#append l)); + w#show (); + Main.main () + +let _ = main Sys.argv diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/dcalendar.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/dcalendar.ml new file mode 100644 index 000000000..6128506b4 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/dcalendar.ml @@ -0,0 +1,247 @@ +(* $Id$ *) + +(* A small calendar *) +(* Needs Unix module, so use with lablgtk_t *) + +open Printf + +type date = { mutable year: int; mutable mon: int; mutable mday: int } + + (* Load the schedule data *) +let calendar_file = Filename.concat (Sys.getenv "HOME") ".camlendar" + +let schedule = + try + let ichan = open_in calendar_file in + let (s : (int * int * int, string) Hashtbl.t) = + Marshal.from_channel ichan in + close_in ichan; + s + with Sys_error msg -> + prerr_endline msg; flush stderr; + Hashtbl.create 13;; + + (* Saves the schedule data when the application terminates *) +at_exit (fun () -> + let ochan = open_out calendar_file in + Marshal.to_channel ochan schedule ~mode: []; + close_out ochan);; + + (* date: Current date initialized to "today" *) +let date = + let tm = Unix.localtime (Unix.time ()) in + { year = 1900 + tm.Unix.tm_year; mon = tm.Unix.tm_mon; mday = 1 } + + + (* previous_month, next_month: change application status *) +let previous_month () = + date.mday <- 1; + if date.mon = 0 then + (date.year <- date.year - 1; date.mon <- 11) + else date.mon <- date.mon - 1 + +let next_month () = + date.mday <- 1; + if date.mon = 11 then (date.year <- date.year + 1; date.mon <- 0) + else date.mon <- date.mon + 1 + + (* leap, mon_name, wday_name: Calendar related function and data *) +let leap year = + (year mod 400 = 0) or + (year mod 4 = 0) & (year mod 100 <> 0) + +let mdays_in_month = [|31; 28; 31; 30; 31; 30; 31; 31; 30; 31; 30; 31|] + +let mon_name = + [|"Jan"; "Feb"; "Mar"; "Apr"; "May"; "Jun"; + "Jul"; "Aug"; "Sep"; "Oct"; "Nov"; "Dec"|] + +let wday_name = + [|"Sun"; "Mon"; "Tue"; "Wed"; "Thu"; "Fri"; "Sat"|] + +let s_normal = 0 and s_focused = 1 and s_planned = 2 +let styles = + let default = (Obj.magic () : GObj.style) in + [| default; default; default |] + + (* class date_button: one button for each day in the month *) +class date_button i (calendar : GPack.table) = + let mday = i + 1 in + + object (self) + val widget = GButton.button ~label: (string_of_int mday) ~show: false () + val mday = mday + val mutable show = false + val mutable have_plan = false + + method widget = widget + method focus_on = + date.mday <- mday; + widget#misc#set_style styles.(s_focused) + method focus_off = + widget#misc#set_style styles.(if have_plan then s_planned else s_normal) + method set_plan = + have_plan <- true; + widget#misc#set_style styles.(s_planned) + method unset_plan = + have_plan <- false; + widget#misc#set_style styles.(s_normal) + + method show wday0 = + if not show then + let top = (mday + wday0) / 7 + 1 + and left = (mday + wday0) mod 7 in + calendar#attach ~left ~top ~expand:`BOTH widget#coerce; + widget#misc#show (); + show <- true + + method hide = + if show then + (widget#misc#hide (); + calendar#remove widget#coerce; + show <- false) + end + +let update_calendar (calendar : GPack.table) (buttons : date_button array) = + let now = Unix.localtime (Unix.gettimeofday ()) in + let _, first = Unix.mktime { now with + Unix.tm_mday = 1; + Unix.tm_mon = date.mon; + Unix.tm_year = date.year - 1900 } in + + (* wday0: day of the week of the zero'th day in the month *) + let wday0 = (first.Unix.tm_wday - 1 + 7) mod 7 in + + let ndays = + if date.mon = 1 & leap date.year then mdays_in_month.(date.mon) + 1 + else mdays_in_month.(date.mon) in + + Array.iter ~f: (fun button -> button#hide) + buttons; + + for i = 0 to ndays - 1 do buttons.(i)#show wday0 done + +let create_GUI () = + + (* views part *) + + let win = + GWindow.window ~title: "Camlendar" ~show: true + ~allow_shrink: false ~allow_grow: false () in + win#event#connect#delete + ~callback: (fun _ -> GMain.Main.quit (); exit 0; false); + + let style = win#misc#style#copy in + styles.(s_normal) <- style; + + let style = style#copy in + style#set_bg [`NORMAL, `NAME "light green"; + `PRELIGHT, `NAME "light green"]; + styles.(s_focused) <- style; + + styles.(s_focused) <- style; + let style = style#copy in + style#set_bg [`NORMAL, `NAME "sky blue"; + `PRELIGHT, `NAME "sky blue"]; + styles.(s_planned) <- style; + + let vbox = GPack.vbox ~packing: win#add () in + let packing = vbox#add in + let toolbar = GButton.toolbar ~style: `TEXT ~packing () in + + let prev = + toolbar#insert_button ~text: "Prev" ~tooltip: "Show previous month" () in + let next = + toolbar#insert_button ~text: "Next" ~tooltip: "Show next month" () in + + let calendar = + GPack.table ~homogeneous: true ~rows: 7 ~columns: 7 + ~border_width: 10 ~row_spacings: 2 ~col_spacings: 2 ~packing () in + + Array.iteri + ~f: (fun i wday -> + ignore (GButton.button ~label: wday + ~packing:(calendar#attach ~top: 0 ~left: i ~expand:`BOTH) ())) + wday_name; + + let buttons = + Array.init 31 ~f: (fun i -> new date_button i calendar) in + + let date_view = GMisc.label ~justify: `CENTER ~packing () in + + let text = GEdit.text ~editable: true ~width: 70 ~height: 50 ~packing () in + + (* Controls part *) + + let save_text () = + let data = text#get_chars ~start: 0 ~stop: text#length in + let key = (date.year, date.mon, date.mday) in + Hashtbl.remove schedule key; + if data <> "" then + (Hashtbl.add schedule ~key ~data; + buttons.(date.mday - 1)#set_plan) + else buttons.(date.mday - 1)#unset_plan in + + let restore_text () = + text#delete_text ~start: 0 ~stop: text#length; + try + text#insert_text ~pos: 0 + (Hashtbl.find schedule (date.year, date.mon, date.mday)); + () + with Not_found -> () in + + let update_date_view () = + date_view#set_text (sprintf "%d %s, %d\n" + date.mday mon_name.(date.mon) date.year) in + + let update_view () = + update_calendar calendar buttons; + update_date_view (); + Array.iteri ~f: (fun i button -> + (try + Hashtbl.find schedule (date.year, date.mon, i + 1); + button#set_plan + with Not_found -> button#unset_plan); + button#focus_off) buttons; + win#set_title (sprintf "Camlendar: %s, %d" + mon_name.(date.mon) date.year) in + + prev#connect#clicked + ~callback: (fun () -> + save_text (); + previous_month (); + + update_view (); + restore_text (); + buttons.(0)#focus_on); + + next#connect#clicked + ~callback: (fun () -> + save_text (); + next_month (); + + update_view (); + restore_text (); + buttons.(0)#focus_on); + + Array.iteri + ~f: (fun i button -> + button#widget#connect#clicked + ~callback: (fun () -> + save_text (); + buttons.(date.mday - 1)#focus_off; + + button#focus_on; + restore_text (); + update_date_view ()); + ()) + buttons; + + update_view (); + buttons.(0)#focus_on;; + +GMain.Main.init (); +print_endline (GtkMain.Main.set_locale ()); +flush stdout; +create_GUI (); +GMain.Main.main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/drawing.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/drawing.ml new file mode 100644 index 000000000..a4623bae0 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/drawing.ml @@ -0,0 +1,19 @@ +(* $Id$ *) + +open GMain + +let window = GWindow.window ~show:true () + +let w = window#misc#window +let drawing = new GDraw.drawable w + +let redraw _ = + drawing#polygon ~filled:true + [ 10,100; 35,35; 100,10; 165,35; 190,100; + 165,165; 100,190; 35,165; 10,100 ]; + false + +let _ = + window#connect#destroy ~callback:Main.quit; + window#event#connect#after#configure ~callback:redraw; + Main.main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/editor.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/editor.ml new file mode 100644 index 000000000..5e3da80cd --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/editor.ml @@ -0,0 +1,101 @@ +(* $Id$ *) + +open GMain + +let file_dialog ~title ~callback ?filename () = + let sel = + GWindow.file_selection ~title ~modal:true ?filename () in + sel#cancel_button#connect#clicked ~callback:sel#destroy; + sel#ok_button#connect#clicked ~callback: + begin fun () -> + let name = sel#get_filename in + sel#destroy (); + callback name + end; + sel#show () + +class editor ?packing ?show () = object (self) + val text = GEdit.text ~editable:true ?packing ?show () + val mutable filename = None + + method text = text + + method load_file name = + try + let ic = open_in name in + filename <- Some name; + text#freeze (); + text#delete_text ~start:0 ~stop:text#length; + let buf = String.create 1024 and len = ref 0 in + while len := input ic ~buf ~pos:0 ~len:1024; !len > 0 do + if !len = 1024 then text#insert buf + else text#insert (String.sub buf ~pos:0 ~len:!len) + done; + text#set_point 0; + text#thaw (); + close_in ic + with _ -> () + + method open_file () = file_dialog ~title:"Open" ~callback:self#load_file () + + method save_dialog () = + file_dialog ~title:"Save" ?filename + ~callback:(fun file -> self#output ~file) () + + method save_file () = + match filename with + Some file -> self#output ~file + | None -> self#save_dialog () + + method output ~file = + try + if Sys.file_exists file then Sys.rename ~src:file ~dst:(file ^ "~"); + let oc = open_out file in + output_string oc (text#get_chars ~start:0 ~stop:text#length); + close_out oc; + filename <- Some file + with _ -> prerr_endline "Save failed" +end + +let window = GWindow.window ~width:500 ~height:300 ~title:"editor" () +let vbox = GPack.vbox ~packing:window#add () + +let menubar = GMenu.menu_bar ~packing:vbox#pack () +let factory = new GMenu.factory menubar +let accel_group = factory#accel_group +let file_menu = factory#add_submenu "File" +let edit_menu = factory#add_submenu "Edit" + +let hbox = GPack.hbox ~packing:vbox#add () +let editor = new editor ~packing:hbox#add () +let scrollbar = GRange.scrollbar `VERTICAL ~packing:hbox#pack () + +open GdkKeysyms + +let _ = + window#connect#destroy ~callback:Main.quit; + let factory = new GMenu.factory file_menu ~accel_group in + factory#add_item "Open..." ~key:_O ~callback:editor#open_file; + factory#add_item "Save" ~key:_S ~callback:editor#save_file; + factory#add_item "Save as..." ~callback:editor#save_dialog; + factory#add_separator (); + factory#add_item "Quit" ~key:_Q ~callback:window#destroy; + let factory = new GMenu.factory edit_menu ~accel_group in + factory#add_item "Copy" ~key:_C ~callback:editor#text#copy_clipboard; + factory#add_item "Cut" ~key:_X ~callback:editor#text#cut_clipboard; + factory#add_item "Paste" ~key:_V ~callback:editor#text#paste_clipboard; + factory#add_separator (); + factory#add_check_item "Word wrap" ~active:false + ~callback:editor#text#set_word_wrap; + factory#add_check_item "Read only" ~active:false + ~callback:(fun b -> editor#text#set_editable (not b)); + window#add_accel_group accel_group; + editor#text#event#connect#button_press + ~callback:(fun ev -> + let button = GdkEvent.Button.button ev in + if button = 3 then begin + file_menu#popup ~button ~time:(GdkEvent.Button.time ev); true + end else false); + editor#text#set_vadjustment scrollbar#adjustment; + window#show (); + Main.main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/entry.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/entry.ml new file mode 100644 index 000000000..30f3c3dd8 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/entry.ml @@ -0,0 +1,48 @@ +(* $Id$ *) + +open Printf +open GMain + +let enter_callback entry = + printf "Entry contents: %s\n" entry#text; + flush stdout + +let entry_toggle_editable button entry = + entry#set_editable button#active + +let entry_toggle_visibility button entry = + entry#set_visibility button#active + +let main () = + + let window = GWindow.window ~title: "GTK Entry" ~width: 200 ~height: 100 () in + window#connect#destroy ~callback:Main.quit; + + let vbox = GPack.vbox ~packing: window#add () in + + let entry = GEdit.entry ~max_length: 50 ~packing: vbox#add () in + entry#connect#activate ~callback:(fun () -> enter_callback entry); + entry#set_text "Hello"; + entry#append_text " world"; + entry#select_region ~start:0 ~stop:entry#text_length; + + let hbox = GPack.hbox ~packing: vbox#add () in + + let check = GButton.check_button ~label: "Editable" ~active: true + ~packing: hbox#add () in + check#connect#toggled ~callback:(fun () -> entry_toggle_editable check entry); + + let check = + GButton.check_button ~label:"Visible" ~active:true ~packing:hbox#add () in + check#connect#toggled + ~callback:(fun () -> entry_toggle_visibility check entry); + + let button = GButton.button ~label: "Close" ~packing: vbox#add () in + button#connect#clicked ~callback:window#destroy; + button#grab_default (); + + window#show (); + + Main.main () + +let _ = main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/events.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/events.ml new file mode 100644 index 000000000..91a9872af --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/events.ml @@ -0,0 +1,25 @@ +(* $Id$ *) + +open GMain + +let _ = + let window = GWindow.window () in + window#connect#destroy ~callback:Main.quit; + + let text = GEdit.text ~editable:true ~packing:window#add () in + text#event#connect#button_press ~callback: + begin fun ev -> + GdkEvent.Button.button ev = 3 && + GdkEvent.get_type ev = `BUTTON_PRESS && + begin + let pos = text#position in + GdkEvent.Button.set_button ev 1; + text#event#send (GdkEvent.coerce ev); + Printf.printf "Position is %d.\n" text#position; + flush stdout; + text#set_position pos; + true + end + end; + window#show (); + Main.main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/fifteen.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/fifteen.ml new file mode 100644 index 000000000..efdf51fc2 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/fifteen.ml @@ -0,0 +1,97 @@ +(* $Id$ *) + +open Gaux +open Gtk +open GObj +open GMain + +class position ~init_x ~init_y ~min_x ~min_y ~max_x ~max_y = object + val mutable x = init_x + val mutable y = init_y + method current = (x, y) + method up () = if y > min_y then y <- y-1 else (); (x, y) + method down () = if y < max_y then y <- y+1 else (); (x, y) + method left () = if x > min_x then x <- x-1 else (); (x, y) + method right () = if x < max_x then x <- x+1 else (); (x, y) +end + +let game_init () = (* generate initial puzzle state *) + let rec game_aux acc rest n_invert = + let len = List.length rest in + if len=0 then + if n_invert mod 2 = 0 then + acc (* to be solvable, n_invert must be even *) + else + (List.hd (List.tl acc))::(List.hd acc)::(List.tl (List.tl acc)) + else begin + let rec extract n xs = + if (n=0) then (List.hd xs, List.tl xs) + else + let (ans, ys) = extract (n-1) (List.tl xs) in + (ans, List.hd xs :: ys) in + let ran = Random.int len in + let (elm, rest1) = extract ran rest in + let rec count p xs = match xs with + [] -> 0 + | y :: ys -> let acc = count p ys in + if p y then 1+acc else acc + in + let new_n_invert = count (fun x -> elm > x) acc in + game_aux (elm :: acc) rest1 (n_invert+new_n_invert) + end in + let rec from n = if n=0 then [] else n :: from (n-1) in + game_aux [] (from 15) 0 + +let _ = Random.init (int_of_float (Sys.time () *. 1000.)) +let window = GWindow.window () +let _ = window#connect#destroy ~callback:GMain.Main.quit + +let tbl = GPack.table ~rows:4 ~columns:4 ~homogeneous:true ~packing:window#add () +let dummy = GMisc.label ~text:"" ~packing:(tbl#attach ~left:3 ~top:3) () +let arr = Array.create_matrix ~dimx:4 ~dimy:4 dummy +let init = game_init () +let _ = + for i = 0 to 15 do + let j = i mod 4 in + let k = i/4 in + let frame = + GBin.frame ~shadow_type:`OUT ~width:32 ~height:32 + ~packing:(tbl#attach ~left:j ~top:k) () in + if i < 15 then + arr.(j).(k) <- + GMisc.label ~text:(string_of_int (List.nth init i)) + ~packing:frame#add () + done +let pos = new position ~init_x:3 ~init_y:3 ~min_x:0 ~min_y:0 ~max_x:3 ~max_y:3 + +open GdkKeysyms + +let _ = + window#event#connect#key_press ~callback: + begin fun ev -> + let (x0, y0) = pos#current in + let wid0 = arr.(x0).(y0) in + let key = GdkEvent.Key.keyval ev in + if key = _q || key = _Escape then (Main.quit (); exit 0) else + let (x1, y1) = + if key = _h || key = _Left then + pos#right () + else if key = _j || key = _Down then + pos#up () + else if key = _k || key = _Up then + pos#down () + else if key = _l || key = _Right then + pos#left () + else (x0, y0) + in + let wid1 = arr.(x1).(y1) in + wid0#set_text (wid1#text); + wid1#set_text ""; + true + end + +let main () = + window#show (); + Main.main () + +let _ = main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/fixed_editor.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/fixed_editor.ml new file mode 100644 index 000000000..1cde124c7 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/fixed_editor.ml @@ -0,0 +1,279 @@ +open Gdk +open Gtk +open GObj +open GMain + +let dnd_source_window () = + let window = GWindow.window ~position:`MOUSE () in + let vbx = GPack.vbox ~border_width:10 ~packing:window#add () + in + let evb = GBin.event_box ~border_width:0 ~packing:vbx#add () in + let frm = GBin.frame ~shadow_type:`OUT ~packing:evb#add () in + let lbl = GMisc.label ~text:"hello" ~packing:frm#add () in + let lbl2 = GMisc.label ~text:"drag from here!" ~packing:vbx#add () in + let targets = [ { target = "STRING"; flags = []; info = 0} ] in + begin + window#show (); + evb#drag#source_set targets ~modi:[`BUTTON1] ~actions:[`COPY]; + evb#drag#connect#data_get ~callback: begin + fun _ data ~info ~time:_ -> + data#set ~typ:data#target ~format:0 ~data:"hello! " + end + end + +let corner_width = 7 +let corner_height = 7 + +type drag_action_type = + GB_DRAG_NONE + | GB_MIDDLE + | GB_TOP + | GB_BOTTOM + | GB_LEFT + | GB_RIGHT + | GB_TOP_LEFT + | GB_TOP_RIGHT + | GB_BOTTOM_LEFT + | GB_BOTTOM_RIGHT + +let get_position_in_widget w ~x ~y ~width ~height = + if (x <= corner_width) then + if (y <= corner_height) then + GB_TOP_LEFT + else if (y >= height-corner_width) then + GB_BOTTOM_LEFT + else GB_LEFT + else if (x >= width-corner_width) then + if (y <= corner_height) then + GB_TOP_RIGHT + else if (y >= height-corner_width) then + GB_BOTTOM_RIGHT + else GB_RIGHT + else if (y <= corner_height) then + GB_TOP + else if (y >= height-corner_width) then + GB_BOTTOM + else GB_MIDDLE + +class drag_info = object + val mutable drag_action = GB_DRAG_NONE + val mutable drag_offset = (0, 0) + val mutable toimen = (0, 0) + val mutable drag_widget = None + method drag_action = drag_action + method drag_offset = drag_offset + method toimen = toimen (* coord. of opposite corner *) + method set_drag_widget (w : GObj.widget) = begin + match drag_widget with + None -> begin + GMain.Grab.add w; + drag_widget <- Some w; + () + end + | Some w -> () + end + method unset_drag_widget () = begin + match drag_widget with + Some w -> begin + GMain.Grab.remove w; + drag_widget <- None; + () + end + | None -> () + end + method set_drag_offset ~x ~y = drag_offset <- (x, y) + method set_drag_action (w : Gdk.window) ~x ~y = + begin + let (x0, y0) = Window.get_position w in + let (width, height) = Window.get_size w in + drag_action <- get_position_in_widget w ~x ~y ~width ~height; + let (x1, y1) = (x0+width, y0+height) in + toimen <- + match drag_action with + GB_TOP_LEFT -> (x1, y1) + | GB_BOTTOM_LEFT -> (x1, y0) + | GB_TOP_RIGHT -> (x0, y1) + | GB_BOTTOM_RIGHT -> (x0, y0) + | GB_TOP -> (x0, y1) + | GB_BOTTOM -> (x0, y0) + | GB_LEFT -> (x1, y0) + | GB_RIGHT -> (x0, y0) + | _ -> (-1, -1) + end + method unset_drag_action () = drag_action <- GB_DRAG_NONE +end + + +let to_grid g x = x - (x mod g) + +let to_grid2 g (x, y) = (to_grid g x, to_grid g y) + +class fix_editor ~width ~height ~packing = + let info = new drag_info in + let fix = GPack.fixed ~width ~height ~packing () in + let _ = fix#misc#realize () in + let fix_window = fix#misc#window in + let fix_drawing = new GDraw.drawable fix_window in + + object (self) + inherit GObj.widget fix#as_widget + val mutable grid = 1 + method set_grid g = + if (grid != g) then begin + let pix = + GDraw.pixmap ~window:fix ~width:g ~height:g ~mask:true () in + let c = fix#misc#style#bg `NORMAL in + pix#set_foreground (`COLOR c); + pix#rectangle ~filled:true ~x:0 ~y:0 ~width:g ~height:g (); + pix#set_foreground `BLACK; + pix#point ~x:0 ~y:0; + Gdk.Window.set_back_pixmap (fix#misc#window) (`PIXMAP pix#pixmap) + end; + grid <- g + + method new_child ~name ~x ~y ~width ~height ~callback = + let evb = GBin.event_box ~border_width:0 ~packing:fix#add () in + let lbl = GMisc.label ~text:name ~width ~height ~packing:evb#add () in + evb#misc#realize (); + evb#misc#set_geometry ~x ~y (); + self#connect_signals ~ebox:evb ~widget:lbl#coerce ~callback; + () + + method private connect_signals + ~ebox:(ebox : GBin.event_box) ~widget:(widget : widget) ~callback:cbfun = + let drawing = new GDraw.drawable (ebox#misc#window) in + let draw_id = ref None in + let exps_id = ref None in + let on_paint _ = + let (width, height) = Window.get_size (ebox#misc#window) in begin + drawing#set_foreground `BLACK; + drawing#rectangle ~filled:true ~x:0 ~y:0 + ~width:corner_width ~height:corner_height (); + drawing#rectangle ~filled:true ~x:(width-corner_width) ~y:0 + ~width:corner_width ~height:corner_height (); + drawing#rectangle ~filled:true + ~x:(width-corner_width) + ~y:(height-corner_height) + ~width:corner_width ~height:corner_height (); + drawing#rectangle ~filled:true + ~x:0 + ~y:(height-corner_height) + ~width:corner_width ~height:corner_height (); + drawing#rectangle ~filled:false + ~x:0 ~y:0 ~width:(width-1) ~height:(height-1) (); + end + in + ebox#event#connect#button_press ~callback: + begin fun ev -> + let bx = int_of_float (GdkEvent.Button.x ev) in + let by = int_of_float (GdkEvent.Button.y ev) in + info#set_drag_action (ebox#misc#window) ~x:bx ~y:by; + info#set_drag_offset ~x:bx ~y:by; + true + end; + ebox#event#connect#motion_notify ~callback: + begin fun ev -> + info#set_drag_widget ebox#coerce; + let action = info#drag_action in + let (mx, my) = fix#misc#pointer in + let (ox, oy) = info#drag_offset in + begin match action with + GB_MIDDLE -> + let (nx, ny) = to_grid2 grid (mx-ox, my-oy) in + ebox#misc#set_geometry ~x:nx ~y:ny (); + if cbfun ~x:nx ~y:ny ~width:(-2) ~height:(-2) then + () + else (* should we undo ? *) () + | GB_DRAG_NONE -> () (* do nothing *) + | GB_TOP_LEFT | GB_BOTTOM_LEFT + | GB_TOP_RIGHT | GB_BOTTOM_RIGHT -> + let (toi_x, toi_y) = info#toimen in + let (mx, my) = to_grid2 grid (mx, my) in + let (lx, rx) = + if mx + let (lx, toi_y) = info#toimen in + let my = to_grid grid my in + let (ty, by) = if my + let (toi_x, ty) = info#toimen in + let mx = to_grid grid mx in + let (lx, rx) = if mx + info#unset_drag_action (); + info#unset_drag_widget (); + true + end; + exps_id := Some (ebox#event#connect#after#expose + ~callback:(fun _ -> on_paint(); false)); + draw_id := Some (ebox#misc#connect#draw ~callback:on_paint); + () + initializer + fix#drag#dest_set ~actions:[`COPY] + [ { target = "STRING"; flags = []; info = 0} ]; + fix#drag#connect#data_received ~callback: begin + fun context ~x ~y data ~info ~time -> + let name = data#data in + let _ = self#new_child ~name ~x ~y ~width:32 ~height:32 + ~callback:(fun ~x ~y ~width ~height -> true) in +(* Printf.printf "%s %d %d\n" (data#data) x y; + flush stdout; *) + context#finish ~success:true ~del:false ~time; + end; + () + end + +(* the following is for test only *) +let window1 () = + let window = GWindow.window () in + let _ = window#connect#destroy ~callback: Main.quit in + let fix = new fix_editor ~width:640 ~height:480 ~packing:window#add in + fix#set_grid 5; + let setter = fix#new_child ~name:"hello" ~x:100 ~y:200 ~width:32 ~height:32 + ~callback:begin fun ~x ~y ~width ~height -> + (* Printf.printf "name=%s, x=%d, y=%d, width=%d, height=%d\n" + "hello" x y width height; + flush stdout; *) + true + end in + window#show (); + () + + + +let main () = + window1 (); + dnd_source_window (); + Main.main () + +let _ = main () + +(* Todo + + change mouse cursor + resize fixed itself + remove_child + (drag and) drop + +*) diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/fixpoint.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/fixpoint.ml new file mode 100644 index 000000000..c33b74d5d --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/fixpoint.ml @@ -0,0 +1,30 @@ +(* $Id$ *) + +open GMain + +let rec fix ~f ~eq x = + let x' = f x in + if eq x x' then x + else fix ~f ~eq x' + +let eq_float x y = abs_float (x -. y) < 1e-13 + +let _ = + let top = GWindow.window () in + top#connect#destroy ~callback:Main.quit; + let vbox = GPack.vbox ~packing: top#add () in + let entry = GEdit.entry ~max_length: 20 ~packing: vbox#add () in + let tips = GData.tooltips () in + tips#set_tip entry#coerce ~text:"Initial value for fix-point"; + let result = + GEdit.entry ~max_length: 20 ~editable: false ~packing: vbox#add () in + + entry#connect#activate ~callback: + begin fun () -> + let x = try float_of_string entry#text with _ -> 0.0 in + entry#set_text (string_of_float (cos x)); + let res = fix ~f:cos ~eq:eq_float x in + result#set_text (string_of_float res) + end; + top#show (); + Main.main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/hello.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/hello.ml new file mode 100644 index 000000000..15ede9a49 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/hello.ml @@ -0,0 +1,18 @@ +(* $Id$ *) + +open GMain + +let window = GWindow.window ~border_width: 10 () + +let button = GButton.button ~label:"Hello World" ~packing: window#add () + +let main () = + window#event#connect#delete + ~callback:(fun _ -> prerr_endline "Delete event occured"; true); + window#connect#destroy ~callback:Main.quit; + button#connect#clicked ~callback:(fun () -> prerr_endline "Hello World"); + button#connect#clicked ~callback:window#destroy; + window#show (); + Main.main () + +let _ = Printexc.print main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/image.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/image.ml new file mode 100644 index 000000000..faf82cf44 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/image.ml @@ -0,0 +1,67 @@ +(* $Id$ *) + +open GMain +open Gdk + +(* load image *) +let buf = String.create (256*256*3) +let ic = open_in_bin "image256x256.rgb" +let _ = + really_input ic ~buf:buf ~pos:0 ~len:(256*256*3); + close_in ic + +let rgb_at x y = + let offset = (y * 256 + x) * 3 in + (int_of_char buf.[offset ], + int_of_char buf.[offset+1], + int_of_char buf.[offset+2]) + +(* let id = Thread.create GtkThread.main () *) + +(* Choose a visual appropriate for RGB *) +let _ = + Gdk.Rgb.init (); + GtkBase.Widget.set_default_visual (Gdk.Rgb.get_visual ()); + GtkBase.Widget.set_default_colormap (Gdk.Rgb.get_cmap ()) + +(* We need show: true because of the need of visual *) +let window = GWindow.window ~show:true ~width: 256 ~height: 256 () + +let visual = window#misc#visual + +let color_create = Truecolor.color_creator visual + +let w = window#misc#window +let drawing = new GDraw.drawable w + +let _ = + window#connect#destroy ~callback:Main.quit; + + let image = + Image.create ~kind: `FASTEST ~visual: visual ~width: 256 ~height: 256 + in + + let draw () = + for x = 0 to 255 do + for y = 0 to 255 do + let r,g,b = rgb_at x y in + Image.put_pixel image ~x: x ~y: y + ~pixel: (color_create ~red: (r * 256) ~green: (g * 256) ~blue: (b * 256)) + done + done + in + + let display () = + drawing#image image ~xsrc:0 ~ysrc:0 ~xdest:0 ~ydest:0 ~width:256 ~height:256 + in + + draw (); + + window#event#connect#after#expose ~callback: + begin fun _ -> + display (); false + end; + (* Thread.join id *) + + window#show (); + Main.main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/image256x256.rgb b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/image256x256.rgb new file mode 100644 index 000000000..25d499594 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/image256x256.rgb @@ -0,0 +1,19 @@ +”·â•ºÝ›±Ï“­ÐŸÒŸ¤ÃŸ¦Î¤¦Ûª¤ÎªªÚ¯ž×¤•Ð¡™Ô±¬â­©Þ®§çž®Ðš¶É”¸Ë¡¶¼¥®Å¢³Ó ´Îª½Æ¨¼Ó¬·Ó¶´ÏµÀÆ´°¼¬¾À·³ÄÄö¾½ÂÇÀ¼¿½·ÆĹÑÆÁÂÏ·ÃÌÅÍÉÙ¼ÍÓ¿ÊÁÆÏÇÄãÍÕßÏØÕÍÎÜÌÇãÑÑâÙÔ×ÚÈâÈÔÜÄÌØÈÒÒÇÍ×ÃÅÛÁÍáÇËàÊËêËÚð½×ïÅáíËÞõ¼ñø¿âã·Úæ¾ÜÙÈáâÅÜÙÃÖ×®Ö̳ÞȱØÉ·ÍÔ²ÑØ«ÑÑ¡Î͎ÒܗÔ،à͑ÖʏϼƒÉ¼ˆÎ¼ˆÝÁÔËzãÇwØɀÚÆ{âÎçӉÝׅáׂÖÜÓފÙԓØ،Ó؂Îá†ÎÒ|ÛàsÓÛzÞ×ráÙyàÔs×Üi×ØgäÆkåÑoÜÏ_áÍdàÈR߸C׸?Ö´GÙ°WÚ°Kç¸EÚ·YÜÊ]ÞÂOÕ¿;Ù½@ÞÃHâË9íÇ<éË@ðÇ8éÉAè´@æ·AòÌ9ÝÄ7é´@ܲ?Þ½Eä¯CÙ²RάLЯPÒ¡RЩ]̨RÀ¿UÀ²XÉ©FÌ´JϱPŹFËÁJÄ¿FÆÄQȼDÒ°OÔ­DدHÒ³PѵPɶYÐÄ^Ë¿WÙ¬PΞ[ѧWتOˬWͨY͘ZΝdØ£ZÌ·XÁ°EŹPε\Ï®N½»T½³Y´ÃY¶¸N¹¶D°³S±¨Y«¨Mª¬U¦¬[§®@ª®T ¯M¥¢M£žZ œG¬‘E£‘K¥Y¢ŒK·[¨…S¦—EžN§`¡–R˜XŸƒ[‘†Qš‚Sš‘R™‡U§€W©€Tœ‡J¢~Qœ~C–tO”iL•rS”tN©lPªoJ¢zT¯pB¥qIž[M lC«gC¤lD±cC³YTÁSI¸OQ´IBÀIE»ZK»OE¸QH°WU¬TK«QG¹VK®TGºV?¬MD¶Z[¾MGÂUK»ZK²QO½NX¸JZÁHP³KV½J[¼ESÀF]Ä@WÆ;VÆ;\·àš´Ù—«Ò”¬Õ™ Î£¥Ê¥±Ë¡­Ø¤«Ñª«Ù¬¤Ò¦›Ñ¯šÝ¬ ×«¦×¦§Û›«Êž¸Å—®Æ ²À§¾Èª¹Î±¾ÅªÀÆ£Æ˨Á͸¹Ç½¼½¾·¸®²¼½µ»½Â²¼È³ÄÄÀÍ·ÂÌ»ÀǽÀÂË¿ÁÀÃÁÃÑÌÐÍÅÐÉÈÞËËÞÀÓßËÐØÌÇäοáÔÄÕÖÒÚÑÍÐÎÑÓËËÑËÐÑÒÆÖÇÄØËÓÙÄÑÞÊÙèÉÛò½á÷ÃÛîÄãö½ëõ¶èé´ÚáÁåݸáá¾ÜØ»ÞׯÓ˳ÒƸÊɳÏÑ°ÍÈ£Ç͝Æ֙È׏ÎƖÙŌÔ•ÌŏÐʖϾÌȊÚσäÉ~ÝÆxÝÆzè׃ãÖ~ßà…Ù܁Ù߈ÑیÑˎÎבÏׅÎÕxÓØyÙÏÙÔzÞØnßÚmÔânÙØmÙÑfèÓpÚÕmÝÉjèÂ_ã¾Oç·Oä¹IزUÓ¯VÙºQâ»Kß½MÖÈVÓÁP×À@àÁ>ä¾=ðÀ;ñÌEîÒ8íÌ4êË@ïºDêÀCëÄ4íÄ9ÝÀ8ܹ?æ´BÝ«RݧPѲIË®SØ®QÔ¤\ϵQõUϯLÏ«PβDĵDƶ?ηHÒ±RɺKDZRÏ·K̼GЯHÒ¶HÌ®V׿\ÖÀRÛ±XѨUП[Æ OÀ¤YɬTҝS֟SÛ§PÕ®ZÔ´WƱIʺLβZÉ»bÅ´Z»¸^±¹U¹ªHº¬D±ªAª¨I±­U°®Q­©Q œG¨¡Q¦¤J¤—G˜N£‹O¦‹Q£ŽO ŠP°„W®ŒQ¬™Y¦•O¨’N¦”\š–Z›”P R™€SœY›ƒU¢€X¥‡R›zL zW¤x\¡PœqYšmR›oP›rS©oN©lIŸvG¦oLŸaW™]T¨fL©jD³n=¶bD²\C»^I´OR½HJ¸HH¿RFÆJG¼EV²SI«XH©TL´LO¾MBºU9ÀU@·VO¿MAÄUAÃVI·ML¼LV³H\³GZ·PTÂKZ¼IUÈMTÈ@Y½ARº9V“°Ù¤ºÙ‘«Õ‹©×™ÐŸ¤ÍŸ¦Ñ®´Õ²¦Î¨¤Ð´¤Ô£¥Ï«£Ø©«Ø±¢Û¯¨Ð¬¹Ô¢·É¢»Å«³Ã›ºÁ¡·Ð¦ÂÌ©ÄĨ½À©ÉÏ°Èɶ»¸³¼¸½º³³¼°¶Ã²¼Â¸¸Î»ËÇÿĺÏÅÄÃÎÁÂÀËÈÇÐÒÃÈÌÌÄÔ×¾ÇÑÀÓÛÌÊ×ÔÃÏÑ¿ÙÑÀàÓÊÙÎ×ÒÊÔÖÎÍÚÎÑÔÜÈÐÉÁÓÓÔÕÔ×èÈàæÍáêÉßô»ÚóÂÞî¶êõµçñ¸åëÅÚé´àáÀáݳÛÛ©äÙ«ÒÇ´Ôη×ĹÉ΢ÐŞÓєØΓÏѕàЌÔŠÒˆÓƂÔÀ‡ÙĂßÈzÞÉ|äÌnÛØwíàuèÚuÕêzÜâ†ß҆×уÑבÙӉÏΊÓ͇ÓփÜÔsåڀßÏzÚÞjàÐqæâ}êÛlèÏuéÊqÝÈ[áÅ^àÊLÞÄIÞÂLÕ¿Tà­RÔ»RæÉXØ¿X×ÄIãÀFåÃJåÁJíÈIíËD÷ÉHõÈ:ëÕ9ôÂ9ö¿Fä½7îÇ7á·2áÆ?ç¾FæªKàªWÞ TÒ­VÒ­LΞ]֝^Ò¨Pö^Á§O̳T϶KÏ´MʼBѼIÖ»Kʱ?̯JÕ¯?Ë­FÚ¨Kׯ?Ú¦BÜ´NݲSß°K΢IÏ¥NͪNÆ®OÒ¯JÕ¦LÙ¨IÍ­NѱRŶT·RÄ´O¾º^ǺSÁ²Zµ»Q¯²O·©@¿¡G¼¯9°¤?¨ª<²­F¯¥A² E«–B¢ E®•@¨šQ¨‰R‹N©•G¡‘K¥‡Q®’P°ŠD­N¨K¥X™ŒU —N›“Y—Š^ ‰`£_ Xœ†\ŸYœ‡Z£ƒM“zV™}UœwZ˜iM’jR¢lU dJ qV¡kP£]L“W_£`W iLª\M´YT³\O´PQ²RSÂJJ¹DEÂGD·MT·EI²FU¦[O¤GR­BN±MHºJCºZ<°_CÄ]<ÊNBÇKEÁTK¿O[¶N\ÃLMÂGOÃGPÃDWÇJLË:YÄ8Pº4\˜²Þ³Ý™²Ô’¢ÐšªÙ¡ Ûª¯Ý­±Øµ©Ì³£Ð·«Ñ®¦Ó¶¥Ù´©Ô±ºÈ±¹Ë®¸É±¶Å¨¯Í¦¹Ë¶ÏžÁÅ¡ºÆ¢»Ä¬ÂħÇÆ«Ì»¸¿¶½»¼½¾³º½³´Â³µÌ¹»ÈµÂÑÀ¿Ì¹ÍÀ·ÎĹϼÁÓÅÍ×ÅÍÔËÌÒÍÃÍÈÄËÃÔÂÌÖÄËÖÅÛ×ÌÙÏÎÝÑÐÙÌÉÑÏÍÚÛÁ××ÍÐËÈÒÍÍ×ÔÛçÍÖðÂÝéÃáîÁáñ·Úì·áëµìè¾ìè½ãæ¸ãÛ´ÞÔµáÛ¯ÝÔªÜϯØȵÖÆ°ÎÀ´ÒȨá̦ÞĒÝ΋×ʋÏϒÐˊÖŅÕÇÐÒsØÒpæØqä×tåÑtá×vßäuÙâuÕÚnßÕwÒځÔцÒ̋à̀äׂÜрåЁàÓwæÍ{âÕvâÝ|ìÚ{ïßyéÛoÞÜbâÔYêË\àÅWá¿TÛÀUݶSÞ»NÜÃHÞÆS×ÉVÚÁIáÂPê¹EåÆ@ëÆHõÈN÷ÅBíËHòÐCêÓ?íÆCéÊ=å¼9æ¹5ã»Bæ°IÞ®NÔ«\Ó¤YÚ \Ó§UÌ®YΣQÒ¡^ɪ]ά_ëXŲPÉ·Jз@кDÖ³HÒ¸DÌ­>̬AÍ®:׫AÓ­7ݦ;ÚµGÙ³JÜ®RØ­IϬRÇ­RÒ«JÕ²HÒ²SÔ¨NЫKÖ«MѸWÄ·P¼ÃV¼ÄY·ÇO¾¾PĽN¸µF³­<³¡?­©:·¦9·¡:±ž=µ˜Aº¢7µ“6¯’9´“B§ŠH¢ŠG ŒE§‡> ’E¦”Iª”@¦’=¬C¡”Qž”X’ŒW”“W•T™„_¤Ž]¤‘b£‹dž‹W£ˆO ‰OžŠS“zP–ƒP“zQ”sS—jJsS“lV›hWœ\Y—b\›WY•SY]R¨RT¯RU®PT´MM¶KN½DJ½GMÄFL¶MN®HF¥KOªMU¯DG§EI¤GG®NCµMI·Y=´S@¾QD¼QNÉTUÅNZÅSUÀTXÀCJÀ>IÉCPÊIYÊAQÁ4\¿.Xž·Û ¶à’³à—ªÎ¡¤Ö¥¦Ó¢²Ô±¦Ó¯©Õ©°Í¢­Ô©®Õ¥£Ó§¦Õ«±Ì¯¸Ã¯»Å°ÀǬ»Ä¥®¿¦¶½¬À¾¥´É¨º½¡½Â¬Éƶ¾½ÄË®¼º­ºÊ¶»Ã´µ¿²¾¸°¹Æ·¿Ê¬¼Ë¶ÄȮøÓü˾ÇÔÏÌÜÅÅÊÊÂÃÃÆÇÐÊÏÆÒËËÒÊÏØÂØÌËÖÒÐÛÒÀÛËÊÐÐÂÈÕÎÚÑÎÞÃÏÛÌÞâÌÏçÊÙèËØñ¿ãï®ãò³àë½äá¿Þí¿ßß·äÙ±ßÙµéβÝÒ³ê̲ÞÄ­ÒÍ­Ñ˟ÙÍ¥ØƟÙĒÞ•ÐҋÜӈÍАÖƉÑÊ}ÍÖÜàqÕßtÞÙsèà|àä|åÙtÝè}àár×âvÑÚ}Ú×~ÓԃàցÞÓ}ÜàˆÔÖ}â×qá×oßÓpíâ{èãzêáwïÛlçÓaÜÖaÚÓWÒÊdÞÃ`Ó¾_áÅRãºKÖ·Kæ·UÛµGéÇGæ´Hã¹Iä¿CãÂLîÃIéÊEçÉMíÑCéÂ@èÈJí½AÝÅDâÁ<ç±JåºBÚ©DÖ²OÚ­PÞ¬[Þ«OϦSɱQÌ°Z¿¨gÀ§UDzYDzRɲKʹPÑ¿?×·?ر7ϸ?Á¡@Í¥?Í«A՞@Ôª4Õ­Iß­HÖ·CÌ´LͦQÆ®[ȪVƪFМGʧIӞAͨHõM¿¸KÀ¶NɳMŶQ»ÄBÁ·?²µB¬­=ª¨<² ;µ£2°¤<¢:¼¥=¼A³œ;§—F°C³–N ‡L©•Dž‹E¡ŠF«–;´‘5©’G¦—O¥˜K—U””W—“R’`—ƒ[˜_ž‘b“]š™Mœ†WŸŠT‘ˆU‘yWtMyP¡rKœmN£aR¡^Q–fV `YšZW”Z]¤]Q©cL¨TU´QL·MW°QT³OF²OS³UK¿OX¼ET°JU¸HZ®JW´FY¬NÁ=FÍ:TÁBTÌ;ZÁ6[Ê4Y‘Âט¼Þ±ä˜¦Û—«ßš°Ö¢´Õ£©Û¡µÙ¢µÒ£´Ï¥¨Ë«³Ñ¡°Ó¬¸Ó·¼Ç¯·Ä¡¼Ì›²È´Ä©±¿¨¿¹°·º©³Æ³¼º«Æµ»Å­Ãȱ»Ê«¼Æ«½ºµ³¸¶¼Á²´½³Ä®ȿ¬¾Ê±ÄÆ·Áº¹É¾ÌÖÊÒ×ÐÆËØ¿ÉÎÄØÐÅÕÅÎÕÆØÌÌÑÍÐØÆÙÏÄÞÆÇÕÂÑÌÅÐÊÕÌ×ÎÃÜÀÔß¾ÔàÌÙëÏÒíÉÜî¹Úã±âç¸Ýíµåä´àã¸êá¬èß«ïÖªéÌ«àѧçÏ©äʨÙƛÚĘçË¡àÏ àɑãΒÙ͔ÓԛÏˑÏэÓ҃ÒáƒÕÞÛæ‡ÞÜØá€ÚázÞßpßìv×ëwÙ݅Üá‡ÓÕ~Õ׀ÒÕ{ÔۈÖç‡ÜîyÖç{åé‚æàxàäyàÞyçãyïÚqìÕnßÔlÔÈdѾcÕ¶hÔ»^Û»XÖ»SÙ¾XܱLä²Jë¿Lì´Eå¹HàºMâÌMäËQçÏIñÏPìÑHäÄMìÃAæÁ>ãÂAàÄMà¸Hå­LÙ­?à´RÕ¯XÓ®UÙ¬VÛ¦cÍ®_˹`Áµc̳`ѨKʪDиIÔ·DǵIʳIж:³C¢JÅ¡RÒ£IÕ¦Eʨ=ʬLÖ¯QѪCÆ®FÆ­DѧRÄ¥IğLęKš<̧CÆ­;êAɯ9ʨ7ƲF¾·MþEÀº?¶µ4º°3±§1±Ÿ7±œ.·‘/—2´Ÿ<¶:±š=°ŒF¯•J´•D¤š:¤<¦“?£Š?¦ˆ3®…6µ…Eª‘I©˜GŽN–”X™ŒU•„P›ˆZ“Y‘ƒSKŠ•OŽ”F›M–„L‘zY’yZyUžoWŸeW¤ZRŸ]MšiF”dI™TR™Q[›RZ¦XP®^LªXM§[TµTJ±MS²UR¯\XµYW±Mb½H\¸O^µMW°?\­?R´CM¹EG¸DD¸OH¾QW´JW±PO·KWÆHNÈLNÌHH¾FSÇJWÇ@OÁ1`¼/`Â6UÌ,P’Æá•È࠿ך¸Ù¡¸Ú™´ä¥²Ï¡©Ú©³Î¢¼Ò›³Íž¨Ï¡¯Ð¬´Ï¦½Ç®À˧ºÊ°¿£µ¹ µ¼¼½©¾½ª»Å³¯»°Æ²¬À¸À¿©»¿´Ã¿®¿À©¯¼±ªµ©³Ä¤¹Ã©¶»ªÈĢ¹¯¿½§Ì¿²Æ½¼ÖÉÊÜÐÅÏÓÆÎϹÏÅÃÞÎÃËÌÈÉÍÎÇÌÉÅÇÏÉÈÓÓÒ¿ÇØÌÒÐÍÒØÍÇÏÄÔÙÇÚÖÉÛãÀÙâÀÕÙÂØà½×è¾ßë½êݵÝÒ¹äÛ´ëà®éÓªäÄ°ìɱèȲáѧéÁ™àÈ£îǘå֞æ֎æדÓҐÐӓÉыÔˋÒ؏ä݊çڅÝׂêçƒçâyëç{äéäæuäã|ÙۂÞâ~ÍÞz×ã‰ÑáwÐ݄Õå}ÒæwÕçsÛêuãåxâàpÜæsÞÖnîÕjç×màÎfáÑ_˾cÔ¼eÙ·^ܳ`Ô³Qã¶QܶNæµTåÁRè½Uõ½FëÁJêÒLðÉKòÖTòÌAáËLãÈDèÄJéÆHãÄ@àÇKÞ´Kè²Hâ´CÖªIÝ°PصTß­V͵ZÉ©dͶ`Ĺ`̳^˦SħTβN³NÀ©JÊ®D̸EÁ¢HƟ>É«>É«Lϧ@¾ @ЫAÖ«DÔ·HϸOÊ­@Ò£KÍ¡D˨Eǖ9ě7Ǫ?­8Á¥>Dz1ǵ:Á´;º¼Cº¹>Á²@²¾,µµ5·´'·¤/Ý4¼›8 /µ—,´˜3°œA¶ˆEº”K¹š;µ—E¦”9¨‰B¥‡;¤ƒ>²„7¨;¯‘Qª‰E™P¥’W£ŠV™ƒT™‹V‡V”|Yˆ‘X‡ŽW‘Y’‰L—Y˜wbšt\’uS•jW§mW•eT¢dSXU™cA‘aF›SH¥VV¨JM£LM³WN¯XNµK\µJKªRU¨WN»_T±]O¸LY·GVµSK½JP±HD·AH¼?E·@H¯MV°JO»TR¿JYºFN·GYËKVÇ?WÂ:ZÇFNÊ@\Ì>ZÍ/ZÉ4TÑ4QÄސÂ㐻鞿ã«ÄÚ©¾à©¬Ö§ªÍ§¦Ô ²Öž©Ó£°Ó¤­Êª³Â­®Â¬´Ã¡µÄ¤±¶¨«¼©³»«¾Å¥ÁÀ©Å´­»´®½¹¸È­·Å§ºÄª±Ì¢²Êž´¼š²½§³Ä¡°¼¡ºÃŸÁ¾§¿½­Ç¿¦Æ½®Ð¾¸ÍdzÙʾÏÑÀÕϸÐËÁÖÉÈÙÒÅÎÉÉÑÈÕÒÃÐËÍÌÔÎÉÙÑËÒÏÏÍÑÅËÓÈÑÛÀØÜÃÞã¸Ùà½àØÀÚÖÁáâ¶ßÞºáÓ½éÒºìÓ±ìÑ®èÔ®ìǦöÊ®ðÒ®õΩíÉ¡öâð͒ö˙îיãϙØҎÎːÓՐÜؙÛݓìçíáçè‡ìâ€ðå|ôäƒèáéè~àézÝßyÕØ}Îà‡Çë‚Íå€Ïæ|Øëzæå}åàoâèqìãsíápáßoéÜgêÍiâËfãÄZßÏUÖÊ_ÜÂbÔ¿]Û½\ÞºXå»ZßÁRê·[ð·Xí¼Q÷¾QóÉNîÍWêÈTôÐQåÚAçÓBåÑDðÌLïÏLíÍHç¿?êÁDݹ<à¯?å²<æ°Dè·NÝ·Yà¶YÓ§`ʲcƬa̵R­QůLƲGÍ©DÊ©F¼²K»©D½¨9»¢;º­D§CÈ¥DÀ¨@Å¥AϱFг>Ò´FÑ·BÈ©Cë>Ǥ5ʦ8Ğ<º¦@¼®7©5Ç­7õ,¿®0¸¸5¸°6º¯.²¹-¶µ/¼°+¹ª/Ŝ,¾Ÿ'Û2¿ 6¸˜2°˜A·B¼•=¹’>¬”5¯Š;«6¨‹B©…Bµ†A´ŒE´H°G¨šR¢™R¥‘N¡HŸ‰N™‚R†Z„ŠSˆW•b™[Ÿ‘U™…Y”{\“zWŸnNhTi[•_T’`G—\I›]G™VF›SG§MR¬P\³K[¯EX¬I\¯DV¦HS°M`µZ[½RM³[J­NPµINµLD¾AF²@E³BOµ=O¬>Z¨L^²L[±DX½JQºNTÃHUÁ@P¼>ZÃE`ÆC`È=^Ï4ZÊ)`Î+[¹å”ÃВ¸Øž´â™¹ß«·Ð§­Í­¬Õ©­Íœ®Î™·Ú¦¬Ï«Î£¯Í¡²É´µÄ¬­º©¸½¥¬Ä©»µ ¿Àž¶²§²® »´±Ã±±Ä³³¼¦¼½«´Ä¤²Á™¨½¤«¿¦¨Á­²Á¡¿Ä£¼¾£º³¶Î·®Å»»Ò¾ÂÕ»»ÚÉÀÐȾÝЭÓÌÀÛÁÈÑÆ»ËÀÈÕÊÊÍпÊп×ÙÁÑÏÎÈ×ÎÒÊÉÁÙÄÅÙ¸Ñ߸Ëå½Ûà¸Ýá¼ÔàÈÕÖµÔî¶àÙµëÉ»äÍ·ïÌ«åÏ°îÍ«òѦ÷θëË®ñɟðƙ÷À˜éϙç܌ÞЎÖҍÞ͈ÑՇȪÞ܅ÞҋêހàÚwæè{äê†ñî†ææ|ÞلÛÙxåæˆÜ܂Íæ…×é‡Çâ†Ùè{Óò{Þéx×ãvÞâjîáiéånÙÛiÛØeßØoæËkßÊ]ÖÒ[ÚÅgÛÈcѶW×¼WÕ»`ã¶Ué¾Rì¾NéµTì¾UðÁMúÇ^ïÐ`öÆSïÑMìÆBóËKóÍ@îÎCôÉEë¿Gç¾Må¸EÞÃ@ܳ>ä°Háµ<Ù®EÙº\Ó±`Ô­YÔ«^È¥eÉ¡aÁ SƦQ»·C¬HǞG½«G°£<·¡D¿?¾¤9­C¾¬H»¤E»­<ŪJŬ>ų=Ê©KȬC¯A¸¢2¾ <Ǚ6¾¥5Ŷ5Á±:Ť8˧1È­2½¤:¯§9´«0³´*÷$¸¸&¹¤.š)É£1ʙ8»Ÿ=·–<¿œD¹šH­‹@ªŽC«‚>¯„H¢‚9«Š>«‰I¯}F®‘H³ŽL¤–F­›UšP¢‹N’U™„HR‹…\’Q†O“Y“‡\š€e“dœ}WœpUnb¨t_›o_œZX—[[˜`P›UI™PI¤KQ¦HZ¦U_¬Dd¨JY¦IS¦U`£UU¦W^©S[³YV°XH¯\F¨HJ¯CC¶@@°:H·?L±@PµJS­EO¯KYµH_³ATÄB]ºLZÀDZ³>VÄ:ZÀB\Ð1UÇ3SÑ(SÏ2Y¯Ò•¹Í’·ÝŸµÞ¥±àŸ¯Ñ¢¯Ø£´Ö¨«Øœ«Ô¦±Ð¥­Ñ¡³É¦»Ê¨·Ñ«´È¦½Á¡´È›²·¤¼·Ÿ·»¦°³¡½µ¤º¨«¶²¨²­¶»«½Ä¯½¾ž·¹ž³Áª§º¤©¼±µ¼²¶Ä¯²º­Á¾ºË°»Ï²ÈÒ½ÄÌǺӿ³ÛÁ«ÓɲÊǯҺ¼Ô¼ÊÇ»Ñ̳ØмÒÒÉÊÔÄÅÏËÎÔÈÌØÆÈÒºÏÔ¶Ìã»Èß®Ñ×®Ëá¹ÐÚ¾Ûç¶Øí¾ÛÚ·ßаÜÖ©èÕ­äͲäÒ§äØ©ôÔ´ïÕ¤ñÊ¥íÌ¢ðĝåēå҉âВâĉàńàׁâÖw×É}ãÊzâÖwäÜ|àÝzá߃âì}åÝ|äÚß߆ÛâŠÑà~Ðá{Îè…Ñð†àôˆÝê„ÞïzÚãréäxæäpÞäsâÓqáÔpÛÙjÝÞ\ÖÓ^ÐÍdÎË]ËÃ`×½WѵSؽ`á²]ïµ[ï­Xð²Mý·MøºOó½YðÁaðÉYãÌDçÔHñËBðÎCïÎHäÍKê»Páµ@æ¼=è·7ã½=Þ¸Dä¬CÙ­QÒ¯Uί^×¹_Ô³l˦hΪ`Ǥ^¸©O·®L¹¨H· N¸ C¯©C¶ H¾¡?´§Bº«E¹®B¼£B¿±DůE»°F·¤>³­<½¦IÀ®9·¦7¹«=Â¥A¸±7¿¬9½¤.Á«1¿ª8Ħ-½§6µ¨6º£2À¨5ʪ$ð"ɨ+¾§5»ž2Ő6͖2Ę=¸–9³’>¨‘5§‹;¦†E£‚D ‹F¦…?¯~C³…C±…N¨O¬•Z¥—S“Y‘•V—ƒS”~GŽT—ŒX—’V•–QŒ†[„[Žz[‡wa—pbžtaq`¡wa¨wfŸf^¦bW£gQ™V\šS[œQ^®SX¬Qe«Id©K_žS[¥][°ZW©a]¬Z[¬^U·XQ°ZF¦UE­HI¤FB¥=E²BL³;S²DL¹DK³LS±MX·BZ½FQ¿DT»4X¹5Rº?[Ç9`É.fÁ0\È-^É*Z–¼Í•·Ô¦ªÕ¡­Ù›¦Ó¡±Ë¤±ÓŸ²Ù£°Ñ”±ËŸ±Ïœ³¿£±Æ§¼Í¬³Ç¯ÂË­¾Ð§ÂÕ£³Ë£½·¦¹´¨±· µ±£¾³¥¼¥º¤®µ¤²·¤·Á¶¾©¶º§§Âš¬´¢½²¥¶°¶½¹³Áµ»Æ±¿É½Åʶ¿Ë²¶Ö¸°Ð¾°Î¸ѹ®Ó°ÃÚ¶³Ì»ÀÊÅÃÇƺÎÖ¿ÐÑÉÌßËÑâÍËÖÅÍáÂÑÛµÏá¼ÑÖ·ÌÜ®ÍÏ®ÞÓ¿Ùç±ÙêºãéµçܨâاÜÒ«àÙ­ëݯãÎ¥èزôÕ¤äΠçҟíΣéÁêƋèŁ澆ÝÉæËzÜËwÜÅtæÓ|ØØtÛÜxäÝsàààâ‚äà…äن×á‚ÑàwßáxÌéÓç×éwâå}æðˆêáæÜläâpêßjáãpÞÛlÖÓhÙàjÚÏdÒÑYÑÌhÉËZÖÏeØÁ[æ½Và±að»_ø½U÷´Rè»Uù»V÷ÃRù¼OïÆ[éÁTáÎ?åÌ<èÑ>éÎDáÐGçÄ>æ¿Bâ»FÛ¶BêºEܼ?ë´Dá®B׫DÙ«SÓ¹OØÄXϬ`ħjÍ«fÇ£bÀ¦Z³¢L´©Qª•W©§Dª¦L¬›A°¢D½©G¼«KÁ¨M¡<ű<Ç©7µ­G°§<À£I·¬O½§?®°6¸¨1´¦B´Ÿ2â4½¥.¾«2²§0±³-·±:°«:¯«:µŸ3¼¨1Ç£ Ä­&¿¤5ĕ1–?½CǍA¼’Bº‹=²‘A¡‘2¬ƒB©ŠE©‰I«‡G°‹?­‰?¨„G­’T¤—L›”QQŒNŽ‰V~G’ŠL‹‰WP•S”‹IŽMŒy[‘€[Št^£rd¥te¤w_§z`Ÿe^¨b\›^a¥W_­Sa²Nd­O^¥Wd¡Vh¦V] [_¥RVŸO^®Vb­[\±PL£RH°SO¢YD£G@¨GA²HG´QPµDF±GJ¯DQµAR¶JSÂ;V¶=QÁGPĸ¢G»ª=¸®5¹­Dµ¨F±¯@¶­E®¨9±®9º«?³›5¹£7¿©)¶©)·­.®°9®¹2°¶4µ³1¹«+µ¢1¹ 5Æ¥)¾ª-½3¿ž1ɒ=Ɨ<½‹9Á‰;¸‡=°6¬Ž:¨‹B§‰@¥‰H³ŠG­ˆL°‹C¨ˆE¦„Q§I˜ŽN–PŠ”F“Mˆ†S‘†NŽŒX—I‘˜JŒ”HŽ†N„‰SŠ~ZŒ}X›v`¤zdœ{c¥sZ©t^¢sf£eb£df®`d°Zh¯Ta¤Oj¢Wf¦^b£\aœWZS`¡QY©TW§HPžHO§JF¢PK¥IF¤KC¥UH¯OGªUO¢SN¤SR§E^¸He¼;aÅä·@æ¾Jí¼Bã¹=Þ¹JܱBÙ´EЬOÖµQɯU˲aÓ´bË·[¿´Z¼ªW±¥`¼¡_±©H¯¤=±ŸI¦–J¯”@¿•M¼–H®¤A·¦=½«;¯©5³¡7°¡A®±=¹¬@¹­E­¨9ºš-2Á®(º¨.·°2½¸&¬µ3±²/¯³-µ§+²£3¼¦0Ǥ)¿¢2ʓ4ʐ3Ȗ;Ñ<º‰9º€:»€:µ€<²ˆA°8§ŠG°B³€D¨I¡K§‰O£‹B™‡B”ŒG”M˜CŠ‡J‡…U„‘X’T™R™>”K‡EŒ‡I‘z^|\v\“„l—‚h¥|b¥{]£tc©i^¥ajž\o§Tc¯^g®Yc§[b¦[Y®^a \cœ]]©YP£[L¤RN£CL›AZ›D\ªNO¤OP¬XI HM¢FM™CSŸDX§EY¯HV«Ea¾GRÁ>c¿:S¾)U¹.S»(]¶3^³)S½-aÌ$YŸ¶ÕŸµÑ£¦Ñ §×¦¦Æ¥­Å¡²Ç™¿É¨À»§¼½§À¸ž½¾¤µÀ¦¼Èª·Ä©·Ç¥¿Ê­·Ð§¬Èž±Êž´È¨·»¨®´¦¯´¦ª·¤³¨¡»¬¦±¢¦³£¦­œ²¯”¶¹œ²·¦·¶­²­¶¼µ­²Âµ³½·¶¼¼»»²»±ºÄ­»Í²¶Ï¶³Ë½µÆĹĿÂͳ¾Èµ»Å½¹Ó¿¾ÐÈÄÌÒË×ÍÁÖÕÁÐÖ³ÍܶÕѹÚÛ³àÓ¤×Ö¦ÝÙ³ßé«åéªÚé¨ßÜ¥ëå§èܛòؤðÖ°íÍ¥àÒ¡æ֔ëϔîΐìדâ͍é˔ñΈ鿊繏뽅îÈtðÌtâ×zÞÛyÔã€ÚÝwàèpáèxÜë|èâ~ÙíÔéwÑîƒßåŠãè€åãÙìÛåˆÖñ‰Ùí{ÓêtÞètßÝc×ÓaÚàfÐÜ^ØÔ`ÕÐcÙÇ]âÉeëÏhâÅZâ¶Wé·TéÁSØÃRâÂZê»`åÂ_ÚÅ]àÂ[Ý¿Xá¾OæËFëÈ@ëÓAåÃGèµMê±Câ²Hç®CÞ¬@å¸Dè»JØ¿R׺LÒ¸IηQØ®UÖ­LÍ¥R̪YË·YǹR«_¾¥\¿ªT¿¤UÀ©F¹Bº¤N­ J¹ J·I°šK¬ >·Ÿ;³Ÿ9´œ,µ©0²¨<¶¦9¯°8±¨A½ž0¹£+Ƥ3Â¥.Á¨2¯0¸°+²²%²¯!¯«)¯ª)»¡9¸™8º˜1¾˜/Ȑ<˔BċAº…@½†4¸{:½}CÁyK¶D¸@©A¯‚<µ€<­C¡Gš{<ž„?–ˆ>™LŒ…G…ŠLƒ†QˆRŠ–EŽ“I—C‹”BœA‹•F••F˜…R™†\€`wn–~jœ~a yf¨vd©lg£gfš\j­\l±Xp±Xm§\f©YY¨`W¦cUª][°[O©VL«WS LU™?WA^žC`¨SWªYV¡PQ›C]ž@[EV­CZ¯>]«=V´AZ¾F`Á>d¿2X´9Yµ1Z´&V´)^³(a¼%e›¯Ú¡ªËœ²Ùš®Û¡µ×ž¨Ð¤½Ì©Ãɟ¸É¨´Á¤±¿¡ÁɟÃœÄÍ«±Ä °ÃŸ´Ì¢²É—¶Ï»Æœ·Ã ²¼ ²¶¤«¸ª·«¡¸¢½«ª±ž©³¢¨¶ª²¹¥·¼˜»«©²²¨¹¹ž»·¦¯´±º¸¼°¼²¾²°¸»¶Â¼±Á¿´¿¿ºÁ¼·Àº´Êijù°Ã´¶ÈǾÌɺÓÅÄÜƸÞ˵ÜÖ²ÝÔµÛ׶çß°ÜÖªåÙ ÝÎ¥àÕ¸ä×®îë¨àá¢èÜ«äážâ۔æß õØ ç׫ë՝çÓ¦ìߝúՖó۔ìȍùЅ뾃êŠïÄ~ü¼{ð¾ïÇ{ã×uïÚoæß|ÔÞu×ÞzÜèÛ܂çëxÚê}Ï݋àæˆáãŽÙê‹ÜáƒßâééŽÙç…ØãrÔè~ßãpÜâd×ÖYÏÓeÖÊiÜÓdãÊYæÏhçÇbÛÎcäÁ^Þ¼ZݾZßÃWÍÅOÔ¾Tæ¸^ØÀVÙÆeÖÆVÞ½SÖÄKÝÆRÝËPåÒPèÄCܬRܬFÚ²NׯCâªDÙºMæ¾Jç¾CÛÀAÒ¸TѼRÙºEß½HÒ©MÕ§TÔ±MƽXªQʯOȟIº«BĨ@½¤>·¢E¯¦Dº™;¯‹<»—5°ž<¹š3©£?µ™0ºž1´¢+²®4ºªA¸¥;°°:½ª3¶š$¶š(¿§.Ê£0¸£$»¥/±«)´©'³›6¼Ÿ4¹ >ś/Ô7ÀŽ<Ȏ3đB½Ž=¸ˆ8ƃ<µ|<À‰>­~F¹Œ>­„G¦Œ7²†9²†>¦†J›Œ<–„G—‘N‘ŽQ‡”S…WŠO„›N‚ŒKQ˜HŒG”’F†DŒ“N”ƒX’‰P `ž}k€h‘vd¤zd§vlœjsšfkXsœai [i£Qe¬]]¢][¢cR ]a«Ze¢X_©XH—XMœVVŸCV˜@h¢@ZŸJb¦N^¥DX£>Q¤;[Ÿ>Y¬I]±BU±?R¬B[­?b±?n¶9`­1Z²,Y­6k±0nµ/d»,m’©É˜«Õ¢«Òœ´Ý¥³Ú´×½Î©¿Ì£´Ê¡´¾¤¶Ã™¹Âž²¿Ÿ»É¡ÀП¶É”¯Ç–¸ÑžµÔ¼ËŸ»ÊŸ°Í¦«ÆŸµ¼¦¯®·«¢¼«£·¨£º²°°«·­¤»´¤°²™®¬®¶™³µ¤­°¦°¯²»·°¸³¹®¾À´º¸·¿¹½¾·Æ®ǾªÊIJ½½±ÃÁ¶ÃĺÈȲÕ´ÝÀ°ØͱØÚ­àÛ¬èÙ´éá®åÔ³ïÔ©èÙ±áÕ®ßקæáªãÜ­ßå¥íã¨ëëšõè‘îܗìޙêá£üàŸþáŸûá“þ҇ÿDŽÿÆÿÐ|úɃõ¾zýÄzóÄzïÃ}òÍqðÒtâÛxßÖxâàzÝáxãÝ}×â}ØéŒÖގÚê†ÛíŒÛê‰Ýì‹Üç’åêŠÛá†ÞÚxåáyÞßqåÛeÛÒ`âÉ]ØÉb×Ç]å¾[âÂ`âÄ\äÆgßÆbÖ¿[ÚÅ[ßÌNÒÂRÝÀWܼ[Ú»YÔÀbÚÃ`ÒÅWÒÌOÔÎWÖÁVáÄNá¶X×°PÙ°\á°Vé³Mß´Mâ²Iâ²Iä±JܹFÕ±EѺMÜ¿SÞ¾KܱQÙ²UÙ´M˺VʵWίPÇ©B½§?í7·¡>¶¥1¿2¹‘.³”;±;µ‘5²•7­ž4¼š(¹ ,°«3±«4®­8¶¯5·¡.º¤0¾ª1»Ÿ#¼£$¨"¨!½œ0¹œ/¶ ,½¥8µ›<´£<À<Ǖ?¾“5¿‘=ÀŒ5À|8¿}DÂH½@º€<µŠF¹‚<°„<¤„G©‰@Ÿˆ8¥ˆ?œ•@™E–P‘“MŒ™PŽ—Y‘¢P‚›S˜S‰”K†MŒF’ŠM‘”FO™‰Mš`Ÿ‰d›zo—vi’x_šwe¤taimž\n”_s—UrŸOn£Pr¦\d¬^]§[[¦VeªL^¡FSžPT LJ•NQAR”Caž@b›BašAb HW§F_©BV¬E`ªA]±7e¦>_£9g­El©>h¬>s³@t°8f¹;o´5q±.mº#lš¢ËŽ³ÌªÍ˜µÐš­Ü–»Ù¨±Ð¦­ÎŸ¸»›§¹Ÿ¸Á£¾»—µÆž®É£­Ã¢­Á¡ªÁ™¶ÉŸ°¾›¶Ë™¸È™¶Á™¯¸™´°§²»¢½±­¹¦¦º§³°§±®­¸¦²¹© º¶œ¬¬¨³±Ÿ²±³±±°«¦¹²§¬Ãµ¶»­µÀ®¼¸·±Ä¿²Éµ·¾½¯»Ã·Á®¶Á°ÁʳÖ̲àʹÚóÜÓ´âѱÛܬÙß­çаäÕ¯êÜ©öß«æͧàÖ¢íØ£ê؝èٟëܚçæœäâçНèà£ëè£íæœëۜ÷ېøЋòNJÿ¿~ø¼ƒù¿óʀöËöË{ûÆyèËwàÖxâËqçÐvãÖsßÖsâáxÜâ‹àéˆâìßé|äó€èòÜé€äé‡àåáäxäÙ{æÙkçÝfáÜgØÓcÖÍkÙÕlÜÌ[èÃUíÇZáÍUØÇT×ÉV×Á^Õ¿]Úº]Õ¸^ã¹\Ù¹XܾVÝÁdÐÅTÒÂZÜÀZ×ÌUÙÊKÜ¿UÙ¸Jå­RÞ¸Nè¬Nê¬Rì¹Ië²Mç»Iå·OÔÀMÒÃUÙ·YнOϵJÒ¬KÉ®YɧWдYɶVÅ®IÊ®C»¢E´¬D¼ž<²¤:¾(·“.²—C©šB·˜9­›8°š@³¤6«/®¥0¸¬)²§2°'²¤4¼¡3¶¬1¹º¤$¹¤"´ž,ºš2½ž6²Ÿ7¾ 9¿¢>Û4¼—FÁ”@º–8¶Š5µ8°ƒ>ą@´8³F½†H«„@·B¤5¢}@Ÿ„D¯;§…C¤•DˆC•“O•RŽ•[’ŽQ†–V†™J–M“—U‚‹H‹N‘T•ŽM•‰IˆO•‘[ž…Y–„VoZ”th–hcbm•gr—arŽOežYl—HlŸMu®fj«cf¤Rf¢Tf¬]g¢T[ªSV£T]O[“FašQg Jf™Ha¨DW CW¤BM¤HZ¨Cf©NW­?a®?[³ê±Dê²Lç¼NÛÁLؼVÞ¹_Ú¼VÒ·QÍ«GԞDÉ¢QÃ¥OȪXÆ¢UɨH·¬I´®B½ 8¶™9²˜0¶•+µ*©‘:°–7¯ž@µ¢8¯¢>ªž7¥œ2²¨3µ¨,±ª)·œ$ê,½«.¾¬*¸ &±—¸˜ ´¢*»¥*¸¢,½¢4·¡2¼™5Ž?Ð@·‡B·Œ9²†0®ƒ/º†,·”8·“9¶Œ=¬‡>°‡>¬ˆ5¦{6­5¥Š6¨ŽE¨‘FšŽD’Œ<Œ›O˜R’“L‘‘QšX‡›O•U‹ŒP…V‹ŽN”šI’—S†šU‡“LŒŽFŒP”sO“p\pX‘aa`]˜\gœ_k—PaœO`œMp¡]r¨`o¡_d£UiŸab£`bª[a¥TVŸTTšU[’Ud˜P[¢OS¢N[©PK¥LG£OPœNb¡KcŸIa£LV«E\¯>f«Hn²Cn¸>l·@`µ6dº=j¸2d½%dº!p¤É†¥Ë‰¬Ï†«Ã—¨¾ ­Áœ¯Àœ¢¾›«·¤ª³—¨Á¥¬º ¦Ä¤Ä­¿‘­»Ÿ±µ™¶¾£¨Ã ¬» «¿š¤¶¢¥«¢¡¤ž©®²¯´±¥¶°£¶¹±±Á¬»¶ ©½›¨¹«©µ¨¤³§¬´›®·¦¬¿£©Áž¶·ž°Ç£ºÆ¬´¹µ´Ê¹ÂÆ»Àƹ¼¼³¼µÈ·ÇɳÈƪ×ήæ̬ÛÔ³ÞÊ£èÖ²ßÍ´ìÚ²îџåÒ¦øޞéá¡õÐ¥é͜çޔí֒èؖ÷ܔúܝõݒðՑåӚçޛáҝãԍê΍ëƗòĔòÒÿÂúȇÿÀ~íÀë½‰óÃèÌèÓxéÅlëÏpêÔwÙÕkéÑtßހßÛ|êð|æéxâìsÞæzÜê|çé{âìsâçxÞífáÞjëâbâápÝëfÓÚdÜ×pÛÍ_áÊdãÐ]ãÀUßÂLÜÒWßÄFäÁHç·NæÂPݺTéÅQê¾Zå¹\æ½Wå®TØ®YÚ¬SÜ°Hà®KÞµEé¶Qì®?Þ±Eê©=î±;é¾JæºRä³QàÁQã´OسWÒ»KγKÒ¦RͦOƧT¹±R¯K¹©Rº¯L¸¦:º©0³˜-¶Ÿ.¯›+¨›%ªš0ªŸ=¢˜AŸœG¦¡H­¤7±•?¨¢3¨¤0´˜)¼ž*¸¢-²¦-½¦/±£!¶”-³š²¥·¬(®§'¾¦+¹Ÿ3½˜0´™<¹‘?¹B¯Ž3¯8µ…%©–.«—-¶™/­–=´†1ºŠ:¦…4¢„1£3«–,š—C¥ŠD•‘C’Š=ŽŽL––WŽ“GŽ¡H’¡H”O…‘N‹ŠT‰ŽK‘“N‰ŒK•ˆJˆ‰KŒ“Qƒ‡Yˆ†Z“v\‘eXˆaY™WY•ab ]j˜XešW\šJl Pl˜]j©ed©dp™Zj¤Vf£XZ¢MU®V]ªQP¡ZZžNZ”NhŸS^§I^¬KX«PK¡FM¨O\˜MfBm¨E]«HY°OZ©Fo¶Pf¾>e´?]·4j¿2b»7f»#l»&s~«Ê‚¢Ã|§Á…¡Ã–ŸÅ™¥¸¢«¶š¡ÀŸœ¹ ž¶¨žº£¬¾£¤Æ—«¾Œ¦È¯Á“®·¤¶·©®½¨¬¾¬«°¢ª«¦¢¨¤§­¤®µ¤§±®¢µ³¬´¾°¹·¥¶·±º›¬¾—®³ž¥·˜¯¸žª´œª¹²Ã¥´» »½ ·Ç¨³Î¥±Å®·¼³¹Áµ¾¸¾µ»¾²ÄͬÌͧÕΫÞÏ°ÜϯÞʦðÒ­ðÍ°ëџ÷ޟêä›ëܙëϓëЛèӕòә÷ޜøۚïՌõ܎ïݏïҔíΖáҔêΛêȔâ̌æĒéȚõ»”ù»ŽÿÈÿÇûÁ‡ûɂïÈyñËxãÌqÜÇuæÍuß×{ÛÙoæÜoäÔ}éÙrïäqìÞyêáwâۂàä|éÞtæàxÛìnáèoãéiåæcáíbÜédÖênÖÝfÞ×háØcâÕYåËXÝÖVßÏJÞÀKãÀHí¼?éÁGêÈVìÂUïºMê´Tæ»Vã°\ê¤Væ¥Xå¬WÙ¯L×°MÞ¬Kî«PìµEì¹Dä±@ê´K߸Eã¸EݽOá¿QÞ¹ZعTÛ¶NɧSƧJŤM´®L·¦I¶©M±«E¶¦6¶ +»˜,³£!¨#¢•-¨’/©ž6šŸA—š9¡ A¨™?­;§.§›1°£-°›+´˜!µ #¯¡)¯–&±˜"«—&©”*±¡#µ˜'²ž3®Ÿ2·–<¾Œ>µ7»-°‰4°Š)°Ž"¸“¯”#¹™%±•,¸4·Œ5²†7ª…7 †1¥’3 ˜9š“=œšB›L¥”EšLšD‘ŸM–ŸRŽ™K““U—UŽY‡”T…“R‹ˆRŒO‰‹T‹R…ƒZ{]ˆjbij^b—^f˜WkX`”Nd’[nŸWg agž`i—`s]mž^^¬M\­W`°RU³ZO±SXŸSfžTd S`ŸLU§QI¯WK¬ULªEY@gžAk¦Bg¥G_²D[²QbµIa½I]·C]½ÔºGÝÅIλJÞ²RÙ©TÍ´Jɱ>¿ªJ¾ªF±¤J­¯C¶§G¶žF·¢@±¥,­“.·–*¨/­.³’7¨—Cš˜GŸ¥:¥¥C ¡5«£:«ª;–©6œ™3®’)²œ(¯¤(²–)¦—+§—* +­š%°’!­Ÿ#¬ž3¯™7®›0¬˜.µ6ª†*ª‘$°Š+°‘-¸’0­Ž%ª–!ª•,·‹4²‚3©ˆ=©5£†4 “:©‹@ CŸ•;œ—DŸŒP¨–J¢ŸO –Q‹—T•‘JIŠ˜V‹˜Iˆ‘Q‚ŠWŒ‹RŒ\Ž‚LŽ‚S“uZu\ih•o`‹`o•\jQu˜Ww’]i‘Zm”]k’`e¦]mŸ^l¢OcžTi¨Od¬Q\­R^²PU¬Oa£QXžY^ Za¥QS¤]U©SI«RV±Q^£HcšDf¥Bh¬Fj¯Ie¹Fh´?fÄAbÁGcÀDl·.h±$mÁ%hÆ$dx¦Î}¡Ï€•¼˜¶„£·§¾†¢»“’µ›”µ’£Ã…£¿‰œÁŠ˜»”›´¬»”«½ ¦¿Ÿ¡¶£©½¤¡È›¢¾ž¤²¤¥¹¤¡·¨£´«ž«¦ µ°¯¶¤¢·¨ ´©¥´¸¯¼œ©À•§Ê“¢È˜§Î–ªÆ¸Ã¦³½¬½½³²Ê²·Æ¸»¹®¸Ê¶¯É·ª½Âº»½º¹¼»Å½¯Ï̸áÌ´áÁ¨ÝÇ¥ëϦôΰçÏ¥ëÓ¤éÒ æʝí՝îԖéɘêǎå׊ì֎÷ɑò̓ôȓëяåЍîуéƀóʋõÊ|é¿}ôÀó»‚ùÇ|÷ǀð¼…ùÂó¾wõ½råÌyÛÊ}ÚÔtÝÔ{çØríÖzáԀáÖzäÕxðÓyîÚvóêmíåfåÔnÝÒfÖÚfàßlØÕnÛÔhÔ×bÔØiÜã^åÖbáÖZ×Ö^ÙÍYäÊ^äÈYæÓ^áÌYÙËKßÄHá¼Fí·EçºVéµWæ±Mè½Tå¶WíµXí°SÞµRè´Mä¶Të¯SìµRâµTÝ¥Dã£CÙ«Hå¨Lã¯FÚ°LÓ¼TÒ¼SήKÉ´LÊ©Eɧ>¸£=²©H²¢B¬›E®£M½«A¨9¾‘(°‹#»‹%·Œ-¾“=´ <¦™9›A™–D ™5¡ž=¢¥9—«4•©0™2™,£ž)¢Ÿ1œ”/Ÿ™$œ™# 1œ”$¥(ª™2§’2žŒ/¦#²‡!ºŽ#¹•©‹"µ‚'µˆ-²†-¯Œ+¤'ª%±Œ%§ˆ+ž1¦ˆ> “?§A¥”E¡“>¤œD¦™D§‹C¡ŽM¥V£’Rš™PU†ŒXŠJ‰V‰ƒR‡‰P‡€]…zUƒzOƒsT‘rdil“of”dl’goŠau’Rs•Qx”_w—ar‹YdœdmŸ]g›R`›QfžQe \l›Qd§VY°OU®O[­\^ŸaZ£eX¨`X§WS®SO­ST¯Pa¦Ba¦Bc²Ea±Hg¯Ol´Fc¾>eº;nÂ9e¸;j²6v·)sµ'o d…œÆƒ½¦½•¤¾…šµ¡¼‡™¼ƒ›°–½Œ£Àƒ¡À€žµŽ—¶‘–Àš¤Â¦·•¡À¡¤¹ž ¿¦¬Ë•£Å¬®š®­œ­±¬¡¶¥Ÿ±­«¥ª°ž§¥œ—³¯”­±ž«¶—£»£¨¿§Êœ¦Í—®Î—¶Ë¢³»¥¶½¯¾Ã«±É§´Â¶´¾¬´Æ´®Ë¶®Á¾·¾¼¶ÄŹĮ̀ÞˬáТç̚áÇ õÔ¬ôË éÒ§é͗꾦àÑ£ðʟâɚôˌñЕéӓåñÒðЗãԌìʈòÑ}å̅ôΆùΈìÅñÂsùÄvó¹ÿÈtù¼€ù¼qè»z÷ÇzéÉ}ÝÐxÓҀÜÛxÚÚsï×nâÕpìØyêÏyíÜnôåvçßjìâsáÚjâÞ`ÒÚaÝÏkÕÜ^ÖÒjÚÎgÒÕ^ÞÜ]åÓVêÚ[äÏXäÐTäËNåÐ[çËLÝÌUæÆSÙ¼IåÀPàÃJîºLî°Tè¿Hò¼JçÀSðÁVï¹\ä¨Vâ®Kë¨LߪVã´Lì´Fæ§Jà¡Jß²P×·Uç³GÚ¯VоXÇ´XƯKƵAƪCÄ´=º´@®­J¸¬@®¤?¯ªR³§>Ç£3³“5º‹%ª—)ª‹6®˜=ª¡1¨š;¡™A ¢5¤ 4–§7”ª5’®2Ž¤5Žª.ž 0›£(¢£0Ÿ£$›™#˜’3¡‘,¢›3•%¬’.­”-¯(¢“®…'·Ž¬‹#³‰ ¦‹0§/²•(£—!«'®‰)¤Ž2¤…)¥‰-ªˆ6¢Š<£›5°šE¤š@¨™I©–L£”A§ŠM£ŠR¢„DšŒQŠN‡KŽƒPŠTˆTˆ{RŽ}ZŠ\ŽsOŠpb—qe“oa˜xc“mi“dl“_o‹Yz_yˆRlZn\hŠas•[g›R`•Xa›TgžYg¡So¬W[²X]°Id¦Z[¯`R¬aY§gP±QK«TQ³XP²RT«KU§DZ©I[©Yg³K_¸NlÀCp»Ae¸8m¿Gb»4i³)uµ%i¿!e‹šÀ…¢ºŒ ¶Š¡¹‚¦Â†¥À‹¦¶~—³‚¢¹½Š“¼„˜´“œº”¢À »šŸ¸¢¨¾¡ªµ™³·˜ªÀ•­¼”­º’¥¯ž©³¤›±¦œ´¦¢©¡¢¥¥—©Ÿš¨«Ÿ£¯˜­½ž«Ã¥¤Á§®Æž°À›±Ë›¬Ð£±Æ¤´¿§»Â©±Ä¶¸À±µÄº»Í±¸Å»±Íõν½Ìǵʼ®Ø½¦ÜÄ¡êÌ çÑ¥éȜêÅ çƙܾßÁžÝ¼œçàäȚììŕÞĒ꼉äëÀãʎ迆ëÃ~éÀ}éÁƒòÁ€ûËuÿÇrÿ¼oûºvý½xö¼pëÇqñÁwçÄ}ßĂÙÊuÕÛtÚÚwßÕiåØißÒfêÛiðßoèÚgèävêàtßßläÙnØÒoÛÐ`ÒÎX×Ô_ÛÚgÖÖcÔÍ^ÚÏ`äÚ^â×TÞÛSëÙVãÎTãÐMÞÑNàÎMÛËPÛÀQÙÈTâÅNí¾Rè»Jê¿Rñ»NíÂXç¼Xè¯_ìªYí©Tæ«Oã´Nå±Sé¨Qá¤Má¬MÙ­TÚ°YݵYÓ®UÓ¸ZηZɸIÄÀPÁ¶G»®A»³E¹ºM±³J¶´F»ªFÀ¦@À¤;.µ“/ª›8«”7´˜:¯ž5¡£2¡¡0 £5Ÿ9‘¥4‘¤2œ¤9•©7”­,¤,˜¦+ž£-˜¥*£Ÿ/ž2œš*˜›0¥•&¦’¨”)°†)­‰«$­Ž ¯‘*¬‘*­–#§‹'¬"Ÿ“(œ‡,¥‹)Ÿ&¨ˆ.¤“7¨•?¦š9­™9«‘?ªA°–F§ŽI¦†E©G¢Š>ƒC™‡F”„KŠ†H‰„JˆƒT‡OzI‹vS…qRŒt_˜t_•qgšqb‘qf…aiˆbj‡dlŒarbq…Vj^t‰Yr“\x—Yl™PeŸTb Na¢Xk®Tq«Qh¯T_±T\³aU°_SµdR¯]O®]Z©WT¤\N¥\X¯R\«U[¬ZY§X]¦S^´Gl±Fo¾dÂAeÄ;m½9w¿-rÁ.wˆ™Á€£¶ž·…¤º|›¼Œ”°…¢¸t›¾¡³zŸµ ¸‰”¯’¢¾™Á”ž¼’¡µ”¤¾§ŸÀ–ž³•©¿™¢ÃŽ´¾™´­¢­ª—¦¤œ ¨™¨©š œ›™«œœ§¥–§«˜¥­¤¥¹¨­¸—­É™­Ä©¨Ñ§Ç£´¿«½Ä¨µÌ³©Ç®¬Ç«¾Ä«¶¿¸»Ñ±´ÌůÌúÒƮϺ¨×½«ê¼¥êśí͘ðžìȒîÑ۾•æΏçœ巗컋쵄åǎã˒éÆïĀäĂçˆâÂzãÃuðÆrðÁqû¾xÿ¼vö¹{ÿ»zÿ¾tÿÀoðÆpïÉxæÀ{è¸xåÌyãÓzØØoãÓxÝÐhÞÎeáÖkÞÏvâÝoêÖqèÔuççmìÝtãÝcÞÊeáÉbØ×^×ËeáÍeÖÕ\áÏcÜÒ`ÝÏVãÓUâÍNêØYëÐWìÓSãÈVâÅUé¿VåÆUá·Jí¸MíÀVä²Gç¼Gò»Sé²RÞ°Rè¸Vê¤`ä¡Uä§KÞ¬Læ±IÛ±Hà¡FÞ­H̬XÛ«V߯Q͹QغVÕºTȶJÌ¿TÄ®N¸ª@µ°=º¹K«¬>²®@´£@¸”;º›A¶2­“6¬•;­›6³Ÿ2¶ž2£¤+¦ 7™•0˜ž0™¢;Ÿ /–¤7£6œš+‘¡1££.¨6¡š%®™+©Ÿ& –$©“"§•+£Œ-ª—0¤"¡'¥‹#³–«—.¯˜.¦,Ÿˆ# •(§—#¡‘)¦‹&§‹'Ÿ”+¥“<¢¢@£•9ª•@¯™Aªˆ@£†E¦’?®‡F£~Oš€@˜=™ŠN‘L—…P‹‹L€PŒ„Q„‡U‚{X…ubˆnZpjˆwXŠh^•c^ˆf`‡fm‘lr“_w‡dq]o’Um’Pg‘Tj˜Oo–Zlš`aœVm¥^gœ[g¬Ug¯_`¥T]§bZ²gT¨XV¢_Q£aQ°RZ§TW¦XN°^b \g©]dªVg­K`­Hf®Gkµ=p½Bd½9j¾6l¼9}¹/xÊ+mŠ“³šµyœ·¥¯~£ª…”¯’®y—¼~¬w˜ªu ±€™­š¹•·Žšµ“¢À¢»œ¼”¥¹“£¾ ´–©·”¦­²¦¥°§ž¬¡Ÿ©š£Ÿž©¥¥¨¨®°©¥«²¡´¶œ®³¤³Àžª¿©¦Å«³Å©´Â³¶Æ·¯Æ¶®Å²¸Ä©¼Â±À¹´Ã½¶Ó¹·ÝµªÛ¶«Ö¾ Ú´¢ßº§ëàçÁ•åÔàÀŒãÁ•íƍæˍïǃó¸‰ñ³‡è·|à»{æȅæÂzé¾wôÀyチâ¾ußÄrçÇné¼pò½|ÿ½xÿ¹wÿ¾sÿÂpþ¾i÷Ãpñ¹‚俁繁àÁ‚ÜÒvÝÖuÞÛpãÓgäÓháÒvâÑrëÔmêÕmîÖmëänòáríÛgÜÉkÚÇeÛÍ]ØÐ]ÖË[ãÏ^àÕ_çËfàÉXêÉQæÇPêÏKäÖFïÎRôÉRçÉOßÉUåÀWð·QîºLó«Wí«Qê¼Uê¾JíºHæ²Lå¤UÞ¥Vޞ\Þ¤X×­TØ®Nã¥Xà¦PÙ¢SЭR׫VϳYɺOÔ¸JÍ·N˼V¾²S¿¯G±®@°³E«®D®­C®›8»–3·Œ2²:­:¯™8¶2±‘9´—:­£1¡ /›6˜¡6£–1 5¢™5 ž5’œ:ž•:›—-§£)§Ÿ-¥-©•(©Š'¦(¢‘1£‰.¥“-¨Œ*¦’&¡‘'©•0°)®"­˜#¨˜&›‘*‡*Œ®”)­“*­‘/œ‘3›”.  4œ›1žž8¥–>§Š4¨“B©F©ŽD¡~MœŠC•ŠE•}S–~X‹~RŽJ“„O„TY‰M_„yf‰gŒ|ZŠwb”fX…`V‡jequ‰kshoŽ[o‘[fWe–Zc“Oo–Wdž^gž`f–R`šJdªRi§^f¤a]°fgµde´[f¢RY X]ª]Z¦]V¨VQ¨[b¦^c²[a²Tl¦Qg«Jh®LxºGwÂGuÂ8kÉ6hÅ2vÇ)xÃ*o„ž¹y›µ|¨·ˆž±|ž®°›³}”·x—·r›«{—¬†–£~•®•«†¢¹ˆ¤½šª´¢œ²›£±’¨­’¤­—£­˜§¥—°¤¡©¬¢£› ¤š¡œ›š¯ŸŸª¦ ¤¨¦®´Ÿª®™¦« ©²—®±œ­À¨®Â©²É°©Ç²¬Å³«Ë¯©Ë³®Ë¸°Ä¾«Ç´­Ï¸²Ñµ¬çº±Û­¨Ø¯æ¾›à´šßµà¾”ܾ“áŠßȏðÍ~㼅åµ{òµyñ±€ò´|ë¿tê¾qâÁxßÆtæÃwãÂjèÅjë½tá¼ö½sòºƒñ¾ÿÄw÷ÅpÿÃeøÇzïºx轀çÃz케çÄrÞÏxÔÞgØÐdÞÙdå×dÝÍfêÒlàÖfâÚoïðpéÚeçàgàÒsàÅfÞÇhØÔ`ßÖeâÊhÝÑcëÉaæÐbáÍOæÃNÜÈVìÇRðÅZñÄMïËOíÇKç¾WäµSòµRä²Jí©Nê°LéÄSæ´Nå±KߪSß²Và¦KážPÛªVâ¡UÞ£^à©XѱVÙ·QÏ®TÈ©S̯OƲIι[Ì®X͹QÁ¶FÀ«M¬µ:«­@¤¢8² ?±š0ª”2§’4¯’7®Ž5´›4¯›?´š;¯¡0¤¤3™¤=ž3¤Ÿ4ž™3š—5œ’=•–:˜”+—¢'¤•.¤˜0 “!¬‹+¢‰­"ª…2§.£0²Œ*¡“0¦‡#°•0´£(§¢ ¯–&žš$ ‹/¦"›‡”"§—"œ™.¢Ÿ*¢ž7˜¦0¢Ÿ;¤ž=¯‹9­†<§„?ªE¤ƒA‡Dž…Mž€Hš„M„Z•‚O’~RŠ}K‰…OŽŒO…ŠP…€^ƒZ€a‡|PŒoK lS˜q^†ug‚rmet‰fmŽYo‡aa’\lŒRj’[r–Qo—eq•\o•Qj£Rc¡SiªZk¦\g§ae§as X`¡QRš^T¡[\¡Xb§L[ž]`¬Tb²Qo¨HiªPl²Rl¾RiÁG}¿Mwº;zÇ;wÅ?‚Ì)tÅ!pƒ›Àšº…›¿ƒ¤µ™®s›ªn“³s–±}Žº}•²š¶‚”¨Š–¬…œ«†£¬ˆ©º˜©«—ª••§šœ¬¡œ¬—§®œ©´šªª¨§¯¤¦ªš££›˜¢—¬¥¡²­¢¶¯¡¯¯¯­£¬–¤§›ª³›ž²žµ­ Å¯¥Ì²¬Ä¹¦À¸¤Ç°±Ò¹ªÑ´¨Ñ¶¬Ñ³§Ø±¨á±¦Ù«¤áµÜ¸›Ú°•Ö¬â¶‹ßÁ‡äÀ‹ấêÆ}ðÅtåµzî¶~õ¶yï¾ué½jéÇhåÂnè»oÙ¾cÝÄkâËmàËwéÅ~ï»|ð´}쾆ö½~ùÂvùÄoíº{î¾zðÃwíÀ~éÉzéÃßÒ|×ØoØÓpÚÓdèÖ`åÍgâÏaßÞaçÞeèêeòÜcêÖjæËjèÏsêÉuãÓsâÐoåÑbèÕ]ã×_àÐSæÉWã»`Þ»Zá¼PêÂVíÈOåÂYâÅJì¹Jñ»Xä¶Uë¬Uâ®Oà¯Hß»KݶEݸJÛ¶Ié­IðžYêžXñ `ìŸZÛ¡dÚ«\Ý´[Ñ°[Ñ¥KΧL΢S¢W£TʱUùUÅ´L»«K¯©>²­3¥¢4¦š6§”2¤‘2¬•=°‹H¨ŽB¦“Eª¡@§Ÿ7¬¡9¥§< ¦<¦¨;8–•4–”5¡–.¢“-¢”0Ÿ-œ(¦”%¡ˆŸ‡&ªŽ+¬‰(®†$¨†,²Œ#«‡'°‡"¨Š-­’.§›(±ž$­™¦‘¢Œ#§)ª‰&­’%£›$¦ž(› "–˜-™Ÿ4šŽ-©Œ2²‹0¬6¥‘9£…<žˆG¤@‚9™€C£wO›zV—zV—Y‘‡N‡ƒO†P‡L•S‘‚Y‘}YlKpJhRjWŠpa‡h^†nelnYi\i†VgXgŠ\sWyŸZsž[s ]s¡Xg•\l”Uf¤Yk¯Ul¨Xo Ynœ^\¤TT Z[§W]¢Ra¥Ve¤Vd«Vi¯Ij¯RmµNj¹Kh¼Ot¾Ky´DºHzÆ>}Ì/‚Ó$u‰µ|˜¶™»€¬¸vœ³r¤¶wš´j’ªtµx•«z—¯‹­| „—¡}™¬Œ§»Šž­—§°‘¤ª”¥¥Š©ª˜ ¦’««“­­˜¨¦™¨¥–ª–˜Ÿš¥¡¦¨ –®«§®£œ°¦ž¢¦˜®¨• ¬¢¥¶Ÿ¡´£¤¼¦®Ä¨¥¸¶«½´¦Ç­¨Ñ±§Í´ Ô²¡Ù²¦Í³˜Ò­Ÿá®—蹞᳖⯐䰒鳁黄޶€åȀìÅ|ð¾~í¶wö±sòÁkñ·nå³rèÂvèÌgç¾eÖÃiáºaâÆqïÃfìÃuçµp嵂ò½zñÊkù½kð·n÷½mñÈvïÁwæÂ{ñÂpðÑsåÒkÞßnáØjâÑcéÕoïÒdãÕgÛÖfÚçdáðnêájàÙhæÏvíÐwêÌsåÒsñÍläÛcäÔg×Ó]åÔ_àÒLáÆRäµYãÁXñ¿LâÅLåºMà¼Zð¶Oêµ]â·T×»RÙ¬QÙ·PÔ»EáµUׯJà­Qà·Fá®OÞ¡Yã©]ߛSå¦_ФPܨZЮLѪTÎ¥MӜEǞPÒ«VÑ®RÌ¡VÏ¥G¼®9´°3­ ?­›:ª¡<­<¥›4¡’>ž‘F±‘C¡Š?¤‘=³ž7±£D²ª@ª›A¨§7˜7œ¡,˜—4œ,¯—.š‘+¢—"¦ ) “$›‰œ‡$«‡/§‹.¯‘*¦'¦Œµ‹&­ ¨Ž#­Ž*Ÿš(‘0¦™$›‘*›—%‹)®Š3¦˜-§Ÿ/š•#‘“ š0Ÿ”4¤Ž6£š1¥/¨›,¯’> }Cª„G§yE¦|<œwD‘vFœ}P’vWŽ‹L„}M…QŠ†I•ŠW†O‹„Z–€^‹sPŒpPžcS•hW—v\‘scŽgj‘mb•[lŽ[j]p…[x‘Vr“YyŸUpž[v¡Ms•\u‹^m–Wc™To\t¥Nh¡[o¨^]§XaŸQe¥P\ªLlœJ`¡JX®Nm«Di´Rd·Gs®RtÃJr²MqµAy½F€À;{Ê8‚Ï$|ƒ“¼}œ·„¦À†­¸‚¬´x¦´uª¯kž«i¢­o¢®j™ t’¡~¢ }¡¢†Ÿ«~œµ€«­“«©“¬¤†¬«…°¦”¨§«¥–« “ª ¥Ÿ–¡˜”“œ™œ›œ™š¦¡®¢›²« ¯¢—¨ª–«©’§¬”§¯£©™«´£§±¤ ½´¨½¬¤Ç¨©Ç² Ã¬›Äª Ð­ ËµžÑ·“Ú¯—峝ﭓꯆç°}ß©€Ø¸„ܵ†îăïÀñ·yù²|û´nöºiò°jæ²uõ·móÇpë¸hä¹eéÆpéÂiè¿hè¶fëµiå­zéµlñÆhó¼n÷¹fï¼pôÂiöËlîÆtëÈpêÒnÝÕrÖÕsÛØjÞÔiâÕpçÐeéËjàÔpâÙiÛèsÜçtßÚnäßuãØoäÞlìÚbëÔ`îÖ[êÖaÜÄcãÆTëÊMò¾Hè½KáºNæÀMêºTâÃKÛ¿Räº\ݱXÞ±Y߯TØ·`à·WתMÛ©QÞ§Qß©GÜ°NÛ°Uã«SצUÜ¡\Ö¡[՛UߖWàœMÚ¤JٛJ˙Q΢F͙SӚWӞEȚBÁ¨7º¥3³©,®4¥¤5¨™5¡›=Ž<£„;ª‹@­‡<§9®—5¯©>¯¬B±ž>®ž7®Ÿ/®£:¨3£”2¯•4§™%™™"Ÿ•™$¤”'š‘(ª’%¬‘.²‹#®&¨‰'³Š ¯Ž(¤‹!+ž˜1›’5¥Š+¡–"•˜*–*£‘1¥˜*Ÿ–- ’-–”-Ÿ›.˜—'  $¥™-²”6°˜1¬Œ3¦ƒ8¡ˆ=¥Dš‚G”xMœuNyS–wIˆ„JŽƒKŽ…U„ŠZ‹WŽzQ‘WŒw`ŽuZŒn_’gWŠmT“j\‘rbŒme‹cd‘gn”[rˆZr„\rNuXtž[|”S‚›Mz›IjŽPk‹Uq•_l¢Xg To¨_k£]a§[e¨J^¡Ae¥Fm¡H\¨O[¨Oc¤Pp­Wf©Ok´Li¼Mt¿No¼>zµ9~¿<€Á0tÇ!u–¼ˆ•·›·‚­¶€¥ªwž°n£¢p¢ªh¤žn¥£uœšnš¢ƒ˜‚¤°€š±‚£ ­¨†°©ƒ¨¨Œ¥ª™« •žŽ¬§—¨—Ÿ™£¡“—œŒ¦“¤ž›¥“¢«¡¥¬¦¢‘¯¨–¬¤š¤´¡¯´ž¤³˜ª¹§¦¹±œ·®¥·ªœÁµŸÀ¨¡Ê¨–Ó²¡Óµ–Ó«ŸÜ¸˜Úµ•è¯™äµ”见䳍à§|Þ¨{䰂丂öÆîµ~ö·rþºoú´nù½oò·kë¹gùºgô¾qð­gôÀmìÄfë½cé´oè²oé¶tôºjëÃgõ¹níÄo÷ÈhúÌiøÍcéÅkçÔtæØmëÕqàÌmßÔißÕfãÓkáÜqÛÒoÝÔg×ànÝëpÚ×j×àpßÓpá×hçÔeìÝ]àÍcîÒbÝÎVßÐ]ÜÉ]ãÍJá»Tî·Ræ¾QÝÄGßÇSÙ¿TÕ¹Tè¿YÙ»bÓ¼[Ó·aÒ¸_ض^Ó²SÓ²QÖ§YÚ«VرFÞ¡Pä¦[ۙ[æ›Và¤ZÒ¡YÚ£QؚRٝNۚWՑV͛KϚWؘWӗHŗKÁŸ4À3ºœ;¶˜6ª˜3®Š@Ÿ“9¢G£‹6§—9¬ŠE®‰G¤£<ªž>¦ 5¨Ÿ9¤¦)²ž/¦¡)«¨/·›4³˜/Ÿ•*¢Ÿ¥“#‹"›•,•˜.¡‹2¥“.¢2«‡+¤"©ˆ#¬Ž%£‡-“%¥•*¡0–Ž/œ“1“1™š&–ž(—“6Ÿ*”)–š'šš5 ˜1¢š* š%Ÿš8£˜=«”<©‹9¨‰8¥:™<•‚E“|SJ‹~R‘{Y—ƒZ‘…c–wVŽ{e‹‰U’}Qz\‹q[ŽyT’sTwO’mV›f]k`‘j]–qlˆia„\t…Sw‰Wx’K]•OsšUy™Uu—IsžYv—W{¡Uz¤Pi¢\i¦P`žRl§Da¡Ae¡En§Hc¬K[«La®Lp§Nt©Jg±DmÂF{ÅBr»=yÇ3~Ä6|Ð1zÃ.|‚š°ƒ‘²„“ºv£¸y«¯~¢¥r¡¥uœ£n¢¢m——q–¢všx¢œƒ¥©†£«…£¤§¡‚ž¢™…­ž¢¡•§“›£–¡¤¢™œ•œ’’Ÿ•ž—‰ª’Œ¥˜‰«¤—¥ ˜ŸªŽ¦¬‹¡­•ª¤±ªœ¨¬ ¥®§™¶¢•®¤”º®œ¾´”Ë­ŽÒ¯”Óµ“×·œà¼”Ü°æ³‹äº‹ñ»‚íªŠã¦‹ãª†Ú¢}Ý©wã±ë»zðµyùÀrø¹lô´jó½eó¾ló¶eôºjú®nô±oø¯gí¼jï½iíÂkç¶tì¸kî®iì²uñ¿wîÀlîÃcðÑdóÚkõÑfñÎkóÔtéÔmêÎpàÎtßÝpÙÛqÛÜnÓÖfÕÖm×ÞoßÞnåÖaÜÝdÚØ_ßÚaÚØaàØaàÑ\åÈXéÈRãÏSÜÏOãÃUêÀ[èÂRè¾SÞÁQàÁUÓ¸VϾ^ÜÄ]Ü»ZÙµUâ°`Ü·aâ¬[Û±Tã«^Ú¤WߟPߣOâ©Tã¤Rç–Nå—Yå [؟Qڛ^á ZÕ£V؜SۚNڌYГNϑNȌBŊDǐC¸”:–4º‰3´‡;©‹>§—G«•@¯˜=¦›?« B°”E¨¡E©A§ 7¤¨-¬ 3«§,µ«1¶©-¯¥)­ž(¦ ©™'¥—&š –ˆ,¡'˜”,œ—*¥•2 ‰0„)¨*­€$«ƒ,‰/œ„&ž‰/•”.-›’.‘Ÿ&˜›)œŸ(£—0—”,™Ž2žŒ7¡’+¦†1§‰+£. 7›‰*¢‡. ƒ;ˆ9¡{D¡{@“…A”ƒNš€UŽ|Y„[–{`ŽtgŽ~a˜ˆf˜‚[”]•v[—pW•uW t\œuR•pX—nW—hZ‹kZ†[hŽZm‰X~‡T}”M~‘S|G}‹Lv“Is—S{œT€O}žWršTn›WhžHm¨Hs£Gm©Ge¤;i¥>fžDg§@k¨:k´>l°Ct´@q¼Gy¼DzÀ«ˆ6¯ƒB¤Œ4´™B±šA¢¥>°¥=£žLª’Cž”FŸ™6›—.£ž*­™'­¥(©¥"«•$©¡%¤“"©”(©–-•Œ–…0ž‘+œ“ ™‹)¡(Ÿ/¬•+¦Ž,¢–)¯Ÿ’/™ˆ%¢#–›$œ‘2šž(œŽ4š4Ÿ—)ª–)¦’)™‰, (ž•(™—)ª•.ž˜/œ:’†7ž1‚1–…:˜{Bžx>Š|I‡‹R–~X‹t[™‚R yV„bŽ}b•tQšT˜oWŽkak]•r\p[¡sc’iV˜sRfV‡b^•hp—fxŒSmLs•W}‘YzŠV{…U€ŒMr’KuM‚•K™I{ Rx£Xj•Tp”Nu”Rj–LfŸCl§Gf¤QuNq¦Cy¦Ir®A€¦Mƒ·CºG{¹6¼AuÆ8ŠÉ4€Ñ6Šm‰«w¯xˆ¬}”µq‹³rª‚–ª€•«t’©m§x—šy£”} ™„©™ƒ¡ ‡¡‹¢¤‚§šƒ£˜ˆœ›£¥‡  †ª–¨Œ£ž’Ÿž‹ œ”’–ž•ž››ž¡£ª¦¢«¬¤¥§–ª¤¡±•ž¬¥³šš³›œ¸¤ ¬¤›±ª‘±¥˜Á¨¿­À³˜¿´ Î©¡Ì±šÛ´“Ö·‘Ôª†Ú±~Ù¨…Þ³ŒÝ®‚â¬~ì¶ró¾nô½uòÁjæ½bë¹Zù¹]ÿ»e÷¶jú½k÷½còÅgë½dàµb߶oá½sî¼eñµoó¹wïÂrâÀoÜÄqßÉcèÍ]ò¿_æÄgãÏ^ìÊhñÓdôÑgïÇtëÂ}ÛÎwÚÑ{ÑÙq×ÝgÜÛgØÚdÙárÔápÐÜhÚÎfÖÎXÖÆ_çÂ\êÀXßÅJß¿KìÆOîÈUíÇVë¹VؼNÕÆKÏÇIÓÆLϳZÔ¶aÌ´`Þ¼Sà²RÒ­Rз`Ô±bç²Tá¤PÝ£VߚLæžPä™Oà”Mà’IٙGۜGݧV× NߨEΪSΜO՗BЌAґ?ύCӘ@œF¶ŽJ´’?¼‘G»ŒH²‘C±‹5®‹5«—8¯–>ª FŸ£<Ÿ¥A¦ŸFŸ“9©-¢•,¥›(¨œ,¥š#­‘&³“!¯ )­¥*©™,¥Š0€+£5£Ž/žŽ)¢$¥%ž—"¨Ž#©–+¦(ª‘ ¥Ž,–“5¡‘.£—'œ(œ)—”-‘. ™4§›*™Ž$™’ ™!–’,•œ2 š1—“0˜”:•Ž:Ž„?“Š7™„9‘{D‹}B‡yH†‚U“xQ‘z[yWšyX’z\•{R}^xXŒr`kXšpZ¢qe£f_škfœu`‘rZ—kdjh•ip’cyUvˆRq”Yv•TzŒL{‰OzˆRŠNw‰PpQwžL€ŸNy™Ip—Uv”Op“Ug—DgDb¦Jh¡Ou£J{šHyžF¥L¡J‡«M„·K‚½9zÉ9†Ã>Ç=„Ò<ƒn|²|Œ¶xˆª´x˜²r–¬‚Š§w’¬u“£oˆ¦p•p¢”z¢—}©¡{¤›ˆ©¤§—‡¥š…—’Žœ–‹’ž’¢£ˆ¡–“«¥Ž¢•’ž›–¢”–’ž£¡“›™¥©£¬ œ§­£§¥šž«£¡®¨­ ©¬Ÿ¤³±¦±¦š´¸™¹¶ŠÂ±“ꊵ±’À±¢Ñ ›Æ¤”Ì¥™Ú³…Ö¦ˆÐ¢‹Ù°Œà¤~ܳ€Ý»~óÁzî½gø¿rö¶bæ½bôº^óÀZìÂ]ú½iô»kñ¸aï³föÄmà¼fÚ¿iéÁgé·oñÃrò°vé³oãÄiêÃeàÎbëÆgîÀhãÀlàÎZßÓhß×véÔmæËußÍxÚÊjØÕtÙÙv×ÓkÜÖoØåkÒåwÓÒsÐÛoÖÐjÓÑdÙËWÜÆXèÇUÞÃMæ»GéÀKã¼[èÄ`ãÇYÖ·SÒ½LËÂFÆÄNȶ^ɶ`Ô«a×»WÓ®ZÔ©QÙªbã°ZèŸQâœ^á¦Sé¦Tە[å–PæIߘBڞNè¤Nè®På›LӜ>Ԗ@̘NԖ@ڔ;ԎI̓C¾ŠDÁŠK¿Ž>»‰LÁ„?µ“EºF©>«…@¡ŠA¥¡BŸ >£ 7•š0–—4›’-œŸ/¬š4°¢0°–3º”+¶—1¹“-®˜4¬œ.µ$¢/ª},œƒ2Ÿ‰-¡5°Œ1©,¥›-¦›&´’$¯”%®žŸ’0£Ÿ:““4œŽ6œ6””.œ•&“œ-˜˜(¬'—‘"”'•'–&›0Ÿœ*›1••>•ˆ:Šx.š…=“=šC‡ƒDˆ‹HQ”…U’‚SyTvQ–yT˜yT‹uY‹y[•kT˜mZ˜mažu_•o`šrWŠkg“n]hf‚hjŠ`wŽexWtƒPyX~’\q‡U‚Vr„Xz”Hx–S{LƒŒNxKm’Mx“VhšTq[e›Uc˜UeŸKgKoŸU‚—HœS‚¢EŽ¬J…´D‹·Eµ<Å9ŒÁ<Ì=†Ï8~{„¯z‚®q‘°y—¯x·ƒ•²†²|…¥u…¦s˜z›¢wžœz•˜}˜—}—ž¤§€«¤€¢™‰Ÿ£Ž“œ‡’“Œœ˜Š›•’ª›Ÿªš ¤’Ÿ§‘žšž“—¢—–¨“¥ ¤¦Ÿ¢™¢¡œŸ¡ª£¥§ž«¯¦³¨¢®©®­ ¥®–§¹“®¼‰µ±‰½¹–¸²”»©”ƤŸÏ¢™ÊŸÇ©“ѯÛ­”Þ§‡å¥ß´‰è´ƒî¼që´ní±gî¹aô½\øÆXñÃYúÃXñ¸aõ±iù²gú¼kó¾læ²qå·tã½xä¿xë»m÷·sý¿yó·näµhàÂjÔ¾vÙ¼rÝ»jàÆgàÏuÙÍzØÔvàËzÞÎkÑÆmÔÐmÖÊt×ËrÊÛoÒÕuÒÜtÙÎuÙÐjØÉcÏÇbÑÊfß¿XÝÉKéÄJïÃNå»Rê¶Zç½\ì¹Nâ½MßÁLÍÁRйRϲY×·XϲXȱWÍ´ZÚ¯]تTקTå™Uà™Pè\éŸ_áZݤVä™Hî–@éšGߧAã£LÜ¡HїC̗GÑ @ӝFҌCÆCÁDÁ•FÀ‹?ňA‹KºŒG´‹@±@¥ˆ<ª‹J¦I­œN¥£E™š>™™0—“0Ÿš-§œ1§š7¯œ8º›>µ¤A¼:º‘;³.¶“*°‡"®‰,§ƒ+°3§ƒ3®‘5°/§™&­™+©ž%¯›©¢Ÿ!¥¤2¡ž1–¡7’5’›8—6ˆ˜,š'“—. +Ÿ‘2š”+‘&‘ž%’˜4—™1“6‰…2†„4’z*”…1›„6ž:“ŒAŒPŠ‚SŠ„O{M’zZŒqYrN•wRŒqSmZœnU›oY¡j]›mc˜jZ‘sYŒiaŒpa‡qc…hs_x‰cy†ZzŒVŽ]}•Tu•Vz‹VxŽR~‘Sƒ—[yU–Sw’Rpœ]r›\hŸbk˜XjWg—\t™Yt£Pt¥O|ŸW†©P‰£O‹«MºG¶F¾I´L‘»Aˆ·;À<Šv‰«~~³|Š®x†¦€—²{‘¨€…³€Š¨vsŽ ~¤{—›x¢˜¤…œ¢›¨†¦¥ƒ¤¡…›’“Ž•Žˆ£Œ¨”—¬””š–ž¢š’——¡Ÿ’£ ž£¢ž¯®¢¡›ž¢¨ž¥Ÿ§²°¢¦ª£µ©£® ¨¨˜£³Œµ¦“¸­†´«“º¬’¾¥œÄ›šÃ©Â¥•Òµ’Э‘Ôµ„屉筍ݰŒæ²yî½tã½uá­qí¾]ð±jé¾Zô½[ê¿_ë¹gö¸bó¨]æ³dç¼dî²të¾kçµtîÃqó¯oç´dó¾uô¿läÊiÛÄdåÀeÕ»nÞÌqÚËsâÆnÙÐs×Ó~àÖnØ×jÍÊt×ÌhÎÓoÑÖrÓØrÌÞlÓÜmÌØfÖËcÑÉjȼaØÆVÞ¾TÝÃIèºJâ¹UìµSÞ¸^ß³[â¯NØ·ZθNËÄIÌ·UѼP̲Y×®^Ú»]Ò¬PÕ­[ЮWÖ£XۗRêŸRôŸIèŸOâ¥Uê›NڍLè”CےHØ£H՚IϤNÒ£?ٝIË¢<ՓCɌFЅH½ƒF½„=¾‰;ÁBÁ‰L¹Œ>¾>¯„:³‘5 >ªŽB©›@žœ9©‘Dœ@­ ;¢“0ª =¯™?µ“;¼˜@¹—@¹™9·œ,«‹)².·‰*¨….³,²„-·‡:³Š(±‰!®™0©ž.ª%¨Ž ¥ž™ !–” ¡5œ—;Ž=š3”“3‘”7–¥',›—$›Œ–‹›'”¥–œ-—•+‘‡0Ž,•~+†x-ˆ+”Š8ŠxAŽ~@’uPŽ„QŽMƒzLŒxY—x[‘mX’zc‘yZ•wb‘t[–dc’r^Ÿhe™la›mh˜lY‹kcˆll†`l’fo‘ps”bu‘Zˆ—_s‹Pu‡boŠ_mŒX}˜\†PyŽX€‘Y|Ws—bj fc›_obu˜Xt¢Ypž^|œTt—]zŸT…¢Uˆ¯Oˆ¶L‹«J’ºI”»O—·A…°I‚µEÌBŽr‡§v„«v€¤w†¬xƒ±wˆ®t|±y~²{‚®~•¥˜«|‘¦z Ÿž›ˆ–­—­Šœ£„™§–›ˆœ‘ —¥‰¯˜‹§—˜™’š–™œ™’©“¢ž¢žŸ©¥¨££¨¥¥¢ªŸ›¢¦¡¡®ž¦£”®®š´ ˜¯ ”µŸˆ®¡µ¨¸£’¾¤šÁ£’ݙə–š“¼ª”Ê®ŠÓ¼ƒÜ·„Þ©ŠÞ¦‡ç±€ä©vá±oÚ½fä·lç¯hâ¯gëµeë¾QíÆZðÂbì³fè¬cí¶cçºeßÀmæ´në¶hì¸lð¶hã°féºuíÅ{ìÅ{äÇnÝÇmßÈjÕÁrÜÄxÕËtØÄwÝÉwãÚrÝáiÖ×oÔÖcÒ×hÏÖbÊÔhÍÝg×ÙqØÎcÈÔeÉÈ\Ò¹[ξVÔ¾WÝÀOí¿Hä¿Hã½Xç±Xâ³XÕ¸SÔ¯WͳKÌÁNÕÈCÑÀI×»YÔ¸\Óº_à¬WÚ®RÕ­Nß©NÚ¡Pá¦HîžGå—JåžNäŸDáŽHيGۖQ؜PНB˕K՞JÜ£CÑ IՓFȎI͎>dž@½‹@·•CÀ•@ƃJʃM¿A¾‹3¯6­‡<Ž<›ˆ>¤‘>­’F¬’C·‘3°™2§•:­•G¦ŽL­˜@·–@½ 3°’7´Š.«ƒ,­‰;ªŠ-±Ž)´Š-¹€2º0¾#²Œ+©•)¢+©’"¢‹› œ™#–’0›˜=–’8œ1–Ÿ9‘¥4˜ž&˜“(›™““!˜Ÿ%Žœˆš‹‘'Ž&Œy0‘~;‹…7—†2“4’|7Št>ƒp<‚tK~€Pˆ€O‰‚Tšvd—zf—sc{[’yY‘u\ihšgh£ma›qcžhf˜ad˜i^Šheejˆs{Žp}Šqz—g‹f{[t“_{‰aq–^€™X}‰\x†O{ˆSz†Ypaf˜_lbr—`ušTl¨VnªWxœW€–Y{ŸX…§Xƒ°Y¨L…©NŠ¯C—±H—°O•³E¾>†ÊB†p|¯j{²s…²pz³oz½zƒÀr|º||°…‡±‡–³z“¨}Œ¨xŸ|•˜‚–Ÿ‚œŸ‘‡’¨€œ›‹’˜’ž’”Œ–••œ˜¢–¥••£“ª£›ž  ©—Ÿ¥•®§§¬¤—¡¬œ­¤£¨§³¥—´¢—»¨—« —º Šµ£‡¹ª•¹¨‹²®”¯¤º¨•¼—“¼ ‘¸«šÀµŒÇ¶Ö¶Ó²~à¸yê­xä¶nà¾gã»så¯nÝ«låªdä¸Té¼XêºUò´_å¹Sâ¬\íºWâ»YèÂdâ¾rå¯hð°jâºké¼mç¹mæ»mê¼pçÃxßÐåÊpåÉ{ÚËrÞÎrÙ×uâÖráÙuÖÜnÖÐ}ÒÐxÐÜdÒÔcÊÏrÒÕiÊàeÖØnÔÕqÏÆ]ÑÄXÒ»TÚÃPãÀ[ïÄJÚ½KèµTä¬Lç¬Ná±UÕ³VײQѹSÔ¶UÍÃJÙ±MÔ±NÑ«[× L×°TÙ¢FÖ®RÞªSæ˜HçœEêžSݑM՚WۓV֟WәGِQɐ>ʞLÖ£OÙ¥LܚA˕JǍ;ÁŠBƎGÀ‡NƏ@ȋEÀ@ƄI¾@½‡:¶“9¦9Ÿ–1¨‘1£2©”8¯Œ>´™E¼œ=®Ž<¶ŽB°•B¸¡Bº–6¶¥1¾’/°˜;«Ž<¹”<¯6¸‘5½‘$¾…1°)µ‹$¸” ª“±#¤›œ–"˜—- Œ"š(“•8“’9;œ¢:—.“Ÿ0‹™‹––•‰š‹žˆ™!Ž#‚ƒ$†€/’z8ŠxA’‚=t6†:’u:s@uJ‹uLxK–yZ˜{fœ}\ ncra’wgžjj™po¥al¤cX¤ngbd¦md”j[˜^išgb–nzpyŽnƒ—q|Šgr^n•iŽm{˜a}c{PzŠ\z”YyŒVu‰Xq’X|•^lžax [w›V{N{¡N‚¨ZŠ¥Kˆ©S²\‘³O‹¥B®PŒ¸N”µ>±G¼I¾9hƒ°jy¿s{Ár}½wyÉ}yÃ}ˆÂ}†·~Ž±‚¯xŠ·vŠ´w‹¨†–¥–©†’¡„‘¢}›˜„˜„—“‘–“’‘•˜œ‘˜›™™¤–§ ¡ “£™Ÿ‘¡£“¡³’¥²š¨¶§¤·¢£®£ª±š©¹–Ÿ¹—˜´¢”³¥–»£™¹©Ž»ª‰²¦«¤–¬ªŒº­»¡Œ¹²†ÃµÌ¶ŽÉµЯ„Ô·|Û·uÝ´tݺlÛºlà³må³méªbë¯^ä¯Vî¿Zè·Lð·Oò°Yä¶Yà´Vç¿Uï»déºfî®cê²lé¼oß¹kêÀqïÁkè½sëÆ}îÆ{ãȅî҃éÌ|ÞØ}áÙoÔÜkÔÕwÕÛrÊÓ|ÖÒzÕÝqÓÙm×ÙjÓÝeÌÕiÊÛnÕÐoßÅcܾcØ¿]â»XèÀWà»UåµIÜ­Hå®KÞ²KݳMܾSܾTиTÚ²UÖ¹YÖ´XÒ±QÕ¥KÖ¤Ká®Iá¨Lå§WÝ¢PáœLà•EٙM܍TߙOՖTҗN͞LҙM̒Aԙ@̝EΚ=؝?Д6ț=ŞGĒJƏJĐNȕH½GÊ>¾ˆB¿‹7±“9¦.¢2œ‘9¢“5›‹5¥‡C­=¶ŽD»“L´B­–<´œG¼™<´ž<»š;²˜=µ˜>¹™9µ1¸Š1¯.³Œ±ŒºŽ °–%¯š ª’#§“¥›&™–()•”0‹.—Ž5™”8–˜,–+‡“-“+‰œŠ‘‰•‰‘‚”%‰‹+‹Œ-‰1ƒ3„v@Š|FŒz;•wEŽuBvOŒzN{KsSœwT›ta}k¡ug¢|_žtg ke¦ekªf[Ÿc\Ÿ^g¤ge¥[cž_ažiišgfŒsoˆqx‚ut†ww‚w€oyŠt~‘n{™mv‘^|“[q™Wl›]s[o‹ZwšS|—U}¢Yw—]†šTƒ Z¦SŠ¢J…¤M…±L®O‹§M“¦CŠ´J²F·K‡µC’¸9Â7Œe±iv®s…¶nŠ»}~½ƒ°zx²x{µ…‰ºˆ²~‹«t§r“ªš›y™ †Œ›‹— Œ–…–Ÿ‰¤˜™–’‘—¡›™¡ “Ÿ¤˜«™ŸŸ¤–™¡˜—œ®”Ÿ¬Œ¦³£¨²™Ÿ´˜¤¯ž¢¦›¢¬¢ ²¢¤š‘µ ´Ÿ~°¥’« •¨ ‰ª£‡¾›‡¹£¹¨Ä­Ì³„ïwÖ®Í¹t׸wâ´sÔ¬uå³lè®lã»eð½Zö°YêÀVí¶Pð´SçÀ]áÂRä³Uâ¼^çºeâÁeÜÁpà´fá¯cé±aÙ¶kè´ièÀgãÉvã¿zÞÄxݽ~×ÃzÜЃÛÓäÍyÑÌw××kÓÍ}ÆÈ{ÆÜl×änØàtÖÓmÎÙdØÙlÏÎeÒÙ_ÖÎbÖÂeãÆWåÆMÚÅUÙ½LÖ¾SØ®V׺Mß»C×ÂIݶVÌÁPDZLÕ¸[Ùµ]ͯPÒ·RÒ­FӛOҟD՞PߟMä›Mâ”EەOߜF֕NӜM֕_Η[Ë VƔAŔBЛ@ۜKס=ЗBٞLƞHǛDƒGĐM˓G¿‘L½I¾Ž<¸•:±‰:®–5ª=¨;¢ž0¨•< Ž:>©ŠF¨–>µH©ŒJ­˜D® ?·œA±š>©Ž6²Š@¨–A°“>©‹0¯†.·…%·“,­Œ#­%ª'«š«’³™§“# ”!£š-’Ž4—/–’)‹š4–˜/Ž $‰#™-ƒ•Ž%†‘ˆ¢%Žš%Œƒ%‡Ž*‚Ž/†v/‡9‘r4ŠzE“C‚EŽzL‡rG‰sM™€\•{X§yZ©oh wl {d¨yt¤oo du›gf¤uW¦a_ kn¢\g¤e`›nnŸinŠioxvz–rtŽu{ŒjkŒn~n{”b„”cy‹\užbseqgq–^s§Q‚¦aw¡Pq¥SwœUv£S®MŠ®X¤N«HºC†¥NŠ¤I‚³OŒ­Q•±BŽ¶F»D‘»1Šb~¤h~ªcƒ¯o‰¶n®xƒ­n}´o€½±„Œ§v’©r‰¡sŠœu™›z“¡~Ÿ†“§‹Ž£}ž¢Ÿ‡—ˆ——¨¢¬”¦­”¤œŸ£§˜¡šš¦§£¤¥²Ÿ£³Œ›«›± Ÿªœ›«—™¦–ž¤¦ ¦–˜¡–›Ž£—›žƒ£¥“©§Œ³˜ˆ¸žŽÃš”Ç¢†½¢{¾¦|ȲzιuÒ¶qÔ·{Öºwß®så¦aÝ®]á³bâ°Zó»[ôÁVæ¶Wíº[éÀcìÁbæ¼_é¾cçºiÞ¸uÞ½që»géµjè¿fÙ¼cÛ¸pé½rëÁæ½|ÛÇxÛÃÔΆÔ΀ÙÅzØÆwÐÒlÐØmÍ×qÓÌvÖÝsÇÝn×ÏhÙÎhÖÏrÖÜmØÔiÓÐWÏËUÐÄcÝÊ`ÜÃOÐÈKÕÂTÚ·RÞ¶R×ÂHßÀIÛÃJÜ»MËÀJ÷OȸUÕ³TÛ­U×­RάGԛJїH؛FߒCàšIޔLؓJÛ¤EÔ¦MΛS̖ZÉ¢ŢQàDțGבGٔJÒ¢G؞HםTїOďF¸“FÀ™Dȕ@ʙI»A¼7·›=²–>´ˆ3¶<¯š6§¡7Ÿœ1£’5£ŒH¦ŠI£–E­žA®–J¹£Nµ¢Aµ‘<­=¢ŠB§‹:¥A¦†@°~=ª-«ˆ'ª‘1²+±‘ ¹±’¯²™!«”«ž$£œ/˜‘)›Ž&‘.ˆ 0ž.–¡"——$Š“(ŠŒ)Ž.ˆ‘)š+‹™#‹’"‰Œ•1ŠŒ6†‰/„x5„s5’uB‘‚OŠˆP‰yOzG‘uG|Tªz_©wa¨{gœ|i§pq¥mq£ru¡sn™qhv[šw\—hižjk¨ccœmqœoq“mwŠpwŠt}•|~•pulnˆl{Šh~…mƒ‘f…ŒjŠ”d†\Še}e†¤^~¢Vv¡Wp¬Qt¥Rs±Pv«N±O‰³VŠ²Gˆ´E€·Oz©K€¤SŽ¨L‘®J–ÀG‹È<‹¾<f€ª`{±b€°c‚¨q~§w€«w…µs„°‚„µ…€¦ƒ” v›~‰œsŠ¦„ˆ¦|›}‹§‚›¢Œ˜•~¢˜‚›•“—”–›–¨ª˜™§– ™Ÿªš¥¤­—ª¨˜¯™œ²œ©‘•±ž•¬¢®š›¤–¤™œ ˜’ž›“¥š«“†¢š­Ÿƒžž°«³¡|Àœˆº£Š¾™„¿¡„È©wÒ²xˬrÕ±uܸqÕ·mÜ®kå®`ܧhá¶aêµ\ó´Vçµbð¶\ìÀ\æÀaá¹`ãÄVàÅeî·eæÁtÞ¼nç¶jß¼pؽlÓ´\ݵpê¸vèÄqßÅuéǂÔÄtÙÐÙÉrÖÒpÇÓqÓÍnØÔjÐÑiÚÛqÏÖxÐâkÓÕlÓ×_ÝÜcØÛaÖÍ`ãÍQÓÏUÍÀbÚÀTâËUá¾OÙ¹[׿QÛ´VÖ»IܺKоJ×¼QÔ®X̼NϪWשPѦ[ܯ^Ù¤WϖIӑFÔ AݓDזDޑSРFÚ£QТDÍ¢NȘ^ͤVˤPÒªUŚN˜HÚ¤DזPϝE՝I̐FƑA¿ DÞK»—D½ G´ž@·‘Eº”AµŠ6±ƒ5­@¨”@¤–6¦–<¤¡A©J¨œFž“JžR°ŸT§£R¶E·•K¯’?©ˆ:©Ž:®:±…C­<®ˆ1«‰)¬ž*²!¨›#µ˜'¯˜!²¢¹£ª$¡£$¥™&‘›&œ’3“›06”'’”3–˜&†Š$€‘2Œ‰'Œ‹!Œ–*—#‚“+‡“'‚“1ˆŒ2’A‡F—}:—E†E‡{FŒ€I™†V¡z]w\¤wc§uk›mp£yi§rtŸkr­nh¬wpžm[ xo¦lr£hn¦ej§sq’uq—mp“r{’pršnx“s{kn”hr’ky—g‹š`ˆ˜k‡”h‹Œl…›f}’\ˆ¬Uˆ¥W¡OsŸ^ož\{©Uv­S~¬O‚©I„­P}²CƒµF}·A~¬H†¬A–»<ŠÄ<Ç6Ç4‰[Ÿ\ˆ¬h‰©f‚ªl„©w…¬yˆ©t|°{{³‚‚¬€…›–›|Œ–‚ˆ¡…Š¦z¢~”¢š¢‚ž”†¢–™”“¡–“¦ ©•˜ž–¡¤Ÿœ«£¢¨¡¡¥š«™–®˜§’“©“›¦Ÿ ¥§›§¥¤™™™™ˆœŸ†ž”« ƒ©œ~£™‰§§ƒº«x»«{¨z¾›ˆ¼˜‘¾•ˆÎ ƒÎ£‚Ø«uÕ«wÎ¥zÕ¯qÕ£jקcÞª]ë­]è¨eñ³^í³Sî·Yé½\è²`êÁgÞÂ\à¼dä½hãÅjâ½tÛ¹sã½pä¾sÝ»fâ¾ué¿u踂ç»ÛÊ{ÚËtÒÐoÓÇrÔÊyÇÏqÍÖnÏÑwÇ×qÏÝmÆØjÍÖmÑÔfØÛ`ãÕYÜÒ^çÐXáÐXãÇ^Ù¿VáÅVßÂKصNÕ·RÒ¶NʲJÖ¸QÑÁUϲTÑ´RÍ·Xʱ^ΫRǬT΢_Ó¢^֖XҔR֓SܚLӒQ̔KƖKѝNͪDȪKÅ¢PÊ©XÊ©QצXÛªYÒ¨XЩTФMÇ S͗GГGƖIßNÁ¤F¸¡E´¥E´œN¸ŸI»›I¿”Fµ‡;³‰@±‹?¦•D§@¢š@¢¡E  >¤žJ ˜Fœ–O¤™R³’U·˜Pµ‘C§Œ<°<«‡9¥’3­7°Œ;¬Š3ª˜.®š0§›0«š%¨’¯›©§²¦!¤ª"›¦)•¡'˜¢0š¤-•˜3šŽ3–‘.Œ‹(Š‡-~‡'‚.ƒ”.„”"~š(ƒ“"…—‰'(„ˆ.’5ŽŒ<’F˜„B‹?Ž„@•EŒ‡Q’~X¡ƒTœ‚b§t_¤j]¥jj¨sežri¢w`ªvg±~l¦ulŸzi¤rt«kv¢op xr™pg™xmŸxr or£l}›rt”tx˜f”f‚œ`ˆ—\‰“aƒ’dŒ›`‡›g‡£`}£Z„¡\«Tt©Pv¥WŸZ{žSz¥EwªGy«@‚»I…¸A†·@Œ¾:Œ³E‰¶>ˆ¼8ˆÀ?Å=‡cŽ¯`¦gˆ¡lŒ¥e~ªh~·ey°p{µm«zŠ°sœv— r§€’©sž~œ~¨}™…™’‹®— Š ž™¤“—Ÿ—ž” °— ¡›˜›Ÿ« Ÿ©›–¦¡“²˜–¤Ÿ¡¦Ÿ¥­ž•Ÿ ˜››”§š‰¡”ˆ¨–…¦’Š™†¬©|®¤º«†¬‚³˜„¸š‡½œƒºš‡ÃžsǨ{ظnЬoÚ§vѤsà±`ã²aåµ^â·hàÁWéÀ[öÀVä²\í®fã´[á¼[àÃcÚ·nÚ¸yÞÀnæ´v×»m׸iسrçÀeçÃpâ»uä½åºzÒÇ}ÛÍnØÄqÖÊjÉÇpÑÒwÕÒjÚÔmÔ×kÑÒfÎÒvÓØ`ÐÐgÓÌ_ÞÆSÔÂRäÅVÖÉLÛÀN×½PÚ¾P̾TÉÄXÊÁNÑ»PÐÄOÊÉKÛºUݱ]Ƶ`Á¨WͬZÏ´]Ö§\͞c͕Q̛MܕJТMʤFӝRҜPÉ£WÓ¡XɧE̟UÇ¢MɬNÒ¬QÈ°WÖ¦^Ï¡WÁV͙JÓMÈ E¼™I˝Q¬AëOœP¿™L³ Mº J¬“I¶˜J¤‘>¬’;³–8®˜8¥ŠC¤’9£’?Ÿ•>˜‹?œ–A¡ŸHª˜H­¢F§—HŸ—C£…7¤‡6«“;¦‰3¤•6£’4®‡1¯0®‘2¯–/³"¯š¥ª"«®%¬§¨˜%¡—%• 0™¡;Žž/‡™3‰”,…Œ5ˆ™'{•*y)€™*„–z— }–‘(‘+‘—*Š”5‘“8‰Ž2‡@˜‡<™F†7‘ƒCŠ’T™Qª~O«wV¨tg§rl¯plªl^¢{`¡}f¤}m°to©liªugªzp¬ll¢w~œlm¨~r™~vœzt™wz•du™fm˜qu™tr›l}—aˆœf…’iŽ]žb†›`ž^y›WvžW~¯_u§Z€£Uƒ¤Oz¥R‚¤J®L}±J}´R´A†»>’¹?‚º@‰µB‡µ:ŽËB’Ê;†^ˆŸS€¥a¡f‰¥n‡¤ez²]}ªd‚³g”­e•¨h‘œp‘Ÿ|Œ§xŸuŒ y–¡t“œt”˜y¤Ž~«Š‚¬—¦•–œ˜–¡Ž•¨‰œª’£¤’›œŽš˜‘©£ž¦™ž¯˜˜ª¡ ™™›©Ž¤¬’¥¨“ª£‰±¦€©žzœ—xž”„§˜|¦¦‚­œ†§™€ª›ƒ´’}½›ƒ¹ª„Ųƨr˵mʶpЫtÜ­sݧpÚ¯hà¯eÝÀlâ¹`ßÂZâÅSôÃWïÆbá¹`ßÃfæ¿dÞÅiá¾påÀs߸vâ±wÖ¸qдzØ´tݼjâÈiâÅgáÅqØÀxØ¿uÚÀyÐÇlÖÆqÑÃtÜÍsÖÏlÞËhÚÊnÞØpÐØoÓÚnÌÕ_ÒÉQÏÃPÓ·]×¼XÕËTÜÈKßÉPлIÄ¿MÈÃXÄÆK̽LϾRÔÉPÙ¼]Ù¸`Ù®eȯZÙ¨YݪbژeؖdӓZԒQ֜TϚQƛOʦOÄ¢NȚ[͞WÔ¬LÓ¨GҟPÒ¬YʯPÄ´U˪bȤV¾™P¿›QŕFŝQÜLÉ£GĬF¼®D¾žIÀ O¼ EªŸK¦•Bœ•D ŽB¯–C¯•7¯‹:¡‹BA™@˜Œ?œŠBœ“;¥—<¬›F¦šH«žC¢’C¦“6¥„0¤’5¯’1­Ž+«Š+²Š/­ˆ&©Ž1¬,¤¨*¦¦ ¡©(§¬%§¤!ª—.© 7¡š/”2Œ’6ƒ›.„—+‡—(} 1y”5u™(p¢#w {œ‡‘Œ—Žž ŒŸ-‰˜+…‘.‰“5Š‹;„FŽ…>–<”D™‹Nœ}W¤zO®v^ªpf®q^¨m^›odšsdzr§vn¥zj¨og¢tp¤kž|u¤nz©|u­|~¥rt—wmŸhy—jv”snŒqk‰s€•k†Ÿg‰˜e‡Ÿ]™\†–Z_ƒ”j{œeu bt£Xk©Y~¤X‚šP‹Dƒ¦Gˆ¬K€¤Bƒ­J´C‡Á@Š»:Ä=Š½5†½:“Æ>”Ì7‹R‚ªZ‚§]Œ¨\‹ª\³a®[ˆ°k…±aŒ­eŒ¯m—«k–—o”f‰‘mš z•Ÿv”›‚¡“…œ†£‰‡¤ƒ—Ÿ‘˜¨‰›£‘ž¦Š—­˜œŽž ˆ«–£˜ ª•œ¥š•¡¡‘¬œ›œ˜¨«’¬¯…¡ƒª¨€Ÿ–xž“ƒ¡¨•…© Œ¢“{¦•}¤’†§Ž‚µ”€Àu¾ª|Æ£kÄ´hÁ°pÓ¹nݸtÜ®wÛ¸kÙ´nâºmÖ¾lÙÅcäÈ`ëÁ^ç¹Yß¼cá¸XïÂeÝÀcݵrØÀj×´oÙ°nѹmÞ¿hÙ¶mßÊjäÌcêÏhÝÃjÙ»tܺuÙÅf×ÍjÛÃyÙÇvÖÌiÞÓiØÇoâÎpÑÏjÜØlÕÒbÏÊVÑÃVÖ½QÖÂ[ÓÄPÔÅGâÍLÏÈF×ÄP×ÄJÓÆ\˽XÄÁRÓÄQÖÌPà·bܲcÚ±fÙ±_Ù¯_اiâŸc֜dڛ_̚]ϛWМX՚\Ô®QѦV֚OÛ¬PÖ¤ZÓªJљVؤ^˧YÈ®a΢`Áž[Á—XǤJºŸNƜHº¢T£SÁ£E¶¤B¿£KÁ£@¶™8¨“6¬9ž”D˜„=¤‡5¢’4©“<¢Š:˜Œ9¡…A£‘A¤Ž6”;©‘HžœC§‘G¨ŒH¨H?ªŽ-¤‰9§Š9«‹'§Œ1­ˆ0ª‹,§™#¤¡ ¬›*ª¨$žž#§¡)§¥%¬Ÿ$¬˜. ˜6˜™/‡Ž+“*¤3‚*w¥*|¡*t¡/‚¦„š„ ”%…‘–‘”†ž"‹˜'’š.•—/˜‡D ;——;œL¡‘R•„L~J¨|U©kb¦mažka i^”jfš~j¥|m¥qg©vo¡i¨~p¢~uªns¥tx«xt¨u}•ty•pu—fu•dz˜kt™ky—_ža‚–bŠ™b~¢hz›e„£\z›^~›\s©VoŸ^x¡P~ªRŸP†¥I¦M‹¦T€µF†¸>®I—¿D‹¿DŒ½H¼<…¾;ËG—Õ;ŒZªU«Q…¥R†¨^{³Y~°c„«c…¯^†²]…ªc’¤e˜œkœ˜e‘k’Œu™ž~‰ªƒ†ª‡«ˆŽ¥…¤¨Ž¥ªšž ”¡¤˜§¤©¦Œ©—™°Ÿ¨ž¬‰¨¤”¥¤’œ¥†¢¬ƒ¤¤} ¥x¢›€©˜| ‡£™Š¡‘… ‘ƒ¥”{ŸŽ‡ª˜ƒµ—y»Ÿuº¤m¹­j¾·fƵrógдjÔ¾hпvÒÀ~áÃuåÍrÞÈdâºoê¼hä½jíÁ\ê½]ê¾cÝ»mÜ·kÜ´dÛ´nÝ·jÛ´fß´kÛ¾qÜÅoèËmàÂyäÇsÝÅqÚ¿kÔÍsÒÊpϽpØÁtàÐx×Íj×ÊpÚ×dÕÙ\ÖÏ]ÕÌTÌÌNÚÄIÖÂPÜÇSÑËQÖÂOÖÀDÓ¼GÓÈJÉËGÏ¿OŵZʸ[ѵcØÁ[âÁcÛ¹[á·\Ú±aâ¤Zâ^ښdٛdДdӖYÒ cқ_͚aÌ¥bͯdÒ©TÓ¬XÞ­Yâ§[Ö¤WͤUÕ©cÈ«ZÆ£^əVɛS¾œM¾£S²¤U¶ªX®¬V³¥Lº˜C°›>±–8·š6³™:ªŽ:¥“0¡‰1¦Š-™†9’6£8¦†7ˆ8 ’.¡5 –<¡’B¥H¦‰HŸ‡Jž†Až†C¨†9¬z4°}3°9­‰.®Œ+¬‘)¥–%¬—$±˜'¦˜+®¤.¨¡%«§$§¢$¨•"¢”,˜‹$‘+†–0†Ÿ,{¥"{š'¥.z§(ƒ® „¥(‚ž%}œ!~˜ƒ—)$”™!’&Ž’)“”8›–7—–:ž“8•†@š‰M“ŽF—ƒO£€ZŸvfšms£un™|f›rh sj§}b±yo©{m®}j³xm®uv¯xz±x~¬qy wužxu’vy”ix•ho˜`sžet•b|”[ƒ˜_„ ]}d|•\u˜`xžVoœWtž[s¨Vv¥N}©GŠ¦?”­GŽ¯I“¬K‘¸MŽ³=´F—µL—ÁR“ÆJŒÉKÃLˆÄB‘ÎC“T†¶`Š¤[‰®Y…£Z}£^}±`~¬g€¬c‡¢d¤^›a–ž]——q–d“Œp›‹u¢z¡‰ˆ¡…‰ª‡¥˜£—› “¢¥—™¥•¤‰ ¨ ”Ž ™‘™ž—œ™‰¥›Ž©£„£Ÿ¢¥†§¢‡©¡†­Ÿ„¨”‹¡…œ™ˆ¦ƒ¤‰¦†„Žˆ­–‹¦œ…³œv²œwÁ›g¹©m»¥fÀ¯v¿³mÌ®pδyÕ¾rÕÆoÕÈmÕÌnàÆlݸoß»jßÁ\ôÅeå»^â¶lçÀmÒ·gÖ´`Ý®cÖ³hâºdÓ¼qÛÀuÞ¾ráÊrãÑfãÊrã»qؼjÍÇpÇÐtÌÁqáÁ}ÚÃláÔiÙÒqáÐ_ÐÍkÊÊ]ËÒSÎÉNÒÉVݾHÔÊMÐÓQÍÌIÔ¾=×ÆOǺRÏÁG˲SκXм_ι]ܳaرVÛ°Vá¬_à¸\Û²]Û¥]Ü©^ݬ_ښYݐfӞW͚SÕ Z̨`À VÒªHеQ߬SÖ¯Wͦ[מSʬXê]¹šg¼©aƤLÁ£M²¨\³ŸMº¢V¸X°ŸC·¦@²˜L´–>³›>¯“7¶“9 ‹5§‡/¨…/¤~: B£–=Ÿ‰1 Œ<¦†1 „1–ƒ?œ†HŒN«~N …KŸ†<›Š?¥ŠB¨}3¥ˆ-|,ª‚+¤‰6©2§.§œ, ˜0¢+¨”#²¡!©§¢Ÿ* ¤"« *”˜'Š›+„£"y¢*~ª0|¢"„Ÿ.~¦'x£+„Ÿ&uœ&~“&ŽŽ0•™-ž  Ÿ+‹‘8›œ>£5œ—=ž’<Ÿ˜=¡”LW¡‘M•ŠS›{j xm£sc•um kežzf§|k­i©sq¥zt²vs°wt¯v}°|q®tsyp®~o¢km“fw’fu¤e}’`yg‰›b…`}š^Ÿb…ž`–[v ]| Tv§U€´L}¨T¯JŠ±LŠµRƒ­L‰°@ˆ¶C‰·I•¼E¼D‹ÁO‡ÉX—ÄF„ÈF“ÑL•ÑESt°[{¨Yƒ£Vˆ¨V„£]¯`¤`„§^•°Y”¨Uˆ¢\‹aˆ’o“rŽŒešu›t›Œ„¤‘‡”¨Ž”§˜’«œ–¡™šž“™¤¡Š¦¥‰›¡’Ÿ—‘˜–•š”‘’‡˜”}£–v ¦}¢~«’}°‡¨†ª–©”„¨Ž‚¡‹{©„ˆ¤‹†¥‘Žª†­™‚°šr³ iĝjǝo»£j¬iͬtίvÚ¾xÓÌjÖÈhÔÅdØÂpÖ½dàµeæ¼]é½dë¼jݹhÖ½h׳`η^Ò¹gà¿jß¼hÞÃkÍÅmÈÏsÒÊpÓÅnäÌfßÀhá¼gÎÅ`ÉÐfËÍtÞÅvåÔxàÙqÖÖqÚÅh×ÐgÄÓbÇÊ^ÑÈLÛÆRÝÃKÕÄUÇÊMÇÄPÏÂCËÂ@˳MÊ»O̶MÔ³WÕ¯RÛ»RÓµ_Ù·_Ø°Z×±Yå²^ë°eß±`Ù¨cÙ°]Ó§ZٙhݝbÕ£TŨVÁ¡U¾«K±JDzJÒ¬L΢LɛW͝UȦQ¾œU·¢dÁ§YŨOº­V¶¡S¹™L¯¡O³£R¶œK°˜JªžM§—F®ŸG±žF±“:¢.£1ž†<£‚:Ž8¡–B©–7¡„/¤}1šƒ2™ƒB™‰I¦…I¦Qž„M¤zF ƒ:£…:—‚1›‡8Ÿ7˜ƒ.œƒ1˜“2žœ)žš*œ¡&ª—(«¡&¬¬¡ ¨Ÿ+žŸ#£§( °)“ª(Š®0y¬+‚§*‚©&¬&ƒž2›'|›&{›t•„˜ Š•(Žš(–™+˜ž.Šœ=‰–C™8—–E“—A•“D–—L˜’N“Q‰`Ÿ‰^˜z_•xc™mf›op¥zk¦ƒi£ti«se nk¦oy¨y{­xv¨}}ŸxzŸ‚|®msq›gw™sžo~škƒ—j„›c{ g{¦Z‚ Zˆžc}œ\y¤_{®b}«]…µS¸X«[Œ»]»Pƒ¶H’°D¶Q“²P‘´M•ÂB‹¾RÆU¾NÆMÄL‰ÍN•W}©X€ªN…­Z…­[‰¦\ƒ­[ƒ«b‡§^‘©]ŸW‘ž_‡œe¡q“ d“oŠ˜pŠ’s—‡{œ‘„‘‘¢Ž’¤œ©š’°š¡’¡Ÿ£š”ª’œŽ””Ž”–Ž•š‘Ž”›xš”|œ¦vœ£z¯š{«„©†²§—~­‘…¨Žyª•„§‡¥‘‰©ˆ‡°|§šiÀœn½¡ihº©h¼¦sÏ°zйwÔ·mߺhÖÂnÕºnè¼fݼdå´gå¹Yâ´eÖµ_Ú·jÙ¯]Ó«bÛ±bϵiÝÀbãÇ`ØÃaØÁgØÅ`ÑÊfÞ»`ÜÊYÛÌiϼgØÐ^ÈÌpËÄkÎÄvÛ×}ÞÜjÙÒhÍÏgÎÇ\¿ÍWÁ¾TÒºSÓÆTÔÂIÓÀDÏÄNŽCĹCϺLÉ«NÊ»K̯HÒ·XÉ«Wض[Õ²TέRѹYáµaÚ¬^׸aá´fÓ«e×°`Ú¤h՘cؘS×¢TœTÁ£O·«SÈ©D½¨F½ŸA½¢QɒGəPȞX¸£]¾›f¶¡SÆ©QǚL·™Q³™U¾›L¶—F¨žB¬§D±žJ¯ŸAº”J­ŠJ«‰C®‘3˜‹6”„3;”“?¡š9—‡7š‰6›ƒ<›Š4£‚;•~G¤€K|R˜vP †J“…9¤ˆ:~0“z.šz,‘}6ƒ0š‹4“š-š—$“+Ÿœ(«–) Ÿš.ž™#œ /›¢$‘¥4£&¡'y ){¢5Œ¨3Ž-ˆ™7ˆ§,{›"… €¢‚ ‰•3”-‘—/‰ŽB‹’C”<™ŽD—ŒA˜˜O››R›˜\¥žX•`©e£’_¥d•}^¤tbœxr¨zjž|e«rbª|iµqj¬x®€~¥w{«|œ„}­{°zr«q{›g…¥sz£pw™n~”v€™i…£j~¨\|¢g€^}ž`x¥e…¨fƒ³W„¯aƒ·T‚¸ZŽ°Wˆ³M‚·Hƒ´E“½G…¹IºK‰ËHƒÀIƒÄTŒ¿R”¾MÏS”ÏR”A†¦Jƒ¯Qˆ°Uˆ°T‹¡Q’£K¤UŒ¡RŒ¤\†–e}–`‚ _‡—kŠžr…˜gˆ”eŠ‡oŠ–•ˆ•‡˜ŽŸ™ˆž ­›˜¥™•Ž™—¤’¦‡Š™‹Ž“•–”•‘}š˜s ¡zœŸ|§’w«u²‘}´—t©”y©y«“³’‹ª—‡¨–‚ª‘«Œx¬•o½•tßoÇ£kÀŸsÉ£tÅ­uɬyÛ¬nå²dß»dà·aèµ^Þ¸Uà¹]׳^Þ·_ß¼dÖº]ݺ]Ô³b׺gÓ¶fÓ·]ÛÆcÔÀcÑÄ]ÔÃVÕ»_Ù½aÙ½]лZÎÊ_ÖÔlÓÎlÑÌsÍÌuÚ×rÙ×tÏÓbÊÇZϽZÃÃTǸQƽSÍÉPÐÇDÍÈCÌÇBýEľOɯZƱVɹK˹JÒ¯JʲSǪTÒ§QΦUØ´\ß²cݵbÞ²`Õ­gصh×´i̳aϦ[Ɨ]ɗX˒Y¿–M¾¥H½¨M´¬Qµ G¶£M”FĚMǔX¼ Y¸£[À¦_ŧYȦMšQÁ›M¼™Q°œR¦¦H žA¨¡?­—<µ“H­ƒM«„@¤‚H—„@•ƒ<‘Ž<‘”7ŽAIŸ@™<Ÿ‡7¨5¢}>¦ƒC¤|M¡wG’‚<y0”}5˜z2‹}3‘‰<“ƒ:—€8–†)žŠ$––*’’'™œ›˜ Ÿ”$”–.–£,’­0—ª/¤7„¬.Š 1¥3€ 0‹¡1„*ˆŸ+„ª(€¥€¦€¡"š'ƒ™6ƒ @‡™?…Ž=†Kœ‡O–ˆM˜–Jž˜P™¡[˜]žš]ª›g±™c¦“^ª˜b ‹] ƒg e£{m ~l¯rq°vo©{y¯y¤|l¦|p¥„x¡|¤€|«twžy¢r¦r{¨jŸr€ pv¦b|ªd³^y±c{¶^€«]~§iy±g·d‰³`ƒ´U´VŒÀX»K‹¾CŒÁI¹Iƒ·Qƒ·S~ÈK…ÅP‰ÈRŒ¾X“Ä]ŽÈZœÑU L˜L|Z}œXŒ UƒŸS˜£KŒ¤S‚ž]ƒ›X„›g‹–h…¢`‰ša‡”lŽaŠŽi’x†‹Š’šž†—•—›’Ž§ †ªœ”Ÿ’’ŽŸƒ™Š…—Œ‰›‰ƒ”Œ„›Ž‚–‹}’z¤y¢s¯™s©–s´ˆ±“¨Ž{¨ˆš’w­Š‚²ˆz§’­—t´›zª›g´•w¼qŬx¸£n¾¨qȸz̲uá­lß´dÓµ_Ú·hà©fã¿eعYÙ¿gÛ·]×±]Ô·S̬fÔ±_Æ»eÔ°fÕ¶]ÉÆ]ζQÅÁ]ϺPÏÆ\Ò·Q׶]ʽeÉÅdÇÃ]ÇÏjÏÔuÐÍrÒÑqÍÓ{ÕËgÐÖaÇÒ^¾Â[ÎÃQżSÐÊLËÎDÆÎGÕÏQÍÀI¼ÄPξWŹ^Ê¿WкTͱYÊ£ZŧLÐ¥Jϲ\Ò¯aЪcض\Я[Ù¯eØ­iÔ®bÒ¬Yͳ_ɜRŞZ̙]ßH¾¨N¼§IÄ¢Q±ŸP¶¤EÒDƏE¼‘T¿œU¬¥XÁRË P¡RãV¶T²§W²¢GŸŸF¨¤Cµ–C´›?¸˜O«‡C¯F¢’>•ŒKŸŒ9˜‰5šŽEŽGŒ‡?—‹B~<ŽG†:vA§AžyIvH”yBˆƒ:ˆ€B–}7‰‚;˜Œ6š‘DŽ‘.“*žˆ&œ/””.¤Ÿ!˜›¢™š'‘¤'Ÿ$’¡-Ž¦.„Ÿ-£&Š¤(z™8|›:†š4‰›4|¥&Œ¯%y§‚˜!ˆ™1ƒ 9‰8ƒ’B…L“N‹”@Ÿ’Dž”JœLœšU™_¥–f§›h¡“^²f¢Œ_œf ŽXž^¥{f¨wj¯v´‚x²zs«‡t¥€t³…s …sœt‚±|€¯h£kyŸ~‹¢~‚®v‰²p}¨n{¬qv°dz«pˆµk|¬i·`‚·aÂc|³^|½f‡¿g†Ãe†¶T²R‰ÅT”»E‰¿M…¶_ƒ¿RÃRˆÄU•ÎU•Î[’Í`—ÇW˜ÔSªOwŒZ|“Z‚”M‚œQƒœLO…¥[‰¢UŽŸ^‰b‹_‚œU}™Y‰[”d‹m‡—uŠ–~—’z›š‡š¥‹Ÿ—‰¥ž“¦˜‘™‰›¥–…¡œˆ›‘“Š‹œ’{ ’v–’‚›{¦šp¡Žk©’s°‹…¶ˆµ“‚§”z˜†~š‡xœŠ€¨‡~«…t«u­s´•k²¤t¸ªw´¯f¿¯eÉ©p̳wЧzÙ¨pÜ¥nЮhØ©fß®bà½fÛ¿a×ÆdÕ½^ÕµZÜ´ZÉ«`Ƴa͸[ðT¿­VǵRεXȱSÈÀVÃÁP÷XξWÔÅ^ÍÆ]ÐÁ]ÌÅlÐÌnÎÎqÍÊsËÖsÒÛ^ÕÕYÒËaÈÊaÅÅZǾVÁÈJÃÈLËÁSÐÆRÑÅOļLÁÄJÌÃTǽPƾOĪQÄ¥W»¬S¾¬Tî\̦bÖ¬[κd˵k̺bʸgÆ´hˬ]À´VÅ¥X¿š[Á¨RȬPÁ®UÁŸN·–J¹G·AŞ@¼œI¸‘J½¢H±¦IŸPœVŔPÀ›Y¶ŸW©§S±ŸS¨˜Dª”@°A¯D¬LªL£@¥L˜ŽJœF†7˜…AŒ|Gˆ‚;Ž{<”‡>ˆK•}Q–€J¤‡L¤Q“sJqAŠ|H‹~@Œ‚Eƒ=–A•B””6˜‹.Œ*ˆ-šˆ*“)©Ÿ(¨›š › (ž›$§#˜ #ž)†¦.‡ž.~š8uœ9|7ƒ˜:…›.‰©+ˆœ'uš&’&Šš/‚”7‹I‰G‹›@‘–Nš—K”—R’ŠVœ™Uš–V‘Yž‹\¦Œ\°˜h¨“g©“]¯W¥‘]²e¯zf¥nª€x­‹vª†s°…q·‡{©|‡£v‚ªsz²k‚¦sŠ¡~…¡­|ºx„¸g}»d†»o­x°u…¾j†¾n|¾o†Äa~Àa„Çi…Ã`ŠÉbŠ½Y¹MŽ·G–ÀR½[¯_†¾^‚»^ŒÉf™Éb—ÄgŽË]–ÊQ–ÑQ¥T~˜P”K{M‹—V‘˜K“”W„ŸZ•V}›U‡‰X‚Š^‘X’`‡_ƒ‘l……j“’u•—|œžr›’‚œ„¤š‚¥“ƒŸ•‡£—˜š””§—Ž¤‹€ …™…‰£”{¢“s‡v›’xœ“sª‘q¦„y­‹€®š…®‘Œ¦Ž…£‘{“’u›„wŸ“z¥Œt®ƒw¬‡n©Šh¸šv´ j·±m·±kË«kϦlÒ¤hÓ¨dÖ®kέb׬_Ù§eÖ±]à´Y×®TÛ¹_Ò°[ϯVΧdȪ]Ê®]È«TɺMýMűXÆ·M¾¼Y̳\¿»ZÁºRý^Æ·]˽hкfÏÂkÐÃnÉÍeÓÎrÇÕgÔÚ[ÑÍ\ÕÈXÇÃUÃÊ]È¿PÇÍQÊÄWȽNϽKøIÒ·]ѲS˲\ȺRȨOÁ¯YÀ§U¹£YÇ«SäaͦdÓ®jô\¼°fŹZ¾¼ZĺaÁ­T¸¤\Á¬fíTÀ¬UǨTƦW½–HµœK½£Iº¢H¼ D­ H¸ŸC¼¥S½™PĞN¸¢T¸ N®›V¥›V¦¤EªŽ=¨ŒA§’Fž‰OŸ”T§”Q—ŽP¢‹K¡ŒIŸF“‰;•„B“ƒ9“vC€<†G’„Hš„IœvP„K—ˆS’wI“qB—qD‡‚EŠ€<€>—†;™B™‡4 ‰5“‹0ž‚.©†1¬‹& ‹¤‘%œ‘%¡™#’˜+—.‘ %”%‰¥'Œ™*‚&x 4xœ9x”:„ž<„¤&zœ0€—)…¥4¤9‚›:ƒšI‰’G;‹šH ’Q›’R——_”™b“—] až“\±œeµ˜k±—i³˜]´`¬“f±•h¯g´nªŠx«‡{®‡{©w±|­€‡¤z†ª®p‚Ÿr†£~‡¡„‘°‹®‚’µx‹±t}Â}}¹}·tŒ¹s‹Àr|¹nˆÁf„Àd}ÃnvÇ`„ÏcŒ½a…¹M‰Æ]ˆÀS½_Ž¸_‰·dŠ»\†·`Åk”¿h•ÍZŽÈY¢ÏW›LŠ•S†•P€ŽS‡‘U‚–K‰V‘’O…•S“J{‡X|ŽT‚‡XŠ‚e€rƒr‰„q‚v˜|œy”–w—‘†œ‹Ÿ“Ž¡”Š˜™Œœš‹“›š’Œ…‰€ŸŠ€™Œw €yšƒs™~x…w ‡™…uª”€ª“†¯—‹­‹…ž‰„~¡–£“w¢’x ˆv«†t¤s¨u²£m³ t¾¬kË´cΪiÒ¦fË­cÔ¨hÒ¤_Ú£XÓ¤bܱ\à²Zصaá§VÒ¯YΨ`É¥aÓ®Yȱ_Å°Wù[ɵOÆ°Zº²TÁ±OǵXξSÄ¿^È·[ϳ_Å¿l˺nÙÂoÕ¿dÏÉhÎÍlÐØeÆÔhÉÐcÒÈ[ÔÌWÉÊXÂÅUÀËL¿ÆQ˾YƼUξW×·WÕ±\̨`É°\ǤPÀ©QÄ­P½©V»¤RÇ©WΩYȯfÁ¬i½±_ƹT¿µY´·W¹¨b´±g¾¬añ`¿ªYÄ¢SşN¼ TÀ”Q¼šR·šEµ—H°¢@¶§H¸›L¸šX¸˜R¼šO¶¥S¶ M¥Oš‘BŸ•F›•HŸ‹TœV –N¢’W˜—P ’VœLš‚E“‚A”‰=•~9˜…;‹~K–~K’yM–{C{I—…I~S–„PyJqOyMœ„L—‹GŒ;’Š?œ….–-›–2ž- ‡+ª‹/ª‘,£•$¢’&œ‹&‘‡(Ž’+„*š%}—£)|¦/|§*s«1v¡9~©1€«/…¬+¤6vCz§Eƒ›N‡˜EŒKˆ’G–”I–“PšO‘˜[™h™ŠdŸ‹l§še¦˜e®˜f³•a±œZ³šd»—cÀž`µ•l¸…s±ƒy«ˆ†²ˆ³Œ´ˆ‰º°‰€¬€ˆ¦vƒ¦v}¡z€«u‘®±|”±ƒ²‡‘¾y‹½uÊtÌs„Ây…Àg»e€º\ƒÉaxÇb‰ÍZŠÑ[ŠÆZ‰¾V‹¶X‹·`‰¸jŠÁ^…¼bÂf†ºmŽºn—Åc–Ô_Ñ_—T…›O—R‰‹G†šJ‹ŒG‰S‘RI{’NŒVO}ŒYˆ‹`ˆ—gˆ„~‘ƒp‰Œq‘‹~{—u›Ÿ†˜œ‹ž“•˜†œš—š‘•‘‘|‰Š•‹„ž‡€’‡y‘„r™Œv•}j™„o—‡o—•{˜‰u«–ƒœ†¨“©‹y—••†z¦†w’w‘x y£k®—j«œm®Ÿp³¬sŤdË°eÓ³bÏ´Vʪ_ΣSÕ«aÙ©bã¨Tå¨Ræ¨`à®Yϳ\ɪ[űZ͵Q¸X¼°Y̺KýUűUƸS¾®MÂÀV·¶TĺZÉÀ`ͲZÆ»hмcβjɳfÆÁiÓÈtÊÒaÈÕhÈÁbžeÆÄSÇÐZÉÐKÂÍIÁÄN½ÃVÄÊ[ȹZ˸QÔÀd̹Uʵ[Á¯UÀ¬\·¥\ĪW©XÇ¢UÁ²`ϧX»´VÁ²\Ä¥S¼¶Y¿°_¶¯Uº©`çZ³^Á®T»œPßK¹“A²ŽD¶œ?½F·ž=«¦;²£C»žJ­˜S¸ F»˜O¶˜FªšG¤£O£”G›–>§ŠD–’[ ‘X—M–’U¤’G •I›ŒG‘ŠF“|A~5•‚9”‡FŠˆBvB•@Œ‚M—zO‹rHš~S”tQIˆROŠ‚J”€H˜HŽ„I”Š@••=›’.˜™4žŽ2¢6“‰&–Š)”– š'•’(•—/Š+ƒ %Š¦0~¬0ƒ©0w£&€¥/r¤:|­.zª5tª-€¥/‚œ=z—C•=’I„ŸF„™I¤Gœ›Pž‘X”›U˜ŸX¡hž˜i©—\¤™]±›h° `¨¡b¼‘h½fµ‘d¬’l·‰y¬yt·…{©€­„°•†·‹Š´Œ~´}„¤~†¨€~¥~´{•±z’ª|Šº|°sŠ»u“Éq”Àj•ÀpÅ}–ÆsÀj€Çn‚ÃjËczÊd‹Ï\€Ð\‰È[ŒÀ`ƒ°fŒÁfŒÂf¼o„¹`‰¼mºb¿aŽÌ_–ÆZŽR„“H{”?‚›Gy”N‘R‡G†ŽDs”Av‘NuN|ŽSv—c˜jŒ’x“{„uŒ‹{˜†mˆn“–m“}•™Ž‘¡›„’…ŒŒŽ••}˜–‚š|—”s“‹u›h›ƒl¨yj£|qŒwž—o¥”x˜ƒ–‘}š”„¢yz¢‹n™…n”Œo—n›y “s¦”l¤¤eª˜b²j½ iȦcɲ^È®UÈ´OάLß³JߪVÝ®Tä¦ZÞ¨NÜ°SÊ®Pȱ[˵OƬHĹQĽXÊ¿MÁ¼M»µKÅ°WżX´¼T¼ÅQ»½U¶¶WÀ®]ʱWÅ´`Á¯`»µ_ȼkÊÁj¾¿lÂÅ_ËÆgŹ_ý[ÀÏUÉÌXÀÏNÂÈT»Í]¶¿^¸ÀYÁÁRǾ[¾_¾·_Á»gÅ·_¿¹Z¼©VºŸMÆ¡T˟OĬRƪ_¶¤\¶­[Áª\Æ¡XÀ¨SDz\¿®[©S¹¨U¼¤P¾›A¿‘?µ•G±™G³’9´™:²œ8±£<²¡O«™PµžJ¼žB¼˜G¾›B® E§N ’G£›MšQ Jš’TŸ”W¨˜O›“I’–L”KŸ„=¡:›†=”‡Cš‚C£xHœ{>—sK“ySQ›zI•†KŠƒUŒ}W‰yI‹~Mˆ{F‘€E›D˜ŒE@’œ=š™A˜‘@Œ’6”0—Ž)”“(‰œ1‹’<Š™5‡5†¢(Œ­%†¦0ˆ«(x /yž-u¦9m«8n¢0lª:xª6ƒ¨7€•A†”9†–<†¦D…¨M’¨S™ Oš¡V”›Y£”_§b£—dŸ‘Y¨’^±•fª’g­”q°Ÿn·š[¬–a°t±€g°wk®|n¬„w¨‹€°“€²‹¯‡µ†‰°|~¬|…²~‘®}œ¯s–²|Š²v†¶q¿t¹m”ºiÅu–¿v•ÇuŠÍpŠÊp‚ËcƒÂh{Çh~ÃdˆÊiƒÀa…¸j‚»sŒºk‰Éo‡Çj…Ìh‰Ê]†Ê]€¾\ˆÇVÄX–N~”MzIy”MsˆM|ŠIy‹L‘Fo†JJ|W{ˆKu™W€Œe‰r‡q‹‚|†wŠj›ˆrœ‘q•š{”†—•‡ŒŸ’„Ž‹‰—Ž…”œw’’{˜›v‹‹r™’mši•u§n¡e™ˆk¦Žp¤˜|›››€””ƒœ‰y¤•z”Šk˜s’šs¥p§—w©—k¦ž_²fµ¥cÁŸV̧UÁ¥R¼¬QÒ¦QÙªMÒ¡Nå¤Tß¡Nç­Lè¦KÙ¸GÍ°GÒªXƳGË»QαFÀ¼MÇÁVÇ»PÀ¶\ı_·¯[³¹Yµ°T°¶O¶µa²¨[´¬g¸ºb´²i±Ã`¿Ãiк[ÀËVÈÁa˺dǹaÁÃV»ÈZÂÐS¿ÔM·Ð[ÀÆ\¼ÃY¶ÊV»¹`úZÀºi¹¼eÀ¶Y¸±_»±e¶Ÿe¾£cĞRŬW»®P·®L«¥X±žU¼£R³ŸR¶šP¿›T»£Z¶¬O²£UÀ¥P¸™G¹™B·’B¹Ž8®5´™<¶ŸH¥™;¥—O¯¢Fµ˜K´•@µ¡A¯šK¬ŸJª’NžŒQš‘IªŸV ’J¨”Q«ŽQ§šU™”H”I‘‰@Œ8œ|>š‰C—‚?™„;™ƒA™xE„IŸ|HšrN¦xP‘€L•ƒG•N‡{B‰G†y@Œ‡A›ˆB’IŠ‰A…’J”L‰‘Gˆ•@†‰>’,‹/’œA—0€™0‚ž3„­)‡¤0…¢6}Ÿ&~£0}¬.}³,w¢,o %v¡)z¡0}œ-v;{<„¥>„ŸBŠ§H‹°J‘£SžªX’ TŸšW¤ Zž¦dž—`¥›e¬‘hªjŸ’i«—c³’h§–e©h²†t²tt²uk§‚u±}®˜ƒ®Š{´Š‡´‚ƒ±~‹©~Œ©t‡µŽ­y—«z…´x½m„¹gˆÄuˆ¶o”Âx“Æl”ÁtŒÆu’Íj~Ðl„Îk‹ÂcˆÇ`„Ée…¾i}Âg€»n†ºm¾eŽÔhŠÉkŽÏY“Â[‰Ç\„Ë]”ÀSš?}ŠFt@|‡Hx†NyƒEu~@u|CvE‚~E„L‚“T~•d„f„r™Šv’ƒuŽ†n•‚p™r–{™“r’“u†ƒˆ‘…„‘‡„“|Ž”€žƒ‹™w’™i‘–h’k“—m’‹hœˆg¢†jšˆf›˜m¤›x™¢w™—z ”v›‹wžŠyž”wœŸm˜št•¤ržm¢£b«Ÿe³—^´žT¾ªUÀ¨W¤KÀ©O¢OÓ£LۜGß Dá£Bà®Fé­Eà¶?Þ°<ϱHűIżIÑ¿LÌ»L͵Y¿¾YÆÄ`ǾYð\¼³`½©W®­T³§Tª­]¶­e±·e¸¿g³À_À¿dŽZ»¹]ÂÅSÇÉZ½aÆÃ]ÇÃYÂÁPÀÐV¼É^¸Ä_ºÈbªÃX­Äg¶¶g¼Àc»g½³k³·a³¨`¹£e¸Ÿ[µ£aµ¬]¶¦L´©N±¤G¨¤N¯˜W­T»•VÁ¥V¾¥W· T»PÀ›D¿ŸH·—B»›;¸™:·Š8¸†=¨F£ŸC§œB«›C¯“A«š@±œH§’K£–W©•V¢–R®šP«˜K² R§–I§ŸQ¡˜NšG–’D”’8—‰8œ†:•€9Žw>Š|=‘9”~B•€J|B˜L {JžsI‘wAŽv@‘€I‡†M‰A“}N•…M‹ŠC…ŠEŽ“AŠ’E‹Ž>ƒ“FŒ˜@’<”ŽF‘AŠ“7„–7€¢0ƒ¨*{¢'y§.t§2|¨)|¤'}¯0oª&qœ$f›$kž-u¥)y«3…°=Ž¤CŽ¯P—³PŒ¬U®_Ž²_œ©Q¢¯X¢©UžŸd¥£f®•q§pŸ–ešŒh˜›gŸ˜g¡‘iª‹i¬„m²l·yl±~l¬Œz²Ž|­‹ˆ®Ž…°²ˆ·ƒª{´v…®tŠ·qŽ¾sƒ¶p½gµm‹ºt‘Âh‹»m‘Èd•ÆjŒ¿kƒÈv‚Ìk~ÌmŠÌqˆÂd‡ÂiÀl‡Ät‚Ä|†ÐnŒÓd†Õg‘Ï^ŽÍ_ŒÐdÈi”½^ByKsŒHj†BsŒFp‰;iƒLjvMqvK~~UxVu•[u›V‰k‡ˆi„ƒx“fˆ…o”„k”y”~qˆvŽ€ˆ’„„ˆ‚ŠŽ‰‘“‹Ž{‹”xŽšm’ŠvŽ_˜o—•e†k”‚^—ˆm“–j”“w©{£¡’˜z’“w‡}–‘s“•u˜“u™Ÿn™”f©`³¥^²¢X¶¤a¬™K· Tº˜ZæVɞLíMëGɱQÒ¯OÞ¬BØ­JÖ·HײOÕ»LÇ·VıK±NDZB¿OÎÃJÈÀUÆÁ^½­Uí`µ²b±¶a«·]®±V§¸R§«^®¶`¯³_»¸\¼ÂQº¾_þOÀÁWÁÂVĹ[¾ÀZË¿YÉÆ]ÂÈ\¿¼\µ½c´Ád¨¾`¦¿^·Â^µ­W¸¬]®«Y¸±f°£a»ŸV¹ŸUªœ\±§O­¡G°§P¬ A´žGµ•S¼–]µ›V´¦[Ã¥ZÀ¥U¸—S¹›M· E±ŸD²”D½ˆ;¸‰FµŒ8³ŠD®—:¢›;±–K©•G²šJ­›B¤›J™FžF¤•Rª’F®ŽK§™I›N¢™FŸ?–A”‘H£–@¡ƒA“Š;™9 }>–€7‘€:‘…8˜„D“z9•yG¤sDyIwL‡€L’vH…{?‚y?’~Lš}U„~Q…†M~}H‘C†‰C“HŒŠIƒ‹;…ˆ:Š=ƒ™:‚›6€›1‡,}«9x¥>wª0§$u¬4p¦8o¢5k¬$i¨.a©6sž0u¬6©B‚žAŠ¥R•³\–¶`ˆ¹c­_–§Yž£PŸ«R¥¡_ª¡b¨“c››o›f œf ‘c d¯_¬c¹„`»~d´‚h±sµ‡n½Šs«ˆs¶’ƒ­|·z…¶€Šªz{¨w€²q“­n}´lx¬c‡±b‡¹sÂn„¿nŠ¹o™Ëk™ÂlˆÍk’Å|€ÂkÐw|Ìj‡Ám}¸o‹¶o‹Æu”½u–Îs…ÊkŽÌkŒËg‹Êa”ÅbÌe„À[“QtGq‹EbBa†D[{;c|GntMuyPu‰Tv[y‘Qw—bœc‡”j‡s„~gŽ†eŠj…yy„}rƒt‚zŠƒ~……‹ƒ‘‡„‡…ŠŠt‘Št‹Šhˆˆeˆ‘i™b•Š_›~_˜Žk—nž“p¢œx™‚“zŒ•r“…yœ”x™˜gž–t¢›t§™t®¡d¯Ÿ]µŸ\¯¢M­•LºžKÁ–XŤYÇ RĤJîOÆ©F˲MÒ¸I̹?Ç·CνPʶSͲSÍ»RÄ´MÀ²QÄ»HʶJȽRÊ®OÀ¬Z»£Y¶ª^¯©_¯¯d¦«a¤´W£»`­¸e¸ÃX¸¾X»¼V½¯S¿³T·¸VÀ¿a¼¹dÀÅm¿ÉeÁ»Y¾¾T³Ã]¯¶^±¹R«½W©ÅXª¼Q©¼P¯«_®ªf³¦^ª©\¯žV¶œO­™Q« G£¤G§¤E±£F¶¨J®Z¬©Qµ£O²¥[¶žX¹›L»¢DèA»§@­›L«™L´†L³D´„>µŒ;­•?®D±™DªŸE¬™AªšC¤œ@ –=©‘> ›G¢ŒL¨ŒPª•HM •F““?•ŽF¡–@¥Ž:œ‰B¨ˆ7£‰8šƒ5›„5—…6–|6˜{1–‰8¢x8£sI›{O•~K‡tJƒoDlP…uL‡rM”R‡V~wR|{G„ƒ?ˆƒB„M‡‹E‡†?†…9€Œ8~‡A~‘=u›>|™8k¬8g®=j®-w¤.pž+r©/h°0o²3qª7g«žšC§œEŸœI¢—JŸ™O¦“Pœ‘P‘’T”‰L˜‰G Dš7„6¦6Ÿˆ6¡;œz6žˆ?§ˆ>£„=œˆ4•ƒ6¥‚DzD—~C˜{?•{>|h;‹pHŒsO„R‡‚Hˆ€MŠsT‡pJ€‚<~~F‹N{M‰~:ˆ€HŒ‰Aˆ’5|Œ8tš6m˜Ctž8`§Ij¤Cv¨6k¦d¦0b©>w¬=m­1q©>}ªDƒ£TŠ«_ˆ¨WŽ·T›»P›°\—£Z©_—œa¡˜f¨ d™˜oš k¥›gž‘h±–g¬•a©‹m·‘m¬q´kª–fµ‰d·…c¯iµ|l­€y·…‹´ˆ§x°‚Š°{¡pƒ¢{~±p‡§b…­q‰¾u¹e—Çq ¼k“ÌršÈp“ÇuŒÁvˆÁtÁt‡Ç|À„‘ÁyÇyˆÅv”ÈoŠÈt”Èl‡Án‡ÅmŒ½qŽ¿eÀ^…FWA^”Ac”;]„6gˆAe‚GhHf‚Lm}Jo}Hj~Ok‡To€Pu†`|c„‰lŒzd‚{n…|uyr†~†v{…€x‡~„~w|‰~ƒ‰‚v€…wŽ‚r‘Šk”Šk‡ŠdŒŠ^‘ˆ_‡‹n—m‡ŽpŒ”h‡Ž`˜f’™q“”o‹pžgž™l¦”j¨”W°“S±ŽO­P®Z´žSƙUșLÌ¡> AÇ¡GŨJƨIÅ©>Ì´<ʼGκE͹NÁµR¿·UŹOþIÊÁKƹM¼B¿³EÇ°Q¾¬Lº«Z¹°X¯µU«³`©¼a«¸U¨¹[¨­\£¶Z©´S¶¹R·±[¯¬Y¬¯d¦¯]¯¿b³Ã_´¹e´¹]©Á[¦²[›±Zš­R®R§´Z¥¨Yœ­_¤¯_¨°dž¥_›Q¡šS§›O¦RžžW›šK¤šK©T¨•R©’O®‘J¥žQ¦›DªžG±’L¦–O¯›K¨J£F¨P§„D®‹C«‹F¯ŒH®‡I­Ž>§…D™…:œŽA™=¡ D¡žD››FŸ>œ¢Eœ™J™‘K–“I•–H˜AŸŒ4 ‰3¬Ž.¬†7§}?¦6£…9§}A¢‡=«‡>Ÿ‹>¢‹:—…A™~AŽy@“z6Žs2…r;Œz;ˆpHwD€zMŠ|Q„oT}nTwrJ†sMˆwHŽy=†ƒB|JŠ…F•F~–=m“FjŸAeœEj£CiªJfŸDgš5c¥7d8_¦9m©4m¯9m´4y¬;v¥Gw©Q|¯R¨[‚´V”´Y—®Uš±[Ž²N¢Q¤]Ÿža§Ÿf¡¡b¥˜`ž™fžj«Œ]´‰\­k«—l©l§d´™h·•p«Žh¸‰e´€i°ˆu¬|µ~v¯…}°…‡ª|„¥~x¤y{¢v~¯l†±r‘¶o•ÃbÅf”Êi™Àq•Ât‘ÌtŽÏmˆÂtÊƒ†ÁŒÄ~ŽÀ†‰¾z‡ÍxŽÇÉzƒÌyŒ¿kˆÅp~Êg„Ïf‚Â_„¨’Fª‘9¬Ž?—H ˜=£›8¨Ÿ= Ÿ@§–H™˜8¥˜:•™BE›JA™‰<—Ž=›Œ=¥|0§ƒ4¦x-©u8§{1ž~6ŸC‡F”<¢‘>Ÿ†Fš}>’‚?œt=}0‰x7‹o>‘{A€rFsMvyL}nIt}J{|L‰tBy>Ž~?ˆŽFƒ@‡“F|’GŒ:s›A{¥8lŸBj¢Fg¥Lp§Pe£Af©s©Hk¬O|ªU‚³Z†´T¿J“¬S–¬]®PŽ¯T˜«_“«cœ`”¡gž£e›žc›aœ”]š`¡—f¥sŸ›d§t© r£Ž`¦’^ª’b³v¯€w¨t§~‚¬µ|~µ}‡³…‰¤|}¥z…¬r“©n–¯w’¼l—½s˜¾w·uˆ¼lŽÒoŒ¾j„Âxƒ¹r…¸~†»z‡Â‚…Ì~‰Ê€ŠÁwˆÁk‡Æh‡¶o¸b‹ÅiƒÇ[‚Ãe†>Y”@`;c‰Dd’>]“I`‡Lc…SozSa‚Mc}M]xKf{Pr†WŒe‚‘a“hˆ„cxvbsqf{f|‚kswo}xqx…u~zƒ}x‹n‚Šq‚|wx‰„nˆlˆ‚aŠ”e”™e‘˜bƒ›^…ŒW†‰^˜•e”i—ˆg „p—‡o¡…t¢ƒl›‰g™Žm›™h­”^«›`¦˜\´£Q²¡VºŸL·©F³¥O¸¦S»±GȪKÍ¥K¦NÀªOê>ʲF˹RƹK¾³SľR¹·FÁ¹L½¹N»»T½·YÅ©ZÁ¤WÄ¥\ºµY¼©b¯§_¨¢a­¦Z³©d­³c³°`§®T©¹J°´PµµR¨°`«À\´Àe­½V²·V©±O¤·W§¯H›°Jš«Tž·W¦·_ ­Zœ¨[šªU±^œ§W˜§K¥ EŸ¨P¢¥K™¡KžB˜>™™K—šN˜–J›šB›AªŽ5­›5¥¥2¥Ÿ;ŸœI¤¤J¦ŸN¤—P®‰F´ƒ=ª€:±ŒB´ŠB«A¡—D™I¨¡K©œD¨˜L™’Iž›@¤”@œ™E™˜@˜ Q—Vœ–NŽGŸƒ;–€6—‚0¡6£|:¦y/v1ž}6•~:€B:–…>˜„6‘…>’x:˜y<˜r3”|7GŠvJ}sAqyHnuMt|J|yE|„C€}:†;‘M’‰M•‡KŒ‘<„—8{‘?v7‚™<¨Hy©Jn¥Jh©Lf¤;]©:c¤E[­>_¸Gcµ>`ºFm·=h¯Mn³Q¿XºQƒ»H”¸I˜¯KŒ°T‰«VŽ¯Q‘¨Z–¬[“©bŸd“œ]¡^‘žP•‹R—Z›d“£j˜m•¡i£›m¬–n¬’`­—p¤Žw›v¢vv©‚~¬†y¨Š|°†‡¨†Ž­~‹Ÿv¢p‘©|·x–µ–»yŠµx‘µrŠ¹p†Ék‹Àn…¼p‚¼sˆ·~½s…Ät‹À€‹Å{¾y}·e€¸m·k²mŠ´j‰¸d~º_|Ha¡=o’Hl“QjKdŠOp„OoyWfxYjwT_vQl…SnˆMk}crb~“\ˆ‹_„‚fu}ns€es|d{t`sqpq€t{|u‚s|ˆp}ƒw~‹qŒ~oˆ†s„„o†ˆg“m˜f„•d——aŠš\•Y’bdš”kŒƒc—…k˜ŽkžŠržˆi“ŠeŽz¤ˆc¥›]§•g¨b¯œ\º¦Y¼©W¹§E¯«Mº¬OşVˤJÁ¨Q½žU̬LÁ§GéI˾Sº¯M¾¶UÇ´WÅ·IÆ´J¼¬KÇ®T»µZ½¦]¼¡[À©^³°S³¦S°ªX¯¡W·°a±¥f­³`§³YŸ¶^£­X¨±W®­Q²¦_±¶^¶Ád«¿W´®Wª³\§»N™¾PŸµH›³R¡µT—¼M ¶Pž­Y«Y¥§T¢¤W§¦Rª£>¨žF£H˜¢> GœŸM˜¡=–•A”=¡<œ“3›7ª 8¬•?Ÿ D –DšœK©—H¦Tª‘Qª~E³B²ŒJ¨I£‘K¥œ@š¡B¢™I©¡J£@”–Kš“F£Jœ•I“ŸB–”HšˆU–‡S™F—Š=—~C—Š8¤„:¥ƒ@ž~8•„,—†3–†1z=•€CŠ…:˜‡@‹A‡>ŠI™„C˜‹B’F‘vJ}vMw†@yyO†J€F†Š<†‹H‰‘F”‡I“”MšLŒLŠ—J„”E†•;¦I€¦?q£Os¢Ik ?c¨Df¢:f®7_¨C^¶BX«C^¾?b´>g¸Go·L}·Dƒ®R|¹M…±I’°U´SªNˆ·Y•«b“§\Š§V†ªc–gŽ£_˜£R–”U“Uš_˜¢h‘—d•™dššgœc¦”b§i¬’~«ˆmzmžm¡~¤‡¨…}®†¦†Ž±„‰¨y°…’¶„·ƒ–±z‰·{‹¿y–Æp“¼r‰´x‹¹rzµtˆ¹|}»yŠºq‚Àyµs‡Âu‹½hÁm‘¶b½^Œ¹e¾c„·_ƒ8l£BxžQ–Rx–TxŒYoˆYh‚Wl~crz]jy\hwTjƒSqŒ^r[r‹hƒ‰j…kt€n}ybxrhpwfomsny}zztƒz{‚mx‚bƒhŠ€qˆ|j‰|i†…h‚“^…“e‡–f‘”^ŒŠc‘dŠše‘—a—li‘’c”ˆn‹…rŠˆhƒo“…uŸŠn ‘f²“h´“e¹™^²¢S´­Y´¦U¹žX¸¢LÀ«J¿¢SÀ£TțQϟJÄ©B¸¶J¼³JÀ¶KÁ°OÁ¬QδXгQÈ°PÉ®VÄ®MÀªSº®W±¨X®®U­´\¢ª^¡¢T¯«Y¦¶b«²^«¶`¥´a©©U¥©P¨¦L¬¤T«­T¶±U¨®K¨¶M§¹K¬µT›³R™ÀOŸ½Lš¾O¥¾W¡¸O °S¥£[ŸYž§T¢£R ›D >ž§; ¬D G ¥:“Ÿ<Ÿ8–—>¤”;¦3¤˜2¢”8K L¨™T¡™L²˜V³ŠPµ‚S±…K¬„A´A·‚@ªŽG£™L£šJ«ž<­>¦”GšŽIŸ—E™’D™›@—˜F““D™ŠPœ…Aš‰>¡„Gš‡> Až…Dž|Dœ‚9‰~;†ˆ1ˆ=…€7‰|E‰„E‰Ž<”Ž?”ŒIŠ•LŠˆMŠFƒ|P‡~O{„AtƒDy‚>ƒ‹HˆŽ=“B‰˜?L‰‹D’–GŽJ•ŽQ‡—VŠ›K—Bx£E|£AuœNnšHn•>k—=j¡C[¤@Z²>^¸H]°Ba½=`º7m³5p½?l³Ey³AyµF†¸L²O‡²SŒ»[²_•³]Œ§]’®\‡¥^©`”£Y¤P‘›UŒ’]Ž”TŒ¢_–ž_˜l k™i£œj–k¥…v«„y¥p¡|}§x¤…±‚´­€Œ£‹‰ªˆµ‘¶ƒ”¯†‘·‰·†•¿‰š·•·v’±m‚µt‚Áo‡Àu†½~‚´z†®~°w„»o’»n‘´f”·\³^“´]†´Z€´d~Ih£JlŸOlœWo”\m“\i†ZfˆUmSo\j‚Tn†]kYp‚ao‰iy…c‡‚p{‹erzg€[ylhykozrwwv}psƒ{s}eˆ}oŠa€kne‹{bt[Œ}aŠ“a‡‹gˆ•b†c”˜d—^™™dŽ“r‰p…s‹Žzˆ‡sˆ‹f‚d’‡s”…oŸ‡s©˜sµd¶—X¶œYª¥N²žK²œF¶ŸI½¤E¹¥EÀ¦DÏ¡PÉ®AÊ«FÆ«CÊ©KħGÍ£SЮRÇ­MƨIÄ­RÌ­S©Q¢R¿¯Z¶®U´³T¥¯S—°V«­S³¯^¤µUª·X­«^¢²f¤¥[®¢P­­L³X®§Q­´P±°Y¥¹L«±XŸ­\¢¯S¡·G˜ÀL›µM¢·U­±F¢©V§£M¤¢O˜£Nž?§«E¡›E¤ª@™£J ¦C›ž?“£4—”C˜C¢“5˜6—›9—9¦•:°†K›’M œN¡ŽD¬‚K¯†G´ŠJ­Š<³„5¬‡7­;¦”E¨–J¦¦C¬›@¦•<¡I¡“Nš›Q–žI ”O™™A™‡KŸK ‘=‘„C‘…>‰E¤KŠ=Œv;†6“>Š‰AŒ„B„}D…J„…?ŒŽL‚‘H‹ˆA‡E‘‡KŠ>‚GwŠHv€Fy†LŒ‹IŠ’E˜H‡’B„@…“J‹’Lˆ”B‘S‹ŸK|¤Cw›H€A‚©@§Cs˜JkŸ;r¥Aj¨@`§FT 2X¦?g±:]­@nµ2h°;p¶8r¸:o°Eu½>ƒÂG~½F‰¶L}±S€¹_‡¯[ŸQªaŒ­_Œ£a„ªW„£V„™T—¢K¡P‹£_Ž–[”šj• gš¡k™¨l¦œjžo™Šs™†l‚nž†y£†¶Ž‰¥‡Š®Ž~¢„‰©–‘ª’«ŽµŠ¹†‘Á…š¾ƒÂz™Ár¹v‰µƒÆ|’Äp‚ÁŽ²zŠ²€‰¹y€¹l‡¶]†¬b‡³^‡¶`„¶\Œ¯V~£i‰¹’B® A® ;¥¡B©•G­–Hž’C˜O“Iœ•P¦–Mž•?“›?–‘C™’I“ŽB•L˜M‘~AŠ{8ŠˆB…F‡ŽMŠŒKŠ‡M‡†Bˆ•LŒ’I}”P~†Fƒ‡@‚‘F}‚=„„@{Bw„Bƒ†A‰ˆM†‹?Ž–@‡:…Ž@ŽŸEŠžE†šL‘™KN|¦IƒHx£G€©<‚¢>z¥=i¤A_Hd¤@^¥9^œ7]¨Da©Ca¥Ek¨5p«:u¹4m»Au®C}±NÁG‡»D…½Qw½Mz¹Pz²Wx¨Qz¨Q…«VŠ£Y…«Y Q…¡R”›L—¢Q— VŒ›d™–h›—Z a›¦\œœe ™c˜œkžu¥Œr †z©–z¯˜…°‹‡ŸŽ|¬Œ†¶”¯‘ªŒ„¸‘–À…˜¾z“¼|¾w†¿z‰¼ŽÂ‚”ǃšÂyŽ¸¯}~°‚†´}‹²eŽ°]Œ³`Ž«e‹´T«R‰žX‡¢bƒ?nŸKnTužV}žVuQy’Vp…Ln‡Qq~Qk~]k€Wqˆ`rŽWy_z‚]‚‚c€‚hv‹rzƒs~o|t{pyzylvvku}iqt{osutwxuqs‚qcƒn^{€\ˆ‡a…]‹b‰‹aŽ›c‘—m—˜hšv“†t‹“wŒ’s—‹q’{i„q•†n—ˆt••p£—p«–p²ž[­™]©¦Y¯§Cµ­B¿µK°§M©²F±³@Á´JÅ­L̪FǨAҞLЧR̜PÙ¨KÖ¤MÊ P̱OÇ¥YÀ©O¸¡P¼±Z°¶Y¯¯O¢¹O—´Q¤±Mœ³W—­V—ªNŸ£O—§S¢¨Z®®V¤¥W­¥J§­M¬°`³ºX§½M¤´R¬¿d§±`£·O¢«Mž§I˜¯M˜¢Sž°@£ IœªI¥§= ©9§©2§°8™¢;¨¤KœA¥›9Ÿ›5”’>Ÿ5¡¤@˜ 5œ›@›Œ7¥–:¨D­3£“<¨D¯…K·†L¼‡>´<½ŽA¶’Cº•?¹7©¥>« F§¢L­›Bª˜J§ŒPŸHŸ™S©’Mœ›L¡ˆBœ‹<”‘H’„?˜ˆAŠF–’MŠ€@ˆ}9ŒD‘„@ŽMƒ‰I‰‹IŠ‘K€˜BœHx•H}„C‹B€F{ŒB{‹?†;€€E|N††K‡‹<‡“:‡™:ˆš>‚™@„¦B‰§FŒ§E{©J°Dƒ›C¡Az¢?‰¤A}¦:f¦>l˜Hr¡:c 6]¡0e 6c¯EY¬:_£:k¬:hµ7jª=i§Iq¶?uÀNxÂFp½Do²Hp²En»Jl»Ft²L¯T‰±V²Q†¯M~ŸVŒ«L’¯L‹¬S£`š_˜™[ Vœ«b•™g¤Žh•‹qžŒs›ŽqŸ…}©ˆ…§”‡¨ž…¬š‚«œ…»•Ž°•Š«‹º†‘ºƒ¾€•¹Œ³~ŒÃ‰‘¸ˆ“¼†”º|‘¾{³‚Š±zx²‚­oŒ°eˆ­j…®[¨aŒ¢U„§Yˆ¨]ˆ¡d‹A|‘Eu”Jv—H˜T{Ts—Jr—Q{†X|“SsU|†^sˆUuX}Š^~gu€e‚}i~…ku}u{€n„{k€mlzlrunwfishjypjtmwug{xdrƒom}ph~uc~ye‰ƒl‚d•ˆk—‹fœŒqš”nœ‹m™ˆo™•pŠ‘nŽh’‚hŽ~b“ƒmk˜™c™™Z§bªœ\°¤\¸¡Y°©I¶ªN¹µB½°H±²D¨°;°­C¤JÃ¥FßFӞJџGќQ˝[Ó¤WÖ¬XÈ©N´QÆ­N¿¨D°¤J¤¥M ¶V¤¹P µV˜´N•¨Hž¤E˜¥O”°_˜«]š¢[§ªW±ªL¬±Q¤²X©¸X¡Ä\ ¿V¦º_¨Á[§²P–°V–±F—ªB‘Ÿ?—¢I¡£DŸ§A¤¢?ž¤8¤5¨¨8¬¥7¨©5§°?Ÿ¨GšŸCšž:–¥<—¤>¡¥<œŸ5ž–9¥A¦‘5¤ˆ5¨‰8¨Š5­–:¯“=®–DºŽ>†GĎHŘE¾™>¼›D´¦?¬­J°¢D¢“R¡‘O©—J¡ŽJ¢˜G©“P£E¥ŒB¨A ŠFC‡K•‰@ŒŽC“PŠKŒˆB…Dˆ–IP„˜Vƒ•N†šP|˜AxOs‰Kw†G}‰MuCyC€’P†KK…=~ˆ@„‰=Œ’?ˆ›:ž8Ÿ?¦>¨C~­I¨>ƒ™G‡šDš?~šAy–Dt?y•FržAs£:i®6c©.Zª6d¯8aª=jª5l°>c®Ab°E`±Gm¼Md¸Jj¹Hg¸Lq·Hj½Cn¼DyµA}­N}±N…©W±SˆªR—¯M”«W“¢^•¤_“£b›¦UšªR¥_•™i”h¢wŽtŸ~¦‚ž„•«ž~©ž|«’€°–ˆ³‹}ºˆµ‘„¸ˆ®…³‘®†Š·‹ŽÀ‡¾†…¾Œ‚¸ˆ„º|‰µ|ƒµ|§o¢l~®f†¬d‰©]„¡]‚™`›\‹T‹I}Mz–Ow‹Mx‰M”PtŽH{‘MqŒQ{ˆU~ŒTr‰Uw€cx^{~[~ƒfw†`}ˆi~„jx†mwyt{z}mmrmprdnqbybdmjuwlrnessnr„rk„yhyrf~{a}tc{{a‡€bv–‹m•tŽv–n‰†n…”t’Šn‹‰g”zm”~hžŠg—ˆb¨—b©œd­\§§Z©›E©©?®¡J·²B¾°O²§K¸¦H¸©G·±OÉ¥>ȦJ͝KҗOÑ¢HÉ£FϯNТMÇ°VÍ«KɬP¸¨L°­C­°N§¯]±Z£·S£¨Pž©Jš¡K ¢O¦[¡«V¢±_§®]©¨U§§Xª¶Z¬ÀRª½W¨µO¥¾V ¶T ¸Q£²Rž­O¥¯C¢¦A¢©H¨¤G£¢K£¢;šœ:©°D¤­D ®6§¤>¡;œ›J¢ D•C•£E¦«5ž›C™C›ŸD¬˜A¢B§0©„2«7¦Š=®š>»‹3ºš@¾CĉB¾˜:ÀŸ:¢A½›<ºªH¸ª9¥¢N©I›”D§I­C¤›M¢D£…8¡?˜‡D’ŒBš…C”’A>ˆP}O’ˆK‰‹E{•?w„>z=‡‘>„C‚–Ez’>~ŠKw’Sx„I|“Dv‹=“M}Š@ƒ…A=vƒ@{A„—BŒ‘?‡š7Œ©>«8~ª<„¯?€°4yœ=x“Eu›>r8w™2už5q 6n¡B^ª2d£8W§Agª:\²8`¶6]³Gd·Gf¶@m³Al¸@n³Ej¾@k¼Bo¯Jm·Mq¸Qt²EoªKt¯Bx¨J‹ªQ«W}§MŠ±Y™³R—­Yœ§W‘¤]¤X•©_‘ k•£g”o–wš”u¤}£…„š‰z¦“‚ •}©¢{£ž}µŸy¸±†x°……ºŽ’³‡„²Š~²“„²‰º†~¸‚ˆ«†‡³|¬‡…©xˆ¬s{¤q}¥f«r‚¨^‹¨\—V{™Xy¥^Š¢R‰Ly‹L{ŒT…M}}BpzDo„FkPx†Rq‹UwXqxRtoSxucw{atz_z}a…ˆe€„ay‚ewpykm{p{yrsppblvmnlkuvwstr{qq|ne}pj€th€ug‚xkˆscƒyl}sŽytŽxp›…n’„xˆƒpŒ‰ehƒe‚gŽx`—xj“€]•ˆ_¦›`¬ X¤£O¢¡I¯D«¡;±¦E¾§Jº®I³«O·±P¾®N¬FΩDÉ¢=¾ BʦDÓ DÏ¡M¬LɯSÊ°QƬXº³M´¥U²¤L¹±L°²R¤­WŸ°UŸªM ­Qž¬S¢žP£¥N¦³R¨¯W¸¸T·³`²®Z¯¼Zµ¾QµºV¬´X§½Q¨»N¤ÃM¦¿L«¾J¤·O¦´Qœ²MªŸP®G¢£>œ¡<ž£@¤±F¡±>š«;—¨@N•Oœ¡?¥­F©¨;œ–?Ÿ”A¦ŸI¥™N ˜=¢’8«Š;¢Œ7¨@³“7³š9»—0¾Ž0³•?º >ß?À™H´–C¬¡9®§<¤§@£ I¤¤D¨™F¡™C§šG•>š…7›‚A™…K™ŠO•G”†O™‰J˜QŠR…HŒ‰Jˆ‰:w‰;‚’?ƒ–<}“7v“Bt–D~ŽMq‰NmŒHm–Gr’F|•Hz‡Dw‰N|„L|Fu†H~†Eˆ”@ˆE‚­>†ª1‰ª0y£/z¨3£:w—:u’4u“2p™:v 4p£:\¢5WŸ6Xœ>eœCd¤9`ªB\±9f¶:d¯Fe´Ij³Ce»>j¸@m»Bf³Dd»El»Lw½Os­Jt®Bv±G{ºQ¶S~³Wƒ³V‚²PªY’´[˜¯[šªb•¡f¢iŒžg’’g˜”jœŽkœŽu›•o£‹t¢‘Ÿ—…›Ÿx¢¥w¬œ® x°¢wª“€­Œˆ¯”‰¦’…¬ˆ|²Žw®“x­…u©~ƒ«ƒ…°ªˆ|¡€€›€…£p}£n†Ÿm†žd†˜c‚—V~ V}™]€›Y|@x?‚ŠPtwFsrPi|@g~Dy}I|zEv|HiwWqjUtg\kq`pvTp{av|ay…bp~_€|bxkrousq}|iewd]uljpcvuqqt|ykm{qfwqk||g…|cŽzb…}p”|m–ql~i˜yn“…f™r‰„z„g‰‡j‹†k“‹oš‚f”qp™‚l•Œi¨’]´Z°šRžšR¦žN©§A±¢AÅ¢Q»¦QæXʲKǶEά@Ë©?é<Ç©>̛=əGÂ¥I¸±KÁºIÀ°UùXººU°¦N®±B°°S©¸W©«R¤®Y²U¯®V©®L®¦Q£ªS¤°Z±²RÀ´RÁ¹O¿°O¶¸W¸²J­ÀO¼¶\¥ÅO¥ÀO«¶N¢¹L¦´Rª´WªµU—¬R¦±H«¢N£¥Jœ¤A©ª<°²I¡±<£¦@¤<Ÿ¥Cš§L¤Ÿ?ª¡I§¥6¤¨8››K›œC¡•Q¤—E¡˜GžšA«?¢B´“=³¢=¹ 1±œ5³¦>¹”@½ =¼ ;¼™C°˜G´¥=©«A¡«K±šD¡§C¥’D¥–I¡‹A•‹2£G›R‘ŽJ••Nœ’O“‹P—ƒJ‰†I…BŽG{”A~“<‚‹CŠš5{‘9tœD{I}OwŠCoHp’LoAtB}…D„Kz‚Ry†E{ŒD…™D¦>€ <„¬2‰®<|¤.x¯.v¤;nŸ;r˜>fš:i™1f™.o¤0i¨2\ ;^¢>U™;\«7d¥3_°7b¦6e§9a²K[­@Y°>\¬Gj»?b¬>m½Io±Hu¹Nl¼Tk¹Gm´Bi¬C|µO¬FŠ­U†µTµRˆ¦W¶\š®Z‹±b”±e„¯a…Ÿa‹–f‘’kŽšm‘•s –i§’w¤“u”’ƒ©Ÿu¤§z¬ v«s¯˜y¯€°Ž|²—‡¨Žƒ·Žz®“ƒ¯–{¨s¨}†«w‚§… ~£ƒ¥p{«i€Ÿq€žwŽžg€”h„—X‹“R‹˜Sz–]v;†…>yE{€HpwDtuHi}Ivu=vsCmjKhhTfnPohRsrOhtTfv[t{ds„_m}Z{te{svwwvmowigyghxkouiozxprwqspfwtft{k}yk€a’wd“oc•si–~`‘~e›d“‰o˜qt‹Œn‹‡oŽˆc™ˆe‘„k™zi—‰j˜‰ež•Zª˜Z¡œW§£T°£P«œ=°£G¾«JȧOƯSͳFαJˤMÆ¥@Á 9˪9Ë©9Á¡GȱB¿µH¿MÀ·V°°K¬·O«¸B«­A¦¯H¡³M¤¼O«´T«®W®¦T´C´£@¹¯M¬¶V¹ºV¹µY¶µLîL¼¹G¼²R¼¹OºÂT¹ÅS¨ÂM±¹Y¬¶T°¹\©¸Z²N¢²G§§G«¡I©›D¦¥A­°Dª´C­­<©«@¤ @ œHœšO¥¨Mª«Hª­A¦©H¥«D–œH——K™S ’S¢ŒO¥”G­˜G®¢=±¢;»¥5¶ª5·¥2¼¤.´š2²¢<¾˜=ŗ9»Ÿ>²¥:°©B¥ŸEª£H¤”RœJ¦Š@ž9—–Iš’L–ŒN”‹K›‰O”’M•–FŒHŒ™E†œ@Š“<}˜;‰Ÿ5„—=†;w–@ŽKyEp™HržEu‘Ir‘F€ŠE€O‹R~‘V€•Vw–M|žAƒ¦6Š¥.Š­4ˆŸ:¢4p¬6m¨2nª7b›4h™7i˜5m—2_¡=Z¥4Z¤3Y­5b¥:g§,a©-d©6cŸ5a3]§BR¯BV³DZ¯Nd®Fe»Mg»If¶HvºKt¶Vo¹Qj¬Ij«Fx¦E§F‚¦M…°Z‚¨[…©c‹µ^·Yƒ¾[‚¶ZŒ¯\‡¨h…¢r‘¡p™žq“l–jœ m¡¤qš–z›Ÿy¥¤q¨¥wœ«u œw§•‚«›„¤”„¢–Š±‰‚·ƒ|­‰w¤ƒx¬ƒ} {{Ÿ~z£z¤v{¡w¬sv®wªs„¥f‹”bŽ–\‘ŒT–VŠŽU|C~{Fv†?y|Lyq¼µ>ÁªC¾«OÆ´CͪQɬK¿¯HÆ°>Ó°7Àœ=Ì£EɯJ¾½KÆ¿L»¶L°ºO®´N³®L´·F°²J®¦=¤³B¦¶U²¸V©¶G³®A¸­?¹²D±®O¼®XôböZ¸²V¼µ[¶´Zºº]ƾW±¸TµºZ¥ÄM¦¿H´¼U¯Á\­µT´¹E²´N®®E¯°Fª¤>¤®E¡¦> ®C¥œA¨¤;¡š?¥>¢£@§¨C«¦C®©E«§?¥œ?˜£E’¡O¦‘Cž‘F¤”F«”J®¤H¨ž>®¡'ª¢*¬¥+±£3¯›1ª—@³§>¼Ÿ<³©=¹¤>¬¬9¨«:¢¥@®¢@¬žA‘7ž™2 Š<˜š:›™EŸ< D˜™G”•H‰>†ŒF‘•>…B|›AŠ˜6•6yš;zžIxœ8—8s”Bm˜Fy“G„˜?œHˆžM{•D‡˜L{ŸB}”M€¨G‡¦7€¤2…ª>Š±:„¦)q¨/z«9h›2c˜8f£=nœq};ryF{mFziGwoOvnX|iO|ePrp\oif}d`~glvkqoe{vktyhmhjqeawaholouygizklzrsyj}tcpfˆm}h‹uaŠ}i•wd•{e›†l”‚tœ‰k“‹g†g™vŸ„l”…`™wb•tdŒ{a’ƒc”‘]¢P£M¡’D¯˜Gµ¢?³«;¿°AêF¿²L˹AÈ®FÇ´OèFЬMΧBĚLƛRÀ¦PÄ´R¶ÃN¹ÁP·¸G¶µE¶ÁH´»D±³;µ©<¬²A°°H©¯F²´H¾°C¿§<ȤMĪUÏ¥[Ȩ\¿¯S¸«P¾¨R¶°\įbÁ³Y·½`±¿\«½T©·M¯²F·¸M¹»Gµ¹JªºD¬«E±¯I§¬F¤¦J¨¨DšŸ>›žDš§G¥Ÿ<£«>¥®/«§2°°<³¯A¥¤; ¬H•¤Nœ›Bš™?š–@©>¯”C¨™D¬£=®­(±4¬/¦™7§ 7¢@®§@²žC®¡?®ŸFµ£=°œ:«Ÿ;²ª4¬£:°¡>®˜:ª”9¡“0ª4£•9ŽAœ”<™’H—EŠ˜@Œ˜I‚™N„D{•G8‡›G~˜G‚˜8‚¢7w¨Hs¡Hƒ•E‡—?~B£L€¨E‚ŸAv˜?z D{¢J§B}µ7ˆ¸=¸-€¨-{¥,u /h§=k¡9a¢3c¦9i°8cª)U¬.Xª;Y¥~–8w”`±1Y­4a¬8Y­-R¨/X¦6Y­9`¢8b¯7\±)c¯7Rª?_«7gª7d¬A_¬Fr§Gv­Kr¥Ju±LvªEo´Km»Ni´No¼Bv­‡–Cˆ–K™Q¢E‚ŸI}›=‡˜?…œB¡F‡¥;€³=~¯>{¬F‚§G‡²E†°@²C„¥9ƒ¥6s¤7z¯0t´5k¯4i·:g®2pª+l¶2m³5_³)[¨,[§9T¦=a ?\ªp¬Lm¨Lj¡>m¤@l²Dj³Gh¼Eq¸As¯Kp¶C|±By»F|¶It¯Hw±DrµB|µJ´P‡°Z€´a…¦Y“¡`‘¦f–›n¡q›¦k›°h—«j©k™uš¨n¡¡k¦ q ªn£©h¡±j¡²f£¥pž˜j¥–f Œg¢Žq§€n©wj¡utžusšxy”n‚žp~Ÿo}šky¢q†•f|˜h‚ZŽY‚Z„–W€/iw8eu8l8ts6l|?t|3muCgf9giAsa5qbDycE}gGƒeFnZJp^Vr^_pZeidqldkw_ynOitWjehom_usp|utuwk|l{}n}|t‡qxƒr‰ƒi‚‚nˆt|c‹ydŠyl—ol™wvˆ~p‘}f‰n€n‰}fƒ`Œ[ƒZ–ŽH‘‹Vœ—I§‹I†H©”>¨©Gªš>¸«KÁªLDz>ºAͳ4ŸEÊ®RͧDǟL¬BįKÀ²HÀ°AøL½¶I¸¬OÍ°KɪH´»6º¿C¿¼:ºµ>¯­:³¨B´«DÀŸIÁ¥MÁ >µ§=¼­@ªS½¼G»ÃB·ÃO¹ÄVĸZ¼·^¼QƶPIJVøIÁ¿J´ÀO­¾G¶µG§°K«°RŸ°H£¥:­£?´£;¡¨5Ÿ *¦ž.¥ 2™¥,›¥7Ÿª:³¡,®¡-¥¤:›ª9¡­: ™6¨Ÿ9¢›?¢ŸA¨£9£°<  <ª£1°©1°ª>Ÿ¤9¦§8¡ 7¨¨-¥©-¦¯4ž¯3ª´3§ª:ª¦C¶¬5¹¬>·ž<«˜;¶š5°ž9¦™4¥¡6©Ÿ5¤Ÿ>¢¨B£¤@“š?”˜C‡™K‹šG¦D…©H‡¦M~¦?Ž›?ž6‡ =Ž D}§>€ªC…®@‚¥Q{¨Bƒ²;Š¦<}©9x¯8«At¹@t¹Y±9c¶]¦:j¥9i°Lw¦Ph¤Jg­Dj§@cºId¸Ls¸?i²HlÀEsÄ;s½Fp´Jz¶Ex»Ow¨@w«J³P€®V…§RŽ±[‹°[¤Xœ¤\™®`£¤n“°_”«m­i•§}— n—ªjš§e•¥t¦k–ªkŸªl¢™l¨•e¥”m¦i£”uƒt™zi—‚h|r wz—}|’tpœrs¡prdpb{‘`tawŽ_„œ`|”S}1mt;ct4cs6bu:p~?rusfMz`KkQRfMPoIRtVanTeeVlo]ovUegchfbgsjmxm|xo€ur~‚m‡€n†€fˆ}n†„p~‚pxyo{od‰ybŽ{a‹xe”rkvj‹m‰xl“~k™ƒ]”…Zš‰e‹c“‹\š‘O‘Q˜U¢‡WŸŠG©šH¨¡9¡¦:«¦H©¦M´¥C¼³C¾´8¾©=»®IȬQŤHͤIìAÀ¨I»¢HÁ°O¹°H·¨?¿©D¾´@¸¶:º³>¶²>¾¹Dµ°E¬¶L´®G¼°;»¡<¿¡@¶¨>±±J¶ªLµºBµ½DÀÄSººY²³Nµ¶T¹´PõWľI¼·Jº¹M²ÁH´ÃKª¸C¢¯Q¥§Pª£A¤¡9­¬5¯¨B­š@¡›5¨ -¡§4¦¡0ª 2±š:¯¡2¤©A©¦B¢®:¢¥6¬¦?¯¡? ž=ž›4›ª(¥­,¬³4§«9«®8ª­6¦²>§¥5°¥5ª«9Ÿ®>¦:Ÿ§2£¦7§§6µ?¯œ7³§6´•-®’4«•;°§1«¨5®§=¥¬>œ¬@”§?«E–¢G™”GœE„ŸN‹¥L„¢FžNŠŸI“™5™2‰œ7„žB~ŸI}±?ƒ©N„O~°Eƒ±@}¯B€²D‡¶>~¸;ƒ»?~¶:v¬2n¬,f¯'f¯(k§(p®&k°)_ª(_®1[³7cµ4b°AY²2\³0f·;bº=[º0^·3T±6Z±v«Dv¤Kh¥Sc¬Fc¶Ir¯Ht­Et²ª¯9¨ª7Ÿª8ª®2¤°>¤¤C¨ž?¨«/©Ÿ-¥¡1­¡<±Ÿ7²¡5Â¥;°–?¯3¬—3´£6ª­8§¡=ž¯G¥²E ¨=œ©?Ÿ¢J‘’B•žL€œF‡–@{—B‰–;‚H›8€£2†¥>}¬B|¡8 9†¬<€¤Q‰£E}­J€­F{¸A|¼F~´Gx³G€²>s¿2u¶+p­,d¶8h¯4f¨/e¨5k«/Z«4gÂ=b¼2l²t²Ep¯Co¤Cg£Sb¤Jl¯Hb©Am¯Fh·>lÁDlÁBv»DmÄ>nÅ?r¿Hs²Ly¸I‚ªR€°R©Oˆ¦Sz³Q¨M¬Q’ª]–´Wž·c’¶c‰¯q•«i“ v”¡l‘¤l¬r”¦i–¡qŠ®cŒ£k›™e’g¥‘n¢œr‘“e˜oŒ’iŸ„j£t•yt˜zy–rl‘yq‘wimeut›kq•bw”e€•Yt“`|3ct7]n5Ys>`t?UhGYbCai?cb;gXGlS:s\µŽB°Ž:§š>©¡3ª¬:­¥8«ž1·¡6À«?¼¤GÄ©>À¬@êE¼§MŸW¼¢Pº©J´¦D¶¨E´¢;¯™6²¡8µ¡:ÀŸ9· ;¿¢B·¨>±«5¹µ>µ²:³¨A½¬?»§Bº±D´»Q¸·R¹¼L··Q¸«FÁ«K¾°F¾²Qº±S¿§R°¦R°®F£¦?£¨Iª¨Mª¥F©£H¨œC©¡F¤¨>¡£1˜©4‘­9™¡8•§0œ9ªŸ@§™B©ŸI¢K¡¨A±©A«¥8°¦1³¦1ª¨)ª¤ ¶¨$¼­3³°2±¨,¥«.ª¦>©¬<­¨7­¨@ª«3¡ 1¡•;©–3¹ 0¸›=¾žEÀ—>´ŸD¹–Cµ–?¬¢:«ž?®§8 ª9£§E¦£Fš©>’¡=ŒE…–@ˆœE‰›F‚™<‚’DŠ™A‰Ÿ:ƒ£=}¥?ƒ«8†¥A‡Ÿ=‘ªDŠ¨F„´L~±Ds±Cv²J{·Sv²L€¾L{½?pÆ@m¾5tÄ8k¾8k¶;f®8f·2n²3`¸/bÀ5b·:i»:^¼3VÁ5Xºr¶Ao¨JvªPe¯Ie¬Je¬OeªIm»Ii»Geº=rÁ7uÈEsÃGrÉKm½Em½M|¼P‰µT„«Hƒ¯GŠ¬W€¨N}­UŠ®S¸_Ž³Xµ^±Z‹¹f†´^‰ªg¡b¢n†§a‡ªbƒ¨fŽ­j‰¥h¥^Ž¢h˜˜i“b”Žl–„e†c‘ƒf›†k|q’yq‹tu•hœ~f•|hštq”in›]{”bv•g{†[z3jl+nc.bk3buAZh@T_B]V:Y\BfYGaTAe[@h[E[R?bJ:`SCVQN[^GcVM^\[VSecXriZajTal[eiejqajsmnthtvbn]~f†bzuY†y[|wY|te…jb‹bd‘wi†s\’t^€s[Œƒ_„€NŒxU€|V‡\…^„‘^Ž—P–T›šL¡R§”=©—;·›?´š<¨—9©©5²ª.¸¥,¼¦9±§:¯™N¹§9°¥?ÁŸ=´¨E¹œ@µœBµ£H·¨B®¨Kº¨D®›:­š3¼˜5¿¢7ÀžBà7Ã¥AÁ¡7¹±6³­3´¬7¹«?»¦<ȤK¼§N¶¯L·®N²µK¿¸V½ªG¾®DÁ±N»©Iµ¨X¶¯HºªC¸®D´«C¸§Aº£E« I¤›>¨­>¬­9£´9«³2™ž;¡¤5¥›B¨©;ž¡A£Ÿ4­¤>®¡J® 9µ¥4´ž:º©4­¥1£©3­©'´¡/¬².¶«<£¨6Ÿª5ž¦:¦­A¨¬?·©:­ž=¥ž8¬˜9±6ºš<µ–@·›A°•G°™@¼›<³™B§¢A¥¨6¯©;¤¦4¦¬7˜¬5¡¨8œ¨Gš˜I˜L¦@ŽšH‰?„£;’žBŠ—E¡;„®>Š­2§=}«@‰¤=~¯F€´P~³G…¹F}²LªP€µA„»=vµB{½An´8yÁ4pÂ8wº5n»o°=t´Gt¸Gw¦Pq¦Oo¬Nm¨Bn¬Dp¬Ij¶Bs³@o»;n·6t»MkºOi»Bu¼R|¿V‚¬O†´K°F{©\­Z„¬M‰µO‡»O‹¾R•«WŽ´Z’¼h‹»e”¸n‘©k‰¡e¤h‚©g‚­_€¬e£kŽž]”n–m˜Šq–“m‘†hŒd’|l‡a•€c‘|q’g–ym™ƒgpzkŠoqru‹`z‘a{†].td/md7mg.\n+\]2\X8RT[UAR[GTdEZ\LVRS]PdiLjfTrt^iq]ordijhkpakvapiapl`€{\€_‰re„nY†k_n\Œs`g`…p`‹ueuh‹s`Šu]~K‚ƒI~T‡…_‰ˆbˆc”‡\’M˜”L”‘IœŠIªˆ?­—E°›;§ž?¦Ÿ0­¡/´¡6¹œ5¯¥B²Cª˜B°›=° @· >»œI·¦Eª£;ª¦B®@½J¾”K¯–=²žG¶œE³š;»¥9¹¨3Ĥ<¿£8³¦8¶ž>â<ƬFÄ¥GÁ E½ªI·§M°ªV·ªJ¼´M¿¨Q¾¢J¶›Q¯¤L®°J²²;¶¬C¼¯DÀ¥B»ž:±ª<§¥?±©J³´C©³=¯¬AŸ¡;š8¬§>²¥=®0¦¤4¬–B­™B¤¢6§ž4­¥-»­*¹¹/¨µ.°¦-®§5¬­6®©7¨©9¥¡>¡¬<¨°E¨¨3°¦/§œ1¥™6°A°’Bµ˜:¶™B®œ<ª–D¼•<¿œ=¤9³Ÿ?µ°<ª´;¡ª8¦¥7¦¯3–´:£Eš¡G¡M†¢I‡¦D–ŸAŸ@Ž¢F„©8‰Ÿ5‹­8‚®3z§C°Bˆ«E}¯My´I†ªJw®Rv¶T…²J„¨=}©B|¶D|¿:v¸<„·?€Æ4„»-x½/p¿0q»Ä G´:Ę6Á¡@À™;ͬC¾¨G»©KÁ°W©ªMº®Mµ¯Mº¢I½žI¯ªNº§L­±F³§?¶«1·²8ºž3µ3·¡=¬Ÿ>®µ=¸«=¬«Eª­I¦¤FªG²˜>±Ÿ@±§4®™+¦›/ª•8§”:«£6¨¥-¯²2¯¨,¯®5²¨,²¯1´«0·µ9®®:¬¤4¬¤1©®G¥ 4°«<¨Ÿ8 £3ž˜<ªŸ=¨œ@ª›AªŒB­Š=ª›=¿™<²œ:¶¨B¦ªB¬¬7£¤?Ÿ£6˜¢6˜¨2œ¦B³P‰©Q¥P‰ªFž«E˜©I‡ EŠ¤G‰œ7¤7Š²:‹µE‚¼Oy®C…¬Gƒ²Ky´G€§F†·N†µQ‰°;‰·A‹¶>‡¼8|ºDv¸<†È7Å5}Ä9{½Ax¿>~ÊEjÉ6mÄ>kÕ)`Æ(\È7`Ó0XÐ4WÊ,YË.aÉ:b·;\»?jºKkºNqµUmºIk§Nt·Er±;n³Do©:j°6e¼?oÂ6oÀ=hºnc0pY.a^4\];VS@XP8\Q4USA^MJZWBSW@UX?YP;[ZFSXINSWZOXeSZ^Ud^c]]gh\_cifjeanmZmt[ktTluS{mSuW{qUul[zmWz]y_ƒz]ˆwg–yc’i`Šj\‘f_…jT…iTŠh^‚s_ŠsXƒwZ‚yO‰zP”G“ˆJŒŠJ–•?¥ŠG¤Bª˜H£—@£–=°”:³™F¬C°„I­‰?©‚=³‰4¬Œ2¥—:«žH ŸEŸ™E­œE±¦=¾¥Eµ¤H½F½9Ñ:ŝ7ÚA¿‘CȓK¿–B½šF¸žK¹—@¹ LĦMÀ²T¯U¿¯P±ªQ¬ L± I¬¡K±¦?¶¡7³¢@·¬6¶ª9º«4µ£,µ©+¼«4¾¡@³¨>»¦A¹¯G­¡N¨¢E® L¬œD¸›;¼žC·¥>¹œ2¶ +¯Ÿ5®¥;²5²¬0¬¯8«²,»¯1±¸4¸·)¸­2³°-²¶2±­*±¢6ª¡:®¬9­¦@¦¥?¦›6œ£>Ÿ9š™< “F¯‹E­@³˜K²ŸDªªG­°Cª´E¤­>§¯?œ¤5Ÿ¡1’¬;“¸=‹¶J‹·F­H®B”²D°BŽ¨?Ž©H¦C–§E¯;Š±<¶L‡­P…³KµG|·B‹¨Cˆ©K~­R~¯Gˆ·Bˆ³;ˆ¶5~¶=|¸2ƒÅ3‰Æ>ÆD|ÁLÌD€×I|ÖBxÔ3hÏ-f×5[Ñ/R×4WË/aÔ.aË+V¾4XÂ8XÄCV¹FW±Pi·Jv·=sº>h¼4j±;d¬¦5¡’CŸŽ9§…<£3©Š1­1¦“;¨‹=©‘=›—>žŸ8¯˜C´ŸA¸¢Eµœ@Ś@ÞB¹”:Õ7ŽBǘF¼’EșJÃ¥B¼˜KÀ L¶•;¹£I¼ C¸ŸI·›T¶¤J«™I±žM¸ŸM¸¢F³™C®¦D¶£7½ž:ºž6­¢2¿ª2´²9¸¨3¯¬>¹±B¼§Fº¯<®¬F³ H­¡B¹”D¯£F¸§@¿¡2°¡3§–(®‘/©¢3µ˜-¶¢9¹¤'Á­2ij2º±*¼«*¼°%º³)¸«:´­6©š6©›<¬ž:­•D¦?­ž: š?¡”@¥ˆH¦‘Fµ‘J©Ÿ?¨= §>ª®<£²D¥¦D¦¨? £4ž¤<˜·=˜¦=˜©K”¬F–¢L—±:›´C”©?† K‹¥=¨Dš¬BŠ­9ˆ¨K½BŒ²Lˆ¸D€µD|ºC‡¶KŒ¯F©B|©AŠ¬E~¸={·@{³1|¼?|Ê:zÉ@|Ò>ƒÆCsÉFrÅ>zÚ@pÚ9gÑ7^Î6dÖ.cË,SÌ5ZÌ3fÎ3^Â3ZÀ3a¿BUÃAj´Dl½KlµAhÀ>f´7[³=^»Bi¹5fÂ6iµ8lÁ7p¿;q¸Ek½Kk©N_¢Un¨Lu¡Vv§Gz¨R†«H„¦G‡®E‹»I…±Q‘µH‹¸W…ÃO€»Iƒ·UŽ³MŽ¤V†Ÿc~§Y¦^ƒ«R„™Vƒ£d}˜]†œf‘–h\„‰Y|“]ƒŽ`‘‹a…‡Uƒ†Yw‡Uz‰a€…V…eŽ†X”zj‹l]„f[‰cpŠmm;kZ0gW/f\3ad/bP+bK4bR.ZW3UM*[G+OS0TS@OR@ULGTWTJWXLUZSRZPb\Sd`O_]W^^g^Qj^]hYkf[npaqjdsqYphKobOxfP„fKuJ„nZ‹fYea•hc‹mb‹pa•mcŽpSˆoNƒzN|sH„lR~kS„sOŽoV‰{K“}@•}Ey?ŸBœ=¦”8£‘6£ˆ>¤ˆD¬”A¬—;œ53ž€7¡< Œ4¡‡4°Š0¯‘-¤‰8”D§œ?«ŸD®–:¡@ʜB½›@º•AÀ›A¼<¸ž7¿=Ê©FȧEÆ¥G¶ŸG»–;¹—:¼”:¹—@µžL·™T³œW±£IºœNº•B²›7®¢<®¢.²ž,¹)°©7²°4»±3¾¸1¶¯?°¨<²©6·±?²§:±¡>µ–@­•C¯š;¾™=À©1À¥%®”'µœ(¯—(¶—*Áž1Ȧ3È¥$Á¯ ·¶-¾©/­(¾©6´ª8¬¢=±:³¢A¯ 9©“E¤Ž@©–5±“;§‹G©ŽO­—N°¢L­›?¤’>©‘;¡¡Dœœ?¨¨A›±?–¬AŸªFœ±>œ²Jš©P—®L‹¥A™¬7—ª>‰ª;Œ›F•žH˜¨DŽªN•§G¬A¶?±D~¶;‹ºAˆ¹L²P†¸C¬<„±C~»E…µ<|¹A~µ4vÂA|Ë=„Í:zÌ6oÄFsÉJtÑo×6gÕ<\Ý2^Ö.UÎ:ZÅ?\Ë0ZÁ/]½.V¹;b¼>`Ã4pÅ8y¿Fn·Ci¾ÃžN½;²œ7´›=ºœ2¼@ÁIÀ™J¶¡MºŸQÀ¥N»•D¿šD¯‘1µ.±¢/­˜(´.²ª8µ©:¶³1·«>¾°9¯§0«©;§œ7«®;­¤=©—@±œC¯•:¾£5½¦/±£0¬ž/ª’!¨–.À’0Ĝ,½§#ñ,¾².ij/ì-Ä­"·²,¿«+©¨8¯¤3³¨3©©=¨•C¦“A¯šA³›6©šF«C°˜N³˜P¢“Nœ“Kš@¢¡9›¦HŸ°;™¯G›ªB—­E¡¶Iž­G¦Q“¨J£Hš¦FžªN‹¥J‹—>‰ J’ŸBš¯B—¬GŒ¶E”²:†¸>‚±8€¸>|·?€¾E‚¼F’¹J„¸BˆÁ?“°A„·:~¼7x¿9„Å>tÎD~ÉE{ÊDqÇFnÒ;xÍFtÉGsÜClÌAiÐ.^É?_Ë@\È1_Á/fÉ;[Ä<\Æ,h¾3o·5ƒÂ?w½Co·E`Å9VÃ<_Á0`¾=`·9e¹0k¼8h¿5c´Co°Jc°Oj¨Pi¨Lo¥IkŸL¢B~ª@„®E…®Q¸L¬N‹¿SŠ²V„µH·Gy±HuºT…«KwµNq©Yu§N|®J~°X‡¡M€¨Y„ PƒžR„—`ˆŽYš_‹ŠX‹Ž^‡Še{€ay‰hs„axŒhy†^Œ…gŽƒ[…vg|}e}}c€wd0T_,aU7YN7`V1Y_+TZ"XQ'\N$RX%OR%MX1CP??IDBQKQNRQU]XTYNSXP`WWeXSeQZZUSSRY]UPb^Wib`ckaav`[~aL}_MƒmLŠlQ‚^HŠaFˆaQ˜nW˜oT—qV”tauf›rbP–O–{P—WyN“pP•qU“{K˜};š‚<“€:—Aš4¡Š6™ŠCG B˜‡Eœ}Jš}DŸwG¤w9›†?¢=®‹=«;®Œ<¤‡4±‡2¬‹1®Ž*¿œ-¿›.ƛ9͑D͐BǗFÀ™E¶¡9º¡=»¡;ĦFº›D¼ž7µ˜9¸’9´›D¿EƕM½šG¾žL¾šC³”>³˜:¸–=º˜.´–)´ 3´œ/¯£5½ 8¼­<¼«0· 4³™8©Ÿ7©¥0³¤4ªœ.¬š6­—;¸ :¸¥7¾¨4µ¥2¶¦(µ+²”+»“ Ĝ$Ä£-ì,ȱ.É®.Á¬*²(µ#¸¦.¨©7¤ª<ª¦3ª¢;¯¢:®“<¨–:®—=±=¬˜H²“E®Q£–Rœ˜L—ªHœ¬?¢¯Fž°>§·Fž®H ¦K˜ªL˜±V”§R•©Q™žO›—O™šL••PŽŸCŽ¨E•¥9˜®<‘³B•¼9‡»9{»5~²:v­D|¹<‚Á6‹ÄA‹Ã?’ÅJ˜½H‘¶DˆÃ=„ÉE„Ë?{ÌwÔ@jÎ@mÒAsÓ=kÌ9gÈ7]ÈAcÆ@iÈ4lÉ0e¿5dÄ3hº0r·;{À8xº5i¸=]¸3_Á9WÂ5_Ç2k¾(h¼/k¼6]·=_²PJTLK[WIZWDTUFXTUi^Tp^[iTTdWNT]PUUSVd`an_coX_mbTsZQxaLylI€fK{hFˆ^OŒ^OŠbT”f]gV‘q]Œnb•o`—‚R–‡PšvSuN’wJqIšwH;˜>˜†?~D’Mœ8¥0¡ŠB™}A‰@šŽ@Ÿ‡<–sHœ‚F­}C z=œ‘Aª?¯C«Š<­1·,±ˆ0½Œ6•9’4¿š,ˊ<͐<ØH•F¾›<¸¡D¼£@¿¡;¶™CÀ˜5´–A¼—/¿’EÖ:¡;¿¢:ºœ?º˜C±ž1´0¼‘4¾–.²”/» ,ºž:¬«5¯¡?¸²?²¦Bºœ:·2¯¢;¤¤?ª¬5« <® 6¹¡9¼§=Ä¥/Å¢6´­4º¬.¯Ÿ)º‘*·›)Ä¢*Å©&Ī/Á¤/¿³6ǵ3õ(¾¯%Á©.¬3¬¦6«9·™=±—F ‹@¦›Kœ”Aœ›<«‘M©›B§RŸ˜Qš¨S’¡KŸ¦F°?›°I˜³Jœ®F›§Hœ±Ož°J˜²P“«N›¥Y¨J’¥HŠ¡R”Bˆ¬GŠ¨>“²A‘°A•µE‰¯I‚¹:¾>{¼B²;·D‚¿?’Ã@ƒÂ?…½M¶Nˆ¹D€ÇC‰Ç@€Ú=tÑ>nÉBoÌG€ÒJ{Æ<€Ò;uØCtÐGpÔHcÈB`Ò7]ÍG^À:aÈ3f¾7gÁ0bÇ9qÄ6hÁ=rÎ0xÃ6a·8b»;eÊ4i»5cÆ/e¸,r°1k¸9`´0g¶0]³9l¨Go£MhšNj™Mož?j§Ez®?i¤Ly¯Qs¬Dy­LŠ¸G‰²LƒÆL|¿Fl»Ix«Bz¶Sh°Fg·Rs±FqªG|±P¯Nz´I{²MŠ­I„ŸM‘š^†œR‘cŒ_€a_x…`{fŽb{‰c€†jm‹ˆlˆ_ƒwl{`.[_)JW4SP2[F9VH6QC-IN/JM+IM4IC-HA6JK7DM>O]RNWZI[`HZWHbYNoeKnaOhWO_VRW[WU\PXfYUcOdjVguZYw^X€`L~dMykK~nOŒpZˆjSŠjXfT‚kT‘sVmR“xWŽ{Q•V™xR•yM˜…L—B–„8˜…<–ƒB‡D‹Š@G™…Ažˆ8¦yDžx>Ÿ‡D …E–LwC£€?§y>£…3¤ˆ6£‘4¯‰>­ƒ?»„/À/¼ˆ2»‡5´ˆ4½“-Ō.ė9»’B¹ BÄ DʦDš9ĝ5º”6Ö?¼‘>¼76¼ž?Àœ>¹¨4¸¢;¹£>·ž8·›4¸‘2²“/´š;¼œ;¹›3«¡1®¬:»¬9¾§?æC»›6ºš2©¨6ŸªB¦¦<¡4¦š=«¨3¸©0¶¤-Á£8²ª.´¤(µŸ(³™,µ-³£+¼¥(ș$Ǥ)·©-²¬-¾·4½³,» -½¤/±=¹•=²E«ŸH¢”M¢œI›žJ š=Ÿ“@Ž?œ–N•ŸP—§N—¦F—©H›«O °J¥£F¢¢H®O˜²L”²B–®Hœ¤W–£Z¬W­J†§LŠ¨L‰­F†ªO†­P•¬?–§IŒ¬J±J{¿G…²H~¶?€¼E…Á?ŒÇDƒÉ;„Ç>ˆ¸MÀL€Æ<ŠÊ8„Ù=€ÛEuÕ?xÍ;wÌ<{Ï5€Ð;„×D{ÐIoÊKdÏFfÈ=kÃ=_Ã5\Ê=\Ì:aË:`ÆBkÇCfË9qÊ7sÆ5g¼-k½%hÈ.bÅ,^µ5dº/kµ/e¬3Z³3SÁ4]½0f®8j¬?p¨GpDm¡Bn«=g¡Jk¤Nv Pr¤C{´E„³M‚µIw½Jl¹Fn¯Av½KlºHi³Qm¸Jq¯Rn¯Pt²Q‰¥J†ªE~®K‰²Pƒ¨PŠ¢U‰•[Š’Z‘Xƒ•[‡‹b…”bs–mx•e„‚c„g|~q‰~m„€f‰†m~c&MJ%QW2VD4XC1PI.HD)MF+CK(GG/ED=HM1CV:CONMeUOZRCaXETP@ZYIedKlXT_ZQgRSY_[abK\VV^h_hh\mi]it[dphZ|fWyeSylWz`W~_]}k]vnTŒg^…{[vRqTqZšyI‘uF™p=y@ž~E”€GƒH™ŠMœJ•{EŒ…Kš|I“ŠBœ„9™u3ƒ:œ€B¡ƒB£z>¨|9¤}D±…0¨‰.§{+±‚1®‚4¹{0¿z)»~:¶ƒ/¸’4µŠ0ʑ/¼Ž0³—;ĖAÀ—Dē?‘>½•5²’.²•4°‘=µ3»‡;Á˜6º•;¯¥C³ 8¸ C¸œ:µ›=µ›(¹¢:¾ .®5´˜1³«8¸ªC» 6½¥6µšAº›G¨¥=§¨EªªF¦¥?¤§G±¢?«¨D¸¬4ºªBÀ9¼›1´,³™)½—3»Ÿ(³¤/´Ÿ'º‘)ƛ2ª3Á¡5¶µ8¸ >µ›3°–9³Ÿ9»ŸC¼¨E±£R«˜Sš‘J’P“¡@¦šD¡•E ˜HšžS žU ¦Q”¤Nœ£P¨F›ªU•¢RŸªJ˜²S’¬R±R®X“°R‹±W‰²[€°RŠ£Y‡§Z§W†¤L™±M•²C†®M­FÄ=Ž·?…¸A„¾9ÁCÍI‹ÇA…É?ˆÃPÌ>†Ï;ŽÌ9ÒG‚Ò?{Ì:{ÕDsÄ=Ì6„Ùs¡Caœ>a©ApŸJj¢Ns¥Ak¡=w´Ou«N~°Nn²Ep¶Js¸?m°Hj­KjºCuÁJq»O}®W…¨TŠ¥Ry°T{³T}¢S‰¤\Ž›[ŽZ‚”b€›^‰TŽZz“iŸkx˜]…‘ha~}izjw^…wd„ƒ`.OF*NN&FK-GF7JK5HE-LA+EI4MN0EI2@T:GQ=MYMH^KGWNDZECdL>\V=f_KeXSj`JeYHZXQ^YPkPMf_S]]^cn_^qfbs^R{]RueUze_}mbte]|iZ}tU…rW†sX„lQvZ™wZ”oJ•fEn=“xF“€?—‡?‘…G’K–KyS‹yIŒL•|?•‚0•€2¢z1 }5®ƒ;¬†<£„B©~:ª-®}+µy.³|.´w)³y*µ&Á€2º‰*¸Œ*¾4¾’.ž/¸™9À—57×;¶•4°Š8·‹+µ’-µ‡4À„9¹Ž7±Aª™?´—?® :ºšD·¡<À¥;»ž.µŸ2¼«0¿«*±¦/¶§1²§=±¤>¯œ;¯¦:¯¤G­š?°¡E¤¥K¨›F£¢E¬Ÿ;²ªBµ¬F¼©E·¦>ºš9Ý)ɧ+¿ )¶™*º›.¹Ÿ+½™0Ɲ*ƚ(Á¨/»ª5´›@·™?°š>¸@³šF´£G«—G¢™M¦—L™—M’“O››C¥MH›§Rœ¥K¡¨R—XŒ©N¤R™«K”±R“µKš±N›°RšºJ“¶PŠ´R†©Pƒ¦^¤bƒ§Zƒ«Y€ XŒ¨U’«K‘¯DŒ¯B®DŒºB”¶F•¼:·CŒÀ?¾JËG‰ÃI‡ËD‚ÕKˆÐA‚ÕAŠÒF„ÎE}ÉDÆ<}Ë:×A€Ñ8ÙE{×FqÚ=lÛCqÛEkÌ?pÍCpÖIqËAgÐGsÐFmÈCkÊBxÒ=sÇ:f¾5c»3i¿/k»0k»3q¸,g¹3iºAiµ?e¾?Z¶9b¼>Y·4\ª?e¨@l¡K3LG7RNADV@?PT9RL>HS:WR>OVNd[H`VLYWV[TOcWP]PRdTO\OYec\encefa]sVQo]TnXW{^]nadpeayq_„hQ€jP…x\Œv\u^™oS™yI‹qNŠnB~=›„EŽ†@‘~NšŠI¤‡Q”O|9”u@–s;w1.§x7¨Š5¬}8«ƒ;«2¢‚7­ƒ/§Š9¶}.¬v&¸z-¶0º~'Ç~0¿)Œ)·‡*¿“(º0½¡:¸™9Ä¡=º—+ºŒ5¯/¯’'µ4·Ž0²•3¬‰@°‘9¬”C´œB§¡?ª Aº—AÁš6¾¤4»œ1­7¶¤4°®.¬¯1±­9³š>ª›Fº¢Fµ¯N°E¶©E´–G¤—I¤¤GºŸ8¸ŸH²´Q·ªHÀ°9¸«;¿›3—0Á¡)¼6¶˜2Ę5Ÿ4ɚ+¾4¼­6ǬB·©7±¦GÀ¦J¿¨=º§Gº¢A¤£EžœU™‘M—šRššD™—D££J¢—L›¨Q•£C˜¤Q¡ªVš£Nš²S•©R›²K˜­Q¡´I–¶Y‘ªP‹µL‰±MŠ©Y‘­^‡¥V†¥YŽ¦]†¬W‡¯\ŒµOŽ°Pˆ²JƒµD“±F†¸I’Ç@Žº=É5ˆÈBŠÃH‡ÇD‰Æ@’ÊA‰Ñ?€ÏK‚ÑT|ËBÄK|ÊK‰ØGƒÒ;vÕ@}Ú@€ÏLyÝGjØGsÒFpÅ>jÍGrÒFdÒHgËHnÆNdÂEqÆEzÓ:uÎ>fÃ>lÁ6`Á0j´-j±+e³/_µ9g³4`±7b¶D`¼8[°8\´>AA@G$>L&JM1MK&HI*SD8JH5BUCDSBOJ8?A?@GG=BU;GWJPMGOVFPWE^XI`MRVQIPbH[\NUT[YP`d[Z]d[`lTZfR`hUYvfTrf_sdglm]no]~iPŒdS‰oN•uM—xP˜yOyR–}EŒr=y;›|DžˆM„G¡ŽJ¡M¤‰=ž‚:£„7žxA›€:|,¬ˆ6©†;«‚8›|1š9¡u=ªy:¢‡;±‚2µ.­y"¯~%±}0¿s+¿„/Ž9̆3ƍ3ǖ-¿š5Ȝ<ʖ5ʙ:ő/À‡4ª‹.­Œ&®Š,¯3°•A¾”?»œ@µ›3¥˜5¨›;µž<¹¡1¼¤1¼£;¬œ3²§0¬¥>´®?¬ª6¸ªD³›Aº¤E·«E·°:®£7¤¥C§šFµ¤A·§=¼«L³­K¼«D½°:·¢0¾–2¾Ÿ/º—8/½—*¿¦*Æ¥/¿¢6Æ©1Á³5˵=¼·?¶¬@²ŸE¾£I¹£Q³§Kª˜S¢˜PŸ—P™›P“”M›šQ¥¡OžžG–¦Q•«I“®K¡­G£§M˜®K˜©K›±Mž¯L¡¯U‘´QŽ¨V€ªW€¦H…§O­O‡²R‰²_”·Y‘±]Š¼Z¸L‚°M‡®VƒµMŠ¯L¯LŽÀE†Ç;ŽÄ<½I‚ÄGˆÈAŽÌ=„ÆI‰ÊG‡ÏI}ÅR†ÉMÇB|ÌQ„ÔO€ßNxßFÔ>{ÕEvÍEnÌFuÉ>kÄ?lÁ;eÆ;]ÎDeÑFiËKgÈFhÔCjÏ=tÉ=nÎBmÑBbÄ?Zº?`¶3_À8g¼5^´¤~CŸƒ?¥Š+©-³„1¨„.¬|+°r*µ€(´‰/¹;¾“Aə<è/˞1ř/ʚ6·•=½‡4·<´Š7³—2¶‹<µ˜@»A±“;®”6¬‘=ª›Eº¢D±§;»®0´¤-³«5»œ<·ª;µ›=²ª?²«;¨¢K¯ªE±£Bµ£8¹­8²¢@´¦G³ K®¤G­®J±«D¸¬C®¶B¹¥4·˜<¼›C¶—B˜?À™7Æ£*»š5é/Æ®9Ò§0Ê©6Ì´=¼ :À­F¹£B¯¡Eµ˜Q¨—N£˜S¦”J¨¥O£¡R›žIž¢K™©R•­Qž¥Mž§Oœ£O´G °V™´J¼Lª°Z£ªMŸ¤S¢W‡©J‡¦H¶H‡·Z“¶W•¯b‰¯Z•¹^µRÅN—³R–¯IŒ¹Q‡±J‰ÁFÀO”¸>‰ÈI‹ÆEˆÆJ†Ä@ƒÅ@‰ÅJ‰ÐKƒÈNvÌL…ÌE†ÐLŠÍNÚOwØK}â@yØF|ÓKyØGmÎAlÉChÍ>uÒ>gÓAiÑDeÐFlÍ=mÊ>fÐ=pÆJrÈHkÃ?_ÎGaÇChÄ:a¼8`¾5fÂ6nµ>sº>a®Aa´?c½8t­Au¯Is¶Lz¬Co¤@n¨Gy­Ns²M}µN~¦M{¨RƒªQs¨Q|¦G£Hw=o­>}¨@u²3w®@~²S}­R}™Q‰©R‚¢S‚¥\”š`Ž›[Š¡bxœV{¨[{©T‡™]}š`†¡k‡žhz h}Žfx•Z}‰azƒ`‚ƒ`‹‚OU?"I@%=?$BO*RI#PI+RC.VM3YK@RNJXHCNMFDIRHP]KOYPJSYMZaIRcNXfW\m\OgTSj]Xb\Rj_UnbYmaTsjZudR|ga…q^‡iXŒpYˆsO‰sU…wTŽoR›vP™rHœzG“Š?˜ˆ7•>¢…EŸ‹C¡=§‡?¤~>„4–ˆ7”.ž†8 ~3¤w/­r/³o6¨x@©†A­ƒ:¢~.¨‚+¨ƒ+¥{'¢v(°z&ª…*¬Š'±”0»™=Ä¢8Ȥ6Áª.È¡0·œ:·‘9¹Œ6²Ž;¾ŒG¿•B¸˜9º™=¯¡<³™;ºœ;±ŽB«Ž7°ž=°›7º©-¸¤+À©:¶ AµžG¯œK§šC³¤F®ªJ²£Eµ¨I¿£K»­=°­:³®>°©?®¥MºžMµ¢Cº¢M¯«G«¡@¨šA¶;µ“C½=º“>´œ1¿Ÿ5¦5ʨ4Õ©5Ñ­6É£8Ë¡D¿›A»¦I¯¡S«—Tª‘^©šZª™S§ŸN¦’K©–R¤¦UŸ§Q›¡Lž¦Už«J™¤MŸ®R¡±Uª¯\ª¶U¢²K£ªM˜žT¡J„«GŠ«N…¸Nƒ·[ˆ¼f‘¯bŠ·eŒ¿a‰»f‘ÄYŒÅQ”µK™¶NŒ´O·G•ÁI‘¹M’»EˆÃOÄK{Ð@„ÎE‰Æ?‚ÇB~ÈLwÉT‚ÆN…ÎJÜJˆÙQ‚åFxáJrâBtÙ@wÔAhËMiÌOqÌKoÈArÓCh×FoÏ;mÈ7kÌ;tÔ@nÊHsÍ?hÉ<_Ò8_Ë@^¼9b¹6f¶6o¹:z¿>t¹1lº3l²;u´Jt¼Kw¼Ey´Gs³R|­Kz­S~´Q´Zv³Xº[ƒ¯O|¨K{¦OwH„£M„¢Gy›<ƒ¨<}¨=¡E{¥Gy©U…žX†¥U‡¦_Œ£S“SœQŸX€§Vuª\¬\~Ÿ\w \¢gˆ›bžj†“d}atŽisŠb‰`~€\$L>!IC.PG"ATEE+QF$NG:TL1GEAUO>FDAOPJLOUPKPNPHN]QSbJ[]ITePOcMMd\RhYFi^IicYikKriSo_ZrdQƒgRƒhbaRƒdXlM€jQ…fG‹kF™gM”wK”tNž|:‘†E‹’=Œ:—8—†>¥ƒA¤‹1“8ž‹<˜…1š„=£{.žt-¯{7§w@¥wIµ…6¥z@¯{2¡}2­-´{8³x#²%ª‡1´3ª”.¸;ŜCț5ř/ɦ6Ǥ.¶Ÿ1¸”/«œ7µ–E–D·JÀœCº 9³•C±›;ª–J«’9º•0´™8¸£6¿«4¾£9»¨<µ¤<® J®¨D¹­O¿°E»¬J¿¤I³®M»§DÀ¦B¶°D´ªQª²Pµ­E¿©G¼±N½¤OªL«I°–E•M·IďB½£9Á8½¦7À¬:̪4È©8ϧGÌ¥LĪD¾žD´¦J§¥V¦£Z®œW§¤]¨žSª˜H¥šV¥œO¨¯X—¬Qš§T¥¡NžžG¥©J§V °O¨ªUŸ¯U˜®K¤¥Q“£E‹¯Tˆ²Hˆ´N‹¼OŽ´V™µa›ÀWŽ¾U›¿_ÃUš¸N“¼J‹¸T½NŠÁM·I–¾LÃJ…»FÉEÃCŒÊEÉ>†ÂH…ËC~ÐYwËVÉD†ÎY„Û_‚ÞWÜUr×ShÚ?pÓAfÑTqÊFxÏJsÈNvÃ@mÅ=qÎ?g¿>tÇFlÂChÆGjÊEh¿3bÇA`Í?aÃ;d¶2k±3tµ;p¸;k·1j·?oº9o¾Bn³A{¶@€¹A†¸Qy»M~®Q€°Z®[ƒ®P…²O‡«F~®K† Q€¡U‹§L|¨K§E‚«?~©LuFt¥J„—J|–X‡žU’ŸS‘˜^• P—\wžMt­S|­dx©X€¨X€ªX~«d…¡_‰›h}Ž[‚˜gƒ—]“cvˆY„PHN'DE,F>0OG%QL)KJ2LN4KM>LA=IFDME9NAAP=8M<>I:?Q@DJK?BG=AHKPDON>QNFISJQQVRUV`IMZQVcNNjHPdQBc^DkaSfeYklTz[Vz[S{ZP{[[x\Y~bM}gG~dH~fKfKpNoOŽzJ˜}A–CŒ‘@‡”B‡<ˆŒ:‘ŽA>š0žŒ3”z?Ÿz9œz4£o<¡u8±r9³|A³‚<¨{6­}9¤}8¨„<³„8ª„-±‰*²‚5ª1°‡A®Ž?´—<¿“<½ 9­8Ş7¹œ/¸;°™8¹‹:·A³™A¶ L­’Mµ’@¬J®œD·š<º˜4¼™0Á¡5ě+Àœ2¹¦1¾§Aµ­Iº¯C¼¨AÀ§O½«G·«P¸¬PÀSµ¤M°£S©©Yª°U¶®V¹¯I¸§O»¤V®¤N°›E¼›EßSÀ™YÁ–NŸAÇ£=Å HÅ CΤBÊ®?É«EÅ­C½¯?¾¡<­¨?¬¢M®›S¬¥\«™V ”Ož’G£’HžšV£ªT¡£KœF¡œF¦¥Ož V¥¢V£®U­¬N£¨F™¢I¢«J¡¦Q“¬Q‘±O˜´R½M™ÁW™·T”ÇO“ÅUœÎ\žÆWšÈZÀMŠ¼Z€½W¶R–¹EšÀL“ÀLËB‰ÄG„Ñ@ŽÑIˆÑOˆÃIwÆSsÈLyÇQ‡ÐMŠÝX‹à]~Üa{ÛWrØKiÏJnØKqÔNtÔIsËFlÊIu¾Gn¿Mk¾Bu¾XÈ;Z¼0NG7LB6IA;V?8L@9EDJE@>E=C@JUHFRJOHOQLGVYGOUCUZ?RkAHeMKlQO`SIaaLfeKh_StfR}_[{[KvZL\Q|_Iw^KƒTF€YH€aH‡hMŽkN’wL•{N€?‰8—?Ž‡<”3ˆ‰>‹‰B‘Ž8—„>š:™„8™{;£„F r<¥nG¯{A¯vC¨u>£‚<ª‚?¤ƒ7¥y8¦‚0³ˆ0­*¥‹0¦Š-°Ž:®‡5±–B½›6Á¦0À±<¿œ;½•-³˜4·‘F®•C´Š=¼M»’E²•A¼”@¬’@³”I» :º @¶š1¼¡:È 3Ì«>¾¨:æF¶©F®;¼§HÀ²QƦM¾¬Y¼­XşYº R¦¥I­¨K®¨Y®¤O¼©T²ªT¾¬O´§N¬H·¤R»§MɖW˒HśJ͘?Ο?΢CϤIÏ°7Â¥EɯBÌ¡CɦB¢G¶©NµW®¬^¤–R®•J¯šL«šMžW¦«J «Q™«Nš«K žN¦¤W©¦R¤¨O§ TœªH›J¢¢H§ªY™­W”¹J´R–³S”µPÀ]“ÀS’ÂW¡¼V”·Zž¾[–ÄZ‹¾Q‡º\Ž·T†¾BÂS”¹[‘ÁO„ÆQÉV“ÄKÊK…ÎH‹ÇNuËV|ËH„ÑJ€Ò\ŒÚV}ÒVrÒYrÉRlÊUsÑXpØSdÐCiËLr¿Dh¿;eºBuÀNnÁw´5q¸BhÂBkµ=r³Ku¸M€»E‡´O~½L‚¸Wˆ«XˆºU‹½Y‹¶O~ºF†°I¬;‹­J}±Iˆ°B…¡D~ŸH‚ŸKƒŸL|šNw’F€’Tƒ–UˆžW’—T«YŠ¥Ux£L«[~«^s¢X} dw™a¦Xw¥a¥Xš_„˜_ŒcŽ”S€ˆS}W[?RI PA+IF5LF>T<>XE?ODDOC:VCAVG9K@7MCACI]FBlKDkUIcbJl^GihGy`G|^S{`R~fSveXyVKu^N€XJ„VJxUCz^C…gA‡o@ƒxEŒxE’B†:‚Ž5Œ?†‡7‡Š6ˆ~5’5“‰@—†;Ÿ@¬…J©ƒF°}K©vM«yG¯}@®€?«€@¤B®|:«…>¦Š8 €:©…3£„*®‘1¨/§‰<·Ž5¸š0º£-º¥0¾œ6´ž9¹=­•F®P·”J´ŽR¸•H·œH¿”D³—:²š=³¤Aºœ=º™CŦ;Ì¢>È«:É£:¾¬> ?À£=È£BîMÀµS°[½¦W¸¡V¸ S«¦J±£T­­Pª¯W®ŸQ¸¦R¸¢UµªY·©LºªK¾P»šUǙLƒFƛNÍ¡GÉ¡HğIϪ9βBůFÄ¥FÈ¥AÁ®E²¬M·¦G­¢R¯¡V²P®˜X¬ŸS¬¨P¢©K¢¯Eœ¨Kš¯M¥¨Y¯œU¨›W¨¡W¢™O£•S¢¢T¦²Pœ²O’»J’³R’µY”µ\ŽÄS“ÂVœÉQœÀS·T—·Y•·O–ÄVŠÉJ…¿O{¿RÇPŒÊ[ŽÃX€¸`€»`‰Å\‡Ã[‰ÅSŽËL‹ÉG‚ÖQxßZÙS|âLÙVwØXuÍ[{ÐVrÐUtÏ^eÒUdÇGcÅGeºIc¸@a¿Jo¸Ip³Jj»Fh·9OEFDU>DNJGTAL[:OW;IWGA\FCiMi_Jc`=d`OghFijLufIaEu\FnQ9rW9‚SD€aI~SB†WF†^I~b<€u7wFˆˆHƒŒ8ƒ‚:…‰3x;‚};…{/‹;Ž~9 F–HŸ€D¦‹L§‡J´vJ©ƒ?­„Cª|=±6¯„8²‡E°†<ªŒ3²Š8«‡>¦0±’@¨’CªŒB«–8«›.¼™)¹¦-­¡7© B± I¨—F²‘Q±šI¯œE±JÀ”KÀ¡D½—=ºA»7½“9´©C¿®8¢>È©@«@´¤I¾¨?Ĥ=Ä©L¼¤Ié]ɪ^­N·§P¶¦G®¥H°«P¶¢O¯ M±•I¸œZ¸ U¹ Nµ¢Nº›T²—ZÎNȜRşHÇ¢VÇ¡VÄ¢NʤCУ@Ï¢:Å«DÁ®D̨7µ­J°¬M³¦Sµ¤Sµ©Q¬¬B¦«N«¥C¦©IŸŸAœ¤Fš¦Mœ¢K©¢TŸ¥Z°ŸU¤¤_¨]¢¢RŸ¨[¨ª\¥¹[œ»W›´P—·N—½S›ÀY˜´`“½[–ËQŸÀ[˜´\ÀN‹¸XŠ¹]Š´YÁ\‚ÒTÍS’º_‚ÀVŠ¹_»U}ÄR‹ÓXŒÑOÜW†ÛI‚ÜR~ÎW{Û^wß[tÔ[ÔZwØ\lÕOkÜU]ÌUeÒRa¿@]ÄKj·Gr²Ck»Jg¼;iÄ9e»HcÈ>^ÅKd´;e²@^¸9eÀ3k¹=o¼6d³Cr³1q°2uÂ5bÅEvÂGpÁC€¾Oy±O…´Iƒ¸F‚³Lˆ·S†ªP‹ºVŒ­J~µH‡¶KŒµC±G‰¯7§?„žH™GŠ¢=…‘H•E~žK‡—Bƒ¨?Ž¥O“ªQ³P†§Hz¢W€ªRŠU~¨\€«a{žet [€£b‚™c…š]y“Y‡Œ^Ž•^†–R”TG>&L>2M?0?I/KM3JN3KJ>H9DL4BE5NIXKN\CLaFP]:H`jdI^[IZgAgdAf_>tfBug=l\8~X8\3v^>wZDy\J^F_8Še:wJ…€HŽ}FŽ~A‡n<ˆo;…:Œ‚.œ€/šq5–s>›uI¯zJ²‰G°ƒ8´7¸@±†>¹}A±x4ª‡C®ŠGµ…>³ˆ?¥D£?°;¬‰?£A¡‡>©•@¥“6±˜0¹™$»—9®¡=¯£B±˜K±žH¬¡F¨¢G®•R°™DÀ£<¼—3²’4ºC³™F¿¢CÁ­>ɯ;ĬB¸¤;»¨CŪFͬBÉ¡DÁ¡MƧYÁœ[½¦Lµ§F»©B²K¸šL¸¤N·¨I´œR¹¡W²¡Y²§OÁ›K´’Nµ’U´—FĒG̖IÈ£S̪U˟LÏ¥GÒ¡9Ø­4Ò©6È¢CÅ >¾®>¹¬E´£Q»¡M½«H­­B£®<¡ Dž¡J¬¡F¤ŸL™©U›¥]ž¥U¬¬Y¨§_¨¨X¢¦`¡§^­¡T¨¤Zž³]˜²T˜·O–½QŒ¿TœÁR›µXžÀ[ÅV–¶R˜µT‘ÀU¹V¼Z‹º_Œ½^”Í[‰ÍbŽÀZÂbƒ½`É]xÌZ‡Ö[„×P…ÛSyÜNrÕ[{ÐY‚Í]{ÕWwÓ]ÖQ|ÒQuÞLtÜNcÕL`ÉEbÉBkÃBnÁHf½Bm¸?r·Fl»ˆ™7~˜.„š6ƒ¡9šI¥N‚£D£Q¦NŠªG„®F| MzT†£[‰›b…¥e…¥bšb˜aw¡\|œ_Ž]~d…˜^‹—U…¡V‹Ÿ\*N=&U>(L91?J1II2BP:AD4CF@CQAAQ€hA„zJ‹~?‰t;w2l>l.ƒ{0–u9™h>™o3£oB¥„I¯?¯y6¾z?­†1±‡A«€;¨z=¥~6³ƒ<¤“:©9¤‰?£†D¨Ž5¯†7«‡;¦†?¥–6£3¬‘/ªŸ­”7´©?¶™>·™Jºž=®ž@³¤K´ T²˜H»—>±Ÿ?¾œ@½Ž9µ™E»™J¸®FµžL»¬H¿ž@¼¬CƛAÒ¦RÄ£OàSÄ NÈ¢Z¼¦U·­HºœNºšN½¦S¢U¼›V°šM¿›Xµ«J·¢FÇ¡O»—H¼˜K»™IǞ@ȧ?Á¨MÛTMƞM˘;ɨ>Ë¡CÍ©BÒ©7ǧHÀªKÁ®H¹§L¸ H®£F´¡C«ªJ§Ÿ=¯›?¢©P˜±N¢­[œ°R©R±«_¬£^¢®[¥«c§ªS§±_¥¯T¨¼Q¢¯K•¾X“¾W™³M’±UŠºO—Ê[’¸Y“´W’»P–ºMŒÆa‰ÈcÁW‘ÄNÀP…ÌT}ÂV†¾V{ÏUËUƒÉPŠÝS„ÖX‚ÑVuË\ÒSÑbtÏa{Ô`|ÐW}ÞOuãIcáM_ÒXXÇLcÅAjÉKqÇTnÀBmÃ?nÀBeÀA]´C_ºNlÂ=jºDa³Aj±De¶AbÉ7nÃ7d¾@tºDp°PsÂBq¹KrÃD}º;€±Nv­Iz­M…¶N‡ºU…·R…©C‚œ>y¡Ly¢M~£G‡žJ‹­E‰±<—«6Ž >›@™6ƒŸ:“”B‚žH{©E³I’³Iˆ®C†­C„¨N¢\œUšdŠ¨[“¥X€©\ƒ£]~˜Z€¨_u–X{Z{—P‘”U’¦M•žX%I3-M4,O6'IH$GS-DL+HL5?H5CE8MI@KGDJQLBNBJNLSRMLJRA?T?9W43Z:oY=oV=rZ3m`8dW;l\7gS>`Q8c`=nk9sf¾”C»£Hµ U°žR¼›OǙJÆ¡DÁ“NǒTϜUʗZ¼§P½©KƲNÁ®J¸§X¶¢X½ ^¿ YĘO½ J¹ªD»£L´—C¾•G´ŠE¶N¶ H¹¢B¶­F¹¦D½¤IÀ¤PƟPÉ KÀ¡?Á¢CÎ¥=ͨ=Ó¥KÌ¥GƱD¾¬NÁ S»žO®šK©¤>¡ªG¨ C§°AŸ±L¥©R¥©T£°\­§[¦´Zª¶b¥±g¦´c¤¹^¨®Už¼Q¢¸W ·Y¤ºQ¤ÁO“»Q™¶VŽÀQ™ÁY™Á[›¾Vž¾R™¿RÉ\¾[ŽÂMŒÌIŠÆQ~ÍY}ÈZ‚ÅX|Í_ÚZ×U{ÛX}ÐS‚Î]uÌVo×WrÑfÌf{×a|ÕXuÜQbÚ[`ÔW[Ê[^ÂNaÇOiÆNqÁMqÈJb¼LcºGa¿@aºCf¾CiÃ8l¼7_¼=dÅ9nÇ;vÍDqÄHmÉSw¾QuÈOtÂK}ÁH}·B~¹K|²J|¹F³L{´R~³H~¡M€ E„™H¢F„¤E‚§NŽ¢D‘«D˜©C•¤A‡¡2…›4ž8‡ŸAŒ§?…¬LŒ§M†³F†®=€§B|E†T~\„›[ˆ—Z£Vˆ¢OªU‚¡P€¤N}Zy•Z‹œ]‹P‹˜Z¢S"<3&I<@8>IKE*C;)HD2A=.F>1::@G>8=IcDCcG=]U=aV7q^2kd4d^6gL?dTC_ODc]@`hAh[„m?‹x<‰r9kBŽa1’c.šx-¤r;£m5ªt9·u>º|8¿‰5¿‡A¹~8®‰=¯‹4§•;ŸŠ9«…3£“9«Š6Ÿˆ8 —/ª‰>´–:°0œŠ;¥›,ªŽ%«š&½¡.»¦0»¡;¸—:´–F¸—:µF´™?µ§B½™HÀF¾œ@¯—>¿§Cµ§S¼šHÁ˜M»¦U›TÀŸNęPĜOǙZÁ¥S¹¦V»¦NÁ§D¹ S±žK¾ª[Ä­S½©VǤRÁ¡SÁªP¼ J¿œO·“Oµ—R¸—Cµ˜O¼¤Oµ©G¾­@Ç¢N¼ªJÀ•EΣKȤ=Á¢Iʟ9Ò¬BÞCɱ<¿±CëPº¥R°¯C¸±8®¤=°£E¯§F±±Q®K«°L¬µVµ°e®¬džµV¥­Y¨ÀZ£¸_›½Yªµa¤Ág ºY£ÅJš¿W”ÄYŒºQŽÅV”¸[—½V•Ê]™¼SÍUˆÇ[ÌaÏWˆÉ]ŠÓT…Í^~ÓWÕ`‰Ä]†Ì]…Ý[…Ód…ÇTtÔasÎZrÉXrÕotÖdzÒ^rÞirÙafÑ]iÓO_ÏN\¿UaÈReÏFiÆFjÍKeÄBrÃF]³K^¿Q^·>`»;gÅ@cÂAgÂ>iÂIfÂCwÀDzµQ€µRw¿L|¼Mƒ½H·Ez´I|´Px®N‰²GµAx·J³@€ªK†ªE|§?ƒ§<€¦N„©N‰³CŒ§H‘¥=•£;‹,‘¤3Ž¨?†¥I…¥OŠ³Fˆ´@¨Ku¯Gƒ¨B™P~žU¥^‡¦U‹¬Y”«Y“¥X‹±Oz«Yuœa„b‡¥WFžX‚®V3/:9<9@D+<>.@8)E@.:C+=8-3<-=:77B=EOJCLNJHJ?IL@JNGLI9IO5;UE6RF>YK@eLAdO5^N7gU³j8¸pA®‚9¹z;¼=·…A°ˆ5¨Š3ŸŽ6Ÿ”:§‰?ž‘@¢“4¦’6¡—:§ >¯—=«”A¤‹4§–*¡’.Ÿ•'­˜0³¡4²˜?¶š:«–?® C³?·›L»¨K²K¶“B¶ŸI¬¦J®œE¾¢LºŸI¿¢Rº§ZºŸU¿ O¸ŸY´žT¿ SƟ[ÁšU¹œQ¿¨IÅ­O¼©JÄ°Y¾­\º¬VƦP»¯F½ªLƞIƕEĔ?´œG¬œH²˜Jµ¤O¶¨HÆ¥Kŧ?¼œBÛDÊ @Ѥ<Õ¨:È¡EÈ«?Ǧ9ñDɪ=Æ¥C¾°L¼±F³@¶¨9·®=»«Q±¬U¥®W ±R«¯d¯°e©«e›°V½`£ºb¡¶^½W¢¶_ª¸gšÃd‘ÅO–ÍJÆU‹ÃY½N’ÆX—ÄYŠÆRŠÈ\‘Í_‘Êa‰ÆfŠÎbŒÊWÒ[†ÒZ‚ÖX‚ÐW‰È[ŒÆe†Õb†Í^€Íd|Ðg|ÎZvÒ_rÙfvÎmvÒgqÕ`mÜioÜ_sÐRtÌWgÍ[hÆWpÆOmÎPfÓJmÄNo¼G_³R]¹Q`ºH\½K_ÄE`ÅBc¹F_·Jk»Lp¼E|½D|¶L{°H~²D©G…°?{¯F{¬N}¤K‚­:~³A}±?v«D}®A†®=‰¦=§@‰ C‘£M’ªI¨H—š5‹¦7¥-™«;¡@•¦:”ªB„£?„«Hy³Jz¬;{©:D 0C1351.D.=@24>+0:46G66DA9B>BHMBKD4RT:KJEFVF;I:FZG;ZJ0cB8jP2mP4mH8kQ8kV5b_;iaBaU8lQ/^W@_Z<\VGbd;`c/a\/dW5mV6iW;lV>v]9t]3ua<Œ_:Œc4Žn;Žn>‘fJ‡i;…{8‘q?‰k4’h1‘^&¢k,¡i0«q3®e>¸l9·w7¹†>±|@²‹2¬;§–0¢–2œŒ3°Š@©“9›•/¤—A¢‡?®A¤™8¥‹7ªŒ5¦Ž1ž'Ÿ+«–,©—3­™;œ˜4œ˜@¬–:©©<¶™M»¡V­—E¸¡V¯™U©¡G·žP³œ[¶¢RµU¶”\µ™S°ž\¿‘Z¶Tâ`º“WɕY¼ X»®JéUñUĦQ»¯LÆ©ZãXÅ¥Tº¦Q·—EƜJº™E¿™TµJ¯™N±˜I·¡BĨ<¼žEʙ@ɞ@Ȟ@՝?Ì¢FÕ¢DЪA̵:Ô°=̶7Í®F¼·;˲BÇ»EÀ°J¯¶?±¨G·¸Mµ´Q²¹P¥³[Ÿ»_žÀ]™¼b˜¿^š½[¢¹`˜ÅU˜·a ½b¢»Z˜È[›ÇYŠ½W“»L…ÂJ‹Ë[ÆUÌT”Éb”È]“Ã`…Ño„Ì_‡ÐhŠÐXÙ_…Ö\×\ŠÊ[…Ú_~ÓdÚauÕjuÒbrÐfpÚ[oäjnàj}Ò`nÛqfÚetÝhtÕ_kÉ\lÉ[mÏS`¿^eÉZbÕLiÅYk»P_ÁNZÅWeÄQ\ÊNg¿FZÉGcÉFdÃDc¹MzºNz¶@z¿I†¼D‹º<ƒ¬7‘·>ŽªC‚¬M{¹L„ªD€¶Au®9ƒ«4|±A„¤>ƒ¤3Žž6‚¢BŠ›A™œD¥;™¢;2—­-š¤-”£:“ª9”µ>®H“¬;‚¦G…¡>@>E;?N9MP8RR7EW7FTD?ZC;g@2e;4gG4bH0kF4bK)aT-jN3iV:lT=gU8]S6]_D]T@_X=b`;[W7\Q1lU+t`.oY2kU7uX0€X>…_:~j6g8„bFˆdD…hH‰n>‡p=p:Žq/˜g,¥i*£].¬h-°h2³s*ºs2½=´€>±‰7«“;©˜7¡’:®ˆ;ªA¯ˆ7¢;£D«ƒ<žŽA¢Ž?ª’F©’@¤–:˜.›*—”2œš,—•-’š2˜¡7›œ?©£@¥¢K¬—S±›R²X­¡Z®™T¸œU´›X´–X­Ž]¬ˆ_±ŽW±”Q·‘Q¾_Á—]¾žUŝ\˦ZȦXÄ«YÆ©UʨIÁ¦L¼œPÝT½–SŸPµGµœM´žM½šQ¶Y¹–R·£D¢?Ǚ:½›<½¢<Å©EÅ©PÉ¡MÉ£GÒ©KرDÙµ<Ö±6Ï»:ÆÅ<ÊÀ7ȶ7ʲE¿¸H·°C·ºH¹·M¿ÁP³¹X©º_Ã_–ÐjšÐdšÐ]˜Éa–ÆW’Ã\›¹h ¼c¢»n ÁhšÇd“ÀZŽ¾UŠÍUÓY‡Ë[ŠÍ_Î^…ÊbŽÆhŽÎq‚ÓmÔn‡Ò`ˆÊaŒÍjŽËc†Ö`|Ó`yÛmyÜuzÐl}ÖbqÚ`m×]kÞiqÛorÙgkÝllÖmlÚbhÎcrÈekÇ_bÄ\`ÇejÁ^jË^i¿`lÄVhÇReÈWnÄSlÉYpÀQeÁRhÇOeÆIpÀArÂJt¹;‚»9¸4‰µ:ƒ³1‹»9…¹;Šµ@Š®K‡³E‹¯@~µ9´0Œ¨/’ž:‰Ÿ5Ž’>ˆ•>Ž>“›=–¡3“¢0–£4•­2—­2—­/–ª0—°A“³F¥>Œ¬K¡It§Ox­N{©V‚¦Z|¬O€¯R‹³LŒ¬U„¨]~°b‰­\ƒ¯[‚¬Uz´W|¶Q|ªJ>.$4)*1:#.<032/(<3/9+4J7.E,/@8.C1?@24:9cC.gL.^P8eB1_K5lP4eQ4hb9]_+aa7eX;qWDrN@d_4dS?]R3]`1VR/fZ.l`$fT+p_,uZ'xW/xX9…e>}_:‚r5‚hD€cCƒu;m9…m7™s>™t=•p.Ÿq2®_+³i1¯n6®q6¼v:ºs7§}E°‹=²J­ˆ9‡9 „@¨‡<£8¤‘FŸ…G®ˆIœ„H£†:©5¬—8¢’0£˜6’œ(œ/™(’5¤–9 ¨?¦4›¦@ ŸDŸšV©¡U¶›S«›W«–Qµ¤M¸¢`²—Y´’Y¶–P¬Z¸T·œO³ SØ[¹—aǚVÅ©^¾£XÅ«]ºµ\À©R¹°MÄ¡NÅ¡OÀ˜Y²£P¹«WÀ¡V¹T½£_¿©RµŸN¶¢C¼š=Ä©8¶›=Â¥=À­Mɤ@˦?ɯHÖ­DÕ®?л:Ǻ?Ì»?ÿBαDòOÍ´LÆ°Q¼¨J´¶H°·P³·\²»[¡¿Y¦ÇbÄ`’ÉcžË]šÒ\“ÐTšÅc¢»f¡¶]”¼džÁj”¶ZŒ»TÂV‹¿\‰ÎP‘ÆbŠÅ\Ê_—ÉfœÂkˆÄr‚ÄkÓ_†Ìa…Êf—ÔcˆÐe‹ÞZ‡Óm‚Úo†Òj…ÒkÓ`v×arÔ`e×dnÞoqÞmhÕimÜhmÊhmÚ_iÖioÖc`ÉibÇZ]¿gbÎfc¿ahÃVeÉZ_½\mÊ`nÉ_e¾Lm¸Nk¸Up»FmÃBoÄE|³:w³F~¹9~±?²7¯>„»F²C„²7´Bz´4„¬7‡¨/ƒ­3„®)ƒ4 .…›7‡¤;‘ F”¦<•©8˜¦4¶<›°4”©,§=œ¶7Š­GŒ«DŒ AœEx°O|®Hr°P} \®Y«W‡²Y‰¯\·U©a€·X}ºT{µ_w´[„µH‚±I7+&52+4(-:-57*-0$&>.)B53?.399.D65F/9J92FK0DQ1LP5NKE>SHBXM:WE7[M0cD-hK2lH(bN+dX9]`7bb:f\2oR;rK>mL=qS/gR-e\8`R1`X*]b&h])o\(t[.uU6wZ.{c8z^4x_@ƒk:ˆs<ƒr;€j6Šl@‰gG‘m@‘h;s2Ÿm/ªr0¶{2°w@·u?°s3§u?©zK¦„B±|H®‚:žˆ4Ÿˆ4¢…6©Œ4ž@œ“MŸ’Iª†H¦†=§> ˜;¢”>¢•4”™+“™+Œ6–4§ <©¡8¢¤Fž¡BŸ«JŸ§G¢›Sµ“N³•J¬šKµ§^»©`³«]¯œ`± N³”Lº™Vµ Uº¥`À¡YÁŸ_·™W°¡Y¹©TÁ±P·°XÀ·S¸¯DÀ£G·£M¶O°¡W¿£]¿¯W¶ªQ¹¨[¹¤Y¹¯M²¦L¼œD¹¤@¶¬CÄ°MÅ®IÒ¢Cͤ<ƯEͯ?Õ´:ѳ=®=Á´EϹMÒ­JĵUïT¼­Q»«T±®S·¬Z¸³O³´S­³V£¼YŸÀN–ÈQ›ÔR¤ÐR›Î[ Ê[¡Á] ½g¶jŒº`‡½d‡¼\ŽÁZ‰½Z…ÅRŽÒWšÂ_›Ãi‘Æk˜Äe”Àh“Æj•ÎWŠÆR‰ÑR•Ö`›×[”×_ŒØb“Òp‰ßc‰ÝcxÕZuÜbzÖ`mÑiiÏnm×cuÑbpÑpw×gsÕ^oÝkoÓipÐjfÂ^eÉ]gÅanÍcnÇYdÀ\\ÀbYÈbgÅTh¹Vx¾T}·Pu¼PlÀAj·ChÁBuºBt¶Ezº@„»Cƒ²D…¨CŠ¯E}²:~¸3}²1‚¬=‚©6Š±,ƒµ4ƒ¨-„§5Œ™8šG€¤L‡Ÿ=ˆŸ>“¡B‘´5˜«4¦5˜¨<—±<•¹GŒ´B†«=Œ¨E€§Kt²El°EsªPt³I{´K„®M~±[y±Y²So¶[n¸\sÀWv¶TƒÀQ†¸J%,8%;*73)71$7-!6+*5=/*F38@27J4:H2:@78J7>VI7TG4UI5QFl^5gQ*kL9hC9uC7iE9bL/kR4gM/tU4pY+kY'mY,if2ya,nY/q[7ka@oh8}`9yiByk?‹kBŒaF•pI–pK{;ž|2¦x;©i3ªyD²w@§q<­~F¤|GµJ­ƒH­@´‰7›Š9£Œ6 ˆ8¢ƒ;¥—L>­“J®ˆ=¨†?¬†>§š5›’/˜>™”:• +ž’-¡Ž:››5©™BœªI•ŸD¡šE¥˜D³”B²LµœT­™Y½¢[¸¯Y±¦`ª–S·š[²ŸH²RºšQºšOŚO¿¦Jº¨L®£Q½±P·°Uµ­P°³M¹±Q·«M·´M¬±T°®Y°¤P³µTÀ³U³´`±±\¹²I¼¯N¹¨F°ªE·¢Qµ³JÇ®C̬C̦6и:ζ<͸FÒ®?ʱ=Æ©HÁ­NÔ¸DÒ´JÂ¥O¹¨Z¹¦V¼­\´¤`¹²_¶®W®±KÂM¨ÁKžÈQŸÍ]™ËQšÂa”Æ^›ÊZ™¾a”¹]¼WŠ³`ŒÁS„¾X‘ºU‘Èd’È\“Ì[’Ái™½g›Ãd¥Ía•¾k–ËX—ÈT˜É_•Ï^’Òc™Úk™Öj—ÝpÝh‡Û`‡Ú\nØckÓeqØ]m×^gÎ^wÖjtÄ`uËczÍlzÒerÍnoÇ^sÍ]iËboÑ^eÄZhÊScÊ]YÃZ^Â\aÆNgÅVvÎMqÅTq¶Aq´Nj±Mi¹Ln·DxÀ>z¶C|º@z·?u³=€±D|®9q«5~¨?zµ7ˆ²2‹§5€«3¥7‰¡,@‡©;…¨D€ž@‰ž@„§:’²6—«8“´9‰¨2–°:ƒ®F‹¥@‚«Mƒ§F‚±Bs¹GnªPk®Us¯W~¸Lt±U}°[©Nƒ´Jw³Mvµ^r¸b}¸Zx¶K´J,21/627-=)53#1;-4C57K90I1:M4:F8;B?=;J3:D4;G10S=2P:3ND4U=-\E2dU7eY>aUFkWǸ9ƽD˺?Ô¬DÑ©GÌ­GǬGóAͲHȲKĪPÇ®Oé^Ç©c¼¦_ª·[§·N¨ÂJ¤ÀMž»K¥ÅX¡¿_ŸÃVžÌZ™Ì`šÍ[™ÅWš»L—ÁO‘ÂJ‰µUŽ¯[Œº\”¿c“Êb‹Éc”Ã`•Ãa£ÊnŸÊk¤½e›¾bšÅYžÏ[¡Õ^¡ågœãn—âc˜ÚgÝoˆÜg„ßXxÐYyØdrÒ_hÉZnÑZsÎasÆ_nÄftÅhpÆdrÒimÔgpÑgrÌfuÐ_mÑYfÐRb×TdÌYoÆQiÎOuÓQwÎJwÇLt»BlÀKb¹Gcº@e¼FpºCo¾Iw¸GsµHz¤‡ª<€«?„¦L‚¦Eƒ·LŠ´Oƒ®Eq­Jo´Pw³Lw³U{±Vo£MpªQu­Kp³Zm³]{®Zy·Yv±O|µG',$-377$;+$?<-8=*0:9>=64;:6C/6?93DA<8BA;FA2F.1C.7C22K?6BB8EE.UB:_TlV5rV6`H._O6_E®‡@¨~G¥‹D ‘S¨’O²…=­‚C¡ˆ>¨‰=Ÿ“?Ÿ™=š’5›™2š“<¤Ž9 Ž;Ÿ˜9¡ KŸ¨G•ŸW¤›Pœ¡Q­’B¹‹<µ“P¾¢K¶ªQ»ŸTÀŸY±ªL¯¢S­±J°žB± F±šK¸™W² I¼žE¼ \¿±]·°T·«W¸¹W·µE¿¹J·¿]°µR¡´]«®W«¯\­·T·¯bº±Q±¦V´¯Y²¨\¬­O±ªR¶®L°¥=²µB¸¹>Ë¿IÉÄNÅ°EÖ®OĵSβO¿¸O¾µLãN·¦Xµ²^¶²^Á°c½§Y·©Z²¼I§ÁK¥¶J¡ÅT§¾^¤Ã\ž»\ Ä^žÇd£ÃV‘ºa•ÅU“Ê]“»[ƒµP…¼V†º\ŽÅ[•Â[–Â`˜Ê^¡Ël¤Àj›Íi£Æo¥Äe¤ÉZ§ÐežÖn—åg—ëg˜Þm“àg“Òj…×d‰Þ]Šà[„Ø^wÐaxÉbkÉZ|ÇXsÁ_oÍgƒÅhnÇboÊbsÕjmÛqjÚexÙ]wÉZlÓYsÖXoÊTgËTnÕYlÈF{ÕGtÁItÈCk¾>n³Gm°Kk°@u¯BkÂBk¼Ei´Nm¨Hl¡5y2u®369;-C>/<@./?=3B@78DB7J:/P17N=3C76GFfS4rU3lP8nG9bH8^M4c@AfD@eF3_X:e[4nf4l_;f\@o`4|c9~\9xdDpjIrqJkg:nrDzqG‚jO‹hH‰aGˆc?ˆp9’p@–o:™{?žzAœk9¯i;±jE·nE²k7«i;´pK¸yR²tI®y>¯{AªƒF¶ˆ@±ŒE§“M«—I¨K¢Š<§ƒ<‰F–@–’;™3¤: ’7 ‘5•Ž=‹–<’™CŸ Kž^¨Q¢ J®–A¯F¯™I½¦N¼¦Pº©Sµ¥T¶¤L°§M³«Mµ­F±ªJºŸF»›Sº£N´žO¶©[¿£b·¢U¹²R¸´V±®K´¸T·µ\¨®]¦®a°ªV²«R©¦W¯±V»°Q·³X¾¶\¶ªW»¯O²§E°žH®£B·ªO¸²L½»LνK͹EίJƱIĹUǵJ¸¬O·¥X³£W¯±T°®Q´£Sµ¤d©¹Y¬¼L¤¶F¡ºMšµW£¼VŸ¾Q »W§¾^¢Â]—¾]˜½a•½b—ÃZ¼RŠ»S’»VˆÁ]Š¿]’À] Âe ¿l¦ÀiÅq›År˜Êgž¼a¡¼ažËlœØmœÜg âmœÚp™Ùr–Öv‰Ún’ÛhŠáY„ÎZ‚ËXtÑbwÇa{ÊetÉ`zÎg‚Éo~ÔnnÑfkÌcwÔi{Þin×ikÑlxË^xØ_o×QhÜPrÑToÖLvÏNuÈCjÅ@pÊHm½Lp²Eq¬=l®Fl¶Dk­=l±Ex£?r 5vª:w¢0{¬2ƒ©8„«1‚3œ;©?|¥EzŸLs¥J{©H}ª?r´Ex¿JŒ¼M~¸Mx¨B…³:‰¹=°=‚®:€ª>|µJqªRn­Sv¨Xq¯Mq¬J`¢Jc¢Tj®Rh¦Vf¤Yq ak­[q¯SoªNs¯Hi¬S"*#"3'.-,;7287?4HB=eN?mM2fE2sYosOvvA‚kHˆrFˆp;…_B˜_8’d<œi=›pC qD“s?©lF¬nF«v?³h6©r9±j@¯uL¼tP´uQ¼pE°t>¿„H´‡L«ŽVªN«‹Dª‚6°Œ; ‰7•‘@”…4”•/›–6“@›‹<œŠ@ŠC¢F—¢M —Z¬S££H¦—N¶—E¯›Rµ§CÀ§E²¢V¶¢E³¥E±±U¾³Kº¥L®´G¾ŸF³ W·«O°žJ¿¡W¹£d´¨e³¯X½¶Qª¬X¸¨Qµ·X²ªZ²¶V±­Q®µN®¸M©±Q³¯N¶¹N¬¶L³´T¸¨M­¤C¹°@µ§G¶£Q³²M¸°UÊ¿JË°YδZǬW¾»_ŸM»³M½«T²¤P´­O¨­J«³[³¡f´µ\§°VÀI˜ºGžÁT—ÆN—½[Ä[•ÊU Ë]¢ÃZ˜Èb’Ç`¢Ì\ÂQ¿`‹µP™¶b–Â^¾b›¹d—¹`½h¢¾qËl•ÂfÆZ¥Ég¦Ìj¨Õc×n§Úi¡áf”ßm’Òn‡ãsŠÞ_ãZ‡ÑQƒÏL‚Ô^ŽÈf†Ðg„Ï_Ï`‹ÂmyÉjvÔhyÓo~×`qÜnpØjxÛcxÍW}Ô`pÑ]sÙWvÎRsËLyÈSs¼Hb¹DcÁJdº@i±>w°6y·8k²8uªIr®Am D~¡5¬0~²-|­2…±=}°2{ª3~©B~­Hw™@~ŸNy§Mv¡P|ªK{®Qx¿R¶R…®Ds®?}¸?Á8>=DBW89Q3?H>DO;AHBXV2ba0i\7i_o`:m^5q`2qe;tZEwZD€ZO~dMrrNrnOwtNvpH}kF‡nG“iE’f>™dDe=˜i?™sE—r@˜kI«u=¬v@¨wG©v?¹kF·l?¹lC¼kG¹rEºlOµzR¾~J¿|J¯‚Q³‚K¦‚;®‹<ª†6¨…7Ÿ†7’†>ŽŽ4”‹4‡E“‚J˜L›ŽN¡–Pœ¢KžŸV¥™L°PºU³—M±ŸF³¤D¹šD¹ M¿¡G»¤KƯDÁ±LÁµQ´­K¸®P¼­J²T»§Lµ°L¼¨]¯Y¹°c¾©d³°Y±³U°±W¶­U¬²W£²L©®R§¯O¬¶X¬¬L§²P¬®K´»P¶ºI²ªF©¬Q¯«O³§N¹¤SÀ®UÀ²Y¼­Wƶ]¿²eÀ²`º°SúSÅ·Z·±R±®Q°´O­©M²­Z¹°^®¬[°N›¾K“¾I“ÁPžÊX˜ÈR–ÍS”ÃU—¼X–ÂY‘ÅVœÆR“ÂV“À]š¿V™¹U‘¾a–·^™¶\—Â]•Àb¢ÆgšÉf—½XžÊ` È\¥ÃZ¤Ê]§Ï[¥ài¢Ö`œÖc”àm‘àf™à`™Ö[”ØM’ÕOŽËX–Èc‹Çg†Íi†ÃmˆÊaÉa{ÐkƒÑg}ÜfuÛhvÜauàgØ]vÖ^tÐXiÊOlÉRf½PqÀJd¼Of²Cj©Bj±En¸As¼=tÀ?w´9w§@q¤@§F{¦<„²B°8w¨4zª6w£@r­Dx£Iy¡CzœBxšKj˜Mm¢Lx¬O}¹SwÀNz¼L‚¹SyºJ€µNy·@sµMq­Nq¬Qp¸HnµBy°Mn©Io§Gm°I_²W]²YY­^^®c]²g[«b^£^[®^W«\f²cd¬Z+47(%<**9,.7.(8#7;)28+)749>C<FC>6P=HKI;TL6KQ?MW=CM;KO8_W1XL7lT=j\?iQ>jO6rJ6mD;eB?rN7eQ9q[=s_Erd=oh-nV<{fycI€\Fxf>zgE{lFudGjE{iCƒiI‡qHŒr<u;ŸnH”sCžuC˜rH–rH›kJ£~>®m6ŸmB¥b7¸lH½o>¶jMÂtB½qI¾tE´xK¹vSµ‚N©ŒN¤ŽG©‚D­{8¦€CŽC‘8‘–1‹8ŸI›…@¡ŠU›‘Q£œQ©•U— \¨£]§œL§™S­œU¼•K¼›E±¥N¸›R´£L²¤N¹¡NɧE»«B¿µO¶²D¿£M®«Y´¤N² ^¸ `¾°U¹®]¯µa¶¤\¯²T»§T©´R£´\­¹]¬±Q®®_¯½[¬Á[­ÀI®»Jº¿Y·ºX¼µT³«W²ºL­µK´°Wµ¶Q¸®Q¾³S¿³W½½[½¬fîVµ½`´´Sµ®Xº±W«´]µ¼T¥»R³°X¯¶b¬°X£ÀG¡³TºL“ÅV•ËK˜Æ[›ÉS‘ÉV£¾[žÂ^—ÇSž¼c‘È_ÁXµX˜¾]“±c”¾Z¢Î_›Æm˜Ëd¢¾iœÇbžÒfŸÈU¥Ì_ ÌU Üc§á`¦×j¤ácœÙ^—Ýc˜ÝXŒÕM˜ÕZØWŽÕ[ÓYÓ]{ÒeÐg‹Ï_Îr~ÓpuÉfpÐczÙj€Ù\tÒTÒ^qÝ\sÖXeÔWuËSl¾Ls¹Op¾Ad¶5p³;g¦Au¹9s´@€·Bx³<|³>}©>©4†«6}´>§3v®,z0vª=r¶@r­@w¯Ar£Hu™Fp Eo¨Ds¸Lv¸X¶Rq¶Rr´Kv¸P|ºBs¾Gr¶Br³Mh¾Db¸Gu¹Ql¯Hi¬Em¥Ob²Ka¨a^¨SY´XU¨\ZµhT°cV¡aeª]Vªfa¯ak¡T%/7,9)'2$&<(-3('0(28.-05/??-A@'AO13G6?H?@M69E98D:4SBkcEzhDza6~b)sU-{ZAvfCv\AƒX?~WA^G„kI}hB†j9…h?†o5„x<xG“oK“qB›mB£v;™nB¥vI¤w>ŸoB¢c8³[<´`F¬pD´tJ°lNºkJ¶n@¯{@²yC²|V©…V£ŒK±†D­x@°ˆ@¢‹?¡‘C•<˜‰F ‡DŸ@ L§ˆP¦’Q¦•N  Z¥œ^©¡Y¥¢U®œN¶˜X½™V·ŸN³›R»¥Hº¦JÀ¦DÀªN¹µR¼°D¿žO³›Q¬ž\°ª\µ¤Q¹¢V¾¥b¸¯_¾«V²¥X®­Pµ¬Vµµ\£»T­º`¶³\¹ÁR­ÅT°»T®¼Q®¹S±¶W¼±_º²X¶¶X´·X¶µY¼¼N··O¹ºW³»`·º\½¯`»²f±¬f³°^³¸[¸±b¹½[³¹Yª°T¤·R¦³S¨±[¬´W¥¸O»M”·J•µSŸ¾O–¿W˜Äa“ÁUŸÇWšÇS˜½\’¾b—Éb”À^•¿[¼h™¶h¡ÅaŸËiŸÃ_—¾cšÎa—Ði ÉY¡ÓYªÓ[¨Í[ªãeªçb­ÜW¤Ü]¡Ú_ŸÖj—ÌU‹ÐO†ÖVßNƒàRƒ×\yÓezÊh~Õe„Ðm|Îq~ÈmqÎnoÍjsÇZyÒ[x×WsÖPqÔVhÖKjÏUnÈRx¹Cu¹Dl¾Fs¹8w²„¬B‡¸8}³/v¯5u¦/…Ÿ/…¢4±<19K08G?=C8=M>8G??FC4XL=JR4N]6FX1SKaEzfE~kGŠl?ŒjC‹tCŽF‰hB‘pO›cJkP‘`NžhH¦t;«jB§fD›k9¬iD¨dH­iL£hJ®xA±vE²uK¡yE¯xI¨NŸE£‘F¯ŠI¥€I¤}F§ƒ>™™KŽ•KžI¨‰D¡‡G¥ƒM¥†F¯”T¨—Q¢–Z¦œXªž]¹¥L·œG³•Oº¡Z±šK¹¤R½¤JÁ¥NĞT·«O´¯P¹§V¿P®’L¯™U³P³¤U´¦W¹¡O«®T¶§U²¢Y·¥T³ªb¥±Rž³P³³Y®°R¼ÂY²¿V¶¾Zµ¸Uº°`«¹c¯¹`±°]±¬V¼¶[¸À^´Ã`¯ÅT»Â\»ÆQ·ÇR¹Å\À·cµºf´¹e±±e¸®i­º^°¸R³²W®»Uª·[Ÿ¬W±R¡±M¢½RŽºJž´Už¿^œ¾Q–¹SÈ\–ÂM¢ÌQ¢ÀWÎ^ŸÎ\œÎb Å] ¼hªµlžÈp¨Ì^¤Êl–¾j¢Çh¡ÓaªÝ_ŸÖ^«Ïi­Ïa£ã\¨âl§Þ\£ç\¥Ód§ÐmœÒ\†ÕN‡×J‰ÚU|ÓX„ØX€Öa†ÈgÇ]†Íe|Å_†ÆkqËbeÓggÉfzÓWwÉQsÜVmÍHeÙDeÐPeÆLq½Nq·JpÂ?k¶:w«;zª=u£7x´Cz«Ko¥@}¡B}®6‰©/ˆ·6|¬:„©2{¨0…œ+Š©3z¦B{¬FuªAo¦@|¤Fx­Ho¤Ez¶Er´Su¾V{¸Uv¶Ul»Yq¶OgµJnÅRp¿Kb¾TeÊKb¸U`¸I`¸He·N`«WW·UZ°Zd¾]W°aYµad¸WVª_`ªafŸha c^£a+,(%(,/'150*/21+*/,45)5:)::.::6>F/6C<6H:6P@;HD9FB4RI6TE¨i9¡e?œkC¥cF¡jF¢jB±yA±y<«x? wE£…M¤ˆG«†B§ŒM­‹N§~I¦P ‹F£ŽB—–Iœ–N¦ŠBŸH§ˆB«O¶‰T»N³V¿šQºŸY´©V²¤Qª¨U±Q«¡R³¢O¹¤T¿˜SœS»¡O¼žN¶§V³›W¹™L¸œJ¾›R¾¢\°¬X³²]¥ªS§£U­ a´¤`¬¬a®­X¨µN¥¸U«¼T±¹X¾Ç_µËZ¼À_¶²g«°_­´W©ªYª¶\´µU¹¾]²Ãb±¾[±Á[¹ÉS´ÆX»½d¸Äa°Ëa·Âj¼¾d¸­`¶ª]¬µ\³®Xª²[£¹_›³R›¼VºT¶W“¿Xœ²Y¶_¥¶\¤¶T›ÆUœËRžÉP£È_ ÏX¤ÇZË^Ïc§ÄgªÅj©Áj¬Êd«ÅcšÉi¥ÕgªØd­Úk¨Öc«×g¤ào°ân«ág¬áf£äZàd£Ô_ äVŒâZ€ä\‚ÜNŠÞZØU‚×\ÊW{ÆVvÇb|Ìc}Äc|ÌdjÍcnÄYlÃ`wÊOqÑOmÕEoËJrÅMkÇFfºBh¾DpÂ4m¸4t¸>z©7|¥<°@u«:t¦E~©A†­5ˆ²8ˆ¸3‰¯.ƒ«+‹¯2£3y5¨@°8t®9z°6o¨BjµNk°Mm·Mt¼RzÇTxÀ^xÁ]pÀ^d¿Rd½OmÄLrÇTuÅRmÆOj¸Pa¸O[¹Q^±M]¸Wh°Yl»__»[c¿_^´Zb·YW¶bZ®gW§]X©RR§W()((+50+31444*,-.(,3+)?/.>)1D24D47;.+E@+@@:BH*I>:PB8EU,IT2NL+P\€XE‡eF‹mE|s=ŠqAyCˆkF†v;ˆmMeN„aI‘aX‹`F—mC^I¨a8¡k9›p<h>¢cG§kCqG¬p<³wC±v>¤†;°‡;²‚?©ŒC°„I­L ƒQ¤O˜ŠP‘‰B’’P•ŽH§‘Vž‚C©ƒ?ªŽQ±•Wµ”S´O¾“U±]¶¤Z¸™P²—Xµ’X¹–^ª¢Tµ˜X¶’S¼•UÙPºŸL¬—V¶ O®¢N¶¤LÀžT¯®Y¬¦^³¡]©šV¨X¬¥b«­W¯©Q£µQª³G¨ÃV¬ÄO¬ÀYÂÆa¸Ád»V¹µY©ªT±±X®®e¯¹Uª¶V­ÈU¸ÃXªËVµÇ^¸ÇQ·Ã\½ÌXÁÅc«»j©¸n¦¿h¬¶i¯»^ ¹U¦¬X£ÀU¦¸Tž¸Z˜³V—®SŸ¸Y˜½W“°b´]™¼W™ÇT¤ÃRËZ¤ËY™Óf£ÑeªÊj£Ç`šÓk¡Ìn³Ës±Ëb¯Äf¥¾` ÎuŸÊf¬Øf¤Ía¢Ýf®Ö`¢Öd¨Ù^¶æg­×WšçT•ØO¡Ï_ßY…äQƒÖYƒàN„ßV…ÓN‚ÔR„ÈWÔ_€Èa‚Î_yËi{Ì^uÊZjÁbrºarËOl¿FlÊDnÅKlÄ?p¾Eg¹Kkµ´=yªJ}«4„²:€¬-¼8Œµ*~§&} ,†©<‡¥?†­7u­Bo¤=v¥Am±DnµSr»Wv´XtµOhÃ^xÃir¾fmÇTm¿\qÎSjÎNgËMdÏVaÄXXÀKT½VcÁLU³Tb¸Zf¬Qb¶V_µ`W½\S°Y]ºXX°ZW©bS±`R§WKŸS.";24(8-'-.5-71%30*4.&A0#>'/=13?,&C0+<8/:=3;?*@=6?I9LP/HQ.F[2QZ0Jb/J\4IN8XQ+YW&JQ*[[%`[0dR/`T2ZK7cN/iV1xU*sV%sZ+vR,~O#W1€^:ƒc8‚cB„iF‹^C‰kF‚kE‚pN‚iM‡gFŽb<•_?hE†]Mˆ`O‘^IŽmJ‘c?že:—c6—m;œkD©gF±rB©l?¯v4©t:®z7«„5©}:®€9´}:¨~@¬†D¤‹MœŽL›I’C”“K“˜K ŒX­ŠM¨ŒC±•@­‘H¹‰AµI´‰T·’X¾˜X¸ŸL®•^±_°£V°¨]¯©]¯™T²“WĜQ¼–J³•N¹žT²œM³¨H±¦Rµ©P¶¬Z¹ªN°šS«¥W­¨cª¬R²©P©¶M£½N«¶M«»Y²Å\¾ÀU¼¿U¹¹Z«¹U®°L¯±T·¼_­À^¬ÄP¦Î\¬ÉX®ÊY´ÌY¸ÒS´ÐS¿ÐQ¹Ä]ª¶V§²`ª¹a¡¼g²Z¡«^¨®Z¬¼T¢³T–¬Y’­Y‘ªaŒ¬a—½`œ°V–°W‘¿M“ÇRžÃUœÍb¤Ò^šÎa­Ín±Ói¨Ðs¢Ìm¯Ìk¯Îo¯Èf¤»`ŸÀg Åp ÃnžÉ\¢Ðg¨Õb¤Éb¬Ë]ªÚ\²ß]¡ØVœØS˜×M”ÌS‡ÔO‰×S€×H‡äM×T{ÚI{ÛFÒNyË\ÕYyÊX~Ð]pÕVpÏ`mÇXsÂ`xÇYm¾KnÅDmÅMr·Pr·Bhº@l°=sº=zµ6x¿6¹4w¸4~§5t²>{¼B±<ƒ¬2‚²3À7~µ;‚­.£/z¨8Ÿ/…¦7‚§;vªAw¯Gq®En²Pt¶Vm­Yh´[fºfjÀbm¼YmÂVoÂToÍafË`lÄTgÊY`ËWb½XR½Z]Å\[¼Vb»SY¶PP³TR´U\³aU®^P¨]X³TQ²RH¶`MªXL¦_4(0!2= )3(&/'9/01 ?%(C5.831@;/44#72AC$EDDJ/>D09O*IJ6CL.FL,BX+BT3@\;NV1WQ3TW.HS-RQ&[WaY'dS*jV&kS+hU'z\*tW-}c"|b~P!…]2…W1~_5`9~Y<ˆf>…nK~oA‡nC‡hB~a@Œ^A~`CŽfGŠ_Q†\QnJ“iC–n@ k5žr9žm; jE©tE©l? f<£t=°w3¯x:­Š=²{?¨9¨:¥†;¡ƒJ˜—M”ˆH‰@œ•K‘’X–“U Y I£‡U¨‰Qµ‘D­ˆI¸‹S½‹T«“T·”O¾žWµ”VºŠf·—d²ªb·¤T¹™^Ä `ř]·šV»™W®”O¸“W·›Y°¢c´œ\²¢_¨§]«¡c«¨W°ª_¥ [««^ª¹P¥ºT´²[¸²P·Ã_¼ºNÂÁRÀµY·¿O¸¾H¾¾Z°º\¹¿_³¿P¯Áa®Ì\®Ã_¯ÄR®ËR¬×T®ÄT«ËX¨ÀY™¸]¤´e›ºj¡·`£µi¦¿e¦µYš¸\ §]œ´TŒ±dŸºeŸ²c˜°V›·`—·^—¹N¤Ë\§Ée£Ëa§Ô^¦Øc·Ùj¨Éb¤Ën®Ðm¯Éu¬Äcª³k¦½b¡»d¢Ãm§Ña Ê[§Ò[¡ÎX°×YµÙ_¤ÙT¢ÛW™Ô\ŸÍR‰Ï`…àY’ÕQ‡ØMÜR}âW„Ü[}âJ„ÞRƒØT„ÙXwÙ`ÒUpÖWuØTtËN{ÂO~»Vt»HoÇGwËLvÄ@q³Di·;p¸8jº4t¯<€±7u´@†´=w´8€µ2ÁCƒ³:ˆ·:}À7}¿4‚¿1€²6}¸-y±2ƒ°<|¢9„¥:~¶I²EpºAo´Js¼\m¹Pu´VrÃ]sÃatÌ`rÇ[sÇYnÒbbÑi`Ì\[Ï\WËe\ÂVL¾^OÃOZ¾\L¿YT¹NU¹UL·T\µ^U§^N¹RR¬LT¯RN¿ZQ®[Qª\;%)<,5 %7<$8?.!<-&E;A9(C@8>9B#=A5@>C)E?)AI+IW2BU7=V=CJ3FK0GT0L^)J`/La&H`%NUUQWV_VjK nLpYjV%qS y_%~V){]"t`-yU9†S9†Z<`;‚]C‰iGŠnB‡qCƒlAˆhB^@‡`F~jFjA‹eK‹gFŠeK–]E—b9žiF¢rFžz;¡s@£tB£mA«z4¨x8§v8¦…3ª‰@©€@¬ˆ@©…B£“9œ–@™ŠH’ŽHš‘T—Yž•\¤šT¥“P¯ŒU¸‹S¸‹N¼ŠO¶ŒN¹Q¯’U¯`³‹Z¶†e½`µ–`ºša¾–fǙaȝiÀ£c¶¥a·žZ¾•SÀ˜[º™e¯¢d°™k­šb°–d­žd´Ÿc«¨Z©¨_¨«[®­M§¸O¬¯[¸µX¹¾OºÀS¸ºT·ÁPµ¹S¾½N³ÅQ¸¿_¯ÁZ±Å^«Ñd®Í`¶Ç_¸É\±ÏP°ÑP®ÊL§ËS§ÉXšÇY›¼Z™·[žÄešÀe–¼ZŸ·[•²X˜­U›¯b˜¬]¤º] ¸_—²`–·\Ÿ¸bœºXœ¼d¢Ía¥ÐhªÍg©Êf¬Îf¨Éd§Æc¬Ém£ÇkœÂuž¹qŸÄg¤¿i›ÉkŸÐc¨Ïg§ÍYªØS¬ÒN£ÍM¦ËU£ÂaŸÈ[Õ_‹Ù\’ÛYŠàZŽÝT‡ØSŽå`‹â[…Ü\}ÜWzàU{ßV€ÒW{ÏW€ÔWuÐN}ÊU|ÀMz¿Nz¼AºJsÇGqÄBwµ¯J{±E{»E€½K{ºOuºWoÁXr¶RlÃTkÇ^sÏdoÓjmÑghÌf`Òf\Ñg_Æ^RÅaSÉ\TÀRP»WH¶SE°RE»SMÁSUºU\°SX°UZ°[K²UG¼NQ¼VW¶ZRµ`5 $9'=2:%0: !/,12.A)465'2;15&CB'4F;AH@%ID.JP%BE/AV19O@>Z;BQ8JN.FK)AV2D[+N]6A`.GZ.MJbZiW+kV*qN#iY'de%g_%vf+nU(rd0uY+y`1~ZEˆ\D~YA„g?‹^:~aE|f@†iL}mI^<~fF€aAŒ[KŒgKŒ`?•dJŠf<˜_>“jIŸpDŸk? l>§l<¦€D£|6®q? w3ª{?¤{G²„E²|I¡zPšŽH‰H–N›Tš™P¢e¥‘\¡YžŒY²‘O³“Z¹V¶‡MµJÀ”F¸M»’]²–b¾‘Y¹¡^°™f³•fºœ_ŗc¤aĚ^Á›i² d¸¢]¶“_¶ŸQ· S±¢b°™`¯_²¨d§®W¦¢a ®]§ªS©´[ ·[¸ÁN°°V¸ÂS¶Á`º½QÀ´XÁÀN¶¶O³¶Yµ¸S¯ÈYªÏV°ËWºËk³ÏY¬ÑX³ÎW¤ÌQ¬ÓGœÂK¡Ã\žÀZ–µc˜¼Z‘³b—Ã]ŸÅW˜Á^™º]Ÿ»L“§Xš±R˜¸X–²^˜¼\Ž³]‘µa‘´a—½`Ìk›Æ\«ÀY¡Èk§Çi¡Ë`±¿d¦Çj¨ºmŸ¾f©¾m¤ºk¢Åf§¸Z©¼`¥¾T§¿V¨ÁY¨ÌP§ÁR¦ÄS›Í\šÉZžÖT‘×U’ÕTÙU…ÛZ’ÍYÖYŠçNƒÖ\ƒÕZ|ÕXvÜ[t×MÍ^~ÍN~ÈLzÁMv½PpºOxÂG{ÂLpÃ@p½E{¹@vª3uªBf¹Gj»Jo±=†¹F‚¹;†´7Œµ2ŒÀ:¿5~Á8„´3wÁ7².¹.v³2‡²J†´L³Mz¨J€©?x­Fz²P…´Z{ºP}¼Xu´OhºYj»lb»aeÊkfÍgsÒ[iÍ_`ÒkSÂjWÌcM¸`Q¹RF½]N²]O±`H¸bXº`Uµ]_³SY°PQ©TM©KR²ZE¶aV®cN°_;'2<"*135%1|hEwjK}i@ˆ`?‡]>‘_?ZE”]<™b>’n@ŽmLšrA¡t?«jE¥pA§z@¤;¡{<¤{Cšƒ8>­G°yM¯tR£|O¤„KˆQ™ŒP¡–U›‘W “b§‰ež_†\«‹X²“O­R¾‘SÁ‹DºŠM¸šOÁ™\¹‘a³•[´¡c¼œg²–\µ—X½ž`¹¦e»žd·’j¼—b´—`¼šW¿˜N±—M¸–S¶ `©œU¦¤X¤ ^¥¬eŸ·Y£µX®¼_¨¹X®¶aµ¼\¿¿_¸Áaµ¼W»²[¹²^²½W«¹S¥¼UªÈ`´Ç[³Ëa´Éf±Ð[±ÈN«ÏK¤ÅI¡ÄO˜ÊMšÀQ¡½Z˜³`’¶a–Ád‘ÀY–»U”¾Y•½VŸ¸T“³TŽ©O©W‹¸R’¹P‘¬W—´W—³cºp˜Äk¢¿^ªº[­Ç\¢ÎdªÂ\«ºb¨¹f¨·m¬Át©Ãpªºd®Á]ª¶\¤³\¯´Oª¸R£½Už¼M§¼O¢ÅP›ÊK£ÑNšÈTŒÏV„ÚX…ÚUˆÑKŒÑO„ÛV~ÚQ‚ÏK…ÍK†×UvÏNÉX{Ò[vÁ\{ÀQuÅHs¼Il¿NoÌBlÆLrÀGs²8}°7x®4r«?z¨9s±Du¬=ƒ¬@‡¯@…¾@¾Dˆ·6xÀ1uÁt¹9t½.{»4€±;†¯Hˆ·N†¶U²P„¤I‹¦TªT…µY{²Uv¶Q{°Xw¹ec¶hd²ijºmp»]mÊ]\ÈbWÅjUËeNÉaR·bJ¶SBµWE®dL³_Lª_U¬]b±WY²QY­UN«SR¬MH«UD²_HµYN­V8(/F)12'.:#103-11&229:8?.851'$?-&9B*@9"@="GG4G=?H>+OA-B@'DE9PM4PV/GM.TM3II5NU3IS/PH3RG(_O(fP(qR'eO5hW'uT/ph1jb)pb(kY'ya-{e2yZ@€d;{lE†j:„g8†n=`I‡fHˆu8h<sCŠl=‰lM‡fC†eRŽkNŽo?˜iE’tE•lFšrAj@¡nD vF¦sF§<–yF£{K …D­}R®~O¢x[¥ƒOž‰Xœ‹W X‘O¤œ`£œY«ŽXª–Z°„]§”O­\¯ŒS±ˆM·…<ÖHǗU×Y¸–V´ž_±¤b«¤f²žj­¥^«¡`²˜h±•a± `±˜a°žYµ’M»—I²œI«‘\²”^®ŸW­¢P§ªbš§gœ±W¢µY¢º^°»SµÀa·Àb¼º]±Å]·¿h¦¯[¯­`«¼d«»`¢ºS¯¿_³Ãg²Åe¸Éd©Åa³¾N¦¿TªÁG™ÂIš¼Pœ¸N•ÅMŸ¶Zš¾SšÇW˜ÃY™ÅU‘¾`šºQŽ³R—´KµM‘¯XŠ¼N¶S¬Nˆ¬P»b¹]•ºi—Àa£Ä^žÈZ¥Í^¤Ëa°¼`¨Áe¬¿r£¼v«´n«¸`­·f¤±^®¶Y¤¶P¬­P¥²MŸ·R ¶O–»H¨ÈOœÔU¥ÄOžÔ\ŽÍXŠÙYÛS…ÙY„ÛZÛZÙJ‰ÎCyÄLrÐP‚ÌZsÑ_…É`†ÁOuÊWx½SvÉD}Á:t¿GzÃGy¸7´7€³:o¨Az¥Cn²Gv¨;°G‚ª=ƒ®Kµ8{¶CxÀ>pÀBpÀ9{º>}¹:t¾9·E¾G¶N´[„±S{¥Y~¯_{±W„¬Zw½Qy¸V{·Yf±hg³pd¯ajº_g½\cÃfWÇdY¼_LÉ\VÇ\F¾^GÂVC¼`D­dN±_R¡^\¦Zb±P`°X^¸]P§JM¯JU²ZN¬aS±ZS«bB%6>+7@+>:)5..92-+6-,576/103,%77%B5%<< G7'LD,R?7WF.O>,N@0JD(SH)UH.QF2LQ5RG+VM0RN2RM5YJ1\M+dR-jL0kM(hP1kS/sa,nf0t_&|^&s`5x_=ncGlj@xhE…n;ƒf?ƒh@‰l@‚jC„q9g:€k?}mL‰pN‡pHˆbQ†kMŽoQ‘vN™lKšiF jI¢mD¢lH§lDžsJžzN—…F–ƒM¥ŠV¢~Y£X™}UŸ„]–„cža§”S¦—Vž P£œW°•P®‹W¥“\¨U¸‚Q¶…Q³†S»DƔFōOƐT¿œZß]¶›h¯p®£gªŸc§£j¦ i«”f¬`¬šS®œT¼O¶ŠN®N±’V±™Q°—O¥¥Q©©P ¢]œ¨[©°bªºb©¸\¬¼V¶½^µ¶c±º]¨¾ežºcœ»_Ÿ«bž¨\ª¶Yª»^ªÄb¶¿W´ÈZ¹¿S­ÂT¯¸J¦±Pœ«G—µM›¼FÀH™ÃM›ÈVœÅPšÀR”¾Uœ¶a›¼Z¹Q‰³T‹¹O‡·T¼Q‰¾RŽ°QŒ¯VºUŠ½b–³lž¿m¢Â`¥¾c¦Äa°¾b«Á_ž¸n¡ºn¯¼h«­l²¹o³µaµµW¯¶U¯²OŸ¯Wœ·Y½L–»O™½DÈP¦ÇVœÉ_ ÉY˜Ç\‡ÑT‰ØQ}ØQˆÖY…ÍW‡ÒI|ÍL{ÇMxÅOrÑV|Í^zÁYÃ]tÌ[rÇOxÄM|¾=º9ƒÂ=³:‚±2ƒ«.|¨;}ª;x²>¶8x¯=tª:€®Du¸Ez³D¶EvÆ:lÍ;rÆ=xÆ?qÉD€ÁR‚»Q‚¬O„­]y©f{¨]|±]ªa~»X{ºRy¹Vl¬edµdi±lp¶^n¼_o¸af¼f]¿bV¸WZ¾PLÄWIÅXMÀYQ²]I­fF­XQ¦Y_­Oa³TW²SV¶SZ¬UN¦TW¦ON£YIªcH®_585A%2968D52?:26<0=;+A2895+>-8;.(A0)I@.I76R@,R@2R@+TB6ZI)YD#L>1OD&ZK7XV:\X:XW9WR7NUx_C‚gP„mF…b@„eA…gGŠpGs@~w9‚iD{i|¤Dˆ¤8€¥@z±>|°L‰»>}ÀJn¿F{¼Bn¹HzÃIyË={¸PŠ¼_©W­_ržU{£Q|by¤W³Yy¼Sk§ai¯Zm¢dp©wj²sn±ak¶_g½`_±fT³aYµWG¾LGµULÃXJµ\H³eS¬gL£^b¥XXµVVµZ^¸XV­VW [O«SH©\L¦TK¡W=399/.=0&G9)P>)HB,DB*=67816D9‹dIˆeM‰`T‘fXmY•qU—qW¡iZ§iKªtO¡|IŸN †P …T¡‚XžT¡tU˜tR}XžƒX”€^’c›‘^Ÿ S¬ S°Z®œS­—Wž‘TŸ•S¬‰P«J³˜Hª”F°—O±“\¾˜Y¬¡R« Z¨\®œg§’b®˜Z¥ ^§¦Pº U»–S°˜P°ŠY±‘b±“]ª˜V¬¤U¯£S¨œ`©™f™f¢ j dŸ ^š®c£²_§¯až¨hœ­a˜ªd£¬`§®T£±Y§¶\ ¬W¬·X©¹Xž¿^£¼Rœ·Z—±X•·\‘¶O³H›ªK›¼R–¾Z–¼^—ÇWŒÉS‘¾_œ¼a–Èf˜ËZ“ÈR‘ÇJˆÂL”ÈY’¾T“«U©^Ž®a­^™³]ž¶^¥²`¨³eªÁa£Çc¥Ãm¯Åo¨¸p­³q¨³r¯­h­¬f¶µY³¬T´´Q§¨Mª­T¤­S¥¾AœÁF¸Cž¸B”ÂN‘ÀE—ÃI‰ÊEƒÐLyÅYzÆY»M…¾E‡ÀD…ÇLxÉO|ÊP‡Å^‹Ë^¿_…¿S‚ºMzÁG{¾Q~ÂKˆÀI„´:‡§E…©>‡®C{§Cx±F}±HŒªD‰ ={¢>xªFƒª>‹¶G†²Hu¯Cw¬@t¸G{ÄG}ÂE{¼M„²^´do¥ZhžOn Tg£Sk¥Zu±Uy¬Xw¥[l§Wr¬iv¡rk¥lg­nh°n[°^V¾fXºgS»USµQNºZJ½UU°eO°eX¦cX¦VX©L\¬OS¦U[¬]Q©ZX¨UO®ZG´PW§YW¤P780A019@/F=&=K!EE)V11P38G<:NG4JL1P=4TL1WE/ZB8[A2]C3^F4`N8YJ@^S>YV:aS3oR3pWBvV:uG5sFEpPCnV?sXIoYJpP@bU9jd?sdJwdLr`Q‰`Pˆ]W‡bK†nV‡lVyeG{qV|rGw|L…tM{nC~eI€rKŒeQ‘_L™_KžsT“x_šyT–p`šuK›{T§€Pœ…R­€Tž„c¤za§‚e£o_€WŸU”zS˜†T™Y˜Q«—`°[ ™P«R¦˜Q›ŠP ‡W©‡Sµ—M¹¡N¼–R»¢I²–Nµ—_¹§Q«`¬¡Z¶šf´Ÿc²–Zµ V¬¬K´¢R¶”I©—Y­‘V¶›O±˜S©™S­ _¡™f¦’a“¡n›e˜—f”˜`”­^™°c”«b§¨fŸ¨aµb¡¥c ¥Rœ­S¨¶_£µO›©Y¦³Pª¯W¥¹T›°P—©Y¦^²[“¬YŽ£N‘§L¸Tˆ¶[”¿Y•½\†ÃOŠÃT“ÄV‘ÃgŽÇa’ÍR¿W…ÈKÂV‹¹Y’°c˜²c‘¸Vœ¯T–®\™µ[¨µ_¨¶^œ¿m¦Äa«Èl§Âi³²k²­q¯¬c¬«a©¼e»¿U±¸]µ¶K«¶T¦¬J²¼C§¹Fž»J¡ºJ˜¶F“¿T“ÊIŠ½AÌAƒÂI‚ÊS‚ÈOŠÁLŽµC}ºS~ÇGˆÂDŠÂG…¸PŽÄQƒ¼YÀJƒ·D|»JºE„¹O…«H‚ªD„´F³:‚°Cx¯I}¨KƒµHˆ£HŽª>«F…¥L«M“¬?„¹9„³Eu»;m²&DI,FG)=F+@N'II,GE3E?/J96U9?T:=H;:H>8R?/QA6SI;SGB\K;XS3_N:o[;m[4iT:gW8qV4o[;jPCtP~³=v±I†®J‡´KŒ²@ˆ¥=¡;‡§G‚¬@‹­>¬@‚¹:}´=v½?x±A~±Ay©Hs²X{§^x¦fm¡cl¤`i«ak£]e¢\p¦]{¨eu¡hz«gu£jo¡ad¦ef­f\§id«q`´j[¸iYº`c±[a³a]©`WªUXª_P©^V¯YU¤\SšUS RO§UV°ZW¦[V Q^¡JT¥R:591B&EE/DD)EI+E="EB%OA4L;6N;+X:1T@FY<7KE0RE3VP]^@cb@pa4vZ;zVo]Ay]Bf\MpU=mOCkVIbTBq]Jk`SqaQtdT}XQ{dTtb]‚me|f_|iV{hVslU{uQ~uPtQ|qU|iL„xQ‡rE”mQ–dL—aYkWŽdxVž€^›…c—zVš{X¦„gž‚b¢‚h¦xc¢nd•ƒZ’…X“}M“ˆT”ŒM˜F£šL©™[¢Œ\™–]¨™O¤¡Y«P© U²žP´›_­¢O¨œN©–W²šR¨œV§™]¶©`±Y§žc«žV±P­©Zº¤M«–L¯O»•\²Ÿ`¥›Yª”V¢^šŸ_˜œ_™ª\Œ£n‹¢a‹—eŠœ[™¥PžR’–Q–¨R¨d’²Rœ²V®W¢¬K”±X¥³Y¥¢Hœ±G¨§R¥²S‘®P“­LKŸV‘¨P‚¥`¶Z…ºS…²Oˆ¼O€·K‹¼S€ÇQƒ¿TƒÑ`‰Õ_ÐNÉL€¾Z~µX‰ºV’½b‘¿VÀg–²i¢ºi ´_™ºf›¾h¦Äq¢¼k›²`œ¼i ¬k¦½_¨²`¿R¡º\¥³P­¼R­ºN¯¹Lª¯H›µV¤­IŸ¶J–°Gˆ¼U‹ÀE¼F¼MŽÉT”ÉL†ÊUˆÄU„½O‰¼FŽ³K„»C±C‰»R„µZ‰¯LŠ¾@…ºO‹±H}´K~¤F‚©L}©>€¥Is«Kz«J‚²Qƒ²?}©@¨G†¦E†C…¦K€§B…¯;‚¯B{¼D{ºB€ºBw´H|°Fp±Tm«Zo°[|©cv¤WqªXp£dl›esœgyªez¬fr¦`s°dk¯np£ii¥cXªmdžkZ©dW±fY¿`[±gb³]a°V^¨Ua±aT«XLŸdU¡XX¥fS£^S™YZ­OOªUV¨N\ W^©WO§`>;,7D*5BAE#>;+@=%KB-FD.OI4MF/IJ0TC>V=:U;5Z<3XN.YQ)NI1LD2XJ2TE1MH/T[)Y]0Xa7\X@meGmg>k_CuT6~[GuZKmZMiXAaMB`Q=ZR=daBg]LkbNieLpdMunZ|iZvkYyjYug`|tdrySpuLplSmnJslGhQ‚vY|vO‡vO”gO‘^]Ž`a”r^ŒzUŽxf–yeœy_“yW‹€\”ˆi˜‘gž‰k¡b qX„[“ŠX’ŽRœ„I“‘N›“LœV¥•P ŒQŸ’SªœZ§žQ¬V¡Y®šc¯£]ªšWª¢Q³£Z·–V´›Q²¢Sµ›]ª£c¨¢b²¬]¯ [° V°š^²œ]»”W·Z®—Zª—`¦•X¥ž[Ÿ¨T™¡Zœ­]­cƒ¬h…œ]“¤_—§W’›^–™S™¡^’¯]Œ¤]”¨\Ÿ«S›°O—«Tž¤S¥¬K£¥B©D¢¯F“¢?Š¢H‡ª@¤EŽ¬L‡¯V~´J~´L‹©HŽ¬T‡­J‰¶MŒ¼TÅR}ÐO…ÑS‹ÅIÂNƒÇ]„»a‹¿cŒ¶Z¿[”¼b™ºm¬°o¨±f¥µg­·t©»v ¹h›®_Ÿ¨b¥±g™²X—¹Z•¶S™¹Vœ¯]Ÿ¬\ž®N¦³M£µL˜¨Sš³R›·K’µJ†­I”¶@•¶B•¼JÀQ—ÅKŒÇQ€ÆSƒ»L€½HŒ³D‰¶K„·N­IŒ®S“¹U•¶E‰­E€«F±K‹°M‹¦IœG„Mu My¬D‚¶J„§C{¡;,:DH:"LE"B>0P?.X<3W@BTC4\=>UG/ZT1[P,XS%NV'SM0JH2TW-NQ.Rf6\d5YX?faCj_Ioa7u\=fY@xcKu\?jUAdKBfM;jV25691*‡·=‰­C{¡OuœQ}šHt£Hv¦M„ªFŽ£@’§DŒªGžG‹¦<ƒ£<†¶:„º<|µ?€¸@}µ>~¾’¡; «9˜¥:’¨>¨H…·A‰¯?«UŽªS•¯H‰®R…µH¿?ˆËC|Ç>~Á=ˆ½P˜ÀT˜»Z’·a‚ÀV‰»c•¾d“Æi“³r§²m¶d¡·q¬¯hž§q§«o³c¢µc’ºX§]•¦T“¥a—´f• `— bŽ§U˜²`Š»P‘®K†»?‹²2†¥AŽ¨<‰¬G”°JŠ«@ ²E”·EŸ°A–µD«F•«;¨;Ž£Eœ§=¢¢B« =¢ªE—¢=¥B•´D–¬8‹¯K…¡D|¤Bs¦M†¤>§H‡ªI’ªM‹«@Ž­C‘œAž@†¤G‰¹Aƒ¶:„¾8ÂE„Â7¶Bt²Bn»El¸OyªZu¤\t«Qs¥Zz¥gq£ns«]n²[t¨\{¢j{¢`{«f~ªgo¦qx¨cq£kh¦ff±dU§nY«lW°rQ¨lL¥lPf^šaW¢[\“]O¡^J^NŸP\X^SXœHa¡MaªUe™QW™WA:;86:?<$A5:6!>H/:Q2;I)A@"O@([=8YHAPR6NO7PO8[O‹³4‰¬7¬:Š¶?’¯G’¨9œ§;¡«7™­@“¬A—¡; Ÿ8¦8˜¢6‘¤4¢¨9¨Ÿ9¥£:•ž7˜¥<’³;Œ®B‘¡Gˆ¤Nx«C©@†œE’¥;«>ˆ«C…¦H©J‘¨IŒ¥B„¨@‰·J¾D‡ÃAÁ9|¼=t¶=k¸Dn¯Mw®Xw§Ul²Zn°Zq²^{£o|¬st«er·`}±_uªXz­b‚±l¨kƒ§bu­it©ca§ee¥o[ s^¢rSžqM›iX¥cY™[TœcNaU•Y\“VQœVR¡QP¡UV£[U¡OR£H`¦MY›V_ŸY5;.54,:?":8EI$EG.>N1EM%DD&PK*GO;MN>\N:Z[2XU8]T0aX1eK3a\9dR?dV>\b2Wh?]f:ekDgY?pi>naCqg?nj9ugEyiLyiKxdHljFrfO{aTo^VrqTwnStwZyqV~p^za\vj`|tTomWrc`roitp_ycg|fdyglssdtogp|q}ossmy€f‡€uŠrdŽ‚g„€d‹za’Œb€ŒYƒ^„g‰ˆfƒŽ_ƒ€f‘ƒdŽ‰c™‹Y•\ \™—X¡V–ŽTœA§~N›„\£“^˜Vœ‘V•™V•aœX ”U§’^¥•\°˜U¶•`´›W§žU¢¨Y¬¬X¬ªU²¨[³©b°´`¢¡\œ®`­±a¡¤^¦§ZœžU–™Vœ˜fŠ¡n•“pˆq—•h”m’jk–“_™–^’¦f“©^¬U‘§WŒ®F‹°M‹§F™¢FŠ¥Kˆ©L‰¨G§A¦G;‡¡8–©7Ž£=‚µ@‰²9‹¨L‡¯DŽµL‹´E{µR{µO|ÁD€ÂJ|¾J|³SºYƒ¶`ˆ®cƒ½UÁg¸]œ³o•·j¡Ák§ºn ©h§­l¦¡kª£c©¡[ §d•ªa“ W‘¡d˜œg›ža™ŸWŒ–Yš©[“°^‰³Lˆ¯D‘¦=µ;Œ±?§:•°8“©>˜±Gž;“­4ž¨8ž¤<—ŸEŸš1™®>¢ª=¦˜6œ8©ž5œœ<›@–­H—®:–Ÿ=—¨O‚ž@„¥K…¯Gƒ£P†¤@–¤?‚¥Iˆ²I®NŽ¢M°L­E²H|½G€³Cu¹FvµGq²Nh¹Pr«Tm²V}¬\s¯Tw­Y‚«dv¬et¯oz©qp«`„®[´hx­h«l¯py­kw³me d`£ti›p[žp\—zZŸmY£kYªbO¦l[¢nN–aV¢aU˜bT‘TN£]J¥ZI˜IT¥Q_£T`«K[¬OW£PG3)94(;9*@B'7H#:C#9@GK)GX&BT1GS6MY8TX4\^1WY,ZR1eU9^J@_TDgV<`XB[Z=X^8^j5gl:f]Ce]Eg^BdbGna;neBniIpjRunL}sDumKupE|gMzoTr_‚sZzi\zl_xpTxybtu`rhZvfYpagqfkkqkpmiore{trr}srxqrtizvmzzq€€uŠ|oˆoˆƒsŒ|i†‹k}Œ\€Œb‹^ˆ’W„‰Z†“ZŠŽZ”•YŒŒQ‹‡P˜“W •N¡ŒU«€N¤ƒK›‹R“…Q›‹T—‹ZœˆYžŠ] ’Z›‘Z–[¡˜`©›d®b¤c©¤h¬Ÿ_ª \Ÿ¨]¤¨Q°ª_¯®[¯§_ «\¢§[Ÿ¥Sž¥_ až—g™œd–›jŠ•kŠ“i‹hŒj‹ˆlŒd”–b¢›b¡•`¤—Vœ¥Y«X‘¨MŠ§KŽ¥F¡C–›H—žAŽ¦Gˆ­@…¨DˆE9•¢/•Ÿ3‹£<Œ«>„«8|³?†¹A±Ly·G~ºM{ÄR~¿Lw´Ky±V‚¯W~µ^µ[ƒ±a€®hŽºeÀoœ¸j¨¸j¦·j«¬g¥©q«¢n¨§g¤£i  [›¢Wž˜W›¡b a•§eŽž]ˆžbŽ–c‘¤Y• Z–¤H¥CŠ¯Bˆ«@–­A“²9”¬7›±=–¤7¢ 9™£4˜Ÿ9¥¤;¡=¨Ÿ2¤¨8°¨2«—5£š8žš7›¨@ ¨D§Bš§IŽ¡Q¡I‹¢D„¬H§I­O…¬N‹©IŒ³@‰­G„³Eƒ¬G~±=„ªD|¯>{³By¼Ev¶AwÀFu¹Nv°Wm®PoªVx¶R…·\‚¹V„°bz©frªcp­my«m{«d}¦[{¨_vªfsªlm§cj¨gd›xn—wk}f’v[”w]‘lW™aRžcX¡`YkOŸnO¡eU—aU’cV”UKœQM›JS¢O[¦Na§Zb­]^¢T;'&52$J9/D?0;I"HQ DG5RM6KT)RS2RT3VW;XS:\S.\N7RU2RT7VX-dZ7]T5fP7`YAXa:av.bm6b^CnSBmW9m_?lZAna7vuJod?ufG{jKilWstKzr\~iSŠlYyn^uwaƒsZ{uWmm^quhoeeqdTxdiqjuwotniunuxw}rrmr~mzykj{nx{‚rt‰u…„p‚ƒyŽo“|f‚}pvŒ_€Ž\€ƒi„‡e}ƒZ‹i‘‚_Žˆ`š‹]ž]¥ƒX¡[¤Ž\—M–‹D›‚M™ˆO›€T“YŸ†P”•W“‘[”ˆ]¢‰Q£–Y¡—`´£[µ˜`«b¦™^¯™Xª¥]¦Wªœ`°¯^ª W™¨]›£dŸQ¡¢_œ£j—•b›Œgˆ“cŠgƒ–a‘k”jŠ”\˜lŒa›™g¡eš¢g“¢Y“¥W…¨R†ŸM¦Q©H£K‹—>¤?ŽžF“©>‹§G…4Œ 6Ž¤@Š¬6„¡>…±@²Ju¹B|½Kw¹M…µD´IwµN†±G†®Sy¬VŠ´d€©TŠ²`„·fŽ¿^³bŸ´k£ºm¤¾oš±lœ©f©ªeŸ¤i¨©j¥”bš›S –UŸ›]ª`’¥X¡S‹œX“œZ‹šR‘œP‹žL‘§>ŠŸIªFŒ«A•­<‹³9“ª:¦- £2—¥;œ6“˜:—¦8œ¢.›¢8¡ž4¨—+«ž,§’:©—@ ¥O•K››?‘£L§EªN¦E§J˜›RŸDŽ¨?Š¬AŽ¨G†¥=„Ÿ:€¦>€¬>­H€£D©A{®Nx¹Rw»Tt´Ls¨Nu«Rv¹Y{´X€°dƒ´]u«aƒ¤mzµe­`t³dx«Zwdxžbz§hj§oq¯gj¡lj mg uhŽuWŠra•cT•d]œ^aŸkZ–t\kK‘cT“bU‘\V•XPœ^X§U_œL[šN^¢XhœSl ZJ/3B)/A**K6)BK2DP-KN-LT9JK1XH/QL8SJ9[D4TF/U>5SG0MP(T\*WO1^N.T\6WY9em6ep2i]?g[<^]7fZ=o`5n_=rj4lo„ D‹¡E‰›M‚¢Mw§Pw©R‚µaƒ´^²O~­O‡¥Vªcy°j}®d„²b¤_‰§i°lt­av©eq¢bx¡azŸku¦nm¨pt¨`h¤ek ra™kc“md—bV‹dP‹_[‘ccn^l^ŠcT‘^VŸ[X›_P¦_S eY›a`œQYWX\e–Oi˜R?*0=$7K18M60JA/QE6RU;NSA^V2^Z8WQ1JP:ML,WK-PG,^H5\N4\\#ZK&QK%SR*d\>b\:fl.m]:cb5oc9p`;q^>lbCwj;qvAoh?urBysMvu_wp]vkd~cZ„db„cnrklk`{niqhiifcgl[lmdkdhqcvhiqkZvzekolt€po‹dq}nu€|wz|uw„wx…ot{p…†|…‚q|Št~j}r{|oƒl‚wd}ƒgƒaŒ~f›Ž\¤~g§Z¡…\ †^•Œ[”ŠG—ŽR•‰?›‘Q¢T•‘P•‘Pœ–X“L•ŽQ •I¥‘L¬V´›X¤œT¦˜Y£œ[®V«™S§¨Yª¤[¥ aŸi“Ÿf•—]˜™gŠmŒŽh–‰h‰Œ^‘`Š“g‡ˆb‰‹b•VŽŒj˜‘bœ—j“aŽ”n•‹h•›i£[”ŸOŠ£U‘œGF•¬;™¢I¥G¢?€¬I£D‡¥Dˆ§J†¦F‚žO{¤K~«Mw­Q}°N‰µ?„¶KŠ­?¯J€ºK‡³R…®Zˆ±c…³P}¯X­SŒµ[•¼i¹dž¶e£­hš°aœªnž¯a¨iŸ©c˜\—šS¢—OŸ—P™¤T‘—Y”`‹RŽ”V—N˜P‡¡=ƒ¦:ƒ¯={«8|¤4Œ¤,ˆ©1˜4’¤7••,¢8•“0™š+“”*šž3 “1§•5¨ -£—:£‹9¤‰>¤–;™•M™•BŒŽN‰™FŽ¡>”žJœH† F—A‘ªG‰¨Nˆ£@~šG‚¨@ˆ N‘œLˆ¦I’™M†«X~¯b|®b}¶\‚´^¨Xy«^ˆ²^¥ht²b­f‚ªg±d‚§o} utœpx¥n~ mo¬mo§ek®cj¬je£_m¤_jŸmfŠkW—_Y…d`b`l[•jb‡haŽcQ”k[›k[˜bTœbd˜Zfš]d›T^]k˜\c˜JkŽN90gc7nc:heBhe”7‹Œ,‹•)‹˜+š. ‹)—•0Ÿ“4¥ž5¬’4¨•3¡Š0 >ˆ=IŽ‘F‹B––@–™Bˆ¤=‡¢DŠœKžK“O„•G‹’NƒžH‰¡J¨K“¦N’ [‰ª\ƒ¬f…¨g†¬`~¦i„£i~¤f…ªg®fzªb…³j±h€¶kw©o{uv›pz›szŸx{tp«lh£dm¢cežf][^›]`Žca–cZŽk_‘fg‡fa„leŒnc‰oT‹q\ˆkV’hcˆbg‹]c–am—Xu”NmKdSjOH68=49;?;>G7KBBU?DSTEaTBN]DVR+JQ*UH!VS.RQ"SP.VN1PR VZ&Y[1WN)`W:_[9`e>k\*_i=n`7le9cnCpmAuk“CƒKŠ—E”—C˜D€Ÿ<Œ¢H‰˜R‰›Q•›\šYkŽ¡m‹ j§a~œn}¡d…£b‚¨l{¥kƒ¦g{°s~³b}¯ls«o~šlq˜hw¢lr¢ju _j¡ie™[mœ__œ]^›aX]Zˆ``‘icdd‰^df\‡nY•pQŠsZi\‰\Z˜an™cl›^f›\p•[q‹XjSbQD44?<7<:2GI5OA3TD@]M?XRKRRCKW2QX(US)^V.YX&O\MV#MX)\a$S\/RX.__2[b:ja7gc/bb5i^5hlCchBf`Ey`Gxc@sa>mKhFy`H}_X€_S‡_Sd]ˆ]aiiuhm{ccy]\w]RnbYqV_gU\j``w^_lXgmZryelvhp‚fk‹sp~iu}otƒ~qy}}‡|uxzŒww‡~to€n}mjzkiˆrfˆuo}d‰u^‘„U–„Z“{e˜}a›}[˜†K™ŠW ˜U¡•H›ˆJ ”Qž™RŸN L–•E—¡A§Ÿ@¥–D¤–<šE¯¥C¯¦J®§U¬¦P¤ªO  Vœ˜ež¡hš¤^¢šbš™g—–h“…j‚o}s‘ˆh“Œ[ƒ†^€„i‡Žg}mŽgˆbŒ‰]Œˆf–b“ŽZ‡Œbƒd˜`›Q¤KœNš£P§C§Cˆ¦>Š¡;‹§G€«K}§Hx¦Ut£Lw¤Pr¬S|¥]¬Zƒ¡Y‰©W¯TyµI}³C‡§I‚¦[z£b€­_†®VŠªU¢P’£Tˆœ^‰¢]–iœ¤gž§iœ¤[š_–›`—¡Y¤žZ¢T¡™[–š`‡¡Z‚¦[~šW~œT‹¢O’£O“ªG•¤E«M‘¬<­<{¤:}¨<ƒœ9†’8~“@†6}’3„ˆ!”‡+›Š*˜Ž%”š%˜š1 ›3§,«2ª9™”?–ŽB‘‹>’”5š9”•8•?‹A†˜A“EˆŽTS’ŽA…ŽF€‘@‚Q’–[Œ^ˆ™c XŠŸ^©cˆ¢lŸq‡šeƒšd†¥l‹®pŠªo‚¢jƒ¤m€¬kz°b}¤`x›bpœ[t«\y¡fz _o›[g’^r–dm”bj™``ŽaeŠaeƒhX‹[Zƒ_Z‹hc`g‹e^’ne_g^c–Ueš\^•[hœNk•Od–]a—Wi†\>1FG;BFA>EBDRQFNGJ^NA\YCPLCHK3K]4SU5X](RW&M[ RT/[U4`c,P^6Te2X]8]cFan@ja:dd6q_=f]=mZCf\Fx^BoiA]@„fF‹gI[SŠYTŽWU‰Za„da‡]i†imr]mt_dq`[kZVhXcsYZkYWjOckYgzZnsTu}ahyhv‹uu‘wg~wh‚q‡x{Žq’x|‹†sŠ||†‰p‰ƒwr}prwnjƒys{mzdqb‡^ŽYŒ„_Š…]›‰VŸ‰S–‡N—›O¥‹IŸ’Q£™W¦ŸQ¤V¤A¡Gœ—C–“F¥G˜–D —O¡¦M§£Qµ§F²¤W¢œM¡¢U¤›X¦¨kž™l£¤hžœoŒa—ˆo›‚p—‰dŠnŠ‡i…l‡Œc„†iŒˆ]‚Œb‰ˆd‰f…Žawaˆe†a„Z ^Š¤RŠ¦QŒ¨Jš˜R—«OŽ¦A“­<§9¦B¦D}¤Q|³]x°Qw JzžW~­\ƒ§Y}›Uy§\}¹O‚ªTv°J„­R€¯U|¤UŒ´ZŽ¬V§Y£[†¤V‹˜\“¤V”¤b”£f‘—c”’Yœ–h˜e ’jšœiŸ[œ›_‘ªSžX¦]š[…¨MŽL†²O…´L‘²B©>†¥G†ªA‡¬=ˆ¤F–2„–+Ž9(€•$ˆ'…* ’!›*›š$˜œ'›'¤š6©‘0¨”3¤<•‰7ŸŽ>•ˆD™“@•ŒC›?‹ŠO‚‘O‰—JŽ‹K‹“G‹Nˆ—D‡”A’•K™]ƒWŠ›k’dƒ¢h’’g‹—qŽ™r‡–q…Ÿh‹žrƒ¢p† l§w…©j}¥nv­fu¡hz«Y£Y|°b}ž]}£byŸTq•Yl”^l–brŠ\dfZŒcb„mj€\jƒh^Ž[iŒf`‰bdn`˜_j–\b“ac”_b“SgšWpœMdšae›QjVM9?K:HM:IHJAGRMSOMNWDYUKPRCPPBSU@KZ=Le1Ub,M]1M[,P^6Xd:Zabg‰“+‚š0Šš+„.(‰0¢Ž(¢*¥˜+¢›&ª+¨‰%¦“+ —/Ÿ‹8™’<Ÿ‡2ž‰6”HŠQM‹‹K‰“V”‘MŽ‹O–“E‘•I–œM•C‹O‰X‘Yˆ’cˆŒ_Š•eˆ™n“n•y‰w‹‰y…”yˆœu‡ w‚§k}¥nq«er¥bp©Y{«`y«ey§av¤ewœ]p“bt™Xt‘OvVm˜_a]_ˆh_ŒafŽZi…ac‚kegk–iq‘\i•]m˜cp‘Wg‘Zo’^s”Qr’QfœTmMl’W9>B=CJKYc6Yf0Y]7]gB^bGZd:a]9k_:j_:q]2y]>ri0€fC…gD€gF‡dGŠiJ’_[‰\NŽ\`Œd^yaezkZ{Zc{aXhZhxa`nXXhOSsTVoO]uSep]hrihu]l„qi}mn‹{jŒ{i‚}iyƒnw‚vozx‚sz‰t†xƒ}v|y}~€mt~zˆ‚k‚rŠql‚zZŠ€Uˆ`Š†Y”SŒM›ŽX šHž”GœŽL¡“O›™S˜¡X¥—J¥šNŸ’MœžR”—M—•T•V®›U°œO®”J°ŸY±”K­ŽV®•T¨£Z¥›h© d›•b”e”j›…b~d‹c„]œŒk›€`•€k•„^W~’a€ˆds‡dvŽb~gy“p `‹P„™MŽ—M†œE—¢BŠ­P…°S…®E†£J~­G|¯Lp£I¦Sy¥X}©W}¦_rž\w¦Vƒ°[x¦TlºPy§Zx«L‚¢Lz®JxµR‡®Z°]‹±[y«[}©[…£V X…›X—˜Q—œW˜œ\š“c˜–jš›c•e U—¢RŸ[Ž¤N„¨\~£U‰®]‚¦IªU„¯G†²BŒ¦A‡¨=ƒªHŒ :‹9—2Œ–)Œ—.…Š(—”+š”2š*•‡/£•*±“-­•&¤”&«•3©“$ª‡7¤”4 1¢Ž0‹A‘ŽK‹‹GQˆ†XŒŠR†•K€‹@ˆE”G™B‘ƒI‹†SŽŽT\‹–cmˆ’kŒ‡gŽ’kˆm‡‰p…‹n|Žr€Ÿq¦mˆ˜mv¥x}™slŸew c|®jx fz£pz˜jUw”Tx”Qs™Vw‘`v‹baŒQ]†T]Œ]Yƒ_[ƒia^cŽihŒalff‰Ymš[l–`l“Yn‹awŒMt“Qg—Ud“agV@=T;AK=CF;?K;LCKPFUPD`RDTWCXUA[]CTZ;OT6IX?HZ0JM.NO-T_1XY5`Y/\Z=c`Gb^BZg=aoGogHsj>q`;€`8b‰›B†•?““3’›+‰7ŽŠ4’0ž‰*¡5˜„8Ÿ‰*®Œ*¡Ž0žŒ.ª‚2ªƒ%«Œ$¦‹41™‹9•C’Hƒ‡L‡†V“…Y’‹J“‰=ƒA’†B‰R•~J‘K“{H”†I‰ŽP‰a‡†mŠŒhŒnŒvƒ”v‚kz†s€†m‰Šs‚žq§z~žyz™qs˜s{¡tt¦mwŸo‚£m‚—f‡–\~™_r’Rt‹WxŽbr‹]i“QiŽP\V\„U[„eZyce|[i…_ab`bnŠbj[d‹_k“\n’Xn‡Wp‡dgˆ`gˆf5@K>GR=FS9HO>LCCLJVOEYG@RZ=MW=NOAPXAMNA=Z9HS6AJ:AQ4V]+[S0U\9`bGI5IO;[S:\N@bZLb\NbVLhQSv]Py^TvbKtbNycS{XY‰^PŒ[G…fH…rG„oIŠtDˆkJ€sN{oYtb_}bhvgm{Zc{a^}WizZeyi^na`sfhpltxsqsty}€v€wpy{xzxzl€{gzr{xvu{n~kxh~‡k‹Žn‡Œw|Žsˆo‡ˆnŒp…upƒhq{e€„`‡wc‡y]ŽV‡†^T“MŠˆP‘‹OŒ†QŠ‘b‰•ZŽV˜—X™_“™^§•P§™R¬’M¬–EªˆJ¥’L¬“W¦•X›˜b“f˜™`›“ci—“h˜še–•Y–“\’…Qž…V˜†bŸ‰h˜’k““l†f‚‹oˆh††fˆf‡„\}“\”^}•^|–`yPx’Nq•Mx¡\€ªWƒªV¦Z†¨]~¯Sx§Q‚¤V~›YWvž[z¦Ut§S}«Uv³[i²\m¨[q¥Ws©[n®Wh²SfºYi±Qh¥_h©\k­at¯[€«Vz¥ax¨ažS†›R‚PŒ˜S„•a–T‰™T…¡LŽ«NŒ­TªK•®H‰¤O‰ Ox©Vs­Tt­Qm¹Ju¶<‚¸9…­4†¯1£/›/””8‰?—ƒ<™1™ƒ2šŽ/œŒ9£’9¦‹7ª…7¨{(¦{ yž‡&¢‰1ž„3—‡>™@Œ†O˜‰M’O–MŒ“R„ˆSŒŠHˆŠG‡~D–~S•|Q”Š^ž†Z—€W™ˆT—bŠh’h–ŠmŒ†rŠu‹‚t…†l{’t}‘{x•}z yn›qœst”|wz{xz™iy”g‡›_ya|Xp•Zi‹aq†Vh‡Zg‚^[ƒWY€PdxVayaY|[_€Z[x`cil„dqZf|^bde‚ZiŒ`n`xlpj@EE@PDANHKRJLWRNTQJN[FMLQ>\V?VDCJL5DS7JR=CILNTACR;UOA[X6eSEZ^Ig[FXJWdUIm]GpdJqaO|_LƒYK†cO€]LƒgUfVeKŠhO~sZylS~sRmg`u_]zchZ[y^Z}U`yWl{ek€i^rij|gpwqpƒtppmƒ|q~€p||qymvoxxp€vp€…qz‚w|py}syj„x|€rz‡iqƒlˆŒr‰†k‹zmzlvˆeozgwƒk‰rg|}cŠ†c’\ˆ‘V€ŠZW„ŒX’‘b““jŠX•X—–\ œUœ[¡˜S©›M°ŽO¨˜O©’U´™M§‘\Ÿd“YžVŠe—ˆ[£—_•–Y”–X™V’ˆZ‘Q¡†a‘˜h“m‘Œf†”o‡n…`‘ŒdŽŽT‡”]‘b~“_}™\‡’Sƒ–]o‘K|œJq›R¥R€£bˆ¬W‚¦\ˆ¬[}žP|œ\ˆ£_y—]p§^tcz¨Zs°]nµPt§_h©[g¢bk¨fq²\q®So¸Zq­Qn«Yp§cjªSr³b{«ct©kwª`ƒ[šM„ Lƒ[~š]–^†“W‡¥U­P¡OŽªL§O‚ QŠ¥Qy«F®Q}¯@~­Kz­Hz´@~¤1ƒ¦9ž6”ž9–Ž+—8˜“<•9›…1’„0Ž6 }3™…@ª},«ƒ0£v)©l"˜z" Œ/ƒ:“yA–€CšŠS‰ƒQ—’E•—K’RŒ…YƒN…ˆM~€JŠƒZŠsO–]¢}b•‡V•ƒ^‚a‹ƒ[Žhœƒ^št‘xŠo•|n…y|ƒv…•}~š~ržrtxw{w†~}ˆm{’i’c„iy“h~Œ^nˆ[c•`r]cƒ[\ƒZZ~`ZzTh[f|Q]€aX€Zg}_g€e^‚f\w]_xc`{\^ZfvdcŠlq…bo‹v=KN@KQ?=J9@TF9W:JRJIVIJUMANLLOWIQ\JLcEGKN5HS2OFCMTETIINJISOC\G7WX?aZIVUHaDRiKFnSQjSMn[R{cWpYSwdTˆ[O`PZW†_TŽa]}rZ€tawj]qg]zj]ol[|b[yrb\_at‚eazbe}hd|eguet}w{€xtŠthŠrf„|o€‚u†r|‡u‚w|}‚~y’~j~“{y‘t|’xt†kl™mo‹esŽks€puvvrqyrym~x{„oƒezc‚‹[z’Y~“a‚Ž[‡“cˆŽk–q•”a–Œf“`£–c¢›\®’X­‘Y±˜b°“Y¯ŽP¦†XšˆI¦‚Y«U©M«ˆH«ˆOª‘GŸŽU¡Ÿ^˜œS‘‹U“˜Vš’Y—™a•’fˆa›‘U‹P‘\“]… Tˆ‘N‘—VˆŠPŠŽX|“H™Fu—USo§Uw R|¤Vy UxŸSx O{Uu¥Xy bx«cl¥cp¥hq¡ht¥Vw¤^r©fr©le§sk£j^¡[m­Xj¯^q©bg·\o¤Wr©dl¡hn¨cqªarª\~š_‚—Z‚–c~ S‚¦ZyšS†¦I¢G…˜N„–N›DªCŒ£L}¥A}ªžƒ=’†?‘6¡ƒ0¡~+›v$¡j(¤{'”s%p.‡x2vDœ}E˜zG‰‚?”„P’„M‡ˆVˆ}_‚xR…yT‡}Tvcl^ŽiP™{Q—tZ”‚b„qeŽ{eY—‰eŒd•„q—xt’wl‹z|‹„~‚‰w~Œu…€p~v„|zŠy‹ƒr€ƒq‰‰qƒgkinjh‡ts•ii‹hf‹\d~[q~_hsWeuQa\cr]es^gpWVxdYn\euqaujXnoUox`usivuu‚mCDV7KQBGX>=YI9ZDENAFKOAOIGDNBDZHGYEASIFOO;UM8MNBLE;ZHAaA8VI@^IM\QHfSFaKMdPKiMWkXMj\ToSNmYU~\W‚gU}i_‚aW|e`‚c_‚sf€rf†ogzn_ty[lu[mr`oqcnih|enwfcwdf€_g„hxykp}xv{|sŠ{lpkƒvr†|s‚wxz{yu…‰{‚Œw‡ryzx“r{tvol’qk‹ok‚no†jtplƒutyx€w†x}„z€w‰g†g…l‰‡a†…l…‰iŒ‚q‹g’‘^“fš—qŸœk£œ]¤•_¡šd©`¥‹X¡‡MžˆDžŠJ¡ˆH¬„O¯‰D«‡E¯†Eª”J¢™H¡˜P™œH–˜MŒ“T’šYV“ŠdŒU’˜Q˜œK••Q“O™R›LŽ‘V…ŽK‰ŽKI‚›My˜Tw Pt¢YrSp—Pt—X‚™P~¤Vy§_o°\t°mr±nr°mk¥poŸjt¨do­bk¥^g ad©kc¨`\¥`h¬gh±fn®cm¬cj©dm¨h|£jy¥a€ªlw«hu°e€¤b}_| [€ŸP€¤KxŸNw™Fz˜G…›LŸA‰«Gƒ«={:x¡9y¤<}š2›/€™7z›4y=t–9sŽ4~‰1|•7’8ˆŽ8™Œ<™ŠC•„A›~<šƒ8•:œƒ/—s5¡p)™s$™v.˜z;‘t@–{C˜zE“{IC”yCM‚Y\z_|}[†x]„r]ŠwU‘mV“oV”v^•w]ŠtdŽ}]’aŒ~d‹j”xu—vr“xxŒ}o…|‹„xˆƒ}…†|Š€~ˆ€|ŒŒz€Žr|’|ƒ‹y{qrmjkkŠuj„le‹lc‹fl€amtdlu[es^k|]i€ek|[`^`q``vgZkranuYmsgo|djymqng|o?BV6DWDIW?FYO>UHFRCAQD>UQ>DMB>PCDUKJ[KKLREWGFJCKLTFWJGTHNYAKRPF]^Qd]UaXMZY[bUZmc]hfRvdVyY]uWV…bU‚Z\v\dv]eu_^wfn}hs}ngva_{gbuudyjmzqnvikycg~al}nrwgrzilurx}~xuxp~~iurztdw|n~‡s„ƒot|Œ€{—€‹yqt“p…—nrŽnz™`y‹nu‰cqˆk{†eokqv{}osƒ{y}yvŠzy~jŒd{^ya}‚mw†iƒc‹i•h†‘oššs™sŸ–n¡‡d¡ˆc ~h¤ŠS®‰[¦ƒS˜ƒC¦‡Q´‰L£‚P±ŒF„L¨‰I’TšŒX™—K–ŠM‘\˜“a…•_ƒ‘Z†‹S†‘L‡‹R‘Y’—\•]ˆQ‹X…“X‘’B„‹R€’G|ŽCv—It–Hp ]xžRpž`t¤Lx¥QRp©et£lt¯ht¬kpœrvŸcz±cp¬Xa®W`¬\]¦qa«`džjb°ep¨ti¬ok£hpª`h¤lt¡ipŸft¦cg¥d{«k}§hs˜Zy˜O‚¤Z}œU—Uw‘P}˜F{œK†ªE…¥K‰ªB}¤K¡=x¤FxœGy•;‡˜7„¡0zœ?{ ?r†2‡0ƒ„7„†B–“@œ‰>—“<ŒF—|=˜‰3œx0 +§v$¨t£q-q%žu/’q;y?’{6›x<Œ{D‹~;‹…C„‚Oyr[w]ˆrd…rTySnU‡rR”qYŽ{a‹zYŒ]”ƒl™vj’~gŽ{n‰ro|uŽst…h‘|n‹}Ž„–z‚ˆ‚€‹y|‡†~Š}Œ‰{‡ˆ{ƒ~q}~l{yq{†vi‚mfŒioŒok‹ih}[sx`dyghveqq`p{W_n^c€W_xn[epZhpbsklo{c|‚syriƒp=MYIQ>LE4VI;QQ=DY?H`GS^GP[FOWIKMLAJHCTHE]VRXUOXFIYKTY[NVe\\cXYZbb_]`h`ie]m]U€ZV„UV†\T‚b_yhhqjjw\ekcbn^nuemtdhuj`vlermm{gu{nmqoprjvthpyqisjmvsn}x}wxxm€rv{n|~ep}`t‰l{Œw}}qv{’xwš‚y …{¡y„“sz”b~•czdray{fr…c|‚k{ws|uzƒp{vwytz|x‰l}az„f}`z€i‹ƒnsŽq‡—k‹“s”l›‰oŠe |h¥{a¢V©zZxK ‡I­D¯O£’S§ŠW¤Mš€HšˆPŸƒXŽ‡S‡T‡’SŒ“]”f„‡]Ž\‰–V‚‹S‰‰XˆˆTŽ‡V—ƒV”Œd‰TŠ”J‹M|‰C|ˆL}’G~›Gv—XsŸ_x•Ws–\{¢O~ŸUxž`k¡ek›ij¢hg iq¦a~¨Ws®Th«]i§fa´g_¦rn§nv£un¦sx›rr¡or§ga§ci™Zh–`ošff£fug¥_¥Ru˜N~˜Xy“Yy•TPx’Ax¢=¡C‡¨?€©NƒªL|œDŸH€‘B‚‘H‚•Iœ8}“9w˜<„F€‚?ˆƒ5’„;™‹?‘Ž>•Š<‹;’ˆ5¢~9¨q5žp(Ÿm$žoœp&—l&žn)l8”t7{4Œu8’y6˜q6•zDˆsQ|oZ„nXŠwbs[†wYƒwa‡z^”qS’xW—{fŠe’}n˜wg‘tjŽu‡sprršvl˜„j—Žk’}š‰ƒ˜}‡~z„sq„zy’‡xŽˆ~ˆ€yzzxq~„xƒ„p}…jq~mwryŽgqdn„_nxbjtehmXdpV^pY`~WiwYcnljlt`zpd€wr}yowv‡kOKmŽ?|ƒB|ˆBƒ„?Šƒ8”€4‹‡AŽ“=‰ˆ0~2œu1§~/¢z,£o"¦kœo"©m. r5—o0’m5˜z-šy<™v.~FŽ}LŠyL~h_‚x\‚xXƒvW‘q]vVyf„`‰zV‹z\’wa‘sg˜vs•xf€r‹tlk—yk“‡nžˆv•Š~v˜x}™~n‡xum’‡q‰v|~~„}xwƒzvŽ€nvuƒ‚nƒˆbxetgs‡bm}gvpnjqWry`iwQcvTgu]ithr|ae…nkzo{…q€ˆ||„p=EiDBhQIiRSXVUUYONPM\WHYSLR\BYcJX[Ja]Mh]S^\W\ONLTIKdJNkZLeXS^]RaUYg_Ueg\scNqYNvTJw\TucZp\en[m|XdnS^p[^pXly_lrWrw_mrbxj`yrSypWsqWp€`s{ay‡bwŠhw{ht{h{yprtt|mqtxrkurplspr}gl|pv||{~~t‰ƒo†p„{€~ˆ q‰¥mŽ™ii‚†p…lˆnƒƒmz~utzm‚uq‚wsw‚{uˆ‚pŒˆo‡‹z‹‚z„ƒr€}jƒ…gzgƒ€q|…h†p‡—eˆ‘i‡dn”}h›t]œ|T¢sS¥~L›€Q—Pž‹Y£R ‹I“†I~M†O”}Q—‰Y’‹e‰^„c„Œ[ŠW’‹^ˆ†_€€V‰„]‡„[‰^Š™fš`‡a˜X‘™Lƒ‹MyŠP|‘G{–Ow–QvSr“Vl‘LtQuMlŠWp–`e–jk›he£^d¡ct¬Yo¨Xo¯dmµhj«^t®eu°[|±bs¨lu«ao¢cs“be“n_‹t]‹nj™ei˜^g–ei•\ray—Tx”Y|Z{—P~–O…–N‹‘N†–K‡žBƒ›B¡D¦Hx¢L€’?z:xŽ:vŒ„Œ?ˆ‹B‹…;™‹<•Š5“Š/¡|4¢y5«{.¯)ªs§k'«s4¤u/g5–i-–u/˜u96ŽyJŠ}PzO†qWŽrZ…t]‘maŒn\…{[†^‡z_‡}d‚{hŒv`€c“pŒucŽqgŒtn‹vmŽxp”{yx™‚|£‚›v}’wt”wm‘wj‡‚mˆ}nƒ}t€ys‰rŠzsƒt†{qƒ‹hzŽ\ŒY~}fzth}xgv~iov]k~^p{\q]r}ZzˆgrŠcvls‚Žs„z:EqMDlGQaWVV`VUZJ[[O`PQXMD_YM_SQ[cWc^NY]UU]QX\S\VRXb\P[X]g\XcfUeYTc_SfmdvicifS{\Y„\Nti`pelzf\‰\`€YfmV\uVdl[qkbun\}o^|rX{kUpv]s|cq„aoub|~c}€pk~pj|mrskktqompmjopvu|k€zhvv|yx€rz{uƒˆp‰q„œpŠž~ŒŸ{”o„•m“jˆ‘m‚dyixwtr~stˆyi€}hwvpq…wv‘{x‡|Ž’v‹Šp€{~v‹i‚‰r}„h~p€r€„s‡‹v|‚k„…q“~oŠth–zf•s[˜u[•y\–ƒV‘\˜c‰ƒY“E“~DŒuO„|QŠ…Mc‹‹k‚}Y’a„]]€Œ`ˆ‰]„^†P†…a‚†VŽŽV–“bŽQŽV‰O‡…HxŽCy˜@{™EvL{Lz‘Lx‡O€NwŒOu’Q_“dh^dšjf¡Yx©Wr°[{«b~©_u±Zo£bs°R}¥\n¤\{dp¡m{œhk›km“lhŒlg†bnhf—bb’Sm‰Os†Uv“IpŒJŽ\t–UŽP…ŒNŒRCŽœMˆ–Kƒ @uE”N~Jxƒ9|ˆAwBu…:}{/}‡=Š‚=‹…@†J…~?Œ‚8‘{C“y2Ÿv8¤j0 o.®p7ªl ´w¥d®g&­`(Ÿl3“g4Ÿt9›t1š…7›zJtMyR”nN‹nVzW‰~`ƒpSu]‹{W–€R“‚\‹ud•yX‰ri~c…xdƒonŽxg‹ml”soŸˆ{”†sŒqšz{¢{o’tw¤tj—tv‹qpssƒsp‚uxqqƒrt‚l†|mŒul~‚_ug}c|‡m|gƒ|govirwal…jxŠanzfuzdu‹`s‹^{}b}‹m|‡rŽ†ƒ‘Mt‹Mk†Oj•Te—QyœVu«Z‚¬Qƒ]}¦Zz¢ay¢Zn£\uœ\všgyap•ct¢Z{šf{Ÿov—iqbp–\v’gx”aw‹ZwŠ^pŒMuIq„RpStƒVƒ[zT…—Jz˜D|œ;q2n6uƒ>uEx…O~„I‚ƒ8‰„4x7{BŽpI”oFwG‡jJ‹w>Œ{>–r6™l9¦o(Ÿl4®e6­r/±a$¸d½g²m¨Y$¦[4–],¢iA—{B’xD’wF‘sB•pG›wS}MyT†€L”~J™RŠuMŽuTiVŽkXˆs^Œl_‡ua–tf‰}j•xk€u›†|Žp™‰qŸ„pˆq~m£sx˜‚o¢zt–nl™tgŠyf‡eŠxjˆ€fŽzj“…h€Š\…Šd‰Ž`Œz^|†b‰|c‚jwŒc}†efv‹js‹pu†mv‰r‡l~a€‰jzYH`XJgSVpWUjQ`bV[k_il^fuYpoZis_gvS[lRcbY]iT^rUZiXWqVen^rn`neotgpxaoz_~q`}gYzcV}hU}fa}d^†_bƒXfƒ^s~SvzXqtasob|ubzq]zsVxo\{rY‚we‚lZ{l`yy`{zio{mj}wmsznv‚mq‰iq€izŒir†rzˆup†ur‡‚t‚ƒt~ƒŒ|„ˆr‡•u’w…œ}}‰y}†~z~s‡…r„Šj„€`„€gupjyinpysv€rq{kz‚tsywˆ|Žˆ{„v„‚~}ˆ~ƒŠ‡yŠ€pŽ…x‰x{‹xv}zz~z‚p‚zk~‚^‘|f“x^Œx^…ka†iasSƒwWxpQttPvs]r^zx^}vSsuWxo_vt]wzh{ˆas_y‡[‚XWˆJ‰”LŒY„T‹‰IˆŽFƒŽD†?Ž—:‡‘FŒ‘<„–?}‰MzI‰CA†ŽP}ˆOtƒMf‹NlMr˜ZqŸZv¡YyVyšcs›hp§[u™W}”c€[x“azšZ{•d~˜_s–il“at’^}Š`z‹gz•k|is‚_{€WuT„Pw|Ms‚Z|Rw•NrœIy˜KoJu“9s…Au…’‚K”v:•x:”vAˆoJ…kEyB—v;›f6žm*¢h- k+£v,¥f&·g*°n"µi²h#¥`*Ÿd%¬\+¢\;g<št:r;ŽqIoD‘tAŸ}FšƒF‘‡I‹zIŠxK˜sY‘pW˜ggžs`“tq“wv‹rt‹nf›lŸwi›ƒzœ{qž|u¢ƒ|¢m¢‡u¢…o¢{~²~s°tl£|jšzh™‚pœešzj‚]“x[ž|`“^”Œ^ˆj‰uh…m~]’h’ˆi‡†l‹„k††n‡Œf€|j€‰lŒ`Œ‹k–‚h‹wTV~Q]wQ^uZfzekwafthd|_n„fcwdfoeUv^TtU^kVacQjdOhgbhrgmmloq_ske|`n|fjsqsknremtii‚rsƒxu~hi…dl‡_i‡Yn€V|yX|pSznSzt`~xgrhpwcovdvz[n]„pk{upvqqz|jv€p~„myˆr„Žn}lk“gj…ru‘lr‘uu‹}jŽsˆ‰o‚ˆsŽx|Œj…i‹qŒw†Šlˆ‹i…‚n‚k…‡pƒ€ozvp~vyuuuwywz|ƒ…v‡ƒ’}‡~ƒw„‹px„vx€x‡|y…}}xx€uv‚owŠorzz‚}|ukxp`um\‚kd}le‚~Zs|NqoOvoFs}M~nI|pPzsZr~Vrw]vmWwpRnyXwƒQy‚PwŒW€‰WƒƒT€‡Lr‰EuŒJqMm’RxŠPvRz|R†€K…’E‹“9y˜yŠA“DxŒGs†Fx‘Cm‰BrŒKmKr–Px‰UyŠ[wœdtŸ^u¡[y›T}¢St¢Ov•R{™Sy[€‹a”cƒo~Œg‚’p{ft‰j}`‡aˆ}h~nc‡|i„…b}‡^q‡Y}N€RxˆSrŠPz’Q|C~Eu?{x>yHy~T…ƒT‚S‚„Iƒ?‰r@„w?{J“rIŽzB˜y@™k:”x7”w&l*¨l¢s+¨i*¬e#¯`!®^#¯_1¤^9ªj2Ÿg8¢`A—d<œoA’vI™oF”|?—~H˜‚R‘†M”RtZ‘p\šr]›khnitv‘mtliŽso—qhyqœuvœxr—~|¢x¦ƒ|‹p©yq«xo¥qf­ue£pi¨qq¡tnš‚r„f¡xb£rd›zf¡†bœ„[“…_ˆ{i‘tcŒqf‹|hŽ…e’cˆo{p…~l~zl„c‘‚p’€nˆ|qŒˆrQIY[[a}Zc‰Zl~Zs€`ez`d^l\coZ^yi[nbfifcsQdhLkfSer_htkrvfylcwml|tqxlxko€xf|xgss„€}‡m|qpcu|aysRuxU„qT€nZxqVp[|}ZtoglsXt€a{wh†pwtm~lsttrry~tm~jjŽuu’t|wt†kxƒ~gˆtjwq’i‰{g‡ƒiy~d{…t„Šr‹kŠ„d‹mˆq€j‹‡m…cˆ}q{u|}t‚€w…w€~ƒ}r…{„‹}‚…€{…}…z}oz{py~ˆowƒzwyoxstˆw|xƒwƒ~ttm~v^|ocˆn^tsZtpX}~]ryLrrRwwHmvJ~mMutVj}UopUy|]wkYhxYz~Tt€Wv€OwIz‚Jz~Tv}DpŠDo„Ro‘\l‰Lt‹G}ˆEz{F‹€<„’@‡”A‚7rŒCx‹@wˆNw—Fp‡Pk“IsIrŽQv‘Ps‘PmSqƒ\jŽ`lŽUqPvŸU|žJu¢O‚”Jˆ•OŠ`~ˆc{e‹›i|˜r„iz_q…gyˆ[xƒi|pfŠpiŒvc†ƒl~ƒXt†Sz`‚ƒ\|YqŽTvŒY„Pƒ‚G†w=ˆw@…HyLƒ‚L{…U~O‹yPyN„vJ„T‹wOœDŸs=’n-Ÿz/šo*—j,ªt(Ÿi-¬f'¦k.¡j)°]1«c9ªn:°l6Ÿ^;£[H›jE—o;™eK“tK“nU¡zG H¢N‚LŽsM›r[‘pe”wo•mg˜mršqqžsj™{w›ut•vo£vŸ}z§†ƒ ž‹r¢‚yªƒp¤}w°tc¦€m¨qj§mq¡yk¡Œzª}q |k§wc¦€kž‚f•‚g”yeŠ|iŒwh‹re–yf_‰kŽˆk‘xg…}rŽ€sŒ~nwmŒ…hš…xŠo\X}eO„ja‡jh†lg~do„ao€\gƒ]]‚[Z}eaxdbsljwheqbmhXigZugZptfk|ksrtwuu~qrxu{ysynˆzlˆƒsƒ{y~x~tu€cwzawuV}pS„nS‰zX„x\{w_ux[poaup[v}d}|duws~sskltcpgkzkk†qj‹pvƒp}Šx~|w…xxŽpj’jd—vaŒ|]Œ{f€„^~†b‹b~j”‡dŽ†h“‚l•‚h‹Šm‰ƒcˆ~k{nx||x‚ƒŠ…ƒ‚{Œ}…ƒ|€„y}‡‰†|…zvvysvtooq’wqˆx|…vq}yt†uy{zy„{vqk‡s\|mYnl^mq_wvasxUl|TsyHpqOupHojKsrVyy^oy\ezcio]sq^xtPxvRs}Gy{Mw{Pr„Vg€J^‰WfŠUo“YkŒLn†D~IŒ‡M‡ˆB‚ƒ8}>yCz•Iu—Rn”MfˆNlŒSoˆMj„Ot€Mu|Iw~Pm„PbWh‰SpŽKs•Tt¢YtžLv™S„•T}b~‘b‹–q‡™nˆ–c~g}‚`s€]ruXwaŠxfˆn]„kh‚sf€xj„Š\}^w‡_u‚]|d€†e…†\‹}SŠtE‹nN‰wS…N}‚Tz‹J†ŠM‚S‡OŠ}V”„O•‚S›zE p6–r0u)–t0‘o4œk)¥r%¦p"¨l$žp0žn.¨h0£fB¯mB§lB£aEža@_AŸbB›iPœoZœmT›oM¢zD¥‚CœxQ‘w^–|i›tlwr˜pnst™j~n”}sœ~}•‰‚šˆ˜‹¥Šƒ¢Žy¡„}£y§‰m¢ƒn§{g¨g¥xo¨‡n¨„v¤‡m¦€n¡m«ƒa¢‚kŸzg’wk–n`‘rX›q_¤v[›gž~l—}jœ„w~rwmsl‹s“{r„v—ƒv^T}kS…qU}qbz^a‹[j„dp†hk†ae…[\}cathrvohnfmkbnoghq]qkipwmvxjz}fyyry€y|ƒxv€y}~„}z~z}|wytoƒxe‚yd„{c…{\‚v\„{c‡}ayx[xpZmxkvya{b}oyznx~krlpqwqnm€nvss€wyx{”nvŽt{ws•eiŒgg†to‘xo„zf‡€e‹ƒjƒv_“‰^ˆ~c‰l‘ŒfƒŠn‘iˆƒcyb„yo{†t|xƒ‰}~Šy‹ˆ‚|u‡†{Ž{ƒ†z‰}pr{‹pyurvuˆm~ˆw}ztt€}qpi„|kzro‚dg~ijtoWgq_fpPp|WxyNn„Nq~LhyOihDooKukVjoXou\jn[j{Tq{IytFj|RnuLyvI|{Pr~EfuQ]ƒQZ‡Kf„Hl~To…N‰€Ay‚G€ˆMy†HpEx–Ip‰LxQm’Um“Om“Xb~IqHn†RrtHsRo„Qh„PvŽWo‘To˜MyŸKr‘Oz‘X‡ZbŠ”gŽžd‰’h€œmˆ’g…†d|v[ƒb…tetiƒ{f†miws`}ƒVƒ„Q„„]x‚j~fy‚\ˆ[‚„Z„L‡tD‰}R…s\{{M|yP†N†‰K†ˆO‘‚G†~RˆƒQ”}H F™oA‘y;l-Ÿu*—t&Ÿt&©h&±s)¤y%¢z'£v.«a6¡m4°aH¦m>œb<žeB•h9£nJ£kSšlOœrP›tDžtKœL–~P”~[—xi•€fŒpkŒ|fžrxi‘~o•o¥uŸƒ„”‹‡¤‡†­ˆ¢†‹«~‚£‚t£Œs«‡n£rf¡j™vi¢‚o¯|g©|p¬ƒ`¤‡`¥Š` uk§tpŸ{i¡h\–ih¨s[©{c¥wn¢xqzvwgŒ‡mŽ€r“tp“ƒh˜…xŽ}w“zvm`ƒl^Šj^gY`fƒclƒbk~ehˆf_Žce‚ee|qt{jl{mrkaxgdlpantkwx^xz`|aˆl„‡h‰pu}|~‡~„…u}ƒw†{x…‚qykk†tdƒ{b~toŠrkˆub~ld~s\z}Zrvftl‚xi€|rƒyivvyszyr{yykuzos}zzp}k„jsŒkn‘in”pjfm‘qm{uˆzk‡xwŠ|q†zjŽ‡aŠ…f^…m‚˜s’q…„i‰€i€{kq~j‚jr„{y{}}‚‚†|…Šwzxx€{z~}{s‚psnoƒpu~|n}{g{qexkmzwnsthkyidqhefsXe|QpuVu}UvƒNl‚JfySkmKkpKnp[ryVt{\rwNtvJo€Gh{Jj|OtnM}xFxtBkvNbwKhwN_†JiMiqWz{I‚w>t˜h?”fHŸeD˜q>œsIžtI¦pG›zNšzRœwb–d˜€Z“y`re“urv–†mŸ„pŸ€v˜x}˜|~¤Œ‹§ŒŽ¬†¦ˆ„©}€ž}w¢ƒz£zt¥‡{š…p¨ym§~b €j¨‚a«„[©dª|nsj x]£s[¤wY¤id¬wp¨tm¥lo˜ls“mq“g™~q’€pˆu˜ƒt•v~˜x|cS}g`~scjV‹mZŒkc~bd„lp„ld‚imwlonmvrss‚vd}piqspxr`‰~d…_‡Œ[€gƒ’j‹‚m{ˆq}€n‘‹m‰†q~|yrs}n}|f}soƒwn‰uguoƒlh„uj…tb„k_vyb|ui}xlzyftvm}tw}qlvfyyyy{sux|Šh‚fw‹uv’sm‡mo’rl‰lo–ym”s‘|p’zw•€c„\‰cŽŽb‰‹hƒ‘gˆ•uƒk{n€ƒcryo}w_~}iwwt€~wz~}{…‚{ˆ‚ƒŒ~t|{}~w€vr†ro†oo{vx~wevpgrtqephdimkgotfrvjixYdXrVq]e†Ll„OpRnvDlmKqv]uoSvyYxxOpyPq|VdqGpsKnkSo{Srv=ouA`rFgFgwWetLhiLloS|~A~~;q€Iu‹CoŒAo†CwCv†Cd”EkŒIrˆXp„Mk‚Ru{QtˆTz†Pv„J€~Mv~OƒSySˆV‘\„T‹SŒ^’Y‘Ž_”–b’†g†€cf…qe‘{jss€{b{nˆpdxukszWx~_uƒd{{d~}ezzb„t^…v\‡xUzrMˆoJxwM…V~rMtK‰xSxE”sMp@ŽmD–lHsCœ}Kœu@žwA¢t1¢x5±m(¶s-·i:¯g1§u4§q4§j:¢`?­hI§gF¤mB jCžfB›oAŸfE”qM¢tN›|F¨~P¢wU¡|W“xY”€c•€[•‚]†o–€w‘k„r™y’ƒszv–„s˜~‰¤‚Ÿ‚€¥†ƒ£ztª|}¦{v Œn˜ƒqš~c ƒ[ª‰Y¦ƒi¤}i©‰c¯tp¤ro®€^²€]®}]§ijni¡kk¤jn£nq•}mŸƒhž‚qŸwh ‡q—}w•‚–z‡lSƒmZ€oZ~oZ…kVƒm^‰ujˆri‚um‚yjzym€xrzn}|o€ul„rrƒ{n~|_‰}Yƒ}aŠŒjb”d‹Ži…‰b…loˆ~t…q‚tswvxywn}‚v|x~tw„np‰loˆmg„ndŠphƒjjƒl_|wc…sd|dysf}sh}psxmqo{xtsyh|†lƒ‰rv€„mx‰qq“tm“€p‚k–€l–xl–€h“ƒc‰_•ˆ^‘‘l‹l†‡rˆnƒ†g~h|hsˆbtfw…ps~~r}ƒv„ˆ……z“„xŒwv‰‚qƒ~z~}sƒ}iqc‡ti‚mtƒporeiyjcnsnjnrplwmgs_j~ej€^_‚Wc€\`ŠRi„Qj}Lt~KqzStzPk~LowVvq\ryTk}VasPeoYdwSguSe|Hf~E^vM_tM]pTkiQqpOmlRutFps<{x=}„AvŠG~“Eu’Ir‡?kˆBp‡F{N~…GxˆOu†Iu†SsˆW‚~I|€D…ˆC|Q‡P‚`Žb‘Œf‰ˆ`„dŽ]˜ˆeŠe}hŠxgŠye“toŠuvˆlrŒnjseyt_|niydxzbwyj‚|m{}e|qhuxfvp[th_€oR{rPymV€tP‚uQ|{T„vS•|T”uEžzE™n>’yG–vHsM•nC£o:£p8°n>±y6¬r>°p4¬u:¢h<©l8¤e2©c?«f<¥^E¦gD¬lD¤h;§p:™iD”mA–zJ ‚N›{K sRyX˜}XŒYa“‡c‘‚g–ˆt‘k‹lŒ‡l‘Šy‹ww’Š†š……’ƒ…™…„ª„}©€v…|›r•‘q l¨„aŸˆbš‡j…b¬…^ª„f¥}b©{j­xm³€j©vl©v`¡j[ n[šh[mh™|h¦}mªxqŸ}n§yj¥zt§z|ž}€lW‚gN…pTŒjctd€n_glgg‹kr‹xnˆlxvxsw{uzh…€k~‚a‰‚k†g‡Žq‘‰l†“j}˜b€†h~‘q…i‘w~€l‚xz…‚tvyswtm‡~xŠu~{kw|qu…nk{zcxmr‚mk„lnzfswmcidrsdzsq{{vvnrsoulpt{qs~n€i|}uu~qƒks†{{e•‡g‘…n‘|cš‡k‘h“ŒfŠ‹]Œƒb†‹w‚lˆŽrˆŠp|Œ_‡|clx‡iq…hƒtzuƒˆƒˆ~„•‚t—nt’vqzv{~o‡wj†yr|mdwdtylmbilbiteinjsnpr^fmeivai}S[x[`ˆSg~^_zNlqZi}KjP~qDk{Kp|^evRk{PdMbwPexOfqPgpJh|?^w@[qHcwR[oMbqMlnSnzNi~?o|CxzLnvExzRn‚DsEi‚Me}Mp€E|ŠIu…JvRvƒTp„Sr{TzG|‡N}J}O~‚Nˆ~T’{iŒ‹W…‚a’„Xˆƒ_”~g‹ˆl_‰}_“mrve“grjoŠnh}ro~{f}lbp_o{U{ob‹sj„sa~k]€s^zia‡s\‚eQ†uO~rJŒqImCŠsQ|lKsNšoF—kO p<pA•{BtAŸo= hF¡j4¡p1«s*«p:°k?¬h4³d;¥e@›i0¦f/§d>¦e7¬iC¨b:§iG£nEŸiB£kF˜@•{B¥qV£zN£~TštW”ˆW•‚_›|a †t‘q–€{„~˜ƒy•„Š…rˆvqšˆ‚š~{‘‡ƒ¦u¤ƒvŸ{€Ÿ‡m¢€i•ˆe¥Š^›€m£g¡‰a•{g§‚m¦€a¥vl­vq£ta¥|h³v[°}Yªq^¡qi¡ej¦ma™nc«yeŸqg£v˜rq™p}£{€v†kOeQ’oVje„sg}qhtf‚lr‰jthxˆhwnw{x€r†zuˆg†„i„f†ˆf‰ƒqˆˆrˆŽm{Žpx•p€Žs‘pˆ‹{~ty€t|‡x‰€Šwp‡o|ƒnv†mwxjmvtg~vn}vo~wnrj‹gujvƒeuvhzv{qyuk€xtvyltuqu}rxx„jw†gv|fxˆsz…uq…vwƒq˜|bšƒ^–Žk—Œo˜Žk—”aƒeŽi‡‚pŠ‘qˆ‘k‚ƒgŽ‹dˆˆqƒ‰pyo~Œn‚{mŒ}‚“„v™yz™s€tu“xz”|yƒ{o€km‰okwfeurmsrltlgk_npdkx^woivcqv\dwRaqWXR]‚V[tRaqV_s\krYiyUvvIzmUpqWmoVfwG]rJYyV`~Z`vPkt?ms?`z>]zF^hG_cKfgU^{XdwTjvHd~UozTzvQwyT€zVxƒOx}NpXm€Zx…O€yR|wNsyRtwVvMy„H}ˆB€ƒMqtKquM}…Sˆƒ`~S„ˆT„‹O‰‚U„wbthƒlo‰peŽjf‘il’j^‹u`‡na‡wm}nn{tazl^vrU…pX‚rZrnbsvc~w]€l^dW‹eTˆoHŠrG”xI‘uDˆoI…iJbP’jW“bMšfF˜kNšuIŸv@˜q;™c9œe?¬]/®d-®h4¶i=¾g4µo8°l9žh7®k;®a6£i7¡d6žk7fC—pCŸmM—mCŸtD¨mR eQ§lR§vZ¯pb¥u]¥~e™xb“|qƒz¦z{¤uƒžz‹z‚wv{w‹{€‚¡¤€s¥w£{}¢Šw›e¡‹cŸ€a©Šc¬…l}hœ~o˜woœzdªrl¯nj¦y^žxa±zf³w]§jlœlo¦qt¡okžtf¤hmjo¢tw qwt{’zŽ{}mXŽnY”fXifrh‡mo„ft†or„ft‹`zi~‰mozsyˆdwŒp‚}r„}j†„e‚}j}Šz€uuŽxrˆlt—t}œp“dˆŽry†hw~mu‚|‡xsˆqm~jvˆjq‚wxhstpjquexpuƒvoŒpw‰pzkq€m~{pqvurz}wsrr|{sly|jw}pyxlvƒrz€u~vvŒmˆvy‚†u–ˆi“~`‰hš“fš‘g—k™‹fœfŽ’oŒf–o„‚gˆgŒh‘uƒ‘|ƒƒ{~‡ƒ‘~{œƒqš€y—zxmn•pr‘l~Œml€nj~^fw`pqerzitl`ojktlf|z_xxiwjqck|gk‚\]~^f|WjƒVf[fuaryXm~Mx}UqxTf|QdoRYrE[yM_{NXuUk|DkxHtmH_uJhFelVigTZrPQ~KY‚Mj{LauPlVysRtItrWluVo€Ovx`r|MxƒS‚IzzU†xZ„|Xt[{…TvN~†RtpXyzX~rNw€Q|…VŠvZŠ}ZsbƒmZˆi]„rWyxU†uiŠoaŒri‡t]v[„nq„~l|l_}{^~^{rPˆ}R€pOzu]}kY{nP‰nW]O–cSŽeE‰vMŠsM”kDŒjIŠjLcWŸgR¥iO¢cH§l<£d9œf2©n4¬q9«b6­n7¯g7¸i<¶lAµo9²a4£c:¥_/¨]@¢a=¯[:¦b4eAŸbJ¢_K¨gN«nG£fJ¦fY«qV¯mN¨u`«h\¥kd¥p`ª~w¡w‚¢w‚tˆ£s€ ~zzš||’xx–y€žz‚ž}x£€ž„s Œ} Œi§i~`yl¥Šn¤ym¦xmšsdžmd©pe­mm£u]gb¤ig²xi«vj›lj§erŸlk¤rqœqz wq¨x›s|–w|—„wŒ€‚_c˜eaŸv`˜u]”gjœie˜usoxŠg‚d‰n}ˆlr‡aoŠfvŽh…oŒ†sŒƒk}gxƒr|…w}„tt‡n‚”q€šrt”ex‰h|…m€„k„ysy}o~‰px…vs‰pvƒxlrsoqll~ug{qm|po‹h{Šqxtszj{tm{wrnvnsxwrqyrr~pxwy{vq€{w|wvŠvrŠos‰|v‡ƒy˜l™‰a˜•^Œ^˜`”Œg•’\š‰[£‘c ”nœg–m”‘m†˜nˆy‡‡|Ž}‚‹x{™rœ„t |rŸwtšrv”f|Šks‰lq„gs|`w‚dn|mrwersljvequd}|czvpukmk`|]d†]`|]azYc„cjbmsfru[u€NqOgIgvQZzP[yIWoK[uMYwKdwBoxEjoKbpMcwVhrOakQ[oMTvK^yJ\Rk}TpsLtzK}qMruPowLfq\k{ZxvXz€T}wTyL‚~O‡}Y|ƒS‚yZz^~|Ty|PvoTulLrrMrmYuZh^k]vlb~nY„iPzqTŠtYˆla|kXj_„njzvcwxd~s\‡qWˆzZ‰~Nˆ{O†|M|tQ…oTiL†`G‘aKŽ_M”iBšdI”pG™eR•]U˜ZX’]X‘\Už[J¥[I¤g:¦f0©b-¢f,ªm5°j5°s7»v-µk4¶j9¬b:§_:¨Y0ªd>£e;­h4¯`2¯d;§Y8ŸYB§bI²bU±lT©mZ¬cO§iR²cS¨__¯j`µtg­po¦x~¢rœn„›z„£~„¡v|—}“}z–us’y{ž€vŸwy£‚r£„zªˆx®‚x¦‡q©ƒb ‚b¡o§uw¤os¦jd¤mf¢tf¦ll¦dc«e^´l`«re¬ri«`eªbb `mšoršnw›hr¤pvœ€}”~y|s€}gdŸr]¨mhšr\›q_š`j‹qo“hz†ip’ntmolo‡hu‚q{ˆu„x‡Ždˆm‡q€gŠ€m„}vŽuw”mšfƒ›l„‡aƒc~ynw…hy~nz{ts‚ou‚ssŠsq~nvvyq|nawnkzjk‘duŽqx€itycqubvxiwvxvwqqwwk{xqy|vxqyjx€o…ƒr‹opŠli‹qo“qšŠgŽ‰j”‹V’‹^š‰Y˜Š_™‰`^–aœ‘f™”k––h‹ŸsŠ§l…o“ˆ|ƒ‡{z™u”}–qsšz| h‘lpb€gx‡a}}hvynp~_wokzjemtgl€c}nnqhp}fk€nd€di‹kb€gd€Xn|gr|gjqbwz`t€Nh~KgxI_oJhpPYuUVzOasSWjN_u?jsMjqIhjJgkRYiQdvN]nHUvLYM]vJ_|ThmSmnJ}lHyxHmvJz~St|Y}~NƒzUsxN}vS{W„sV|tS‚rYwnY}t\yf]~v^ygUn]~ocxndzqf‚cdƒkc…iUxr[vqX{aalbgdm\‚{auvp|u^tja€zQˆrSŠ}S„|LŠxEmU‰jV€_Nƒ^T‹YQ]H•h@”m>qF•_H‹iJWUŽXP_FžTJŸ[B¥oF«e7 a1¦^5¬b-°c,¹d8³j0¬b-°Z7¨X+¤S'§_,ªU.«W9°[2¶Y1§`7°^0®]=œiCªeS¯bG¥eL¢eP¯bQ«nV²nU­l]£qa©diŸe{¤kt¢v}œo€ u€šu{˜y|t|•uƒ•w~—usžpx¥s{žw{›†{¤wiª…l¤„a sp©€p­vv­ez©nl©pi¢j`£de£bl®`e§pm®ah¯hp¥]l«\yždr™^~žcz§fz©ct–yvœ~}yt’v„ma­v`¡k_§oa£hnhndzot’ov—rtvl‘hrˆh‚‡s‚‰oŽˆrŒo„“h†”f‚—g‹‰hŠŽt•j…•j|a}“g–d|fx|j|_~„ixrrytwuuqq€nlztesliskmwmhŒnp‹`}…hƒdqlv€gr|nwx{~pnzrlo~rz€jvsm„rg„‚kˆw~qo‹{i’wr—{o“Ž]—Œ[˜‹c“Š^›‘^’•f”˜g••j ‘sŸšo’“mš¢s”¤zŽ“q“p•›xŒ™tŠ¡z~uœrv›kr–fwže}“`ƒg}…_ŠesŠft}dumtrpr}huyp}piyegxmp„jl|qc€gfvda}[bw]qnctndoYqt`kmVnmUfuIc{FbqP]oPbnI`iK[cH]hTmmTccOafG^mNZzJdtP^vNdUcyNa~IdsKyvP}xT}uP|}PuzOsUQ~SyYvySs|\wr^qo^{o^tmX|f`„d_€k`zie„me{bg€eg|f\_^‡k[„fbƒeicdjn|fkwkk|ujupnpwnwk`vi_}eQ~qR~S€}P‹uLŠjH‚_X„dZ‹iS‘_O‡]G‰fM‘jQeC_DŽeJˆZI[HœaO™^DšjD§iB¤n?¦c/ª_1£U+¯`2²^/®Z/²b(¹T(®Q,·X(¯_&§\*¥T'·V)ºU.·Z)®a1¨d> iE kP§cK°fL§eF§eG®nWµh^ªid®gi¦bi©kp¨nx«wƒ£q‚ sŸv¡sq–ls•hw•q…¢kx£qs¢zw•{v—‚syfŸ|k¢yfž~e¦rk®otªho¨bqžci¤`d¨\c°cn¦hr¢mc®ae¨hs¯`}´Z€¬X~­_}¡i¨`¬cv¥jx“p{”pw˜s€ie h^Ÿim¨io¤ukœm~“v€”yy{r™voŽum˜ar‰p}˜hu–v‚{Ž‘uŠ—oˆ_‡’b’”`•iŽo‘o}Ÿd€”cƒh€‚_uƒerˆ_{…^s|qw~ov|go~cnzgjqslyirzroƒqlŠ]}‹bv‡ao…joyju`x‚esum„jt†oƒ†`wwlvn‹‚ok…†{}yt‡x‘usŒ…n‹‡fƒW•†[ŸŠf¢Šb¡”f”bœŽi˜•r—‘yš‘m›˜z©y‘¥|Ž£p–•}…›}§s}œv{›wr—kžh‡›jŒ’m‚—[Š^€‰gy‚bw‡h€|mzxs}zjvyh{fb†lq~dsz`rzeqzcon\orfoifeuV`kdp~`en]ewakx\\rWcnWbdN]gJeeRhcNfcWicLefNgsWapSYkQUrIdySfqTexUkk]mtTdwKmnKnvLyzIk}MztHs‡T|~Kt‰RqŠQn‚Sx{_l{a|mR€pW}lZƒX`ˆha‚a[ylf…d_`av\avY_ƒcZ‰X`~Za{[h‡_fiarnfyugvlb~wjnnitq_|d\~m_xnU~sZ{QˆjF“tPlV‚kW‹fO—dQ—_V‹fQ˜bJcIŠ]Gœ]N”WT‘^Fž_EŸ`D–f@¨i;¦fA Z:­W5¨W4¨P'´Q*ªX$²Q/¶R*¬V °Q*¸\*¶]­V#¸V(»K2¾^6·d8³_;«]:§\?§`J¶kP·jD¨mZ©vR¥o[§ob¯jh¨boªdl¹ey²op¢k}£jy zu¡nr—tz›v~›zŠ˜s†§s}“ju˜sz wg¤xqœvežvqžqo¨hmžfh§el¥pf©`f¡Ye¨\l¯ho¢gl°ku¬dr©ar²a†°Y¤\‡¢f‚¦f~b„­bˆ¤h r~¡n€Ÿohh¯kbªwm¡rvŸz€£t†—p€”v‚“v„ wz›rv—ju’c}’mt›q~t~•rhŽaŒ‹d_‘a•‰o–”k“s‚‹mŽc{Œe{‰kval…dsyfqwmw}cr}dh{dmxlp‚ni„st}ht€]v†ax†bwƒayhr|bt|a|‚myƒb|ƒb†ŠdŠŒi†…fŒ‹q†rƒo…qzzv~jŽj‚fŽyd”~c§}]«k§…h—…m”Žl—’n¡Œuž—|–šs›£p‘Ÿu˜¢|‹¥r©n‰Ÿo‹¡oz¨nz¤rŠ£hˆ›iŽšj‹–h‹Œ`€Œb~d††g}~o|xwmmzkgƒokop}lgw`esdqpbot\on`ir_bkZilTbv_f€Z_yaho]_vTbeOYdX[dYggSalQkdTjiW]iT[tKdsPYnO^uVep\fyUqk[qj]zl\rqMpfIokMvmPkvQp{Vy€I~ŒUw‰Zo\o\i\qyT}lVwhX„bfƒZc|Y_‚`f„ikzfarf\xXdyQ[[`„Vdƒ_d†dc…_cubovgklnksserxfynjvm\vh_j[|nZ…kQ„jNeG“pP“oJcOŒjWaVšcPš`M—TK—YT›YQšSQ˜QS›]Kš[FœfO¤fM›[D¨bH§[>±N@¬P1´V7­J-¬V-±Q(½R,»R¸Q²Q$¶R!¹Y%¼U1·O1¹Q7¹X;¸^?®_5­i5´dC·kMµbM°gX©p]¯o_°oa·nb´jq¯iy¹hs³n{±cs®jmªrt¦yq£ru¦uˆŸrŠžmŠ›i{—wt–utxt ol•ni›skœgg™go¢nb¡oa i\¥bg¢Wa§[d©ae¨fh¥av±^w¯X‡¶V‡©X§ZŠ [€¨b€«k‹ fŠœhƒ¢v‚¦yƒ˜x„sg¤gl­vlœrq¨{t–pvnz–y~–nœv}p{–`q‘h}™o™wuŸuyœl˜m”˜h•h‘˜d™Ža†o‹šu–ŸsŽ™f{•jx‹qy‰ku‰lw‚itdl~anxdvƒcq~jstnwdikuxeyvjtfxybx†]}†ft‹]ugy‘fpu‚Œp‰“tŒŽq†p„ˆjŒŠo‰ˆpŒ‚d‰lŠ„f…„mf‡c”ˆh£}f¤’b ‹g¦‡q¥—f¥—w•r›ž|—›x§¨w ¢s˜›l™¤sŠ¬o‹§s’§q‰Ÿg‚ªoˆa‡¥`‰˜_‹—^Ž–Z‰‰eŠˆl‡€k{†ksg{w_€ma…xZ„iaom\xi\wjdofaw_qzcfqmio`jsifthajmWwc]rajyTgoOl\Wb_TbsLfaUaeUYaXYePUf\YnQXiWSqUZlPamTpm`qf]ueYrfLiuLltPvkVuwKntMz{Ev‚QzOk†Sj|To]wwO}oU{eV‚X`|aczZ\ck…acxa[wae€c[€\WxNXƒ__^p†dbed[j{hnstnzxl„gb|igig{dZ…cc‚kRŠbVgIƒoM•n]ŽlY†lO`RŠ[Z’\T–aVŸcX™_TVX ]M§]W¤_T—fJžhM™gIŸ\C«XD§N>«X:ªG,«C1¡R)©T,§R&°O(¹K+ºS%±G½O ¬M'­N2µM2ºN5½T@°R=¬b2¬ZB³^<»ZG½fM±aY­mU°]f®ed±ik­ge²pjÀohºesµ]u¶_|¹s~¤dr¡l€švx¡jŠ›gŠmv•j{˜nvœoy¢oo¤gr¦mk©mtž]r­gq¯b`¦b\±Th§]l³\m°Uq±Vg©Vk®Yy©S€¥Z‚¨Q®X‰¢^‰¤YŠ˜k†i‹›sže€›{†¢pŠhg°ll¦rq§vz¥ww§tw˜uq”uziqˆiqkw¡gv¡my¤k|¤v{¡zk‡œd—cfœ”j“•iˆ˜h•¢ro„“o‚n|†lwŒl€‰kƒzfvƒdr}hoouwl}|h‚sgt|ipyaqvZw}fy…l}}r‚|j|}f‚Ž\y^x‘or’{x™u~—n…Šx—†uq–e…‘h‡Œg‰’f””i˜Œc”Œjž‹i €d¤ˆhªŒe®‹c­Žm°›m¦™l›œr›˜uš¢u¡§f“©c‘¤kŽžt‹¤rŽžo‘¨i•§m‡ p†§j jŽšY‰c”ˆcŒd†dˆcˆ„g~}i…~_‚~UƒyWynbuibnj_hkYnmaxrkwosrtlnnqiermkbvi_nehplmlbnm^nePpnXioRgfQaeVaa\UkQXkZZd\Vf^VfTYmRejYew_srWkrU`kObkUmkSsgMzjPtwQ~wQz{MrQvv[ryZysMtnOu]T]]rZ`sbQzgV^a~V]ƒZ\ˆaf‚]^zO\yP\[_~`k‡\e‹Y]‚\Ztghyrdlcy^h‚`\„a]xqa|dW‰aV’jYgN“mP‰h[pOgNVQŽU[Š^MŽbO•^O›d_¢Z_¡`W¥VK¦XKžZHžaH¡^G¬]DªW=¡QFªQ@¡C2¤C.¢R*«Q(®V#µN,²K0°C&¹D ±@)®I6ºG1¹D=®@E´HCªV:ªX9¶O8²OE·RC¹^P¹^J´YO»dW·^k·_g·lb¿inºji¼luÀ^|µaƒ·f~±]u¤d{¦c„¦q† a€˜b}•bx•o{“iz™ls¥kk¨qi¥og«`o¥Tf°WfµOb®Ua¸Sbµ[l¶[xªQv®Rs Qq¨Uv¤Xt©azµ^ˆ®^„žV‚›h‰–j‹˜fŽ£dˆ¤q‰¡yqe«is¦oh°~r²rxªst™wy–w…vqœwpšvp™kv›sƒªi‡ n€¡}ˆn†e‘m˜g’œe^‰Žk’”gŒ¢m„›d“^zf‚Œp€kx}at€`vis~s}ym{prhrl}w_‚€\|z\xj‹l|ylx…hyŠ`zŽ\{™dz‘s†”j’v‡‰{˜‹oˆy…p~›iŽ•i‘]Ž_’˜d’‘_”…eŸƒp­Œd¦ˆb³‰a¥Œ`¦ a­¢q §pžšhŸ­g©k£j¦d‹œx•¢qˆŸi”¢f”©mŠ¨d‰š_‡–d‹SŠP„]Tƒƒf‚}X‡ƒ\|†`†€]€yS{yQwnWvg_bsUeoZjobjmfk{gwofizldhkshpmr_slcrhhvmpi`liTmjL^nO_eQc_TTdSY]Y`]^QlXOh[VgYbaUfpUacJsoVinH[ePneEelOmgH}gDreLrfXwrYwQl}R}z^rs]|vRvh^xkVu[PjaPyWW„T^ƒOaˆU]~T^ŒO`ŠR[‡Vc}ZhŒ\i…[b‰Na‚^hƒZqvZbx^hƒ^W‰j^~gXƒb`„i^€a]ŽkUn]gUŽlYm\_O›bT O\’RU—_[™^RiV™]Y¢iZ¢\K¦SC¥SN¥\P«eHªZH¥\H QP›JB¤FB R/¢L1¦V/´^"ªN%¬U(»J+µA/²K3°L<´L1·K@¾EG¸OC»T?®W<®J8²N>¶QG´UH²IU²R[²S[¿ah¾Zn·lcÁoaÃkfÂ]r·[ÁWyÂf…¶ct¦k‚®o}£fŠ£gz¥h„¨hƒj€¡qrœps¢gk oh®cl¹jn®ao­Zf²Qg³^p³_k¹^p°Wm¨Kv®I{©PwªVo¤_q§[u¬X} \„¥Sy¤f„•l…œb‰—_ƒ›h t‘ds¦mq©kq²ym­~o¥z}¦z…¨w‚ž}s©}t§~y¡ot¢h~›rˆ£n‡¬n£u‹¢j‰’a–‹]””\”Z“’]‘—h›h†Ž\‹]’bˆm‚“g}†bŠdt‚g}…qƒzh€tl‰zl‚uj…xb‚r]~{a†}_‰`‚‰dƒˆg^~—g†h|šo€g’’h—t””t”oˆ™u…¡n‹žfŸ[‹—^‡ˆ[’‰[ ~c ƒa¬‚i±^­—^©›_±œd¯¡i®¤]«ªhª«eŸ¬`¤¥d—žf’™j¤d’§k“¥\™¥\¥\”˜SŽšZ†•V‡‰MŠŠNƒ…S€[„‹N„R~ˆXƒ€Uz‚NwRorOjyRdpM`tM`yMi}XpxSk{^g{nlvponhqweqrmwtmrntn^qvZmkNcfS[_HWcNVdZ^^[[^\RgMTiTWfOXaPViRekUbkGlr¸RC±IG³M<§KD¬@D®=E³FM·HP¹Ja¾Pb½[e¾XjÇfoÑ\rÊ_jÉWrºRz¿Z~¿Z|¶`y®f|«b‚®g‡²dˆ³i}±_‡¤e€¢r€žmvml¥jn²fkµdnµak´Ov¿Tw¼]r¶Up¶^p¯]g­Vm®Qo£G{°H€¬Ux®S€°Q{¡]t ]|]‹›_‰”f€’`ƒœn†™r‹kq°cq²lk²pw¥npªvq­zsŸs{œo}©m¯wn dƒ§r¤rƒªnˆ¤q—kˆ¤l„Ÿ_Ž™aŠX“žT’cŒ“q¥b’œV‚˜`„›\z^}’jƒ“awƒZtjƒ}oˆ†^}uh€uiŒ†d€b|yW€Wx‡Q‚„b‘`ˆ‹az‹g‹‘^ƒš_‡hŒ¡d‡ mŽ•{‹™{ˆ”j…£iŠ§n› bŒ¡j‹‘e—c–ša ‘cœŒa¤”f¸l±’_ª•X·˜^¸¥]®¨`©¥aŸ¢_Ÿ°g¥Y¡­f”¤a–¨XŽ¢W’¨b„¬YŽžY‡ Y˜›]‘—_‰”[‡‡[ƒ‹Q‚„TˆŒR‡ŒRq‹ZsKoŒIjJomLlnUlvShrMgnYbu_j‚T^yYachygjjalm`mflsmkobll]qhVppXjlNgbPO]\VaVRcaLfU[sTWkRcgRVoXYeJanTecDafDlnMjiCmg@l^OgeTofYqeZkiXnbQsl]tkUniTrs[qkVxgXuXUvbR†]`ŒSd}V`uT[‚U`XqXmXq„U^‡\eŒUkUj‡Re‘Z\†\d…Xg~eTdF‡_S}YVˆWP‚R^ˆRb“X_”^_šbS‘\`—Y`¢`[šKcšYW£[R c\‹ZS•_VŸbJ§RG­OH®MI±ZF¤UB¶SJ®[F­GB­JM HB¬DC¸H5§H>¢O;§U1¶K4°O-¶N5¹@5¿H9¾IHÈJ=¼@C¾D=¹K=ÀB>½G<¸HD¯MA¹LG¯PQ®@[ÀPb¼]eºTfÏa`ÆXcÂ^k¹_rÇJpµY}¾S‚¸]v´Z{´g|´]Œ¹e€¼_~´[ˆ°lŒ°j…¢m} f}®Yz³[m±]x¹Xv´Mu­Vn²Ww¼Ws³Ws°Ss®Uy±UvM„ J…¸[‚¯S{¸O‚¥]w¬f}¤^Ž•^‡ Uƒ¡e~–hŽ«i“ju©fh±mtªf{¤lm©km©el¬m|¦s|¢uq«hy¢c‚ªi†¥eŠ«g“®m–¥jŽœh‡£`‡®U‘¨O“ŸW–gœ˜j—¤`Œª[ƒ¤dž]}Ÿ\‡—g‰‘`‚ŒZwb…ƒ_‚„W…y_„~[~ƒX|‡RƒŠ]z€W{…SŠ[~ŠY{”]}”b‰‰b‹Ž`’Y|c„£u„¢wŽ˜xŽ r“ j›¥a›¡fžžo›“p©˜l¦™p¤•b£—`¥”h­Že°˜`µ—T¹¢Y¶©b°¡e ¨d®Ÿb®¢d¢§U›ªO££X ¨Uš¢QŠ©_†¡`ˆ¢Y˜W‘“^‰ŒVŒU…ƒYƒ]ŠV‹•R†‰Kp„LpŽRp‡Qv…JoxQu~WjxSt|LoqSp}\_€Sg‡[_‚]Ypg^ohWpjajn_nmjco`[kdafkTifU^_VV[ZY\\Q\bZfVSmVVqV_jW^nUcgO`eTldJp`FbiSffIksFfoIk_Zn_biaXs]YtZ[ud[|mVkfKk^Qs`Tm\_tYW€\\€^Y…Pb„MfvJZuRa|Th„Hf„Mm‰Zg~YcxX`‚\iYcR\‡Xab]‡eT†_KWN‰^P‰U^ŠNZˆK]”XY˜]_—VZžWi \fŸM[£L`ŸX[¨ZT™dW–^SžWQ RSžLI¨IMªIQ¯IG°US°WP¯GI°FE£=EŸ>H­FAµA0«B2¥H8²U;±Q3ÀW@¿LA¼VC¼QI¼F;ÅA>Å=C»?B¸DF½>IÉJBÃGIÂAK¸GK·?]´F]»I\¼NiÈSlÆKaºMh¼YgÆZiÄQw¸L‚´Q}·VxÀX{®c«]ˆµ[†»W†À]†³c‡°b³ez®`u«W{®QªJv¦Jr®Co¬Gm«XxµX²Z~ºPx·Ry¯SužD¨Kz³T„½O¹J~³^ƒ­`† X‹›W•ŸR†ŸZ†¢]Œ¬b–et¨ev§_}¡\}©cxŸhj´ps¬nx£r{­s{³fy³c„¨\Œ¯g“¥d…¯k’ª`¯_°_“«U›¶O•¡U›­WŸ£k”œbŒœZ‡œc¨fŠ¤[~n†‹XŒŽa…”a…‰]’‹\…†i‹ƒbˆ„^~Z…ŠTŠŒ_}‰[…ŽQŠXˆ•e‹g„Žc˜c‚œaŽ eŽŸm r¢k‘¡jž›`—©ežžkšm› m«¢o¤‘iª•j­”f¡’n§›e±–c´Ÿe¬¢\´²Vª¦Q³§\¨ W©©P¨©R¦®Uª­R¥°OœL¥QžUšWŽŸ\”’SŠ–Uƒ‹W~ˆZŠ‰MZ…ŠN‚ŒSo’Sw’Sn‹ClŠPo€MdxYhtSpuR_~W_ƒf^‰W]‹be^_~mYqi^r_hwekitnhike^nbdbgn`]bcTacbV[XYk`^kcaeV\kSZ]_X`Y_]LggMmeIj_KjqRgoMbeIq_OjgWt\PnaXq^WtUYx[Uw[SocRpVOqPOsOSsZ\tZU}SY|T[†U[yISwP\TeuJlzFm|Gk‚SgyZg{a[\\„Zb‰Uai`…^TŠ]U‚`LŠOTƒU[ŽVb‹[X”S`–Q`¡JeªPb©Z_§I\®IX¢PVœYU¥RU˜QS§ZY£TO¬KF¨SU¨ES¶PI±WH¯QV¬KR²BC±DN¢C@©?;­J5©I7³A7©S8³O7ºJCÁK9¿K@ÃNGÃQD¹IB¸?F¶EBÆHR»;P¸GM½DBÇAB²AN¾AN¯K]¿CYÂE[ÌIkÑDf¼J`ÆOcÃUjÈUw½Wu¹Zm´NqÇSy´Q…²WŠ»[~¼a·\Ž¾\ˆ¿f…µ_}ÂWx¾Uu¹V{§Ss¥Lr¨>i·Iz¯Lv©Lx±T|°L|²Tp§Kt¦Ls°N¬MtºJt¸Q|«M†³[Ž¬aŽ›]”©aŽŸV‹¦^Š²Y–q«oz¨o{§by¤iu¥dp®d{·kw®czµl|¶]z½\³\‰§W¬V”¦XŠ®]Ž¦\–­R”µY™´V ¸Y¡¬`“¨Z•¥b†¥`‡¢Y¡b‡¡\‰˜cg–_i‹ƒb‰\…ˆa‰ƒc‰Y‚ŠTˆˆW‰‰XŽ€U†„O‡TˆŒb„…dˆˆf“i‹™`Žšg‰˜e‰¥r™ o Ÿa§Ÿg¬˜c¤¢c¡¢m¨§n©¢n¯™n«a«ži­šd© f¤ªc©«_¤¤W®«N¬¥KµTµŸS©¤M­¢O§¢W¦¤Q¥¦Q“žX‘aŽ£X™Y‹]†ŒT‡V‚ˆQ|ˆV}ŽP‚’Q[‚“Vy˜In”KkMt‘EpƒGd„Si}Tgz__~\V„_Y†Xb€_`bdkbmhyaeznaijeildaakdfmdf`ckg[eca[djWlg]nWa`We_Q^`YY]V[bYhiXffQddSdgJjhHjhOf]OlbMp[Mr`Ys\Xh\Zm[WpYXgP]fSPbRXkMWhJYkK^uQ_{PbTc‚R]{DZ|F^wKU{K]ƒTXMbƒZhƒW]ƒb_Š\ZeR‹eR…hLˆ`R‰[LNO‰TL‹QZŒS^W[—OW¤L_¨F_¯NV«Cd­Ia¦EcžK_¢VV£OR¥NU¯QJ¸SH¯KM®J[¸NW±UO³LN¶HMµLIµIF®EC¹D;´L8´L9±I5­JD­FBµH@¸SAÄK>ÃPIÇTN¾FM½?U½CSÉFQÃ=Gºh‰Hh}Lf…N^ƒRf^\Š\S‚d_~c[zc^†i]†\\zc\id`fbjYhc`_ejeg\Zc^`ZVbdW^jWTjcTka`bUfcM^aQa^[icRa\PciZ\gVe^BefBmbHs\UnYRmfVv`_u^Sj^VuZ^l_Vga^jVTjU\AUvI[mAcoKV‡Zf|LaˆS\zGb|KY‡Ni‰HiˆUkMa‡L[ŽUT†^P‹iZ‡cPˆZZ…`]}[Z[LWPŒ\SˆK\ŠWQˆ]]VbžP\¢GUªUUžQV¬DZŸOg˜Lb–LQ¡RI©TH§KQ²LH®JF©@U«JI­ET²ILºGJ°GF¬?L±C<«K?­B8¥Q;±E0´K>³K8·D;¿T?ÅENÁCQÈRRºLL¼MGÆHUÇ@KÂDBÊDB¸AE·F>¼DNÁ:F½FT¾IW¼<^ÅHbÅGX¾T\ÀQg¶MfºIj³Mo¸Rs¸Nt¹Yv¼\r·S€¨\y³Z®[€²Sƒ¼Y‡Æ]¾Lt¶X|¶Wp¸So¼Lj²Cs±=zÁLt°Ds¹Rz¸S·GuµVªS}¬NzªSu¯T³N…²L‚©S„£Y˜[ˆ§dˆª^’§g•¢i•oz«s~£oƒ§b|¦cŸou¢t¤kŸeƒ¡iy¨h¨a~§]„¯R‰°Lˆ§G­L§Y˜¦V›¯]Ž¦gœ©eŸ«oœ¥kž¯jš¨`•Ÿj”ši‚šg|¡YœS‚™^““]…“]‚•^…‘_‰g‰Že‰ƒ`‰S„•_‚—Z‚‡O‹N†˜P‚ŒSƒ‹_„ˆZ€‹[`šœe¡Ÿe˜`Ÿ›fžl¨œe¯Z®•_°œZ§žd¬§g¥ž`¨žh¬˜n¥Ÿh¨˜h©œ_¥§]²¢\«£_±¡T¢”U¢•QªQ¦•Z¢–Vž—N™ŸQ–—W—”U›–Y—“WžTˆa‰ŽX‹‹]Š[ƒ‘Uw‘[p†Ou‡Fs„Dy€>n~HiŠJ`ˆV^†QcŠMl†UiŒb[‚`f€`exb`}]Z}dZph_gbX_k]XedVX`daagYY^[NZeTQ[YL]mXYlWX_Tca\edS`cOkW[d^Vi`WgWQ]^J][BlZHlWLz_X~bbz]_qbZp[ThUTk`Pw]TvW_wVUFPsE^uB[xP^‚R\†SWˆJ^~SZ€Lc‚Ga‹KfVo‡QfZcŠRX„WUŠdTŠYVy]\xbTcTƒjR‚`TŠXRQOJ[ŠRXŒJ[ŸJX¡LZ•Xa˜ScžJcšGY˜L\O]•LO›OK¡CF¡DH§>J7L¢@J«HX¹MU²JGµ:@³C;§>D£F:ªH@ŸB8¢E8±D2±F7·O:¾FIÆLFÁBM½NR¼LI¹BIÂFLÈGOÄHDÂMM¾JI·PÈCXÃ=T¼JV¹GZ»J`±Q_ºGf±Jk¨En­Pv¶Pl´SoªTm­Y{®Ut­T}¬Ry²S}ÀV¿Y{ºMq³Qu¹Kq½LvµQn³In²G¸Bƒ¼F~ºM¬Nx­By´Qp­OsªHo¶Rv©Pu¥O¨MƒªZƒžX„›Y‰œT¤WŸT–©b•u‰±m‰¤k…¬`{«b¬msžb†£d„šp„¤f{¦]‚¦f{²V‚²V~±KŠ¬A‹ªN©^•¥Y¥Yš°e«c¨¬j›¢nŸ«k›­]‘ b•¥fŠb“_‡“g…šaˆŽe„ˆm‡•k~—\„…]‹’^Ž’\‚™Rƒ”R‹ŽQ|LŽMˆ˜L•O€’Sˆ]Š‰^—’i£Ÿi˜Ÿa¢šc¨¥]°¢d¬—b§—`´¥`±¦^¥¡Z ®hªd§—k¦št©“mž‘hª¡b±—`ª¡bµ¥X¤š^ž”c£—Qª–MŽK£‘M¤™W••X›™Z“Ÿ\’–V——X™™ZŠžiŠ‘Z‡…L„ŠH{‹L{’P„Sy€L€Gn|VvyWmzQb‚TZ~Nb‚JlˆNa`e|ahvS`yX\r\]v[Unlb_c\ejYV`Y]QZR_WSTPZRYS]NSeYXcdQZeQg`VagYflUlb[bUSc\_h_SiaG`WRiUTnULqXXpa[XTy\X~Q\t\W{^[va^nP[qT[~EW€NU‚?XI`zK`}G^|U^ŠTh„JYTkƒWaŽSj„HoŽFnŠKcMP]Z€cW[XaZX[€\Z~XS‚^a}P[„XYŒYR†P[™\UY[”MX“TcŸHd”Qj Q\’RP”MT‘TP•NIšML¨HJŸFGŸIH¡IN£=VµMR´=Hµ4R¨>G³7I¦:L¨>P ME¨DJ¨PF°R@»IL´KM´DQÂ@Q½AJ¶NUÄEBËFG¼HAÃPDÆKOÂLQ¸=QÇ@Jº:TÅJQÂHMÀT¼EYÁFV¿JYºR[³Hk®Dk¹Nj¶[t¬Ww­Ty¥Qz§_‚¯^~¨R…­T‚²N|·Kƒ½HzµL{¬H€²P†­[‹¶[„¸^~ÂR}ÄT}¼DÆF„¾DŒ¾Eˆ®;Š­<†°G{²At¯Lx´N„¬P€²Q|¯I¤X}¨WŸ^†¤g†¡dš¤ižcŠ±p«`ˆ«p|¬n¬nˆ¨b†žhŒž_’ž[„¦cŠ¬X†«R|¢[Š­Yƒ©M¥[‰ Q—”S”œQŽ«e› l•¬iŸ¥e›Ÿdš­g–¥dŠe„¢pyowšgƒV‚ay›f~–b‹a—h€Ž[†ž`’•[„ Y‚œXƒŽK€—]ŒŒR‡–Wz†Yƒ‡e„Ž`›XŸZ™‘U–žX¥§S©Ÿe¬ t¨ªb¬¢h¦[¥«b¤_¢©\§™h“h‘lŸ—i°V©”W´œTŸ]›šažš^¨™_ž›K›”Pš‰J””[ O››_œ k•g—b— b€¡`€‘T‡—T†’D{J~ŽPx|FƒNv„WqUm}`hxUf{`_Z\~Q`T]ƒV`|Ri{UfiR[fUedXUbQUbSTed[]b[^aLQQTQTJUOGK`OGd^Sc]S]ZU`iO]iTbfZ`gXhjLhWLrSEh^LcVVjTXaZTg_YrZXn`UxWTy[MrUSw\Xq]X|P_xEW{GS}TM€JL€HJ„GUS`„M`ŠTd’WkJ_ŒV`ŽChŒU^•U[’RSPPŒZVVY†cJyXH~YT}XO~]Z~P[€U]‰U^†__“dI•f]Šj_•_ZœRVšN\¢YY¡PR™MI›MM˜HS LT˜9M IE—BN§AN¨E±GS¹KP¼ES»QYºATÀAP¾HF¼PT½H[¶URºSWÃHbÂH\¹Pn°Hs­Hp¯Hj«JoªNu§Jw±S}°X† Mˆ¨S§Kˆ¯M‡¬O€¨C…®M}»M‡¯V‚¹Y¶L{Á[ÆI~¿EŽµH‡¿F•°Gˆ°?ŠºA†³K|¬Pˆ±Sx¨Zµ`ƒ¯Q‰¬R±W‹·f‰µh‹¬h’±`šœo£eš¢h˜£a‰­eˆ¬hŠªm–£r”§g•¦[¡WŽ¦\¨Z|¬]z¨O…«[ŒžV†œ[ŒŸT—”R¡Y•¢]• q l¥dŸ¨rš¤t‰¤q} izžd€žjx›h€¡\ƒ¡d~”\}‘Sy–Z„›d’g‹“`•Y ^šS~˜S€•U’S’[‡‹X}c‚‘]„‘X‘›Z™šQ’˜V–œ]¢¥k§n£¬qœ b¢˜_•]¥¢a¡§Xª¡^¤–` •d¤e¯›V®•V¯ŽV®\£–Z¥S¢˜JœO™’T T Ž\ XŸš]Ÿ˜l–eš™[’•m‹—m{š_€˜Z€”PzC|ˆ>{…Hy{Vo€Zqz[l~_cz^T|aV‰PV{P_zT\vT_zSbqSfg`[o]alY`nNb_Q]cYYWaPWaJ\SGUUHMcOIbOO_SU`XVb_YZZPYfVWdKihToeMv]St[Hh^HfXPb`Yg\[vW_tcUn^QndQpdSsdMvlYoc[tbO„OO‚HS‚NO†VL‹YR”\R‹MRˆV[ŒNc„IhŒM^DY‰HY—VP–RV‘WSW\„VX…aS}VQ†[K„bI…_S}]N‚US†]`‹^cX`‹[Q’eRe`W[–VZ¢QWŸU[¥LT›FKšAHHI›GO£9OšFCœFB DHªAQ©9T¤6G£7O¢8M¤GI¤HP™KKžJF–RJ›LK›KU¬PS´CM¼?Q¾F]¹C^¶@T»MW·BP²>T¯CN­IN­MN´LU´DV¾DN»KFÄKJÄHQ½SZºU_¹Md·Ki¼Na½Aj­Ds¬?k´IhµKn¦R¬PŽ¨KŸK†G¨N¤Gˆ B~§Iƒ²K{·J}¶C‡¹I‚ÅY‚ÇZ{ÃPzÇR€¿V·J“¸E½Cƒ¹Pˆ¶MŠ¸R‚³Q‚¯Y±d…¯b•¶W”Á]”»e‹ºjŽ¶f§^¤d™^“mœl–­i®d•«qž¨l› c”¤k’­b›¬Q†°]ŠªMˆ°LˆªQƒ£Z‡£YŠ\—‘U›ž_‰•a‡Ÿp„dŽ¢d£˜ge¡c„§jm‚›oy©b¢kx§e{˜b€“Z†Y„ŸX†•ca{¢`†šU†¢Lvš^‡’X“X•‹T“~bˆa…•Y‰ZŽ”NŽšX‹_ž¢Z™¡[š jŸ¤a¦¦g¥”i¦ž]£¡S ža°šZ¨’d¨‘]¡•b°a©’U¯‡^«“d¦ŽS¡•X©ŽX¢•S¤’ZœƒV¥ŒVž‹\™™_–‹m•j‰‘h•–n†”nv\}™dr˜NuˆGn‡Th‹WtXe\oˆVn~Y[~]Uƒi[„TYJb}X[€S_pNghKfcV_kb]aRhaVeXT[bRLZ]OPZE\Z@KWJNfPO`KMcQPbOVgPSiSV]]K[eQ]fMt`Fs_Vs[WjZUcaQmUSn^XwhPg^Pk^SsgOlbRwaOp_KsaZycSwdN„]R…QJ„_F‘[RŠMQ‡GN‘NY–GX’T[“R\’L[…UOWW™VX™^N–bQ‰^PkOƒfZ…WQ|YKzeZ†eU|bT‰b_…^]Š]`—ZK”]V–^T˜VV‰P[“PU¥V^£NK£IJ•ND˜BM¡GJ¡4G¨@@¡HE£AL¤8WŸ@Q›>R£¡E‚­E‰³S‡±T~½U‰½M†ÃU‹ÉO‚ÅX{ÅNƒÆOŠ°K½Q‚¼P€¸S…¶P‘ÁTŒ±d•·`‘²b‹ºfµg’Ã^—¼hµjšµh’±cœ±Z”]Ÿ™h¢n «pš©r—°h¡¯f—²p™§i”¡b˜¤Y”§S‹«[Š©W‘ K›¤N”˜P—V˜_‰–k‰p‚˜e†—r””q—™k•œb¡\Œ¨g|¦c„ c‚«^­iy gu£h~šc’a•]‰œV•_—Y‚£\|›U}•a†•\Œ‹R‰QŽ[ˆY‹‹^’ƒZ•Š[œŠY‘‘Y›S”™YŸ¨_«¦a¯©g©ž]©—]§–_°•]¬”U®V¤[´T²‹^¨„`¯Žf«Že«•a¨‘XªŽQ ’[ž‰^›~[£„a‰a¤‘aœ‰f“d‘‰e‰“_ŠŽg|ˆkz‡drŠ^w‚Ql…Zn‹baa^_iŽ`fcY’lT„gZ‡fT‡UY|MWrTTvNXySblZllVg\^b[]W[ZZ_VKX_NV[KTYQR^GOjFNeSQnOKeOMaNSiORhYH_[LkUSgZLqdRs\Vi^QjZVnSWrXXsgSkfNmgYucYogNniRjmStaRseUvjY~gV_QŠ`IUHIUJP’EQ–PT”X]“OZ‹Z]VR’VR•[T˜\TlQ‘nRjZ„]V]Q|_Qe[Š`b…jYŽa`…hb‘lV’aT]T“_VWMYOšTU™JS£IV¢DL¦FMžCH¥CDšT©6\«;g´>]¶9d²A^µGdº>c´CY¬CYµATµCP³?MºBKºHR¾MK½NQ»KS¯MR©SM©RX±KVµGb¬>a¬El£=g©Fl£Mm P}¥D}œI‰œF“G‚‘Ež@¬>Š«LŠ¯R€±L€½M¿S¿Y¾NŠ¿RÄN‰¶L·Jˆ¼VÁ[†»VÂ]‰ÂbŽºf˜±_•·f“³d¿j¼j™¾m˜µkœ¯d±b’¯a•b¡cš©mšªuš¯lš°n££wœ¦pªvŒ§`—Ÿe‘¨_Š¢[ˆ©P‘¤W˜˜C——[•”`£—Zoˆ’_Žk—™nžžq¤g•›b”§ežot›oƒ©r¢a{¨ds•lƒŸ`{a–b‚¦d‰¡Y¡_‚©Z‚¤Xˆ¦UwžX–W‚š^„ŽXŒ~_‰W‚“Vƒ’N˜—Y‘–P˜œ]™T’¥V¢œT¥¢d³œf²˜X¬“U¶žP§’T­‡X®T«N¢‘I¶V¯‚]´Žh©•]§R©–Y©‹U©ZŸ…b ‘d¨‚_§Z‘Œf’ˆ^ŒZ–f‚‹Y}_ƒ†ixdsUv†QqwT_„fWY^c^ƒeg``‡bPj`„aWˆYMu`]wV[mXapZ]i_\gZgUYbTTNSPU][IYQHOYTDaGOWGGZNJlQPbPVcSIdUJ_NSfNSbXOn_KkUQrdUsh[u]UgYVvRNnXV|[OpVS|aVx\_tXUq[Vm^WnaXvj[}jS‰[RƒfD†TT–HE“LI„MT•QO‰SL…ZR†ZR_UŽ`K’dKWL˜cY™cQŽganT’l]Œg\‹^S‰[]Š]d~h\{adŒqb[V„]O]T‹^]_]–^XXS•OUJQ“BLœKEšAF–=@’7N”6D—>D¢2W©?K¦DJ¨W1LŸ5P;UœCZŸEe˜Hb’=b¦IZª7T§9[¥K^´I\µ8i±D^­Ec³Bgº>^¹9S®EU¹GZ¯JP±CL·CS¾EYÃ>[¨BT«N]©E`©Nc²S^­HX©Q˜KJŸHO¨;U£3W™Z¤?b I\¤Cc¯EgµEm´Ge²F]¯9Y­Cb®@Zº=R¶KX¯>T¯@V¼?\·ŽªE“²S“¯Q‚«KŒ°K­JŒ­M‚­Oƒ»Q‚ÂLŽ¼W‘°VŽµY~³XŒ»]ˆ¸]”²U˜±[¢¹bœ³n˜³h¶p—¯p‘­f¤µe¥¶h ¦i¢«^ ®\X¨žU c¦©e˜µa“«l“¥m—v’ j’¥l•c•ž_•¨\•¬`‘ªO’¢Pž^¤¤\©™c¦™b™›_¢–f¢›p¡™kœ¢rŒ™oŽ¦k‚£i€ o|–vsžg|šebt›aƒ“g‡¥n„ j†žkŽžg‚¢^ˆ«_…žY}¢X†”aˆ‘_œcŒˆi€–f†\ˆSˆ•R‰¡TœQ•›H›«Q­¬XµŸT¯–W±Rª”T±“N¯‰L¯—P´…A²‚H¥ŠJ¯’U¬“Y«“S¯‹`­•a¯•Q¦ŠWªŒ`¢„b©[¥c•Œeˆ[Œ‚f—’[•„[”‚_“R}“]vˆVo‰Qf†X`„Zf†\Y‰hS€iU†[T\^„_P‡iS‡eS{l_uXVlaSk[de\VkbYVSQQTRMZXHPOP^PSULTK[@VZN^OJaO?jHJgPL`WObWHoKJlZDuMJj]Ujb`vaXo`NoXUkWSr\[v\Rn`_€QZsUSMV~YUy[ZwRZ|_P‚YR†NK‡`C„^A‚ZIHUŒFTŒQKŠKO†OAˆ_I|YL^N‡mR‘_JšbEŸbU–cQ”pW‘fXˆaP‘m[ˆ[ZS^‹^Y{gaƒg[’jXŠcQ~aRTa•V]SRYM”MJ‹VFSM‹J?KIJE“JG‘HMW˜7[›:S 6V•9YŸG`=ZC]C_IV”EU˜HbœLX¤Jb¥Ae¦>aªD^«<`µXŽ@O’EVš>[™CW“Cc˜C]Œ>_šAe˜FY‘MX˜Qa’J`œI\©Kg¦y­Fy¦B|¨H}§J~šL˜B‹•<‚›?ˆ J•­P‘²L·SŒ¹^’®Y“ªX‹®K„¶Mƒ¶P‰°R¨]Š«WŠ¥[…§g‡ªa“¯f•´Yª]¢«`¥¦fœ£bœžZ™c©fª¥e¥¢c ¯d¤­`™¬P”X¤¢Vž«V™ž[š­a˜¬kš¦b£«p§±s ­p— m‘¥]™¯dŸe¡©cž¢^ žXž£W›•P¡R¡«V©¦]£š\¢šlŸ–q™m’žfƒ¢h}œuyœjt“g~“i†•cƒ–hx¨n†©l~ªq„›rz£l‰œg”eƒ›e‹§gˆ¥h’ hŒ˜\€ŽW€–i£d‡šN”™[’˜Rš“U˜V¡žP­—HµœL±›RµL¼ˆX°šX¯O¸ŠK®…C·…E´ˆJ ˜W£S¥^­‹N¨‘S¤†R¦†]ª_©€d£W¡~h–€^‹‚h”…Z—d’Z€\’[‚…X{…bzŽ]o‡\bƒTdˆ_f…`Z‚pUzhN‡eO}cR]V]^zgWybci]]qd]f\fRaZT\]U]UTjTP`WL\QMbSMZQO_QGQM=_PAhQI_RDhNU`YNmNSbPLlMNq[ZlOMvTOl]Tg\QrfWf`TbeOiQR|YH~MGŠUK}MUyKNƒVN{SG‚NN‡YMX@RK|ZR‰XIPN“FO‰U@PE“^B‚d?lG€kF‡cA“tPvP˜fM–gW‹iQ‹eUZO”]]ŽWX‡aXUX†eW™ZIŠVWŠTY’UR˜W_†XLQSZB†T>…]K„^HŠW>UCŠYCOF‰KE>QŠEGJPŒHYšCW˜>OžF_”F_žFWž·H²ˆE®“NºV¹ŒO±…W²‡N­ˆP¦‰C¤N§‘S«“I£ŽO«‹T­S²‹S·„a®c |Z }Xœ€^a”‰c”„]ƒ”Xƒ–\v–\t†ZkŽah’esˆWm}[j~]_‚kQwtQqmKoeQ|eVz]W€c[zcWmb`c_febcZnd\ic^^`X^`UjTTdVCeMBgP?hRBgIDVOCaNFeRL_JJcOT\QV`PW]Y[iTUkVNnLLrNYlSVxZQvcZvdZgYRlWKzXKˆ\C‰RGDG…GJwHFzVLŠSI‰_E„\@‰X@~OI‚PM†LH•HBG=”RA‘a?‘f?‰]@†a>gD”oF–jM“iSŒbaŠe`‘^T‡WR“`Yd]•[`Œ`V‹dU—WFŠSE†WRQQ‘WU]V\QˆSANB‚Y9‘X>—WKYJTJPAˆ?Gˆ>I‰?M—EU‹GUGYGVŸLd–Q^–L`–E_—GfŒG_…8i•6o“=lk™Fo =o¨8n¥Ch¬>^¯;e±FZ¢I]©8]¢4c§?dŸ;hª?t©Hq°DtªAr§>i¦3m¤>nŸCo§CsFl›;w¡8v“9z•@‡”>ŽŸ@Ž©L”±SŽ¨L“¥UŽ¡S‡¡P‹©M‘¤H•¨O‘¤X‚¤T£PŽ›R…X‹ŸYš­[—ª_’§jŽ `Œžb•§f•ªo¢«b™a——d¤ŸX®¤T¬¤V ¯^˜´W™d™¨d¤©i˜¢h”šg« n«°q¡®r «n £q¡ªh¡°d¥ªh£ [¡¥U¥¤a«ŸO™I¤ U¦šP©¥X¢£bšœe—™[Œ‘kˆšn’¢fƒ’nx’i{špx–js›mr£r…¦t{•o£wy›hƒ›e„¦c„žb£dª]|¨`|¤b…ž`‘d†Œ_ˆ‘a’¦U”—Zœ‘S˜˜E–‹R›‡A£˜D£–M¦Ž=¬Œ<½„I´ƒH·@º‚B¸‡K¸I­~K´ƒB­Œ@¥ŠS±ŽC¦…I·†F°’Q±ŒQ®†]·ŒY¨‡Wž‡g‘‰X˜Š\”b”d’_‡‘`‚…g|ˆdl”Ul–_rƒWf|[l_hxd\tsUufTslZ~oX\_th[ke[ggUnjkflbbhjYpZQbfTfdYdTWpRVoZNh[ClNH^PI_MF^LQhKPiRQcSPgLQdVZmU[h\XlVGvVKjWUjHZwPXveSj[YnQJqTDoXCzQKŽKK~LK‰PKƒKS}\I…QH‡g@SB‡\:~^M†MKTFRGŠV?P9˜P@[FŽfHŽi=‡a@‰hK™oJ’i\˜`^Ža\…c[‡SM‡dY†hZ‡^Z’WXSKžRG“QGŒXH‘OKŒ]R‰RP€TAˆZFˆO;‡S?T@‰[AŽTO‰VO’KH‡FEŽFMPU‘IUTU‰P\”GXšK`—EeR_DqŸAl“Dn‘=s”@iŒIg‡KyAp—Ai£Ic˜Dv›Ju¨LtœEc >^©5h¢=`Kb«Ah @rŸCk˜:gžKy¥=l©7x£?r2m¦/m›1s™CeœEu=v§9t›9s¦:|•9Œž7«=‹§A±O‘£P”­VŽŸU’œU’¢M‡¦JžW†¡T¡R‚¦WŽŸ`Œ \‘°[²kŽ¬d•¬l†¥j›¤h§ež¤iŸªršœp‘¡g¢¥T¬¥[­¡a¢©[¨´N©m’¥`™ªj˜®cŸ£g¯¢b­¨c®©m¨°pœ°pœ¬s˜©d£­]«¡^®¡W±š[ª U°—S±šQ­S¨£N¥¥X¢ W—¥c‘˜c–œfŠ›^‰že|˜]vžau’pœrx›wvt€t{¨qx¡rzk†g~¢_‡¤d‡™a„›eŠ d˜g{Ÿi€•h‚˜_‘œ`˜žU’ŽYŒ„P“ˆH›ˆBF¬‹H¬…B¶‹<¼…7´€B¹†D²€D¼€L»}Gµ„?¨D©ŠF«J«~P¨‰D±ŽQ·…Q¯ŒY¬‰V²‡^ª€d¦†aŸ‚_“…aeŽ^Ž‡g€…_€auat‘Xj–dgˆ`hˆngnhxw_xn^rgSkoRur]vkXqiXpvSml__rcUq_`ga[ifYoZRu]WkbWlgIs[KkNFiRKaLIdKFiUEaNNfGNiNQrPQlSKuZKrVQjaGpZNjVWqNZwZVxUMvOJuYP{ORrNFxE@LFŠDD…GC‹JF†STŒaK]D„`=ˆWC‰RKXE…OJ‡WA”W>“O@”V=ZF„Z=‰j@‚pG‹iDŒbR“gT˜[V[Z’^]‰UVŽ^_c]XP—XOOV”WN•SPˆ^A‹U>„TD…TJŽO@ŠM=…QEW8‘X<^ISH‹JQŽNK”HM–PD‘[LUW•R[‘OY’Dc–E\Ÿ@h™Gg’8m•:t›5p?n‰@kˆEs’;j’cJc¦Dg£LhžBoAz›Ew©Ao§AxŸ@¤2~§7|1qŸ,p”4h“1g™:o˜Ao¢m˜7hœ2mBx C‚¨@‚³It±H{¢O{ªJ~°GžG’§AŸPŽ•V…I€ªY¦U‡ªUŒœd‡œZ«eˆ³h­`—§c­d¦h“k§l”ªdš®h“§a ªY®§Z¯©eª³Z¨¨P¬o¨ªož©mœ¤t¦›q«¬g©¯m¥¨y§°k­­d£¯b–ªp˜¯q™´n¡°iª§c·ªa¸¥\´¦]®«cž°k±d‘¤a… o…™a…•Y…^•edzŸf~•fz^{›mw™j|¡c‡¤jƒ¬k†¯Z†¬eŠµe’¯d¨j‡¤a~šd•^ƒ—]ˆd£j˜dœ“dž—]•ˆY‘‰N”†L¢ŒR¬‰Gª†T¦‹R°T±„G¶xM¶C·ŠM¿|M¸|L¯„G¨ŒC¨B¤†;~Cš€@—†I£…R£Už†S“„_—Žl—g‘ŒX„ˆZˆ“X’cƒf}‘Zq‹Tk•Za’bkŽ[l[b†lX~qf„qb~o^{^WvcUknZeg`jkVlsPdsRcnMYePNcYPgYNtUJsUOqWSr^QkOChI?_ICVQBgONpERtCDuIEyFKlONmLKyZXmYKhPMoIPoNYxWZyUU|QTpSYl]Zw[IzNGƒPBŒS@P?”QQ‡VYŒSP‚K>ƒS>…`7€]F‡bEŠj>„c=‘W>“[@QB‚QF…VT‹gR„cOcD‚gRˆ[OŠaU‰eL„mV€hV‰`NŽcT’l`ŠhZ’eUŽaP†]QŠ^TƒaP{XBx];€`EƒV:€S;{IG€MR€FVŠMJSHƒHH€DTˆIRLQ€F[SS„PZ‰Ng˜EbšF_˜IdžLa™BbšNe—Mr“FqGs“OožHižDn‘>~…kGZA‰Z?Ž]@Šb;^?{OO{RSƒfX€aS]FƒYI‚iJ…ZEzfHŠfRˆnL…fRfKŒgYŽp_ŽgXŠe]ˆb]Œ\U|^JZIeCfN‡aL„\FO=~LK„SH{PKVKZP…RS…AI‚IQ‚HQƒO[PT€UV‡Sf•P^•Rl›FdŒG^šPkSo—Mz‘Km™Rg•Hr”ApŽ:„’E„¡E}™Lx˜Ks˜Np¢LmJo•Io‰Ru…LpœNo›Kz—Epœ0u3|•<}§:„(‚¨'†¦'š0x=t‘:{šE¡4w¥5{¡5|©;ƒ¤{AA{@G>Nƒ@QsIXkKToSQoLPuPYmPOxVPnGIxM>w]B„\K„_G|RA}TCƒMJŒGF}QG„R9|\A‚^=ƒd@Šd=Š\G’kK…hC†`G‰YIXOzcQv`SxZUx]E…ZR„gK†kD}`SwkMydK„nW‹zT‡|M{XvN‹u`‚c`‚d]…sK„kP{kO„cVeQ‘`F|RL}VAp\K`K}]Mˆ[_|YS…SW‚NM~[R…NY‰T[‹Ne‰Wj‘ah’T`ˆ`^„Xh’Xh”ZtNkŽTlŽUzš?|›HwžIxš9Š‹D{›@z¢Hp‘En›Ut–Sl‹[u“YuR’I€‘Ep–Cw˜B}Ž5v“B˜?¤>€9…¥/€›7„8{›8‚“=‰–C‹¤6Œ¡7‡ž;‰œ8ƒ§9ƒ :~§=›BŽ§A—ªG‰¬LƒŸR‰¡Yƒ¢\‘«X¥a„¤`\†—bŠšX”¤X‘­Q™§]“«`¤\‡ªV•°]›«X•£_œ§^¤Ÿ\¸[§¦d¨n ¬d§©qª¤o§¥u ¬jª«r™žu˜¡w”¥mš°t¥«q¥¯j¬©j¥¤k·®a»·a«²f¬µb«°X›®eŸ²g–±e¨l‘›^Ž¦Zˆ¤`¨[…§]}¥S…›d†œdˆ™]ˆ™W‰œ]‹«ZŽ®Tˆ¨T“±]–¥[‘¤j‹¢h–£iž¥e˜¡W¡šTœ£V§Ÿ^¥ž[§¥UššU•‹R–O“M …Oœ„[§ŽX›€VžƒKœ‚Q¦P«zT¨{^¥‚Y­‰L¨I°@µD¨F©R›~Sš€DŒxP^™{\’ˆU]ˆŒh‚’kvŒg{do–hpŒh|ˆpzŽmk‹ni‰_a…[Ye_}b\ta`j]anb\xcgt\fm\k]S`e[U\[T\\SSbQWcUScLMlO9gG;nJ>gB:eDEhGFhK;qG;oI6yH2tA6zL2oG;yE;w=K9Tƒ=P„HWwKSvQWvORnQ]sQVvKKzJBN8}V<ƒWF…RF|QD{OD}NB†JH‹JH‚T;Š\F‡[D_<‰Y?„dKŠiKiKiD~^OŒ\R†WS\Q}aQyeN|kW|cO|bM€hO}dDƒdEuQ‰}^‚s\zwOtkL|kVyeRlV‡qW}xK}uO‰`V‹ZLˆ`P€]OrZKn_JpVNr^N|XWzXOzOQ~LX{QO{U]ˆJZ“X]Œ[e“`j\`‰de€^a~caYe’Ym–Xq•OuŸAv™HsœAš>{=‡’H‡œHw£IlšOo–[u‹Un’Zy–W}‘Mp™Lj–Dl•Iu?o’•£Aˆ£K‚¦Wˆ«TŽ©YŽ¢Z‘ŸTŒ¦T–œ_’Ÿ^–žV›¤S¢¯`œ´^˜­d‹§fŠªc”¨f•ž^”¤X§ªT¬žaµ›\¬gŸ­j­¤g¥¨k±°b©£c««o¡¥o—¬j¡£r ¬i«¤t¯¢m¥°e®¬a²¸]º®f¶¶g¯·c¦«ZŸ«^›¨n›«n”©n•£b‘¨N’±XŽ§S|¯]‰¤Nˆ¥^‚ž]…”a™U£Q«^š©S˜¬S‘¨`Ž²`­`›¢p” _™œb¤žZ§ U§ªXžŸ_¯–`§œW¢•\”ŠV¢‚_œ‚U¨’^œ‹bš‘\—Š_š~M¦†K¢zS°‡W¬~Q³†a¦‰]©W²O£’PžŒG Ž\›~TšzN”tPU‰‚Xƒ‚QŽ‹]“hˆ‘iŽ[{Š^zŠ_j•gk†qvŠuilh„ob\_Šgg}c]ud^o[nrcpqVoxWerangVfWOQaUIXZSMWMHUIV]MAiFEoDa?=^I9lJ=lD1i?1m>1n=4l?8~B?v;M„:K|@PzDMyNMzRN|FEzHHwMZvTM€DJ{RJZ:†LC‚JMzH?ˆRE‡R;ƒJ?„U7ŠTF‡Y?ˆZC‚]Ag?ŠjFƒaH‡lG~gBŒiCdI€fI„`NzjNƒbV~dHkQz^V~mNxpJwhOzqO‚YtqMzqRlHxmJrfU€gXznK…~N~sQpV}iV‰jW{]Gz]GzYRtPFpVGxYTzMXnNV€[TsRYzX`K]†QZŽOaˆNe‘Rd‹]b~VeŠ\bƒ]oˆVo“Rz›Um£PvŸE|’RtšC|œ>„9|™KzJkFl—Ir™Zl•Pxš^vžXw›NiœGw‘Hv•Bs˜@}¤B|¨;‹¡A„˜9‚?zŸA‡§0‰Ÿ7”ž-ˆ“0˜>ˆ˜:† 8’œ<žBŽšE†ž@‡¨6€£7‡ D‹¢C‡©M…žL‹§X‘˜[•UŸ]”¢S‘ W•¢[•¤WŸ§`–³cŸ§_™­_ª^—¯Xœ¨\˜§T–®VªŸ\¡žc¨h°±j®«n³³e«ª`´¨i®£p«¬w¤¦x«¤j¡¬už¯qª£qª§d­´e·²c³³[¥¬Y¦°a¦­\™©X˜§e«\®a®X†¸O‹´Yƒ­R„¦Uƒ®T¦Uˆ X‚UŽ˜Q JŸT–©S“ U™¦Z”¢_›©^¡g˜›b¢›`§˜c«–[¡¥]¨ \­žg¨¤b¢œd¥—XŸŽZ¥‘b£Žjœ†a‚Xž|W˜Xœ€S¢ƒJ­€M¬†X¬Œ[¯[¶•T­ŠR©’Q¤ŽSŸ“W—‹M—zJ‹zUƒ~RƒV„„W…Z„ˆ\‡]v„`veq“du‘cj‰opkp}qn}womg~pi}cazd^}VixYb€VlxNovTgfRdbOQVYLLVLPTOVXMKiCKiJDpP9iM;iI5dF<^=>d@/l?5nE7gMAkK;nB;rB8|=;=D|BH„9OˆEQƒDKOE†HIwJTtNOuIKvFE}JH~QB~QD„NHH?†J9{K9W3‡Y8X?ˆcAˆ]@ˆfM‹jN“aK‰gJlF‰k=‚n>‡fE„kFkO`X^PyjU|jMrdRseNvmNuwI‚Jy|WouLvvHptCtkN|rHziP~jU†rW~rZwMwxU{jMqhPrYOpQTsVNwNLtTKpVIs\V|V_yXWxM`ƒR^„W_OjƒIn‡RbRd‚M^ŠYgƒXm‹Ru’Vx‹Ur•MvJs“QxžR{™A|‘;y=o=g“Kl¡LjMl–Xu•Ym bi›\hŽLs’Mx™Fw™Izž>z¡5‚¬;ˆ©B}¯7‹¨;Œ£8˜™/“”9ž—1›˜:’7Ž—C‹š>–ŸH”ŸA“™Gˆ¡; HƒEœA–§I‘¢PŠžT’¥L—žT‘Ÿ_˜£X—¤ZŽŸ`–Ÿc¢¨bœ¶Zœ²]™¬^–³\’«Q¢W•«[œªUŸ¥_£ f¡`®·m©°h§°`¤ªh§ªl¥¬jŸ¢u©v£¦g¨¢m¨¦r¬¨l¬²k³²k«ª]°¼` ¸Z˜­Vš¶S’®bŒ«dŽ¨aŠ²]‹µPƒªT¢\ƒª_~¤O¤R|¨VŒŸX‚¦^‡£]’¯RŽ¬^‰¤T‘®\“œ\•­c•¬c™®\™šf ¥^Ÿ›]ª¦b£«c¡žf³¨c§—g£œd¡[žŒWªcœ“_¥ŒU£”R¥‰S¥]¥Z°ŽK¥‹S£ŒN°•_¹˜O³“O¨R«‰GŸ†X ‰L£ˆHš‚Q’tV‹wZ‚‰S‚~TŠ[}UƒX„‹cY~huŠpn–xf“sdˆch‡unsg|m_zdYr^[}[iuTjyOdvP^rXbi[X^X^QYLTbGQXNUh\PqHBnMvI/z<8uN:sEA„CFzADƒ@@‡1EŽ@IJ>‰IH„JH„CBvAKtEJm@4~S:vQX3gC…rIcFŒ_K‰nAŒ^DŒa={Z8€cI~iDƒmKƒbW{`IviOtfCzhSplB‚sKtM…†KtrHrvRvvIniXwoYtmN|xRzyNvTwmLtoNtlTodVvZNzZNv[Jy_XpVSzVKyaWrbQzW]wVcRgŠ]e€Id€Ln…Zq†Ka†P^…YrƒTpŠ]u„K{’Nr”J~“S|ŠH|’Ky˜E€’Gw?{ž?yKg˜Uq›Tu–YiŒUp‘Ql™Xh—Ow”KsJ•B}’E…–<†£A‰«HªA‹¡7’‘0‘%–’(Žž.—’7‹š8œ7ˆ™CŽ =”š;‰ 5‹>~›C¨>’¢@Œ¤E•œW”žS–O—¢[‘¨PŽ¦T™¢T’­X™©a•¥[§ŸUžªe—®c•º[™¤`®]–£`•§Xª V¡¦d¨]±Äd³Áj¬¾c¦¯m¢²o¨¦q¬Ÿ|¥©zž§t¥£|¦£{¦¥l©«b±®b¥´a¦³[¦ºe™·a—²X’²]—¶_Œ¬Vª^…¯W‡¯Vƒ Vž]‰£]… V‡™UŒ–Y…¤\”§W‘¬\†¤\ˆ¬Z‰žZŸb”°Y•±U¤¬R¡ [¦ž[ž ]œa¥ l¨ªe«¢j­›c¬–Z¢–[¢“Z ‘[¦S«‹S®”P¥Ž[£‡[­‡S¯ˆX´”Xª‘X¯‘[³•Q®”R¬‹W¥ˆLªQ ‹NŸˆH¡‚F’xVŽ{\Œ}V‚|_~ŒUyV}…TuŠ_~”]ƒˆ`zŒem‘pkjl‹df…cg‚oonlqr`arifu`crWVcTZdTYldcpa_aU]]cNfcP^bQ^iZVnMKxD@j<@mCDkO=jJ?qOAuH9K4yJ5w=;}>8}ME~KG{=F8F~5@…8B>8ŒC;‚76;;}E>A@x?7mH1rI4~JB{M?}LBƒP…hJ‹`LŠfQŒmLŠbO‡_C}X8wZ8|k@wdQylRsfF~^B}_Dy_J„tH€zE{{?€„D†uI}qOtnQpuQywNzj[w{Tv|N~{XzlSvtP|lL{qXufXqiWpaTm[PuXTwX\o_SmaexVe€Xg{]_y[[‚S\{S`xZs{Lm}Mm€Mr€WwTl‚Lo…LwLx‹LwCy–HzGz™D€™A|–8p™@pQuŽ\zŠZsŒ`t”Um—On—Ql˜Oy•E‚—Jƒ“P€˜G£M…£B†•6‘“9•’+’*”-‘—/-™0—š1Ž?‡’?œ@…•:zŸ:ž@~¬@ƒœE‰Iˆ›V“›S˜œI™ŸPˆ¦Gƒ J‹ªY‰©[’ ZŸS §X¥¡b¦«_š¯Wž¯a’¬fŽ¢^” Z£¬W ­d¨e§ºb®»k²²a«ºb³³q°²p·´y´¨t«¦z°®v«·{³¶m¦·[£®[§²X›¿`§¹dž²Y—±Sµb¸lŒ¦l±j„¥V‚¢V{U~¨\…§R¥P‰¥`€›Z’«bƒªb”°S† [Œ¢U‘§UŽšL‘¥^Ÿ¶[›®X¡¤V©¥T©¡X¯¥_©Zµ­a¶žY©¦\³¦c¢žZ¢–a¢‰Y –_¨”O±“Y­[ªRªƒW®ŒQ¥Ža§ŒX±’R²”^©’Q­ˆVžK£ˆK¥|R’‰H“€SzL†y[„‡^~‚Ztƒ]y‰Os…S}‚Uu•_~‹bwƒfvˆrnfkƒguynvqglmfhs[hdccbe`obhbWdf[iki`lcblbZc\b`_][fWTm[WjYOHK}N=qAN|L

AqJEw@>ƒI:z@=yM5‚B:}DE}A?ŠBN‚5A‹6HŒ99‰63>0‰<5}57??€<8qE/r9*tA-t?<{?AJD}?:lF+sM+~`-}W+€_4X-…d=„Z3‚l:‚gJ…eN`H}hEwgJvS>t]8~aC|eDtmKwlFx^H}`BndD€nK„w;ƒuFw…Dƒz=„|AlGvn[{o\{oV{x[p€Or~SzsJpjO|lWu^Tw]Zn^VuVRp_O|eSj^\hYWv]as`]|Y_t]_vY[nV^yKmuR|tYm|Uhs\oˆWz†Yv…Vy‡Mu“U†šSvIpJs™Ju‘:s•E‚‘>xŸ>y‘J}‹[s–`u•d{–Uj—Lq–Ns“PtŒK„˜FCv˜EˆŸHŒ§?C0›”-‘‘(•—+™‰'‡3•‹.ˆ‰8†ŽG’›<Š™C›8‰ž:§A©?~ŸAˆ¡PƒŸS‘¨I˜›N–¡P’¦R‘¬Q…­O„¨U…©SšœTš¢Tš¡_ª§U¡§Z¢¬_’¨l”¤i–¦f› f¨¨b¦r¶Âk¯Äa·¹h³¶r·²nº·pµ·‚¶±«·{«¹u¤»w®»p¨¸e£¿aŸ¼]ŸÂ\œÈS¢½R£»Z›¯e”¬hŠ°e„£mƒ¡\‡¢[}¢]{ŸVˆœ\†§R‚¥X©]¨^•¦]‰ª^ªSœU””M˜šH˜žS©X§œO¡[ž£Y¨¤R¬¤U¶¦Z¸¡\´¨b¨®d¨¤Z¦¢ZžŽ]¤‡b§Šb²Y­™a«šW¨‰T³‘V³‰\§ƒ^¦Ž]¯ŒVª”R‹T¡Wž†Vž€XšuI“yK˜†P„P€\}†[t[z†av~Uo†OtXxŠfw‡fxƒkp„gqlpj|v`sjbtfWwh\kck^dk]bpaahhjiimcdjedfdffcldkeYnmJjcL{UCzSG†TOHKzFŒH=‘@;A6’<0Œ@6Š?6„62v9=~8:w:1r>7n>3xB8x:5pE2qD*tL,~U+wS'zO'\1„^7€b<g9‰ZD…]L…gJ€eKxaLx^;zeJyeHnp>rjCvf;qkDwpErnJr~>}|AwF|{BƒxJ}vBvQzrW„qZ|tNƒMzUm~HltLkhSphPqaVj\Lp_SuYV~UUva]sabrZcr`]qf_te`idad_`ePfdXonPwv[wnZp\z‚]x~dyˆa~‡e~‘Wƒ›UƒSr•Lz–Es•Au“=Œ@ƒ•H…™O€Ž[w’V{‘]r†Yr…Qm‡IqŠGz‘DuŠIw”Jƒ™F€“I…›B8‘2—)ž…'—„3šŒ-Ž)’Š.†‡5ƒ>ŒF–™B¡A”£:’›A†œ8„˜?¢J‹«V“©PŽŸL” I§L„§H†¯E†¦GˆªVŽœTš–P¡Y¤šZš§d–¨]—¥f”¢h™¨p›©p¢¬pžtµÅp¿Âj¼Çr´¶t»ºe¸»r¶¸|½|¶¹z«»°·{­Åe§Àiž»gŸÆi¿[ž½U¡¶Z‘°e“«^Š³f¬jŒ¨pˆ­e‰¨d‚˜Zˆœf†•]~¦]£\‹©a‰­e‹®^“«V‘ŸN™©J¡R—¡Jš©X˜¨W¤«]˜¡M¨¥`¤¢Y¤¨Qµ¥T±¤_¯žX«Ÿ`¨žX®h¡–g¤—h±”d¶—\´U±”P°P©ŽJ¬N©‘O®…X¤S¯‹Oª’W¡‚_¢‚]¢…O¡‡T›}U‰Š[„ˆaƒ…gwvbubs‡U{\qˆS|‹Oz~Sv„W‚bpslvƒeixkmf[wieocgqjdrdk\WiWUkd^Y_khg^ggahZbh^eqafrebsiRxcOq^KsWLtWGKFtCEyBNy7E}3E„6LA‚A;77‘;6“71…8}77s@07.rA-}B-{A5…C9‚<&x9*tF!‡M)ƒT zO'tZ-~V5…XA…XEˆcJ‡b=dI}gC€cA€l?{eD{gwpCzc7p]HvfJzgP{nDtjHqs>m}>rzH}wHxLywMvqJ~yX}U~Hv‚Lj~FnsHkwOgwTfrWdjIkgNhjZicZmhYf`Yb^Rf]]`jj]kga\ncip\qehcqdVkjZwnOsuNwnMu{aovcx|[~„_‡…]…ŠXƒ‡N…J†ŽJu‚@tŒIo…Dw€Gw€?„‚Fˆ‘K}T~as‡SwŒS„…WŽPŠƒJ’‡JŽˆTˆ‰Vƒ‹Q‰@–Œ?“•7›Ž/“’3Œ(–‰,‹•:Š–A‘FŽŽ<Œ™C‡œI§D¢8ž©=”¤<–¦@— L†¥NªKŽ§K‹™J£Q…¨G‚¦SŠ¦PŸK• SšXQ¢™T•£^–˜`—b—Ÿg¨o”°y®qtÊÄ¿ÂvÄÂo½Ïl½½v¾ÇvºÆp¼¿z½Á{ÀÁ}®Æm³Ìq¤Êm¨Ìc˜Ãcž¼rŸÂv—Äjž½cˆ³l´j‡®c‚¥b„¡l‹¡`Š¨h†˜o‡¡g’—k‡˜j‘¡^ˆ±V‚¦Tˆ¥S“›`œ¦R‘£Y–§S‘®\›©U—±dœª_¤bª°Uª©e«©Y¬«\®Ÿ`²›Z©˜W³ ]³œY¶’a²•T³’U±–H»šW»šK±P¥ŒU°‘S¬—N¯V«T¡…`œ‚X‰]¦€R”‰`‰€d|\—€^„„\ƒyVƒy`wx\xxV|sbt~S~wZ{uYmxctxbopendet]cqfjydcgbgkSjo^hhY^fbUacX^`T[^l\cl\gzZbz`e„e_}^U|_\€LX€ONuKF€PR{:V€9N„9E‚A?„>?}@A€83~5.|73Œ*-‹*-7*Ž,:ˆ47Š/.Ž25;=Š:*†85ŒB/„6*ˆ?1…59}068/v4,w@+zA€J/|H/vI#‚P2ƒ[:tZ>YB|S<‡g>‚^Bƒd:vm5sk@xp7tp6qlEyj@ql@‚j?wo:qvAy}@{|@r„@psNnwPwoTtNn€QoxPrƒKgqGl{E]}V[lW[v\kmRcpZki[jkTclZacU\_Xahg\hd\lhj[tipw\li\aha^fm_nkWomWxo[uxY|T|t\…‚Q‹_~b|‘RzˆO‡ˆJ|†Ay€@w€Jt„=wwD~ƒI‹J|‰[yŒTyƒK‰K‹…J‘€LŠˆJ…”VˆL’XŽ†R”ŽF¡…@’˜?Ÿ—8¢;”“?Ž3˜ˆC™“@‹—@’L›P’G’—H ¦:—¢9˜©>”©Mˆ¥EŒ¢W†¤XˆŸFŠšCŠ¨?‚©H”¨S‘ U›©Y©N”šV£“V—Oœ[¤•\–™^—¡f¦q›o™¢tsȼzƽ}ÃÆxÂËpÊÅtÂÀp»Åx¿ÅxÅǼÄrÁÑu·Îw©Óz¤Ñq›ÍkžÇw¤ÉxŸÁ|šÄr¼k”­qŒªn‰¤aŒ©m’«g—©f™¨i‘Ÿm…™m…Ÿe‹œ]ŠªW†œS…ŸO’žX•ž^›–]žb¦Y«_¯e›§e™°_§®i«²b°©Z¯¥^­ž`¦¡\ªŸ\´š\¹’R´Y¶™P¯”O´žS¼L³Y³“[®‘V«X°”M²†P®‰P«Zœ‚W¤ƒSž†W wa‘yj˜ze”}^ŽzVŒ{Pƒ}[ƒtR{rW|r_vq^tudqxaet`cubiibnhgp]lj[lo^ja[_d\`ic`keSbdW_[b^_[a[^dYrV^pZ[v[btaa€_`a`|UW~\YxQK|IV?Sƒ:Jw9Lw=€=8}=,u<4}2/ˆ22‹0113Ž4)‘4/‰.&“5(71”2+‡=%†<"ƒ:*…+2z-2‚,,3,80x9$u9/zD(F)…F*ˆE.|N5‚N3|R9~b@ˆc9†g6‚a:ze:zp1wi1}sAu?wwB~tA{v@z€?|y?€wEFw„HqxEw‚Iv~NuzKlƒMdxEhvA`€EdyIfoK[pY`wUesWZpW`qVZfTcdUa`\ZkaUq\alajimbdsj`}blzcdnn^ppb|i\vrb„pbƒtc‰{V}R‡yR…ˆQ‰‰]’T„K~ŠUw‚N{IwˆCw~HuJs‚Km…TuZ}}R„{N†|I‰|P‰ƒOŽ’K‹QŠˆZŽŠR•‰S“„SœƒG¢G“OGŒ@œŠ=—„K–M–’H‘K’G™R•U¤žFš§Bš¢BŒœQ—¥O’™WŽœT‘›JŸH„£L‰ D”šJŽ T•¡U”£Rœ–Pœ’P›”O¤Œ_¢œ]—›hœe£aŸœ^¤£j—}ÁÍ{ÁÎy¾ÏxÈÂyƽuÃÄzÇÂmÉË{¿Êp¿ÈwÃÄnµÆx¶×s±ËhŸÌi­Ép­Ët¦ÊsšÅj›Ám“·h—ºd—¶gŽ·h—µf’®eŽ¥m“©e¤g†®mŒ«mŒ£e‚ _‹¥[Ž¥b˜™[’ Xˆ•c‡œX˜¤_š¡`’Ÿa¥§a¨£U°ªT­›V°š\§¨W£¤Y§š[º›^²žW½•a²¢U³•U¼“M¹•Z¸^¸’]¸‡c°—Y­‹S¯ŒG¨‘\¨‰Z›‡\©yX®X•{[ŠwhŠ{gš`”u_ƒx\Œwco\~lVzmWzv_wtYdm]jp\ht[^d\k_aigjoVusammdiu\ji[Xo^[p^^nOakUUfKjYOzXUw[YuV^|`drb[q`Ur`QrVWsPVyBMx@TsJKrB=xBAyDAƒ;2z;->14>‰4:‡75…9#‹7)†>#Œ94Ž1+‘B*?*ƒ9+€9"Š71…69y5;€+9=,sC5B's=.xD!}O.|G$zT.{R>~N5y[>†Z.†f<Že>~_-‚g4„s3€y9rs"ƒ44ŒB+ŒD/<3…7)…;3‹?3Š=8{35y27‚99€E6vC*zE!sHvJ vN&xT1yT;|]=„[2€U+…Z3ƒZ3‡j0p5n6tq@ws>v|Dpu?soDmkFvj8zh8€n9ufHmr@op;ksK_kL[vL]{NexN]rEb{HYyH[}J[|QcrVhvRdoMaxTkr[gjTbiVYcYUlfUjiYmp\`gQafUcvbjwddobSmdRviWxt\zq[v{_€{Y†~[ƒzP…vKvsIwUu‚P€|R€G…|I}|J{zMy€LyvQ„xR~qcvtc„…R…X…{M…ƒG‚P’ˆX˜‰NŠN}LŸˆAŸƒCŸ†?˜ƒG–€=“~=x;–~;˜zDŠƒIŠ~<‹†>’H”’D¡‘P˜ŸQ“šT¤J–O™•V™NS›[ˆ–T‰žP™Zˆ¦P”¡H–¤I•šP ›Q¤X—£Z”•`šZ™Z—©jœ§mv½ÊuÈÁxÇʆÅȅËÐ|ÄÏmпuËÈkÂÊvÇÆh¹ÅqµÆo²Íg²Ôi¥Îr³Êm¨Óf«Ìf¤»f›¸u¡Ål–¹u•µv¥·u¤®q£°q–±i›·mš¬bŠ´s‡ªlªwªqˆ£jˆ§mˆ£_Ž™`‹œa‘›]•Ÿfš™Z¡‘fšši¦¢_­ W¯™f¯¦a²X¶˜\¸–X¾’d®^»™^ª”R°–ZØT²Vº’g²\·…b¸€Y³T³J£{V |Z¡sV«zT²zX¡ue“rY˜wTwe…om{dgŽqfiZ‚gczndulOok[ql[maZf^big[`fdhc`gai|\jkcptSmqT_g^\rVaeTd`IYeIaYQwfFhdKng_uYPhVMn`ThZJhSUjSSlKEsXIrICqE*‡I*‡G)Š>+ƒC3‰9!ƒD+ƒ=1}E4‚7.w;6Š@=‚42u>2yD#oMvR/vO5ƒP-{\CzT8z`AyY6zXAzh/…k8xq3€rB{n=rz>px=i{Gqr;rv@tbCpg;yhLnlAmm:kg9on?jhA[t?U|FduH[zR^|FcqE\{UTtPXySgvTg}W^tXpm^aqVkk\^\Zde_Sad^`ldSgQZqZ`|aVufZwa`re\sgb€u]xwc|px\}p\~pYtrH‚vGulUsvW„tM€rRoH|tP„zH…|Qƒ|XŒlSvvinz[yƒS‚‚W€{Z~HŽ~R†L‹‰R‡ˆL€F›v@”}D˜{@¢wD™‡A=ˆ}<”yBƒJ•„C•u8•‚3•D˜Œ8šœ@”IšU‘¤T˜¡SˆšV…’N…‘L~NƒX‡˜N~—_“S• Kž O £T©¥O  ^šŸUœ—b£^Œš[œk“§a …ÃÈzÈÄ|ÑĆÍÏyÖÙqÑÒtÚÆqÑÆmÇËxÁÆyµÂqºÅp¹Çu­Êg°Ôe®Óo±Óh­Ðq¥Ái¨¼m­¸s£ÂpœÇx¤»u¥¹z¦³v˜³m™¶b—®f˜´sµo’®j‹ŸvŽœn“Ÿm‡žk…¤b‰˜]‘ e“šhŽ™n™Œe¡‡f§“d¢gªša¨–[´ f¿ž_ºX³‘^µ•W¶ŒV±^®Y¸‘]Á“X½ŠX„aµ~^²{W¬X²S«|M¨rX¬q[µwT¯sU§uc•sX›j^jbˆbf…_j„ah…i\†^_~d^uiSgfWh`Mh\QhbWh^_c`_iYfxdiv_doXilTrsQilR`oMafP^^KcYKpdLoeIimSmdTf^QoZJr^AqdIcYBf]Ki[AnZ>~M<|N9sD0zI4{L;ƒ=:‡:4zE=zE>|N/…D$€K)vF"zN#zF1~D1ŠK'ŠD&€D.‚D0ƒG.€;4x@094wB7}>+‚K1vQ)tS2vZ2†T9‰[:}U@{\?ydB{bA}l<|o6yr9}i>vsAmoDpsAoz=}w9|sAtpHufDmc>skHrqIpf—€DuD’tEy7š?¦‹<¢“E™˜N•”Yˆ–RŒžQ‡•Zƒ’]„ˆU€ŽX‡–J•F†”S…N“™V›šR—¤M£¯UŸ©\¢£S•›Y’˜\Š cžZ˜ž`¢„ÏՀÎՅÍ×{ÌÔqÓÔrÈËvÊÏzÑÇiÃÉm·Ív·ÉpÃÂ}¿Êw´Ôm³Ùb­ÝkªÍ`ªÔm Îq¢Íw­º{¡¿w®Ç}¥Ã…¦¿w™­u“®i˜½h’¿o˜¹hŽ¹l˜«sªoˆšsŒ˜y‚˜fŠ•jŽ[Œ\›šdš”h™˜_¦˜jªn¤˜o¥Ÿc¥šb«œe°˜hº¡f­’q¬—f®l°‡Y¶’^ª”_¶•fµŒ]·}kµ€`­†X±„Yµ…W«uP«pV¯uM®hV¥zYªvb r_šeYc^‘dl‡h^ŒfdŠndxp\bcjj[k__lYVcdbhaThZXlZZpbde`mkUom__tNcuZcsOkiNgeZb]DjbCc_DjcKu[JqjMrfGlkCf`OgeOpcEj]QmXzP:N>zO7sF.pM1}H;yF5vRBtQ6V4„O1‚L)~T+}G!€Q2|C9yA6|N,‚D4‡;,ŒA-ŽG4~B:x3-t4+s3.‚J$P.€V3€^'„T5Ša3|g6€Z;wm?t`>wgAqg1ƒkBuqGlxKekNiwAp7pzGt{;pgCllGshEddEon9sb0lk1jy:XsFO|QRtST€L`lUijPcyJZoZfyTex_jve[l\`hUseXjlUddUf]`iVcgSi`]gcUhg[yaau`[nSso`|t^€uh{zfzplknnrnZ|hWvwGymRxqPƒvN{}K„kG~qLyMŠ|P|Y’‚Z}uV|rXvƒU…ƒQ†…a‰]‡YL’†M•F’€P‰P–qI“€AvJš{Jw6w-Št<Žq>—yHœq=œr<‘„@‘~7—|;‡F”‰L—”UŽ“ZŠ‘OŠ_‡…X„…Wy’UšTŒ’\~’Syš[‹[”™L£ŸT— SšªV¡ªV›¢RœYš©[‹¢\ ¢i©…ÇՇÊ×}ÉÐ}ÑҀÔÇsÍÈl×ÊqÑÃoÏÑn¾ÍÁÎ~ÂÂpµÐq²Îq®Õ`¯Ý\¨Ùh¥ÕmªËw£Ïq­Ìv©¿~±Ç¨ÂŠ˜·„–±z ¾uš¼m—Âs’·{•±u‘¬kžoŽ¡l„ªt‹£l“•b˜‘\^œiš™g˜k——a¥˜f¡—j§šg£m©–a«™c·”rµ—r±Šy»pµ…l¯d«’g´•c®‹`´€l½wfµ{Pº‚JÀ~I¼{G¯mS²kS°nQ¬tW¬sU¤nZ‘bYg[‰rhwe…e‡we|bdx^fm[`_eek^cn\fj``gfff[be[kjaid\\tR`rXZjU_oXZcYc\S_cAca>pbKmYSeaNk`GrhHnmGkjOabI_SRkTIyTDwU;qJDuB=yO2nK*uH.kN:jNHqPFkQ1tU-tU.€J/vM0{N-€Q2ƒL6‡H2zH7zJ2‚”s2Œp1n;•kDŸhG›r;‘@‘x@–w;~E’€OŒˆU„‹aƒ‹`‰}S‹[~ŠY|”[z^…–YyŽ_~—ZˆžU™¨V£«L›¢Uš¡\–¦^’¨P˜°Q™¦V¥Vš›b¥‰É݇ÈށÆցÑÑyÕÈzÑÊtËÌpÉÃyÀÁsÀ͂½¿}»ÄmºÃl©Ëb«Ïj¢Ún±Ðl®Þw¨ÎwÊ|¥Óz¦Á}¨Ã¬Ãƒ ¿€›®…•¶³v“¯qŠ©€‡Ÿs„«oƒœl•˜h¤s…•eŽŸaŸb¢šW •fœžiª™d®šY¨Œh¦œm©Œl£’l©Žm¨’b±“q­ƒx¬Šq±u´Œn·€c´Žg¦†c±€aºƒc¹‚[»y[Ã}TµsN¾xS¸wQ°uU¯|Q¯qN±tZ tX•gW–if™rb˜{`‚}f‰tc|qfhehehglZej^gc^nn_ok`nahja[afZcbWrfZe\[e]^`^`^ShYU\`KdfI_hHeiYqiKfhHi\DkgN_^>`aFaZ;q]@eWFtT?wK8lC5wL)qA/sG+zL2tM5wKJnO=vP7wZ7‡U8{L3zV9~G+€O+‹L+L2…D-‹::‚72ŠI1xB+x:7=)z3.=&€D)…E-„U+~_;`0}f?ƒfEˆq?ƒe7}rCkB€p>xnMth>hl>tzGfnDck;heEjl9fe=kj@bd5Z`>jd5^o9]h;anNSyKRyFZsL[mN[uLbjXNiZbr_jybjnXXhUcbdm`bahg\U]ie[gVjback^fp_rp\{_^sXhzbYufPwpc}yevv_r}fym`qnayx]€qWzrW‚eO’lY†vLŠjPyR‘tU†ƒ_Ž‰dˆ{`~ycˆe}†UˆV|’^…Ža…ŽU”…R™N“‚DŠ‚BŽwL†q?†p=ƒxG…€;Žl4‘r,‰n2‘g>›r=iMœrO“}Lw?˜rDš{>’mTŒqP‡yeˆƒV~y[„‡\‰€Z€ŠX†Yƒe„Yˆ–S•–[—˜S—ªQ“«NœœW”¡^”¯Z”¬Zš§S™¥c”œ]¢‡×܇ÏԁÐ׃Ë܂ÃÍyÉÊyÍÄzÑƅÊÄ~ÄÆuËÌ|ÀÈq°ÈjªÓq¤Õm¦Öo¦Øh«Ûi¥ßsžÔƒžÏŸÇžÄƒ¤Á†©¹†œ»€“Á‚·ƒ˜­{’£‚Š–zƒšm€i”aˆ“h˜a™b˜‘Xœ_Ÿš`œ”cª—^µ[®‘Y²•_«Žg©•p§’m«rª€r±Šx·ƒq·|s´…q±}p¯‚v°|r±ƒk¹e³d³~U¼vX»nP¹qS³}Q¸wK¼tS±wa«v_©w[¡pb“pZœl`“ra‰xjƒrk…k_}nbzcagadhagelbokbrf]robii[mkXfk\`f^imako[`d_Zffe^chUahFbbGjjNplJiaIgZMcZJ`hK`g@`_:iU5nN7lJ;rD4lB+iC1iD0xR6wS0uP:yU<[2}Y4xM4‚N=~S;€T;ŽQ;K/”G/I+’D9‡;7}G:}A7xB2ƒ<,†8.='„@1‡H3J>ŠX7‰\;}e;‚j:ƒk@e5~l7ti3zj;ycIukGue>npBruAlp?sb:l^@hW7d_9]]:bd;fd=_d;d_AY`GcmN]mJcnF`vBcwQ\lO`m[TrbVve^rbfl^feamgkicnjXjj^hi_jmdfxjru`ln\mmWvbZq`^nd\}fX{dR…rZ€qlwwpz|kwqdwwa{qW…qX†gZ‹dO„mOŒtQ‰sZ’xW’†c‡Šd†aƒ‡]zˆ_‚‡aƒ’_Š–_ˆ‰W†ˆRŒP”•F’ˆ<‘ˆ9Žy>Œ{J’vD‡u9Œu5ˆk1ˆl7•k>”i>’cDšlDžoE“oM—tAœsEšhL—iJŽoP‹s\xVwX„~Rƒ~[‰w_ˆ}cŒ€W’‹W‰ŠW‹SšŸX—¡R—¥Yž ^˜¤\¯V’¦_¤[–¢^ª_—ŠÛâÙΉÐÏ|ÓÜ{ÎÌpÊÌzÆÑsÎЂÊÄvÏÍ|ÏȅËÓv»Ös´Øx³ÜnªÛt®Ôl¯×y£Ú}šÏ„ªÓ‚žÁž¿‚§¿„•¸“”º‡šª—¬€‘¯Š‹¤¨†›rˆ nŒx•i‹”j•Œq˜…d ›li¤—b©šk¬l®Žh¦Œb ƒl¡‰w®“t²u¯ƒm¯ˆo­ˆpª}o©{q¶|o´€s­q¨um®pl­qd´|c¹|X¯v[®nO»sU°}S»rV¸|c¦yb¥yf—sdŒoi–od—ej‚pfƒkd„d`~ekochnfadc\kmbge[sfgpiad`\igW`dbfnW^pUjf_bddbciiS]gJ`nDadNclJ]_OddN\YBX`BZ_JanH`^>kWFbZCpF8mD2uR;f?6fK+jP)~K8qO3vP9zK0‚X,zR3ƒU7†I?L.ƒO%L(B2ŒI/Š=/;447}39ŠD/Š9(ƒ@ yJ%|P$ƒL3‰O5X(ˆV*„`9u[?~_9ƒd1ƒu.{p=zl?wp@moHloEoe9uj;snImt6_d5fh4]h5ca5[`6\_1a`9YlBVe?ZcOSsEbjM^vC]pHakYckQ[h^[kWloWorXkg_chggeflineffrZjcdieimz[rm_nk]~qU{sYurUti]xqcnW|mexvmyoet~^smi…he‰o_‹jYŒm\ŠtQ†lR†i]“xW…‰f‡…V}vdŠ}W‚Ža„TŒ‰^‚M‹ŽYE‰ˆAˆA‰A‰}@ŒƒF‚w?†qDzsC‰q:†f7–o,’k4œk<o;Ÿr7œwJwDvM”m?wBxG‘mNsa•yRŒ|S~VvQ~Z•„\Œ\’S”‰S‘N”ŸH¢›W—O–ª_¡ž_˜ªZ§W› V¡¥V› X¦sÛÒxÝՂÙÏÊρÏÍvÌÌzÚÐvÖÉwÑÐzÏØwÑӁÊÔwÈÏw½Îy¶Òn«Õx­Ìq©Ër¬Ö|¡×{«Ê„ªÈŒ£¿‰žµˆ¢¸Ž•´”•¨ˆ’¦…†°‰¬ƒ‰ªŒ ˆ‰‘w–“y—‘y˜‘™•vŠp¢“r¦˜s²”i¬k¢‹n§Žo§ŽsŸ†v«†u¨’w·‘g´…t·}o­‚m¶zl­i§~v¨yw¡|p¨mp¥hb«ohµli®u[¸dY±bg¸kc®ub¹xa´vb£tažm]Œod…sg†jhŽbsŠ\nwfj€llyjl{oivcdviXk]emRblXbkYbd^Z]ecblbgtU`nVabhe[iq]bmR`lZ_oQ[pM]_LT_J\]A]i6WfoS9jB2rA#vM0uR.uO)|O1†U.€Q+zP.yP=‚U6}N'|M-ŠG&‹D'ˆ=2‹E;‰?6ˆ4)ƒ6-B.?+‹C,|K$vL$|R)yZ€S!P-~\2}Z-v`+€c+yl2}pcd5mh6rj=ntAbo?`l;Y`.Y`0\f1[].[X0b`4cf9_iG`fOZoJ_nFckJmsMfqUci]gd_ieUrk\ig_pqdpummggkgtlessgphadkgjmenw]qtZ~xZ}uWynW{kX€tUzr`xii|mf‡ymƒ{bzp]Œlfs]i^q]zqL…nWƒpPƒ{Z„|Y}UxU„wU…T‹\|R‚€P†…K‰‹@‡‡B|‚8€‰8}‡>…„F‚vB~uH|u;xj0ƒd0‹i'—j;”hA”r=u;™y@˜t@ŽvE†p@ŽuNŒxOŠt\“xZŒxS“€Pš‚F¢}M™ŒL’\˜’Q‘ŽV“‹Mš—M”U”‘Pš’T–£N ¨SšŸ`—¡Z›§Z ¤^¢™\¤†ÒمØ؂ÖÒzËÕsÍÒpÒÎqÎË{ØπÒÎy×à‚Ò߈ÍÎzÊÙ|ÉÏo³Ëx¬Éx¬×o±ÆzµÆx±É~¨ÌŒ¨¹€¨¾‡™³¢¸Ž²ˆ”¨~”¥€‰¤ƒ~®¡‰¥€‘•€˜–|‹v‘•v—–y‡s“Žr¤Œzª•o±–w¯‚i«Œt…}£‚s¨ˆx®‹y°h»…r³ˆf¢k¯ƒtªvj¬tq¤vlªjp›rt§hg©onªke©jc«mZªhY¤jkŸq_¡hl³y_ f`˜gj“pgŽkh„m]ƒhfŠds‚gpzdqvceyfb{a^u]Sg]S]PYh\a[]\e^cdml_sXjgbpahhabs\asYXoJXsGXfNVfN`lPZh=U`GTeEZcET\CSh=]g<]X@^\GfYHoM?j[=qW4vD(lB/rI1rP$~Q3sL6L)R6|R=xO1|R.ŠE(C'„N/‹@*’84ˆ=2~C+‚:5Œ:,F1ŒG ƒW#‰L#~U|Y*‚U[+ƒ]0Z#{a/sd-ps9vk5s}3cu5``0nl*ln.pk-`s9]p>er=bd5ba([m.dd,gk+hf:arXrKZiO_oHbnLduDooLmr]ig]xbcnqalhiqnjn]ivdfqcstmnv]nj`hgWjee{q\vuMvRuave[|qgoa}vboiˆik„qhƒqgykjygƒm\’ejˆoY‚mVcMoLkP…}_‚Q‰yPXƒ~Yˆ†^uW†€U„‚GƒBzwAƒˆI‚ƒAuz?yxEr?yqJ‡n:{t+{j(„s#™b2–k;‰f>“w5’zCˆzH‘pI“tH‡jSŠs[ŒyL–qZ~M–uN”zZ“|F¡‹L¤†[ŸŽK™~H›‹Oš’D¢ŒJœ‹T™”J¤˜DžY£V”£^˜šX¥™^™c¤€Ï܀×҂Í×yÓÔyÕÖzÜÕwÖÚtÕÞtÛÕyÑÜtÎЀÍÔ{ÊÓoÈÊo¹Òs´Ìp³Õt½Î|½Òƒ¶É¹Á‹¬±ˆ§«‹®~Ÿ®~—³|Š­‰©~‘ †Œ¤ˆŒŒ‹¡‡†˜~‘œ{™zšˆ“Œƒ•“‡œ›|£‘s¢‰vªŒm¤„m¢€p†w¦‹xª‘y­Šn­t±„i¤b§„eªtp©qp«ijžjr˜roŸoo¦to¦ps˜cjš`m¡be¢^l¥ae›`d¨op¤tf¦k`œcim`‹gbŠb^ˆgl‚hh€kpydf|g`|bbrg[a^X^UZbU\]VdY__Yjgbtd^oifgendim]aobed^YgO`cQUkM[eDUlCRdGS`ET[IQXGWZNQbLJgIT]*‡>&?/‚@,€D.‡N*‹I‹UŽJ…MuL&tS)w`&v_$qi'pf*zj0rj/fk.ku)`s,dm)jr,br#bl1_u1hp3_g5`k1[g,\d1\q$]k-cp/hv<`m=[oGfoFdqLngJtqGioIlhKukX|oSrn^qbg~^ruapv_sv^uzhwvfoubwsb…lXƒtW‚tPvY{i^vdhwgjw`brjewmfŠkqŒqzŽosjdŒuc‡qh“hf‘h]ˆdVŠbV‚bVƒeW„saypexWˆ„a€ZŠve…|^ŠvX†wSƒrG‹sKv@~€Cu~=|z?…~:Œs=ƒo7ˆq0ƒk0m+”n:Žh;Šc=†o=Œo:“pH‹mOrHŒgR‹mV“oLœnR—zOž{Z—x\œ…O¢…Iª{M¢IŸK•ŠPžJ•ŒF K›‡Oœ‹Iœ’T–W›—YŸ•b¡›c¢[ž‰Ð؆âÞ{ÐÙÒÒ}ÏÚzÛàsÍäzÍçvÎä{ÏßyÏÑ~ÒÙzÍÎvÌÅoÄÎxµÖs³ÊxÁÐ~­Â“­¾Š¶´‰¨·€£«…¦­|˜¨„–¯†‰¯|Ÿ…œ}‡©Œ”œ‹™‰š{Šœ‚Ž†sž}ƒ™ƒ}›†œ„Ÿ‘tž”}°’q¦ˆr¨ƒk¥‰oª‹k¬Šu±…i°†o²‚i¤‹c¦ƒjŸqs£rq›oh“og£ja˜kk˜qy¤oc¡hb¡i[£ZhšY^¦cdgnžqgžoo¡uf—lcˆh^„ec~gcŒ^e‰jr‰ik†mkuqjmeelnXod\`NPhUPXRZbYU`lYal^lmbjfbncXbeWn^`jQYgQ\vHKnQQnJPh>Xq?JiSQeO[aCVdHVkHT\GPe>`[CZ`CiX@mb1gY,l[#oV"sV"iHzGqN0vV-qK)uU3uQ6†P*‡P)‰V/K%†Q!‡B!‡=*?/‹I)C&†P+†P"ŽQQ‡R†K'~Y-uW)xa$qa+ej"l_+qm8od)me1ip-_r&_k"cq0[m,]m-Vh2dh>Vl&[]0Rf'Qd&Zl+dv4cp@]jDek:fhGadCfnJjfL\rJsjUll_liYyha{do}mh{e}u`up[xrdn}curczzUlPˆxU…}K{wW†g_€neufspeg~okwok‚ju‰cmskfi€tcƒpbŽpkŒcYŒ`Rb\ˆdOlXƒo_xjUˆpT{V‰†ZŠ|X„xZuM…lL‚}QxxMwsBss?|vC~tE~rEtC„p<v9‡e+€v%ƒj5qB„mJ‘qH‡kL’vH€qC‰sBuQŽyK}Tš~V—r[šp`¡„Mš‡R®W¥vG›ƒI ŠQV‘‰JˆK¢ƒW“ŠWVžŠQ’aŸ–a§‘c£]¡©W”ŠÝé|ÛÛzÛÏyØÍxÖÒ|ÍãyÙêwÕä†ØӇÉцÆ˂ÉÌÏԁÒÏwÆÒw¼Õz½Ïx¸ÉŒºÍ‘ªÀ”§¼…®º‚¥¬«¨‹™£ˆ‘¥†ƒª}ƒ£ˆ‹š„ŠŸ„‡‹“Ž†”‰”–|‡y—€w¤}„¢ˆŠ¤¡z›r¤y§„r£…t§q¤†i ˆn¬ˆl¤Ši©‰f®Šq«~pœvh•il”sm•tinaib™pq¡fcšg`žgc¡\`™UdžXe jpªnn¥mdšei™l`Žldnozmmbt‚iw‡qyzlrtmdrrgkg]l]^nXQiQQ\YXe_[kebea^hldcoXhdScd]fYXpYYpYUrUIvEMpH[qFMrOMtOUdOY]@RdCUfISeH]`:Tg@Z]9Vb6Xb:g^4p`#nU+jT$kS*jMrU$yM'Q2zL-~V&}[+za.\-€\'ŠJ “?(=*ŽD-‹I,„D1N*ŽH#…R'ŒK#†NOP${RuQi\&i]*j_._h/fk(^e'di*ai(Tc/Ra0Pf5Vc4Ql|l?ys>um?~l@}p2xm(ƒt2€sAŽuE…nNŠtH‰zK†|K‰zJ‚B}G›xK˜ƒY•„[–uY›xTž|S©yJ£xLŸ‚L˜‡V˜„NžŽM¤„Q†U›U ‰V¨’b©‘\§–_¬‰S¢–K•£S™€Þá~Öæ{Ðß~ÒÌxÊֆÖ؀ËêxÚê}ÔçÈىÐ̀ÒÎ|ÇLjÆÇzÇÐwÄ؁·Ì‰³Ò‡²Â†¯¾Œ©µ¬ºŒ±­|¦¥©«—›z£x‹–’„†‘„”ŠŒ–‰‹‰”™ˆ˜ˆ…š„„”…š†w Ž„¤‹ƒ˜†u›‚t ƒt x¤ˆy—yn§„x¬ƒu™u–„u¢twž|lžpe–nf›ii”mnbkak™i`ªad¥`d¨`^›Yg§bc¢[k§pv›fo˜er”mn’oh…pi~pxpzvus}kxzu{~qo{bjqfkec\maas]W`aJ[UPa]VidYh`XfaV`^VbY^jV\laTdXPp]LvFFsKF~IRrCYyLUvPUq=^_8TlAS]CN]IWhGM^4_c;Ma0Sb9X`&f[*m^*n\&iS'jLsUoVyQ)vX"X „`{^"zd/z\*ŠSˆG(ˆK#†I+–R#’L(ŽU%ƒZ)‰N(}U'‰R‡P#wTU|ZpW+fZ&`j0]l)X[$U`)Um.ed2_c[i>Uf2Uh/Qd.Yg-`\)h^&bf&Zf*Vh5]c@XfETn;SsARgFUl;bo=hfJhb]_kaXk^b^drWmtasuc€sj|hi~kWtiTrXrSƒwPwwV{z\}{\|s^yjevqf€zg‰rkŒth“ljˆdcƒ^iec‚bh†kl„jaƒeT}fWd[…[Q€_I‚`P…pYwp]yme}s`~lV{qO{|PmuPlwTltOrfNy`YrXYm_NghMri=qb3tc3qg2h7s?‰pJsPŽvKŽtG•oE•tRŠ}QˆzH˜€H˜}N‘„O›L™N ƒQ¤v\£v`©wZzPˆN’E¢‹F«ŒF®…N­ˆU¥ƒP£M£ˆO¡“H¤˜J¡ŸOž˜V§€éÝxàè…Ü×}ÜÞxÙÞ}Öã€Ôà|Ðà{×܃ÑßÞÑ~ÒǁØԈÑÓ}ÓÓ}Ñ́¾Å„¼¿„®È”§À‰¨¹ƒ««x«ž~¤¤}¦¥†ž£|žš‹›ƒ––‡’ƒ•†„„Œ‚“}†Œ†ˆŠ–~™€“{}™ƒ€™€v–|˜‚{ ƒs‘zt™uu¡€w¢€l‘pq”sy•po‘|o vdŸdg˜_i•_ežhs—Zbš_e˜fjšf`¢\h—_e˜Ve£hj dr•Zv™[z˜aq…gs„cqznpxnxrukztx}rhymkmVllVjj[Zh_a`\Xla]g_Rq[VqaRfa_c`[lZ^oNOjPZ`KYaNVsCWrELxNQtNE}@PyEbn:]c|`|gDysIvBjI‹yN‘~Y“yWžwM™‚V€N‰J‡ŽTŒŒ\—~_¡|`¢ƒh¤Šg¢†[¦„]˜|Y˜zS›€[ ‰K¡K°€R­PžU£ŠV¬Œ\¤…S¨‰L¨ŽV›„Þé‡æìƒÚí„Ùâ†Ùè€åââãqÙãvÛӄÑ×uÓӂÚρÐǎÓÍ{ØÌoÈÍwÂÐ}¿¹°¶¯ºŽ³±ŽŸ­y«©³™z«§zŸ¢šœƒ‹™ŒŠšŠ—‹‘’Š“†„Œ…”†‚˜|“‚™|Š|€˜uˆ†‰¥z›}ˆŸ~¡ƒ~Ÿ€‹p…£z|£lv¡rlŽxs’hz¡pl™``žXh¥Xo£bo¡_u˜Uh•dgšYfQm•Rc˜Rf§Pg˜Rm¡Ji•TyavS€€Vkvct|auyjtpjjp\u~Vkrbjlgke`mk]paer[ZbcVhhOZeNczVapZWlN\wKgkRYpCcgJVpLZj?]q=OzAWnGL}CUg@W_8bg;Sf@\]CXX?He=Qe;Kh3Vl1Z[+aU&eV&_d_X\_cWbYqSzOW^yS}P‡SuX-z\…K%zO…C"ƒR&|Z yN~W'oT&uRfY"fglcx]iSlZhehgWc+Jg)Oe9`Y1eb2Zd?a`=jjC_s7amFZh8cm;^m3k|3Yv4]|0Xn7VrIYmLcfB\pDad:TlM_^CZhG]cS_dYgfPgf^]kmalrhxzuwo{xvxttqm}pf„xc„wfxvV|x\xyaƒpgŠwdˆyd‚€W‰k“ljˆci’kg‹eo€btin\jh_–db“cQˆdDˆbP‹fH|eR†gKzmS~p]ŒxcŠg`ˆkXr[Œt[€sX†mR~mWzncthYud_waRvkGrgA~nJxm=†m;ˆm7‚mCˆtC„gO‡mIoPŽtV›sL’€Wœ{K“‡]š‚XŽ‚S‡Š[„[˜†`¥…^©‰a«Z©z^¢‰`™„T ƒT WªF­ŒR¢€P¤‹V¯‰X±‰ZŸŠZŠZŸY–ŽëìŽâî–êäççŠëކåۂÜÚxÝÝtàÚ|×ÍzÓӄÙNjÓЁÐʆÚÇyÒΆÇÁ†È…ÇŌ¸¿ƒ¸Á‰©±…ª§z©¤ƒ ¯ƒ’­‰‰§Œ¢Š–ª“”¢–Šš‡ˆŽ†ŠŒ‘€’x… }{¢{‚œ|‡¤ˆ£}¬~ƒª{¢Ž£{†ªnˆ­p{«w~£vƒ˜f|˜fs—_lŸdk£`c [k™cf [l˜OpŸSt™NmŠSu“Ln”Mp˜Lg¡P^˜Cf›GvRxŠS|†W|„Svt\uobnsawpckqcfvUilSombti]uidokes`_he_ihMllKdsSfq^]sYh|NdsM`hM_f?baAbeJcuKZwD\nBRrBRp:Wa>Ue;V]9IY=MV:HSBN_>VYdcD]e=Z`AYkLagGmtJoqQkpgksmluoi|wftutuurtzqvƒvm„xg|c|c}sg‰qc„{j‹ye…{k‰|a{`‹mg•bc“akŠdg’iknq•al“fa“a^š_\‘kNbS†hN†tM‡rS†wZx[‹|_•pg‘nm‡ya~_uT‚tZunbwxf‚q^€lR|iU~qK‚lR{qJxuH~v8€k9‰r>iJŒrP†jQŒpLˆvQ’{V{S˜…TŸ}\™xd„Z’z_~g”vj¡}ežƒa›‚a¥|bª…\Œ\«…OªŒM£‹Qª…Qª~Vª…T±„_§Œc¥…[Ÿˆ[¥†QŸêóêî…çàŠÜâˆåçŠå݋çå{âقÔÛzÒψÎʈÔƉÓÓ}ÐÐtÙÏzÑÀwÇÆyË΁»ÇˆµµŒ­¶‰µ®‚«°r«®ƒ¦°•¤‚›£}‡Š¥Œ˜›Ž“›ƒ“ŽŒ“‘œ‡˜†Š¤Ž–…Ž¤y„¤‚Š¤„Š¥€€£x…¨qŒž|¨p€ž~z™zu¢ws–pr—qx—b¢ei—hr XlRt¤ThžR{¤W{œQpNfNlšGb—Vm¡MfŸLcŒPb“Si…KkxJt{RnsUiuYtwMhz]tnZby\tzWjwYvgXq_eze_tmWzhOftGivMk~WXnU[{K`kSWpC]q9__?__I[dCWpMYm9Sr;Qo?[a@Q\:Pc@TV8O]6YN1H[8Ld:S]1Sc.OX(P[*SU%fZfZnbrTsNnYzRZy] sSZuMxQ~Y*qO)K!VOvO|Sl]sVcVnYeQ"jV)hd*YVdU+dX*gc%Rb'[`.\b2]a2Xb7cj7]l5Zw=_gEfhHeo@lmI`m9bs9c€BVI^z9Uv<]aGe`Nc`A\bFbeJY]JbhHcgRaaSmeTuoXpspo|pn|fn|itwppuxpntrw‚h„wmt|cv|[…pf‡nd‚tb{yqpsŠ~m‰vfŽgdimŒmq“bl™ir“Ynœ[]Ž_[ j[yTrLgQƒj]mSŽp_w[”mb”tiu_ŽxU…zQzwW{sS€je€h\ˆmaƒgV}hJxcMxoR{pR†tEiK{vElH€tO‚pKmW‡tQ–nO“yV”}asXŸYŸ…O›{Oœ…axk“{dŸ‹]œ}i „i›}m¤„eŸf¢[­^žˆT©€`¡ƒ^žU«‰S¢{\¨‚S¥‚\¢ƒR˜Ýñ~ãí{äìƒáڎß߉ë݅ßۄ×áÜӂØσÕȂÔ҉Ï̄ÌτÖÆtÕÃÇÃyÂÈ~ÈÀ„½³|±±|²¸v²·{¨±„›®€›¥ˆ’«~Œ£‡š|Œ•…•‘ƒ‘Ž–’œ’ˆ ’†ŸŒ† œ{Œ›v£yœwŠ¥p‡Ÿnƒ”z‡š~| }Ÿvy˜ry›wvškƒŸa„”cƒž]r¢^kžYq¨Sw WxLp”Tt’OfˆFbNj‘Um”UlŠOhŽQeƒPcReqEvtEvpAmnJdsKisIgzZo{Zqt[poSxadw_cxc_wvTz{SrqEp}J`xQ[vTZzGSuGReFWj9Te4Qh?UgIchG`k?\oGWp=X`6U^3Vd4J[3OV7SP0OW2MY5RX(Ph#J]-Ma%]W!fWob k[lRqUlY +paxfv\{Q +pQqV!xW |J(sN'xQ&V rNlJnIpUm[hYc[dQ!\N#Q\"]\)]Q'`Z&Z\-P\.Rb3Xd/Ob+Qb6Th9Tm=[q:co5ag>mfKglGgt9Zs:bxG]{Cb{IZt>\o9_eEUe@YlGgiNciLdfJedPn]Sid`piiutdsomlvfxpbrsgyoisqlyfkey„nvzirx^€s\‚s`xi{uj‡usŒzgxiŒkt˜`n’\q“hr“`j^jš^kžmZ”oN‘vJ…p[‡w[†s[uT“vRŽnYŒudˆx]‘vR…T‚|M†Sxayn]l]ˆuY‰gL}cNxkJkPƒqT…mP„iFxoI}pG„rV‡kUŠf[‹qS”qQ‘q^šs]’}TzQ€K•€O„\žy^˜ƒ^¡ˆf ‰f~k•{t™{k¢h ‚_¡€X_Ÿ–\œ‹]¡‚Z§€X yY§{W¨‹IJ¢’å߇èé‚èäîã‡íۀàßÚÒ~ÙÒäՂØ΁âՀÙ΅ÙʅÒÐvØÃsÑÍÇÃ~É…¾À{º¹z¸Á~µ¿¶°~Ÿ·{ž®„—ª‡—Ÿ„§x•¤‰•–|‰…‰“‘Š–†š†•’•“‡œ—‡˜§w¥sªl‡žx„š|€œs„—o„œu…—z}—xˆ–j{l‹Ÿcœ^†œZ{¡bz©cu Z| Tv—LoU|šXlŒMl‡Sl’Kj‘Rjˆ[`ˆTixW`pMgnBlvIuy?sqDszL|nBztT|vZwxWolStmZva]ziLtiTpxIlwJe{QdyIe~NVs?_mEWlCPp>Ik7MeELkDWl9ao9``6O^Tqan6gl=dnDhg=fsEWy@Y?f…IiKbwI]jLatL\nA`fLakGZdP[]Hd`Njd\gdeoebsj[pgelqkiwiordnulvilljux_qqdx{hmlesvhv~kvslqin|{l…yi‰gu‹al™anhg–hl™Yi¡l_iY‰iS•vU‡rS‡waŽqb‹}[•~Z’w^oW”rc~]”zRŽ}Zˆ~M‰|SxvR{nVymV†mV}kKƒbSaKŒmK_W…rV‚oK}jP€v[f_m_‰uV‡vI‘oY”p[o\™~W”}V¢†X–{a•ygœj‘aŒk“yr yc£„n§†oœƒh§hš`¢‰_Ÿi—…f˜ˆZšvVžrQ©„PžIœ”âܓäޏå؅ïà‰ìå†á؇æۈäԇãÈxçÊtÙÆvÙÉwÎÈxÑÐ}ÙÃ}ÒÅqÔ¾uÒ¼€Ï€ȼ~»Æ†µ¾‚¨µƒ§¶†ž±‹˜®Š’ ’œœ†™—‰‘’ŽŽ‡Œ”ŠŒ‘”‹†–šˆ‘œˆš—ƒ “¢w‰¦r¤p€žr‚šr†›jŽœnˆœxˆ¡xœsŠ–gƒœe‰ža^†£_xšVxXySv‘]wŒ_xOqHs„Ld‹Se‡Y[ƒT\†V`{HcqHfxGgsBjoHotArvG}zBsuFxnPwlGxiHllFqhRssNplHsmVjyRj~RbwCUs=XzE\@YzJQlIKk=I^CN_7Wh3Uf@[^[o@WlCYl;^vo€M{mLynUqoEpnDpcI|nKucMirKk|Cc€MlxEeyDRpDSw=SnHUl=TqHMg5Vi>Ii9Yl?UfEPo9F_7Hi+Dh0Kd3Bh*Ng5F]2GU0DP*QTBbUY +PP\RYO ]JbSiIgQ cK_FbX +uYdMlL#gGrR$kLjL!`N%gJ%^O^N&fCRD WN!]I+VQ(PI#TP!SB/GH7QL-[D/MA/OS&OP#SU&\b6bV5\a.[l;`i3f`BaiBYn=Zm>QsCXpBil:esIjgBcl>kgB_r;ggC`l?\iHSeTVh\WbXY\Zgfnol[ykexpjxue}sqrqovmbqodenft[ml^xdbzw^xt_‰op~}hwvw†tr…orzehhv‡hm—ad m^’l]ž_^—e^‹nhl[•ja‹mV}V‘qWœc’sežv\‘vf—uc‰~Z‰uZŽ~R†yPzRƒvOypR†xVƒyS€jF‚iT‚[E{gO‹mP€nXŒq[’jT€eT‰hctWˆr^—z[’}PzQ’wSyV•w^Ž|W˜‡Y›b™…l•i™†r–}u–€u–„u™ˆe¡‰h˜c›ŠTd‘†Tž|ašxU“{S—~S˜R£‡R§Šóðˆõëƒý߉öãŽð؋ôلëàƒè܃åã‚ð؅è͂쿂äʼnâІßˎϿ‡Ì¼~ÃÄ|ʾ}Æ´uǽz¾Âˆ¸¼„«³ƒ©­‚ž±‚¢§~ž¥}—œ‡— ›•ˆ™„™Œ†¢–¥Š˜™~•—‚Ž y¤u‡¦{Žªx¤s‡s„–o|œf„”h†‘m“™u˜r“‘c”j•™aˆc|œat—Wz[p›WrHwšKmSt”Rs‰NoƒTb‹bkŒcl}UpzKe€QlXguQvzCsv>j{Lg{Mt|HqqKgp?ej>uc8{f;rsHiqNbwHlzBh}AbwEPq?Kz3Mz>Oj=Rp9\h:On@Nh9Om6Vo8Jk;Cm3Mc#J_"TX,Na(Mc7Kc9NU)QV)PS%DWITPMNVZMUW `RcIgL^FZE_NnWoL_M#nTkW$k]#cS gJ dP ^P#`>%`B(YG^IRS%TI1NE+SE(GS)SN+WJ6]B2QJ,WS%T\+bb4`Y4QT-SW+[c4Wn4`m6_j>[sDVsAPpbd;fb@f`DbiC\`TTgSWlQUh_Qmb]jfac[ui^trctneuqcukxmfjffe\rqamlh|jk{jg€n\oaxp†wu€x}€gz|`iƒef•djša_œmcšm_Ÿda–daŒqbo]–h]’a^j^˜oZšxa™t[“oaxb‰vZq`—sUŽu_‡|Z€sV|iL€uY‚vW‡uQytMyfKbHƒeM‰nQ…{SŒvW’sV“j\‰ob†t]ŠwT“pV’tO‚X‰ŠSUŒ€][˜e™ˆg‘”e”qŠnŽ~o˜xk—~s’ƒq›Šh—†g™‘XœL›~Q›€U‘€PŒƒ\~Yž…Z¬Œ[¨‹õð€ðíõè‹óæ‰òå‘ôâ…úٍíæ‰îá…ì҅çāðŋßÁ~ÚʋÚÖÑȃž~¾Ç½Ä|ɺ{¿µ~ƽ€´ÄŒ°¿¦²…ª®«©Žœ£ƒ˜œ‹”’‡””œ †ž›{¨Ž§}›~‘œp†¡tŠšv†œ}‚Ÿv’ªo“¤tŽ™fˆ™p‹ŸhŒ”v“”q˜q•f™c“ži•U€‘T‹‰X‰L„•Tv•TzšIu“Uf‰Lu…Ze‡[g’]kŒ_i{Zly[mxPbwUjQw~LxuIlrJf~@pnEliDnv8noFyp7vl8np=elFoj:l{3as:fz=Yo/Pn7Nn6Xg0Ug>^h3No1NfAJn.Hk,Gh/Ri7Pb/SZ%T^([d$UZ-O[4Pf4R[$W_$IXIMLZ VJNMXUVKgQdR`N]M gW +mYfQbG$`R"eW#dQZ\&^R(_Dg@#b>,\;[;YD&TL&]QGR,KT"HR4HV8]L9SN+^W`]:iaHUeM`n\SjV_ifced_pb]pkmolseXxr`{gk€f_~ljto`gijghpa`liiymg„hctb‘ogŒsoŽkzŒtuz`z`oˆfl˜gnŽmeždežhY”i[–h[m`‰qb‹ef˜h_‹mT‘r\‹tZˆmW”qX…rQ‘}W–kX˜kZ—tex^„n\ˆhGƒiJ‚h[‡qO|fD‚iE{hP€nKrL‹w]–ySŽq`hg‹ob•}g†yZ‰„a†[‡x`‚†_‡`•~YŒ‡_šŒc}c‘Žg““i„zŠs‘k”ƒw—zj—…\—U“ŒU–†Y ‡MGŽ‡N™ƒWž‹Vš†Jª‘W©îæ‰ïæ€öí…ðå†ñè‡ûރ÷â…÷â€üà€ðׁ÷χíÄßÉȬÏӌÐ΍Ềľ…õÁ¼}¿¸{ÀÂ~¼Àƒº½‡Á·Š¸¹‰©©¨¤“«“–¢“Š ‰¤•~¥Œ}«Ž‚§†«zŒ›|—q‹žmƒ˜p„œgƒ¢c†žd—Ÿh’œe˜šk’Œk‹ŽmŠ…t—‡r›‡m‘cšˆV”‹MŒ„NŒ‹K„’S}šVršMq–Qk›^fŽ]cŒRe‡XbˆQ_‚Vc‡Pg|Tn}Oq{Gz}KuuMmzAmrBon7co:frDpk%aDg>#hBaQ^YPT#SP3QR1WS/QF0YP8\]:Tg5V`6^T2bS1eN.]Z,a_3]f.fi9`f=VmF[gEYgKQlD]h8_b:^h@]h;gc;ah>YjGXfVWea`ea_jbgfb`iajtjqpeno^skYyf_pk^xj_tqnkik_ajafm\kral…lh‚v`km—hq‘^r…dv…\y‡_l[m•al‘c]žl\œuZ›m`“f]’fT’rR›l]’fU…qS‚yR‚t[†pUˆuS‹{Y–tZŸkY¢pb™th‰sbxZŒvO‡kGkO†gS‹fL‡oQ}tJ‚xJƒzTŽuS‰l[’sjmgta˜`„_š‡^–…iš}bŒ‡_…Z”W—…U•†_œkœ‹e•‘p•–r‹v‰†q”‚l‘ˆi™~[š~TœŠ\O•”N”’M”ŒL•M•‰F£ŽFŸ…R xùãˆêã†çۀèæ}úÝóØ{úàƒôԊóã…ðۄñʓå͏á͍àƂÑǕØٍÕÀ‹Ì½ŠÁµ‹Å¼…ľ†¼´ƒ´¸|°»Œ²·‰µª¼§Ž©˜‰ªš¯•Ž¨‘”«˜†°ˆ§Š¬|ˆ§y‡¨ƒŒžsŒ˜oŽžp¥qŒ¦oŽ h”™b‘¢m— g™h‰“h•‡a‹“e’–m“[Š•S›…P–ˆS‘J‹‡[‹NQqœXdMdƒNcŒRk…Lf†Wa…[m~JtyVpzPguItpIyvMszCim8rwEck6ie6jh@dp=lh0so4sh;mm7bk6fq-Wp!Rq&LkVe)Zi \y-X‚9Ro.Ok,Ic,Hq(Wd'PZ-R^*J_NiY_,WkgkZjOc#Q\N^ XV +_XORRMUUOO +_JaT[UhZ _N_FeOVXUU"]SUKcL+bG&g@`@e5%^9&h>!fIbEQWF[OO#HL%TJ2M>-ZQ)\Z*d^,Yf;dY4dP5XU9Ma8V_ZsLNn>Si8Yb9dj9dd;[_G`lNa_N`qW\aYap_\fbXnb_j]kzgcvhoz\rnkuwbofmtkgpbpmog`jl[iebjqfg€oowa˜gb‘dvŽ_t‡ov†jnˆ\w‡cl‹[e_dšqc—uh mk¡tb›gf“m\Žuhn`…d\†d`Žic‹md‰w]‘pQ”lWžxU—sY tg’|nŒmYŒoX‡kNgN†hK‹sPŒoFˆxP‡yQ€zLŠxN’yd‡uXvfŽ€UŠ}Y†‰\‰b†…iŠ†^†ƒi…vWƒU“ŠX“Šd‘\ž‰p‘r—ŽeŠ—f‰q†…f‘|c‘uk¢‰_˜‘ažˆU›‹P¥”Y‘V‰G™•Tœ„R ^©sóävìã~éåîßxíÖvíÜzðҁúֈñáŒíەæՓäјîĒçĈàȌØԆÙɌÎÅȺŒ¿ºƒÆ½ƒ¾¶²¶‚´°Œ°¨ˆ½¨†Â¦†·—Š¸‘–²•©Š¯Ž“¨Š‹¥„‡¦Šƒ¤ˆ~Š§ˆ¢xŒ—t„£iƒ¥n‹žc˜hžd™ži•g“‹a•‰\Œ“hŽ“iŠ[—Š[–]Žc‘ŒXŠWŒP}To”\h–Yn†Gb…Nf…LcyXm}Up}LwxKjvRlkLuoGzqNrs>jv9ug;nd?ot5ar9av2co2pu3qq6ev5iu.Zu(Vp#SvWjcs_t&]|-S{&Ju$Jg+Qs1Sp-Pf$[h'QcOhKjWjcpcf!Wf$McKfP] +YZXGYE]OYJ\O`J^U ZTePjQbHZR$a[]P#[V[P$_N ]E]9\Ad9b6Y="YK"[JJLGQOFKH'GB!NETP_L'ZY0\a2Xb.[\2Yg8Nc=JaANc?Z[7W]9akHamFVrGYqGXmI^a;_]Aih;]`CVfOXnN]jW]fLcoMfiaZse`k^endol\nvcwv`qvmuvhkkknktnfmrldedhemmplzmn‹ja‘blˆfp†mk’moŽdi”bret‘_ngr‡msŽrv’tr op¢hj’jstoŠf`ƒf`‹keŠddˆsX”p]”rb’rX•nX–qYye—viŽqb†v_fX“eO†sSpL†rJuK‰lOŠpJmQŠt[‰uYxX“€X…T‹ƒV’‚g‡‹o‡†iƒ‚]ˆxa†y[†YY‰ŒY“‡_”Žp’c“a“‚^d|_‘|i¢„`©‰[§ŒSŸT¥‘S¡“V–›Y—’R›•`ª^©uöõ~ïã÷äîãrîéwõå{ù؄òօëӌîԘíՏãϒçԘä̊ÙÁ“×ːÖ̏Ë‹ÈǔøÂ°·½}²°…¸¬~²¨…Á¦‹´ªƒ¼”Ž®’—¶‰Œ°‰¦‡’§…Žž„€Ÿ„ˆ¯‹‹ª…‹¤w¥rŒ–u‘¢{‡›tŽšvš‘n”“n›”qœ—]•ŠZ™“[—•]•aŽ—_‡„bš“_—‹T–ŒQ’‹QŽyZy‡RtŒSw„PwwI|yGl‚Bl‰HuuMr€GpoNpsPjmIvsQvgDwn=jo1et?gm5ao/dc4cc,Zh%ds*ko"kg&eg#jh+`d"cpYlXs\i$`h*Rn$XgYi!Yp*KoMt!TjRk[m```hXleaYa^ZSV UWYP XG_DYM +XMVVVS[R^T +f`YPfN\JZUZSRM`TTNUDW7W9]B a@_8XKYHJRNQEGKG$OG#^K]F^R2]T%_^6_`:be3Lc5O[>Rk@Um8Uk8ObEShgf9a^6e`(bl$_o%_q'knbq$df!`ddbig^f_c`h$YoVl]f\i]k OlHgKjRfYqUo`_Vh[b +```W^PUNTQSI +QK +`QX[T^U\ [W aXW_P^ZXVR^N UU +XL[MSM _B]AV= +XG +XN +^C]=TBSNQITLQOWJ\G[D)`N0aP2Z^.^b,W^:V_?Qa + let name = sel#get_filename in + sel#destroy (); + callback name + end; + sel#show () + +let w = GWindow.window ~title:"Okaimono" () +let vb = GPack.vbox ~packing:w#add () + +let menubar = GMenu.menu_bar ~packing:vb#pack () +let factory = new GMenu.factory menubar +let file_menu = factory#add_submenu "File" +let edit_menu = factory#add_submenu "Edit" + +let sw = GBin.scrolled_window ~height:200 ~packing:vb#add + ~hpolicy:`AUTOMATIC ~vpolicy:`AUTOMATIC () +let vp = GBin.viewport ~width:340 ~shadow_type:`NONE ~packing:sw#add () +let table = GPack.table ~columns:4 ~rows:256 ~packing:vp#add () +let _ = + table#focus#set_vadjustment (Some vp#vadjustment) + +let top = ref 0 +and left = ref 0 +let add_to_table w = + table#attach ~left:!left ~top:!top ~expand:`X w; + incr left; + if !left >= 4 then (incr top; left := 0) + +let entry_list = ref [] + +let add_entry () = + let entry = + List.map [40;200;40;60] + ~f:(fun width -> GEdit.entry ~packing:add_to_table ~width ()) + in entry_list := entry :: !entry_list + +let _ = + List.iter2 ["Number";"Name";"Count";"Price"] [40;200;40;60] ~f: + begin fun text width -> + ignore (GButton.button ~label:text ~width ~packing:add_to_table ()) + end; + for i = 1 to 9 do add_entry () done + +let split ~sep s = + let len = String.length s in + let rec loop pos = + let next = + try String.index_from s pos sep with Not_found -> len + in + let sub = String.sub s ~pos ~len:(next-pos) in + if next = len then [sub] else sub::loop (next+1) + in loop 0 + +let load name = + try + let ic = open_in name in + List.iter !entry_list + ~f:(fun l -> List.iter l ~f:(fun e -> e#set_text "")); + let entries = Stack.create () in + List.iter !entry_list ~f:(fun x -> Stack.push x entries); + try while true do + let line = input_line ic in + let fields = split ~sep:'\t' line in + let entry = + try Stack.pop entries + with Stack.Empty -> + add_entry (); List.hd !entry_list + in + List.fold_left fields ~init:entry ~f: + begin fun acc field -> + (List.hd acc)#set_text field; + List.tl acc + end + done + with End_of_file -> close_in ic + with Sys_error _ -> () + + +let save name = + try + let oc = open_out name in + List.iter (List.rev !entry_list) ~f: + begin fun entry -> + let l = List.map entry ~f:(fun e -> e#text) in + if List.exists l ~f:((<>) "") then + let rec loop = function + [] -> () + | [x] -> fprintf oc "%s\n" x + | x::l -> fprintf oc "%s\t" x; loop l + in loop l + end; + close_out oc + with Sys_error _ -> () + +open GdkKeysyms + +let _ = + w#connect#destroy ~callback:Main.quit; + w#event#connect#key_press ~callback: + begin fun ev -> + let key = GdkEvent.Key.keyval ev and adj = vp#vadjustment in + if key = _Page_Up then + adj#set_value (adj#value -. adj#page_increment) + else if key = _Page_Down then + adj#set_value (min (adj#value +. adj#page_increment) + (adj#upper -. adj#page_size)); + false + end; + w#add_accel_group factory#accel_group; + let ff = new GMenu.factory file_menu ~accel_group:factory#accel_group in + ff#add_item ~key:_O "Open..." + ~callback:(file_dialog ~title:"Open data file" ~callback:load); + ff#add_item ~key:_S "Save..." + ~callback:(file_dialog ~title:"Save data" ~callback:save); + ff#add_separator (); + ff#add_item ~key:_Q "Quit" ~callback:w#destroy; + let ef = new GMenu.factory edit_menu ~accel_group:factory#accel_group in + ef#add_item ~key:_A "Add line" ~callback:add_entry; + w#show (); + Main.main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/label.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/label.ml new file mode 100644 index 000000000..b9829fb77 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/label.ml @@ -0,0 +1,48 @@ +(* $Id$ *) + +(* Embedding xpm data into an ML file *) + +let openfile = [| +(* width height num_colors chars_per_pixel *) +" 20 19 5 1"; +(* colors *) +". c None"; +"# c #000000"; +"i c #ffffff"; +"s c #7f7f00"; +"y c #ffff00"; +(* pixels *) +"...................."; +"...................."; +"...................."; +"...........###......"; +"..........#...#.#..."; +"...............##..."; +"...###........###..."; +"..#yiy#######......."; +"..#iyiyiyiyi#......."; +"..#yiyiyiyiy#......."; +"..#iyiy###########.."; +"..#yiy#sssssssss#..."; +"..#iy#sssssssss#...."; +"..#y#sssssssss#....."; +"..##sssssssss#......"; +"..###########......."; +"...................."; +"...................."; +"...................." |] + +open GMain + +let main () = + let w = GWindow.window ~border_width:2 () in + w#misc#realize (); + let hbox = GPack.hbox ~spacing:10 ~packing:w#add () in + let pm = GDraw.pixmap_from_xpm_d ~data:openfile ~window:w () in + GMisc.pixmap pm ~packing:hbox#add (); + GMisc.label ~text:"Embedded xpm" ~packing:hbox#add (); + w#show (); + w#connect#destroy ~callback:Main.quit; + Main.main () + +let () = main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/lissajous.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/lissajous.ml new file mode 100644 index 000000000..9d6cf3b1b --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/lissajous.ml @@ -0,0 +1,48 @@ +(* $Id$ *) +(* Lissajous $B?^7A(B *) + +open GMain + + +let main () = + let window = GWindow.window ~border_width: 10 () in + window#event#connect#delete + ~callback:(fun _ -> prerr_endline "Delete event occured"; true); + window#connect#destroy ~callback:Main.quit; + let vbx = GPack.vbox ~packing:window#add () in + let quit = GButton.button ~label:"Quit" ~packing:vbx#add () in + quit#connect#clicked ~callback:window#destroy; + let area = GMisc.drawing_area ~width:200 ~height:200 ~packing:vbx#add () in + let drawing = area#misc#realize (); new GDraw.drawable (area#misc#window) in + let m_pi = acos (-1.) in + let c = ref 0. in + let expose_event _ = + drawing#set_foreground `WHITE; + drawing#rectangle ~filled:true ~x:0 ~y:0 ~width:200 ~height:200 (); + drawing#set_foreground `BLACK; +(* drawing#line x:0 y:0 x:150 y:150; + drawing#polygon filled:true [10,100; 35,35; 100,10; 10, 100]; +*) + let n = 200 in + let r = 100. in + let a = 3 in let b = 5 in + for i=0 to n do + let theta0 = 2.*.m_pi*.(float (i-1))/. (float n) in + let x0 = 100 + (truncate (r*.sin ((float a)*.theta0))) in + let y0 = 100 - (truncate (r*.cos ((float b)*.(theta0+. !c)))) in + let theta1 = 2.*.m_pi*.(float i)/.(float n) in + let x1 = 100 + (truncate (r*.sin((float a)*.theta1))) in + let y1 = 100 - (truncate (r*.cos((float b)*.(theta1+. !c)))) in + drawing#line ~x:x0 ~y:y0 ~x:x1 ~y:y1 + done; + false + in + area#event#connect#expose ~callback:expose_event; + let timeout _ = c := !c +. 0.01*.m_pi; + expose_event (); + true in + Timeout.add ~ms:500 ~callback:timeout; + window#show (); + Main.main () + +let _ = Printexc.print main() diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/nihongo.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/nihongo.ml new file mode 100644 index 000000000..48f7d8c22 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/nihongo.ml @@ -0,0 +1,31 @@ +(* $Id$ *) + +(* ¤³¤ì¤ò¼Â¹Ô¤¹¤ëÁ°¤ËLC_CTYPE=ja_JP.EUC¤Ê¤É¤È»ØÄꤷ¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤ *) + +(* cut-and-paste ¤âÂбþ¤·¤Æ¤¤¤Þ¤¹¤¬¡¢edit¤Ï¤¦¤Þ¤¯¤¤¤­¤Þ¤»¤ó *) + +open GMain + +let window = GWindow.window () +let box = GPack.vbox ~packing: window#add () +let text = GEdit.text ~editable: true ~packing: box#add () +let font = Gdk.Font.load_fontset + "-*-fixed-medium-r-normal--24-*-c-120-iso8859-1, \ + -*-fixed-medium-r-normal--24-*-jisx0208.1983-0, \ + -*-fixed-medium-r-normal--24-*-jisx0201.1976-0" +let button = GButton.button ~label: "½ªÎ»" ~packing: box#add () +let label = GMisc.label ~text:"¤³¤ì¤Ë¤Ï±Æ¶Á¤·¤Ê¤¤" ~packing: box#add () + +let _ = + window#connect#destroy ~callback:Main.quit; + text#misc#realize (); + text#insert "¤³¤ó¤Ë¤Á¤Ï" ~font; + let style = button#misc#style#copy in + button#misc#set_style style; + style#set_font font; + style#set_bg [`NORMAL,`NAME "green"; `PRELIGHT,`NAME "red"]; + button#connect#clicked ~callback:Main.quit + +let _ = + window#show (); + Main.main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/pousse.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/pousse.ml new file mode 100644 index 000000000..ecf0dff3a --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/pousse.ml @@ -0,0 +1,199 @@ +(* $Id$ *) + +(* The game logic *) + +type color = [`none|`white|`black] + +module type BoardSpec = sig + type t + val size : int + val get : t -> x:int -> y:int -> color + val set : t -> x:int -> y:int -> color:color -> unit +end + +module Board (Spec : BoardSpec) = struct + open Spec + let size = size + + let on_board x y = + x >= 0 && x < size && y >= 0 && y < size + + let rec string board ~x ~y ~dx ~dy ~color l = + let x = x+dx and y = y+dy in + if on_board x y then + let col = get board ~x ~y in + if col = (color : [`white|`black] :> color) then l else + if col = `none then [] else + string board ~x ~y ~dx ~dy ~color ((x,y)::l) + else [] + + let find_swaps board ~x ~y ~color = + if get board ~x ~y <> `none then [] else + List.fold_left [-1,-1; -1,0; -1,1; 0,-1; 0,1; 1,-1; 1,0; 1,1] + ~init:[] + ~f:(fun acc (dx,dy) -> string board ~x ~y ~dx ~dy ~color [] @ acc) + + let action board ~x ~y ~color = + let swaps = find_swaps board ~x ~y ~color in + if swaps = [] then false else begin + List.iter ((x,y)::swaps) + ~f:(fun (x,y) -> set board ~x ~y ~color:(color :> color)); + true + end + + let check_impossible board ~color = + try + for x = 0 to size - 1 do for y = 0 to size - 1 do + if find_swaps board ~x ~y ~color <> [] then raise Exit + done done; + true + with Exit -> false + + let count_cells board = + let w = ref 0 and b = ref 0 in + for x = 0 to size - 1 do for y = 0 to size - 1 do + match get board ~x ~y with + `white -> incr w + | `black -> incr b + | `none -> () + done done; + (!w,!b) +end + +(* GUI *) + +open GMain + +(* Toplevel window *) + +let window = GWindow.window ~title:"pousse" () + +(* Create pixmaps *) + +let pixdraw = + GDraw.pixmap ~window ~width:40 ~height:40 ~mask:true () +let pixdraw1 = + GDraw.pixmap ~window ~width:40 ~height:40 ~mask:true () +let pixdraw2 = + GDraw.pixmap ~window ~width:40 ~height:40 ~mask:true () + +let _ = + pixdraw1#set_foreground `BLACK; + pixdraw1#arc ~x:3 ~y:3 ~width:34 ~height:34 ~filled:true (); + pixdraw2#set_foreground `WHITE; + pixdraw2#arc ~x:3 ~y:3 ~width:34 ~height:34 ~filled:true (); + pixdraw2#set_foreground `BLACK; + pixdraw2#arc ~x:3 ~y:3 ~width:34 ~height:34 () + +(* The cell class: a button with a pixmap on it *) + +class cell ?packing ?show () = + let button = GButton.button ?packing ?show () in +object (self) + inherit GObj.widget button#as_widget + method connect = button#connect + val mutable color : color = `none + val pm = GMisc.pixmap pixdraw ~packing:button#add () + method color = color + method set_color col = + if col <> color then begin + color <- col; + pm#set_pixmap + (match col with `none -> pixdraw + | `black -> pixdraw1 + | `white -> pixdraw2) + end +end + +module RealBoard = Board ( + struct + type t = cell array array + let size = 8 + let get (board : t) ~x ~y = board.(x).(y)#color + let set (board : t) ~x ~y ~color = board.(x).(y)#set_color color + end +) + +(* Conducting a game *) + +open RealBoard + +class game ~(frame : #GContainer.container) ~(label : #GMisc.label) + ~(statusbar : #GMisc.statusbar) = + let table = GPack.table ~columns:size ~rows:size ~packing:frame#add () in +object (self) + val cells = + Array.init size + ~f:(fun i -> Array.init size + ~f:(fun j -> new cell ~packing:(table#attach ~top:i ~left:j) ())) + val label = label + val turn = statusbar#new_context ~name:"turn" + val messages = statusbar#new_context ~name:"messages" + val mutable current_color = `black + method board = cells + method table = table + method player = current_color + + method swap_players () = + current_color <- + match current_color with + `white -> turn#pop (); turn#push "Player is black"; `black + | `black -> turn#pop (); turn#push "Player is white"; `white + + method finish () = + turn#pop (); + let w, b = count_cells cells in + turn#push + (if w > b then "White wins" else + if w < b then "Black wins" else + "Game is a draw"); + () + + method update_label () = + let w, b = count_cells cells in + label#set_text (Printf.sprintf "White: %d Black: %d " w b) + + method play x y = + if action cells ~x ~y ~color:current_color then begin + self#update_label (); + self#swap_players (); + if check_impossible cells ~color:current_color then begin + self#swap_players (); + if check_impossible cells ~color:current_color then self#finish () + end + end else + messages#flash "You cannot play there" + + initializer + for i = 0 to size-1 do for j = 0 to size-1 do + let cell = cells.(i).(j) in + cell#connect#enter ~callback:cell#misc#grab_focus; + cell#connect#clicked ~callback:(fun () -> self#play i j) + done done; + List.iter ~f:(fun (x,y,col) -> cells.(x).(y)#set_color col) + [ 3,3,`black; 4,4,`black; 3,4,`white; 4,3,`white ]; + self#update_label (); + turn#push "Player is black"; + () +end + +(* Graphical elements *) + +let vbox = GPack.vbox ~packing:window#add () +let frame = GBin.frame ~shadow_type:`IN ~packing:vbox#add () +let hbox = GPack.hbox ~packing:vbox#pack () + +let bar = GMisc.statusbar ~packing:hbox#add () + +let frame2 = GBin.frame ~shadow_type:`IN ~packing:hbox#pack () +let label = + GMisc.label ~justify:`LEFT ~xpad:5 ~xalign:0.0 ~packing:frame2#add () + +let game = new game ~frame ~label ~statusbar:bar + +(* Start *) + +let _ = + window#connect#destroy ~callback:Main.quit; + window#show (); + Main.main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/progressbar.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/progressbar.ml new file mode 100644 index 000000000..b614f08f8 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/progressbar.ml @@ -0,0 +1,51 @@ +(* $Id$ *) + +open GMain + +class bar bar = object + val bar : #GRange.progress = bar + val mutable pstat = true + method progress () = + let pvalue = bar#percentage in + let pvalue = + if pvalue > 0.99 || not pstat then (pstat <- true; 0.0) + else pvalue +. 0.01 + in + bar#set_percentage pvalue; + true + method reset () = + pstat <- false +end + +let main () = + + let window = GWindow.window ~border_width: 10 () in + window#connect#destroy ~callback:Main.quit; + + let table = GPack.table ~rows:3 ~columns:2 ~packing: window#add () in + + GMisc.label ~text:"Progress Bar Example" () + ~packing:(table#attach ~left:0 ~right:2 ~top:0 ~expand:`X ~shrink:`BOTH); + + let pbar = + GRange.progress_bar ~bar_style:`DISCRETE ~discrete_blocks:20 () + ~packing:(table#attach ~left:0 ~right:2 ~top:1 + ~expand:`BOTH ~fill:`X ~shrink:`BOTH) in + + let bar = new bar pbar in + let ptimer = Timeout.add ~ms:50 ~callback:bar#progress in + + let button = GButton.button ~label:"Reset" () + ~packing:(table#attach ~left:0 ~top:2 + ~expand:`NONE ~fill:`X ~shrink:`BOTH) in + button#connect#clicked ~callback:bar#reset; + + let button = GButton.button ~label:"Cancel" () + ~packing:(table#attach ~left:1 ~top:2 + ~expand:`NONE ~fill:`X ~shrink:`BOTH) in + button#connect#clicked ~callback:Main.quit; + + window#show (); + Main.main () + +let _ = main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/radiobuttons.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/radiobuttons.ml new file mode 100644 index 000000000..5743ee232 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/radiobuttons.ml @@ -0,0 +1,39 @@ +(* $Id$ *) + +open GMain + +let main () = + + let window = GWindow.window ~title: "radio buttons" ~border_width: 0 () in + window#connect#destroy ~callback:Main.quit; + + let box1 = GPack.vbox ~packing: window#add () in + + let box2 = GPack.vbox ~spacing:10 ~border_width: 10 ~packing: box1#add () in + + let button1 = GButton.radio_button ~label:"button1" ~packing: box2#add () in + button1#connect#clicked ~callback:(fun () -> prerr_endline "button1"); + + let button2 = GButton.radio_button ~group:button1#group ~label:"button2" + ~active:true ~packing: box2#add () in + button2#connect#clicked ~callback:(fun () -> prerr_endline "button2"); + + let button3 = GButton.radio_button + ~group:button1#group ~label:"button3" ~packing: box2#add () in + button3#connect#clicked ~callback:(fun () -> prerr_endline "button3"); + + let separator = + GMisc.separator `HORIZONTAL ~packing: box1#pack () in + + let box3 = GPack.vbox ~spacing: 10 ~border_width: 10 + ~packing: box1#pack () in + + let button = GButton.button ~label: "close" ~packing: box3#add () in + button#connect#clicked ~callback:Main.quit; + button#grab_default (); + + window#show (); + + Main.main () + +let _ = main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/rpn.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/rpn.ml new file mode 100644 index 000000000..e701f185c --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/rpn.ml @@ -0,0 +1,129 @@ +(* $Id$ *) + +(* reverse polish calculator *) + +open GMain + +let wow _ = prerr_endline "Wow!"; () +let main () = + let stack = Stack.create () in + + (* toplevel window *) + let window = + GWindow.window ~border_width: 10 ~title:"Reverse Polish Calculator" () in + window#connect#destroy ~callback:Main.quit; + + + (* vbox *) + let vbx = GPack.vbox ~packing:window#add () in + + (* entry *) + let entry = + GEdit.entry ~text:"0" ~editable:false ~max_length: 20 ~packing: vbx#add () in + + (* BackSpace, Clear, All Clear, Quit *) + let table0 = GPack.table ~rows:1 ~columns:4 ~packing:vbx#add () in + let bs_clicked _ = begin + let txt = entry#text in + let len = String.length txt in + if len <= 1 then + entry#set_text "0" + else entry#set_text (String.sub txt ~pos:0 ~len:(len-1)) + end in + let c_clicked _ = entry#set_text("0") in + let ac_clicked _ = Stack.clear stack; entry#set_text("0") in + let labels0 = [("BS", bs_clicked) ; ("C", c_clicked); + ("AC", ac_clicked); ("Quit", window#destroy)] in + let rec loop0 labels n = + match labels + with [] -> () + | (lbl, cb) :: t -> + let button = + GButton.button ~label:lbl + ~packing:(table0#attach ~left:n ~top:1 ~expand:`BOTH) () in + button#connect#clicked ~callback:cb; + loop0 t (n+1) in + loop0 labels0 1; + + (* Numerals *) + let table1 = GPack.table ~rows:4 ~columns:5 ~packing:vbx#add () in + let labels1 = ["7"; "8"; "9"; "4"; "5"; "6"; "1"; "2"; "3"; "0"] in + let numClicked n _ = + let txt = entry#text in + if (txt = "0") then + entry#set_text n + else begin + entry#append_text n + end in + let rec loop1 labels n = + match labels with [] -> () + | lbl :: lbls -> + let button = GButton.button ~label:(" "^lbl^" ") + ~packing:(table1#attach ~left:(n mod 3) ~top:(n/3) ~expand:`BOTH) + () in + button#connect#clicked ~callback:(numClicked lbl); + loop1 lbls (n+1) in + loop1 labels1 0; + + (* Period *) + let periodClicked _ = + let txt = entry#text in + if (String.contains txt '.') then begin + Printf.printf "\a"; + flush stdout; + end + else + entry#append_text "." in + (GButton.button ~label:" . " + ~packing:(table1#attach ~left:1 ~top:3 ~expand:`BOTH) ()) + #connect#clicked ~callback:periodClicked; + + (* Enter (Push) *) + let enterClicked _ = + let txt = entry#text in + let n = float_of_string txt in begin + Stack.push n stack; + entry#set_text "0" + end in + (GButton.button ~label:"Ent" + ~packing:(table1#attach ~left:2 ~top:3 ~expand:`BOTH) ()) + #connect#clicked ~callback:enterClicked; + + (* Operators *) + let op2Clicked op _ = + let n1 = float_of_string (entry#text) in + let n2 = Stack.pop stack in + entry#set_text (string_of_float (op n2 n1)) + in + let op1Clicked op _ = + let n1 = float_of_string (entry#text) in + entry#set_text (string_of_float (op n1)) + in + let modClicked _ = + let n1 = int_of_string (entry#text) in + let n2 = truncate (Stack.pop stack) in + entry#set_text (string_of_int (n2 mod n1)) + in + let labels2 = [(" / ", op2Clicked (/.)); (" * ", op2Clicked ( *. )); + (" - ", op2Clicked (-.)); (" + ", op2Clicked (+.)); + ("mod", modClicked); (" ^ ", op2Clicked ( ** )); + ("+/-", op1Clicked (~-.)); + ("1/x", op1Clicked (fun x -> 1.0/.x))] in + let rec loop2 labels n = + match labels + with [] -> () + | (lbl, cb) :: t -> + let button = GButton.button ~label:lbl + ~packing:(table1#attach ~left:(3 + n/4) ~top: (n mod 4) + ~expand:`BOTH) + () in + button#connect#clicked ~callback:cb; + loop2 t (n+1) + in + loop2 labels2 0; + + (* show all and enter event loop *) + window#show (); + Main.main () + +let _ = Printexc.print main() diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/scrolledwin.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/scrolledwin.ml new file mode 100644 index 000000000..8f4bee21e --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/scrolledwin.ml @@ -0,0 +1,35 @@ +(* $Id$ *) + +open GMain + +let main () = + let window = GWindow.dialog ~title: "dialog" + ~border_width: 10 ~width: 300 ~height: 300 () in + window#connect#destroy ~callback:Main.quit; + + let scrolled_window = GBin.scrolled_window + ~border_width: 10 ~hpolicy: `AUTOMATIC ~packing: window#vbox#add () + in + + let table = GPack.table ~rows:10 ~columns:10 + ~row_spacings: 10 ~col_spacings: 10 + ~packing: scrolled_window#add_with_viewport () + in + + for i = 0 to 9 do + for j = 0 to 9 do + let label = Printf.sprintf "button (%d,%d)\n" i j in + GButton.toggle_button ~label + ~packing:(table#attach ~left: i ~top: j ~expand: `BOTH) () + done + done; + + let button = + GButton.button ~label: "close" ~packing: window#action_area#add () in + button#connect#clicked ~callback: Main.quit; + button#grab_default (); + window#show (); + Main.main () + +let _ = main () + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/socket.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/socket.ml new file mode 100644 index 000000000..687389ca9 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/socket.ml @@ -0,0 +1,16 @@ +(* $Id$ *) + +open GMain + +let main () = + let w = GWindow.window ~title:"Socket example" () in + w#connect#destroy ~callback:Main.quit; + let vbox = GPack.vbox ~packing:w#add () in + let label = GMisc.label ~packing:vbox#pack () in + let socket = GBin.socket ~packing:vbox#add ~height:40 () in + label#set_text ("XID to plug into this socket: 0x" ^ + Int32.format "%x" socket#xwindow); + w#show (); + Main.main () + +let _ = main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/test.xpm b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/test.xpm new file mode 100644 index 000000000..9b0d2efdb --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/test.xpm @@ -0,0 +1,92 @@ +/* XPM */ +static char *openfile[] = { +/* width height num_colors chars_per_pixel */ +" 20 19 66 2", +/* colors */ +".. c None", +".# c #000000", +".a c #dfdfdf", +".b c #7f7f7f", +".c c #006f6f", +".d c #00efef", +".e c #009f9f", +".f c #004040", +".g c #00bfbf", +".h c #ff0000", +".i c #ffffff", +".j c #7f0000", +".k c #007070", +".l c #00ffff", +".m c #00a0a0", +".n c #004f4f", +".o c #00cfcf", +".p c #8f8f8f", +".q c #6f6f6f", +".r c #a0a0a0", +".s c #7f7f00", +".t c #007f7f", +".u c #5f5f5f", +".v c #707070", +".w c #00f0f0", +".x c #009090", +".y c #ffff00", +".z c #0000ff", +".A c #00afaf", +".B c #00d0d0", +".C c #00dfdf", +".D c #005f5f", +".E c #00b0b0", +".F c #001010", +".G c #00c0c0", +".H c #000f0f", +".I c #00007f", +".J c #005050", +".K c #002f2f", +".L c #dfcfcf", +".M c #dfd0d0", +".N c #006060", +".O c #00e0e0", +".P c #00ff00", +".Q c #002020", +".R c #dfc0c0", +".S c #008080", +".T c #001f1f", +".U c #003f3f", +".V c #007f00", +".W c #00000f", +".X c #000010", +".Y c #00001f", +".Z c #000020", +".0 c #00002f", +".1 c #000030", +".2 c #00003f", +".3 c #000040", +".4 c #00004f", +".5 c #000050", +".6 c #00005f", +".7 c #000060", +".8 c #00006f", +".9 c #000070", +"#. c #7f7f80", +"## c #9f9f9f", +/* pixels */ +"........................................", +"........................................", +"........................................", +".......................#.#.#............", +".....................#.......#...#......", +"...............................#.#......", +".......#.#.#.................#.#.#......", +".....#.y.i.y.#.#.#.#.#.#.#..............", +".....#.i.y.i.y.i.y.i.y.i.#..............", +".....#.y.i.y.i.y.i.y.i.y.#..............", +".....#.i.y.i.y.#.#.#.#.#.#.#.#.#.#.#....", +".....#.y.i.y.#.s.s.s.s.s.s.s.s.s.#......", +".....#.i.y.#.s.s.s.s.s.s.s.s.s.#........", +".....#.y.#.s.s.s.s.s.s.s.s.s.#..........", +".....#.#.s.s.s.s.s.s.s.s.s.#............", +".....#.#.#.#.#.#.#.#.#.#.#..............", +"........................................", +"........................................", +"........................................" +}; diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/testdnd.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/testdnd.ml new file mode 100644 index 000000000..8c10f7b98 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/testdnd.ml @@ -0,0 +1,510 @@ +(* this is a translation in Caml of the gtk+ example testdnd.c *) + + +open Gaux +open Gtk +open GObj +open GMain + +(* GtkThread.start() *) + +let drag_icon_xpm = [| +"36 48 9 1"; +" c None"; +". c #020204"; +"+ c #8F8F90"; +"@ c #D3D3D2"; +"# c #AEAEAC"; +"$ c #ECECEC"; +"% c #A2A2A4"; +"& c #FEFEFC"; +"* c #BEBEBC"; +" ....................."; +" ..&&&&&&&&&&&&&&&&&&&."; +" ...&&&&&&&&&&&&&&&&&&&."; +" ..&.&&&&&&&&&&&&&&&&&&&."; +" ..&&.&&&&&&&&&&&&&&&&&&&."; +" ..&&&.&&&&&&&&&&&&&&&&&&&."; +" ..&&&&.&&&&&&&&&&&&&&&&&&&."; +" ..&&&&&.&&&@&&&&&&&&&&&&&&&."; +" ..&&&&&&.*$%$+$&&&&&&&&&&&&&."; +" ..&&&&&&&.%$%$+&&&&&&&&&&&&&&."; +" ..&&&&&&&&.#&#@$&&&&&&&&&&&&&&."; +" ..&&&&&&&&&.#$**#$&&&&&&&&&&&&&."; +" ..&&&&&&&&&&.&@%&%$&&&&&&&&&&&&&."; +" ..&&&&&&&&&&&.&&&&&&&&&&&&&&&&&&&."; +" ..&&&&&&&&&&&&.&&&&&&&&&&&&&&&&&&&."; +"................&$@&&&@&&&&&&&&&&&&."; +".&&&&&&&+&&#@%#+@#@*$%$+$&&&&&&&&&&."; +".&&&&&&&+&&#@#@&&@*%$%$+&&&&&&&&&&&."; +".&&&&&&&+&$%&#@&#@@#&#@$&&&&&&&&&&&."; +".&&&&&&@#@@$&*@&@#@#$**#$&&&&&&&&&&."; +".&&&&&&&&&&&&&&&&&&&@%&%$&&&&&&&&&&."; +".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&."; +".&&&&&&&&$#@@$&&&&&&&&&&&&&&&&&&&&&."; +".&&&&&&&&&+&$+&$&@&$@&&$@&&&&&&&&&&."; +".&&&&&&&&&+&&#@%#+@#@*$%&+$&&&&&&&&."; +".&&&&&&&&&+&&#@#@&&@*%$%$+&&&&&&&&&."; +".&&&&&&&&&+&$%&#@&#@@#&#@$&&&&&&&&&."; +".&&&&&&&&@#@@$&*@&@#@#$#*#$&&&&&&&&."; +".&&&&&&&&&&&&&&&&&&&&&$%&%$&&&&&&&&."; +".&&&&&&&&&&$#@@$&&&&&&&&&&&&&&&&&&&."; +".&&&&&&&&&&&+&$%&$$@&$@&&$@&&&&&&&&."; +".&&&&&&&&&&&+&&#@%#+@#@*$%$+$&&&&&&."; +".&&&&&&&&&&&+&&#@#@&&@*#$%$+&&&&&&&."; +".&&&&&&&&&&&+&$+&*@&#@@#&#@$&&&&&&&."; +".&&&&&&&&&&$%@@&&*@&@#@#$#*#&&&&&&&."; +".&&&&&&&&&&&&&&&&&&&&&&&$%&%$&&&&&&."; +".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&."; +".&&&&&&&&&&&&&&$#@@$&&&&&&&&&&&&&&&."; +".&&&&&&&&&&&&&&&+&$%&$$@&$@&&$@&&&&."; +".&&&&&&&&&&&&&&&+&&#@%#+@#@*$%$+$&&."; +".&&&&&&&&&&&&&&&+&&#@#@&&@*#$%$+&&&."; +".&&&&&&&&&&&&&&&+&$+&*@&#@@#&#@$&&&."; +".&&&&&&&&&&&&&&$%@@&&*@&@#@#$#*#&&&."; +".&&&&&&&&&&&&&&&&&&&&&&&&&&&$%&%$&&."; +".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&."; +".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&."; +".&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&."; +"...................................." |] + + + +let trashcan_closed_xpm = [| +"64 80 17 1"; +" c None"; +". c #030304"; +"+ c #5A5A5C"; +"@ c #323231"; +"# c #888888"; +"$ c #1E1E1F"; +"% c #767677"; +"& c #494949"; +"* c #9E9E9C"; +"= c #111111"; +"- c #3C3C3D"; +"; c #6B6B6B"; +"> c #949494"; +", c #282828"; +"' c #808080"; +") c #545454"; +"! c #AEAEAC"; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" ==......=$$...=== "; +" ..$------)+++++++++++++@$$... "; +" ..=@@-------&+++++++++++++++++++-.... "; +" =.$$@@@-&&)++++)-,$$$$=@@&+++++++++++++,..$ "; +" .$$$$@@&+++++++&$$$@@@@-&,$,-++++++++++;;;&.. "; +" $$$$,@--&++++++&$$)++++++++-,$&++++++;%%'%%;;$@ "; +" .-@@-@-&++++++++-@++++++++++++,-++++++;''%;;;%*-$ "; +" +------++++++++++++++++++++++++++++++;;%%%;;##*!. "; +" =+----+++++++++++++++++++++++;;;;;;;;;;;;%'>>). "; +" .=)&+++++++++++++++++;;;;;;;;;;;;;;%''>>#>#@. "; +" =..=&++++++++++++;;;;;;;;;;;;;%###>>###+%== "; +" .&....=-+++++%;;####''''''''''##'%%%)..#. "; +" .+-++@....=,+%#####'%%%%%%%%%;@$-@-@*++!. "; +" .+-++-+++-&-@$$=$=......$,,,@;&)+!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" =+-++-+++-+++++++++!++++!++++!+++!++!+++= "; +" $.++-+++-+++++++++!++++!++++!+++!++!+.$ "; +" =.++++++++++++++!++++!++++!+++!++.= "; +" $..+++++++++++++++!++++++...$ "; +" $$=.............=$$ "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" " |] + +let trashcan_open_xpm = [| +"64 80 17 1"; +" c None"; +". c #030304"; +"+ c #5A5A5C"; +"@ c #323231"; +"# c #888888"; +"$ c #1E1E1F"; +"% c #767677"; +"& c #494949"; +"* c #9E9E9C"; +"= c #111111"; +"- c #3C3C3D"; +"; c #6B6B6B"; +"> c #949494"; +", c #282828"; +"' c #808080"; +") c #545454"; +"! c #AEAEAC"; +" "; +" "; +" "; +" "; +" "; +" "; +" .=.==.,@ "; +" ==.,@-&&&)-= "; +" .$@,&++;;;%>*- "; +" $,-+)+++%%;;'#+. "; +" =---+++++;%%%;%##@. "; +" @)++++++++;%%%%'#%$ "; +" $&++++++++++;%%;%##@= "; +" ,-++++)+++++++;;;'#%) "; +" @+++&&--&)++++;;%'#'-. "; +" ,&++-@@,,,,-)++;;;'>'+, "; +" =-++&@$@&&&&-&+;;;%##%+@ "; +" =,)+)-,@@&+++++;;;;%##%&@ "; +" @--&&,,@&)++++++;;;;'#)@ "; +" ---&)-,@)+++++++;;;%''+, "; +" $--&)+&$-+++++++;;;%%'';- "; +" .,-&+++-$&++++++;;;%''%&= "; +" $,-&)++)-@++++++;;%''%), "; +" =,@&)++++&&+++++;%'''+$@&++++++ "; +" .$@-++++++++++++;'#';,........=$@&++++ "; +" =$@@&)+++++++++++'##-.................=&++ "; +" .$$@-&)+++++++++;%#+$.....................=)+ "; +" $$,@-)+++++++++;%;@=........................,+ "; +" .$$@@-++++++++)-)@=............................ "; +" $,@---)++++&)@===............................,. "; +" $-@---&)))-$$=..............................=)!. "; +" --&-&&,,$=,==...........................=&+++!. "; +" =,=$..=$+)+++++&@$=.............=$@&+++++!++!. "; +" .)-++-+++++++++++++++++++++++++++!++!++!. "; +" .+-++-+++++++++++++++++++++++!+++!++!++!. "; +" .+-++-+++-+++++++++!+++!!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" .+-++-+++-+++++++++!++++!++++!+++!++!++!. "; +" =+-++-+++-+++++++++!++++!++++!+++!++!+++= "; +" $.++-+++-+++++++++!++++!++++!+++!++!+.$ "; +" =.++++++++++++++!++++!++++!+++!++.= "; +" $..+++++++++++++++!++++++...$ "; +" $$==...........==$$ "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" "; +" " |] + +let window = GWindow.window ~title:"DnD Test" () +let _ = window#misc#realize () + +let drag_icon = + GDraw.pixmap_from_xpm_d ~data:drag_icon_xpm ~window () + +let trashcan_open = + GDraw.pixmap_from_xpm_d ~data:trashcan_open_xpm ~window () + +let trashcan_closed = + GDraw.pixmap_from_xpm_d ~data:trashcan_closed_xpm ~window () + +let targets = [ + { target = "STRING"; flags = []; info = 0}; + { target = "text/plain"; flags = []; info = 0}; + { target = "text/uri-list"; flags = []; info = 2}; + { target = "application/x-rootwin-drop"; flags = []; info = 1} +] + +class drag_handler = object + method private beginning (_ : drag_context) = () + method private data_delete (_ : drag_context) = () + method private data_get (_ : drag_context) (_ : selection_data) + ~info:(_ : int) ~time:(_ : int) = () + method private data_received (_ : drag_context) ~x:(_ : int) ~y:(_ : int) + (_ : selection_data) ~info:(_ : int) ~time:(_ : int) = () + method private drop (_ : drag_context) ~x:(_ : int) ~y:(_ : int) + ~time:(_ : int) = false + method private ending (_ : drag_context) = () + method private leave (_ : drag_context) ~time:(_ : int) = () + method private motion (_ : drag_context) ~x:(_ : int) ~y:(_ : int) + ~time:(_ : int) = false +end + + +class target_drag ?packing ?show () = + let pixmap = GMisc.pixmap trashcan_closed ?packing ?show () in +object (self) + inherit widget pixmap#as_widget + inherit drag_handler + val mutable have_drag = false + + method leave _ ~time = + print_endline "leave"; flush stdout; + have_drag <- false; + pixmap#set_pixmap trashcan_closed + + method motion context ~x ~y ~time = + if not have_drag then begin + have_drag <- true; + pixmap#set_pixmap trashcan_open + end; + let source_typename = + try + context#source_widget#misc#get_type + with Gpointer.Null -> "unknown" + in + Printf.printf "motion, source %s\n" source_typename; flush stdout; + context#status [context#suggested_action] ~time; + true + + method drop context ~x ~y ~time = + prerr_endline "drop"; flush stdout; + have_drag <- false; + pixmap#set_pixmap trashcan_closed; + match context#targets with + | [] -> false + | d :: _ -> pixmap#drag#get_data d ~context ~time; true + + method data_received context ~x ~y data ~info ~time = + if data#format = 8 then begin + Printf.printf "Received \"%s\" in trashcan\n" data#data; + flush stdout; + context#finish ~success:true ~del:false ~time + end + else context#finish ~success:false ~del:false ~time + + initializer + pixmap#drag#dest_set targets ~actions:[`COPY;`MOVE]; + pixmap#drag#connect#leave ~callback:self#leave; + pixmap#drag#connect#motion ~callback:self#motion; + pixmap#drag#connect#drop ~callback:self#drop; + pixmap#drag#connect#data_received ~callback:self#data_received; + () +end + +class label_drag ?packing ?show () = + let label = GMisc.label ~text:"Drop Here\n" ?packing ?show () in +object (self) + inherit widget label#as_widget + inherit drag_handler + method data_received context ~x ~y data ~info ~time = + if data#format = 8 then begin + Printf.printf "Received \"%s\" in label\n" data#data; + flush stdout; + context#finish ~success:true ~del:false ~time + end + else context#finish ~success:false ~del:false ~time + + initializer + label#drag#dest_set targets ~actions:[`COPY; `MOVE ]; + label#drag#connect#data_received ~callback:self#data_received; + () +end + +class source_drag ?packing ?show () = + let button = GButton.button ~label:"Drag Here\n" ?packing ?show () in +object (self) + inherit widget button#as_widget + inherit drag_handler + method data_get _ data ~info ~time = + if info = 1 then begin + print_endline "I was dropped on the rootwin"; flush stdout + end + else if info = 2 then + data#set ~typ:data#target ~format:8 + ~data:"file:///home/otaylor/images/weave.png" + else + data#set ~typ:data#target ~format:8 ~data:"I'm Data!" + + method data_delete _ = + print_endline "Delete the data!"; flush stdout + + initializer + button#drag#source_set targets + ~modi:[`BUTTON1; `BUTTON3 ] ~actions:[`COPY; `MOVE ]; + button#drag#source_set_icon drag_icon; + button#drag#connect#data_get ~callback:self#data_get; + button#drag#connect#data_delete ~callback:self#data_delete; + () +end + +class popup () = object (self) + inherit drag_handler + val mutable popup_window = (None : GWindow.window option) + val mutable popped_up = false + val mutable in_popup = false + val mutable popdown_timer = None + val mutable popup_timer = None + + method timer = popup_timer + method remove_timer () = + may popup_timer + ~f:(fun pdt -> Timeout.remove pdt; popup_timer <- None) + method add_timer time ~callback = + popup_timer <- Some (Timeout.add ~ms:time ~callback) + + method popdown () = + popdown_timer <- None; + may popup_window ~f:(fun w -> w#misc#hide ()); + popped_up <- false; + false + + method motion (_ : drag_context) ~x ~y ~time = + if not in_popup then begin + in_popup <- true; + may popdown_timer ~f: + begin fun pdt -> + print_endline "removed popdown"; flush stdout; + Timeout.remove pdt; + popdown_timer <- None + end + end; + true + + method leave (_ : drag_context) ~time = + if in_popup then begin + in_popup <- false; + if popdown_timer = None then begin + print_endline "added popdown"; flush stdout; + popdown_timer <- Some (Timeout.add ~ms:500 ~callback:self#popdown) + end + end + + method popup () = + if not popped_up then begin + if popup_window = None then begin + let w = GWindow.window ~kind:`POPUP ~position:`MOUSE () in + popup_window <- Some w; + let table = GPack.table ~rows:3 ~columns:3 ~packing:w#add () in + for i = 0 to 2 do + for j = 0 to 2 do + let button = + GButton.button ~label:(string_of_int i ^ "," ^ string_of_int j) + ~packing:(table#attach ~left:i ~top:j ~expand:`BOTH) () + in + button#drag#dest_set targets ~actions:[`COPY; `MOVE ]; + button#drag#connect#motion ~callback:self#motion; + button#drag#connect#leave ~callback:self#leave; + done + done + end; + may popup_window ~f:(fun w -> w#show ()); + popped_up <- true + end; + popdown_timer <- Some (Timeout.add ~ms:500 ~callback:self#popdown); + print_endline "added popdown"; flush stdout; + self#remove_timer (); + false +end + +class popsite ?packing ?show () = + let label = GMisc.label ~text:"Popup\n" ?packing ?show () + and popup = new popup () in +object (self) + inherit widget label#as_widget + inherit drag_handler + method motion _ ~x ~y ~time = + if popup#timer = None then begin + print_endline "added popdown"; flush stdout; + popup#add_timer 500 ~callback:popup#popup + end; + true + + method leave _ ~time = + popup#remove_timer () + + initializer + label#drag#dest_set targets ~actions:[`COPY; `MOVE ]; + label#drag#connect#motion ~callback:self#motion; + label#drag#connect#leave ~callback:self#leave; + () +end + +let main () = + window#connect#destroy ~callback: Main.quit; + let table = GPack.table ~rows:2 ~columns:2 ~packing:window#add () in + let attach = table#attach ~expand:`BOTH in + new label_drag ~packing:(attach ~left:0 ~top:0) (); + new target_drag ~packing:(attach ~left:1 ~top:0) (); + new source_drag ~packing:(attach ~left:0 ~top:1) (); + new popsite ~packing:(attach ~left:1 ~top:1) (); + + window#show (); + Main.main () + +let _ = + main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/testgtk.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/testgtk.ml new file mode 100644 index 000000000..6c937f56d --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/testgtk.ml @@ -0,0 +1,1140 @@ +(* $Id$ *) + +open GdkKeysyms +open GMain +open GObj + +let create_bbox direction title spacing child_w child_h layout = + let frame = GBin.frame ~label: title () in + let bbox = GPack.button_box direction ~border_width: 5 ~packing: frame#add + ~layout: layout ~child_height: child_h ~child_width: child_w + ~spacing: spacing () in + GButton.button ~label: "OK" ~packing: bbox#add (); + GButton.button ~label: "Cancel" ~packing: bbox#add (); + GButton.button ~label: "Help" ~packing: bbox#add (); + frame#coerce + +let create_button_box = + let rw = ref None in + let aux () = + match !rw with + | None -> + let window = GWindow.window ~title: "Button Boxes" ~border_width: 0 () in + rw := Some window; + window #connect#destroy ~callback:(fun _ -> rw := None); + + let main_vbox = GPack.vbox ~packing: (window#add) () in + + let frame_horz = GBin.frame ~label: "Horizontal Button Boxes" + ~packing:(main_vbox#pack ~expand:true ~fill:true ~padding:10) () in + + let vbox = GPack.vbox ~border_width: 10 ~packing: frame_horz#add () in + + vbox#add (create_bbox `HORIZONTAL "Spread" 40 85 20 `SPREAD); + vbox#pack (create_bbox `HORIZONTAL "Edge" 40 85 20 `EDGE) + ~expand: true ~fill: true ~padding: 5; + vbox#pack (create_bbox `HORIZONTAL "Start" 40 85 20 `START) + ~expand: true ~fill: true ~padding: 5; + vbox#pack (create_bbox `HORIZONTAL "End" 40 85 20 `END) + ~expand: true ~fill: true ~padding: 5; + + let frame_vert = GBin.frame ~label: "Vertical Button Boxes" + ~packing:(main_vbox#pack ~expand:true ~fill:true ~padding:10) () in + + let hbox = GPack.hbox ~border_width: 10 ~packing: frame_vert#add () in + hbox#add (create_bbox `VERTICAL "Spread" 30 85 20 `SPREAD); + hbox#pack (create_bbox `VERTICAL "Edge" 30 85 20 `EDGE) + ~expand: true ~fill: true ~padding: 5; + hbox#pack (create_bbox `VERTICAL "Start" 30 85 20 `START) + ~expand: true ~fill: true ~padding: 5; + hbox#pack (create_bbox `VERTICAL "End" 30 85 20 `END) + ~expand: true ~fill: true ~padding: 5; + window #show () + + | Some window -> window #destroy () +in aux + + +let button_window button _ = + if button #misc#visible then + button #misc#hide () + else + button #misc#show () + +let create_buttons = + let rw = ref None in + let aux () = + match !rw with + | None -> + let window = GWindow.window ~title: "GtkButton" ~border_width: 0 () in + rw := Some window; + window #connect#destroy ~callback:(fun _ -> rw := None); + + let box1 = GPack.vbox ~packing:window#add () in + + let table = GPack.table ~rows:3 ~columns:3 ~homogeneous:false + ~row_spacings:3 ~col_spacings:3 ~border_width:10 + ~packing:box1#add () in + + let button = Array.create 9 (GButton.button ~label:"button1" ()) in + for i = 2 to 9 do + button.(i-1) <- GButton.button ~label:("button" ^ string_of_int i) (); + done; + + let f i l r t b = + button.(i) #connect#clicked ~callback:(button_window button.(i+1)); + table #attach button.(i)#coerce ~left:l ~right:r ~top:t ~bottom:b + ~xpadding:0 ~ypadding:0 ~expand:`BOTH + in + f 0 0 1 0 1; + f 1 1 2 1 2; + f 2 2 3 2 3; + f 3 0 1 2 3; + f 4 2 3 0 1; + f 5 1 2 2 3; + f 6 1 2 0 1; + f 7 2 3 1 2; + button.(8) #connect#clicked ~callback:(button_window button.(0)); + table #attach button.(8)#coerce ~left:0 ~right:1 ~top:1 ~bottom:2 + ~xpadding:0 ~ypadding:0 ~expand:`BOTH; + + GMisc.separator `HORIZONTAL ~packing:box1#pack (); + + let box2 = GPack.vbox ~spacing: 10 ~border_width: 10 + ~packing: box1#pack () in + + let button = GButton.button ~label: "close" ~packing: box2#add () in + button #connect#clicked ~callback: window#destroy; + button #grab_default (); + window #show () + + | Some window -> window #destroy () +in aux + + + +let create_check_buttons = + let rw = ref None in + let aux () = + match !rw with + | None -> + let window = GWindow.window ~title: "GtkCheckButton" + ~border_width: 0 () in + rw := Some window; + window #connect#destroy ~callback:(fun _ -> rw := None); + + let box1 = GPack.vbox ~packing:window#add () in + let box2 = GPack.vbox ~spacing: 10 ~border_width: 10 + ~packing: box1#pack () in + + for i = 1 to 3 do + GButton.check_button ~label:("button" ^ (string_of_int i)) + ~packing: box2#add (); + done; + + GMisc.separator `HORIZONTAL ~packing: box1#pack (); + + let box2 = GPack.vbox ~spacing:10 ~border_width:10 + ~packing: box1#pack () in + + let button = GButton.button ~label: "close" ~packing:box2#add () in + button #connect#clicked ~callback: window#destroy; + button #grab_default (); + window #show () + + | Some window -> window #destroy () +in aux + + +let create_radio_buttons = + let rw = ref None in + let aux () = + match !rw with + | None -> + let window = GWindow.window ~title: "radio buttons" + ~border_width: 0 () in + rw := Some window; + window #connect#destroy ~callback:(fun _ -> rw := None); + + let box1 = GPack.vbox ~packing:window#add () in + + let box2 = GPack.vbox ~spacing:10 ~border_width:10 + ~packing: box1#pack () in + + let button = GButton.radio_button ~label:"button1" + ~packing: box2#add () in + + let button = GButton.radio_button ~label:"button2" ~group:button#group + ~packing: box2#add ~active:true () in + + let button = GButton.radio_button ~label:"button3" ~group:button#group + ~packing: box2#add () in + + GMisc.separator `HORIZONTAL ~packing: box1#pack (); + + let box2 = GPack.vbox ~spacing:10 ~border_width:10 + ~packing: box1#pack () in + + let button = GButton.button ~label: "close" ~packing: box2#add () in + button #connect#clicked ~callback: window #destroy; + button #grab_default (); + window #show () + + | Some window -> window #destroy () +in aux + + +let create_toggle_buttons = + let rw = ref None in + let aux () = + match !rw with + | None -> + let window = GWindow.window ~title: "GtkToggleButton" + ~border_width: 0 () in + rw := Some window; + window #connect#destroy ~callback:(fun _ -> rw := None); + + let box1 = GPack.vbox ~packing: window#add () in + + let box2 = GPack.vbox ~spacing: 10 ~border_width: 10 + ~packing: box1#pack () in + + for i = 1 to 3 do + GButton.toggle_button ~label:("button" ^ (string_of_int i)) + ~packing: box2#add () + done; + + GMisc.separator `HORIZONTAL ~packing: box1#pack (); + + let box2 = GPack.vbox ~spacing: 10 ~border_width: 10 + ~packing: box1#pack () in + + let button = GButton.button ~label: "close" ~packing:box2#add () in + button #connect#clicked ~callback: window#destroy; + button #grab_default (); + window #show () + + | Some window -> window #destroy () +in aux + + +(* Menus *) + +let create_menu depth tearoff = + let rec aux depth tearoff = + let menu = GMenu.menu () and group = ref None in + if tearoff then ignore (GMenu.tearoff_item ~packing: menu#append ()); + for i = 0 to 4 do + let menuitem = GMenu.radio_menu_item ?group:!group + ~label:("item " ^ string_of_int depth ^ " - " ^ string_of_int (i+1)) + ~packing:menu#append ~show_toggle:(depth mod 2 <> 0) + () in + group := Some (menuitem #group); + if i = 3 then menuitem #misc#set_sensitive false; + if depth > 1 then + menuitem #set_submenu (aux (depth-1) true) + done; + + menu + in aux depth tearoff + + +let create_menus = + let rw = ref None in + fun () -> + match !rw with + | None -> + let window = GWindow.window ~title: "menus" + ~border_width: 0 () in + rw := Some window; + window #connect#destroy ~callback:(fun _ -> rw := None); + window #event#connect#delete ~callback:(fun _ -> true); + + let accel_group = GtkData.AccelGroup.create () in + window #add_accel_group accel_group ; + + let box1 = GPack.vbox ~packing:window#add () in + + let menubar = GMenu.menu_bar ~packing: box1#pack () in + + let menuitem = GMenu.menu_item ~label:"test\nline2" + ~packing: menubar#append () in + menuitem #set_submenu (create_menu 2 true); + + let menuitem = GMenu.menu_item ~label:"foo" + ~packing: menubar#append () in + menuitem #set_submenu (create_menu 3 true); + menuitem #right_justify (); + + let box2 = GPack.vbox ~spacing: 10 ~packing: box1#add + ~border_width: 10 () in + + let menu = create_menu 1 false in + menu #set_accel_group accel_group; + + let menuitem = GMenu.check_menu_item ~label:"Accelerate Me" + ~packing:menu#append () in + menuitem #add_accelerator ~group:accel_group _M + ~flags:[`VISIBLE; `SIGNAL_VISIBLE]; + + let menuitem = GMenu.check_menu_item ~label:"Accelerator Locked" + ~packing:menu#append () in + menuitem #add_accelerator ~group:accel_group _L + ~flags:[`VISIBLE; `LOCKED]; + + let menuitem = GMenu.check_menu_item ~label:"Accelerators Frozen" + ~packing:menu#append () in + menuitem #add_accelerator ~group:accel_group _F + ~flags:[`VISIBLE]; + menuitem #misc#lock_accelerators (); + + let optionmenu = GMenu.option_menu ~packing: box2#add () in + optionmenu #set_menu menu; + optionmenu #set_history 3; + + GMisc.separator `HORIZONTAL ~packing: box1#pack (); + + let box2 = GPack.vbox ~spacing:10 ~border_width:10 + ~packing: box1#pack () in + + let button = GButton.button ~label: "close" ~packing: box2#add () in + button #connect#clicked ~callback: window#destroy; + button #grab_default (); + window #show () + + | Some window -> window #destroy () + + + +(* Modal windows *) + +let cmw_destroy_cb _ = + Main.quit () + +let cmw_color parent _ = + let csd = GWindow.color_selection_dialog ~modal:true + ~title:"This is a modal color selection dialog" () in + csd # set_transient_for parent; + csd # connect#destroy ~callback:cmw_destroy_cb; + csd # ok_button # connect#clicked ~callback:csd#destroy; + csd # cancel_button # connect#clicked ~callback:csd#destroy; + csd # show (); + Main.main () + +let cmw_file parent _ = + let fs = GWindow.file_selection ~modal:true + ~title:"This is a modal file selection dialog" () in + fs # set_transient_for parent; + fs # connect#destroy ~callback:cmw_destroy_cb; + fs # ok_button # connect#clicked ~callback:fs#destroy; + fs # cancel_button # connect#clicked ~callback:fs#destroy; + fs # show (); + Main.main () + +let create_modal_window () = + let window = GWindow.window ~modal:true ~title:"This window is modal" () in + let box1 = GPack.vbox ~spacing:5 ~border_width:3 ~packing:window#add () in + let frame1 = GBin.frame ~label:"Standard dialogs in modal form" + ~packing:(box1#pack ~expand:true ~padding:4) () in + let box2 = GPack.vbox ~homogeneous:true ~spacing:5 ~packing:frame1#add () in + let btnColor = GButton.button ~label:"Color" + ~packing:(box2#pack ~padding:4) () + and btnFile = GButton.button ~label:"File selection" + ~packing:(box2#pack ~padding:4) () + and btnClose = GButton.button ~label:"Close" + ~packing:(box2#pack ~padding:4) () in + GMisc.separator `HORIZONTAL + ~packing:(box1#pack ~padding:4) (); + + btnClose #connect#clicked ~callback:(fun _ -> window #destroy ()); + window #connect#destroy ~callback:cmw_destroy_cb; + btnColor #connect#clicked ~callback: (cmw_color window); + btnFile #connect#clicked ~callback: (cmw_file window); + window # show (); + Main.main () + + +(* corrected bug in testgtk.c *) +let scrolled_windows_remove, scrolled_windows_clean = + let parent = ref None and float_parent = ref None in + let remove (scrollwin : GBin.scrolled_window) () = + match !parent with + | None -> + parent := scrollwin#misc#parent; + let f = GWindow.window ~title:"new parent" () in + float_parent := Some f#coerce; + f #set_default_size ~width:200 ~height:200; + scrollwin #misc#reparent f#coerce; + f #show () + | Some p -> + scrollwin #misc#reparent p; + match !float_parent with + | None -> () + | Some f -> + f #destroy (); + float_parent := None; + parent := None + and clean () = + match !float_parent with + | None -> () + | Some p -> p #destroy (); parent := None; float_parent := None + in remove, clean + + +(* scrolled windows *) + +let create_scrolled_windows = + let rw = ref None in + let aux () = + match !rw with + | None -> + let window = GWindow.dialog ~title:"dialog" ~border_width:0 () in + rw := Some window; + window #connect#destroy ~callback:(fun _ -> rw := None); + window #connect#destroy ~callback:scrolled_windows_clean; + + let scrolled_window = GBin.scrolled_window ~border_width:10 + ~hpolicy: `AUTOMATIC ~vpolicy:`AUTOMATIC + ~packing: window#vbox#add () in + + let table = GPack.table ~rows:20 ~columns:20 ~row_spacings:10 + ~col_spacings:10 ~packing:scrolled_window#add_with_viewport () in + table #focus#set_hadjustment (Some scrolled_window # hadjustment); + table #focus#set_vadjustment (Some scrolled_window # vadjustment); + + for i = 0 to 19 do + for j=0 to 19 do + GButton.toggle_button + ~label:("button ("^ string_of_int i ^","^ string_of_int j ^")\n") + ~packing:(table #attach ~left:i ~top:j ~expand:`BOTH) () + done + done; + + let button = GButton.button ~label:"close" + ~packing:window#action_area#add () in + button #connect#clicked ~callback:(window #destroy); + button #grab_default (); + + let button = GButton.button ~label:"remove" + ~packing:window#action_area#add () in + button #connect#clicked + ~callback:(scrolled_windows_remove scrolled_window); + button #grab_default (); + + window #set_default_size ~width:300 ~height:300; + window #show () + + | Some window -> window #destroy () + in aux + + +(* Toolbar *) + +let make_toolbar (toolbar : GButton.toolbar) window = + let icon = + let info = GDraw.pixmap_from_xpm ~file:"test.xpm" ~window () in + fun () -> (GMisc.pixmap info ())#coerce + in + + toolbar #insert_button ~text:"Horizontal" + ~tooltip:"Horizontal toolbar layout" + ~tooltip_private:"Toolbar/Horizontal" + ~icon:(icon ()) + ~callback:(fun _ -> toolbar #set_orientation `HORIZONTAL) (); + + toolbar #insert_button ~text:"Vertical" + ~tooltip:"Vertical toolbar layout" + ~tooltip_private:"Toolbar/Vertical" + ~icon:(icon ()) + ~callback:(fun _ -> toolbar #set_orientation `VERTICAL) (); + + toolbar #insert_space (); + + toolbar #insert_button ~text:"Icons" + ~tooltip: "Only show toolbar icons" + ~tooltip_private:"Toolbar/IconsOnly" + ~icon:(icon ()) + ~callback:(fun _ -> toolbar #set_style `ICONS) (); + + toolbar #insert_button ~text:"Text" + ~tooltip: "Only show toolbar text" + ~tooltip_private:"Toolbar/TextOnly" + ~icon:(icon ()) + ~callback:(fun _ -> toolbar #set_style `TEXT) (); + + toolbar #insert_button ~text:"Both" + ~tooltip: "Show toolbar icons and text" + ~tooltip_private:"Toolbar/Both" + ~icon:(icon ()) + ~callback:(fun _ -> toolbar #set_style `BOTH) (); + + toolbar #insert_space (); + + GEdit.entry ~packing:(toolbar #insert_widget + ~tooltip:"This is an unusable GtkEntry" + ~tooltip_private: "Hey don't click me!!!") (); + + toolbar #insert_button ~text:"Small" + ~tooltip:"Use small spaces" + ~tooltip_private:"Toolbar/Small" + ~icon:(icon ()) + ~callback:(fun _ -> toolbar #set_space_size 5) (); + + toolbar #insert_button ~text:"Big" + ~tooltip:"Use big spaces" + ~tooltip_private:"Toolbar/Big" + ~icon:(icon ()) + ~callback:(fun _ -> toolbar #set_space_size 10) (); + + toolbar #insert_space (); + + toolbar #insert_button ~text:"Enable" + ~tooltip:"Enable tooltips" + ~icon:(icon ()) + ~callback:(fun _ -> toolbar #set_tooltips true) (); + + toolbar #insert_button ~text:"Disable" + ~tooltip:"Disable tooltips" + ~icon:(icon ()) + ~callback:(fun _ -> toolbar #set_tooltips false) (); + + toolbar #insert_space (); + + toolbar #insert_button ~text:"Borders" + ~tooltip:"Show borders" + ~icon:(icon ()) + ~callback:(fun _ -> toolbar #set_button_relief `NORMAL) (); + + toolbar #insert_button ~text:"Borderless" + ~tooltip:"Hide borders" + ~icon:(icon ()) + ~callback:(fun _ -> toolbar #set_button_relief `NONE) (); + + toolbar #insert_space (); + + toolbar #insert_button ~text:"Empty" + ~tooltip:"Empty spaces" + ~icon:(icon ()) + ~callback:(fun _ -> toolbar #set_space_style `EMPTY) (); + + toolbar #insert_button ~text:"Lines" + ~tooltip:"Lines in spaces" + ~icon:(icon ()) + ~callback:(fun _ -> toolbar #set_space_style `LINE) (); + () + +let create_toolbar = + let rw = ref None in + let aux () = + match !rw with + | None -> + let window = GWindow.window ~title: "Toolbar test" + ~border_width: 0 ~allow_shrink: false ~allow_grow: true + ~auto_shrink: true () in + rw := Some window; + window #connect#destroy ~callback:(fun _ -> rw := None); + window #misc #realize (); + + let toolbar = GButton.toolbar ~packing: window#add () in + make_toolbar toolbar window; + + window #show () + + | Some window -> window #destroy () + in aux + + +(* Handlebox *) + +let handle_box_child_signal action (hb : GBin.handle_box) child = + Printf.printf "%s: child <%s> %s\n" hb#misc#get_type child#misc#get_type action + +let create_handle_box = + let rw = ref None in + let aux () = + match !rw with + | None -> + let window = GWindow.window ~title: "Handle box test" + ~border_width: 20 ~allow_shrink: false ~allow_grow: true + ~auto_shrink: true () in + rw := Some window; + window #connect#destroy ~callback:(fun _ -> rw := None); + window #misc #realize (); + + let vbox = GPack.vbox ~packing:window#add () in + + GMisc.label ~text:"Above" ~packing:vbox#add (); + GMisc.separator `HORIZONTAL ~packing:vbox#add (); + + let hbox = GPack.hbox ~spacing:10 ~packing:vbox#add () in + GMisc.separator `HORIZONTAL ~packing:vbox#add (); + + GMisc.label ~text:"Below" ~packing:vbox#add (); + let handle_box = GBin.handle_box ~packing:hbox#pack () in + handle_box #connect#child_attached + ~callback:(handle_box_child_signal "attached" handle_box); + handle_box #connect#child_detached + ~callback:(handle_box_child_signal "detached" handle_box); + + let toolbar = GButton.toolbar ~packing:handle_box#add () in + make_toolbar toolbar window; + toolbar #set_button_relief `NORMAL; + + let handle_box = GBin.handle_box ~packing:hbox#pack () in + handle_box #connect#child_attached + ~callback:(handle_box_child_signal "attached" handle_box); + handle_box #connect#child_detached + ~callback:(handle_box_child_signal "detached" handle_box); + + let handle_box2 = GBin.handle_box ~packing:handle_box#add () in + handle_box2 #connect#child_attached + ~callback:(handle_box_child_signal "attached" handle_box); + handle_box2 #connect#child_detached + ~callback:(handle_box_child_signal "detached" handle_box); + + GMisc.label ~text:"Fooo!" ~packing:handle_box2#add (); + window #show () + + | Some window -> window #destroy () + in aux + + + +(* Tree *) + +class tree_and_buttons () = +object + val tree = GTree.tree () + val add_button = GButton.button ~label: "Add Item" () + val remove_button = GButton.button ~label:"Remove Item(s)" () + val subtree_button = GButton.button ~label:"Remove Subtree" () + val mutable nb_item_add = 0 + + method tree = tree + method add_button = add_button + method remove_button = remove_button + method subtree_button = subtree_button + method nb_item_add = nb_item_add + method incr_nb_item_add = nb_item_add <- nb_item_add + 1 +end + +let cb_tree_destroy_event w = () + +let cb_add_new_item (treeb : tree_and_buttons) _ = + let subtree = + match treeb#tree#selection with + | [] -> treeb#tree + | selected_item :: _ -> + match selected_item#subtree with Some t -> t + | None -> + let t = GTree.tree () in + selected_item#set_subtree t; + t + in + let item_new = GTree.tree_item ~packing:(subtree#insert ~pos:0) + ~label:("item add " ^ string_of_int treeb # nb_item_add) () in + treeb #incr_nb_item_add + + +let cb_remove_item (treeb : tree_and_buttons) _ = + let tree = treeb#tree in + match tree #selection with + | [] -> () + | selected -> tree #remove_items selected + + +let cb_remove_subtree (treeb : tree_and_buttons) _ = + match treeb#tree #selection with + | [] -> () + | selected_item :: _ -> + try selected_item#subtree; selected_item#remove_subtree () + with Not_found -> () + +let cb_tree_changed (treeb : tree_and_buttons) _ = + let tree = treeb#tree in + let nb_selected = List.length (tree#selection) in + if nb_selected = 0 then begin + treeb # remove_button #misc#set_sensitive false; + treeb # subtree_button #misc#set_sensitive false; + end else begin + treeb # remove_button #misc#set_sensitive true; + treeb # subtree_button #misc#set_sensitive (nb_selected = 1); + treeb # add_button #misc#set_sensitive (nb_selected = 1); + end + + +let rec create_subtree (item : GTree.tree_item) level nb_item_max + recursion_level_max = + if level = recursion_level_max then () + else begin + let item_subtree = GTree.tree () in + for nb_item = 1 to nb_item_max do + let item_new = GTree.tree_item ~packing:(item_subtree#insert ~pos:0) + ~label:("item" ^ string_of_int level ^ "-" ^ string_of_int nb_item) () + in + create_subtree item_new (level + 1) nb_item_max recursion_level_max; + done; + item # set_subtree item_subtree + end + + +let create_tree_sample selection_mode draw_line view_line no_root_item + nb_item_max recursion_level_max = + let window = GWindow.window ~title:"Tree Sample" () in + let box1 = GPack.vbox ~packing:window#add () in + let box2 = GPack.vbox ~packing:box1#add ~border_width:5 () in + let scrolled_win = GBin.scrolled_window ~packing:box2#add + ~hpolicy: `AUTOMATIC ~vpolicy:`AUTOMATIC + ~width:200 ~height:200 () in + + let root_treeb = new tree_and_buttons () in + let root_tree = root_treeb#tree in + root_tree #connect#selection_changed ~callback:(cb_tree_changed root_treeb); + scrolled_win #add_with_viewport root_tree#coerce; + root_tree #set_selection_mode selection_mode; + root_tree #set_view_lines draw_line; + root_tree #set_view_mode + (match view_line with `LINE -> `ITEM | `ITEM -> `LINE); + + if no_root_item then + for nb_item = 1 to nb_item_max do + let item_new = GTree.tree_item ~label:("item0-" ^ string_of_int nb_item) + ~packing:(root_tree#insert ~pos:0) () in + create_subtree item_new 1 nb_item_max recursion_level_max; + done + else begin + let root_item = GTree.tree_item ~label:"root item" + ~packing:(root_tree #insert ~pos:0) () in + create_subtree root_item 0 nb_item_max recursion_level_max + end; + + let box2 = GPack.vbox ~border_width:5 ~packing:box1#pack () in + + let button = root_treeb #add_button in + button #misc#set_sensitive false; + button #connect#clicked ~callback:(cb_add_new_item root_treeb); + box2 #add button#coerce; + + let button = root_treeb #remove_button in + button #misc#set_sensitive false; + button #connect#clicked ~callback:(cb_remove_item root_treeb); + box2 #add button#coerce; + + let button = root_treeb #subtree_button in + button #misc#set_sensitive false; + button #connect#clicked ~callback:(cb_remove_subtree root_treeb); + box2 #add button#coerce; + + GMisc.separator `HORIZONTAL ~packing:box1#pack (); + + let button = GButton.button ~label:"Close" ~packing:box2#add () in + button #connect#clicked ~callback:window#destroy; + + window #show () + + +let create_tree_mode_window = + let rw = ref None in + let aux () = + let default_number_of_item = 3.0 in + let default_recursion_level = 3.0 in + let single_button = GButton.radio_button ~label:"SINGLE" () in + let browse_button = GButton.radio_button + ~group:single_button#group ~label:"BROWSE" () in + let multiple_button = GButton.radio_button + ~group:browse_button#group ~label:"MULTIPLE" () in + let draw_line_button = GButton.check_button ~label:"Draw line" () in + let view_line_button = GButton.check_button ~label:"View line mode" () in + let no_root_item_button = GButton.check_button + ~label:"Without Root item" () in + let nb_item_spinner = GEdit.spin_button + ~adjustment:(GData.adjustment ~value:default_number_of_item + ~lower:1.0 ~upper:255.0 ~step_incr:1.0 ~page_incr:5.0 + ~page_size:0.0 ()) ~rate:0. ~digits:0 () in + let recursion_spinner = GEdit.spin_button + ~adjustment:(GData.adjustment ~value:default_recursion_level + ~lower:0.0 ~upper:255.0 ~step_incr:1.0 ~page_incr:5.0 + ~page_size:0.0 ()) ~rate:0. ~digits:0 () in + let cb_create_tree _ = + let selection_mode = + if single_button #active then `SINGLE + else if browse_button #active then `BROWSE + else `MULTIPLE in + let nb_item = nb_item_spinner#value_as_int in + let recursion_level = recursion_spinner#value_as_int in + create_tree_sample selection_mode (draw_line_button #active) + (if (view_line_button #active) then `ITEM else `LINE) + (no_root_item_button #active) + nb_item recursion_level + in + match !rw with + | None -> + let window = GWindow.window ~title:"Set Tree Parameters" () in + rw := Some window; + window #connect#destroy ~callback:(fun _ -> rw := None); + + let box1 = GPack.vbox ~packing:window#add () in + + let box2 = GPack.vbox ~spacing:5 ~packing:box1#add + ~border_width:5 () in + + let box3 = GPack.hbox ~spacing:5 ~packing:box2#add () in + + let frame = GBin.frame ~label:"Selection Mode" ~packing:box3#add () + in + + let box4 = GPack.vbox ~packing:frame#add ~border_width:5 () in + + box4 #add single_button#coerce; + box4 #add browse_button#coerce; + box4 #add multiple_button#coerce; + + let frame = GBin.frame ~label:"Options" ~packing:box3#add () in + + let box4 = GPack.vbox ~packing:frame#add ~border_width:5 () in + box4 #add draw_line_button#coerce; + draw_line_button #set_active true; + + box4 #add view_line_button#coerce; + view_line_button #set_active true; + + box4 #add no_root_item_button#coerce; + + let frame = GBin.frame ~label:"Size Parameters" ~packing:box2#add () + in + + let box4 = GPack.hbox ~spacing:5 ~packing:frame#add ~border_width:5 () in + + let box5 = GPack.hbox ~spacing:5 ~packing:box4#add () in + let label = GMisc.label ~text:"Number of items : " + ~xalign:0. ~yalign:0.5 ~packing:box5#pack () in + box5 #pack nb_item_spinner#coerce; + + let label = GMisc.label ~text:"Depth : " ~xalign:0. ~yalign:0.5 + ~packing:box5#pack () in + box5 #pack recursion_spinner#coerce; + + GMisc.separator `HORIZONTAL ~packing:box1#pack (); + + let box2 = GPack.hbox ~homogeneous:true ~spacing:10 ~border_width:5 + ~packing:box1#pack () in + + let button = GButton.button ~label:"Create Tree" + ~packing:box2#add () in + button #connect#clicked ~callback:cb_create_tree; + + let button = GButton.button ~label: "close" ~packing:box2#add () in + button #connect#clicked ~callback: window#destroy; + button #grab_default (); + window #show () + + | Some window -> window #destroy () + in aux + + + +(* Tooltips *) + +let tips_query_widget_entered (toggle : GButton.toggle_button) + (tq : GMisc.tips_query) _ ~text ~privat:_ = + if toggle #active then begin + tq #set_text + (match text with + | None -> "There is no tip!" | Some _ -> "There is a tip!"); + GtkSignal.stop_emit () + end + +let tips_query_widget_selected (w : #widget option) ~text ~privat:tp _ = + (match w with + | None -> () + | Some w -> + Printf.printf "Help \"%s\" requested for <%s>\n" + (match tp with None -> "None" | Some t -> t) + (w #misc#get_type)); + true + + +let create_tooltips = + let rw = ref None in + let aux () = + match !rw with + | None -> + + let window = GWindow.window ~title:"Tooltips" + ~border_width:0 ~allow_shrink:false ~allow_grow:false + ~auto_shrink:true () in + rw := Some window; + let tooltips = GData.tooltips () in + window #connect#destroy + ~callback:(fun _ -> tooltips #destroy (); rw := None); + + let box1 = GPack.vbox ~packing:window#add () in + + let box2 = GPack.vbox ~spacing:10 ~border_width:10 + ~packing:box1#add () in + + let button = GButton.toggle_button ~label:"button1" + ~packing:box2#add () + in + tooltips #set_tip button#coerce ~text:"This is button1" + ~privat:"ContextHelp/buttons/1"; + + let button = GButton.toggle_button ~label:"button2" + ~packing:box2#add () + in + tooltips #set_tip button#coerce + ~text:"This is button 2. This is also a really long tooltip which probably won't fit on a single line and will therefore need to be wrapped. Hopefully the wrapping will work correctly." + ~privat:"ContextHelp/buttons/2_long"; + + let toggle = GButton.toggle_button ~label:"Override TipsQuery Label" + ~packing:box2#add () in + tooltips #set_tip toggle#coerce ~text:"Toggle TipsQuery view." + ~privat:"Hi msw! ;)"; + + let box3 = GPack.vbox ~spacing:5 ~border_width:5 () in + + let button = GButton.button ~label:"[?]" + ~packing:box3#pack () in + + let tips_query = GMisc.tips_query ~packing:box3#add () in + button #connect#clicked ~callback:(tips_query #start); + + tooltips #set_tip button#coerce ~text:"Start the Tooltips Inspector" + ~privat:"ContextHelp/buttons/?"; + + tips_query #set_caller button#coerce; + tips_query #connect#widget_entered + ~callback:(tips_query_widget_entered toggle tips_query); + tips_query #connect#widget_selected ~callback:tips_query_widget_selected; + + let frame = GBin.frame ~label:"Tooltips Inspector" + ~border_width:0 ~packing:(box2#pack ~expand:true ~padding:10) + ~label_xalign:0.5 ~label_yalign:0.0 () in + frame #add box3#coerce; + + GMisc.separator `HORIZONTAL ~packing:box1#pack (); + + let box2 = GPack.vbox ~spacing: 10 ~border_width: 10 + ~packing: box1#pack () in + + let button = GButton.button ~label: "close" ~packing: box2#add () in + button #connect#clicked ~callback: window#destroy; + button #grab_default (); + tooltips #set_tip button#coerce ~text:"Push this button to close window" + ~privat:"ContextHelp/buttons/Close"; + + window #show (); + + | Some window -> window #destroy () + in aux + + +(* Labels *) +let create_labels = + let rw = ref None in + let aux () = + match !rw with + | None -> + + let window = GWindow.window ~title:"Labels" ~border_width:5 () in + rw := Some window; + window #connect#destroy + ~callback:(fun _ -> rw := None); + + let hbox = GPack.hbox ~spacing:5 ~packing:window#add () in + let vbox = GPack.vbox ~spacing:5 ~packing:hbox#add () in + + let frame = GBin.frame ~label:"Normal Label" + ~packing:vbox#pack () in + GMisc.label ~text:"This is a normal label" ~packing:frame#add (); + + let frame = GBin.frame ~label:"Multi_line Label" + ~packing:vbox#pack () in + GMisc.label ~packing:frame#add + ~text:"This is a multi-line label.\nSecond line\nThird line" (); + + let frame = GBin.frame ~label:"Left Justified Label" + ~packing:vbox#pack () in + GMisc.label ~packing:frame#add ~justify:`LEFT + ~text:"This is a left justified\nmulti_line label\nThird line" (); + + let frame = GBin.frame ~label:"Right Justified Label" + ~packing:vbox#pack () in + GMisc.label ~packing:frame#add ~justify:`RIGHT + ~text:"This is a right justified\nmulti_line label\nThird line" (); + + let vbox = GPack.vbox ~spacing:5 ~packing:hbox#add () in + + let frame = GBin.frame ~label:"Line wrapped Label" + ~packing:vbox#pack () in + GMisc.label ~packing:frame#add ~line_wrap:true + ~text:"This is an example of a line-wrapped label. It should not be taking up the entire width allocated to it, but automatically wraps the words to fit. The time has come, for all good men, to come to the aid of their party. The sixth sheik's six sheep's sick.\n It supports multiple paragraphs correctly, and correctly adds many extra spaces. " (); + + let frame = GBin.frame ~label:"Underlined Label" + ~packing:vbox#pack () in + GMisc.label ~text:"This label is underlined!\nThis one is underlined in a quite a funky fashion" ~packing:frame#add + ~justify:`LEFT ~pattern:"_________________________ _ _________ _ _____ _ __ __ ___ ____ _____" (); + + window #show (); + + | Some window -> window #destroy () + in aux + + +(* reparent *) + + +let set_parent child old_parent = + let name_opt = function + | None -> "(NULL)" + | Some w -> w#misc#get_type in + Printf.printf + "set parent for \"%s\": new parent: \"%s\", old parent: \"%s\"\n" + child#misc#get_type + (match child#misc#parent with Some p -> p#misc#get_type | None -> "(NULL)") + (name_opt old_parent) + +let reparent_label (label : GMisc.label) new_parent _ = + label #misc#reparent new_parent + + + +let create_reparent = + let rw = ref None in + let aux () = + match !rw with + | None -> + + let window = GWindow.window ~title:"Reparent" ~border_width:5 () in + rw := Some window; + window #connect#destroy ~callback:(fun _ -> rw := None); + + let vbox = GPack.vbox ~packing:window#add () in + let hbox = GPack.hbox ~spacing:5 ~border_width:10 + ~packing:vbox#add () in + + let frame = GBin.frame ~label:"Frame1" ~packing:hbox#add () in + let vbox2 = GPack.vbox ~spacing:5 ~border_width:5 + ~packing:frame#add () in + let label = GMisc.label ~text:"Hello world" + ~packing:vbox2#pack () in + label #misc#connect#parent_set ~callback:(set_parent label); + let button = GButton.button ~label:"switch" + ~packing:vbox2#pack () in + button #connect#clicked ~callback:(reparent_label label vbox2#coerce); + + let frame = GBin.frame ~label:"Frame2" ~packing:hbox#add () in + let vbox2 = GPack.vbox ~spacing:5 ~packing:frame#add ~border_width:5 () in + let button = GButton.button ~label:"switch" + ~packing:vbox2#pack () in + button #connect#clicked ~callback:(reparent_label label vbox2#coerce); + + GMisc.separator `HORIZONTAL ~packing:vbox#pack (); + + let vbox = GPack.vbox ~spacing:10 ~border_width:10 + ~packing:vbox#pack () in + + let button = GButton.button ~label: "close" ~packing:vbox#add () in + button #connect#clicked ~callback: window#destroy; + button #grab_default (); + + window #show (); + + | Some window -> window #destroy () + in aux + + + + +let create_main_window () = + let buttons = [ + "button box", Some create_button_box; + "buttons", Some create_buttons; + "check buttons", Some create_check_buttons; + "clist", None; + "color selection", None; + "ctree", None; + "cursors", None; + "dialog", None; + "entry", None; + "event watcher", None; + "file selection", None; + "font selection", None; + "gamma curve", None; + "handle box", Some create_handle_box; + "item factory", None; + "labels", Some create_labels; + "layout", None; + "list", None; + "menus", Some create_menus; + "modal windows", Some create_modal_window; + "notebooks", None; + "panes", None; + "pixmap", None; + "preview color", None; + "preview gray", None; + "progress bar", None; + "radio buttons", Some create_radio_buttons; + "range controls", None; + "rc file", None; + "reparent", Some create_reparent; + "rulers", None; + "saved position", None; + "scrolled windows", Some create_scrolled_windows; + "shapes", None; + "spinbutton", None; + "statusbar", None; + "test idle", None; + "test mainloop", None; + "test scrolling", None; + "test selection", None; + "test timeout", None; + "text", None; + "toggle buttons", Some create_toggle_buttons; + "toolbar", Some create_toolbar; + "tooltips", Some create_tooltips; + "tree", Some create_tree_mode_window; + "WM hints", None + ] in + + let window = GWindow.window ~title:"main window" ~allow_shrink:false + ~allow_grow:false ~auto_shrink:false ~width:200 ~height:400 ~x:20 ~y:20 () in + + window #connect#destroy ~callback: Main.quit; + + let box1 = GPack.vbox ~packing: window#add () in + + GMisc.label ~text: "Gtk+ v1.2" ~packing:box1#pack (); + + let scrolled_window = GBin.scrolled_window ~border_width: 10 + ~hpolicy: `AUTOMATIC ~vpolicy: `AUTOMATIC + ~packing:box1#add () in + + let box2 = GPack.vbox ~border_width: 10 + ~packing:scrolled_window#add_with_viewport () in + box2 #focus#set_vadjustment (Some scrolled_window#vadjustment); + + let rec aux = function + | [] -> () + | (_, None) :: tl -> aux tl + | (label, Some func) :: tl -> + let button = GButton.button ~label: label ~packing: box2#add () in + button #connect#clicked ~callback: func; + aux tl + in aux buttons; + + GMisc.separator `HORIZONTAL ~packing: box1#pack (); + + let box2 = GPack.vbox ~spacing: 10 ~border_width: 10 + ~packing: box1#pack () in + + let button = GButton.button ~label: "close" ~packing: box2#add () in + button #connect#clicked ~callback: window#destroy; + button #grab_default (); + + window #show (); + + Main.main () + +let _ = create_main_window () + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/testinput.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/testinput.ml new file mode 100644 index 000000000..a6aceb825 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/testinput.ml @@ -0,0 +1,43 @@ +(* $Id$ *) + +open GMain + +let main () = + let window = GWindow.window () in + window#misc#set_name "Test input"; + window#connect#destroy ~callback:Main.quit; + + let vbox = GPack.vbox ~packing:window#add () in + + let drawing_area = + GMisc.drawing_area ~width:200 ~height:200 ~packing:vbox#add () in + + drawing_area#event#connect#key_press ~callback: + begin fun ev -> + let key = GdkEvent.Key.keyval ev in + if key >= 32 && key < 256 then + Printf.printf "I got a %c\n" (Char.chr key) + else + print_string "I got another key\n"; + flush stdout; + true + end; + + drawing_area#event#add + [`EXPOSURE;`LEAVE_NOTIFY;`BUTTON_PRESS; + `POINTER_MOTION;`POINTER_MOTION_HINT;`PROXIMITY_OUT]; + drawing_area#event#set_extensions `ALL; + drawing_area#misc#set_can_focus true; + drawing_area#misc#grab_focus (); + + GButton.button ~label:"Input Dialog" ~packing:vbox#pack (); + + let button = + GButton.button ~label:"Quit" ~packing:vbox#pack () in + + button#connect#clicked ~callback:window#destroy; + + window#show (); + Main.main () + +let _ = main () diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/tictactoe.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/tictactoe.ml new file mode 100644 index 000000000..be01e19b9 --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/tictactoe.ml @@ -0,0 +1,113 @@ +(* $Id$ *) + +open GtkNew +open GtkBase + +(* To create a new widget: + create an array sig_array containing the signals defined by + the new widget; + call: + make_new_widget name parent:parent signal_array:sig_array + where name is the name of the new widget (a string) + parent is the type of the parent: of type Gtk.New.object_type + This call returns a triple: + (get_type_func, new_func, sig_array_num) + where get_type_func is the new widget get_type function, + new_func is the function returning a new widget of the new type + sig_array_num is an array containing the Gtk id of the signals + of the new widget. +*) + +module Tictactoe = struct + type t = [`widget|`container|`box|`tictactoe] + module Signals = struct + open GtkSignal + let tictactoe : ([>`tictactoe],_) t = + { name = "tictactoe"; marshaller = marshal_unit } + let emit_tictactoe = emit_unit ~sgn:tictactoe + end + let create : unit -> t Gtk.obj = + let _,tictactoe_new = make_new_widget + ~name:"Tictactoe" ~parent:VBOX ~signals:[Signals.tictactoe] + in fun () -> Object.try_cast (tictactoe_new ()) "Tictactoe" +end + +open GMain + +class tictactoe_signals obj = object + inherit GContainer.container_signals obj + method tictactoe = + GtkSignal.connect ~sgn:Tictactoe.Signals.tictactoe obj ~after +end + +exception Trouve + +class tictactoe ?packing ?show () = + let obj : Tictactoe.t Gtk.obj = Tictactoe.create () in + let box = new GPack.box_skel obj in +object (self) + inherit GObj.widget obj + val mutable buttons = [||] + val mutable buttons_handlers = [||] + val label = GMisc.label ~text:"Go on!" ~packing:box#add () + method clear () = + for i = 0 to 2 do + for j = 0 to 2 do + let button = buttons.(i).(j) + and handler = buttons_handlers.(i).(j) in + button#misc#handler_block handler; + button#set_active false; + button#misc#handler_unblock handler + done + done + method connect = new tictactoe_signals obj + method emit_tictactoe () = + GtkSignal.emit_unit obj ~sgn:Tictactoe.Signals.tictactoe + method toggle () = + let rwins = [| [| 0; 0; 0 |]; [| 1; 1; 1 |]; [| 2; 2; 2 |]; + [| 0; 1; 2 |]; [| 0; 1; 2 |]; [| 0; 1; 2 |]; + [| 0; 1; 2 |]; [| 0; 1; 2 |] |] + and cwins = [| [| 0; 1; 2 |]; [| 0; 1; 2 |]; [| 0; 1; 2 |]; + [| 0; 0; 0 |]; [| 1; 1; 1 |]; [| 2; 2; 2 |]; + [| 0; 1; 2 |]; [| 2; 1; 0 |] |] in + label#set_text"Go on!"; + try + for k = 0 to 7 do + let rec aux i = + (i = 3) || + (buttons.(rwins.(k).(i)).(cwins.(k).(i))#active) && (aux (i+1)) in + if aux 0 then raise Trouve + done + with Trouve -> label#set_text "Win!!"; self#emit_tictactoe () + + initializer + let table = + GPack.table ~rows:3 ~columns:3 ~homogeneous:true ~packing:box#add () in + buttons <- + Array.init 3 ~f: + (fun i -> Array.init 3 ~f: + (fun j -> + GButton.toggle_button ~width:20 ~height:20 + ~packing:(table#attach ~left:i ~top:j ~expand:`BOTH) ())); + buttons_handlers <- + Array.mapi buttons ~f: + (fun i -> Array.mapi ~f: + (fun j button -> button #connect#toggled ~callback:self#toggle)); + GObj.pack_return self ~packing ~show; + () +end + +let win (ttt : tictactoe) _ = + Printf.printf "Gagne!!\n" ; + ttt #clear () + +let essai () = + let window = GWindow.window ~title:"Tictactoe" ~border_width:10 () in + window #connect#destroy ~callback:Main.quit; + let ttt = new tictactoe ~packing:window#add () in + ttt #connect#tictactoe ~callback:(win ttt); + window #show (); + Main.main () + +let _ = essai () + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/tron.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/tron.ml new file mode 100644 index 000000000..eced44a9c --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/tron.ml @@ -0,0 +1,204 @@ +(* $Id$ *) + +(* Tron? Game *) +open GMain + +let m_pi = acos (-1.) +let clRed = `NAME "red" (* `BLACK *) +let clBlue = `NAME "blue" (* `WHITE *) +let clBlack = `BLACK + +type point = {mutable x: int; mutable y: int} + +let main () = +(* Game State *) + let gameSize = 64 in + let gameState = + Array.create_matrix ~dimx:(gameSize+2) ~dimy:(gameSize+2) 0 in + let gameInit _ = + for i=1 to gameSize do + for j=1 to gameSize do + gameState.(i).(j) <- 0; + done + done; + for i=0 to gameSize do + gameState.(0).(i) <- 3; (* left wall *) + gameState.(i).(gameSize+1) <- 3; (* floor *) + gameState.(gameSize+1).(i+1) <- 3; (* right wall *) + gameState.(i+1).(0) <- 3 (* ceiling *) + done in + gameInit (); + let lpos = {x=4; y=4} in + let lspeed = {x=0; y=1} in + let rpos = {x=gameSize-3; y=gameSize-3} in + let rspeed = {x=0; y= -1} in + let keys = "asdfhjkl" in + let keyMapL = [|(-1, 0); (0, -1); (0, 1); (1, 0)|] in + let keyMapR = [|(-1, 0); (0, 1); (0, -1); (1, 0)|] in + +(* User Interface *) + let window = GWindow.window ~border_width:10 ~title:"tron(?)" () in + window#event#connect#delete + ~callback:(fun _ -> prerr_endline "Delete event occured"; false); + window#connect#destroy ~callback:Main.quit; + let vbx = GPack.vbox ~packing:window#add () in + let area = GMisc.drawing_area ~width:((gameSize+2)*4) ~height:((gameSize+2)*4) + ~packing:vbx#add () in + let drawing = area#misc#realize (); new GDraw.drawable (area#misc#window) in + let style = area#misc#style#copy in + style#set_bg [`NORMAL,`WHITE]; + area#misc#set_style style; + drawing#set_background `WHITE; + let area_expose _ = + for i=0 to gameSize+1 do + for j=0 to gameSize+1 do + if gameState.(i).(j) = 1 then begin + drawing#set_foreground clRed; + drawing#rectangle ~filled:true ~x:(i*4) ~y:(j*4) ~width:4 ~height:4 () + end + else if gameState.(i).(j) = 2 then begin + drawing#set_foreground clBlue; + drawing#rectangle ~filled:true ~x:(i*4) ~y:(j*4) ~width:4 ~height:4 () + end + else if gameState.(i).(j) = 3 then begin + drawing#set_foreground clBlack; + drawing#rectangle ~filled:true ~x:(i*4) ~y:(j*4) ~width:4 ~height:4 () + end + done + done; + false + in + area#event#connect#expose ~callback:area_expose; + let control = GPack.table ~rows:3 ~columns:7 ~packing:vbx#pack () in + + let abuttonClicked num (lbl : GMisc.label) _ = begin + let dialog = + GWindow.window ~kind:`DIALOG ~border_width:10 ~title:"Key remap" () in + let dvbx = GPack.box `VERTICAL ~packing:dialog#add () in + let entry = GEdit.entry ~max_length:1 ~packing: dvbx#add () in + let txt = String.make 1 keys.[num] in + entry#set_text txt; + let dquit = GButton.button ~label:"OK" ~packing: dvbx#add () in + dquit#connect#clicked ~callback: + begin fun _ -> + let chr = entry#text.[0] in + let txt2 = String.make 1 chr in + lbl#set_text txt2; + keys.[num]<-chr; + dialog#destroy () + end; + dialog#show () + end in + let attach = control#attach ~expand:`BOTH in + let new_my_button ~label:label ~left:left ~top:top = + let str = String.make 1 keys.[label] in + let btn = GButton.button ~packing:(attach ~left:left ~top:top) () in + let lbl = GMisc.label ~text:str ~packing:(btn#add) () in + btn#connect#clicked ~callback:(abuttonClicked label lbl); + btn + in + new_my_button ~label:0 ~left:1 ~top:2; + new_my_button ~label:1 ~left:2 ~top:1; + new_my_button ~label:2 ~left:2 ~top:3; + new_my_button ~label:3 ~left:3 ~top:2; + new_my_button ~label:4 ~left:5 ~top:2; + new_my_button ~label:5 ~left:6 ~top:3; + new_my_button ~label:6 ~left:6 ~top:1; + new_my_button ~label:7 ~left:7 ~top:2; + let quit = + GButton.button ~label:"Quit" ~packing:(attach ~left:4 ~top:2) () in + quit#connect#clicked ~callback:window#destroy; + let message = GMisc.label ~text:"tron(?) game" ~packing:vbx#pack () in + + let game_step () = + let lx = lpos.x in let ly = lpos.y in + gameState.(lx).(ly) <- 1; + drawing#set_foreground clRed; + drawing#rectangle ~filled:true ~x:(lx*4) ~y:(ly*4) ~width:4 ~height:4 (); + let rx = rpos.x in let ry = rpos.y in + gameState.(rx).(ry) <- 2; + drawing#set_foreground clBlue; + drawing#rectangle ~filled:true ~x:(rx*4) ~y:(ry*4) ~width:4 ~height:4 () + in + game_step (); + let keyDown ev = begin + let key = GdkEvent.Key.keyval ev in + for i=0 to (Array.length keyMapL)-1 do + let (x, y) = keyMapL.(i) in + let k = keys.[i] in + if key = Char.code k then begin + lspeed.x <- x; + lspeed.y <- y + end; + let (x, y) = keyMapR.(i) in + let k = keys.[i+4] in + if key = Char.code k then begin + rspeed.x <- x; + rspeed.y <- y + end + done; + false end in + window#event#connect#key_press ~callback:keyDown; + let safe_check _ = + if lpos.x == rpos.x && lpos.y == rpos.y then + 3 + else + (* player 1 *) + (if gameState.(lpos.x).(lpos.y) != 0 then 2 else 0) + + + (* player 2 *) + (if gameState.(rpos.x).(rpos.y) != 0 then 1 else 0) + in + let timerID = ref (* dummy *) (Timeout.add ~ms:100 ~callback:(fun _ -> true)) in + let timerTimer _ = begin + lpos.x <- lpos.x+lspeed.x; + lpos.y <- lpos.y+lspeed.y; + rpos.x <- rpos.x+rspeed.x; + rpos.y <- rpos.y+rspeed.y; + let result = safe_check() in + if result!=0 then begin + Timeout.remove (!timerID); + message#set_text ("player "^string_of_int result^" won.") + end + else begin + game_step() + end; + true + end in + let count = ref 3 in + let timerTimer2 _ = begin +(* message#set_label (string_of_int (!count)); *) + if (!count==0) then begin + Timeout.remove (!timerID); + timerID := Timeout.add ~ms:100 ~callback:timerTimer + end + else begin + count := !count-1; + end; + true + end in + let restartClicked () = + Timeout.remove !timerID; + gameInit(); + lpos.x <- 4; lpos.y <- 4; + lspeed.x <- 0; lspeed.y <- 1; + rpos.x <- gameSize-3; rpos.y <- gameSize-3; + rspeed.x <- 0; rspeed.y <- -1; + drawing#set_foreground `WHITE; + drawing#rectangle ~filled:true ~x:0 ~y:0 + ~width:((gameSize+2)*4) ~height:((gameSize+2)*4) (); + area_expose(); + count := 3; + timerID := Timeout.add ~ms:300 ~callback:timerTimer2; + in + let restart = + GButton.button ~label: "Restart" ~packing:(attach ~left:4 ~top:3) () in + restart#connect#clicked ~callback:restartClicked; + restartClicked (); + + window#show (); + Main.main () + +let _ = Printexc.print main () + + diff --git a/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/xmhtml/test.ml b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/xmhtml/test.ml new file mode 100644 index 000000000..6c9d3715a --- /dev/null +++ b/helm/DEVEL/lablgtk/lablgtk_20001129-0.1.0/examples/xmhtml/test.ml @@ -0,0 +1,38 @@ +(* $Id$ *) + +let test_string2 = String.concat ~sep:"" [ + "\n"; + "The Gtk/XmHTML test\n"; + "This is the Gtk/XmHTML test program

\n"; + "You can invoke this program with a command line argument, like this:\n"; + "


"; + "./xtest filename.html"; + "
"; + "Click here to load a different test message"; + ""; +] + +let read_file file = + let ic = open_in file in + let b = Buffer.create 16384 and s = String.create 1024 and len = ref 0 in + while len := input ic ~buf:s ~pos:0 ~len:1024; !len > 0 do + Buffer.add_substring b s ~pos:0 ~len:!len + done; + Buffer.contents b + +open GMain + +let _ = + let w = GWindow.window ~width:600 ~height:500 () in + w#connect#destroy ~callback:Main.quit; + let source = + if Array.length Sys.argv > 1 then begin + Sys.chdir (Filename.dirname Sys.argv.(1)); + read_file (Filename.basename Sys.argv.(1)) + end + else test_string2 in + let html = GHtml.xmhtml ~source ~packing:w#add () in + html#set_anchor_buttons false; + html#set_anchor_underline [`SINGLE;`DASHED]; + w#show (); + Main.main () -- 2.39.2