From f7314c870669f105d21814729b9fe2dd1160437d Mon Sep 17 00:00:00 2001 From: puppetmaster Date: Mon, 25 Jul 2005 17:06:37 +0000 Subject: adding last snapshot of ecore for ecore_x_screensaver --- ecore/.cvsignore | 28 + ecore/AUTHORS | 17 + ecore/COPYING | 20 + ecore/COPYING-PLAIN | 33 + ecore/CVS/Entries | 29 + ecore/CVS/Repository | 1 + ecore/CVS/Root | 1 + ecore/CVS/Tag | 1 + ecore/ChangeLog | 4 + ecore/Doxyfile | 139 + ecore/INSTALL | 14 + ecore/Makefile.am | 38 + ecore/NEWS | 0 ecore/README.in | 36 + ecore/autogen.sh | 16 + ecore/configure.in | 1040 + ecore/data/.cvsignore | 2 + ecore/data/CVS/Entries | 5 + ecore/data/CVS/Repository | 1 + ecore/data/CVS/Root | 1 + ecore/data/CVS/Tag | 1 + ecore/data/Makefile.am | 2 + ecore/data/fonts/.cvsignore | 2 + ecore/data/fonts/CVS/Entries | 15 + ecore/data/fonts/CVS/Repository | 1 + ecore/data/fonts/CVS/Root | 1 + ecore/data/fonts/CVS/Tag | 1 + ecore/data/fonts/Makefile.am | 10 + ecore/data/fonts/Vera.ttf | Bin 0 -> 65932 bytes ecore/data/fonts/VeraBI.ttf | Bin 0 -> 63208 bytes ecore/data/fonts/VeraBd.ttf | Bin 0 -> 58716 bytes ecore/data/fonts/VeraIt.ttf | Bin 0 -> 63684 bytes ecore/data/fonts/VeraMoBI.ttf | Bin 0 -> 55032 bytes ecore/data/fonts/VeraMoBd.ttf | Bin 0 -> 49052 bytes ecore/data/fonts/VeraMoIt.ttf | Bin 0 -> 54508 bytes ecore/data/fonts/VeraMono.ttf | Bin 0 -> 49224 bytes ecore/data/fonts/VeraSe.ttf | Bin 0 -> 60280 bytes ecore/data/fonts/VeraSeBd.ttf | Bin 0 -> 58736 bytes ecore/data/fonts/fonts.alias | 11 + ecore/data/fonts/fonts.dir | 51 + ecore/data/images/.cvsignore | 2 + ecore/data/images/CVS/Entries | 12 + ecore/data/images/CVS/Repository | 1 + ecore/data/images/CVS/Root | 1 + ecore/data/images/CVS/Tag | 1 + ecore/data/images/Makefile.am | 10 + ecore/data/images/ball.png | Bin 0 -> 2204 bytes ecore/data/images/bar.png | Bin 0 -> 4385 bytes ecore/data/images/bar_shad_above.png | Bin 0 -> 136 bytes ecore/data/images/bar_shad_below.png | Bin 0 -> 142 bytes ecore/data/images/bg.png | Bin 0 -> 60786 bytes ecore/data/images/crosshair.png | Bin 0 -> 875 bytes ecore/data/images/e_logo.png | Bin 0 -> 46481 bytes ecore/data/images/evas_logo.png | Bin 0 -> 19736 bytes ecore/data/images/shadow.png | Bin 0 -> 1169 bytes ecore/data/pointers/.cvsignore | 2 + ecore/data/pointers/CVS/Entries | 4 + ecore/data/pointers/CVS/Repository | 1 + ecore/data/pointers/CVS/Root | 1 + ecore/data/pointers/CVS/Tag | 1 + ecore/data/pointers/Makefile.am | 8 + ecore/data/pointers/mouse_pointer.png | Bin 0 -> 1360 bytes ecore/debian/.cvsignore | 11 + ecore/debian/CVS/Entries | 9 + ecore/debian/CVS/Repository | 1 + ecore/debian/CVS/Root | 1 + ecore/debian/CVS/Tag | 1 + ecore/debian/changelog.in | 5 + ecore/debian/control | 35 + ecore/debian/copyright | 32 + ecore/debian/ecore0-test.install | 2 + ecore/debian/libecore0-dev.install | 8 + ecore/debian/libecore0.install | 6 + ecore/debian/rules | 88 + ecore/doc/.cvsignore | 3 + ecore/doc/CVS/Entries | 5 + ecore/doc/CVS/Repository | 1 + ecore/doc/CVS/Root | 1 + ecore/doc/CVS/Tag | 1 + ecore/doc/ecore.css | 178 + ecore/doc/foot.html | 2 + ecore/doc/head.html | 19 + ecore/doc/img/CVS/Entries | 9 + ecore/doc/img/CVS/Repository | 1 + ecore/doc/img/CVS/Root | 1 + ecore/doc/img/CVS/Tag | 1 + ecore/doc/img/ecore.png | Bin 0 -> 74944 bytes ecore/doc/img/ecore.xcf | Bin 0 -> 2126397 bytes ecore/doc/img/ecore_big.eps | 45178 +++++++++++++++++++ ecore/doc/img/ecore_big.png | Bin 0 -> 937116 bytes ecore/doc/img/ecore_mini.png | Bin 0 -> 753 bytes ecore/doc/img/ecore_small.png | Bin 0 -> 3755 bytes ecore/doc/img/hilite.png | Bin 0 -> 6127 bytes ecore/doc/img/prog_flow.png | Bin 0 -> 45897 bytes ecore/ecore-config.in | 59 + ecore/ecore-native.oe.in | 24 + ecore/ecore.bb.in | 58 + ecore/ecore.c.in | 378 + ecore/ecore.m4 | 198 + ecore/ecore.oe.in | 58 + ecore/ecore.pc.in | 11 + ecore/ecore.spec.in | 73 + ecore/ecore.supp | 46 + ecore/ecoreXnative.bb.in | 24 + ecore/examples/.cvsignore | 13 + ecore/examples/CVS/Entries | 13 + ecore/examples/CVS/Repository | 1 + ecore/examples/CVS/Root | 1 + ecore/examples/CVS/Tag | 1 + ecore/examples/Makefile.am | 69 + ecore/examples/args_example.c | 25 + ecore/examples/con_client_example.c | 53 + ecore/examples/con_server_example.c | 59 + ecore/examples/config_basic_example.c | 93 + ecore/examples/config_listener_example.c | 26 + ecore/examples/event_handler_example.c | 42 + ecore/examples/list_destroy_example.c | 26 + ecore/examples/list_example.c | 28 + ecore/examples/timer_example.c | 40 + ecore/examples/x_window_example.c | 20 + ecore/gendoc | 9 + ecore/m4/CVS/Entries | 5 + ecore/m4/CVS/Repository | 1 + ecore/m4/CVS/Root | 1 + ecore/m4/CVS/Tag | 1 + ecore/m4/ac_attribute.m4 | 14 + ecore/m4/ac_expand_dir.m4 | 14 + ecore/m4/ac_path_generic.m4 | 136 + ecore/m4/pkg.m4 | 57 + ecore/src/.cvsignore | 2 + ecore/src/CVS/Entries | 12 + ecore/src/CVS/Repository | 1 + ecore/src/CVS/Root | 1 + ecore/src/CVS/Tag | 1 + ecore/src/Ecore.h | 916 + ecore/src/Makefile.am | 12 + ecore/src/bin/.cvsignore | 6 + ecore/src/bin/CVS/Entries | 10 + ecore/src/bin/CVS/Repository | 1 + ecore/src/bin/CVS/Root | 1 + ecore/src/bin/CVS/Tag | 1 + ecore/src/bin/Makefile.am | 148 + ecore/src/bin/ecore_config.c | 229 + ecore/src/bin/ecore_evas_test.c | 27 + ecore/src/bin/ecore_evas_test.h | 36 + ecore/src/bin/ecore_evas_test_app.c | 174 + ecore/src/bin/ecore_evas_test_bg.c | 412 + ecore/src/bin/ecore_evas_test_calibrate.c | 285 + ecore/src/bin/ecore_test.c | 899 + ecore/src/e_ev_filter.c | 132 + ecore/src/e_ev_signal.c | 320 + ecore/src/e_ev_x.c | 1234 + ecore/src/e_events.c | 430 + ecore/src/e_ipc.c | 187 + ecore/src/e_util.c | 10 + ecore/src/e_x.c | 3610 ++ ecore/src/lib/.cvsignore | 2 + ecore/src/lib/CVS/Entries | 13 + ecore/src/lib/CVS/Repository | 1 + ecore/src/lib/CVS/Root | 1 + ecore/src/lib/CVS/Tag | 1 + ecore/src/lib/Makefile.am | 13 + ecore/src/lib/ecore/.cvsignore | 6 + ecore/src/lib/ecore/CVS/Entries | 26 + ecore/src/lib/ecore/CVS/Repository | 1 + ecore/src/lib/ecore/CVS/Root | 1 + ecore/src/lib/ecore/CVS/Tag | 1 + ecore/src/lib/ecore/Ecore.h | 254 + ecore/src/lib/ecore/Ecore_Data.h | 591 + ecore/src/lib/ecore/Makefile.am | 34 + ecore/src/lib/ecore/ecore.c | 236 + ecore/src/lib/ecore/ecore_anim.c | 169 + ecore/src/lib/ecore/ecore_app.c | 64 + ecore/src/lib/ecore/ecore_events.c | 519 + ecore/src/lib/ecore/ecore_exe.c | 263 + ecore/src/lib/ecore/ecore_hash.c | 713 + ecore/src/lib/ecore/ecore_idle_enterer.c | 105 + ecore/src/lib/ecore/ecore_idle_exiter.c | 104 + ecore/src/lib/ecore/ecore_idler.c | 106 + ecore/src/lib/ecore/ecore_list.c | 1537 + ecore/src/lib/ecore/ecore_main.c | 635 + ecore/src/lib/ecore/ecore_path.c | 282 + ecore/src/lib/ecore/ecore_plugin.c | 109 + ecore/src/lib/ecore/ecore_private.h | 262 + ecore/src/lib/ecore/ecore_sheap.c | 419 + ecore/src/lib/ecore/ecore_signal.c | 455 + ecore/src/lib/ecore/ecore_strings.c | 79 + ecore/src/lib/ecore/ecore_time.c | 41 + ecore/src/lib/ecore/ecore_timer.c | 223 + ecore/src/lib/ecore/ecore_tree.c | 816 + ecore/src/lib/ecore/ecore_value.c | 118 + ecore/src/lib/ecore_con/.cvsignore | 7 + ecore/src/lib/ecore_con/CVS/Entries | 7 + ecore/src/lib/ecore_con/CVS/Repository | 1 + ecore/src/lib/ecore_con/CVS/Root | 1 + ecore/src/lib/ecore_con/CVS/Tag | 1 + ecore/src/lib/ecore_con/Ecore_Con.h | 168 + ecore/src/lib/ecore_con/Makefile.am | 36 + ecore/src/lib/ecore_con/ecore_con.c | 1270 + ecore/src/lib/ecore_con/ecore_con_private.h | 86 + ecore/src/lib/ecore_con/ecore_con_url.c | 408 + ecore/src/lib/ecore_config/.cvsignore | 8 + ecore/src/lib/ecore_config/CVS/Entries | 14 + ecore/src/lib/ecore_config/CVS/Entries.Log | 2 + ecore/src/lib/ecore_config/CVS/Repository | 1 + ecore/src/lib/ecore_config/CVS/Root | 1 + ecore/src/lib/ecore_config/CVS/Tag | 1 + ecore/src/lib/ecore_config/Ecore_Config.h | 308 + ecore/src/lib/ecore_config/Makefile.am | 65 + ecore/src/lib/ecore_config/ecore_config.c | 1623 + ecore/src/lib/ecore_config/ecore_config_db.c | 286 + ecore/src/lib/ecore_config/ecore_config_extra.c | 828 + ecore/src/lib/ecore_config/ecore_config_ipc.h | 50 + .../src/lib/ecore_config/ecore_config_ipc_ecore.c | 378 + ecore/src/lib/ecore_config/ecore_config_ipc_main.c | 284 + ecore/src/lib/ecore_config/ecore_config_private.h | 28 + ecore/src/lib/ecore_config/ecore_config_storage.c | 172 + ecore/src/lib/ecore_config/ecore_config_util.c | 781 + ecore/src/lib/ecore_config/ecore_config_util.h | 63 + ecore/src/lib/ecore_dbus/.cvsignore | 7 + ecore/src/lib/ecore_dbus/CVS/Entries | 6 + ecore/src/lib/ecore_dbus/CVS/Repository | 1 + ecore/src/lib/ecore_dbus/CVS/Root | 1 + ecore/src/lib/ecore_dbus/CVS/Tag | 1 + ecore/src/lib/ecore_dbus/Ecore_DBus.h | 209 + ecore/src/lib/ecore_dbus/Makefile.am | 39 + ecore/src/lib/ecore_dbus/ecore_dbus.c | 1235 + ecore/src/lib/ecore_dbus/ecore_dbus_private.h | 56 + ecore/src/lib/ecore_evas/.cvsignore | 10 + ecore/src/lib/ecore_evas/CVS/Entries | 9 + ecore/src/lib/ecore_evas/CVS/Repository | 1 + ecore/src/lib/ecore_evas/CVS/Root | 1 + ecore/src/lib/ecore_evas/CVS/Tag | 1 + ecore/src/lib/ecore_evas/Ecore_Evas.h | 165 + ecore/src/lib/ecore_evas/Makefile.am | 69 + ecore/src/lib/ecore_evas/ecore_evas.c | 1605 + ecore/src/lib/ecore_evas/ecore_evas_buffer.c | 634 + ecore/src/lib/ecore_evas/ecore_evas_fb.c | 542 + ecore/src/lib/ecore_evas/ecore_evas_private.h | 216 + ecore/src/lib/ecore_evas/ecore_evas_x.c | 1938 + ecore/src/lib/ecore_fb/.cvsignore | 6 + ecore/src/lib/ecore_fb/CVS/Entries | 7 + ecore/src/lib/ecore_fb/CVS/Repository | 1 + ecore/src/lib/ecore_fb/CVS/Root | 1 + ecore/src/lib/ecore_fb/CVS/Tag | 1 + ecore/src/lib/ecore_fb/Ecore_Fb.h | 116 + ecore/src/lib/ecore_fb/Makefile.am | 32 + ecore/src/lib/ecore_fb/ecore_fb.c | 1273 + ecore/src/lib/ecore_fb/ecore_fb_keytab.h | 128 + ecore/src/lib/ecore_fb/ecore_fb_private.h | 30 + ecore/src/lib/ecore_file/.cvsignore | 6 + ecore/src/lib/ecore_file/CVS/Entries | 13 + ecore/src/lib/ecore_file/CVS/Repository | 1 + ecore/src/lib/ecore_file/CVS/Root | 1 + ecore/src/lib/ecore_file/CVS/Tag | 1 + ecore/src/lib/ecore_file/Ecore_File.h | 91 + ecore/src/lib/ecore_file/Makefile.am | 40 + ecore/src/lib/ecore_file/ecore_file.c | 257 + ecore/src/lib/ecore_file/ecore_file_download.c | 292 + ecore/src/lib/ecore_file/ecore_file_monitor.c | 126 + ecore/src/lib/ecore_file/ecore_file_monitor_fam.c | 305 + .../lib/ecore_file/ecore_file_monitor_inotify.c | 235 + ecore/src/lib/ecore_file/ecore_file_monitor_poll.c | 357 + ecore/src/lib/ecore_file/ecore_file_path.c | 84 + ecore/src/lib/ecore_file/ecore_file_private.h | 75 + ecore/src/lib/ecore_file/ecore_file_utils.c | 4 + ecore/src/lib/ecore_ipc/.cvsignore | 7 + ecore/src/lib/ecore_ipc/CVS/Entries | 6 + ecore/src/lib/ecore_ipc/CVS/Repository | 1 + ecore/src/lib/ecore_ipc/CVS/Root | 1 + ecore/src/lib/ecore_ipc/CVS/Tag | 1 + ecore/src/lib/ecore_ipc/Ecore_Ipc.h | 312 + ecore/src/lib/ecore_ipc/Makefile.am | 39 + ecore/src/lib/ecore_ipc/ecore_ipc.c | 1257 + ecore/src/lib/ecore_ipc/ecore_ipc_private.h | 66 + ecore/src/lib/ecore_job/.cvsignore | 6 + ecore/src/lib/ecore_job/CVS/Entries | 6 + ecore/src/lib/ecore_job/CVS/Repository | 1 + ecore/src/lib/ecore_job/CVS/Root | 1 + ecore/src/lib/ecore_job/CVS/Tag | 1 + ecore/src/lib/ecore_job/Ecore_Job.h | 41 + ecore/src/lib/ecore_job/Makefile.am | 31 + ecore/src/lib/ecore_job/ecore_job.c | 86 + ecore/src/lib/ecore_job/ecore_job_private.h | 16 + ecore/src/lib/ecore_txt/.cvsignore | 6 + ecore/src/lib/ecore_txt/CVS/Entries | 6 + ecore/src/lib/ecore_txt/CVS/Repository | 1 + ecore/src/lib/ecore_txt/CVS/Root | 1 + ecore/src/lib/ecore_txt/CVS/Tag | 1 + ecore/src/lib/ecore_txt/Ecore_Txt.h | 36 + ecore/src/lib/ecore_txt/Makefile.am | 34 + ecore/src/lib/ecore_txt/ecore_txt.c | 78 + ecore/src/lib/ecore_txt/ecore_txt_private.h | 4 + ecore/src/lib/ecore_x/.cvsignore | 6 + ecore/src/lib/ecore_x/CVS/Entries | 23 + ecore/src/lib/ecore_x/CVS/Repository | 1 + ecore/src/lib/ecore_x/CVS/Root | 1 + ecore/src/lib/ecore_x/CVS/Tag | 1 + ecore/src/lib/ecore_x/Ecore_X.h | 1320 + ecore/src/lib/ecore_x/Ecore_X_Atoms.h | 152 + ecore/src/lib/ecore_x/Ecore_X_Cursor.h | 86 + ecore/src/lib/ecore_x/Makefile.am | 81 + ecore/src/lib/ecore_x/ecore_x.c | 1685 + ecore/src/lib/ecore_x/ecore_x_dnd.c | 405 + ecore/src/lib/ecore_x/ecore_x_e.c | 37 + ecore/src/lib/ecore_x/ecore_x_error.c | 95 + ecore/src/lib/ecore_x/ecore_x_events.c | 1565 + ecore/src/lib/ecore_x/ecore_x_gc.c | 29 + ecore/src/lib/ecore_x/ecore_x_icccm.c | 1082 + ecore/src/lib/ecore_x/ecore_x_mwm.c | 93 + ecore/src/lib/ecore_x/ecore_x_netwm.c | 1238 + ecore/src/lib/ecore_x/ecore_x_pixmap.c | 95 + ecore/src/lib/ecore_x/ecore_x_private.h | 210 + ecore/src/lib/ecore_x/ecore_x_selection.c | 773 + ecore/src/lib/ecore_x/ecore_x_sync.c | 48 + ecore/src/lib/ecore_x/ecore_x_window.c | 768 + ecore/src/lib/ecore_x/ecore_x_window_prop.c | 342 + ecore/src/lib/ecore_x/ecore_x_window_shape.c | 159 + ecore/src/lib/ecore_x/ecore_x_xinerama.c | 54 + 319 files changed, 95640 insertions(+) create mode 100644 ecore/.cvsignore create mode 100644 ecore/AUTHORS create mode 100644 ecore/COPYING create mode 100644 ecore/COPYING-PLAIN create mode 100644 ecore/CVS/Entries create mode 100644 ecore/CVS/Repository create mode 100644 ecore/CVS/Root create mode 100644 ecore/CVS/Tag create mode 100644 ecore/ChangeLog create mode 100644 ecore/Doxyfile create mode 100644 ecore/INSTALL create mode 100644 ecore/Makefile.am create mode 100644 ecore/NEWS create mode 100644 ecore/README.in create mode 100644 ecore/autogen.sh create mode 100644 ecore/configure.in create mode 100644 ecore/data/.cvsignore create mode 100644 ecore/data/CVS/Entries create mode 100644 ecore/data/CVS/Repository create mode 100644 ecore/data/CVS/Root create mode 100644 ecore/data/CVS/Tag create mode 100644 ecore/data/Makefile.am create mode 100644 ecore/data/fonts/.cvsignore create mode 100644 ecore/data/fonts/CVS/Entries create mode 100644 ecore/data/fonts/CVS/Repository create mode 100644 ecore/data/fonts/CVS/Root create mode 100644 ecore/data/fonts/CVS/Tag create mode 100644 ecore/data/fonts/Makefile.am create mode 100644 ecore/data/fonts/Vera.ttf create mode 100644 ecore/data/fonts/VeraBI.ttf create mode 100644 ecore/data/fonts/VeraBd.ttf create mode 100644 ecore/data/fonts/VeraIt.ttf create mode 100644 ecore/data/fonts/VeraMoBI.ttf create mode 100644 ecore/data/fonts/VeraMoBd.ttf create mode 100644 ecore/data/fonts/VeraMoIt.ttf create mode 100644 ecore/data/fonts/VeraMono.ttf create mode 100644 ecore/data/fonts/VeraSe.ttf create mode 100644 ecore/data/fonts/VeraSeBd.ttf create mode 100644 ecore/data/fonts/fonts.alias create mode 100644 ecore/data/fonts/fonts.dir create mode 100644 ecore/data/images/.cvsignore create mode 100644 ecore/data/images/CVS/Entries create mode 100644 ecore/data/images/CVS/Repository create mode 100644 ecore/data/images/CVS/Root create mode 100644 ecore/data/images/CVS/Tag create mode 100644 ecore/data/images/Makefile.am create mode 100644 ecore/data/images/ball.png create mode 100644 ecore/data/images/bar.png create mode 100644 ecore/data/images/bar_shad_above.png create mode 100644 ecore/data/images/bar_shad_below.png create mode 100644 ecore/data/images/bg.png create mode 100644 ecore/data/images/crosshair.png create mode 100644 ecore/data/images/e_logo.png create mode 100644 ecore/data/images/evas_logo.png create mode 100644 ecore/data/images/shadow.png create mode 100644 ecore/data/pointers/.cvsignore create mode 100644 ecore/data/pointers/CVS/Entries create mode 100644 ecore/data/pointers/CVS/Repository create mode 100644 ecore/data/pointers/CVS/Root create mode 100644 ecore/data/pointers/CVS/Tag create mode 100644 ecore/data/pointers/Makefile.am create mode 100644 ecore/data/pointers/mouse_pointer.png create mode 100644 ecore/debian/.cvsignore create mode 100644 ecore/debian/CVS/Entries create mode 100644 ecore/debian/CVS/Repository create mode 100644 ecore/debian/CVS/Root create mode 100644 ecore/debian/CVS/Tag create mode 100644 ecore/debian/changelog.in create mode 100644 ecore/debian/control create mode 100644 ecore/debian/copyright create mode 100644 ecore/debian/ecore0-test.install create mode 100644 ecore/debian/libecore0-dev.install create mode 100644 ecore/debian/libecore0.install create mode 100644 ecore/debian/rules create mode 100644 ecore/doc/.cvsignore create mode 100644 ecore/doc/CVS/Entries create mode 100644 ecore/doc/CVS/Repository create mode 100644 ecore/doc/CVS/Root create mode 100644 ecore/doc/CVS/Tag create mode 100644 ecore/doc/ecore.css create mode 100644 ecore/doc/foot.html create mode 100644 ecore/doc/head.html create mode 100644 ecore/doc/img/CVS/Entries create mode 100644 ecore/doc/img/CVS/Repository create mode 100644 ecore/doc/img/CVS/Root create mode 100644 ecore/doc/img/CVS/Tag create mode 100644 ecore/doc/img/ecore.png create mode 100644 ecore/doc/img/ecore.xcf create mode 100644 ecore/doc/img/ecore_big.eps create mode 100644 ecore/doc/img/ecore_big.png create mode 100644 ecore/doc/img/ecore_mini.png create mode 100644 ecore/doc/img/ecore_small.png create mode 100644 ecore/doc/img/hilite.png create mode 100644 ecore/doc/img/prog_flow.png create mode 100644 ecore/ecore-config.in create mode 100644 ecore/ecore-native.oe.in create mode 100644 ecore/ecore.bb.in create mode 100644 ecore/ecore.c.in create mode 100644 ecore/ecore.m4 create mode 100644 ecore/ecore.oe.in create mode 100644 ecore/ecore.pc.in create mode 100644 ecore/ecore.spec.in create mode 100644 ecore/ecore.supp create mode 100644 ecore/ecoreXnative.bb.in create mode 100644 ecore/examples/.cvsignore create mode 100644 ecore/examples/CVS/Entries create mode 100644 ecore/examples/CVS/Repository create mode 100644 ecore/examples/CVS/Root create mode 100644 ecore/examples/CVS/Tag create mode 100644 ecore/examples/Makefile.am create mode 100644 ecore/examples/args_example.c create mode 100644 ecore/examples/con_client_example.c create mode 100644 ecore/examples/con_server_example.c create mode 100644 ecore/examples/config_basic_example.c create mode 100644 ecore/examples/config_listener_example.c create mode 100644 ecore/examples/event_handler_example.c create mode 100644 ecore/examples/list_destroy_example.c create mode 100644 ecore/examples/list_example.c create mode 100644 ecore/examples/timer_example.c create mode 100644 ecore/examples/x_window_example.c create mode 100644 ecore/gendoc create mode 100644 ecore/m4/CVS/Entries create mode 100644 ecore/m4/CVS/Repository create mode 100644 ecore/m4/CVS/Root create mode 100644 ecore/m4/CVS/Tag create mode 100644 ecore/m4/ac_attribute.m4 create mode 100644 ecore/m4/ac_expand_dir.m4 create mode 100644 ecore/m4/ac_path_generic.m4 create mode 100644 ecore/m4/pkg.m4 create mode 100644 ecore/src/.cvsignore create mode 100644 ecore/src/CVS/Entries create mode 100644 ecore/src/CVS/Repository create mode 100644 ecore/src/CVS/Root create mode 100644 ecore/src/CVS/Tag create mode 100644 ecore/src/Ecore.h create mode 100644 ecore/src/Makefile.am create mode 100644 ecore/src/bin/.cvsignore create mode 100644 ecore/src/bin/CVS/Entries create mode 100644 ecore/src/bin/CVS/Repository create mode 100644 ecore/src/bin/CVS/Root create mode 100644 ecore/src/bin/CVS/Tag create mode 100644 ecore/src/bin/Makefile.am create mode 100644 ecore/src/bin/ecore_config.c create mode 100644 ecore/src/bin/ecore_evas_test.c create mode 100644 ecore/src/bin/ecore_evas_test.h create mode 100644 ecore/src/bin/ecore_evas_test_app.c create mode 100644 ecore/src/bin/ecore_evas_test_bg.c create mode 100644 ecore/src/bin/ecore_evas_test_calibrate.c create mode 100644 ecore/src/bin/ecore_test.c create mode 100644 ecore/src/e_ev_filter.c create mode 100644 ecore/src/e_ev_signal.c create mode 100644 ecore/src/e_ev_x.c create mode 100644 ecore/src/e_events.c create mode 100644 ecore/src/e_ipc.c create mode 100644 ecore/src/e_util.c create mode 100644 ecore/src/e_x.c create mode 100644 ecore/src/lib/.cvsignore create mode 100644 ecore/src/lib/CVS/Entries create mode 100644 ecore/src/lib/CVS/Repository create mode 100644 ecore/src/lib/CVS/Root create mode 100644 ecore/src/lib/CVS/Tag create mode 100644 ecore/src/lib/Makefile.am create mode 100644 ecore/src/lib/ecore/.cvsignore create mode 100644 ecore/src/lib/ecore/CVS/Entries create mode 100644 ecore/src/lib/ecore/CVS/Repository create mode 100644 ecore/src/lib/ecore/CVS/Root create mode 100644 ecore/src/lib/ecore/CVS/Tag create mode 100644 ecore/src/lib/ecore/Ecore.h create mode 100644 ecore/src/lib/ecore/Ecore_Data.h create mode 100644 ecore/src/lib/ecore/Makefile.am create mode 100644 ecore/src/lib/ecore/ecore.c create mode 100644 ecore/src/lib/ecore/ecore_anim.c create mode 100644 ecore/src/lib/ecore/ecore_app.c create mode 100644 ecore/src/lib/ecore/ecore_events.c create mode 100644 ecore/src/lib/ecore/ecore_exe.c create mode 100644 ecore/src/lib/ecore/ecore_hash.c create mode 100644 ecore/src/lib/ecore/ecore_idle_enterer.c create mode 100644 ecore/src/lib/ecore/ecore_idle_exiter.c create mode 100644 ecore/src/lib/ecore/ecore_idler.c create mode 100644 ecore/src/lib/ecore/ecore_list.c create mode 100644 ecore/src/lib/ecore/ecore_main.c create mode 100644 ecore/src/lib/ecore/ecore_path.c create mode 100644 ecore/src/lib/ecore/ecore_plugin.c create mode 100644 ecore/src/lib/ecore/ecore_private.h create mode 100644 ecore/src/lib/ecore/ecore_sheap.c create mode 100644 ecore/src/lib/ecore/ecore_signal.c create mode 100644 ecore/src/lib/ecore/ecore_strings.c create mode 100644 ecore/src/lib/ecore/ecore_time.c create mode 100644 ecore/src/lib/ecore/ecore_timer.c create mode 100644 ecore/src/lib/ecore/ecore_tree.c create mode 100644 ecore/src/lib/ecore/ecore_value.c create mode 100644 ecore/src/lib/ecore_con/.cvsignore create mode 100644 ecore/src/lib/ecore_con/CVS/Entries create mode 100644 ecore/src/lib/ecore_con/CVS/Repository create mode 100644 ecore/src/lib/ecore_con/CVS/Root create mode 100644 ecore/src/lib/ecore_con/CVS/Tag create mode 100644 ecore/src/lib/ecore_con/Ecore_Con.h create mode 100644 ecore/src/lib/ecore_con/Makefile.am create mode 100644 ecore/src/lib/ecore_con/ecore_con.c create mode 100644 ecore/src/lib/ecore_con/ecore_con_private.h create mode 100644 ecore/src/lib/ecore_con/ecore_con_url.c create mode 100644 ecore/src/lib/ecore_config/.cvsignore create mode 100644 ecore/src/lib/ecore_config/CVS/Entries create mode 100644 ecore/src/lib/ecore_config/CVS/Entries.Log create mode 100644 ecore/src/lib/ecore_config/CVS/Repository create mode 100644 ecore/src/lib/ecore_config/CVS/Root create mode 100644 ecore/src/lib/ecore_config/CVS/Tag create mode 100644 ecore/src/lib/ecore_config/Ecore_Config.h create mode 100644 ecore/src/lib/ecore_config/Makefile.am create mode 100644 ecore/src/lib/ecore_config/ecore_config.c create mode 100644 ecore/src/lib/ecore_config/ecore_config_db.c create mode 100644 ecore/src/lib/ecore_config/ecore_config_extra.c create mode 100644 ecore/src/lib/ecore_config/ecore_config_ipc.h create mode 100644 ecore/src/lib/ecore_config/ecore_config_ipc_ecore.c create mode 100644 ecore/src/lib/ecore_config/ecore_config_ipc_main.c create mode 100644 ecore/src/lib/ecore_config/ecore_config_private.h create mode 100644 ecore/src/lib/ecore_config/ecore_config_storage.c create mode 100644 ecore/src/lib/ecore_config/ecore_config_util.c create mode 100644 ecore/src/lib/ecore_config/ecore_config_util.h create mode 100644 ecore/src/lib/ecore_dbus/.cvsignore create mode 100644 ecore/src/lib/ecore_dbus/CVS/Entries create mode 100644 ecore/src/lib/ecore_dbus/CVS/Repository create mode 100644 ecore/src/lib/ecore_dbus/CVS/Root create mode 100644 ecore/src/lib/ecore_dbus/CVS/Tag create mode 100644 ecore/src/lib/ecore_dbus/Ecore_DBus.h create mode 100644 ecore/src/lib/ecore_dbus/Makefile.am create mode 100644 ecore/src/lib/ecore_dbus/ecore_dbus.c create mode 100644 ecore/src/lib/ecore_dbus/ecore_dbus_private.h create mode 100644 ecore/src/lib/ecore_evas/.cvsignore create mode 100644 ecore/src/lib/ecore_evas/CVS/Entries create mode 100644 ecore/src/lib/ecore_evas/CVS/Repository create mode 100644 ecore/src/lib/ecore_evas/CVS/Root create mode 100644 ecore/src/lib/ecore_evas/CVS/Tag create mode 100644 ecore/src/lib/ecore_evas/Ecore_Evas.h create mode 100644 ecore/src/lib/ecore_evas/Makefile.am create mode 100644 ecore/src/lib/ecore_evas/ecore_evas.c create mode 100644 ecore/src/lib/ecore_evas/ecore_evas_buffer.c create mode 100644 ecore/src/lib/ecore_evas/ecore_evas_fb.c create mode 100644 ecore/src/lib/ecore_evas/ecore_evas_private.h create mode 100644 ecore/src/lib/ecore_evas/ecore_evas_x.c create mode 100644 ecore/src/lib/ecore_fb/.cvsignore create mode 100644 ecore/src/lib/ecore_fb/CVS/Entries create mode 100644 ecore/src/lib/ecore_fb/CVS/Repository create mode 100644 ecore/src/lib/ecore_fb/CVS/Root create mode 100644 ecore/src/lib/ecore_fb/CVS/Tag create mode 100644 ecore/src/lib/ecore_fb/Ecore_Fb.h create mode 100644 ecore/src/lib/ecore_fb/Makefile.am create mode 100644 ecore/src/lib/ecore_fb/ecore_fb.c create mode 100644 ecore/src/lib/ecore_fb/ecore_fb_keytab.h create mode 100644 ecore/src/lib/ecore_fb/ecore_fb_private.h create mode 100644 ecore/src/lib/ecore_file/.cvsignore create mode 100644 ecore/src/lib/ecore_file/CVS/Entries create mode 100644 ecore/src/lib/ecore_file/CVS/Repository create mode 100644 ecore/src/lib/ecore_file/CVS/Root create mode 100644 ecore/src/lib/ecore_file/CVS/Tag create mode 100644 ecore/src/lib/ecore_file/Ecore_File.h create mode 100644 ecore/src/lib/ecore_file/Makefile.am create mode 100644 ecore/src/lib/ecore_file/ecore_file.c create mode 100644 ecore/src/lib/ecore_file/ecore_file_download.c create mode 100644 ecore/src/lib/ecore_file/ecore_file_monitor.c create mode 100644 ecore/src/lib/ecore_file/ecore_file_monitor_fam.c create mode 100644 ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c create mode 100644 ecore/src/lib/ecore_file/ecore_file_monitor_poll.c create mode 100644 ecore/src/lib/ecore_file/ecore_file_path.c create mode 100644 ecore/src/lib/ecore_file/ecore_file_private.h create mode 100644 ecore/src/lib/ecore_file/ecore_file_utils.c create mode 100644 ecore/src/lib/ecore_ipc/.cvsignore create mode 100644 ecore/src/lib/ecore_ipc/CVS/Entries create mode 100644 ecore/src/lib/ecore_ipc/CVS/Repository create mode 100644 ecore/src/lib/ecore_ipc/CVS/Root create mode 100644 ecore/src/lib/ecore_ipc/CVS/Tag create mode 100644 ecore/src/lib/ecore_ipc/Ecore_Ipc.h create mode 100644 ecore/src/lib/ecore_ipc/Makefile.am create mode 100644 ecore/src/lib/ecore_ipc/ecore_ipc.c create mode 100644 ecore/src/lib/ecore_ipc/ecore_ipc_private.h create mode 100644 ecore/src/lib/ecore_job/.cvsignore create mode 100644 ecore/src/lib/ecore_job/CVS/Entries create mode 100644 ecore/src/lib/ecore_job/CVS/Repository create mode 100644 ecore/src/lib/ecore_job/CVS/Root create mode 100644 ecore/src/lib/ecore_job/CVS/Tag create mode 100644 ecore/src/lib/ecore_job/Ecore_Job.h create mode 100644 ecore/src/lib/ecore_job/Makefile.am create mode 100644 ecore/src/lib/ecore_job/ecore_job.c create mode 100644 ecore/src/lib/ecore_job/ecore_job_private.h create mode 100644 ecore/src/lib/ecore_txt/.cvsignore create mode 100644 ecore/src/lib/ecore_txt/CVS/Entries create mode 100644 ecore/src/lib/ecore_txt/CVS/Repository create mode 100644 ecore/src/lib/ecore_txt/CVS/Root create mode 100644 ecore/src/lib/ecore_txt/CVS/Tag create mode 100644 ecore/src/lib/ecore_txt/Ecore_Txt.h create mode 100644 ecore/src/lib/ecore_txt/Makefile.am create mode 100644 ecore/src/lib/ecore_txt/ecore_txt.c create mode 100644 ecore/src/lib/ecore_txt/ecore_txt_private.h create mode 100644 ecore/src/lib/ecore_x/.cvsignore create mode 100644 ecore/src/lib/ecore_x/CVS/Entries create mode 100644 ecore/src/lib/ecore_x/CVS/Repository create mode 100644 ecore/src/lib/ecore_x/CVS/Root create mode 100644 ecore/src/lib/ecore_x/CVS/Tag create mode 100644 ecore/src/lib/ecore_x/Ecore_X.h create mode 100644 ecore/src/lib/ecore_x/Ecore_X_Atoms.h create mode 100644 ecore/src/lib/ecore_x/Ecore_X_Cursor.h create mode 100644 ecore/src/lib/ecore_x/Makefile.am create mode 100644 ecore/src/lib/ecore_x/ecore_x.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_dnd.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_e.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_error.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_events.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_gc.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_icccm.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_mwm.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_netwm.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_pixmap.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_private.h create mode 100644 ecore/src/lib/ecore_x/ecore_x_selection.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_sync.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_window.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_window_prop.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_window_shape.c create mode 100644 ecore/src/lib/ecore_x/ecore_x_xinerama.c diff --git a/ecore/.cvsignore b/ecore/.cvsignore new file mode 100644 index 0000000..e4dcd11 --- /dev/null +++ b/ecore/.cvsignore @@ -0,0 +1,28 @@ +Makefile +Makefile.in +aclocal.m4 +build-stamp +compile +config.guess +config.h +config.h.in +config.log +config.status +config.sub +configure +configure-stamp +depcomp +ecore-config +ecore.pc +install-sh +libtool +ltmain.sh +missing +mkinstalldirs +stamp-h +stamp-h.in +autom4te.cache +stamp-h1 +doc +*.tar.gz +README diff --git a/ecore/AUTHORS b/ecore/AUTHORS new file mode 100644 index 0000000..1ce2b42 --- /dev/null +++ b/ecore/AUTHORS @@ -0,0 +1,17 @@ +The Rasterman +Tom Gilbert +Burra +Chris Ross +Term +Tilman Sauerbeck +Ibukun Olumuyiwa +Yuri +Nicholas Curran +Howell Tam +Nathan Ingersoll +Andrew Elcock +Kim Woelders +Sebastian Dransfeld +Simon Poole +Jorge Luis Zapata Muga +dan sinclair diff --git a/ecore/COPYING b/ecore/COPYING new file mode 100644 index 0000000..dee3047 --- /dev/null +++ b/ecore/COPYING @@ -0,0 +1,20 @@ +Copyright (C) 2000 Carsten Haitzler and various contributors (see AUTHORS) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies of the Software, its documentation and marketing & publicity +materials, and acknowledgment shall be given in the documentation, materials +and software packages that this Software was used. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ecore/COPYING-PLAIN b/ecore/COPYING-PLAIN new file mode 100644 index 0000000..376875e --- /dev/null +++ b/ecore/COPYING-PLAIN @@ -0,0 +1,33 @@ +Plain English Copyright Notice + +This file is not intended to be the actual License. The reason this file +exists is that we here are programmers and engineers. We aren't lawyers. We +provide licenses that we THINK say the right things, but we have our own +intentions at heart. This is a plain-english explanation of what those +intentions are, and if you follow them you will be within the "spirit" of +the license. + +The intent is for us to enjoy writing software that is useful to us (the +AUTHORS) and allow others to use it freely and also benefit from the work we +put into making it. We don't want to restrict others using it. They should +not *HAVE* to make the source code of the applications they write that +simply link to these libraries (be that statically or dynamically), or for +them to be limited as to what license they choose to use (be it open, closed +or anything else). But we would like to know you are using these libraries. +We simply would like to know that it has been useful to someone. This is why +we ask for acknowledgement of some sort. + +You can do what you want with the source of this software - it doesn't +matter. We still have it here for ourselves and it is open and free to use +and download and play with. It can't be taken away. We don't really mind what +you do with the source to your software. We would simply like to know that +you are using it - especially if it makes it to a commerical product. If you +simply e-mail all the AUTHORS (see COPYING and AUTHORS files) telling us, and +then make sure you include a paragraph or page in the manual for the product +with the copyright notice and state that you used this software, we will be +very happy. If you want to contribute back modifications and fixes you may have +made we will welcome those too with open arms (generally). If you want help +with changes needed, ports needed or features to be added, arrangements can +be easily made with some dialogue. + +Carsten Haitzler diff --git a/ecore/CVS/Entries b/ecore/CVS/Entries new file mode 100644 index 0000000..d61aa49 --- /dev/null +++ b/ecore/CVS/Entries @@ -0,0 +1,29 @@ +/.cvsignore/1.9/Tue Mar 22 11:37:22 2005//THEAD +/AUTHORS/1.17/Wed Jun 22 14:51:34 2005//THEAD +/COPYING/1.3/Tue Sep 23 08:09:19 2003//THEAD +/COPYING-PLAIN/1.1/Thu Mar 10 15:19:30 2005//THEAD +/ChangeLog/1.4/Wed Jun 8 20:51:06 2005//THEAD +/Doxyfile/1.5/Fri Jul 30 12:28:28 2004//THEAD +/INSTALL/1.4/Thu Mar 10 15:19:30 2005//THEAD +/Makefile.am/1.17/Tue Mar 22 10:54:16 2005//THEAD +/NEWS/1.3/Tue Sep 23 08:09:19 2003//THEAD +/README.in/1.1/Thu Mar 10 15:19:30 2005//THEAD +/autogen.sh/1.10/Tue Apr 26 22:55:54 2005//THEAD +/ecore-config.in/1.8/Sun Feb 20 12:18:09 2005//THEAD +/ecore-native.oe.in/1.1/Thu Mar 10 15:19:31 2005//THEAD +/ecore.bb.in/1.1/Thu Mar 10 15:19:31 2005//THEAD +/ecore.c.in/1.14/Wed Sep 22 08:17:13 2004//THEAD +/ecore.m4/1.4/Fri May 21 18:43:54 2004//THEAD +/ecore.oe.in/1.1/Thu Mar 10 15:19:31 2005//THEAD +/ecore.pc.in/1.5/Sun Feb 20 12:18:09 2005//THEAD +/ecore.spec.in/1.4/Wed Jun 8 20:51:06 2005//THEAD +/ecore.supp/1.2/Tue Oct 19 16:40:25 2004//THEAD +/ecoreXnative.bb.in/1.1/Thu Mar 10 15:19:31 2005//THEAD +/gendoc/1.5/Fri Jul 23 00:01:02 2004//THEAD +D/data//// +D/debian//// +D/doc//// +D/examples//// +D/m4//// +D/src//// +/configure.in/1.97/Sat Jul 23 17:35:05 2005//THEAD diff --git a/ecore/CVS/Repository b/ecore/CVS/Repository new file mode 100644 index 0000000..b7be86b --- /dev/null +++ b/ecore/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore diff --git a/ecore/CVS/Root b/ecore/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/CVS/Tag b/ecore/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/ChangeLog b/ecore/ChangeLog new file mode 100644 index 0000000..ee16b53 --- /dev/null +++ b/ecore/ChangeLog @@ -0,0 +1,4 @@ +Wed Jun 8 16:56:30 2005 Michael Jennings (mej) + +Fix spec file. +---------------------------------------------------------------------- diff --git a/ecore/Doxyfile b/ecore/Doxyfile new file mode 100644 index 0000000..df5e921 --- /dev/null +++ b/ecore/Doxyfile @@ -0,0 +1,139 @@ +PROJECT_NAME = Ecore +PROJECT_NUMBER = +OUTPUT_DIRECTORY = doc +INPUT = ecore.c.in ./src/lib +IMAGE_PATH = doc/img +OUTPUT_LANGUAGE = English +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = doc/head.html +HTML_FOOTER = doc/foot.html +HTML_STYLESHEET = doc/ecore.css +HTML_ALIGN_MEMBERS = YES +ENUM_VALUES_PER_LINE = 1 +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = NO +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = YES +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +INTERNAL_DOCS = NO +STRIP_CODE_COMMENTS = YES +CASE_SENSE_NAMES = YES +SHORT_NAMES = NO +HIDE_SCOPE_NAMES = NO +VERBATIM_HEADERS = NO +SHOW_INCLUDE_FILES = NO +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 2 +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ALIASES = +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +SHOW_USED_FILES = NO +QUIET = YES +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +FILE_PATTERNS = +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = ./examples/ +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +INPUT_FILTER = +FILTER_SOURCE_FILES = NO +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 2 +IGNORE_PREFIX = +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +GENERATE_MAN = YES +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = YES +GENERATE_XML = NO +XML_SCHEMA = +XML_DTD = +GENERATE_AUTOGEN_DEF = NO +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = NO +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +CLASS_DIAGRAMS = NO +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = NO +COLLABORATION_GRAPH = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +GRAPHICAL_HIERARCHY = NO +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 512 +MAX_DOT_GRAPH_HEIGHT = 512 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +SEARCHENGINE = NO diff --git a/ecore/INSTALL b/ecore/INSTALL new file mode 100644 index 0000000..3a3ad7e --- /dev/null +++ b/ecore/INSTALL @@ -0,0 +1,14 @@ +COMPILING and INSTALLING: + +If you got a official release tar archive do: + ./configure + +( otherwise if you got this from enlightenment cvs do: ./autogen.sh ) + +Then to compile: + make + +To install (run this as root, or the user who handles installs): + make install + +NOTE: You MUST make install Eet for it to run properly. diff --git a/ecore/Makefile.am b/ecore/Makefile.am new file mode 100644 index 0000000..86d454b --- /dev/null +++ b/ecore/Makefile.am @@ -0,0 +1,38 @@ +## Process this file with automake to produce Makefile.in + +SUBDIRS = data src examples + +MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \ + config.h.in config.sub configure install-sh \ + ltconfig ltmain.sh missing mkinstalldirs \ + stamp-h.in build-stamp configure-stamp depcomp \ + ecore_docs.tar.gz ecore.c \ + README \ + ecore.pc \ + ecore.spec \ + ecore.oe ecore-native.oe \ + ecore.bb ecoreXnative.bb \ + debian/changelog + +bin_SCRIPTS = ecore-config + +EXTRA_DIST = AUTHORS COPYING COPYING-PLAIN ecore.c.in gendoc ecore.supp ecore.m4 \ + Doxyfile \ + ecore.pc.in \ + ecore.pc.in \ + ecore.spec.in ecore.spec \ + ecore.oe.in ecore.oe ecore-native.oe.in ecore-native.oe \ + ecore.bb.in ecore.bb ecoreXnative.bb.in ecoreXnative.bb \ + debian/changelog.in debian/changelog \ + debian/ecore0-test.install \ + debian/libecore0.install \ + debian/control \ + debian/copyright \ + debian/rules \ + debian/libecore0-dev.install + +m4datadir = $(datadir)/aclocal +m4data_DATA = ecore.m4 + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = ecore.pc diff --git a/ecore/NEWS b/ecore/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/ecore/README.in b/ecore/README.in new file mode 100644 index 0000000..7fede7a --- /dev/null +++ b/ecore/README.in @@ -0,0 +1,36 @@ +Ecore @VERSION@ + +Ecore is the event/X abstraction layer that makes doing selections, +Xdnd, general X stuff, event loops, timeouts and idle handlers fast, +optimized, and convenient. It's a separate library so anyone can make +use of the work put into Ecore to make this job easy for applications. + +------------------------------------------------------------------------------ +COMPILING AND INSTALLING: + + ./configure + make +(as root unless youa re installing in your users directories): + make install + +------------------------------------------------------------------------------ +BUILDING PACKAGES: + +RPM: To build rpm packages: + + sudo rpm -ta @PACKAGE@-@VERSION@.tar.gz + +You will find rpm packages in your system /usr/src/redhat/* dirs (note you may +not need to use sudo or root if you have your own ~/.rpmrc. see rpm documents +for more details) + +DEB: To build deb packages: + + tar zvf @PACKAGE@-@VERSION@.tar.gz + cd @PACKAGE@-@VERSION@ + dpkg-buildpackage -us -uc -rfakeroot + cd .. + rm -rf @PACKAGE@-@VERSION@ + +You will find all the debian source, binary etc. packages put in the directory +where you first untarred the source tarball. diff --git a/ecore/autogen.sh b/ecore/autogen.sh new file mode 100644 index 0000000..952505a --- /dev/null +++ b/ecore/autogen.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +rm -rf autom4te.cache +rm -f aclocal.m4 + +touch README + +echo "Running aclocal..."; aclocal $ACLOCAL_FLAGS -I m4 \ +&& echo "Running autoheader..."; autoheader \ +&& echo "Running autoconf..."; autoconf \ +&& echo "Running libtoolize..."; (libtoolize --automake || glibtoolize --automake) \ +&& echo "Running automake..."; automake --add-missing --copy --gnu + +if [ -z "$NOCONFIGURE" ]; then + ./configure "$@" +fi diff --git a/ecore/configure.in b/ecore/configure.in new file mode 100644 index 0000000..18f9b00 --- /dev/null +++ b/ecore/configure.in @@ -0,0 +1,1040 @@ +dnl Process this file with autoconf to produce a configure script. + +AC_INIT(configure.in) +AC_CANONICAL_BUILD +AC_CANONICAL_HOST +AC_ISC_POSIX +AM_INIT_AUTOMAKE(ecore, 0.9.9.011) +AM_CONFIG_HEADER(config.h) + +AC_C_BIGENDIAN +AC_PROG_CC +AM_PROG_CC_STDC +AC_HEADER_STDC +AC_C_CONST +AC_CHECK_SIZEOF(int, 4) +AM_ENABLE_SHARED +AM_PROG_LIBTOOL +AC_C___ATTRIBUTE__ + +if test "x${bindir}" = 'x${exec_prefix}/bin'; then + if test "x${exec_prefix}" = "xNONE"; then + if test "x${prefix}" = "xNONE"; then + bindir="${ac_default_prefix}/bin"; + else + bindir="${prefix}/bin"; + fi + else + if test "x${prefix}" = "xNONE"; then + bindir="${ac_default_prefix}/bin"; + else + bindir="${prefix}/bin"; + fi + fi +fi + +if test "x${libdir}" = 'x${exec_prefix}/lib'; then + if test "x${exec_prefix}" = "xNONE"; then + if test "x${prefix}" = "xNONE"; then + libdir="${ac_default_prefix}/lib"; + else + libdir="${prefix}/lib"; + fi + else + if test "x${prefix}" = "xNONE"; then + libdir="${ac_default_prefix}/lib"; + else + libdir="${prefix}/lib"; + fi + fi +fi + + +dnl Set PACKAGE_DATA_DIR in config.h. +if test "x${datadir}" = 'x${prefix}/share'; then + if test "x${prefix}" = "xNONE"; then + AC_DEFINE_UNQUOTED(PACKAGE_DATA_DIR, "${ac_default_prefix}/share/${PACKAGE}", [Shared Data Directory]) + else + AC_DEFINE_UNQUOTED(PACKAGE_DATA_DIR, "${prefix}/share/${PACKAGE}", [Shared Data Directory]) + fi +else + AC_DEFINE_UNQUOTED(PACKAGE_DATA_DIR, "${datadir}/${PACKAGE}", [Shared Data Directory]) +fi + +dnl Set PACKAGE_BIN_DIR in config.h. +if test "x${bindir}" = 'xNONE'; then + if test "x${prefix}" = "xNONE"; then + AC_DEFINE_UNQUOTED(PACKAGE_BIN_DIR, "${ac_default_prefix}/bin", [Installation Directory for User Executables]) + else + AC_DEFINE_UNQUOTED(PACKAGE_BIN_DIR, "${prefix}/bin", [Installation Directory for User Executables]) + fi +else + AC_DEFINE_UNQUOTED(PACKAGE_BIN_DIR, "${bindir}", [Installation Directory for User Executables]) +fi + +dnl Set PACKAGE_LIB_DIR in config.h. +if test "x${libdir}" = 'xNONE'; then + if test "x${prefix}" = "xNONE"; then + AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${ac_default_prefix}/lib", [Installation Directory for Libraries]) + else + AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${prefix}/lib", [Installation Directory for Libraries]) + fi +else + AC_DEFINE_UNQUOTED(PACKAGE_LIB_DIR, "${libdir}", [Installation Directory for Libraries]) +fi + +dnl Set PACKAGE_SOURCE_DIR in config.h. +packagesrcdir=`cd $srcdir && pwd` +AC_DEFINE_UNQUOTED(PACKAGE_SOURCE_DIR, "${packagesrcdir}", [Source Code Directory]) + +dnl Use -Wall if we have gcc. +changequote(,)dnl +if test "x$GCC" = "xyes"; then + case " $CFLAGS " in + *[\ \ ]-Wall[\ \ ]*) ;; + *) CFLAGS="$CFLAGS -Wall" ;; + esac +fi +changequote([,])dnl + +AC_CHECK_FUNCS(gettimeofday) + +AC_CHECK_HEADERS(netinet/in.h) + +case "$host_os" in + mingw|mingw32) + winsock_libs="-lwsock32" + ;; +esac + +AC_SUBST(winsock_libs) + +AC_MSG_CHECKING(whether ecore_txt module is to be built) + +iconv_cflags="" +iconv_libs="" + +have_ecore_txt="no"; +ecore_txt_cflags=""; +ecore_txt_libs=""; + +AC_ARG_ENABLE(ecore-txt, +[ --disable-ecore-txt disable the ecore_txt module], [ + if [ test "$enableval" = "yes" ]; then + AC_MSG_RESULT(yes) + have_ecore_txt="yes" + else + AC_MSG_RESULT(no) + fi +], [ + AC_MSG_RESULT(yes) + have_ecore_txt="yes" +] +) + +AC_ARG_WITH(iconv-link, +[ --with-iconv-link=ICONV_LINK explicitly specify an iconv link option], +[ + v=$withval; + iconv_libs=$v; + echo " Ecore iconv link flags explicitly set to: "$iconv_libs; +]) + +if test "x$have_ecore_txt" = "xyes"; then + if test -z "$iconv_libs"; then + AC_CHECK_LIB(iconv, libiconv, + [ + AC_DEFINE(BUILD_ECORE_TXT, 1, [Build Ecore_Txt Module]) + AM_CONDITIONAL(BUILD_ECORE_TXT, true) + iconv_libs="-liconv" + ecore_txt_libs="-lecore_txt "$iconv_libs + have_ecore_txt="yes" + ], [ + have_ecore_txt="no" + ] + ) + + if test "x$have_ecore_txt" != "xyes"; then + AC_CHECK_LIB(iconv, iconv, + [ + AC_DEFINE(BUILD_ECORE_TXT, 1, [Build Ecore_Txt Module]) + AM_CONDITIONAL(BUILD_ECORE_TXT, true) + iconv_libs="-liconv" + ecore_txt_libs="-lecore_txt "$iconv_libs + have_ecore_txt="yes" + ], [ + have_ecore_txt="no" + ] + ) + fi + + if test "x$have_ecore_txt" != "xyes"; then + AC_CHECK_LIB(c, libiconv, + [ + AC_DEFINE(BUILD_ECORE_TXT, 1, [Build Ecore_Txt Module]) + AM_CONDITIONAL(BUILD_ECORE_TXT, true) + ecore_txt_libs="-lecore_txt "$iconv_libs + have_ecore_txt="yes" + ], [ + have_ecore_txt="no" + ] + ) + fi + + if test "x$have_ecore_txt" != "xyes"; then + AC_CHECK_LIB(c, iconv, + [ + AC_DEFINE(BUILD_ECORE_TXT, 1, [Build Ecore_Txt Module]) + AM_CONDITIONAL(BUILD_ECORE_TXT, true) + ecore_txt_libs="-lecore_txt "$iconv_libs + have_ecore_txt="yes" + ], [ + AC_MSG_RESULT("no - disabling ecore_txt") + AM_CONDITIONAL(BUILD_ECORE_TXT, false) + have_ecore_txt="no" + ] + ) + fi + else + AC_DEFINE(BUILD_ECORE_TXT, 1, [Build Ecore_Txt Module]) + AM_CONDITIONAL(BUILD_ECORE_TXT, true) + ecore_txt_libs="-lecore_txt "$iconv_libs + have_ecore_txt="yes" + fi +else + AM_CONDITIONAL(BUILD_ECORE_TXT, false) +fi + +AC_SUBST(iconv_cflags) +AC_SUBST(iconv_libs) + +AC_SUBST(ecore_txt_cflags) +AC_SUBST(ecore_txt_libs) + +have_ecore_x="no"; +ecore_x_cflags=""; +ecore_x_libs=""; + +x_dir=""; +x_includes=""; +x_cflags=""; +x_libs=""; +x_ldflags=""; + +if test "x$have_ecore_txt" = "xyes"; then + AC_MSG_CHECKING(whether ecore_x module is to be built) + AC_ARG_ENABLE(ecore-x, + [ --disable-ecore-x disable the ecore_x module], [ + if [ test "$enableval" = "yes" ]; then + AC_MSG_RESULT(yes) + have_ecore_x="yes" + else + AC_MSG_RESULT(no) + fi + ], [ + AC_MSG_RESULT(yes) + have_ecore_x="yes" + ] + ) +else + AC_MSG_RESULT(ecore_txt not enabled, so ecore_x will not be enabled) +fi + +if test "x$have_ecore_x" = "xyes"; then + AC_PATH_XTRA + AC_CHECK_HEADER(X11/X.h, + [ + AM_CONDITIONAL(BUILD_ECORE_X, true) + AC_DEFINE(BUILD_ECORE_X, 1, [Build Ecore_X Module]) + BUILD_ECORE_X=1 + x_dir=${x_dir:-/usr/X11R6} + x_cflags=${x_cflags:--I${x_includes:-$x_dir/include}} + x_libs="${x_libs:--L${x_libraries:-$x_dir/lib}} -lX11 -lXext" + x_ldflags=" "$ecore_x_libs; + ecore_x_libs="-lecore_x"; + ],[ + AM_CONDITIONAL(BUILD_ECORE_X, false) + BUILD_ECORE_X=0 + ] + ) +else + AM_CONDITIONAL(BUILD_ECORE_X, false) + BUILD_ECORE_X=0 +fi + +AC_SUBST(BUILD_ECORE_X) + +AC_SUBST(x_cflags) +AC_SUBST(x_includes) +AC_SUBST(x_ldflags) +AC_SUBST(x_libs) + +Xcursor_libs="" +Xcursor_cflags="" +use_Xcursor="no" +PCFLAGS=$CFLAGS +CFLAGS=$x_cflags" "$x_includes +AC_CHECK_HEADER(X11/Xcursor/Xcursor.h, [ + AC_CHECK_LIB(Xcursor, XcursorImageLoadCursor, [ + AC_DEFINE(ECORE_XCURSOR, 1, [Build support for Xcursor]) + Xcursor_cflags="" + Xcursor_libs="-lXcursor" + use_Xcursor="yes" + ], [ + Xcursor_cflags="" + Xcursor_libs="" + use_Xcursor="no" + ], [ + $x_libs $x_ldflags -lXrender + ] + ) + ], [ + Xcursor_cflags="" + Xcursor_libs="" + use_Xcursor="no" + ], [ + #include + ] +) +CFLAGS=$PCFLAGS + +AC_SUBST(Xcursor_cflags) +AC_SUBST(Xcursor_libs) + +Xprint_libs="" +Xprint_cflags="" +use_Xprint="no" +PCFLAGS=$CFLAGS +CFLAGS=$x_cflags" "$x_includes +AC_CHECK_HEADER(X11/extensions/Print.h, [ + AC_CHECK_LIB(Xp, XpQueryScreens, [ + AC_DEFINE(ECORE_XPRINT, 1, [Build support for Xprint]) + Xprint_cflags="" + Xprint_libs="-lXp" + use_Xprint="yes" + ], [ + Xprint_cflags="" + Xprint_libs="" + use_Xprint="no" + ], [ + $x_libs $x_ldflags + ] + ) + ], [ + Xprint_cflags="" + Xprint_libs="" + use_Xprint="no" + ], [ + #include + ] +) +CFLAGS=$PCFLAGS + +AC_SUBST(Xprint_cflags) +AC_SUBST(Xprint_libs) + +Xinerama_libs="" +Xinerama_cflags="" +use_Xinerama="no" +PCFLAGS=$CFLAGS +CFLAGS=$x_cflags" "$x_includes +AC_CHECK_HEADER(X11/extensions/Xinerama.h, [ + AC_CHECK_LIB(Xinerama, XineramaQueryScreens, [ + AC_DEFINE(ECORE_XINERAMA, 1, [Build support for Xinerama]) + Xinerama_cflags="" + Xinerama_libs="-lXinerama" + use_Xinerama="yes" + ], [ + Xinerama_cflags="" + Xinerama_libs="" + use_Xinerama="no" + ], [ + $x_libs $x_ldflags -lXrender + ] + ) + ], [ + Xinerama_cflags="" + Xinerama_libs="" + use_Xinerama="no" + ], [ + #include + ] +) +CFLAGS=$PCFLAGS + +AC_SUBST(Xinerama_cflags) +AC_SUBST(Xinerama_libs) + +AC_SUBST(ecore_x_cflags) +AC_SUBST(ecore_x_libs) + +AC_MSG_CHECKING(whether ecore_job module is to be built) + +have_ecore_job="no"; +ecore_job_cflags=""; +ecore_job_libs=""; + +AC_ARG_ENABLE(ecore-job, +[ --disable-ecore-job disable the ecore_job module], [ + if [ test "$enableval" = "yes" ]; then + AC_MSG_RESULT(yes) + have_ecore_job="yes" + else + AC_MSG_RESULT(no) + fi +], [ + AC_MSG_RESULT(yes) + have_ecore_job="yes" +] +) + +if test "x$have_ecore_job" = "xyes"; then + AM_CONDITIONAL(BUILD_ECORE_JOB, true) + AC_DEFINE(BUILD_ECORE_JOB, 1, [Build Ecore_Job Module]) + ecore_job_libs="-lecore_job"; +else + AM_CONDITIONAL(BUILD_ECORE_JOB, false) +fi + +AC_SUBST(ecore_job_cflags) +AC_SUBST(ecore_job_libs) + +have_ecore_fb="no"; +ecore_fb_cflags=""; +ecore_fb_libs=""; + +AC_MSG_CHECKING(whether ecore_fb module is to be built) + +AC_ARG_ENABLE(ecore-fb, +[ --disable-ecore-fb disable the ecore_fb module], [ + if [ test "$enableval" = "yes" ]; then + AC_MSG_RESULT(yes) + have_ecore_fb="yes" + else + AC_MSG_RESULT(no) + fi +], [ + AC_MSG_RESULT(yes) + have_ecore_fb="yes" +] +) + +if test "x$have_ecore_fb" = "xyes"; then + AC_CHECK_HEADER(linux/fb.h, + [ + AM_CONDITIONAL(BUILD_ECORE_FB, true) + AC_DEFINE(BUILD_ECORE_FB, 1, [Build Ecore_FB Module]) + ecore_fb_libs="-lecore_fb"; + ], [ + AM_CONDITIONAL(BUILD_ECORE_FB, false) + have_ecore_fb="no" + ] + ) +else + AM_CONDITIONAL(BUILD_ECORE_FB, false) +fi + +AC_SUBST(ecore_fb_cflags) +AC_SUBST(ecore_fb_libs) + +ecore_evas_cflags=""; +ecore_evas_libs=""; + +evas_cflags=""; +evas_libs=""; +AC_ARG_WITH(evas-config, [ --with-evas-config=EVAS_CONFIG use evas-config specified ], +[ EVAS_CONFIG=$withval; + echo "using "$EVAS_CONFIG" for evas-config"; ], +[ if test -z "$EVAS_CONFIG"; then + AC_PATH_PROG(EVAS_CONFIG, "evas-config", "", $PATH) + fi +]) + +have_ecore_evas="no" + +AC_MSG_CHECKING(whether ecore_evas module is to be built) +AC_ARG_ENABLE(ecore-evas, +[ --disable-ecore-evas disable the ecore_evas module], [ + if [ test "$enableval" = "yes" ]; then + AC_MSG_RESULT(yes) + have_ecore_evas="yes"; + else + AC_MSG_RESULT(no) + fi +], [ + AC_MSG_RESULT(yes) + have_ecore_evas="yes"; +] +) + +if test "x$have_ecore_evas" = "xyes"; then + AM_CONDITIONAL(BUILD_ECORE_EVAS, true) + AC_DEFINE(BUILD_ECORE_EVAS, 1, [Build Ecore_Evas Module]) + if [ test -z $EVAS_CONFIG ]; then + echo $PROG " is not in your \$PATH. Please ensure it is."; + echo "Read the manual page for you shell as to how to extend your path."; + AC_MSG_ERROR(Cannot find $PROG) + fi + evas_cflags=`$EVAS_CONFIG --cflags` + evas_libs=`$EVAS_CONFIG --libs` + ecore_evas_libs="-lecore_evas"; +else + AM_CONDITIONAL(BUILD_ECORE_EVAS, false) +fi + +AC_SUBST(evas_cflags) +AC_SUBST(evas_libs) + +AC_SUBST(ecore_evas_cflags) +AC_SUBST(ecore_evas_libs) + +have_ecore_evas_gl="no"; + +AC_MSG_CHECKING(whether ecore_evas gl support is to be built) + +AC_ARG_ENABLE(ecore-evas-gl, +[ --disable-ecore-evas-gl disable gl in the ecore_evas module], [ + if [ test "$enableval" = "yes" ]; then + AC_MSG_RESULT(yes) + have_ecore_evas_gl="yes" + else + AC_MSG_RESULT(no) + fi +], [ + AC_MSG_RESULT(yes) + have_ecore_evas_gl="yes" +] +) + +dnl GL support requires X support, so we should +dnl handle the case where our user is on crack +dnl i.e. user disables X but enables GL +PCFLAGS=$CFLAGS +CFLAGS="$evas_cflags $CFLAGS" +if test "x$have_ecore_evas_gl" = "xyes" -a "x$have_ecore_x" = "xyes"; then + AC_CHECK_HEADER(Evas_Engine_GL_X11.h, + [ + AM_CONDITIONAL(BUILD_ECORE_EVAS_GL, true) + AC_DEFINE(BUILD_ECORE_EVAS_GL, 1, [Support for GL Engine in Ecore_Evas]) + ], [ + AM_CONDITIONAL(BUILD_ECORE_EVAS_GL, false) + have_ecore_evas_gl="no" + ], [ + #include + ] + ) +else + AM_CONDITIONAL(BUILD_ECORE_EVAS_GL, false) + if test "x$have_ecore_evas_gl" = "xyes"; then + have_ecore_evas_gl="no" + AC_MSG_WARN(Silly monkey: ecore_evas_gl requires ecore_x ... disabling ecore_evas_gl) + fi +fi + +if test "x$have_ecore_evas_gl" = "xyes"; then + BUILD_ECORE_EVAS_GL=1 +else + BUILD_ECORE_EVAS_GL=0 +fi + +AC_SUBST(BUILD_ECORE_EVAS_GL) + +have_ecore_evas_fb="no"; + +AC_MSG_CHECKING(whether ecore_evas fb support is to be built) + +AC_ARG_ENABLE(ecore-evas-fb, +[ --disable-ecore-evas-fb disable fb in the ecore_evas module], [ + if [ test "$enableval" = "yes" ]; then + AC_MSG_RESULT(yes) + have_ecore_evas_fb="yes" + else + AC_MSG_RESULT(no) + fi +], [ + AC_MSG_RESULT(yes) + have_ecore_evas_fb="yes" +] +) + +if test "x$have_ecore_evas_fb" = "xyes"; then + AC_CHECK_HEADER(Evas_Engine_FB.h, + [ + AM_CONDITIONAL(BUILD_ECORE_EVAS_FB, true) + AC_DEFINE(BUILD_ECORE_EVAS_FB, 1, [Support for Linux FB in Ecore_Evas]) + ], [ + AM_CONDITIONAL(BUILD_ECORE_EVAS_FB, false) + have_ecore_evas_fb="no" + ], [ + #include + ] + ) +else + AM_CONDITIONAL(BUILD_ECORE_EVAS_FB, false) +fi + +if test "x$have_ecore_evas_fb" = "xyes"; then + BUILD_ECORE_EVAS_FB=1 +else + BUILD_ECORE_EVAS_FB=0 +fi + +AC_SUBST(BUILD_ECORE_EVAS_FB) + +have_ecore_evas_buffer="no"; + +AC_MSG_CHECKING(whether ecore_evas buffer support is to be built) + +AC_ARG_ENABLE(ecore-evas-buffer, +[ --disable-ecore-evas-buffer disable buffer in the ecore_evas module], [ + if [ test "$enableval" = "yes" ]; then + AC_MSG_RESULT(yes) + have_ecore_evas_buffer="yes" + else + AC_MSG_RESULT(no) + fi +], [ + AC_MSG_RESULT(yes) + have_ecore_evas_buffer="yes" +] +) + +if test "x$have_ecore_evas_buffer" = "xyes"; then + AC_CHECK_HEADER(Evas_Engine_Buffer.h, + [ + AM_CONDITIONAL(BUILD_ECORE_EVAS_BUFFER, true) + AC_DEFINE(BUILD_ECORE_EVAS_BUFFER, 1, [Support for Buffers in Ecore_Evas]) + ], [ + AM_CONDITIONAL(BUILD_ECORE_EVAS_BUFFER, false) + have_ecore_evas_buffer="no" + ], [ + #include + ] + ) +else + AM_CONDITIONAL(BUILD_ECORE_EVAS_BUFFER, false) +fi + +if test "x$have_ecore_evas_buffer" = "xyes"; then + BUILD_ECORE_EVAS_BUFFER=1 +else + BUILD_ECORE_EVAS_BUFFER=0 +fi +CFLAGS=$PCFLAGS + +AC_SUBST(BUILD_ECORE_EVAS_BUFFER) + +AC_MSG_CHECKING(whether ecore_con module is to be built) + +have_ecore_con="no"; +ecore_con_cflags=""; +ecore_con_libs=""; + +AC_ARG_ENABLE(ecore-con, +[ --disable-ecore-con disable the ecore_con module], [ + if [ test "$enableval" = "yes" ]; then + AC_MSG_RESULT(yes) + have_ecore_con="yes" + else + AC_MSG_RESULT(no) + fi +], [ + AC_MSG_RESULT(yes) + have_ecore_con="yes" +] +) + +if test "x$have_ecore_con" = "xyes"; then + AM_CONDITIONAL(BUILD_ECORE_CON, true) + AC_DEFINE(BUILD_ECORE_CON, 1, [Build Ecore_Con Module]) + ecore_con_libs="-lecore_con" +else + AM_CONDITIONAL(BUILD_ECORE_CON, false) +fi + +AC_SUBST(ecore_con_cflags) +AC_SUBST(ecore_con_libs) + +AC_ARG_ENABLE(openssl, + [ --enable-openssl enable openssl support (default: autodetect)], + [use_openssl=$enableval], use_openssl=yes) + +if test "x$use_openssl" = "xyes"; then + PKG_CHECK_MODULES(SSL, openssl, use_openssl=yes, use_openssl=no) +fi + +if test "x$use_openssl" = "xyes"; then + USE_OPENSSL=1 +else + USE_OPENSSL=0 +fi + +AC_SUBST(USE_OPENSSL) +AC_DEFINE_UNQUOTED(USE_OPENSSL, $USE_OPENSSL, [Use OpenSSL]) + +have_ecore_ipc="no"; +ecore_ipc_cflags=""; +ecore_ipc_libs=""; + +if test "x$have_ecore_con" = "xyes"; then +AC_MSG_CHECKING(whether ecore_ipc module is to be built) + AC_ARG_ENABLE(ecore-ipc, + [ --disable-ecore-ipc disable the ecore_ipc module], [ + if [ test "$enableval" = "yes" ]; then + AC_MSG_RESULT(yes) + have_ecore_ipc="yes" + else + AC_MSG_RESULT(no) + fi + ], [ + AC_MSG_RESULT(yes) + have_ecore_ipc="yes" + ] + ) +else + AC_MSG_RESULT(ecore_con not enabled, so ecore_ipc will not be enabled) +fi + +if test "x$have_ecore_ipc" = "xyes"; then + AM_CONDITIONAL(BUILD_ECORE_IPC, true) + AC_DEFINE(BUILD_ECORE_IPC, 1, [Build Ecore_Ipc Module]) + ecore_ipc_libs="-lecore_ipc" +else + AM_CONDITIONAL(BUILD_ECORE_IPC, false) +fi + +AC_SUBST(ecore_ipc_cflags) +AC_SUBST(ecore_ipc_libs) + + +AC_MSG_CHECKING(whether ecore_dbus module is to be built) +have_ecore_dbus="no"; +ecore_dbus_cflags=""; +ecore_dbus_libs=""; +dbus_dir=""; +dbus_includes=""; +dbus_cflags=""; +dbus_libs=""; + +AC_ARG_ENABLE(ecore-dbus, +[ --disable-ecore-dbus disable the ecore_dbus module], [ + if [ test "$enableval" = "yes" ]; then + AC_MSG_RESULT(yes) + have_ecore_dbus="yes" + else + AC_MSG_RESULT(no) + fi +], [ + AC_MSG_RESULT(yes) + have_ecore_dbus="yes" +] +) + +if test "x$have_ecore_dbus" = "xyes"; then + AM_CONDITIONAL(BUILD_ECORE_DBUS, true) + AC_DEFINE(BUILD_ECORE_DBUS, 1, [Build Ecore_DBus Module]) + BUILD_ECORE_DBUS=1 + #dbus_dir="/usr"; + #dbus_includes=""; + #dbus_cflags="-I"$dbus_dir"/include/dbus-1.0 -I"$dbus_dir"/lib/dbus-1.0/include" + #dbus_libs="-L"$dbus_dir"/lib" + #dbus_ldflags="-ldbus-1"; + ecore_dbus_libs="-lecore_dbus"; +else + AM_CONDITIONAL(BUILD_ECORE_DBUS, false) + BUILD_ECORE_DBUS=0 +fi + +AC_SUBST(BUILD_ECORE_DBUS) + +AC_SUBST(dbus_cflags) +AC_SUBST(dbus_includes) +AC_SUBST(dbus_ldflags) +AC_SUBST(dbus_libs) + +AC_SUBST(ecore_dbus_cflags) +AC_SUBST(ecore_dbus_libs) + + +AC_MSG_CHECKING(whether ecore_config module is to be built) + +have_ecore_config="no"; +ecore_config_cflags=""; +ecore_config_libs=""; + +AC_ARG_ENABLE(ecore-config, +[ --disable-ecore-config disable the ecore_config module], [ + if [ test "$enableval" = "yes" ]; then + AC_MSG_RESULT(yes) + have_ecore_config="yes"; + else + AC_MSG_RESULT(no) + fi +], [ + AC_MSG_RESULT(yes) + have_ecore_config="yes"; +] +) + +if test "x$have_ecore_config" = "xyes"; then + AC_ARG_WITH(eet-config, [ --with-eet-config=EET_CONFIG use eet-config specified ], + [ EET_CONFIG=$withval; + echo "using "$EET_CONFIG" for eet-config"; ], + [ if test -z "$EET_CONFIG"; then + AC_PATH_PROG(EET_CONFIG, "eet-config", "", $PATH) + fi + ]) + eet_cflags=`$EET_CONFIG --cflags` + eet_libs=`$EET_CONFIG --libs` + AM_CONDITIONAL(BUILD_ECORE_CONFIG, true) + ecore_config_libs="-lecore_config"; + AC_DEFINE(BUILD_ECORE_CONFIG, 1, [Build Ecore_Config Module]) + AC_SUBST(eet_libs) + AC_SUBST(eet_cflags) +else + AM_CONDITIONAL(BUILD_ECORE_CONFIG, false) +fi + +have_ecore_file="no" +ecore_file_libs="" +use_fam="no" +use_inotify="no" +use_poll="no" +use_curl="no" + +AC_MSG_CHECKING(whether ecore_file module is to be built) +AC_ARG_ENABLE(ecore-file, +[ --disable-ecore-file disable the ecore_file module], [ + if test "$enableval" = "yes"; then + AC_MSG_RESULT(yes) + have_ecore_file="yes" + else + AC_MSG_RESULT(no) + fi +], [ + AC_MSG_RESULT(yes) + have_ecore_file="yes" +] +) + +#AC_MSG_CHECKING(whether inotify is to be used for filemonitoring) +#AC_ARG_ENABLE(inotify, +#[ --disable-inotify disable inotify in the ecore_file module], [ +# if test "$enableval" = "yes"; then +# AC_MSG_RESULT(yes) +# use_inotify="yes" +# else +# AC_MSG_RESULT(no) +# fi +#], [ +# AC_MSG_RESULT(yes) +# use_inotify="yes" +#] +#) + +if test "x$use_inotify" = "xyes"; then + AC_CHECK_HEADER(linux/inotify.h, + [ + AC_DEFINE(HAVE_INOTIFY, 1, [ File monitoring with Inotify ]) + use_inotify="yes" + ], [ + use_inotify="no" + ] + ) +fi + +#AC_MSG_CHECKING(whether FAM is to be used for filemonitoring) +#AC_ARG_ENABLE(fam, +#[ --disable-fam disable fam in the ecore_file module], [ +# if test "$enableval" = "yes"; then +# AC_MSG_RESULT(yes) +# use_fam="yes" +# else +# AC_MSG_RESULT(no) +# fi +#], [ +# AC_MSG_RESULT(yes) +# use_fam="yes" +#] +#) + +fam_libs="" +#if test "x$use_fam" = "xyes"; then +# AC_CHECK_LIB(fam, FAMOpen, +# [ +# AC_DEFINE(HAVE_FAM, 1, [ File monitoring with FAM ]) +# use_fam="yes" +# fam_libs="-lfam" +# ], [ +# use_fam="no" +# ] +# ) +#fi + +AC_MSG_CHECKING(whether polling is to be used for filemonitoring) +AC_ARG_ENABLE(poll, +[ --disable-poll disable poll in the ecore_file module], [ + if test "$enableval" = "yes"; then + AC_MSG_RESULT(yes) + use_poll="yes" + else + AC_MSG_RESULT(no) + fi +], [ + AC_MSG_RESULT(yes) + use_poll="yes" +] +) + +if test "x$use_poll" = "xyes"; then + AC_DEFINE(HAVE_POLL, 1, [ File monitoring with polling ]) +fi + +curl_flags="" +curl_libs="" +AC_ARG_WITH(curl-config, +[ --with-curl-config=CURL_CONFIG use curl-config specified], [ + CURL_CONFIG=$withval +],[ + CURL_CONFIG="yes" +] +) +if test "$CURL_CONFIG" = "yes"; then + AC_PATH_PROG(CURL_CONFIG, "curl-config", "", $PATH) +elif test "$CURL_CONFIG" != "no"; then + AC_MSG_RESULT(using "$CURL_CONFIG" for curl-config) +else + CURL_CONFIG="" +fi + +if test -n "$CURL_CONFIG"; then + use_curl="yes" + curl_cflags=`$CURL_CONFIG --cflags` + curl_libs=`$CURL_CONFIG --libs` + AC_DEFINE(HAVE_CURL, 1, [ Downloading with CURL ]) +fi + +if test "x$have_ecore_file" = "xyes"; then + AM_CONDITIONAL(BUILD_ECORE_FILE, true) + ecore_file_libs="-lecore_file" + AC_DEFINE(HAVE_POLL, 1, [ File monitoring with polling ]) +else + AM_CONDITIONAL(BUILD_ECORE_FILE, false) +fi +ecore_file_libs="$ecore_file_libs $fam_libs $curl_libs" +AC_SUBST(curl_cflags) +AC_SUBST(curl_libs) +AC_SUBST(fam_libs) +AC_SUBST(ecore_file_libs) + + +AC_ARG_ENABLE(pthreads, +[--disable-pthreads disable building with pthread support], +[ + if test x$enableval = xyes; then + pthreads=yes + else + pthreads=no + fi +] +) + +if test x$pthreads = xyes ; then +AC_CHECK_HEADERS(pthread.h,pthread_header_ok="yes", pthread_header_ok="no") + if test "$pthread_header_ok" = "yes"; then + AC_CHECK_LIB(pthread, main, PTHREAD_LIBS="-lpthread", PTHREAD_LIBS="error") + if test "$PTHREAD_LIBS" = "error"; then + AC_CHECK_LIB(c_r, main, PTHREAD_LIBS="-pthread", pthread_lib_ok="no") + fi + fi + if test "$pthread_header_ok" = "no" -o "$pthread_lib_ok" = "no"; then + HAVE_PTHREADS=0 + else + HAVE_PTHREADS=1 + fi + if test "$PTHREAD_LIBS" = "-pthread"; then + LIBS="$LIBS $PTHREAD_LIBS" + else + PTHREAD_CFLAGS="-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS" + LIBS="$LIBS $PTHREAD_LIBS" + fi +else + HAVE_PTHREADS=0 + PTHREAD_LIBS="" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(HAVE_PTHREADS) + +AC_CHECK_LIB(dl, dlopen, dlopen_libs=-ldl) +AC_SUBST(dlopen_libs) + +dnl Checking for Perl: +AC_PATH_PROG(PERL,perl,0) +AC_SUBST(PERL) + + +AC_SUBST(ecore_config_cflags) +AC_SUBST(ecore_config_libs) + +AC_SUBST(USE_OPENSSL) + +requirements="" +AC_SUBST(requirements) + +AC_OUTPUT([ +Makefile +ecore.pc +data/Makefile +data/fonts/Makefile +data/images/Makefile +data/pointers/Makefile +src/Makefile +src/bin/Makefile +src/lib/Makefile +src/lib/ecore/Makefile +src/lib/ecore_job/Makefile +src/lib/ecore_x/Makefile +src/lib/ecore_fb/Makefile +src/lib/ecore_evas/Makefile +src/lib/ecore_con/Makefile +src/lib/ecore_ipc/Makefile +src/lib/ecore_txt/Makefile +src/lib/ecore_config/Makefile +src/lib/ecore_file/Makefile +src/lib/ecore_dbus/Makefile +examples/Makefile +ecore-config +README +ecore.spec +ecore.oe +ecore-native.oe +ecore.bb +ecoreXnative.bb +debian/changelog +],[ +chmod +x ecore-config +]) + +echo +echo "$PACKAGE $VERSION" +echo +echo "Optional Modules:" +echo +echo " Ecore_Job...............: $have_ecore_job" +echo " Ecore_Con...............: $have_ecore_con (OpenSSL: $use_openssl)" +echo " Ecore_Txt...............: $have_ecore_txt" +echo " Ecore_X.................: $have_ecore_x (Xcursor: $use_Xcursor) (Xprint: $use_Xprint) (Xinerama: $use_Xinerama)" +echo " Ecore_FB................: $have_ecore_fb" +echo " Ecore_Evas..............: $have_ecore_evas" +echo " Ecore_Evas GL Support...: $have_ecore_evas_gl" +echo " Ecore_Evas FB Support...: $have_ecore_evas_fb" +echo " Ecore_Buffer............: $have_ecore_evas_buffer" +echo " Ecore_Ipc...............: $have_ecore_ipc (OpenSSL: $use_openssl)" +echo " Ecore_Config............: $have_ecore_config" +echo " Ecore_DBUS..............: $have_ecore_dbus" +#echo " Ecore_File..............: $have_ecore_file (Inotify: $use_inotify) (FAM: $use_fam) (Poll: $use_poll)" +echo " Ecore_File..............: $have_ecore_file (Inotify: $use_inotify) (Poll: $use_poll) (CURL: $use_curl)" +echo +echo "Now type 'make' ('gmake' on some systems) to compile $PACKAGE." +echo diff --git a/ecore/data/.cvsignore b/ecore/data/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/ecore/data/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/ecore/data/CVS/Entries b/ecore/data/CVS/Entries new file mode 100644 index 0000000..e7db7d9 --- /dev/null +++ b/ecore/data/CVS/Entries @@ -0,0 +1,5 @@ +/.cvsignore/1.1/Wed May 12 18:57:56 2004//THEAD +/Makefile.am/1.2/Thu Mar 10 15:19:32 2005//THEAD +D/fonts//// +D/images//// +D/pointers//// diff --git a/ecore/data/CVS/Repository b/ecore/data/CVS/Repository new file mode 100644 index 0000000..81c0853 --- /dev/null +++ b/ecore/data/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/data diff --git a/ecore/data/CVS/Root b/ecore/data/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/data/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/data/CVS/Tag b/ecore/data/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/data/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/data/Makefile.am b/ecore/data/Makefile.am new file mode 100644 index 0000000..0eb6a4e --- /dev/null +++ b/ecore/data/Makefile.am @@ -0,0 +1,2 @@ +MAINTAINERCLEANFILES = Makefile.in +SUBDIRS = fonts images pointers diff --git a/ecore/data/fonts/.cvsignore b/ecore/data/fonts/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/ecore/data/fonts/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/ecore/data/fonts/CVS/Entries b/ecore/data/fonts/CVS/Entries new file mode 100644 index 0000000..94d1c53 --- /dev/null +++ b/ecore/data/fonts/CVS/Entries @@ -0,0 +1,15 @@ +/.cvsignore/1.1/Wed May 12 18:57:57 2004//THEAD +/Makefile.am/1.5/Thu Mar 10 15:19:33 2005//THEAD +/Vera.ttf/1.1/Thu May 13 09:39:43 2004/-kb/THEAD +/VeraBI.ttf/1.1/Thu May 13 09:39:43 2004/-kb/THEAD +/VeraBd.ttf/1.1/Thu May 13 09:39:43 2004/-kb/THEAD +/VeraIt.ttf/1.1/Thu May 13 09:39:43 2004/-kb/THEAD +/VeraMoBI.ttf/1.1/Thu May 13 09:39:43 2004/-kb/THEAD +/VeraMoBd.ttf/1.1/Thu May 13 09:39:43 2004/-kb/THEAD +/VeraMoIt.ttf/1.1/Thu May 13 09:39:43 2004/-kb/THEAD +/VeraMono.ttf/1.1/Thu May 13 09:39:43 2004/-kb/THEAD +/VeraSe.ttf/1.1/Thu May 13 09:39:43 2004/-kb/THEAD +/VeraSeBd.ttf/1.1/Thu May 13 09:39:43 2004/-kb/THEAD +/fonts.alias/1.1/Thu May 13 09:39:43 2004//THEAD +/fonts.dir/1.1/Thu May 13 09:39:43 2004//THEAD +D diff --git a/ecore/data/fonts/CVS/Repository b/ecore/data/fonts/CVS/Repository new file mode 100644 index 0000000..e92a752 --- /dev/null +++ b/ecore/data/fonts/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/data/fonts diff --git a/ecore/data/fonts/CVS/Root b/ecore/data/fonts/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/data/fonts/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/data/fonts/CVS/Tag b/ecore/data/fonts/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/data/fonts/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/data/fonts/Makefile.am b/ecore/data/fonts/Makefile.am new file mode 100644 index 0000000..c4d04b7 --- /dev/null +++ b/ecore/data/fonts/Makefile.am @@ -0,0 +1,10 @@ +MAINTAINERCLEANFILES = Makefile.in +FILES = Vera.ttf VeraBI.ttf VeraBd.ttf VeraIt.ttf VeraMoBI.ttf \ + VeraMoBd.ttf VeraMoIt.ttf VeraMono.ttf VeraSe.ttf VeraSeBd.ttf \ + fonts.alias fonts.dir + +fontsdir = $(pkgdatadir)/fonts +fonts_DATA = $(FILES) + +EXTRA_DIST = $(FILES) + diff --git a/ecore/data/fonts/Vera.ttf b/ecore/data/fonts/Vera.ttf new file mode 100644 index 0000000..58cd6b5 Binary files /dev/null and b/ecore/data/fonts/Vera.ttf differ diff --git a/ecore/data/fonts/VeraBI.ttf b/ecore/data/fonts/VeraBI.ttf new file mode 100644 index 0000000..b55eee3 Binary files /dev/null and b/ecore/data/fonts/VeraBI.ttf differ diff --git a/ecore/data/fonts/VeraBd.ttf b/ecore/data/fonts/VeraBd.ttf new file mode 100644 index 0000000..51d6111 Binary files /dev/null and b/ecore/data/fonts/VeraBd.ttf differ diff --git a/ecore/data/fonts/VeraIt.ttf b/ecore/data/fonts/VeraIt.ttf new file mode 100644 index 0000000..cc23c9e Binary files /dev/null and b/ecore/data/fonts/VeraIt.ttf differ diff --git a/ecore/data/fonts/VeraMoBI.ttf b/ecore/data/fonts/VeraMoBI.ttf new file mode 100644 index 0000000..8624542 Binary files /dev/null and b/ecore/data/fonts/VeraMoBI.ttf differ diff --git a/ecore/data/fonts/VeraMoBd.ttf b/ecore/data/fonts/VeraMoBd.ttf new file mode 100644 index 0000000..9be6547 Binary files /dev/null and b/ecore/data/fonts/VeraMoBd.ttf differ diff --git a/ecore/data/fonts/VeraMoIt.ttf b/ecore/data/fonts/VeraMoIt.ttf new file mode 100644 index 0000000..2404924 Binary files /dev/null and b/ecore/data/fonts/VeraMoIt.ttf differ diff --git a/ecore/data/fonts/VeraMono.ttf b/ecore/data/fonts/VeraMono.ttf new file mode 100644 index 0000000..139f0b4 Binary files /dev/null and b/ecore/data/fonts/VeraMono.ttf differ diff --git a/ecore/data/fonts/VeraSe.ttf b/ecore/data/fonts/VeraSe.ttf new file mode 100644 index 0000000..4b4ecc6 Binary files /dev/null and b/ecore/data/fonts/VeraSe.ttf differ diff --git a/ecore/data/fonts/VeraSeBd.ttf b/ecore/data/fonts/VeraSeBd.ttf new file mode 100644 index 0000000..672bf76 Binary files /dev/null and b/ecore/data/fonts/VeraSeBd.ttf differ diff --git a/ecore/data/fonts/fonts.alias b/ecore/data/fonts/fonts.alias new file mode 100644 index 0000000..bbb99b3 --- /dev/null +++ b/ecore/data/fonts/fonts.alias @@ -0,0 +1,11 @@ +Vera-Bold-Italic -Bitstream-Bitstream Vera Sans-bold-i-normal--0-0-0-0-p-0-ascii-0 +Vera-Normal -Bitstream-Bitstream Vera Sans-medium-r-normal--0-0-0-0-p-0-ascii-0 +Vera-Bold -Bitstream-Bitstream Vera Sans-bold-r-normal--0-0-0-0-p-0-ascii-0 +Vera-Italic -Bitstream-Bitstream Vera Sans-medium-i-normal--0-0-0-0-p-0-ascii- +Vera-Mono-Bold-Italic -Bitstream-Bitstream Vera Sans Mono-bold-i-normal--0-0-0-0-m-0-ascii-0 +Vera-Mono-Bold -Bitstream-Bitstream Vera Sans Mono-bold-r-normal--0-0-0-0-m-0-ascii-0 +Vera-Mono-Italic -Bitstream-Bitstream Vera Sans Mono-medium-i-normal--0-0-0-0-m-0-ascii-0 +Vera-Mono -Bitstream-Bitstream Vera Sans Mono-medium-r-normal--0-0-0-0-m-0-ascii-0 +Vera-Serif -Bitstream-Bitstream Vera Serif-medium-r-normal--0-0-0-0-p-0-ascii-0 +Vera-Serif-Bold -Bitstream-Bitstream Vera Serif-bold-r-normal--0-0-0-0-p-0-ascii-0 +Vera -Bitstream-Bitstream Vera Sans-medium-r-normal--0-0-0-0-p-0-ascii-0 diff --git a/ecore/data/fonts/fonts.dir b/ecore/data/fonts/fonts.dir new file mode 100644 index 0000000..2dab016 --- /dev/null +++ b/ecore/data/fonts/fonts.dir @@ -0,0 +1,51 @@ +50 +VeraBI.ttf -Bitstream-Bitstream Vera Sans-bold-i-normal--0-0-0-0-p-0-ascii-0 +VeraBI.ttf -Bitstream-Bitstream Vera Sans-bold-i-normal--0-0-0-0-p-0-fcd8859-15 +VeraBI.ttf -Bitstream-Bitstream Vera Sans-bold-i-normal--0-0-0-0-p-0-iso8859-1 +VeraBI.ttf -Bitstream-Bitstream Vera Sans-bold-i-normal--0-0-0-0-p-0-iso8859-15 +VeraBI.ttf -Bitstream-Bitstream Vera Sans-bold-i-normal--0-0-0-0-p-0-iso8859-9 +Vera.ttf -Bitstream-Bitstream Vera Sans-medium-r-normal--0-0-0-0-p-0-ascii-0 +Vera.ttf -Bitstream-Bitstream Vera Sans-medium-r-normal--0-0-0-0-p-0-fcd8859-15 +Vera.ttf -Bitstream-Bitstream Vera Sans-medium-r-normal--0-0-0-0-p-0-iso8859-1 +Vera.ttf -Bitstream-Bitstream Vera Sans-medium-r-normal--0-0-0-0-p-0-iso8859-15 +Vera.ttf -Bitstream-Bitstream Vera Sans-medium-r-normal--0-0-0-0-p-0-iso8859-9 +VeraBd.ttf -Bitstream-Bitstream Vera Sans-bold-r-normal--0-0-0-0-p-0-ascii-0 +VeraBd.ttf -Bitstream-Bitstream Vera Sans-bold-r-normal--0-0-0-0-p-0-fcd8859-15 +VeraBd.ttf -Bitstream-Bitstream Vera Sans-bold-r-normal--0-0-0-0-p-0-iso8859-1 +VeraBd.ttf -Bitstream-Bitstream Vera Sans-bold-r-normal--0-0-0-0-p-0-iso8859-15 +VeraBd.ttf -Bitstream-Bitstream Vera Sans-bold-r-normal--0-0-0-0-p-0-iso8859-9 +VeraIt.ttf -Bitstream-Bitstream Vera Sans-medium-i-normal--0-0-0-0-p-0-ascii-0 +VeraIt.ttf -Bitstream-Bitstream Vera Sans-medium-i-normal--0-0-0-0-p-0-fcd8859-15 +VeraIt.ttf -Bitstream-Bitstream Vera Sans-medium-i-normal--0-0-0-0-p-0-iso8859-1 +VeraIt.ttf -Bitstream-Bitstream Vera Sans-medium-i-normal--0-0-0-0-p-0-iso8859-15 +VeraIt.ttf -Bitstream-Bitstream Vera Sans-medium-i-normal--0-0-0-0-p-0-iso8859-9 +VeraMoBI.ttf -Bitstream-Bitstream Vera Sans Mono-bold-i-normal--0-0-0-0-m-0-ascii-0 +VeraMoBI.ttf -Bitstream-Bitstream Vera Sans Mono-bold-i-normal--0-0-0-0-m-0-fcd8859-15 +VeraMoBI.ttf -Bitstream-Bitstream Vera Sans Mono-bold-i-normal--0-0-0-0-m-0-iso8859-1 +VeraMoBI.ttf -Bitstream-Bitstream Vera Sans Mono-bold-i-normal--0-0-0-0-m-0-iso8859-15 +VeraMoBI.ttf -Bitstream-Bitstream Vera Sans Mono-bold-i-normal--0-0-0-0-m-0-iso8859-9 +VeraMoBd.ttf -Bitstream-Bitstream Vera Sans Mono-bold-r-normal--0-0-0-0-m-0-ascii-0 +VeraMoBd.ttf -Bitstream-Bitstream Vera Sans Mono-bold-r-normal--0-0-0-0-m-0-fcd8859-15 +VeraMoBd.ttf -Bitstream-Bitstream Vera Sans Mono-bold-r-normal--0-0-0-0-m-0-iso8859-1 +VeraMoBd.ttf -Bitstream-Bitstream Vera Sans Mono-bold-r-normal--0-0-0-0-m-0-iso8859-15 +VeraMoBd.ttf -Bitstream-Bitstream Vera Sans Mono-bold-r-normal--0-0-0-0-m-0-iso8859-9 +VeraMoIt.ttf -Bitstream-Bitstream Vera Sans Mono-medium-i-normal--0-0-0-0-m-0-ascii-0 +VeraMoIt.ttf -Bitstream-Bitstream Vera Sans Mono-medium-i-normal--0-0-0-0-m-0-fcd8859-15 +VeraMoIt.ttf -Bitstream-Bitstream Vera Sans Mono-medium-i-normal--0-0-0-0-m-0-iso8859-1 +VeraMoIt.ttf -Bitstream-Bitstream Vera Sans Mono-medium-i-normal--0-0-0-0-m-0-iso8859-15 +VeraMoIt.ttf -Bitstream-Bitstream Vera Sans Mono-medium-i-normal--0-0-0-0-m-0-iso8859-9 +VeraMono.ttf -Bitstream-Bitstream Vera Sans Mono-medium-r-normal--0-0-0-0-m-0-ascii-0 +VeraMono.ttf -Bitstream-Bitstream Vera Sans Mono-medium-r-normal--0-0-0-0-m-0-fcd8859-15 +VeraMono.ttf -Bitstream-Bitstream Vera Sans Mono-medium-r-normal--0-0-0-0-m-0-iso8859-1 +VeraMono.ttf -Bitstream-Bitstream Vera Sans Mono-medium-r-normal--0-0-0-0-m-0-iso8859-15 +VeraMono.ttf -Bitstream-Bitstream Vera Sans Mono-medium-r-normal--0-0-0-0-m-0-iso8859-9 +VeraSe.ttf -Bitstream-Bitstream Vera Serif-medium-r-normal--0-0-0-0-p-0-ascii-0 +VeraSe.ttf -Bitstream-Bitstream Vera Serif-medium-r-normal--0-0-0-0-p-0-fcd8859-15 +VeraSe.ttf -Bitstream-Bitstream Vera Serif-medium-r-normal--0-0-0-0-p-0-iso8859-1 +VeraSe.ttf -Bitstream-Bitstream Vera Serif-medium-r-normal--0-0-0-0-p-0-iso8859-15 +VeraSe.ttf -Bitstream-Bitstream Vera Serif-medium-r-normal--0-0-0-0-p-0-iso8859-9 +VeraSeBd.ttf -Bitstream-Bitstream Vera Serif-bold-r-normal--0-0-0-0-p-0-ascii-0 +VeraSeBd.ttf -Bitstream-Bitstream Vera Serif-bold-r-normal--0-0-0-0-p-0-fcd8859-15 +VeraSeBd.ttf -Bitstream-Bitstream Vera Serif-bold-r-normal--0-0-0-0-p-0-iso8859-1 +VeraSeBd.ttf -Bitstream-Bitstream Vera Serif-bold-r-normal--0-0-0-0-p-0-iso8859-15 +VeraSeBd.ttf -Bitstream-Bitstream Vera Serif-bold-r-normal--0-0-0-0-p-0-iso8859-9 diff --git a/ecore/data/images/.cvsignore b/ecore/data/images/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/ecore/data/images/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/ecore/data/images/CVS/Entries b/ecore/data/images/CVS/Entries new file mode 100644 index 0000000..1b28edd --- /dev/null +++ b/ecore/data/images/CVS/Entries @@ -0,0 +1,12 @@ +/.cvsignore/1.1/Wed May 12 18:57:57 2004//THEAD +/Makefile.am/1.3/Thu Mar 10 15:19:33 2005//THEAD +/ball.png/1.2/Tue Sep 23 08:09:20 2003/-kb/THEAD +/bar.png/1.2/Tue Sep 23 08:09:20 2003/-kb/THEAD +/bar_shad_above.png/1.2/Tue Sep 23 08:09:20 2003/-kb/THEAD +/bar_shad_below.png/1.2/Tue Sep 23 08:09:20 2003/-kb/THEAD +/bg.png/1.2/Tue Sep 23 08:09:20 2003/-kb/THEAD +/crosshair.png/1.2/Tue Sep 23 08:09:21 2003/-kb/THEAD +/e_logo.png/1.2/Tue Sep 23 08:09:21 2003/-kb/THEAD +/evas_logo.png/1.2/Tue Sep 23 08:09:21 2003/-kb/THEAD +/shadow.png/1.2/Tue Sep 23 08:09:21 2003/-kb/THEAD +D diff --git a/ecore/data/images/CVS/Repository b/ecore/data/images/CVS/Repository new file mode 100644 index 0000000..db597ce --- /dev/null +++ b/ecore/data/images/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/data/images diff --git a/ecore/data/images/CVS/Root b/ecore/data/images/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/data/images/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/data/images/CVS/Tag b/ecore/data/images/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/data/images/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/data/images/Makefile.am b/ecore/data/images/Makefile.am new file mode 100644 index 0000000..6a7d4a9 --- /dev/null +++ b/ecore/data/images/Makefile.am @@ -0,0 +1,10 @@ +MAINTAINERCLEANFILES = Makefile.in + +IMAGES = ball.png bar.png bar_shad_above.png bar_shad_below.png \ + bg.png crosshair.png e_logo.png evas_logo.png shadow.png + +imgdir = $(pkgdatadir)/images +img_DATA = $(IMAGES) + +EXTRA_DIST = $(IMAGES) + diff --git a/ecore/data/images/ball.png b/ecore/data/images/ball.png new file mode 100644 index 0000000..6549ac3 Binary files /dev/null and b/ecore/data/images/ball.png differ diff --git a/ecore/data/images/bar.png b/ecore/data/images/bar.png new file mode 100644 index 0000000..ed619c3 Binary files /dev/null and b/ecore/data/images/bar.png differ diff --git a/ecore/data/images/bar_shad_above.png b/ecore/data/images/bar_shad_above.png new file mode 100644 index 0000000..fda2e8a Binary files /dev/null and b/ecore/data/images/bar_shad_above.png differ diff --git a/ecore/data/images/bar_shad_below.png b/ecore/data/images/bar_shad_below.png new file mode 100644 index 0000000..7f242f8 Binary files /dev/null and b/ecore/data/images/bar_shad_below.png differ diff --git a/ecore/data/images/bg.png b/ecore/data/images/bg.png new file mode 100644 index 0000000..d3b680c Binary files /dev/null and b/ecore/data/images/bg.png differ diff --git a/ecore/data/images/crosshair.png b/ecore/data/images/crosshair.png new file mode 100644 index 0000000..612d117 Binary files /dev/null and b/ecore/data/images/crosshair.png differ diff --git a/ecore/data/images/e_logo.png b/ecore/data/images/e_logo.png new file mode 100644 index 0000000..54100d5 Binary files /dev/null and b/ecore/data/images/e_logo.png differ diff --git a/ecore/data/images/evas_logo.png b/ecore/data/images/evas_logo.png new file mode 100644 index 0000000..932555e Binary files /dev/null and b/ecore/data/images/evas_logo.png differ diff --git a/ecore/data/images/shadow.png b/ecore/data/images/shadow.png new file mode 100644 index 0000000..327567f Binary files /dev/null and b/ecore/data/images/shadow.png differ diff --git a/ecore/data/pointers/.cvsignore b/ecore/data/pointers/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/ecore/data/pointers/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/ecore/data/pointers/CVS/Entries b/ecore/data/pointers/CVS/Entries new file mode 100644 index 0000000..f1759b9 --- /dev/null +++ b/ecore/data/pointers/CVS/Entries @@ -0,0 +1,4 @@ +/.cvsignore/1.1/Wed May 12 18:57:57 2004//THEAD +/Makefile.am/1.3/Thu Mar 10 15:19:33 2005//THEAD +/mouse_pointer.png/1.2/Tue Sep 23 08:09:21 2003/-kb/THEAD +D diff --git a/ecore/data/pointers/CVS/Repository b/ecore/data/pointers/CVS/Repository new file mode 100644 index 0000000..a55c002 --- /dev/null +++ b/ecore/data/pointers/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/data/pointers diff --git a/ecore/data/pointers/CVS/Root b/ecore/data/pointers/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/data/pointers/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/data/pointers/CVS/Tag b/ecore/data/pointers/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/data/pointers/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/data/pointers/Makefile.am b/ecore/data/pointers/Makefile.am new file mode 100644 index 0000000..56d7c8c --- /dev/null +++ b/ecore/data/pointers/Makefile.am @@ -0,0 +1,8 @@ +MAINTAINERCLEANFILES = Makefile.in + +POINTERS = mouse_pointer.png + +pntrdir = $(pkgdatadir)/pointers +pntr_DATA = $(POINTERS) + +EXTRA_DIST = $(POINTERS) diff --git a/ecore/data/pointers/mouse_pointer.png b/ecore/data/pointers/mouse_pointer.png new file mode 100644 index 0000000..b4e2e12 Binary files /dev/null and b/ecore/data/pointers/mouse_pointer.png differ diff --git a/ecore/debian/.cvsignore b/ecore/debian/.cvsignore new file mode 100644 index 0000000..6ab87c7 --- /dev/null +++ b/ecore/debian/.cvsignore @@ -0,0 +1,11 @@ +Makefile +Makefile.in +ecore1-test +ecore1-test.substvars +files +libecore1 +libecore1-dev +libecore1.postinst.debhelper +libecore1.postrm.debhelper +libecore1.substvars +tmp diff --git a/ecore/debian/CVS/Entries b/ecore/debian/CVS/Entries new file mode 100644 index 0000000..ec038d4 --- /dev/null +++ b/ecore/debian/CVS/Entries @@ -0,0 +1,9 @@ +/.cvsignore/1.3/Thu Nov 13 12:30:47 2003//THEAD +/changelog.in/1.1/Thu Mar 10 15:19:34 2005//THEAD +/control/1.11/Fri Jun 10 08:00:55 2005//THEAD +/copyright/1.4/Tue Sep 23 08:09:21 2003//THEAD +/ecore0-test.install/1.1/Thu Mar 10 15:19:34 2005//THEAD +/libecore0-dev.install/1.1/Thu Mar 10 15:19:34 2005//THEAD +/libecore0.install/1.1/Thu Mar 10 15:19:34 2005//THEAD +/rules/1.9/Thu Mar 10 15:19:34 2005//THEAD +D diff --git a/ecore/debian/CVS/Repository b/ecore/debian/CVS/Repository new file mode 100644 index 0000000..7dd3a6f --- /dev/null +++ b/ecore/debian/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/debian diff --git a/ecore/debian/CVS/Root b/ecore/debian/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/debian/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/debian/CVS/Tag b/ecore/debian/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/debian/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/debian/changelog.in b/ecore/debian/changelog.in new file mode 100644 index 0000000..63044a8 --- /dev/null +++ b/ecore/debian/changelog.in @@ -0,0 +1,5 @@ +ecore (@VERSION@-1) unstable; urgency=low + + * a CVS release + + -- Sytse Wielinga Sat, 18 Sep 2004 14:22:13 +0200 diff --git a/ecore/debian/control b/ecore/debian/control new file mode 100644 index 0000000..7c4c3aa --- /dev/null +++ b/ecore/debian/control @@ -0,0 +1,35 @@ +Source: ecore +Section: libs +Priority: optional +Maintainer: Sytse Wielinga +Build-Depends: debhelper (>> 4.0.0), libedb1-dev, libeet0-dev, libevas0-dev, libssl-dev, libfreetype6-dev, libdirectfb-dev, automake1.7 | automaken, libtool +Standards-Version: 3.6.1.0 + +Package: libecore0 +Architecture: any +Section: libs +Depends: ${shlibs:Depends} +Description: Core abstraction layer for enlightenment DR 0.17 + This is the core event abstraction layer and X abstraction layer that makes + doing selections, Xdnd, general X stuff, and event loops, timeouts and idle + handlers fast, optimized, and convenient. It's a separate library so anyone + can make use of the work put into Ecore to make this job easy for + applications. + +Package: libecore0-dev +Architecture: any +Section: devel +Architecture: any +Depends: libecore0 (= ${Source-Version}), libc6-dev | libc-dev, xlibs-dev +Provides: libecore-dev +Conflicts: libecore-dev, libecore0-dev +Description: libecore0 headers, static libraries and documentation + Headers, static libraries and documentation for the Ecore library. + +Package: ecore0-test +Architecture: any +Section: libs +Depends: ${shlibs:Depends} +Description: Test programs for libecore0 + Programs for testing Ecore and demonstrating what it can do. + diff --git a/ecore/debian/copyright b/ecore/debian/copyright new file mode 100644 index 0000000..71899fd --- /dev/null +++ b/ecore/debian/copyright @@ -0,0 +1,32 @@ +This package was debianized by Laurence J. Lane on +Sat, 28 Oct 2000 17:56:46 -0400. + +The source code is from the e17/libs/ecore module of the enlightenment CVS +tree. For more information, see: + + http://www.enlightenment.org/cvs.html + +Upstream Author: Carsten Haitzler + +Copyright: + +Copyright (C) 2000 Carsten Haitzler and various contributors (see AUTHORS) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies of the Software, its documentation and marketing & publicity +materials, and acknowledgment shall be given in the documentation, materials +and software packages that this Software was used. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ecore/debian/ecore0-test.install b/ecore/debian/ecore0-test.install new file mode 100644 index 0000000..75f80b6 --- /dev/null +++ b/ecore/debian/ecore0-test.install @@ -0,0 +1,2 @@ +usr/bin/*test +usr/share/ecore/images/*.png diff --git a/ecore/debian/libecore0-dev.install b/ecore/debian/libecore0-dev.install new file mode 100644 index 0000000..e2738a0 --- /dev/null +++ b/ecore/debian/libecore0-dev.install @@ -0,0 +1,8 @@ +usr/include/* +usr/lib/lib*.a +usr/lib/lib*.so +usr/lib/ecore*.a +usr/lib/pkgconfig/* +usr/lib/*.la +usr/share/aclocal/* +usr/bin/*-config diff --git a/ecore/debian/libecore0.install b/ecore/debian/libecore0.install new file mode 100644 index 0000000..70f1c39 --- /dev/null +++ b/ecore/debian/libecore0.install @@ -0,0 +1,6 @@ +usr/lib/lib*.so.* +usr/lib/ecore*.so +usr/share/ecore/fonts/*.ttf +usr/share/ecore/fonts/fonts.alias +usr/share/ecore/fonts/fonts.dir +usr/share/ecore/pointers/*.png diff --git a/ecore/debian/rules b/ecore/debian/rules new file mode 100644 index 0000000..a07ca63 --- /dev/null +++ b/ecore/debian/rules @@ -0,0 +1,88 @@ +#!/usr/bin/make -f +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + + +# This is the debhelper compatability version to use. +export DH_COMPAT=4 + + +CFLAGS ?= -Wall -g + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif +ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) + INSTALL_PROGRAM += -s +endif + +# These are used for cross-compiling and for saving the configure script +# from having to guess our platform (since we know it already) +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) + +INSTALL=/usr/bin/install -p +CONFIGUREOPTS = --prefix=/usr --build=$(DEB_BUILD_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE) +package=libecore0 + +configure: configure-stamp +configure-stamp: + dh_testdir + + test -x autogen.sh && ./autogen.sh $(CONFIGUREOPTS) || ./configure $(CONFIGUREOPTS) + + touch configure-stamp + +build: configure build-stamp +build-stamp: + dh_testdir + + $(MAKE) + + touch build-stamp + +clean: + dh_testdir + rm -f build-stamp configure-stamp + + -$(MAKE) distclean + -rm -f configure-stamp build-stamp + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp/ + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installdocs AUTHORS README + dh_installchangelogs + dh_install --sourcedir=debian/tmp --list-missing + dh_strip + dh_compress + dh_fixperms + dh_installdeb + dh_makeshlibs + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/ecore/doc/.cvsignore b/ecore/doc/.cvsignore new file mode 100644 index 0000000..cc370ed --- /dev/null +++ b/ecore/doc/.cvsignore @@ -0,0 +1,3 @@ +html +latex +man diff --git a/ecore/doc/CVS/Entries b/ecore/doc/CVS/Entries new file mode 100644 index 0000000..756a6a2 --- /dev/null +++ b/ecore/doc/CVS/Entries @@ -0,0 +1,5 @@ +/.cvsignore/1.1/Mon Jan 24 02:26:31 2005/-ko/THEAD +/ecore.css/1.2/Tue Sep 23 08:09:22 2003//THEAD +/foot.html/1.2/Tue Sep 23 08:09:22 2003//THEAD +/head.html/1.2/Tue Sep 23 08:09:22 2003//THEAD +D/img//// diff --git a/ecore/doc/CVS/Repository b/ecore/doc/CVS/Repository new file mode 100644 index 0000000..64cc830 --- /dev/null +++ b/ecore/doc/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/doc diff --git a/ecore/doc/CVS/Root b/ecore/doc/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/doc/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/doc/CVS/Tag b/ecore/doc/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/doc/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/doc/ecore.css b/ecore/doc/ecore.css new file mode 100644 index 0000000..6117b39 --- /dev/null +++ b/ecore/doc/ecore.css @@ -0,0 +1,178 @@ +td.md { + background-color: #ffffff; + font-family: monospace; + text-align: left; + vertical-align: center; + font-size: 10; + padding-right : 1px; + padding-top : 1px; + padding-left : 1px; + padding-bottom : 1px; + margin-left : 1px; + margin-right : 1px; + margin-top : 1px; + margin-bottom : 1px +} +td.mdname { + font-family: monospace; + text-align: left; + vertical-align: center; + font-size: 10; + padding-right : 1px; + padding-top : 1px; + padding-left : 1px; + padding-bottom : 1px; + margin-left : 1px; + margin-right : 1px; + margin-top : 1px; + margin-bottom : 1px +} +h1 +{ + text-align: center; + color: #333333 +} +h2 +{ + text-align: left; + color: #333333 +} +h3 +{ + text-align: left; + color: #333333 +} +a:link +{ + text-decoration: none; + color: #444444; + font-weight: bold; +} +a:visited +{ + text-decoration: none; + color: #666666; + font-weight: bold; +} +a:hover +{ + text-decoration: none; + color: #000000; + font-weight: bold; +} +a.nav:link +{ + text-decoration: none; + color: #444444; + font-weight: normal; +} +a.nav:visited +{ + text-decoration: none; + color: #666666; + font-weight: normal; +} +a.nav:hover +{ + text-decoration: none; + color: #000000; + font-weight: normal; +} +a.qindex:link +{ + text-decoration: none; + color: #444444; + font-weight: normal; +} +a.qindex:visited +{ + text-decoration: none; + color: #666666; + font-weight: normal; +} +a.qindex:hover +{ + text-decoration: none; + color: #000000; + font-weight: normal; +} +p +{ + color: #000000; + font-family: sans-serif; + font-size: 10; +} +body { + background-image: url("hilite.png"); + background-repeat: no-repeat; + background-position: left top; + background-color: #dddddd; + color: #000000; + font-family: sans-serif; + padding: 8px; + margin: 0; +} +div.fragment +{ + background-image: url("hilite.png"); + background-repeat: no-repeat; + background-position: left top; + border: thin solid #888888; + background-color: #eeeeee; + padding: 4px; + text-align: left; + vertical-align: center; + font-size: 12; +} +hr +{ + border: 0; + background-color: #000000; + width: 80%; + height: 1; +} +dl +{ + background-image: url("hilite.png"); + background-repeat: no-repeat; + background-position: left top; + border: thin solid #aaaaaa; + background-color: #eeeeee; + padding: 4px; + text-align: left; + vertical-align: center; + font-size: 12; +} +em +{ + color: #334466; + font-family: courier; + font-size: 10; + font-style: normal; +} + +div.nav +{ + border: thin solid #000000; + background-color: #ffffff; + padding: 1px; + text-align: center; + vertical-align: center; + font-size: 12; +} +div.body +{ + border: thin solid #000000; + background-color: #ffffff; + padding: 4px; + text-align: left; + font-size: 10; +} +div.diag +{ + border: thin solid #888888; + background-color: #eeeeee; + padding: 4px; + text-align: center; + font-size: 8; +} diff --git a/ecore/doc/foot.html b/ecore/doc/foot.html new file mode 100644 index 0000000..308b1d0 --- /dev/null +++ b/ecore/doc/foot.html @@ -0,0 +1,2 @@ + + diff --git a/ecore/doc/head.html b/ecore/doc/head.html new file mode 100644 index 0000000..9330de5 --- /dev/null +++ b/ecore/doc/head.html @@ -0,0 +1,19 @@ + + + + +$title + + + + + + diff --git a/ecore/doc/img/CVS/Entries b/ecore/doc/img/CVS/Entries new file mode 100644 index 0000000..b7ff2cd --- /dev/null +++ b/ecore/doc/img/CVS/Entries @@ -0,0 +1,9 @@ +/ecore.png/1.2/Tue Sep 23 08:09:22 2003/-kb/THEAD +/ecore.xcf/1.2/Tue Sep 23 08:09:22 2003/-kb/THEAD +/ecore_big.eps/1.2/Tue Sep 23 08:09:25 2003/-kb/THEAD +/ecore_big.png/1.2/Tue Sep 23 08:09:27 2003/-kb/THEAD +/ecore_mini.png/1.2/Tue Sep 23 08:09:28 2003/-kb/THEAD +/ecore_small.png/1.2/Tue Sep 23 08:09:28 2003/-kb/THEAD +/hilite.png/1.2/Tue Sep 23 08:09:28 2003/-kb/THEAD +/prog_flow.png/1.2/Tue Sep 23 08:09:28 2003/-kb/THEAD +D diff --git a/ecore/doc/img/CVS/Repository b/ecore/doc/img/CVS/Repository new file mode 100644 index 0000000..7c5982e --- /dev/null +++ b/ecore/doc/img/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/doc/img diff --git a/ecore/doc/img/CVS/Root b/ecore/doc/img/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/doc/img/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/doc/img/CVS/Tag b/ecore/doc/img/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/doc/img/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/doc/img/ecore.png b/ecore/doc/img/ecore.png new file mode 100644 index 0000000..47597a8 Binary files /dev/null and b/ecore/doc/img/ecore.png differ diff --git a/ecore/doc/img/ecore.xcf b/ecore/doc/img/ecore.xcf new file mode 100644 index 0000000..2fdf355 Binary files /dev/null and b/ecore/doc/img/ecore.xcf differ diff --git a/ecore/doc/img/ecore_big.eps b/ecore/doc/img/ecore_big.eps new file mode 100644 index 0000000..97535e4 --- /dev/null +++ b/ecore/doc/img/ecore_big.eps @@ -0,0 +1,45178 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: GIMP PostScript file plugin V 1.11 by Peter Kirchgessner +%%Title: /home/raster/C/ecore/doc/img/ecore_big.eps +%%CreationDate: Fri Feb 21 15:39:04 2003 +%%DocumentData: Clean7Bit +%%LanguageLevel: 2 +%%Pages: 1 +%%BoundingBox: 0 0 171 171 +%%EndComments +%%BeginPreview: 255 256 1 256 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000001000080000000000000000000000000 +% 0000000000000000000000000000000001400100000000000000000000000000 +% 0000000000000000000000000000020002400240000000000000000000000000 +% 0000000000000000000000000000010005500150000000000000000000000000 +% 0000000000000000000000000000028002900520000000000000000000000000 +% 0000000000000000000000000000014005240a48010000000000000000000000 +% 000000000000000000000000000002500aa80aa4024000000000000000000000 +% 000000000000000000000000000001480a492848048000000000000000000000 +% 000000000000000000000000000005542aaa2a944a2000000000000000000000 +% 0000000000000000000000000100054895525520894800000000000000000000 +% 00000000000000000000000000a005552a94aa55142000000000000000000000 +% 0000000000000000000000000140054a2aa55488294800000000000000000000 +% 00000000000000000000000000a80aa8d5555525525400000000000000000000 +% 00000000000000000000000001542aaaaaaaaaa9548092000000000000000000 +% 00000000000000000000000001520aaaaa955492a52a05000000000000000000 +% 0000000000000000000000000155555555555525524849000000000000000000 +% 00000000000000000000000001541552aaaaaaaaa92294800000000000000000 +% 0000000000000000000000400155aaabffdd552aa49452a00000000000000000 +% 00000000000000000000000001552af5556feaaaaaa54a400000000000000000 +% 00000000000000000000005002aaaf5affd57d55491524980000000000000000 +% 0000000000000000000000280aaab555557bd6d55254a9500000000000000000 +% 00000000000000000000001602aaaaaabdad7d754aaa85200000000000000000 +% 00000000000000000000002952adaab6d56ad7dea952a8824000000000000000 +% 000000000000000000000015456b56aaab5b5d75452a25540000000000000000 +% 00000000000000000000002a8adcaad5b56aabdfdaa549009000000000000000 +% 00000000000000000000002aa563555aadad6ab5655494aa0200000000000000 +% 00000000000000000000002aadad6aab6ab5ad6fdaaa4924a000000000000000 +% 00000000000000000000002ab2aaad6d56d6b5aaba9492520800000000000000 +% 00000000000000000000002aad5555aadaaad557eca92554a100000000000000 +% 0000000000000000000400aab2aad55555b556aabaaa48aa8800000000000000 +% 00000000000000000000002b6d555ab6db56aad56fa92b552200000000000000 +% 00000000000000000002825552aaab55556adaaaaa9244aa4800000000000000 +% 00000000000000000000a02dad55aaadb6ad55555fd493555000000000000000 +% 00000000000000000002a4ab5555556aaad5ab55556a4aaa8480000000000000 +% 00000000000000000000aa2caaaaadadb6b6b55555aa936aa800000000000000 +% 0000000000000000000155d75555557b6d5556aaaaf525550000000000000000 +% 000000000000000000015528aaaabfdfdbedaaaaaaae936aa800000000000000 +% 00000000000000000000ab6f5555ea5576bab555556aaaaa8100000000000000 +% 00000000000000000000acd155555adfddef5555555b45552800000000000000 +% 00000000000000000002ab2eaaafd5a9775ad55554ad76d48000000000000000 +% 00000000000000000000ad52aabaab56ddf7f5555292aaaa5000000000000000 +% 00000000000000000004b555556ead6ab75d5aaaaaadaaa90000000000000000 +% 00000000000000000001555555b155b6ddf7f6aa95555554a000000000000000 +% 00000000000000001408755556eebaaaaaad5f555492aaa20000000000000000 +% 000000000000000009129aaaab515555557bf5aaaaab55548000000000000000 +% 0000000000000000056aaaaaadaeaaab6aaeaf555294aaa10000000000000000 +% 0000000000000000055555555b52aaad5555faf4aa52aa941000000000000000 +% 000000000000000002aaaaaad4ad55555555afaa9548aaa10000000000000000 +% 000000000000000001552aab6aaaaaaaaaaafafaa928554a0000000000000000 +% 00000000000000000156d556aaaaaaaaaaaaadad25402a900000000000000000 +% 00000000000000000155555555555555555556d6aa482aa48000000000000000 +% 000000000000000000aaaaaad555555555555b5a928015280000000000000000 +% 000000000000000004aaaaad9555555555552aab540015420000000000000000 +% 0000000000000000006aaab66aaaaaaaaaaaa75521000aa84000000000000000 +% 000000000000000005555555555555555554aaaac80005520000000000000000 +% 0000000000000000006aaad555555555554a955540000aa48000000000000000 +% 00000000000000000915555aaaaaaaaaaaa952aaa00005520000000000000000 +% 0000000000000000005555aaaaaaaaaaaa9528aaa00002489000000000000000 +% 000000000000000005555555555555555554a57aa00012aa2000000000000000 +% 0000000000000000002aab555555555554aa880d500042554000000000000000 +% 0000000000000000095555555552aaaaaa912036a80201548000000000000000 +% 000000000000000000555555554a55554954000d501000952800000000000000 +% 000000000000000002aaaaaaaaaaaaa92a420017284000554100000000000000 +% 0000000000000000005555555554952552900004d40000952800000000000000 +% 000000000000000005aaaaaaaa8952aa4920000ba8000052a200000000000000 +% 000000000000000000aaad555552554954400005540000954800000000000000 +% 000000000000000000aaaaaaaa8494aa42800002d200004aa480000000000000 +% 0000000000000000035555555528a510942a0002aa00002aa900000000000000 +% 0000000000000000015555555480094400000004ea0000495200000000000000 +% 0000000000000000015555555554922800000001540000255440000000000000 +% 000000000000000002aaaaaaa4aa0000000000015400004aa900000000000000 +% 000000000000000002aaaaaa95494400000000027500002aaa48000000000000 +% 000000000000000002aad55554aa5020000000005a0000456a80000000000000 +% 000000000000000005552aaaaa928a8900000000a90000125420000000000000 +% 00000000000000000552d55524aa5250000000015a0000256a80000000000000 +% 0000000000000000054aa924aa912484400000002d00000aaaa8000000000000 +% 0000000000000000052aa55549254929000000013a000024b500000000000000 +% 000000000000000005555aaaaa489540080000002500000aad50000000000000 +% 00000000000000000aaaaa5492a52914000000013c000022b544000000000000 +% 00000000000000000aaaaaa2aa925241000000005500000a6d28000000000000 +% 00000000000000000aaaab552a554a9400000000950000255aa0000000000000 +% 000000000000000015555554b554a921000000002c000009754a000000000000 +% 00000000000000000aaaaaa97d529244000000012a0000252ea0000000000000 +% 00000000000000002aaab5452f4aa510000000002d0000095aaa000000000000 +% 00000000000000000aa556a8fbd52880000000002a0000255d50000000000000 +% 0000000000000000252aaa856ef4852400000000b400000936a5000000000000 +% 00000000000000001aa56a28ddbd280000000000ac0000255b50000000000000 +% 00000000000000005255ad457bef4aa0000000005400000956aa400000000000 +% 0000000000000000154aa8926f7bd10a000000002c0000253d50800000000000 +% 00000000000000002a52b524dadef450000000002a000012abaa000000000000 +% 00000000000000005495a89277b5bd00000000003400004a7ea8800000000000 +% 000000000000000012a55249dd6fef040000000004000012ab52000000000000 +% 0000000000000000552ab524b7dabbd0000000000000004abed4800000000000 +% 000000000000000014a9a092ed6feef000000000000000126b52000000000000 +% 000000000000000092a55524b55abbbc000000000000004abea8800000000000 +% 000000000000000035556249d6ab6eef0000000000000092b5d5000000000000 +% 000000000000000044958892aab5bbbbc0000000000000253f54200000000000 +% 00000000000000009552aa48b5556eeef000000000000094b5a9400000000000 +% 00000000000000000aaaa125555555bbbc0000000000004afed4000000000000 +% 0000000000000000a9254a90aaaaad6eef0000000000012555aa800000000000 +% 00000000000000000aaa944a544556dbdbc0000000000094ff54000000000000 +% 0000000000000000aaa952a4a91255b6bef000000000012ab5a9400000000000 +% 00000000000000000a4a49125249555df7bc000000000252ff6a000000000000 +% 0000000000000000aaa924a948922aab5def000000000095d5a9200000000000 +% 00000000000000000a92aa9252008556f77bc00000000554ff54400000000000 +% 0000000000000000a52a49254892295aaddef00000000125aad5000000000000 +% 000000000000000014a49254920044a5bb77be0000000a55ff54400000000000 +% 00000000000000008a92aa924400092aaeddeb80000002ab6ad5000000000000 +% 0000000000000000255492495000809555b77f4000001491ff54400000000000 +% 00000000000000004a4a495524000a22aaeddbf000000557aad2800000000000 +% 80000000000000009551552490800049555b76de00002aab7f54000000000000 +% 0000000000000000052a4a9552000004aad6dff700001257ead5000000000000 +% 80000000000000005549245244000091155bb55de0004aa6df50400000000000 +% 00000000000000000aaa92aaa80000024aaaefff7800155ff5aa800000000000 +% 8000000000000000a54929492100000011555aabde00952dbea8000000000000 +% 00000000000000000aaa452aaa000004a4ab6ffef780355feb55000000000000 +% 8000000000000000254928a494000000024aaaabbde128bb7d50400000000000 +% 000000000000000009524a955200000008955b7eef786937d6aa000000000000 +% 800000000000000052c952524a0000000122aad5bbdf104efda4800000000000 +% 00000000000000000554894aa900000000092abbeef6d0abaaa8000000000000 +% 000000000000000012a92aaa552000000444a2aebbbfe012fea5000000000000 +% 800000000000000024b252494a80000000110155d6eda02baaa8000000000000 +% 800000000000000002a9255552400000000200aabdbbc011fb52000000000000 +% 000000000000000014aa949295400000000000256bef000aad44000000000000 +% 800000000000000001592aaa54a0000000020014aebb00057550000000000000 +% 0000000000000000155651254a9000000008200a95d600026d49000000000000 +% 800000000000000000ad4aaaa954000000008015557c00055aa0000000000000 +% 00000000000000000a569494952a00000054000495a80000aa88000000000000 +% 8000000000000000015552aaaaa4800001010002aaaf50013551000000000000 +% 000000000000000008aba525249540000454240252b1ea004a80000000000000 +% 8000000000000000022d54a955525000910080009552b5402aa8000000000000 +% 000000000000000000abd295292a8aa524aa0000a4a2afe81500000000000000 +% 800000000000000004556952a549524892009200554152be0aa8000000000000 +% 00000000000000000112b52a54aa552a495400019200ab6bc500000000000000 +% 800000000000000000554aa54a9292a5240148056a0152dd5150000000000000 +% 00000000000000000220aa54a955544892aa008aaa00a555aa02000000000000 +% 8000000000000000008a5392952492aa4840a215d4004ab6aad0000000000000 +% 00000000000000000029285552aaaa9292950856a00029555504000000000000 +% 80000000000000000084956a4a4924a449204156a0004aaaaa50000000000000 +% 000000000000000000292a955555552aa44a955aa80012aaaa80000000000000 +% 800000000000000000024554a924929112900576aa00292aaa54800000000000 +% 000000000000000000549a954aaaaa4a49255ad4158005555540000000000000 +% 800000000000000000012a55a92524a95248ab541520148aaa94000000000000 +% 00000000000000000014d552aaa8aa9224935da0165402a95549000000000000 +% 80000000000000000022b4955a4a924a922cb54014880a455522200000000000 +% 0000000000000000002aad24a7a95528a555f500192501155554400000000000 +% 80000000000000000045a95296d692a52afd8a08125442a2aaa9000000000000 +% 0000000000000000002d6c8a51fd6a556b5552204a92814a5552400000000000 +% 80000000000000000055aa52aa57b7db5daaa58004aa2892aaa9100000000000 +% 000000000000000000aab52552bd6aaaaa5506a109294254aaaa420000000000 +% 8000000000000000005b5496cb47dd6b555055500a952892aaa9100000000000 +% 000000000000000001aaad25527577aaa92505240455422aaaaa400000000000 +% 80000000000000000155684d490b2d6d54885494054a54925555290000000000 +% 0000000000000000005b5d35a4aa5bb542e28249225549255552400000000000 +% 80000000000000000002a8aa9295445295142927849552555554920000000000 +% 000000000000000000295955492a2aa924a904aac2a54aa4aaaa440000000000 +% 8000000000000000000552aaa4aaa4aa49545247a11554955551100000000000 +% 00000000000000000052b9556955495492a90492f2aaaaaaaaa4a08000000000 +% 8000000000000000000552ada255255525244257a8455555554a040000000000 +% 000000000000000000aaaab568aa92aa4955148afd5555555524a00000000000 +% 800000000000000000055555e355495492aa82a3544aaaaaaa91080000000000 +% 00000000000000000052b555a95525552512a916ea92aaaaaa4a200000000000 +% 8000000000000000008aaaabe2aa92aa48abc2535d5555555490000000000000 +% 00000000000000000012aaab6aaaa55592a5648ad549555aaa44800000000000 +% 80000000000000000084aaafc555c954a529c92555b6aaab5490080000000000 +% 00000000000000000029577aeaabc54bc49572536aaad5b55221000000000000 +% 80000000000000000082aad7aaab55559253d12555555aaaaa84000000000000 +% 00000000000000000014556d4aabc52b454ab49556aaab555420000000000000 +% 800000000000000000214ab7d55754abe893d922aab6d55aa940000000000000 +% 00000000000000000084955a9557e556c52aaa4aaaaaaaaaa408000000000000 +% 800000000000000000012aadeaaed54da947752aaaaab55552a0000000000000 +% 000000000000000000124ab7555dea57f22dac92aad6d6aa9400000000000000 +% 8000000000000000000012aadf5ba556b4956b65555aaaaa4940000000000000 +% 000000000000000000024955b5f7692fe2a75aaaaaab55555208000000000000 +% 8000000000000000000012aadeaeeaad5915ab5555556aa88440000000000000 +% 0000000000000000000084ab55fbd24ffa4b756aaadaaaa52880000000000000 +% 80000000000000000000292ab6aeff5aafa6ad56d556d5524200000000000000 +% 00000000000000000000025555fbabf7faddd5aaadaaaa889010000000000000 +% 80000000000000000000088aad56feaeaf76b6b5555b55520480000000000000 +% 00000000000000000000212955bbabfbfadb5ad6daaaaa24a000000000000000 +% 800000000000000000000245556d7eaeafb6eb5b555555480000000000000000 +% 0000000000000000000000125557d5fbfadb5ab56aaaaa410400000000000000 +% 8000000000000000000004a4955abb56adb6d6d6ad5554941000000000000000 +% 0000000000000000000000012aaad6fdf76dbb6db55552200000000000000000 +% 80000000000000000000004a49555b575adb6aaaaaaaa9400000000000000000 +% 00000000000000000000000092ab6aedb76dadb6d55524088000000000000000 +% 800000000000000000000009255556b6dadb7555555249400000000000000000 +% 000000000000000000000020089555556db6ab6daaa492100000000000000000 +% 8000000000000000000000009252aadbaaaad555551244400000000000000000 +% 0000000000000000000000000125555555b6ad5554a490800000000000000000 +% 800000000000000000000000244895555aaab555524904000000000000000000 +% 000000000000000000000000011252aaaaaaaaaaaa9020800000000000000000 +% 80000000000000000000000004448a5555555555442244000000000000000000 +% 000000000000000000000000001124aaaaaaaa49294000000000000000000000 +% 8000000000000000000000000104491252aaa492440800000000000000000000 +% 0000000000000000000000000020024924952924912080000000000000000000 +% 8000000000000000000000000001289249224489240000000000000000000000 +% 0000000000000000000000000004022492492922008000000000000000000000 +% 8000000000000000000000000000008924924208540000000000000000000000 +% 0000000000000000000000000000121000249441000000000000000000000000 +% 8000000000000000000000000000002249010008000000000000000000000000 +% 0000000000000000000000000000000000482200240000000000000000000000 +% 8000000000000000000000000000004001024020000000000000000000000000 +% 0000000000000000000000000000000220000000000000000000000000000000 +% 8000000000000000000000000000000000080000000000000000000000000000 +% 0000000000000000000000000000000000004000000000000000000000000000 +% 8000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 8000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 8000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +% 8000000000000000000000000000000000000000000000000000000000000000 +% 0000000000000000000000000000000000000000000000000000000000000000 +%%EndPreview +%%BeginProlog +% Use own dictionary to avoid conflicts +10 dict begin +%%EndProlog +%%Page: 1 1 +% Translate for offset +0.000028 0.000028 translate +% Translate to begin of first scanline +0.000000 170.078740 translate +170.078740 -170.078740 scale +% Image geometry +1720 1720 8 +% Transformation matrix +[ 1720 0 0 1720 0 0 ] +% Strings to hold RGB-samples per scanline +/rstr 1720 string def +/gstr 1720 string def +/bstr 1720 string def +{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop} +{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop} +{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop} +true 3 +%%BeginData: 3234763 ASCII Bytes +colorimage +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcC<$JcC<$JcC<$JcEjlJ,~> +JcC<$JcC<$JcC<$JcF=$jo0i2JcC<$JcC<$OT0h~> +JcC<$JcC<$JcC<$JcF=$jo0i2JcC<$JcC<$OT0h~> +JcC<$JcC<$JcC<$JcF=$jo0i2JcC<$JcC<$OT0h~> +JcC<$JcC<$JcC<$JcFX-d/JUrJcC<$JcC<$SH"*~> +JcC<$JcC<$JcC<$JcFX-d/JUrJcC<$JcC<$SH"*~> +JcC<$JcC<$JcC<$JcFX-d/JUrJcC<$JcC<$SH"*~> +JcC<$JcC<$JcC<$JcFg2a8UYiJcC<$JcC<$T`9N~> +JcC<$JcC<$JcC<$JcFg2a8UYiJcC<$JcC<$T`9N~> +JcC<$JcC<$JcC<$JcFg2a8UYiJcC<$JcC<$T`9N~> +JcC<$JcC<$JcC<$JcFs6^]&faJcC<$JcC<$V#Pr~> +JcC<$JcC<$JcC<$JcFs6^]&faJcC<$JcC<$V#Pr~> +JcC<$JcC<$JcC<$JcFs6^]&faJcC<$JcC<$V#Pr~> +JcC<$JcC<$JcC<$JcG'9]DdB]JcC<$JcC<$V>l&~> +JcC<$JcC<$JcC<$JcG'9]DdB]JcC<$JcC<$V>l&~> +JcC<$JcC<$JcC<$JcG'9]DdB]JcC<$JcC<$V>l&~> +JcC<$JcC<$JcC<$JcG3=[/PXVJcC<$JcC<$W;hA~> +JcC<$JcC<$JcC<$JcG3=[/PXVJcC<$JcC<$W;hA~> +JcC<$JcC<$JcC<$JcG3=[/PXVJcC<$JcC<$W;hA~> +JcC<$JcC<$JcC<$JcG<@Y5X"PJcC<$JcC<$X8d\~> +JcC<$JcC<$JcC<$JcG<@Y5X"PJcC<$JcC<$X8d\~> +JcC<$JcC<$JcC<$JcG<@Y5X"PJcC<$JcC<$X8d\~> +JcC<$JcC<$JcC<$JcG?AW;_AJJcC<$JcC<$YlB4~> +JcC<$JcC<$JcC<$JcG?AW;_AJJcC<$JcC<$YlB4~> +JcC<$JcC<$JcC<$JcG?AW;_AJJcC<$JcC<$YlB4~> +JcC<$JcC<$JcC<$JcGHDU],iEJcC<$JcC<$ZN#F~> +JcC<$JcC<$JcC<$JcGHDU],iEJcC<$JcC<$ZN#F~> +JcC<$JcC<$JcC<$JcGHDU],iEJcC<$JcC<$ZN#F~> +JcC<$JcC<$JcC<$JcGNFT)QJ(qu20HJcC<$JcC<$rr7K~> +JcC<$JcC<$JcC<$JcGNFT)QJ(qu20HJcC<$JcC<$rr7K~> +JcC<$JcC<$JcC<$JcGNFT)QJ(qu20HJcC<$JcC<$rr7K~> +JcC<$JcC<$JcC<$JcGTHRJt_9ec(."JcC<$JcCl4J,~> +JcC<$JcC<$JcC<$JcGTHRJt_9ec(."JcC<$JcCl4J,~> +JcC<$JcC<$JcC<$JcGTHRJt_9ec(."JcC<$JcCl4J,~> +JcC<$JcC<$JcC<$JcG]KeGeq8dJhu%bPm(mJcC<$JcD&9J,~> +JcC<$JcC<$JcC<$JcG]KeGeq8dJhu%bPm(mJcC<$JcD&9J,~> +JcC<$JcC<$JcC<$JcG]KeGeq8dJhu%bPm(mJcC<$JcD&9J,~> +JcC<$JcC<$JcC<$JcFF&hYkq&m/O]sJcC<$JcC<$Sc=3~> +JcC<$JcC<$JcC<$JcFF&hYkq&m/O]sJcC<$JcC<$Sc=3~> +JcC<$JcC<$JcC<$JcFF&hYkq&m/O]sJcC<$JcC<$Sc=3~> +JcC<$JcC<$JcC<$K)aX*eG[hpr;Wr!JcC<$JcC<$U&TW~> +JcC<$JcC<$JcC<$K)aX*eG[hpr;Wr!JcC<$JcC<$U&TW~> +JcC<$JcC<$JcC<$K)aX*eG[hpr;Wr!JcC<$JcC<$U&TW~> +JcC<$JcC<$JcC<$L&^$/bPd"krVhBJJcC<$JcDJEJ,~> +JcC<$JcC<$JcC<$L&^$/bPd"krVhBJJcC<$JcDJEJ,~> +JcC<$JcC<$JcC<$L&^$/bPd"krVhBJJcC<$JcDJEJ,~> +JcC<$JcC<$JcC<$aT(c/df82'm/?DNm/;M7rVhBJJcC<$JcDSHJ,~> +JcC<$JcC<$JcC<$aT(c/df82'm/?DNm/;M7rVhBJJcC<$JcDSHJ,~> +JcC<$JcC<$JcC<$aT(c/df82'm/?DNm/;M7rVhBJJcC<$JcDSHJ,~> +JcC<$JcC<$JcC<$dJq_qm/Pi>nbq;Anbn% +JcC<$JcC<$JcC<$dJq_qm/Pi>nbq;Anbn% +JcC<$JcC<$JcC<$dJq_qm/Pi>nbq;Anbn% +JcC<$JcC<$JcC<$f`.38oDR2:o)4.=!<.QLJcC<$JcDbMJ,~> +JcC<$JcC<$JcC<$f`.38oDR2:o)4.=!<.QLJcC<$JcDbMJ,~> +JcC<$JcC<$JcC<$f`.38oDR2:o)4.=!<.QLJcC<$JcDbMJ,~> +JcC<$JcC<$JcC<$h>`Z;o_n+Rq"sCToDO7>!<.QLJcC<$JcDkPJ,~> +JcC<$JcC<$JcC<$h>`Z;o_n+Rq"sCToDO7>!<.QLJcC<$JcDkPJ,~> +JcC<$JcC<$JcC<$h>`Z;o_n+Rq"sCToDO7>!<.QLJcC<$JcDkPJ,~> +JcC<$JcC<$JcC<$i;\u>p&4IZj88BEo_j@?JcC<$JcC<$YQ'+~> +JcC<$JcC<$JcC<$i;\u>p&4IZj88BEo_j@?JcC<$JcC<$YQ'+~> +JcC<$JcC<$JcC<$i;\u>p&4IZj88BEo_j@?JcC<$JcC<$YQ'+~> +JcC<$JcC<$JcC<$jo:GAp&4O\fDG4 +JcC<$JcC<$JcC<$jo:GAp&4O\fDG4 +JcC<$JcC<$JcC<$jo:GAp&4O\fDG4 +JcC<$JcC<$JcC<$kl6bDpAO^_bkq)2o_m)7i;MC/JcC<$JcC<$ZN#F~> +JcC<$JcC<$JcC<$kl6bDpAO^_bkq)2o_m)7i;MC/JcC<$JcC<$ZN#F~> +JcC<$JcC<$JcC<$kl6bDpAO^_bkq)2o_m)7i;MC/JcC<$JcC<$ZN#F~> +JcC<$JcC<$JcC<$l2QqGp&4X_`r#H,o_mD@eG\5&JcC<$JcC<$[Jta~> +JcC<$JcC<$JcC<$l2QqGp&4X_`r#H,o_mD@eG\5&JcC<$JcC<$[Jta~> +JcC<$JcC<$JcC<$l2QqGp&4X_`r#H,o_mD@eG\5&JcC<$JcC<$[Jta~> +JcC<$JcC<$JcC<$li3.Ip&4X__>Es(o)7YK`r4ipJcC<$JcC<$\,Us~> +JcC<$JcC<$JcC<$li3.Ip&4X__>Es(o)7YK`r4ipJcC<$JcC<$\,Us~> +JcC<$JcC<$JcC<$li3.Ip&4X__>Es(o)7YK`r4ipJcC<$JcC<$\,Us~> +JcC<$JcC<$JcC<$mJi@KpAOa`l20fCkkk,PnGVeSjSeTGli#iBJcC<$JcC<$\c70~> +JcC<$JcC<$JcC<$mJi@KpAOa`l20fCkkk,PnGVeSjSeTGli#iBJcC<$JcC<$\c70~> +JcC<$JcC<$JcC<$mJi@KpAOa`l20fCkkk,PnGVeSjSeTGli#iBJcC<$JcC<$\c70~> +JcC<$JcC<$JcC<$n,JXOp&4[`m/,W8m/-PTbPgAsnGVGIJcC<$JcC<$])R9~> +JcC<$JcC<$JcC<$n,JXOp&4[`m/,W8m/-PTbPgAsnGVGIJcC<$JcC<$])R9~> +JcC<$JcC<$JcC<$n,JXOp&4[`m/,W8m/-PTbPgAsnGVGIJcC<$JcC<$])R9~> +JcC<$JcC<$JcC<$nc+mRp&4X_n,)\PnbMbPmec\Tg&9=roDReMJcC<$JcC<$]`3K~> +JcC<$JcC<$JcC<$nc+mRp&4X_n,)\PnbMbPmec\Tg&9=roDReMJcC<$JcC<$]`3K~> +JcC<$JcC<$JcC<$nc+mRp&4X_n,)\PnbMbPmec\Tg&9=roDReMJcC<$JcC<$]`3K~> +JcC<$JcC<$JcC<$oDdGAi;Md:nbr7\n,)kUi;**CmecYSjSd-so_mtPJcC<$JcC<$^&NT~> +JcC<$JcC<$JcC<$oDdGAi;Md:nbr7\n,)kUi;**CmecYSjSd-so_mtPJcC<$JcC<$^&NT~> +JcC<$JcC<$JcC<$oDdGAi;Md:nbr7\n,)kUi;**CmecYSjSd-so_mtPJcC<$JcC<$^&NT~> +JcC<$JcC<$JcC<$p&EhHd/ES8meunXnb`(Wo(i"SnbMtVn,)VPp&4+PiVW3DpAO1RJcC<$JcC<$ +^]/f~> +JcC<$JcC<$JcC<$p&EhHd/ES8meunXnb`(Wo(i"SnbMtVn,)VPp&4+PiVW3DpAO1RJcC<$JcC<$ +^]/f~> +JcC<$JcC<$JcC<$p&EhHd/ES8meunXnb`(Wo(i"SnbMtVn,)VPp&4+PiVW3DpAO1RJcC<$JcC<$ +^]/f~> +JcC<$JcC<$JcC<$pAa%LY5S+m!W/qhqt^*_q;_8Dq>'mUqpkVoqt9m\rTO63s+13$s+13ds*t~> +JcC<$JcC<$JcC<$pAa%LY5S+m!W.oKqt^*_q;_8Dq>'mUqpkVoqt9m\rTO63s+13$s+13ds*t~> +JcC<$JcC<$JcC<$pAa%LY5S+m!W,siqt^*_q;_8Dq>'mUqpkVoqt9m\rTO63s+13$s+13ds*t~> +JcC<$JcC<$JcC<$pAa+NYl4:nrVQW.p\Xg`q"`S;q"aa^mebr?bPV#2p\j@UJcC<$JcC<$_>f#~> +JcC<$JcC<$JcC<$pAa+NYl4:nrVQVWp\Xg`q"`S;q"aa^mebr?bPV#2p\j@UJcC<$JcC<$_>f#~> +JcC<$JcC<$JcC<$pAa+NYl4:nrVQUrp\Xg`q"`S;q"aa^mebr?bPV#2p\j@UJcC<$JcC<$_>f#~> +JcC<$JcC<$JcC<$q#BCRmeu2Dir/NIqYU9*qtp6dq>&D4q>'j_lhg/K^AI[&p\j@UJcC<$JcC<$ +`;b>~> +JcC<$JcC<$JcC<$q#BCRmeu2Dir/NIqYU8Sqtp6dq>&D4q>'j_lhg/K^AI[&p\j@UJcC<$JcC<$ +`;b>~> +JcC<$JcC<$JcC<$q#BCRmeu2Dir/NIqYU7nqtp6dq>&D4q>'j_lhg/K^AI[&p\j@UJcC<$JcC<$ +`;b>~> +JcC<$JcC<$JcC<$qu>dWnboflp\OrjrOr7.qYL'ameH8FmJ-MQqYHKSq#'pclMcA7JcC<$JcE^h +J,~> +JcC<$JcC<$JcC<$qu>dWnboflp\OrLrK7-WqYL'ameH8FmJ-MQqYHKSq#'pclMcA7JcC<$JcE^h +J,~> +JcC<$JcC<$JcC<$qu>dWnboflp\OqkrE'$rqYL'ameH8FmJ-MQqYHKSq#'pclMcA7JcC<$JcE^h +J,~> +JcC<$JcC<$JcC<$rVu!YoDPrlp%ncj]`#P@qYU*XpuD, +JcC<$JcC<$JcC<$rVu!YoDPrlp%n`Jr/pmQqt]aVj7i'KUXJcC<$JcC<$ +`rCP~> +JcC<$JcC<$JcC<$rVu!YoDPrlp&"Vfqtg3cnG)& +JcC<$JcC<$JcC<$rr;-[o_n1Tm/,T9nG<9g]Y+6W!P\F,q=OIVpZhJHp[\+Uq>'m9qq:i6qt^0c +rTjH6s+13$s+13js*t~> +JcC<$JcC<$JcC<$rr;-[o_n1Tm/,T9nG<6FOSk4@qYL$[q"OOJp@n=Pq"jg^qU>>pqX47Vr;$ +JcC<$JcC<$JcC<$rr;-[o_n1Tm/,T9nG<5h>pqX47Vr;$ +JcC<$JcC<$JcC<$!<;6]pAOU\e,/\5lMCVYXT#m3]`>eFq=OIXpYY]?p[e1Vq>'m]qZ+\"qsXCM +q=FIPqt^0crTsN7s+13$s+13ks*t~> +JcC<$JcC<$JcC<$!<;6]pAOU\e,/\5lMCYZN0*q!rV?*\q=ie?q=jLUqYBs`p\OrUkPO`En+lSO +nGE%Zq>K[ZJcC<$JcC<$aT$b~> +JcC<$JcC<$JcC<$!<;6]pAOU\e,/\5lMCYZ=]YE$rV?*\q=ie?q=jLUqYBs`p\OqmkPO`En+lSO +nGE%Zq>K[ZJcC<$JcC<$aT$b~> +JcC<$JcC<$JcC<$kl1;Sp&(lfrqcYrrOi0Ds1\1$qY0aXl1OfEqY0XWqYBj]rVQW8n,)YOhtd!B +nb`1\q>K[ZJcC<$JcC<$b5Zt~> +JcC<$JcC<$JcC<$kl1;Sp&(lfrqcYRs,d,?p%\CXp\*kEp\+IXo_A:YpA4abs-<'MnbV/=pA4=V +qY^0fm/DS9JcC<$JcEmmJ,~> +JcC<$JcC<$JcC<$kl1;Sp&(lfrqcXt!EW>!=7u@bp\4CGp%S1Vp[n7Wq=a[`qu9deqsjO?q=a[T +qtg6drTsN7s+13$s+13ms*t~> +JcC<$JcC<$JcC?%l2LDTpACugqtg>nrOi-Cs1\=(qtKs\g\(F:qY0XWq>'g^!3?+>kPFZCoD%nP +q>0[Zqu$9gli)J8JcC<$JcEsoJ,~> +JcC<$JcC<$JcC?%l2LDTpACugqtg>OrfI#>q=sj]qY&\:qY'd[o_A7Xq"auOrfu[Cn+lSMo(i+X +o)&=^q>KXYJcC<$JcC<$bl<1~> +JcC<$JcC<$JcC?%l2LDTpACugqtg=qpfI:dqtKs\g\(F:qY0XWq>'g^!*T;'kPFZCoD%nPq>0[Z +qu$9gli)J8JcC<$JcEsoJ,~> +JcC<$JcC<$JcCE'l2LGUp\_)hq>1-es/H(2rOi0DrkA@+r:g']de3M2qtKaXq"aja!36% +JcC<$JcC<$JcCE'l2LGUp\_)hq>1-es,-lrV6 +JcC<$JcC<$JcCE'l2LGUp\_)hq>1-es&o2"!a&N*rV6 +JcC<$JcC<$JcCH(l2LJVq#'"G!;b(>q"jpas/Q+2rk/-AqtL$^nb)2>o(DnRqtKaXp\=lja2e.u +q"jOVeG/k8qYKj]qY^3gl2H86JcC<$JcF0uJ,~> +JcC<$JcC<$JcCH(l2LJVq#'"G!;b(>q"jpas,?u=rfI#>qtL$^nb)2>o(DnRqtKaXp\=fMqj$sQ +nbL]0q>'m`o_\L_qYf[XJcC<$JcC<$df4g~> +JcC<$JcC<$JcCH(l2LJVq#'"G!;b(>q"jpas'#5"!a&N*qtL$^nb)2>o(DnRqtKaXp\=emqcNXi +nbL]0q>'m`o_\L_qYf[XJcC<$JcC<$df4g~> +JcC<$JcC<$JcCK)lMgVXq#'ITh"p=5pA4U\ri5t0rk/3C!kuABqtB^Up[n"Ip@S%NqtBp]o(`1Z +!ij;]r5S:&aS>W-qtfs^qu$ +JcC<$JcC<$JcCK)lMgVXq#'ITh"p=5pA4U\rf$i;rK.#@!g8]?qtB^Up[n"Ip@S%NqtBp]o(`1Z +!0?uAnbL9$qYC$bo_\O`qYfRUJcC<$JcC<$f)L7~> +JcC<$JcC<$JcCK)lMgVXq#'ITh"p=5pA4U\r`],!r`B2&p\X[Wp%S+KoChhLp&"I[p[\+Xq#FUp +=Rl4.q"jg`qXj[^r;-BSrdk*#s+13$s474#~> +JcC<$JcC<$JcCN*li-\Xq>B[X\GH$srqQJmr4;sAqRun%p@\:Siq*$=p@\=VqtK[Vs/Q(=rPn[/ +j7r$9meH\Tqtg!_qu$9gir4N/JcC<$JcFR+J,~> +JcC<$JcC<$JcCN*li-\Xq>B[X\GH$srqQJOr/^i=r/q!Pp@\:Siq*$=p@\=VqtK[Vs,[#Aq>'(G +mJ$&Dqt^-cp&"Xaq>K=PJcC<$JcC<$h>`!~> +JcC<$JcC<$JcCN*li-\Xq>B[X\GH$srqQIrpfIGs!*B0np@\:Siq*$=p@\=VqtK[Vs&f>'qcN[i +j7r$9meH\Tqtg!_qu$9gir4N/JcC<$JcFR+J,~> +JcC<$JcC<$JcCW-lMgVXq>BaZo_RSCjne`IqY:&i!5/6A!5/0Aq"=OVqX`n@q=FLUp@\=VqtKgZ +s/Q+>!QN1Y`o[!Op[\+Vq>C*_qtg6erS@I(s+13$s+141s*t~> +JcC<$JcC<$JcCW-lMgVXq>BaZo_RSCjne`IqY:&K!0I,>rfI)@!0[-Mqt0aVkOSH?qt0UTqtBp] +pA"ZKs-3SKr0?C=h=pL8qt^0dpA=^aqYf7LJcC<$JcC<$j8XW~> +JcC<$JcC<$JcCW-lMgVXq>BaZo_RSCjne`IqY:%n!*K%ur)iaeqt0aVkOSH?qt0UTqtBp]pA"Yj +r`B#"jnR[+o(`+Xr;--aqY^3gh>W!*JcC<$JcFd1J,~> +JcC<$JcC<$JcCZ.lMgVXqY]m\p\N84q>0[Xq"XfeqRZa?qRuh"r:KmXh"(@6qt0XUqtBm\qtU/j +s2Y/Zs2FuWmJ->Jkk=cFp%\F[r;--aqu$9gg\ud(JcC<$JcFp5J,~> +JcC<$JcC<$JcCZ.lMgVXqY]m\p\N84q>0[Xq"XfGs,d,=s,d2A!0[9Qr:KmXh"(@6qt0XUqtBm\ +qtU/Os-K(IJcC<$JcC<$kPp&~> +JcC<$JcC<$JcCZ.lMgVXqY]m\p\N84q>0[Xq"Xejs&f(ur)imir:KmXh"(@6qt0XUqtBm\qtU.n +qcEc!mJ->Jkk=cFp%\F[r;--aqu$9gg\ud(JcC<$JcFp5J,~> +JcC<$JcC<$JcCZ.m/HhZqY]s^q"jXYk4ms3o(W3`rhoS(s1J6Br:KmXnac;AnacSKr:KaVqtBgZ +s/Q%JtFJcC<$JcC<$m/MS~> +JcC<$JcC<$JcCZ.m/HhZqY]s^q"jXYk4ms3o(`0A!g/S+qi:`=rK7,Cr:KmXnac;AnacSKr:KaV +qtBgZs,d2Er075HpA"=Tnb2\LoCi%TpA"R]r;--aqu$9gf`$I%JcC<$JcG*:J,~> +JcC<$JcC<$JcCZ.m/HhZqY]s^q"jXYk4ms3o(`/dr`K"uqcNdgqt'@KoC;AAqt'aXp\"FWq"Oel +pfIJtpA"=Tnb2\LoCi%TpA"R]r;--aqu$9gf`$I%JcC<$JcG*:J,~> +JcC<$JcC<$JcC]/li-bZqY^!_q>0j]eG/b5m.gVTrMTJ'rk/-A!;-3\p%%26o^_qOr:KaVqY'm^ +ri5q;s2OuU!64R'p%IJ>q"FUZpA"R]r;--aqu$ +JcC<$JcC<$JcC]/li-bZqY^!_q>0j]eG/b5m.gVTrJLc@Ocbb&NrY:?OoLREo_e=Ro&T?5o)/+W +o_8%TpAOabOStI@PQ7!=p\"7@p%\7Xp\+C[q>C*_qtp +JcC<$JcC<$JcC]/li-bZqY^!_q>0j]eG/b5m.gVTr)s#$qH*Pr!;-3\p%%26o^_qOr:KaVqY'm^ +r`]"s!*Jdcp%IJ>q"FUZpA"R]r;--aqu$ +JcC<$JcC<$JcCc1li-bZqY^!_qYL$`ZhXIms/,dnpq-OJ;3JcC<$JcCB&J,~> +JcC<$JcC<$JcCc1li-bZqY^!_qYL$`ZhXImr/CZ=s,d;Cqi:`=rfR2Cs7?!UqXNe=qXO:Mr:BjY +p@\:U!frG)r0@)Bq=jRUfCf"6qtKj[rV?BfpA=abq>J;3JcC<$JcCB&J,~> +JcC<$JcC<$JcCc1li-bZqY^!_qYL$`ZhXImqHC*_qtp +JcC<$JcC<$JcCi3li-bZqY^$`qYL'aZhXCks7ZAes18'=rOi!?qss[TqXEe=q=+=Pp[\7Rr:K[T +!;?Ajr5\fVqo/:&kOnWBmIgAMr:g!]rV?Bfp\Xgbq>J#+JcC<$JcC`0J,~> +JcC<$JcC<$JcCi3li-bZqY^$`qYL'aZhXCks7ZAKrK72DOSb(=OT(C@P5FhJnbVb?n+lJNnb;VP +oDJ7Ro`4^aO8P:C*`qtg6drOr2]s+13$s,I&/~> +JcC<$JcC<$JcCi3li-bZqY^$`qYL'aZhXCks7Z=lr`T8'qcESqqss[TqXEe=q=+=Pp[\7Rr:K[T +!;?@o!*Jkpp@d\Bq"3tHqtBs^q"Xg`r;-0bqY^0f^&ET_JcC<$NW4M~> +JcC<$JcC<$JcCu7l2LMWqu$9e"0''4qtp6dqpZ;2Fp\X[^V>e(&]DT>=]`@X$nbhn5n,)VP +nbD\QoDJ7Tp&1lea8a0V`;mpBp#>W9p&+O]p\=O^q>C*`qtp +JcC<$JcC<$JcCu7l2LMWqu$9e",r?=qtp6dqpZ;2Fp\X[^MYrV +JcC<$JcC<$JcCu7l2LMWqu$9e"'AY%qtp6dqpZ;2Fp\X[] +JcC<$JcC<$JcD,;k5P5Uqu$3c!iWlKr;- +JcC<$JcC<$JcD,;k5P5Uqu$3c!fW5&r;-Gq31lEnFcJHmIU)Ep@\@WrV-*^rV?Bfp\Xjcq#.i(JcC<$JcCr6 +J,~> +JcC<$JcC<$JcD,;k5P5Uqu$3cs&]8&r;- +JcC<$JcC<$JcD8?jSnuRqu$0b!3#n3!P\F.q=OIVpYPW2p\4CXp&(TdV7HK7qn)g>qn3"!p[@nF +o^2GAp@%qKrUKXQr:BgXs/>ssrPnoXrl>&YqS`HSq=XLSo(2VHp%/%Pp\"LYrV-*^rV?Egp\Xgb +q#.f'JcC<$JcD&9J,~> +JcC<$JcC<$JcD8?jSnuRqu$0b!0$o=!K[*Tq=OIVpYPW2p\4CXp%sXHOo1@BOo1:=OSb1@nFuDH +me#oAme6,InGVnOo)/+Vo`'sOO8Y=AQ2$RDQ21+Io^_VJo(DVNo_8%WpAOa\q#1$eqY0m`r:p6% +rdk*#s+139s*t~> +JcC<$JcC<$JcD8?jSnuRqu$0br`B5'=Shsko_A1ThY-@2p\+IVqc=#)='&L+=]nl)=8,esnFuDH +me#oAme6,InGVnOo)/+Vo`&%n=moGfp%S+LoCqhKoD8+Rp&4U_p\=O^q>L0aqtg6crOVuZs+13$ +s-E\8~> +JcC<$JcC<$JcDGDi;WTOqu$0bs7u_nrk8EJ^Ads%q"a[Vp@.b2p@\+UV#Rt+]"@mOr4Dp?qn;mq +r9j:Gq<[hBqsO7JrUBaTq""=R!;-8gs/>q:s2Y#Vqo/TTp[n4OiUZj:qt0[VrV$3aqY:!arVH9c +qY^*d\c.0[JcC<$Rf@m~> +JcC<$JcC<$JcDGDi;WTOqu$0bs7u_SrK%#?rqZ9_q=jOTnFbW2p%A3>rK7&A!0I,>rK%#Ar0$sG +r9j:Gq<[hBqsO7JrUBaTq""=R!;-2Lr07/Fq3:oEp[n4OiUZj:qt0[VrV$3aqY:!arVH9cqY^*d +\c.0[JcC<$Rf@m~> +JcC<$JcC<$JcDGDi;WTOqu$0bs8)[r!EWD&q=aUZp[n1Kp"f?7p%h_p=BAR+=BSd/r)`VpqsXIN +p?h\Bp?hbFq!\1Nr:0RQqssg[r)iAgp[n4OiUZj:qt0[VrV$3aqY:!arVH9cqY^*d\c.0[JcC<$ +Rf@m~> +JcC<$JcC<$JcDVIh>[6Kqu$0brqcYmr4_n"qtKmZeb/h5m.CGPUnmpbrji$?rOVs>rOi!?!:TmS +qX*G3qsF=Lq!\1NrUKUP!VC*`qtg6` +rOVuZs+13$s.01?~> +JcC<$JcC<$JcDVIh>[6Kqu$0brqcYRrfI/@pA"OZq"E82qtBCL!;-,Fr/h,FOcklhrK$o=s,m5B +!:TmSqX*G3qsF=Lq!\1NrUKUP!;$2Lrf6o@rK[/Bs-3TVp@Hi*qt'aXq=X^[rqH6`rV?Bfp\Xgb +p&2K$JcC<$JcD;@J,~> +JcC<$JcC<$JcDVIh>[6Kqu$0brqcInpA"OZq"E82qtBCL!;-%f!*K5%"'A]/=T)=p=9.ggmeZ>5 +m/-2JmeH8LnGVnNnc8:\=9D].=B=ik!;-!VeaiV/r:KgXrV$6bq=spar;-0bqY^$b])I9\JcC<$ +Sc=3~> +JcC<$JcC<$JcDbMgA^sIqu$0brV?TkVl0F+qtU'_qY%Glr:L#br2'D'!4r0Ar4;m>rOi!?r9`5) +r9aINq="7NrUK^S!iDfjrh]_7`VIOL`W!mWoBc&5nauDMoDS=Wp&4U`p\FU_q>L0`qtg6^rO`&[ +s+13$s.KCB~> +JcC<$JcC<$JcDbMgA^sIqu$0brV?TkN/[atrf?sOqtKs\\FodlqMP<7qiLrCOc]O&rK.#@rK@*G +g?eb)rU0LMr:'[Tq=4THN/[aqqiq&Eq3:lDs7>UJlLFN;r:BmZq=X^[rqH6`rV?EgpA=^aoDQ<# +JcC<$JcDDCJ,~> +JcC<$JcC<$JcDbMgA^sIqu$0brV?Niq,mOhqtKs\\FodlqH*\t!EWD&L0`qtg6^rO`&[s+13$ +s.KCB~> +JcC<$JcC<$JcE"Tec,FDqY^*br;-Hhs/5_-rqQEcqtB@Kp@R,4q=O[Xrh]Ogrj`$?rk&$L0` +qtU*ZrP/>_s+13$s.]OD~> +JcC<$JcC<$JcE"Tec,FDqY^*br;-Hhs,?r=rK$sQr:g*^lh0uDg\(C7rq$,Hr/(E7r/h&DOc]R' +rK-u?rK?pAkNhj.rU'ROq!\1Nr:0dWqi(K +JcC<$JcC<$JcE"Tec,FDqY^*br;-Hhs&f;&r)isnr:g*^lh0uDg\(C7rq$+jqc3c"=BPQ(#?Y,2 +=B8I(=8Z2#=8c7qm-!^.m/?>MmeH8LnGMhUo)Dhl=oVV(L0`qtU*ZrP/>_s+13$s.]OD~> +JcC<$JcC<$JcE=]c2RSl&~> +JcC<$JcC<$JcE=]c2RSMmeQ>LnGVnSMu].>Pl6mBPl?sGo(_bJnFc8DnGDbNo)81Zo_S7Z +pAXg^q#1$eqY'g\r9F7#rdk*#s+13Hs*t~> +JcC<$JcC<$JcE=]c2RS,=]ed, +<``B#=T;J$=T.U`lfm^2lhKiFmJZJKn,2\RnbuYi=TVW(L0`qtL$RrPnhfs+13$s/#aG~> +JcC<$JcC<$JcELbbPq>9qu$0brVHHf!r/[krP& +JcC<$JcC<$JcELbbPq>9qu$0brVHHf!r._5rK-r +JcC<$JcC<$JcELbbPq>9qu$0brVHHf!r,l"q,[T!p\aaXp%\1?oBPuCoDJ1W=8u>$=8l5%='/T( +=8c8$#=T7X`lKRR1lMTuCm/?>MmeH8MnG68b +JcC<$JcC<$JcEai`r>f4qY^*br;-BfrqQJjrkA +JcC<$JcC<$JcEai`r>f4qY^*br;-BfrqQJOrfI# +JcC<$JcC<$JcEai`r>f4qY^*br;-BfrqQIppfILhp@\:Sp%.bFht-R4q,dJp!`rK+r`B&#r`9&# +r`K,#s&]8&rp&A)r9F7Hq<\(IrU0ILqH3Vps&SVjqXE&(r:'[Tq==OVrUg![rq? +JcC<$JcC<$JcEso_Z'?/qu$3cr;-Bfr:p8hrkA3AqXsaXqX_Dk!:ff[!kGhNrODp>rO`!=rjr0C +pq?LflKIs+rTa@Iq<\(IrU0XQrMTUkqo&HP!64TKnF,Q.p@%qKrpfjUrq$*\qt9s^rqH6`rV?Bf +o_\.Uh>Q..JcC<$JcDeNJ,~> +JcC<$JcC<$JcEso_Z'?/qu$3cr;-Bfr:p8MrfI#Q..JcC<$JcDeNJ,~> +JcC<$JcC<$JcEso_Z'?/qu$3cr;-Bfr:p7np/h+`qt0aV^%)0np/h5o!*B/%r`B)$"'8K'Q..JcC<$JcDeNJ,~> +JcC<$JcC<$JcF*s_#F--qY^*brVHHfqtU/f!kl=^pq?\"r:KmX^%2'j!2]Xir1j;&s1&$!5/*?!9sFFki_j,q<@kCrTj:GrU'ROqPOA4_u%C>`VT&tmcs39me?2LnGVnSo)A7[o_S7[ +pAXg_q#'scqXXOIr8dh7rdk*#s+13Os*t~> +JcC<$JcC<$JcF*s_#F--qY^*brVHHfqtU/L!frG)qiC`:rq63]qt%MlqsjE;p5o<:q2kE7s,mBH +r93A-qrmk?rTa@Iq<\(IrU0N@!LB#CPl?sFPl6mDn+Z88mJ?8Fn,DhTnb_nVoD\CYp&=[ap\O[_ +q>C*[qrmt=rS[[+s+13$s/c6N~> +JcC<$JcC<$JcF*s_#F--qY^*brVHHfqtT_`rq63]qt%MlqsaYfpf@Dsr`0##r`K/$r`B8(MmeU#d='#2us&SSiqX=1HlL"H9p[A+NrUKdUrq$-]qXsj] +rqH9ar;$9eo)%YKjSe$9JcC<$JcDhOJ,~> +JcC<$JcC<$JcF7"^Adp+qY^*br;-BfqY:#cs1SHHpq?\!r:BLMj72R.p[S1NpS7_us1&$C*Yqqq> +JcC<$JcC<$JcF7"^Adp+qY^*br;-BfqY:#Js,[2AqiC`:rq--[o((i2mdg,Br:'H;oT0'8qN1K7 +s-!GqX4.GlKnB7r9jCLrp]pWqssaXrq-*\ +rV$6bqY:!ar;,p[hu)j>ir4N/JcC<$YQ'+~> +JcC<$JcC<$JcF7"^Adp+qY^*br;-BfqY1%kr`/Slrq--[o((i2mdg,Br:'G]r`K/#!*B/%r`B)$ +"'8K&rCJcC<$JcDqRJ,~> +JcC<$JcC<$JcF=$^]*s*qY^*brVHKgq=jsarM9LioY(4pp%%kIm-s3.q!e:Op7qVtrj_p;!4r-@ +r4;p?rk/'?o]H#3o&fl5rTO+BrTa@Iqs= +JcC<$JcC<$JcF=$^]*s*qY^*brVHKgq=jsarJU`7plGB6rU]^Qp[RV>kOJ?:rpTQ;l]Ck'!0[!: +qW7;1r9+%BqW[tDrTj@Is,-Z2s-EYLop#?=s-3GHqsE/)r9aINqX=CPrpfmVs7?6^qt9s^rV-0` +r;$9elhfW +JcC<$JcC<$JcF=$^]*s*qY^*brVHKgq=k$cC*Tqr%D@rT!m.s+13$s0;TS~> +JcC<$JcC<$JcFC&_>a-+q>C!ar;-BfqY:'a!2]Xirk/\G`r<])B5A]"@sQ!5&3Bq7ZgjpuV;3puV84rTF1Dq<@kCrTjLMs.oLf!lMspqSN +JcC<$JcC<$JcFC&_>a-+q>C!ar;-BfqY:'a!0$l7rf7&>r/^c9p[\4Oo^MPBi:-L0r/(<,s,[5A +mZ@.)!g;^.puV;3puV84rTF1Dq<@kCrTjLMs,-Z2!gK":rg!2Aq3:rEr0?j>mHaE2rU'UPqX=FQ +rpfpWrq$-]qt9s^rqH6`r;$6dj87s9oDRbLJcC<$JcE%UJ,~> +JcC<$JcC<$JcFC&_>a-+q>C!ar;-BfqY:'ar)WDjp[\4Oo^MPBi:-L0p/_2q"]nf-<`W<#=T2D$ +=9DT( +JcC<$JcC<$JcFI(_uB9+q>Bs`rVHKgqY:$`!;?>drOi3DrOr0Bs1S@$qsjOP_X@KmoqMGr!P#]= +\Gj&=])K;F]">Pb]=\$Sq7Qdiq;h80q;hG7q<%Y=roj1BrTXCKpnS%h_o'F2q8<*Kq8E0Lr9X4E +mcsW6q!@tHrpK[Prp]pWr:9jYrq-*\rq??cq=sm`qtetBmel_Uk5Kr3JcC<$Zi>O~> +JcC<$JcC<$JcFI(_uB9+q>Bs`rVHKgqY:$`!VVHMMZ8_:NrY4=O8Ft8o)%tRnA=VomeVb;L]3A8 +O84k;O8"b/OT=M=jS%X0jSS'7k5FKBkkXKAl2^/FM?Jj%Pa7X7Q1gI6Q2L"DlgF'6lhKiFmJcPN +n,DhUnbhtWoD\CZp&=[ap\FU^q>:$@qsOCSrT=*1s+13$s0M`U~> +JcC<$JcC<$JcFI(_uB9+q>Bs`rVHKgqY:$`!;?=knlPb[qsjOP_X@Kmoi:un"]nf-<`W<"=T;J% +=9DW)<`\lp!9O%;p>bu0qrRY9rTF1Dq<@kC!:0D\#$4f)='&F'qc3Ys!*B/%oiM/or9X4EmcsW6 +q!@tHrpK[Prp]pWr:9jYrq-*\rq??cq=sm`qtetBmel_Uk5Kr3JcC<$Zi>O~> +JcC<$JcC<$JcFO*`r>K+q>Bs`r;-BfqY:'arq?8c!5/ +rODj;s18-?s1/3Br4Mj=jl?:"rT3k;roa7Dq<7qFV>6qc_uI[O_uI[O`V[UN`Vo,slL4!6lMKoD +m/?>NmelPQnG_tUo)A7[o_eC\pAXg^q"sm`qUPK6r:U$Mrdk*#s+13Ys*t~> +JcC<$JcC<$JcFO*`r>K+q>Bs`r;-BfqY:'arq?8Irf.&@NfO+"qi1]:o)/%UnA=Yjmeqq:LAm;7 +O84n;O84n0OlbX$jSe39k5OQBkkXHClM-88PQ@&8rK[/Bns01>pZh53qWdtDqX"1JrpK^Qrp]pW +r:9jYrq--]rV$6bq=sj_qYJb>o)/1Zjo0i2JcC<$[f:j~> +JcC<$JcC<$JcFO*`r>K+q>Bs`r;-BfqY:'arq?@mr`9)#nlGh^r:0^S_XI?hoi:uns&T>*=&r@' +r)iu#r`B5'<`\iojl?:"rT3k;roa7Dq<7nEpf@Dos&B/%=&rB""lhB]5l2']B +lh]uHmJcPOn,DhUnbhtWoD\C[p&4U`p\FU]q>0s +JcC<$JcC<$JcFU,c2R#,q#'j_r;-BfqY:'arUp6ar1j;)rk8?Erk80@!:g!Vp$^#jqsF'NrOMd7 +rji'?r4E!?!5&3Bpq?XdnDa-$rT*t>q<%\>rTO4Eq5++e!6"lSs2=lR!6"lSs2=`PrP\QOs6AG) +r9F7HqX"4KrpK^Qrp]sXqssdYrq-*\rq? +JcC<$JcC<$JcFU,c2R#,q#'j_r;-BfqY:'arUp6ar/(H5r/Uc;qi1]:nbhnLn&b"pmIc54OT1C: +O8t@ +JcC<$JcC<$JcFU,c2R#,q#'j_r;-BfqY:'arUp6ar)`o!nlGh]r:'CJamT&noi:rmr`B)"!*B)# +!*B,$!`rE'oN2"OnDa-$rT*t>q<%\>rTO4EpK%8m!*/tuqc3Yss&]5&oN2&ns6AG)r9F7HqX"4K +rpK^Qrp]sXqssdYrq-*\rq? +JcC<$JcC<$JcFX-e,JP/pAFU\rVHKgq=ss`rq??aqkO2(s1SBD!583@!5&!oq6roNt +JcC<$JcC<$JcFX-e,JP/pAFU\rVHKgq=ss`rq??as,$]1s,Ho9!0@#;s,@#=p[@qGh6roNt +JcC<$JcC<$JcFX-e,JP/pAFU\rVHKgq=ss`rq??as&](unQ5JRqq<%\>roj&Vr`&ntrDreqs&T/$s&eqqr`8dXm-+0-rTa@I +qs==Ls6fgRrp]pWr:9mZ!`\gaqt9s^rV-*^qYBj]eGJt;p\j=TJcC<$JcE7[J,~> +JcC<$JcC<$JcF^/f`(%3o_e=XrVHHfqY:'arq?9_qkX5(s1S*nO5_u@UR_Z7XS_uI[L`W*mT`W!gOkj.F. +kkXKBlM^&Hm/HDPmelPQnGi%VncJF3e,K":p&=[`p\4IYq="18qtBs_rTX<4s+13$s1//[~> +JcC<$JcC<$JcF^/f`(%3o_e=XrVHHfqY:'arq?9_qhb<3ooB!1r9sROq!I&,qsEhq<%_?p58m8rKR>I!1*SKr0.2HrfmDIrg*>Eq<7/-qWRb> +rp'IJr9XFMs6fgRrp]sXr:0p\S=KTNqt9s^rV-']q>'LUh#$gCq#0IVJcC<$JcE:\J,~> +JcC<$JcC<$JcF^/f`(%3o_e=XrVHHfqY:'arq?9_pf?odr9sROq!I&,qsEhrp'IJr9XFMs6fgRrp]sXr:0p\<)ikhqt9s^rV-']q>'LUh#$gCq#0IVJcC<$JcE:\J,~> +JcC<$JcC<$JcFa0h#?C5o)/.Wr;-BfqY:$`rq?9_rM9Ffpq-U=r4E0E]Xteer9jLM`U*QhqP*h[ +qmlO4rODp>qRc^=pV$@[s53A)r8IV6qW%S9rT4"?s.oCc!li3urPSWQrkncSs2+iTn\tIFqrd5+ +qrdqAqW\"Erp0LKrpBaRr9sXSs7-*Z"M3(2oCMtRqt9s^rV-$\p\F%LjSS`Mq#0IVJcC<$JcE@^ +J,~> +JcC<$JcC<$JcFa0h#?C5o)/.Wr;-BfqY:$`rq?9_rJCN0r/LH2r/LXBr9_JirTj<7qM"g.rJpu@ +Oo1=>O8G%2Ondl7hsoY&iVhd4j8S-)o,Q2QsIPlR-JQ2[$JQ2d*IQ2HsEQ2Bb/k54?? +kkaQClMg,Im/HDPmelPQnGi%XncY;LSFc@Oo_\=\pAOaZq"OUJqW.PKr:p6Trdk*#s+13^s*t~> +JcC<$JcC<$JcFa0h#?C5o)/.Wr;-BfqY:$`rq?9_r`/_onlPbWr9_JirTj;[qGd>or`B)"!*B&" +!*B)#!*8\mpu)20n_j?(rSm\6roF%>rT=,[qc +JcC<$JcC<$JcFj3i;Vprk.s +JcC<$JcC<$JcFj3i;Vp+r.t3/pl>93rU'1Bjm2[-p$;SA!/:9( +qh=m.rJpu@Oo1==O8"b3OoO>2hYH((i;V^6iqh^7jSe3?M>)o+Q2QsIPlR-JQ2[$JQ2d*IQ2?mE +Q/:[%kPaWAl2KuIlhp,LmJlVPn,MnVnGnpSSGr-[o_S7[pAF[Wq!n1EqWn%Rr;$ +JcC<$JcC<$JcFj3i;Vpl@Y$oDeIZp&=[_p[n7Nq<@bAqtU*brTX<4s+13$s1SG_~> +JcC<$JcC<$JcFm4iVr3BlMU,Jr;-?eqY:'arq?6^rq-#]pq6X=rOi*@s17skq!7)-q!7VeOppg=6s18*>rk.sKUXJcC<$JcEIaJ,~> +JcC<$JcC<$JcFm4iVr3BlMU,Jr;-?eqY:'arq?6^rq-,Ere^K2q2Y?3p[%\@k3Da-p$2J>o7d+( +!frG)rK$u@r/gf:n +JcC<$JcC<$JcFm4iVr3BlMU,Jr;-?eqY:'arq?6^rq-+hr`AttnlPSPq!7)-q!7VC'elMcA7JcC<$ +^Ai]~> +JcC<$JcC<$JcFs6ir8HGkksfEqtg9eq=ss`rq?6^rq$3^qkO1c!5&0A!5&6Crk&3CrO`*@!4i'p +r9O.CjQZU-n*0D:rj_s]_/u(h>H..htl:1iVhd7j85YNV>d7ja8O!Z`Pf^n +_u@RS_u%CC`Vd[IjS\'3jS\-8k5OQCkks]ElMp2Jm/QJQmelMT\^T%*dK&k;oD\CYp&4U^pZqV> +q=OOQqt^0crTjH6s+13$s1eSa~> +JcC<$JcC<$JcFs6ir8HGkksfEqtg9eq=ss`rq?6^rq$9`Lku"ds+pH0qi:N4rTsIJq!-r)r9Eb8 +nqHt&!KW??O8k@?OSY%.OR(a#hYl@.i;V^6ir.p7M>E)0QMQmHPlI$KQMZsIPl?pJPl?sDQMd$@ +jS\'3jS\-8k5OQCkks]ElMp2Jm/QJQmelMRQMR-Po)A7[o_S7ZpAF[Nq!.\IqXFCXr;$ +JcC<$JcC<$JcFs6ir8HGkksfEqtg9eq=ss`rq?6^rq$9`<`]0#pf?rerTsIJq!-r)r9Eb8nl5Kg +!EWD%=8u;'='/R-pK6ufleVKqrSRJ0ro*h8rT!cTq,[Gos&Atts&T/$!`i9"r`/u!r`9)%p/h/m +p#Q&2p>l/5q<%\>roj:Erp'OLr9XINs6fgR!*oA"!:p-\rq-'[rV$0`lhKc@o_S(Sq>C'eli)J8 +JcC<$^]/f~> +JcC<$JcC<$JcG!7jSn`KlMTlCqtg6dq=ss`rq?6^rq-3]q4[l#rk&0B!kZ+XrOW'BrO`*@s1/-p +qs);frTO9SoV)2ms1&0?\bEW4\H'5>]D]D8^$shOh>Q40htl:1iVhd0U][HhaN+4us2=lRrknfS +qo&'Er5@^Wr8dhp\OFWqY^0f +li)J8JcC<$_#Jo~> +JcC<$JcC<$JcG!7jSn`KlMTlCqtg6dq=ss`rq?6^rq-3]re^Q/pPo*2q2PC>qs);frTNg+qN(`= +OSk1>OoLLCO8b7$h"TY'hYuF/i;V^6ir"W0M>rG5QMHgGPlI$KQMZsIPl$a@QMd$0j8A!: +jnn3>kPj]Dl2KuJli$2LmJlVSn,J^LScA9[oD\CYp&+O\pZ2, +JcC<$JcC<$JcG!7jSn`KlMTlCqtg6dq=ss`rq?6^rq-3]r`B&!!*Aqro2kqWqs);frTNfOqH*c" +=T)>$r8dh< +qr[n@roj=Frp'OLrTsONs6fpUs',:us760\rq-'[r:^$^jS83>p\OFWqY^0fli)J8JcC<$_#Jo~> +JcC<$JcC<$JcG'9jo4lMmel)Aqtg6dq=sp_rq?6^s7H<^s76,_rLj8(])K>A]`5VD]_f>>])K8? +lLX8hkksWAT`:_\T_c/#\[]2\ppg:5!4r-@rk.m:pY,Gtr7q,(rndV2qr%M5rh]Ccs.oe=a2e+t +s2=lRrknfSr5A0Fr5AQonDa-$rT*t>qr[n@s60CFs6BXMrTsON"7E_1e+hAjo)A7[o_J1XpA+I= +q"=IYqXXO[r;-BXrdk*#s+13es*t~> +JcC<$JcC<$JcG'9jo4lMmel)Aqtg6dq=sp_rq?6^s7H<^s76,ErJ1'*rf6c5s6B4?e*-_mnV-e# +!frG)rK$u@s,[5ArfI#kPscDl2U&Kli$2Lm/l^AQM6sLo)A7[o_J1XpA+I=q"=IYqXXO[r;-BX +rdk*#s+13es*t~> +JcC<$JcC<$JcG'9jo4lMmel)Aqtg6dq=sp_rq?6^s7H<^s76+io2bHas6B4?e*-_mnPoq:ki&q;)&,rSRM1s5EWNs&T/$!*9"t!*&qts&T/$!*0"t!``9%nlP`irT!D, +p#H#3roO%>roa=Fr9=7Hs6KXMrp9dT>?gi$rpp'[rq-$Zr:]s\h>$[=q>0[ZqY^3gli)J8JcC<$ +_Z,,~> +JcC<$JcC<$JcG*:k5P#Onbh>Bq>1$bq=sp_rq?6^rq-6^rUTo\rLa.arjr-As1J?C"2)7W])K>? +])K5?\GPOdkg\emk4,)E\+mK5\bN]5\H'5>])oXY]_/r<]^FMPg\oq(h>Q40hu2L3V>$bfbK7fF +r5ScTrknKKo#:OF!93A(qr7G3roF(?r9""As60CFs6BXMrTjOOrj`$XpX9$2rq$-]q"=OXq"NV> +p\FX]o_\L_q>K[ZJcC<$JcEXfJ,~> +JcC<$JcC<$JcG*:k5P#Onbh>Bq>1$bq=sp_rq?6^rq-6^rUKrEreLH,!/L6,rf6`4qs!q?eE?_k +pkAR!!0?u"gATe)h"ok*hYuF2huSXjrJ:9+!go=?p6GZDo9K*: +r079Am,@j$q;_J8roO(?roa=Fr9=7Hs6KXM!:BcOp7;0Qrq$-]q"=OXq"NV>p\FX]o_\L_q>K[Z +JcC<$JcEXfJ,~> +JcC<$JcC<$JcG*:k5P#Onbh>Bq>1$bq=sp_rq?6^rq-6^rUTnfrDiMko2khRq<6>kqr[EJpfIT! +=BPQ(!`iB(oN:]d!*8OArS.;+qVD,,rnm\4s&AYkr`9)#r)Ebsp\FX]o_\L_q>K[ZJcC<$ +JcEXfJ,~> +JcC<$JcC<$JcG0]">TR]E,^Yot:@0s[ +qtg6erTsN7s+13$s2=qf~> +JcC<$JcC<$JcG0rfI#Mrg`oWrq$*\q"=LWo(V/=q>'m`o_\L_qYfd[JcC<$JcE[gJ,~> +JcC<$JcC<$JcG0'm`o_\L_qYfd[JcC<$JcE[g +J,~> +JcC<$JcC<$JcG3=kl1;Sp&*\DpA4[^p\=a^rV$-]s7H<^r:0jXrh0+]!5&0?"M;=Y]=S!R!P5i> +])K8>\GbU:k5"-;T`(M]T)PA^T)Q4n\,a)6\Gj#A]">Se]^ri:]_pCVf_jFugATe*h"oh,UA:S] +U]nucbK@oHr5ScUrPSBJo>UUFk2?3srSmb8roF+@r9"%Bs60FGs6BULrji!VqpPJks7-$XrU^$\ +p@\.Qm.]lAqYC!ap&"XaqYfg\JcC<$JcE[gJ,~> +JcC<$JcC<$JcG3=kl1;Sp&*\DpA4[^p\=a^rV$-]s7H<^r:0jXreC9)rf$orf@)@qiC9/r7C_rr7Uo"rS.>,qV;.,q2"p)rg3_QQM$OCQLgC; +QMZs0i;MX5ir%j9jT"?>k5XWEkl'cGlMg,KQMI*LSH&-Wo)81Zo_.tOp?_P?q"jg_qXsa_r;-BZ +rdk*#s+13gs*t~> +JcC<$JcC<$JcG3=kl1;Sp&*\DpA4[^p\=a^rV$-]s7H<^r:0jXr`/eqr`/_opf@Grr)`j[cfY&b +rD`\nq,I&is&T2&rDs##=7o\e=8u>!fD+"rg%jA#g]$")h>C1H;u]esk5XWEkl'cGlMg,K>P(npnbhtVoD\CUp%J+Gp[%\Oq>0s\qtp +JcC<$JcC<$JcG9?kl1;SpAEkGo_SF[p\=^]rq?6^rq-3]r:9mX!hc6\rh'7brh0(us1A9A!kZ%T +rji'?rji$UUFs53M+q;:u*ro*k9r8[e;s5j4As6'FGrTX@IrOM^P +s3gnorpfmVrq$'[o_%_Inb;MIqt^-cp&"XaqYfj]JcC<$JcE^hJ,~> +JcC<$JcC<$JcG9?kl1;SpAEkGo_SF[p\=^]rq?6^rq-3]r:9mX!/CB+reCB2!06`3s,Ql6pZC/j +pZ)>7q1\Qrrf?o;rf7&@rK$r>rf7&@qN(60!KW?5fDO;"g%sG%g]$"-h>)g+M#3&-QiWP>oT]EB +q3:rGrK[/Dqj%3=p"oN%pu)/1ro3k9roF+@rT=.Cs60FGs6BQKpmq>QrpfmVrq$'[o_%_Inb;MI +qt^-cp&"XaqYfj]JcC<$JcE^hJ,~> +JcC<$JcC<$JcG9?kl1;SpAEkGo_SF[p\=^]rq?6^rq-3]r:9mX!*/nsrD`o" +JcC<$JcC<$JcG<@l2LGUp\a+LnbW%Vp\=[\rq?6^rq-3]r:9mXs7#`TpppI;rji0C]"7aKrj`!; +s5s4?g>qqem[a?dp:(+5pUL76!4r0As1J!;s1J$UpXfDsrRq&$rnI1@s.]Ogs.fkDbfn8RaiF:u +s2FrSpr)dCqS_p[qVM2.qV_D4ro3k9s5a4ArT=.Cs60IHrODpXpXB/jrm:`8rpfmVrU]sZme-#A +p@n.Qqt^0dpA=abqYfj]JcC<$JcEaiJ,~> +JcC<$JcC<$JcG<@l2LGUp\a+LnbW%Vp\=[\rq?6^rq-3]r:9mXs7#i>s+UN-rf-rrf7&@qN(91s,Zj(pXfDsrRq&$rnI.%reUT2r0RMOQL'n: +QMm*EQMQm:h>6",htl:2iVqj7j8\3?jo+?AkPscFl2?nJT(efRS,i'Xnb_nUoDJ7Kp$VPIp[\+V +q>C*_qtp +JcC<$JcC<$JcG<@l2LGUp\a+LnbW%Vp\=[\rq?6^rq-3]r:9mXs7$%hr`/hr"'&B& +JcC<$JcC<$JcGBBl2LGUq#'CRnG;hRp%\L[rV$-]rq-3]r:9mXrpTpVp7MN!\[o?M\cB;?])T>@ +](ro9\Gs&8jO*#dipN?;[f3c4\,a#;\,a)6\Gj&=]DfJ8]`>_CeG7Ymf(mqrf`'S%gAdfCT_P2d +UH./htu@3iVqj8j8\3?jo+?AkPs`G\,Nl=\^].'df@hq +d/q\anG_tSo)81Wo]>c +JcC<$JcC<$JcGBBl2LGUq#'CRnG;hRp%\L[rV$-]rq-3]r:9mXrpTpVr.k6*s+UE2rf6Z2!06i6 +qrH/brSm6u!07&>qN1Z:!0I)=!0I2@!0I&c +JcC<$JcC<$JcGBBl2LGUq#'CRnG;hRp%\L[rV$-]rq-3]r:9mXrpU!Xq"OIVqt^0dpA=abqu,s^JcC<$JcEdjJ,~> +JcC<$JcC<$JcGECl2LJVq>BUVnG;bPoD&:YrV$*\rq-6^r:9jWs7$$Vqk3kZ"M2.S]".gOs1/-? +rj`$?rOE!>\[h^LrjVO[guA4irgrbQrLEnrrjVa6s0qX1rji'@s1J!;!5.jOrRLktqUb`!rRh1A +rLWt[rh01_rltJe"3\j/a8EsW`W*mV_tV+A`VIIAh"]_)hYuF1i;V^8ir.p;jT"??k5XWE[KO(L +\CB%&e,RkrdJqSmnG_tRo)/+To]#Q=pA+IVq#'scqY'g`r;6H\rdk*#s+13ls*t~> +JcC<$JcC<$JcGECl2LJVq>BUVnG;bPoD&:YrV$*\rq-6^r:9jWs7$$VqhP0*s+UB1rf6<(o]+`d +qr.'urIb-1rf?o;nrNg4r/^K3!0?["rRLktqUb`!rRq+'onWF3s-E_Orfll:rg*PKqNgrBnD*fp +rndY3r8@S5s5O";s5a4ArT=.Cr0@;RpRV2Orp]pWq==ITq=N\>q"FOXpA"R]r;--aqu$?imf%e; +JcC<$ao?k~> +JcC<$JcC<$JcGECl2LJVq>BUVnG;bPoD&:YrV$*\rq-6^r:9jWs7$$VqcrRLktqUb`!rRq*H!)rbmr)3Sq +r`8u!!*9)!!`i<$q,[Mqs&AtuoN1ihnD*fprndY3r8@S5s5O";s5a4ArT=.Cr`T8)qGdAmqc*Ra +rpfgTr:BaViq<*?q=jUXr;$9epA=abqu,s^JcC<$JcEjlJ,~> +JcC<$JcC<$JcGHDlMgSWq>B[XoD8%RnG)qUrV$*\rq-3]r:9mXs7$!UrLj"Z!MI%%\c02>\H'5< +\HKFQ\@B*K\Gir=[c?EDinWMgi;0#BSG\lUS,g%t[K*f4\Gs&2\G`u;])]M9^%KkKeG[qsf)!tu +f_qB>T),)YT`348bQH&2aiF>!s2G#Vs24TLoYpXEp=fAtrS78*rnd\4r8@V6s5O";s5a4AroO?h +ZaI6MrRCSjs3^nprm:]6rp]pWq"":Qp%7D>q=a^[p\=[^r;-0bqu$?imf%e;JcC<$b5Zt~> +JcC<$JcC<$JcGHDlMgSWq>B[XoD8%RnG)qUrV$*\rq-3]r:9mXs7$!UrJ1?+rIt93rJgf:l](r) +q;U2gq;D+&r.Fp!rdt33rf-u>q2k3/rfI&=oT8appXK/lrmpqt!8.+%pP8[6"IYXDQ^7W8n!3m< +s-pRV5P!h8ZIrp]pWq"":Qp%7D> +q=a^[p\=[^r;-0bqu$?imf%e;JcC<$b5Zt~> +JcC<$JcC<$JcGHDlMgSWq>B[XoD8%RnG)qUrV$*\rq-3]r:9mXs7$!UrDr_o!*&qtr`9&!rDrnt +rDio"qcq=a^[p\=[^r;-0bqu$?imf%e;JcC<$b5Zt~> +JcC<$JcC<$JcGHDli-_Yq>BaZpA4@Um.gMQr:^![rq-3]r:9mXrp]mT!:KNQ!M?t$\c98>\H9@Q +\G`u7\Giu:[eet5i;_[7SbnrWRfJoPRfT%grO)^8qRHL5p:(48]",EO])]M:^&$.QdeqSieGe"s +f)O@tSc,/WT)kV1rltGd"3\j/a8EsW`W*mV_t_1@`VROAgATe*h##q-hYuF2i;_d9ir.p;jT" +JcC<$JcC<$JcGHDli-_Yq>BaZpA4@Um.gMQr:^![rq-3]r:9mXrp]mT!:Kc?s+^H*#_\4uNK0!X +NfN@`qVfu_s53[*on!3sO8Y(=O8=t/NrkE*OSk14OS[B$deqSieGe"sf)O@pLAHZ*RJ`ETR@'>- +QN!-KPlR'?Q2R$KQ2$[AQ1*H*g]$"*h>c@2hu2L5iW%p9j8\3?jnt8CPF\9DT(efRS,f&Xn,DhT +nb;VKoC;J>p&"I[p\4I]q>C*`qu$BhrU0Z9s+13$s3(Fm~> +JcC<$JcC<$JcGHDli-_Yq>BaZpA4@Um.gMQr:^![rq-3]r:9mXrp]mT!:Kbcq,IDorDiht!*/tu +r`/Ymr)`aRe_pJbrDNDhqc!Pqq,dGqoiM,p!a/W,r)iYoqU,/fr6tJkrmgtus47?N;c?Tm;ZK_p +;uKVn;uTes +JcC<$JcC<$JcGKEli-_YqY]m\p\ORYl1k/Mr:]sZrq-3]r:9jWs7#sTs6fWS".u0V])9)E\@T8^ +\[]/[\c0)=\bWc7\,Wl:[Hlc7hu2F1SGerQRK/iURfBkq[K*f5\G`o1\-':Q\[qdP!5/$=nBq3_ +rR:Vmrm_&#SFrHQT)PA^cN)8ic2Gifb/q^%`rF$X_uR^N_u[iqn\tCDo\'#nrnIG-r8%D0s53e5 +s5F";rSmn=ricO1ZEhs.psf5js3gqprm:T3rp]mVoCDMEoCVSGr:^'_p\=^_rVH9cr;?Hjmf%e; +JcC<$bl<1~> +JcC<$JcC<$JcGKEli-_YqY]m\p\ORYl1k/Mr:]sZrq-3]r:9jWs7#sTs6flA!/CB)re192rJgi; +l&G#ekhl?qpOiHsq1A^.O8Y(=O8=t/NrkE*OSk15ORUZrdf%YkeGdu!eqNXK!/LN@rL!VQs-EtV +Q'@MuQ'@O,Pl[29rKdJKpQk]Ao\'#nrnIG-r8%D0s53e5s5F";rSmn=qi^fHrLWqXr1*eVr9sXS +rUKLMoCMSGnb)hRr:fs\rV?Egp\Xmdqu,s^JcC<$JcEsoJ,~> +JcC<$JcC<$JcGKEli-_YqY]m\p\ORYl1k/Mr:]sZrq-3]r:9jWs7#sTs6fV^r`&qtr)N\r!*0#! +!``3!p/_,n!*8FDkhl?qrDNDhq,I)ir)iVnr`B;+=BAU+r`JnrnBq3_rR:Vmrm_/&;GpFlqc*Ai +s&]/!$s$G3=BAR)<`N.#<`Srrr`'##='"imqc<@BptG`%rnRG-s5*e5rS[_7s5O";!9F#Ypf.)i +r)E\pr9sXSrUKLMoCMSGnb)hRr:fs\rV?Egp\Xmdqu,s^JcC<$JcEsoJ,~> +JcC<$JcC<$JcGQGli-_YqY]s^q"ja\kP4lIr:]pYrq-3]r:9jWs7#sTs6fpSqOdh\r13o"rji!; +!4r0?rO;s=\@B*K\Gir;\Giu:[K_ +rk%m;r6P/bpsK)hrR:\opRM#Lrm(\lbg"E2bQQ)0a2Z*t`WX9!`5BLg`9kPC`;/$]f_sM"gA]k, +h#-".hZ)L3i;_d9iW/$9YQ1s-e+hGje,Ri!dEp7dmeZDNnGMhEo()DIo^qhSpAF[\q#'sdqY9sb +r;6H]rdk*#s+13ps*t~> +JcC<$JcC<$JcGQGli-_YqY]s^q"ja\kP4lIr:]pYrq-3]r:9jWs7#sTs6fpSs+^H*qh4p.rJ^f; +r/C]8mZ%8)pYXueqVC[o!.t0%qi:];qN1Z:!0Hr9!g&P+rK$Z6r6P/bpsK)hrR:\opP&Bsr0dMN +s-X(XQBd`"Q'M<4pQbT@!1!5Crg!<2qUkc"qV(r's4mP.s5*e5rS[_7s5F+?OcfR)qORPUr13bU +!LrNRn,;bRna>u=oD%tMp&+O]p\FU^q>L0bqtp +JcC<$JcC<$JcGQGli-_YqY]s^q"ja\kP4lIr:]pYrq-3]r:9jWs7#sTs6fpSpf@>ns&AnrrDinu +r`0)#<)iQlrDs&$i8F@einjOfpJ^cboiM)or`9)%q,dPt#$G&0=BAU,pK.:=psAf`rmLbor7(^D +qG[5is&/u"=',?#"BJT+=BGK&!*/Yls&B&"m8s9fq:GJqrRq&$rnIJ.r8%D0s53e5s5F";!omBb +r)`VlqGmGm!E8F_n,;bRna>u=oD%tMp&+O]p\FU^q>L0bqtp +JcC<$JcC<$JcGTHm/HhZqY]s^qYL!_kkOoHqtBgXrUg*\qssdWrp]mTs6fmR!:9ZW!2'(Y!4r0? +r4)a:s0r3@\@B#Wrj_g6rO2a6q;0i]!o0<9oUGlLrgEeRs0hs:rjDg9ppg=4!P#W7\-TXV]",D` +]=Y`N^%]hLchu/ddJhSne+K7,Sc-k:c-4DVrlbPhb/hWC`W!mV`;daN`9bGC`:;IXf_sM$gA]k, +h#6(/hZ)L3i;_a:iii9as4%(tpXK,i"k(fGd*U, +JcC<$JcC<$JcGTHm/HhZqY]s^qYL!_kkOoHqtBgXrUg*\qssdWrp]mTs6fmR!:9ZC*aqu$BhrU9`:s+13$s3CXp~> +JcC<$JcC<$JcGTHm/HhZqY]s^qYL!_kkOoHqtBgXrUg*\qssdWrp]mTs6fmR!:9S`r)Nbtr`&eq +rDrqus&T+uoiD)os&SsPg>)bar)<)aoN1unr`9)%q,dSus&f>(r`B,%pfI48qp52eqU,;jrmUO= +q,@Gr<``B$< +JcC<$JcC<$JcGTHm/Hk[qY^!_qYL'alM1)Iq=aRUrUg*\qssaVs7#sTs6fpSs6T`Xs.B4\rgj(Z +!4r0?#.V.P\%&rYrj_g6$FmRS[^W]S[^NTPrjChCo%a6!s.'(Xp6tuKrg9qof/cb/q^&`W4!W`;[[N`9bJ@ +ebRelfDaG%g&0S(g]-(-h>c@3hu2L3YPtcteGReqdf7_ociEJ4meQ>KnFuJ9o(qtTo_8%WpAOa] +q#1$eqY9scr;6H^rdk*#s+13qs*t~> +JcC<$JcC<$JcGTHm/Hk[qY^!_qYL'alM1)Iq=aRUrUg*\qssaVs7#sTs6fpSs6TK6re1<(s,I&= +s,I&;qi1T6mu?Dao%a6!s+C<&n:CV!qi1Z;plPK9!0Hu:"H\b.OHBI&plPI!o?R<\rQtDg!n)aT +rIb!#s+U?)!1<\PrL!VQ!go=?r0@,CpQb35r71Voq:GVurn75's4dS/rS@M1s53e5rK7)B"J20T +S=KMJrLWqXr1*eV!:BdRq="4Mp[RG;qXaUVp\"LYrV--_rV?Egq"t!equ-$`JcC<$JcF$qJ,~> +JcC<$JcC<$JcGTHm/Hk[qY^!_qYL'alM1)Iq=aRUrUg*\qssaVs7#sTs6fpSs6T;WrD`_qrDrqu +s&K5%<)clkoDA1Sp&4U_p\FU_q>L0bqu$BhrUBf;s+13$s3CXp~> +JcC<$JcC<$JcGWImJcq[qu$-aqYL'ameHJLq"FCRrUg'[qssaVs7#sTs6fpSrTjQXTDY;ZSH,2Z +RfL&!\c9/E\%&oV\@K,ZrO2j:\$l7Er3lL1s5!>&l.c*h!h5XIqjIANr0dPO!13Vls0r$:!4Va5 +rjMs=\$u4D!4i'>rk&0Br4VjKqp"r^rQkJis3^Y2!h5^Mr13eV!1j&6!RAsebQH&2aiOG#!6+rU +rkn]Q!QE"E`V@s[ebn"qfDaG&g&0S(g]-(.h>c@3hZ2U2Y5kfteGReqdK%\nd/NG2me?2GnFQ2< +o)&%Vo_A+XpAOa]q#:*fqY9scr;6H]rdk*#s+13ss*t~> +JcC<$JcC<$JcGWImJcq[qu$-aqYL'ameHJLq"FCRrUg'[qssaVs7#sTs6fpSrTsB7q1SU(s,?i7 +rJ^6*s5!>&l.c*h#(hDWJ:N-!rIFlupji=&r/Uf +JcC<$JcC<$JcGWImJcq[qu$-aqYL'ameHJLq"FCRrUg'[qssaVs7#sTs6fpSrTsJ_p/_,kr)N\r +s&K)""'&<"$\$i`SrjMj9qR6:/q:jc[!87@?rL*VQqjIDMs-E_nr3lX7s0_p:ppg@5 +rj`!;qmZX:rOW!?rk/3CoZR0VrQY/`s3L8)rL +JcC<$JcC<$JcG]KmJcq[qu$0b!/UOKqt]aVp%S1Ro_&.SrU]pWrpg$Xr9s[Rs6]aN!:0Q:qLnj% +q2PB4qi1T6qi1W7pl5+(hV%t_rdaZks+'urs,?r:r/Uf +JcC<$JcC<$JcG]KmJcq[qu$0b!)rdkqt]aVp%S1Ro_&.SrU]pWrpg$Xr9s[Rs6]aN!UEbW +JcC<$JcC<$JcG`LmJct\qY^'a!rBI0rqcNfoD&(Sp@e%Lqt0jYqXXXUs7#sTs6fmRrTsRM"R;SM +SXobMpmV>r\[h^LrjVp9#e.=R\$i`Q[^Q1C!k5VHqmHI2rjD+HnCdcms-inSrL3bSqj@DMr0@>j +r3lX7s0h[3s0r!;s0qs:rji!=rk&-As1S0LpWNNZrQY;dr0mPOp6kuNqTf2fc25]lbK@rI`l5s: +`Pf^n_u7LS`Ph5aqU55hq:,Dos47,"s4IA)rS%;+s4mY1poabIe'mm;rR:bos3^hmrTsLMqsNqA +o^M\Hp@A.QrUfpYrq? +JcC<$JcC<$JcG`LmJct\qY^'a!rA+:rqcNfoD&(Sp@e%Lqt0jYqXXXUs7#sTs6fmRrTsRM!pYJn +qLn^!q2PB4qi1T6qi1Q5qMjjqnCdcms+'`kq0r?ns,?o9rJpl8irmh&"r7Cu$s4RA)s4dS/ +s5!I4r1 +JcC<$JcC<$JcG`LmJct\qY^'a!r?%urqcNfoD&(Sp@e%Lqt0jYqXXXUs7#sTs6fmRrTsRM!:'8Y +r)N\pr`/tts&K&!r`'## +JcC<$JcC<$JcGcMmJct\qu$0brqZW*riZ4qo_A7Vp@dqIqt0jYq==OTs7#sTrpKgRrTsRMs69[M +SXobMp6u,q]".dL!4Vm7"1YhL[edE2[f3Z8['fn?rj;a5pY"lbq:GP4rg3\RrL!JKqj.)es0r$: +pUL74rjW$=\@;IIrOMp=rO`$@rQ+cUr6"iYrQG>fR$[N6rL*PO!7(Ge"4#08bPo`cb6,o/a2\+t +rl"`Prl"]Q!6"iT!6"`Qp +JcC<$JcC<$JcGcMmJct\qu$0brqZVYre^ULo_A7Vp@dqIqt0jYq==OTs7#sTrpKgRrTsRMs69UK +pOrO"re191s,?o9rf$`6rf$`6qi(E3pY"lbq:GXsrdXorr."Bgrf$f8rJpl/WSGo#Sm/68Imcs9:nG;\Mo)/+Yo_S7Z +pAXg_q#1$fqY9sdr;6H^rdk*#s+13us*t~> +JcC<$JcC<$JcGcMmJct\qu$0brqZUtr_rdko_A7Vp@dqIqt0jYq==OTs7#sTrpKgRrTsRMs69UK +q,[;ks&8kqs&K(us&K&!r)E_rr`/MipY"lbq:GODpf$lc!EWD& +JcC<$JcC<$Jc>`MmJct\qu$0brV?Q)\,NN1q=XOZp\FOMp%n=XoD.tVnc&%Un,DbTmJZDOli68M +l2R:ES,U"t\Gs&;[f[/[Q6[/JY9fDjFtR.lsCQ2n>h[f\%&oVrj_s:-gqu-$`JcC<$JcF4!J,~> +JcC<$JcC<$Jc>`MmJct\qu$0brV?\\ObejNq=XOZp\FOMp%n=XoD.tVnc&%Un,DbTmJZDOli68M +l1p#2L&?W'NW+n8NW+n6NW+n7NVSP2NW%MgfDjG#J,OiqI/n`oI/n`pIK+crIJf''NW"n9O8=q< +O8b4AO-'=$s,d2A!K`B>OR^Eiao0B[bPltfJ,b$!Jc(,tK*$XmRJN&arR1\or7(bss47/#s4IA)rS%:5s,m5@!h>gPrLX%[r1!bXr1:-gqu-$`JcC<$JcF4!J,~> +JcC<$JcC<$Jc>`MmJct\qu$0brV?Ot=T25!q=XOZp\FOMp%n=XoD.tVnc&%Un,DbTmJZDOli68M +l2"HV&arR1\or7(bs +s47/#s4IA)rS%9Rs&o;&"'JT':-gqu-$`JcC<$JcF4!J,~> +JcC<$JcC<$JcG-:qYg?ipA=da!r9=7rN>qjqtKp[n+HJJqt'URrUKmVr9sXQs6]dOs6K^MrTXmIfoL0cqu-HirUBf;s+13$s4%(!~> +JcC<$JcC<$JcG-:qYg?ipA=da!r7t@reLQ2q"Xa\q=a:Mq"4ITq""CRrp]jSrpKgRrTsRMs6BRI +n:Uk'NK*mqrJgf8qi1T6r/LH0rf-X'mah6b!IoR_IJ]!&NW"n8O8"_;O-#J&O8k=?Ont1;`q[UL +aSs<\b5HbgIf4cqJH(3"JcLB$Jcp^XR$jB=R/WNQR/`TSR/`NQQ1U=0Q1rW&d/)/hdf7eoeGn)! +f)=5#fE'[ZpQ5EFs.0+[s.0(X!1j%ZrLNkVrgWrQrTj1Dp[.YAo'cMGrUK^Srq$*\qt9s^rqH9a +rqZNhq>:-gqu-$`JcC<$JcF7"J,~> +JcC<$JcC<$JcG-:qYg?ipA=da!r5r#rDWLdqtKp[n+HJJqt'URrUKmVr9sXQs6]dOs6K^MrTX8] +qGmDn!*&qrrD`ess&B"ur`8bno2bS:mah6bs&AVhqc*Jns&K2&=BGK&nlP`k!`rK+r`B#"q,dL6 +prE0NrlP/^peq&hqGdGm!)i_pr`9&#!*9)!s&T)"rDrqup/^ifr`9#"pWrcaqU,;js3pnqs4./# +rR_)%&)#Z;='/O*=BJX,=B&7"r:'[Tq==OVrUg![ +rq??cqY:'crVH?erVZQknG\"=JcC<$eGk%~> +JcC<$JcC<$JcG0;qYg?ip\XmbrqZT&r3#tmqtL!]nFcSKq=F@OrUKmVqsXOPs6]dOrp0ULrosIH +pRD,OrL3o$]"5HO\Gs&;[f3]6[K*`6Zi[S@[/RK/ZiIN5[/AMDeb.GjR/<6LQM6[CQN+;l[J@64 +\$id:\-BFP\@8rW\G`u;])TDA]_BDB`r3sRaS;)!QhZpPREWn#c-FW4cNDJ;bfot-"Nnj,`Pqeo +qnrHPqo/QQrl+fRp!3N^rQtJirmLhqrRCkts47/#!8.%KrQtSl!RfHgeGRepdeqJml2BoFlgjE9 +mJ-,Bn,;bSnbVhUoDS=Yp&=[ap\Xabq>L0cqu-HirUBf;s+13$s4.."~> +JcC<$JcC<$JcG0;qYg?ip\XmbrqZSUrJ1H1r:p0`qtBOPq"4CRp[\:Qrp]gRrpKgRrTsOLs6BUJ +s60'-rIY-2NVe\6NW+n7NVnb7NV&/0NVqAreb.GjIeJ3eIf+TqI#X-`N;\b8Nr4t4O9Uc-OH5Ha +OSk7;OS?`k`r3sRaSgPbIf4cpJ-(:PJGk'!QiNQMR/WNQR/`TSQi`V?Q1L70Q1`H$ci)5gdJhSo +e,@erec45!f)XItOSt^LSc,/[Sc"uXSc,/XSc##WRfM^OlMTu=m.TiAme-&InGVnRo)A7Zo_\=\ +pAXg`q#:*fqYC$er;6H^rdk*#s+14#s*t~> +JcC<$JcC<$JcG0;qYg?ip\XmbrqZRqr)Pc]=bfR`:_+J`r3pZaHi+iQMm*KQMQsFR/bA7c-FSZcHjl:cNDJ;bfp". +s2kGca2Q$r`;@IP`;@OQ`;[aT`:hIOcMl/hd/;;kdf7epeGn)!ec==qY5Q`Id/qbFe+;)ee,Rkq +d/qbDdJ`>-lMKo8m.fuFme?2KnGVnSo)A7[o_\=\pAXg`q#1$fqYC$er;?N_rdk*#s+14#s*t~> +JcC<$JcC<$K)b9 +JcC<$JcC<$K)b9Nli68K +l2TrIkOqmV<)rcor_r_os&B%ur`/qupf6re!7g5]qU>FDr)E)arDrr#!*B,"nlPZis&])"qH*R4 +ou6mLrPnoZqbdDmr_iSkq,@Ap<;]`"<``='='#<#s&T,#rDrkspK$rgr`8a;q9Jucrm:Sjs3gqr +rRCkts4.2%r)W\rrD`esr)Nhu<;TSo<;BPk<<#nql29iDlgF-7mJH>Gn,;bSnb_nVoD\CZp&=[a +p\Xaaq>U6dqu-HjrUBf;s+13$s4.."~> +JcC<$JcC<$KE(B=qu-Hjp\XmbrV?Hfs0Vg1s0)F)s7cHbo_&%Pq=F1Jr:0aTqsXOPrpBXMs6K^M +rTX@Gs5sCEqjR2Is189Brj`$Zi7<3[Ipp(eFD#]df,U1QN*5.c2Z&icd;[;!mSs5 +qof#^#KXp(`Pf[4`;@IP`;@OQ`;dgU`;@aSbl,f`cMl/id/;;kdf7eqeGn(lY5HZHd/h\Eo$mTd +rR1Ylq<@eAq!7A7qsF=Lq=":OrpfmVrq$-]qt9s^rqH:-gr;H-aJcC<$JcF=$J,~> +JcC<$JcC<$KE(B=qu-Hjp\XmbrV?Hfs,[2:r.tCIr:]dUq=OLSo()_KrUB^QrpKdQr9XILs6BRI +s60LG!9X65o7R('!0-u:!/pf7rf$o:r/LT4rf-Q/qpb/bpMnG_tTo)A7[ +o_\=\pAXg`q#:*gqYC$er;?N_rdk*#s+14$s*t~> +JcC<$JcC<$KE(B=qu-Hjp\XmbrV?Hfs&T/!r) +rO;X5!4Vd6s0r!;rj`$?r4DR;r58KOrl+o%!1!MIpQbWArg*W.rlk>c$I6uEcd0n]bfn8QrQG5` +#KXp(`Pf[3`;@FP`;@OP`;dgV_uRsObPfZac2>leci;AjdJqYpe,RqsXn]%!chl)hd/h\Eo@3]e +r6kPks601@q!.V>oBcDBr9jFMrp]pWqssaXrq--]rq??cqtU0drqcHfrVZTlnG\"=JcC<$fDg@~> +JcC<$JcC<$K`CK>qu-Hjp\Xpcr;$O84n;O8b7> +Oo1=4_Yh=M`;[aPIJeQiIJnWpIfPi.R/NHQR/`TSR/`KRQBh*,rKRDJQ2QsGPlStubPfZac2>le +ci;AjdJqYpe,RqmO8b4@S,8`USc,/[SbnrPSc##VS,_^Gl1jQU6dqu-HjrUBf;s+13$s4@:$~> +JcC<$JcC<$K`CK>qu-Hjp\Xpcr;$tt<<#no:FCrP\]Sr)3PnpJh/ks&Atts&B#!!EE+s<<-)!U6dqu-HjrUBf;s+13$s4@:$~> +JcC<$JcC<$L&^T?qu-Hjq"t!crV??cs0Md4riu[3Yct=7p\"FUqXa:KqXOIPq="=NrpBXMrp0UL +rTX@Gs6'@Cs-iPKrLEku#e@IU\@8uW\$l+?s0VX/osF,6pX&rdpm1]?rfm5B"1#;@Zi7?3[JRE2 +\,*T7\,!Q6\,Wu:\H'5>]DfV@_=thG_tfPfPlR-LQiG8.bl,cncd:%bcd'eZbfe0-bQ#]faMu3< +`;.=M`;IUP_u[iqqoS`Xq9/c]s3:Jes3L_lrR(YnriPpts3LShs3Ukqe+;)ee,7YmdJrD.kjn!4 +lM9c>m/?>MmeZDOnG_tUo)A7[o_eC]pAamaq#:*gqYC$er;?N_rdk*#s+14&s*t~> +JcC<$JcC<$L&^T?qu-Hjq"t!crV??crf@&9re^Z2p\"FUqXa:KqXOIPq="=NrpBXMrp0ULrTX@G +s6'@Cm=Y@ss,?u9",r.sN;8J0N;nn1N:#$ed/VGeI/&$gHMi-fHM`^"N;eh7Nr+krkSGrL*\Qs-`nSs-EbPQ1U=>Q26^GQ'D0fqo\`XrlkDer6G>g +s3U_ls3g\'rK.&Kqjd\WrLX%[qjdGPr1*_Ts6'@Eo',o6q:-gr;H-aJcC<$JcFC&J,~> +JcC<$JcC<$L&^T?qu-Hjq"t!crV??cr`8hop\"FUqXa:KqXOIPq="=NrpBXMrp0ULrTX@Gs6'@C +r)EVnp/Lof!E)kp<<#qu<;ontleci;Aj +dJqYoU6dqu-HjrUBf;s+13$s4I@%~> +JcC<$JcC<$L&^W@qu-Hjq"t!crV?!4_s9!4Dg5rO)X3qQon&rmCGdp!kjRd3 +lMKoBm/HDNmecJPnGi%Uo)J=\o_eC]pAamaq#:*gqYL*er;?N`rdk*#s+14&s*t~> +JcC<$JcC<$L&^W@qu-Hjq"t!crV?<5oo/mtp<`KYqp,1gq0VOUqi1N4s,Ho9q2b?5s,[2Ar/pu? +pV6U@rPAHLs*XNg!.ONfr0R/FrL*\Qs-X"WQ^=#'o9B3=qNLuFpW3#\s31JerQbGhs3Ubm +!KE-;O8P+=S,/ZTSc,/[SbnrPSc,)VRfMUKkPOK3l1sWAlhKiGmJZJMn,DhVnb_nWoD\C[p&=[b +p\Xabq>U6equ$BirUKl +JcC<$JcC<$L&^W@qu-Hjq"t!crV?JcC<$f`-I~> +JcC<$JcC<$LB$`Aqu-Hjq"t$drV?9a!;HGt!4;^2s0DX/!;69^r:BROqXOFOp@%tJrU'LKs6K[L +rTX@Gs6'@Cs5a:Bj6W97])T>@\,a#:[K*`7[/IE4[.q!%[/828cMu/cQ2d*KPQ-gDOnk1=^@]2=_"s8jPkLCBQN,2.bP]Tabm_qFd*L%`c-4DS +b0/!-aooi,`Podj_u.IP`Vd[Na8!aSaoBN]bPo`cc2Gohcd:& +JcC<$JcC<$LB$`Aqu-Hjq"t$drV?9a"o"%;O,o7uMuS\6M#d5Ho_e=Qo(qnQnFl>LmeuPMm/QDN +lM]uIkl9iEk5XNDjQ#TZqi(T7rJUZ6qi0s$qp4TRs3:CerHe +JcC<$JcC<$LB$`Aqu-Hjq"t$drV?9a!V]Xo=8Gqr;ulUho_e=Qo(qnQnFl>LmeuPMm/QDNlM]uI +kl9iEk5XNGjPs3<;uT\p;tO&c;u]_q;uK\nrdc2u>=d.LE@=&i8p<<#tt:-gr;H-aJcC<$JcFI(J,~> +JcC<$JcC<$L]?iBqu-Hjq"t$drV? +s0;d6['[0Grj;^5r3lR5qmcX7qmcX7s1&'="1l+V]_9&:^AG\APP17@Q2HsJPld8pbl#Z^bR)P? +d*U+ac-4DTrlY8as2kJda2Q$9pr!!I!6+lSrl+`RrQ"cUs2k8_rQG5bs3:Mfri?%"riQ+$!7(Ph +qp>Aj!RfHgeGRendf%Snjn@j4kP496l29iFlh]uImJcPOn,DhVnbhtXoD\C[p&Fabp\agcq>L0d +qu-HjrUBf;s+13$s4dR(~> +JcC<$JcC<$L]?iBqu-Hjq"t$drV?Ubap!*?W!.4Nfpj)LXq2P?3rJg`8plG<6rf@)@ +rK7,A!5/$=r4`'CqL&!bqL/KoIX_*ZpmD#Jqj@DMs-E8@rKRGKPEZ!1rl+`RrQ"cUs2k8_rQG5b +s3:Mfr/C]:rf?u=!1NkUqjd\WrLX%[qOIAPr1*_Ts5it:q<.P:p$)D>rTj=HrpB^Qr9sXSs7-$X +s7?6^r:U*`rqH?crqZNhqYU6hr;H-aJcC<$JcFL)J,~> +JcC<$JcC<$L]?iBqu-Hjq"t$drV?rTj=HrpB^Qr9sXS +s7-$Xs7?6^r:U*`rqH?crqZNhqYU6hr;H-aJcC<$JcFL)J,~> +JcC<$JcC<$M#ZrCqu-Hjq"t'erV?U*Zi@?2oCqhQnbVbIn,)POmJ?2Kli-2I +l2TuIkPaQCjo=E@j7JfTBq3D*)bfp". +r6,Jlcd:"acHXSWbPoZabQ#]faN)9=`;%7D`:_+J`r=$UaT'B^b5KN`bl>raX8f:#XoGR'cMc)d +d/VJodaRg;r6tVmr6YN*r8mM3q<.Y=pZ_YArTj@IrpB^Qr9s[TrpfsXrq$0^r:U'_s7cEcs7uWi +qYU6hr;H-aJcC<$JcFO*J,~> +JcC<$JcC<$M#ZrCqu-Hjq"t'erV?l[o.sqi(T7rJUW5r/LH0!/pZ3qp"lZoZQrSs*=s-3MH!0m/qrPniWqoJfZ +s2t;`s31MfqMkN8rf@)@!goCErL<\Ss.0+[s.0%WpmqARr0m]Ir8mM3q<.Y=pZ_YArTj@IrpB^Q +r9s[TrpfsXrq$0^r:U'_s7cEcs7uWiqYU6hr;H-aJcC<$JcFO*J,~> +JcC<$JcC<$M#ZrCqu-Hjq"t'erV?MlMToH +kl9iEk5XQCjSn3=;?0Y_<;KPn;ZB\p<;fhq!8 +<<#tq;ufkr<;fhs<;TSo<;BPm<;]YpjS\-1k5"3;kkF??lM^&Gm/HDOmelPRnG_tVo)A7\o_eC] +pAamaq#C0gqYL*fr;?N_rdk*#s+14*s*t~> +JcC<$JcC<$M?!&Dqu-Hjq>:-erV?M +lMToGkl9iEk5XQCjSn3>iq&TZ2_-0ZN@M?Zi7?2[J[K3\,Ei8[fO"JrODj9!4`! +JcC<$JcC<$M?!&Dqu-Hjq>:-erV?s5NHurIb-1qi(T7rJLc:Mil2BoHlhp,KmJcPOn,MnWnbhtXoDeI\p&=[bp\agcq>U6dqu-HjrU9`:s+13$s5*d+~> +JcC<$JcC<$M?!&Dqu-Hjq>:-erV?orDj#%<`W6";ufqts5O(;lBqge]=YYc\brr9[0*eD['T\;q6U+,s0MU0r6+lXprWKUrf[;D +r0$W5q2kT\!4)U1!jo;?rj;X3rO2^7r4)^7!P#W<\G`l:\Gj#=](NW3])K;AP4t15Pl$aGQN##- +bKTn-rlbbnbg+P]cd0n]bfn90ap6,4b/q`E`PhbnrkeNLr5ABIr58NPqo/TTrl=uYs2b;abPnL? +WqrdrXT$QGcMu5dcihbEdF-MBe,[tneGRendeqMij8.j4jn.^5kPaW@l2KuIlhg&KmJcPPn,DhV +nbr%XoDeI\p&Facp\Xabq>U6equ$BirU'T8s+13$s5O'/~> +JcC<$JcC<$M?!&Dr;HQkq>:-erV?O8b7@OnH9_])K>?IJS?[IK+cjQiUIS+rNRSc,/[SbnrQ +Sc##US,;7BjS@p0k5=E@kkaQClMg,Hm/QJPmeuVRnGi%Wo)A7\o_eC^pAamaq#:*gqYL*er;?N\ +rdk*#s+140s*t~> +JcC<$JcC<$M?!&Dr;HQkq>:-erV?flrX-f +!*Aj(r4;m>qbd8hmo06cs&K"u!`rE'r`&ntr`8u!!*8tsqc<\rq,RMt +JcC<$JcC<$MZ:-erqZEcrqHBbs7HZ"XK/A#Wi(nH_u@UQ`W!mWa8X-aaeku6W2Zcq +WqrdocN;D +JcC<$JcC<$MZ:-erqZEcrqHBbs7QDOqMb<2s,?r8rpfsVp@%nHqsF.Er9O@Iqs"+D +s6'=Bs5j:Aro=%s,m)dpUU3Mqg@dZp6YcGrKm2ErKdMLp65TCPl6mI +Pkr5k_Z%IP`;R[S`rF*Ya8j?ZMuJ\3NW#4HR@9V7q4.JUr1 +JcC<$JcC<$MZ:-erqZEcrqHBbs7Q:js&T5%JmecDGm/62KlMKiF +kl9iDk5XQCjSn3>ir@s;i:0eC;uBSr;c6Nm;[69#;GpFl<)icqs&K,$pf72lqT83Is2Y"9!*/kr +r)E_rrDiYm!)reqn5emWrE'&$ppg(/s%rborDEMkm8F'e!=8Kc._Z%IP`;R[S`rF*Ya8j?]U6equ$BhrTjH6s+13$ +s5s?3~> +JcC<$JcC<$MuW8Fr;HQkq>:-erqZEcrqHEcr:U)j"feQ#W4',2ZiIN3[/TRhn,2VNmIooFli$,F +l2KoHkPXKBjo=E?j8\-=iVqd-RJE6KRK'hs])T>=[fa(G['Tb=!42X2pp:"+s0M^3ouQsLqo7KT +s0;^2ZEjJ9qR$4/rjMg8r4)U4s1&';!4`!,_!6Y;arlb_mbg"J\ +cd'eZbfg".s2tVhaiVWD`Ph_mr5/?K!6"iNqnW0Hqni?Ms2=iSs2G5_aJG`1VZ*IoW2]crr2]V= +qToAmdaHUnrRCborRCbor6kMj!RTg&iq)4,jS\-8k5FKBkkjWElMg,Im/QJQmeuVSnG_tVo)J=] +o_eC^pAXgaq#:*gqYL*er;6HVrdk*#s+148s*t~> +JcC<$JcC<$MuW8Fr;HQkq>:-erqZEcrqHEcr:TrG!/pi8r/LW5rp][Nr9jILp?_bDrTa7DrojCF +r9"%@s5a.=s5O(;ro!O'rdt-#!.t#ts,?r:rf$i9!K;s9M?&S5N;eh3N;nh6N:k9fa8rK$r>!0R/eqR?C4rI"Wnqg@dZ!1*>Frg3NVo.GR@9V7q4.JUrLX%[qOIDQr1*YR!9*h7 +oAf].r8mb:rTF1Dqs".Grp0LKs6]jSrU9dUrpfsXs7?9_r:U*`rqH?crqZQiqYU3gqu,aXJcC<$ +JcG$8J,~> +JcC<$JcC<$MuW8Fr;HQkq>:-erqZEcrqHEcr:U"is&K,"pK%8nrp][Nr9jILp?_bDrTa7DrojCF +r9"%@s5a.=s5O(;ro!EJq,@2js&8qss&/kqs&Anpr`&hrs&K/%U6equ$BhrTO63s+13$s6BW7~> +JcC<$JcC<$N;rAGqu-Kkq>:-erqZEcrqHEcqt1#jWMofq"1>SE[Ipp(n,2VNmIooEli$,El2KoG +kPXKBjo=E?j8\-=iVqd8htEK7R/NHPQiak0\c02?\-TRP[^W`R['R+R1rVl6Pn +WiE,#d.bl_cihbEdaQ\DeGI_oeGRendf%Pqd*LY.qr.D2o],l1rT3n +JcC<$JcC<$N;rAGqu-Kkq>:-erqZEcrqHEcqt9lGrep`6rJg]5qsXINqsF+Dr9O=Hq<@nBroa4A +s5j:ArT!q;s5Et8s53X)!.s`lrf$i9rf$i9!K;s9M?&S5N;eh3N;nh7N;LZk`q@:NHMi-dHMDjZ +HN&m)N/dgsqi1W7rJg`8r/^f:rK$u?rK$r>s0_F+r-[US!L8uEQiEHMQhHgFQhH[DPlR'JPl[,` +p:pRArk\NLs24lTrP\cVregQ1qMYKCQ^@Z<".>UIS,&TSSc,/[SbnrQSc##URf]&:i;;L0iq2:/ +jSe3:k5OQCkks]ElMp2Jm/QJQmeuVSnGi%Wo)J=]o_eC^pAXgaq#:*gqYL*er;6HUrdk*#s+14: +s*t~> +JcC<$JcC<$N;rAGqu-Kkq>:-erqZEcrqHEcqt9tjrDrqup/_/mqsXINqsF+Dr9O=Hq<@nBroa4A +s5j:ArT!q;s5Et8s53WPr`&_mpf.8ls&9"t;Z9Sp<;TVo<;fhsM1M_uI[R`;mpQU6equ$BhrTF02s+13$s6Tc9~> +JcC<$JcC<$NW8JHqu-Kkq>:-erqZHdrqHEcqt:!]!36$tri5t*oX+YerU0UNp?__Cr9F+BrTO7D +r9"%@roF%7qm?7.s0hp9rOD[4s1&';!k>eOpU'h*qN(Q9!g8b2mZ[dla3">'s2tem +bK@uNbKS2RbK\?3cNMPM1M_Z@]prM9Ii +r20Ll#,nGuWN+=lpWr``s3^kps3pqrq9o>nr6kMjrQtSjq;D,.qVq80rT*q=qr[n@roj=Frp'OL +rTsROs6fjSs7$'YrUTsZs7H9_s7ZHdr:p9erqcKgr;?Hjk5Kr3JcC<$mf.e~> +JcC<$JcC<$NW8JHqu-Kkq>:-erqZHdrqHEcqt:!]rf$`4r/CW7qi(RDrU0UNp?__Cr9F+BrTO7D +r9"%@roF%%=OSt7?OS?-Z[JP@DIK"]gI0,XuQM-[FR/30DR/WEP +QM$ICQ'D95qn;pAqS3$Fs2"WMs2+lU`VYPiMu/J5R/WHOQiibFS"'5Ds.0+[s.0%WrgieRrL +JcC<$JcC<$NW8JHqu-Kkq>:-erqZHdrqHEcqt:!]!*B,"s&T2#r)Netqc<\rs6opSr9a4Er9O:G +q<@kAroa4As5j7@rT!q;s5Et8s53k5qc3)as&K(us&8qs"]J;s;c?Zm;ZKep +o#:ID!5n;*s&8bnnQ#$YlW4'gpU'h*ohkWbq,./ir_ierr`/r"s&BA+=&r@'=&r=#<;onsM1M_Z@]poiD)mrDrYls&JqqrDWSmqc!Mo!*/bmqc!=K +qVh;1pZ)55rT3q=roa:ErTX=Hs6KXMs6]jSrU9dUs7-'Yrq$0^rUp3arqH?crqZQiqYU3gqu,[V +JcC<$JcG0 +JcC<$JcC<$O8nYIr;HQkq>:-erqZHdrqHEcqt9s\!i`3"rMfe(pU'n,s6fjQp[%hDqs*t@roj=D +r9""?s5a+nrOMp:%^rdR[^pQ597s0;L-rNlC.qmHF3s0qs:q7$C6s0r$iebg-46#0tK;bfe/OrlYJfaiMNB`;ION_?7]m_o)8^rOr3EqnN0Hs2"ZN +!5nf2rM9Cg!2fXk!iXJmpWr]_!7Ceos3pqrq:#8ir6bGh!71Z%o\fW*qr7G3rT*t>qr[qAroj=F +rp'OLrTsROs6fjSs7$'YrUU![s7H9_s7ZHdr:p9erqcKgr;?HjjSj`1JcC<$nc++~> +JcC<$JcC<$O8nYIr;HQkq>:-erqZHdrqHEcqt9s\rf$f6s,$f7o8N_;rU'@Gr9O7Fq!%eArTF+@ +roO1@r8[h:s5Et8s53k5!8[R)!.juspjr?nr/CZ8r/:l?N/NUOMMmDkMu\k3N;eb8N;^`l`;7CK +_Z+rWHi89bH1lRaN;S\8Nr"_8N;S\8O8b1;O8P%:NrY:?NrY:5ZN.B2I.;X`IeJ0kPa.R.QiqLHMZ/P4N;o:CQNW\DR[]fASH#/YT)YAYSH#/S +SG\iVRf;4:i;;L1iq_X5jSn9 +JcC<$JcC<$O8nYIr;HQkq>:-erqZHdrqHEcqt9s\rDro!!E3"qlC0s6'CFrTX=Hs6KXMs6]jSrU9dUs7-'Ys7?9_rUp3arqH?crqZQiqYU3gqu,UTJcC<$JcG9? +J,~> +JcC<$JcC<$PQ1"Kqu-Hjq>:0frV??crqHHdqt9s\s7?&crO)[4s0_a2rj;anq!@qEr9F%@rTO4C +qr[n>s5a+/`rQ5,`rlkDc"jG9;cd0l8bl>idb5TQfb/q`F`l.blrPAZS_SWn]]D9,=^&GbE +^]2+L_#V@OUAgqeV#@.iVZ!Fkd.bl_ciDJke,@ele,7YldJV>kci)_tht5k)iVhd4j8S-=jo"9? +kPscEl2U&Kli$2MmJlVQn,MnWnbr%YoDeI]p&Fabp\agcq>U6equ$BhrT*s/s+13$s762?~> +JcC<$JcC<$PQ1"Kqu-Hjq>:0frV??crqHHdqt9s\s765LqMYB2s,6N.!:BRJr9O:GpZ_Y?rTF(? +roO1@r8[h:s5Eq7s5*h5rS@L*s+0Hcs,6i7s,Hr8"-&7uMuJS6Mt2i+MZA_5_t1bE_>/HUHLlFV +HN&m%NW+t1NW5(=Nr>%9Nr>"=OSt7[qPEhF,QiU6equ$BhrT*s/s+13$s762?~> +JcC<$JcC<$PQ1"Kqu-Hjq>:0frV??crqHHdqt9s\s7?7kqcb<<#tq<;fbl<;TVe<;TVmhYZ4& +i;DR4iqh^7jSn9=k5OQDkl'cGlMp2Km/QJQmeuVSnGi%Wo)J=]o_nI_pAXgaq#:*gqYL*er;6HR +rdk*#s+14@s*t~> +JcC<$JcC<$Q2g1Lqu-Hjq>:0frV??cs7cNdqt:!]rpp-\rMfaqr3ZO3rO)O0rjD^kr9O:Gq!%_? +rTF%>roO.?rT!n:s5Eq7s5*h5rS7M0g\mN6R/r\Ap6Gij\@K2^rO<-B[^NTO[^ENLriuR2[.:O) +ZEpn6_YV+F^]BOXrK-u?jcBJHrilR2Z*CV4Zhq-+[K!]7\,Wu5\,Nl<\%24:riu6Zr/U]9rK.#@ +!0[8DrfdT%_Sa@5ao0?^bP]KabKS30b6?,8cd0n]rlkDc!6Y;a"j4p-a2Z'p_u%=K\bs&;]DT>@ +^&PhF^Au(HUAgqeV#@.iVZ3OodJ_GdchbugdJhVmeG.MjdeqMkd/VGih>?(*htQ(-iVqj6j8S-= +jo+?@kPscEl2U&Kli$2Mm/ZSQn,MnWnbr%YoDeI]p&Fabp\agcq>U6equ$BhrT!m.s+13$s7H>A~> +JcC<$JcC<$Q2g1Lqu-Hjq>:0frV??cs7cNdqt:!]rpp0]N;eb6N;nh9M?&S,Mu\k9m/62IlM0WA +kl']@k5OKAjSe-2O8k7IK+]pIJS?jIK,E3P*;/rp6YfH +!13\Nrg3YPs-NPKs-EbPQ1U==\bs&;]DT>@^&PhF^Au(JM#W>3M?&M4MZ8P5L]`KkMi7M#r0IPR +R@9V7q4.GTrgs.\qOISVpRM2Os-ilAqqh2,pYc#/ro3h8roF(?rT=+Bs60FGs6BXMrTsRO!:KgS +s7$'YrUU![s7H9_s7ZHdr:p9erqcKgr;?Hjj8OW0JcC<$o`'F~> +JcC<$JcC<$Q2g1Lqu-Hjq>:0frV??cs7cNdqt:!]rpp-\rE&r"s&/qtj8S' +JcC<$JcC<$RK)ONqYg?iq>:0frqZHdrqHEcr:U']s7?6\s/Gjp"1>MD[JmN5[e@--li$,Cl2BiD +kPF?>jo=E=j8\-=iVh^7huDR3h#cBdg]!T;RJiNQQh6RJQ+"03]"5EM\,Wo9[0!eDZi763Za@+0 +Zi7f;_"PMENfT7qOSt71OSk1>Yl:m0ZE^[?r3Q:-q6^42rO2d:pp^43pTOS#!06r;p5]$2rK%&B +P5CIC^]_Kk`Q-+!aoKW_ao]c1bl5chc-FY]cHZ=3!R&Xbb65u/a2Z*p_u.CM\G<]6])TD?]`5\E +^A=T(U&UheU].(fV$!TmdF%p>pWr]_!7L_m!7^hnr6kMjr6YJip"fN%r87>.rSdb8r8[e;s5j1@ +s6'FGrTOCKlg+N9s6]jSrpTmVs7-'Ys7?9_rUp3arqH?crqZQiq>:*fqu,FOJcC<$JcGTHJ,~> +JcC<$JcC<$RK)ONqYg?iq>:0frqZHdrqHEcr:U']s7?6\s,6`4regi8Mi77e!0-sCrTa.ArTO1B +qW@boQoeJs*=['rJ^]7 +s,Q`2"HJP(NfO$uqMtH6pTOS#!.4Tjr-SHkq0hj^rfI;HPa.O-QiEESQ^3s9QiEHOQi!-OQ^3p/ +Pl8,f\c',>]DT>A^&Gb@M#N81M?&M4L]N?jqj@;J"IPUFS"'5DrLNt[s.0%Ws./nSr1!_Tp"fN% +r87>.rSdb8r8[e;s5j1@s6'FGrTOCKlg+N9s6]jSrpTmVs7-'Ys7?9_rUp3arqH?crqZQiq>:*f +qu,FOJcC<$JcGTHJ,~> +JcC<$JcC<$RK)ONqYg?iq>:0frqZHdrqHEcr:U']s7?6\s&]/$r`0,!;cHcpdp"fN%r87>.rSdb8r8[e;s5j1@s6'FGrTOCKlg+N9s6]jSrpTmVs7-'Ys7?9_ +rUp3arqH?crqZQiq>:*fqu,FOJcC<$JcGTHJ,~> +JcC<$JcC<$SH%dOqu-Hjq"t'erqZHdrqHEcr:U']s7?3[qPsRprNug;[C!Z3%A> +[.CU([._92^AknGNh() +rf@2DP*5a,%)9Tn_8O=5b0%iKb00_*s31Gb"jP?qSWmcd(;Bh"KS%hYl@.i;V^7ir%j:jT"?> +k5XTEkl'cGlMp2Lm/QJQmeuSUnF?&Io)J=]o_nI_pAXgaq#:*gqYC$dr;-BIrdk*#s+14Ms*t~> +JcC<$JcC<$SH%dOqu-Hjq"t'erqZHdrqHEcr:U']s7?3[qMbH4!/gZ3oo&m1rp':Cr94+Bq<%Y; +roEt:s5O%:rS[_5s5*b2s4mY/s4[L'q1%g_qMY--!f`.sre^f9N/W\eMu\k2^\Y\E^%m!5H2ig% +N;eh9NqA;6NfT6]Nr4t6Nr4t7Xo5EoHiJKiIIhjbOTUf3Q'V-1!LT5QQMm0MR/ETc +qmZO6qml^;s1A3As+gN.r.b?0M2D4h!f;_hq3_)H"IPUFR[a,CrLNt[s.0%Ws./nSr1!_T!8ID+ +p>,Z'rSRJ0ro*k9r8[h:*fqYf4KJcC<$JcGcMJ,~> +JcC<$JcC<$SH%dOqu-Hjq"t'erqZHdrqHEcr:U']s7?3[r`K2%s&T/""Ar&q<)rfrs&8tur`0)# +<)ik^q!%_?rTF"=rT4%>qr@_9ro*h6s53k5rn[V0s4dS-qGdAks&APh!)rkrs&B%ur_j##;c6Ll +;cNWmq,R>nr`&r!p:pI,Z'rSRJ0ro*k9r8[h:*fqYf4KJcC<$JcGcMJ,~> +JcC<$JcC<$TE"$Pqu-Hjq"t'erqZHdrqHEcr:U*^rq$'Yr2Taq%&g)3[^ENO[C!qW%V8ro*h6s53k5rS@M/s4dP,!87@%q833Lp9st0rj_m: +rjr-ApnIYZ!huHcrMBAQ4/htu@3iVqj8j8\3> +jo+U6dqtp +JcC<$JcC<$TE"$Pqu-Hjq"t'erqZHdrqHEcr:U*^rq$'Yr/CQ3!/gW2oo/b3rTO4Cpu_P:roEq9 +s5O%:rS[_5s5*_1s4mY/rn7A*r.+Ehpji?nqMY--!0-u9s,-`4oo&mcqnDs@qRlfRpNca_l$<8d +rf$i9rf6W1"HJP(NfO(!pQ#66rN,munTt7`pjMg_rK.5GPEhE!p6PfIQi<:'eqYf1JJcC<$K)^?~> +JcC<$JcC<$TE"$Pqu-Hjq"t'erqZHdrqHEcr:U*^rq$'Ys&]2#r)Ent;H$Lo$<<0f2^AGV?]E1u.;>*of;uK\pQ4/htu@3iVqj8j8\3>jo+U6dqtp +JcC<$JcC<$U&X3QqYg?iq>:0frqZHdrqHHdr:U']s7?0Zs7-&fri$=)Vl$l0[^NQN[^+f\$1in!=!=qNM,j['d?OrjVs;rjMj7rNuR1 +s0;d6ZEpmCqQg1-rj)[5]tO*OrO_ocs,I)?q2YH8!fi>%pQ,<6s,I&;s0)O-Yl1j,YQ2!-Zi7<3 +Zi7?2[/dZ6[/dZ-\,Nl;Wqi^]Nq\V7OT1IBP5`3%^qmn+`lQW"JVZeV5nqqM)) +q;)#+rnmY3ro*n:rT!q=s5j4As6'FGrosIJs6K[Ns6]jSrpTmVs7-*Zs7?9_rUp3arqH?crqZQi +q"t!eq>K%HJcC<$L&ZZ~> +JcC<$JcC<$U&X3QqYg?iq>:0frqZHdrqHHdr:U']s7?0Zs7-&Hr/:Q3qMY$*!KH@Bkl']?k5=?? +jSIp9ir7p7i;_^7hYl:1g]6+-g&fs[f`$E`J,"rsN;eb8MYrD/Mu\e8Muo!P^%K&:]D$UHGj9SQ +MuJ\7NW5%2NW+t7O8+b7NrZ3UX7(E6I/A?cI/K*0P*;/rQM-XGR$[fZSH#/TSG\lUReb\7g\oq' +h>Q40hu)F3iW%p9j8\3?jo+?AkPscFl2U&Kli-8NmJlVRn,MnWnc&+ZoDeI]p&Fabp\agcq>U6c +qu$BfrS%7%s+13(s*t~> +JcC<$JcC<$U&X3QqYg?iq>:0frqZHdrqHHdr:U']s7?0Zs7-%gr)F#%;Gg=i;cHasr`08(<)cjt +<`W6";ul1]kl']?k5=??jSIp9ir7p7i;_^7hYl:1g]6+-g&fs[f]uN:]`#GB;tk;Z9Vp;?0bq=8l;(=&i7$r)Wkur)E\rs&K,$pf@AqpJq>s<`].*rO)L1rjVp;r42W'rDrqu +pf@/inPo?`rD`Yms&AJdq:b`#rS75)rSIP2r8@S5s5O";s5a4ArT=.Cs60IHs6BXMrp9[Ps6fmT +s7$'Yrpp*\s7H9_s7ZHdr:p9erqcEer;?BhgAZ['JcCH(J,~> +JcC<$JcC<$U]9BRqYg?iq>:0frqZHdrqHHdr:U']s7?0Zs7$*Yr2KdsVuc:1g\oh0g"=s/Q^@0,!1!;Cs0_m6s0hm8!4Mg5s0D^4rj2R/ +pp9t*s0M[:r4Dj;rjhiaq2YH6q2Y<4s,R,=rf$l]ric:*s0)L/rNlL1!jf8@rNuX6r3ZO5osat2 +po=1NrK$f8s,[2?pQ,<8!0R8DrP&WR_8=13ai_cJqT8l_bfp%/!6tMgs3:Per6#8daiDHA`;RUR +_uR^NZi.91[J[K4\,Wu/UALYaUB&[8d/_PgchbugdJ_Mce,@_odJqSkcN2>Dr7Uhur7h2*qq_8. +rnmY3s5F";rT!q=s5j4A!pAe2rTOCKlg+Q:s6]jSrpTmVs7-*Zs7?9_rUp3arqH?crqZQiq"ssd +q>K"GJcC<$M#Vu~> +JcC<$JcC<$U]9BRqYg?iq>:0frqZHdrqHHdr:U']s7?0Zs7$*Yr/CZ6re^]4regT2oo&m1rTF"= +rT4"=qW%P6s5Ek5s53k5rS@M/s4dM+"khP\f78D4J+nlrN;eb8MYrD/N;nh9N;^Ee]DK2=\bCCE +GjBYPMuJ\7N<#"2NW+t7O8+b8O8,aOHi8?gHi&3hIJ/'cOTgo4Q'IZ$pQkoJQi<9PQ^F-=R/**J +QiWM +JcC<$JcC<$U]9BRqYg?iq>:0frqZHdrqHHdr:U']s7?0Zs7$*Yr)WhtrD`bns&/krs&K)"!*0"t +#$"])ZfA]a3<`E!rr)ESms&/kq!*&kp +r`&\nr`9&!rOi'?qmud;!E<"h;Z9Vk<<#nith +JcC<$JcC<$VZ5WSqu-Eiq>:0frqZHdrqHHdr:U*^rq$*Zrpg$Xri-+#W2HMirMBM$s0hp7!4;C, +qW@b&ns-3DEr07/e!4Dd6!OoN:[K!W4ZN7A< +rNcF/!4)O/riuO1r4;U4!4_c_rf6f6q2YB6rf6u;!K<$:YlCp+Z2Us-ZMh-0[/[K4[/IB6[^ELA +[0*kH\$l(@!4_j'q2Y31!06Z3rK.#Ar4`BM_8F74rQ4oY!mAg3rlY>dc2Q#gc2GlcbQ#]faN)?? +`;RUR_uR(?ZMCj+[/[Q3[K*#kUALVcUc@2hu2L5iW%p9j8\3?jo4EBkPscFl2U#Kli$/OmI'EAn,MnWnc&+ZoDeI]p&Fabp\agcq>U6c +qtp +JcC<$JcC<$VZ5WSqu-Eiq>:0frqZHdrqHHdr:U*^rq$*Zrpg$Xrf$l8reg`4s+pZ3qMY'+!0-j; +rT4"=qW%P6ro*b4s53h4rS@M/s4dP,s4RG)rn$+YpP\g*repf6qht?1s,-l9r4;U4!4_]Iq0;UY +rcn9b!.+U%!fW%qrf$i9!06]2rf6l:pPo67q5F+9pNusfqgA?jp3c_!"Ho"7Q'V-1#FLjDQC!r* +Qi,qq_;/rnm\4s5F";rT!q=s5j7Bs6'FGrosIJ!:0UM!q#FDrpTmVs7-*Z +s7?9_rUp3arqH?crqZQiq"ssdq#/kEJcC<$MuS;~> +JcC<$JcC<$VZ5WSqu-Eiq>:0frqZHdrqHHdr:U*^rq$*Zrpg$Xr`9&!r)E\r$W0f!;GpFm<)lq! +k<;KMn<;ohm +JcC<$JcC<$WW1oUqYg?iq"t'erqZHds7cNdr:U*^s7?0Zs7--Ys6g5oWiE"pVPg;grh]V%rjMd5 +oX=e^roO+>q;_G5ro*b4rnmb4r8%D.s4dM+s4ID)rRV/&eX)X!QMZsGPk:.CZEppFZaB\>!k5VG +rNuO0"1#8=Zi.01Za0M8riuO1r42^7rO;'OpQ#!-r364)#-bDc@3hu)C6iSrkqj8\0?jo+L0bqtp +JcC<$JcC<$WW1oUqYg?iq"t'erqZHds7cNdr:U*^s7?0Zs7--Ys6ouH!/pf5s,$c3!/LQ2rJLZ7 +repK/!fc@)roO+>q;_G5ro*b4rnmb4r8%D.s4dM+s4ID)rRV/&eUW23J,autMZ8V7MYi>,N;ne9 +MY`8.N;ne9N;U6`\G`o.H2Dj]H2DjbH2W'eMZSiqMuAV,N<,'!rJpc9qMkW"Ho"7QBq62rKdJM!LT5QR.cjJQBda6PQ7!HYl(d*ZMV!.[/[Q*L\QT)LRA(-pR(lF"IPUF +R[a8G!1j+ZrLNnYq47;Nr0m];pXfArr7Ur#rnIG-r8%D0s53b4!o`.urT!q=!9O1A!pAe2rosIJ +!:0UM!q#FDrpTmVs7-*Zs7?9_rUp0`s7cHdrqZNhq"ssdp\i_CJcC<$O8j_~> +JcC<$JcC<$WW1oUqYg?iq"t'erqZHds7cNdr:U*^s7?0Zs7--Ys6oqf!*/qrs&K/#;uBMn;uTbr +<<-)!;ufqtc:1g\ok+f`9\'f)sUStiO2^;uKVf;?'Ph=8l>$nr=8,_q=8]<#Z2V'+Zi@E4 +[II5s +JcC<$JcC<$XT./VqYg?iq"t'erqZHdrqHHdr:U*^s7?0Zs7--YrpKlgWrAprVZ*FkV#Ib'[^ERA +[K!Z8[J.-/jS@j7ir7p5i;_^6hYc40h#H.-gAfk+f`'M&f)O8#Qhm$EQ2[$>P6[8UZEggDZaB_> +s0_p8rNuO0s0DX1rNZI1ZM_'.ZN%H4\,!K+N:`)0Nq&,.N;Tp[Y6(r6Z2Us-ZMq30[/[K4Zj*qH +[C3NO[/RH9[^W`S[f!T8\@;I6rh][Vqi:];s,Q]3s,d8Arf@,@q2bZ?^:sQ\"i.sk`5]mrans3] +bKTq."3f$8cMl)ebl>ldap#o.a2c0;rPST;q69k's0DR/q4[JUr1X/:q9])frQtGfr6YGjr6kPm +p!Wies3Ubkrmgqtpt,JsrRq)%rnIG-rS@M1rnm_5s5F";rSmt?jlQL(s5sCGrTOCKlg+Q:!q#FD +rpTmVs7-*Zs7?9_rUp0`s7cHdrV?Hhp\XgbpANYCJcC<$P5g%~> +JcC<$JcC<$XT./VqYg?iq"t'erqZHdrqHHdr:U*^s7?0Zs7--YrpKlHMuJV6M>i>1L]320MuSb8 +MtW)0NW/#7j8J!:iVML4hu;L1h>c:1g\ok+g&K_(fDjG%eGt-hJ,FcqJ,OirI0"eFreg`6qhkE3 +pl+p)r/CZ6s1&!9q6oj>!-n0^q0;j`!.+Wir/1W8Mi7OmoSim3NW"n7O8=k;O,j49rh][Cqg8?j +s*O9`qgJ9f!e$/lqiM&FPEhE!QM-[DQN* +JcC<$JcC<$XT./VqYg?iq"t'erqZHdrqHHdr:U*^s7?0Zs7--YrpKkhl=8Q%u +=8Gtt=8o&qVZ'Kn;?'Po;u]be;u0De;#jMh=8c5&=&rB"=8u;$nr=8,boYPGF% +Z2_--ZgLijqlFf(dkqf_sM#gA]k+h#6(/hYuF3i;_d9ir.m= +jQ5M&k5XTEkl'`IlKdd8liQSBmf)\TnGi%Xo)J=]o_nI^pAambq#1$fqY0m`r:^*Ardk*#s-!D4~> +JcC<$JcC<$YlEMXqYgd7j[/IB: +[^EQO[C3L8[eo+air.j4i;VX5hYc40h#?(,gAfk+f`'M&f)O;#eGGR.Q2[$EPPUI@PQ%ieZi@?1 +[K!Z8[JmN6Za0S:rj)R1rNZL2ZEjG8s0DI/r3ZR4N:r2.N9ZE$N;nh5YlCm2Yd1Oldb5]T``rX/trkncgrR(PkrR:Gf +s3^hms3LSlrRLhsq:GVurn72&s4dS/r8%D0s53h6s5F";ro=%>!9O1A!pAe2rojLLlg+Q:s6TgS +rpTmVs7-*Zs7?9_rUp0`s7cEcrqZNhq"smbpAN\DJcC<$PQ-.~> +JcC<$JcC<$YlEMXqYgi>2L]!&.MuSb9 +MtW)0NVhc8ir.j4i;VX5hYc40h#?(,gAfk+f`'M&f)O;#eG+OlJGt&nIe\?jMZ8V3MZ/P0N:r2. +N;nh3[f!N5[,ZH0GklXbGl3L"N;nh6N:r82NWb?%NfB(rO8=k;O,j17k'[#Rq0W0jrK-r>"d5(7 +Q'Ra0Qi36MQi*6EQNEJ;L5,S\qhG-;s-NeQpR(lF!1
!9O1A!pAe2rojLL +lg+Q:s6TgSrpTmVs7-*Zs7?9_rUp0`s7cEcrqZNhq"smbpAN\DJcC<$PQ-.~> +JcC<$JcC<$YlEMXqYgth + +JcC<$JcC<$ZiAeZq>L3gq>:-erqZHds7cNdrUp0^s7?3[s7--Yr9jdVWMl_mrh]^mV#6tf[/IB8 +[^EQO[IUd)ir.j4i;VX5hYZ./h#?(,gAfk+f_sD'f%&=MeGn"kQ2[$EPOt"?Z*:LOT1C?OSFq=P*,[*s1JBGrP&NO_8F74 +aSa0Wb5BH_bl>udc2PrebQ#`baTBN&`;[XSXSApsY5YX'YkFdiT`1YbUACPabg-46n'M$ZrQtMj +rR1Ynp!Wies3UelrmUYlrRLktqUb`!rn75's4dS/rS@M1s53h6s5 +JcC<$JcC<$ZiAeZq>L3gq>:-erqZHds7cNdrUp0^s7?3[s7--Yr9j^TMMh:f!/UQ.r/1H2rf$l8 +pP]*3rSme7qV_A1rndP.s4mV.rS%;)s4I;%!nPoPrm^tsqLAHordX]lp3d1'M2I1KMi*AhMZ8V2 +N:`&-N;nh8[J[E0Zf??2GklX_Gl*F!Mu\e5N:r82NWb?%NfB(sO84e9O8bpSHi/9kIJ/'gIJ\Eg +IJJ6jIJf3)OTgo4Q'IZ$p6YcEs-NSLpQkoHQ2[!JXSApsY5YX'Yl0@ULAll.KS>-ZLAQc*L'!^/ +Qh-UBQN3EPR/i`TSGA`ST(nlPSH#)Xe+hGkec"(qfDaG%g&0S(g]-(-h>c@3hu;R6i;hm9ir\<' +jo4BDkNM./klU/9li-8Nm/ZSRn,MnWnc&+ZoDeI]p&=[bp\Xabq>L0aqt^0^rS.=&s+138s*t~> +JcC<$JcC<$ZiAeZq>L3gq>:-erqZHds7cNdrUp0^s7?3[s7--Yr9j^T +JcC<$JcC<$[K#"\q#1*fq>:-erqZHds7cNdrUp0^s7?3[s7--YrU9dS!puqarMBRjqP4(trNuX6 +r3cL3!4DU1s5Eh4rSRV2qq_8,s4dJ*s4RG)rR_)#s4.+us3h"sdJ0"+PkpU8Oogc-Z2V!-Z2q59 +rj;^5!OfB7ZN.9,Z2h60ZN%92ZLkL&Z2fdRMtDu(NW"h8MuJV4YQ1m+YlCm4Z*L[>Z*CU@Zi7?1 +ZN.B1[Ka.H['dOn+V0OoLUCP5pjH]`5_F^]2(Q_8F74aN=G&s2k2]r6,,a +s3CPerlkDcrlPDc`l?!8_u-S6XS]."Y5b^)T_Y;YT`:\cT_b>abg"GYrQju[rm1Sjr6bJkrR:Gf +rmCbms3^enr6tJkrRLnuqq(l#rn78(s4dS/rS@M1!8mb5!o`.uro=%>!9O4Bs5sCGrosIJ!:0XN +s6TgSrU0gWnaZVLs7?9_r:U*`s7cEcrqZNhp&"R_oDRJDJcC<$R/_[~> +JcC<$JcC<$[K#"\q#1*fq>:-erqZHds7cNdrUp0^s7?3[s7--YrU9dS!UYdAM>i>1LB*)+MZ&J4 +N;nh1Muo!tiVML2hu;L0h>Z40g\fe*g&K_'fDjG%ec+(udfInEr."ZqrdXWjpO3'h!/gc4s,-r9 +M2D1gs,6`4oS`[,pp9t*!-mRMs*F]js*FWhqfqsqs,6r9qi(6.r/Uf:!07#=qMkWc=3hu2I7 +iSrkrj8\0?jo4EBk5a`Fl2U#Kli-8Nm/ZSQmfN"Knc&+ZoDeI\p&Facp\Xabq>L0_qt^0]rS7C' +s+13;s*t~> +JcC<$JcC<$[K#"\q#1*fq>:-erqZHds7cNdrUp0^s7?3[s7--YrU9dS!:BV`qc3Vpr)0rndP.rnRP.r7_2(s4I;%s475#rm^ts!RfBg<;f_q;Yj8j;Z9Vn;ZBSod;Z'Al;Z'Mk;uK\o;ZTcnoMPci%c=3hu2I7iSrkrj8\0?jo4EBk5a`Fl2U#Kli-8Nm/ZSQmfN"Knc&+ZoDeI\p&Facp\Xabq>L0_ +qt^0]rS7C's+13;s*t~> +JcC<$JcC<$\Gt:^q#1*fq"t$drqZHds7cNdrUp0^s7?3[s7--YrU9dSs6Tfarh]^mV"pbeU9h6$ +[JdQ6[J730i;MR4hYZ..h#?(+gAfk+f_sG%f)O;!e-+7Kda?JqiUN4pQ5H=rf[PN]Xthh^:sT]s1efS`5]m? +ao9B\ao0B[bQ#fdcMYrebl>lbaoof*`l5jlWr9!tXSo:#TDbG[U%k;XT`iQ_c-FW5cgT6\ci2;h +dJ_Mle+V5hdJqSgdJ_Mle,%Snec+.tfDjM'g&0P*gYCT_h>c=3hu;R6iW%p:irS6&roX7D!9jFH +s69UMrp9[P!:KjTs7$'Yrpp*\s7H6^s7ZKeqtU-crVH3ap\aX]hYr*+JcD2=J,~> +JcC<$JcC<$\Gt:^q#1*fq"t$drqZHds7cNdrUp0^s7?3[s7--YrU9dSs6]`@rJ:K/rItiD3M>iD3MuJ\8MZA_.MuJY8Zi.3-YlM$,Gj0MKHM`!fGlN'bMuS_9NW+k:MuJ\/NW"n; +N<#";O8=n:T`0<9I/&-gI/SKlHiSNbHineYO,s1"rfI>IQ'IZ$p6Y`Ds-NSLpQtoG!0m>[rN#q! +rN6'QqM,!'qh5!'!/CB+rg3/Br0IPRR@0M5rLE\SrLWhUq4.6-rR1YnqUGMprmq#!s4IA)r7V5, +gt_kas5!b5ro!h8s5O% +JcC<$JcC<$\Gt:^q#1*fq"t$drqZHds7cNdrUp0^s7?3[s7--YrU9dSs6]edq,R;kr)o<`N1$q,dMss&T2$qH")+ +JcC<$JcC<$]`6X`q#1'eq"t'erV?BdrqHHdr:U*^s7?3[s7--YrU9dSs6]jQrh]anUndp`rM0Ce +s0;X2p9jq/"LkhI[^Q1ErO2a`rndM-rnRM-r7_2(rn.2$s475#rm^tss3gno!mm0rrK[5Drfd&= +r/gu@rK$u`ril@+$*pnE[C*HMZa6t:Z2Cm-Zi%-/Zi@?2ZN.9*YQ0U[MZ&D0MZ&J/N;\_9N;eh2 +N;\\4YlCm/Z*:F9rNQI/ZEgh7[/RB4['fnAs0_m6rjDU2!1s1Os,[/@s,[2AqiUN4pQ>E;!0dAo +!PQ5H^BhWk_8=.1a2uI&aSsudc2Z#fbPfQeaMu6=W2TZoqPsOq"0A#aT)P>^T_P5X +T`:VaT`1Yab6,u5cHcC7nBh3]r6YDirR1Ynq9o/f!mo9>rQtAfrR1YnqpbVqs47,"s4IA)rRq>- +gt_ka!oDhlrnmk:_o)K6!p&J)roO7Ekl0iHl2^/Lm/QGQmeuSUnF?&Jo)J=]o_eC^pAXg`q#:*e +qXsaZr:BmFrdk*#s-s%=~> +JcC<$JcC<$]`6X`q#1'eq"t'erV?BdrqHHdr:U*^s7?3[s7--YrU9dSs6]jQs+pc6M>i>1L]3&. +L&Zr/M>W80MuJ\8Mt`/3NSiXmhYQ(-h#?(+gAfk*f_sG%f)O;"eGn"tdf.Vqd!pQDJGOcpIeA-h +I/83iMZ/J3MZ/J3MZ/P5N:;c*Mu^-XYQ/tIGl)ddHLuL]H2r6iHM)OaH?o@Frepu>N/W[Qrf$Q1 +rf6u;!07#=qi1ZJr-S?hq0hp`qKr$c!e$/lrf?r<#*G(4Q'IZ$p6Y`Ds-N_P!1EhRpQtoGs/>mq +qPsOq"0@-.K`6]%LAlo(K`?`+LAlr.R/NBBR/E9NR/WKRRf&]OSc,/USbelVci)5ddJ_Mle,.Yo +ec44ufDjM'g&9V+gYCT_h#cHjhu;O8iK00#ir\<'jo4BCkNMp0s69UMrp9[P!:KgS!q>aMrpp*\ +s7H6^s7ZHdqtU0dr;-*`pAFO\i;S<-JcD5>J,~> +JcC<$JcC<$]`6X`q#1'eq"t'erV?BdrqHHdr:U*^s7?3[s7--YrU9dSs6]jQpJpufrDW\n!)rep +s&8qsrDihrs53h4qVD/+rnIA)s4RD(rR_)#s4.+us3q"rrm:_moMkfgqGR/gs&/bls&Jtr!``2u +r)E\p"BAE#;cEBhqc*X$poj`srDNYmrDNYos&/hn!)i_nqc!Por`&Ddr)E\r!*&qtr`&ksk#MJR +r_rhpr_rhps&8eoohtigqbd/e!)rhspfIDrpK.Aq$<:&*C*^qtBsZrS[[+s+13>s*t~> +JcC<$JcC<$^AlmcpAOmdp\XpcrqZHds7cNdrUp3_rq$*Zs7$*YrU9dSs6]gPs/#mpUnja_U]-tk +TqJZrZaBJ7s0`*?[^ENO[emQ1h>Z4/g\fe)g&K_&fDjG%ec!u!e'c\DdJqSnchW80Mt)`+Mtr>1Mu0aY +Y6;,7YHY81Ylh59ZEsJ9rj)X4[JmT7[JmQ3[J[H8O-#HcplPK;rf@,@ooT39rK@#>!Kt(m]E,^[ +rkA`S_84",a2lBErlG&[r6"u]"O,09bfp%1!mJj2rQ52^`l@qSrM]^prMg9pS"-%@StD[KTqS3T +rLs.^rLa+_!29A7"3f$8cMl/aciDDgd/MAjd/DAidf%YjdeqMjcMc)fd.u)gdf._neGe"uf)=5# +f`0Y'g&g$ah#?.0h?Mlqi;^^4ir8! +JcC<$JcC<$^AlmcpAOmdp\XpcrqZHds7cNdrUp3_rq$*Zs7$*YrU9dSs6]gPs,$i6M#<&.LAZ`, +LPUfaMZ/P5N;nh1Mu\k6h>Z4/g\fe)g&K_&fDjG%ec!u!e'c\DdJqSnch;kgIK=kGomQjfs*OWh +!f2\jrJCQ3r/(H2s,6l8n;@=+Yl(^(Y5`hAH2`-WGlW*`Gl`5:q2>62!f`.trepc7pPo04rf$o< +rf?r:!.+Nhr-\Hkrd4]mp3c[_qg8EmO8Y1>O8P(DOckroQ'Ra0Qi36MQiQMdZZ +W;`dpWr%DMKS>-VLAlo,K`$Q(L'!-sR/NBBR/E9NR/WKSR[a;HpmqATq47GRr6G8erQtAfrmLep +r7(_rs47/#s4IA)rRq>-gt_nbs5!t;i8DtCOQ-9"s5X1AroOIKkih9qlK[^7m/QGQmeuSUnF?&J +o)J=]o_eC^pAXg`q#1$eqXaUXr:BmHrdk*#s.'+>~> +JcC<$JcC<$^AlmcpAOmdp\XpcrqZHds7cNdrUp3_rq$*Zs7$*YrU9dSs6]gPpf6udrDW_o!)rep +r_rhrrDiksqVD/+rnIA)rn7>(r7Cu"s4.(t!n5TGrmCbms3L77qbm2f!)ibms&&ns<)riq!*/kp +s&8nrs&8Vjr)Ea$r3-+&qG[8hr_iepr_WYnnl#Ndo2GNcs&B%ur`/qsr`/,^"&r9"<;9Dk<;oer +;YF#h;Yj8f;?9]tr)WPnr`Jnrs&KA)<)lq!<``?#<c=9hr*F::/BmKj8\0?jo4BIkNM-ol0@R"rp9[P!:KgS!q>aMrpp*\s7H6^s7ZHdqtU-crVH-_ +pAFO\ir4N/JcD8?J,~> +JcC<$JcC<$_>i3fpAOgbq"t$drV?BdrqHHdr:U*^s7?3[s7--YrU9dSs6]gP!:0W\"/M]fV#I+i +U7qRZ#bS9(Z*L^D[C5n=#.D"M[C*HOqmZU]rnRM-qqD)'rn./#s475#rRCkrs3gnos3LhncHc0K +qNLc=qiUf)rRq>-gt_nb!oDi7rPSZps5X.?!9O4B!pAe2rojIKli-8Nm/ZSQmfN"Knc&+Z +oDeI\p&Fabp\Xaaq>C*[qt9mZrSmg-s+13Bs*t~> +JcC<$JcC<$_>i3fpAOgbq"t$drV?BdrqHHdr:U*^s7?3[s7--YrU9dSs6]gP"7(f"M#E,.LAQ]( +LB`QkMMd=LMZ/P5N;eb1Muo!ph>Z4/g\]_)g&BY%fDjG%ec""te,RkqdJqPpcd'i1J,auhIK+]p +Hhi!fM#W;3MZ&A3MYr>1MZ8V7N!"uqMi..bs/u4#s*EXLq0;g_!IB%eMuAS9NJrhqMuJ\0NW+t; +N<#"-VLA6K&LAI8-R/E9NR/WKVR[]e:SGA`RT)"rUSGpe/cMc)fd/25idf._o +eGe"uf)=5#fDsV'g&g$ah#?+2hVZWXNsCd+ioB([jQ6C'!pAe2rojIKli-8Nm/ZSQmfN"Knc&+Z +oDeI\p&Fabp\Xaaq>C*[qt9mZrSmg-s+13Bs*t~> +JcC<$JcC<$_>i3fpAOgbq"t$drV?BdrqHHdr:U*^s7?3[s7--YrU9dSs6]gP!:0J]pf%Q"<)cdq +<)Zap;uT\l<<#ns<;fhs<<(eRh#?(*gAfk*f_jA$f)O;!eGn"tdf.YociVP=cLXs(;u';o<)Zaq +g;ZK_p;uBVk)!o)Mc +rnRY4hfeuo#>a@=j5]4]jo4BDkNM./klL)8rp9[P!:KgS!q>aMrpp*\s7H6^s7ZHdqtU-cr;-!] +p&+I\ir4N/JcDABJ,~> +JcC<$JcC<$_Z/?hp&4abp\XpcrV?BdrqHEcrUp3_s7?3[s7--YrU9dS!:BaOs6BZ]r1s@f"eq]` +TV%kUSd2F%Yd1UB[C5n=s0`-@[C*HO\%)@Fs4dG)rn7>(r7Cr!s4.(ts3q"rrmCbms3L\i!6t)! +!0d8BqiUZ8(6>])Z*:I9Yck77Yd(L>Za7$GZEga?rilC,qm-1,!j\r1r2fpX!0$l7pknm*repi8 +rJ^E-rf$i7ric7(s0)I-!jAi4rNZC.!42U1s0Ma4"LY\H[C-"@rNug;O,f6]O8P.6OSOt6OSt:A +OSk7@OoW,j]F;Kf^V@S"_84%.a2uI#aSsogbfft-!QiF^V#@.hVZ!CmRJ`NR +SH#,bStD[LTq\9TqOmbY!m/U-rlb>c!6tMgs3LGdp! +JcC<$JcC<$_Z/?hp&4abp\XpcrV?BdrqHEcrUp3_s7?3[s7--YrU9dS!:BaOs6BZ@r.k<,r.Y*& +reCW4M2@+Jre^`8MuAV7Mu8M6NW+n:NW7c1gA]e*f_jA#f)O;!eGn"tdf.Yod/VGkc2c,bJ,aug +IK+]pHhVjcM#W;3M#N52MYr>1MZ8V7Mu\e8MY)i,Xo,:#HK0;DGl)adMYW2/MunutN;eb6N;/D4 +Nr=q;NrG+>NWaZRH$Xf6HhVp`Hi8?fHi/9kI/o?*OT(==O9gu4Pa.Q#Q^=*8Qi36KQiEEQRJiNK +Qid@jVu;5JK)1*$KS>-VLAur-LAZ`+Q'V<6nX06@!1 +JcC<$JcC<$_Z/?hp&4abp\XpcrV?BdrqHEcrUp3_s7?3[s7--YrU9dS!:BaOs6KP^p/D,o<)cfp +<;ohr;YsGn;uTbqd@jVuBZp;u]hp +JcC<$JcC<$`;eTkp&4^apA=gbrqZHdrqHHdr:U*^s7?3[s7--YrU0gUmHsl=!pf.:r1s@f!MZ:d +TDb>fSZ]-"Z*LaE[^Q%?s0`'>[^EQPrjVj9rn@A)rn./#s472"rRCkrs3gkns3LblrQYJhbfosK +!0d;ErKI/BrK.,BOnOn:YQ(j-Yl(^(YQ1s,Z2h61Z2Cj+Z2Cp*Zi7$)WW\cec-+8]TDkM_ +U&1M]TE!%5b5TTabQ,oecMl/bd.P]bd/;;ide_Gjdf7\pb5'6[bl,f_cMu5id/;;kdf._oe,n1O +f)=2%f\+sWg'$0ch#%'H_ZA`Uro4%?jo4BDkNM./klL)8rp9[P!:KgS!q>aMrUU![s7H9_rq??c +qY:$bqtfdYp&+L]jo0i2JcDMFJ,~> +JcC<$JcC<$`;eTkp&4^apA=gbrqZHdrqHHdr:U*^s7?3[s7--YrU0gUmHsl=!pf.:r.k<,s+U6$ +rJ(]8M2I4LMMd@OMuJ\8Mu&D2NW.Z2g&BY%fDjG$ec""te,RkpdJqPnci),jc-4E/J,aufIK+]p +HhMd]M#W;3MYi81MZ8V7N;nh9MY2o,X8]-VH1uRZGlW`tMuAS9NJrhqMuAV0NW5%;N<#"-TLAcf-Pa.R3Qi!-MQhZsGQN3EPR08tJS"-#ESberUSc>2[b5'6[bl,f_ +cMu5id/;;kdf._oe,n1Of)=2%f\+sWg'$0cgr@J5NrkF%ir7s=jQ6C'!pAe2rojIKli-8Nm/ZSQ +mfN"Knbr%YoDeI]p&=[ap\O[`q>:$Wqt9m[rT4$0s+13Fs*t~> +JcC<$JcC<$`;eTkp&4^apA=gbrqZHdrqHHdr:U*^s7?3[s7--YrU0gUmHsl=!pf.:rDibpr_r\n +s&K(u#uaf&jAp;cH^pr`&hps&8tuq,@>mr`&kqpJh,lri?$u!)rhojAY\Kr)*Glqc*Dlr`&ksoiD)mqc<_r +r_rhrr`&qtpJV&ilr!^Zs&/nur`Attq,dSup/h8prDibrr`'&$='&H#=8nukV#I1jVY='Z +JcC<$JcC<$`rFloo_nR_pA=gbrV??crqHHdr:U*^s7?3[s7--YrpTmTs6]gPs6K^M!9sKYrhBLf +T`(M]T)Y>gXfeh1Yd(OA[C3O?[0="J[^EQPrjVj9!87A(qq(l!rmgtss3q"rrR(Yls3L\is31Vh +bKKgJooo?;rK6r#*4eJYHY:9ric@)rNQ:+!OB'2Z2Cj*Z2M!,Zi-p(WW.qWN<"q-MZAY0 +MuAS7MuJ\7Mt`2/YPbX)YQ(j,YQ(j+Z2V$0['Tb=s0Da5[JmT7[JdH6[?$CHNWY?(OHK@#!0R5A +qN(?3!0R5Crf[Ao]D9)O]t_=t^qmn*`5]j>aiMNCaN4>%qo\r^!R/gdbQH,6bfg".s.TCcrhKFf +qO.AP!LoVXSc>8]TDkM`U%k;\aT0K]bQ#cdc2Q#fchYr[cN;J@df.YmdeM;jdK%\oao0BYbPo`a +c2>ldci;AidJqYpe,@ereH"2!f)jUXg&B\,p%ZK$_ZA`Uro47EjlPXekND(.klL)8rp9[P!:KgS +!q>aMrUU![s7H6^s7ZHdq=spaqtfaXpAFU^k5Kr3JcDPGJ,~> +JcC<$JcC<$`rFloo_nR_pA=gbrV??crqHHdr:U*^s7?3[s7--YrpTmTs6]gPs6K^M!9sKcr6G;fs3U\ks3gqrrRCkt!7q,#!nc2Zrn7Cg`;>VpO9+>"ro47EjlPXekND(.klL)8 +rp9[P!:KgS!q>aMrUU![s7H6^s7ZHdq=spaqtfaXpAFU^k5Kr3JcDPGJ,~> +JcC<$JcC<$`rFloo_nR_pA=gbrV??crqHHdr:U*^s7?3[s7--YrpTmTs6]gPs6K^M!U3V^<;fbk +<;ont<<#nqmr`&kqpJh/mrMomsr_ieroi(cds%rbop/:rhr_r_mq,.)hqGd>l +r`&ks!EN4p"ldci;Ai +dJqYpe,@ereH"2!f)jUXg&B\+DK,MJr_ +JcC<$JcC<$aT(,ro_nO^p&"^arV??crqHHdr:U*^s7?3[s7--YrpTmTs6]gPs6K^Ms69QZs.]Uh +T`(M^T)5&cXfeh1YHbF@[C3O?[0X4M[^ENO[^WaE\GXtYf)F4teGn"tdf%Snd/VGjc2u87bl5cc +b5RXuPPgUBOnt.@O,f8!O8k4?NW-*fYd(I9Y-5"2YHRl.!O8s0YlM!+Yl:p+ZMh-.W;_bTN<5&s +MuJV-MZAY0MsZK&Xobf0YPbU/YHY77YHY81Z2V'/Zi7<6Za@*IrjDg7rj2`eO,s-trf?r9bfe/OT_Y;]UA:5TRK8nJ +rLEt\TCnlUaT0K]bQ#fdc2Z)fchc#\cN)>kdK%\mdeD5jdeq2bao0BZbPo`bc2>leci2;idJqVp +e,@ereH"2"fDjJ*g"Plarl"WM!TE&;is4Z,jlY^gkNMp0!UB"Mm/QGQmeuSUnF?&Io)J=]o_eC^ +pAOa^q#'saqX47Sr:^*Prdk*#s/#aG~> +JcC<$JcC<$aT(,ro_nO^p&"^arV??crqHHdr:U*^s7?3[s7--YrpTmTs6]gPs6K^Ms69Q=s+^Q- +p4WI"!/CE,#)J+nMi3INr/CW5qi(K5r7Cu"rmgqrs3q"rrR(Yls3LYh!mSs5rlY;ardXfos*alo +!.Fios*a]j!.4BbqhY9-reLT3M#<,/MYrD4MY;u,W;(Z;Gk64ZHKoeUM>iD0MuAS9NJrhqMu8P1 +NW+t:NW+8#H1lRYHh;^^HiK0-O84kJO-#HaO-#HdPa.N"QC!r*q3V&Grg3YPs-`hQrKdMWq4[h_ +q1JNqr.>!&re:3's+gTle +ci2;idJqVpe,@ereH"2"fDjJ*g"O'OqiCZ:!TE&;is4Z,jlY^gkNMp0!UB"Mm/QGQmeuSUnF?&I +o)J=]o_eC^pAOa^q#'saqX47Sr:^*Prdk*#s/#aG~> +JcC<$JcC<$aT(,ro_nO^p&"^arV??crqHHdr:U*^s7?3[s7--YrpTmTs6]gPs6K^Ms69J]r)<;g +r`';);c?Xqleci2;idJqVpe,@er +eH"2"fDjJ*g"L1Wqb@#a!`.e7ro47EjlPXekND(.klL)8rp9[P!:KgS!q>aMrUU![s7H6^s7ZEc +qY:!aqYKXWpAFX_kPg&4JcDSHJ,~> +JcC<$JcC<$aoC8to_nO^p&"[`rV??crqHHdr:U*^s7?3[s7--YrpTmTs6]gPs6B[MrTOH\USFQV +rLX(]q4.qaX/rJ,YHP18['d?Nq6^I9\$`WP[^WaD\Gt.Zec""se,RkpdJqSnci)/hblGudb6,o/ +acuF]rK@,Aq2bT;pPo65riZC-Z*F50qQBq(Z2(X'Z2M!-Zi6m#N!#&uN/RUks,6`2s,-l7pl"^% +",i+sMuBd[YHG),YQD#4Yl:j+YlD!-ZN%9/[/[Q6[K%)0Kk^qde'`5Ta:aiXM%!6G)[rQ>,_qTK)ebfn8QrLa%]s.T.Sr0dYUSGo)ZScGDW +TE*.5aT0K]bQ#cfc-FW3chl)]cN)Agde;,i`r3sSaSs<\b59B]bl5lccMu5jd/DAldf7eqe,n1O +f)F8'io]OorP\QM%H-4)ioB([jlPXekND(.km-M>lg4!*mI'rA!q>aMrUU![s7H6^rq??cq"Xd_ +qYKUVp\adakPg&4JcDYJJ,~> +JcC<$JcC<$aoC8to_nO^p&"[`rV??crqHHdr:U*^s7?3[s7--YrpTmTs6]gPs6B[MrTOE>L5(EU +K`6Z,KS>0XLBWNlMi3IMqi(N4r/CQ5s472"rRChqs3gkns3UelrQbGf!6kDb"3Sa-J,+QmIIhj_ +Hi&-hHN8BhM#W8/L]N?gqhb?1rJU]5pP]$Kqg&!^s*=Hcqg&0ems,+^H$OXjLl)+gqht<0rep]5 +qMkN8rf-Pqr-A?gr-J0coR-L^"-8P*O84kJO-#HaO-#HePa.N"Q^=),q3V)HrKmPOs-`hQrg3SU +rLj1ap4N3nre(3'pP&[5rfdGKQMQsGR/NBKR/NBOR/WKVR[]e:SGA`LScHe/a83mVao9H[bPo`b +c2Grfci;AjdJqYpe,Ihue^i=Nf)r4^\%DR!qiD9FiSrkWj5f=`k2tjikl0fOlKdd&m-X3.rU0gW +naZSKs7?9_r:U'_rqH3_r;$3cmJHYUp\j:SJcC<$VuM8~> +JcC<$JcC<$aoC8to_nO^p&"[`rV??crqHHdr:U*^s7?3[s7--YrpTmTs6]gPs6B[MrTX;\r)<>h +!`N&trDikr!*&qt"&r2t;YsGn;uK\nlr`&eqpf@Aor)EYo +p/D#jrD`eq!)iAbr_iSirDrkur)WVps&etrs&T,!r)Wbr!*9#!rLa%]s.Ss^nl>Zgr_ihslg4!*mI'rA!q>aMrUU![s7H6^rq??cq"Xd_qYKUV +p\adakPg&4JcDYJJ,~> +JcC<$JcC<$bQ$Q#oDSF]oDAL_rV?!+r/:T6s,6cW +!3c=)s/uF,ric@+s0;R/s0MX1!4Dg7!O[paNr=t8NWP9'OT(@EOHGZepQ,-3!KiQAP5r5o\cBA< +]F;Nh^VIY$_SjF5aN;O%`rO3Yao0B\bP]Tac2Yufb5._0TD"]KRKT+MSXlAOTD>/[b5TN_b5BH_ +bQ?&7cMPrbd.u#fcMl,idJ;5be,I>b`r=$TaSs<\b5BH_bl5lccMu5jd/MGmdK%bpe-=ISf%Jj; +jnm!m_[YP_io9"YjQ,Fbk3(pkroj[Qlg*p(mHs??mfN"Knbr%YoD\C[p&=[ap\=O\q>'mSqtU*` +rTO63s+13Ls*t~> +JcC<$JcC<$bQ$Q#oDSF]oDAL_rV?.N;eb4N;S\7 +NW>(.H2`-hH2;jaHglF_O8k:AO84kJO-#HaO-#HeQ'IZ$Q^=),qNq/HrKmPOs-`kRrg3JQs.At: +q1ATu!/1?*qM#',Q'M?5!L8uIQi*6LQi!0KQiEHPR08tJS"-#@Sc#)Y`VmgUa83mVao9H\bQ#fc +c2Grfci;AkdJqVpe,@c#e^i +JcC<$JcC<$bQ$Q#oDSF]oDAL_rV?tt<;okt<;ohg<;fhpeGn"sdf%Snd/VGjcMu/hbl5fcao]]+aSo*<;X[Q_;Z9Vn +;?0Yo<;]\p<<#nr<;oec<<#nq<;onslrD`_q +qc3f#<`W5t<;ohc;ufkl;Yj>d;Z'So=8Z+q=8uCr=8u>"lg4!*mI'rA!q>aMrUU![rq--]rq??cq"Xa^ +q>0LUq#'mbkl-/5JcD_LJ,~> +JcC<$JcC<$bl?]%o_nL]oDAI^rV??crqHEcr:U*^s7?3[s7$*YrU9dS!:BdPs6K^MrosIH!p?>P +rh'1]r13YR%'-J3Y-+t3Yd1XD[C5q>qmQL5rODjUs3ghms3UelrQbGfs31Jcs2tA`rl>)[nWX!9 +!g/S,qN(]QMu/G5Mu/D0M><&+Mt`2. +MuJY9MlllZ!3cC+!O8m,YPtd*Z2_-/Zi.6:[C3N&N/`gWNqeV5NrP1?O9:W,O-''rq2bW>P5:@C +]"@sQ!5&*?!58BH$,FBo_o0O6aN;O%`rO3Yao0B\bPfWhc-FSXbab4%Sc>;\R/`TSR/<6b0'_*!6Y5_rlbGgcHc=5qp>/brQYGjdJ;5ce,RA_`W!mUa8F$Xao9H]bPo`c +c2Q#gci;AkdJqVpe,Ii#e^2dtgr9-.qSNd#iSieVj5f:_k2tjikl0fIlKeH9s6TgSrU9dU!:g$Y +s7?6^r:U'_rV-']qt^$`n,)kWq#0IVJcC<$WrIS~> +JcC<$JcC<$bl?]%o_nL]oDAI^rV??crqHEcr:U*^s7?3[s7$*YrU9dS!:BdPs6K^MrosIH!p>;l +q1Sa$q1Jd&LAHZ/M2I1KMMqCkrJUT4rJgg*s3ghms3UelrQbGfs31Jcs2tA`rl>)[qL8Elq0`3h +!.=WirHeBgqKhsns+gN.qhb?1rJUZ4q256Kq0D^Zr-.p\np1.XrcnKgreUT2s,-]3qMbE3qi(H4 +s,Q8fr-J6en9k4rs,[5ApQ5B8$BUC6Q'IZ$Q^=),qNq/HrKmPO!1EeQs-NbUrLNt[rdt0&s+:'! +r.=j!s+LB*qhG6;Q'M?5!L8uHQi3 +JcC<$JcC<$bl?]%o_nL]oDAI^rV??crqHEcr:U*^s7?3[s7$*YrU9dS!:BdPs6K^MrosIH"6WW^ +;tj8e;u]hptt<;okt<;ohh<;fhre,RkodJqSnci)/hc2Z#ebQ#`bao9?]a5p8!;?0Yn<;BGo +<)Z`pg<;T\o<;]bo +JcC<$JcC<$cMuu)o_nL]nb`7\rV?s6B[MrTOIKkND!$ +rh'1]s./hQs/QF,Xfeh1YHY:2Nr>"=Nr4t9NW>.:O91Q-P5:CB\cBAA +](ru=^&GbQ^qmn*`5Ta;aiOG$qoSfZrlb5`"3o-9bl!t1SGnlOR.m$JRfAiWSGo,ZT`1VgTZ>-p +b0'_*!6Y5_rlbGgcHc=5qp>2cr6>>idJ;5ee,R;`_u@UO`W!mVa8 +JcC<$JcC<$cMuu)o_nL]nb`7\rV?s6B[MrTOLLkNCu] +L&?W(L%U-!K`Hl(LB*//MZ8V5N;\\4N;eh:df%Smd/VGjcMu/hbl,]db/qd)aT'9^`dWC8I0>"I +I=-G@HN8HhHNJM?Hi/3fHhr$gH2*3qL\uu)M>rJ4MuJV1MtqYdGl;jcGk64XGlN$hGlrJ0 +Mu8P4MuJY8MuJ\6NV.PsHLlF[HMi$gHN&9_I/K&uOT(:JOHGcmQ'R`&Q^F0:Qi36LQiI!gf:ArgNapQ5E;%H-4(ioB([jQ5OdkND(.klU/9 +li-5PmI'EAn,MnWnbr%YoDeI[p&=[`p\+CYq>'mUqtU*arTaB5s+13Ns*t~> +JcC<$JcC<$cMuu)o_nL]nb`7\rV?s6B[MrTOFJkND"& +<:j)h<;T\q;ZKeq[;YX/j;Yj8i;ZBYq;Ya8f<;]bo<;]brnf<;]\m<;oho;Yj>j;YsAm;YsMm=8c1q=8uCr=8u>"'mUqtU*arTaB5s+13Ns*t~> +JcC<$JcC<$ci<,+o_nL]nb`7\r;$3arqHHdr:U*^rq$-[s7--YrU0gUmHso>s6B[MrosIHs6'FE +!2'4]!1ihRr0m\eri?I/Y-+t3Z*UgF[C5q>qmQO6rj`!Us3UbkrQbGfs31Gbs2k>`rQ#,^`l?!: +plYW@rK@2CpQ5B8qi:B0!3Z7'!jJr6riZ4%r2p((Yl(^)YQ1m+YQ;#7rf$c5qMbE3onrI$r/CE/ +rf$fX!NrR'Xp)#5Yd(F:ric@+qm$1,s0M^3rJU]7mZ%4+!0-r;r/L`:qMtZ=Oo1CBPQ&,q]=PSc +q7H^@rkAZQ_8=./`Q%nurl5#[qoSi[rQG,_!mT$8rL3bUqj7/HpR2#L!h5^Nrh'1_s.Kh?a2l?E +b/qcJbKJ-/bPo]ec-FW4chl)bci),icd;F7r6kY^qni"k(-#_o^4&`VROL_uJX&iSrnXjQ,Fbk3(pkrojLLlg+Q:!q#FDrpTmVs7-'Ys7?6^qt9s^ +rV-$\q>'j_n,)qYq>KRWJcC<$XoEn~> +JcC<$JcC<$ci<,+o_nL]nb`7\r;$3arqHHdr:U*^rq$-[s7--YrU0gUmHso>s6B[MrosIHs6'FE +re1E,Kn]5Rr.>!'reC<*#De4oMMm@MMuJ\6Mu8P5NW7E+d/MAicMu/hbl,`baoKQ^a99Q'`l5pr +I/eWmI.Vd]HMr3dHN&3bM#W8.M#)u.MYrA4MYrD,H16(UGQ)j]H2)X`H2EC!M2I2eMu8P5MuJ\8 +MuJ\8NVdtsH2W'_GlW*fH2W!eH2W'`HiJKjO7eV6Ns:]/Pa.N"QM-[EQMm0GR/NKRS,7d5K):3" +K)L?$K`6])LB!&+Q2d'MQ'Ra3QiD+J_u@UO`W*sWa8F$YaoBN^ +bQ#cdc2Gohcd:& +JcC<$JcC<$ci<,+o_nL]nb`7\r;$3arqHHdr:U*^rq$-[s7--YrU0gUmHso>s6B[MrosIHs6'FE +qc*&`!`W0!rD`nu;cN`r!EN4l<;ontdJqSmci)/hc2Z#dbQ#]bao09`a2Z-<`V<=2;u'>f;tj8b +;Zp&u<)cfq#D+J_u@UO +`W*sWa8F$YaoBN^bQ#cdc2Gohcd:&'j_n,)qYq>KRWJcC<$XoEn~> +JcC<$JcC<$dJr>-p&4U^nGE+ZrV?s6B[MrosIH!9a@D +!9O0N!1j+Z!1WnVq3qemX/rD)Xfeh1YHY=>p9jh,rjN!>d*L&9cMu/hbl,`bb5]T_aT'9\`r3jW +`09kWs,m&;rf@#utqMkW&[qoSl\rQG,_!R8phQiNQKQhm*ERJiQUS=Q8NT*V*`TuP*m +aN2O'aTK]/bKTt/rlbGgcHc@6rQkSkd.u#dc2l8a +s31MfrltVld*U2>^&c$dqo/HNq8<6j$fU+*j5f:_k2tjikl0fJlKdd8liQSBmf)\TnGi%Wo)A7\ +o_S7[pAF[Xq"aa]qXOIYr;$ +JcC<$JcC<$dJr>-p&4U^nGE+ZrV?s6B[MrosIH!9a@D +!9O36!JZ=-KE-Z&K_^9#L&Zo(LBWKjMM[4Jrepc7rJUT4"-([Rchu)gc2Z#dbQ#`bao9B]`rO-X +`;mjPI.Vd]HN&9kHN&3fHMr*hLA6T)L\uu)M>rJ5MZ\ipMi.Ikpj):Pqfi'bpj)RXs*4ThqhY9/ +!/gW2r/CW5rf$l8rf$\urH\'^qg%p\qfr0fpj<$gqN(W;!0@#=!KiKCNs1W.Pa.N"qj.;KrKmJK +rKm8G!1ES4qL\?lre19)!euJcqj%/F!gT(;q3V)JrKmJM!13PLrL!\TS,JlMSc6G(_>D+K_u@UO +`W*sXa8F$YaoBN_bQ#fdc2Puucd:%dQBd\uQBIAmOHG\$OSb1?i!\N'j5]4]jlY^gkNMp0!p]+; +rp0^RmdC)Cs7$'YrUTsZs7H0\rq?9ap%\@Yq>0XYq>C'elMcA7JcDnQJ,~> +JcC<$JcC<$dJr>-p&4U^nGE+ZrV?s6B[MrosIH!9a@D +!9O,Xn5BBd;cNWo!`W)tr`'##g;ts8h;u9Ji;ZTirq,[Gqr)WVps&f8%s&T/$!*9)#!*9%uqc<\r!EN;$QiNQR +<;BJi;Y3o_<<6&tr_i_o"]SK&<``?#cs3:Pg#g^lEd8j7G;cN?_r([_ti8ESRj5]4]jlY^gkNMp0!p]+;rp0^RmdC)C +s7$'YrUTsZs7H0\rq?9ap%\@Yq>0XYq>C'elMcA7JcDnQJ,~> +JcC<$JcC<$df8J/pAO^_nGE+Zr;$0`rqHEcr:U*^s7?3[s7--YrpTmTs6]gP!pf.:rosIH!9a@D +s5j9Ps.'.[rgWhUqO@JS"0/E&XT#@%Y5b[,Z*Uh3[/m_FrjMg8!4`$RrltJerQG5`s2k8]s2Y/Z +rl+oU!5n_us-!>E!0[8BqN1`utqMtT:rK.&A +s,mGI]"@sQ"1u.U]D9,>^AkqS_8=+.`Q#s>aiOJ%s2b5^!6G/]s2t;`rQGJjcBjocQ'V02r0[8I +rgNkVs-s:aStDXJTuI#N!QW:ZaT0K\bPo`bcMZ#ed.biicHXVZcdDF6qnN-Grk\KKrkn`RrPecU +s2Y)Z!m/U-rQ>8dc-?75!71SW!5JBLqo&?Krnmh9ir7s=jQ6C'!U&\GklU/9li-5PmI'EAn,MnW +nbhtXoD\CYp&4U^p[n7Wq>'mXqt^0crTjH6s+13Rs*t~> +JcC<$JcC<$df8J/pAO^_nGE+Zr;$0`rqHEcr:U*^s7?3[s7--YrpTmTs6]gP!pf.:rosIH!9a@D +s5j67!JQ4+KD^DtK*6j^KnY9WLBNHkM2I2hMuSb7Mu8M6NW.6&c2Z#dbQ#`bao9B]a8a0Y`W*jV +_tJKPHhi!eHiJEjH2N!dGlWToM#W8-M#W;3M#E2/MZ8V6MYDDaGl)^aGklXVGl!6rM>rJ1MZ\or +N/[aorJ^`6q0;g_s*FTgpNl^^rHS3brHeBgrd=^+!0I/?s,d8Ar/gr@rf7/COcu(0QM[!OQC!r( +Qi36KQi!-OQ^F05Jc(,mKDU?%K`[!aPkp[EPQI,9QMQsHR/NBMR/`NMR/NERR[a,CqjmW!rkSNL +qni?Mrl"cSrl4uYrQ#&^b0'\+!mJp6rlteqR$X,(P`q;or/pl +JcC<$JcC<$df8J/pAO^_nGE+Zr;$0`rqHEcr:U*^s7?3[s7--YrpTmTs6]gP!pf.:rosIH!9a@D +s5j2YmSa3b;c?Zm$D+K_u@UQ`W!mWa8O'\ai_d)b6#o4c2PumcWO@N0[Zq>C'eli)J8JcDqRJ,~> +JcC<$JcC<$e,SV1p\jg`n,*"Yr;$0`rV-I+YHbC?[.q'/[KX/rH#Y5tl4rN6.&riH(#!NrX)Y5b[+Ycmq_qMY<2 +s,6i5s,$]3s,$H,p5Ag*s,6]Ts/la3Y-5%5Z*:I9YHY81Z2_-/Z29FXMu&CsNVSV3O8b4AOcoUQ +s18^AkqS^r""-`Q#s>aiOJ%s2b5^!6G/]s2t;`rQGMkQBmc"Q'I[3Qhm*JRK&ZQRJr]S +Sc>;]TDlh0`W=-$r5er]qTJo_rm(GfrQt;b"jYB;cHsu4df7#[^AG\E_#D1J_Z%IQ`;R[T`rF*X +aT'?^b5KKbbg"E3^&>\@`Vd[N_uIUQhuVfrro4%?jo4BCkNMp0!p]+;rp9[P!:KgSs7$'YrUTsZ +rq-'[rV$-_o_A7XqYKd[qY^0fm/DS9JcDtSJ,~> +JcC<$JcC<$e,SV1p\jg`n,*"Yr;$0`rV-93repc7s,6Ysnp0kRp3HX`r-SEjrJpr?rK$u?s,[)>s,m;A"-AY/Q2[*LQN3?N +QNWV@Q^4!:QMm0JR/`KPJG4WkK)L?%K)L>sK`?c*Pl$aFPQI,9QMQsHR/NBMR/`NMR/NERR[`u? +!hI$0sYqtg6drTsN7s+13Ss*t~> +JcC<$JcC<$e,SV1p\jg`n,*"Yr;$0`rV-kc2Z#cbQ#`bao9B]a8a0Y`W*mV_uIUQ;XIE^;Yj>j +;YF#l<)Zaq;u9Ms;c6Lm(='&F'rDies#Zk&, +EO;cENlr_reqq,@;krDW\ppJq5ms&/nqrDNl!?b96=B8Go:&%K_huVfrro4%?jo4BCkNMp0 +!p]+;rp9[P!:KgSs7$'YrUTsZrq-'[rV$-_o_A7XqYKd[qY^0fm/DS9JcDtSJ,~> +JcC<$JcC<$ec4h3p\jjan,*"Yqt^'_rV-S,AfKRg#7ZWiE,$riQ1&"L#&7ZaBM8s0hp9!k,SIrQG2_s2k8]s2Y/ZrP\iV_o)Jj +s2"Al!0[;CrK.#>r/Uf:q2G'-"0/E(Y5>C'Z*4/0"0JZ*XSo7%Y-7c+!jAhfrf$T0!0$o8regW1 +!/g]2pkf'.regZ4pPK$1MMh22%'H_7YHP18Yct=7Yd",3s0;X0pPJs/pl,64s,?i7q2G<4q2Y?5 +s,[AEOcm8cr4;p?!4qs<&&#]l^VI_(`5Ta:aN;NDa8X0[aT0E]aoBN_bP]QcQ'7F2PlI!KQMQsG +R/WNOR/`QWR[]e:SbnuY`;[^X`lH0Ar5er]q9&c_rm(GfrQt>c!7(Sg!m]0?pX9#Qrk8'm`o_\L_qYfd[JcC<$Z2]=~> +JcC<$JcC<$ec4h3p\jjan,*"Yqt^'_rV-93repc7qKVISr-IdVrd+Qjr-\F'!0I/?s,d8Ar/gr@rf7/CP*D72QN*9WQC!r(QC!r( +Qi36LQi*3PQ%+;_JG4WmK)UE#K)UDsK`./3Q2d'LQ'V64rL!PMrL!SNrL!POs-`qWopkunrk8 +JcC<$JcC<$ec4h3p\jjan,*"Yqt^'_rV-b5]T_aT'<\`r3jX`5BLl_Z.IL;Xm]b;Yj>i +;YX2j;?]uu<)Zapqc*So!`Dutr`&eq!`W)sr)ESms&&hor_iVlrDNYmlVd^\p/:oh##\K%<)Zap +r_i_oq,I;mrD`Jg!)rbmqbmJoqG[Akqc!MoqG[;irDN\opK%2nrDr_qs&f5$s&K>*<`W:'<`]0! +r`9&#s&K/#Q2FSQ<;]\m;Z9Vn<;9Jn<;KMs<)lt#='#6!s&B"urD`\pq,@>mr_`er<)iTlrOi-C +rkA9Es1nWMr5/KOs2=lTs2P)ZrlG,]!6Y8`s'#D+!a8`.ohG-T"Q/.qiSsjs!T`AAjoOZ/rosIJ +!:0XNs6]jSrpTmVs7-$Xrq$-]q=X[ZqtKaXq>'m`o_\L_qYfd[JcC<$Z2]=~> +JcC<$JcC<$fDk(6p\jjan,)tXqt^$^rqHBbr:U*^rq$*Zs7$*YrU9dS!:BdPs6B[MrosIH!9a@D +s5a7Aro4'MS"';FoUGiK"K/9"X/u9%riQC-Z*UgEppL.1rO2pQb0%iJrQ,#Zs2P#V!lW!orke]O +s1nJpqNCl@qiCf=qi1Z9o8N^/rJ^cV!irE*ql^7/YHG%1XfST$XT,F'YPkU,N/`gUN;8D2N;eb4 +M>rA5M26ueM>N2-M>`>2M$&QjM2M4f!K)a4XT5O%XTkr1Xfek3Z2Us.YH\#2s0;W]pPS^'pPf*0 +r/CZ8pl>95s,d8A!K`HC\bs&=])]G;]FV]i^V@S$_o0O6a2lBDa2e2#s2bDbaiV]JrQG/`!L/fG +PQ7!JQMQsIR/WNMQj&nHR[]h)[s2b;abPo-R]`,SE`:q7L`;RUN_?AcSi8N\pirS6& +roO7Ekl0iHl2^/Lm/QJQmf)\TnG_tUo)J=[o_J1XpA=UUq"jg`qXj[]r;$ +JcC<$JcC<$fDk(6p\jjan,)tXqt^$^rqHBbr:U*^rq$*Zs7$*YrU9dS!:BdPs6B[MrosIH!9a@D +s5a7AroHb/qd(aT'<\`r3jX`5BLl_Z.IP +_"N0THi&-hHi89iHi89hH2N!gH2i3hH2WHtL[p9$M>rD1M>iD3HN/9gGQ<$bGk6.VGlN!fGl)^a +Foul1G'Ek-!I&_cL]E;0M#W;3MYW/1N;\Y7N;.Y`H2`'YH2`-iHiAElHi&j(OSt7?OT1C>OT1IB +NsCc0Pa.Q$QC%T:#+(XAQ^=#)rg*MLrL!G3p4<3pre('!re('#r06r@s-EJIrL!SNrL!SN!LT;S +R/NERR[`u?rk&'?rk8)[s2b;abPmh-Qi:$\qtg6drU'T8 +s+13Us*t~> +JcC<$JcC<$fDk(6p\jjan,)tXqt^$^rqHBbr:U*^rq$*Zs7$*YrU9dS!:BdPs6B[MrosIH!9a@D +s5a7Arob0%iJrQ,#Zs2P#V!lW!orke]Os1nJ/ +k>V=Wr)V7N_uI[R`W*pXa8X0[aT9Q-r`T8)s'#M-9_M3Q:'BJ4 +i8N\pirS6&roO7Ekl0iHl2^/Lm/QJQmf)\TnG_tUo)J=[o_J1XpA=UUq"jg`qXj[]r;$ +JcC<$JcC<$f`117q#1!cn,)qWqt^$^rV-OTSXuFk_o0Lm`<4-#aN4>%rlY,]"3f$8cMZ#ed.biicHXVZcd;L9rji$>rk&'?s1SEG +r4i9Is2"ZNs24lTrl+oW!6>)[!QhqO]DoMD^&GtE`VmaS_u%:S_;F2/iSsjs!T`AAjoOZ/rosIJ +!:0XNs6]jSrU9dUs7-!Wrq$*\q"=RYqtK^Wqt^-cp&"U`qYfg\JcC<$Zi>O~> +JcC<$JcC<$f`117q#1!cn,)qWqt^$^rV-O9gu1O,oBbPEhI4Qhm!J +Qi*0JQiEHQJ,k0!JFnElK)L?"K)UE!K_q#.Q2d0GQNEP@R/NBMR/WETR$jA0R/NERR[a&Arji$> +rk&'?s1SEGr4i9Is2"ZNs24lTrl+oW!6>)[!6P/)s-E_Qrf[2Cs-!DE!0Zr9"Q/.qiSsjs!T`AA +joOZ/rosIJ!:0XNs6]jSrU9dUs7-!Wrq$*\q"=RYqtK^Wqt^-cp&"U`qYfg\JcC<$Zi>O~> +JcC<$JcC<$f`117q#1!cn,)qWqt^$^rV-qr;Y3i\;Z0Gm;Ya2i;Ya5k<;ohr;Z9Sr;Gg]DK8@^&GbD^]2+L_>V7N_uI[S`W*pXa8X-]a]_mI=oVY*>Q.=k:%M*`:Z(*g +iSsjs!T`AAjoOZ/rosIJ!:0XNs6]jSrU9dUs7-!Wrq$*\q"=RYqtK^Wqt^-cp&"U`qYfg\JcC<$ +Zi>O~> +JcC<$JcC<$g&L=9q#1!cnGE%Xqt^!]rV-9ar:U']s7?3[s7--YrU0gUmHso>s6B[MrosIH!9a@D +$0C7/j5].YiLHG3RfJoTS,/Q[W2HSoX/i>(XfVK(s02R0rj;L/!4Mm9s2b5\s2P#Vs24oTrPJTN +!5STKs1SPtPEYp-q2tZ;"-AS)Nr4n/N:r/5W2ckuXKDB'#I(D7Y-"h-X8T+#X0)B(rJ^K/s,6u: +MZ/J+M#<,/L]E;0M#N82M#2u,M#<)0XT#@%Y5GC+Y,nb.YHY;0YQM.cLktk`onrR'qMP60!0$f7 +r/UQ5!4`!pq.-O^V@S#_Sa@4a2c +JcC<$JcC<$g&L=9q#1!cnGE%Xqt^!]rV-9ar:U']s7?3[s7--YrU0gUmHso>s6B[MrosIH!9a@D +#Nb%-j5].YiVJ3,K_pE#K)^B%K)L9#L'NEeLPCP=LPG\]!JlX4M>rJ.MuUlua8a0X`W*jV_u7IP +_#V:M^]2%BI/\KSHM2XaL'*-aL55>Ure^Z2re^Z$s*=Ebs*=Whp36IYr-/*_!-e?as*"HdpiZFV +!/LN/!/^W0s,$c5qMPB5MtqSrGjfqXGkuXYGl)dbH3&A?rd+X*qMtWs-EMJs-NhRR/NBMR/WEPR/WKR +R/NESR[]fBSH$+r\c02>]DT>A^&GbE^]2+L_>V4P_o0Lm`W*pZa2jPCQN*:$]qtp +JcC<$JcC<$g&L=9q#1!cnGE%Xqt^!]rV-9ar:U']s7?3[s7--YrU0gUmHso>s6B[MrosIH!9a@D +#Nb%-j5].YiV6@L;?0Yh;?Kio:f73ks&B%urDikr!`W0"r`8ttqc*U:s2Y/ZrPefT!5ncPs1n]N +rkJKIs&/nqnP]Eelr3XV!)`Yns&8eorDNet;c?Zn<<-"p;uT\h;tNr\;Z0Jm;Z9Pn;#O8j;Z9Vp +;Z0\sX2_;>a>k;>j>g;?'P`;Z]io;=moe=8Z+q]DT>A^&GbE^]2+L_>V4P_o0Lm`W*pYa2n*[s'#Cqq+^BS"]+%6i8N\pirS6&roOIK +kih9qlK[^6m/QGQmeuVRnGi%Uo)A7Zo_A+VpA=UVq"smaqXsa_r;-BZrdk*#s0VfV~> +JcC<$JcC<$gAgF:q#1$dnb`.YqYBm\rV-9aqt:!]rq$*Zs7--YrU0gUmHso>s6B[MrojLJkNDj, +!TiDAj8\*>iSaO$r0mSRr0mPO$E0l#WiN2%Xf\\,riQ=+Z*O>8q6^@6\$sAsrPefT!5ncPs1n]N +rP&HK]tM)XP5g^GP5(1>O91K'Nr"b-N:`#4VlHbtX0&Q%YPt^)XTGT)X8]1%X/rK$N;eb8N;e_= +MMm@LM2D+cs+gQ/pP8L!q1es+r/(HTriQ4'r2g.*XK8S.YPbX)L]<2+M +JcC<$JcC<$gAgF:q#1$dnb`.YqYBm\rV-9aqt:!]rq$*Zs7--YrU0gUmHso>s6B[MrojLJkNDj, +!TiDAj8\*CiS]??JqJ^TK_pDuK):*-Knb;9LPCP=LPCP=M#N/1Ll2.fs,-W1s2P#Vs24oTrPJTN +!5SQJ"2;I^]_d*THN8BkHiJEkH0fkLGlWQsL&d#"M#N82L]E;1HN/9aGlDpdG5c^[G5HF\Fp)r2 +G'.p&Fo$:]L]*#/M>W20M>rJ0MZA"tGQ)jVGlW*fG5ugbGQ2mfH2;d]H2i0jI/SElNr"e:OSt4? +OT(==O9gu1OH5KcPEhI4QhZjHQ2['LQi;F7It6j9!eQ&Vr.Fj!s+LH +JcC<$JcC<$gAgF:q#1$dnb`.YqYBm\rV-9aqt:!]rq$*Zs7--YrU0gUmHso>s6B[MrojLJkNDj, +!TiDAj8\*AiS[X5;Z'J^;ZBYs;,C-h<<#tu<;ol#<)Zarh +r_rhp!*K2$s&K(ur_i_or`&ntr`&blqbZcZqG@)erDN8d"]A8s;Gg<_ng<;]Yp<;ohn<<#nn<<#qu:$^qtp +JcC<$JcC<$g]-RaNreg]3reUH, +!/CK.reCE+reCH.pk\^#qhY9Q!3H1%s/u:%"g4u/Xfnr-Yl':PM#N7tMYN)0N;8J4Nr+k;OT)ch +\biu;]DoPD^&>SS]tV7r^qmn+`Q#s=aiVWEq8`WZb*2gh!0d;Erg!MLoU#NEs-ihSrLE`&rP\iX +a2n/"s2t5^!6kDerQkGhps/rcrlkMid*_g?!4D^4rjVm:r42j=rk&-As1SHHrP&EL_86,fs2+oV +\@DLJs186Bs2FoSp;R$L!5nfQqnWHmhr*GOir7s=jQ6C'!pAe2rojLLlg+N9!q#FDr9s[TrpfmV +rU]sZp\"FWqtKdYr;$9epA=abqYfg\JcC<$\,Us~> +JcC<$JcC<$g]-Rh=M +^]2"J^&GYE]Dd3VHi89cH1-(VH2i3jH2i3iGl`YRr.Y3,o8*C&!/UMus*=Ebrce9`rce0]q/l[\ +r,qs[q/u^\rH/0tLPPha!/^W0s,$c5r/:T"q02UYp3?X_rHJ9brce*]q0E!dr-SF'qMtW +JcC<$JcC<$g]-RTjrE'#!s&Atqr_reqr`/bkr(ul[pJClerDN8dr_i_m!*B/#!*/borE&eqr)Wl#rE'#" +!*B%ur`/nq!`Drqoi1Zaoi1lis&T,#!*9)!rDWbqrD`ess&K/%_=O_Z7XR>5_S->$4Ws:/1^]qG$HS"lA.pi8N\pirS6& +roO:Fkii$1!p]+;rTjUQmdC#As7$$Xqss^Wr:KaVqtBp]p%\I\r;--aqu$ +JcC<$JcC<$h#H[=q>L-eo)&:[qYBj[r:g0`qt9s\rq$*Zs7--YrU9dS!:BaO!pf.:roj[OkND!i +jlPS&irS/urnme6rgNhUrgNkVq3q/Js-O1kVl6MlWiN2%XfSW'Xotr4Z*Ue9[/%*3[`$)$rke]O +s1nWKs1\NHrk&9D](V2M[-2YW2ckuXKMN*!j8`1riZ:'s/Z1$ +oo/m.s,$l7Lku%cre:T3L5(D:LAHW'LAlu,M"6<$M#N/3Lo[SXrN-(&r2g1+XfSY.YH[VRs+gZ3 +m#(Rrs,?f6rJpl&rj_p;qmug>rk/9ErO`KN^;%Fu_8=.0`Q.qu!6=oVs,mMKPa%Aqqiq)F +s-E>Es-WeRqj[MRq8E9Os2G)[aSO$Tb5oi3rm(Mhs3Lemd.biicHXVZcd;X=!42[3s0_a4rjVp; +r42j=s1A6Bs1SHHrkJKK!5\ZOrODg:s1/3Brl+fRp;R'Ms24lRqS +JcC<$JcC<$h#H[=q>L-eo)&:[qYBj[r:g0`qt9s\rq$*Zs7--YrU9dS!:BaO!pf.:roj[OkND!i +jlPS&irS/urnmn9JqJ^TK`$K$K)L?%K)U?"J-gm_L5(D:LPCP=re:H/M#N2,M>rJ1MZUi7_u@OQ +_>h=M^]2%J^&GYF]=RuhrHnKhs*4Thp3HU_s*=Heqg&!`rcnO!L&?Z*L]*#/L\Zc*M>DMuH2)Ua +GPQF]GPQFWFng(QFoHIbFbkg.rJ1H1r.tB0s,-f6rcn3^q0;g_qfr$_s*"Bcqfi*drHS0as*F]l +"F>EANK*pt!KW9>NrY:@O8k=?O8Y.GOcYZcOHPinQ2[-KQ2m3JQ2m3KIf=isJEh^bK)L?%K`$Q( +Q2$U=Q2d0FQN3ENQi3_=J +PlR-LQhcgDPPLC6OTjV!i8ESRro47EjlPXekND(.l2U#Kli$2MmJlVPn,MnVnbVhSoDS=Tp&"I[ +p\+C[q>C*`qtp +JcC<$JcC<$h#H[=q>L-eo)&:[qYBj[r:g0`qt9s\rq$*Zs7--YrU9dS!:BaO!pf.:roj[OkND!i +jlPS&irS/urnme6r_i_ol;IX\!`;ckr_rktr`&nt"B8;u<)iitr`&r!r`/tt!lW!orke]Os1nWK +s1\NHrk&9D])>P);uK\q;ZK_m;>jDl;u]bl;u9Jg;uT\p;uBVp;uT_t;cH`m;u]hq;u]es*o_;>jDj;#jMn;#jMn=T2A(<`N*tr_i_orD`\ls&/kor(ur]ohbZcrDN8dr_i_ms&]2# +s&Jkqr)`Yoq,dPr!*B%u!*/qqs&/kqoMkWbp/LriqcC*`qtp +JcC<$JcC<$h>cg?q>L-eoDAC\qYBgZr:g0`qXsj[s7?0Zs7--YrU9dS!:BaO!pf.:rojIIkPjWD +jT+B@irS/urnn%=hO9n&S!ofES,/TLRJiKXVPgAjW2ckurN$"$riQC-Yd1UArj;O0rke]Os1nWK +s1\NHrk/9C!kPqQr0%#@$BUC3OH5E]NfB$WqhkH5qhtE3s,H]1rJM2FVl-JnWiN5'YHP16Y-5&. +Y5bU*XK/GqN!5,sMM[1GreLE+qh>$&r.Y0*reCK0q1nm&pP8aKs/c4%!NrO&XTbl0XKA[\nqR7% +MeG^]2(L_>Cb@\H'5=`Vd[J`W*mV_uIUM_%>J\i8ESRioB([jlPXekND(.l2U&K +li-8NmJcPOn,MnVnbMbSoDJ7Sp&"I\p\4I\q>C*_qu$BgrU0Z9s+13\s*t~> +JcC<$JcC<$h>cg?q>L-eoDAC\qYBgZr:g0`qXsj[s7?0Zs7--YrU9dS!:BaO!pf.:rojIIkPjWD +jT+B@irS/urnmt;hLgH6K`$K%K)C6$K)C2sJ-:OZKnbeG^]2(L_>'8rQC%?/!0d/?oT9^Ahr*GO +io9"YjQ5Lck3(pkrosIJs6K[Ns6]gRr9s[TrpfgTrU]sZp@\=Vr:fs\r;$9epA=dcqYfj]JcC<$ +\c70~> +JcC<$JcC<$h>cg?q>L-eoDAC\qYBgZr:g0`qXsj[s7?0Zs7--YrU9dS!:BaO!pf.:rojIIkPjWD +jT+B@irS/urnn(>hGR6M;c6Lll;IX\"&_rm;u9Pn<h=M^]2%J +^&G\E])oRS\boA';ZKep;uTYp;>jDl;ts8g;u]bk;uKVn;uBVp;uT_t;cH`h;ts>l;u9Gk;"dc[ +;X.-X=T2A(<`N*tr_i_os&Akms&/kor(ur]ohbZcrDNMk!)i_nrDNVls&]/"s&Jkqr)`Yoq,dPr +!*B,"qc!Gks&8MgqG[8js&B%uqc3Jo!`i<$pf.8ns&T/$!*8qrr)EVppJ_;p;GpFm<;onpZi@E3 +[J[K4\,Wu:\c98@]D]DB]`>eG^]2(L_>.:6=o;%r:/1^]qG$HS&Dl=&i8N\Tj5]4^jlY^gkNMp0 +s6BXMrp9[PrpK^Qs7$$Xq==LUr:K^UqtBs^p\=[^r;--ar;?Eimf%e;JcE:\J,~> +JcC<$JcC<$hZ)p@q>L0foDAF]qYBgZr:g-_qXsj[rq$'Ys7--YrU0gUmHso>s6B[MrosIH!9a@D% +cud4j5].YiS`YOhqm1XqO@;LrL!YSrgEYN%&]u$W2HVpX/rD)XKDK)"L#&7ZEsM:qm?LA^qfras +1\NHrk/9C!4r->rf[/@rf@2BNfEsqoo&9tqMPKQVl6Pori6:+Y->.6Y-+u-Y5bU(XS7\RMuS\6M +$&QhLPG\[s+CB)re(?*KS98Wr.b6,onN3rrN#t"rN-($rN-4*XfR83reL0$!JcL0M=-8tMuJ\1N +V\\6\GWo:\d>pY]">Se]Y2%mrO`-ErkJKL"N/3t`lInrrKI5Dr0.,EqN_)Hpm;#JrL*\SrLs1A9Cs +1SHHs1\TC\,3]7\ba;D`:h1L`;daT_YV(VhV[8LiSrkWj5f:_roO:Fkii$1!p]+;rTsROrpK^Qr +p]pWq==ITr:K^Ur:^'_p\=^_r;-0bqu$?imf%e;JcE=]J,~> +JcC<$JcC<$hZ)p@q>L0foDAF]qYBgZr:g-_qXsj[rq$'Ys7--YrU0gUmHso>s6B[MrosIH!9a@D +&EW!6j5].YiS`YOhqm1AKS9>Wr.=p#s+:0"pj`O%KS>/7L&H`-LPCQ]L]<2.M#`G2MZU`1_#D+K +^AknG]`5SD])B2=I/J?iHN/9fGk?:NHMVmfK8'/V"c/"lLkgc`L]N?grd+QhrcnEds*4Neq/ua^ +r-&*_"*A[.G5cX[FSp4LFT.*qL]3)0M>W20M#rQYGQ)jVG5umeGlW*`GQ)dcGPZOaH2W!aH2Dmf +Hi8s'NWG3$q2bQ;rK$c9"Hen5Q'VE9rKdJKrI=fqr."]rmt(:drdt3(re1?:rK[2Cr078JrK[DK +nsBs1A9Cs1SHHs1\PupQb'-o8sF;hr*GO +io9"YjQ,G%joX`0kl0fJlKdd7m/QJPmelPQnG_tRo)/+Wo_.tUpAF[Zq#1$dqY0mar;6H\rdk*# +s185\~> +JcC<$JcC<$hZ)p@q>L0foDAF]qYBgZr:g-_qXsj[rq$'Ys7--YrU0gUmHso>s6B[MrosIH!9a@D% +cud4j5].YiS`YOhqm0er)<2b!)rShs&8qo!)rkr!``3!r`&qtr_ierr`9&!r`0/%<5HAcrkJKIs +1SEEs189BrOM`%oi(ifr_rVjs&&bnp/Cid"&i)r;uBVp;uTbr;ZKej;uK\l;ZK_p;>a8a;>F,g; +>sD[;>aPq +JcC<$JcC<$i;`-Bq>L0fo_\L]qt]p[qtL'_q=XaZrq$'Ys7--YrU9dSs6]gPs6B[MrosIH!9a@D +!TiDAis=Z'iS`YOhqm2bS,&KQRJiTRRJN9\VPg;hW2HVpWiW;(XK8Q'Y5ba+Z2h60[/IE3^]2%J +^&G\E]DoJA\HKFO[uupOOoCFDO,f4uN:MnsN;8A8N2rA5LPCQ_L&H])K*6dYK7\aSK`6]$LAur/L4t?YLA-K$X8f7(XfSY,XT#@%Y5X1TL\-<&LPUca +M=HJuMuSb3N<5-"NW"n8\,j.Orj`HK\[o>_]">Se]Y2%mrk&9F^AbnI_$.`q`Q#s=r5ei"s-!GG +qNLlBrK[AJpQtlHrg)[r5nu]rQ>>fc-=PZrQkMjp!3fec-=P\dJU6J +Z2_--Zi7?3[JdQ6\,Wu:\c98@]DfGH]sb>V[^Z.Ds1.sEs2=QKrl"iSs2+ZL%,Kdti8ESQioB([ +jQ6C'!pAe2rosIJs6KXMs6]gRr9sXSrUK[Rr:BjYp\"IXr:g!]rV?Bfp\Xmdqu,s^JcC<$]DmB~> +JcC<$JcC<$i;`-Bq>L0fo_\L]qt]p[qtL'_q=XaZrq$'Ys7--YrU9dSs6]gPs6B[MrosIH!9a@D +!TiDAis=Z'iS`YOhqm2gK`6W%K)^K&K)C2oJ-L[\KS>/8L&H`+L]3&-LBE?fLku"d!/g`5rkJKI +s1SEEs1A2GQ)j[GPu^bGPudWGP-4WH2DmfHi&g$Nqn_9OSk19O9Lc0 +Pa.N"rg3SLrI4cr!.OcorIFBgqh"d!s+LE+s-3JIrfdDJrKR8Gs-EVKs-E5BrL!SN!1Hpm(--oT9R +JcC<$JcC<$i;`-Bq>L0fo_\L]qt]p[qtL'_q=XaZrq$'Ys7--YrU9dSs6]gPs6B[MrosIH!9a@D +!TiDAis=Z'iS`YOhqm2d;ta,f;tNuf;[?8t;H$Oo_Kp/:K\q,7,fs&/Vjq,.;n;H$Nl<<#nq<9[?[;>a8a;>jAn;c( + +JcC<$JcC<$i;`0Cq>L3gpA4liqtp6eq=XO[p\aa\p&=U_oDJ1Ync/+Wn,MhUmJcGRlg!d7klU)3 +kPjTEjlHF$!TN);huV`lrn[F?opYoKr0[MPrL!V_!N)doW;ik$X/rG)XKDK)s0)U1ZEpn9[/RH7 +^:h5Z]`5VD])K8?\,a#;[K)KfOoCFEO,f3ZrJ^E-s,6r9pPf*0!0$T/&Z)A'Vl?\tX/rJ-YHY45 +YHG&)N;eb8MZ/J3L]W?dLAci)K`?]'JcLH%KE-`&L@p9"LAZi)LA\(VXKAS*Xf\](Xo3tCLB!&- +L]E;!MYrD1N;SY8Nr4k;Njnqr!P,f@\I6!Z]",D`]=Y_g]tOBW%_]Tk^VIY%_o0O6a2c9BqNCiA +s-3GFrKR>Irg*;Frg +JcC<$JcC<$i;`0Cq>L3gpA4lEqtp6eq=XO[p\aa\p&=U_oDJ1Ync/+Wn,MhUmJcGRlg!d7klU)3 +kPjTEjlHF$!TN);huV`lrn[U-!/(-"s+C<&r.4Nks+LT/KnY88rIt<-reCE-rJ:E/s,-f6!ku@] +rk/9Cs183?s0r' +JcC<$JcC<$i;`0Cq>L3gpA4kiqtp6eq=XO[p\aa\p&=U_oDJ1Ync/+Wn,MhUmJcGRlg!d7klU)3 +kPjTEjlHF$!TN);huV`lrn[QPpJUido25Qcr_its;,^Fn\,Ni.;YO,c;Yj8j;YX2c;?Kiq;cENl!)rkr!E2tq;uK\g;ZK_p;>sDb;>sJm;ZK_o +;>a5j;>a8d;>a5j=8l;'='/Q'3le;>sDi;>O,a;=mcc;u9Gmt?b64=T2J(=oMV!:B4/b:%(g^h;7&Ii8NYSro4%?jo4EBk5a`E +l2U&Kli$2MmJcPNn,DhTnbD\QoDJ7Tp&+O^p\=O^q>L0aqu$BgrU9`:s+13_s*t~> +JcC<$JcC<$iW&9Dq>L3gp%nd\W;ZSiq=XO\p\aa[p&=U_oDA+Ync&%Vn,MeUmJZAQlg!d7km-G8 +kN:pgjlHF$!TN);huV`lrnRS0qj[ALr0dMNrgEYNs/5mori#gr"K\`,XKDH(!jJr7rj2R1!4Dd< +!kZ%Trji'=s0r!9!O\*cOTCN'rJg]5qMXs(rJU]5p5AsI$)XZ!W2Zl!X0&T)YQM&3Y)N@>rJ^c7 +!fDhkreUT0s+^H*s+L<&rIP3*KS4u2L&HbtL&Qf,L\QW$X8f=%X9,N*XS[_>LAlu.M"li#MYrD1 +N:r82NW?Qd\Gs/>\I6!Z]",A_]=Y_g]tOBW!58BH"Mhjj`5V_q!6=kts-*GHrKI5Frg!MLpQtoI +qjIGPr1!Z&p;I!Ms2G&Zr5eo[rQ>,_"O,-8cHcF8s3UGbs3:\jcHlKlriZ7(r364+s0DR/s0Vg6 +rjMj9s1&'=!kPeIrjMg6!4Vp:s2O9As24oTrPJHJ!o;_jrnmh9ir7s>jQ5M&joX`0kl0iHlMp2J +m/QJPmecJOnGVnOo)/+Xo_8%WpAOa]q#'sdqY9scr;-B\rdk*#s1SG_~> +JcC<$JcC<$iW&9Dq>L3gp%nd#L&LlFq=XO\p\aa[p&=U_oDA+Ync&%Vn,MeUmJZAQlg!d7km-G8 +kN:pgjlHF$!TN);huV`lrnRY2KS0,Qs+C<&r.4Kj#ChG]KS5&6L&H`+L]3&,L]3,-M>rG5MuC9i +]=PTQ\c92>\,Nf:[=%arqg/*ar-7s]r-JjQ5M&joX`0kl0iH +lMp2Jm/QJPmecJOnGVnOo)/+Xo_8%WpAOa]q#'sdqY9scr;-B\rdk*#s1SG_~> +JcC<$JcC<$iW&9Dq>L3gp%nbt<;l[jq=XO\p\aa[p&=U_oDA+Ync&%Vn,MeUmJZAQlg!d7km-G8 +kN:pgjlHF$!TN);huV`lrnRV1;ta,c;t\,Nf9[J*T!;ZK_p;ZK_m;u9Gm;uTZ!;,U7h;,UO2j;ZK_m;?'Jm;>a8h;>O,g;>j>i;>O,`;=.9];ZKks +=8l8"L& +YPbX)Z2_--Zi@E4[JmW7\,Wu;\HocK=B\p5>$+o+>5qb*;#!id:AR]P:'08.hu;O7iSsjs!p&J) +roO:Fkii$1s6BXMr9XINrpK[PrUBdUp[\7RrUfjWrV$3aq=sm`rVH +JcC<$JcC<$irABEqYgI*YHY:;rj2R1 +!kZ%Trji'=s0r!9#dq%HZ]L92OHBF'!KW9>NV8>2MuSb7NW4q;Mu8P5Mu/D+MuKRPVZ<^qWr]?* +ricC*r/LZ6s,-u:M2@&fL]<,*K`Hf)KD^?"K*$^[LAci+K^sisLAZc)LAS%OXoGI&Xnmb;L&m'c +pke[$rJUT4pPo04!OfK9\,s4P])K5J]",D_\[oDb]Y(qkrO`-ErkAZQ_8=.0`l@b9!0d8D#*Y:9 +Q'IZ$p6Y]EqjRGPqnr-G!6+rWqoJfZrQ>,_"3f$7cMc)hd.P`ac2apEXSf4"Y5b^'YlD!.ZMh-0 +[/[Q5[f +JcC<$JcC<$irABEqYg9rItE0L4tB]L]*&-M>iA6 +]=PTQ\c92>\,Nf<[C!1HN&3gGk-%_ +G'A.RG'.s*FSg+ZFSKqWErU4SFS^(PL]DSpG5ZUbG5ZOcFEMbMrce?bms"bUr-/!^qK_p`!dflb +r/LW7qi:f?O-':#!K`B@O9^o2PEhE!Q@8OW!.XosrI4ftnq$^jqLea"qiq)Fq31oFQN!0JQ3*>; +QL^C?R/`KQR/*-NR]HFhr2ot$s0)@)s0;U0rNlO2s0_j7s0i$=P4t1>Pld26PNS)/Oo(==OTO@q +hu;O7iSsjs!p&J)roX7D!9jCGs6BXMr9XFMrpKXOrUBdUq""@Sr:KgXrV$3aq=sparVH +JcC<$JcC<$irABEqYgC/q=XO\p\X[Zp&=U^oDJ1Ync/+Wn,MhUmJcJPli68Lkm-G8 +kN:pgjlHF$!TN);huV`lrnRV1g\k"M;u9Jh;t*lg;c +JcC<$JcC<$j8\KFqYg_KrjMj7!4;a3q2bZ?O,j-tpl,64repi:rJpl9!/pc6!/pZ1pl#*I"/_uoW;Wb(Y->-i +NJrjUN/NYnMuS\7M#W81LA?N'K`-Q%K):3!L&H]%L&ZhtL&Qi'X8f:%XS%;8L&d#-M#<,'MYrD1 +N:`)2[C3RC\,s4P])9)@]",A_rk&3Cs1SEE!58BH"2Maj`:fAoPQ$gFQ2[!OQ'R`&R$dl>s-NeQ +qO%;NrgN_R!1`l&pr*3Orl+rYr5eo[rQ>,_"3f$8cMc)hd.P`bcMjjCX8f:!Xo>L'YPk^*Z2_-. +ZN@MA[JmW5Zi@E4[K!]7[/mbHrPn'?!6"lSrPJHJ%Gfmuhr*GOio9"YjQ,G%k5XWEkl'cGlMp2J +m/HDOmeZDMnGVnPo)/+Xo_J1YpAOa]q#1$eqY9scr;6H]rdk*#s1eSa~> +JcC<$JcC<$j8\KFqYggA?L%KDgE"Jb4HmJ,XlsKDpT)KE?j^L&H`.LPCM;reLH. +rJCQ3rOE!>\$u@Fs0Vj6rj2BHqg/9fs*4NgpiuOYrd"Qir-86e!IB+jHN&0mK7no1K_gE+LP^k6 +HN&3dGjoqWFoZ[^FR4)BFSg.WL]E5/M#VVkFoZ[`F96T.G4p.YG5-:\Gl2d^Gku^]HN&m$NVeb6 +O8b7>O8k=AO8b4COcu#pp4!$krdY3(J:N-!J:RTLs+:6$s+16%qL\NqrIk!2s- +JcC<$JcC<$j8\KFqYg\$u@Fs0Vj6rj28qr_r\l!)rbmn5KNar_i_mqb[;ip/(chs&]/$!EW:n;>*fg;,U:hq,%#e!)WVkr_i\ll;IU^!`rE(rDrnt +qc0>$>'2=B\m':Jam^:BXEe:/+IW:&n)^:(?%9hr!AM +iSrkWj5f:_roX7Ds60FGs6BXMr9XFMrpKXOr:'[Tq""@SrUfpYrV$3aq=sparVH +JcC<$JcC<$jT"TGqYg$Lo.s'#M,>5hY(>5X*QK`-W)LA@kNXbQM& +m=tXrs+pN.pko!-qMbE5rf$c7s0Vm9\,Ef<\[oBM\HBFR\[qdPs1JBFrk&6ErkAKL_Y'&lPPp^P +Q'R`&QBd]"QC%00rgEeTqj[VUpqumFs2G#Xs2Y&Ys2k5^s2tPhc-=PZrQkMjp!3]bWN#cps/Z1$ +r2p"%s0)C*s0;U0rj2X3!O]62Zi@E4[K!]7[/d]6`r +jQ5M&k5XWEkl'cGlMp2Jm/HDNmeZDMnGVnPo)81Xo_S7ZpAOa^q#1$eqY9scr;6H]rdk*#s1nYb~> +JcC<$JcC<$jT"TGqYgrG7\@8sH +[f<`8[/I<5ZE\e)rd4Wlqg/9f!I/h[GkZL`H2r6hGQ<$gHN&9fH3AkRKS+sRL&cT!H22^^G5ug\ +G62r1Fo$4YF8o#:;,I0dr_NSjr_NVk;#GG0F8LapLPUccFnTtYFo?C`F`qs%GPu^]GPud`GPZRY +H2MsgNW+n7NW5"=NW+t9O8b7>O8k=AO8k=AOT:UDIKP(KIXhhV[5Ki8NYSro4(@jlQL(s6'FGrTX@Is6KULrpB[PqX=@OrUK[RrU]sZqXsg\rV-0` +rV?Egq"t!equ-!_JcC<$_#Jo~> +JcC<$JcC<$jT"TGqYg#%gg:f.-es%`Jfs%WPgpJ1]`oM,\JhV[5K +i8NYSro4(@jlQL(s6'FGrTX@Is6KULrpB[PqX=@OrUK[RrU]sZqXsg\rV-0`rV?Egq"t!equ-!_ +JcC<$_#Jo~> +JcC<$JcC<$jT"WHqu-EipA=darV?KnrM]Yhr:g-_p\"LWrU]pWrpg!Wr9s[Rs6]gPs6K^MrojLJ +kNDj,!TiDAirS/urnmh7hYu=3gtVh^!nj'4qO7;L!1<_Qq3^uEs/#^m#H"DtW2ZesX8T+"Xo>L' +Y6(r5ZMq07['mEN[C!=?ZNIM$G81>Q%b)=oMS)>l%\(>5h\)=oqo3=T2P)>5qh, +=o__%=9D^-X/c-!s+^3#qh>*)o7d=%Lktnapko!-qMbH6qi(N6rj;g9\$u@H!kGnRr4)p@\[fc=3hu;O7iSsjss5X1ArT41Ekihs/s6BXMqs=:KrpKUNr:'[Tq==LUrUfpYrq? +JcC<$JcC<$jT"WHqu-EipA=darV6W?b_1Y'L&C`Dp\aaZp&4O]oDA+Xnc&%Un,MhUmJcJPli68L +klU)3kPjTEjlHF$!TN);huV`lrnRV1g]#n,g%^0rJb4HmJ,OiqJ,b0$K`[!^K_U9)KnbA=L]3,- +M$AjG[^ENM[/RB6ZE^[=q0W0hr-JBg!-n?apNZ=Us*4Qho6LOlKS4u1r.Y9.H@#O8qKVm]rc\(prr2Tdts/c.#s/uC*rilF-s0;d6Ocbfip65N@ +qNLi>k*#V(s5!_3!8me6!TE&;j8\0?jo+L0cqu$BhrU9`:s+13ds*t~> +JcC<$JcC<$jT"WHqu-EipA=darV?J1!)rkrr:p3ar:]mXrUg'[qssaVrp]jSs6fpSrp9[Ns6BUJ +!pJh1roO7CjSn0?io0mp!T2c5h#ZnAs;c?Ol;u9Po +<<,qr;u]hq`g;H$Km;t*cc;uBPm;ZSg?r]^F&b;>=&h;tX&c;>sGo +<)ris!*B,"r`/hrrDs##=8Gtt;u]bj;ZK_l;uT_r;sdQ`prr2Tdts/c.#s/uC*rilF-s0;d6=BJ^/r`T;)r)io#r_EJhs%rVgr(m#] +r(lu\s5!_3!8me6!TE&;j8\0?jo+L0cqu$BhrU9`:s+13ds*t~> +JcC<$JcC<$jo=`Iqu-EipA=dar;$?l"fS>tW;-/cp\aa[p&+I\oDA+Xnc&%Un,MhUmJZDOlN$5K +km-G8kN:pgjlHF$!TN);huV`lrnRh7gY1B7f[u\mRfAlWReiEPRf8`NR.lsIV>d@nVPjEls/H(" +rN$"$rN6I1YctF=Za7'H[/RE3Z2h0/YQ:qiqiCi>NqJD3N;eh/N;SS6N:Vu)MuolQVZ*FkVZNm! +N;eb3M?&M2KE[!]KN_Vcr`]P2>$G06=o;G'>l@n*>QA"-=T_i4>$Lr.s'#D+r*&u#s&f;(s'#E' +rN#s&!*]>(q1\g&qh=`us+gW1rJC6*rJU6*rf-la"h(nL\@B*K])9)@]",A_rO`!?"22F3PP(+= +PQ$dLQ'Rc(R/E`6khV\=j!o`.uro4(@jlQL( +s6'FGr9=7Hrp0IJrU'ROq=":OrUK^SrU^![qXsj]rqH9arV?Egq>:*fqu-$`JcC<$_>f#~> +JcC<$JcC<$jo=`Iqu-EipA=dar:pWCcH_)rKn]rK$u?s,R20J,FcqIfP#uIfb(KJ,Xut +JcC?"JbOcpKD^?!KDgH(Pa1s,!1!PJs-qjIJ]r29Oms/Gprs/Z1$rN6+& +!3c@*!3uKbs-!/@s-3ADs-!;Bk*#V(rnRV3hu;O8iSrkrir\<'jo4EBkPscDl2U&Jlhg&ImJZJK +n,;bSnbMbSoDS=Xp&=[ap\O[`q>L0cqu$BhrUBf;s+13ds*t~> +JcC<$JcC<$jo=`Iqu-EipA=dar:pV9Df8NP<)iYfr:g-_q"=RWrU]pWrpg!Wr9s[Rs6]dOs6B[M +rTORNkND!ijlPS&irS/urnmh7hYu=9gtUQ:g"=qVr_rbpqG[Am!)rkps&&\ls&/nsr)Eer;,dHk +"]A8t;H$Nk<<#tu;ZB\p<<#r"[C!=?Zi@<2Z2Us-YN/UX;uTbn;uKVa;Zfop;H!Hlo2G`h2?#H4 +2$>fr4[)(/4oRVK4[(qj4?WL&!B`OD48h8H4Zkkh3]fGbqDnO9rB(9G3]]>a4?WUC"]e],=?&;= +2ZPc3;>3lh;,U:hq,$rcpeq)iohtZar_`o#<)lt":*fqu-$`JcC<$_>f#~> +JcC<$JcC<$k5XiJqu-Eip\XmbrV?Hfrr<"r!iW#qrqH?aq"=RWrU]mVrpg!Wr9s[Rs6]dOs6K^M +rosIH!9a@Ds5aFFj5].YiVqaDhqm2Fgt^Z7s0;X0rNH@,Y*&UC!KW9>NW4q=NJrhlNV&2+MZSiqMuJ\4Mti81 +VZ*FkVu;PPJcLB#JcgR0?!R>4$sZt>>Zt95>$>-6>?q,2rETA*#$P59>?b96r*')($X-Y9>Zt?8 +>$4s0=o);%>Q.h*XT#7&W`r\2qcWr&rE9/Tqh=d!rJ(B/pPJg*rJLZ7rJUN2s,-l9rf-i`!OfK: +\,a)=])9)@]",A_rO`!?s-!DGpQGK="I,1;QC%K9!13JJpmM,MqO@N&!6"TKq8<9PrPncVrlP/^ +rQ>;ec-FW6ci;AdcN'd?V>mFjVuEXpWVrjsX8f:"XTbl2YHY::ricI/ZEjG8!4;^4"1H:ka8O$W +`Vd[G`V[UQ_u7IL_$\uRh;7&Hi8ESQir8!MmeQ>MnGVnQo)A7Z +o_\=[pAXg_q#:*fqYC$dr;?N^rdk*#s2+ed~> +JcC<$JcC<$k5XiJqu-Eip\XmbrV?HfrltY"K7no3rqH?aq"=RWrU]mVrpg!Wr9s[Rs6]dOs6K^M +rosIH!9a@Ds5aFFj5].YiVqaDhqm2Fgt^Z,7KSB5V!elA` +reLK/rJCQ\s0;X0rNH@,Y'g1ps*Ofnr-JBg!-n3]s*4Ngqfqg[ms=nb"+u;^LAcAtAc?3E@q9([ +A7JR9;?0Sn:^0cm:f1+f;#X>e;#=&e:Amrg;#X5p:/+JX9hnIW:]=,dL]E5*:&@W_Fo?LZGPlXW +G5umbGPl^\H2i*hH2`-fN<5&uNrG%;NrP+%It.BFrdalq!.b$!qgng!rIP$# +qh"g"qL\Wts+LE:!1!,>rfmYOQ'R`$Q2Hs;Qi!0IR/j&^V>mFjVuEXpWVrjsX8f:"XTP`0YH[qe +!0[&>!0m>Drf[2Ak*#V($JaInhV[5Ki8NYSro=%>s5j7Bs6'FGr9=4Grp0IJrU'ROq=":OrUK^S +rq$*\qt9p]rqH9arqZNhq>:*fr;H*`JcC<$_Z,,~> +JcC<$JcC<$k5XiJqu-Eip\XmbrV?Hfrbqg6!`DrrrqH?aq"=RWrU]mVrpg!Wr9s[Rs6]dOs6K^M +rosIH!9a@Ds5aFFj5].YiVqaDhqm2Fgt^Z\f48h8H4Zkhg4$>Yer]($@3B@'us#9m9q`4U9s#C'= +r`',&='/N`3;b]82Z,H42ZHYO;#aDm;?0Sl;#!od;ZBVn;ZB\f;Ys>j;ZBc%<*!%"j;Z'JM<<#u!=8#\n +JcC<$JcC<$kPsrKqu-Eip\Xpcr;$9crr;qps/>niq"=UXrU]jUrpg!Wr9sXQs6]dOs6B[MrTOCI +kNDj,&EW!6j5].XiS`YOhVR)EgtVh^"PMGZf@Knis-itUqjRMPr0[8GrKdGLs.o[k"K/,pVPjEl +!ii<%riH.%riZ:)s0)X2ZEga?rilF+"0Sc.Oo1=@NrY4>NW+n9MuSb6NVJJ4NW"h5Mu&D2MtW)7 +V5C)dV5:&erdk6)>[:Y4>QA"-=o_e+=o__)>52>%>Qn>8>$5$5r*&u%rE9J3>$>'2='&L+r)Wr% +=]tW*s'#J+riH+""0,R0>5MJ&>5_V'=T2CqLAlu.M"cc)MYrA4N;AJ2N;eb7N;Bp^\,Nl;\c029 +\H'5=])]MCP5ga?P5UUEPQI,9QgpIL0c +qu$BirU9`:s+13fs*t~> +JcC<$JcC<$kPsrKqu-Eip\Xpcr;$9cs3:VgrIk3)rV$$ZrUg'[q==OTrp]jSrpKgRrTsRM!:'OI +!pJh1roOdRjQ,@]io/kSi8r0@;Jrg!GJnr0dJYrh]Xlr29Rns/Gsss/Z1$riQ!Y!0[)?!0m;Crf[2A +k*#\*s,[E>h;-rEhu;O8iSrkrj8\0?jo+?AkPj]Cl2KuIlh]uHmJcPLn,;bSnbVhUoDS=Yp&=[a +p\O[aq>L0cqu$BirU9`:s+13fs*t~> +JcC<$JcC<$kPsrKqu-Eip\Xpcr;$9crbqd5!`N&trV$$ZrUg'[q==OTrp]jSrpKgRrTsRM!:'OI +!pJh1roOdRjQ,@]io/kSi8f?62`Nhs;?'Mo;>a8c;>sJl;?'Po;tNu_;>sT#$=8l5#;Z9Sp;Z0Gm;YsDl;YsDLLI>.$Cs+Uc6 +L5(JmObB?!LW=>?kG2?2\+,?NON=ZMq3,>l@t+>l@n,=oMV->$5!4q-*f$"J3WRaN4A&qTAfZ!6G/2 +s.JqVpS.Y_qka4frMBOkrho4^rhfdobl#Zab5KHZb5]Z^b4EdVbl5lYc2c,gbl>lcaoKN^WWB0% +riH7)YHRr0!O8s0Zi@B4[JmW7\,Wu;\H9@S]DfJC]`>eG^]2+L_>_:V_o0L4`Q#p^s+14&s*t~> +JcC<$JcCo5k5P5Ur;?EgrqcWir:p$G-4r`B/'rE0)#rDs;9?sR#@>$GHFA,]s;@0pFPA7K1M<)ln@repf3 +!JlL0L&Zf-K7\aSJJ`lSDf]>tARoCaAn,:Z@q9+]AnPjnDfp3fG5l[eG'.tOrH/3aF)l=#F8p:[ +EW9tXDu=SSEW:(ZEVa_UEW:"VDu=MQDt7f=D?"MJD>eAMD?"MQD>nDQD>S5MDuFSBDuOYSD[16" +DJj<.DJo2er,2OQrb_[OrG2FI%qo]mBkM-n@U`bZB5)'p;Z0Mo;Yj>l;?0Sj;Z0Jl;?]uu<)\^5 +rf$\Os&8blrDjDl;>3lgKTqbuQN!0JQ3!>iD1MtW%oMuJY9 +MjX4)qNq8Lq3L$,rK[GKrKR;]!NW=$XTGZ/YPta,Z*OA8s0Md6rjMj9s1&'=!kQ"Urk/9E!5AHI +s1nZNrk\oX`5KX6`l?'ua?@Yfb0.uPc-=PZcd:%ddF-LneCE+#f@S[.g=k<:h;-rEhr*GOioB([ +jlY^gkih9qlKdg'mHs?1n*oi:rpg-^o^r.Us7QHerV6Bfs8)Wirqu`noDX=@JcFC&J,~> +JcC<$JcCo5k5P5Ur;?EgrqcWir:phqm3k<`W6"sGq<)Z^pr_id/'"b`c\[],W[^EKK +Za-j?Yck43nPfHcr'LTQ6:+%+r^-ZPr]qPl1,1F8/hS\21,1L>0f([E1c7*I5!(kh7S6?H8cD?^ +8cM +JcC<$JcCu7jo5,Tr;?BfrqcWir:pIra,e9@qK:_raQFI +@:E\S@:3PP?t>J3\[MCA+L/5VY,n\(X/r:`R#n)XEH-#>F)5T+D/aH4F*MqXKSK8W!/C-$!JZ=+ +LAuu-K`$E'JUi:LJcC?%JHC@OJ,+WmIfk+HI!ts@rHnKhr-A?(H$Xa[G'J4SF`MSIF`_\Hrb;[R +G'e^jJR2[]?2n72?2n10>Q7t+?2\+,?NOQ>ZMq3,>l@t+>l@n,=oMY*=TM]1q-*f$s2G,\aN4>% +qo\f-!M?%\U&Uk_U&(JbUSO^`V>I.gV>mFkVsgM_VuP!Abl#Zab5KHZb5]Z^b4EdXbg"E'c2c,g +bl>ldao]\`WW&n&X/rD)Xfeh1ricI/ZEjJ9!joACrjMj9!4`$=s1/3BrO`3F^:sT]!l2Xgrk\]R +`;[aU`WaE(aN;QHrl[%?c-FV\cd:(edaQ^qe^`7&f@\d1g=tE=h;7&Ii8N\Tj5]4^k2tjjl07Ku +lg4!*mf)Y[nF?&>o(2JFrq6 +JcC<$JcCu7jo5,Tr;?BfrqcWir:phqm2FMMd8gM?&S6MZ8P3L]E5.LAci*K_^6'Joc99K)L?$K`-N;KY+h+\[],W[^EKK +Za-j?Yck43XmgcC?!:H8=]bT*r)a)'=BAO)rDj#%=BAT'RcB4GC[@q9._B4u'uF8^7YFoZ[TG4p%\FE;JCrc8'[rc.sWs)7gSs)J'Zs)ImU +s)J'XrGVUOs)7IGp20eHpMKkHr+uFOrGD:HrbqgS!c;gmq/?1KrbqaQ$#ad%Df0H0D/O7cDu=MQ +DuO_UD?OlpCi!ncCB%rLC1h6qraH%>BPVI*E;if8;Z'Jn;?0Sj;Z0Jl;?]uu<)\^5rf$\Os&8bl +"]8)n;,C-g;Z9Pf;#ca[Q26gGQ2d0GLB*/-LB`QkM26tCL]*&-M>E,.MtW%nMuSb9R/iWJQhm'L +Qhcs,Qi33MQ2[!KW2]cr#HOr-Xf\b/YPta-Z*L\7ZN@MA[JmW7[fEr;\c95@]D]AD]tV5[^B23e +_>_:P_o2Pns2G5_aN2KFb5TR=bg"GYcd0tcdF-LneCE+#f@S[.g=k<:h;-rFi8ESRioB([jlY^g +kiq?slKdg'mI'uB#Oq9Ro()DDo`"O`pAamcq#C0iqYU0hr;?Ncrdk*#s4I@%~> +JcC<$JcCu7jo5,Tr;?BfrqcWir:pV9`@cd:'49g<`/Wi!)_fT!)`Yjq+prcrDEPjqb[>inkfHb +;,R9gqG.,e:]=2j:]F8g:B45d;#jGl:]F8j:]F2f:\R]a:]4,Y:]F5k:[1dU;%QQ":esnb;c6Li +<)?Lm;c6Tn8d@gV8kVc?5^ +JcC<$JcD#8k5P5Uqu$9erqcWir:pd:iU]7%jTqJ'NrLX%[!1a%Xs-itT#\]ZtM56rDW2KTm +(8Rh)\[f5Z[^NTNZa6sBYct=6Xf\[io9LDFG("abIqN5#@UWSL?t!DM?sd2I?t!GPAn>O`A,Kg8 +@4Ykq?t5;/\[SrP['[0GZ*LU;XK/A&WMc/IUU?GEO)f;\CM@^+EH$)HH@^eKLA6N(L@g6$LAlo* +L'!'^K`-N&JcC9!JcC?%Jc:/oJGt&uIK=hErI"NirHeBeq0Mmas*Xfms*=Zjr-86e!-nKg!dK!9 +rH\KkI//-fHN&/>l7n*>lIt-=oMY*=TM]1q-*f$s2G&ZrlG&[s2tA4 +qk!h[!204_rM'7as.BIfTV8(WUAq%eV>@(fV>mFlVs^DaVp3K1qof#^rQ4rZs3(;^o?.3Zc-?13 +rQY8cs3:SfrlY;arhfdqWW&muX/u<&s/l@*rilF-!4)U1s0Md6rjMj9!4`$=s186Brk&U6gqu-HkrUg)?s+14&s*t~> +JcC<$JcD#8k5P5Uqu$9erqcWir:pLH@0`3KD^B=K7\c0\[f5Z[^NTNZa6sBYct=6 +Xf\[Qo6q0U>$YHA@TQZ7=BAU+=B>E&!a&K(rDs>.='&F'='&F(<`])t"EKH[Mhq@fre:B*s+;2@ +JUr8uDfU5ZEcH86An>I]A7T7`BPVI*FT$=`G'.s)FoZ[TG5-4[F9$C\ErU1\ErL(YDuahRE;sqW +EXHf,EcH,>EcH)A)JDuOVRDZ"GKDZ4SRDZ=YT +DujlprbVXQp2BnIrGVUQ!cDjmrbW9aCM[d#BkV3nC1q$b@UN\U@UT16s&/hprDNVlr)3Jjr_i\n +s,6l8!)rbms&8_k"Ahrm:f70hr_`Dds-*MKqNh/HnV7+#rJC?+s,$Q/rJUB,l&,Y&R@0H8Qhm'L +Qhcs,Qi33NQ'D9G!N_=O_Z7XS`<"!!rl>,^b5TQobg"GYcd0tcdF-LneCE.Lf-K#%g=k<:h;-rFi8ESRj5]4^k2tji +kiq?slg4!*mI'H3nF5uIncJFTo`"Lbp@n=[q#C0hqY^6hr;HTdrdk*#s4I@%~> +JcC<$JcD#8k5P5Uqu$9erqcWir:pI`rDFJ3;c6Rm\[f5Z[^NTN +Za6sBYct=6Xf\[&o2>iE.P!&&/NEVo%mrWK6:+%*5X@\&5X.Lt55mbr5!M7s5<_7o4$?&+91hcI +8kMZH84Z6A84H$;7R\pm5<^qo852oS9hS=^:&dri:K:=#h;<1UT;>a8d:]4)j;,I6h!)WPi +s%r;as%r_mrD3Mj:Amug:'+3f;#X8j;#=&_;#jGl:B45i:]F2f:\R]a:]4,Y:ZkRO;&`>,:Jjqe +;,U4h;,gFl;H$Fa8kDWI9gh?55!Jd*s#ga5j:]=&i:/=[[;#[?nW2]cr!NW=$XoGO(YPtd+YlM*/Zi@B4[JmW7[fEr;\c98@]DfGE]tV5[ +^B)-drke]Q!6"lU!QN1Za8sE*rlYeqc-FV\cd:(edaQ^qe^j`O,hUf(g=tE=h;7&Ii8N\Uj5f=a +k3(pkl07L!m-O-,mdKW6nF?MK!qZ'Vrq-?dp\4X]s7uZjr;6HjrVcBfJcC<$f`-I~> +JcC<$JcD):k5P2Tr;??erqcWir:psqs/#dmrM9Ffs.]Od!2'1\rgbR0S"#k8R@'A.QBRe=UnjiaW2Q\o +WMZMg\$i`Q['R*EZ*:I9Y-"h-X/_HXQ48:dI=6HjB5"EKW23j-ra?7D?=.#I@:*JUA7]7]A,Kg9 +@4bqs?t5G3\[]&R['[0GZEg^a?3":/>QJ&6 +r*B8-!af>Br*BB/rj2W1r*9/*r*95*#[1A7>?b65>$Lf+s&oBA!6>)[s2k51qO[_Z!201^rhBCc +r1O(`r1X4eV#7(cVYm7jVZ*L_VZ3RmblGubbQ#``ans6\bPTHRb5fcbc2Q#ec2>leblGudb5nH: +rhfdqWW&n&X/rD)Xfeh1rilF-!4)U1s0Vg6rjDm;\@DOK!kQ"Urk& +JcC<$JcD):k5P2Tr;??erqcWir:p$&q1As)K7ec,FF-i9re(-%rdtim[^NTNZa6sB +Yct=6Xf\\*WdXPh!FAt/?3t%AlqGIGn:f1(dr)3MkpJCmS!1!JJrJ:$"s+p]3pk\s,regZ2s,-c5p583ps,?oE!1TR]E5d\ +^AbkJ^qp#es2,>b`Poj:a2l?Dai_fMbg$.4-I:&ddF-LneCE.%f@\d1g=tB;h;-rFi8ESRj5]4^ +k2tjjl07L!rp0[Qmf)YUnF?MK!qZ'Vrq6 +JcC<$JcD):k5P2Tr;??erqcWir:p*3&X,i5X,07r]pTP5sbK:)*pJO5!D1r5<_:r5X.Fr4?G\q91qlK +8P2VS8HVLR84`_L#t6[75!;A)7nleV9a"3c:/4jc;>F,h;<:^U;>sDe:]4)n;,C(d;,I0fr_W5a +r_WVlrDAhr=Su+n;Z9Mp;H$Nk;Z0Go;H-Wp;ts8h;>a5j +:B!rg:/CU\!Mu[mVZE`qri-4(XK8P+Y-+u-YlCs.ZMq31[/[Q5[KTR]E5d\^AbkJ +^qp#es2,>b`Poj:a2l?Dai_fMbg$.4-I:&ddF-LneCE.%f@\d1g=tB;h;-rFi8ESRj5]4^k2tjj +l07L!rp0[Qmf)YUnF?MK!qZ'Vrq6 +JcC<$JcD/=NS,SiVRJ`BVJsoc[< +qK`0hI/A9iHMr3aHMMpfI/J?fI.r!fI/JBmIf"WpJ/`i[H[0mYGB\4QE-?AKCM7HsCi+E[@53rE]>+r`]Y3=^#$6=]np4q-*f$s2P)ZqjmSTrh'4` +qP!n_s.T=_s.TCc!McIgV>6tgVe#L(B7 +Unji`VZ*IoW2]crs/Q.$riH7)YHRr0!jT&:rj)[5[C-"Bs0i!_:P +_o2Pn!QN1Za?I_gbKJ,Sc-FV\d*^7he'umtf%8O+g"P07gtgfChr*GOioB([jlY^gkih9qlKdg' +mI'E2n*ol;o()DDo`"O`pAamcq#C0iqYU0hr;HTcrdk*#s4RF&~> +JcC<$JcD/['R*EZ*:I9 +Y-"h-X/bf@%pWCI?=6i8JqAGuH?XLREr9#= +qf2XTqetk>pMKbErGDRPrb_XPrG2OPDJoAhqJH:Orbh[O!,h^QnS\AFr,21GrGMLNqJcFR")r0q +DuOSdChmg"BPM3p@q&qV@Uj%]@Vo$B;uKVn;>a>j;>jDk;ZMaTN;6?O;u0Ap;,C+e;#F5j;>3oe +PQ@&8reLH.nV?ams,$c5rJCH0s,6]1l&,S$R/NEQR.ZgBQiNKKQM-[EQLL7@Q3EPLUnsobrhfdq +WW&ptWrT7#XTGZ/YPta-Z*L\7ZN@MA[JmW7[fEr;\c95@]DfGE]tV5[^B)-drk\]R`;[^V`lJ)" +50:sjbKS5UcHab_dF$CkeC<%"f@S[.g=k<:h;-rFi8ESRj5]4^k2tjjkiq?slg4!*mdBQ4nF?&> +o(2JFrq6 +JcC<$JcD/F,h;<1UT;>sDe:\mo`;>sDb;>j>k +;>sAn:JO[a:]=)i:Jh!c!)WPg!)WVks&/em!)WJe!)EGfqb[&`r_W&Zk>:qNqbR\r:f1%f:K(1i +<)lmqr^mGf91_T@6T.(kpc\Ij;$'Wo;u9Jk;$'Zq<;ohk;Z0Jk:]X?er_3Dg +:\dieV#R7kVZ*IoW2]crs/Q.$riH7)YHRr0!jT&:rj)[5[C-"Bs0i!_:P_o2Pn!QN1Za?I_gbKJ,Sc-FV\d*^7he'umtf%8O+g"P07gtgfChr*GOioB([jlY^gkih9q +lKdg'mI'E2n*ol;o()DDo`"O`pAamcq#C0iqYU0hr;HTcrdk*#s4RF&~> +JcC<$JcD5>jSnuRqu$9erVHNhr:p^S=BJG!13PL*L`R8VPU/fVl6Sn +WMZMuZa-j?Yck43XfSS'Wi;9XQ61BpH[L0QB:c6)Vl$5ZR$O#!MM?\1H?j^HAS#C^@q#@cs*t2\ +?t!UF\HB@LZaB_<)mZ`RYcb(/X.YiM_h3u/FDu/6DfTo?Fa/LjK_pH)L4t?\LA6Q&LAcl4L51P= +LPLVlS".>l7n-?N4C4?iXR3?N7>2ZNFH<>[@;5rE]>+r`]Y3=^#$6=]np4q-*f$ +s2G&ZqjmSTrLa+_qk="`rh97_rh9:b!McIhV>[:hVs(#SblGucbQ#`_ans6\bPTHRb5fcbc2Z)e +c2Z)ebm;P:U8+N[V5:'gVZE`qri6"!!3H1%s/l@*rilF-!4)U1s0Md6rjMj9!4`$=!kQ"Urk&9F +^Abk]^qmk(_Sa:0`Poj;a2l?Db0.uPc2Q!7cd:(edaQ^qe^i@(f\,!4gYCW@hV[8LiSrnXjQ5Od +kNM0plKeH9#4:jIn*oi:rpg*]o_nFap@n=[q#C0iqYU0hr;HTcrdk*#s4RF&~> +JcC<$JcD5>jSnuRqu$9erVHNhr:pYAZa-j?Yck43 +XfSS'Wi:F@IMlBm?!^i>=*]CHI!U*^FE2>:BOtX]?!LQ8qcEf-$XmLTi>2K`Qp^ +rdtr;JUqrdHAuccG%PAr@q9.^BPM=%ErL1\FoQObF`_a)Fng.YFo$7bF`qqNG'E,]`6qf)IQ!-8$X")r7"E;FM?DYS)EDZ4MQDZ+GPD?+PQD#\>PDYn;JDZ=YSDZ+DPDZ"GC +DZ=YQDY\5NDuahSD?4ZnrGVRPrc.jT%W?6&Ci+$)C2.EqBkM-grF,k=ARo9L;uKVn;>X8j;>jDk +;ZMaTN:BdK;,C+e;#F5j;>3oePQ7$JL]*%uL\?Q'M>rJ4L]E;1MZ8V1MWp&qR/iWIQhm'LQhcs@ +Qi< +JcC<$JcD5>jSnuRqu$9erVHNhr:pjDm<<#nsZOO4F +Yct=6Xf\\*WiE$rpJW.`-nQu%3&Wue5sIIq4$,G^3&E?F0J=t/5l;?0Sh;Z0Jh;?0S];?B]l;"d]^ +;#4&e;"dcb;#aDl:]aEf:B"&g:'"-ep.kZbr_`\nr)*8cs%`JfrD<2`r_NVk;"7?F;"mic;#aB' +:esn`:Jjtf;,L4g;cHUnr^mAd9M%T?69b0-qEO^<5?(T_ +n5B?eTR +]E,^[rkB/__84"*_o'F3`Q#s=aN2KGbKJ,Srluh9d*^7he'umtf%8O+g"P07gtgfChr*GOioB([ +jlY^gkiq?sli-5TmI'H3nF5uIncA@SrUg6cp\4X]s7u]kqtpBjrVc?eJcC<$g&HR~> +JcC<$JcD;@jSnuRqu$6drqcWiqtU3cs7ZEas7H?_rpp*Z!:^!Vs6]mSrp0[OlMg#Kki_s-!TiDA +irS/urnn+?hVI#CgtUQ:g&7cNVl$>fV>d:hUB70`T`1S\T)Y>^S=BJGs-WhSqj7SMRolP`Uo!se% +]$D8Yct=6XfSS'Wi;qppm)tJFa\XbI;!2oWMcYiSX>_.Nf/XEIsQ?_Fb#!kIt@TJ#(M5WJm_tsr +j`-?[Bm7>ZQ6?VZ*:C5XJhn[Y*Os5O)o>XDfTo?G'S^mKnY25qh5$)re:?+s+^`3LPLV>r.b0*s ++U]4L51P=L&Qc'K`QjZrdsutr.+]pr.+`qrdOfnq0W'drH\3bq0N-iHiA[:"a,$5FE;F#FpVr!BkqO2E +Gf)hrETA,!*oJ.ra,V3s'Ph6r*KB.!OH&1?2\%,?2Rt,>6nD8>$G05=^#&*>5q_-`lH,%rgikVr +h'1_qP!k^!29@arLs4brhBIhrh]RjqkjFkr29"\prrZZs2t;^qTAi]qo\QSs31Gds3CVgrQb>cs +.K[lUSFW\V5:'gV['0"WN)u!X/u<&s/l@*rilF-!4)U1s0Md6rjMj9!4`$=!kQ"Urk&9F^AbkJ^ +qp#e!Q2kT`@]*MaN2KGbKJ,Rc-FV\d*^7he'umtf%8O+g"P07h;-rFi8ESRj5]4^k2tjjrojUOl +g4!*mf)YUnF?MK!qZ'Vrq6 +JcC<$JcD;@jSnuRqu$6drqcWiqtU3cs7ZEas7H?_rpp*Z!:^!Vs6]mSrp0[OlMg#Kki_s-!TiDA +irS/urnn.@hVI#CgtUQ:fo#ccreg`4reLQ0rJ(6(qh4ctrIXot!ciWarIb$$%tfJ>Z*:I9Y-"e+ +WiE%sVtb]`>Zk?=?XQr9Jpr)nH?XIODes-"@piVI>$59C@:dYG\@"d$"da^C2J!3FEDU&F9?Z-FERS)rcS6a"Eem2Fa!\*qK<6hG'8"OG'.qL +F`hg*FTQZ+F8BqVEW:"XDu4MOE<(%YEW:"XEVXP?DYe5EDZ=SQDZ+GPD?+PQD#%rED?=`oDYn;L +Ds;08DuXeTDuX_TDZF\SDu+GPEW'kVE>`e:Df0E1D/F')Bk_3ljPa.P1LPPhamt^[oqhb9-!f;ekp58*mq3_5Mp6YTB +!13MIpQtiEnWcHjkbdF-LneCE.%f@\d1g=tH>hV[8LiSrnX +jQ5OdkNMp0"mYF?m-X6?mfDqJrpg-^o^r.Us7QHerV6EgrqcQirVZWmo_sFAJcFF'J,~> +JcC<$JcD;@jSnuRqu$6drqcWiqtU3cs7ZEas7H?_rpp*Z!:^!Vs6]mSrp0[OlMg#Kki_s-!TiDA +irS/urnn+?hVI#CgtUQ:g&4kI<<#nqcOr[emF1dODl4[(ti3]B#S2)?p>/hJV.1G\qcs"js:1c7-R3^$:<9*7aX +91o1T(J%%c7n6$,2*O/[77pa8j;?'Go:JOX_:]=)i:Jga\r_`YmrDhohYN_mSE%C +q,.)es%rbmr_F>,;,C%`:f((f;,U@m;c6Id8kMZI7RKQ<4o.D;56"X_#=8l>%=nPnf=oVUr=8>eq;u0Dk;$'Wo;u0Dj +;$'Zq<;ohl;Z'Dj:]aEf:&[lf:]+&hTa.TR]E,^[rkAKL_>_:P_o2Pn/]PiPaN;TJbKS2TcHab_dF$CkeC<%"f@S[. +g=k<;h;7&Ii8N\Uj5f=ak3(t-klpAU6gqu-HkrUg)? +s+14's*t~> +JcC<$JcDABjSnuRqY^-crqcWiqtU3cs7ZEas7H?_rpp*Z!:^!Vs6]mSrp13^lK[Wuki_-kk2k[b +j5].Xrnmh7hYu=7gtUQ:g"?5"rh]UirhKLf!29=_qk!hY#+V0PR[KS2r0dGL#+J\cVPU/frMU1) +VQd8,Xf\\*WiE%sVtlVoIa>Xf87qURmm>Q][/\KRS:IGQW,=J:@HH$@[PXJ72hqVRa7H +rNuU2!4)U/'X+WuS!(FKLQdpDFE28=EccPOKS98Ws+L-#reCH.!JZC)LAlu*L&cr+K`$N(K`6T! +JbsurJ,FirJ,OipI//-fHMr-bHMMmgI!bj=!."Kerd"Hgqg&3frd4Qhr-8BjH[C)3HhVjWHi&3g +Hhr-fIK+coJ,OosJ,Fg5I!^-bH?jXXG][nIF*;>6CMIU#E,gkCr`oJ-s'5P/ra,V3s'Ph6r*KB. +!OH&1?2e+-?2In+>6nD8=^,'4=^,,+>5qb*`WF1_SbSfTTDkM\U&C_cT`Cb^U&UkdUB%+hV>[:j +VuN^kVt[(fVuERebQ,icao]c/b5KHZb5]Z^b4EgTbl>ofcMl)dcMu/hbl=@9U&UheU].%iV5F6i +!iW)tri-%#XK;E'!j8`1ricI/ZEjJ9#ILnH[^NZS\Gj$<]">Se]Y2"m^V@S"_8=(,`5KX6`lH0A +ai_fMbfn>WcHjkbdF-Lne^i@(f\,!4gYCW@hV[8LiSrnXjQ5OdkNM0plKdg'mHs?1n*ol;o()DD +o`"O`pAamdq#:*hqY^6hr;HTcrdk*#s4[L'~> +JcC<$JcDABjSnuRqY^-crqcWiqtU3cs7ZEas7H?_rpp*Z!:^!Vs6]mSrp13^lK[Wuki_-kk2k[b +j5].Xrnmh7hYu=7gtUQ:g"?7[s,-f4s+p]1rJ(<*q1SWtq1AKp"aX!nK7nmSKFEI:YHG"0XK/A$ +WMl`jINDj">[CfH;BP:pb?sHo?>%(lK@JjU7AH,X5YJ,ODf0IjD#eJQDs2*7DuXeQ +DuOYRDu=SREVsbUEVsheDf0H0DJa3+C2%?qB5;&V@KU+N@rM?Er)*Air_`VlrDW`S",r4:;>a;l +;u';t;,C+e:f1+g;,[BjpJ;$XQ'P4$L]*%uL\ci%M>`81M=ui(MZA_1MuJ\7MZB.>R/iWJQhm'L +Qhcs@Qi36?QiE`YU&UheU].%iV5F6i!iW)tri-%#XK;E'!j8`1ricI/ZEjJ9#ILnH[^NZS\Gj$< +]">Se]Y2"m^V@S"_8=(,`5KX6`lH0Aai_fMbfn>WcHjkbdF-Lne^i@(f\,!4gYCW@hV[8LiSrnX +jQ5OdkNM0plKdg'mHs?1n*ol;o()DDo`"O`pAamdq#:*hqY^6hr;HTcrdk*#s4[L'~> +JcC<$JcDABjSnuRqY^-crqcWiqtU3cs7ZEas7H?_rpp*Z!:^!Vs6]mSrp13^lK[Wuki_-kk2k[b +j5].Xrnmh7hYu=7gtUQ:g"?7%pf%5nq,RJqr)WbrrD`_qq,@Mi78QiZ;>jDm<")^0YHG"0XK/A$ +WMl`k;ZfuM-nG9K+u_AF5sIOs4?GV`3&ENK0etC6/1WG21GUaB1c$sF1Hdc_rC[,^r_*5^*_8dj +84PQk5!gto7nl`S:/=VY9i+S\<)?Fh;c?Rkr_NSlr_WVlqbdDkrDNMir)3Mkm8iooiLle!)r_lr_W_p;cEQkrDaN;TJbKS2TcHab_dF$CkeCE.%f@\d1g=tE=h;7&Ii8N\U +j5f=ak3(sml0@U$m-X3.n*fc9nac8BoCW%Ts7ZKerqQKgs8)ZjrVZWmoDX=@JcFI(J,~> +JcC<$JcDDCjo5&Rqu$3crqcThr:p!;G&q_CDfKlFH\-qHL&Zi"L%C&uL\c`*L&H]'L&Zf-K7\^RJH1<$ +JbsurJ,OorJ,XosIK+]iHi89iH2)^^HiJHnHiA?hGlE!dH3/A[:!.+Qg!.+Qi +"FPQCI!kj=pNlFXqL&3fqL&3hs*jips+(&tr.+cts*PK,H$FRXG'A%GF`qS;C1h9rF`MC!>lS%. +>lJ%.?N4C4?iXR3?N.52ZX!K8s'5J-qcs,)#[1A6>?Y04>?go,s&oBA!lnDDpn%GVrh0.^rM'%[ +rM'=e!MlRiVZ3RnW;3@dVZ!FmV=i%4bPfT`b5f]aans6\bPTHRbPTN^c2>lec2X@?T:hjNTq\ +JcC<$JcDDCjo5&Rqu$3crqcThr:p**ccU?=?o;?Y0=@U]7Fs'l7DAnG%CY3liPa.P1:]6+W/0M>)o)MuSb2MuAV7MZ9(=R/iWOQiEHPQhm'LQhcs@ +Qi36AQiEW^T:hjNTq\ +JcC<$JcDDCjo5&Rqu$3crqcThr:p1G^dB1GgsF2)@EX4[_t:91_`K9E%Kj84Q-? +7lO,h;>a>k;>sJk;>X8j;=.6];>a5h;#O2e;#4&h +;#a;k;#!ob;#aDm:BF9c:&Rle:B+/b:B=9hr)*Yp;Gp@grD3;cohPQaqbR2fmSE%Cpeh#es%rbm +r_NGgr_`Yk$W0\s;Gg4g;HHgk9E%Nc9LD3:r]^?Fs$$k;$'Wo;u9Jk +;$'Wo<;fbk;Z9Pj:]O;h:(0op:S+/MTV/!PU8+L_U]IaN;TJbKS5VcHjkbdF-LneCE.%f@\d1 +g=tE=h;@/KiSrnXjQ5OdkNM0plKeH9#4:jIn*oi:rpg*]o`"O`pAamcq#C0iqYU0hr;HTcrdk*# +s4[L'~> +JcC<$JcDDCk5P/Squ$3crVHNhr:p9cs7ZEas7H?_rpp*Z!:^!V#O_!Hm-O'(lMg#dki_*jjlPR` +j5T%Vi8EMLh;-lAgY1B7f[naSV?!IjV#R4iU&q$]T_tGZT)YA]S,o+Jr0dSPs-`_Ns-FIi=/Vpl +Vl-JkW2Q\sX/`2!W2HPjV#6MnG]\=\I:m2(XJi(nSsbt3P)G-MJ:%9?%sNSSIXlouIt*$&JV7H? +F8i]M\,Nc7Zi76EYcj"TNk1L3RZV]6Ec?#>Fa8RlK_L3#K_C,kLAlr1L4tA9re:E,rIk*&s+:<' +r.+j"rIP!!!eGlPrI=crrdXlqrd=copj;scs*=Bcq0W-h"+,??H2W!eH2)^bH2W'fH2i3gH2`-g +Hi8?iHh_pXHi&3gHhr-fIK+clIfP#uJ,=cqJc:3"Hjb7FH$FOWF`VYICi')c$#G!/Dd6OO>?kG4 +?2e11?iOL6?i47/Z2e//>l\.,?2In+>6nD8=^,'4=^,,,>5h\)`WF1_;[TDbG\U&C_[ +U&C\cU].%hV>R4_VtHneV=Vn2bPfT`b5f]]aoBN`bPTHRbP]T^c2>ifc(4j*#G7Z^TqS3TU].%o +V5C,fVl6Pnri6"!!3H1%s/l@*rilF-!4)U1#ILnH[^NZS\Gj#>]"@sS6+t"I^VI\%_SX4/`Poj; +aN2KGbKJ,ScHab_dF$CkeC<%"f@S^0g=tE=h;7&Ii8N\Uj5f=ak3(sml0@U$m-X6?mfDqJrpg-^ +o^r.U!quB_rV6Egs8)Wirqu`noDX=@JcFI(J,~> +JcC<$JcDDCk5P/Squ$3crVHNhr:p9cs7ZEas7H?_rpp*Z!:^!V#O_!Hm-O'(lMg#dki_*jjlPR` +j5T%Vi8EMLh;-lAgY1B7f[naSMYr>2L]E5.LAlo&K_pDrK)C3!J-1*oK7iuQ$*:2-Wi;qpVl$9f +IN2Tp?=.&@=&jj$IOI +M/RB\HtR,)AS5XlCiOOqFT$7\FSg.RFRsYPG5ZR`FT6L`F9$I_F96N*F8BqSEW9tXDu=SSE<'tT +EVseODte,LD>A)FD!NDWRP;Z9Vj;@-2s:f1%d;Gp@i +r_`Dd"I,1;:J^tGmt^drpPB*3M2@%EM2D"bqhtH4onrg-rL!DKs-W\Ms-WSJ!LT5LQM-[DQLpLD +Sc52cT:hjNTq\9VrhKdqVP^8hW2Q]pWrK+"XT#@%XoP[)YlCs.ZMq08['daN;TJbKS5VcHjkbdF-LneCE.%f@em3gYCW@hV[8LiSrnXjQ5OdkNM0p +lKdg'mI'uB!V#XYncJFTo`"Lbp@n=[q#C0iqYU0hr;HTcrdk*#s4[L'~> +JcC<$JcDDCk5P/Squ$3crVHNhr:p9cs7ZEas7H?_rpp*Z!:^!V#O_!Hm-O'(lMg#dki_*jjlPR` +j5T%Vi8EMLh;-lAgY1B7f[naO<;fet<)r`p!*/tur)Nbrr)E_rr)FjF8kM`Lr^dhq +7n-$-0g.`V84QBM:JO_]:/=__<;oeq;>sAl;>sGn;>O)h;>X8j;>jDk;>X8j;=.6];>j;h;#O2d +;#4#k:esk`q,-ub##S2m:JOVYr_NJfs%rGc!DlYh;?9Wkr_NDdm8*^XmSE%Cq,.)es%rho:J^ja +r)*Jj$rTku;H-Lktr=TV],=8c7j=oVV(=8Gqt;ta2j;u'>j;?'Pn;>sJl;$'Wo +<;ohm;ZB\q;?9WkqbR,bs%`Wcrgj@eTV/!PU8"F^U^*`nVPg>jW2]crs/Q.$riQ4'!3cC+s02R0 +rj)j:[C*HO\$rmH\H0:Rrk(P1^;%Fu_84"*_o0O5`lH0Aai_fMbg"GYcd:(edaQ^qe^i@(g"P07 +gtgfChr*GOioB([jlY^gkiq?slg4!*mf)YUnF?MK!qZ'Vrq-?dp\4X]s7u]kqtpBjrVc?eJcC<$ +gAc[~> +JcC<$JcDJEk5P/SqY^*brqcThr:p9cs7ZEas7H?_rpp*Z!:^!Vs6]mSrp0[OlMg#Kki_s-'BS<8 +j5T%Vi8EMLh;-lAgY1B7f`'J'VPX3drhBUjTqS-PrL`nWs.01["IkjKR@4&ArgEVMs-NbQ"]p8P +Vl$BiW!KE&W2HPjV50CUQ54jiI=-EjB4md7W2?5YR$EtrM2$Y2H2`$uJUi6$I=H`pIY33&?smLD +\H04Jrj;^3'XG*NYDU2f^4qZ@F`__GEH65KIY7WRs+L0$s+L*"re:E,pP/[&#)7hbKnb;8r.P!% +!eZ)Vr.4m"rdjutrI=fsrI=fqrI"ZnrHeNlrHnKh!."?cpj<$g"+,??H2`'fH1uXbGl`5:rd"Wk +G^0%0rd+TkqgA?h)3s'>V1s'Pe6!+5Y1rNZE.pKdZ$r`]Y3=]ns4>$5'6qHEo%#$Amca&lDEr13kZrh'.^ +rLs.`p7_M\s.fRhs/#XjoV_AZr6+lZ!6b;_s2tDbqT8]YrQ4lXq9/][r6>/b!h5^Nrgj@eTV/!P +U8"F^U]RBiVZ*IpW2ZcqWWB0%riQ4'!3cC+s02R0rj)X4[JmTB\%&rY\[oDb]Y(qlrkC_6_8=(, +`5T^8a2l?Db0.uPc-FV\d*^7he'uq!f@S[.g=k<:h;7&Ii8N\Uj5f=ak3(sml0@U$m-X6/n*fc9 +rpg-^o^r.Us7QHerV6EgrqcQirqu`noDX=@JcFI(J,~> +JcC<$JcDJEk5P/SqY^*brqcThr:p9cs7ZEas7H?_rpp*Z!:^!Vs6]mSrp0[OlMg#Kki_s-'BS<8 +j5T%Vi8EMLh;-lAgY1B7f`'M&MYr>2L]rQgL51M%WN!"omLkkt`re(r$ +S9Tm/G(=4S5HD=)3@D>\5ID>J,RDf0H0Ci')frGUqj;Z9Pl;Z0N!Mi +JcC<$JcDJEk5P/SqY^*brqcThr:p9cs7ZEas7H?_rpp*Z!:^!Vs6]mSrp0[OlMg#Kki_s-'BS<8 +j5T%Vi8EMLh;-lAgY1B7f`'M#<;fhs<<#tqjB";cKcrW2HPj +V5.)i<@KII.kE8(2`*]a51,CgF1GgpE4ZYc&r_"5'91qlK8OuBB +82X4-5=J+89heDX;,0k\;,U7gr)3Plr_N\o;GpBg:]OAl;?Bcp;Z0Jl;Z0Jj;Z'D[;?0Pl:]4,g +:\moa;$0Wj:Jgmbq+q8m:esk^9ht[`r_'55[Y>56"X_a5P7;@5m9VB5s[b#r'16J +rBCTR5sRY6<`VIM5lOa[;uKYqsJl +;#jMn;ts8j;u]_r;,I-crD*Ag!h5^Nrgj@eTV/!PU8"F^U]RBiVZ*IpW2ZcqWWB0%riQ4'!3cC+ +s02R0rj)X4[JmTB\%&rY\[oDb]Y(qlrkC_6_8=(,`5T^8a2l?Db0.uPc-FV\d*^7he'uq!f@S[. +g=k<:h;7&Ii8N\Uj5f=ak3(sml0@U$m-X6/n*fc9rpg-^o^r.Us7QHerV6EgrqcQirqu`noDX=@ +JcFI(J,~> +JcC<$JcDPGk5P/SqY^*brVHKgr:p9cs7ZEas7H?_rpp*Zs7$'Ws6]mSrp0jTlK[Wuki_s-)!0i= +j5T(Wi8EMLh;-lAgY1B7f[na+etr>@rM0@crh0:`pn%MVs-s(YrgEhTrL!VQo9]M[rMKUn25dCP +W2HPiUnjcOQ@!h%H[^ETB4\'@VP0WMQB[DeKn=c"H$FL_It)utIt2uuJV/Pa?t6VD\H');[/[HH +ZEpj?X-]uSM4A^1FE2AAFa8CfKD^H&K_U9$K_L3#LAlo%LB!&/L&m!]rIt0&rIk?,K7\^RJc13" +Jc1,sJ,b&uJ,OipI/nZnHN8HlHi86jH22d\HiJHsH[:!`G^045p3Q[_s*=`lG^0%0r-A?ir-\Eh +pj2LXqL&6gqL&6irdONiq1&HrrIFlu*.i`hH[C'`H$FOUE,]Z2ChdU#Cj0o=>?b?;?![G9s'Pe6 +!+5Y1rNZE.pg*`$r`]Y3=]ns4>$5'6qHEo%#$Ajba&lDErLNt[s.B4^rh94`qk=%_rh9=crM9Fh +r20+apSRf1q98l^r6#&_!6Y/[rQ>)\q9&NVr65)`rltM4rgNqYSc52cT:hjNTq\9VrhTRj!2fan +!iW)tri-%#XK;E'!NrX*YlCs.ZMq02['fnA!OoT<\Nd[;]Y(ql^;%Fu_8=(,`5T^8a2l?Db0.uP +c-FV\d*^:jeC<%"f@S[.g=tE=h;7&Ii8N\UjQ5OdkNM0plKeH9$gmBNn*ol;o()DDo`"O`pAamd +q#C0hqY^6ir;?Ncrdk*#s4[L'~> +JcC<$JcDPGk5P/SqY^*brVHKgr:p9cs7ZEas7H?_rpp*Zs7$'Ws6]mSrp0jTlK[Wuki_s-)!0i= +j5T(Wi8EMLh;-lAgY1B7f[na+er'E_reLZ3L51Q`LAuu(K_^8pK)L8qJ36Y\KS4u2K7noWW2HPi +Unjc7IU62_?!gu>=&sg!H[0jYEH#`.ARf.S>[(B@@:sJn;ts6!;,C(d:f1+g;,U:h;>3lj +Pa.M0:JgnCreUH,rJ:H.s+pB*reUN0r/1<.r/CB.qO%)H!1Vf]tV4q +^VI\&_Sa=2`Q#s>aN;TJbKS5VcHjkbdaQ^qe^i@(f\,!5gtgfChr*GOioB+]k2tjjl07L!rp1$[ +mdKW6naZ2@oCMVRp&Facp\ssfq>U6gqu6NkrUg)?s+14(s*t~> +JcC<$JcDPGk5P/SqY^*brVHKgr:p9cs7ZEas7H?_rpp*Zs7$'Ws6]mSrp0jTlK[Wuki_s-(Zj`< +j5T(Wi8EMLh;-lAgY1B7f[na+f)8SHjDl;>a>i;=7tr=o2=h=oVS(=8Z+t;ta/j;ts8i;?'Pn;>sJl +;#jMn;ts8j;u]_r;,I-crD!?]rgNqYSc52cT:hjNTq\9VrhTRj!2fan!iW)tri-%#XK;E'!NrX* +YlCs.ZMq02['fnA!OoT<\Nd[;]Y(ql^;%Fu_8=(,`5T^8a2l?Db0.uPc-FV\d*^:jeC<%"f@S[. +g=tE=h;7&Ii8N\UjQ5OdkNM0plKeH9$gmBNn*ol;o()DDo`"O`pAamdq#C0hqY^6ir;?Ncrdk*# +s4[L'~> +JcC<$JcDSHkPk8TqY^'arVHKgr:p9cs7ZEas7H?_rUL$[nF6GG&FSrQm-O'(lKRQski_*jjlHF$ +"leM!i85[RfStGrg3bRR$mH2!36$q1oI:M +W2HMhUnjc[Q?I\(H[TR?AZDZ*U7[j?Q&UWSKReAoG]n=^Jq&9$IXcs#KS+td@@dD.!4Vm5rj!,V +MiG!.NMCW;EH#r?G^G$rK_gE$K_U6$K_L3#LAlo%LB!#3L4t>7K`6]'K`-W)KE-Z&Jc(-"Jc1,s +IfP#tJ,XopI/nZoHiAElHh;XYHiJHrH[9s_GlE!]HMr-hH3/A:GklX_H2r[:Y7?N4C4?iXR3?N%/0 +>khV$>lIq5>$5!4>$>'5>P_P'=ThjGa2_<]=8nciTDP;\U&:Y`U&:S`U&UheU\pqeV>R4fVt$Y[ +bPBB^bPfT_b5f]]ao0B\ana*SbPfZ_c2Z)hR/i]TRfT%Mrgj1`TV2:X#GRugUnji`VZ*LnVuWgr +WWK6&XT#=&Y-7i/s03'>Za7$G[C3NQ\%&uZ]"@sS5/"\F^VI\&_Sa=2`Q#s>aN;TJbKS5Vcd:(e +daQ^qe^rF*g"P07gtgiEi8ESRj5]4^k2tjjl07L!m-O--rpKmWnc&([oCW%Ts7ZKerqQKgs8)Zj +rVZWmo_sFAJcFI(J,~> +JcC<$JcDSHkPk8TqY^'arVHKgr:p9cs7ZEas7H?_rUL$[nF6GG&FSrQm-O'(lKRQski_*jjlHF$ +"leM!i8o@$O=&j`sH[0gVEH,c-ARo4U>[(B:@UikVraQ=I@q9._ReCi+-4qfMj\s)dpT!H`J[FT6L_FSL"VG5cXXFT-@YErL%[E,fmgE;sqRE;FMKDZ=PTDJa7h +DYS)8D?+POD#8)ED?+PQD#\>PDZ4S=DX_TCDZ4PXE,T]7EH1nqs)IjT!-A!WrG`$\DfBT4DJoGg% +;]NbA7B(Y@;9=_:f1*g;Z9Pl;Z0MoMuJ\?:f1(f;H$Nl;?0Sn;@HE!:f1%d;Gp@i;GgT.rilF-%^NFI['[6L[^W`U\[f;`rk(G.^ +;%Fu_8=(,`5T^8a2l?Db0.uPc-FY^dF$CkeC<%#f@\d1g=tE=hV[8LiSrnXjQ5OdkNM0plKdg'm +I'uB!V#XYncA@Srq6 +JcC<$JcDSHkPk8TqY^'arVHKgr:p9cs7ZEas7H?_rUL$[nF6GG&FSrQm-O'(lKRQski_*jjlHF$ +"leM!i8qt<;]\o<:s2i;?0Sm;C\TA +V50o^U/`Wn/1W>42Dm]`5!:th3B/rS1G^a>0.nh-1,CaB1c%!G2#]?:4$6&.91qnV9E.T`8.A'N +5!;+f7nQNN:esh_r_W\p;Z'Jh;?Kcm:f73ir_`Yks&&bns&8knrDNSkr)3Dhn5B9`!`2Zgqb[5e +qb[,d!)WYjqbd&`s%`\k9ht[`r_4oeU^hs&]8&rDrhpp/D#jqGI>m;Z9Pn +;Z9Pm;Z0Gm;Z9Vj;Z9Vp;?9WkpeUpX!1NnV!M#_[ScYOWT`1ViU8+KZUnsobrhodp!3,st!irE( +riH4(YPtd+Yn"(GZa@*I[^NZS\@K/]]DfH,]tV7r^qmn)_o0O5`lH0Aai_fMbg"GZd*^7he'umt +f@S[.g=k<:h;7&Ii8N\Uj5f=ak3(sml0@U$m-X6?mfDqJrpg*]o`"O`pAamdq#:*hqY^6hr;HTd +rdk*#s4[L'~> +JcC<$JcDYJkPk5SqY^'arVHKgqtU3cs7ZB`s7?<_rUL$[nF6GG)=HnZm-O'(lKRQski_*jjlGL_ +j5T%Ui82;(\[]&Trj;^2 +&%$J[QEGt2Q?@=kEHHGRJbt,tL&?W"K`Hf$L&Qi*L%pB(LPCN^K`6])KE6d[rIt9)!/(6$qh"ct +!.arr!.b&urI4Zm!.=cmrd=]lom6=Ys*Xims*4ZjH$T(/r-8[:Y7?N4C4@/F:/Z2e/)?27b*>6nD8 +=^,'5=^,,,>5q_5=N/>$=BAU+SXl@Eqk3n]rM'7aqk*q_rhBFf!2TLgqkj:hntu0)q98l^rQ>/` +!6Y,ZrQ>)\q9&KUrQP2a$C@-IR@9S6S"-">rgj1`TV2:X!huHbrhKRkVZ*LnVuWgrWWK6&XT#=& +Y-7i/$aI"CZa7$H[C3NQ\Gj$)]">Vf]tV7r^qmn)_o0O5`lH0Aai_fMc-FV\d*^7he'uq!f@S[. +g=tE=h;7&IiSrnXjQ5OdkNM0plKdg'mI'uB!V#XYncJFTo`"Lbp@n=[q#C0iqY^6hr;HTdrdk*# +s4[L'~> +JcC<$JcDYJkPk5SqY^'arVHKgqtU3cs7ZB`s7?<_rUL$[nF6GG)=HnZm-O'(lKRQski_*jjlGL_ +j5T%Ui8?bTH@:E^F@g?OSAS+tCCQ&1NreUN-&qj\DFb+IYI:m/'AnPst +E--2CqK2a[s)dpT!d&R-qfMg[rH.gWr,r'_olU1Src/'[EcV/!!cW.!rbqjUr,;XUrbqsXE,fmn +E;FMKDZ"AMDYS)8D?+PPD#/#DD?=ZkD#S;ODs2*.Du=MMDuObTE;jkJErC"WEXm)-Df0E/Ci!m$ +AnPXbA,]p?Ht6\`;>jDl;>jDk;ZMaTNsH%;,C(d:f1+g;,U:h;>3lkPa.M0 +:JamdL]*&+L]3,.LB*/*M>W2-M>N2-Mu/J/Mu&eBQ^F09R/iWPQirgj1`TV2:X!huHbrhKRkVZ*LnVuWgrWWK6&XT#=&Y-7i/$aI"CZa7$H[C3NQ\Gj$)]">Vf +]tV7r^qmn)_o0O5`lH0Aai_fMc-FV\d*^7he'uq!f@S[.g=tE=h;7&IiSrnXjQ5OdkNM0plKdg' +mI'uB!V#XYncJFTo`"Lbp@n=[q#C0iqY^6hr;HTdrdk*#s4[L'~> +JcC<$JcDYJkPk5SqY^'arVHKgqtU3cs7ZB`s7?<_rUL$[nF6GG)=HnZm-O'(lKRQski_*jjlGL_ +j5T%Ui8]hrDiht"]\N%^,5!DG,;,C"` +:esqa;u9Jk;u'>k;#sKjr_i\ls%i\mr_i_o!)ien"&`&r;Z'Dk;Yj8^;?fur;Gg:f:\mod:]!ud +;$'Wm;#X5j;#F2a;#a>j:B"&g:'+3f;#3ue:]OAg;?0Sm:\mi_:]4&b:]F8Y:ZbLN;>j>k;>sA_ +;#aDk;#aAm;Z9K";,gFj;,U:k<(p$b8d%mU6pAeh;ufkm;Z0Jm;Z9Pm;Z0Gm +;Z9Vj;ZB\p;?9WkqG.HbR$a;1R[]e:S=TYN!hZ-Yrh0CfUSIga!Mu[mVuN[qWW&n!X/rE%XT>T. +ricd8ZEggC['d^ +JcC<$JcD\KkPk8TqY^'ar;-EgqY:*brq?<`s7H?_rpp*Z!:^!Vs6]mSrp0[OlMg#Kki_s-(?OW; +j5T%Ui85[Rf]%HRJrQKR/NBIQk>[NQDpdZ +Vl-JkUS=HUTV%firb!=OV5'WOQ^!YmLkU>+G^4OWJU`/uIt*!!Jq8K)@:=T_])B#O['R'EGF"i< +LR`O2F`_\JH[g[&L5#MXrIt-%nq@."Kn]M\rIss"s+UK+re:?)!JQ4+L&Q`*K)L8rK)^B%JG4Ql +If+TuI!^3fI!pDAHhMdYHiJHnHMi'\HMVpdGklX`H2rlJ%/?N"7.?Mq,(?27b*>6\86=^,'5=oMY&>5q_- +=N/>$r`B;)=Iu.Wr1O"^rhB:`rLa.ar1X1eq5+"dr29Rlqka.dp<39Us3(A`s2tDbqT8]Yr5ncW +q9/][rQPS5Q^=),R@0NCRfT%Mrgs.^!20=bs.TLgrhKUlVPa?j!N^ +JcC<$JcD\KkPk8TqY^'ar;-EgqY:*brq?<`s7H?_rpp*Z!:^!Vs6]mSrp0[OlMg#Kki_s-(?OW; +j5T%Ui8?PG7@K0dCA7K.ZA7S\?AW-PH!/^]2re;,?A9<0XEI;G4AnPdkDfKi= +F`_\GqK)^[rcIgS!-J3_s)\JD>.oQD/=$*D/O91k\fm.rGMLN!cW.!r,DXTnoF_Lqf3EmE,TZ4Df'?, +C2%Bl@U`bS@XM]q;>jDl;>jDk;[JAANJrfn;,U:jrDNVlr_a)#:f("c:f:1g;H!KkpeV*XQ'G-@ +r_NTMr.t6*reUT0reUB,r.t6,qhjd!q3_2K!1T.ricF.ZMq1!['d?N\$rlX\[oDc]Y2%o +^VI\&_Sa=2`Q#s>aN;TJbg"GYcd:(fe'umtf%8R-g=k<:h;7&Ii8N\Uj5oFckNM0plKeH9"mtaH +n*olHncJFTo`"Lbp@n=[q#C0iqYU0hr;HTdrdk*#s4[L'~> +JcC<$JcD\KkPk8TqY^'ar;-EgqY:*brq?<`s7H?_rpp*Z!:^!Vs6]mSrp0[OlMg#Kki_s-(?OW; +j5T%Ui8f +qb[2f##\;p:JXe`r)*/as%`\j:/:dar_A +JcC<$JcDbMkl1AUq>Bp_rVHKgqtU0brq?<`s7H?_rpp*Z!:^!Vs6]mSrp0jTlK[Wuki_s-"m+h* +j5T%si!nT#h;-l@g=k64f@SU(rmV"uUS@[[rh04^qk!YTs.'+X!h#FCrg3MLr0R8Is-NYL!1!M\ +.&`i4T:VXFS7SUqU7Rg@QBR8_KReDqH?aXaJUi6!J:<$#JqJed@=%m`!4Mm7(UUNSZ@A:RQ&D8X +G'.nJG^b:!L51MqJ,Fcn +I0"_Brd4`pI/\KdHM)UcI!bd:o6U:Zrcn6ar-A?irI"QjpNl@VqgAlS"0>$5#-=p%o2>?gu. +s&fG+`Q-$r=9+ukT`1Y`UALYaT`(SaUAptgV"pkaVYm@lVYd4fVZ+a=bl#Z_aoKW]bl>lbb5]Wb +b506Yb5KHWb5'6Ybl>rePl[2;rg3bTR[X5F#Fq?USt;RHT`1YbU&^tfU]RBiVZ*IoW2]cr&?Dn6 +Xf\b/YHY79Z*L^B['fnA::IaD\[oDc]Y2%o^VI\&_Sa=2`Q#s>ai_fMbg"GZd*^7he'uq!f@S[/ +g=tE=h;7)JiSrnXjQ5OdkNM0plKdg'mI'H3nF?&>o(2JFrq6 +JcC<$JcDbMkl1AUq>Bp_rVHKgqtU0brq?<`s7H?_rpp*Z!:^!Vs6]mSrp0jTlK[Wuki_s-"m+h* +j5T%si!nT#h;-l@g=k64f@SU(rmV&!M2@&eL]3&,L&Qc*K)gT%KD:&oJb=QiIfOrsK`?ZATqJ$L +St2BNI=-<`FE;D=C1^sc?sR#A>Q/+3@K'a@ARf7`jDm:^9io;,U:h;H!KkpeV*XQ'G-@ +r_NSirJ:?+qhY0,!/gc4qhY0,qMO^!rg3\Rr0[GL!1[SF
+JcC<$JcDbMkl1AUq>Bp_rVHKgqtU0brq?<`s7H?_rpp*Z!:^!Vs6]mSrp0jTlK[Wuki_s-"m+h* +j5T%si!nT#h;-l@g=k64f@SU(rmV"usJl;u0Dk;ts8j;>O2j;$Bir;c6Omr_ibn!)iepr)*GkqGHrarDe>s;,C4n9`@Zf8kVfF7/]@M5kmMCe;>sJl +;#jMn;uT\p;>jDm;u]_s;,C*f:]?U[QC%T +JcC<$JcDeNkl1AUq>Bp_rVHKgqtU0brq?<`s7H?_rUL$[nF6GG-1:0fm-O'(lKRQskND!ijlGI^ +io8qTi8t8R/WHPQiNQQR/<6KR/WHMQMd!e +VPg>jSt;LCS"#k7T:;46PE(HQJUVrjG]e.ZrI,$%IY*3)Jmi(urON!qJ,Fcn +IJnQnI/nZoHhVjYHNAM?rcnKgqg&6fq0MsarHS-`r-A?ird=WjpNlCWqgA7"J9=^#!5 +=^#$6qca#&$!>3ea&lGH=BS`'T_b>^T_G/YU&q*cV"pkbVYd7kVY[.fVYA:5b5]Z]bQ,i^b506Y +b5KHWb5'6YbQ?%QPl?pKQC%TXcd:(fe'umtf%8R-g=k?< +h;7&Ii8WeWjQ5OdkNM0plKdg'mI'H3nF5u=o(2JFrq6 +JcC<$JcDeNkl1AUq>Bp_rVHKgqtU0brq?<`s7H?_rUL$[nF6GG-1:0fm-O'(lKRQskND!ijlGI^ +io8qTi87uKD>.oJD>\5JD>.oLD/=%fD?"PQE,kborc.XP!-/!YrGh[Ss)\0[$#jg# +D/O6.Chm\_@fTs:@KC"LpJUrg$&jk'N/UV2;GpHl;Z0Jl;ZBPu;,C+f;Gg=ir_`Ge"I,1::J^sd +!)EKKqhP0,r/(E1re^Q/qhb0,qhkH5oo&R3rg3YPqO%>Nr0RDMr0RDKrg3SLrKmGJqj78IrKdPK +Pl?pKQC%TXcd:(fe'umtf%8R-g=k? +JcC<$JcDeNkl1AUq>Bp_rVHKgqtU0brq?<`s7H?_rUL$[nF6GG-1:0fm-O'(lKRQskND!ijlGI^ +io8qTi8V,K#t[ZY/hfCQ2+C@?:BXKh;,gEl;Z'Jk +;?Tip;H$Nh;?0Si;ZBSt;H$Ll;cEZn"]8/q;c?Tk;#jMi;>*od;#jMm;>j>g +;>*ff:JO[`:]4#h:JgsbqbR8iqbmGk!)WViqbHr_r_E;cs%r,Zk"tkNlVIX[;GmEi!)`YlrDe;>sJl;?'Po;ZK_o;>jDm +;u]_r;,I3e!L&cIPl[2;rg<_R!1NnV!h>gPrgj@eTV/!PU8"F^V#R7kVZ*IoW2]cr$`gA1Xf\b0 +YHY79ZMq1-['d?N\%&uZ]">Vf]tV7r^qmn)_o0O5a2l?Db0.uQcHab_dF-LneCE.%f\,!4gtgfC +hr*GPj5]4^k2tjjl07L!m-O--n*fc8nac8BoCW%Ts7QHerV6Egs8)Wirqu`noDX=@JcFL)J,~> +JcC<$JcDhOkl1AUqY^$`r;-BfqtU0brq?<`s7H?_rUL$[nF6GG#O_!Hm-O'(lMg#Oki_*jjlHF$ +(ZOE3i8Mrg3JI +rKSe&R]!'\Vk'?IS!ob4R$DALkphAL4t?ZK`?])KE-`(K_^<%K_pK"LAci#LAci'K`?`/KS>,5K`6W&Jbt&u +JH15qJ,=ZqI=2$Bs*Xcn!.=cmpj2LX!.+Thr-JBgq0N!br-8$_rHeKjrd=Wjpj2IWqgA$G5.=q=b<=N8A$=BJ^.=BD/fT:l.V"/)?\T_Y;YU&q*cV"pkaVZ*LmVY[.f +V?"j7bPoZabPTK`bP96Vao0B\ammLRbPfZbP5g^GPl?pQQC!r*R$jA2rgWqX!1j+\!hZ-Yrh0@e +U].(hV#[ClVZE`qri-""XT#=&Y-7i/9!P\.Za@-K[^WcW\[oDc]Y2%o^VI\&_Sa=2`lH0Aai_fN +c-FV]dF$CkeCE.%f@em3gYCWAhr*GOioB+]k2tjjl07L!m-O--rpKmWnc&([oCW%Ts7ZKerqQNh +rqcQirqu`noDX=@JcFL)J,~> +JcC<$JcDhOkl1AUqY^$`r;-BfqtU0brq?<`s7H?_rUL$[nF6GG#O_!Hm-O'(lMg#Oki_*jjlHF$ +(ujN4i87aVr.b3)!ec8]re19'pk&6komlmgrI+cjE;kM*K:SO% +S!ob4Qu?q[BP(d`?%7J>s'l"aG_U*aIVSjq"_r!sF*;g- +GQ2gfF`_a)F8p@^F8L(QEr^=TFo?FRFoHL_F8g7aF*)MFF8g4VEVj_TDu"AODZk$!EH#jnE;FML +DZ"AODZ+DPD#/#EDZ=SJDZ=SQD#J5EDZ=SRD#\>RDJsIWDXhZCDZ"DSE,fmsE;OYLErU.YEr9qS +EWU<&ErC(ZDuOV`D/=!'An5F]@UikVARkL5rDO#]NK&mU:f1+g;uKVm;>sJn;#X>l;ZBSo;Z9Pg +;#cabPtt1P:esiBq1ns*re^Q1re^Q/r/(9-qMYB4p58p=pR(rHs-W\O!1aN;TJbg"GYd*^7he'uq!f@S^0g=tE= +hV[8LiSrnYjlY^gkiq?slg4!*mf)YUnF?MK!V>s_p&Facp\ssfq>U6gqu6NlrU^#>s+14)s*t~> +JcC<$JcDhOkl1AUqY^$`r;-BfqtU0brq?<`s7H?_rUL$[nF6GG#O_!Hm-O'(lMg#Oki_*jjlHF$ +)rfi7i8k#%S"#k7R$]fm3&WTK0eb74/M&S21GUaB2D[0I1Gq6Y8GYsl8OuB01-[rk8P`,W:Jabb;,L0f +;Z0Pl;ZBVo;?0Yd;ZB\o;YsDk;Z9Sp;Ys;k;Ya2`;YX,f:]O;i;#X8f;#X;q:f:1g:f-sbp.tfd +:/:a`rD*2bqbR8iqbmGkrD38bqG7)cq+q#emn`%Aq,.,fs&&;_#>nAs;,C%b;>jDg;?'Gn;,I3h +&5uS/9h\/Q8kDWD6pEn$5X5'.r)Ne_r]g6Es$$lW6:*t(6:*t(5X.L35QF+J56=)95Q4X_62j.L +5lapa5h\#=Sc1s=SQ#!<:j,h<<#ts;ufkl;Ya2h;Z0Jm;ZBYq;Z9Pk;ZB\q;@$,r +:J[.:PEV71PmT.rif#" +ZEpmE[C3NQ\@K/]]=bei^;%Fu_8=(,`5Ta:aN2KGbKS5VcHstddaQ^rf%8O,g=k<:h;7&Ii8N\U +jQ5OdkNM0plKdg'mI'uB!V#XYncA@Srq6 +JcC<$JcDkPl2LMWq>Bp_r;-BfqY:'arq?<`s7H?_rUL$[nF6GGs6]mSrp0[OlMg#nki_*jjlPR` +j5T%Ui82^S!ob5rg<_Rr0[>Irg<\OqNh,G +"IbU9L40'!%%E]RR$a5+Q&13IIsV*<%sEMSI=6WpIXm!&JqINAB)]@A\,NcJ['R'#V4ktfSTT+# +F`hnWJVB![M>rD3LB<3aL&?W(KDC2rK`Hf'L&-Q&L%^9#L&-K$K`Hf*K)gN$Jc(-!JH15qJ,=Zq +I=2$Bs*Xcn!.=cmpj2mc!.+Bd!.+ThrHeKhq0Msar-8$_rHeKjrd=ZkpNlCWq0`0grI"Wl!.=co +s*arrrI+`rrI4Zos+(&tqgeWrs*t0%JqElPs+L6&'n:UYH[9s_G'@\8D/*m$Ci+64?!Ue8?i47/ +Z2q::qH`l$s'#J,r`T8)"'Jf3>Pq\)=oVV(`X'Ue=BSa.=*pS7T_kGYUAptgV"pkaVZ*LmVZ*Fg +V?5,ibkK<[b5]Z^bQ,i]b506Yb5KHPaoKWablVf]tV7r^qmn)`5T^8a2lBF +bKJ,TcHjkbdaQ^qe^rF*g"P39h;-rGi8N\Uj5f=akNM0plKdg'mI'E2n*olHncA@Srq6 +JcC<$JcDkPl2LMWq>Bp_r;-BfqY:'arq?<`s7H?_rUL$[nF6GGs6]mSrp0[OlMg#nki_*jjlPR` +j5T%Ui8Ec5]&?A*uaS!ob4 +R$X,(BP(a`?X$]<>%1oK?t*PSA,^!@AQ;c3repi8reM2AKnXAjH]N5sBk_Cs).mTrbhgVEW'kSEV=DQEW1"U +EVOSSEr^7[F8p4ZDZF\SD?"DNA-HFP@UWhWq,7/i$&jk'N/US1;GpHl;Z0Jl;ZBSm;>sGo;,[Bj +pe_!T#F/(\:f'q_A,:u[M#N8.MYr;2M#E/2MM_1eqhtH4pPT*AR@3f:rg3YPqj@GOrg*\RQ^@]= +r0RDKrg3SLrKmJKqNq/H#FCR8P*2#mPl?pQQC!r*R$jA2rgWqX!1j+\!hZ-Yrh0@eU].(hV$3`o +Vl6Pnri0&#XKAV-Y-5(6Z*L^B['d?N\%&uZ]">Vf]tV7r^qmn)`5T^8a2lBFbKJ,TcHjkbdaQ^q +e^rF*g"P39h;-rGi8N\Uj5f=akNM0plKdg'mI'E2n*olHncA@Srq6 +JcC<$JcDkPl2LMWq>Bp_r;-BfqY:'arq?<`s7H?_rUL$[nF6GGs6]mSrp0[OlMg#mki_*jjlPR` +j5T%Ui8jr_iepr)*GkrD*fe:JUjar(d)aqb[,e!)`YiqbHr_r_E8b!)W)Zk"u(T!)WSjrD5h\#=T2Ir=Sl5'=B/="r_ierpf%2ls&K"s!)rYj +q,.,hrDESms&/nqr_`Sks&8qq#uOMpOcbfiPEV71PmjW2]cr=0&F)Xfeh1YctCai_fMbg+M[ +d*^:jeC<%#f@\d1gYCW@hVd>NioB([jlYail07L!m-O--mdKW6nc&([oCW%Ts7ZKerqQNhrqcQi +rqu`noDX=@JcFL)J,~> +JcC<$JcDqRl2LJVqY^!_r;-BfqY:'arq?<`s7H?_rUU!Y!:^!Vs6]mSrp0jTlK[Wuki_s-$0C7. +j5T%Ui8Pq\)=oVV(`WsRe=BSa.=+^4?rLrnY!2TIfr20CioVM];d*D@. +rlY8aqof&`pr`HTrQ>)\n]D6_bfl-0OcbfiPEV71Pld8rgs.^!20=b!MZ@g +UgU$rVPg>jW2ZesX/rD)Xfek3Yd(L?Za@*I[^NZU\[oDc]Y2%o^VI\&_o0O5`lQ6Cb0/#RcHaea +dF-Lne^i@)g"P07h;-rFi8EVTj5f=ak3(sml0@U$m-X60n*olHncJFTo`"Lbp@n=[q#C0iqY^6i +r;HTcrdk*#s4dR(~> +JcC<$JcDqRl2LJVqY^!_r;-BfqY:'arq?<`s7H?_rUU!Y!:^!Vs6]mSrp0jTlK[Wuki_s-$0C7. +j5T%Ui8[1HBrF,_8#\7FUA7ehC +JcC<$JcDqRl2LJVqY^!_r;-BfqY:'arq?<`s7H?_rUU!Y!:^!Vs6]mSrp0jTlK[Wuki_s-$0C7. +j5T%Ui8oh +!)rbmr_`/_r_rhpq,@8js&8qqr)*GkrD*i`:]4&a:]+#h;>O/j;#F,e:A@Wa:AIZc;"%3A:]OAk;#X>k;#O5k;#O8d:^Bor +;G^1c:f1*h;Ya2g;#O8k:^'Wm;,gOtr(@5c91)*45X5'.r)Wh_s$-BG!^T(9r^-WNs$H`O!^Jt7 +r]pKL!'pKI!^K%:r`&qar]pKL"@uTq=BG<#pfRT#qcWi!s&nqqrE0;+='&C%<;f_q<;9Dl<<#ts +;ufkl;Ya2h;Z0Jm;ZBYq;Z9Pk;ZB\q;@68tO-#KdP*2#mPl?pLQC!s;Qj9%JR[]e:S=TYNs.9:a +rh0@eU].&sV5C,fVl6PnWiE,$XKAV-YHY79ZEpmE['d?N\%0&\]=bei^;%Fu_8=+.`PojhV[8LioB([jlY^gkiq?slg4!*mdKW6nc&(\oCV\So`Fj]p\jme +q>^s+14)s*t~> +JcC<$JcDtSl2LMWqY^!_r;-BfqY:'arq?9_s7H?_rUU!Y!:]sU!Uf@SljrFIlKRQskND!ijlGI^ +io0mp(>n!)h;$c=g=b-1f@JL%eC2jndEp4bqk3kZrLWqXs.'+Y!1NhRs-WDEs-WhQpm*D!P`CHG +IXQWnB5OQEQ^3o%P`q8nOa2(mJUi3!JUW*!K7ebb@Usbq]!qXG&@ActO-l2kWHNN1F*2t^Jr9Pd +!/pc3!/UT/!/CE)r.Fm"qM"p%r.Xs$re:9)"GMSbKnfMZs+CB)rIk3)#)%V]JqJZ,rIOlurIFs! +pj`6k!e#HDr-\Qord=iqH[GO6rHeTlH[>O8s*F]js*+Nhrd+Qhpj2marHS-`r-A?ird=Wjq0MRX +npLIa!.=cos*jrqs*artrI4Zos+(&tqLJTsrdb$"rdt'#!/16'qh>c7I$G5/>5qb*=:3'gaB2PI=BJU\\GMruU%=uZUSRgaqkj7g +p87l:!n#B?p<3HXs3(;`!R&X`ans6Zao0B\ammLSbDuR_!K`HCP5g^GPl?pLQC!s;Qj9%JR[]e: +S=TYN!hZ-Yrh0@eU].%iV5F6i!N +JcC<$JcDtSl2LMWqY^!_r;-BfqY:'arq?9_s7H?_rUU!Y!:]sU!Uf@SljrFIlKRQskND!ijlGI^ +io0mp(>n!)h;$c=g=b-1f@JL%eC2jndEp4bqhG$&rIjlrqLS3fp4!p#De`cg?XI2KRDJsIXDXhZCDZ=YSDZ=VTEW'kSEVa_UE<(%XE<(%TEVFMPF8g7_ +F`DC"DZ4J[ChIW8-M=lc&Mu/J0MuK1HR[Nl:rg3YPqj@GOrg3DIs-N_Nrg3SLrKmJKqNq5J!07&> +!K`HCP5g^GPl?pLQC!s;Qj9%JR[]e:S=TYN!hZ-Yrh0@eU].%iV5F6i!N +JcC<$JcDtSl2LMWqY^!_r;-BfqY:'arq?9_s7H?_rUU!Y!:]sU!Uf@SljrFIlKRQskND!ijlGI^ +io0mp(>n!)h;$c=g=b-1f@JL%eC2jndEp4bqc3Vpqc3Yqr)NVnr)N_qnPf9`+#Yr0/h8G'/hK%A +;GrjIQ'IStP*1q[/M&S31GgpE2#]?O1H[c_5tXgC8kVfL8P(a$4YoW$:esk^:/b%erDNPjoht]b +n5B6a!)iVkr_ibps&/blrDNVlr_NSlr_i_m!`DlnrDESk"&Vll;>sDk:C'co;,C%b:f1*d;#aGm +;#jMk;>*i_:]4&a:]+#h;>X5l;,I-cr_E2`r_E;cs%r/[k"u(Tr(mAjrD<8dq+q&gr_`kq:JXea +r_iPhr)!Dj!DlSj;?'N(:f:1k9M.rN8kM`D6pO!455eLb:d@915Pm\L5sRY#6:1Z;"[YL@5X.L4 +5lX+M5lEnK5X@[7<<,>a5QjA<8PrXd=Su>%=SGtu=Su=n=T2G.=BAR(!K`HCP5g^GPl?pLQC!s;Qj9%JR[]e:S=TYN!hZ-Y +rh0@eU].%iV5F6i!N +JcC<$JcE"TlMgSWqY^$`r;-?eqY:'arq?9_s7H?_rUU!Ys7$$V&FSrQm-O'(lKRQski_*jjlHF$ +)rfi7i85ZRfJoVRK&ZQQN3EIQiQ.e)=ohc0r`fA*s&o>'$HC--=BJ^.=&tBlrLj.`qP+"bqk=+d +V#."gVYI(_VZ"jBccu1,rlP5aqTJu`b43URb4<[PaofhHNfO+"!K`HCP5g^GPl?sJQ2m9NQi`\E +Rf8cWS=TYNs.9:arh0@eU].%iV5F6i"fSE#WiN6#X]2I,YctC^ +JcC<$JcE"TlMgSWqY^$`r;-?eqY:'arq?9_s7H?_rUU!Ys7$$V&FSrQm-O'(lKRQski_*jjlHF$ +)rfi7i8C2S$2Ed)eSGkcL^G5l[b +FSKqVFS'VSFS'\UFSg1cFEM\IF`__JrcJ0]!-7sXs)S!Vs)7sXqf)OQpi-4Ns)A!Vqf)FNpMU"J +rb_^QrG;@JqJQ:Lp20qKCi')foPX\Gs(hdSDJjCVDXhZCD?+VRD?+VQE;FSPErL%YEr9nWE;FSL +ErC(WFT6IdEH#l7DZ+DYAn,@^@UikoAn1^9rDNoZNJp\1;,R6hr)*Gks%r\l"B&/r;,[?iq+qE_ +Q'G-@:esh\EJaUKs+pW2qMFg$qht?1q2>6A!h,OFp6biG!1^ +JcC<$JcE"TlMgSWqY^$`r;-?eqY:'arq?9_s7H?_rUU!Ys7$$V&FSrQm-O'(lKRQski_*jjlHF$ +)rfi7i8X5k;uKVl;=IKU;ZK_p;ZK_m;>jDl;>sAl;>sJm;#jMk;?'Gn;,I6hs%r\j"]/&n:espe;>O,h +;ZBVo;Ys>b;#3ue:A@W_:]OAi;?9WkqbR2dpeUlaq+guemn`%A!)`Jep/1Z_"&Vro;>s>l:f73i +q,.)es&&emr_NPk!DlYl;@??"91_cK9M8#H76gQ2r`0.u5X7Ouq`k_5Qs_V=]eg0r`K,%r)iDjoiV5s!*K5%r`'##^ +JcC<$JcE%UlMgVXqY^$`qtg9eq=ss`rq?9_s7H?_rUU!Ys7$$V!q,ICrp0[OlMg#rki_*jjlGL_ +j5T%Ui8Gs-NeQ +qNabs,I2@N/WYlM#`A1LB<3aL&H]'KD^DuL&H]'L%pB&L&?]'K`Hl*L&Zf+KDgK'K`Zp[ +KDgE#Jc:9$K)gN&JH15qJ,XosI/nZmIK+cqI0"_BpNljdr-JE@H$T@5rHeHgq0N!br-8'` +r-A?irI"Qjq0MOWo6gOa"FPWGIX_9EqL8$c!J#[tJH(-!JH(3#K)L?%KE-`*K`?c*L'r]gKS>,7 +Lk'l"H@#R8$[69"DJs<(D3Ap6:AJ5rZN!`$>l.h$>lS"5=]eg1=^"s2r`fA*s&o>'%`ZQ1=BJ^. +=&tZsTV/!Pq4dna!MlLgU&h$bqka:hq5,VgTqS3TUSO]^V5C/gW2]cr=0&F)Xfek3 +Yd(L?Za@-K\%&uZ]">Vg^;%Fu_8=+.`Q#s>aND]Lbg+M[d*^:jeCE.%f\,!4gtgfChr*JQj5]4^ +k3(sml0@U$m-X60n*oi:o()DDo`"O`p&Ojcq#C0iqY^6hr;HTdrdk*#s4dR(~> +JcC<$JcE%UlMgVXqY^$`qtg9eq=ss`rq?9_s7H?_rUU!Ys7$$V!q,ICrp0[OlMg#rki_*jjlGL_ +j5T%Ui8DJa>i;>sJn +;#X;n;H$Kj;>O)s;3[?2:JXe_:/,nhrJ1E0regK-reg`4qMP--qi(?/rgWqVs-`\M!h#FCrg*VP +qO%>Nrg3GJs-N_N!gf:ArKmPOs-NSJrKmMB!f`5#rf7)AOoCODP5pjHQ2d-MQi^ +JcC<$JcE%UlMgVXqY^$`qtg9eq=ss`rq?9_s7H?_rUU!Ys7$$V!q,ICrp0[OlMg#rki_*jjlGL_ +j5T%Ui8i;ZBVm;#4#h;Z'Di;#X>l;#X5l:f1*h;#X>i:^9cm +;Gp@h;H!EioMGE\r_EDf!)EMhqbR8iqbdDkqG7)cpeUlaqbR2fmn`(Bs&&MeohkW`s&&eo!)WYj +!`2cmp/1ids&&emr_E_p;,U4f:fRBk"&i)l8cD?c9MIlK:AI*RRj!*K/%qcN;ioiV5ss&f;&rD`o",VgTqS3TUSO]^V5C/gW2]cr=0&F)Xfek3Yd(L?Za@-K\%&uZ]">Vg^;%Fu_8=+.`Q#s> +aND]Lbg+M[d*^:jeCE.%f\,!4gtgfChr*JQj5]4^k3(sml0@U$m-X60n*oi:o()DDo`"O`p&Ojc +q#C0iqY^6hr;HTdrdk*#s4dR(~> +JcC<$JcE(VlMgVXqY^$`r;-?eqY:$`rq?9_s7H?_rUU!Ys7$$V!q,ICrp0[OlMg#Kki_s-,N\"H +j5T%Ui8=NS,SlMR/WHPR/N?OR/WHLQ9Lh- +ObeO3I=6W[BWeJ8VPBcOQBJ/.OH5H_NJrgSMh$D3K7m`E@U?XV\$WQN['XalQ^*N1GBnF[H@UU' +N;SYd@fVt[(bciMJ;qTJl^!6bAa!6b5_!R&XVaoBNRao9E`MMqIm!f`5#rf7;GOcbfiPEV71 +Q2d-MQi +JcC<$JcE(VlMgVXqY^$`r;-?eqY:$`rq?9_s7H?_rUU!Ys7$$V!q,ICrp0[OlMg#Kki_s-,N\"H +j5T%Ui8pPI!U$ZEc-PmOH5H_NJrgSMdp4+A7ba@"'(>>MuJP4L'D!oG&VMWCAquNDK9c?r-86e +rcn9`rc\C!,qjSs)7gSpi6:RrGh[QqJl=O +r,Vm\F8g:]FV].EGBe.HE,TT2DJa6)An5F^@Ua"^:&[oc;ZMdU;#X>i;Z9Mo:f73is%r\l!`Drp +qbd2ds&&f]s%a#!:JOW2MMd1FLl%#_M#`G3M>E,+Mu/J0Mu9(ERfAfPR/WKRR/WEPR/33NR/WHJ +R/`NPQ3*D?R/NBOR/`NLQN!3OMMqIm!f`5#rf7;GOcbfiPEV71Q2d-MQi +JcC<$JcE(VlMgVXqY^$`r;-?eqY:$`rq?9_s7H?_rUU!Ys7$$V!q,ICrp0[OlMg#Kki_s--0=4J +j5T%Ui8X5k;#3ue:A@Wa:A[id;".9B:]OAl:]OAi;"[]`;#aDm;?0Sm +:B=sJm;$9cq;c6Ni;?'Mq;i6M4Muo!!NrG(EOHGZgP*;)org!ML +!13\Ps-WkUrgNqYSc52gT:hjNTq\ +JcC<$JcE+WlMgYYqY^3e!*K3sr;-?eq=ss`rq?6^s7H?_rUU!Ys7$$Vs6]mSrp0[OlMg#Kki_s- +,N\"Hj5T%Ui8_ViQn!NJrgSMM[1GK4AD#@'7#K[C-"@%<6H6J;ps\H$FX] +JqAmUNrD1LB*).L&?W(KD^DuL&H]'L%U0%Knb?]K`Hf)Ka!3bKnP,3rIb6+KS0/R +r.4m"s+:<'rdb'"pj`9l!e#HDr-eTord=fpHhVgeI!bj="*o3>Hi89jH2VsfH2`-hH2DpaH2W!` +H2W'hHiJKkHhi!WHh2XaHiJHpI=?YEIJJ?dJ,XoqJ,b&sJ,b'!JcC?%KDpN(KDpN(L&Qi*KER!` +Ll$ufM@kAbI!L!`H?j^IDf9N/Bl%s5r_EJhra,P"qH`f"#[:J7=^"s3=]t`.r`T;)rE'M1aN7Oe +=]ea+V73k,UA^ecU&^tfV#R4iUAgqfV#7(hVY-k`VYSR>ccu=0rlbAcrlP5aqoo)`!6XlSs2slR +"j2[YMMd>kMuo!!NrG(@OHG\)Op@28Pa.N"QC%T +JcC<$JcE+WlMgYYqY^3e!)idmr;-?eq=ss`rq?6^s7H?_rUU!Ys7$$Vs6]mSrp0[OlMg#Kki_s- +,N\"Hj5T%Ui8S5MD>S2ND>eAPD#eDOD=h`DD>nJ;DXq`DDZ=YSDZ=YQE;=MQ +EW^<#E,k_ns)A$Xr,MRRq/cOWs)eBdGBa%2&TVi0DJa9-DJWosA7]7[@qK9N:B+,h;uKPl;>a>k +;#sKjr_ibmr_W_p;ckMuo!!NrG(@OHG\)Op@28Pa.N"QC%T +JcC<$JcE+WlMgYYqY^3e!(Qqar;-?eq=ss`rq?6^s7H?_rUU!Ys7$$Vs6]mSrp0[OlMg#Kki_s- +,3@nGj5T%Ui8jrDWbsoi(rj<;KPm<&uZj +1GCF2.kE;)3&3cc5Wq7l4#f/W1fBBqNfB!VMi*@JLc%=X5!;J18P)QJ8P)6:77B^?:Jstb;#=,j +;uK\o;ZK_k;>sJm;uBPn;>a;l;tX&Z;u]bm;>jDm;>a8`;>X2i;?'Jl:BXKk;,C*f;>j>k:BjWn +;Gg:h;Z0Jd:]aKj;#=&f:B"&h:B"&e:]OAi;?0Sk:BOEh:/:R[r_E>dr_W)[j\YtSp/(T_s&&ho +qbRAl;GpBj:B45_;$9]m;,C*g:BOHl;H*Nl&Pl5";,L7h;cc^g92%uM9LM>K:B+,h55e:Y5sYE6 +r'1EO5X.P$6N'1Q5X@\$5Q3qJ64,tB5!D1q5sRY7Q7n(=oVV' +=o)8"=oVS(<;TZ%<`N.!;c?Xp;cEWor_ikt +JcC<$JcE.Xli-_Yqu$6ds0D_&r;-?eq=sp_rq?9_rq-6^rUU!Ys7$$Vs6]mSrp10]lK[Wuki_-k +k2k[aj5T%si#:M0h;-l@g=b-1f@JL%eC2jndEp4bcHOJTb5Iq*Sc>5[S,Si@R/<3kSXGUrJ9ZNn +Iq`T!XJr%lSXPn0Nf&UFJ9d-5N/NSmM$\unL14SN\@8lRrj32lF*<(o[Wd"BH?t3qMNQA(*>R4P:=BSg1>$5&.>Q.e+=oDG2=3/Kc +=]nj.?E:QCUA^ecUAq"fV#@(eV#@.iVY$e`VYAF +JcC<$JcE.Xli-_Yqu$6ds,R0Wr;-?eq=sp_rq?9_rq-6^rUU!Ys7$$Vs6]mSrp10]lK[Wuki_-k +k2k[aj5T%si#:M0h;-l@g=b-1f@JL%eC2jndEp4bcHOJTb5-ecKE$Q&Jc1*!Jc(&tJ,4]jIi``P +D.R*Y?XR8DmOH?sdWEc>c*A7K"RNJrgSMZ/Gi;@L2171CitYMCMIU%F)lI" +GlE!dGl2d`G5ZL_F8g:]F8L(SF8g:PFTur1F`__HF8^4XF8U(VE<'tWEW:"VDuXeTDte5NDuXeU +DuXeVDuXeUDt.`ED?"DPC]/,MC]J>LDZ4MODZ=SODZ4JOD=h`ED#eJQDrts0Du=JQDuOYSDu=SM +EW'nXEVOMQEW:"VEVXYNF8g7^Fa!b.r-/lrE,TW2DJj<-AS,L`@prk[A55o!:]!uf;>a>k;#sKj +r_ibmr_W_p;cIs-N_N!gf:ArKmPOs-NSJ!/UW2!fDnorepoVf^;%Fu_SX4/`Q#s>ai_fN +c-FY^dF-Lne^i@)g"P39h;-uHi8N\UjQ5OdkNM0plKdg'mI'H3nF?MK!V>s_p&F^cp\jmeq>^ +JcC<$JcE.Xli-_Yqu$6ds&9!qr;-?eq=sp_rq?9_rq-6^rUU!Ys7$$Vs6]mSrp10]lK[Wuki_-k +k2k[aj5T%si#:M0h;-l@g=b-1f@JL%eC2jndEp4bcHOJTb5,-8<;TYs<)lrs;ufqr<;ohm<;KPn +<$""V1bUC//1iG52FKhq5!D(h3]ArR1GLU:NJrgSMZ/GNLkg^K5"&"78P;]K8Mrk'6qC!K;GU(b +;c6Nm;>sJk<<#nr;Yj8i;Z0Pn;Z9Pk;?0Yg;Y!cc;Z'Dk;ZBVk;#*rg;#X>h;#aDm;#X5n:f1(d +;#O8i;#a;q:f:1g;,UjDm;#jGk:BaKi:esh]peUlaqbR2fn5&mW +r_MuZ!)`Abr)*Djr)!Djs&/kns%`Vkn593^r_EVm;GpHk;ZB\p;#aB&;Gg=j9he8Q8kD]E6r$MV +:]!rh5sYE6rBU?J"$](<6N0:N5lX+N5X565s$@&Y5<_7q5=%P!Q7n"=nc%uVf^;%Fu_SX4/`Q#s>ai_fNc-FY^dF-Lne^i@)g"P39h;-uHi8N\UjQ5Od +kNM0plKdg'mI'H3nF?MK!V>s_p&F^cp\jmeq>^ +JcC<$JcE1Yli-_Yqu$0bs0D]-rqcThq"Xj_rq?6^rq-6^rUU!Ys7$$Vs6]mSrp1$YlK[Wukih3l +k2k\'iud:>i8EMLh;-l@g=k64f@JL%eC2jndEp4bcHXPUb/sURpmqAR!1NkSoU,ZFq3_,I%%`oM +Ne;_,I=-QZB!2-3)k`^hQB$oZL4F\sG'KpCMM[1GLPCP;KS-_@[JmNFQ)o1[O1KO\H@:*kJr5_Q +O,j$q!fi8!reg`4reUK-!/CH+rIb0'r.Oj!re16(onNBus+L3%r.G-*KS05Ts+(0%r.4m"s+C9$ +!.aiordFlrI/A$+p2=^"s3r`fA*rE0)$$cpFl=]nj.A[8eQ[/H[" +U8+L_U]@1dV#@.iVX^S`VYAI;cN)2cbPo]gbK@uNbPTKabKBP#rQ#)_b0%j)aS3gVLB*/0M#rQm +MuJY:NK0%uNrkE*OoCLKPE_;sQ'R`&rg4(]R[T_8S=Q4BStD\TTj"1cUnjiaVl-JmWiE,$Xf\b0 +YctCVg^;%J"_Sa=2`Q-'@b0.uQcHaeadF6Upf%8O,g=k<;h;7&IiSrnYjlY^g +kiq?slg4!*mdKW6nc&([oCW%Ts7QHerV6Egs8)Wirqu`no_sFAJcFL)J,~> +JcC<$JcE1Yli-_Yqu$0bs,R.XrqcThq"Xj_rq?6^rq-6^rUU!Ys7$$Vs6]mSrp1$YlK[Wukih3l +k2k\'iud:>i8EMLh;-l@g=k64f@JL%eC2jndEp4bcHXPUb/sX9!el;\p4N9os+(*"s+(#s!e>cM +q1/En.dKH['^UE,96#ARJnN>$Q`=MM[1GLPCP;KS,0]M%>DsE.MYC!c2Xgrb_XN!,_UNrb_XPrb_UO!c;airGD1ErG;OPrbqXNrbq:D +rbqdRqeuCMs)7mSs)7jTpi6:R!-.aPs)J'Xrc.[Qq/cRX!HiSbGPl^cH3/,+Du=GQCLd?S"_(th +Akl,#:]!uf;>a>k;#sKjr_`bo;#X;n;H$Kj;>X2h;?)p]:Bs]l:037/MMUeZqhk9/q2><3rf$i7 +!1N_Qs-itUqO%8M"IPOBR$dc=!1,%dfUnsrdVl6SpWiN5'Xfek3Yd(L?['d?N +\%0&\]=bhk^VI\&_o0O5a2l?EbKJ/UcHstde'umuf@S^0g=tH>hV[8MioB+]k2tjjl07L!m-O-- +n*fc9rpg*]o`"O`p&Ojcq#C0iqYU0hr;HTdrdk*#s4dR(~> +JcC<$JcE1Yli-_Yqu$0bs&8tfrqcThq"Xj_rq?6^rq-6^rUU!Ys7$$Vs6]mSrp1$YlK[Wukih3l +k2k\'iud:>i8EMLh;-l@g=k64f@JL%eC2jndEp4bcHXPUb/sW_!`i<$qc*Jns&Atts&B"u!`i<# +r)3Yr;cEKkrDPj<2)I$@.kUR5sIOr4?GM]2Dd0D0.nk1;N$EhM26qAL4t;58P)QJ8kCZu +6q'[@;,L+c:f:.g;Z0Jl;?0Yo<<#nr;Yj8h;Z0Po;Z9Pk;ZB\i;Xm]c;Ys>k;Z9Pj;#*ug:]OAh +;#aDm;#X5m:f1(dr)*Dhs%`Yl;Z9Mn;Z0Jd:]O;j;#F,f:&n)g:B"&g;#X>k;Z9Mn;#X5p:/=\_ +:JO[[:]F2d:]=2\:\did:[h3\;=dW_;>sGn;>j>k;?'Mt;,C(b:JgRYr_WVjs%r_n!)rhor_rhp +rD3u$;GpIo9h\/Q8kMcF:/:daqbR;Z5lO"H5lO%O5=%V&r^$QLs$6ZN5Q3qJ63'=N56!kI5n6+Z +r!=^(Z+!*\tspfRMqr`&hr#$+`(<)cdqr_rbps&8qss&K"s!)rPgr)*Gk +r_Wer;c?RlqbdBK!/UW2!fDnorepo,%dfUnsrdVl6SpWiN5'Xfek3Yd(L?['d?N\%0&\]=bhk^VI\&_o0O5a2l?EbKJ/UcHstde'umu +f@S^0g=tH>hV[8MioB+]k2tjjl07L!m-O--n*fc9rpg*]o`"O`p&Ojcq#C0iqYU0hr;HTdrdk*# +s4dR(~> +JcC<$JcE4Zli-bZqY^'as8)c%!*B*oq=sp_rq?6^s7H<^rUU!Ys7$$Vs6]mSrp9[N!:'RJ.d6'X +k2k[bj5].Xi8EMLh;-l@g=k64f@SU'eC2jndEp4bcHXSVb/q_rq47DQ!h5XIrL!eUQ^=)+r0[DK +qO%5J.[lQ]L4=DqIt26GYH4V"V4O'APE(KUKn"DmG^t`;3MuASHIX?BdG^4OXEG9B1CMI[qE_cU0qb[/q!*oM/q-420>$+p2=^"s3r`]G-=^(c+s&TTL +a]M\K=BB@K\$`UBT`Us`U\LVcUSRjbs/,=a!N)dfciVP=bkfN^bQQ,3b0/!*bQ5o0p +JcC<$JcE4Zli-bZqY^'as8)bV!)`[iq=sp_rq?6^s7H<^rUU!Ys7$$Vs6]mSrp9[N!:'RJ.HosW +k2k[bj5].Xi8EMLh;-l@g=k64f@SU'eC2jndEp4bcHXSVb/qa(K`Hf&KDpN)K7`fJs+'opqLJNo +4*#4R@piJI@:<8>Jq/2qHZsOPDe`lq@UNMG>[q;TKSbM?LPCP;KS+o/M2-h*EHuSKW+g$_Ci4<7 +GPla_Gl)ddGl2d`FoZ[`F9$CTFSp4YFRaMOFT-@]FS^%\EcH)>qf2XT!-/!WrGM[Tr,;=K!,qjU +qJQ@Qrbq=ErGDRM!c2^jrG;=Jrb_[QrGDLN!c;airGD4FrG;OPrbq^Pqeu"BrGVUOrGVUO!,qjS +s)7gSq/Q@R!-.dQs)J!V!-.^Qq/cRX!-\hs-e2k>DnDsM"?K"MYi>0N;8A3N;f:ARfJoVRJN +JcC<$JcE4Zli-bZqY^'as8)ap!(Hh]q=sp_rq?6^s7H<^rUU!Ys7$$Vs6]mSrp9[N!:'RJ.HosW +k2k[bj5].Xi8EMLh;-l@g=k64f@SU'eC2jndEp4bcHXSVb/qa(b!)NSjrD32`rD3GirDESmr_WYlrD*Mj:Jame:A@Tb:ARcc +;".9W;#X8Z:]OA`;#X>j;?0Sm;#aAn;GmEi!)NSjnkoE`r_EVm;,U?k;Z9Vm;?Tip:f($g;@-8q +91qlL927iLr_NDf!C9!M5Q*kH5m'>:6:1Z;s$6TM!C/mK5ScXP5sIOs5Q%at=nl+ssJm;$9cq;c6Nl;>u:O +LPUccM#rQmMuJY:NK0%uNrkE*OoCLKPE_;sQ'R`&rg3_SRf8cWS=TYN?([d`Tq\ +JcC<$JcE4Zm/Hk[qu$-arqZf)['Wq;q>'gap\sm`p&=U`oDJ1Znc/+Xn,MeUmJcJPlN$5Lkpko[ +k2tdejQ#:[iS`YOhVI#CgY1B7f[na+e^W'rdF$=ecHa\YbK@rJaS_V-SH#/ZSH#)VRK&ZGQhm*L +QURF3Nei74I=?ZtAn\?HVP^#UR[B.pL4Xu)H$4F_K7SW-KSP;:KnP)2Jq8K'I]edMO4AH#H@:9q +K8YqWP*1rhO,f3Yq2PB3s,$f5reUK-!/CH+p4W3ps+L?)p4iHure1-%r.G-*KS08UpjrHs!eZ)V +rIO`n"FbiLI=1d;$[d;JH?spbI!^0cH2`-gGli>=HN&3dGl;sfGli;;HMVpaGklX`HN/?lI/J?h +HL6(ZHLcCbI!pHmrdFWl!.FiqqL8KorI+]ps*srqrdP!"JV!fPs+:<'re(3's+C<(!JQ:-M#W>2 +MZ8V4N"_2!IX??eH?aXNDej6-Bl/*9:J^jar_`Jsq-420>$+p2=^"s3r`]G-=^(c+s&TZNa]M\K +=BBUR\$iZKUAgqbV#I+iU87dbrhfUk!2fFeo[!ZccHQ..rlbMgb0%oNrQGAebfe0&ao09_ai_cJ +rQ+iWs+UH,!f)SfreU]6Mi7Rns,@#=rf7,BOcfX+#EtC:Q'IZ$Qi<@`R@9V7S=H.AStD[LTq\9V +UnjiaVl-JmWiN5'Xfek3Z*L^B['mEP\@K2_]Y2%o^qmn*`5Ta:aN;TJbg"GZd*^:jeCE.%f\,!5 +gtgiEi8N\Uj5f@bkNM0plKdg'mI'H3nF?MK!V>s_p&Facp\ssfq>^ +JcC<$JcE4Zm/Hk[qu$-arqcVTs&&jmq=sp_rq?6^rq-6^r:9mXs7$$Vs6]mSrp9[N!:'RJ/a2B[ +k2k^cj5].Xi8EMLh;-l@g=k64f@SU(eC2jndEp4bcHXSVb/q`GKnP-VKDpQ(KE$PsJcC8rJ,4]q +IlhakCLppZ?=.)MnoKnP)2Jq8K'@srEXG,8ngCi+*3 +F*IJ+qKVj^s*4Kdr,r'_rH&$\oQ:%QrH.UQqfMgYs)e*Y"*/C$Er9qSE;XVSE;OSKDuahUE;"5@ +DZ"AOCBAe;IDZ4JQDZ"AMDZ=POD=h`ED#eJQDuX_NDt%ZDDu4GODu=MQDuOVSDu=SLEW0tY +EVFDPEVsbUEVa\UEW1"SErgB*r-/-bs*=Tjrd+Ta&8uH)DJj9&A7]=_@q01`:J^jarDEJjs&&em +!)`_n#>n;o;,L4i;Ys>h;#O8kPmU8^:eshpMi3IKL\?T$MYi>0N;8D3Mu]:FRe`EQRf8`OR/WKV +R$X/,R/NESR$j?@QhZsJQi<9PQ^F0=QiEHQQi<ai_fNc-FY^dF-Lne^i@)g"P39h;7&IiSrnXjQ>Ufkiq?slg4!*mdKW6nc&([oCW%T +s7ZKerqQNhs8)Wirqu`no_sFAJcFL)J,~> +JcC<$JcE4Zm/Hk[qu$-arqcUns$d"aq=sp_rq?6^rq-6^r:9mXs7$$Vs6]mSrp9[N!:'RJ/a2B[ +k2k^cj5].Xi8EMLh;-l@g=k64f@SU(eC2jndEp4bcHXSVb/q`G<`N/s<;ono<;fhqX8k;u'>g;Z]os<;TVm;Z'Dl +;Z0Ji;#=,`;#X>l;#a;k;#*rl:f1%c:Jgg`p/(cbs%rVhrD!>grD*>fr_WPj!`Dlmr_WPh"\qii +:JO[R:]=2\:\did:[h3\;>3oe:]F8i;>sGn;>j>k;?'Po;#sKhrD<;e!)WSjr_WVj"&Mim;uKVn +;ZTcnqbmGks%j2(;Gg=g:/";R8kDB<:J^jar_`YZrBU?J"$]%;6N0:N5lX+N5X565'L>&O5<_7q +5=%S"!g&P,rfRMMPa%GuQBmm:Qt;\SS"#qVg^;%J"_Sa=2`lH0Bb0/#RcHjkbdaQ^r +f%8R-g=tE=hV[8MioB([k2tjjl07L!m-O--n*fc9rpg*]o`"O`pAamdq#C0iqYU0hr;HTdrdk*# +s4dR(~> +JcC<$JcE:\m/HhZqu$0br;$Nk['d=@=Sqmlp\sm`p&=U`oDJ1Znc/+Xn,MeUmJcJPlN$5LklL#2 +roPWjjQ#:[iS`YOhVI#CgY1B7f[na+e^W*tdF$=ecHa\YbK@rJaN'jBrLEhW!1a"W!1NhRs-WeP +rg*AHqNs@2S)5L&?T) +KnK>Upjr?prIOZl!e,NEr-\QmrdFfos*FusH[C-fH[9u9HMr-hHN&3gGQ;seGlE$gGm8S?H$Xa] +HN&3dGku^`H2r$Co0s&fA+=oMP'=9$DB=UA87>(*lh[^<<7qkX7erLsChUnspeVZ3RmVYm@kW;WXcciMJ2`prWKU!6P5_!6P2\r5ntk!ec8]re:K0Lku%es,$f7rf$l:!07&>!g&P,rfR;G +Pl?pUQC!r*R$jD3S"#q=rgm;cTV8'RUSO]^VPg>jWN*##Xf\b0Yd(L?ZaI6M\%0&\]Y(qm^VI_' +_o9U7aN2NIbK\>Xd*^:jeCE.%f\,!5gtgiEi8EVTj5f=akNM0plKdg'mI'H3nF?MK#kR]\p%A%P +p\4[^s7u]kqtpBjrVcBfJcC<$g])d~> +JcC<$JcE:\m/HhZqu$0br;$Ehrf@%VqtU-arq?6^rq-6^r:9mXs7$$Vs6]mSrp9[N!:'RJ!U/_G +js]?Pj5].Xi8EMLh;-l@g=k64f@SU(eC;spdEp4bcHXSVb/q`Ga+T-EKDgK&KDpJrJH15qJ,Fir +Il_[iBjt=R?XR8AgJH[0gXEc>i.AR]+T=^#h;ZBVn;#X>t;,C(d;,U=jqbd8frDET[!DZGi:^(EgMi*=GpPJd)qht<0qMYB4rgEeTq3qGS +R@3lrG5MuJ\8N<#"< +NrkE*OoCLEPEc'3$^R-GR$a;1R[]e:Sc53aT:hmOU8+N[V5C/gW2ZetXKAV-YHY:;Za7'J[^WfX +]"G\h^V@S$_Sa@3`lQ6DbKJ/UcHstee'uq!f@\d1gYCWAhr*GPj5]4^k3(sml0@U$m-X60n*olH +nd+jZo_%nNp@n=\q#C0iqYU0hr;HTdrdk*#s4dR(~> +JcC<$JcE:\m/HhZqu$0br;$Ehr`&kdqtU-arq?6^rq-6^r:9mXs7$$Vs6]mSrp9[N!:'RJ!U/_G +js]?Pj5].Xi8EMLh;-l@g=k64f@SU(eC;spdEp4bcHXSVb/q`Ga&Q.<<;fhl<;fhqJ]2Dm6E0eY+11c$pEr\G?I22-^:K7ec,J:KO?5"A7@:esqd +;c6Ki;Z9Pm;#aDm;Ya8j;ZBVn;#O8k;?p,u;Gg7e;,R6hs&8hns&/nqqbmPqc;#X8j;#F,g:&n)f:B"&g;#X;n;Gg*id:]F8j;>sGn;>a5l;,U+_I] +Tq\ +JcC<$JcE=]m/Hk[qu$0br;-Bf"gthL\6)l4q#0sdpA=O^o`"I\o)J7[nGVhUmJuYRm/QAOlMg#K +ki_s-.coaOj5T%Ui8,8LUr+iJUi99Qc+WY +GBnI_JV8`9P5LODP5gXGOH,>"N;JV4MZ\inM2;(b!/CH+on<*o!/1<)p4`U%K`6](KER!^KS>*Y +L&?T(KDgDtJc:6&JV&LQJHULQIsukCIfY"GrI"frI=-Hkrd=`m#C:`DI!g9eH2`-fH2i3iH2Vsi +GBe@Xrd+He#'tQ?H?a^\qKVj^r-AKmI!g9fq0MIUpj2jbrd"]oI!pHmrdFWl!.FiqqL8KorI+Hi +rdXrurdjrus+:]4K7\`.KS5&6LPL]aM>rJ5Mu8P6NrP.PKm\8pH[0p]EGBB1D/3pMF&2^1r_`Ym +s&8l%q-3u*>$1`+s'#D+s&fA+=oMP'=9$DB=U826@>),![^<=;U]@1eU'@BgV5:&cV>I.fVuEXo +Vt87;cd:"`q9/c]s2tGcbP]T_b5f][ao09_ai_cJrQ+oY!.t3&!ec8]re:K0Lku%es,$f7rf$l: +!07&>!g&P,rfR;GPl?pKQC%T<@[W[SS"-">St;RITqS3UUnjiaVl-JnWiN5'Xfnt5Z*L^C[C3QS +\[oDc]tV7s_8=+.`Q#s>aihlOcHaeadF6Upf%8R-g=tE=h;@/KiT&tZjlYail07L!m-O--n*fc9 +rpg?do^qhLp@e7TrqQNhs8)Wirqu`no_sFAJcFL)J,~> +JcC<$JcE=]m/Hk[qu$0br;-Bf"cne.P#>3Wq#0sdpA=O^o`"I\o)J7[nGVhUmJuYRm/QAOlMg#K +ki_s--fsFLj5T%Ui8@X?!:HAqd^ISAS#M6K7\Z)J8o[kEJ8+B +D/XB8Fa3n2!.+KerHS?f!-n9a!-nKer,r'_rH&$\oQ:%Q"*A[.FRjPTFE@G'"ESU)F*.D&!ci@' +rc7gSr,D:Hs)A!Vq/H7M"E&-qDf>/`rGDRNs(_XOD>e8ND>S5JD?"DWD/O3.DJa3+rGD4FrGDFL +pi#\?rbq[Or,;RPs)7mS!,qdSpMp4R!-.sV!-.^Os)IpVrc.sYqJua\F`qs+GQ2mhH$Xi5H4b:= +E,TZ4Df'2tAn5F^@XMc`r)!Air_ibpr_`_nr_WSl"Aqul;,R0=s-ieRs-itUq3_/Ls-NhRR/EBDR/`NPQ3*D?R/NBOR/`KRQ@f*g!ec8]re:K0 +Lku%es,$f7rf$l:!07&>!g&P,rfR;GPl?pKQC%T<@[W[SS"-">St;RITqS3UUnjiaVl-JnWiN5' +Xfnt5Z*L^C[C3QS\[oDc]tV7s_8=+.`Q#s>aihlOcHaeadF6Upf%8R-g=tE=h;@/KiT&tZjlYai +l07L!m-O--n*fc9rpg?do^qhLp@e7TrqQNhs8)Wirqu`no_sFAJcFL)J,~> +JcC<$JcE=]m/Hk[qu$0br;-Bf"]SK%<^oRXq#0sdpA=O^o`"I\o)J7[nGVhUmJuYRm/QAOlMg#K +ki_s-.coaOj5T%Ui8jAn;cNZnr_`_nr_WMirDEVmr_WVlr)*Mnr)3Pn!)i\m"&r9"<;]\n;Z'Al +;Ys>h;#=,_;#aDm;#X8i;#4&g;#X;p:f1%d;>!cb:B45g:]=)h:]*ue:]F8f;?'Jm:C0cl:JOY] +:esh]qbI2ep.tZank]'Xr_NMis%i;as&&Mer_EMjr)*Jl!)`\ks%rborD!g&P,rfR;GPl?pKQC%T<@[W[S +S"-">St;RITqS3UUnjiaVl-JnWiN5'Xfnt5Z*L^C[C3QS\[oDc]tV7s_8=+.`Q#s>aihlOcHaea +dF6Upf%8R-g=tE=h;@/KiT&tZjlYail07L!m-O--n*fc9rpg?do^qhLp@e7TrqQNhs8)Wirqu`n +o_sFAJcFL)J,~> +JcC<$JcE@^m/Hk[qu$0br;-Bf"o,O8\@K0L=T8'npA=O^o`+O\o)J7[nGVhUmJuYRm/QAOlMg#K +ki_s-.-9OMj5T(Wi8EMLh;-l@g=k32f@JL%eC2jndEg+`c-4ASb/hZE`l7kHs.&tUrgNkT"dk^G +R$X0;QMm0FQmQF6Nei:1I=-NWBs"A3VP0EEQ'@;cKn4]"G'ALgJq8Q,KSG/7L]4jq]7GKuOdql0 +G'\LaIt`Q6rf[2Cs-!DE!g&J&rf$`6!0$i6re^T/s+^H*re(9*q1SBop4`U%K`6]%KER!^KS>-Z +K`6W'K(sorJdR'\Jq8H'J:E&tIenNpI=2!Ard=`ord=Zkrd4iqH$O^^qg&3frd"Kfs*+Kf!."Qi +r-ArJ5Mu8P6NrP1?OV!"jH?jg^H$=1BDK0N/D=r&L;#X>k +;Z0Po?27b*>6%e(=TDY(>Q7h,>$:i,s&TWMa]VeN=_Wi(\$iZKrM0Fgqk=+dV#7(dVYd:kW;`^c +d/VDmcHZ4/rQP5`rQP2_!6Y)YrQ#)_b0%j)aSj3^JV&LQK*$^[L&Qi,LB*/0M>rG5MuJ\8N<#"< +O*m%OOcklkPE_>tQBml)R$jD3S"#q=St;RITqS3UUnjiaVl6SpWiN5'Y-5(6ZEpmE[^NZU\[oGd +]t_=u_SX71`lH0Bb0/#RcHjncdaZdtf@S^0g>(N?hr*GOj5]4^k2tmll0@U$m-X60n*ol;o()DE +o_%nNp@n=\q#C0iqYU0hr;HTdrdk*#s4dR(~> +JcC<$JcE@^m/Hk[qu$0br;-Bf#l'LDP*1r+;H!MgrV$-]rq-6^r:9mXs7$!Us6]mSrp9[N!:'RJ +!U/_GjsoKRj5].YiS`YOhVI#CgY1B6f@SU(eC;sqdF$:ccHXSVbK@oIa2Z)NKDpPtK)gMuJcC9# +J+\=CM.0e?s[&AraZ"=raZdVAS,M6NK&mJJ8fLSEdVS:D/XB8 +FF*\,!dK!9rHRs[rc\NhF`qqNFmjGNEr^=NFTHT*rcA6`EcZ:"F8p7aF)l;@EH(hqqJc4J#&\?t +E,]`6qJc=MrbhaSno"ABs(q^N!GlWOC]J>LDZ"AND#S;OD?4Tjr,)+Erb_LLq/>b?rbq^Pr,;OO +!,qjSs)7dRpi-=TEW'kVEV=AOEVskUEW:(VErgB*rc\3`s*+NhpNlje"EJI"DJoGj#\[a]ARo7[ +^LmC?r_`YmrDN_p;>sDk;?Tin:f1*h;Ys>i;#O6#:m@5?:JakkDi9O2LkkkaqMP0.q2G--qj@GQ +q4%DQs-`_NrL*VOrL*5Ds-N_N!gf:ArKmPOs-Ee +I#sJQP*2#mPa.N"QC!u+R@9S6S"-%@StD[LTq\o(2MG +p%A%Pp\4[^s7u]kqtpBjrVcBfJcC<$g])d~> +JcC<$JcE@^m/Hk[qu$0br;-Bf!r,_pr`9"frqHBbqt9s\s7?0Zs7--YrU9dS!:BdPs6B[MrojII +kPjTljlGI^io8qTi8);G^4e +;GpIj92%uP8P2fJr)!Air_i\ns$6TM"[>7=6:!p:5lX.M5Q3n^5sdh$4Zu"o5X@Y8sJY=nl+u=8Ptr<sJm;$Tut;c6MEJqEuS!ec8]reCH. +!/UW2s,$f7rf$l:!07&>I#sJQP*2#mPa.N"QC!u+R@9S6S"-%@StD[LTq\o(2MGp%A%Pp\4[^s7u]kqtpBjrVcBfJcC<$g])d~> +JcC<$JcEC_m/Hk[qu$3cr;-?erqQK&!P5oB=9/*ppA4I^o`"I[o)J7[nGVhUmJuYRm/QAOlMg#P +ki_-kk2k\'j!E^Di8EMLh;-l@g=k64f@JL%eC2jndEp1ac-4ASb/hZE`l5ogrgj(Zr1!YR!h#FC +rgoL%^6%KnTGZqLf', +KS5&5KS9>WrIXfqs+:9%!ePuSrdb#us*jfo!I]@pIJnNnIJnQlHiABnH[5U:qg&3frd"NgrceBe +!."Qir-A*s&fA+=oMP'9qTJi]rQG/`rQG5`prWHTprWPds+(0%rIY0)Kn]M\!f)Sfre^Z4!/pi8!f`5# +rf7)AOoCLEPEc'3!LB)OQtr+YS"#q=St;RITqS3UUnjibVl6SpWiN8(Y-5(7ZEppG[^WcW]">Vg +^;%J"_Sa@3a2l?EbKS5Vcd:(fe'uq"f@\g2gYL]Bi8ESRj5f=ak32'olKdg'mI'H3nF?&>o(2MG +p%A%Pp\4[^s7u]kqtpBjrVcBfJcC<$g])d~> +JcC<$JcEC_m/Hk[qu$3cr;-?erqQGS"HlV[;YU1aqXsm\rq$'Ys7--YrU9dS!:BdPs6B[MrojXN +kND!ijlHF$.,s4Di8@UE8D?XQl>IscQeG]RkCC1_'f?sd2D>@V,QAH$-BB4bagr/D.h?[?^=BkhL&EHH;JHM2Xa +GQ<$eGkH=fG^"=SF`hkMFo6=]F7jYREr^=NFTHT*rcA-]rc7sYr,MjYE,b_pqJc4J#&\?tE,]`6 +qJc@NrGDURnS\8A!,VXMs)%^N!,_UNrGDOMrb_XPs(qXNoPOYGq/5tGnS\>Er,2CMrbhaSrb_^S +qJc.JrG_aUpi-7Qr,VaUrc7mWs)nj;#F0":m@5?:JakoFGl'7Lkknbqhk0,qi(B0!1Vg^;%J"_Sa@3a2l?E +bKS5Vcd:(fe'uq"f@\g2gYL]Bi8ESRj5f=ak32'olKdg'mI'H3nF?&>o(2MGp%A%Pp\4[^s7u]k +qtpBjrVcBfJcC<$g])d~> +JcC<$JcEC_m/Hk[qu$3cr;-?erqQIns&T:k7Rm.OpA4I^o`"I[o)J7[nGVhUmJuYRm/QAOlMg#P +ki_-kk2k\'j!9h\&M4YoT( +:Jjnc;cj!)`\ks&&Mgpeq8osDl +:B45i;=m]b;>sAl:]4,d;?'Jl;>j;k;>!c[:]=,h:]*ue:]F8h;#jGl:]F2h:B4/h:]F2g:]4&^ +:]F8^:\did:]=2i:\IWb;>3od:B45e;>j;m;,Ua8j;#jMm;>sAo;,U:hr(mAjqbmGm!)i_l +rDNYoqG[Glr_NSlr_s,!9MS2Q8Ou8I;#X>l;YsAq5XIb$5lO(M62j.L62s1K5Sl^Q5X.Fq5X8k;u_CJJH1<# +K*$^[L&Qf.LPUccM>rG5MuJY:NK0%uNrb?)rfR;GPl?pKQC%T^ +JcC<$JcEC_mJct\qu$3cr;-Bfr:gK+\%0)_^;'YLqXsj[rq$*Zrpg$XrU0gUmHso>s6B[MrojXN +kND!ijlHF$-K="Bi8K->B$9Mh6;*It20EXf/+pSXPq3Nf/[JJUD`eG(5!mJ:`<)L4t>/8LPYncrJLW5rf$l:s,[2AqiUl+%!d5FH?X4FDJ +O'+\9.^Hr_`Ymqc!Mo!F/k,>lS".=T)A&>5_\*=TM]/r`K2%&'2jq>$>'QS%#l8['d@dVZG)hn^.<^!RAsbb5fcabPfZ`b5f]Zao'6UaT-hiJH(0#K)L<'KS>-ZL'!-dM#N82M? +&S6N!G?&NfT6_OHKO*F-DiRQ'R`&R$a;1S"#q=St;RITqS3UUnjibVl6SpWiW>)Y->.8Za7$I[^ +WfX]"G\i^V@V%_o0O6a2lBGbK\>Yd*^:jeCE.%f\5'6h;-rGi8N\UjQ5OdkNV6rlg4!*mdKW6na +Z2@oCV\Jp%J+Rp\ssfq>^ +JcC<$JcEC_mJct\qu$3cr;-Bfr:g;TOSt:DP#G7VqXsj[rq$*Zrpg$XrU0gUmHso>s6B[MrojXN +kND!ijlHF$.H9=Ei8E=+YmKH?OFPE,00#AR]"P>?YNG@q0%YAS,RdB9)qM%p*%CM0Ph2DJsH8G'J@\ +HM2X[GkH=aG^"=Sr,qFLrc8']n9+bQs)S6`F*%>$s)\$W!c`0ur,MRPphp7PDf9UoDu+GNDuFPR +Dt.`DD?"GPCBAe;IDZ+GOD#S;OD?4Tjr,)+E!,_LKpi#\?rbq^Pr,;OOrbhjUDf>Mlp2U%M +rGhXPs)IpVrc.mWr,Vp]F`m\,!I&_dG5umeH2;jeHiJKlIK"0oDJsB/Ch@6iA7K/8B)YX+;>sJj +;u]hs;#O;l;#aAo;Gg?h;>sDi;%QQgPtk+O:h+d/Mi*=G8Vr<$MYE&+N;AG5Q^IW;!1N_Qs-itU +pm;&Lr0[GNnsKHDrKdJMs-WeP!.Xuus+(0%rIY0)Kn]M\!f)Sfre^Z4!/pi8#E=b(O,oBaOoCMb +PE_>tQBml)R$jD4S"-%@StD[LTq\ +JcC<$JcEC_mJct\qu$3cr;-Bfr:p+hr^QbWrq-3]rUTsXs7$!U!q,ICrp9[N!:'RJ#3b75k2tdd +ro5UR5X.Fo4?GJ\2Dm6E0/"k/1GgjA1G^jE2)I-`r_3bo7S-6:7o)rY:f:6j +;Z'Dg;Z9Mr:esk`;>sJn;u]et;cd;Ya8k<;okt<;fbo;Yj:]OAd;"d]a:B+,g:Amug;#F/j;#X8j:B+,i:B"&h:B"&f:A.K_ +;"IKX;#X8i;#X8h;#aD_;#O2c;>j>k;?'Pn;>a8j;?'Pm;?'Gr;,U:h:f73g!)`Vks&/nqqbd>j +s&8\l&5uG&;G^@k;,U+]9hJ&N:.,"Wr_`Ymqc!Mo!^T%9r^$TNr]pKLs$-HI(I:;N5!;+p5X@Y8 +<'`c65=A.?;,U:h3pg)E=9;Q&;u0Jm<<-"s;Zp'"V(P&lhOQ'IZ$Q^F/.R[]e:SXuFFTV8'RUSO]^Vl-Jm +WiE/&Xfen4Z*UdD[^NZU\[oGd^;%G!_Sa=2`lH0BbKJ/Ucd:(fe'uq!f@\g2gYL]Bi8ESRj5f=a +k3)!nlKdg'mI'H3nF?&>o(2MGp%A%Pp\4[^s7u]kqtpBjrVcBfJcC<$g])d~> +JcC<$JcEF`mJct\qu$3crVHHfqY19)\[oJg^Vg%QrUp0^rq$'Ys7--YrU9dSs6]gPs6B[Mrol-# +kND!ijlGL_j5T%Ui8`5*K`Hf)L&6PrL%g<%L&Qc) +L%p?$L&Zi+KDgE$JH15tJcC?%JH:@Rrdb#urdO`o!.OiorHnTnrI"TkrHnTjrd+Hes*FWhs*4Qf +s*+Nhrd+He!.+Wi!dK!9qKW!brceEgr-AEkI!bd;s*=WjmX#"]H$TC8rd"re^Q1s,6o9s,@/AO,oBarK7)B!/gc'%XEDI +G&hG=Dej-,G&pJVr_`Ymqc!Jn!EEA&>lS".=T)A&>5_Y-=]ej1r`K2%!Q`C^=p\G_U:7V?['?j1 +r1X7fUnmd^s/,Og!m]-rG5MuJZ_NK0$[O-#KdP*2#nPa.N"Q^F/.R[]e:SXuFFTV8'RUSO]_Vl-JmWiN5'Y-5(7 +ZEppG[^WcW]">Vg^V@S$_SjF5a2lBFbKS8Wd*^:jeCE.%f\,!5gtgiEi8N\UjQ5OdkNV6rlg4!* +mdKW6naZ2@oCV\Jp%J+Rp\ssfq>^ +JcC<$JcEF`mJct\qu$3crVHHfqY1&PrfI8FPEl,FrUp0^rq$'Ys7--YrU9dSs6]gPs6B[Mrol0$ +kND!ijlGL_j5T%Ui8rJbsuo +Ii)1*ChI0^?=7/B7+kLA7K+\AS,RdBDmeu=C#3?AuTN]DJsNL_@qK:K;#X>k +;YsDl;uourr_ibms%rhq;,[9gr_WPjs%j/hPtk+O;.tB9Mi*@HLAHf$Mu8P3MuS_;Q^F0:R/i]O +S,\oXR$m`:!1EbPrL*5Ds-N\Ms-NbQs-Ee9It.HJs+(0%rIY0)Kn]M\s+^T1re^Z4!/pi8I#X/H +O,oBbOcklkPa%GuQC!u+R@9V7S=Q7CT:hmOU8+N[VPg>jWN*##Xfek3Z*L^C[C3QS\[oDc]t_=t +_SX71`lH0Bb0/#ScHstee'uq!f@\d1gYCWAhr*JQj5f=ak3)!nlKdg'mI'H3nF?&>o(2MGp%A%P +p\4[^s7u]kqtpBjrVcBfJcC<$g])d~> +JcC<$JcEF`mJct\qu$3crVHHfqY9th"BAAg7Rm@Lrq-3]r:9mXs7$!Us6fpSrp9[N!:'RJ0^.]_ +k2tddjQ#:[iS`YOhVI#CgY1B7f[na+e^W'rdF$=ecHXSVbK@rJa2Z*;`5;IQpf.2j!*&hqs&AYi +(G@[%0J+b*/M9"?5sRXt4$#A\2Dd-D0`sDk;>3ua;u]hr<<-"s;uKVc;$0Wj:Jh!es%i\k +pe^rer_NSjrD<>fs%r\lrD3Jkp/(HYr_EJhrD*>fr_WMi!)WYjs%`Sis%`Sir_EGgrD*&^r_W2^ +q,%&dr_WSir)!Air_NSlp/(`a!)WJgr_WVlr_ibnqb[;ir_i_ms%iep;GpBi:]OAi;ZBYq;Ys>k +;Z9Vg<<#c+:Jahc:fC4a:/";S8OPsC;#X>k;YsDl;uou`r^$iU5X7P"5sIU45Sl^O5<_4p5jWN*##Xfek3Z*L^C[C3QS\[oDc]t_=t_SX71`lH0Bb0/#ScHstee'uq!f@\d1gYCWAhr*JQ +j5f=ak3)!nlKdg'mI'H3nF?&>o(2MGp%A%Pp\4[^s7u]kqtpBjrVcBfJcC<$g])d~> +JcC<$JcEIamJct\qu$6dr;-Bfq=k9j\@K8c^;7e0>5hV(p&=U_oDJ1Znc/+Wn,MhUmJcJPlN$5L +kqVDbkN:pgjQ,@]io/hRhqm2FgtUQ:g"=p.f%&:"da?Ihcd'h[bKJ&MaN)<>`Pf[2rLNkUs-itU +!LT5QR/WKWR$X,)Q^@ZDNrG%rd+Hes*FZis*4Ne +s*+Nhrd+Kfrd+Kfqfr*crHJTnH?sj^H@1'dr-A?grd+!Z!d]-;rd+QhqKi-fs*X`mrI4]n!.Oco +rdOlqrI4`q!.Olrs+'Zks+1E,KnY89L]3/-MZ8S?N/`gWNfT6_OSt=?OqEn2I!pEiG^+CLD/O6, +DL$A$r_`Ymqc!Jnr`/o%s'#J*r`K5'r*02'!ErY*=T;G3aN7Xi>%<;e\$rfQZ*=,"!McIiV>d:i +V>d@fVuG!Acgf?accsbZpri]]rQG/`rQ>2`pWb]tV7s_8=+/`Q-'Ab0/#ScHjnce'uq!f@\d1gYCWAhr*JQj5f=ak3(smlKdg'mI'H3nF?&> +o(2MGp%A%Pp\4[^s7u]kr;6HjrVcBfJcC<$g])d~> +JcC<$JcEIamJct\qu$6dr;-Bfq=k6iOH>TePE_?!rDEXgrq-3]r:9mXs7$!Us6fpSrp9[N!:'RJ +1$If`k2tddjQ#:[iS`YOhVI#CgY1B7f[na+e^W*sdF$=ecHaYWbK@rJa2Z*;`5BIjK`$K!K)1&o +JGamD<`3pRA6rJJ?=?l8J9uTgF`_S=Bk1a`?X6i<@U`kXA7T7_B4YZPN=0i6?tEtdCi435Fae8ND>S5KD>nAOD>nDQD#A/9DYe;?DZ4SQDYnANDYnALE:n5ME;jkP +E;sqUErC"TErL+[FT-F\G5c^cGlN'cHN/?iIJnU+FDl/:Df'?-An,C`@q04b;#X>k;YsDl<;ons +;ZBSl;#jMk;>sDj;?'H%Pa,$?:f_CcMi3ILLPG_aoo&a,!/pc6rg3YPqjIJQq3qDRRJ*$JRJiNO +RIZaFQi36MQiEHQIK+crJ,XuuJH1<$KE$W)L&Qf.LPUccM$JorMi +JcC<$JcEIamJct\qu$6dr;-Bfq=k-f<`N1$<;oer7K,aVp&=U_oDJ1Znc/+Wn,MhUmJcJPlN$5L +kqVDbkN:pgjQ,@]io/hRhqm2FgtUQ:g"=p.f%&:"da?Ihcd'h[bKJ&MaN)<>`Pf[2rDiVlrDN\q +r)N_q!)rhqr)4[l0/bU?/1N2&/N5RR5<_7m3]K&V1bg^l:]O;d;#X>k:]O;i;#4&h;#aDj:]OAd;"d]a:&n)f:B"&h;#=,h:]F2h:B4/h:]F2h:]*u] +:]F8_:\[cc:]=2i:]4,e;>!ca:\[fd;#aDl;ZBVl;#aDk;Z9Mr:f1+g;>a5j;>O/k;c5=%S"5Q*hd5sIRt4[)(q5sSFL5s[_# +7SQZU;Gp@j=]eg0rE/espK7Gpr_r\nrDibo!`W0"p/M&lrD`_qs&Aqqp/:idrDNZDs*jutrdb$" +!.t3&s+LE+re:K0Lku%e#E"FtN/WaUNrG(?OHKO*E0HNOQ'Rc(R$jD4S"-%@StD[LTq\b]tV7s_8=+/`Q-'Ab0/#ScHjnce'uq!f@\d1gYCWAhr*JQj5f=a +k3(smlKdg'mI'H3nF?&>o(2MGp%A%Pp\4[^s7u]kr;6HjrVcBfJcC<$g])d~> +JcC<$JcEIamf*(]r;?K2enkKO+i"2I"-]\YH"LtTUV@9NerLDIW81MuJ_9NrP1?OSt=@P5g^XP*:BDH[L3cG'.S>CMdm+JUdYrs&/\l +r`&ks!ENJ(>6%e)=TDS%>Q7e+>$:i,s&TZNa]hqPCQ>^0\$iZKYl(3qU].%kUSOZ\rh]Ukq5=2: +s3LDc!71Vj"4,6:bk]H[bl>lbbl,]bb4s*TaSs9]I/\QoIfFosJH(0#K)L<'KS>-ZL'!-dM#N5F +MMmCON/`jXO,oBbOcklkPa.N"Qi<@`R@B\9SXuFFTV8'SUnjiaVl6SpX/rG+YHY:;Za@-K\%&u[ +]Y(tn^qmn*`5Ta;aND]Mc-FY_dF6Upf%8R-g=tE=hV[8MioB+]k2tjjl0@U$m-X60n*ol;o()DE +o_%nNp@nO\s7u]kr;6HjrVcBfJcC<$g])d~> +JcC<$JcEIamf*(]r;??YKG@Us$KAHQOWAS(h"$Zq53@qKIkCiFH< +Gkl^dHM2XYGkcOcG^"?0FoHRaFmsJRF*-kn!d&L(rc@^Ps)J$Ws)J$W!,qgTq/?:Nqeu@Nr,:q> +r+uFMrbDOND>e8ND>S5LD>nAND?"MMDL_A8lJd;?'Pj;uTbq<sDj;?'H%Pa,$?:g7srMi3ILLPGecoSWd0Mi7Ci!1t +QC%T +JcC<$JcEIamf*(]r;?k<;ol)<^K)<5X.J!5sR[55QX595Q3hY5tQC%T +JcC<$JcELbmJd"]qu$6drVHKgq=sp_s7Qo7^V[t2bgG,&>$+j.oDJ1Znc/+Vn,MeUmJZAQlg!d7 +kqhPdkN:pgjlGI^io/hRhr!;Hh;$c=g"=p.f%&:"e'cXjcd'h\bfe/NaN2B?`Pf[2_8,u=s-s%W +pmM)J!13MKs-FjUB:G-DJUDorIqNGtWMZJaR@'4uM2$V2GBe:\It3-(re1H0KSI):]*l$2Rr`e! +I=[$(M2qFos,lr:s,dMIO,f6[N/[Xn!0$o8"H&%mLku"b!/C0#qh4ZspP&m+KS+o1Kn]8S!/:E* +s+:T.JqAQ)J:N3$rIFs#r.+p"It.BFqgSTprI+Wl!.Ffnrd4TkrHe?drd+Qh!-nKercnEgqg&3f +s*4ZjH$T72rd"Kf#C1WAH$O^_Hi&*hH2W'XHNJM=H2`-hH2`-iH2i3iHi&3hI/n`pI/n`lJ,+Nq +It3#tr."3e!J5t'Ka*9eLl$tGM>iD2MuSe:NrP1>OSt=AP5g^KP*;)oMZ/&'H4"h7DJsE.DMj!B +;>sJj;uTbp6%e)=TDS%>6A#1>$:i,#Zk-LaBMhOF-cg7"Lb\BY[d[,rM'FgUSId`s.o^m +q5=/9s3LDcs3L\k"4#08bk]HZbQ,ibbl,]bb4s*UaT'B^HiJKmIK+crJ,XuuJH1<$KE$W)L&Qf3 +LPUbCM2I1Krepl;NrG(COHG]hPEc'3BU5!PR$jG5S=Q7CT:hmPUSO]^Vl-JnWiN5'Y->.8Za7$I +[^`lZ]=bhl^VRe)`5Ta;aND]Lc-FY^dF-Oof%8R-g=tE=hV[8MioB(\k2tjjl0@U$m-X60n*ol; +o()DEo_%nNp@nO\s7u]kr;6HjrVcBfJcC<$g])d~> +JcC<$JcELbmJd"]qu$6drVHKgq=sp_s7QnaPEV5sR%'eK;Gg:hoDJ1Znc/+Vn,MeUmJZAQlg!d7 +kr.bgkN:pgjlGI^io/hRhr!;Hh;$c=g"=p.f%&:"e'cXjcd'h\bfe/NaN2B?`Pf[2_8(\UK)L?% +K)L9#K):,nJH(*A>uPi_BOP4S?sm#9Jpr)mG]\"FBkCmb?X6l?@q&qZAH$-AB4YZPN=1A[FD#<& +D/XH;G^B.3s*FBap3?CY!dJp4rH8-`rcS!X!-S'Ymr\eUF)l;BF7XDPEW0qWEW:"XDuFYNDuX_P +Du4MODuFPRDt7fCD$=`kCM[j)rG;@Kr,)FLrb_[Q!,VRMlYcN:n8A5DrGMLNrbhRN!cW'rrG_LN +rG_aUpMg"Mqf2OS$ZgE4F`_bKG'.qNG5c^cGlN'dH3/G@I/\QhIK4TkE"-`'Des#sB4YU`F)OoQ +r_iVlr`&hrr`9%qrD.8Za7$I[^`lZ]=bhl^VRe) +`5Ta;aND]Lc-FY^dF-Oof%8R-g=tE=hV[8MioB(\k2tjjl0@U$m-X60n*ol;o()DEo_%nNp@nO\ +s7u]kr;6HjrVcBfJcC<$g])d~> +JcC<$JcELbmJd"]qu$6drVHKgq=sp_s7QIn<;ohr;?g-*77K^8oDJ1Znc/+Vn,MeUmJZAQlg!d7 +kqhPdkN:pgjlGI^io/hRhr!;Hh;$c=g"=p.f%&:"e'cXjcd'h\bfe/NaN2B?`Pf[2_8,hFq,78m +r`/bnrDOac/iPUA0.JM(/N>UR5s@Fo4$,AY1bga>0J5"81,Ahc%Poq"2)@s$:JFMA4u?#1r_N\p +<)HNk;Z9Vp;Z'Df;YO#o;H$Oo;c6Ii;Z9Vn;YErg:f7!c!Dubi;ZKep6Yr_NMir_EMjpJLW\r_EMjq,.)e!)`\m!)`Shqbm;gr(mAjpeprcs&/eoqGdJnqG[c" +;,C+e:f1.g:Ad`e8k`)Zr_iVlr`&hrr`07i5X.J!5sR[55QX5:5Q3hZ5.8Za7$I[^`lZ]=bhl^VRe)`5Ta;aND]Lc-FY^dF-Oof%8R-g=tE=hV[8MioB(\k2tjj +l0@U$m-X60n*ol;o()DEo_%nNp@nO\s7u]kr;6HjrVcBfJcC<$g])d~> +JcC<$JcEOcmJd"]r;?+`(h[OGA@2IXZ$EAuqr-Un!m>P`(6NJ:)QbG(5$nK7ejVL'!-l])K;LMj_;7T6Yd5JqSu@ +plPNi>0L]<,&L&-JsL%pE&Ka!-^K7no3pOiO#re1<(!J,k% +JcC6$JUm]M!.t-"!e>cMrI4Wns*joprHnTnrI"TkrI"Qiqg&3frHSBfrceBe!."Qir-A9fs*4Zj +H$T:3rd"He#C1WAH$O^_Hi&*hH2W'XHiArJ3MZo'!NK0$[rK-u?!0[8Ds-3PK%tT.VH[C']F`)&6Chdg+K)S[E +;uTbqQ%\)=SuA*=]ej1r`B_5=NJQf>$?6C\$rfS['HoMqP*q`rhKRkVZ!FmV?!OjcMu5a +d/MAkcj%e?bfn8Rb5BHWbl#Wab4s*Ua9Kb4H@(!dI/\QoIfFosJH(0#K)UE&K`?c+LB!#/M#N6L +MMmCON/`jXO,oBbP*2#mPa.N"Q^F//S"#q=St;RJTq\Yd*^:keCN7'g"P39h;7&IiSrnXjlY^gkiqBum-O--n*fc9rpg*]o`"O` +p&Ojcq#C0iqY^6hr;QZdrdk*#s4dR(~> +JcC<$JcEOcmJd"]r;?\=r;H!)Vrpg$XrU9dSs6]dO!pf.: +rojgSkND!ijlPR`j5T%si$I:;h;-l@g=k64f@JL%eC2jnd*L"_c-4ARaiMQC`Pod5_SO%&rdt*$ +qgnd!qgnHk(fjUVD.R*Z?sm);LDZ"AND#S;ODZ"A:DYe;?DZ=YQDZ"GPDYe;OE;skUE;OVTE;aeT +E;sqOE;FVQEVsh[FEM_JFSp:]G5ldcGlN'eHN/
  • sDk;?'JmPlFMd:h>$5Mi3ILLPAq+Mu8J4MuAV7MZA_6R/`NQR/<s-N\M#+'X^H[C-frdFfqs*t#us+(0%re(6(s+UK-s+^T1reYQNMi3OQNK0$[ +O-#KeP*;)oQ'IZ%R$a>3S"-%@StD^MU8+N\VPg>kWiE/&Y-5(7ZEppG[^WfX]=bhk^VI_'`5Ta: +aN;WKc-FY^dF-Oof%8O,g=tE=hV[8MioB(\k2tjjl0@U$m-X60n*olHncA@Srq6 +JcC<$JcEOcmJd"]r;?p;,U:jrDNYos&/blq,6ra$;sf%<)Z[l;,U:jr)3/a!E)km;?B]n;Z0Mo<;oer<;T\q<<#ns +;Z'Dl;#!li:esk`rDESjq,%&frD3Jir_WDf!)WYlrD3Jkp/(]`!)EDer_EJhrD*>fs%rSir_NMg +s%`Vir_NPhr_NGepJ:cboM>3Xr_NPjr_NPjpJLW\r_EMjr_WYlrDEMi!)`_ns&&VhqGR5gr)!>i +!)`\mq,./irDWSmr_r\n!)rkr%o?,#:Jt(i:eaYX91hcK8cDWa;uTbq*YHY:;Za@-K\%0&]]Y2%o^r!t,`Q#s>aihlPcHjkbdaZdtf@S^0 +gYCWAhr*JQj5]7`k3(smlKdg'mI'H3nF?MK!V>s_p&F^cp\jmeq>^s+14)s*t~> +JcC<$JcERdmJd"]r;?$+j.naZVJrU9dSs6]gPs6K^M +rojgSkND!ijlPR`j5T%si$[F=h;-l@g=k64f@JL%eC2jndEg+`c-4ARaiMQD`Pod5_SO%&^Rb@o +!h5XIrgE,?-#&j8O,&7/DJNotBWJ,2UR[g>OGegFJ9uQeJ:N6&Kn=u3L4k<[]*k=(WM#`*G^P0u +M2V(hrK6f:s,dGGO,f6[rf$c7!0$o8!/g`2rJ1B,p4`BspP&Bs!el;\rdt6)L%g6#L&Qc*K)pOT +rdk*"!J,e"JH1<"JHC@OJ,OinIfOrrIJeHmIJnQmHi8?jHM`!fHN&3iGlDpeGQ<$gHMi'fH38G; +H$T72rd"Kf!dT*6A#1>$:i,&6DuTaBMkVJY]ca[^NQJY]0K6rM0@f!i;cjqkj27!71>br6PDf!6kGc +!6Y5_q98]Y!6Y)YqoJ_^s*OcnrdFfqs*t#us+(0%re(6(!/:E,s+^T1reUZ5MuJZKNK0'\OHGZg +P*;,qQ'Rc(R$sM6S=Q7CTV8'RUnjiaVl6SpX/rG+YctC=ZaI6N\@K2`]Y;.r_8=+/`Q-'AbKJ/U +cd:(feC<%#f@em4gtgiEi8N\UjQ5OdkNM0qlg4!*mdKW6nc&([oCW%Ts7QHerV6Egs8)Zjrqu`n +oDX=@JcFL)J,~> +JcC<$JcERdmJd"]r;?BP(d`?X$e6@g?RTAS#LcAWHbL$[6cCGC4.? +E,fuBH1lUbHLuLUGku[eG^"?/FT?UaFng(YFnp.KFTQZ+F74,LEW0nWEW0qWDuFYODuOYPDu4MO +Du=JQDt7fDD?"GPCB86grG2INqel@LrbVRNs).^Nl>HH:n8A5DrGMLNrbhRN!-%mTs)@mUs)@sW +r,D[UpMg.Pr,VgW!-%pWr,Mp^F`heJr,r$_s*+Hes*=Ng!IK4nIIqt"I=#pPDJsK3ChI<,-rBMi3IML5&t/Mu8J4MZAY3Mu/nAQN3ELRK&`T +S,8WSRJ3*ERIHUDQi36KHN/?lI/\QoIfFosJH(0#K)UE&KE-`*LB!#/M#N53MMqImBT8%5O-#Kd +P*2#nQ'IZ%R$a>3S"-%@StMdNU84T]VPgAlWiN5'Y->.8Za7'J\%&u[]Y(tn^qmn*`Pom=aihlP +cHjkbdaZdsf@S^0gYCWAhr*JQj5f=ak3(smlKdg'mI'H3nF?MK!V>s_p&F^cp\jmeq>^s+14)s*t~> +JcC<$JcERdmJd"]r;?[2)R*B0/"q71,:[B1GgpH2)@s&:JO,h;>a>i +;>X2g;?0Sm;?0Pi;?'Pm;uK\q;Z]iq;u0Gr +JcC<$JcERdmf*+^qu$6drVHKgqY:'arV$3_s2>/`d+I4;l2BuQ='A[,=Rc7Ws6fpSrp9[Ns6BUJ +3p>bik2tdejQ#:[iSi_Qhqm2FgtUQ:g"=p.f$r3uda?IhcHa\YbKJ#KaN)<>`5BI.^q[XuSXc1= +rgNhSp6bZB-@0BrOc!deDJO$&BWeA5VP0HFQ&^fVKn"GnG_(EuJqSf4L4tGKrOWEbr6GGhbfp(0s2t;`q98`Z +!6Y&XrQ#%bH$T@7s*F`nrI+]p!.Xrt!eGrTrdt9*Kn]M\!JcL1M/8'-Mit +QC+&-R[]e:SXuIHTq\Vg^V@V%_o9U8aN;TJbg+M\dF-Ln +e^rF+g=tE=hV[8MioB+]k2tjkl0@U$m-X60n*olHncA@Srq6 +JcC<$JcERdmf*+^qu$6drVHKgqY:'arV$3_&X/HGS"Z^\Yd1R>Y>/"n;,Zo]n,MhUmJcJPli68L +kr.bgkN:pgjlGI^io/kSi8ZGi^BDl$6=W:IpJ:)`gFE2>:BkCmb?<^ZF@qB1^AS5XfB6O65$@ZuVFae(BE-$/IoR$R` +om-4TqKW-eGBW_'q/lUYqK24L!H`DNEWC+YDuanWE;skTE;FMPDZ"GME;XYADYn8ND#S2NCi0,e +!,_UNrGDOMrb_[Qr,(_:qJYh?rbqdRqeuLPq/?:PrGM[Tqf2US!-.pUs)IdPrc.mW!-/!Ws)IsW +!crL,rcJ'\s*"Eds*4NgrHeKjrdFEfrI#6!E,]`6DJa-#An>O_@Us%Jqc!Gmr`/bp!EW1o;>sB* +;,U7f:m@2?:K_RiN/NUOMMHpoqMY0,qhkH@qNq;MR/33NRf/`QRK/cLR/36?R/`NQQ3);VH2W'h +HN8HlIK+`rJ,Om!JV&LQK*$^[L&Qf-LPYqdCl4./N/WaVO,oBaOcklkPa.N"R$a;1S"#q=StD[L +U8+N[VPg>kWiE/&Y-5(7ZEppH[^`lZ]=bhl^VRe)`Pom=ai_fNcHaeadaQ^rf@S^0gYCWAhr*JQ +j5f=ak3)!nlKdg'mI'H3nF?MK!V>s_p&F^cp\jmeq>^ +JcC<$JcERdmf*+^qu$6drVHKgqY:'arV$3_&Q;S);H@"0@U`bR>sCbI77QeEn,MhUmJcJPli68L +kr@nikN:pgjlGI^io/kSi83ub;uT\n;>=&a;$Bir<)cdor_WYnrDESmr)!GlqG@5jr_r_ms&&eos&8nr!`N&tqc3Yq!)rkp +r)*Jjr_WYlr)!Pm:JXgc;?'Gf;#X>j:]O;j;#4&h;#aD_;#O/i:A[ic:&n)f:B"&h;#F/j;#X8j +:B+,i:B+,h:B"&f:A.Ha:f6j\pJCibr_WVjs%rJfohbW`rDEPj##S2m:Jakbr_ibnqb[8hrDNPj +qbR8ir_ibnr_`bo;#=,h;Z0Pn<<#ns;ZB\m<;TZ-<)?Fh:f1(g:eaPV91qiI6W3e[rD`brq,RW" +5s[b#q`t*Es$6TMs&K%a!Coi_:]sZp;,]aQ=T2J#=9)=t<t +QC+&-R[]e:SXuIHTq\Vg^V@V%_o9U8aN;TJbg+M\dF-Ln +e^rF+g=tE=hV[8MioB+]k2tjkl0@U$m-X60n*olHncA@Srq6 +JcC<$JcEUemf*+^qu$6drVHNhqY:$`rq?6^#P?$\e_K3Km/HAVm-*P6=]\`)n,MhUmJZDOlN$5K +kre1mkN:pgjlGI^io/kSi8uK_U8rL&m!]rIacr!/:E*"+u2VK)U?$ +J,t4OpjiKsIt.BFqgSTprI+Efs*O]lrHe?drd+Qh!-nKercnEgr-A9f"F56:H$T:3rd"Hes*FZi +rd4Qh!."Nhrd+Wmo6UObH$TC8rd"Khs*=Tir-SBir-\WoI=D$B!J#[rIKG"LJGOcpJFe=(JqJ`0 +KnY8;Ll$qDM2@+IMi7Rns,@&>O8Y1=OT:RDP6@&4PE_=1PnKCLPC@n,H?sj\EGTT2Ci"!3;YsDl +<;fhn6A#1=]tZ)s2b4E$>ts3\$rfS['HobrM'7cqkX.d!m8a3q9Audp<```"4#08 +bl5fcb5KNZbkoQ`b4j$Wa96^3G^4T5HN/
  • ,7L51P?M2@+IMitQ^F/.R[]e;St;RJTq\s_p&F^cp\jmeq>^ +JcC<$JcEUemf*+^qu$6drVHNhqY:$`rq?6^&bM?UT;/BhZ*LX=Xf83q;Gg?kn,MhUmJZDOlN$5K +kr7hhkN:pgjlGI^io/kSi8[(?7>?P*1=+YmKH?aINEGK3!@piVJ>@V2Srac^SBP(k:NK&s:F,=jdC2@g/Fa3J( +rd+6_om$=Y!dJp4pN?:RrcS'Zn9"bRF7+&KEW0nWEW0qWDuFYODuOYPDu4MODs_H>D#eDOC]A8M +D#8,JD>nAND?"MPDsB+ +;,U7f:m@2>:L&"!NJi^PMMHpsHiAp(N/RLhr/:Q@pmCoG!1NnVr0dYSRdujERIHUDQN`\!G^+LZ +rHeKj!.=`ns*artrI=s#JqEuS&;5akL5(J=Ll$tGMMmFPNK4"!@??V7P*;,qQ'[l*R@9V7SXuFF +TqS3UUnsrdW2ZetXf\e2Yd1UB[C3QT]">Vg^V@V%_o0O7aN;TJbg+M\dF-Lne^rF+g=tE=hV[8M +ioB+]k2tjkl0@U$m-X60n*olHncA@Srq6 +JcC<$JcEUemf*+^qu$6drVHNhqY:$`rq?6^"nYYi<*EW-@K^+G>Zt8/70#gVn,MhUmJZDOlN$5K +krItjkN:pgjlGI^io/kSi83ua;$Bir<)cdope_#hr)!GlqG@5jr_r_mr_Wnu;cH^r<)Zck<<-"t;Z'Dl +;#X>l;#O5n:esk`rDESjq,%&fq,$obs%r_mnPK0[!)EDer_EJhrD*>fr_WMir_NMgs%`Vir_NPh +r_NJfp.tZaohYO,g;>jDk;>X/i +;>sJm;?'Mq;,C*e;>jDk;u]hs;u]bq;u9Pj<=2]*>m6V1!J;,L4i;,]bQr`B/'qcNi#r)iqtqc*f!;c?Xp +JcC<$JcEUemf*+^r;??erVHNhqY:$`rq?6^s7?K:dFmI?li-8\m-3Wlj&]Dd='4nYmHsl=s6B[M +rosIH!9a@Ds5c6$j5].XiS`YOhVI#CgY1B7f[na+e^W*sdF$=ecHXSVbK@oIa2Z*:_ns:+^V@Lr +]UYL]R[TY4pmCcA-#[[DO8b.;N;\_9N;e_8MZ/G0L\uo%L&$DtL%pB(KnP-YKCsltL&Q`-K7\Z+ +rdk*""+buRJGOfuJ:E(HIf"TpIf4]hI/eQlI/SBgH2`-hH2VpgG^"H4HMi'fH38G;H$T72rd"Kf +!I9"jGli;=Hi/0iH2W'WHiA?kGlW0iH2`-hH2i3hHi8/9r.tB0s,-i7rf$l:s,[,?rfI2Drf[JJPEV5qrKS(_Q^F/.MLBo"H?saYD/F3.C2Im1 +r)[)B=[^W`S[^``cN)8i +bl>lcb5KNZbkoQ`b4j$XaSpD`GlN'fHN/
  • uQ^F/.R[]hkWiN5'Y->.8Za7'J\%0&]]Y2%o_8=+.`Q$!? +b0/#ScHstee'uq"f@em4gtgiEi8N\UjQ5OdkNV6rlg4!*mdKW6nc&([oCW%T!quB_rV6Egs8)Zj +rqu`no_sFAJcFI(J,~> +JcC<$JcEUemf*+^r;??erVHNhqY:$`rq?6^s7@(nS=uj_Yd1O=XfA:rVbU,e;,ZiMmHsl=s6B[M +rosIH!9a@Ds5burj5].XiS`YOhVI#CgY1B7f[na+e^W*sdF$=ecHXSVbK@oIa2Z*:_ns:+^V@Lr +]_mBTJc:3"J,=cr?N4:/>5q_T<`ad#H?j^VEc,W)A7JtQ>[1cK@V'+_B4kd[NK&s3EdMqWC2@g- +Fa&0%HiA?aH1cFYGlr;8G'irGDOMrb_[Qr,(_:qJYnAs)7pT!,qjSqeuLPq/67Pr,;RRrc.mU!-.pU +s)IdPrGhgW!-.sV!-.sX!-A$ZqfVp^s*+BdrHeKks*aQhr-eNm!-eE]rb`!VAnG[f@q&t\r)b]tV7t_Sa=2`lQ6DbKS8Wd*^:jeCE1& +g"P39h;7&IiSrnYjlY^gl07L!m-O--n*fc9rpg*]o`"Lbp@n=[q#C0iqY^6ir;HTdrdk*#s4[L'~> +JcC<$JcEUemf*+^r;??erVHNhqY:$`rq?6^s7@((;cm:5@U`bQ>?Y-1=[5DF77Q_5mHsl=s6B[M +rosIH!9a@Ds5c&tj5].XiS`YOhVI#CgY1B7f[na+e^W*sdF$=ecHXSVbK@oIa2Z*:_ns:+^V@Lr +]Mql);ZKerl;#X>l;#a;k;#O8k:]=/j:]4,h;>F&b;?'Jm;=RK]:B4/e:]=,h:]4#k:JO\^;#F/j +;#X8j:B+,i:B"&h:B"&f:A.Hb:f1'^:\7K`:B45j:B45d;#sKhpJClc!)WYlrD3Yp:ejb^;#F2e +;#O8j;Z'Di:]OAl;Z9Pn;?0Sn;#O8h;Z0Mq<)Z`p;?0Ym<;KSq<)rlr%T$"u;G^7e9h\5R8k;NA +r) +JcC<$JcEXfmf*+^r;??erqcThqY:'arq?6^rq-6^"4c5gli$2OlK/$)#3"QH>$"g.rTsRMs6BUJ +s6'IGroQ-#jQ,@]io/kSi8C2.HtDJXopG(5-rJq\l4L5:\]rjrZ?Njk%tH$t3r +LQ.CWO,rgmrfR,A!0R5C#*G"/O,f3ZrJ^]7!0$o8!/gc3r.k3)pP&Hsq1\Tu!el;\rIafs!/:E* +"+u2VK)U?"J,t4OqLJ]uIt.BFr-n]qrI+Efs*O]l!.4]kqK`*ercnKgrHJ9d!."Qir-A9f"*o-: +H2DjcH2VsgH$]I8!d]3?rH\Hhr-J?h!.=EcrHeKhqKi*c!.+Qird=`os*Xip"+5NFIf"WpJ,k)u +IKb4MIXcluqg\QpoRR!ordt?,KnbA&rK.&As-!DGs-!DGs-3JIs-NbQ +&Xf#SIscTgH[9mWCiXE0CMn:m;uTbp6.l/r`T5&&6[)r>[2]L[^W`S[^``cN)5hbl>lcb5KNZbkoQ`b4j$XG5ZXbGlN'fHN/
  • ,7L51P?M2@+Jret?HNfT6_OckllQ'IZ%R$a>3S"-%@T:hmPUSO``Vl6VqXKAY/Yd(O@ +[C3QS\[oGd^;%J#_SjF5aN2NIbg+M\dF-Lne^rF+g=k? +JcC<$JcEXfmf*+^r;??erqcThqY:'arq?6^rq-6^".uBhYPtd8Y,\CrVP^2e;c6Ij;Z5t^li68L +l2TrIkPjU#jlGL_j5T%Vi8EMLh;-l@g=k64f@SU(eC;podEp4bcHOJTb/q`F`l5m6_SX.(^V7Co +]DR9ZJH1?Zt96>%:T6JU_umGB\+ID/!Qk@UEAE@q9%YrFZ(C&q5h"NdPf$ +FeihkEH65IH[C'bo6^I_qKW'crH\'\rHSWmH$OXYGBS0)Fo$4ZFo$4LFTQZ+F7=5MEW9tYDfPbq +s)7mUqJZ=Mr,;LPr,:t?qec@Ls(_XOD>e8ND>S5LD>nAND?"MPD(N@hr*JQj5f=ak3)!nlKdg'mI'H3nF?MK!V>s_o`Fj]p\jmeq>^ +JcC<$JcEXfmf*+^r;??erqcThqY:'arq?6^rq-6^!`iK3raH.@?!:<1=BJX-r^HiVrTsRMs6BUJ +s6'IGroQ*"jQ,@]io/kSi8O2b;ZK_o;>=&b;$Bir<)cdonkoEbqb[>kr_r_m"]8)n;H$Nnk;?0Ym<;0Dj<";\u;,:+h:f'hY9MA#N7/U!_<;fhn(N@hr*JQj5f=ak3)!nlKdg'mI'H3nF?MK!V>s_o`Fj]p\jmeq>^ +JcC<$JcEXfn,E4_r;??erqcThqY:'arq?6^rq-3]"5;\sm/HAQlK8**%cH=*iE08c='4hUlg*j$ +rojLJkNDj,3p#G`j5].XiS`YOhVI#CgY1B7f[na+e^W*tdF$=ecHaYWbK@rJa2Z*;_ns:,^V@Lr +]XtbER[TY4p6bfF!1HrfmPNQ^@Z< +&=JoFI=-?gH?OILDes6(Dfu"Wr`&hrq,[GqrE'&'r`]M/=BSg1r`B_7aN7[tKVl2e\$i`PZETLd +r1j.brhTV:rQ>/aqTf,ep<```"jP67bfe3/b5KNZbkoQ`b4s*YFoQX`GQ2pfH2`-iHiJKmIK+cr +J,Xs'JV&K+K7no3re:T3Ll$tGMuJZJNK0'\OHPcjPa.N"Q^F20S"#t?StMdNUSO]_Vl6SpX0&M- +Yd(L?['mEQ\[oGd^;%J#_SjF5aN2NIbg"G[dF-Lne^rF+g=k? +JcC<$JcEXfn,E4_r;??erqcThqY:'arq?6^rq-3]%&'W%Yd(I:X/MkkVPF-e$;OJs;,ZcIlg*j$ +rojLJkNDj,2ZtD3=qk@R<`Xd"I!TsWEc5`*An5=W>[:ke;ND>eAMD>nAND#eJODQhZsER/i]TS,A]TRJrTPQfOP6FoQX`GQ2pfH2`-iHiJKmIK+crJ,Xs'JV&K+K7no3re:T3 +Ll$tGMuJZJNK0'\OHPcjPa.N"Q^F20S"#t?StMdNUSO]_Vl6SpX0&M-Yd(L?['mEQ\[oGd^;%J# +_SjF5aN2NIbg"G[dF-Lne^rF+g=k? +JcC<$JcEXfn,E4_r;??erqcThqY:'arq?6^rq-3]&6W:I@U`bP>$+g,=B/I+=[2mS#"ItGlg*j$ +rojLJkNDj,2AoY4$#DR/iY^S5!M1l4$#;Z2)I'C0.ee31Gq!G2)I3K1egh@/j;NZ92/8\ +;c?OlrDNVlr)38fr_ibnpJUib"]A8u<)Z]c;?'Pk;#jMn;uKVo;$9]m;H$Nnfs%i\mn50*[!)EAdr_j;k;>sJn;?'Mq;,C'f;#O8i;Yj>l;?0Yl<;0DitQC!u,R[]e;St;UKTqeEZVPgAlWiN8(YHY:;Za@0L\@K2`]Y;.r_SX71`lQ6D +bKS5Vd*^:jeCE1&g"P08h;7&IiSrnYjlY^hl07L!m-O--n*fc9o()DDo`"Lbp@n=\q#C0hqY^6i +r;HTdrdk*#s4[L'~> +JcC<$JcE[gn,E4_r;??erqcThqY:'arq?6^rq-6^rpg9Tm-O-,lK8**%H-4)iS`SJ?!CE4=R,2M +klU)3kPjTEjlHF$1ZIBPi8EMLh;-l@g=k64f@SU(eC;sqdEp4bcHXSVb/q`F`l5p8_SX.)^V7Co +]=PPBRf8`KR/`NPR/`L/EGfW-NeDk3It)'CWi;niS!]P(MM[+>I!KmZJV&N+K8,)8Ll/gWEjM"S +S!SGJK858CqiLftK_gDuLAuu-K`-Pt +K`?c*KE[![JV&H(r."g!JGOfuJ:E(HIf+ZuIXQWlIJ8-hHi8?jHMVpeHN&3gG63#5GlE$eH2`*l +H$FU[qfr'brceHhHN&3iH2rq3(cAs-3PKs-E\O!LT5PR/`Qc +Jp_rmH?j^TD/aE/C2\2m;uK\p$+p2=oMM6=ie]iCQ#='\$rfS['Hp'r1j+a +s/#b;rQ52bc-?.2s3LDcr6GAfr6,)^r6+u]qTAl]q8rYYs)n?brHJ9ds*=Tis*OcnrdFfq!.Xuu +s+(0%rdt6)L&Qf1LPUeDMMqImArVk4OHG]hPE_>tQ^F/.R[]h +['d?P\[oDc^;%J"_SjF5a2lEHbg"GZdF-Lne^rF+g=tE=hV[8MioB+]k2tmll0@U$m-X60n*ol< +o(2JFrq-?dp\4[^s7u]kqtpBjrVcBfJcC<$gAc[~> +JcC<$JcE[gn,E4_r;??erqcThqY:'arq?6^rq-6^rpgGsYd(I:X/VtmVPBsdV$Nll<)ZXk;X3QG +klU)3kPjTEjlHF$1ZIBPi8EMLh;-l@g=k64f@SU(eC;sqdEp4bcHXSVb/q`F`l5p8_SX.)^V7Co +]=PP)K):,uK)U?$JcLB!J0A6)?!M,S?=72M<`ad!H?aRREG]H'A7AnO>$GKHA7T7`rFl4j$X8.( +OaMUnD/aQ?H2DsfHM;aeI!bj=qK`$a!."6^s*4WiH2W!eGQ)d^FTHT*qfMg[qK2:Ns)e9^n8ePK +s)8'YEH#mrDuO_PDuOYODu=SRDZO`om;Df&]7VNJi^PMMR"1I#EpXMZ8V7Q2I!CR/33NRf8fSRK/cTR/<65R/_:.FoQX`GQ2pfH2`-i +HiJKmIK+`rJ,XuuJH1<$K)pXZre:T3Ll$tGMuJZINK9-^OcklkPa.N#R$a;1S"-%@T:hmPUSO`a +Vl?\sXKAY0Yd1UB[C3TU]">Vh^VI\&`5Ta:aND]Mc-FY_daQ^rf@S^0gYCWAhr*JQj5f=ak32'o +lKdg'mI'H3nF?)?oCMVRo`Fj]p\ssfq>^ +JcC<$JcE[gn,E4_r;??erqcThqY:'arq?6^rq-6^rpg%rraH+>>$+g+=B/H$=U/%s77K^8lK\?4 +!pJh1roO7CjSn0oio/kSi8sJj;#jMm;uT\p;$Bcn;H$Lnr`&qtpf.Ap;cfs%i\mnPK0[!)EDer_EJhrD!Jk:/=\_qbd>gs%`Sis%`Ph +!)EJgrD*&^s&&Jcq+q&er)!Dhr)!2d!)WYjr_WVlrDj;Yj8i +:]OAl;Z9Pn;ZBPp:Jamc;>jDi;u]_q;u'Deb0/#RcHjnde'uq"f@em4 +gtgiEi8N\UjQ5Odkiq?slg4!*mdKW6nac8BoCW%T!quB_rqQNhs8)Wirqu`no_sFAJcFI(J,~> +JcC<$JcE^hmf*._r;??erqcThqY:'arq?9_rq-3]rUL`fm-X6-kMtR]iSieUiSWJHgeh6X='5Id +s60LGroO7CjSn0?io0mp0AkXBh;$c=g=b-1f@JL%eC2jnd*L"_c-4ARaiMQC`Pod4_SO%&^:h1k +]",A?Rf8`HR/WElI@lmkMLg/)JV.QGWMQGaR[98!M1pY5I!9gcJc:97KS+o4LmkrgOdWe?dWg1j +KnkZ`OT(=3OT(C@P5C@AOSt1>NW"h6NW4q?Mi*@IM#<&+LA$>sK_pK!LAuu-K`-PtK`6]*KE6^W +rIOls!J,duJHC@OJ,=]mIfOrrIJ8-hHiABmHiA?fH2`-hH2VpiG^"FZHMi'eHN/3iH2;dbH2W!c +Gl`50YL]<21M#iKlr/:`;NfT8"OS=nCPE_;sQ'Rc'qj8%bR$jA%IXQTjH$41CDf0B,DK\tW<;onn +?Y34=^"u-=:\QUaBWbL['mHQ[^NQKYd")$qP=.frlGAebK@uNc-?.2s3LDcr6GAf +r6,,_qoel\qTAl]qoSeYrcS6arHJ9d!."Nhs*Ocnrd=isIt.HJ!J,k%K6)^"Knb>;Ll$tGMi3S"6.BTV8'SUnsrdW2cl!Xfek3Z*UgF[^WfY]=bhl^qmn*`Q#s>aihoQ +cHjnde'uq"f@em4gtgiEi8N\UjQ5Odkiq?slg4!*mdKW6nac8Bo^r.U!quB_rqQNhs8)ZjrVZWm +o_sFAJcFI(J,~> +JcC<$JcE^hmf*._r;??erqcThqY:'arq?9_rq-3]rUL`+Yd(F7Wi)\jV50raVPU&_Ude6\;,[DX +s60LGroO7CjSn0?io0mp0AkXBh;$c=g=b-1f@JL%eC2jnd*L"_c-4ARaiMQC`Pod4_SO%&^:h1k +]",A'K):,uJcLB#K)^E#J21DREGfGu?!q)N=&j`sHZsRPDes&sA78eK>@D#PA7]@`AnPe&NK%k! +M0,G,DJsT?H22gdHM;dcI/eNhH16(YGl`/8rHSn>QD/O4iDZ"AND#S8ODZ+GMD?+VCDYe;HDZ=SP +DZ=YTDYJ)LDY\2NE;XYOE!1)uE,fmqDuanPE;aeUEWC+XDuanUEr0tWFoQR`FoQUdGBeB2H2i3j +Hi8BfIf+WjIf=fsJGt*1H?!nBE,KK,AnP^d@Uj"KrD`brq,[DprE0&%)c9F/;,C+e;Gp=fPa,$N +Fc26=Mi3IMLk^Y3Mti20MuJtBQ^Ic=pR(fF!1NnVr0dVRrL!GJl^7WmrcS6arHJ9d!."Nhs*Ocn +rd=isIt.HJ!J,k%K6)^"Knb>;Ll$tGMi3S"6.BTV8'SUnsrdW2cl! +Xfek3Z*UgF[^WfY]=bhl^qmn*`Q#s>aihoQcHjnde'uq"f@em4gtgiEi8N\UjQ5Odkiq?slg4!* +mdKW6nac8Bo^r.U!quB_rqQNhs8)ZjrVZWmo_sFAJcFI(J,~> +JcC<$JcE^hmf*._r;??erqcThqY:'arq?9_rq-3]rULS0@U`bO=]\X+='/U.>$4s0=Z-1I!(QtP +s60LGroO7CjSn0?io0mp/`5F@h;$c=g=b-1f@JL%eC2jnd*L"_c-4ARaiMQC`Pod4_SO%&^:h1k +]",B>;uT`7.Q]OG0eFn,/MB%>5s@Fp4#o5Y2)?s@0J5!W1(Q2t1c$sG2FUA:2a0Js<)EQl!*&_k +r_`SkpJ^NYrD<_r;cH^p;Y*cb;Ys;k;Z0Pn;?p&q:f1+h;cN`r!*&\m!E2nn;?'Jl;?'Jl;?'Jm +:B45j;>sAj:]O;j;#X>e;#4#l:f1(d:\.E^:]F2e:]=,h:]4#k:JO\^;#F/j;#X8j:B+,i:B+,i +:B"&e:A7Nc:f1'_:]!ug:]!ug:]+&b;>sAi:]OAj;#a>f;#aAq:JO\];#=,f;#O8j;Ya2i:]OAl +;Z9Pn;?0Pm:]F8k;$'Qk;>jDj;u]_q;u'De5MJ#u +Q^F//S"#t?StMdNUSO``Vl6VqXKAY/Yd(OA[C3QT]">Vg^VI\&_o9X9aN;WLc-FY_daQ^rf@S^0 +gYCWAhr*JQj5f=ak32'olKdg'mI'H3nF?)?oCV\So`Fj]p\ssfq>^ +JcC<$JcE^hn,E7`r;??erqcThqtU0brq?6^rq-3]r:1$]mI'B*jndsHhqm2FgXt"W>$+j.kih4/ +k5XNCjSn0?io0mp/`5F@h;$c=g=b-1f@JL%eC2jndEg+`c-4ARaiMQD`Pod5_SO%&^:h1l]",BN +Rf8`HQo(.VCndA\Lk0l$Jq@X7W26AaR[91tMhck4H[0d`JV&Q/KnbAi +OSk1LkpnEMYrG5N<5-$O8b4@Onk.FPEM,oQ'IZ$rKdSQQ^@Z<&Xf)VJpVlmH$=FNCiX?,CN%=p%l0>$:i,%p?up>^;dH[^W`S[^; +Ll$tGMi +JcC<$JcE^hn,E7`r;??erqcThqtU0brq?6^rq-3]r:1$]Z*CI4W;`[nV#[CkU^EroUJ=]a;,ZWA +kPjWDjT+B@irS/urnoBchVI#CgY1B7f[na+e^W*tda?IgcHa\YbK@rJaN)9=`5BI.^q[Us]Y(hd +\c.3XJbaorJ2:G3H#db5@9d/K@9.l,H[BsZEc5`,ARo1T>ZtQGA7]@bBP2$mNf@1jI!:9qCi=?: +GC'%2rHeEhs*FZkrd=`mqK_RTs*=Hcs*+HcqK;gZqfMg[piQ.Ns)e9^n8ePK!cW'rrc%jTrc%^P +rbhUOrG_XPn888DDYn;ND#\8OCi0,es)%^Pr,)FLrbVXQrGDIM!,q=DqJZ.Hrb_UO!cMsop2BtK +qJZCQrGVRPs)7pV!-.pUs)IdPrc.pX!-.sV!-.mVr,hm[rcJ0_s)nHfG^014s*=]mI/SKgIf4]k +If4cpJcC<3F)Gr9DJX*$AS#Ia@V&L;<;fhn/8LPUeDMMmFPNK0'\OHG]hPa.N"R$a;1S"-%@T:qsQUnjlcW2ZetXf\e2Z*UdE +[^WfX]=bhl^VRe)`Q#s>aihoQcHjnde'uq"f@em4gtgiEi8N\UjQ5Oekiq?slg4!*mdKW6nac8B +o^qhLp@e7TrqQNhs8)ZjrVZZnoDX=@JcFI(J,~> +JcC<$JcE^hn,E7`r;??erqcThqtU0brq?6^rq-3]r:1-`@U`YI='&L+r`K5)r`T5(#[9M^7R]f1 +ki_s-s5a7Aro4%=iVqaehqm2FgtUQ:g"=p.f%&:"e'cXkcd'h\bfe/NaN2E@`Pf[2_8*h"]tD"h +\[hQ8s&/Ph),qt=3ArZI/1E,%/iGpZ5!;%k3]8oR1GLT_/eTlo1GgpG2)I-J9i3H!4uGu1;"IT` +;>X8e;smQ_;$Bir<)cdoo25Kbqb[>krDW\n#>n;o;,U:j<;okt<;0An;ca8i;>sJg;?'Go;,Uj;j:]XEir_`VlrDW_os&8bnp/Uid&62\+:/Fec;,BkX9M8#N8Q5UfrDi\pr)`i!r)j1f +5X.Iu5lEtR/8LPUeDMMmFPNK0'\OHG]h +Pa.N"R$a;1S"-%@T:qsQUnjlcW2ZetXf\e2Z*UdE[^WfX]=bhl^VRe)`Q#s>aihoQcHjnde'uq" +f@em4gtgiEi8N\UjQ5Oekiq?slg4!*mdKW6nac8Bo^qhLp@e7TrqQNhs8)ZjrVZZnoDX=@JcFI( +J,~> +JcC<$JcEain,E4_r;?BfrVHNhqtU0brq?6^rq-6^r:9jWs6]pQk5FB@iXb)-hqm5Gg=F]saBVkM +=6KSFs5a7Aro4%=iVqahhqm2FgtUQ:g"=p.f%&:"e'cXkd*Bq]bfe2OaN2E@`Pf[2_8*h"]tD"h +\[f5=Rf8`TR/`NKR/WF/Hto7?PDFd>IY)9GXf/%iS=5b,M26q$+p2=]ea-=ieZkJ>0K\\$rfR['Hp?USI[]"/X&YaSs<\b6,o1 +bg$%1!71>brQbMibl#Zab59B]bQ>u3bkoQ`b5B?]ErL.YFT6L`G5ZXbGlN'fH3/G@I/\PDIXcit +J:W9'K7ei1Knb>;Ll$tGMi1:Za@0M +\@K5a]t_=u_Sa@3a2lBGbg"GZdF-Lne^rF+g=tE=hV[8MioB+]k3(sml0@U$mI'H3nF5u=o(2MG +p%A%P!;HHes7u]kr;6KkrVcBfJcC<$g&HR~> +JcC<$JcEain,E4_r;?BfrVHNhqtU0brq?6^rq-6^r:9jW"0o&2WVrapV%9H"UnjiaVPKrXRo3-] +;CdIH$4:LDJ<]oA7/\I>@V2SAnM$T%VTI7NH00!Gd;.' +E--;Mp3Zaar-SEh!.4]ms*Oclr-A-`!."?as*=Hcs*+HcqK;gZqfMg[piQ.Ns)e9^n8ePK!cW'r +rc%jTs)@dPrbhUOrG_aS!cDppmV_o=s(q^N!GlWOD#\ANDZ"AND#\>PDZ+GMDZ=YDDYe;IDZ4MO +DZ=YTDYJ)LDY\2NE;XYOE!(#tE,kbo!-.pU!-.sVrc.mW!-/!W!-.mV!-A'[rcS0]s)n?bs*4He +s*=]mI/SKmIK4fpIf4]jIf=fsJGt,uJcL&oE!pQ"Bk:me@Uiq\<)ifrq,[GqrE/o!s%rbmrDESk +s-3X`BR]r?s,6o7",M\dI//X"Mu8h?QN!9OQhZsDRJiWRRfAfRR/**JQiNKEQiM1+F8^4\FoQX` +GQ2pfH2W$jH[L5?I=H]qIt3'#JV&N,KS5&6L51SAM2I4MN/`jYO-#NfPE_>uQ^F//S"#t?T:hmP +USO`aVl?\sXKAY0Z*L^C[^WcW]=bhl^VRe)`Pom=aihoQcHjnde'uq"f@em4gtgiEi8N\UjQ5Oe +kiq?slg4$,n*fc8nac8Bo^qhLp@\L\rV6Egs8)Zjrqu`no_sFAJcFF'J,~> +JcC<$JcEain,E4_r;?BfrVHNhqtU0brq?6^rq-6^r:9jW"CbbC=BPQ+s&f>*r`KV4>?kE:>$49_ +7RcM>k5XNCjSn0?io0mp0&POAh;$c=g=b-1f@JL%eC2jndEp1ac-4ASaiMQD`Pod5_SO%&^:h1l +]",A]r)?_1_Vc(2)@*a:GG$u7Slr[ +:fL=j;cEHhrDEAgq,?ra!)renr_Wes<)cdoo25Kbr)*JlrDW\ns%rqr;,U:j<;okt<;0An<)WWk +r_WSks%r\ls%r_k!)WYlr_NPjs%iVjr_`GeqbdAis&&;_r_NPhqbR2d!)NJe!)NSjr)*Ghs%`Ph +!)EMh!)EJgrD*)_!`2`jpJ:Z_r_NDfs%iPhq,.,erD3Jkr)!DhqG7An:esh^:f.!crD;Ll$tGMi1:Za@0M\@K5a]t_=u +_Sa@3a2lBGbg"GZdF-Lne^rF+g=tE=hV[8MioB+]k3(sml0@U$mI'H3nF5u=o(2MGp%A%P!;HHe +s7u]kr;6KkrVcBfJcC<$g&HR~> +JcC<$JcEain,E7`r;?BfrVHNhqtU0brq?6^s7H<^r:9jWs6pB]kN1jgkN(X_iSXXk'\qBkd)sAD +='A^-=Q\`+jQ#:[io0mp1uI0Gh;$c=g=b-1f@JL%eC2jndEp1ac-4ASaiMQD`l5m6_SO%&^:h1l +]",A][[NYQR$di=pm7=NeW"6IXu*FX/W"lSXGe,MMR">H?aX`K7\c/K8##8LPrc]\"'(i +H$k*pLQ.FZrfR&=r/^c;r/^c;rfR2Cr/gu@rf@&=!0-r9qi(`;Mi*@Ir.k3)p4`9prIt$$s+UK+ +rIaitre:B*!J?"&JbjopJcC6#J,=]mIg(:LI=-HkpjE*grHnZnH@#C4s*FZiqf`*eH@#O8r-JBf +!."HdrH\?dr-@s]s*Ocnpj;g_s*=EdrcnNjHiA8r6,,_qoeu_s2tDdqo\u^rlP1[s)S-\r,hs]s*"?bs*4Qhrd+Tk!.=co +s*artrd]'@JqJ]/KS>/8LPUeDMMmFPNK0']OcklkQ'IZ%R$jD4S=Z=ETqS6WV5C/hWiE/&Y->.9 +Za@0M\@K5a]tV7t_Sa@3a2lBGbg"GZdF-Lne^rF+g=tE=hV[8MioB+]k3(sml0@X%mI'H3nF?&> +o(2MQp&F^cp\jmeq>^ +JcC<$JcEain,E7`r;?BfrVHNhqtU0brq?6^s7H<^r:9jWs6q57Wi2kqWhuViV50o`VPg;dTq.X= +:/Xqd;Wd*%jQ#:[io0mp0AkXBh;$c=g=b-1f@JL%eC2jndEp1ac-4ASaiMQD`l5m6_SO%&^:h1l +]",A][ePFRK)1$BJ6l5tE+rfg@:3ME=+YmJH?XFMD.mQn@pN;D@Us"\A7]EQBF\a9=+bdAKkbFD +F*;hUI.hpcHMi-gH3ASBI!^5>HMr-cGlN'bGlN'cGlN!eG5?@\F8U.ZFng(NFT?O_F7=5MEOD>A&MD/T2e!,VXMs)%^Ns)%aQr,)FLrbVXQrGDIM +!,q=DqJZ.Hrb_UO!cMsoq/6:QDuOYNDuXeSDuFYSDuXbVEV=AOEW0qUEW0tYEW'kRErU4YFT6L] +FT6IcG'A1UrH\Eh!dfJV&N,KS5&6L51SAM2I4MN/`jYOHG]h +PEhE!Q^F20S"-(AT:qsRUnsrdW2cl!Xfen4ZEppH\%&u\]Y2%o_8=+/`Q-'AbKS5VcdC1ieCE1& +g"P39h;7&IiSrnYjlYail07L"m-X60n*ol;o()DErq6 +JcC<$JcEain,E7`r;?BfrVHNhqtU0brq?6^s7H<^r:9jWs6p4u>$5$5>[%&.$!LP`5BI.^q[Us]Y(hd +\[]*I;u9Ji;uKZ;-nmV=1G:4//1rk>5X7Ot4$#>Z2`*6C0.nk41GUdCr\Op=1c8#Z2a0)k;#X;o +<)QXor_rVjrDE;eqG[)cs&8kor_Wer<)cdoo25HarDESmrDW\ns%s)!;,U:j<)cjt<;0An<)WWk +rD3Jkr_WSks%r_k!)WYlr_NPjs%iYkr_`GeqGI8hs&&;_s%iYiqbR2ds%iMe!`)Whr)!Gjr_NPh +s%iYis%`VirD3Aep.k`d;,I!_qb[8fr)!Dhr)!2d!`2ZgrDi<<#kt<)``prDNqu:f0ta;,C$e +9*7dZ6WF"aq,[GqrE/hts$-KJr]pch<'s5O:esmd;$9fp;H$3`=oD=tqu +<)`co!)rhqr`/bnr`/tt!*/nqrDW`9s)S-\r,hs]s*"?bs*4Qhrd+Tk!.=cos*artrd]'@JqJ]/ +KS>/8LPUeDMMmFPNK0']OcklkQ'IZ%R$jD4S=Z=ETqS6WV5C/hWiE/&Y->.9Za@0M\@K5a]tV7t +_Sa@3a2lBGbg"GZdF-Lne^rF+g=tE=hV[8MioB+]k3(sml0@X%mI'H3nF?&>o(2MQp&F^cp\jme +q>^ +JcC<$JcEdjn,E4_rVZKgrVHNhqtU0brq?6^s7H<^r:9mXrpUorl/q3nl0%'dio/hQhqd)>e'6"O +^:LdZ>$+j.ro=%<38rfRhr!;Hh;$c=g=b-1f@JL%eC2jndEp4bc-4ASaiMQD`l5m6_SO%&^V.:m +]",A][^MWmR@*o=qj@DM+FSWMR?NYcIXcftBP+3?VP'HGR#[,[L4OYqGCY6tK7s5Y%Z-"R]Si#e +No521K8>DHrf[8CqN1W9s,d8A!0I&rK`-W" +LAuu,K`6VuK`6]*KE6^WrIP!!!.XrtqgecuJ,=]mIg(:LI=-Hkpj<'grI"Wls*FNerd+Ti!-nEc +"*f*;HMr-fH2r6cGl;peGl2jZH2r$+j-=ie[%O0H($\$rfR['Hp?U].(gV>J=5aT0K] +b5fc_c2c2ad/;2jcHQ40s2t8_rQP&[!m8X,rGhjXs)\*[s)n?brHJ9d!."Nh!df.9Za@0L\@K2` +]tV7t_Sa@3a2lBGbg"GZdF-Lne^rF+g=tE=hVd>Nj5]4^k3(sml0I^&mI'H3nF?MK!V>s_p&F^c +p\jmeq>^ +JcC<$JcEdjn,E4_rVZKgrVHNhqtU0brq?6^s7H<^r:9mXrpU6_XJr5"XJr%nVZ*D&Vl6MiU7[sC +QB[S3;c-Ciro=%<1u[BNhr!;Hh;$c=g=b-1f@JL%eC2jndEp4bc-4ASaiMQD`l5m6_SO%&^V.:m +]",A][^Ps^!.t-"s*uk0>ubl^Bk(FV?t*5=IX?BbF`MJ(D +Ci468GC0=:o6UXeH[C'bHi/3gHiA?iH2;dbH2;dcH2;dcGQ)daFTQZ-FoHI[FT-FXFS'\UFT$:N +ErU+_E,TZ6DfG\os)@mS!H;uUDZ"GNE;jbWDJsIiD?+PLD?4TlqJ?@OCMRa'rG;LNrGMOMrbVFJ +r,2OQmr%u?q/61KrGMXRs).XN")r0rDYe;OE;OSQE;jeHE;sqWE;jkVEWC+XDuanUErU4YFT-F\ +FT6L`GQ2peH2`*kH[L5>I/n`qIK+cnIJSBpIsultrIOlus+:f'E,]`6Chm]qAn>O`AnM$Bq,[Gq +rE/es!Er=u;?'JmPmpr;LQ.:PMi3IMLk^Y3reg]5rK[DIs-3SMrKmSOpmCoG!1NnVr0mYRqj@8I +rL!8ErGhjXs)\*[s)n?brHJ9d!."Nh!df.9Za@0L\@K2`]tV7t_Sa@3a2lBGbg"GZdF-Lne^rF+ +g=tE=hVd>Nj5]4^k3(sml0I^&mI'H3nF?MK!V>s_p&F^cp\jmeq>^ +JcC<$JcEdjn,E4_rVZKgrVHNhqtU0brq?6^s7H<^r:9mXrpU-\>?Y69?X3M3!a8i7ra#V1>5hY. +=@>SI77R::s5Gloi8EMMhVI#CgY1B7f[na+e^W*tda?Ihcd'eZbKJ#KaN)<>`5BI.^q[Xt]Y(hd +\[])Vr_r\lr_r_o(apgd2Dd-@.kE5(3&Wuc4Ztkf2`EWN1G\q^(,I^'1Gh!G1c7-b:c:I$7p8_d +;,U@lr`&kqs&/korDNSkoht]dqGI;lr_i_or_i_m"B&2u;c<0`rDNVl!)i_nrDEu":f1+g;cH^r +l;#a;k;#X>k:]F8k:]F8j;>k:A[id:&n)e +:B+,i;#F/j;#X8j:B+)i:B"#h:Amue:A7Nc:f1*a:]!uf:]!ug:]4,b;>sAj;#aD_;#a8j:]4,e +;>sDk;>sJj;?'Mp;,I6h!)ibm!E)bi:]F8k;>jDf;ZKer;ta5h<;]Yr<)Zcn;[uZ$;,C(d;G0\V +91hiN6iL*]!N!Or]pch<(';Q:espe;$9co;H$3b=o21rM2@+JN/WdXO-#KePE_>uQ^F20S"-%@T:hmPUnjlcW2cl!Xfen4ZEppH[^`lZ]Y2%o_8=+/ +`Q-'AbKS5VcdC1ieCE1&g"P39h;7)JiT&tZjlYail07O#m-X60n*olHncA@Srq6 +JcC<$JcEdjnG`=`rVZKgrVHNhqtU0brq?9_rq-6^r:9jWs7$!Us6(;N;AM9N/EIKr.k3)p4`9prIt$$s+UH*re'ru +re:B*!/(3#s*t*!rIFlu"G22UIt.?ErI=fq!e#HEpNusfrHnTlrd+Eds*FZiqf`*dH$]F7r-AEi +G^912r-A9dr-@s]s*Ocnqg/BjH[GR7s*=EdrcnNjHiA?iHiSTlI/\O!I!pElIXcitqLABms*sut +oR[$ordt3(r.Y0*s+gT0",`"pN;\b7O84q8Op.&6Q'@Q!rg*SL#*tUAQ^F20rgE_R&Y"`-I!U-a +GB.M;Dej!'G#_Q<5hS8=ie[,QFF<2\$rfR['Hp?USIdaqSrZYaiaP)!6k;b!71Ac +r6GDhbl5cfb0.rMqof#`pWET[ao$/XErU4YFT6L`G5c^cGlN'gH3/G@I/\NpIXh?ICk71jK7nr4 +L5(J>M2I4MN/`jYO-,TgPEhE!R$a;2S"6.CTV8*UUo(&gWN*#$Y-5(8Za@0L\@K2`]tV7t_Sa@3 +a2lBGbg"G[dF-Lne^rF+g=tE=hVd>Nj5]4_k3(smlKdg'mI'H3nF?MK!V>s_o`Fj]p\jmeq>^ +JcC<$JcEdjnG`=`rVZKgrVHNhqtU0brq?9_rq-6^r:9jWs7$!U"KSW,XJl&o8uJYfVkg&YR@';( +OcYW%;c-HQio/kSi8@V2RAS#OfBP1tPrgWhSs-`bO!1*PLrg,7L51SAMMmFPNK0'\OcklkQ'IZ&R$jG5SXuIHTq\?Y +VPgAlWiN8)YHY==['mEQ\[oGe^;%M$_o9U8aN;WLc-F\`daQ^rf@S^0gYCWAi8ESSj5f@bkNM0q +lg4!*mdKW6nc&([oCW%T!quB_rV6Egs8)Zjrqu`no_sFAJcFF'J,~> +JcC<$JcEdjnG`=`rVZKgrVHNhqtU0brq?9_rq-6^r:9jWs7$!U"C,5??X*J3%U*+C?XR8J>Zt<6 +=BAO(r^Ah:j5T%Vi8EMLhVI#CgY1B7f[na+e^W*tda?Ihcd'eZbKJ&LaN)<>`5BI.^q[Xt]Y(ke +\[])V[Jj,&;ZB\m<#d;90/bXA0.SS*0/b^Q5l;#a;k;#X>k:]F8k:]F8j;>h;#*ri:esmc:]OA_:]jKg:J^pc +qbdAirDEPlr)*Gk!Du\h;#jGi:BjWk:Jakb;>jDc;tX/i<;BGm<;KMo<)``l$WBnr9hS2Q91hTP +; +Ll%"IN/WaVO,oEdP*;/rQC+&-S"#t?T:hmPUnjlcW2ZetXfek3ZEppH[^`lZ]Y2%o_8=+/`Q-'A +bKS5Vd*^:jeCE1&g"P39h;7)JiT&tZk2tjjl0@U$m-X60n*olHncA@Srq-?dp\4X]s7u]kr;6Kk +rVcBfJcC<$g&HR~> +JcC<$JcEgkn,E7`r;?BfrqcThqtU3crq?9_rq-6^r:9jWs7$!U=RPPClfdEiio9"WiSNDDe'5tM +^:C\ZZa$^:>$+j.iS`YOhVR)EgtUQ:g"=p.f%&:"e'cXkd*L"^bfe2PaN2EA`Pf[2_SEq$]tD"i +\[f5Z[^EK1R@*lUn3s@P)bEUJphlhG_1O#KnG,6LPLc"Ocm\C +h0OL%LP_+TOckn*Ont1;O8b79O8=t7OT:LAO8k4?NW"h4N,5re:B,s+gW1s,$l9N/[aq!07&>!0I#=rfRAGP*;+.Pl6jOPa.Q#Q^=*;RJrZS +Rh(j:I!g6aG]dnADe`s"QWcs3LDcr6GAfrQG,]nB:fMr,M^Vs)\-\s)n?brHJ9d!."Qis*F`nrd=frJ,Xt;JV&N, +KS>/8LPUeDMMmFPNK9-^OckomQ'Rc(R@9V8St;UKU8+N\Vl-MoX0&M-Yd(OA[C3TU]"G_j^VRe) +`Pom=aihoQcHstee'uq"f\,!5h;-rGi8WeWjQ>UfkiqBum-O--n*fc9o()DDo`"Lbp@n=\q#C0i +qYU0hr;HTdrdk*#s4RF&~> +JcC<$JcEgkn,E7`r;?BfrqcThqtU3crq?9_rq-6^r:9jWs7$!U"n&LrY,eK"VG*qfWi;tpUS"$C +Q^!VoO,f3Z;Gg:hiS`YOhVR)EgtUQ:g"=p.f%&:"e'cXkd*L"^bfe2PaN2EA`Pf[2_SEq$]tD"i +\[f5Z[^EL>uu8kCh7$[?XdJGRM!,2@E$ttW;EfP:E +Ci=<8GC0:9p3Zacr-S9dr-SHir-A-`rH[pXrc\6_rcJ-\r,hp\piQ.N!-J0\noF_L")r0sE;XYS +E;a\VE,T[nDZ"GOE;jeUD?+VOD?+PLDYS)KD#\8OCi0,es)%aQr,)FLqJH.Js)7@DqJZ1Irb_UO +s)7pTq/6@SDf0IhDuXeRDuO_TDuO_UEVOMOE<'tUEW:%ZEW0nWEVa_UF8U+[Fo-:\FoHUbGR&M? +H?jg`H[PX;"+GZHI/SKgIK=qKrIOitrIYW3Ec>u9DJa-$An>L`@XhDR/8LPUeDMMmFPNK9-^OckomQ'Rc(R@9V8St;UK +U8+N\Vl-MoX0&M-Yd(OA[C3TU]"G_j^VRe)`Pom=aihoQcHstee'uq"f\,!5h;-rGi8WeWjQ>Uf +kiqBum-O--n*fc9o()DDo`"Lbp@n=\q#C0iqYU0hr;HTdrdk*#s4RF&~> +JcC<$JcEgkn,E7`r;?BfrqcThqtU3crq?9_rq-6^r:9jWs7$!U"R]W*@:&n89Nte/?t!JO?<^T: +=]\X(`5BI/^q[Xt]Y(ke +\[],W[C#p3r_i_oqc"C\0fV'I0.\P'/M8n<5sILo4$#8Y1c-p?r\"4+">hnk1Go(g#Z!?A5XnpQ +;GmElrD`\ns&/emr)*Mlohkcgr_rkrqGR8j!)ibo!)ien!)iep!)i_ls&/Sgr_`ep;H!EkrDEkt +:f1+g;c?Zf<sDl;>sDl:B45j;>sAk;#a>k;#X>e;#4&h:]aKj:\.E_:]=,e +:]4#g:]!lg:Jamc;#jGl:]F2i:]F2i:B4/g:]4&^:]F;e:\moe:]!ug:]4,b;>sAj;#aD_;#X8g +;#=)i;#F2j;Z'Dj;?0Ph;#jGf:]=2j;>jDd;ZKei@c`8kDWL; +Ll$tGMi +JcC<$JcEgknG`@ar;?BfrqcThr:p9crq?9_rq-6^r:9mXs7#sTs6_&tmd'&sj5]4\io&_Lf$VUX +^Ugk\Za$^;XfSR+=BOM=hYu=cgtUQ:g"=p.f%&:"e'cXkd*L"_bfe2PaiMNB`Pf[2_SEq$^:_+j +]",>[[^EKKR$dQ5s(a6VQ]?iMIsur`Bp,KqURms@Oc,'PJUD`fItE6+L5:S=M2SudZ]q&ZGC"dn +M2hIrs-!ADpQ5?7rfHo9q2kK9!0I/?s,I)=r/CN4"H87sMMV.breC<(!/1<)pk8X#pP/^%re19' +pOrR#re(9(rIOru!.Xuuqgeg!It.?ErI=ir"+>QFIJ8*hHiAElHN8BfH2i3jGlW*eG6<)8H@#R9 +r-A?gq0;g_rcn?dom6Xbrd=]lrd+Tkq0N'dqKi*c!IB+lHMr3kIJ\EkIK"TqI=?\FJGOcgJG"Kn +K)^H-KS>,5KS>-ZLB!#9Ll%"HMi6%h*eL2`ra?(b5BE_bko]cch>``cN)5gbP]NQbPuM[E;X_UErL.YFT6L`G5c^cGQ<$gHN/
  • +JcC<$JcEgknG`@ar;?BfrqcThr:p9crq?9_rq-6^r:9mXs7#sTs6^0[Ycb"(VPgDmri-^4V4sNL +R$EhrO,f3ZN/NTm;,Z?0hYu=agtUQ:g"=p.f%&:"e'cXkd*L"_bfe2PaiMNB`Pf[2_SEq$^:_+j +]",>[[^EKKqLSKns'IC#E,&oj@:*GF=)i_C_q,[GqrE/htr*',)r_`\ls-3V! +J,YE:N/NUOMMR"AI!gj9PEc!1rfdGKQh-U@R/i]TS,A]TRJN;Ll$tGMihr*GPj5]7`k3)!n +lKdg'mI'H3nF?)?oCV\So`Fj]p\ssfq>^s+14's*t~> +JcC<$JcEgknG`@ar;?BfrqcThr:p9crq?9_rq-6^r:9mXs7#sTs6^!V@UWO@=V4kD?=75O@:3AF +>$+j,[[^EKK;cEZnrDWVn)FHqQ2)-d9.kE842EO2h4Zkbd2`a>l;tj2i;uTbm;YX/j;Z9Mn;Z9Sp;Z'Dk;YX,d;Z'Jl;Z9Pm;?9]q +oMkrl;ck:]F8k:]F8j;>k:A[id:&n)d +:'+3f;#F/j;#X8j:B+)i:AI]a:A7Nc:f1'a:\moe:]+&h:]+&b;>sAi:]OA_;#X8f;"[Zc;Z'Dj +;YX)h;#3rj:/=Y^;#X>j;Z'Gs;H$Il;cNBh!*&Jes&Aqs!E)_l:^9ci9hS2P9254_rE&r"pf[Mu +s'#Lg5lO(L<;Ll$tG +Mihr*GPj5]7`k3)!nlKdg'mI'H3nF?)?oCV\So`Fj]p\ssfq>^ +s+14's*t~> +JcC<$JcEjln,E7`r;?EgrVHNhqtU0bs7ZB`rq-6^r:9mXs7#sTs6fmR(?suAjQ>OaiSiYHe'#bH +]XG2QZ*1@6ri61$>$+j.rnT?bgY1B7f[na+e^W*tda?Ihcd'h[bKJ&MaN)<>`P]R0_8!b!]tCtg +\[],W[C!9GR$dW7rbMOK/89fdIXZi\Br\21Tq.R;PDtq2kW=!0[>D!0[;Es-3PKs-3PKs-``cN)5gbP]NRb5cGZDuXeREW:(ZF8^4\FoQXaGQ2pfH2`*jH[Pg@!IfOtJ9-9n +K7ei2L5(J>M2I4MN/`mZOHG]iPa.Q%R$jG5SXuIHTq\?ZVPgAmX/rG,Yd(O@[C3TU]"G\i^VRe) +`Pom=b0/#ScHsteeC<($f\,!5h;-uHiSrnYjlY^hl07L!m-O--n*fc9o()DEo_%nNp@nO\s7u]k +r;6KkrVcBfJcC<$f`-I~> +JcC<$JcEjln,E7`r;?EgrVHNhqtU0bs7ZB`rq-6^r:9mXs7#sTs6fpS'X4^=VPpMpX/`5$Vk]lR +R?j%uNfO*urego:;Gg:hrnT9`gY1B7f[na+e^W*tda?Ihcd'h[bKJ&MaN)<>`P]R0_8!b!]tCtg +\[],W[C!9Gr.4]p!a]5@r`oM6ra-FM<`ss%H['^UEc,W'ARf"O>@V/UAS1pS%;9I9H#epeX_hur +FEi--I.r!dI/J?fHMi-gHN&0jG^'(1rH\!Z"F569GBWq-s)e0[rcJ*]pN6(N"E\^*F*$nmrc&9a +DJsK4Df0K3E,bbo!H;uTDZ"GOE;jbWDJsIiD?+PMDZ=PRDYe2QChmg&D>e;ND>nGMD>nAJD>nGP +DsqT?Du";MD>eAPDuX_NDZarsDJo;hs)@jRrc%jTrc%gUr,;[VE:n5LDuanSErL.ZFT6L[FT6Oa +GQ2pfHN&0jH@,I8!e#HErd=]npjW6m!.b'"r.=`s%toIRE,]`5D/*ZoB4PL_B)>X-=8c7r=o;J% +>6%P";#cd]D2%qJs,.5AM26n@I!h-APa)*2rfdGKQh-U@R/i]TS,A]TRJW?QQ^3s9QiM2I4MN/`mZOHG]iPa.Q% +R$jG5SXuIHTq\?ZVPgAmX/rG,Yd(O@[C3TU]"G\i^VRe)`Pom=b0/#ScHsteeC<($f\,!5h;-uH +iSrnYjlY^hl07L!m-O--n*fc9o()DEo_%nNp@nO\s7u]kr;6KkrVcBfJcC<$f`-I~> +JcC<$JcEjln,E7`r;?EgrVHNhqtU0bs7ZB`rq-6^r:9mXs7#sTs6fpS&n50N=]o!8?XR>S@UWPI +>?P$.r)EVpr^?fVrnTBcgY1B7f[na+e^W*tda?Ihcd'h[bKJ&MaN)<>`P]R0_8!b!]tCtg\[],W +[C!9G;c?Tm;uBVo74q%s6n^&@/1rk?5a>j;uT\o;tO&i<:Wue<<#r2<)lq!;bp4f:fC7f9h\5Q8k;>H5_\*5lX.M<<5ZdrDJV&N,KS>/8LPUeEMihr*JQj5f=ak32'olKdg'mI'H3nF?)?oCV\Jp%J+RrV6Egs8)Zjrqu`no_sFAJcFC& +J,~> +JcC<$JcEjlnG`=`rVZKgrqcWiqtU0bs7ZB`rq-6^r:9mXs7$!UrpKgRs6LKajlP[fjl>@Ygss]k +_S*FcZE^U:Y5YL%WB$oS=]ee^gtUQ:g"=p.f%&:"e'cXkd*L"_bfe2PaiMNB`Poa3_SO"%^:h1k +]",>[[^EKKZE]dapm:tq05>38BP(k*JnJbsW2?8WR[B+pKSY/)H?OpmKS5&7KnkMB]W@OS=h3OT1I@OT(=@NrG%;N;JS7N;e_9M2;(brJ('#q1S^#pP/^%re16& +pk8[$re(E+JUi<&qgeWr"G22TJ:IEErI=ir"+>QFIJA0iHi8?lHiJEgH2i3iH2MmdGlN*hH2`-i +HN8BfGl2jcGl;p[H2rcr6GAfrQG&[p<3DPrbqdTr,MaWs)\-\s)n?brc\EgH$TC8!IK4nI;s^cJ:N3& +K7ei2L5(J>M2@+JN/`jYOHG]iPa.Q$R$jG5SXuIHTq\?YVPgAmX/rG,Yd(OA[C3TU]"G_j^VRe) +`Q#s>b0/#ScHsteeC<($f\5'7h;7&IiSrnYjlYail07L!m-X60n*ol;o()DErq6 +JcC<$JcEjlnG`=`rVZKgrqcWiqtU0bs7ZB`rq-6^r:9mXs7$!UrpKgRs6KoiW2ZesXT#7,WhlAY +R?s,!NfO*urepc52Mk@0;Vg-_g=k64f@SU(eC;sqdF$=ecHaYWbK@rJa2Z*;_ns:,^V@Lr]Xtbc +\@8oS['R'Crdjlqs'Gb4rEU:G>@Cu@Ji!,_OL!Gu`OD?"GPCB86grG;LNrbhUMs(qOK +rGMUQmr%u?q/61KrGD[TDJo8gs)A!Uq/67PqeuIQrbqdTrGh^Ro5XbK!-.pW!c`7$rcA'\s)n3\ +rc\`G6M[G>uLk^Y3I$9bYPl-gGPQ@&9nsK/8LPUeDMMmFQNfT9a +P*;,qQC!u,S"#t?T:hmPUnjlcW2co"Xfnt6Za@-K\@K2`]tV7t_Sa@4a2lEHbg+M\dF-Oof%8R. +g>(N@hr*JQj5f=akNM0plKdg(mdKW6naZ2@oCW%Ts7QHerV6Egs8)Zjrqu`no_sFAJcFC&J,~> +JcC<$JcEjlnG`=`rVZKgrqcWiqtU0bs7ZB`rq-6^r:9mXs7$!UrpKgRs6LJ*=]o!8?XR>SA7AkM +>?Y-/<)Z^p<;]`T<)Z4T7bukSg=k64f@SU(eC;sqdF$=ecHaYWbK@rJa2Z*;_ns:,^V@Lr]Xtbc +\@8oS['R'Cr)X8k;Z]io;>O/j;uT_r;u'>f;uTYq;,[Bl!)i_lrDNDfqbmAkr)3Plr_`er +<)iNj!`W)rrDsDl:B45j;>s>k;#X5j;#X>d;#4#k:f1(co2,E^s%`Ger_5VV)>R!GZ5ZLfV:]4,h;$g,t;,U"Y;c6Omq,I>nr)ESor_ierr)Wes##nN!;H$OnrD`es +!*&qrrD`brs&AqqrGMUQrc%dTs)S-\rH/'^s*"Bc!dK!9rd"TlI/\P6IXcluJV&N,KS>/8LPUeD +MMmFQNfT9aP*;,qQC!u,S"#t?T:hmPUnjlcW2co"Xfnt6Za@-K\@K2`]tV7t_Sa@4a2lEHbg+M\ +dF-Oof%8R.g>(N@hr*JQj5f=akNM0plKdg(mdKW6naZ2@oCW%Ts7QHerV6Egs8)Zjrqu`no_sFA +JcFC&J,~> +JcC<$JcEjlnG`@ar;?EgrVHNhr:p9crq?<`rq-6^r:9mXs7$!Us6fpSrTkTgk3(mhjQ,=Wf[7gY +^:1MVZ*:F7XK/D%WMl\jUnmuls4T0[f[na+e^W*tda?Ihcd'h[bKJ&MaN)<>`P]R0_8!b!]tCtg +\[],W[C!9GZ*9U_qNh2JrbF*#Bk_6nAn>RcAZDZ)TUD47NJiODIscNcJ:iK.KnbANrY4=NW4t7N<"q:MZSclM#E,-LA-DtK`6]!LAuu, +K`-Q!K`6])KEQmXJ:W:KJGk$%Jq8H&J,4WmJ,as"I=-Hkpj<'grI"Wls*FNes*FZirHJ9d"F5<> +H$T@7!df6=q0;g_rcn?dom-Ubrd=]lrH\Hjpj2scqKi-d"aYNBH?sr;HiSTlI/\QnHie_FJ,Fip +J+eBoIt3(CJc13%KSBAXs+UK-s+gW2s,$i8N;eh:NrP.@OH9:#qiUi?s-*AFs-crQbMibl,`[b5'6YDZ4SRE;X_UErU4ZFT6L`G5c^cGQ<$gH3&A?rdAR2 +It3'#JqJ]/Knb>;Ll%"IN/WdXO-#NfPEhE"R$jD4S=Z=FTq\?YVPgAmWiW>+Yd(O@[C3TU]"G_j +^VRe)`Q#s>b0/#Scd:(feCE.%f\5'7h;7&IiSrnYjlYail07O#m-X60n*olHncA@Srq-?dp\4X] +!;ZWjr;6KkrVcBfJcC<$f`-I~> +JcC<$JcEjlnG`@ar;?EgrVHNhr:p9crq?<`rq-6^r:9mXs7$!Us6fpSrTk,rWN3)$X/i>&VkKZM +Q]mPmNrG%:MuSYpM26qB;,L6Fg=b-1f@JL%eC2jndEp4bcHOJTb/q`F`l5p7_SX.(^V7Co]=PP_ +\$i]OZa-j?JV!WIs'Gb4rE]G-(L:6K>CV$GG]\"HCM79i@:*;FA7T7`Ac??BBF8ZuM0#V4D/jZA +HhMj]Hi8?iHN8BjH2i3gHi/3iGlW*fGQ2pdH1Q:\Gli57GPu[`FT$:[FT$@VFS0bZFE;JDF7OAN +E<0uqrGMdUDf9UnDuXbVDuFSNDuFYSDZXfpDt.]GD/T5fs(q^Ns)%^Ns)%aQr,)FLqJH4LrGV1C +qJZ1Irb_UOs)7pTq/6@SDf0IhDZFbRDuO_TDuO_REVseLE<1#urGVaVqf2gZEcQ5BrcJ-^qfMj] +rc\EgH$]I8s*F]l"akZEH[L2;I/\QgIfFrsJc:8sKD^B4Km[lZDfBQ/BP(gd@q're5_\'>lRY#PlQ%+NW4nAMM[.DL4"B4rfm>GrfdDKnX03A!1NnVrL3bSqj7GOQBqK9rg/8LPUeEMi +JcC<$JcEjlnG`@ar;?EgrVHNhr:p9crq?<`rq-6^r:9mXs7$!Us6fpSrTk5%=^56>?t*_Z@piSI +>$"a(;c?Xpr)GjY;c?Xp77Kc#g=b-1f@JL%eC2jndEp4bcHOJTb/q`F`l5p7_SX.(^V7Co]=PP_ +\$i]OZa-j?;cH[oqc*Sa*CN7`6UX:.6UO1/5sILo4?>G\2Dd'@0.nk41,Llf2#fE@1bLpU7oW;^ +:fC7jp/D#jqbmAiqbmGm!)ibmr)3Pns&8tspepufr)3Mm!)i\k"&`&q;Ya2e;Z0Pl;ZBVn;?Bcr +<:j/k;ck:B45j:B45j;>3oa;?'Jm;#jD`;#X8j:Adoe:B+,e +:'+3f;#F/j;#X8j:B+)i:AI]a:A7Nc:f1'c:\did:]!ug:]4,c;$'Qi:]4)i;=RK^:]!u^;#jGi +;>jDl;>a5k;,I*bs%`Sir_WVlrDNVnr_i\noi1uknl,Kd!*0"t!*/qt%9$)#:f:.b:/+AT8kMeV +5_\'>Qd>Xl;ZBVo9)V]a<;onq<;fes<;oer<;]er<;Ll%"I +N/WdXO-#NfPEhE"R$jD4S=Z=FTq\?YVPgAmWiW>+Yd(O@[C3TU]"G_j^VRe)`Q#s>b0/#Scd:(f +eCE.%f\5'7h;7&IiSrnYjlYail07O#m-X60n*olHncA@Srq-?dp\4X]!;ZWjr;6KkrVcBfJcC<$ +f`-I~> +JcC<$JcEjlnc&FarVZKgrqcWiqtU3crq?9_s7H?_r:9mXs7$!Us6fpSrTkNikNM*ljlPR]gX=6_ +^U^bYZEUO8XfJM&WMcShrM0Fgr`Cl,f@SU(eC;sqdF$=ecHa\XbK@rJaMu3<`59C-^q[Us]Xtbc +\@8oS['R*DYcsL^r0RGL"`.siC2%G^AcQEAAg1\oA"8mOP`1EOJphoiGCbC#KnbD=LQ&j0Nm+/a +I=Hp,Nr,";OoLUDOnb%9O8k=9O7JD1O8Ot;N;JS7N;e_:MM[/fL])u)K`Hf*L&$E$L%^9$L&Qc( +KDC3"L&Zf0K7\Z)JV!]Krdk*$"+buQJ,=]nJ,XluI=-J;HiSNlI/eQnHMVpeHN&3gGQ2miH$Xd^ +rHeKj"+#6;H2DjbH2W!cH1cI`HiAEmHi/0iHhi!fH2;jcGl`5(N@hr*JQj5f=akNM0qlg4!*mdKW6nc&([oCW%T +!quB_rqQNhs8)Wirqu`no_sFAJcFC&J,~> +JcC<$JcEjlnc&FarVZKgrqcWiqtU3crq?9_s7H?_r:9mXs7$!Us6fpSrTjRNX8]1/X/rJ*WM5uQ +Q^!SmNrG"[ +[^EKKZa$a=JV!`Ls*k)X?XE_;s'#J/rEBh<>?Z2jEc>`)@q8qP?!ClOrau1D$tj=8EH..kJ8K7H +G'W_-p3ZacrHnQjrd"Niqg89fs*4ThrHJ9drH\!Zs*=Wh!I&_dFoHL]F8g:[Fn^"NFTcf-EcZPVM+:mI;or/L`7#)\7nL5()'rKR5FrfdDKnX03ArL/9Ll$tGN/WaVO-#KePEhE! +R$a>3S=Q7ETq\*Yd(O@[C3TU]"G_j^VRe)`Q#s>b0/#Scd:(geCE.%f\5'7h;7&I +iSrnYjlYail0@U$m-X60n*olHncA@Srq-?dp\4[^s7u]kqtpBjrVcBfJcC<$f`-I~> +JcC<$JcEjlnc&FarVZKgrqcWiqtU3crq?9_s7H?_r:9mXs7$!Us6fpSrTk6a>$P?>?t*_[ARSkL +>$+g);c?Xpr)N_ps&B"u!*&qe0%ee-f%&:"e'cXkd*L"_c-+;QaiMQC`Pod4_SO%&^:h1k]",>[ +[^EKKZa$a=qGdJn*C`Ic6UO7/6:4+,6UaC069@.f2`EQL0eb43/M]*\1_2H#1cA)d4[;S6:Jt"f +;H*6f"B/2r;,R9is&&Yks&8qqr_`Sks&8qss&8_kqc!GkrDN\oqb[Jo;c?RlqGI5i!`MuprDWVl +s&&bns&/nsoMkoj;Z0H#:esk`;,C%b;,L.dr_EMjr_`Yj!)WYj!)WYlpe^fas%ibo:f$[Zr_EMh +qbR2ds%iPfs%iYkr)*Ghs%`Sis%`DdrD*&^s&&Sfq,%&dr)!DhrD<8dr_NMis&&;_r_NGgohb]c +qbd>jr_`\l!)NPiqG7)cs%iYkr_`Vls&8nprDN\qp/M)lo2GE`s&B)#e.XI=6QnIt3'#JqJ]/KnbA= +M2@+KN/`jYOHG]iQ'IZ&R$sM7SXuLJU8+N]Vl6VqXKAY0Z*UdE[^`lZ]Y2%o_8=+/`lH0CbKS8X +d*^=le^i@)g=k?s_o`Fj]p\ssfq>^ +JcC<$JcEmmnc&FarVZKgrqcWir:p9crq?<`rq-6^rUTsXs7$!Us6fpSrTsRM!p]"5roFjRh:9`g +^Ugk\ZE^X;Y,eV&W2HJgrM26EU8"EX=P)-SeC;sqdF$=ecHa\XbK@rJaMu3<`59C-^q[Us]Xtbc +\@8oT['R*DYcsMmQi<9TI;,?gBPD,WAcuXQ@q90MA/gD_L4Xf!H@pg%KnY>;KnkP+Su@S(H[gR# +M3.Rsr/q#BrfQu;n;m.%qiC]8!0$f7!0$o8s,$f4rJ1<*r.P-(re:3%rIss"s+UH*rIap!re:B* +"bVDXJ:W:KJGt-"JcgRSIt.?ErI=fqrdFQhs*O]l!df6>qK`*ercnKgrce?drd"QirHeKj"+#3: +H2DjbH2`'dH1cL`HiJKmHi86jHh_peH2;jdGl`5]FZ +IPVP(>lr)QVZ+('[Ka.HZ`p[0V#J=5`r!gVa8jB\b5oi3qp,2e +p<`fb!RApfb5f]aao'9abKA#Nb5H2SDZ4SSE;X_UErU4ZF96T.G5c]2G^4R\H@(!dI=6QoJ:N3& +K7ei2L5(J>M2I4MNK0']OckomQ'Rf)R[]h +JcC<$JcEmmnc&FarVZKgrqcWir:p9crq?<`rq-6^rUTsXs7$!Us6fpSrTsRM&*g6tX0&S-Whc8V +Q^*\oNrG"[:S5>l._+>[%,0)JWkp@p`PKAn,CaAnPagB4tIkIrqf0DK0`AnpL.X +rI"Qjs*FZird+Efs*F]j!-nHds*4HeoQ^C]s*+QgG5cX`F9Q`-F)uGFr,qaUolUCZF)l>CnoFbM +!cW'qrGMdUDf9UoDuO\UDuFSODuFYPDt@iHDuOYOD?"GPCB86grG;LNrGMRNrbVRN!,hdQrbh[Q +mr&#@q/61KrGMXR!,hUNs)8$XDJo;h!-%gRrc%jTrc%dTr,D@LqeuOTr,VgWrc8![rH/-_FoHL_ +FoQXbGPZUbH3&A=qg86gs*afo!.Ffps*k$!rIOp!qLea"rIt9)$$L<,DJj6)An>ZTA,p3>=8c7s +=oDP%>PVP(>lp9sJc(N-M[#&qLk^Y3I/T<.Q2QpIQLU@?R/i]RS,SlVRJW?PQ^7Q9"IPOCQ^@Yf +qelCOs)@mUs)S-\rH&*`G';Ll%"IN/`jYOHG]iPa.Q% +R$sM7SXuIIU8+N\Vl6VqXKAY0Z*UdE[^`lZ]Y2%o_8=+/`lQ6DbKS8Xd*^=le^rF+g=tE=hVd>N +j5]4_k3(smlKdg'mI'H3nF?)?oCMVRo`Fj]p\ssfq>^ +JcC<$JcEmmnc&FarVZKgrqcWir:p9crq?<`rq-6^rUTsXs7$!Us6fpSrTsRM''`b/?t*_\An#(O +>$+g);c?XprD`hsr_req!*0"ts&L^Af@JL%eC2jndEp4bcHXPUb/q`G`l5p8_SX.)^V7Co]=PP_ +\$i`PZa6p@YkqE!;ZeI'3^id2'1G8U6:=1-68g\W0eP%11,:[C2>o?;2Cp[K7p&Sc:]+/ak;Z0Mo;Ys>k;?Bcp;Ya2i;?Bcp;Z0Pl;ZBVn;ZBYq<:j/k +;ck:BXKi:Jame;>k:A[id:&n)e:&n)h +;#O5k;#X8j:B+)i:B"#h:Amue:A7Nc:f1'c:\did:]!ug:]4,c;$'Qi:]4)i;=RK^:]!u^;?'Jj +;>sJm;?'Jm:]=2e:]4&g:]F8k;>a;l;uT\n;u]hk<<-"h;ts>ktt5nr_`\ns&&egrDWMkr`/kqrD`hsr_iku<`T-"r`')#;c?Rmqc*Sq +!`W)sr)1;ZaI6O\[oGe^;%M$_o9X:aND]McHjkb +e'uq"f@em4gtgiFi8N_VjQ>UfkiqBum-O--n*fc9o()DDo`"Lbp@n=\q#C0iqY^6hr;HTdrdk*# +s4I@%~> +JcC<$JcEpnnG`@ar;?EgrqcWiqtU3crq?9_s7H?_rUTsXs7$!Us6fpSrp9[Ns6BXKroOjShUg&n +_7[7aZa-j>YH4b(W2KWkrhM?FU7no6C2%R/=',?&q-!W!rEK&%rETG1Xo>g.[Ka.HZ`p[;V#J@0`ra?( +b5BE_bkfWach,Qccd'c5bPfQ]b5]ZaaoH8VD>S5MDuO_SEW:(ZF8^1^F`qs-G6W;;H$Xd`I/\P8 +IXcluJV&N,KS>/9Ll$tHN/WdXO-,TgPa.Q$R$jG5SXuIITqeE[Vl6VqXKAY0Z*UdE[^`lZ]Y2(p +_8=.0`lQ9EbK\>YdF$Fme^rF+g=tH>hVd>Oj5]7`k3)!nlKdg'mI'H3nF?)?oCV\Jp%J+RrV6Eg +s8)Zjrqu`noDX=@JcFC&J,~> +JcC<$JcEpnnG`@ar;?EgrqcWiqtU3crq?9_s7H?_rUTsXs7$!Us6fpSrp9[Ns6:-ZXfSY.Y,eFm +S!]M(O,o>#NW+h:MM_=gr.k3)/;I-QeC2jndEp4bcHXPUb/q`G`l5p8_ns7*^V7Co]=PP`\$i`P +Za6p@YcdqTrdP;b?WMAlDJ*3Z>?Y50>6J,6>$4u,=oV\*>81@Q@qB4`AnPaWDL$AaH%BjPF*;iu +I.hpdI/Jn>QD/O4hDZ+GPD#J5N +DZ=SQDZ+MCDYe;IDZ4MOD?=`oDY\2QE,TW3qJZCQqeuIQrbqdTrGhaSp2TtK"`\R'EH6+!EW:%\ +F*)O#FoQR`FoHOdGBeCXrH\Eh!IK.iHi/9jIJnWpIK"]qJ,b&tJc:9#K)gN&KDgK&L&?T7HZF+E +Df'9%AS,I_A7ntFrE/kur*'&'pg!c'!FCNYNW4n@MM[.DL4t$SPl-gGPQ@&8nX06B!1NbR!h,OF +qj7DNQMm0MR/WEPD#J5JDZ4SRE;aeVErU4ZF96T.G5c[iG^4R\H@(&=I<0jeJ:N3&K7ei2L51SA +M2R=ONfT6`P*2&pQC!u,S"#t?T:qsRUnsufWiE/&Y->1;ZaI6O\[oGe^V@V%`5Ta;ai_fOcHjnc +e'uq"f@em4h;-rGi8WeWjlY^gl07L!m-O--n*fc9o()DEo_%nNp@nO\s7u]kr;6KkrVc?eJcC<$ +f`-I~> +JcC<$JcEpnnG`@ar;?EgrqcWiqtU3crq?9_s7H?_rUTsXs7$!Us6fpSrp9[Ns6:3\?=./RB4k^] +>[(<2<)cdq<;fes<;ohm<%qk:BXKi:Jame;>O)`;#X8g;#a>i;#!oe:]=2j;=[Q_ +:]!u^;>sDj;>jDm;#jGk:B45e:]4&f:B45j;>jAm;uT\n;u]hk<<-"h;ts>jl;Z9Mn9)_cb<;fhq<;]_r<;oetS5MDuO_SEW:(ZF8^1^F`qs-G6W;;H$Xd`I/\P8IXcluJV&N, +KS>/9Ll$tHN/WdXO-,TgPa.Q$R$jG5SXuIITqeE[Vl6VqXKAY0Z*UdE[^`lZ]Y2(p_8=.0`lQ9E +bK\>YdF$Fme^rF+g=tH>hVd>Oj5]7`k3)!nlKdg'mI'H3nF?)?oCV\Jp%J+RrV6Egs8)Zjrqu`n +oDX=@JcFC&J,~> +JcC<$JcEpnnG`@arVZNhrVHNhr:p9cs7ZB`s7H?_rUU!Ys7$!Us6fpSrTsRMs6BUJs5t$ViRuT! +_nNXfZa-j>Y-"_(W2KTjs.f^kU7qCW.FZ_mdEp4bcHXPUb/q`G`l5p8_ns7*^V7Co]=PP`\$i`P +Za6p@Yck2.Qi<9WJpqI*R?E;WItIZ3,%>%mARf4\A7]@aC27KqB4tsjAnPXbB=>+1U;(u'JVT/F +rKI,Ar/puAs,m&;qN(Z:qN(Q9rf?o;qiCc;s,I&;r/C]8rJL]6M>W/-LAZ`*K`6]%K`-VuLAuu, +K`-Q"K`6Z2L4k54Jq8H'Jc1,tJc:6'JUi6"qgSKns*joppjE*grHnZnH@#F5s*FZi!dJp5rceEg +qKi0g"F>?J/MDuO_SEW:(ZF8^1^F`qs-G6)r6rd&7)I!pEl +It3'#JqJ]/Knb> +JcC<$JcEpnnG`@arVZNhrVHNhr:p9cs7ZB`s7H?_rUU!Ys7$!Us6fpSrTsRMs6BUJ'X"[DXJ_b] +R$NnsO,f3ZN/W[QMM_:fs+^W0L\uo,L]<)Xe'cXkd*L"_c-+;QaiMQC`Pod5_SO%&^:h1k]",A\ +[^NQLZa$a=YH@eSrdP_l?<2/fCh7'`@U!#?>$G-5=^"s2=BSf*>7t%A=^"s1='/L\JTQ0uC2Is4 +GOBkYHN8BfHiAEjHN8BkH2`-iHN8HlHiALDZ+DP +D#J5NDZ=SPDZ4SCDYnAIDZ=SPDZ=VTDY\5NDusrqDYe8OE;OSQE;jeTE;X_SE;";KE!C<&EcH)> +ErL%ZEc_5%qK2d[rcS6a!-eBdrH\?fr-S?hqgANpI=;*DrdXrurdk$"s+:<'rIb*&re:3%$%I#8 +DfBQ/C1h2YA-%3^rE/kurEB/(pg!c'ra#S_r/L`7#)\7nL5(D0rfm>GrfdGKQgpI@R/i]QS,\rW +RJWBOQMm0MR/`NPD#S;JDZ=YSE;aeVErU4ZF96T.G5c[dG^9:7BR>,TI=?ZrJ:W<)K7nr5L5:\C +MN!LRO,oBcP*D5tQ^F21S"6.CTqS6WV5L8kWiW>*Yd(O@[C3TU]"G_k^VRe*`Q$!@b0/&TcdC1i +eCE1'g"P3:h;@/KioB(\k2tmll0@U$m-Xf@$h3]Wo(2MGp%A%Pp\jmeq>^ +JcC<$JcEpnnG`@arVZNhrVHNhr:p9cs7ZB`s7H?_rUU!Ys7$!Us6fpSrTsRMs6BUJ'4PNdBOkLT +>?Fs,<)Zarr]pHI&O&HF5sRRs9K,*o8l/A];H$Nn +;ZB\f;uooprD3Pm;H!KmrDNVn!)ienr)3Jl!E<"n;Yj>k;Z9Vp;Ys>k;ZBYq;Ya2i;?Bcp;Z0Pl +;Z9Pm;?9]qoMkok;Z9Pn;#a;s:f1%b:f1(d;#X5u:f1(d:JXe`:JXe`r_`GeqbdAis&&>`r_EMh +qbR2ds%iSgr_NPj!)ibmr_NPhs%iYis%iYir_NMgp.k`d;,I*bpe^udqb[;grD<;e!`2ZgrD3Jk +nPK3\r)!)ar_WPjrDNYm!)WVis%rMerD*Ag!)WVkq,72js&B"u!*&hqs&Ako!*&_l!E<"o<;ons +/8Ll$tGN/WaWO-#NfPa.Q$R$jG5SXuIITqeE[Vl6SpXKAY0Z*UdE[^`lZ]Y2(p +_8=.0`lQ9EbK\>YdF-Lne^rI,g=tH>hr*GPj5]7`k32'olKdg'mJcP^nF?)?oCV\Jp%J+RrV6Eg +s8)Zjrqu`no_sFAJcF@%J,~> +JcC<$JcEpnnc&Ibr;?EgrqcWir:p9cs7ZB`s7H?_r:9mXs7$!U!q,ICrTsRMs6BUJs6(HbinMo& +`4rmk['Hs?Y,nY&W2HJfV59u`US=HUr1X1brLt[ed*L"_bfe2PaiMQC`Pod5_SO%&^:h1k]",A\ +[^NQLZa$a=YH=r+QiE@(J:V@(P`UWLJqJehXK>rCAR]+ZAS,LdCMINpBP;$jAn>LaB6'WDMq`T0 +KSY]dPP^O@OoCODOnXt6O8k7:O8P+rJ7N/daqrK$c9r/pr@rKI5F"dP=; +QBmm:R/WKRR/WNPRfAlPRLPU:J:)]eFE;;:Chda)rE/kurEB/(q-crm15`s3C\irQ>2`rQ5#\s3(FXrG;IMqelCOs)@mU!ci@'rH*4*G'8(R +G^+L[H@(!dI=6QoJ:N3&K7el4L51SAMMmFQNfT9aP*;/rQ^F21S"6.CTqS6WV5L8kWiW>*Yd(OA +[C3TU]"G_k^qmn+`Q$!@bKJ/UcdC1ieCN7(g"P3:h;@/LioB+]k3(sml0@X%mI'H3nF?MK!V>s_ +o`Fj]p\ssfq>U6gqu6NlrUg)?s+14%s*t~> +JcC<$JcEpnnc&Ibr;?EgrqcWir:p9cs7ZB`s7H?_r:9mXs7$!U!q,ICrTsRMs6BUJ'^2d*Xf8%a +R$X"uOH,<[N/W[QMM_:fs+^]2LPCN^LB!&.L+.n4dEp4bcHOJTb/q`G`l5p8_ns7*^V7Co]=PP` +\$i`PZa6p@Yck12rdb#u%piXCF_tr*?=IDSQ.h(=Tr&6>?b65r`Th7='&F0FaeD3D/XH; +H%(21I._jbI/\HmHMr-hHN/?lI/\KkHN/6hGQ2pcH1Z@\H2i*hG5ZR`F9Q`-FE;MFqfVXTp2pFY +F)q8$o5akN!cW'qqeuLRs)7jT!,qgRr,;OQr,;4FrbqdRqeZIPCMRa'rG2INr,2IMs(qXNs).jR +rGMUQn8A)@q/61KrGDXSDYS,PE,TW3qJZCQr,;RRrbqdTr,MXRp2TtKs)S*Y!-8'Y!HN8\FS0eV +G5Z[`H2W'fHi/9gI0+kGIK"]qJ,XusJc:9$KE$Q&KDgK'L%g6#F8g+aDJX!"An>I^AGoX+=oDP& +>PVP&?2\(0?i,i_MuSY;Lk^Y*Yd(OA[C3TU]"G_k^qmn+`Q$!@bKJ/UcdC1ieCN7(g"P3:h;@/LioB+]k3(sm +l0@X%mI'H3nF?MK!V>s_o`Fj]p\ssfq>U6gqu6NlrUg)?s+14%s*t~> +JcC<$JcEpnnc&Ibr;?EgrqcWir:p9cs7ZB`s7H?_r:9mXs7$!U!q,ICrTsRMs6BUJ%HqA:Bk:^W +>?P$-j:^'Wk;,L.dr_F##;,L.c:Jak`:Jakb;Gm3cqb[Dk;,Qj[r_EMhqbR2d!)NMf +s%iYkr)!Gjr_NPhs%`Vir_NPhr_NMgp.k`d;,I-cpe^rcr)!DhrD<8dr_NMis&&>`r_NDfp/1fc +r_`Sks%rbmr_NPjpeUi`s%iSjpeq,js&B"us&Anrs&Akos&A_kqGdDns&K5%<)Zco;[l]&;,L.e +:eXSU:/"8PrE/kurEB/(q-;Ll%"I +N/`jYOHG]iQ'I]'R@B\:StD^MUSO`aW2ZeuXfen5Za@-K\@K2`]t_A!_SjF5aN;WKc-FY_daQ^s +f@\d1gYL]Ci8N\UjQ5Oekiq?sm-O--n*fc9rpg*]o`"Lbp@n=\q#C0hqY^6ir;HTdrdk*#s4@:$~> +JcC<$JcEsonG`@arVZNhrVHQiqtU3crq?<`s7H<^rUU!Ys7$!U!q,ICrTsRMs6BUJs6(?`jPA>/ +`k]3q['R$AY,nY&W2?DeUnsl_U]$nbUApqdUA^c2cHOJTb/q`G`l5p8_ns7*^V7Co]XkYa\$i`P +Za6sAYck12XT"P>Q@41SS!K"_IY!-*BWS;5V5.R2A7]@aBkqEsAnbpiB4YXbAnH1U^m'%jJ;/rD +plkW=r/q#BrfQu;qN(Z:qN(Q9r/^c;qiCc;!0-u:r/C]8rJL`7M2;+cr.b0(s+LB*qh4p%p4iU$ +rIk0&qh4s&s+^Q,"bVDXJ:W:NJGk&uK)^B'J:E(HIf+]qIf=cjI/\KlHiSNmHM`!fHN&0jG^'+2 +!."Bd!IK.kH2;dcH2VsfHN&3eH2rPVP&?2\+/?i@J4[L9LM['6d&s)e/9Ll%"IN/`jYOHG]iQ'I]'R@9V9StD^MUSO`aW2cl!Xfnt6Za@0L\@K5a +]t_A"_SjF6aN;WLc-F\`daZdtf@\g2gtgiEi8N\UjQ5OekiqBum-O--n*fc9o()DDo`"Lbp@n=\ +q#C0iqYU0hr;HTdrdk*#s4@:$~> +JcC<$JcEsonG`@arVZNhrVHQiqtU3crq?<`s7H<^rUU!Ys7$!U!q,ICrTsRMs6BUJs6(*YY,\7f +R$X&"OH5B\N/NROMM_:fs+gW/re:B,s+^W0L&-NLcHOJTb/q`G`l5p8_ns7*^V7Co]XkYa\$i`P +Za6sAYck12XT!_UIp66'F)Yi$?2e=<=+PpNH[8lo=WCOH>[(B7>$5$4=]ea,5_\$>l@t, +?N+=/NW4q:M?J`iL4t$SPl-gGPQ@&9nsK&s)e/9Ll%"IN/`jYOHG]iQ'I]'R@9V9StD^MUSO`a +W2cl!Xfnt6Za@0L\@K5a]t_A"_SjF6aN;WLc-F\`daZdtf@\g2gtgiEi8N\UjQ5OekiqBum-O-- +n*fc9o()DDo`"Lbp@n=\q#C0iqYU0hr;HTdrdk*#s4@:$~> +JcC<$JcEsonG`@arVZNhrVHQiqtU3crq?<`s7H<^rUU!Ys7$!U!q,ICrTsRMs6BUJs6'dPBkCdY +>?P'/j:^'Wk;,L.dr_Enu;,L.c:Jak`:Jame;>F&b;$'Qk;=[Q^:B4/e:]F2i +:]4&f:]F8h;$]uo:JOY\:JO[a:]F2i:]=,_:BF?i;#=&_;#a>g;#a>i;#*uf:]4)i;=[Q_:]!u^ +;>sDj;>a;m;,I6fs%rJdrD*Ag!)WVkq,75ks&B"us&Att"&r9"<;f_t<)Zaqp/CferD`o"+Yd(OA[^N]V]=bhl^r!t,`Q-'A +bKS5Vd*^:keCN7(g=k?^ +JcC<$JcEsonc&Ibr;?EgrqcWir:pYH=q.X8\GLbFaTFKdcMr-nNm!.OoqrHnTnrI"Tkrd4]mrd+Hes*FZi!I/hf +GlN'cHN/A?>5_\$>l@t,?Me+/ +[h#pV[^NTN['6dS5NDuO_S +E<:0%F8g:]FT?UaG6)r6rd&L0I!pElIt3'#K7ei2L5(M@M2R=ONfT9aP*;,qQ^F20S"6.CTV8-V +V5L8lWiW>+Yd(OA[^N]V]=bhl^r""-`Q-'AbKS8Wd*^:ke^i@)g=k?^ +JcC<$JcEsonc&Ibr;?EgrqcWir:pM +R?s2%OcPK]N/R[ms,$`2!/LQ.re:B,s+^`3Knb>9rJ(<*,0S-NaN2B?`Pf[2_8*h"]tD"h\[f5Y +[^EHJZEUR:Xf\\*rdb#T/9l,OBOP7V@UrJiIXQQgF`VM==]ej4>?Y-4=^"s2=BAR3Ap&EmCMe$4 +G^fXA!IfIdI.Vd_I/S?oH$Xd`Hi/9hH2r6iGQ2pcH1Q:\H2i*hGPu[^FT6C^FSg4TFS9hYFE;L% +F7XGPEn>OD>\;GD?"MQ +D>nGPDt%Z@Du";MD>e>QDf5>g")r0rDYe8OE;OSQE;jeTE;X_SE;";JE;stTE<^H)FEDYKG5$.Z +FoZabGl;pdHMr3hI/&-hIf=irJGk&uJcLB$K)L?$KE-_tKFN6IE,TW1CM.9lARf:aqHe.XI=6QoJ:N3'K7nr5L5:\CMi(N@hr*JRj5f@bkNM0qlg4!* +mdKW6nac8BoCW%T!quB_rqQNhs8)ZjrVZWmo_sFAJcF@%J,~> +JcC<$JcEsonc&Ibr;?EgrqcWir:p?P'0 +YH=q.X8Z)u.2Y''1bgU5/M8Y56:!e!4?PVa2aThr5sRX55Q3nW5sRV"4$GW(:/Fhd<)`cqs&8ko +!)rPis&/nqr_`\ls&&epr)3Pn!)ibmrDNPlpeprerDNVn!)iYjs&&kr;Ya2h;?9]or)f;#4#j:f1*g:]OAe;"mcb:B+,g +:B"&h;#F2i:]F2i:B4/h:]F2h:]F2_:BF?i;#F,`;#X8g;#a>i;#*ri:esmc:]OA_;#X8g;"dcb +;#X>i;?9WkrD*DipJ:`_s%`VkrDEDhs&8nrs&K(us&K"srDN_r;uTbi;u0Jm</8Ll$tH +N/WdXOHG]iPa.T&R@9V9StD[LUSO`aW2cl!Xfnt6Za@0L\@K5a]t_A"_o0O7aN;WLcHaeadaZgu +f@\g2gtgiEi8N_VjQ>UfkiqBum-O--n*fc9o()DDo`"Lbp@n=\q#C0iqY^6hr;HTdrdk*#s4@:$~> +JcC<$JcEsonc&IbrVZNhrqcWir:p9cs7ZB`s7H?_rUU!Ys7$$Vs6fpSrTjUOlK\?4)sHJJk2t=A +aMYa&['R'BY,nY&W2?DeUna`\U]$nbUA1G]T`(KYaMu3<`5BI.^q[Xt]Y(hd\[])V[Bm3FYct=6 +XfSS'Q\0^$U77@$JpW'%LhEihV5BuXS-rjN6C\$i`Q['['A +YGM6:rl4rXs2Y2^qo\uaqp+o]r6PPlcHXT4b5f]`ao9H[C]/)KD>S5NDuXeTEW:(ZF8g91F`qqP +GBe@XH?spcI=6QoJ:N3&K7nr5L5:\CMN!LSO,oEdPE_>uR$jD4SXuIITqeE[Vl6VqXKA\1Z*UgG +\%&u\]Y;.r_Sa@3a2lEHbg+P]dF6Uqf@S^0gYCWAi8EVTj5oFckNV6rlg4!*mdKW6nac8Bo^qhL +p@e7Zq#C0iqY^6ir;HTcrdk*#s4@:$~> +JcC<$JcEsonc&IbrVZNhrqcWir:p9cs7ZB`s7H?_rUU!Ys7$$Vs6fpSrTjUOlK\?4&Er(OcYT_N/R[ms,$c3s+gT.re:B,s+^T/r.P9.Knb;8rId=daMu3<`5BI.^q[Xt]Y(hd\[])V +[Bm3FYct=6XfSS'J7;hdH#mk7?sR5OAQ=>3H[0jZF)c&/An5@X>Q.b9>$4s/=BAmNLin\pDfKoG +r-n`rII_dVHi&3jHi/3hHi8nGPD>nGQ +DsqT@Dtn5MD>eAGDuXeVDYe;OE;OSQE;skUE;X_RE;";KDujs!qJlOU"ES[-G'- +rJ_,BMi3ILLk^YR/i]QRfJoVRJWBOQN!6JC]/)KD>S5NDuXeTEW:(ZF8g91 +F`qqPGBe@XH?spcI=6QoJ:N3&K7nr5L5:\CMN!LSO,oEdPE_>uR$jD4SXuIITqeE[Vl6VqXKA\1 +Z*UgG\%&u\]Y;.r_Sa@3a2lEHbg+P]dF6Uqf@S^0gYCWAi8EVTj5oFckNV6rlg4!*mdKW6nac8B +o^qhLp@e7Zq#C0iqY^6ir;HTcrdk*#s4@:$~> +JcC<$JcEsonc&IbrVZNhrqcWir:p9cs7ZB`s7H?_rUU!Ys7$$Vs6fpSrTjUOlK\?4&Er?Y-1<`N*u +YHG"/X/],L.5jr_iepqGI8j!E2nl;>sGo;ck:]F5k:]=2i;>F&c;?'Jm;>j;k;>3o]:]=)h:]4&f:]F8h +;#jGl:]F2i:B4/h:]F2i:]F2_:BF?i;#F,_;#a>g;#a>i;#*uf:]=2j;=[Q_:]!u^;>sDj;>jAn +;,HdYr_EJh!)WSjqbmGmrDWo"<)cjtrD`_oqc*So!)iYlpf%;p<)iBd$rBf!;GU+b91qiK92>@e +rEB/(q--r)!Ais&/ko"Ah`i;H!Kmr)EYqr)EVp!*&qr!`W3$qc*Vqr_rbp"'&<"S5NDuXeTEW:(ZF8g91F`qqPGBe@XH?spcI=6QoJ:N3&K7nr5L5:\CMN!LSO,oEd +PE_>uR$jD4SXuIITqeE[Vl6VqXKA\1Z*UgG\%&u\]Y;.r_Sa@3a2lEHbg+P]dF6Uqf@S^0gYCWA +i8EVTj5oFckNV6rlg4!*mdKW6nac8Bo^qhLp@e7Zq#C0iqY^6ir;HTcrdk*#s4@:$~> +JcC<$JcF!pnG`@arVZNhrqcWir:pn`b_8*h#]tD"h\[f5Y[^EHJZEUR: +Y-"e+Wi:JsBUkHOL4au.K4SYsW26;_R[TJ%M2-k:I!^U&LPh"HMi3UO8b1>NW4t7NW4t:MZScmM#E,+LAlo,K`6]'K_pJtLAuu+K`6W%K`-W) +LAuo-K7a&Qrdb!!rIY'#!e>cMr-nNm!.OoqrHnTnrI"Tkrd=Zjr-A[:"aYNBH?sr;HiSTlI/\QnHie_G +J,OoqJ+eEmIft:QJUi:JJc(-"KE$T*K7s5XreCH.s,$c5!fN"sqMkQ:r/_/GOH>NbO-#J%OTL]0 +PPg[DPm*J?R$a5,rg<\Q".5LFRIcjISGo&gR"Kg9H?XLRD/X<+CR4m$rEB2)q-&[!6P,]!6tAcp!idb5KE^b5#iOD#S;KDZ=YTE;aeV +EWC1[FT6I`G5c]&G^4U]H[L6iIXcluJV&N,Knb>;M2@+KN/`mZOckomQ'Rf*R[]h=T:qsRUnsuf +WiN5'YHY==['mHS\\#Mg^VRe)`Q$!?b0/&TcdC.heCE1'g"P3:h;@/LioB+]k3(sml0@X%mI'H3 +nF?MK!V>s_o`Fj]p\ssfq>U6gqu6NlrUg)?s+14$s*t~> +JcC<$JcF!pnG`@arVZNhrqcWir:p!k_BP@?Y$"8"@DF*E!0IfFosIe.sX +Hhr-iHi89iHi8?kHiJBoH$FRXrcnBeo6C:\s*+NfrH8!Z!HWA[FnTqOFTQZ+ErC(OErU+_E,TZ6 +DfG\oqJcIQrbhXPr,DRPrGDURr,2FNrGMRNs(q^Ns)%aO!,_UNphg"Jrb_[Qrbq:DqJZ1Is)%[O +qelIRrGMdWDf0IhDZFbRDuO_TDuO_SEVseLEVaVSEr'eUEWgH*F`qs&FoQXbGPudbH2W'fHi8?e +I/n`oJ,OosJcC?%Jc:9#K*-^XKS/lL!/:E,#D@2=DfBN/C&V`E@fUuU=oDP'>PVP&?2\+*?iOO5 +NGrfdDKnX03AqO7JRrL*VO".,=>QhbFqD#S;KDZ=YTE;aeVEWC1[FT6I` +G5c]&G^4U]H[L6iIXcluJV&N,Knb>;M2@+KN/`mZOckomQ'Rf*R[]h=T:qsRUnsufWiN5'YHY== +['mHS\\#Mg^VRe)`Q$!?b0/&TcdC.heCE1'g"P3:h;@/LioB+]k3(sml0@X%mI'H3nF?MK!V>s_ +o`Fj]p\ssfq>U6gqu6NlrUg)?s+14$s*t~> +JcC<$JcF!pnG`@arVZNhrqcWir:p?Y-2=&i4!i;ZBYq;Yj8h;Ya2h;?9]or)sAk:]O;j;#X>f;#=,i;#aDk:]OAe;"mcc:B+,g:B"&h;#F0!:esk^:/=Y\ +:/=Y\:B"&h:A%Ba:f1'f:\IWa:]+&h:]4,c;$'Qi:]4)i;=RK^:]+&_;>sDj;>a;l;#F)h;"d]b +:B+,i;#O8g;ZB\o;ufqt;ufqs<;f_u<)lpt<;ohr;Yj>hU91hfL +r)ru%r`f2'rE]A.q-X/0rDYdF$Fme^rI, +g=tH>hr*JQj5f=akNM0plKmm)mdKW6nc&([oCW%T!quB_rqQNhrqcQirqu`no_sFAJcF=$J,~> +JcC<$JcF!pnc&IbrVZNhrqcWir:p9cs7ZEas7H?_rUU!Ys7$$Vs6fpSrTjUOlK\B5s60LGroOgS +jMepH\$NBFYH=h(W2HJfV#@(gUApqcUA1G]T`:YaSc,/YSO^K1^V.:m]=GJ^[^NTMZa-j?YHG"/ +X/`.tJ8(L>NJ3"7J;%X8XJVegSsu(2O,/LDJ:2m"LPUeFM2R@KJ=i[jH%1O&N03t"rKHl:plYB6 +r/^i;qN(W;q2bN:rf@&=rf$o:qMbK6regl9M26ueL\li*L&Qc*L&?W$L%g?%L&Qc(KDgK%L&Zl1 +KnP,3K)L6#JGausK)^B'J:E(IIenNoIf=coHiSToI/\KkI/SBhH2i3iH2W!eH2;gkH[:!`G^4T3 +GlE!fGR/S@H?jd_H[:#:Hi86jHiAEgHhi!fH2MsgHi83jH@,X;rd=`or-\Klrd4cqIXh9GrI=Nk +rdXs!rdalsr.=s$!ec2YrIt9+s+gW2re^u>NK0!YNK0!Yrf?rI!LoVXSIV6]ML^,$G'7qED/O*'DuNo<>5_\%>l@t,?M\%-@/jXC\$icS[^EKM +Yct=,rl"fUrl>&[!6Y2^!6t;ao?RK`bfp(0!6Y8^phThErb_OMs)7pVrG_mZF*%>&EclPKGB\:W +H$Xd`I!pElIt3*%K7ei2L51SAMMmFQO,oEdPE_>uR$jD4S=Z@HTqeE\Vl6VrXKA\1ZEppH\%0)_ +]Y;.s_Sa@4aN;TJc-FY_daQ^sf@\d1gYL]Ci8N\UjQ5Oekiq?tm-O--n*fc9rpg*]o`"Lbp@n=\ +q#C0iqYU0hr;HTdrdk*#s474#~> +JcC<$JcF!pnc&IbrVZNhrqcWir:p9cs7ZEas7H?_rUU!Ys7$$Vs6fpSrTjUOlK\B5s60LGroORL +jHu:!PEM#fNK!gnre^W0rItK0L5(J=LA-E#K`$K$JOdMj^V.:m]=GJ^[^NTMZa-j?YHG"/X/`.t +?WM5eBk(U[@:N>gJUMfhGBInECM%-g?sd;RB4bgiBPD0jBR+s%D/O?9GCBCoKE-`(L(/iZE,]`5CM@EnAn5C_r`T2'rEK,'rE]A.qHs2/s'bqe +$&je#MM[.DL4t$SPl6mGPQ7$>R/<S5NDuXeTE<:0%F8g9%F`qqP +GBeCYH?spcI=6QoJ:W<)K7nr5LPUeEMi +JcC<$JcF!pnc&IbrVZNhrqcWir:p9cs7ZEas7H?_rUU!Ys7$$Vs6fpSrTjUOlK\B5s60LGroORL +jB>\g=B8F$sAj;#aD`;#X8g;"dcc;#F2h;?9WknPB0[s%iVjrDh;ufkq<:3Zk;Gg:h:f1"`9M>=Vr`T2'rEK,'rE]A.qHs2/s'bn' +r_Wr!;c-Cg92e_dr_r_or`/kqrD`hsr_ir"<`N*urD`hsr_rbprDiksr_rT-rG;IMqelFPs)@pV +!ci@'rcE1'G'8(RG^4R\H@($fI=?ZrJV&N,KS>/9Ll%"IN/`mZOckomQ'Rf*R[]h=T:qsRUo(&g +WiN5'YHY==['mHS]"G\i^VRe)`Q$!@b0/&TcdC1ieCN7(g"P3:h;@/LioB+]k3(sml0I^&mI'H3 +nF?MK!V>s_o`Fj]p\ssfq>^ +JcC<$JcF!pnc&IbrVZNhrqcWir:p"-/G'OSt7?Nr=q;N;AM6N;e_;MM[1GreLB*re:?)s+UB(qh=d! +s+UH*re(-%rIt9+"GMM^K7a&Q!.b'"!J5n$K)^B'J:E(IIenQmIK"WoIK"WnHi8?jHMr-hHN&3g +GlE!aH3/G>HN&3eGlE!fGQ<$gH3AM>I!^2[:!IB+lH2riA5Mi@Ll!07&>!K`BAOSt7? +OSt=APPg[BPl[5=rg*SN#FLpIR$a;/RJ!$KS,JoXT)YDmNIZA&H$==LD/=$'Dcp6B>5_\%>l@t, +?MRt-@/XO5\,Wl<[C!=?YQgoA`5T^8`r=$Ya8jB\b6#o4c2#ZVcN;D9bl5faanKTLD#S;KDZ=YT +E;jkWErU4\FT6I`G5c]0G^4U]H[L6iIXcluJV/T.KnbA=M2I4MNK9-_P*;,qQC+)/S"6.CTqS6W +VPgAmX0&M-Yd1UC[^WfY]Y2(p_8=.0`lQ9FbK\>ZdF-Oof%8R.g>(N@hr*JRj5f@bkNM0qlg4!* +mdKW6nac8Bo^qhLp@e7TrqQNhs8)Zjrqu`noDX=@JcF=$J,~> +JcC<$JcF!pnc&IbrVZNhrqcWir:pC1q-f?sR.=B)cKPBPM6qHB35uD/XH=HMW*iJ,artIIhj]HN8Hk +Hi&3gHiJElHiJHuH[L3fH[:!`qfr-d!I/n]GlN'gGQ;seFo-7^F*)O%FnTqOFTQZ+ErC(OErU+a +E,T]7DfBW5q/H@Ps).aQqf)IOrbhaSrGMLNrGMRN"DhjhCi0,eqel4HrGMRN!,hdSn8A)@q/64L +r,24H")r0rDYe8OE;OSQE;jeTE;aeSE;";KDujs!qJcd]F)uGGG'8"MqK;g]rce9brH\?frd4Tk +rd=corI"Zpqg\Qp"+buRK)U?#K)^K'K)UDoK_gE6KmRfYE,KN.B4kge@qAeGr`]8)qHWu)rEf;, +ra>\5rf-r9!fDhjre:K%Q'D33rKI;JnX06B!1NbR!1NnTr0RMOQM51nD#S;KDZ=YTE;jkWErU4\ +FT6I`G5c]0G^4U]H[L6iIXcluJV/T.KnbA=M2I4MNK9-_P*;,qQC+)/S"6.CTqS6WVPgAmX0&M- +Yd1UC[^WfY]Y2(p_8=.0`lQ9FbK\>ZdF-Oof%8R.g>(N@hr*JRj5f@bkNM0qlg4!*mdKW6nac8B +o^qhLp@e7TrqQNhs8)Zjrqu`noDX=@JcF=$J,~> +JcC<$JcF!pnc&IbrVZNhrqcWir:pJ^2Dm6E0eY4;2)Rh;?0Sm;?9]qoi2#l;Z0Gs:esnb;,C*g;?'Jm +:B45j;?'Gk:]O;j;#X>k:]O;j;#4#h;#X>k;#aDe;#X5j;#F,g:&n)g:B"&h;#=)t:esk^:JX_\ +:JX_\r_EMhoM>H_rD3,`r_NGgs%iSiq,%2i:J^pc!)`;`r_NDfp/1fcrDEMk!Du\_:BF9e:]=2c +;?'Po;ZTirpf.2j!*&qt!*&qrs&/Ykr)E\pr`&;a&QDb1;G^1e:f1"_9M8#N7p0!o>5_\%>l@t, +?MRt-@/XO5;#X;m;H*Ql!D?Aj;ZB\n<;onr<;]_r<;oetS5NDuXeUEW:(ZF8p@^FT?UaGB\:WH?spcI=6QoJ:N3'K7nr5LPUeEMi +JcC<$JcF!pnc&Lcr;?HhrqcWir:pO8b1>O8P%;NrY:?O8b1:O8k4CNK0!XN;AM6N;eb8M?/QireLB*re1K.K7nr4rIk$$pP/^% +re19'r.P$&s+UZ1KS4u0rIFs!rdbE.JV&N+Jq8K'It.EGqgSTprI+Zms*alord4Wl!.4ZjrH\Eh +rd"Herd"?ds*Ocl!dK!9qfr*crceEgrd"]mH[L0drHnKh!.4]mpj;j`s*=Qhs*O]is*Ocl!.4]m +!.F`lrdFcn!e#QJrIFfqp430m"Fu&SJ:RNJr.=s$s+LE)r.Y0*s+pW2!fW+tr/L`:s,RPLO-#Ea +O,o<^O-#J&OT:R@Pl-gEQN!3PR$j<>QiNQIRK/lUSH,8[T+$j4I=-?aFE228D/=.h>5hb%>lJ%- +?MRt-@/XO5@fNn?[^WZO[/R96Y/J8t`Q#ps`ra?(b5BE_bl,f`cL]?`cHON3bQ#]aCA2NBD#S;L +DZ=YTE;aeVEWC1[F9-N-rc`""H$Xd`I!pElIt3'#JqJ`1L51SAMMmFQO,oEdPE_>uR$jD4SXuII +U8+N]Vl6VrXfen4ZEpsI\@K2`]t_A!_SjF6aN;WLcHaeadaZguf@em4gtgiFi8N_VjlY^gl07L! +m-O-=mfi4No()DErq6 +JcC<$JcF!pnc&Lcr;?HhrqcWir:pjNJrepMZ/J4M#W81L&d#.LB!#/LAQZ)K`6]'K`6W'K)C2sJhX^C[^EKKZE^X;Y-"e+ +Wi;qpVPU)`@UPVP'?2\+* +?iFI3@K'a9NW4n.9ZaI6O\[oGe^VI\&`5Td^ +JcC<$JcF!pnc&Lcr;?HhrqcWir:ph;?0Sm;?9]qoi2#l;Z0Gs:esnb;,C*g;?'Jm:B45j;?'Gk +:]O;j;#X>k:]O;j;#=,i;#X>k;#aDe;#X5j;#F,g:&n)g:B"&h;#F2j;#a;n:/=Y\r_NPhn5''\ +rD3&^!)NJgs%iSiq,.,e"&Vlk;=RK^:]+&_;>sDj;>jAn;,HXUrD<;es&/kq#?4W$;cH[p;uTbp +;ZKer<<-"t;u]bk;uBVp;u]h`;uK\r;uTW";Gg1a9M8#N8c;il>PVP'?2\+*?iFI3@K'a9;#X>l +;uTVp:fI?ks&0#!;cH`p\;ODuXeTEW:%Z +F8g7^Fa!b.B6\]JH@($fI=?ZrJ:W<)KS>/9Ll%"IN/`mZOckomQ'Rf*R[]k>T:r!SUo(&gWiN8) +YctF>[C3TU]"G_k^qmn+`Q-'AbKS8Wd*^:ke^i@*g=tE=hVd>Nj5]7`k3)!nlKdg'mJcPXnF?)? +oCW%Ts7QHerV6Egs8)Zjrqu`no_sFAJcF:#J,~> +JcC<$JcF$qnc&IbrVZNhrqcWir:p%H=h'Z*1:2Wi;qoV5:!dU\LS]U&:S`T*1aVS=H/LS-#1MSGJ`TS,f&XRQ.XZZ*:F7XfSS' +WMl_lV50l\TmqcNB-YK_gDsLAuu, +K`6W&K`$Q(L'33`KS+mPJc:6+K7\]+JUi6"rI4Wn!.Olprd4]ord=Zkrd4]mrHeEfs*FZirHS?f +q0E6lH?sj]H$T:3rd"Kfr-ABjI/J?iH2r\$`TMricI,`5MYorPnu\aiaP)!6k>brQb#\!mSs5rlY;`rbD1CrG;IMr,2OQs)@sWs)J*\ +rcE+%G'8(RG^4U]H[L6iIXcluJV&N-KnbA=M2I4MNK9-_P*;,qQC+)/S"6.CTq\?YVPgDnX0&P/ +Z*UdE[^`l[]Y2(q_Sa=2a2lEHbg+P]dF6Uqf@S^0gYL]Ci8EVTjQ5Oekiq?sm-O--n*fc9rpg*] +o`"Lbp@n=\q#C0iqY^6hr;HTdrdk*#s4.."~> +JcC<$JcF$qnc&IbrVZNhrqcWir:p#3(i0O,]*VregZ2!/UW0#_n+iL5(J=L5,V[s+LB*rIk0&rIXruqL\]t34#oqYck43XK/A# +W2HMhUnaZX?t\;ODuXeUEW:%ZF8g9#F`qqPGBeCZH@($fI=?Zr +J:W<)KS>/9Ll%"IN/`mZOckomQ'Rf*R[]k>T:r!TUo(&hWiN8)Yd(O@[C3TU]=bhl^r""-`Q-'B +bKS8Xd*^=le^rF+g=tH>hr*GPj5f=akNM0plKmm)mdKW6nc&([oCW%T!quB_rqQNhs8)ZjrVZWm +o_sFAJcF:#J,~> +JcC<$JcF$qnc&IbrVZNhrqcWir:p"6*Ea(91c73K2)R9O4Z?;6;,U7hrD`_o!)ibms&/kqs&&hqq,I,f!)i_l!)iSj +lVd^\!`DrqrDNYos&/\jr)3Pl!)ibm!)iVkqbdDkrDEYp<:s5l;ci;#*uf:BXKk:f1*\;#X8g;"dcc;#F2h;?0S]:]+&b;#jMg;uTbp;ZKer<<-"t;u]bj +;uTbp;ZKe`;ZKep<<,ts;$p6!:esbW84uNX>5_\%>lJ%-?MRt-@/XO3@fK:(;?'So;#sKlrDNYp +!`N&tr)N_qr`'#! +JcC<$JcF$qnc&IbrVZNhs8)`jr:ps5FIGZEUI4X/W"pV59u`rM0.^rLs7a#+qQ]T:VXFrgX._S=H(HiAEbHiJElH2W'gHi86iHiJBlHiABmIJ\EkIK"TqIXckG +JGaokJGt$!J:[]MqgnZs"bVJ]K7ejTK`d'bLPc"f!fN"qr/CZ8!06o:rf7#>s,d8C!KrZCPl6mE +QM[$IQiNQJRK8nJr1+RoT:_^HSXl@AL44PsG'7hBE,09.>5hb&>l@t-?MRt-@/XO1@Kp>O[^WZO +[/R92Xi/0W`VmgYaN;U&b5fc`c2Q#ZcN;A8bl5faCA2NBD#S;MDZ=YTE;abXEcZ=$FEDYKGB\:V +H$Xd`I!pEmJ:N3&K7nr5LPUeEMi1;['mEQ\\#Mg +^VI_(`Q#s>b0/&TcdC.heCE1'g"P3:h;@/LioB+]k3(smlKdg'mI'H3nF?)?oCMVRo`Fj]p\ssf +q>^s+14#s*t~> +JcC<$JcF$qnc&IbrVZNhs8)`jr:ps5F7AOH,9XMi.Cg!/UN-!euJcreCB*re1<*rIk-%rIXruqL\`u!.t-"+0DWFWi;qpVPU)` +U7n6PSl^JjH[9pXEGfN(AR](S?2J7DC2$UkLj"5bDfU#HIt.$\;MD#eJPDt.`ADtIrEDuXeTDZarsDJo;h!-%gRrc%jT +rc%gUr,DCMqJZITEr9qVErU1aFEVhMFEID&rc\6aqKW$crd+NirHnTnrd=]n!.OcoqLJQrqL\a" +oS!6uqM+s&%u,jmFE);=DJNouB4GI_>5hb&>l@t-?MRt-@/XO1@Kp>%Mi3ILM#N,/L&.)6PQ@&9 +pm;&Jr0[AL!1NeSs-iqTrg&FEMbNGBe@XH?spcI=6TqJ:W<) +KS>/9Ll%"IN/`mZOckomQ'[l+S"#t?T:r!TUo(&hWiW>*Yd(OA[^N]V]=bkm^r"".`lH0CbK\>Y +dF$Fme^rI,g=tH>hr*JQj5f=akNM0qlg4!*mdKW6nac8BoCW%T!quB_rqQNhs8)Zjrqu`noDX=@ +JcF:#J,~> +JcC<$JcF$qnc&IbrVZNhs8)`jr:ps5F(<=8c,'<)Z^qj>i;>jAn;,H[Vr)!/cp/CujrDN\qr`&qtr_rhp +pf%/ks&/ts;cN*^!*&hq%TZM);,^:g:eaYX84uNXr`f5(rE]D/q-X,/rF,P3!Fnt*;?'So;#jGj +;ZB_r;ZKepeAPDuXeTE<:0%F8g9'F`qtQ +G^+L[H@($fI=HctJV&N-KnbA=M2I4MNK9-_P*;,qQ^F21S"6.CTq\?YVPgDnXKAY0Z*UgG[^`l[ +]Y;.r_Sa@4a2lEHc-FY_dF6Uqf@\d1gYL]Ci8N\UjQ5OekiqBum-O--n*fc9o()DDo`"Lbp@n=\ +q#C0iqY^6ir;HTcrdk*#s4.."~> +JcC<$JcF$qnc&LcrVZNhrqcWirV6Bds7ZEas7H?_rpp*Zs7$$Vs6fpSrp9[N!:'RJs6'IGroX7B +!9F.>s5F=Ci308aX/`(qrhTUjrM0.^rLs4`s.B=_s.0%W"e1sLS!ofAS+rHNR4P;7VPU)`U7n6P +St;IAV59`OQB[DcKS4o'H\R92MM[.IN,=okZZpkLLPq>pPQ$a>OoLU@Oo1C1OT:L=NrY4P_V(?2\++?i=C3@JOC4@g0?M\$`WN +ricR.`5KX6`r=$Ya8sE*r6#)aqp#,co$7H`bfn8Rr+btArbVRNr,2OQs)@sWs)J*\rcA0`G5c]- +G^4U]H[L6iIt3'#JqJ`1L51SAMMmFQO,oEdPE_?!R$jG5SXuLJU84W`Vl?\tXfnt6Za@0M\[f>b +^;%M$_o9X:ai_fOcHjndeC<($f\5'7h;7&IiT&tZk2tjjl0@U$m-X60n*ol^ +JcC<$JcF$qnc&LcrVZNhrqcWirV6Bds7ZEas7H?_rpp*Zs7$$Vs6fpSrp9[N!:'RJs6'IGroX7B +!9F.>s5F.>i/WfrMu/A2M"ui)LAlo*K`?`-KS+sVKDgDuJbjulJJtJbVPU)`U7n6PSt;IAH[9jW +E,TN(ARo1T?2eIHBP2!mBjPqP_V(?2\++?i=C3@JOC4@g.jMMi*CJre:N/Q'I[6Q2[!K +Q'_95s-N\Oqj@GQqO7JRrgEeRr+btArbVRNr,2OQs)@sWs)J*\rcA0`G5c]-G^4U]H[L6iIt3'# +JqJ`1L51SAMMmFQO,oEdPE_?!R$jG5SXuLJU84W`Vl?\tXfnt6Za@0M\[f>b^;%M$_o9X:ai_fO +cHjndeC<($f\5'7h;7&IiT&tZk2tjjl0@U$m-X60n*ol^ +JcC<$JcF$qnc&LcrVZNhrqcWirV6Bds7ZEas7H?_rpp*Zs7$$Vs6fpSrp9[N!:'RJs6'IGroX7B +!9F.>s5F(cr_ihq;uKVn;ZK_k;>jDm;#jMl;#jMj;u9Gm;>jAn;cNEi!E2np;$Kim:f1(d;#X>l +:]X?gr_W_n:J^g`r_`\l!)NSjqGI8hr_`\ls&&Jds%`Vkr(m;e!)NPgr_NPjr_X/';,L.d:JO\] +:/=\^:/:=Tr_WVjmnj$[!`2ZgrD<;er_NMis&&>`r_NGgp/1fcrDEMk!Du\]:]!ua;#jMf;ZKeq +;ZKer<lJ%-?M\%-@/aU1@fKpA +:f1(d;cEZm!)WVl"]JB";c?Zm +JcC<$JcF$qo)ARcrVZNhrqcZjr:ps5F@Di8C`=X/`(qVZ*FjU\UY^U&L_bTDtJ_SbeiVS,8ZNS+rHOR4NiQL4H+rUS=HUT:VXE +S"#h:S!K%nLkLJ4H[^['MMR1HN/_h9b0kN`KSkcePQ$a4Oo1C2OoCI=O8Ot;Nr"h8Nr4q')"bhV^Jq8ONJbam%JUi9#IsukE +J,WCD;ufkq8lT:VX5I=6BeG&qV?Chn$:qHX#*rEf>-ra>\5qI9D5s'u8@\$`WNricR.`5KX6`r=$Ya8sE*r +6#)aqp#,co?RNac-4E/CA2NCD#S;LDZ=YTE;jkWEWC1[F9-N-rc`7)H$Xd`I!pEmJ:N3&K7nr5L +PUeEMiOj5]7`k3)!nlKdg'mdKW6naZ2@oCW%T!quB_rqQNhrqcQirqu`no_sFAJcF7"J +,~> +JcC<$JcF$qo)ARcrVZNhrqcZjr:ps5F.>i8BUoMu/A1M#2u)LAuu+K`6Z*K`$K#K)1&rK(aa:?>a:]V50l\TqS*MSt):>R?Xs&/qr;uKSp<)`co +r)LO!lY +D/O0(B4b^c@qb^Dra#J/qHs50rF,P3rF>ko(2MQo`Fj]p\ssfq>U6gqu6NlrUg)?s+14"s*t~> +JcC<$JcF$qo)ARcrVZNhrqcZjr:ps5FIGi8@U7Tes&8kqr_jmc0J"]MUnaZX +Tq@pJS=?"94?>M^2Dm6E0J>+:2)[Dm2$l*+4[;t>;,:%frDNSmqbmAiqbdDmq,I,f!)i_l!)iMh +r)3MkoMY]fqGR>l!)iVir)3Ag!)iYlqbdDkrDEYp<;';n<)Z]n;$Kim:f1(d;#X;o:esk`r_W\m +:\did;?'Gm:]=2g;>rKQ2u5K62uY`82uY];4?GScpcS=7"ZoRZ;,L0g:]F2i;#a;[:]F8j:[_-[ +:]!ua;$'Qi:]4)i;=RK_:]+&_;>sDi;>jAm;!h'U;#X;l;#O8b;ZKeq;ZKer<k/9Ll%"IN/`mZOckonQ'[l+S"-%@TV8*UV5L8kWiW>+Yd1UB[^WfY]Y2%o +_8=.0`lQ9Fbg"G[dF-Opf%8R.gYCWAi8EVTj5oFckNV6rlg4!+n*fc9nac8Bo`"Lbp@n=\q#C0h +qY^6ir;HTdrdk*#s4%(!~> +JcC<$JcF'rnc&IbrVZQirqcWirV6Bds7ZEas7H?_rpp*Zs7$$V!q,ICrp9[N!:'RJs6'IGroX7B +!9F.>&)uR,i8EMMX/`+rVP^2dV#I.bUALVaT`1S`T)YA]S,f&WS-,7LR@4&Cr1!JMrL"XSP_F[' +TU_aMTq@pJS=?"9R$a5#Lkg\8IX?BoreLu@M2R@6G,i>1L\uo+L&Q`*L&Qc$L%g?$L&Zi+KDgK#Ka3?dKnP)1 +JV*iO!J5n%JcLH%Jd-dVJ5fNJ<;fbq<;ohn;ufkqa, +q3CrF!13YMs-EeSR@3flJ%-?M\%.@/XO1 +@f9g8AH0.=[/dT5YQ_/I`5T^8rl>&[!6P,]!6kGe!mJp6rm(,]!m]$6qeGk@rG;IMrGMXRs)@sW +s)J*\rcE%#G'8(RG^4U]H[L6iIXls"JqJ`1L51SAMMmFQO,oEdPEhE"R$jG6St;UKUSO`aW2co" +Xfnt7ZaI6N\[oGe^VI_'`5Tds_o`Fj]p\ssfq>^s+14"s*t~> +JcC<$JcF'rnc&IbrVZQirqcWirV6Bds7ZEas7H?_rpp*Zs7$$V!q,ICrp9[N!:'RJs6'IGroX7B +!9F.>$0'q&i8EMMMi3JiM>i>.L\c`*L&Qc)K`Hf(KD^>sJc:8oJK.s5@pi>\F/#A%T:VXES"#h5 +R$VT#AS#7W?!_.AB+&BeBk(_$T58FcG'a+:r-nQlq0r?lpO*!f!.+Hfrd=ZkpjD^\!IB%gGlN'f +GQ<$_GlN'hGQE#3rcS!XrH7gUpN6IXqfDCM!-/!W!-/!W!,qXOs).pUDuE<.9DqQ[9D2'Y9E%lf +;?9`qrDNPlrDE\o;H!BhrG;OPr,;IM!,_OLqeu+Eo5FYHqJZCQr,;RRrbqdTrGhaSpMp%Kqf2RT +#BP!/G'8"MFSg4ZG5ZXaGQ`58G^4T5HMr3dHie_FIenQiJGt,sJcgXYKS0#PrIt*&!/:E,s+gT0% +Z-!hEcH&9D/3cqA7T2:r*95,rEf>-ra>\5qI9D5rF?%iMi*CJre:N/Q'I[5Q2d'KQM6dGQih +r*GPj5f=akNM0plKmm)mdKW6nc&([oCW%T!quB_rqQNhs8)ZjrVZZnoDX=@JcF7"J,~> +JcC<$JcF'rnc&IbrVZQirqcWirV6Bds7ZEas7H?_rpp*Zs7$$V!q,ICrp9[N!:'RJs6'IGroX7B +!9F.>#iah%i8EMM +R@'A.2`3BI0eb761c7-LrA=jJ6oe(=;G^:jqGR>lqbmAiqbmGmqGdJn!)i\m!)i_l!)iMhr)3Mk +oMY]fqGR>l!)iVi!E)eo;ZBSo;Z0Jm;YsDi;?0Sm;?9]qp/M,m;uBJs:esnb;,C*g;$0Wj:Jh$f +!DlSf;#aDl:]NBM2Z>Z72Z>Z32uko:2ZG`82ZGo>3WM8:4S_,B4?GYfr&Y'F:Jah^:@V-Z;#a>[ +;#X8j;#X5j;#*uf:]=2j;=[Q`:]!u_;>j>i;>jAm;=.0V;#X;l;#O8];ZKer<-ra>\5qI9D5rFGq*!`2for_WYl +rDE\q<)iiqqGdMpr`&qtrDNbss_o`Fj] +p\ssfq>^s+14"s*t~> +JcC<$JcF'ro)ARcrVZNhrqcZjr:p&E;[-i8EMMhPmHOVP^2dUnn!bqP*n]s.K@`s.97]!1a"Ws-s+ZRf8`SRfAlRRK/cTRf/Wr +J!5S;BqCiVL7t62St):>R[BJ/Q'I)XJp_ljK8GMDreh)"F*E\?H\-p-OSk=?P3S20P5g[COSP"= +OSt=?OSk.>Nr=q;Nr"h7NrP.ANfT4mN<"q:MZJ]lreUQ/r.b3)re(?,KS9,SpP/[$s+LE)re1-% +#DRqdKS+l-K)L6$Jqq-O&-s'>h8 +?sm>IrEfJ/!aJr7r*0/GrH\NlI!kj=s*F]lrI"6as*=Kfrd4Wi!IB+lHMr3kIJ\ElIK"TqI=?\E +JGaojJH(*"J:[]MqgnZs#(qS^K7ei1r.PE2LPUeDMMd=LrJUZ6"c\P%NfK1tNW>.>O9:W.P*>d- +q3;&JQ'R^5Q3/VT)P>jOb%n,H?aILE,0^ +JcC<$JcF'ro)ARcrVZNhrqcZjr:p$0'q&i8EMMhM[9fM>i>.L\uo+L&Zi*K`Hf(KD^?$JHLFRJUm6@/7*.%?rhDkCh063St;IA +S!o_3Q^*hK@pr_L?=[_`BkM-o?=RSiJo,IKGC9=IWBFIDes0&An>I^J,W^O?2e1,?i=C3@JXI3A,Ts;AHRjJMMV7d",3#* +QMZpJPa;'2rg3VOqjI8L!LfGQCA2NCD#S;LDZ=VTE;ad)EcZ;DFEMbMGB\:WH?spcI=6QpJ:W<) +KS>/9Ll%"IN/`m[OckonQC!u-S"-(BTV8-VVPgAmX0&P/Yd1UC[^`l[]Y2(q_Sa@3a2lEHbg+P^ +dF6Uqf@\d1gYL]Ci8N\UjQ5OekiqBum-O--n*fc9o()DEo_%nNp@nO\s7u]kr;6KkrVcBfJcC<$ +e,Op~> +JcC<$JcF'ro)ARcrVZNhrqcZjr:p#iah%i8EMMhGjJQ!*&epqGdJps&T,!!E<(s +R[BJ/Q'F3^0eb761c7-L1c7-W6q'R::/Fed;u'>k;u0Dl;?'Po;uKSo;u0Jn;uKVn;u]bo;#jMe +;Zfop;,[?ioMPZfqGR>l!)iPgr_ibn!)ibms&/_mqbdDkrDEYp<;';m<)`]l"].uk;,L0g;$0Wj +:Jh$f!DlSi:]i[92E:[orAFU5!]N"qr\sd6r\s^6!&sj7s#9s9s#gZ;#a>j;#X8d;$'Qi:]4)i;=RK_:]+&_;>sDj;>jAn;,H[VqG@2hs%r\l!)iAd +!*&qts&8tsr_i\n!*&bmrDEYp<:!N`<;]bqQ8P]7irE]D/qHs2/raGY4 +rF>e:rac1/:fC[C3TU]=bhl^r"".`Q-'BbKS8XdF$Fme^rI,g=tH>hr*JQj5f=akNM0qlg4!*mdKW6nac8B +o^qhLp@e7Zq#C0iqY^6ir;HTdrdk*#s3q!u~> +JcC<$JcF*snc&IbrVZQirqcWirV6Bds7ZEa!qc*UrUL$[nF6GGs6fpSrp0^PlK\B5!U/_Gk5XNC +jSn0Lio/kSi8V; +C7LcUM1^MR[BJ/Q'IStP'q_5LPCVAMi*F?G'][$IY*<4q31`>nr`m4rfR5DrfR/@qN:c= +s,m8AqiC]8s,Qu;r/Uf%oSij0regf7M>i>1L\li+L&Q`,KnP-SL%g?%L&Qc*KDpQ#KaEKf +KnP)1JV&H(qcWr$"BST'<*&lq!EE+t;u]hq;uBVo;u]hs< +!+#P0r`oV2>?kG2>6eD;>[2T%I!kj=s*=ZlrI"6a!IB%gHN&6kHN&3iHiJBlHiABmIJ\EkIK"Tp +IXh9GrI=Nks*k*#JV!fNqgn]ts+:H-K7ei1r.Y0*#D\+lMMd=LMYrA4N;eh:NW>.:Nr>%@Ockq* +Pl$^GPl?pKQBhB6s-EeSR@3i=rgWqXpRV2Qr1=IcJphrjGBIhDChmsT>[786rEfA.rF#V5q-s>5 +rFGh;"1P\G[/R91Xi14X!65#Ys2Y2_r6,,arltJe!6tMgo?RE^qeGh?rbVRNr,2OQ!-%mVGB.bG +FEDYKG'A.TH$Xd`I!pElJ:N3&K7nr5LPUeEN/WdXOHG]jQ'Rf)R[]h=T:qsRUo(&hWiN8)Yd(OA +[^N]V]=bkm_8=+/`lQ9EbK\>YdF-Oof%8R.g>(N@hr*JRj5f@bkNV6rlg4!*mdKW6nac8Bo`"O` +p&Ojcq#C0iqY^6ir;HTdrdk*#s3q!u~> +JcC<$JcF*snc&IbrVZQirqcWirV6Bds7ZEa!qc*UrUL$[nF6GGs6fpSrp0^PlK\B5!U/_Gk5XNC +jSn0Gio/kSi8QqLAElr-eEjrdFQhrd4Tir-SHkr-S3doR$U`qfi*d +rHJkr_Wnu;,C+d;,_B3D>S5JDtS#GDZFbO +DuX_ODZFbRDuO_TDuXeSEW'kMEVsePEW'qXF8p=_G'3e+r,qp\r-/0cs*+Kfs*=TirHn?f!e#NH +r-n`rJ,Fg"It3'#Jbt'!K*$^YKD1&tL%g?$L]3,-M%5&VE,TZ2CM@BmA7U-o>lJ%-?Me+.@/aU1 +@fBm9AGg!@Mi*CJrItB=QBqE5!L/rFQi`S?Qi/9Ll%"JN/is\OckroQC+&.S"-(BTqS6WVPgDnX0&P/Z*UgG +[^`l[]Y;.s_Sa@4aN;TJc-FY_daZdtf@\g2gtgiEi8N_VjQ>Ufl07L!m-O--n*fc9o()DErq6 +JcC<$JcF*snc&IbrVZQirqcWirV6Bds7ZEa!qc*UrUL$[nF6GGs6fpSrp0^PlK\B5!U/_Gk5XNC +jSn0Fio/kSi8U=Q<;BPj<<#qutqR[BJ/ +Q'IStOt\RH2)I0L1c7-E6q'X?:JanemSa$]!`Drqr)3Pnr)EYorDNVn!)ibm!)iJg!)iViohkcg +qGR>l!)iPgr_ibn!)ibms&/_mqbdDkrDEYp<;';m<)`]l!DlSk;#jGk;$0Wj:Jh$fs#10B2Dm?M +2`Z62Z>Z33;kc82ubf949@T*3rV5;4S_,?48qA@3se#55<_7o4?bqnr]^3T +r_NSjmSNmYs%r\j!)WJgr_NMi!)`8_s%iPhp/1fcr)*Gk!Du\]:\die;?'Jm;?'Pc;ZKer/9Ll%"JN/is\OckroQC+&.S"-(BTqS6WVPgDnX0&P/Z*UgG[^`l[]Y;.s +_Sa@4aN;TJc-FY_daZdtf@\g2gtgiEi8N_VjQ>Ufl07L!m-O--n*fc9o()DErq6 +JcC<$JcF*snc&LcrVZNhrqcZjr:p.#Nfs4%r0$W5r/gr@rf[;D +r/gf`81L\li+L&Qc*K`Hf%L%^9$L&Zi+KDpQ" +Ka!3bKnNT5qcO>2>?P'0=B&:$6S89>[1H9r`oGL!d]3?rI"6as*=NgrHnNh!.+Wk!.+Wls*afmrdFcn +!e#QJrIFfqpON6ms+10"qgn]ts+C?)!eZ/Zr.Y0*!f)Sgr/1B0!0$o:pl><7"-Jb0PPg[BPlR'G +Q2R$JQNEPBRJEI=$6`F`VGrbVRNr,2OQ!-%mVEcQ5BFEDYKG'A.TH$Xd`I!pEm +J:N3&K7nr5LP^kFN/WdXOHPckQ'Rf*R[]k>T:r!TUo(&hWiW>*Yd(OA[^WfY]Y(tn_8=.0`lQ9F +bg"G[dF-Opf%8U/gYCWAi8EVTj5oFckiq?slg4$,n*fc9rpg*]o`"Lbp@n=\q#C0iqY^6hr;HTd +rdk*#s3q!u~> +JcC<$JcF*snc&LcrVZNhrqcZjr:pW2.L\uo&Ka!-^JqAW-rdt*"s+(-!s+'`ms*u"nDdd$RFE),,@:NhZ +Jt&6uR$a5*Q'@JqOc]NS%VTKgBnKu5ODAZRFaALcqLAElr-eBis*aWhs*OZirHnQlr-S3do6UI_ +qfr-drceEgp3?U_s*4Qf!d8^/piQFVpiQ4Ps)e-Zol:+R:/Cd_rD!5a"\ME[8kVeT9DqK_9E%W` +9*.^Y9D;*_92&#P9E%lg;ZBSp<)``nr_r_ms&&bnr)!Glr)!bs;,C+g;c6Lj;>tJ0Dt\)HDuXeV +DZFbRDuX_PDuXeSDuO_TDuO_SEVseMEVsePEW'qXF8p@^G5cU\Fo?L]GQ2pfGQ2pfH2W'fHhr-i +IK+cpIfb(KJ,Om#It3'#Jbt&rKD:,uL%g?$L]*&-M>rA?J9#RIDes0%AnGR`Ac?!6?Me+.@/aU2 +@f9g8AGKg:M?&J2L'!X+QMQjHQhQjKQC!s;R/EBORf&ZOCA)HBD#S;LDZ=VTE;acsEcZ;DFEMbM +GB\:WH?spcI=6TqJ:W<)KS>/9M2@+KN/is\P*2&pQC+)/S"6.CTq\?YVPgDnXKAY0Z*UgG\%0)_ +]Y;.s_SjF5aN;WLc-F\`daZguf@em4gtgiFi8WeWjlY^hl07L!m-X60n*olHncA@Srq-?dp\4[^ +s7u]kr;6HjrVcBfJcC<$e,Op~> +JcC<$JcF*snc&LcrVZNhrqcZjr:p!A2)R3J6UXRA:JXkgpeq&fp/:ifr_i_or)E\pr)3Pn!)i_l!)iMh!)ien!)ibmohtfgqbmGm +s&/VhrDEYn;Z0Jm;Yj>i;?0Sn;ZBYq<;';m<)WWks%r\l!)WVk"].3=3B&tt2[))s2E!KRpbr+/ +r\jX4r\ja7qDeF3s#9s9s#^BF3]T8#48V/94o[VC4T7DK4?btn5!;"j5!T!0#!G.54]"sNm83gY +r_WVj!)WJg!`2Zgr_WVlnkf?^qb[#ar_WMirDEVlmSEXTs&&ems&&eoo2>Wgr`/tts&8qqrDW_q +q,@8jnl#Nfq,78mrDihtrE'#$rE0,!r_WPh"ADH\8PB%grEfA.rF#V5qI9D5rFG_8!`2for_WYl +rDEYp<;oer<;'>i;uTeq<<#qu<;oer<;LA'C]8/LD>\;ODZFbTEH6)@F*)MHG'8(RG^4U]H[L6i +It3'#JqJ`1L51VBMN!LSO-#NfPa.Q%R@9V9StD^NUnjlcWN*&%Y->1;['mHS]"G\i^VRe*`Q$!@ +bKS5Vd*^:ke^i@*g=tE=hVd>Oj5]7`k32'olKdg(mdKW6nc&([oCW%T!quB_rqQNhs8)ZjrVZWm +o_sFAJcF4!J,~> +JcC<$JcF*so)ARcrVZQirqcWirV6Bds7ZEa!qc*UrUL$[nF6GGs6]mSrp9[N!:'RJ#O(@6k2tde +jSn0Kio/kSi8JV8f?rf[2CqNCE3r/gc;r/gc; +plPE7!07#;!06o:r/Lo@NfK0\oo/s1regi8M2D4fs+gK+s+UH*p4`3ps+UK+s+C<(qLo)T>$>'3 +>5MG/>$G*3=BJR&<`]3"!EN5"QJr#YTP*(lgqi:`=qi:o@NK0$[O7&&)NW4t9NW4t;NVeb2 +NW"h2NW+k;NK!jrs,?l8oo9$5qN1**q2kK7rK-u?pQ535qiClAP*5g,qN1N8rK@,Ar0%#@s-!AF +qi^uCr0%)Ds-*MIrKR8Gs-ESLr0I;JqO%8MrL!VQ!h,UJqj[YWqjdPSrgs%[rLiqZ!2B1^rhTCe +!2fanri#gqri6!t!35ps!3H1%qQBh$s02O.rj)L0!4Mj8s1&'=#J.R]]t_@u_>_:U_o0L4`l?'u +a90T.bg$.4rm1Vk(X^UWd*^:ie'umtf%8R,g"P39gtgfChYuI5iVqj:j8S->jWWBu[]#jgR$3\l +L4k)+HZs^YF`hkLMMR%AIWLO5Q'RGjgPseaqJZ7Ks)7mUrbhgTDu,RiOnb%;AHHCPA,Tj<@:3LA +?iFC3?2In+>PhUt=o;J&>Pqb+?2n71?P$UR@:E\UA7T7_AnPdjBkqMZs7MHHN_be#Pa.T&R[]k> +T:r!TV5L8lX0&P/Z*UgG\%0)_]t_A"_o9X:aND]NcHsteeCE.%g"P39h;@/LioB+]k3(smlKdg' +mI'H3nF?)?oCW%Ts7QHerV-BgrqcQirqu`no_sFAJcGcMJ,~> +JcC<$JcGTHo`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nknrHn*f]2m-Es$l0%3kjQ#:Zi8q5Q'@GoO,f0WM26n?pe_#c +pe:EV!)EDcqc+8,;,C(b:JOVV6:O:/77B[;8knYJqG.#cs%rAaqb[)aq,$i^rD*,`r_sDl:\dfe:\mid:\di`;>sGn;u9Jh;u]_q;>O2f;Zouq;,U5h_+>5MP%>lJ"/>lJ%/?M\"3?t!JQ@f9j9B)cKGBPD0orb;@H"`%pkD/O4i +D?OlsE,p!uF8U.[FoHRaG7JkCH?spbI!pElIXcitJ,OosJJNNJ@p;i.9M%ZA6pX"$4ZPP`4$5Sb +7/fIU7RBI077-ZHpJpZ_%CisZ]">Yh^;.S%_Sa=j`M,r`f8'p0%;sr`f;*s'>Y2 +ra-4E@: +JcC<$JcGTHo`"gfrqu]ks8)ckrqQNf!;?Eb=S24Vo()>?n*f]3m-O$%l0.rj`iV:esh\:!/m?H\%!2OdMiF_SO%&^:h2X]DK2=\c'#<\+[91[J[K5 +[/m_DrjMC*q6^10r3ZF1rO2[4rO)^6o="S+s1&$:!4`$;s1&*>osjk/pppI9qmuU5qR?C4r42j= +o""b2qn)m@rk8foZmNarR(Yn +rR:errmq)#rn.2&q:bi&s4dV1rn[_6i8FUnr8RS5rT+1EkNM-orTaFK!:9^P"RbaJnF?MK"7u0X +p\jmeq>^9lr;O8,'^OGqa2Ps<_m?A@VkK`WTU_XDS!j8B$(-X]_90m!ZDb(s\bNc3]@?lTOnk1> +Onc`k^Au(@^].pFAcH<@A,]s;@K0a5?iOI3?2@h'>PVJ">Ph\*?2n70?P?gU@:E\UA7T7_AnPdj +BkhF!D/T1Lr4`3Es1SKJrP&3Crk)$iPE_?!R$sM8StMdPUnsufWiN8)Yd(OA[^WfY]Y2(q_Sa@4 +aN;TJc-F\`daZguf@em4h;-uHiSrnYjlYail0@U$m-X60n*ol^ +JcC<$JcGTHo`"gfrqu]ks8)ckrqQNf!;?Eb?n*f]3m-O$%l0.1N;\_9N;JS8NfEgos,[#Frg!MLr0R>IrKmAJrgE\O".>UIS,8`USc##TSc,/YTDbGXT`Ch\U].(cV#[Ck +VuEXpWVrjsW;rsqX8]7#XoP[)Y5PR(YQ1s,ZMq62[f*Z8\Gj#V]">Vg^;%J"_8=(,_o0L4`l?'? +aN;TKbg$.4s3L\k!7CemrmLeqs472%s4[J-!8[Y2s5l.b$>5MP$>lS+0?N"4E?t!JQ@UiqZAS#IdBP;*pCMRd)q>^ASqiCH2:Qgp+Q'[l, +S"6.DTqeE[Vl6VrXfen5Za@0M\[oGe^VI_(`Q$!@b0/&Td*^:ke^i@*g=tH>hr*JQj5f=akNM0q +lg4!*mdKW6nac8Bo`"O`p&Ojcq#C0iqY^6ir;HTdrdk*#s8W+L~> +JcC<$JcGTHo`"gfrqu]ks8)ckrqQNf!;?Eb?n*f]3m-O$%l0.dq,$f]r_E2`rD*;e +rD*>ds%`Phr_WGg"].uj:f'sd:B+,c:&n#f9_V9]:@h6^:/C[\nk\gQr_`Ge!)NSh!)WYln50!Z +s%r_kq+q&eqG.#cqG?ubpepod!E)en;?0Yp;Z'Gp;Gg$G37qciu'r`oM/ra#P1rEfP4ra5Y5s'kq;rFQ4GBP;*oB`;`GC'JHiD/F0-D>nGQE;jnW +F8U.[FoQXaGQ2sgHN/jDj;Z]j/B)ZBAAH-0=@fKm:@/OC3?N+7,>l.b$>5MP$>lS+0?N"4E?t!JQ +@UiqZAS#IdBP;*pCMRd)q>]tar_req:Qgp+Q'[l,S"6.DTqeE[Vl6VrXfen5Za@0M\[oGe^VI_( +`Q$!@b0/&Td*^:ke^i@*g=tH>hr*JQj5f=akNM0qlg4!*mdKW6nac8Bo`"O`p&Ojcq#C0iqY^6i +r;HTdrdk*#s8W+L~> +JcC<$JcGTHo`"gfrqu]ks8)ckrV-Hgp@eLY=7l+To'u5g&B_& +g&.fKVtd4eWW&jp])T><])T;Q:!/m?H\$p0OdMiC]"l(p]tF<](rl7\,Wl:\,;%D_uI[R`W*sUa8O$Va8rpBaSs6p9`o()DDo_%tX +q#:'jqYU6'rtkOle]PnN_ofZtWMuegStV^DSXc1;Q^@];$^I%&\tkUoR$h2tFn3*;])'%frrA/R +Oo1CBOnZZi^\ttA^].pHB)Q<@A,p-<@fKm:@/OC2?N+7(>l7h#>lJ%/?N"72?iXX7@M30]A7]=a +B4tsmC27U$D/O92EVoe3^AG\F^AGTCPEhE"R$sM8StMdPUo(&hWiN8)Yd(OA[^WfY]Y2(q_Sa@4 +aN;TJc-F\`daZguf@em4gtglGiSrnYjlYail0@U$m-X60n*ol^ +JcC<$JcGTHo`"gfrqu]ks8)ckrV-Hgp@eLYr/^c9rf?K-!f`5#rf-r:rJgf8!0-l9pl562r/C]: +rf-o9!KE';NW4t8NW5"=NVJM6O84n*O8+h7O8P+5ZT_Y;]U@tA] +V#$nfVZ*LmW;`dqWrK$uWr&gsXT#@$XoP[)Y5YX)YlD!-Z2h61[/[T5[fEr;\HfaZ]tM.q^qp#e% +`?6'`Poj;a2l?DbKS5Urm(PiqU#5is3q,#f%0iQ#hn%ggtgfChV\=j!9*n9)rorfrqJZ(Fs)7Rls,m8CrK6r!+Yt:s'bq8r*TG0ra#5&r*/o#ra#P1rEoS4!+Gk9&n>H_AS#IdBP;*pCMRa'DJsK6qu?SUq +iCH2<0NT4Q^F52SXuLJUSOcbWN*#$Y->1;['mHS]"G_k^r"".`lQ9EbK\>ZdF-Opf%8U/gYCWBi +8N\UjQ5OekiqBum-O--n*fc9o()DEo_%nNp@nO\s7u]kr;6KkrVcBfJcC<$s8RT~> +JcC<$JcGTHo`"gfrqu]ks8)ckrV-Hgp@eLY=7l+To'u5O)j;,C'f:&n)W +;#=,i;#a>h:]jKi:f$p_r_N>dqGHubqGRGn;,R0fr)$>-7>5MP%>lJ"1>[:Y7?MRt-@0'hIrabt>s(D@F!GQ6HC&ViIC]8/UDJa6. +DJsK6rc8!Z"*A[-FT-F_G5ldcH2i3jHiJKqIXQ\DIk#tuIrf7-<`)[c8Ol375<_7l3BK8a4?>J^ +3BB2]3''/f4Zb\a0eOFq.f33?PDD% +?2n70?iOL6@K'^K@q9+]AS,RgBPD3sCM[j*DfB^ns6s"c;cJsGQ'[l,S"6.DTqeE\Vl?\sXfen5 +Za@0M\[oGe^VI_(`Q$!@b0/&Td*^:ke^i@*g=tE=hr*JQj5f=akNM0qlg4!*mdKW6nac8Bo^qhL +p@e7Zq#C0iqY^6ir;HTdrdk*#s8W+L~> +JcC<$JcGQGo`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nl##In*f]3m-Es$l0.9ljl>C[i8EJJgtLK7 +f@JI#da?Cdc-+8Na2Q!6_SEq"]XkY_[^q6QBdYsOH5B[MM[,Ag&B_% +g%D<=WVi^p\b3NF\]pPZH[pm1OI2Z<\\Gkl]`#JB\cK@QrOMj9!4VF*!4Da5o!S8"!4Da3rO)U4 +rj;d8[JmW7[Igp*\,No9[fX(K\,No;\b3K/\bWi:\biu6\G`o:[K*f7\GWo;](*?2])0)@]XtfR +]E5d\^AYhA_#2%F_Y:qJ`;R[T`r*mT`r=$Ua9B].bKJ,RrQP>foZmNarmC_nrR1esec+/!fDXA$ +g%jA$g]-%/h>Z74hr*GliV_^3j8J'Ck3(sll0834s6K^Os6U3^n*fc9nac8Bo_%qVq#C0iq>pNn +^&JW;gsO?f_oBI$X/DnlT:__RRhhH\Q^=)*Q^*l#PE_5mR-AMY4OS])0+fs8J,POoCO: +_#1tF_"kbEBEDgYB)ZBAAH-0<@fKm9@/OC2?N"0u>lJ%.?Mn.3?t!LC@Kp=QA7]=aBDuQPBkhF" +D/O60E,fo>r;ZT-!kuFarkSQKs1\HF;jEZ8R$sM8StMdPUo(&hWiW>+Yd(OA[^WfY]Y2(q_Sa@4 +aN;TJc-F\`daZguf@em4gtglGiSrnYjlYail0@U$m-X60n*ol^ +JcC<$JcGQGo`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nkelGn*f]3m-Es$l0.9ljl>C[i8EJJgtLK7 +f@JI#da?Cdc-+8Na2Q!6_SEq"]XkY_[^q6QBdYsOH5B[MM[,]SF2%+ +K)^o)OUdJVGD^'LE--;NJVB&EOSk.>OSt7%,NWP3#NrG%Ont.@Ockn,Ont18Oo:I@Oo:IAOoCOD +PP^OBPPp[EPQ$dHPPpaEQ2d0JQi36JQhm*LRJ`EPRJrWTS,8]USbnrSSc55YTDbGXT`Ch\U].(c +V#[ClVuEXoWW&psW;rsqX8T1#XoP[(Y5YX)YQ1s,ZMq33[C6%C!4`$=)7mGn]tV7s_84"*_o'F3 +`Q#pADfK`9DfBW5DKK)N9jC%i@qbe"qMas(df9/^oksejooT08r0%)BqiLej!bZ+W +ral+?s'u":s'bn7r*TG0rE\ksra#M0r*KM5@:B.E#%M1SAS#Idrb)[RC27X&DJjB3EH6-us87uU +O8+`8O,fKkQ^F52SXuLJUSOcbWN*&%YHY:<['mHS]"G_k^r"".`lQ9EbK\>ZdF-Opf%8U/gYCWB +i8N\UjQ5OekiqBum-O--n*fc9o()DEo_%nNp@nO\s7u]kr;6KkrVcBfJcC<$s8RT~> +JcC<$JcGQGo`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nl##In*f]3m-Es$l0.9ljl>C[i8EJJgtLK7 +f@JI#da?Cdc-+8Na2Q!6_SEq"]XkY_[^q6QBdYsOH5B[MM[*b;#!lf +;"[QS:@_Em>XCeF6:+127n?AH:]F/i:\[Zb:]=2a:]F8k;>sDg:\di]:]4&d:B45j:]=)i:JUmb +r(d8dr_EGgr_WGg!DlSk:]O;i:B+,d:B+&f9__?]:@h6^:/C[\nk\dPs&&Pf!)NSh!)MuYqbdAi +s%iPhs%`Yl:\dcc:\di`;>3ub;u]_q;>O2f;Z]io;>sJn;u]hm;ZKei% +=Tho4>?Y5.>Pqb*?2n.0?2e1+?NabF@:E^EAGp*DB4tsmBP@BZs(_RLr,)FN!cN$trc8$[r,hs] +rc\lJ%.?Mn.3?t!LC@Kp=QA7]=a +BDuQPBkhF"D/O60E,fo>r;ZRkpJh)i;jEZ8R$sM8StMdPUo(&hWiW>+Yd(OA[^WfY]Y2(q_Sa@4 +aN;TJc-F\`daZguf@em4gtglGiSrnYjlYail0@U$m-X60n*ol^ +JcC<$JcGQGo`"gfrqu]ks8)ckrV0Rjp@e1Po^qbGo'u5rODm:l*g/jo!JD(r3lU4r3lX5 +oX=\,rj_p9!k>_Krj`!=osjk/q7?U:qmuX6r3u^7!4Vm9r42j=n[\\2pq-I:!kl=^rP/-Cr5&6H +pVR!LrPefVr5\`Trl=oW"j+p0bKS3/blH&\cN)>kdJqYne,Rqsf)F;"f`'S"gA]k,g]610hZ)L5 +i;_d5iqqa9jSe0Ck3(sll2BlKlg4!;m0)kGnF5uIncSLUp@nR]s7u]k!W2f/rtt1Xbf@]@ahG'] +W2HD_T:VOBS=5n6QC+$TV8-VVPgDnXKA\1ZEpsI\@K2`]t_A"_o9X:ai_fOcHsteeCE.% +g"P39h;@/LioB+]k3(smlKdg'mI'H3nF?)?oCV\Jp%J+RrV6Egs8)Zjrqu`no_sFAJcGcMJ,~> +JcC<$JcGQGo`"gfrqu]ks8)ckrV0Rjp@e1Po^qbGo'u5plP<6qN(iBP*1riq2kE7rK@)@rK@,Arf[;FqNClB +rK@/Ds-*MIr072Gs-ESLrKdAJqO%;Nr0[MPs-`qWqjd\Wr1*YTrLWt[rLiqZ!huHapS7baq5"(g +rhoaori,ptri#mtql9^uriQ1&!3cC)rNH7*!3uO/"gbSC[C3OB\,EiD]"G_j^;.P#_8?2h%)g-( +`lH-@aiV]Lc-?75s3LYj#g^lEdF-IleCFQL"5);\g]$".h#ZBir89?hin)&QVOs9AP`h#]Jpi#n +G'A.RFE;MDEcH,>E,]f:E,]]4D/X<2DJrT]ASOb,A7bb"qi(9/!0$o:cis'u":s'bn7qd98-nm23#r*TG2!+Gh8(h7)eAS#IdB4tsmC27U$D/O92 +EH-#@FERQ^r/gf:pPr15QC+)/S"6.DTqeE\Vl?\tXfnt7ZaI6O\[oGe^VI_(`Q$!@b0/&Td*^:k +e^i@*g=tE=hr*JQj5f=akNM0qlg4!*mdKW6nac8Bo^qhLp@e7Zq#C0iqY^6ir;HTdrdk*#s8W+L~> +JcC<$JcGQGo`"gfrqu]ks8)ckrV0Rjp@e1Po^qbGo'u5fZ5stW<"[tpM8P)\N:\@H_:]=2b:]F8j;>sDh:\[c]:]*ud:]F8j:]=,e:]4&f:&[of +:]4,e;?'Gq:Jak`:]4&g:\mid:&[i]:&[o[:]F/i:\dcV:[q9];>3ua;Z]io;>O2g;Z]io;>sJn;uTbl;ZKeq<<-(s$Lu0r*0)(r`oP0?2\++?N=L5@0'hIrFGk=rb)@IBP@BZ");UeD#A/LD?4Zqrc8!Zs)\co +FEDYJG'8+SG^4R\H@(#;IK"[5Is,O6>#A-j8ju075<_4m3BT>a4#]2\3]R+!'K7p/3BK5\3B&rY +4?=uI2*!QO1cP20pJq8or`0Z:ZF%$I[^NZT\[f>b^:q@t_86,fs2,Ge`lQ9Db0%oOc-=P[d*L%b +dJhPseCE1(gAX;95QZdF-Opf%8U/gYCWBi8N\UjQ5OekiqBum-O--n*fc9o()DE +o_%nNp@nO\s7u]kr;6KkrVcBfJcC<$s8RT~> +JcC<$JcGQGo`"gfrqu]krqcZjrqHQhp@eLY;tT\Po'u5q6QBdYsOH5B[MY#L$W;ELh +W;NXpW;ERj\b`lM\[n*AI"@$1Od2H8Ye@]]]=PTL\c'&<\*:?m[ILX'[J[K5[JRB4[I^j)\,No6 +\,No;\b3K/\bWi:\biu7\GWi9[K*f6\G`u<](*?2](io8]E#YE^AbnB_#2%F_Y:tJ`;[aU`r*mT +`r=$Ta99W-bKS3/blH&\cN)>kdJhSmdf\+Mf%0iPr7M&&ptG`%s4dV1rn[e8i8ESQqr7J4rT+4F +kNM-ol2BlYlg4!*mI'H3nF5u=o(2JGpAOadq>U3kqu+A2)#NOJb/VH=`P/UVVP^)[St)7ra2,BT +Q^@];%@<s'tt9s'bn7pg<]#q-X/0raGe8s'l%>racjWB4kmkBkhF!Ci+'-DfB]:F*)MIGBa&d +pV?dCr4r?Is1V?tR@B_;StMdPUo(&hWiW>+Yd1UC[^`lZ]Y2(q_Sa@4aN;TJc-F\`daZguf@em4 +gtgiFi8WeXjlYail07O#m-X60n*ol^ +JcC<$JcGQGo`"gfrqu]krqcZjrqHQhp@eLY;tT\Po'u5q6QBdYsOH5B[MY!A-KDgE! +KDL]+OUR>/GDKjHDKBuJItN^ZO8b7?O8Y+:O6Vc)N<"q:NW"h9NW"n3NVnb6NW5%[j)hr*DMi8N"oYGIhWQ]dGhKn4Z"rH8EgS!B.sF)u@#DuaqX +E;segD/O60Ci=3.Ci"!.D.[U'F*3K?N;&>2N6_J"Dtn5MO8Y+:O84n:Oo:IBOoCFECMITurFl4D +!+u1@s().>r*o\7ra>M.oj7H$s'Yh7raPn;!+c(?(1q2lBP;*pCMRa'DJjB3EH6,BFEVkPrr;qY +qiCK3s,U$ER@B_;StMdPUo(&hWiW>+Yd1UC[^`lZ]Y2(q_Sa@4aN;TJc-F\`daZguf@em4gtgiF +i8WeXjlYail07O#m-X60n*ol^ +JcC<$JcGQGo`"gfrqu]krqcZjrqHQhp@eLY=7l+To'u5q6QBdYsOH5B[MGI#E;#!lf +;#O/e:%_9\:]=,[b!)WVkr_WJfq,$f]r(d2ds%r\js%`Ge +rD*>ds%`Phr_WGg##J)k:f'q`rD*AgqG%#brClu\r_E)]s%WPiq+gKVnPK6_peUrdr_aQqD/=', +DJsK6rc8!ZrH/$]!I&_dGlN'hH3&A?rI#Z7Ir]++=&D^d8Oc*55s7@m3BB/]:.n,I3]]8^r\t$@ +4#o;^r]('?3]f>#2[;<'3B9/_5XG9IpK%8n'="jJZEppF[C3QS\[oDd^:q@t_>M.Y_o9[EG'A00s7'%f<;f`mR$jG6SXuLJ +USOcbWN*&%YHY==[C3TU]"G_k^r"".`lQ9EbK\>ZdF-Opf%8U/gYCWAi8EVTjQ5Oekiq?tm-O-- +n*fc9o()DEo_%nNp@nO\s7u]kr;6KkrVcBfJcC<$s8RT~> +JcC<$JcGNFo`"gfrqu]ks8)ckrqQNf!;?Eb;tT\Qo()>?n*f]3m-O$%l0. +oXOb.q7?U:qmuX6r3u^7!4Vj8rOMs>n[\\2pq-I:!58BGrkJ6Dqn`0HpV[$Lrl+lVrQ"fTrl=oW +!m/U.rlkAds3C8_s3UenrmLbo!S#[!f)OA"f`'S"gA]k,g]610h>lI4huMa4iqqa9jSe0Ck3(pk +l2BoIlN$;Nm0)kGn*olHncSLUp%J@ZrqZZmr5/IWp#"3?b/D02\?;d/UnFD>_#1tHCBA6b +C&VfGBE)TBAcH<@A,Kg8@JsU$?i=C4@JjR9@q9-LAJf#lB4tsmC27U$D/O60E,fl^s+11Ms*t~> +JcC<$JcGNFo`"gfrqu]ks8)ckrqQNf!;?Eb;tT\Qo()>?n*f]3m-O$%l0.q%(r/^`:rfQu;q2tN8"Hek1OcfF#qN:`>r/pr@r/q#Bs-*;Bs-*ADs-*JI +s-*DGrg!JKrKmGJr0R8Is-`eP"IY^JR[a2E!1j%XqORVWr1Eq\pn7b`US@LXs.oLfs/,dnri#gq +!36!ss/Q!t!3H1%riQ7)riZ4's0)L.riu^6['[6K[f3c9\Gs,>\cf[Z^;%J__#V@O_u@U[`lH-@ +ai_cLrQP>frm*mWcd:"ad*U1gdaZgtf%8R-g=tB;gtgfChr!AMgrHn(Tq%O8OH#'LJ:;ijGBS/) +R$<\kM26n,DfBZ6E,TW3D>nGcD/Xr*oY6rF##"rF#Y6r*f_;A7Y[N(hRDnBP;*pCMRa'DJjB3 +EH-#?FEMbNG^98frfHl8qMn71R@B_+Yd1UC[^`lZ]Y2(q_Sa@4aN;TJc-F\` +daZguf@em4gtgiFi8WeXjlYail07O#m-X60n*ol +JcC<$JcGNFo`"gfrqu]ks8)ckrqQNf!;?Eb;tT\Qo()>?n*f]3m-O$%l0.c55nRWV4Q_o0R9rlP2_"j>-7c +-FW6cNqnFd*^=lf%8XS4o[_E5Q+Y +d1UC[^`lZ]Y2(q_Sa@4aN;TJc-F\`daZguf@em4gtgiFi8WeXjlYail07O#m-X60n*ol +JcC<$JcGNFo`"gfrqu]ks8)ckrV-Hgp@eLY;Y9SOo'u5q6QBdYsOH,9Xr7^ktor%ef +!3,srq5O%t&\>NaUm/NPFA;N]=YZL\c'&<\*:?n[ILX'[JRB4[JI<6[C3NQpU:"/rj_g6 +rj`!=osjh.q7?U:qmuX6r3u^7!4Vj8rOMs>s1&-@oXY"5pq-I:!58BGrkJ3Cr5&6Hpr!-Mrl+lV +r5\`Trl=oW"j+p1bKS3/blH&\cN)>kdJqYne,Rqsf)F;!f`0Y"gA]k,h#?11huDX7iVVX2j8J'C +k3(pkl0803$L@'FmHs?0n*oi:rpg0_o_/%Yp]1-hq>pNn`;_4Qg<[j\_o99qX/W"kT:MLAeAoA: +[Bd'$Lr-mVd^5*sOHP`fP`q@2Oq?]$(-OOSb1?OoUX>^\tt@ +^\knG^]/-LC]A/LC&VfGBE)TBAcH+Yd1UC[^WfY]Y2(q_Sa@4aN2NIc-F\` +daZdtf@\g3gtgiFi8WeXjlYail07O#m-X60n*ol +JcC<$JcGNFo`"gfrqu]ks8)ckrV-Hgp@eLY<:oeQo'u5q6QBdYsOH,9XSXoABo7Qsm +q1J@%%Zuj8HZb'SC2S$7H%(C%rfI/@r/UZ8lAkb$r/CZ8rf6]3r/CW7rf6u;!0$c6$&jk'NfB$Y +NfB%oNrP1:ORA2)OSb+9OT(C;OSP%8O91Q-P5^U>OSY+5[T_P2^U8+IVU]7.dV#[ClVuI'YPt^'Y6(r5Z2V$3Za@*I[f!W7\c98@]`5\K^VI\%_Z%FQ`;[^[`lH-@ai_g)bm2P? +cd:"bd*M^c@Xi7GiQVk0e>VD/O0+D/=(gD?OfmCi4(gDZalsE,bT3s,>/$qJZ4JrfI/@pl>95rK.&ArK@,A!g%57 +rbMOKs(VIGs(D@DrFQ">raYh7rF,P1rEoD/rF,V5s'u(>rad$\B4kmkBkhBuCM[j*DJsK6EcZ>E +Fa&%SH?sr;s8J,OO8Y)2S"-(BTV8-VVPgDnXKA\1ZEpsI\%0)_]t_A"_o9X:aND]NcHsteeC<($ +f\5*8h;7)JioB+]k3(sml0I^&mI'H3nF?)?oCMVRo`Fj]p\ssfq>^s+11Ms*t~> +JcC<$JcGNFo`"gfrqu]ks8)ckrV-Hgp@eLY;Y9SOo'u5q6QBdYsOH,9Xr_EMjpe_)h +:J^RVr(d&`s&\hns$6rY5sn%/7Rp$C:&IfY:B+,h;#*oe;#F2i;#F,b;"d]_:B"&g;#X5j:ARcb +:B+&f:B+,g;#4#m:esk`:f%$bs%iGc!)l;ZBVj;Z'Gp;GgBE;g\rFu7H"`/$lD/=%fD?4]r +rc8!Zr,hs]rc]*&G^4R\H@($eI#S-h8OZ'95lNn\3BB2\9hIlE6pj:/5t".47mAsn3;kiC +4$#D]2`WlX3rV,G3'0/`4[)"l4?rUAs&Bl=Yck:8Z*CU@['[9N\@K2_]Y2%n^VI\b_?Ror`Q-'A +aSs9bb0/#Qc-H=7rm1eqe(*%&r&k-G4[)(.56*nA;Z'Dj;?0Ye;ZCS4C]A/LC&VfGBE)TBAcHOj5f=akNM0plg4!* +mdKW6nac8BoCW%T!quB_rqQNhs8)Zjrqu`noDX=@Jc>`MJ,~> +JcC<$JcGNFoD\afrVZTjs8)ckrqQNf!;?Eb!VH!_nkJZDn*f]3m-Es$l0.9ljl>C\i8EJJgtUQ8 +f@JI$da?Cdc-+8NaMu3:_SEq"]XkY_[^Um&?8J:WN:P*_oE](`c6\,a#%[e-uu[/RK0[K*`0[K*f2[f!W6\GE]6\Gs,4 +\GEc2])T><])&r7\,Wl:\,3]6\c982\c989]DT>A^&PhF^\GVB_>;%D_uI[R`W*sUa8EsVa8lI4huMa4iqqa9jSn9@k5XTG +kiq@2lMp2Mm/QGUmdKW6nG_t\oCV_LrV6Bg!W2f7s$?DBf#l%Q_o00jXJ_tkT:;=?dDil/['Hoq +K#>p\af1&kXH6qSPE_/lP*(ojOcYWaO,]0ZNfK6cPEhDrWg/j\rk&0@b5_@#qiLlAo=k:@oY:=> +s1eSO!c;airbMOK!,;CFs(D@Dr+5n=raYb5nmVB(raYt=ral+As(D@Fs(N?cCMRa'DJjB3EH-#? +FEMbNGBnL\I!pJDs6RNhS=Z@GTqeE\Vl?\tXfnt7ZaI6N\[oGe^VI_(`Q$!?b0/&TcdC1jeCN7( +g=tE=hVd>Oj5]7`k32'olKmm)mdKW6nc&([oCW%T!quB_rqQNhs8)ZjrVZWmo_sFAJc>`MJ,~> +JcC<$JcGNFoD\afrVZTjs8)ckrqQNf!;?Eb!VH!_nk\fFn*f]3m-Es$l0.9ljl>C\i8EJJgtUQ8 +f@JI$da?Cdc-+8NaMu3:_SEq"]XkY_[^plP<6qN(c@P*5g,q2kH8rK@)@rK@)@s-!DGqNClBr0%)Ds-3PI +r072Grg*MLrKdAJqO%;Nr0[MPs-`qWqO@PVr1*YTrLWqZrLiqZ!huHapS7baqPF4hrhoaori#mt +rMfgsr2Th!rN6+&!3cC)rNH7*s0;R/s0Vg6!4Mj8$+ROV]"5Pf^;%G^_&^D1_o0L4`Q#s=aN;TI +bK\;Uc-=P[cd:"bd*L(crmD,%e^`7&f\,!5g]#tch;7#1\uqj!R[0/!N.le1If$>sd"DK'Q8E.DqJqi(T7b5VHZqJZ:Ls,m;Brf?f6 +r/^l>rfR5Dr/q"s!c;airbMOK!,;CFs(D@Dr+5n=raYb5nmVB(raYt=ral+As(D@Fs(N?cCMRa' +DJjB3EH-#?FEMbNGBnL\I!pJDs8J,KO$oM0T:hmQUo(&hWiW>+Yd1UC[^WfY]Y2(q_Sa@4aN2NI +c-FY_daZdtf@\g3gtgiFi8WeWjlY^hl07L"m-X60n*olHncA@Srq-?dp\4[^s7u]kr;6HjrVcBf +JcC<$!<7Q~> +JcC<$JcGNFoD\afrVZTjs8)ckrqQNf!;?Eb!VH!_nkJZDn*f]3m-Es$l0.9ljl>C\i8EJJgtUQ8 +f@JI$da?Cdc-+8NaMu3:_SEq"]XkY_[^3ua;ZK_p;>X8h;u]bq;>sJn;u]hm;ZKen<<-(u%=o;J$>Pqb(?2\+0?iOI4?iFI5@K0g8A-6CTAnV!Srb2@IrbMFJ"`8-pDfB^qErL,CFE;PG +F`hkOG^4RZH$O^^I!]gB>ut!"9h7`@69dRq4?>M`3D2q66ps@+6U*t.7RB3t3&WH43'0/^2`L[p +rAbFG'A.UH?sseIfKH7;ad.IT:hmQUo(&hWiW>+ +Yd1UC[^WfY]Y2(q_Sa@4aN2NIc-FY_daZdtf@\g3gtgiFi8WeWjlY^hl07L"m-X60n*olHncA@S +rq-?dp\4[^s7u]kr;6HjrVcBfJcC<$!<7Q~> +JcC<$JcGKEo`"gfrqu]ks8)ckrV0Igp@e1Po^qbGo'u5q6QBdVqO,f1fgA[rJVY6qa +W;iji\c92>[g]Z_Y^1_JLlRUaTW#n[\\2pq-I:s1SHHrP/-Cr5&6Hpr!-MrPefV +r5\]Ss2Y#Xs2b;abPo`bblH&[cN;J@dJhSmdfItKrmq,$qq1r%ptGc&s4dV1rnd\4s53t;ioBsr +qW%P9s5jFHkih:0l3ckDm-X3.mdKW6nc&(]oCV_MrqHKhrqZZmrlG*pnD;O6aMu!.\$2j0VP0WO +R[_L9]\\[\H%_';P)k]cNfK1uNXq89PGkI[X-Am:Q^ODV]=Q)`qN1W; +pqQjCotLL@r4i0F!P`RPDZ=PRD#J,NC2%D\B`D`FB)H6>AGp$(@fBm:AGp*>AcQKCB`DcLC27U$ +D>nDdDfKc;F*)MHG'A1VH@($fIXltKm(bu[T:qsRUo(&hWiW>+Yd1UC[^WfY]Y2(q_Sa@4a2lEH +c-FY_daZdtf@\g2gtgiFi8WeWjlY^hl07L!m-X60n*olHncA@Srq-?dp\4[^s7uZjr;6KkrVcBf +JcC<$!<7Q~> +JcC<$JcGKEo`"gfrqu]ks8)ckrV0Oip@e1Po^qbGo'u5q6QBdVqO,f0iSb&BOSbRj1 +K)C8mOT1@ONF@ENBkqX1G^P*sNKB5"Nr"h7NW>.;NW>.8Nr+h8N!>3!N/`gWNqJD1N;eh9Nr=q; +N;/D4NW>(OSY+SGJfUT)5/ZT_P2^U8+IVUB%+cV#[Cl +VuYi^V@S#_8=(,_o0O5`l?'? +aNDZKbK\91c2Q#nd*L(ccd:&e^rF*g=k<9gt^`<_R6;6S!TG%NJW@?I=-6]G'.nmP)bKW +L4XB&LRXZ`H#S7?=[c(k6FG'EqFaSu6Xpi$1MrK7)@ +s,Zo7r/^i=s,m>ErK.(urbhaQ!,VUL!buF`rFl4Ds(;1?rabt;lXKj'rabt=s(27Drb2=G"DV^f +Ci0/h'5ql1EcZ>EF`qtRH$XgbI=?]ss8J,KO$fM2TqS6WVPgDnXKA\1ZEpsI\%0)_]t_A"_o9X9 +aND]NcHjndeC<($f\5'7h;7)JioB(\k2tmll0@U$mI'H3nF?MK!V>s_o`Fj]p\ssfq>U6gqu6Nl +rUg)?s+11Ms*t~> +JcC<$JcGKEo`"gfrqu]ks8)ckrV0Igp@e1Po^qbGo'u5q6QBdVqO,f1u:]F8e;#jGk +:[UsT:B+,c=8Z+u<=Dhj6pX+,6qBd<8P;eJ:&n)h;#F,h:]aEh;#F2h;#O2c;"[W]:&n)h;#O/i +:ARcb:&n#f:B"&g;#4&h:]sQj:esmc:B+,d:B+&f9_V9]:@h6^:/CUZo2"jP!)`Mf!)NShs%i#Y +qbdAis%iPh"A_ij:J^g^r_NAeq,-obq,78kr_`PjqbmPo;,RA^&PhF^\GVB_>;%D_u@UR`W*sUa8s1nBDrkA-A +s1\EGrP8GP!,qgR!c;airG)ILBkdNZrb)7Cqdo_:qd]G2qd]V9r+5n?s(D=E+DGS*CMRa&D/O60 +E,flY +dF-Lnf%8R.g>(N@hr*JRj5oFckNV6rlg4!+n*fc8nac8Bo`"O`p&Ojcq#C0iqY^6ir;HTcrdk*# +s*t~> +JcC<$JcGKEo`"gfrqu]krqZWjrV-Hgp@eLY;tT\Po'u5=n*fZ1m-Es$l0%3kjQ#:Zi8=6 +KCXWhKCt<mFlVuEXjWW0!r +WrT7"Xo#:"YQ(j,Z2V$3Za@*I[f*ZS\@K/]]"G_k^VI\%_SX4.`5KX6`lH-@ai_fMrlkAds3LPg +"jtcHe'uqIf)aOXrnC'#bdssPS=,b,OGnpGJ:2fhFEM_pP`C`[L5'hhOHu/nI;3nIECEi.6s3r2 +Ak,@%Anu:(F`r"S7nH3E>(;'RE,fo?Fa&%TH@*^4s).aQ!,hdSs-!>Cr/^o>pQ#04r/gl>s)7sV +rGD[RCi'&c!buF`rFl1Cs(;.>rFGe8q-s52rabqYdF-Lnf%8R. +g>(N@hr*JRj5oFckNV6rlg4!+n*fc8nac8Bo`"O`p&Ojcq#C0iqY^6ir;HTcrdk*#s*t~> +JcC<$JcGKEo`"gfrqu]krqZWjrV-Hgp@eLY;=sJNo'u5=n*fZ1m-Es$l0%3kjQ#:Zi88:/+>N6:3t#4$>Vc3&jT&7mo[25XRk+77BI'3B/iL*[rTl/2B+D2DR-K3]fMi5X[t! +2`Nob91hf?5sds<6jH.N7]WVlXfhW+'Vg^:q@t_>_:Q_o9Xp`sTo.aN;QH +bKS2TcMl,nd*^:ie(44Us&A_kku.P#!,qgR!c;airG)ILBkdNZrb)7Cqdo_:qd]G2qd]V9r+5n? +s(D=E+DGS*CMRa&D/O60E,flYdF-Lnf%8R.g>(N@hr*JRj5oFckNV6rlg4!+n*fc8nac8Bo`"O`p&Ojc +q#C0iqY^6ir;HTcrdk*#s*t~> +JcC<$JcGKEoD\^erqu]ks8)ckrqQNf!;?Eb;=sJOo()>?n*f]3m-O'&l0.fo?[H`s3^horR1brrmq)#qq1r%ptGc&s4d\3hVS7hs53n9qVqD4!9F+? +#3P+3kih9qrp'OMrTsaUn*fc8rpg0_o_%tWq#C0lqu$H;s%)\=dE9MK^r3[dX/;hjSsu4Vms)%dPrbMOKs(VCEs(D=CqITM6rF>Y6qdoe>s(D:D,ACn-CMRa& +D/O60E,fl^s+13#~> +JcC<$JcGKEoD\^erqu]ks8)ckrqQNf!;?Eb;tT\Qo()>?n*f]3m-O'&l0.5C +KCb3)Nsq"UH?s4>E,g&IItN^YNr+n9NrG+;NW>.8Nr+h8N;nh9N;nk;NrG"((7NrP1:OR\A3OT(=9OSk19OT1I;OSP%8O91Q-P5^U>OSY+;P5UO@P5UOCP5^[BP5^[D +P5^[FPlHsFPlI$IQN!6KQMd*GR/`TPQiNQRRK/iRS,f,XSGSlUT)>5[T_G,]U8+IVUB%+cV#[Ck +VuEXpW;rsrW;rsqWrT7"Xo#:"YQ(j,Z2_*5Za@*I[C6%C&@f9]]"5Sh^VIY$_8=(,`5MYo"NJL' +aNFM*rlkDe!m]-@_G687Q7GDK0fCG^2eN7nl["J:N2iE,p&DGBe@YHc?$aDZ+JSDK#E8s,m2? +s,Zu9r/^c;rK7,"!cW'rrbhaQs(q[Ms(_RJr+Q+Crau" +JcC<$JcGKEoD\^erqu]ks8)ckrqQNf!;?Eb;"XANo()>?n*f]3m-O'&l0.)"WpK.>p$WTAV6UF"*7Rp!?9(GaV;#F,f;#=,g;#X8e:]X?gr(d;hqG6u`!`)WhohYK\!_lEb +r_NJhqG@Dm:JXe`:]*rf:\dcc:&[i]:&[oZ:B=3dpJ1js&&horDNVn!*&_lqGdSts3^qsebD<)<;0>`;Z9Vp;Z9Ms;K6\qDf>Vms)%dPrbMOKs(VCEs(D=CqITM6 +rF>Y6qdoe>s(D:D,ACn-CMRa&D/O60E,fl^s+13#~> +JcC<$JcGHDo`"gfrqu]ks8)ckrV-Hgp@eLY:\=8Lo'u5A^&PhF^\>PB_>;%C_uI[S +`W!mTa8^\GV@^\bbE^\tnB^ArFG'A.TH$XgbI=?ZrJV&N-L5(M@n%_DeUSOcbWN*&%YHY==['mHS]"G_k +^r!t,`Q-'BbKS8XdF$Fme^rI,g>(N@hr*JQj5f@bkNM0qlg4!*mdKW6nac8Bo^r.U!quB_rqQNh +s8)Wirqu`noDX=@K)^?~> +JcC<$JcGHDo`"gfrqu]ks8)ckrV-Hgp@eLY:\=8Lo'u5(7NrP1: +OR\A3OT(=9OSk19OT1I;OSP%8O91Q-P5^U>OSY+;P5UO@P5UOCP5^[BP5^[DP5^[FPlHsFPlI$I +QN!6KQMd*GR/`TPR/`TSRK/iLSGSlUT)5/ZT_P2_U8+HWpS7baqPF4hrhoaori#mtrMfgsr2Th! +rN5t"r3$1+Z*F;6"LGJB[C,qA#.V4S]">YirkJWP_SX4i`;dgV`r='XbQ#fcc2Q&fciVP@dJhSo +e.pQdf@ej(]U=^l#184I0'D/aT? +G^2eM7nl^,J:W9%E,]f^s+:9$~> +JcC<$JcGHDo`"gfrqu]ks8)ckrV-Hgp@eLY:\=8Lo'u5crD6.u5r*9/*q-O&-s'Yk8!b,YLrF?%BB4kmlr+H7JC2.O!CAr#JC^"ZnDK'T8rc7sYrcJ-_s*.mi +AmSS;9h\/K6ps7)4?P\e3]K)i7n#d25WqG%6UX."4ZG;P*@WHj/M]4<2)@-M3]oVl6:3^k3'KN" +91_]I5sn"+6q'L377O2RWiN5&Xfee.Y-5%5Z*CXC[C3RD])TAd]Y2%n^VI\&_Sa:0`Q#p4TSM^q,I)epJUofr_WZ9rc.sWs)7mSs)%dPrbMOKrb;=Erb)1Al"0j+ +s(D:Ds(MIJrbMOM+)Pn5DfBZ8EH6,BF`qtQG^4U^I!pHnJ:W<)KSG5;M=4A4U8+N]Vl?\tXfnt7 +Za@0M\[oGe^VI_'`5Td^s+:9$~> +JcC<$JcGHDo`"gfrVZTjs8)ckrqQNf!;?Eb!VH!_nk/HAn*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-+;PaMu3:_SEq#]Xt_a[^EHIYcb+/Wi2hlUnXQTSt):;Q^*euOo*i(gAfk+f_;?9 +VuN^f\Gs#I[C48F]R#-\M34$kUTa[-r4)d9pU113[^EO;[f*W5[/IE4ZiIH,Zi[YB[/@?%[f3c4 +[edK4\GE]6\Gs,4\G<]2])B2<](rl6\,Wl:\,*W6\c982\c989]DT>A^&PhF^\>PB_>;%C_uI[R +`W*sUa8hr*JQj5f=akNM0qlg4!*mdKW6nac8BoCW%T!quB_rqQNhrqcQi +rqu`noDX=@K)^?~> +JcC<$JcGHDo`"gfrVZTjs8)ckrqQNf!;?Eb!VH!_nk/HAn*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-+;PaMu3:_SEq#]Xt_a[^EHIYcb+/Wi2hlUnXQTSt):;Q^*euOmnn@Sc,)AKCt<= +OcYZbO/R8XB527%Fa8@eLlRMmO8b1;O7\J/NW4t:MuSb7NW+n3NW4t8N<#"0NV\Y8NV\\7O8=t+ +O8"b6O8=t#.qO^^VIY$rkeWPs2=uXrl>)]rlb;brltJhqp>Ajs3^tteCFQM9#J'; +URRU8OH5shh-BgtU&A86"$F`r%%84QBKIXm!# +IrKCIF*)SMH$Xd`_uKXPrbq[rqi^r@s,d5@q2Y<4rf@8FFE;JCrc.sWs)7mSs)%dPrG2FJs(V@D +rb)+?ok"&5rb)1Cs(VLJrbMOM!,_^Q+)c+hr*JQj5f=akNM0qlg4!* +mdKW6nac8BoCW%T!quB_rqQNhrqcQirqu`noDX=@K)^?~> +JcC<$JcGHDo`"gfrVZTjs8)ckrqQNf!;?Eb!VH!_nk/HAn*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-+;PaMu3:_SEq#]Xt_a[^EHIYcb+/Wi2hlUnXQTSt):;Q^*euOo.uT;#X>i;#!iN +:B+,\=8l5-5X@_&6:41384cPS:&n#c:An#f:]4,e;>a8j:\mod:BXEg:Jama:]4#j9hnJ\ohY?X +s%iMgr)*Jjs%`\m:J^pas%iGc!)sDl:]+#k:Jak` +peLibqG?ubpJUids&/hnqbm>j!`DlmrDNVn!*&bmr)Ebub7s'u"<"_D:YB4u#XBE2cGC'&0cCAr#KD#\APD?4]rrc7pXs)\6`rcT&l@9ci3 +9M7lE6UF"#4$>_g3&jN$7n*DC9g_356UEsu3B/`B*@39h0JtjK1Gh'Q3^#_o6T6q`5!DY58P2Q@ +6:4./7R]^577O2RVlHbtXK8P+XKAY/Yd(I>['dhr*JQj5f=akNM0qlg4!*mdKW6 +nac8BoCW%T!quB_rqQNhrqcQirqu`noDX=@K)^?~> +JcC<$JcGHDoD\^erqu]ks8)ckrqQNfs7ZKcs7B%Wo()>?n*f]3m-O''l0.A^&PhF^\>PA_>;%D +_uI[R`W*sUa8c!7(2^s3UenrmLbo!7_#!rn%&"s4R2$s4dS/s4m\3rnmb6 +!9*b5rT!q=rT4"@s6'IIrosOMm/?>Omf2bUnG_t\oCV_MrqHWlqYU3hdJlf)hTj3``P9'nYH"Fq +URdpDS^#$_['?p>OG'dZb-IOsX`\8iCg1t2M/?'cK8>YRS"64E;c-OoN2ikVW0nDsDfB]9EcZ>EF`qtQG^4U]I!pEmJ:N6(K8#&8Ll%"JNK0(j^d"WlVl?\tXfen5Za@0M +\[oGe^V@V%`5Tds_p&F^c +p\jmeq>^ +JcC<$JcGHDoD\^erqu]ks8)ckrqQNfs7ZKcs7B%Wo()>?n*f]3m-O''l0.">OH9'pq2GB5rJU]7rf-l8pl5<4r/C]:nrErfQu;qiUf>rK7#@rK7)Bs-*;Bs-*ADs-*JIrfd;Frg!GJ +rg3SLr0R8Is-`bO!1EhT!1WYOqORSVqk*n]pS%P[pS._aq5"(grMTXnri#mtri,ptql9^urN5q! +rN?4*riuL/"gbSC[C*IA[g'@Q\\#Jf^AbqH_Z%LR`W*sWa8jB^bPo`cblZ2:chu/idJhSoe.L6Z +^9a`0R[B;#NJN7=I=6Barc:#cOcG9SLOsSaKp.[OGAqt8:/+SW=C>cB7n.$$DJsW?G]u_K9h]JU +JUr;iEH-&AG'A4UH?t"Us86d7DuPjrOo1CAOoCI@O8Ft4NrY:@FT6F^ErL(YDuahTDZ=SRD#J/K +CB&#EB_uH;B)H<=B`;`GCAr#KC]J>ODBWq;EH-#?FEDYKGB\:WH?sseI=HctJqJ]0L51SAMN!OT +nW,o1VPgDnXKAY0Z*UgG\%0)_]t_=u_SjF6aN;WLcHjkbe'uq"f@em4h;-uHiSrnYjlYail07L" +m-X60n*olHncA@Srq6 +JcC<$JcGHDoD\^erqu]ks8)ckrqQNfs7ZKcs7B%Wo()>?n*f]3m-O''l0.!=8u;36U4"+5XRk+84ZsDl +:]+#k:Jak`peLibqG?ubpJUfc!)ienqbm>js&&hor)3Pn!*&bm!*&nsrDir#l7n'?N+=3@/j[7A,Tp% +F`D&&>#S6m8Ol0:5X.Fs4?5G_3_;k37R9:(6iKCm5s.1d2D61!.4Zo(2Dm?J2E3i^4[2;&2`Eo` +7SE_Ps$@;b6q0U66psI48>`8^W2ZesX8]1WXfek2Yd(L>Za@-K\%&u[]">Vg^:q@s^qmn)_o0L4 +`lQ9Db0%oOc-FV\cd:%bd*U1ge,DQ04o87K<;]Yp;Z0Mo;Z'JmFT6F^ErL(YDuahTDZ=SRD#J/K +CB&#EB_uH;B)H<=B`;`GCAr#KC]J>ODBa"*Yd(OA[^WfY]Y2(p_8=.0a2lBGbg+P]dF6Uqf@S^0gYL]Ci8N\UjQ5Oekiq?s +m-O--n*fc9rpg*]o`"O`p&Ojcq#C0iqY^6hr;HTdrdk*$s*t~> +JcC<$JcGECo`"gfrqu]ks8)ckrV-Hgp@eLY:A"/Ko'u5=n*f]2m-Es$l0%3kjl>C[i8EJJgtUQ8 +f@JI$da?Fec-+8OaMu3:_SEq"]XkY_[^fo?[E_s3^kprR1esec+/"fDF5#g%X2#g]#t0h;7#fhZD`piVMR4j8\3=jT+HB +kPscGl2U&Klhp/Mmf2_VnF?MK"7u3Zp\spjq>:*grm^s5o]FcL`lPm3]s"H8UnaTQS=?(n`4E=] +[',XI\&un$T7a5!G%#07F*rk#:elXuOcu9)TUf"YD6^Ai?TFT6C^ErBtZE,T[nDZ=SRD#A)JCAqr1B`DfGCAhoLCi+%gD?4Zprc''$F*)MHG'A.T +H?spcI=?ZrJV&N-KnbA>M2R=PNfT!_jVl?\tXfen5Za@0M\[oGd^;%M$`5Tdo(2MQp&F^cp\jmeq>^s+C?%~> +JcC<$JcGECo`"gfrqu]ks8)ckrV-Hgp@eLY:A"/Ko'u5=n*f]2m-Es$l0%3kjl>C[i8EJJgtUQ8 +f@JI$da?Fec-+8OaMu3:_SEq"]XkY_[^e +&!)g4NH9hbBkqX/H$t0rN;S_:Nr"h1NqeS6N;\\7N;eh8N;/A4N9lQ"NW>(:NWG3$rf?o;nrEd4 +rf?f8r/^]9s,m)B8s,m>ErfQu;qiUf>rK7#@rK7)Bs-*;Bs-*ADs-*JIrfd;Frg!GJrg3PK +rKm>I!1E_O!1EhT!1WVNqjm\Wqk*k\pn@Y\pS._apn[tfrho^ns/?!uri,ptqlBaur2on"r3$1+ +Z*F;6!OK04[JdT7\-TXV]=bkm^qdec_YqCZ`Q#p3QLP'\dMNj9WG\;G9<_-"m='oQO7RUd!DK']@G]u\K9hg+fJ:W/g +EH?8FGBnFZH@:1Vs8-^6OT1C@OSt=?P5^UAOSk1=Nq\V7FoHL_Er^7ZE<:)tDuFSRD?"GMC]8)J +C$010C&VlGCBAnDRDfG\q+EDOFFEMbNGBeF[H[L6jIt3*%K7nr5LP^kGN/`jYOco*Yd(OA[^WfY]Y(tn_8=.0a2lBGbg+M\dF-Opf%8U/gYCWAi8EVTj5oFckiq?slg4$,n*fc9 +nac8Bo`"O`p&Ojcq#C0iqYU0hr;HTcrdk*%s*t~> +JcC<$JcGECo`"gfrqu]ks8)ckrV-Hgp@eLY:A"/Ko'u5=n*f]2m-Es$l0%3kjl>C[i8EJJgtUQ8 +f@JI$da?Fec-+8OaMu3:_SEq"]XkY_[^O)h:]+#i:Jh!cs%WVk:f-s`r_EJf!)EAd +s%`MgpeLfar)!8f"].uj:f'sc:B+,d:B+&f9_V9]:@h9]:&n)a:@h9D;#a>j:&n)V;#=,i;#a>h +:]sQj:esm_:B"&c;#4&`;Ya5k;Z0Jj;YsAo;GgZa@-K\@B)\]">Vg^:q@t^qmk(_Sa=3 +a2lBEb08)Sc-FSZcd:%bd*U1hq`b$\q,R,fs&Jtrr_rhrr_rhpr_ri>rcJ0]!-8$X!cW'rrGMXP +s(qUKrbDFHk@jm0rbDCI!c2^jrb_aTE;ji"EcZ>EF`qtQG^=[_I!pHnJ:W<)KS>/9M2@.LNK0'^ +P4MU>VPgDnXKAY0Z*UgG\%0)_]Y;.s_SjF6aN;WLcHaeadaZguf@em4gtgiFi8WeWjlY^hl07L! +m-X60n*ol;o()DErq6 +JcC<$JcGECoD\^erqu]ks8)ckrqQNf!;?Eb:A"/Lo()>?n*f]3m-O''l0.n[\\2pq-F9!kl=^rP/*Br5&6Hpr!*Lrl+lVrQ"cS +s2Y#X"j+p0bKS3/blH&[ci;AldJqYne,Rqsf)O@uf`0Y"g&Tn,h#H11hYuF4huMa3ir.m;jSe3? +k5OQDkl9lKlKdd6mJlVSn,MnUncSOWp\4[^"8_rorRLoYmGQ:3`PfO(\$)g0USFENrgGde_Rd+Z +ZEKLJ^r+=+Tnfq6Ip-B0:O7hU:Jlh#NK]m&TV#+Z^\5AEGBS.PFoHIaF)l="E<:)tDuFSRD>nALC]8)HC%5m8C&VlGC]A5ND>nDRDfG\q,][sJ +FEMbNGBeCZH@($fIXcm!JqJ`1L51VBMi +JcC<$JcGECoD\^erqu]ks8)ckrqQNf!;?Eb:A"/Lo()>?n*f]3m-O''l0. +plP64r/gr@s-!ADplPB8r0%#@r0%#@rf[;FqNClBr0%)DrfmGHr075HrKdGLr0I8IqNq8Nqj@DO +s-`qWoUPcKrLWnYs.K+[rM'%]!2TFe!2fanrM]^p!36$t!35pss/c+"r3$"%!3lI-s0D[2rO)U5 +$+ROV]"G_k^VIYa_>qLP`;dg^a2l?Db0%oNrlkAds3Chpcd0tbrmnGOOSt7>OT1I@P5g[@OSk1>Nqn_=GBS.PFoHIaF)l="E<:)tDuFSRD>nALC]8)HC%5m8 +C&VlGC]A5ND>nDRDfG\q,][sJFEMbNGBeCZH@($fIXcm!JqJ`1L51VBMi +JcC<$JcGECoD\^erqu]ks8)ckrqQNf!;?Eb;"XANo()>?n*f]3m-O''l0.hqbcu^r(m;es%rJds%`Pf!)EAds%`MgpeLibqb[2fs%r\j +!DlSi:&n)c:B+&f9_V9]:@h9]:&n)`:@q?E;#a>j:&n)V;#=,i;#a>h:]O;j:]O;d:B+,d;#4&` +;Ya5k;Z0Ji;Z'Gp;GgQ.h+>PMJ% +?2.b*?NjhG@:E_VrFGq?#\RgbBkV0oBPI?Yr+cRSD/F00E,fo=rcZaI3M\@B)\]">Vg^:h7q^qmk(_Sa@5aN4D'#Kt?8bKS5U +cMYuid*gA@55\IWnALC]8)HC%5m8 +C&VlGC]A5ND>nDRDfG\q,][sJFEMbNGBeCZH@($fIXcm!JqJ`1L51VBMi +JcC<$JcGBBo`"gfrqu]ks8)ckrV-Hgp@eLY9_@rIo'u5n[\\2pq-F9!58BGrkJ0BrPA?Ipr!*Lrl+lVr5\]Ss2Y#X +s2b;abPo`bc2Z)\ci;AldJhSmdf@nsf)O@uf`0Y!gATe.h;7#fhZD`piVMR3j8J*>k5OQDkl9lI +lMg,ImJlVSmfDqJrpp*]!VZ9ep]UEir;HWIrtb@kfZ_CU^VmdgX/MhgTpqO>S'&[^\GicgXcnRW +bJq2kLmO?k=\!d3G_:uJ;M'X\PF%i6T28E\Pks)%aOqeQ+EoP+5 +JcC<$JcGBBo`"gfrqu]ks8)ckrV-Hgp@eLY:%\&Jo'u5O:[J7NK0!,IqED1D0'lII=d:KO8"\0N<"q8MuS_9NV\UpNUi,-O8=t/NrY:@O8"b7O84n; +Onb%4Oo1=@OoLUDOnb%8Oo1C@Oo1C?OoLUEPPUIBPPgUDPQ$gGPPpaGQ2HsJQi*0IQhm*LRJW?S +R@9S6S+WmFmVu*Ob\9uEc,VX4^16U@VJ,!@qB=kF*2_R84c9F97VPDIW9=IFEMhRH?sse +J%bm\D>TFmO8k=AOo:IBOnk+3NrXG(GQ2gdFo?C`F)l="E<:)tDu=MQD>nAKC]%r>C&D`DC]A5N +D>e?'DfBZ8EH6,AFEDYKGB\:WH?sseI=?]sJV&N-L5(J?M2R=PO,oEdPEhH#R.cS-WN*#$Y->1; +['mHR\\#Mg^VRe)`Q$!@bKJ/Ud*^:keCN7(g=k?^ +JcC<$JcGBBo`"gfrqu]ks8)ckrV-Hgp@eLY9_@rIo'u53ub;u]bo;>a>i;u]_q;>a>l;u]hn;ZKeq#0=BSd1>$G37>$G50 +>QA(.>l7n,?3":0?N"47?t!MR@q5LK$>!g]BP;*oBPM6qqeH"DrbV^TE,bess)UqO@pE,59hS&H +6UF"#4[)%j3B/ui84Q'85=%J#6:4%)4?5>Y0e=:l/1iJ23%m*F2``ua5=7dr2`YHY:;ZF.*L\@B)\]">VfrOiWS^qmn)_o9X9aN;TI +rQ>8dc-?75rm(VmdeuB*UfkiqBum-O--n*fc9 +o()DDo`"Lbp@n=[q#C0iqY^6hr;HTdrdk*%s*t~> +JcC<$JcGBBo`"gfrquZjs8)ckrqQNf!;?Eb!VH!_nji6>n*f]3m-O$%l0.Q'e2C[(-+ErO2L/pU:+0r3QO5[']h=ppBh(o!\G)rO2R3qmcR5rO;j< +oXOb.q7?L7rOVg7r3u^7q7-C6!4q^2s18!;qn)pBrkABHp;$XCqSN$Frl"cSs2OuWqSrQUr5eo[ +!QrUbbl,cdcL]B]d/VMndf%VueCE.$f@TiNs4R2$!8IM.s4m\3rnmb6!9*e6r8[_:s5s=Ds60LI +rp0LLrpBjVnF6GJ$hO#_p@n@Wq>1$frn7s(q[OrbhaS!-%pWs)KQ0FEDYKGB\:WH?spc +I=6TqJ:W?*KSG5;M2I4MNK9-_P*;/sQ^F52SG9l^WiN8)Yd(O@[C3TU]=bkm^r"".`lQ6DbK\>Y +dF-Lnf%8R.g>(N@hr*JQj5f=akNM0plg4!*mdKW6nc&([oCW%Ts7QHerV6Egs8)Wirqu`noDX=@ +K`?Q~> +JcC<$JcGBBo`"gfrquZjs8)ckrqQNf!;?Eb!VH!_njrT,riZ1&riuL/!OK03 +[JdQ<\@K2^]Y42`b0/!-bl>ofcMZ#fcp5@RWM,iKPE1][K7JAuH?F:K +Ec[J+NJWCDJp23fK9MIPH>.J +JcC<$JcGBBo`"gfrquZjs8)ckrqQNf!;?Eb!VH!_nk&B@n*f]3m-O$%l0.s55s@_(69[\$4?>DY0eF@n/M8Y22_[-K3&s&`5HaY->1;ZaI6O\\#Mg^VI_(`Q$!?b0/&TcdC1ieCN7(g=k?s_p&F^cp\jmeq>^s+LE&~> +JcC<$JcG?Ao`"gfrqu]ks8)ckrV07ap@e1Po^qbGo'u5H@:@#NKBHtVm3_?r3lC.pU:+0qR$4-q6]n(o!\G)rO2R3qmcR5rO;j +JcC<$JcG?Ao`"gfrqu]ks8)ckrV0:bp@e1Po^qbGo'u5H:URs:/+B4JUh`ZE,p&EH$=R\ +Hb'1VD>fUpOSY">OHG\(P5CC?OS4b8HN/6jGl;gfG'.s,FT6F^ErC"XE;skRDZ4MOD!u0.9ZaI6O\\#Mf^VI_(`Pom=b0/#ScdC.heCE1&g"P3:h;@/KioB+]k2tmll0@U$m-X60n*ol< +o(2MGrq-?dp\4[^rqZTjr;6HjrVc?eJcCH(J,~> +JcC<$JcG?Ao`"gfrqu]ks8)ckrV0=cp@e1Po^qbGo'u5j>g:]*rf:\mic:&do]:&[oZ:\.?R:ZYCQ:]=)h:[CpT;?'Jl:\dfe:\[]a:\moa;>3ua;ZK_o +;>X8h;u0Dk;ZKem;ZKeq#$G37>$Lo0!+#P.rETD.q-O&- +s'Q7D@U`hWA7T7_AnG^irb2@Irb2CJC&VlECHlWPD/O92E,K/k=]/$i8Ol094$>Yf4?5D]3(ZS/ +6UF+'4[MG$5!_=m6oI"X.3'Zc/hSn=A3BKDh5XbT1s#pcM8kDW?6UO7177R8F#"bM_U8+KZ +rM:I1Vl6PnWiE,$XKAV-YHP18ZEpsI[^WcV\[oBO],J>q^;%J"_Sa=2`lH0AaiMTGb0.rNbfn>V +cMl/ld69bato<;]bi<<%:EGlW*fG62r1FoHL_F8p:ZEW:"XDu4GOD>e;>C]/)LD>\;ODZFbU +EW:&1F*)MHF`qtQG^4U]H[L6jIt3'$K7el4L5:\DMi +JcC<$JcG?Ao`"gfrqu]krqcZjrqQNf!;?Eb!VH!_nji6>n*f]3m-Es$l0.9ljlGI]i8EJJgtUQ9 +f@JL%da?Fec-4AQaMu3;_SO"$]Xt_a[^EHIYck11Wi;nnUnXQTSt):aN(s1]!/35UnOBLR[BM`^UCGQYcb@ZOj5]7`k3)!nlKdg'mI'H3nF?)?oCMVRo`Fj]p\jmeq>^s+UK'~> +JcC<$JcG?Ao`"gfrqu]krqcZjrqQNf!;?Eb!VH!_nj`0=n*f]3m-Es$l0.9ljlGI]i8EJJgtUQ9 +f@JL%da?Fec-4AQaMu3;_SO"$]Xt_a[^EHIYck11Wi;nnUnXQTSt):.NqSG4N;eb8N;nn8N;ne9N9-&iNr4t5ORnM7OH5IsOSk17O8tF< +OSFt8O8tFBP5UOL$YPk^.ZEppF +rjbNf/aKKR\,_MiWs\J9GUUChc@7:L6@l@VJ/#7:]tHE--;MDb3Mp9hTtdJT5XJEHHAJG^=[_ +\,Z>fqN1W9s,[5Cr0$l +JcC<$JcG?Ao`"gfrqu]krqcZjrqQNf!;?Eb!VH!_njrh;#O/W +:]FMi$>-7r`T;+r`fG/qcs,+ +!F/q+?N4C4?iXX7@fKs.83fL.5t".2 +7RT[7TV/!QU8+KZV50rbVPgAkWMunuWiN5&Y-5%5Z*LaF[^WcV\c')L]=bhj^;%J#_o0L4`l?'s +a9]o1b0.uPc-=T5d-Xm4\;O +DuXeUEW:%ZF8g83F`qtQG^4U]H[L6iIXcm!JqJ`1L51SAMMmFQO,oEdPEhH#R$sM7StD[LqGKS\ +Y-5(8ZaI6O\[oGe^VI_(`5Td +JcC<$JcG?AoD\^erqu]ks8)ckrqQNf!;?Ebs7AqTo()>?n*f]3m-O''l0.f\#iLqV(u&q:G\Eqkrt_ +r4)I0s0`NIZa-mAOgBC]J:i`APae>G[/RN/[J%'/[JdH8[C!juRa2c$8^9OZ9Unj]RS!]Vb_Rm4] +YHOj^K!3/6[@rAHT8d;gBRNTsJr!&r;LsRYOd)B-ThnZcUfkiqBum-O--n*fc9rpg*]o`"O`pAamdq#C0hqY^6i +r;?Nbrdk*(s*t~> +JcC<$JcG?AoD\^erqu]ks8)ckrqQNf!;?Ebs7AkRo()>?n*f]3m-O''l0.n=09EqO7JRqLeKVJU`)oGBItJEg2ZE +Mhd"/9Ll%"JN/`m[OckonQC!u-S"-(ATV8-VV>H<6YHY==[C3QT +]"G_k^qmn+`Q-'AbKS8Wd*^:ke^i@)g=tE=hV[8Mj5]4_k3(smlKdg'mI'H3nF?MK!V>s_p&Fac +p\ssfq>U6gqu6NkrU^#>s+^Q(~> +JcC<$JcG?AoD\^erqu]ks8)ckrqQNf!;?Ebs7AkRo()>?n*f]3m-O''l0.r_N8bs%i,\qG-QVr)`Sm +qc+))5!hM#5X@b*7n6*D:B"&k:Jama;=m]_:]=)j:Jam_:]F2f9`Rrd:]4&g:\@K_:]4,i;>j>e +:\@K^:&do]:&du]:BF9e:\.?R:ZYCQ:]=)h:[:jT;>sDl:\[`d:\[]a:\moa;>3ua;ZK_o;>a>h +;u9Jk;ZKen;u]hq<<-(u=8Z(nQ7k,>PDD%?2n1*?N+:5?t!LC@K9p; +A-HOVB4kmkrb2LMBk_UfkiqBum-O--n*fc9rpg*]o`"O`pAamdq#C0hqY^6i +r;?Nbrdk*(s*t~> +JcC<$JcG<@o`"gfrqu]ks8)ckrV-Hgp@eLY9D%iHo'u5=n*f]2m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-+;PaMu3:_SO"$]Xt_a[^EHIYck11Wi2hlUnXQTSt);&f_*qngAfk*f`'S'f_q]E +VtI"Z\G`l:[f3ZFZ#ZM*H@UU)NK]a%WO'%Aq6fn(s0_g4"LYVDZa9G6pU0V$q6pF6\$l7Es0r'< +qRHL5n$r5)pq$C6rji*?q7-@3!OfK4\Gj#=](*?2])'#?]XtfR]`5\F^AYh?_#;+G_YM+J`;[aT +`r*mR`rF*WaT'?_b00e.rQP>fo[!K_s3^kprR1esec+.pf`0Y#gAfq-g]ZBeh;-rehuDU7iVMR4 +irJ0>jo+?@k6'r4l0A96!:9[OrpKgT%IioYo(2JFp@e7Uq>:*Is%M_8d`KPL]>_@bWMcPeSXZ%8 +R)ZqMZE^X4ObLTr`keULNN72C=^lbPG(>B@:f2arLQ@UdSY2WQ;c-Oq<2ustWKWO3Q'[r2StMaa +s6[Yt_"th?^A`Q\HiSNlH3/A:GlDpeG5l^`FT6F^Er9qVE;a_ADZ4SRE;aeVEWC1[FT6IdG'A.T +H2`+ZdF-Oof%8R.g>(N@hr*JQj5f=akNM0plKdg(mf)YZnF?)?oCV\So`Fj]p\jme +q>^s+^Q(~> +JcC<$JcG<@o`"gfrqu]ks8)ckrV-Hgp@eLY9D%iHo'u5=n*f]2m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-+;PaMu3:_SO"$]Xt_a[^EHIYck11Wi2hlUnXQTSt):=RdusESGSfTReMI-K^t6# +Nt71XH$a.[7kVuqLQ_uRgVa8X0[b5]ZabYQO/^9FQ.S=#P$OGedB +IsQHaF)l;@PE(QXL4aqrDN0sCMgTkhHX'N;93X_b?tM\o87H(@D/aQV&P5(1=OSk1=IK+ZpHi86lH$FT5GQ2jdFo?F^F8p:YEW0qUDsVB@ +DuO_SEW:%ZF8g:]FTcl3GBeE4H74,fI=?ZrJ:W<)KS>/9Ll%"JN/is\OckonQ'[l+S"-(ATV8-V +V5L9iO#4)HZa@0M\[oGe^;%M$`5Ta;aihlPcHsteeC<($f\5'7h;7&IiSrnYjlYail07L!m-X6? +mfr:Oo()DEo`"Lbp@n=[q#C0iqY^6hr;HTcrdk*(s*t~> +JcC<$JcG<@o`"gfrqu]ks8)ckrV-Hgp@eLY9D%iHo'u5=n*f]2m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-+;PaMu3:_SO"$]Xt_a[^EHIYck11Wi2hlUnXQTSt)9G:Z>4F:A%ER=8Gr2`r_NGg!)`\kq+pZYr_
    Y0!+#D,s'Gh8@:B.E +s'u%="D)1XBP@BZs(VXMC2.J^CAVcqCh6mS<)HC_7n#d04Ztnh4?5G^3(HG,6pX"$6U=(.5X%4l +2`366*[L_;.l0(62DR*I3'05e5=7dt2`Ei`4%i.:8jG^06UjL47RT\:T:_dLTq\9VU].(hV#dHk +r2:R6WiE/&Y-5%5Z*L^D[^NZT\@K/]]">Vg]tV;]_?[us`5T^8a2\,!$cpH3b0%oOc-FV\d-"I. +/9Ll%"JN/is\OckonQ'[l+S"-(ATV8-VV5L9i;)GM_Za@0M\[oGe^;%M$ +`5Ta;aihlPcHsteeC<($f\5'7h;7&IiSrnYjlYail07L!m-X6?mfr:Oo()DEo`"Lbp@n=[q#C0i +qY^6hr;HTcrdk*(s*t~> +JcC<$JcG<@o`"gfrVZTjs8)ckrqQNf!;?Eb9D%iIo()>?n*f]3m-O''l0.jo+?@kPj]G +lMg)Lm/?>Nmf2_bnF?)?oCV_Lp@nCZqu,OS:%R>rc,IZ9a1nm\W2HA`S=,e3R)?MBZEUF/LoS)( +`iYb_VMg%,8Td^IIYs%Z;1O=TOHZ''SY/eW;H?gsHN/9jGlDpeG5l^`FT6F]Er0kUE;FMLDYnAOE;X_UErU4[FT6I`G5c\>G^4U]H[L6i +IXcluJqJ]/L5(J?M2I7NNfT9aP*;/sQ^F21S=Z=FTqeE[Vl6SpXT$!pZ*UgG\%0)^]Y;.s_Sa@4 +aN;TJc-FY_daQ^rf@\d1gYL]Ci8EVTj5oFckNV6rlg4!*mdKW6nc&([oCW%Ts7QHerV6Egs8)Wi +rqu`no)=4?L];l~> +JcC<$JcG<@o`"gfrVZTjs8)ckrqQNf!;?Eb9D%iIo()>?n*f]3m-O''l0.RdusESGSfSRe27-K^b*% +Nt@;0NaR(GB5)4#Ed)k\K8GZ`NqSG9N/NXRNK*jprJLZ7oo/s1o8W=$r/^T6oT0$6s,Zo9r/^9- +plYH8!0R8DrfQr:r/po?r/pr@r/q#Brfd2As-*ADs-*JIr0.,Es-[7kVu_=N_uRdTa8a3]aiaV+s3)%n[]-!lR$<\pO+W"5I!KpYrc0<)Oc50Q +Kn+SiK8beNIs5ONBO="g=@6+sAS=S)@Uj%eE,p&CH2^>H:JFPVJUi;iDfBZ9F*;bNH?uptr/g]9 +plPN +JcC<$JcG<@o`"gfrVZTjs8)ckrqQNf!;?Eb9D%iIo()>?n*f]3m-O''l0.3oZ:A@WS=8c2" +<=Mtm5tF7)6:F:47nH9Hr_WDfp/(W^r_5hb+>5qh%>lS+/>QA(*?3FVC?t!LC@K9p;A--=SB)ZKC +Ba&6cBkhBsrbDCI%qf6Q#5sIFi2`qRs.BFeU8%X^s.gR0VP^8iVl-JmWiE/& +Xfek2Yd1UC[^NZT\@MUM#.qO]]tV:urke]Q'Z@u/`Q#p<`lH0Aai_cMc-=P[cdCfSr`/ttpf7>n +!e5ZJrd=iqH[Ga +JcC<$JcG9?o`"gfrqu]ks8)ckrV-Hgp@eLY"n_EWo'u5Kmm$4+m-Es$l0%3kjl>C\i8EJJgtUQ8 +f@JL%da?Fec-+;PaMu3:_SEq#]Xt_a[^EHIYck10Wi2hlUnXQTSt,f4p=]2oqq:o"r20"^r3u4+ +s0iNI[EOf=I=$R$MNa?rTrYX![Igm-[JmQ4[K!T6Zh_!$[I^j&[fs4L\%&oVosk%2n$r2(qRQ^> +])9,<\cB;:\GWf:[^Z%AmCE8.qRZgA]=\!Rs1SHHrP/'ArPA?Ipr!*LrPefVr5\WQs2Y)Zs2k;` +!mAg3rQYAfo[!K_s3^kprR1o!e^i@(pt,T"rn7A*rS%8*"l.kegtgfbhuDU7iVMR5j8\3>jo+?@ +k6'r4l0A96!:9XNrpKgT%Is#[oCMVIp@n@Yqu$HTs%3.Ph9X-^_S*aqXJi(nU7RgAR?tq.[Bd$@ +WK)Y?_T03]LSCAn?#=CMDg7(r:JuXnLQ@UeS"H^s+gW)~> +JcC<$JcG9?o`"gfrqu]ks8)ckrV-Hgp@eLY"n_EWo'u5Kmm$4+m-Es$l0%3kjl>C\i8EJJgtUQ8 +f@JL%da?Fec-+;PaMu3:_SEq#]Xt_a[^EHIYck10Wi2hlUnXQTSt,eKo:,THqj[PQ!1Wn[:kVuEXmWW0!uW;rstX8B!nXoGR%Y5kg+ +Z2_-0[/RK5\,Wu<\HKOW]Y2&Y^];4M_>qLQ_uRgVa8a3]aiaV+4NY1BVK7JDuH$47L +EcI;'MM[(?I;s+ZNK/^Oo(=;Oo1=@JH(*!If4ZrI!^5>HN/9jGlDpeG5l^_FT6F]Er'eOE;jePE;FSS +ErU4[FT6I`G5c[dG^9:7FF/C`I=?ZrJV&N,KSG5:M2@+KN/is\OckonQ'[l+S"-%@TV8*UV5L5j +WiW>*O,pWS[^WcW]=bkm^r"".`lH0CbKS8Xd*^=le^rF+g=tE=hVd>Nj5]4_k3(smlKdg'mI'H3 +nF?&>o(2MGp%A%Pp\4[^rqZTjr;6HjrVc?eJcCN*J,~> +JcC<$JcG9?o`"gfrqu]ks8)ckrV-Hgp@eLY"n_EWo'u5Kmm-:,m-Es$l0%3kjl>C\i8EJJgtUQ8 +f@JL%da?Fec-+;PaMu3:_SEq#]Xt_a[^EHIYck10Wi2hlUnXQTSt&UH;#4&_;#F&X:Ae/]=8u;& +;E[>F5Q=(T77Tj>8l&:Z;>*i`:]F/i:]4,c:B4/d9`Rre:]*rf:\@K_:\R]\:\IQ^9`Rl\:&dug +:B45d:BF9e:\%9R:ZYCQ:]=,h:[CpT;?'Jl:]4)i:]=/j:\[]`:\mob;>*o`;ZK_o;>a>h;uKVk +;u]hp;u]hp<<-)!=8u>#J] +0e==m.4-Mu2)tRl(H+664[22!6T?t`4$Gbg8kDQ=5=.\(7/]Oh7%Bg=St;RHTV/!PU8"EWUnji` +VPa?js/7$=WiN5'Xfnq4ZEgjF[^NZT\@K/]]">Vh^;%J!_8=(g_\0i(`5KX7`lH0Aai_fNc-=P[ +d,A%)<<-"nUfkiqBum-O--n*fc9nac8Bo^qhL +p@e7TrqQKgs8)ZjrVZWmoDX=@L];l~> +JcC<$JcG9?o`"gfrquZjs8)ckrqQNf!;?Eb!VH!_njDs:n*f]3m-O'&l0.m$WO2W3o="V)rjDI,p9jM#osY"4\$u%?s0qI,q76:3r42gA^&PhF^\5JA_>;%D_u@UQ`W*sUa8*aTa8F$YaT9Q-rlk>c!7(5_ +rQtSlrmLep"OtuQf@TiNrn7>*s4RD*qV)&+h>Q71i;)C4j8S-=jo+?@kPj]GlMg)Lm/?>Nmf2_b +nF?)@oCV\Jp\=U^r;GdX8FYQgbK.Z:`kARSVP^&[S=,b2R)6JBYct.+LTA/,`Mo;aWJP_"@sUgm +Jr<9$:P=F^P*qf4T28E_1H['d?P\\#Mf^VI_(`5Td +JcC<$JcG9?o`"gfrquZjs8)ckrqQNf!;?Eb!VH!_njDs:n*f]3m-O'&l0.P5LI@P5LIBP5^[AP5gaDP5gaFPl6gFPlI$GQN*9PQC%T:r0R8I +!1E\N"IY^IS"',AqORPUqOde\!29@cr1X(`qP3k^!2]Xks/5jpql0Uq"KAE$X/l)urN-($rN-(& +qlft'!j]/>rj<*A\%&rY\\#Me]tOB["2Vjk_u@RT`Q%nts2Z>)b0.].WM,iKP`ClcK7JGuH$FFP +F)l8^N/<:BIsl3erf&(LF`)P=<'s>a6!7W15tFCRA8H1)FE`%%8OlNM97VSEJGsKjDfKlBGQ)jh +HN!gArj;_!OSFt:OT(C=P5:=?OT0n2JH(*!If=cqI/eQmHN/9jGlDpeG5cX_FT-@\Ep.NBErU4Z +FT6I`G5c^cG]J(UH@($fI=?ZrJ:W<)K8#&7LP^kGN/WdXOHG]iQ'I]'R@B_;StMdOUnsrdWN*&% +Y->0l['d?P\\#Mf^VI_(`5Td +JcC<$JcG9?o`"gfrquZjs8)ckrqQNf!;?Eb!VH!_njW*ds%`Db!)EMhmnWjXpJCW\p.k-Ps%`5_!DZG\ +:A%EE:]O;j:B+,V;#=,i;#X8d:]O;d:Adob;#4&`;Ya5k;Z'Di;Z'Jl;YsDm<;]\p<;]brns&]8(rE')'>5hb*>5_\+>Pq_+?2\".?27h,@/aU5@f9g5XIh*6q'L4779S7SGo)ZT)YG_TF.BeU8+HXUnji`VZ!FmW"5l.XKAV-YHY== +Za@-K[^Z7G$G!aZ]=kqm^VI\%qn`r_`5KX7`lH0AaihiMbg"G[d,.mu0.['d?P\\#Mf^VI_(`5Td +JcC<$JcG9?oD\^erqu]ks8)ckrV0+]p@e1Po^qbGo'u5P*MZ8Xo>a*[K*f5[f3Z4[J.'$[I^j"\,Wr<\+R62\*gd%\bWi5 +\c95@\bWc5[fNqHpUKY%s18'=s1A?Dr4N'Cs1\HHp;$XCqSN$Frl"cSrl4lVq8NETr5eo["Nnp2 +bfp%1!7(2^rQtSls3gkps4.,#qUkf#s4[M+rn@5'!o2Vgrnm_5!9*e6s5X+>roO+@roXRNl07Ku +lg*p(rU'UPs6p!Xs7?9_#PIfcq>:*grosGHq;g>V`lGp1]X+Z:VP9]SR@0D/`4radYcascK"JtB +\=nSDP_E.JFA$\)LeCQ@It`lFR%9kA:f:.j<)TaqW=5#TQ'IT"R\$+CU7e6`rr^*S_SQ/eo>17< +qS2m@s+:9%rdY'"IX_9Es*Xinrd+Tis*4Kds*"Ebr,hmYrGqFJrGqpZr,hs]!-\?cs*+Nhrd&=+ +I!pElIt3'#JqJ`1L5(M@M2R=ONfT9aP*;/rQ^F21S"6.DTq\?YVPgDnX0&P/Z*L^D[^`lZ]Y2(q +_8=.0a2lBGbg"G[dF-Oof%8R-g=tH>hr*JQj5f=ak3)!nlKdg'mI'H3nF?MK!V>s_p&Facp\ssf +q>U6gqu-HkrU^#>s+p]*~> +JcC<$JcG9?oD\^erqu]ks8)ckrV0(\p@e1Po^qbGo'u53NrY4;O8"b/ +O7SJ2O6r&(Oo(4?OoCOCOnOn7Oo:I@Oo1C@OoCODPPUIBPPgUCPQ-mFPQ-mHQ2?jIQi*0IQhm'L +RJN9NRJrWTS+`BJSc55VTDtPaU&C__U&C__U\U_cV>d@kVuN^mWW0!uW;rstX8B!sXT5I#XT5O% +Y5kg*YlV2I;s([NfSm=BQJ$"5YP3F7eSI=6QoJ:N3&K7nr5L5:\CMi +JcC<$JcG9?oD\^erqu]ks8)ckrV0(\p@e1Po^qbGo'u5(<)lq!<`f,uq,[T!=o;A%>5_\*>5__+>PMJ'?2n42?2\(1?XWh@raH(AA7]:_AnV*Vqe?(F +s(Ou2>#nKs9hIrE6U!Xp4?Ybd3&rof770I/5!D:u5X@Xt3B/rP//ore/h8Y70/YRB3''/d5=7as +2`S=Q5MT)YG_TEq6cTq\9VUnspdV@TT'W2ZhuXKAV-Yd(L? +['fnAs0i0A\[oAa^&G_a^VI\%_SO+*_SX4/`5Ta:a2lBEb0.uQcd0tm7eSI=6QoJ:N3&K7nr5L5:\C +Mi +JcC<$JcG6>o`"gfrqu]krqZWjrV6Ee!;?Eb!VH!_njDs:n*f]3m-O$%l0.M:JlRnLlmmlR\*AR;,pRnWrAptPEPp1#a_$PStD^MUSP!k!5\ZOs24cOotgI> +qS2pAre(6&!.k*!!e5ZJrdFfos*O`ks*=WhrHJ9brcS*[r,_IMrH%jXs)n?brc`1'H$O^^H[L3h +I=?ZrJ:W?*KS>/8Ll$tHN/WdXOHG]iQ'I]'R@B\:StD^NUSOcbW2co#Y-5(8ZaI6N\[oGe^;%M$ +`5Ta;ai_fOcHjnce'uq"f@em4gtgiFi8N_VjQ>Ufkiq?tm-O--rpL'\nac8BoCW%Ts7QHerV6Eg +s8)Wirqu]moDX=@M>r)~> +JcC<$JcG6>o`"gfrqu]krqZWjrV6Ee!;?Eb!VH!_nj2g8n*f]3m-O$%l0.2N:i2*NWP9%Nq\V/ +OSOq>OH5Kao8rm2rf@,@nWYdF$Fme^rF+g=tE=hVd>Nj5]4_ +k3(sml0I^&mI'uB#4V0Ro(2JFrq6 +JcC<$JcG6>o`"gfrqu]krqZWjrV6Ee!;?Eb!VH!_nj2g8n*f]3m-O$%l0.hs%iDd!)NDcr(m/cqbd&bq,78krDEGir)3Yp;c5_Y+>$Lu2s',5&s'5\4?![D8!+5\5raPn;#A%FWAS5XhB_uNDC.Dc? +=&`$k8P)695X.Fn4?PY`3]8ia770F.5!2.t5mFmVuN\3WiN2%Xfen5ZEpmE +[C3KO\$rlX]">VgrkABHs1nWMs2"lU`5KXo`sKi/ai_iOcHjkbgK+2Ore(6&!.k*!!e5ZJrdFfo +s*O`ks*=WhrHJ9brcS*[r,_IMrH%jXs)n?brc`1'H$O^^H[L3hI=?ZrJ:W?*KS>/8Ll$tHN/WdX +OHG]iQ'I]'R@B\:StD^NUSOcbW2co#Y-5(8ZaI6N\[oGe^;%M$`5Ta;ai_fOcHjnce'uq"f@em4 +gtgiFi8N_VjQ>Ufkiq?tm-O--rpL'\nac8BoCW%Ts7QHerV6Egs8)Wirqu]moDX=@M>r)~> +JcC<$JcG6>o`"gfrVZTjs8)ckrqQNf!;?Eb8+cEEo()>?n*f]3m-O''l0.A^&PhF^\,DA_>1tD_u7OQ`W!mTa8!XSa8X0Z +aoBK`bPo`ablH&]ci)5jdJhSndfItKrn%#!rRh2)rn7;)rn@G,rn@M0h;8.grnme8qVhM8r8dn> +r9"%B#jCO;lK[^$m-O](N@hr*JQj5f=ak32'olKdg'mI'H3nF?MK +#kR]\p%A%Pp\4X]s7u]kqtpBjrVc +JcC<$JcG6>o`"gfrVZTjs8)ckrqQNf!;?Eb8G)NFo()>?n*f]3m-O''l0.0O8k=AO7JD,Oo(4?OoCOCOnOn7Oo:I@Oo1C@OoCODPPUIAPPp[DPQ-mFPQ-mH +Q2?jNQ^3r(QBqH8nsKEE!h,UJpmh,MrgrnWs.B@cr1a.`rM'.`rhKOhrM9Iis/,am!3#an!36$t +s/Q+"qlKe!s/c.#!3Z7'!3lI-!j]/>rj<0C\%&uZ]"5Pe]tM.qrP8QP_o)JlG'J4VH@(!gJ,9'Ar;QZprjDdpOS+b1P5ULEKnP-YK*$XUJc:3"J,ausIK+ZpHi89jH2i-f +GQ)dbFnp.NF8C"YFoQX`G63#7H2`,+H[L6iIXcluJV&N,KS>/9Ll$tHN/WdXOHG]iQ'I]'R@9V9 +StD^MUSOcbW2co"Xfnt7Za@0M\[f>b^;%J#_o9X9aND]McHjkbdaZguf@\g2gtgiEi8N\UjQ5Od +kiq?slg4!*mdKW6nc&(boCV\Jp%J+Rp\jmeq>^ +JcC<$JcG6>o`"gfrVZTjs8)ckrqQNf!;?Eb7eH?n*f]3m-O''l0.cn4ipXmT03d +rDj=i2aBJk5t".37n?3Hr_WYlr_`Mgq+h#f;>j>g:B4/b9`e'c:]!le:\IQ^:]=/l:Jajd;"mcY +:@_*Z:@q<_:/CCTohX[G!)NShs%huXqbd>hs%iDd!)NAbr(m2dqbd&bq,78kr)*AiqGRAlr)3bu +;cH^p<;oer<;T\q6.o3r`oG,pKRf+?(Y->19ZEpmErj<Vg^:q:p^VIV"rkScT_o'F3`r=!aaN;QI +c-=P\d+MIu<<@l-K`6T*Jq8LPJH(-!If=cqHiSNlHN/9jGl;jcG5cX[FRsSMFT6L`G5ZUdG^4T6 +H>IqUI=6QoJ:N3&K7ei2L51SAM2R=ONfT9aP*;/rQ^F20S"6.CTqS6WVPgAmX/rG,Yd1UB[^WfX +]=bkm^r"".`lH0CbKS8Xd*^:ke^i@)g=k? +JcC<$JcG3=o`"gfrqu]ks8)ckrV6Ee!;?Eb!VH!_nj2g8n*f]3m-Es$l0.9ljlGI]i8EMKh:pZ: +f@SR&e'ZOfcHOJRaN)9<_SO"$]Xt_a[^EHIYck11Wi;nnUnaXojV?"(! +\,Ni4[JmQ5Zi@9?Y@q`jIY!<3N00BqTrYR"[f)qRQ@3qml^;!4hp8qR?4/m^`>.qRcU:s1SHHrP/$@rPA?Iq8<0LrPefVr5\WQs2Y,[rlP2_ +!6bAcrQP>fo?[B^s3^kprmLque^j`Oqq1i"!8@G*rn@5'!SlQ2hu2L/ir%m:jo+?@k6L58l0@R" +lg4T;s6fpUs6pEdo(2JFo_/%Tqu$E[rt+GPe'#eN^rEg`W2QMaT:),HQmoqg\[J`GXK.20ZG+>^ +SUmPkG#i$t9Qu,I:JuXmLQIdkSY&_V:fUDarhp9iP*D5tR@TqATqS6XVPsOp_>_=J_tCkB_"b\C +^''1EKnP-YK*$XUJc:3"IfOrrIK+ZpHi89jH2i-eGQ)dbFm=)JFoQX`GQ2mfH2`,2H[L3hI=?Zr +J:W<)K7nr5LPUeDMihr*GPj5]7`k3(smlKdg'mI'H3nF5u=o(2JFrq6 +JcC<$JcG3=o`"gfrqu]ks8)ckrV6Ee!;?Eb!VH!_nj)a7n*f]3m-Es$l0.9ljlGI]i8EMKh:pZ: +f@SR&e'ZOfcHOJRaN)9<_SO"$]Xt_a[^EHIYck11Wi;nnUnaX^SFW0GSG\iVRf&ZTSH#)HJcLhu +O8P%OT(=4OS=n7O8tFBP5^U;OSk7>P5LI?P5UOBP5gaBP5^[CP5gaGPl$[EPlI$DQ3*D= +QMd*GQiNQMR/`TSRK/iPSG/TRT)##YTE(\_UAgkaUACYbU]@1fU]RBiVZ!CmW:m4jWrK-rXT,F% +XSo:$Y5GI,Yd(I=ZEsP+Yd(OA[^WcW]=bkm^r""-`Q-'AbKS5Vd*^:keCN7(g"P3:h;@/KioB(\k2tjjl0@U$m-X60 +n*oi:o()DDo`"O`p&Ojcq#C0iqYU0hr;?Nbrdk*,s*t~> +JcC<$JcG3=o`"gfrqu]ks8)ckrV6Ee!;?Eb!VH!_nj)a7n*f]3m-Es$l0.9ljlGI]i8EMKh:pZ: +f@SR&e'ZOfcHOJRaN)9<_SO"$]Xt_a[^EHIYck11Wi;nnUnaX\:]=,`:\mod:\IWQ9`S2Yr. +2`fpe:ca:\mfd:\d`e:JO[`:]=2h:]F8d:\@KQ +9`Rr\:[_'O:ZYCQ:]=,h:[:jS;?'Jm:\[`d:\[]_:]!ub;>3ua;u]bo;>a>g;ZK_n;u]es;uTbq +;ZKenYf2`EWQ2+Bu%6U7 +K`6T*Jq8LPJH(*!If4]pHiSNlHN/9jGl2dbG5cXLFT-F_G5ZXbGQ<$gH?4F\I!pElIt3'#JqJ]/ +KnbA=M2@.LN/is\OckomQ'[l+R[]k>T:qsRUnsufWiE/&YHY:<['mHR\\#Mg^VI_(`5Td +JcC<$JcG3=o`"gfrVZTjs8)ckrqQNf!;?Eb9D%iIo()>?n*f]3m-O''l0._ns4(]tCqe\$iZMZ*:C5X/`+rV52o#g"P05g&0Lcg&K\+f@JL@VZ+%# +\,Ni9\,Ni5[1osSZ*CO:B52=3J:r`:Mj'HuV6.3*\,Ec7[/dT2[0!_C[J[E)[J[H=\$i`S[^NZS +[emQ6\,a"l\GNi1])0&<])T>9\GNc0\F-p,])'&7]E#YE^Abn?_#;+G_YM+J`;R[T`r=!ZaN++r +rl>#Zs2k;`s3(GdrQP>fps/rcrQkGhs3^kprmUns!7q/$qq1i"!8@G*rn@5'!o2Vgrnm_5!9*e6 +!9="a5]WnH5W1fcP +R$jA/Qc$DCZ*:C1O+sL7^Vm:GJYIsuR$jD4S=Z@GTqeE[ +Vl6SpXKAY0Z*UdE[^`lZ]Y2(q_8=.0`lQ9EbK\>YdF$Fme^rF+g=tE=hV[8MioB+]k3(sml0@U$ +m-X60n*olHncA@Srq6 +JcC<$JcG3=o`"gfrVZTjs8)ckrqQNf!;?Eb7.g*Bo()>?n*f]3m-O''l0._ns4(]tCqe\$iZMZ*:C5X/`+rV54*\s.01[oUG]Ip7))PrgWA.r/U]9 +rf6]5s,R,`J4NW5%;NVe\4MuSb3NVeY@NK0!XNfB$YNfEgoqi:`; +qiCK5qN('+r/^i=rf?W3plYH8!0R8DrfQo9r/pr@r/po?r/q#Bs-*;Brfd8Cs-*JIqih&Es-rg*JKqj7AOq3_/L!LfMQSG/TRT)##YT`:_`UAgkaUACYbV#R4gV#R7kVYm@bWW0!uX8B!t +XoGL#XT5O%Y5kg+YnF@K['dgElr;Z`qrjDdoOS+b0P5gXEL]3&.K`Hf*KE$N'Jc1*#IsukFI0+eCHi89jH2`'dGQ)d` +FnBeSFoHR^GQ2mfH2`-iHN8HmI;+.[J:N3&K7ei2L51SAM2R=ONfT9aP*;,qQC+)/S"-(BTV8-V +V5L8kWiW>*Yd(O@[C3TU]"G_k^qmn+`Q$!@b0/&TcdC.heCE1&g"P39h;7&IiSrnYjlYail07L! +m-O--n*fc9rpg*]o`"O`pAamcq#C0iqYU0hr;HTbrdk*-s*t~> +JcC<$JcG3=o`"gfrVZTjs8)ckrqQNf!;?Eb7.g*Bo()>?n*f]3m-O''l0._ns4(]tCqe\$iZMZ*:C5X/`+rV53r`r(d&`qG@,dohbQ\ohGK]r`/u! +s&]2#r`/Ym!EE2!<=LlD1d4/i6UXC67n?3GrDEDfqbR5gs&&_k!DcPk:B4/a9`e'c:]*uf:\mid +:B4/f:BF?g;#O/i;"mcY:@V$Y:A%EN:A%EE:]O;i:&n)U;#=,i;#X8d:]O;e:A[ia;#4&`;YX2g +;>X8a;u]es;uK\p;u0Mm5VV)>lS"/>$Lr1!*fA+rE]>- +!+>b6s'l"!50/bXF3BB8e5X[Uj2Ej8f8OuH<62j7O7/o^T7gM[YQ'IZ$Q^=*=RK&`US,\ubSXuIHTV8'R +U8.[_s.p1%Vl-JlWN*&&YHY::ZMq0=['dVg^AY_I^;%J!rkS`S_o0O6rl5;cair#S +cHjh`f2hoO!/LQ.s+LH+re(6&!.k*!!e5ZJrI"`pH[G^;s*=Tgr-/-`r,qXRrH8*_r-/0c!."Qi +s*F`nrdAL0It3'#JqJ]/KnbA=M2@.LN/is\OckomQ'Rf*R[]h=T:hmQUnsufWN*&%Y->1;ZaI6O +\[oGe^VI\&`5Ta;ai_fOcHjnce'uq"f@em4gtgiEi8N\UjQ5Oekiq?slg4!*mdKW6nc&([oCW%T +s7ZKerV6Egs8)Wirqu`no)=4?MuS;~> +JcC<$JcG0n*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-4AQaMu3;_SO"$]Xt_a[^EHIYck11Wi;nnUtsf)gAfk'f`0Xuf_*qtfE9aVe^X;j +qPO.us0qp7s0Vj8r3[BKZa-pBZ*:I9AnZ=6I"-m,N0KWuTWGN0rO2=*r3Z.)rO2a8s0`*?[^NZS +[f3`>\@8rW\@;1A!4h7%qmlC2r42j=s1.m6r3uF1m^`>.qRcR9!58BGrP/$@rk\HJq8<0LrPefV +rl5)]a2e(srQ"oYs2k;`s3(DcrltJgq9K&drQkGhs3^hormLquf%0iPr7Lbsrn@5'!SlQ2hu2L0 +iW/$:jSn9>k5OQCl2U&Kli6>NmJlVSn,MkWnc&.[oEFs`q>:*ho)DP`jkJ2)`PBC,Z`Bt#US"*E +R@0G/_S*C_Z*1.0L4ZbI`4r4;MkYpG/qSWWs+16%rI=s!IX_9Es*XinrHeHgs*4Ba +r-%aUrHA'^s*4Qhrd"cqI!g?jIXh?ICOq(iK7nu6LPUeEMiuR$a>3S=Z=FTq\?Z +Vl-MoX0&P/Z*L^D[^WfY]Y2%o_8=+/`lQ6DbKS8Xd*^=le^i@)g=k? +JcC<$JcG0n*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-4AQaMu3;_SO"$]Xt_a[^EHIYck11Wi;nnV#6e`SGSfFSGAZSSGerNK)^E"K'SHr +NW4t:M[rce@V'7gD/aT?H@CL%N/mgqrf6r:qi(H2rf$]5qi(K5"ceS%NfK+oNr+k;Nr>">OH9-t +qiC-+r/^i=rf?T2q2tQ9!0R8DrfQl8r/puAr/po?r/q#Bs-*8As-*ADs-*GHr0./Fs-Ks-`\MrgF" +XT5O%Y84@IZ*L^B['d?N\$roZ]">Se]tV4r_>_=N_`GZEXJDGVQ][;fKn=f$G^4LSEcQ/6S +KnFi'D/4ocNer.)DK]5\77g]L=CGo07n$luD/XN>H2^A79c?WRJ:MNUDfKf?GBe@YH[C3lp\4IY +q>0sbqu6NnrVul)s6c!AOo(:AOo:FGObegKL]3#0KnP-YKE$N'Jc1*#IsukGIK+]pHi89iH2i-c +GPlXWFo?L\GQ2pfH2`*oH[L3hI=?\FJ89^fK7ei3L51SAMMmFPNfT9aP*;,qQC+&.S"-(ATV8*U +V5L5jWiN8)Yd(L?[C3QT]"G_j^VRe)`Q$!?b0/#Scd:(geCE.%f\5'7h;7&IiSrnXjlY^gkiqBu +m-O--n*fc8nac8BoCW%Ts7QHerV6EgrqcQirVZWmoDX=@MuS;~> +JcC<$JcG0n*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-4AQaMu3;_SO"$]Xt_a[^EHIYck11Wi;nnV#!ma:@D!N;"%0R=8u=nhpJ:HWnkK-Z +ohY!NohX[G!)NPg!)MoWqbdAir_N>ds%iJdqG6ubqbd&bq,@/fr)32dr_rtu<)los;u'Gm?b97>Q.k->Pqb(?2\(1?XWh@"CbkNA7baP%qfQhB3nb@ +;G^(Z7RTR-5Q*]62E*NO2ag&$6U0/YF>3BB;f5X[Oi2EX2_ +91_Z=5X[t,6psI37S--B99b[+Q'Ra8QiEF+R@9S6S"-">T:_dLTqS3TUSO]^UnsobVl-JmX/rJ, +YHY::ZEpjC['dWs+16%rI=s!IX_9Es*XinrHeHgs*4Bar-%aUrHA'^s*4Qhrd"cqI!g?jIXh?ICOq(i +K7nu6LPUeEMiuR$a>3S=Z=FTq\?ZVl-MoX0&P/Z*L^D[^WfY]Y2%o_8=+/`lQ6D +bKS8Xd*^=le^i@)g=k? +JcC<$JcG0?n*f]3m-O''l0._#;+H_YM+J`;R[S`W4'Ya8j9Y`r*mVaSs<]aoKWa +bl,cgcHjh^r6PDgrQkGhs3^kprmUnt!7q/$r7Lo"!8@G*rn@5'!o2Vgrnm_5!9*h7s5X%rTs[Sn*g8F!:p-\#5%T_q>:*goD_YPh:0]h`kTU&Y,J.mSt;I>Q^+a]GCkcG<.0CSOHQ'&TMSQa<`N%rWMki@PE_?!S=cCHTVJB_V#U;- +rkeZPrPJ;Ll%"IN/WdXO-,ThPa.Q%R$sM7St;UKU84T^Vl?\sXfek3 +ZEppH\%0&]]Y;.r_Sa@3a2lBGbg"G[dF-Lnf%8R-g=tE=hVd>Nj5]4^k3(sml0@U$m-X60n*olH +ncJFTo`"Lbp@n=[q#C0iqYU0hr;?Nbrdk*.s*t~> +JcC<$JcG0?n*f]3m-O''l0.jNVeb6 +N=h,-MMY>]AS5dpDK0fFI"I$/r/L]9rf-c5rJUW5qi1H2rf-H.qi:`;rJpu@O8+h5O6r&,O8b7? +O788-Oo(4AOckn+OnFh6OoCOAOoLRGPEM+,OoLUEPPLCAPPgUDPQ$gEPQ-mHQ26gHQi<F%Z2_-9 +['dW=^u/3875n=CiFE;Gt:Ls9h\7[J.?F8E,fo?GC"IZH[LM2I4MN/is[OckomQ'Rf)R[]h=StMdOUnjlcWN*#$Y-5(8 +Za@0M\[f>b^;%J#_o9U8aN;WLc-F\`daQ^sf@\d1gYCWAi8ESSj5f=akNM0plKdg'mI'H3nF?MK +!qZ'Vrq-?dp\4X]s7u]kqtpBjr;H6dJcC]/J,~> +JcC<$JcG0?n*f]3m-O''l0.j:&n)U;#=,i;#X8c:]O;g:AI]_;#=,f;?0Sl;Ya8g;>a>h;u]hq;uT_u;cHar +r_rVmr`0#!rD`ess&K,$qH!Go$!:>5=BJX+=BSi*>6S89>?Y37r`oJ-r*92+rE]P4?srtB)e*;e +A7T7`AnPaa>#eNu9hRrE6pNt"4?Ybc3;tco7RTR05X7In5s[_$5Wq(d2`EE=+Wr'a/1rb=0fCgE +3BB;f5X[Li2a0Dd91_Z<5XRk)6psL4r^R#]8sB7=s-rA3L]3&.L&Zi*K*$XUJc:3"J,ausIK+]pHi/3iH2`'`GP64UGQ2pfH2W$jH[L5? +I;=:]J:N3&K7ei2L5(J>M2I4MN/is[OckomQ'Rf)R[]h=StMdOUnjlcWN*#$Y-5(8Za@0M\[f>b +^;%J#_o9U8aN;WLc-F\`daQ^sf@\d1gYCWAi8ESSj5f=akNM0plKdg'mI'H3nF?MK!qZ'Vrq-?d +p\4X]s7u]kqtpBjr;H6dJcC]/J,~> +JcC<$JcG0C\i8EJJgtUQ9 +f@JL%da?Fec-4AQaMu3:_SO"$]Xt_a[^EHIYck11Wi;nmhYu=5gtLH7r7M#%p=T&ks4IA&rm^G7 +pU9n*!OT94[/[HIZ*:C5YAKW=I!p['MN*deS"Zmj[^Pe8rj;=*r3lX7!4M[3s0r'_#;+H_YM+I`;[aT`W4'Y +a8j9Y`r!gVaSs<]b5]Zbbl,cgcHje]r6PDgrQkGhs3^hos3q"u!nPuTqq1f!!8@G*rS%,&!SuW3 +hu2L0iW/$9jT"?>joOZ/rosIJs6K^Orp9dTn*g8F!:g$Z#5.]bqY^D(L_u7II_>M+F^\khGMZ/G6LkgcbLAur-K`6W(K)^E$JH(-!If=cq +I/eQkHN&3hGjBSQGlN'fHN/
  • U6gqu-HkrU^#>s,?u.~> +JcC<$JcG0C\i8EJJgtUQ9 +f@JL%da?Fec-4AQaMu3:_SO"$]Xt_a[^EHIYck11Wi;nmT)>/ZSG\lGSGAZRSG\lGK'eQqNrP(R +N/NRMMI:[aAS>mtEclSQItNN8NK*msrf-c5rep]5qi1K3rJgB.qiCc;rJpu@O8+h5O6r&,O8k=? +O788-Oo(4AOckn+OnFh6OoCOAOo1C?OoLUDPPUIBPPgUDPQ$gDP5pjHQ26gGQN3?KQi3F"XT5O%YAg_NZ*L^B['dSe]tV7s_8=($Yc+:eR$E_oN.cb0H['[UF)Z,JH$OaaI=Hg!JqEarp]L?gqYU9is8Dus[K$,d +o8rO*rf[2As,-f4!f2VereCH,!/1?(s+:9%rdb#us*jrqs*Xinr-J?frcmaQrcnHgrHeKj!.=co +s*ep:J:N3&K7ei2L5(J>M2I4MN/is[OckomQ'Rf)R[]h(N@hr*JQj5f=ak3)!nlKdg'mI'H3nF5u=o(2JFrq6 +JcC<$JcG0C\i8EJJgtUQ9 +f@JL%da?Fec-4AQaMu3:_SO"$]Xt_a[^EHIYck11Wi;nmq+po`mSEFNqb?cZnlPfkpf75k"$f1? +6N04V6UaL984cKO:f%$drD3GirDEPj##S2n:JX_\pJ(KZs%iSgs%`VinkT6^pJ:T[s%iYinP'!Y +oM>hs%iAcr(d#_qb[,drDEVmr)3>h!)i_lqbm>js&Atr +rDX##<)lms;c?ZkQ.e/>?kE;>Pqb(?2e11?N=L4 +@K0j;A4U9DAn"tF;c$:a8jbs35X%@o3BB)W2)[<[6pa.)5!2.s6:!k#3]8rT0J+=i,qU]"0fCU@ +1,LpM3]oYm6oI"`4[(u#8OuJP63fqI6q9X97nEVPs%EEWrg!MLs-NbQs-X=bS"#q=StDXJTV8'R +UAgniUnsrcrhg($WN3,'Y-5(7Z2V$6Za@-J[^WcWrOW$@!5/_=O_Z[os`l?."b5TWb +blQ,9i)]kXr`8qss,-f4!f2VereCH,!/1?(s+:9%rdb#us*jrqs*Xinr-J?frcmaQrcnHgrHeKj +!.=cos*ep:J:N3&K7ei2L5(J>M2I4MN/is[OckomQ'Rf)R[]h(N@hr*JQj5f=ak3)!nlKdg'mI'H3nF5u=o(2JF +rq6 +JcC<$JcG-;o`"gfrqu]krqcZjrqQNf!;?Eb!VH!_nj`0=n*f]3m-O'&l0.]",BH\cKFSqmla.qRcd?rk8)[rPn]Ss2b2]s2tAbrlkAdrQbAfrm(Mhr6YJkrmLhq"OtuQf%9iPp"B>uqV)),h;8.g +!oVtoqVqP8r8dn>r8n(Dkii$1s69UMrp9XO!UfFTn,W%Yo*4j\p\F^brV?Itrq5.#ccF/F`5AdZ +VPU&ZS=>q3Q^,D#\$3'=X,MV3^pM"\SVEYuL0\1tH:r=.LPS`):4n7[OdMW0T28E_<`N%dW2HSW +PED)qR@Kk@Tq\;Ll%"IN/WdX +O-,TgPa.Q$R$jG5SXuIITqeE[Vl6VqXKAY0Z*UdE[^`lZ]Y2%o_8=+/`lH0CbKS8Wd*^:keCN7( +g"P3:h;7)JiT&tZjlYail07L!m-O--n*fc9rpg-^o^r.U!quB_rV6Egs8)Wirqu]moDX=@NW4M~> +JcC<$JcG-;o`"gfrqu]krqcZjrqQNf!;?Eb!VH!_niu[6n*f]3m-O'&l0.eLr1!bXn!s_.+r/D;HMMcG)AS>jrD/siGIY*61NW"n;NVSP4Mu8P3NV\V5NU`&+O8k7=O7n\3O6r&,O8k=? +O8P(>O7eV3Oo(4AOckn+OnFh6OoCOAOo1C?OoLUDPPUIBPPgUCPQ-mEP5pjHQ26gGQN3?KQigKoCJ'Ble*#77^'U +6!.K*B1>BY@qBFnEccMO84c0sbrqufp!<0D+ +qN:B2n;Ll%"IN/WdXO-,TgPa.Q$R$jG5SXuIITqeE[Vl6VqXKAY0Z*UdE +[^`lZ]Y2%o_8=+/`lH0CbKS8Wd*^:keCN7(g"P3:h;7)JiT&tZjlYail07L!m-O--n*fc9rpg-^ +o^r.U!quB_rV6Egs8)Wirqu]moDX=@NW4M~> +JcC<$JcG-;o`"gfrqu]krqcZjrqQNf!;?Eb!VH!_niZI3n*f]3m-O'&l0.sAr;,C(b:JO[Z:&7Tb:]*uf:B4/\:B45c:\dcc +:]=,[9`Rr\:\mid:\RWW:]=2i:[:jW:]=)h:]4/Z;#=,h;#a>c:]O;i:A@W^;#4&f;?0Sk;YsDm +;Z0Jh;Z'Jn<;ohm+s'5S.r*92+ +ra,V3s'Yh7&n5?]A7]4T=]83o:.RlC69m^tr]C-=-8m_=6q0O25Wq4s5=%S#4ZYP^2)$U'+XJ`m +/2B+E2)I!D3&j#br^$QD'K80=4A&198j>R,6:F:07RT^98P/nS*_f=$9hpt=QBml(R$a;1R[]h< +StDXJTV8'RU8+N[rh]Uk$)a`$X/rG+Y-5)/Z2_*6['d_:W_o0L4 +a2lBEb5TQdbg"DXhcB\U!*9%u",r.rMZ&A5LkgcbL'!'^K`6W(JcLB#J-(4LIf4]pI/eQjHN&3g +Gk6.XGlE!eHN/?lI/\NpIXh?IBRtbfK7nr5L51SAMMmFPNfT6`P*2&pQC!u,S"#t?T:qsRUnsuf +WiE/&Y->1;ZaI6O\[oGe^;%M$_o9X9aND]McHaeadaZdtf@\d1gYL]Bi8ESSj5f=akNM0plKdg' +mI'H3nF?MK!qZ'Vrq-?dp\4X]s7u]kqtpBjr;H6dJcC`0J,~> +JcC<$JcG-;oD\afrVZTjs8)ckrV/tYp@e1Po^qbGo'u5C[i8EJJgtUQ8 +f@JL%da?Fec-+;PaMu3:_SEq#]Xt_a[^EHIYck10Wi4k5hYu@2g]H6agAT_)gAfh+f_sG"f`'S# +gAfh-f[n^ReH+1Kr201ar3cR5pU0h(rj2X0&[8OCX`'YQH[pd)MMmXdS"m%U[K!W*[JdQ2[fEr9 +\*pj+\`gR%\H0:PpUUC;])0&<\cB;4\,a#8\Gj&=\F-p,])'&=]`,VD]E#YE^\YbF_>D%H_>;%F +_u7OO`W*sXa8a3\a8O$Sa8a6[ao9H_bQ#fac2Q#fci)/hchl)hdJqYpdfe1Ne^i@Mf_*qsgA9P* +gtgidhZMfoi8FIk!9P[42ccO/G +_Sid_Vl-8\S=Gt3QBmcK\?iBBWNV&-Ydh][Sr/o'H!aicH>@SMLJ(B>IY*95Od2E*TMJH_;,gLm +W2Z_VP*;&oQC456T:r!SV5gW!Y-"n2Yl1i-s7F,-_Y(bC_#;%D^Aa)kMZAY6M>rA3L]3&.L&Zi* +K*$XUJc:3"J,aurIK+]oHi&-fH1H4ZH2N!gHiJKmIK+`rJ,Xt/JV&N,KS>/8LPUeEMi*YctF>[C3QT]">Vh^VI_(`Pom=aihoQcHjnde'uq"f@em4 +gtgiEi8N\UjQ5OdkNM0qlg4!*mf)YUnF?MK!V>s_p&Facp\jmeq>^ +JcC<$JcG-;oD\afrVZTjs8)ckrV/tYp@e1Po^qbGo'u5C[i8EJJgtUQ8 +f@JL%da?Fec-+;PaMu3:_SEq#]Xt_a[^EHIYck10Wi2P]T)"rUSH#/LSGerTSGerWRfA!2Jb>&o +N>.D4NJrjSMI:[(6N;nh5N;S\4N;\b,Nr+n:NrG+4OT1@AOT(=.OSb+= +OSt7striQ4%r2ft%rNH7*s02p: +Za7$G[^N]U\[qdP?bF(d]sju9Ssbq0O,f!KIXQNeG'.hEE,KTRMhct>eO0AO/dU?X[P^DK9iBGt:Ir7SQQLJ:N2gDJsH5FEMeQH?spbI=Qj#JV/T.L&H`-q>1!fr;Z`q +rjDe&On4\#OoC=>MZAY6M>rA3L]3&.L&Zi*K*$XUJc:3"J,aurIK+]oHi&-fH1H4ZH2N!gHiJKm +IK+`rJ,Xt/JV&N,KS>/8LPUeEMi*YctF>[C3QT +]">Vh^VI_(`Pom=aihoQcHjnde'uq"f@em4gtgiEi8N\UjQ5OdkNM0qlg4!*mf)YUnF?MK!V>s_ +p&Facp\jmeq>^ +JcC<$JcG-;oD\afrVZTjs8)ckrV/kVp@e1Po^qbGo'u5C[i8EJJgtUQ8 +f@JL%da?Fec-+;PaMu3:_SEq#]Xt_a[^EHIYck10Wi5nnohYTaohXsOnP/p]oiCulr`9"uqc!Y_ +5sRU45R'SE84c?E9`7fe:]F8h;?'Jm;?'Jm:B4/a:&.Na:]4&W:]=2c:\dcc:]=,[9`Rr\:\mic +:\[]_:B4/e:]=2h:[CpX:]=)h:]4/Z;#=,h;#a>c:]O;j:A7Q_:]aKj;#=,h;Z9Pk;YsDm;Z0Jh +;Z'Jm<<#nn[(G1>l7n- +?N+=3@/jXG@UiqX?mTR$jD3S=H.@ +StDXJTV8'RU8+N[V5=0gs/-U2WiN8(Y-5(7Z*L^AZa@-J[^NZS\Gj#G]">Vg]tV4q^qmkd_?Iiq +`5]m>rlGAebKJ,Sbg#$Gpf7bK7nr5L51SAMMmFPNfT6_P*2&pQC!u,S"#t?T:hmQUnsueWN*&% +Y->.9ZaI6N\[oDc^;%J#_o9U8aN;WLc-FY_daQ^rf@S^0gYCWAhr*JQj5f=ak3(smlKdg'mI'uB +!V#XYncA@Srq6 +JcC<$JcG*:o`"gfrqu]krqZWjrV6Ee!;?Eb!VH!_niZI3n*f]3m-O'&l0.R^m[JmQ/ZN7A:riZp9CQc#OI=[-/Mj'NuTW,-&[e@*/[.Ld([emN6 +\GWi)\Gj&&\G`u3])K>=\c95@\a6j*\c92=\c922\c02:]DoPC^&GYH]tV7rqS<*HqS<*HqSN*H +rP\WQrl,)]aN2EBrPn`T!6G)[s2t>a!6kAcrm(MhrQbGhqp>AjrmCu!eC<%"f)++mg&Ke&gB$*c +rndV2!9!_5s5X%:Jt%e<)cbnW2HST +PEV/nQ^O>7T:qsRV5^PuriZ:*qQ[1&lbNS:rPAHJr4i*B!fi8"repo:MMhCi!f2Vere:K.KS9>W +s+:9%rdb#us*jops*XfmqKh[Wqg/6g!.=`nFaegiJ:N3%JqJ]/Knb>;Ll%"IN/WaWO-#NfPa.N# +R$jD4S=Z@GTq\?ZVPgDnX0&P.Yd1UB[^WcW]=bhl^qmn+`Q$!@b0/&Tcd:(geCE.%f\5'6h;-uH +i8N_VjQ5Oekiq?slg4!*mdKW6naZ2@oCV\Sp&F^cp\jmeq>U6gqu-HkrUTr=s,[21~> +JcC<$JcG*:o`"gfrqu]krqZWjrV6Ee!;?Eb!VH!_niZI3n*f]3m-O'&l0.M2I4MN/`mZOHPckQ'I]'R@9V8StD[LU84W_Vl?\sXfek3ZEppH\%&u\]Y2(q_8=.0 +`lQ9EbK\>Yd*^=le^i@)g=k<;h;@/KiT&tZjlYail07L!m-O--n*fc9nac8Bo^r.Us7QHerV6Eg +rqcQirVZWmo)=4?O8j_~> +JcC<$JcG*:o`"gfrqu]krqZWjrV6Ee!;?Eb!VH!_niQC2n*f]3m-O'&l0.qnohYTaohY?Z!)`Mf!)N8^r_35hp/V#k +r)`ku!*/qr!^T(=rBLZU779X:92&)W;#X5j;#4#o:f1(d:esk^pJ(?V!DQ>X:]=2d:\[]a:]F2\ +9`Rr\:]!oc:\[]_:B4/f:]4,f:[M!Y:]=)i:Jh$fmnijXs%i\kp.tfd:/:IXr_WVl!)WMhs&/hn +r)3Djr_i_mq,7/ir`&nrq,@>orD`Vnr`0#!r`&hrpK%2nr`K2's&f;&!a&T/rEB;+>Q%b*>Q7t. +>Pqb(?2n72?iOO5@1m$T>?=]t9M@uH6U.84l-46UO1.6UXF47S$$?9M.uO9MJ4[:AdofQP5aSR@9V8 +S=Q4BT:_dLTqS3TUSRmc%]6)"Vl6VrXf\b/YHY::riuU4[^H+C!k5\Lrj`'A]`,SJ^;%Fu_86,f +"iJ9t`lQ7#aTBW.bPo`BM2I4MN/`mZOHPckQ'I]'R@9V8StD[LU84W_Vl?\s +Xfek3ZEppH\%&u\]Y2(q_8=.0`lQ9EbK\>Yd*^=le^i@)g=k<;h;@/KiT&tZjlYail07L!m-O-- +n*fc9nac8Bo^r.Us7QHerV6EgrqcQirVZWmo)=4?O8j_~> +JcC<$JcG*:o`"gfrVZTjs8)ckrqQNf!;?Ebs7ASJo()>?n*f]3m-O''l0.j]^VBW\rk\HH +rPABJ!Q2kR_u7OP`VmdVa8X-[a8O$S`rO3ZaoBN_bQ#fac2Z)gci)/hchl)hdJhPte'umte^jWM +p"BB!q:bo)rSIP2!T;r5iW/$9jT"??joX`0kl0iHlMp2Mm/HAQmdL,D!:p-\AbGclq"jpfs8Vr] +gsjQf`P0:+XfJ:oU7[sEQBml%_7I(ZYHG$dJ@!)(]q^pYJTu0KB4u%"I>:Hk:k+%OO-6!%T:ShV +;-$[q;5gImW0!4,Ocu-"S"?7FTVA9]XKA_0Xfel&Z2V&4s6IN#^];4K_#;%E^Aj8oNW>(; +Ll%"IN/WaWO-#NfPEhE"R$jD4S=Z=FTq\?YVPgAmX/rG,Yd(OA[C3TU]"G_j^VRe)`Q#s>b0/#R +cHstee'uq"f@em4gtgiEi8N\UjQ5OdkNM0qlg4!*mdBQ4nF?MK!qZ'Vrq-?dp\4X]s7u]kqtp?i +rVc?eJcCf2J,~> +JcC<$JcG*:o`"gfrVZTjs8)ckrqQNf!;?Ebs7ASJo()>?n*f]3m-O''l0.%3OT1@COH5IhOSk1=OSt7O91Q-P5UO9OSk7?P5LI?P5LIBP5^[AP5^[CP5gaGPl6gEPlI$EQM6aFR/EBJR/WKSR[a)B +q47GTqOde\rh9@d!2K=`oV;D]!i;ckqkjFmor7tk!3>sts/l:%r2ft%rNH7*s0;U0#ICeF[^W`V +\c033[]ZI"S=#S'O,J[CI=6EdF`_S@Df(PnMM?b7IrT7YN/<=:F)#)d(< +N;ne9MZ/J4L]E50LAuu-K`6T*Jq8LOJH(-!If4]oI/eQdHN/9aHN/?kI/\QoIK4lsJ,t4Qre"g9 +Knb>;Ll%"IN/WaWO-#NfPEhE"R$jD4S=Z=FTq\?YVPgAmX/rG,Yd(OA[C3TU]"G_j^VRe)`Q#s> +b0/#RcHstee'uq"f@em4gtgiEi8N\UjQ5OdkNM0qlg4!*mdBQ4nF?MK!qZ'Vrq-?dp\4X]s7u]k +qtp?irVc?eJcCf2J,~> +JcC<$JcG*:o`"gfrVZTjs8)ckrqQNf!;?Ebs7ASJo()>?n*f]3m-O''l0.X8h +;uT\o;>F,g;uKYq;u'Ao5_Y+>$Lr/!*fG- +s',G,r*B;.s'Pe6&n,-NlQ2bQ_58jYd/6:+(,6q'L47n6/M9*@p_9M8(X:Adoe;#Zm_S,]#Y +SHtgZT:hjNTq\=]V#I2(VPgAmWiW>)Y-+t4Z*L^B['[6KrjE'@\@B)[]=Y`T]`c'a^VI\b_Z.LU +`Q#s>rlP2_rlb>chH'JQs,[2?!0-u:s,-l7re^Z2!/LQ.s+UK+rdt9(JV!cMs*t&trI+Zms*OEb +s*=M2I4MN/`mZOHPcjQ'I]'R@9V8St;UKU84T^Vl6Vr +XKA\1Z*UgF[^`lZ]Y2%o_8=+/`lH0CbKS5Vd*^:jeCE1&g"P39h;7&IiSrnYjlY^gkiqBum-O-- +mdKW6nc&(\oCV\So`Fj]p\jmeq>^s,[21~> +JcC<$JcG'9o`"gfrqu]ks8)ckrV6Ee!;?Eb!VH!_ni?70n*f]3m-O$%l0.6rj2@+osOh,r3HC.rics:X_j?2H@CL$M2[R_R@g@Yl*^N!qR?L7"1PeL +\,No;\b*E1\bqLQ`;IOP`;dgR`W4'Ya8j9Z`r!gVaSj6\b5TTabl#`bc2c2fc2c2fd/MGm +dK\1MeCE+#fDO:nf`9b%gB$*crn[e8hV[5KqVqP8qr@b=rT=.Cs60LIs6BUL!:9[O!:KgT!:p-\ +AG,Zkq"agcp[d7mbfRlA`kegWVPKuYS=Gt2Q'@NH\$E0?W31l*[B@EIS!8GMFDGH#95o968kr33 +JVT8KR[]t";Gp@l<)TWmVl5W=P*D/pR@9\:T:hmPV>lmKYHG"2YH[c+qm*O-s2"`Pp;$aEqn`'C +r4i*BrJq#?NK*pr!fMqnreU]4LPPk`!el;\re(6&s+10"s*t&tr-eQlrd4'Zrd4WlrI"`rIt.HJ +!J,k%K5?3pL5(J>M2I4MN/`mZOHG]iPa.Q%R$sM7SXuIIU8+N\Vl6SpXKAY0Z*L^D[^WfY]=bkm +^r""-`Q-'Ab0/&TcdC.heCE.%f\5'6h;-rGi8N_VjQ5Oekiq?slg4!*mdKW6nF?)?oCMVRp&Fac +p\sseq>^ +JcC<$JcG'9o`"gfrqu]ks8)ckrV6Ee!;?Eb!VH!_ni?70n*f]3m-O$%l0.r/go=oT9*8qN1`> +!0[;CooT*6rf[2Ar0$u?s-!AFqNCiAr0%)DrfdDHqiq,Gqj-oArg; +Ll%"IN/WaWO-#KePE_>uR$a>3S=Q7DTq\*Yd(L?[C3QT]">Vh^VI_(`5Td +JcC<$JcG'9o`"gfrqu]ks8)ckrV6Ee!;?Eb!VH!_ni?70n*f]3m-O$%l0.j:\RTW:B+&b:]F2b:]4,c:\dca:]=,\9`Rrd +:B4/e:\mff:Jaj]:Adlf:Adod;#=&U:]O;j:'"-er_`)[qbco\o1o?_rDfs&8hp!)r\m!``3"r`&bprDinur`&hrpf@;orE0&%#$=r.=BSg2qcj&'!*fG-s',D+r*B;.% +UWUM>$+^":J48K6pa.&r]Ek93&`ZP2)[fh69me"4$c+r5!Ctb1G1+(+s\Kf/29%82)6sI2`a)c5 +X[gq2E*f`3D2q783oL+6UO1,6pj@17S$'AKKh[o9he8QqbI&bqbST-S"#qkWiN5'Y-+t4Z*CU@Zi.<2[Kj:O\[f;`]=e-V"2;Rd_>V4S_o0R8a2n8%$-LB4bKJ.2< +``A]YdF$Fme^i@)g=k<;h;7)JiT&tZjlYail07L!m-O--n*fc8nac8BoCW%Ts +7ZKerqQKgs8)Wirqu`no)=4?OT0h~> +JcC<$JcG'9o`"gfrVZTjs8)ckrqQNf!;?Ebs7AGFo()>?n*f]3m-O''l0.\[]/Y +rj`!=oXOk1p:1(3ppg:5pppU=]"5Mcrjr'=!P5i<\,a)7\,a)<\G<]6\FmE3])'&=]`,VD]E>j] +^VBW\rk\HHrPAHLrkncSr58KOqSiNUrl>)[rPn]S!6G,\rlY8as31DcrltMiqp#2fqp>>is3gqr +s3q,#f%9fOp"9?!ptGf)qq_D3i8OOl!90gEfZhOW`ko[#X/D_fTU_O?QBmf"^ppbTYH"^^K!321[@_r6HZO%:B7"B:K8NE%I=I$5Od_c3 +BMhW'<)ZYlW2HSTPEV/nQC456StMaKUSOjgs-K,PQN3?EYkbQ1rrBn5_YCtG_#D1F_#1tE^Aj;q +OT(=@NW>(/8LPUeEMi +JcC<$JcG'9o`"gfrVZTjs8)ckrqQNf!;?Ebs7AGFo()>?n*f]3m-O''l0.O8Y1=O7\P6Ont19OnFh5 +OoCOBOo1C?OoCODPPUIAPPgUDPP:=Z"[6BgtU"@V9LqEclY.84Z3D91j\aJ:DHTDfBZ:FoHUk +H$XgbIXgJ@F8U.QL&$K'rVul+rrA2ZP4Xn9OR&#/OT(=@NW>(/8LPUeEMi +JcC<$JcG'9o`"gfrVZTjs8)ckrqQNf!;?Ebs7ASJo()>?n*f]3m-O''l0.fq,$rar_3)]qc3Vp +pJ_)kpJh8ok:B4/b:%qBc9hnDW:A[ie:A@W` +;#3u_:Amuf:@h0[:Amuf:Adob:B+)j:f$g\r(d;fr(m8fqbQTU!)NSh!DcPk;=79Z;#sKjoM>Qc +;"RQ`;"[Zc;Z'Di;Z0Pn;Z0Jf;Z9Vn;ufkl<<#tt<;T\qQ%b(>QJ#4rET8+ra$XQ>Zk'(:JFJP77':)4?Yeg3&ifS2)Ici6UF(&4%'!5.R#pQ +3&W99-6sll.5!G92)I-J3''2d5X[[m2EVf]tV7r_#D1L_@+<$ +`lH0AaiMQFaiaV,!*9#!j&Z%Ws,d;Crf@)>!0-u:s,-l7re^Z2!/LQ.s+LH+rIY0'JV!cMs*t&t +r-eQlr-S-`r-SEjrI+]ps*t'!s++s;K7ei1Knb>;Ll%"IN/WaVO-#KePE_>uQ^F21S"6.CTqS6W +V5L5jWiN8)YHY==['mHR\\#Mf^V@V%`5Ta;aND]McHaeadaQ^rf@S^0gYCWAhr*JQj5]7`k3(sm +l0@U$m-X60n*olHncJFTo`"Lbp@n=[q#C0hqY^6hr;HTcrdk*2s*t~> +JcC<$JcG'9oD\^erqu]ks8)ckrV-Hgp@eLY!VH!_ni61/n*f]3m-O$%l0.TR])B/?]".[Is1.s8s1/-=q76I6ost(5qRcd?qRlsE^VBT[ +s2"QIrPAHLrkncSr58NP!6+fSs2Y/\s2Y,YqSrTWr5nu]rlb>cr6>8e!71Pfs3LVirmCbos3q"t +!nGlRqq1f!!8.2%rS%>-rS.A.r8.J2!9!_5s5X";!9O1As6'FG!pT"8rTjFLs6^lqnF5u=oCV\J +p\=LBf[%^Z`P'4#X/DegTU_L@rg#'tOhS?4YHOt.Mh.qI_6]Y]S">=:B51smG_\md:k!tNNg#p% +Skr<^FOHBI& +!fi8"repl9MZ/J4L]E50LAuu-K`6W(JcLB#JH(,uIf+WlI.VdaI/JEmIfFosJ8'RdJqJ]/KnY89 +LPUeEMiYdF$Fme^i@)g=k<;h;7)JiT&tZjlY^hl07L!m-O--rpKmWnc&([oCW%Ts7ZKerV6Egs8)Wi +rqu]moDX=@OoKq~> +JcC<$JcG'9oD\^erqu]ks8)ckrV-Hgp@eLY!VH!_ni61/n*f]3m-O$%l0.Do +T9!5rf[5Brf[;Fs-!ADrf[;FqNCiAr/q&DpQPZCqNg`>s-W\OqO%8Ms-`qWpmh5PqO[_Z!1s1^r +h07as.TLgpnIDUrhTLir20OnoVqkj!3>doriQ1&rNH7*(9t0NZa7'J\$W03T:2+3NfT$KJ:2chr +cL;ADf0B.NJiUHJpr,eCOqP(JTk^HEFV=0:JOelA3`US@:NteE--5J7n?0F9MBtdIt2ETDfKc=G +'J92H3\eFIt3+2jQ?A]rH.ggp4iVH\GuSkq3'^!rfR>FOHBI&!fi8"repl9MZ/J4L]E50LAuu-K +`6W(JcLB#JH(,uIf+WlI.VdaI/JEmIfFosJ8'RdJqJ]/KnY89LPUeEMiYdF$Fme^i@)g=k<;h;7)Ji +T&tZjlY^hl07L!m-O--rpKmWnc&([oCW%Ts7ZKerV6Egs8)Wirqu]moDX=@OoKq~> +JcC<$JcG'9oD\^erqu]ks8)ckrV-Hgp@eLY!VH!_ni61/n*f]3m-O$%l0.Qc +;"[Wa;#F/j;YErg:f7*fr_reor)*8fr_rDfr`/qsr)N\rs&K%ts&B)!5MP' +=o_e+>lIq0>[(HZb$(:/+>O779F,4Ztkg3B/rU2`*B\6UF+)4Zc"r5XIUq2`N]N/fc5d +/LiG20/YLA3&j#`5!qXs2`rA3L]3&.L&Zi*KE$N'Jc1-!J,XopIJeKbHi8?i +IK+crJ,Xt4JV&K+K7nr4L5(J>M2I4MN/`jYOHG]iPa.Q$R$jG5SXuIHTq\?ZVPgAmX/rG,Yd(OA +[C3TU]"G\i^VRe)`Pom=aihlPcHjnce'uq!f@\g2gYL]Bi8ESSj5f=ak32'olKdg'mI'uB!V#XY +ncA@Srq6 +JcC<$JcG$8o`"gfrquZjs8)ckrqQNf!;?Eb4nS@;o()>?n*f]3m-O''l0.cr6=u]!71PhrmCbo!7Uqs!nGlR +qq1l#s4I5%rS%>-rS%A.h>?%1hr*JjirA'9jT"??k5XTHkiqBtrTjFLs6a4^nF5u=oCV_Kp>t&X +bf7W9`4`4NV4sWRS"#_/P`q0B\@&WFYG\L[JZ?B!YaU$6S:t$[CIi5eLIt<=It +!0-u:!fMqnreU]4LPPk`!el;\re(6&s+1-!s*t&tqL/6gr-S; +Ll$tGN/WaVO-#KeP*D5sQ^F20S"-(ATV8*TUo(&gWiE/&Y->1:ZaI6N\[f>b]t_A!_SjF5aN2NI +bg+M\dF-Lne^rF+g=tE=hV[8MioB([k2tjjl07L!m-O--n*fc9nac8BoCW%Ts7QHerV6EgrqcNh +rqu`no)=4?P5g%~> +JcC<$JcG$8o`"gfrquZjs8)ckrqQNf!;?Eb4nS@;o()>?n*f]3m-O''l0.r/gl< +oT9'7qiLf>s-!DEoT9!5rf[5Brf[;Fs-!ADrf[;Fq3(cArK7/Ep6>TBqj-i?rgV%F8g:]F8L[`L&eHfs8S5TP2q`*PQ$aFOT:LB +O8k4?NW+kM2@+KN/`jYOHG]hPa.N#R$jD4S=Z=FTq\*Yd(L?[C3QT\\#Mf^VI\&`5Ta; +aND]McHaeadaQ^rf@S^0gYCWAhr*JQj5]4_k3(sml0@U$m-X60n*ol;o()DDo`"O`p&Ojcq#C0h +qYU0hr;HTbrdk*4s*t~> +JcC<$JcG$8o`"gfrquZjs8)ckrqQNf!;?Eb4nS@;o()>?n*f]3m-O''l0.h;#*le;"[QUhqbQTUr(d;hr__oV!)`Ab!Du\d:]=2i;?'Pg;?'Gm +;>X8k;uKVl;>=&g;tO&g5MP(=o_e+>Qe87>?kD3 +>l@q9=BAEt9h\,J6pX%$r]U9@!&sj71IXVt69dXs4$u;!69[Ii3&`QE*%!$].PN\32)@*L3BTGj +6:*Uh2Ej;`91_ZH5qt +PQ$aFOT:LBO8k4?NW+kM2@+KN/`jYOHG]hPa.N#R$jD4S=Z=FTq\*Yd(L?[C3QT\\#Mf +^VI\&`5Ta;aND]McHaeadaQ^rf@S^0gYCWAhr*JQj5]4_k3(sml0@U$m-X60n*ol;o()DDo`"O` +p&Ojcq#C0hqYU0hr;HTbrdk*4s*t~> +JcC<$JcG$8oD\^erqu]ks8)ckrV-Hgp@eLY47r.8o'u5=n*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-4AQaMu3:_SO"$]Xt_a[^EHIYl!DYi;_[:hVHuApt>`$pt5W"rS%8(!SH$'eHFCM +dEp8;cN'a5V!bYa[K?]D]>?\H0:PqmcU8qmc7.rODO2rjqsH.0hZ;Zor8R_9r8dn>rT=.Cs60LJrTaIMrpB^Q>jq1Po(2MEl.a_3ai;0: +_69l9US+0JR?s8*PE3Ae['Hp(73S=Q7DTqS6WV5L5jWiN8)YHY==['mEQ\[oGe^;%M$_o9U8aN;WKc-FY_dF6Uq +f%8R-g=tH>hVd>NioB+]k2tjjl0@U$m-X6/n*fc9rpg-^o^r.U!quB_rV6EgrqcQirVZWmoDX=@ +P5g%~> +JcC<$JcG$8oD\^erqu]ks8)ckrV-Hgp@eLY47r.8o'u5=n*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-4AQaMu3:_SO"$]Xt_a[^EHIYkt*mTD>)MSbnrSSc>5ZRfo1JR@'B>QN3EFJaSQl +Nrk?$NrG";M@bV^G@Y2sBl%[,Fa8@aJqf0WMu\k6N;8J+Nr+n:Nr>%2OT1IAO8t@:OT1COSt==OT(CBP5g[:OSb1?P5UOBP5gaGP5^UCP5gaAP5gaGP5^[=PlI$GQLgIB +R/EBLR/E?RR[]fASGf#OT)PA]T`1YbU&^t`UAL\cV#-qeU]@7jVYm@lW;EOoW;ERoWW9*mXT,F$ +Y5PR(YlD":Za-[.TU_C8OH5BTJpr&mGBJ"JDJjWs+:9%rIFotrdOZkpO)dbs*jut +rI=p"K)UB'KSBD[AVZ(uM2I7NNK0'\OckllQ'I]'R$sM7SXuIITqeE[Vl-MoX0&P.Yd1UB[^N]V +]"G_j^VRe)`Pom=aihlPcHjnce'uq!f@\d1gYL]Bi8ESRj5f=ak3(smlKdg'mI'E2n*olHncJFT +o`"Lbp@n=[q#C0hqY^6hr;HTcrdk*4s*t~> +JcC<$JcG$8oD\^erqu]ks8)ckrV-Hgp@eLY47r.8o'u5=n*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-4AQaMu3:_SO"$]Xt_a[^EHIYkq8j:\R]`:\did;>X2a:B4)]:$P^Y<;]brd!)WPgm83^V!)WVkl;.IXoM>Td:f-m^r_WSkr_iJfs%r_m +r)3Pnr_iVjpeq)io2P]hs&AnrrDrntr_ru"<)clm5MP(>5qh,>lS".>5hb+ +>S:=I=B85ttPQ6pGOo^],rf@)>!0-u:!fMqnreU]4LPPk`!el;\re(6&s+1-!s*t#sq0i!bq0i9l +s*sut!J,k%K)pXZre>!>Ll$tGN/WaVO,oEdP*D5sQ^F//S"-%@T:qsRUnsueWN*#$Y-5(8Za@0L +\@K2`]tV7t_Sa@3a2lBGbK\>YdF$Fme^i@)g"P3:h;7)JiSrnYjlY^gkiqBum-O--mdKW6nc&(\ +oCV\So`Fj]p\jmeq>U6gqu-HkrU^#>s-!D4~> +JcC<$JcG!7o`"gfrquZjs8)ckrqQNf!;?Eb47r.9o()>?n*f]3m-O''l0.XhuqrohVHr]gAT_$fDsV&gAfh2f[n^)eC2jm +ps8c3rh]Xlj0fi4[C!H&IXd!*M2[O]S"?CU[/.05[^EQO[JdQ2\,Ei:\c'&:\bW`: +\[]0G\c9/>\bru6\c'&<\H'/=\bE]7\H9@S]DT8=\bio8\bio.\c'&2\c02:]DfJ?]`Pp_^\P\F +_>1nF_>_=N_uI[Q_u@RS`VIOOa8O$S`rO3[ao0B]bQ#fbc1fN`chl)hdJqYpe,Ro!e^i@Lf_sM& +f_sM'gA]k,h#H./h#H4-h?)TmiV_^7j8A!;jo+?Ak5sl3lM^#Km/?>Omf2bUnON*3gXF9d`l5p7 +ZDjasU7[pER?j&$O1`$1ZELF/X/DDba/QqVS!JhkLNHHbF@pJ!LIuc8ItEN=Q(4G;:Jt"h;c0Hk +ViLb=%$[0MS=Z@GTq\KdXfhL"s-N\Mr0R8GpTa\$ri`s6qSDsDrk\3DLl$tG +Mi^s-*J5~> +JcC<$JcG!7o`"gfrquZjs8)ckrqQNf!;?Eb47r.9o()>?n*f]3m-O''l0.Es,lr8oTB0:s-*JGrfR2Cs-*8AqNLT:!1!GIo9]HDr0dGL +r0dSR!1WbRrLNVQrh'1_rh9@d!2K:_s.][lUSO^_UB%+hV>mFjVuN^mW;rmnWW0!kXT,F$Y5GJ3 +Yd(I6UnF3FQB[GjL4Xl$G^+=QF)Pu6D2jI0L4k,,I[=$]hmAO9U,@:X%g +EH?;K7n?-D92'hcJ8K1AEH6,DGBeF[H[LFOHBI&!KN0=N;ne9MZ/G6LkgcbLAur-K`-N)Jq8LNJH(,uIdDL^IfForJH(0#K)UB' +KSBD[CPR_&M2I4MNK0'\OHPcjPa.Q%R$jG5SXuIHTq\?ZVPgAmX/rG,Yd(O@[C3QT]">Vh^VI_' +`5Ta;aND]McHaeadaQ^rf@S^0g>(N?hr*GPj5]4^k3(sml0@U$m-X60n*oi:o()DDo`"O`pAamc +q#C0iqYU0hr;?Nbrdk*5s*t~> +JcC<$JcG!7o`"gfrquZjs8)ckrqQNf!;?Eb47r.9o()>?n*f]3m-O''l0.O,e:\die;>O,`:]=&`:&duOk;Ys;m;Gg5MM/>$G39>[(E9 +r*'b8<`;gi91_WB6:!e!4Zkhe3W:p.2ap&$69[Op4#o5b6p3[p2a'&U2CBIl/1rJ-2D-[<1H7BW +4[DG%2`N]Z4ZQ/,83oI*5t""+6UXC684Q[/RK5[Ka4N\[oAa]_fDI^VI\&_o'Fl`W*p`a2uHGbK@uL +b5,06=7]Jm +JcC<$JcG!7oD\afrVZTjs8)ckrV/YPp@e1Po^qbGo'u5=n*f]2m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-+;PaMu3:_SEq"]XkY_[^\Gj&5])K5A]">TP])B2:\G`u8\F[90\GEc9])K8>])0,<]_fAD +^;%GY_#M7H_#;+K_Yq@P`;RUP_uRdO`r3sV`qm^WaN;R%b5TTabl#`[c2c2fd/MGmdf7c!eCE+$ +fDF5"g&BY&g&B_*g]#t0gYCT`h>H.0huD[5irA':jSn9>k5XWEkQ'oHli6>NmJcPRmmH6md`KVN +`PTL%WMZDbSt)7=QBIDnO1DR%YH=b'VO3U0O,^$)MM[sVHr+TjHq\U3F`hkQIt`iCQ^XP<:f:(i +;c3Ol%ul[5Od)3$S=Z@GTqeQdY4qtqQhm$HQhm$GYQ1s,YlCp+Y5bWuQ^F20S"-(ATV8*TUo(&gWN*&%Y->.9Za@0M\@K5a]t_=u +_Sa@3a2lBGbK\>YdF$Fme^i@)g"P39h;7&IiSrnYjlY^gkiq?slg4!*mdKW6nc&(\oCV\Sp&F^c +p\jmeq>U6gqu-HkrUTr=s-3P6~> +JcC<$JcG!7oD\afrVZTjs8)ckrV/YPp@e1Po^qbGo'u5=n*f]2m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-+;PaMu3:_SEq"]XkY_[^NI=d01nr3C(ooAs2rJpf:ooT39rfI,?qN1Z:qiL]9rK.&? +r/glDrf[;Fq3(Tgos/>gos/H("orJ.qr3#t$>,nBl +S!]M*O,f$IIX?EdF`VVCDJX-)Mhm(?JUVrkFDu)5BmXu*2mZ@L8 +rg!MJ!0dDFs,d;Crf7;ENK&mUMi3JlM#rKgL]3#0KnP-XK*$XUJc(&tJ,XodIK"]pJ,OotJH1<$ +K)pXZre>$?Ll$tGMi +JcC<$JcG!7oD\afrVZTjs8)ckrV/YPp@e1Po^qbGo'u5=n*f]2m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-+;PaMu3:_SEq"]XkY_[^5MM(>5h`7>[(E9>?b?6 +<`2gj8P;TC6:*n!4Zkkf3B&lT2`3rj69[Rr3]T/V2)@$L3&riP1+4"e-SI&(1b1:61G^pK4?l+u +69$t`5!;#$8Ou-35X@_'6pjC47n?0D9MBnbJ:[]O!eZ/ZrBL6Er]g?Hq`k!S!3uL,s0)F)s/d97 +U7nVgrk8]P^:qD!_SX71`;[aU`WsT, +aiMTFaiX9XqH*8hr)NbtrD`i`rg!MJ!0dDFs,d;Crf7;ENK&mUMi3JlM#rKgL]3#0KnP-XK*$XU +Jc(&tJ,XodIK"]pJ,OotJH1<$K)pXZre>$?Ll$tGMi +JcC<$JcFs6o`"gfrqu]krqcZjrqQNf!;?Eb!VH!_nhot,n*f]3m-O'&l0.2"lJ1nh;$c\gA'>%f\-2Vs4IJ+f@BlM"k(fF +d*L&9cMl&gU\gkbV=q@b[0F(HZa-j?Y5YO9Ngk9@ItEB2MN3piT;&\G\c0,1\c'&7\bWi6]D]DB +^&>YF^\>PD_>1nF_>V7M_uI[T_u.IQ`V@IOa8O$Ta8a3\ao'<\bQ#fac1fK`chl)gdJqYpdfe1N +f%/IMf`'S&f`'S'gAfq,g]cHfgtgiCqq_D3i8ORms5X(=rT4(Aroa=F!9sIJs6T^O7df[*gsXoGO,f-TLP:A-H[9gXEcZ>CEclMKGC>!sO-#g"TNP,i +:K:@krhg9cO-5ThQ'n/6TV/!QW2cuns8J;aQhQgGQhcsEYlCp,Y5>?9s7aA+_Yq=M_#M1I_#;%F +^&sahQBqN8#F(F9P*1riOT(:GNfB$WN/NUOreU]4LPPk`!el;\rIb-%s+1-!rI=cpp3ljfs*srs +!eGrTrdt6)L&Qg9LPUeDMMmFPNK0']OckomQ'Rc(R@9V8SXuIITqeE[Vl-MoX0&M-Yd(OA[C3QT +]">Vh^VI_'`5Ta;aND]McHaeadaQ^rf@S[/g>(N?hr*GOj5]4^k2tmll0@U$m-X6?mfDqJrpg-^ +o^r.U!quB_rV6Egs8)WirVZWmoDX=@PlH7~> +JcC<$JcFs6o`"gfrqu]krqcZjrqQNf!;?Eb!VH!_nhot,n*f]3m-O'&l0.0O8b1:O7eV7OoCIAO8=t:O8G%9O8Y1? +O8Y1=O8=tQi*6KRJiNLR0&hH +S+rNQSb/NQTDtS_U&UheU\CM_U]%"cUB%+hV>mFjVuN^nWW/poWW/suX7`OoXo,@%Y8".>UnO6D +QB[GiM1^8(H['[REH#gpC_hqaKnY),H[0^PD/3ftARf1T>?b33'1o8s6= +Occ#tQBqN8#F(F9P*1riOT(:GNfB$WN/NUOreU]4LPPk`!el;\rIb-%s+1-!rI=cpp3ljfs*srs +!eGrTrdt6)L&Qg9LPUeDMMmFPNK0']OckomQ'Rc(R@9V8SXuIITqeE[Vl-MoX0&M-Yd(OA[C3QT +]">Vh^VI_'`5Ta;aND]McHaeadaQ^rf@S[/g>(N?hr*GOj5]4^k2tmll0@U$m-X6?mfDqJrpg-^ +o^r.U!quB_rV6Egs8)WirVZWmoDX=@PlH7~> +JcC<$JcFs6o`"gfrqu]krqcZjrqQNf!;?Eb!VH!_ni$%-n*f]3m-O'&l0.j>_:]F8k;>j>d:]4,g;>O)h:\mib:\mc_:%hWT +<<-(t<<-"t;\;/W3B]Ph5=._,7n-*C92JD[rD*2`qG-l]!)EMhs%`Pfs%`>br)!>fr(d2bs%`Jf +r_E)[qG-ubqG%#dr_NSjpeL`_"&;Qb:Amug;#=&V;#F,h;#X>k;#O2Y:]OAb:]XEiq+pudrDEJj +r)!Mn;,R9gs&&Siq,-obr_rDfq,R>nrDi_o"BAK'?b99=&r6s +:eFAO7R9@*4Zbeh3B9&V2Dm +JcC<$JcFs6o`"gfrVZTjs8)ckrV/VOp@e1Po^qbGo'u5C[i8EJJgtUQ8 +f@JI$da?Fec-+8NaMu3:_SEq"]XkY_[^=ugiVqd8hZVflgtUTYg@a.ug'cTdf%&=#e'l^kd*MU7 +rQY>:rM9@fosOG!rj*WPZa7$FZa$d>Y-"b+XHK6'I=R$,M2RO`S=l^Z[/RK6\,*Q2\,Ei8\c92: +\bio.\HB@P\[_FFrj_m:p:C76!P5o>])B2>\Gs)>\G`u<\Gs,>\FR30\GEc3])0,<]`5\D^&YqB +_#D1H_#;+J_Z%IQ_uR^P`;dgO`r3sV`r!gVaSO'ZbPo`ac1fN`chl)gd0S1Le'upuf%8ONf`'S' +f`'S'gAfq,h#H+0gthe_s53n9qr7Y9rT*q=roX7Ds6'LJlMg,Km/QH)m,ZpLb/hTA_SNd^WM?2Z +R[KS0O-#H_\?W?BY,\LTJ#ABgMi!.?K6qohGBNn+s)KH.F\Y_[JVK/GQ^XM;:fC4n<)c\mW2GZ; +OcblmR@Kh?T:hpVX/u!on!3s?q3D)IYHRr.r2ot"!3*Yd(L?['mHR\\#Mf^V@V%_o9U8 +aN;WKc-FY^dF-Oof%8R-g=tE=hV[8MioB([k2tjjl07L!m-O--n*fc8nac8BoCW%Ts7ZKerV6Eg +s8)Wirqu]moDX=@Q2c@~> +JcC<$JcFs6o`"gfrVZTjs8)ckrV/VOp@e1Po^qbGo'u5C[i8EJJgtUQ8 +f@JI$da?Fec-+8NaMu3:_SEq"]XkY_[^;\&T_kART(&[q2P*.r/^f:r/^N4rfR2Arf?o;rK$f:qiC`s,m>E!0Ql7o8s$9rKI,Arfd2Aq31`@s-S +o:GuS!204_!huHbpnIb_rhTFds.o[ks/,^ls/>jpri#aos/Q+"r2]n!qlK[t/ZPV?R[9>)O,SpI +J:)]gG&q_DD/=$*Mhd">JUVr_BRsu8BkCmb@U3/@=BAQ&=!1OH=[khf@V0CoEHHGN7nH6G9MA$, +It2ESD/XB6Fa/01H4,+MJUlS5hr!ANioC%!!9O&sqf;COrGqqAriZ1$ri?+#_>j4ko9/^-rfI/I +s-E_Orfm_QPEV/mOcbb)Nrb9#rf$l8!/gc4!f2Vere:K.KS9>Ws+:6$r.+crnUCFdrIFp!s+:6& +!JH1+L2D^%M2@+JN/WaVO-#KeP*D5sQC+&.S"#t?T:hmPUnjlcW2cl!Xfen5ZEppH\%&u\]Y2(p +_8=+/`Q-'AbKJ/Ucd:(feC<($f\,!5gtgiEi8N\Uj5f@bkNM0plKdg'mI'H3nF5u=o(2JFrq6 +JcC<$JcFs6o`"gfrVZTjs8)ckrV/YPp@e1Po^qbGo'u5C[i8EJJgtUQ8 +f@JI$da?Fec-+8NaMu3:_SEq"]XkY_[^8n/rDbr_WPjqG7/fqG-rar_3)] +oi:W`r_req!*/qrrDNkt5!h@m5Q3qQ6q0U991_kU:AR]]:A[cc:B"&h:B!uf:A@W_;#F,f:Amoe +:Adoe:@h0\:/1[^rD3;cs%iYks%iDbr(dDi9heC]:]F8g:[V'W:]F8j;>sDj:[_*[;=mZc;,I*b +r_WMir)3Gi!E)em;#aDk;?0Sn;YX,a;ZBYr<)rTjq,R>n"'&B%)!aJr7r*02%'N.e)91h`D6:3t#4$5Sa3B/lS2DkD#s$%/[4$c.t2Dd-E0eb75/1W;&.P!(L +/M/V51c%!J3]oYn6UEam2Ea5e2bQ_569mb$5sn%-7R]d;7nHBHI!pHmIt3*%rdt?,59FLl$tGMi +JcC<$JcFs6oD\^erqu]ks8)ckrV6Ee!;?Eb!VH!_nhot,n*f]3m-O'&l0.cr6=u]!71PhrmCbo#1M)Pe^i@(qq1o$rn.5' +rS%;+rnIY2gtgiEqq_D3i8FIks5X+>r8mq?"R#"4l0835rp3eRjP/,)aMu39_7?PEUS=BNR[KS- +OH,@5Z*LO7WiDkFUoLi?YD%U\IF#WrT0:s7X;*_Z%CM_"YV@^&XT#R/`KQQN!-SP`q;oP*(lgrf7)? +NW+kStMdOUSO`aW2ZetXfek3Z*UgF[^`lZ]=bkm^r!t,`Q$!?b0/#RcHstde'uq! +f@\g2gYL]Bhr*JQj5f=ak3(sml0@U$m-X60n*ol;o()DDo`"O`p&Ojcq#:*hqYU0hr;HTbrdk*8 +s*t~> +JcC<$JcFs6oD\^erqu]ks8)ckrV6Ee!;?Eb!VH!_nhot,n*f]3m-O'&l0.uO8Y+: +N>me7Mi3IMM26tBLMqBHA8#^oDfBfBI"6g'LlM.fqMk3/r/^f:r/^T6!KiKCOoCI@O8P+:O8G%9 +O8b7@O8Y.BO-#HaqN1`qN1`>s,mAEo8rR+!0[;Eqi^rBqNCc?q3:oEs-3PKq3LcAqO%2K +rg)O,SpIIscNcG'%eGD/=!)Mhd%?Jpr&kBn(VeN.,;G?sQu?<`W6"c@7i8N\Uro=(@pMp%MpN-:Rr2ot"rMopu +_Z0=lqNCl@r0$Z6s,[5Krg<_P!1*VL#F(F9P*1riOT(:ANfF$s!fMqnreUZ3L])r/KnP-XKE$Q' +JbsurJ+nEiJ,FisJcC?$K)pXZre>Vh^VI_'`5Ta;aND]Mc-F\`dF6Uqf%8R.g=tH>hV[8MioB+]k2tjjl07L! +m-O--n*fc9nac8BoCW%Ts7QHerV6Bfs8)Wirqu`no)=4?QN)I~> +JcC<$JcFs6oD\^erqu]ks8)ckrV6Ee!;?Eb!VH!_nh]h*n*f]3m-O'&l0.d +r([2dr(m>fo1]6\:&Ric:]!oe:]F8k:\[]_:BO?d9htX_s%rSgmSNgWs%r\lr_WPhmna!]r_NSl +peV#h:f.$br_WMir)3Dh!E)em:]OAk;ZBVo;YX,a;Z9Vd<;KVmbm6UEam2EX)b4@Vn58O5U+6UF1.7/fXY84Q6FHiAEmIKP(MJV*lR!/0r.s$$EHq*=mC +r2ot"rMpU3U8"H[VPpJnWiE/&Xfeh1YctD2Z2h61[03qI\%'$K]DoPD^&G_H^r$&f"2_sn`;[dS +a8a3\anAd3=8Gtf<StMdOUSO`aW2Zet +Xfek3Z*UgF[^`lZ]=bkm^r!t,`Q$!?b0/#RcHstde'uq!f@\g2gYL]Bhr*JQj5f=ak3(sml0@U$ +m-X60n*ol;o()DDo`"O`p&Ojcq#:*hqYU0hr;HTbrdk*8s*t~> +JcC<$JcFp5o`"gfrVZTjs8)ckrqQNfs7ZKcs7A;Bo()>?n*f]3m-O''l07Bnk2bR_iS`VMh;$`< +f[n^(eC)ajcHXPTaN)9<_ns4(]tCqe\$k5Qq;M>2"lJ1nh;$f_g\ok!g&Kb-g"=mTe-=CMdF$=f +ci)/cc2=F8V#R:c[J[E1Zh:U/Z*Ud?YHFq-ri-NkSpPj9KntSEO-H*)USk6'qR6@3r4)^9!4_m9 +qmc=0!4qa3!4`$=!kPqQpU^=6!kQ"Uq7?R9!4_p:rj_=*!4_s;pU^76r4E$CrOr9HpV?dEqS<$F +rke]Qp;?sMpr<9QrPn]S!6P)[rlb>cr6=u]!71PhrmCbo#1M)Pe^i='qUkf#rn%5(r7_2*rnRP. +s5!_4r8%P5i8NYlirA'K;Y*s[-T6O^E@!P@aI"m>M;1!kIN/s6nS"1:ZaI6N\@K5a]t_=u_Sa@3a2lBFbK\>Yd*^:keCE1&g"P08 +h;-uHi8N_VjQ5Odkiq?slg4!*mf)YUnF?MK!qZ'Vrq-?dp\4X]s7u]kqtp?irVc?eJcD&9J,~> +JcC<$JcFp5o`"gfrVZTjs8)ckrqQNfs7ZKcs7A;Bo()>?n*f]3m-O''l07Bnk2bR_iS`VMh;$`< +f[n^(eC)ajcHXPTaN)9<_ns4(]tCqe\$hp$q4RSVoq(`Fs.'"Us-WqUQ^@Z:rKmMNoRZ+arf%/A +NK&gPLk^]aL(A9M@qB@iDf9W;H$t0nL5Pbbqi19/r/^f:r/^T6rK7)@r/^c;qiCW9qiCc=rf@#> +"-8P*O8G%OoLREOn4\+OT:RCPP^OBPPUI?PPLI?Q2-a@Qhd$GR/iWMRJrWTS+iHQ +Sb&HPTDYD^UAq"`U&^tdV#7"fV#R:jVYm@lW;NXoW;W^qWrB'sX8o=!XBVg.WMH2UQ^3eqN/<.; +I!BmZF`VP>CM[d%Lk^V7J:)TVI=m33IWT(AEa;1&8QnAZ?Y!_;7:'J8C2S!3Fa6JJ84Q?J9M0__ +JU_QSDJsK7FEVqTH?spdIt@USs5!_4"5r.tj8J'rA3L]3&.L&Zi*KE$Q&Jbsuf +J,FirJH1<#K)pXZre=s=Ll$tGMi^s-E\8~> +JcC<$JcFp5o`"gfrVZTjs8)ckrqQNfs7ZKcs7A5@o()>?n*f]3m-O''l07Bnk2bR_iS`VMh;$`< +f[n^(eC)ajcHXPTaN)9<_ns4(]tCqe\$l95rD3Jir(d#_qG?u`r)!>hr(m;gs%iSgr(m>hoM,'[ +r)EVnoMY]fqGIo&4[M7o5X.P#6q'O78P;WM:AIW]:Adid:B"&h:Adid:Adof:B+,f;#X8h:B!rj +9MJ5V:Adof:@V'W:Adoc:B+,i:]O;b:Amrj:/+GXrD3GiqbQWVr(m>hr_`YkrD2lY!Du\m;>X8h;#sQlr(mAjr_i_m!)iPgpeq)io2PTeqH!SqqGdAmqc6:!k"4ut_kr]Vhs3B/rV1+aRi,V:W!1H%6N2)@$G3BTGi +6:-84c-65=%U76O-"L7Rfp>8kf52s*Xiq"+PiPK)L<'4[)'u5P@AB5Q7b_X8An' +UnsufWN)u!XKDK)"0\r5Z2V$0ZaB_>&[o3[\@T;a]">Vg]tV7t_8=+g_?@cp`5T^p`r=$YaS&[1 +=8l8#rA3L]3&.L&Zi*KE$Q&Jbsuf +J,FirJH1<#K)pXZre=s=Ll$tGMi^s-E\8~> +JcC<$JcFp5oD\^erqu]ks8)ckrV6Ee!;?Eb!VH!_nhot,n*f]3m-O$%l0.Ycb./X/W(TQ'loGK8#/?N0'?oStr9er3lO4s0r*?\F[65 +\@K,Zrji'?qRQX;o!nb1rjh[4rOMp>q7?I6s186@rj_+$s1/3BqRZR9r4E$CrOr9HpV?dEqS<$F +rke]Qp;?sMpr<6PrPn`T!Q`C[b5TTabl#`[cMu5gd/MGmdf7c"eCE+#f@ToPrn7;'s4R>(s4dP. +"P__fhV\7fs53k8qVqP8s5a(=roX1C?0^b@jP//)ai236_RZ\FUS=BOR[B>)OcYT_Z`p[9XK/4K +I]KinXdFEtSUb'L@!G:aIYUQk:jRVGNK9KrT4Ukr:fgRp;KJb7ViHb"P*D2sQ_'_Vh^VI_'`5Ta:aND]Mc-FY_dF6Uqf%8R- +g=tE=hV[8MioB([k2tjjl07L!m-O--n*fc8nac8BoCW%Ts7ZKerV6Egs8)Wirqu]moDX=@QiDR~> +JcC<$JcFp5oD\^erqu]ks8)ckrV6Ee!;?Eb!VH!_nh]h*n*f]3m-O$%l0.!FE_5+CM[m-Ecl\UItNK6qMb<2p5]$2rf6o;p5o68rfI&= +r/gc9r/gf:s,d5@rK%#?plPK9qiLi?qN1`>s,mAEplGKSo:?#UTV27WrhBFfpn@b`qkX1crhKOjrMKLjs/>jps/>mqs/Q(!p8et- +US+'BQBI8fM1^>+H$FLTEc5o6rb=0EL4k/.I!TRAK7o23FCT91@7N[W>!Q.rAO/dT?XdYbDK9iE +<(KPL9MJ2R?\!]XDuOVaEH6&AGBeCZH@('iJUlMSg^)`mhV[8MioB(ujSa&uE;+AKErC(YErL.X +ErW39WrK'rfn([PEV/mOcYZcO,f6[N/W[QMZ/G6LkgcbLAur- +K`-Q'K)U>sJG4QiJH(3#K)L<&KSBD[!JcL1M/%p+N/WdXO-#KeP*D5sQ^F//S"#t?T:hmPUnjlc +W2ZeuXfek3Z*UgF[^`lZ]=bkm^r!t,`Q#s>b0/#RcHjnce'uq!f@\d1gYCWAhr*JQj5]4_k3(sm +l0@U$m-X60n*oi:o()DDo`"O`pAamcq#C0iqYU0hr;?Nbrdk*9s*t~> +JcC<$JcFp5oD\^erqu]ks8)ckrV6Ee!;?Eb!VH!_nhK\(n*f]3m-O$%l0.hr_`YkrD2lY +r)*5cs%rbmqbI2gq,.&fr)!Jm;>a8j;?'Pn;#jMg;>3uf;Z]os;tj8g:=BABr:eOGP7RBF,5!(eg3]K#W2Z>T567P2`3]fVn5X.Fn2`N]N0-;8^/M&D-2(g^C1Gq0R +4[)+t3]B#W4[)(l5lO:X69mh%5skQ<#t.9Q7S$'B9M0X1HO,"II=?ZrJV&LQKDn%654:`.5QX0N +X8/dqW?.q7WMunuXKAV-Y-5(6Z*CU?Za7$H[C3NR\[oAa])K;I]Y;+q_SO++_>_:O_u7LY`Q#p< +a2lBDp/_#krDr>ds-j(YR@4&A!LK,OPnB7EPEM)kOH>NaNfK*XN/NUOreU]4LPPk`s+LH+rIb-% +rdjlqpOE$is+13%rIY-(L&Qf-LPYqdC5Rq.N/is[OHG]hPa.N#R$a>3S"6.CTV8*UUo(&gWN*&% +Y-5(7Za@-K\@K2_]Y;.r_SX71`lH0CbKS5VcdC.heCE.%f\,!5gtgiEi8N\Uj5f@bkNM0plKdg' +mI'H3nF5u=o(2JFrq6 +JcC<$JcFm4o`"gfrVZTjs8)ckrqQNf!;?Ebs7A;Bo()>?n*f]3m-O''l0.H25hr!;Hh>,h*gA9M%gAT\/f[eU&eC)eDd/q\@ +cMYoeN;\b5NrP(?Ni&]QV=M%n[/RE*ZN%3/Y5k^(WtMA/N15*=J:rZ5Mi?\E:@%])K>>])0,;]E#YD^&YqB_#D1G +_#;+K_Z.OI_uRdN`r=$V`r!dWaN=;$rlb>cr6>5d!6tGes3LVirQto!e'lgse^i@(qUkf#rn%5( +r7_2*#i+1igYCWAhr"Chs53h7qr7V8!9F%=roX1C>O(;'f#l+Q`5'4"W2QJbT:MF=Q'IAkNJk0I +Y-"k0X+Po)`Oi:EItjV2DcB/N8oT-38ki-.ItirFR[TjE;G^1h<)Q\oW2HPQOHPflQ'n)3S=cCF +U84`fY4)DaQN!-LQM?a;QN!3NQN!o]W;rmLl$tGMi^ +JcC<$JcFm4o`"gfrVZTjs8)ckrqQNf!;?Ebs7A5@o()>?n*f]3m-O''l0.gos/>prs/Q(!qlE/cXK8CrTUM75P`Lc[ +K7J;oG^"7NE,]W/C1rKZKS+f)Hu*MLO,&1-AnlEg;*R-F5ZM-%5Xn4M@qKOpEccOq7n6&J9E7`b +J-pdED/XB5EccMLGlE!nI"$QrK%o)ZgBcTkhV[8MiT&ttjR.$cEr:"XErL.WErN*9W;rmLl$tGMi^ +JcC<$JcFm4o`"gfrVZTjs8)ckrqQNf!;?Ebs7A/>o()>?n*f]3m-O''l0.gr_NSjp.kT_s%`Sg!)EJgs%rSg!)WYlnkf6[s%r\lr_WPh +m83dZpe^uf!)WPg!)WJgr)3Dh!)i\j!)`_nohkE\r_ikt;cEBhr)NPnr`/eor)NVpr)`i!qH3f% +rEDuu<)ZUi9M7oF6UF%%4?>Pa3B&lT2)R3X6:!n%4?>_m6:!^p3&icO/gMGa/1rG.2(pgD1H.?U +4[),"2`EWR4$>\g84c?E5sR_$62j4Y6q0^:8Ole +JGt-"K)L=EKS>,7L51S@M2@+JN/WaVO-#KeP*;/rQC!u,R[]h=StMdNUSO`aVl?\sXKA\1Z*L^D +[^WcW]=bhk^VRe)`5TdhVd>NioB+]k2tjjl07L!m-O--n*fc9 +nac8BoCW%Ts7QHerV6Bfs8)Wirqu`no)=4?R/_[~> +JcC<$JcFm4oD\^erqu]ks8)ckrV-Hgp@eLY3qW%7o'u8>n*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-+8OaMu3:_SEq"]XkZ1hr!AMpYc>7hr!;Hh;%k]s4[;%r7VD/f[n['e'lbDd07nC +cHXSWrepc7qi1N6s,@)?VPWdirj;[2pTjh()Qp3EY,nY'WMYcMH$t6sL5:_IPa7f2VQ-u2rO;g: +s1&->n[SY0rji$>qRQU:rOMs>pUTk+rj`$?r4Dg:r42gqn)d=!58BGs1eldci)5hd07tIe'upurn%#!rn7;' +!878'rnID,s5!b5rSIS3!oW%rqr7V8!9F"<:?La&kih'[e]GkM`5'4!WMcMaTUhOIY*N=QC4@A;,C(g<)QVmVl,N7rfRDLR$jM8rgj=f +USt/mY-.0ls-<>Ens/m6rg*VNri,dnaoD%MqSN9KrkS6Bqn<*%SGo#XRK/cTQiWP>rfmMKPQ$^G +Oc]R'!KN0=Mueiore^Z2!/LQ.s+UK+rIb-%rdjHerdk*$rI]'BKnY89LPL\BM2I4MN/`jYO-#Ke +PE_>uQ^F20S"-%@T:hmPUnjlcW2ZeuXfek3Z*UgF[^`lZ]=bkm^qmn*`Q#s>aihlPcHjkbdaZdt +f@S^0gYCW@hr*GOj5]4^k2tmll0@U$m-X6/n*fc9rpg-^o^r.U!quB_rV6EgrqcQirVZWmo)=4? +RK%d~> +JcC<$JcFm4oD\^erqu]ks8)ckrV-Hgp@eLY3:uh5o'u8>n*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-+8OaMu3:_SEq"]XkYFStGSHs.B"Vq47GT"J)'QS!s8Cs-WhQrKdJ"")D^hD>nGN +D>S2OJqjps/>prri5suqlDr[US"!BQ'75eM1^;*H$=IT +E,fi5CMIQtB4upLIt)f^BRkbnHuih8Dd5\"9O0nb@;/"r7:9YADK'ZB7fGpW9ERqcqf;IQqJuS7ql%X:oo]*6o9&j1!M,b[ +S,\oWRJrQSQ^7W9!L/fIOo^],rf7)?NW+k;Mi.Ljs+gZ1reCH,s+L?'s+:6$m=>1es+:3%E.iq! +L5(J=Ll$tGMi*YHY:<['d?P\[oDc^;%J" +_Sa@4a2lBGbK\>Yd*^:keCN7'g"P39h;-uHi8N_VjQ5Odkiq?slg4!*mdBQ4nF?MK!qZ'Vrq-?d +p\4X]s7uZjr;6HjrVc +JcC<$JcFm4oD\^erqu]ks8)ckrV-Hgp@eLY2>$M2o'u8>n*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-+8OaMu3:_SEq"]XkZN;>sAl:]=,^:]!ub;#jGk;#sKjr_NSjr(d&`r]gBIr^$QL +r]g9F!DZAYm35<_1j3]T2Y2`CXm,Vq>55s7Fp3^>tr50JtXD +2`a&b5XPH/"?&A*4?NO5!C9'O5lX4O6jH.N7R]j=8kf4Vs*=Wj$$giCH[U_:[_ns=/`5T^8a2lrA3L]3&.L&Zi)KE$Q&JaJ!e +JcC?#K5cKtKnb>;LPUeDMMmFPNK0'\OHG]iPa.Q$R$jD4S=Q7DTV8*UUo(&gWN*&%Y-5(7Za@-K +\@K2_]Y;.r_8=+/`lH0BbKJ/Ucd:(feC<($f@em4gtgfDi8ESSj5f=ak32'olKdg'mI'E2n*olH +ncJFTo`"Lbp@n=[q#C0hqY^6hr;HTbrdk*;s*t~> +JcC<$JcFj3o`"gfrquZjs8)ckrqQNf!;?Eb3qW%8o()>?n*f]3m-O''l0.1nF_>_=O +_tM"K`V7CPa8rdaQ[pe^`7MfDF5!g&K_)g&0S&g]$". +hYuF4hZ)I7i8NYlir7s;LPUeDMMmFPNK0'\OHG]h +Pa.N"R$a;2S"-(ATV8*TUnsueWN*##Xfnt6ZEppH\%&u[]Y2%o^r""-`Q$!?b0/#RcHjnce'uq! +f@\d1gYCWAhr*JQj5]4_k3(sml0@U$m-X60n*oi:rpg*]o`"O`pAamcq#C0iqYU0gr;HTcrdk*; +s*t~> +JcC<$JcFj3o`"gfrquZjs8)ckrqQNf!;?Eb2"^D2o()>?n*f]3m-O''l0.O8Y18 +O8Y1Onk+P5pj>Q1^I@Qhd$@RJ`NRS,/ZQ +Sb/KRTDkM_U&C_cU\LP`U\gkeU\pnfV>d@hVuN^mWW/psWW&psX8T+6Vk]lQQ^*bqN/<1:I!BjZ +FDl,:D#J)LBPIEY-Y@"&H]!9+H#dA8B4X/#:d%][@q\>$?"%>]D/jZB7S$$<9h\2oJ,X +JcC<$JcFj3o`"gfrquZjs8)ckrqQNf!;?Eb2"^D2o()>?n*f]3m-O''l0.i:B!ud9`Ife:Adlf:@_-X:AI]c:B+,h:]O;d:'"-cr_NPhs%NJgrD*DiqG.)fr_`5_r(m,b +"A_cf:J^[\!)NGfrDEAes%rbmqbI;j;,L6h;>a>h;#sQlr)!Djs&/PfohtWbp/Lujq,[GoqGdAm +qcSa2*!QQ2)R3K1,UjDr\Zep5=7Rs3ArfR0J+1j.46Mt +1cR?M0f:pN4[),"2`WcS5!:tq83K7)585)]L9MJ3*rcnZnH$Xd`I/\QtIt3'$ +K)UE#4oRSD4TI\65Oh#StMdO +USO`aVl?\sXKA\1Z*L^C[^WcW]"G_j^VI_(`5Ta;aND]Mc-FY_dF6Uqf%8R-g=tE=hV[8MioB([ +k2tjjl07L!m-O--n*fc8nc&([oCW%Ts7ZKerV6Egs8)WirVZWmoDX=@RK%d~> +JcC<$JcFj3oD\^erqu]ks8)ckrV-Hgp@eLY1\C;0o'u5=n*f]2m-Es$l0.9ljl>C[i8EJJgtLK7 +f@JI$da?Cdc-+8Na2Q!6_8!^s]Dg[ehuDX/i?](``9]"@UGrOE!@]=e*SqRZX9rji0A\@DCGs17X/s17s:!5/,!SuW2hZhrphr*GOiV_^6j8.j_jP&,3a2l3:_nrsbVk]oXSXYt2Q&gudNJidS +Mhm4HMM[1GLAlrcL6[UTF`C5JED(.qL.b9>H@^j2PF@u4:Jt%k<)QVQNK0![Od)#qR@Tn@St;[Q +W2d#'Xf^mgr07&CrKd8Er072Gn"eVBXSXl;MRfStGrg3_QQN!-M +P`u*0#*G".O,f6[repl9MZ/G6LkgcbLAuu-K`-Q&K)U>lJGt-!K)L<'KS>-ZL&m'creYHKMi*YHY:<['d?O\[oDc]t_=u_Sa@3a2lBFbK\>Y +d*^:jeCE1&f\5'6h;-rGi8N\UjQ5OdkNM0plKdg'mI'H3nF?&>o(2JFrq6 +JcC<$JcFj3oD\^erqu]ks8)ckrV-Hgp@eLY1\C;0o'u5=n*f]2m-Es$l0.9ljl>C[i8EJJgtLK7 +f@JI$da?Cdc-+8Na2Q!6_8!^s]DeE%TCSZTTD>)WSbJ]\SXc4>R[TY4rg<\Os-E\%r+u@Lr+uCm +rbhUMqJPqcq2P?3*fGu8MMm@LLkphBL51G%G@=umC2@d+EH?DRIt<<0pl5-1q2YN9r/^Q5rK7)@ +qiCc=!KiKO8P(>Onk+=O8=tmFhVZ<[mWW/psWVrjrWu%e2TV%X>Q'.;i +M1^>+I!BdUEGoc3C23`^2eQf;B4baeAS,LaAn,@iCMR-S4?QY1<*a$#7S$ipB5DO,Fa-DI7nlZN +95A?\DJa92EH?8HH2`+/I"$KpK7\`.g=b36gY1E9g=tE=hV[5KiSieUrolJGt-!K)L<'KS>-ZL&m'creYHKMi* +YHY:<['d?O\[oDc]t_=u_Sa@3a2lBFbK\>Yd*^:jeCE1&f\5'6h;-rGi8N\UjQ5OdkNM0plKdg' +mI'H3nF?&>o(2JFrq6 +JcC<$JcFj3oD\^erqu]ks8)ckrV-Hgp@eLY2"^D1o'u5=n*f]2m-Es$l0.9ljl>C[i8EJJgtLK7 +f@JI$da?Cdc-+8Na2Q!6_8!^s]2JK&r_NSjr_E8br_drCm5c##7rj:JX_\nkK$WqG7,ds%iVj!)NAbr(m>fs%WDe!)WMf!)WYlnkf6[q+q2i:/4S\ +pe^rcqG@,fq,%)gs%rVh"&Mim;Z'Di;Ys;l;Gm?gs&&bnpJLT]qG[)er`/\nrDi\nr)NYqqcEc! +rE0h:<)c^k:/"8P77BI+5!D(k3B9&Zr\Xg71c-pDr\OO2q_K0L1c$d4)^d0h.kih62)I'H3&s,c +6UWjn2Ea5&4T@PS5sR_%6UX:07n?*@7n?>Q9)hQbGQ)jeGm/M>H$XgbrdG!"J:N3%rdsu0r&k!C +mm$;,qPOCrXf_T*!3cC+#dL\@Za@-K[^c=Gs0r0A]=koU^';Bf^qmk(_>_:U_o0L5`Q#staRrU1 +=8c1h<<]"dSt2FBrgNqWRJrQSQ^7W9!L/fIOp7&1O,o<]NW+k;Mi.Lj!f2VereCH,s+L?'rdt-# +npp^jrdt*$!ec8]re:H/M#N6IMMmFPNK0'\OcklkPa.Q$R$jD4S=Q7DTV8*UUo(&gWN*&%Y-5(7 +Za@-K\%0)^]Y2(p_8=+/`Q-'Ab0/&Tcd:(fe'uq"f@\g2gYL]Bi8ESRj5f=ak3(sml0@U$m-X60 +n*ol;o()DDo`"O`p&Ojcq#:*hqYU0hr;HTbrdk* +JcC<$JcFg2o`"gfrqu]krqcZjrqQNf!;?Eb1\C;1o()>?n*f]3m-O'&l0.H56hqm2Fgt_e]!8@G*qV(r%s4@J*e^W'rrmCbm +!71P$qi1N4s2OuHr/L]9!0?u:osO_)s0Ma2rimQLY-"h/X/rD&WMlbURs'+,KSYD?MN\bs&:\c',>\c',8\ad90\c9;A]`,P=])K8?])T>@\G`r@]",A_](NW6])B2=](`i3 +]E#YE^AbnA_#M7H_#2%J_Z.OL`;[aD`r3sXaT'BYb5TTabkTH^cMZ#ed/MGmdf7breGe&!fDF5! +f`9\'g&9Y&gBQHhh;7#Gi;MR5i;_d6ir.m;jSe0cin2`'a2Z'9_nrp_VPBcTSXYt2Q&Uf`N4c]Y +Mi!=HLkgeBLAlr2L4t87LAlu]LO;[6I>^`n:k!tPNg-!);,:%d]SGnuYR[O/B +&!rTIQ'@MsP*1rhOH5H_NW+kAMi*CKM26tCrItB-KS98Urdt*"p43*mrdt*$s+CB+re>6ELkpnE +MMmFPNK0'\OHG]iPa.N#R$a;2S"-(ATV8*TUnsueWN*##Xfen4ZEppH[^`lZ]Y(tn^r!t,`Q#s> +aihlPcHjkbdaZdtf@S^0g>(N?hr*GOj5]4^k2tjkl0@U$m-X3.n*fc9rpg-^o^r.U!quB_rV6Eg +rqcQirVZWmo)=4?S,\!~> +JcC<$JcFg2o`"gfrqu]krqcZjrqQNf!;?Eb3:uh6o()>?n*f]3m-O'&l0.O8P+>Ont1>O8Y.COcYZeOnk+9Ont1,OoCLDPPUIBPPLCA +PQ$gmFhVuN^mWW/ms +WVrh4X/D_cSXGe.PECi]Jq/5qGBItHDf9IkC'foYB4tmgAnGUdrae`5ARo:]AS#IbAn>75='oZ- +7RgcqBPh^1GXk:q7nm]2CM[m*Df'E3EH?>KH$Xd`I=?a!JqJ]/f\+s3g=t?7g=k<:h;7#Gi8NYo +irA*0E:IrIEqaYSEr;4#Vp58?OoCOAOnt74Ont1>TDtM_SH,2ZRfStGrg44_QBd`"P`q8nOcYZc +O,f5!N!G8uMM[1GLkkq`!el;\r.G!#rIOZmrIOs"rIb-'!/:E,Ckmh&M2@+JN/WaVO,oBbP*;,q +Q'[l*R@B\9St;UKU8+N\Vl-MoX/rG+YctF>['mEQ\[oGd^;%J#_SjF5a2lBGbK\>Yd*^:keCN7' +g"P08h;-uHi8N_VjQ5OdkNV6rlg4!*mI'H3nF?MK!qZ'Vrq-?dp\4X]s7uZjr;6HjrVc +J,~> +JcC<$JcFg2o`"gfrqu]krqcZjrqQNf!;?Eb1\C;1o()>?n*f]3m-O'&l0.j;n:JOY\r_WPhr_Wfqc!Jlr_ieprD=Cq5Wh+j5!D4t6UXC58P)TL:/4S[:/+GXrD3Dfr_<8b +s%iPfr_NMi!)NJes%WDb!DQ>f:B4/[:&Ic^:B4/h:BF?g:]!lg:JO[_:]=)h:%V3];#X>_;#F,b +:]sQh:/=[\;#O2e;#O8e;#X;l;#=#i;,UjDf;>a5j;>sJf;>!i_;tj8j%=X@-K;c$4`9M.fD6U3h!4Zbbd3B/uT2)I-Z6SgPT1,:^D1GUaAr\GKN1c.!G1c7-F/M8h= +0JtRB2`Wua5XRCf3&Wqu4;C%C5s@P!6:4+.7n,m;7nQHI9MA/SrceBes*4usH$O^_I!pHmIt3(K +JcC>s4o@GB4nV#>55RS:5l=RYVuNmuXokl3Yd+25!OK34[f3`<\@T;ark8['mEQ\[oGd^;%J#_SjF5a2lBGbK\>Yd*^:keCN7'g"P08h;-uHi8N_V +jQ5OdkNV6rlg4!*mI'H3nF?MK!qZ'Vrq-?dp\4X]s7uZjr;6HjrVcJ,~> +JcC<$JcFg2o`"gfrVZTjs8)ckrV/DIp@e1Po^qbGo'u5h>Z73hr+1d"5r(nh>Z12gY1B\gAot,g%jA%fa$0]f%&:!daJ-B +o8NU,rl+ZBs,@&>NW+q\bs#@\[oA_p:C:7!4r*=s1/3BqRZ^=rOW!="M24W]Y+3Tq7?U:s186@s1&$rjqj9pq-U?rkABHpV?gFq7upErke]Qq8E9Om`,4Gs2b5^qTAi]rlk>c!6kDds3CMf +rQtSlrmLhq!7_#!rn%)#pt>Z#qqM/+s4mb5hr+Ijro!h8ro3k9-fjCNhpp/ta2Z'9`ko-^V5'ZS +SXYt1P`Uo`Mn6@'Ycb(+WJ?4aLAlrEKnP29Lkgb?L4tD:KnbA;L51M1tJ_>_7E^\keITqJ%W +SdV*ZS=?":R@0G0Q^7W9&*ALkpnEMMmFPNK0'\OHG]hPEhE!Q^F20S"-%@T:qsQUnjlcW2ZetXfek3Z*UdE[^WfX +]=bhl^VRe)`5Ta;aND]McHab`dF6Uqf%8R-g=tE=hV[8MioB([jlYail07L!m-O--rpKmWnc&([ +oCW%Ts7ZKerV6Egs8)Wirqu]moDX=@S,\!~> +JcC<$JcFg2o`"gfrVZTjs8)ckrV/>Gp@e1Po^qbGo'u5 +rK-]5!0I)=p5o<:qN1`Dte5NEVXSGEW1"R +F82"#QMm`-s88#VOoUX?P4Oh5O92,KTDkDiSXc4>S!ob5R$a5+rfn%ZPEM)kOcYWbNfB$WN/NRN +reU]4LPPk`s+UK+rIb'#r.4`qr.4j!r.G$&!/:E,BSVD"M2@+JN/WaVO,oBbP*2#oQ'Rc(R@9V8 +SXuIITq\?YVPgAlWiN8)YHY:b]t_=u_Sa=2`lQ6DbKS8WcdC.heCE.%f\,!5gtgiE +i8N\Uj5f=akNM0plKdg'mI'uB!V#XYncA@Srq6J,~> +JcC<$JcFg2o`"gfrVZTjs8)ckrV/>Gp@e1Po^qbGo'u5dr(uu^s%i\kqbI/TpHSL>r_E5f!^T(: +rBL'BoMtihr)_;#F,a;#X2i:\[cb:]!ue;>F&f;#jGj:BOEj +;H!BhrDNDfrD1c@-I2)[*ALkpnEMMmFPNK0'\OHG]hPEhE!Q^F20S"-%@T:qsQUnjlcW2ZetXfek3Z*UdE +[^WfX]=bhl^VRe)`5Ta;aND]McHab`dF6Uqf%8R-g=tE=hV[8MioB([jlYail07L!m-O--rpKmW +nc&([oCW%Ts7ZKerV6Egs8)Wirqu]moDX=@S,\!~> +JcC<$JcFg2oD\^erqu]krqcZjrqQNf!;?Eb!VH!_nh0J%n*f]3m-O$%l0. +\c027]D0#=^&GbF^]2+J^\ttJ_>1nE_>_=O_t_1M`W*pXa771Ka8X0[anj0ZbQ#fbbm)D:c-4GW +cMPrcciDJmdf7breG[tufDX@rg&B_%gBQHhh;7#Gi;VX4huMa8iqqa=g!nHj`r3e-^TOQ4U7e-I +R$X)#O,]'U]!J]FY,nY%IsSZ>[(rVpKnbD=L5(A7L5(D9KSG3[L*VJ.LP:G:L4tA9KnbA@M2S6k +NffKgQ'n25SXuFHUo:;rY-"nis8%rUPk:78Pl?sHQM/Aua90P]Vl.oAr4r0Fq830Js1nBDqn<0+ +TV.qVScPCPrgNqWRJrQWQ^3o%P`u*0$^$O3O,f6[N/W[QMZ/G6LkgcbLAuu-K`$K%K(=KlK)C9$ +KE-`*LB!$KLl$tGMMmFPNK0'\OHPcjPa.Q$R$a>3S"6.BTV8*TUnsueWN*##Xfen4ZEppH[^`lZ +]=bkm^qmn*`Pom=aihlPcHaeadaQ^rf@S[/g=tH>hV[8MioB+]k2tjjl07L!m-O--n*fc9nac8B +oCW%Ts7ZKerqQKgs8)Wirqu`no)=4?SH"*~> +JcC<$JcFg2oD\^erqu]krqcZjrqQNf!;?Eb!VH!_nh9P&n*f]3m-O$%l0.qRn=TcRq4@PUq4@VWrgX"YRf8]TR/Lq!D>J)JC]0RkO7@,] +NVe\7M]Rb4M26qBL4t84Dfg>9@qTLmDfTlAH@:9qL5LqLNW"n:O8k:AO8b7;O7n\3OoLOAO8Y15 +NrY:>O7eV7Ont1>O8Y1?OTLW,Onk+7Oo1=.OoCLHPEM)mPPpXEPPLC@PQ-mR.fV#[CfVZ<[mWW&hOUnOEKR$ +D/O61E,p)FG^4U^H[^EpJqAW.f%/I)f_X8)g=tE=hVS7is5=(>j5]4uDtn;NEVaYHEW1"WF7YY! +QDURXd/O*/rK6Z6o9&p3"/2B\TDkD_SXf\K!LfGUQj&hBQ'IStrfRYOOH5H_NfB!VMi3JlM#rKg +L]3&.L&Zi(KDpJnJc:9!KE$T)L&Qi,LN/-,M2I1KN/WaVO,oBcP*;,qQC!u+R[]e;St;UKU8+N\ +Vl-MoX/rG+YctF>['mEQ\[oDc^;%J"_Sa@3a2lBGbK\>Xd*^:jeCE1&f\5'6h;-rFi8N\UjQ5Od +kNM0plKdg'mI'H3nF?&>o(2JFrq6 +JcC<$JcFg2oD\^erqu]krqcZjrqQNf!;?Eb!VH!_ngs>#n*f]3m-O$%l0.h:B+,h;"@Ha:f%$bq*+[?s$6TKr]pEWoMb9F +p/V#ir_rbnr)"2*4$Q(q4[)"o5i;>sJk +;>a>f;>j>j;>sJh;>!i];tj8kpY-5(6 +Z*CU@Za@*I[C3NQ\@K2_]=beir4W?L^q[\#_>V4R_o9U8a8O*WkuQ^F//S"#t?StMdOUSO`aVl?\sXKAY0Yd1UB[^N]V]">Vh^VI\&_o9U8 +aN;WKc-FV]dF-Lne^rF*g=k<;h;7&IiSrnYjlY^gkiq?slg4!*mdKW6naZ2@oCMVRp&Facp\sse +q>^~> +JcC<$JcFd1o`"gfrVZTjs8)ckrV/SNp@e1Po^qbGo'u5:rid +qmlmA]"5HL\cBA?\cTFR])K8?])K>>])B8?])K5C]"G_h]_oD7])T;D\@K2]\bs&3\bNc1]D0#> +]tXEZs1nTJrP8EKq7usFrke]Qpr*3O!li:$n](ULrlG)\qTAf\rlkDerlbPjbfn>WcMPrdd/VMm +dK7nIec+/"fDX@qg&Ke&g]-(/h#uTli8_FmTpKhaO,$q@Knb;8LAZc'L)5PuLP:J:L4tA9Ln^T?ViHb!P*2,uS=KSM +#,.llWiiM,jT"q;r06o?op#H@n]1[Nrhe*Cr4r-EqSN6Js1nBDr4W?/TqS-PTDkDqSXc1=R[TY3 +R$X,(Q'@MsP*1rhrf7)?NW+k;Mi.Lj!f2VereCH,s+L<&rIX]nrIXs"s+LE+re:H/M#N6EMMmFP +NK0'\OHG]hPEhE!Q^F20S"-%@T:hmPUnjlcW2ZetXf\e2Z*L^C[^WcW]"G\i^VI_'`5Ta:aN;WK +c-FY^dF-Ooe^rF+g=k?U6g +qu-HkrUTr=s.01?~> +JcC<$JcFd1o`"gfrVZTjs8)ckrV/MLp@e1Po^qbGo'u5q2kE7r/g9-r0%)DrK7/Eq3(`@s-3)>op5QCrgDJX$"Bo@h&K7\Z&HY6lHO,/I6EF*NsA4/aoA7]@cB4baeAS,NPAe/HcAnP^hB4u$p +I!g?kDJfAk&or)=G^4U]H[^HqJqAX)eCE+#rn%&##hn%gh;-rFi8FUns5O+?pi$%Kqf2OQoPskN +s-E2?rhe*Cm?7%&r/_)VTqS-PTDkDqSXc1=R[TY3R$X,(Q'@MsP*1rhrf7)?NW+k;Mi.Lj!f2Ve +reCH,s+L<&rIX]nrIXs"s+LE+re:H/M#N6EMMmFPNK0'\OHG]hPEhE!Q^F20S"-%@T:hmPUnjlc +W2ZetXf\e2Z*L^C[^WcW]"G\i^VI_'`5Ta:aN;WKc-FY^dF-Ooe^rF+g=k?U6gqu-HkrUTr=s.01?~> +JcC<$JcFd1o`"gfrVZTjs8)ckrV/;Fp@e1Po^qbGo'u5C\rD!>eqbI/erD*5c!)WVir(d5c +s%NGe!)EMhs%`Jds%N5_qbH`YrD!Di:/:U\rD)u\!)WYlnkf-Xs%rYir_tp<;T\naihlPcHjkbdaZdsf@S^0g>(N?hr*GOioB+]k2tjjl07O"m-O--n*fc9rpg-^o^r.U +s7QHerV6EgrqcQirVZWmo)=4?Sc=3~> +JcC<$JcFd1oD\^erqu]ks8)ckrV-Hgp@eLY!VH!_nh9P&n*f]3m-Es$l0.9ljl>C\i8EJJgtLK7 +f@JI#da?Cdbfe/Ma2Q!6_:mZ!h;8.g!9!P/"Q81oh;&"arn@D,!nu>\rRqY4g=k65f\"g+eC2k> +NW4t;NVJJ2`W!mF\GhNdO84e9O86-jZa$dAYct:4XfAG$rhgNiQC2oAI=m92MMmO\R\-:QY-Y[M +]".gO!4i'>s1/$]D]>=]DfD@\HKLV]tM)V]D9#<]DfD?\c95@\bs&3 +\bNc1]D0#>]tXEZs1nTJrP8EKpqZjEs2+fRpr*3O!li:$nAbLK!6G/]q9&][rlkDeqof,dcHc=5 +r6PGkrmCkseCFQLrn%/%p=]H!qV)81h;-rFhr*Dii;_d9iaUs+e^;RZ`5BO3_R?D@US4' +OcYQ\N4Q%HqA:)Lk\Z"NIZ\>KnY89Knb7W:JOkg>G@gfVN-Xu +P*2#sR[p"ASt;aTW3!/)XlKHUP5pdEPQ$g@Q1pOCQ0lWiVUGM?_#;+F_Z.IO_"b\A^&Xo,Ta%0^ +T:VXFSGnukR[KP1Q^3r&Q'@JqP*(ifO,o<\repl9MZ/J4L]E5/L&cr,K`$K#K(soqK)C9$K`?c* +L'EEhLl$tGMuJZBNK0'\OcklkPa.N#R$a>3S"6.BTV8'SUnsrdW2cl!Xfek3Z*UgF[^WfX]=bhl +^VRe)`5Ta;aND]Mc-FY_dF6Uqf%8R-g=tE=hV[8LioB([jlYail07L!m-O--rpKmWnc&(\oCV\S +o`Fj]p\jmeq>U6gqu-HkrUTr=s.97@~> +JcC<$JcFd1oD\^erqu]ks8)ckrV-Hgp@eLY!VH!_nhK\(n*f]3m-Es$l0.9ljl>C\i8EJJgtLK7 +f@JI#da?Cdbfe/Ma2Q!6_47'eSt;RHqOmk^q4I_[pn%JUrLO:cSt;LDS=H(mO8b4@O8Y1>Nrb?' +rf@,BqN1Q9rfI,?qiLN4!0I,>ooT39qiLfq2kE7r/g9-r0%)DrK7/Eq3(`@s-3)>op5QC +rgUeB4aV' +7SHKPI!gBlDJjB3E,g#DGBs16s*auuJc:9%e,Ii*e^i='f@\a/g">!3g]$%/hu;O:iSrnXjSEcq +E,YPk!c`7$r,M[Spi6=SqNgc=r2.pBm?7('qiCfPrh0OhT:_^HSXf\K':P>VR$X,)Q'IStP*1rh +OH5H_NW+k;Mi.Ljs+gZ1rIt<+re13%r.=]prIXs"s+LE+re:W4LkpnEMMqIm?]C),O-,TgPE_>t +Q^F//S"#t?StMdNUSO``Vl6VqXKAY/Yd(OA[C3QT\\#Mf^V@V%_o0O6aN2NIbg"GZdF$Fme^i@) +g"P39h;7&Ii8WeWjQ5Oekiq?slg4!*mf)YUnF?MK!qZ'Vrq-?dp\4X]s7uZjr;6HjrVcA +J,~> +JcC<$JcFd1oD\^erqu]ks8)ckrV-Hgp@eLY!VH!_nga2!n*f]3m-Es$l0.9ljl>C\i8EJJgtLK7 +f@JI#da?Cdbfe/Ma2Q!6_>I12;>X5k;>a5k:Jh$fs%i\kr([5fr)!)as%r\joKE+9q`k*Vr(cc] +r_ik`5eqbI/erD*&^ +r(d8dr_3>d!)EMh!)EDcs%N5_r(cfYrD*Ag!)E;br_E)]!)WYlnkf-Xs%rYir_3S"6.BTV8'SUnsrdW2cl!Xfek3 +Z*UgF[^WfX]=bhl^VRe)`5Ta;aND]Mc-FY_dF6Uqf%8R-g=tE=hV[8LioB([jlYail07L!m-O-- +rpKmWnc&(\oCV\So`Fj]p\jmeq>U6gqu-HkrUTr=s.97@~> +JcC<$JcFa0o`"gfrquZjs8)ckrqQNf!;?Eb2>$M3o()>?n*f]3m-O''l0.Nr"h8Zm;raZ*1@6YH=q,XK/A"W2GTAF*;hXK85;BN0'])B8?\cTLV]`,PB])T;D]=bhj]_oD;])TDB])B28](NW/](`i3 +]E,^[r4i9IrP/&Za2d\h!QW:[ana*XbQ#fcc2>fcblH&dchu,i +dJhPqe'uqIf)F;#f_4"tgA9S(g]cNjhr!ALr8@S5"5MARb5T@V`5]^%W2?;]TUM:9Q&q)iMiEY* +Yd(:1Wi;b@SZ]K>XdOHjSni:AAoC1RFG,TE:47P@L5qC`R\$(:;,9qd<)]NbUSarJNKK?dPF7i0 +Sc52bTqeNcY-+kas7hfWP5CICPkgU>PQ8eka8Vq6VUYY@_#;+F_>qFO_"YVA^Ajr.UAgheTV)4T +"eD0QS!ocEQk#IKQ'IStP*1rhOH5H_NW+k;Mi.Ljs+gZ1rJ(?+s+L<&qh"`sqh"`us+LE+reCH. +!/UW2DMj@2N/`jYO-#KeP*D5sQC!u,R[]hAJ,~> +JcC<$JcFa0o`"gfrquZjs8)ckrqQNf!;?Eb2tZ_5o()>?n*f]3m-O''l0./ZSGo#XD>eAKD>nAGD>BLtNpr,. +NrEqrD>eALD#nNmrJ_5ENJi[OM2I+FL51M#nB5;@&EH?8JI"6d$Ll7=Tq2bZ=OH9=$ +s,m2?qN:c=rf?o;pQ,?9rK$W5!0R,>rf@#>r/pf:q2tT:m#h4/s-*DEs-*;Brfd>Go9K!7rKmMN +rKmMNopP`HrgWhUrgiVOrh'1_r1X+arM0Cer1j4ds/#XhrM9Lkq5=7k6`HrVT:2+3PE:odLOai# +HZs[TEH#c2CM.?mMhd"=J:MukB6o2cMg]_WC3*HV4AJj<;-@CB5t,9k@qKOpEHHGLF8eZ/9E7`b +Hkq3\DJa<1E,p&CGC"O\H@('hJV&H)df._qe,n1Of)F;$fFHTef\5*8h;-rFhr*GOir7s@jDSsU +DtS&ODfB]9rGqjVs)@gS!13GGp6GWRrMJ*Em#pt&r/grR!2BId!MH(aSct[TS"#k7rg41^QBd`" +PEM)kOH>NaNfF$s!K2j7M>rA3L])u-L&Zi(KDU8uJbt&sKE$W)L&Qi,LB*/0M/J3/N/WaVO,oBb +P*2&pQ'Rc(R@9V8SXuIHTq\?YVPg>kWiN5'Y->1:Za@0L\@K2`]Y;.r_8=+/`Q-'Ab0/#ScHste +e'uq!f@\d1gYCWAhr*JQj5]7`k3(sml0@U$m-X60n*oi:o()DDo`"O`pAamcq#C0iqYU0hr;?Nb +rdk*@s*t~> +JcC<$JcFa0o`"gfrquZjs8)ckrqQNf!;?Eb0D+l-o()>?n*f]3m-O''l0.jAm;>F&f;#sKhqb@8i:esnap/1fc!BiR=4oRSB4oISE5Q4IV +:B+;cjDf;#jGl;$'Wm;>sJk;=d][;u9Mog5X%4f2`3BE-Q4E`.4Qu.3A<ss#pTN5!D1p +55d\G<:Nob<;r`mVZ3k2Z*L[AZa@-K[^`iX\[oDcrOW'Br4NEN^V@S#_8=(,`;[aU`rF*Q +JcC<$JcFa0oD\^erqu]ks8)ckrV-Hgp@eLY2"^D1o'u5])B8?\cTLV]`,PB\d#^V]=bhj]_oD;])TD@])T>? +\cBA?](W]0](`i3]E,^[r4i9IrP/f$Vjd`5]^4`5SsYV4sQQR@0D, +NKB*XNJP*NYHP"-Whk/hXi%lSS9]pWD/rHCE(4SdKo8MsN.6J=O-?!"T:&GM:K1:lU7nE\Vi?[t +OckooR@Tq=T:VXLV5L>sY,nb_s7_]ZP*;)mqih&Eqj%,E!1!PJrQ+EIr2'@hec5E[r5&9Is2"`N +p:pR?s.gg5U8"?TTV%jJSt2C@S!ob5R$a5+Q'IStP*1riOH5H_NW+k;Mi.Ljs+gZ1rJ(?+s+L9% +nq-aks+CB+rIt?.M#N6LMMmFPNK0'\OHG]hPE_>uQ^F//S"#q>StMdNUSO``Vl6VqXKAY/Yd(O@ +[C3QS\[oGe^;%J#_SjF5a2lBGbK\>Yd*^:keCE1&g"P08h;-rGi8N\UjQ5OdkNM0plKdg'mI'H3 +nF?&>o(2JFrq6 +JcC<$JcFa0oD\^erqu]ks8)ckrV-Hgp@eLY2Y?V3o'u5LAli>K5u3E@qB7eD/O?6G'SLcJV8c8q2bT;rf@2D +OHBI(rK-u?s-!ADrfI,?qiLN4s,d2?pQ,H=OHKC$rf@#>r/pf:q2tQ9m?.=0s-*DEs-*;Brfd>G +o9K!7rKmMNrKmMNo9oTHrgWeTs.0%Y!2'%Xrh'4`qk=%as.][lUS=L\U]%"gV>I(fV#[CgVa[PX +St2=9Q'@AmNJ;t4H[0dXF)c)7CMRQrB8VM!K7SJuH=pc>Nei.-A8,p`%=N\SDJa90E,ouAG^+H3H3/MEIf=m$JqMP#df.\reCFQLs4@;'rn.h9gYCWA +hV[5Ki8N\Tj5]4uDtJ#KDZOfsqf;LPrKm5Dq3ClSrMJ-Fs,m#3S"-(ATV8'SUnsrdW2cl!Xfek3Z*UdE[^WcW]"G_j^VI_' +`5Ta:aN;WKc-FY^dF-Ooe^rF+g=k?^s.B=A~> +JcC<$JcFa0oD\^erqu]ks8)ckrV-Hgp@eLY0(ec+o'u5B[!)sJk;>a>b;$'Wm;>sJk +;=d][;uBVoPd]Xteg]`#PD^AkqN^qmn)_u7LV`Q#prA3L])u-L&Zi'KCXWkKE$T)L&H`,LPYqd +Di0I3N/`jYO-#KeP*;,qQC!u+R[]e:St;UKTqeE[VPgAmWiW>*YHY: +JcC<$JcF^/o`"gfrquZjs8)ckrqQNf!;?Eb!VH!_nhBV'n*f]3m-O$%l0.\rS%5'!SH!%N;nn;Mu\k: +N:r8.N;pip`VdaK\+@-.\bqHdNW>.9O9VqoZ*(41X8](7W2?GgOI^H:H@:?uMN!OXPa@u7Vld25 +pppO=]"7mQrjr-A!4r-@!kQ"Urjr-?rjr!=s1/3Brk/3Arji*Ark/:qK^VIYa_>_=O_th7N`W*pZa2ls6_8O!eV50iVSXGn4Q&UlbNJrb* +ZELF5X/i7NH_S-M\YGI4Q&gPu?tF^XEdWd::/64gLl@LdR\-!D:JOke +T:VXJUSb&nY-+n0h>d24s-!/@s-3GHr06utn]1X)rMBIif)PQ]pqcsHs2"`N!5JKHqnN*DrhKRi +UAghiTV%gISXf\K&t55UR$X,(Q'@JqP*(lgO,o<\repl9MZ/J4L]E5/LAuu-K_pDnK):3#K`?c* +LB!$GLl$tGMMmFPNK0'\OHG]hPEhE!Q^F20S"-%@T:hmPUSO`aVl?\rXKAY0Yd1UB[C3QT\\#Mf +^V@V%_o0O6aN2NIbg"GZdF$FmeCN7'g"P39h;-uHi8N_VjQ5OdkNV6rlg4!*mdBQ4nF?MK!qZ'V +rq-?dp\4X]s7uZjr;6HjrVc +JcC<$JcF^/o`"gfrquZjs8)ckrqQNf!;?Eb!VH!_ngO%tn*f]3m-O$%l0.r/pf:q2tK7mudO2rfd>Es-*8As-*GHo9K!7rKmMNr0RGNopGiJ +RJrZSS,8]USa`6MTDtS]U&Uk\U]%"fV>R.fV#[CjVcT[eSXYt4PEV,iMM-J,H[0gXEcGu3CMIKp +ArDFuKS"`(Htm8AMg^>*EaNa!?pI7V>X2=sB0\pT?t*ecE-$,GF@Sbh9hS3.I!pH\D/O92EccGK +G^'.5"ab]IJUrFPKDspQ>HN!McCgT`q*]St;LCrgOOhR@'A.QBd`"PEM)kOcYWbNfF$s +!K2j7M>rA3L])u-L&Zi'KCa]lKE$W)L&Qi,LM_j(M2I1KN/WaVO,oBbP*2#oQ'Rc(R@9V8SXuIH +Tq\.9Za@-K\%0&]]Y2(p_8=+.`Q$!?b0/#RcHjnce'umuf@S^0gYCW@hr*GO +j5]4^k2tjkl0@U$m-X6/n*fc9rpg-^o^r.U!quB_rV6EgrqcQirVZWmo)=4?T`9N~> +JcC<$JcF^/o`"gfrquZjs8)ckrqQNf!;?Eb!VH!_nga2!n*f]3m-O$%l0.a>i;?'Mo;>F&f;#sKhr([;h:f.-e!)WMhs%rSVn3-Y2rD38bj&Q"@ +!'g0Br`&nrr_i_mr_O1j69ICq5!;+r5X@_*7nH3B9DM?]:]F2^:]*rh9h\7[:&Ica:&[i_:&%K_ +:B45e:]4&L:[_-U:]=/j:]*rf:\R]b:[V'Y;#jGk:BXKk;,UjDh;#jMm;>sGn;>sJl;=[WZ +;uBVono +5s7=j2E!EH/K>r]0J+k33%m*F1H.?V4[;5"76*=e4?Yc!9M7r@5X.G!6pX1.6q'X98Ou?D9M8#Q +9hTPKqfDj]FT-F_G5c^bGlN'rH[L6iIXZcrJ:IQKj#mK.5<_:+<:Wrf<;r]lV>[7pZ*L^C['fnB +!4`$>rk&3A"hVFZ]Y2#X^AkqL^r!te_uI[T`<+'"a7*./=8u>#*YctF>['d?O\[f>b]t_=u_Sa=2`lQ6D +bKS5VcdC.heC<($f@em4gtgfDi8ESSj5f=ak3)!nlKdg'mI'E2n*olHncJFTo`"Lbp@n=[q#C0h +qY^6hr;HTbrdk*Bs*t~> +JcC<$JcF^/oD\^erqu]ks8)ckrV/GJp@e1Po^qbGo'u5Z1-g&Tn(gAT\*Mi@Rnrf$f8!06Z1s,?rq +rl+cSn[J"t!4i&f"ceY(NfT8"OT1C@XrOODWiE"pVkp;RRr`atI"I-0NK96fQ_'hHX0K/5\cBAA +])TAB])K>@])TAB])'&<])T>?])0)@]">TR]_oAC]">WS]`>_C]D9&:]DK2<]DT8<\c98@\bNc1 +]D0#>]tXEZrkSNJrP8EKqS3*GrkSQMrkeZPq8<l*GLl?:o:e,IuCjUqo:/6h#KT;+\R\-*H:/Fkgd=lVqD%E_">JC_#M1H^AbnG^Ak&0U`cG,U7n9RT:VXF +S=H(Vg^VI\&_o9U8 +aN;TJbg+M\dF$Fme^i@)g"P39h;7&IiSrnXjQ5Oekiq?slg4!*mf)YUnF?MK!V>s_p&Facp\jme +q>^s.KCB~> +JcC<$JcF^/oD\^erqu]ks8)ckrV/5Dp@e1Po^qbGo'u5Es-*8As-*GHns/m6rKmMN +rKmMNp6buLR@4&Cs-rnUs./YNrgs1`qOmn`pS7Y^rh]LfrhW2`Vl-DbSXc(5P`q2iNei79H[C!\ +F)c)7C2%BoAS-dQKS"c)Isc!DA;6+uI\%M;7VlLDC2S'5G]u\K7fH-^I/eX% +D/O60EcQ;EH$K=7$[dAPJ:W<(K7ei1dJ_Mke,Rttf)F;$f`0Y)gAp%.h>c@:i8NYSioB(nDt.fD +EqG^lQN!0IV#@.hV?!OHs7qfTP4k%6OSY+>V>m>6US=KVTqJ$LSt2CAS"#k7R$a5+Q'IStP*1ri +OH5H_NW+k;Mi.Ljs+gZ1rJ(?+s+L9%oRcsms+LE+reCH.!/UW2AVuD)N/`gWO-#KeP*;,qQ'[l* +R@B\9St;RJTq\?YVPgAlWiN5'Y->1:Za@0L\@K2_]Y2(q_8=+/`Q-'Ab0/#ScHstde'uq!f@\d1 +gYCWAhr*JQj5]4^k3(sml0@U$m-X6?mfDqJrpg*]o`"O`pAamcq#C0iqYU0hr;?Nbrdk*Bs*t~> +JcC<$JcF^/oD\^erqu]ks8)ckrV/5Dp@e1Po^qbGo'u5EBO54^r;4T/(P:&n)Mbk4[21s5se"18OQ-C:/Lpbr(m>fo2#<[!_l?^r_<>dqb@&` +qG$c\oM>E\jA55@q+pudqb@,epJCfamnj!\!)WYjs%r_m!)iVir_iSi!)ibmqGR8hnP]0]qc*Pp +s&Aqsq,[Mq!*&epr_sk;;c-@d:/+DQ84,d25sIIp4?GS`2`*BK1bpdPr]re45!1kl5X.S$4ZYJ[ +2)?m6)^d-g.kih@2)RWT2)m]`5XIjs3B9/a4\JIA8O#L*5"%b)6UXC77S--A8kVcKrCd5dErL.W +F9?Z-F`m\,rceBes*>*#I!g?kIXcirIt*!!k<8i/rB9dPo2GR_rMBLj"fJZ4['mFB[fEu<\cBA@ +])K;C]Y2#X^&l'b_>V7N_uI[T`W*sCm>6US=KVTqJ$LSt2CAS"#k7R$a5+Q'ISt +P*1riOH5H_NW+k;Mi.Ljs+gZ1rJ(?+s+L9%oRcsms+LE+reCH.!/UW2AVuD)N/`gWO-#KeP*;,q +Q'[l*R@B\9St;RJTq\?YVPgAlWiN5'Y->1:Za@0L\@K2_]Y2(q_8=+/`Q-'Ab0/#ScHstde'uq! +f@\d1gYCWAhr*JQj5]4^k3(sml0@U$m-X6?mfDqJrpg*]o`"O`pAamcq#C0iqYU0hr;?Nbrdk*B +s*t~> +JcC<$JcF[.o`"gfrquZjs8)ckrqQNf!;?Eb!VH!_nh0J%n*f]3m-Es$l0.9ljl>C[i8s,[/@rf82&Wi;qpWhu_mOd^?7H$t7!Ll@FYQ'\)9V5pi.]">Pb +q7H[:qI^])%K_>_=N_th4O`Q%hro#:aOaN=;$s2k;`rQG5brltAb!6tMgqp58g +rmC_n!n>cNr7Cu$o[s5uptH&/h;7#@da#u6`!O;o`PS[RVPKoWrg=%VOc>?XMi3J!riJ,\WN;nF +H)%RJ]r[fjFH_Q6NaNfF$s!K2j7M>rA3L])u-L&Zi&KD'ooKDpQ(L&QgLLPUbCM2I1KN/WaV +O,oBbP*2#oQ'Rc(R@9V7SXuFGTq\aihlP +cHjkbdaQ^rf@S[/g=tH>hVd>NioB+]k2tjjl07L!m-O--n*fc9nac8BoCW%Ts7QHerV6Bfs8)Wi +rqu`no)=4?U&TW~> +JcC<$JcF[.o`"gfrquZjs8)ckrqQNf!;?Eb!VH!_nh0J%n*f]3m-Es$l0.9ljl>C[i8OD#J5HD#%rIDZ4MF +Q2m$=O7\J+NW!\oDZ"AODZ+MRLAuoHK8"o1K62BH@:WtbCMn*4Fa8@aJV/]6NKB9aOSP"=OSb.? +P5^UBOT1C=OS4b5O8t@>O9Lc.OHGZerfR#d=lVqD%COT:R?OoCFBOnOn8OTD>UrhK^mU7n9R +TDkDtSXc1=R[KP1Q^3o%P`q8nOcYZcO,f5!Mueiore^Z2!/LN-s+UK+qLeKnqh+m$s+UH,Fbbd/ +M2@+IMi^ +JcC<$JcF[.o`"gfrquZjs8)ckrqQNf!;?Eb!VH!_ngEtsn*f]3m-Es$l0.9ljl>C[i8hs%i\krD!Di:f.-e!)WSjr]]s;rBBm;qG7)cr_EMo +pf-]^pJh/Ws#pEIq*=pD$rg/';Gg=h:f'>A4$d>$VmEb< +[^NZT\@K2^\[hXL$bO'a]tM.p^VIY$_>_:O_u@US`NaNfF$s!K2j7M>rA3L])u-L&Zi&KD'ooKDpQ(L&QgLLPUbC +M2I1KN/WaVO,oBbP*2#oQ'Rc(R@9V7SXuFGTq\aihlPcHjkbdaQ^rf@S[/g=tH>hVd>NioB+]k2tjjl07L!m-O--n*fc9nac8BoCW%Ts7QHe +rV6Bfs8)Wirqu`no)=4?U&TW~> +JcC<$JcF[.o`"gfrVZTjs8)ckrqQNf!;?Eb1\C;1o()>?n*f]3m-O'&l0.Q72i:c+7i8rn@D,r7_2(pl#94N/[Xn!0$f7qi:Z8 +rP\]Sq8WHDn@%hqr4)`d!0@&_A]DoJB])]G=]D]><]DK2>\bE]-]D0#>]tXEZrkSKIrP8HL +r4iBM^q]las2"]OrknTNs2G#XrQ"iU!6=lS!lrC(qTAi[s2t>arlkAdrQP;ds3CJerm:YlrmLhr +!7gtu!8-qss4[5%A(/ZEaMc$7^r4*tVkp2_T:D=9Q'@;hO,JmP[BHd:XK&D%J:)U@_m-G=Q$J%D +K8s&77X.RCI#!JQ:6'pWNK0BoT:SkS:fLCoO/&SLN/ip\PF7i/S"H:EUSXlhY-+n0Y5YWXs8S>W +PQ-g;PO-Bca8_q3V#I4iVZ3RJs8Kk/_"khH_#D+@^&k40V>d84US=HUTV.pKSt2C@S!ob4R$X,( +Q'@JqP*(ifO,o<\repl9MZ/G6LkgcbLAlo,K_g>qK)1-"K`?c*LB!#/M#N53MMqImAW;_2O-#Nf +PE_>tQC+&-R[]h['d?O\[f>b]tV7s_Sa=2`lQ6DbKS5Vcd:(f +eC<($f@em3gtgfDi8ESSj5f=ak3(smlKdg'mHs?1n*olHncJFTo`"Lbp@n=[q#C0hqY^6hr;HTb +rdk*Ds*t~> +JcC<$JcF[.o`"gfrVZTjs8)ckrqQNf!;?Eb2"^D2o()>?n*f]3m-O'&l0.tErbh\"p6PH6 +ooAI"rb_UOs(qaRqemF+KS+o.6?7?r@U`k^C2Im2Fa/7^J:iQ2MNOn=b5On=b7OnOn-Oo1CAPPpXEPPLCAPP^U;Q1^IAQi2\UA1M\V#I4eUgTgbSNaNfF$s!K2j7M#rKgL]3&- +L&Zi&KD0uoKE$W)L&Qi,LB*/0M#iKlretEJNfT6_P*2#nQ'IZ&R$jD4S=Q7DTV8*TUnsueWN*## +Xfen4ZEppG[^WfX]=bhk^VI_(`5Ta;aND]Mc-FY^dF-Oof%8O,g=k?U6gqu-HkrUTr=s.]OD~> +JcC<$JcF[.o`"gfrVZTjs8)ckrqQNf!;?Eb/+iH)o()>?n*f]3m-O'&l0.3!)NShr_EMhqbI8i +i\2)I0K1,D6_ +6:!du4?,Sk5!M:q4?5;Z1bp[:*??LZ/LrM53]8i\2)[HX5X7Y'2E08kD955=%\)6UX=5 +7nH6A8P2QJ9M>=Ys)J!Xs)\0]s)eBbF`mV*rce?es*FrtI=6QnIt%BH!e]\[o?N\dZ3`]Y2%n^V@S"_84"e_u7LR`V`d6j +<d84US=HUTV.pKSt2C@S!ob4R$X,(Q'@JqP*(ifO,o<\repl9MZ/G6LkgcbLAlo,K_g>q +K)1-"K`?c*LB!#/M#N53MMqImAW;_2O-#NfPE_>tQC+&-R[]h +['d?O\[f>b]tV7s_Sa=2`lQ6DbKS5Vcd:(feC<($f@em3gtgfDi8ESSj5f=ak3(smlKdg'mHs?1 +n*olHncJFTo`"Lbp@n=[q#C0hqY^6hr;HTbrdk*Ds*t~> +JcC<$JcFX-o`"gfrqu]ks8)ckrV-Hgp@eLY1\C;0o'u5VlR,3]=Y`S])]G<]DoPD]DK2>])]M@ +]D9,=]*,d[]tD#S]DoJ9]DfD;]CEK)]DfJA^&P_G]tXEZrkSKIrP8HLs1nTL!PlJL_#D1L_Z.ON +`;[aU`rF'[aN*nls2P/]ans6ZaoBK`bP]Tac2Prdc2Z)cci)2jdJhSodfS%Mf)4/"f_!hsgA9Q7 +eBZ7X`PKI/^;IadW268aT9tq2Q'72cNf&XIZELC4X/E"pIsIj'W4f*rHZ5^9EaVd9DL"ioI#!SO +:JZIkMN3piSXrSP:/=hf;PBq`VMpRrOd2E+SXc:CTqnNaY-4q/Y5YWVs8A2HPN^*b`rMk5U\gke +V>d@kVq_7L_>:tC_>_7M^[o/^Vl$;eUnjc[TqS-PT:VXFS=?":R@'A.QBd`"PEM)kOT(:FNfB!V +Mi3JlM#rKgL]3&.L&Qc%KD:&pKE$W)L&HaALPUbCM2I1KN/WaVO,oBbP*2#nQ'Rc(R$sM6S=Z=E +TqS3VUo(&gWN*##Xfen4ZEppH[^`lZ]=bhl^VRe)`5Ta;aND]Mc-FY_dF6Uqf%8R-g=tE=hV[8L +ioB([jlYail07L!m-O--rpKmWnc&(\oCV\So`Fj]p\jmeq>^ +JcC<$JcFX-o`"gfrqu]ks8)ckrV-Hgp@eLY0D+l,o'u58]Sb$[pD>A#ED#fh"Q2d-MQ2$[@ +O7nUsNVRJfD]46p6?7?r@:<\\C2Is3Fa&1\J:`H0MN*a\P4t(=P5^U:OT1@DNfT6]qiCH4p6#!/ +rfQ<(qN:c?r/po?rfd;D!0d8B!0d5Cop,39rKmMNrKmPOpR1uIs-`nUrgWeTs./_Prh'4`q4Re_ +rhBIhrM04brMBLhA>,Q`R$X##OH5E[K7JDuH['XQDf9H,B52*lAVl+nJU`)rH"^`;N.$M/F(AO! +Am._h4]5KL.9Za@0L\@K2_]Y2(p_8=+.`Q$!?b0/#RcHjnce'uq!f@\d1gYCWAhr*GPj5]4^k3(sm +l0@U$m-X6?mfDqJrpg-^o^r.U!quB_rV6Egs8)WirVZWmo)=4?U]5i~> +JcC<$JcFX-o`"gfrqu]ks8)ckrV-Hgp@eLY/+iH(o'u5i#2?#QF3^#Gq9M%c?5X.V'6pa<@7gMXW8kVcM9he=\:&f23 +EW1"XF8g:]FoQUbFoHR_GQ)meHiAHlIfFltJGh\,4oIS<4mZ/B;ZNQkU\gkeV>d@kVZ=.([fO"L +r4)d;rji0C]Y4_:W_ns=._o'F2`V`d0rK)1-"K`?c)L22R#Ll$tGMMmFP +NK0'\OHG]hPE_>uQ^F//S"#q>StD^MU84T^Vl6SpX/rG+YctF>['mEQ\[oDc]t_=u_Sa=2`lQ6D +bKS5VcdC.heCE.%f\,!5gtgiEi8EVTj5f=akNM0plKdg'mI'uB!V#XYncJFTo`"Lbp@n=[q#C0i +qYU0gr;HTbrdk*Es*t~> +JcC<$JcFX-o`"gfrquZjs8)ckrqQNf!;?Eb!VH!_nhBV'n*f]3m-Es$l0.9ljl>C[i87]`,VE]`#GC]Y"0SoXb+7pq-10!P>r8]DfJ>]`>eE^])%I^Au(C_#_?drkSNLrke]Q +r5AQQs2P)Z!Q`=\`W4'S`r=!ZaN=>%rQ5)^!6b;arltGd!mT$9ps8rd!7Ceos3h&!e^jZMs4Hts +s4[J,9%hS6a2Z$8_7de)Xf&%kTq7gAQ'RMmN/EUQLki:=XKAM'WgJ-WW5Q0HS!8#YQ[\\XY +E.!G!8l&90ItW]>Pae/69iFhar_sh7U8FiINfK3aR$sP7SXuIJV5LAtXf\e2Yck7]rrA5[PkgLC +P4b%#aSj0YUAgqcV#R:jVZ*LKs7jG/_"khF_#M1B^Ak,2V?E`kUna[`Td6;'St;LCS"#k7R$a5+ +Q'IStP*1rhO,o<\NJrgSMMd7ILkpibLAuu,K_g>sK)('!K`?c*LB!#/M#N53MMqImCQ4@8O-#Ke +P*D5sQC!u,R[]h +JcC<$JcFX-o`"gfrquZjs8)ckrqQNf!;?Eb!VH!_ng3hqn*f]3m-Es$l0.9ljl>C[i8&ZSY#dqn8/&?pMBkHs-3DGs-E\Mqj-c4if*qs +qelCO!cUFkrB_6>G^*V*AS5^oEH?5FH$XphK7nu;O8"b:P5^U:O9L]*NfT3\qN(B4rfI2DqN:?1 +!0R8B!0?B+qN:c?r/po?rfd;DplkNZ!7F:L-4c?"@Y87n-cn@qfe!F*2a,7i4]i9hn<.IXc0ODJsN:G'A1VH?ssfIY!(LKE$Z* +KE0^s.fUE~> +JcC<$JcFX-o`"gfrquZjs8)ckrqQNf!;?Eb!VH!_ngC[i8l;#=&f:]sQh9heC^:\dib:[V'Y;#jGl:\R`d;ZBSo;YsAk9)h?`6UX:-55mYW3]T5Y2`*?L1bg^P69mh!4#f8"59E6V3]K&V2DZj0)^6U^ +/hA\53&*6I1Gq'M4?Yqr6oY**+ZhhN4\JF<5X7V"6UX=06q9^;7n?3D8PDiP:/4MXDfB[oEW1"Y +F8g:\FoHObGBWt0s*4Qh!d]3?rd=frIK"ZsIt9`[557;;55[S/<;9DkUAgqcV#R:jVZ*Ip[^WaE +\Gs#>\@9!H\cTOX^&G_J^VI\%qSN9Ms2=h9rDi_ooi:cdr`/urs/#pqUnjc[rh1U1T:VXFS=?": +R@'A.QBd`"PEM)kOH5H_NK&mUMi*CKM26tCrJ(?+re1-#q1AEps+LE+reCH.!/UW2!K)g7N,+E5 +O,oBbP*2&pQ'Rc(R@9V8SXuFGTq\ +JcC<$JcFX-oD\^erqu]ks8)ckrV/JKp@e1Po^qbGo'u5" +_ScAkqSi7]`,SE]_oAB]Y"0Sl+?W"p:L@;s1A9CqRlmCr4i6HrP&?Jp;$jH^VIY`_>_=O_u.IO`W*sV +a8a0Za8![Q`rX9'r6"u[s2t5_rltJes3:Shps8rdrR1_p"4YlPf)4,"f_!ksg1oBjbK.]A_8="& +^pp>@UnXNRR['2%P)tW[N/E@DZ)t1/VlZhHHD7sL^8.'?LQI($='9!X95Jp/N(HfAH%:O*O-?!# +T:SeS:/Fni;c99bVN$UqNf]NoR[fkYd*^:keCE1&f\5'7 +h;-rGi8N\UjQ5OdkNM0plKdg'mI'H3nF?MK!qZ'Vrq6 +JcC<$JcFX-oD\^erqu]ks8)ckrV/8Ep@e1Po^qbGo'u5GBRA'@qTOnDK9f@G^=dgJqSr;N;8S9P5^U:O8t@>Nr"h2OT(@BP5:=/OT1C,OSY+=P5LI? +P5^[DP5(7:PkLC7Q33J@R$[c=rg*VPp6kiG!1EhTrgWeT!1itX!2'.[rLa+_pn7\^rhBIhrhK:b +9;S;OR[08'P)bT`MM$D-H?j^WFDl&6CM@BnBOtY,K7\T%I!TF:I>NB/H#dD/CLL%*6;(NJ<*WsJ +5t=CN@:X(gE,p&GGt(:n7fH+!8UGo8D/O3.E,p&DH$FU\H[U?mJ:W?*K`6Z*c2Q#fci2;kdJhSn +e,Iksec+/!fDjP(gCW/rh;7&Hi8ESQio9!9DJsImE;4ALE;jeQQhHa8QNEJHU&LedU\pqfV>d@j +VqqC5Oo(7>OoD6^VPU)aUS@a])5*UnSt2C@S!ob4R$X,(Q'@JqP*(ieO,f5!Mueiore^Z2!/LN- +s+UK+q1JNqq1J^#re:?+s+^T1reYBIMiYd*^:keCE1&f\5'7h;-rGi8N\UjQ5OdkNM0p +lKdg'mI'H3nF?MK!qZ'Vrq6 +JcC<$JcFX-oD\^erqu]ks8)ckrV/,Ap@e1Po^qbGo'u5h-4odkI6j?+P7nH?I9_qNb:Amuf:&n#f9`Iid:&n#d9EIp^9_hEX +:B+,h:B"#h:>AY9;#X>l;#=&f:]sQh9heC^:\dib:[V'Y;$0Wj:Jgd_r_i>b!)iboqGR8johtcf +r_s&$<)cjt84`_P##%`b +9hnH$rbqgUrc.pXrcA'\rcS6aqfi'bs*=`nI!km@rdG'$J:]mG4[&d.pc\F:k>_7Us.TFds.fLf +s/#^lrMTY(s0`*?[^NZT\c0/M]=bhj^:q@u^qmk(_8=%e_Z%INaihlPcHjkbdaZdsf@S[/g>(N?hVd>NioB+]k2tjjl07L!m-O--n*fc9rpg-^o^r.U +s7QHerV6EgrqcNhrqu]moDX=@V#Pr~> +JcC<$JcFU,o`"gfrquZjs8)ckrqQNf!;?Eb2>$M2o'u8>n*fZ1m-Es$ki_*jjQ#7Yi8MJOHGltT:r$WY-b_:])fRVrOi0BrOW$@ +rk/3Aot::;!5/9Brk/6Ake$Q"p:L16qRlmCr4i6HrP&?Jp;-^CrPAKMs24cQr5AZUrQ"rXrl=iS +rPnr[ao'<[aoBN\bl5lebQ?&7cM,ZaciDJmdf7bueCE.$r7Cu$p"=*/ccF/F_o'7&`58[RV5'`W +SX5V,OcYT]LP^nCYcb+/WMlbbI!2R+[&f^[F,uE3?WBU:7qm*tN(ZrBH%1I)Ng-!$T:JbR:/Fqi +;cA@DVPfE6NK0'bR[BS6SXuFIV5L>sY-"k0YcuOTrK?luQ^F//S"#q>StD^M +U84T^Vl6SpX/rG+YctF>['d?O\[f>b]t_=u_Sa=2`lQ6DbKS5VcdC.geC<($f@em4gtgfDi8ESS +j5f=ak32'olKdg'mI'uB!V#XYncJFTo`"Lbp@n=[q#C0iqYU0gr;HTbrdk*Gs*t~> +JcC<$JcFU,o`"gfrquZjs8)ckrqQNf!;?Eb0D+l,o'u8>n*fZ1m-Es$ki_*jjQ#7Yi8T)PAYT_P5\TECgZT:bqNrG)CLp1sM@!,_RKq/$+Jrfm2CqN_,Hr/Uf: +rJp]7rJp$"!K;s9M#`>062NtaE-PPo?t3h_Bl%d0F*;hUIXm')LPq5kOTL].OnFh9O8Y+6O8+h: +OoCO@Om\>1O6_o(OoCOAOo1CAPPp[>PPLI/O8u6YV^J@.9Za@-K\%0&]]Y2(p_8=+.`Q$!?b0/#RcHjncdaZdt +f@S^0gYCW@hr*GOj5]4^k2tmll0@U$m-X6?mfDqJrpg-^o^r.U!quB_rV6Egs8)WirVZWmo)=4? +V>l&~> +JcC<$JcFU,o`"gfrquZjs8)ckrqQNf!;?Eb..m-%o'u8>n*fZ1m-Es$ki_*jjQ#7Yi8en5!M:u6UO@384Q9F:&Ice:B"&g:B+&f9E7fd:B+&d9EIp^9_hEY:B"&f:B+,i +:>J_:;#X>l;#=&f:]sQh9heC^:\dib:[V'Y;>j>c;>sJb;#jMm;u0Dl;Z]os;tX&f;u]etbm6p`gl3&s,`4ZPu*91V<65X.P&r^-iX7n6*?8H)6]9`Iie:B,,1D>nJR +E;aeUErU4[FT-F^Focf1rceBe!dT*NaNfB!VMi3JlM#rKgL]3&-L&Zi%KDU8qKE$W) +L&HaALPUbCM2I4LN/WaVO,oBbP*2#nQ'Rc(R$sM6S=Z=ETqS3VUo(&gWN*##Xfen4ZEppG[^WfX +]=bhl^VRe)`5Ta;aND]Mc-FY_dF-Oof%8O,g=tE=h;@/KiT&tZjlY^hl07L!m-O--rpKmWnc&(\ +oCV\So`Fj]p\jmeq>^ +JcC<$JcFU,oD\^erqu]ks8)ckrqQNf!;?Eb2Y?V4o()>?n*f]3m-O$%l0.9ljl>C[i8j\Ef>iu=]f$V95Jp0MFgT=I=[05OdMW1Sk`'V +:fLFm;k]t`VN$UqNf]HjR[fn>SXuFIV5L>rYH4k/YHY7XrrA2ZP5(7=P5g^Gb506Aa8hn2U&Uke +U]%"gV>mFkVuN^Qs8Bh0_>M+K_>1nC^\tnHW;ib9VPU)aUS=HUTV%gISXc1=R[KP1Q^3o%P`q8n +Oc]R'#*+\%N/NRNreU]4LPPk`s+UH*q1JQrq1J["s+UH,s+^T1reYTOMi +JcC<$JcFU,oD\^erqu]ks8)ckrqQNf!;?Eb0_Fu.o()>?n*f]3m-O$%l0.9ljl>C[i8q*H$E=C>NGAS,UmDK0`>GC"^gJV/c9NKK?dP*(n"OT1C?Nqe\2OT(CAP5CC0OSk1,OSY+= +P5LI?P5^[DP5(7:Pk^O7Q2m9NQiNKPR/`NQR.ZmGR/`TRRf8fRSH#/WScGD[T)PA^T_P5\UAptg +V#@(gUhQHjR[9;(P`h)fNer@;IsZHbG&qS>ChdTqAS,RdLP1;2IscWeB4QONK77r]?>F.W6psUL +5u_-#BL,*W?XdV`DK0cDG=G(k7ncWL8UPo7IVit>DK'T:G'8+TH$ajbIXZiuJ:`E,re1?qrlbAe +rm(Mhrm:\mr6kSn!n>cNrmhD-f\"m2gY:N>h>Z=3i;_d9iW3t:rbhdSr,;OQr,;USpQtiEl^%UE +r1X.bs.fOgs/#amrMT[ohuEYsq*N#[/UnaZXTqJ$LSt2C@S!ob4R$X,(Q'@Jq +P*(k*Ns:W(N/W[PMZ/G6LkgcbLAuu,K_^8tK)(&uK`?c*LB!#/M#N6MMMmFPNK&sZO-#KePE_>t +QC!u,R[]h +JcC<$JcFU,oD\^erqu]ks8)ckrqQNf!;?Eb..m-&o()>?n*f]3m-O$%l0.9ljl>C[i8Pr9M7oA5X.J#6pj@06UjR984Q3C9M8%X9F"9e:2=W]D/T>ks)@sW +rc8!ZrcJ-^s)nHfG';ZNKgU&UkeU]%"g +V>mFkVuN^o[0j@O\%&rY]"5Md^AbkL^;%IurP8HLs2+fPs2+_9s&T,!rD`\nqc*Mos&Akqr`&or +s/-m7V50o^U7n9RT:VXFS=?":R@'A.QBd`"PEM)kOT(:FNfB!VMi*DkM#rKgL]3&.L&Qc$KDU8r +KDpQ(L&Qi,LB*/0M/\?1N/WaUNfT6_OckomQ'IZ%R$jD4S=Q7CTV8*TUnsrdW2ZetXf\e2Z*L^C +[^N]V]">Vg^VI\&_o9U8aN;TJbg+M\dF$Fme^i@)g"P39h;7&IiSrnXjQ>Ufkiq?slg4!*mdKW6 +nF?)?oCMVRp&Facp\jmeq>^ +JcC<$JcFR+o`"gfrqu]ks8)ckrV/JKp@e1Po^qbGo'u5%rQ,)_bPTN\c1TE_ciDJmdK@tJeCFQLr7Cu$rRhA, +d`]eP_u@OQ]`5cCXJhtkTq@d?Q]dGjNJWCDLP^bhXf\\&V5pJBGbW*RZ(@5(M3;FamFkVuN[qWSmgT_YM%D^];4I_#(nF^Ak/XW2HPjV50o^U7n9R +T:VXFS=?":R@'A.QBd`"PEM)kOH5H_NW+k;Mi.Lj!f2VerJ(?+s+L3#qL\Nqs+LE+rJ#KNLkpnE +MMd=NN/`jYO-#KeP*;,qQ'[l*R@9V8SXuIHTq\aihlPcHaeadaQ^rf%8R.g=tH>hV[8MioB+]k2tjjl07L!m-O--n*fc9nac8BoCW%Ts7QHe +rV6Bfs8)Wirqu]moDX=@VZ2/~> +JcC<$JcFR+o`"gfrqu]ks8)ckrV/;Fp@e1Po^qbGo'u5Nq\V2OT(CAP5CC0OSb+;O8tF7 +OSY+=P5LI?P5^[DP5(79PkgU8Q2m9NQiNKPQiNKOR.csHR/`TRRf8fRSGo)WScGD[T)P>^T_>&Z +UAgp&Una]VS=5b/Pa%>kO,f0QIt)ilG]\"HDf'6'An>LaB4Q[KK7JH"I[qJ67RgcqBP_X.Fa.4_7Rg*H8kFDXIXc3PDJa<2F*;_OGBnL\I"$QpJ:W=OKDpT'b6#o4 +c2Q#fci2;jdJVGle,Insf)OA8g"P07gt^cChr!AMiSieVDJsIjE;a_PE;skMQi!*9QimFkVuN[qWSmgTP5179OR\J5OT2:*W2HPjV50o^U7n9RT:VXFS=?":R@'A.QBd`"PEM)k +OH5H_NW+k;Mi.Lj!f2VerJ(?+s+L3#qL\Nqs+LE+rJ#KNLkpnEMMd=NN/`jYO-#KeP*;,qQ'[l* +R@9V8SXuIHTq\aihlPcHaeadaQ^rf%8R. +g=tH>hV[8MioB+]k2tjjl07L!m-O--n*fc9nac8BoCW%Ts7QHerV6Bfs8)Wirqu]moDX=@VZ2/~> +JcC<$JcFR+o`"gfrqu]ks8)ckrV.u=p@e1Po^qbGo'u5;uKVo;uT\l65i3K +1bq-T4Zu"n5!VD#6pjF47S$-C9h\;X:]=)h:&I]a:&n#`9_qK_:B"&g:B"&`:>\k<;#X>l;#=&f +:]sQh9heC^:]=2a:[V'Z;>a8b;?'Pd;>sJm;u'>j;ufki;Z9Vp<;fhr"4?PV`2Dd0@+rr$^/h/M23&*]&Y5!(kd92%uL5X7P!6UO1.6UX@57Rfs>8P;]J9MA/Sr_56!e*<;TVnT`(SaUAq"eV#R:kVZ!FmVuWgr[JmW@ +\@K2_]=bhk^](qJ^V9]^s1nZN!5e`O!Q)eR=8l5#Xd*^:jeCE.%f\5'6h;-rFi8N\UjQ5OdkNM0plKdg'mI'H3nF?&>o(2JFrq6 +JcC<$JcFR+o`"gfrVZTjs8)ckrqQNf!;?Eb2Y?V3o'u8>n*fZ1m-Es$ki_*ijQ#7Yi80!SuQ&M#<)3Ll$tGqMbE5s,?l8rJ^cl"2Vjl +`;.CG`qm1@[f!W7\Gs&9\GIP*20#SY2XQ +VlmA8rOi*@"M24W]Y+0Sp:U=:s1JBDrk/9C!4q:(q7?O:o=P(:qS)mBrkSKI!5S`T:;45PECl`MMV7c4c$;EX/`(rWMl85FelOJ];1a=K:Qgu5AP+-Bm,)e8l&?3JVT8L +R[]pH:ejhd<)HPeUo(#LNK0*bQ'n-?SHYUZV5C5mriQ4'!3cC+bl@^)rfR5DpQPT@rQ=iUlH'!t +rh04`!huHbrM9Iis/,dns/>ss!35&YrPJBHn\G"9rk9GRWMuhoVl$;dUnaZXTqJ$LSt2C@S!ob4 +R$X,(Q';31$B^F2O,f3YN/NUOreU]4LPPk`s+UH*q1JNqq1J^#s+UE+!JcL1M//!,MiY +d*^:keCE1&g"P08h;-uHi8N\UjQ5OdkNM0qlg4!*mI'H3nF?MK!qZ'Vrq-?dp\4X]s7uZjr;6Hj +rVc +JcC<$JcFR+o`"gfrVZTjs8)ckrqQNf!;?Eb0_Fu-o'u8>n*fZ1m-Es$ki_*ijQ#7Yi8`50K`Hf(6N9Ch<``C1@:Ee\Bl.d/F`r%VIt3'&KSbSIooK07r/UN4qN1]=rf[/@mZ@7*npltT>ns09Brg3\Pq3_,Ks-W_Pr0RJPrgNhUqjdYVr13n\qO[\Yp7_M\s.^L' +S=,Y,PEV,iNK&mOJ:;omH$=@ME,BB*B4h-R5A#V&Jq8E"InGKDuahRE:fLmQLL7@TDkM^T`Us` +U]%"gV>mFlVuN^qW;rsXs8A,VOnFh/OoLLaWi;trVl-DgUnjc[TqS-OSt;LCS"#k7R$a5+Q'IR4 +Op[>5O,o<\N/W[QMZ/G6LkgcbLAuu,K_^8sK)('!K`?c)L&m'creYEJMi3OQNK0'\OHG]hPE_>u +Q^F/.S"#q>StD^MU84T]Vl-MoX/rG+YctF>['d?O\[f>b]tV7s_SX71`lH0BbKJ/Ucd:(feC<%# +f@em3gtgfDi8ESRj5f=ak3(smlKdg'mHs?1n*olHncJFTo`"Lbp@n=[q#C0hqY^6hr;HTbrdk*I +s*t~> +JcC<$JcFR+o`"gfrVZTjs8)ckrqQNf!;?Eb..m-%o'u8>n*fZ1m-Es$ki_*ijQ#7Yi8eq= +;#X>l;#=&f:]sQh9heCP:[V'Y;>sDc;>sGp;,C*`;?'Pm;u0Dk<<#nj;Z9Vo<;onr#5TN0T4ZYM]2)6g4)_*5O,o<\N/W[QMZ/G6LkgcbLAuu,K_^8sK)('!K`?c)L&m'creYEJ +Mi3OQNK0'\OHG]hPE_>uQ^F/.S"#q>StD^MU84T]Vl-MoX/rG+YctF>['d?O\[f>b]tV7s_SX71 +`lH0BbKJ/Ucd:(feC<%#f@em3gtgfDi8ESRj5f=ak3(smlKdg'mHs?1n*olHncJFTo`"Lbp@n=[ +q#C0hqY^6hr;HTbrdk*Is*t~> +JcC<$JcFO*o`"gfrqu]ks8)ckrqQNf!;?Eb0_Fu.o()>?n*f]3m-Es$l0%3kjQ#:Zi8W/3M27"Fq2"p)"c/"lMMmDjN;eh7N;nn; +^]_Kj_o0Lk`V7CO`rO-N\,Ni*\+R3.[K!Q4YQ:o1riH4%XSkKa6Q0ZVE,g#DH[UF!M2m^^PaRu2 +T:r0[Y-POL]_f>@]`#J9]_oJB]`5VD]]$Ku])B84]E#YA^APbF_#;"J_"PVD_#D1I_Z.OO`;[aS +`rF*Y`rF*S`r3pYaN=>%rlG2`bPTN]blH&^ci;AldJhSoe,\%tf)=34f[@pb_na%&^:_"l^oaT6 +U7n3KR$EhtNf8gML4t;9YHP",W2HPlRs]@PZ)kC5R?NYaQ[F6QDJE`sF+0$@:Jc@fLlROaR\-*F +:/=kh;H'9aVP]?6NK9?lR@Te;St;[QV5^NpXoGU%Yfm%HOSk7?P4t1>ao9HTamI1LT)YG_T`(Sa +U&^teV#R7kVZ!FmVuiruWoF'Y_>hCJ_=>>;^](r%Wi;trVl-DgUnjc[TqS-OSt;LCS"#h5R$X,( +Q'@JqP*(ieO,f6[N/W[PMM[1GLkkq`s+UK+q1JNqq1J["s+UH,s+^T1reUZ5MuJZDNK0'\OHG]h +Pa.N"Q^F20S"#t?StMdNUSO]_Vl6SpX/rG+YctF>['d?O\[f>b]t_=u_Sa=2`lQ6DbKS5VcdC.h +eC<($f\,!5gtgiEi8EVTj5f=akNM0plKdg'mI'uB!V#XYncA@SrUg6cp\4X]s7u]kqtp?irVc +JcC<$JcFO*o`"gfrqu]ks8)ckrqQNf!;?Eb-1pg#o()>?n*f]3m-Es$l0%3kjQ#:Zi8J)KPQ$gAQ2$XJQ'R_rNqJJ#NqJD1 +N;ne8M$A`kL51M;L&F@:6Prg+?=72MA7oOkDfTrAGC+^eJ:W?,M2IAiOT1C?NqSP1OT(CBP5170 +OS4b+OSY+=P5LI?P5^[DP4t19PkgU8QN*s^o`Fj]p\jme +q>^sJ~> +JcC<$JcFO*o`"gfrqu]ks8)ckrqQNf!;?Eb..m-&o()>?n*f]3m-Es$l0%3kjQ#:Zi8k +;Z/r\6Q%[>3]]Ac4Zu"n5!VD#6pj@26q9d?8k_oQrCm5c!_uHar(I/d9MG:WrD*;es%`SiohOF@ +nkf<_s%rSgr_N_n:/+GXn5&IKr_`Ykp/1fe!`;cjpJLrgrDWSk!)rkrs&8Vhr_reqrDihts&BM+ +;,L+`9MA)O7mfX15lO"J49IZ)2`^jq!AuY30gS,n5s[_"4?5De5.9Za@-K\%0&]]Y2(p_8=+. +`Q$!?b0/#RcHjnce'umuf@\d1gYCWAhr*GPj5]4^k3(sml0@U$m-X6?mfDqJrpg*]o_nFap@n=[ +q#C0iqYU0gr;HTbrdk*Js*t~> +JcC<$JcFO*o`"gfrqu]krqZWjrV/AHp@e1Po^qbGo'u5[dact'gYL`CrSRV4qVhA1rnmL-!f2\iregW1s+pH,s,-c5rJ^`8s,?rm!l;ak +rl"fTq8WiO-jp/Fa&.[K8PVLP*;,u +R[p(FVP^N%\,Er;]`,P;]_fD=]]$Ku])B87]`,V?^APbF_#;%J_"#8<_Z.OO`;[aS`rF*Y`r=$S +`r3pYaN=>%rQ,2bbKS2RrlkAdrm(5`rm1ksdaHUne^aWLs4;#5b/hH8^VIUr\\Pn[W2?5]T:VO< +OckidLkUM9KS+u]XK/=tV5^&6FeGS3Z`':TN.?/$J6,cC@:i,QIu6or:O.DDNK9EpTUekQ:/Fkg + +JcC<$JcFO*o`"gfrqu]krqZWjrV.l:p@e1Po^qbGo'u5Gq3CcAs-3\PQ'I[3 +NrP1=Nr"h$NrP+=N!kQ$M2@%ELPCS=Kn]Ilr'M>iF*Cqu?t!SZC2@g0F*)SOI=?a!K8,5@O8P+= +O8b16O84n;OoCO=On"P4O8k7:O7JD1Oo:I@Oo1CAPPp[=PPLI=Q26dHQhm$JQi8`SXuFFqk!h[s.K=as.KCc#G%?NQ'7AoOoC>IMhQY0I<^$]F`VP?Ch[Km +A7K+Y@tTDcJ:;ilG\CT6I=ZusFDbi&>@(Z&5s@n85uqB+6UsXQ@V':jEHHJN7n6$<9heB1I"$Q] +D/O94F*2\NH$XdbIXcp#JqJ]/qM"mirlY5`!6kGes3CVirQtJis3^nrrm^turn%2&#MIkdgtgfC +hYuF4hu_lsiqdNiDu=PSR.?U;QM-[FQMmETTDtS`U&UkeU].(hV#[CkVZNfrWW&pXs7VTJOSt=@ +P5LIBOT2?\W@4^CVl$;dUnaZXTqJ$LSXc1=R[KP1Q^3o%P`q8nOcYWbNfB!VMi3JlM#rKgL]3&. +L&Qc%KD:&pKDpQ(L&Qf.LPUccM/\?1N/WaVO,oBbP*2#nQ'IZ%R$jD4S=Q7DTV8*TUnsrdW2Zet +Xf\e2Z*L^C[^N]V]">Vh^VI\&_o9U8aN;TJbg+M\dF-Lne^i@)g"P39h;7&IiSrnXjlY^gkiq?s +lg4!*mdKW6naZ2@oCMVRp&Facp\sseq>^ +JcC<$JcFO*o`"gfrqu]krqZWjrV/#>p@e1Po^qbGo'u5E_:f-sbr)3JjqbdGl;#O8j;#3?Q54_#655RM@55n@T:AdoZ:t8P@;u0Al;>iiZ6Pi-S +5s%.j4?Ynl5<_=u6UX=0779[:8P8qTqb@#_s%NJeqb?u`q+pZYi(ruA!Du\m;?'Ji:]=/o:JOVY +:/:=TmSNm[r_W;cr_i_lpJLrgrDWVlr_req!)rShs&8kqrDiku%8p&":eaYX9M%`A6UF*<4r6=C +4#]2[3B8oR1bpd?1I4>m5Wq4j3C*O-5rjrEH]=Y_h]tV2Y +^&u-a^VBcas2"cRr`9&!!*9)!s&AMepJh0ms/@EFVl-DgUnjc[TqS-OSt2C@S!ob4R$X,(Q'@Jq +P*(ieO,f3YN/NUOreU]4LPPk`s+UH*qLeQpqLed#s+UH,!f)SfreYTOMio(2JFrq6 +JcC<$JcFO*oD\afrVZTjs8)ckrqQNf!;?Eb2tZ_4o'u8>n*]T0m-Es$ki_*ijQ#7Xi83;FgY1<3 +f$r0rdEfqWb08,VdaZk$g>1WChV[5Khu;R1iVh[7hscL#MYr>2M#)u+MZ&J4N;gTo_8=+h`;[aP +`qm^Y`l5p+\)Fdg[gKROZa@*DZELI7Xo>@$WW#6^6iTOmNg+I$FEVtXItro?O->clR@9\=Tr+cl +ZF@IE]`,P;]_]>=]]$Ku])B87]`,SE^AYhG^APbF_#;%J_"#8<_Z.ON`;[aT`W4'X`r=$S`r3pY +aN=>%rlP2_"3\p3bPo`bc2Q#_ci)5jd2^T`e(*""f%&0ja2>[,_7mOk^V$\HV4jQSSsYlDOAh0t +Lk^V9K7^5+X/W"lW1SK^S=ZgeVjW]iJ9Z!G?UeF5F\6\&Ll=r&:O.JFNK9EqTUntS:/Fnh;08M. +V2^IpOHl*!S"#t?St`'XX0&P,YHRf,`rH"!r/po?s-*&rqoJZVpW39Qs.0.\s.B=arh9@d!2KLg +!i;ckrhodp!3,psjT"nhn%ek9rkAE4.B08DVl$>fUnaZXTqJ$LSt2C@S!ob4Q^3o%P`q8nOcYWb +NfK*XN/NSmM>rA3L])u-L&Zi&KD0uoKE$W)L&HaFLPUbCM2I1KN/WaVO,oBbP*2#nQ'I]'R$jD4 +S=Q7DTV8*TUnsueW2cl!Xfek3Z*UdE[^WcW]"G\i^VI\&`5Ta:aN;WKc-FY^dF-Lne^rF*g=k<; +h;7)JiSrnYjlY^gkiq?slg4!*mdKW6nc&(\oCV\Sp&F^cp\jmeq>U6fqu6NlrUTr=s/H$K~> +JcC<$JcFO*oD\afrVZTjs8)ckrqQNf!;?Eb,kU^!o'u8>n*]T0m-Es$ki_*ijQ#7Xi83;FgY1<3 +f$r0rdEhcX#ah$KS"-%?StGbMqkP5LI?P5^[DP51=9PkgUAQN!6IQ2m9NQiNKLR/`TQR/<cs3:Pgrm1Sj#LUoFdF$Cje,IkseH4=RfDaD/g=tB;h;-rEhr"Fk +!TE&5D?"MODuH'pQh6UYd*^:jeCE1&f\5'6h;-rGi8N\UjQ5OdkNM0plKdg'mI'H3 +nF?MK!qZ'Vrq6 +JcC<$JcFO*oD\afrVZTjs8)ckrqQNf!;?Eb,kU^!o'u8>n*]T0m-Es$ki_*ijQ#7Xi83;FgY1<3 +f$r0rdEhefs%rMgr)3JjqbdSp:f("d;"QpL55.;A56!kA56!eG4T7MC:]!oa:\@Qa:]45D<;]Yq +;H*NlrDEP\r'UKP)*U8H3]fGe5!;"k5!VG$6q'L46q0[<8k_qV:&Rc\:&Ic^:\IQ@:\7K];?'Ji +:]=/o:JOVY:/:=ToM>N`r)!Air_W;cs&&hor_WAerDNSmrDNVnr`&nrp/1lhr)=&(;c-Ce:JFMW +91h_R6N]Y>5!Am-s#;nq3&roT1GppC1I=Am5<_4k3C#em5&*C&ViLCM[j*rGV^T +rc.mWs)\0]s)e<`rcS6arc\KjH?spard4Zm"FY`IIXglNgJn/Ns.0.\s.B=arh9@d!2KLg!i;ck +rhodp!3,pss1/0>!4i'>s1A9Cs1S9Cs1eWNrkeY8qc3VpnPf0]s/INIW2HPjVPU)`U7n9RT:VXF +S=?":R@'>,Q'IStP*1rhO,o<]NJrgSMZ/J4L]E5/LAuu-K_g>qK)1-"K`?c)L2_p(Ll$tGMMmFP +NK0'\OHG]hPE_>tQ^F/.R[]h*YHY: +JcC<$JcFL)o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nfI>jn*f]3m-Es$l0%3kjQ#7Yi8s24`Prl+]Qrl=fRrPnoZ +qo\o[s2kGebfe3/bl>rdcM,Zad/MGmdg"=Pd`onQ_#D+K]OSI`]re3.TqS*MR?s%uOH>r0$WmprNBTp;m9Ss.'+[rgs.^!20=bs.TLgrM0Lk +VPa?j!iW)tri6"!jo>%jm_Jb8s1U%bWiE%sVl-DgUnjc[TqS-OSt;LCS!ob4R$X,(Q'@JqP*(ie +O,f3YN/NUOreU]4LPPk`s+UK+qLeKnqLeg$s+UH,s+^T1reUZ5MuJZDNK0'\OHG]hPEhE!Q^F// +S"#q>StD^MU84T^Vl-MoX/rG+YctF>['d?O\[f>b]tV7s_SX71`lQ6DbKS5Vcd:(feC<($f@em3 +gtgfDi8ESSj5f=ak32'olKdg'mI'uB!V#XYncJFTo`"Lbp@n=[q#C0iqYU0gr;HTbrdk*Ls*t~> +JcC<$JcFL)o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nfI>jn*f]3m-Es$l0%3kjQ#7Yi89he2UI!gBYDJa92EHQJKG^=X_ +IsuluJV/T.q1SghrlG&[s2t;`!mJp6rm(Mhrm1_od*Vd>#L_)MeC<%!f)F;$fE9g]gYDeas5*e5 +rnmh9DYS)HDZ?(#R.Zg;QMHmISH#/ZT)YD_T`1YbU&^teU]RBiVZ*IpW2ZcqWrK-]s7VTIOT(C< +OtMlYX/`2!W2HPjV50o^U7n9RT:VXFS=>t8R$a5+Q'IStP*1rhO,o<\N/W[QMZ/G6LkgcbLAuu- +K_g>pK)1-"K`?c*LB!#/M#N53MMqIm@?$;.O-#KeP*;/rQC!u+R[]e:St;RJTq\?YVPg>kWiN5' +Y->.9Za@-K\%0&]]Y2%o^r!t,`Q$!?b0/#RcHjkbdaZdtf@S^0g>(N?hr*GOj5]4^k2tmll0@U$ +m-X6?mfDqJrpg-^o^r.U!quB_rV6Egs8)WirVZWmo)=4?WrIS~> +JcC<$JcFL)o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nf[Jln*f]3m-Es$l0%3kjQ#7Yi8X8i;>a;l;>sAl;=$IE55RSE4p!l24nq5@4o[YC:]!ob:\IWa:]F8Z +;tj8i;tEud;u9Jm;>ro[6iBCj4[D.l4$5Yj4$,Si5X@_)7RKX57S$-D9MGF[s%N/]rD*>f!)WSh +p.jL@oMGH_s%rPfs%ikp:/+GX:@V-Q;#a>g;#aDl:]aKl;YR,5XRn,6U=437nH9C8kM`M9h\@\;#a>kBE2]E +B`;`EC'/9hDJoGlrc%jVrc8!ZrcA0`FT-F^G5ladGl2meHN8HlI/nch4o[Xt<<#nsSH#/ZT)YD_ +T`1YbU&^teU]RBiVZ*IpW2ZcqWrK.!\,a):])TDB]E5d\^AbhG^]2(O_SO(*r`8ttrD`;cpJ`]E +WiE%sVl-DgUnjc[TqS-OSt;LCS!ob4R$X,(Q'@JqP*(ieO,f3YN/NUOreU]4LPPk`s+UK+qLeKn +qLeg$s+UH,s+^T1reUZ5MuJZDNK0'\OHG]hPEhE!Q^F//S"#q>StD^MU84T^Vl-MoX/rG+YctF> +['d?O\[f>b]tV7s_SX71`lQ6DbKS5Vcd:(feC<($f@em3gtgfDi8ESSj5f=ak32'olKdg'mI'uB +!V#XYncJFTo`"Lbp@n=[q#C0iqYU0gr;HTbrdk*Ls*t~> +JcC<$JcFL)o`"gfrqu]ks8)ckrV.f8p@e1Po^qbGo'u5s24lT!5nfS +rl+]Qrl=iSr5SiZans6[aoBN^bQ#fdc2>l^ci2;jd::PLaN)01^:h4m]XYPcXf/+iTq@gBQBI>k +O,JdIL4k,,Jul#QW2-2cQ[<_HZFQp(O*$,FDhh,!@X1[`G_D&N:esr:Jr#AIQ("58SPW'U:KCCn +;N.rA3L])u-L&Zi&KD'onKE$W)L&Qi,LB*/0M/\?1N/WaUNfT6_ +OckomQ'IZ%R$jD4S"6.BTV8'SUnjlcW2ZetXf\b1Yd1UB[C3TU]">Vg^V@V%_o0O6aN2NIbg"GZ +dF$Fme^i@)g"P39h;7&IiSrnXjQ>Ufkiq?slg4!*mdKW6nF?)?oCMVRp&Facp\jmeq>^ +JcC<$JcFL)o`"gfrqu]ks8)ckrV.f8p@e1Po^qbGo'u5s-*DEs-)u;q3CiCrg3JI!13\P!13;EqjIGNs-`hSrgNnXqOIVVrgj(\ +!2'+Z"e;!IQ'%4.O>i5ZN/<7?IscNdGB@nFDes0&B4b[a?smDpJUr&ZrlP/^rlY;crltGfrm1Mhrm:eqe'nc@3hZMfoi8FNNphfnpr0[2E +nWs*>s-j([SXobOs.9:arh9@d!2KOhs.o^mrhodp!3,sts/Q1%Xlo`TOnFe9Onk1?OWpj+Wi;qp +Vl$;dUnaZXTqJ$LSXc1=R[KP1Q^3o$PEM)kOT(:ENfB!VMi.Ljs+gZ1rJ(?+s+L6$p4E-ns+LE+ +reCH.!/UW2E/KR4N/`gWO,oBbP*;,qQ'Rc(R@9V7SXuFGTqS6WUo(&gWN*#$Xfen4ZEppG[^`lZ +]=bhl^VRe)`5Ta;aND]Mc-FY_dF6Uqf%8R-g=tE=hV[8MioB([k2tjjl07L!m-O--n*fc8nac8B +oCW%Ts7ZKerV6Egs8)WirVZWmo)=4?X8d\~> +JcC<$JcFL)o`"gfrqu]ks8)ckrV.f8p@e1Po^qbGo'u53r]^NL4ZtnirB:$ArD3;cqbR5g"&D`i;>sDi +:B=9hk>V7Wq,@#e!)ren"&Vro;>ro[6i9=k4?knh3]]Ad5M^2`g2]".dNs1ApK)1-"K`?c*LB!#/M#N6MMMmFPNK&sZO-#KePE_>tQC!u,R[]e;St;UKTqeEZVPgAlWiN8( +Y->.9Za@-K\@K2_]Y2(p_8=+.`Q$!?b0/#RcHjnce'uq!f@\d1gYCWAhr*JQj5]4_k3(sml0@U$ +m-X60n*oi:o()DDo`"O`pAamcq#C0iqYU0gr;HTbrdk*Ms*t~> +JcC<$JcFL)oD\afrVZTjs8)ckrqQNf!;?Eb+nYBso'u5iD.M>iD#M>rA3M>W53^;'Z_!l;akrl"iUqo8HP +s2G8^`5BI.\@DFH!4_s9r3lO2pU9b&&%&[KZ`pa>Y-+n.X/`3e6Ms4I6lVD/E,p#DH$t*nLl7:U +PE_B#S=lOMV5LB![(6%Gr4N*ErOr0BqRZa?n%8S3rk&$RV,9.D0JWnIYg`q:j.5aRuOc]="m`G.Cr5ncUrgWqXs.0.\#G7Z^TqS3T +U].(hV#[ClVZNfrWW&n"X/rD)kPt%foYCC>s1SK6ri.QLW2HPjV50l\TqS-OSt;LCS!ob4R$X,( +Q'@JqP*(ieO,f3YN/NUOM2@%EL])u-L&Zi'KCjclKE$W)L&Qi,LB*/0M/\?1N/WaVO,oBbP*2#n +Q'IZ&R$jD4S=Q7DTV8*TUnsrdW2ZetXf\e2Z*L^C[^N]V]">Vh^VI\&_o9U8aN;TJbg+M\dF-Ln +e^i@)g=k<;h;7&IiSrnYjlY^gkiq?slg4!*mdKW6naZ2@oCV\Sp&F^cp\jmdq>^ +s/Z0M~> +JcC<$JcFL)oD\afrVZTjs8)ckrqQNf!;?Eb+nYBso'u5StDYKT`(PcU24Z@C\qrGD>nGJD>7rEC]8/JPQ$g;Q2d*DQ2Qd[C`E@Uit^BkqX,F*2YMH[UBpJqSi5MN*YmO8"b/Oo(7=O8=t; +O8P%8O7\P3Oo:I@Oo(=APPp[EPOXn4Q2HsIQi!*JQiEEQQh-UARJrQRRJ`NQS,&TTSGo)VSctXP +Q^*_rrfA%YO,SmPK7SN"H$FRTEcGo2CM.3h@q&kT?\JE01k'k!H"^c9H[pWlF)5,tBRNW9;,gac +='oT,84Hik@VBRrEH?DN7n?->78-EM9QPT/IVf"$&T;Z0F`r"SH?jjdIXcp"JqAXNK`K*k`W4'X +aSs<\b5TQabl5iecMZ#gciDDkd/VJndf._qe,n1Of)F8'g"P07rnRP0s5*b4s5Vh^VI\&_o9U8aN;TJbg+M\dF-Lne^i@)g=k<;h;7&IiSrnYjlY^gkiq?slg4!*mdKW6naZ2@ +oCV\Sp&F^cp\jmdq>^s/Z0M~> +JcC<$JcFL)oD\afrVZTjs8)ckrqQNf!;?Eb,4tKto'u5sDi:]F8k;?'VX +;uBVb;Z]ir;uKVn;?&u\6i'1N55dME3BTGhr]L\2`NTN2)@$F1bqEb5X@Os3]K>f5X.Fp4#o/V1b_!:)_*/9M7W95=%V&6UX:08Oc5L8-V[[92&#R:ARcbBE)WFBDlNC +C&_oLCM[keDZ4SRE;jkWEWU6%F8L(YFoHOcG^4T4HN&6oI!pBkJ,MS+4oJ=5;ufkrS,]#YSc52c +T:hjNTq\9VrhTRj!2fan!iW)tri-7)XK8P5\%&uZrOW$@s1JBFr4`3Gs1nZOs&K%ts&JempJ^fc +!3?+!/ZG\HVl$;dUS=HUTV%gISXc1tQC+&-R[]h +JcC<$JcFI(o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nf72hn*fZ1m-Es$ki_*ijQ#7Xi83;Fg=k32 +f$r1HaoBKibg4\cf%Jg5hVe@k!93q8rSmX/qhb9/q2,!+mtq%$#JRsf^qmk(_u@UR`V[[Oa8a-_ +`Pf[2_8,uYqRQU8rO;X3!4DR0pU(.2[Bd$@riZL-XK8J(6Mj.G6le^aDK0]=GC"[cL5:bKOHbrq +R%0b?Tq\E`X0K.Frk/0Bs1\HFrOi$>!5.d4rOi0BqRZU:p:UCZaR>7r!:$ND">7H%1R*O-Q0)T3+l`9i"_e;I6&j +V5903O-#NhQ'n/4rLO:iV5L8mXf\b0poqR6s,[;EOHB=$s2k2]oZ?^Gr5niWs-iqV!h>gPrgj@e +TV/!PU8"F^U^*`nVPg>jW2]cr!irE(riPDamD8P4r4i9G/$#\MWMl_mVPU)aUS=HUTV%gHS=?": +R@'A.QBd\uP*1rhO,o<\NJrgSMZ/G6LkgcbLAuu-K_pDmK):3#K`?c*L2_p(Ll$tGMMmFPNK0'\ +OHG]hPE_>tQ^F/.R[]h*YHY: +JcC<$JcFI(o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nf72hn*fZ1m-Es$ki_*ijQ#7Xi83;Fg=k32 +f$r1EQNESDS,Sr]StDXJT`1Y_T`(S[D#8#FD#8)HDYJ#CD#\;LPPpa;Q2QsBQ26R7NqA>%NX^u. +Mi*CKMMd4FLPCLLqa:0I*CY-V?=.&KAS#LgCN"36F`r%VI=?]sK8#&:Mi5Y +SHYUTS!]P*rfI,?B8h\*L4Fc&I!9g[F)l59CMINpA7K(W?snVoicHjh^rm(Vlci2;jd07tIe'upurmh8)f\"p4g]$".h>Q41hZ2U5 +D?+VSDZ+GPQM-[BR.ls;QN*EQRf]+NSc52cT:hjNTq\9VrhKdqVP^8hW2Q]pWWK6&XT#?cs6YsF +OSb1?P5gXpX/`2!W2HPjV50o^U7n9RT:VUDS"#k7R$a5+Q'@JqP*(ieO,f3ZN/W[PreU]4LPPk` +s+UK+qh+Hkqh+p%s+UH,E/07*M2@+IMiYd*^:keCE1&g"P08h;-uHi8N_VjQ5OdkNV6r +lg4!*mdBQ4nF?MK!qZ'Vrq-?dp\4X]s7uZjr;6Hjr;H6dJcDhOJ,~> +JcC<$JcFI(o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nf@8in*fZ1m-Es$ki_*ijQ#7Xi83;Fg=k32 +f$r/Er(d8f!)`\mqbd;irDEMkofW19!'^0@r]]X2s#g3TqbHu`s%r\lr_WMg!)WYlr`/ttoi(li +oMbZeoMb`erDNer;,TaX6hs+N76pf4(-=ZB5!1tl5X@Y&770L46q9^;8P2TNrD!2b!`)Wgr_WPh +pJ0UAoMGH_s%rPfs%i_l:B!rf:@V-W;"RN`;#=,h;Ya2e;#!od;YO,h<;ohq;Z9N::ej\W9M7rJ +7n,j55X.Lu4$5Yf3BB)X3&EKK2)6pC1.2%+s#r"r3B9&_50JG4: +2E!TY5!MD&2`NiY3BfJe55n1l8j5I*5XIe)6pj:384H*?84cEG92&#R:AIZcB)-*=B`2WIC27X& +rbh[Qs)@sWs)J*Zrc/'^F*%>&rcJ?eGB\=Xrd+Tk!.+Wks*OirJ,MP/55dXo<<&EdRf]+NSc52c +T:hjNTq\9VrhKdqVP^8hW2Q]pWWK6&XT#=(\%&rYrOW$@s1JBFr4`3G"i.sj_GjP(<;KPf<%G#L +Wi;qpVl$;dUnaZXTqJ$LSXc1=R[KP1Q^3o$PEM)kOH5H_NK&mUMi.Lj!f2VereCH,s+L9%nq-ak +s+LE+re>BILkpnEMMd=NN/`jYO-#KeP*;,qQ'[l*R@9V8SXuIHTq\aihlPcHjkbdaZdsf@S^0g>(N?hr*GOj5]4^k2tjkl0@U$m-X6/n*fc9 +rpg-^o^r.U!quB_rV6EgrqcQirVZTloDX=@XT*e~> +JcC<$JcFI(o`"gfrqu]ks8)ckrV.f8p@e1Po^h\Fo'u5FF&@bKntYIOoCOQR$jP< +TqJ3ZX0&_;]`#PC^AYbD]_oAA]^NK2]`5V?])926]`,SE^@]2?_#1qI_!o2;_YqCP`;d^U`5VMk +rl=oUqo8`Yans6[ans9\bl>rdcMc(%cHOAL^q@:k]"GYb\%&cDVkTrZSt;=9QBRGlN/ECDK7JK% +I]99EVl->bUmmU2NJ`V$[@`\BDkMc.='J4A9l,*0EcZ;FH@^m2O-c?/Ski*U:/t4l;kft^V2p^t +OHl*!R@KeD%F^G +JcC<$JcFI(o`"gfrqu]ks8)ckrV.`6p@e1Po^h\Fo'u5[CcE@:Ee]C27^,F*)MKH$ashJq8T0LP^qKooSm0r/gf:r/go= +r/UZ8oT9!5rK@)@qi^uCr/q&Dn=)7nA6)c7>[LrRCN"99H$KF`r"TH?jgbIXZctJV/Q,pOrUdr5ScW +r5elZrlP5arlkDes3:YkcMPred/VJndf._qec+,%f@\a/rnIG-s4mn9h;7#GiSjNKr0I&Cr0[2E +o9KZLR@9S6S"-">rgj@eTV/!PU8"F^U]It8R$a5+Q'IStP*1rhO,o<\N/W[PMM[1GLkktas+UK+qh+Ejr.G!%!/:B+ +CPR_%M2@+JMi3S"-(AT:qsQUnjibVl?\sXKAY0Yd1UB[C3QT\\#Mf +^;%J#_o0O6aN2NIbg"GZdF$FmeCN7(g"P39h;7&Ii8WeWjQ5Oekiq?slg4!*mf)YUnF?MK!V>s_ +p&Facp\jmeq>^ +JcC<$JcFI(o`"gfrqu]ks8)ckrV.o;p@e1Po^h\Fo'u5k;#F,h;#O8k<;ont<:s2e +<:j)h<:j,h;ZBYt;H$FZqa:3JrC$cQ4$sJh;>sAn:Jam_;>jDe;uTbr;uTYn +:]F''9M.oJ7R][05_f3&iiU3&WYl1BB3sr]qqq5!(ec2E*NK1Hdc\3&NTN0.\+c-8$o% +0fCX:0ekOE3''/c5XRmur]'sBr]L0Q"A1jD5=5<:"%,OJ7K,d_84cEH92&#R:A@W`B)Q?DBP1uV +B`;]HC2Eldrbh^Rs)@gSs)S*[rcJ-^"*Sm4H2`*lH[:$brHeWoI=QkF4oIRnE\@K0K])TDB]`5\C^Al"K_t8R$a5+Q'IStP*1rhO,o<\N/W[PMM[1GLkktas+UK+qh+Ejr.G!% +!/:B+CPR_%M2@+JMi3S"-(AT:qsQUnjibVl?\sXKAY0Yd1UB[C3QT +\\#Mf^;%J#_o0O6aN2NIbg"GZdF$FmeCN7(g"P39h;7&Ii8WeWjQ5Oekiq?slg4!*mf)YUnF?MK +!V>s_p&Facp\jmeq>^ +JcC<$JcFF'o`"jgrVZTjs8)ckrqIf6p@e1Po^qbGo'u5\Gs)>])B2=\Fm?'[f3ZB['d_#;"J_"#8; +_YM(P`5T^8`V[[Sa8ijbK.fB^qBZXA\#=][CE98Tqe6PSXGn3 +Q]dMmN/E=CJUr8tI&a*AVPKoZU3Vr`N/NIEJq&2pG&qS8F&-I\I;T.p9;1/!g&P,rK.&A!li:$rlG,]qo\ZTnAtOL +"j!'uR@9TDRfT%Mrgj^oTV/!PU8+KZUnsrcVl-JlWW&muX/u<&s/l@*lMp(ar4r0D!3?+!,,qN= +VPU)aUS=HUTV%gHS=?":R@'A-Q'IStP*1rhO,o<\repl9MZ/G5Lkkq`!/:E*r.Fp!qLSQrr.G!% +!/:B+#)A"jM2@+JretWPNfT6_OcklkQ'IZ%R$jD4S"6.BTV8'SUnjlcW2ZetXf\b1Yd1UB[^N]V +]">Vg^V@V%_o9U8aN;TJbg+M\dF-Lne^i@)g"P39h;7&IiSrnXjlY^gkiq?slg4!*mdKW6naZ2@ +oCMVRp&Facp\jmeq>^ +JcC<$JcFF'o`"jgrVZTjs8)ckrqIl8p@e1Po^qbGo'u58#DD>\2MPP178Q2HmEPlR-LQ2[$@O7&&(NW5%< +O8b.ENK0$YN/NRMrJ1;[:]E@:<\ZBkhO)EcZ;GGC"XbIt<6*KntYHp5o'3rK-f8 +rfI,?r/UZ8oT9!5rK@)@qi^rBrK7/EnW`g6qj.5J!1*JJrg3\PqO%5JrgcNrmh/&g"HAZrnRP0#N":mhV[5LD>A&NPa.O3 +QM-[ER.H[Vg^V@V%_o9U8aN;TJbg+M\dF-Lne^i@)g"P39h;7&IiSrnXjlY^gkiq?slg4!* +mdKW6naZ2@oCMVRp&Facp\jmeq>^ +JcC<$JcFF'o`"jgrVZTjs8)ckrqIf6p@e1Po^qbGo'u5b5!1nh4[21t62j4X779L77Rp'C92>I^!`2`krDsJh;?'Jm:]=2d;>jDe;^#+=;,L.b:J=DR +91_]E770=)5sIRr4$5Ma3B8uV2`VF[pJ_-nri.0AW2HMhUnjc[TqS-OSt2C@S!ob4R$O#&P`q8nOcYWbNfF$s!K2j7M#iEfrIt<+ +re13%r.=crr.=j!re(9*rItN3LkpnEMMqImCQ4@8O-#KeP*;/rQC!u,R[]e;St;UKTqeEZVPgAl +WiN8(Y->.9Za@0L\@K2_]Y2(p_8=+/`Q-'Ab0/#ScHstee'uq!f@\d1gYCWAhr*JQj5]7`k3(sm +l0@U$m-X60n*ol;o()DDo`"O`pAamcq#C0iqYU0gr;HTbrdk*Ps*t~> +JcC<$JcFF'o`"gfrqu]ks8)ckrqQNf!;?Eb+8#0qo'u5ZkQC4;9TqJ6ZVld22\%_gSr4N$@!5/->s1J0>rOi0BqRZU:ot:=P_>V1G^FQCdWiE%sVl-Dg +Unjc[TqJ$LSt2C@R[KP1Q^3o%P`q8nOcYWbNfB!VMi.Lj!f2VereCH,s+L<&r.=`qr.=j!s+LE+ +reCH.!/UW2!K)g7N+J!/O,oBbP*;,qQ'Rc(R@9V8SXuFGTq\hVd>NioB+]k2tjjl0@U$m-X3.n*fc9rpg-^ +o^r.U!quB_rV6EgrqcNhrqu]mo)=4?YQ'+~> +JcC<$JcFF'o`"gfrqu]ks8)ckrqQNf!;?Eb+nYBso'u5Grg*PKrfll4 +pl><6rf6`4r/V/ENJrdRMM[1GM>Ta:7/]RS7Nb3BG["BZ@:Fa&(WI=?a!KS>2< +MN*\nOT1FCP5LI@OS=h9OT1C=Nr+n0OSk7>P5LI>P5^[DOoU^;PkLC>QM-[EQiNKMR/ERfAlWS7S1VR$Nu!OHGTaNK/sSLkgP2IX?BcG'%bDDf'<+Bk:jc@:9h]>MI",sKDJsT:rc\Yd*^:jeCE1& +f\5'6h;-rGi8N\UjQ5OdkNM0qlg4!*mI'H3nF?MK!qZ'Vrq-?dp\4X]s7uZjqtpBjr;H3cJcDqR +J,~> +JcC<$JcFF'o`"gfrqu]ks8)ckrqQNf!;?Eb+8#0qo'u5a;l;>rZV4T7M74RbN/55dYD49/4T:]4#g:]=2h:B45i;>sDj:]=2j +;#jMn;>sSq<;ohr<:Wuf<;fhr<;0>f<;BJj6hs.K7K5g\7m91"4?EF(s#^?G3^*I,!^]7Br^HfV +#"VB\9MSA\rDsJi;?'Jl:]=2d;>jDi +;\`2-:f'q_:/";S8P)HC7R][/5sR\"r]C->#rXXu2`k>s(DCFrb2=G#\n-kD/F0.Df5Mls)A!Xs)A!V"`\R'F)uC#Es-W/GBeE3H38M?H[>[< +s*OisJGDA-;?0YG;ui9aQiWVDrgOIhSXl@DT:hjNTq\]DfJC^&PhG^]2+)<%G&NWiE%sVl-DgUnjc[TqJ$LSt2C@R[KP1Q^3o%P`q8nOcYWbNfB!V +Mi.Lj!f2VereCH,s+L<&r.=`qr.=j!s+LE+reCH.!/UW2!K)g7N+J!/O,oBbP*;,qQ'Rc(R@9V8 +SXuFGTq\ +hVd>NioB+]k2tjjl0@U$m-X3.n*fc9rpg-^o^r.U!quB_rV6EgrqcNhrqu]mo)=4?YQ'+~> +JcC<$JcFF'o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nf.,gn*]T0m-Es$ki_*ijQ#7Xi83;Fg=b-1 +aiXG$$HgQ8bg4_ee_&[6ro!h8"6/;!iqSB-MY)c!M?&M%MZ1Bj_#D.N_ScAkrl+lVprEES#04a& +`Pf^4r5&EFr4;d9rj_d7rO;j:q7-F5q6g:2rj)U1ricI*Y,qRhq*b3Nr^QlW+dJR8E-$,EH?ssi +K8#5CO-5TeQ'du2TVJ6XVPpPtZaI@A]`,MC]_T2=]_]8=]`5V?])923]E,^[otULArP&?Jo>14= +q8<3Mrl+cSs2Y)XqSrTWrlOrXqoa0'`l,[-]Xk\b[^WcU\$EEAWM?2[T:D:8Q'7AmOGo$PKn"T" +H[:":VPBr]Tq.ZrF.8l.[]#aZG*8PWQtes*A:/BBFao4,>Yn4WIY!<6OI)H0T2/9W9ib7m;0\e0 +VN$UsOd)0!R[fq>T:r-ZW2m&&Y-7K%\,ZAgs,d9#rPefVs2Y/\rlP&[qoS3G!m-aprg4(]R[T_8 +S=Q4BStD\TT`Lm_rhKpuVPg>jW2ZesX/i?$XTYf1YHY7ts6mf(_#(tE_#;#%XK/A$WMl_lV50o^ +U7n9RSt;LCS"#k7R$X,(Q'@JqP*(ieO,f3YN/NRNM2@%EL]3&.L&Zi(KDgDqJc12uKE$W)L&Qi, +LB*/0M.MR&N/WaVO,oBbP*2#nQ'IZ&R$jD4S=Q7DTV8*TUnsueW2cl!Xfek3Z*UdE[^WcW]"G_j +^VI_'`5Ta:aN;WKc-FY^dF-Oof%8O,g=tE=hV[8LioB([jlYail07L!m-O--rpKmWnc&([oCW"S +!quB_rV6EgrqcQirVZTloDX=@YQ'+~> +JcC<$JcFF'o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nepuen*]T0m-Es$ki_*ijQ#7Xi83;Fg=b-1 +rKd8G"IPXISXo\Ns.K=a!,V7DoPF2;mr%c^!1!AG!L8oHQ2R$JQ2[$JQ._2pNW5"ANJrjVMuJS8 +Ll$rd6hs.L7K,dU7j2qu>?tQB@:/9LPq+PrfHu=rK-`6!g&J( +qi:Q7oT8s4rf[2Aqi^rBrK7/Eo9As6qj-oAs-NeQr0[AJrgTOsPlI$HQKFP0Q2m9N +Qj]=NR[]e:SXl@DT:l1W!MZ@gU^O#rVl-JlWN)u!X/u<&"Knr3Yd!KoglX:lX/`2!W2HMhUnjc[ +TqS-NSt2C@S!ob4Q^3o%P`q8nOcYWbNfB!VMi*CKM26tCreCH,s+L<&rIX`orIXs"s+LE+reCH. +!/UW2AVuD)N/`jYO-#KeP*;,qQ'Rf)R@9V8SXuIHTq\aihlPcHjkbdaZdtf@S^0gYCWAhr*GPj5]4^k3(sml0@U$m-X6?mfDqJrpg*]o_nFa +p@n=[q#C0hqY^6hr;?Nbrdk*Qs*t~> +JcC<$JcFF'o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nf72hn*]T0m-Es$ki_*ijQ#7Xi83;Fg=b-1 +;,L0h:]F2h9`\!brDNYo!)i_lr_iPR!'L-AoK;J'pce^Sr(m>frD3Dh!)NSjr)*Gis%iSi!`;in +r)*Jpr`/ttlVdd_qGmMoqc!>jqc!G\q*b3Nr^QlW!^8k2r]19G4?Yeg5!(h)5Q=%Z6UaL67nH3@ +7S?BK9MPC[qbH!Dnkf9^!)WMfr_NSjr_3Afo2#6[q+pi^!DcPh;?'Pj;#jGk:]=2d;>jDm;]J\3 +:JOY\9hJ#N84uNF7R]a15sRUq4?GVb3&`hr2-2[n1c$mD1bpjQ5<_7o4ZYSg5<_:r4?GM[3&`]K +2^KCj-8%&1/i#@G1c@6V1c@*;ZB\J;ur;Org4(]R[T_8S=Q4BStD\TT`Lm_rhKpuVPg>jW2ZesX/i?$XTu#4YHY7@\[hXL +s1AaihlPcHjkbdaZdtf@S^0gYCWAhr*GP +j5]4^k3(sml0@U$m-X6?mfDqJrpg*]o_nFap@n=[q#C0hqY^6hr;?Nbrdk*Qs*t~> +JcC<$JcFF'o`"gfrqu]ks8)ckrV-Tkp@e1Po^i(Q)tEFdn*]Q/lg!`ukN:mej5T"ThVHu@g=Y$" +ans-laihoOc-Xqhf%]!;iSieTio9"rMY;o,MY)beMZ(9i_#;(M_ScAks2FuWouI*P"NAC!_nu;e +pq#h&oXOn0rjMj5#-kJ(1rBpBKrC-`Ur'r0$SSiCeFED_RI"6d$M2[OXP*;/tR%'_@TqeEZ +Vl-W%ZaRKY]=Y_gqRc^=rOW*C]D]AB]D9&9]CWZ;]tV7spV6^CrP&?Jo>14=q8<3Mrl+cSs2Y)X +qoA`XrlOrX$H^?/`594#]=GJ^rjFr!['I!>WMH>`SXc+7Pa7GoNfT'TLkC;/I=-EhVkp/^U7e$D +G&j4PWN;k_O)p&DI>Cs,96,>UEI3M%r_P+BI=[00Ng,s%TV#"V92&,^<)cbOTr"TFO-#QjQ^O;4 +SXuFHVP^;mY-"o!YdON-Onlur`rF*VaS3gCa:X]'QC!u+R@0M5S"-%?St;RIrh0[nUSO]^VP^8h +W2]cr!NW=$XTGZ/YPtcms7!l%_#M7G_#M.rXK/A$WMl_mVPU)aU7n9RT:VXFS"#k7R$a5+Q'@Jq +P*(ieO,f5!N!>2tM2@%EL]3&.L&Zi(KDgDoJc:9!KE$W)L&Qi,LB*/0M/S90N/WaVO,oBbP*2#n +Q'Rc(R$jG5S=Z=ETqS3VUnsueWN*##Xfen4ZEppG[^WfX]=bhl^VRe)`5Ta;aND]Mc-FY_dF6Uq +f%8R-g=tE=hV[8MioB(\k2tjjl07L!m-O--n*fc8nac8BoCW%Ts7ZKerV6Egs8)WirVZWmo)=4? +YlB4~> +JcC<$JcFF'o`"gfrqu]ks8)ckrV-Tkp@e1Po^i(Q)Y*=cn*]Q/lg!`ukN:mej5T"ThVHu@g=Y#D +rg*GJ#+1aDR@9Y:r1F"^s.KFerG2@Jqec@Ls)%CEokjA>s)%dRrKI;GplkcDqNh#DqNh,G!0mDH +duOEes,7/>Mi!7HM2;*tq*b0Ms$loV,'A09?!L`D@:E_ZBPD:#EcQ8FG'J=]IXcp#KS,#7Ll..N +qiUi=p5]9:O,s0uqiCB2qiUi?rK6u?rfd;D!0d#=p6GN@op>]Gs-NYNr0RDMpmEIrR@';)P*(ie +NK0!XN/EFJLkL>.I!U![F`hbEE,TN,BP:sf@UT1B86g[pI=-?dGB7;'H[^HnH#mh/BQ%3e5smk; +>XMOuASX_*7n@#tB52:%F*)\Q84Z3>7nlZN8o&g&IV`nuQ^F/.S"#q>StD^MU84T]Vl-MoX/rG+YctF> +['d?O\[f>b]t_=u_Sa=2`lQ6DbKS5VcdC.heCE.%f\,!5gtgiEi8N\Uj5oFckNM0plKdg'mI'H3 +nF5u=o(2JFrq6 +JcC<$JcFF'o`"gfrqu]ks8)ckrV-Tkp@e1Po^i(Q*:`Oen*]Q/lg!`ukN:mej5T"ThVHu@g=Y"T +;,I6fs%`Me"AVcj;H!Km!)i_l!)iJOrB1*CoK;;"s$$EYpeUW\r_`Ge!)`_nqbd;mr`/ttku7R\ +qGmMos&8hpr)j3:ejh^9M7rM8P2ND +8ju0:5X.Ru4ZYVd3]K)XrAO[4!];ekr\H2_5X.Lt5!1ka5X7P!5k%D4$?#*9M.K55uQ^F/.S"#q>StD^MU84T]Vl-MoX/rG+YctF> +['d?O\[f>b]t_=u_Sa=2`lQ6DbKS5VcdC.heCE.%f\,!5gtgiEi8N\Uj5oFckNM0plKdg'mI'H3 +nF5u=o(2JFrq6 +JcC<$JcFC&o`"jgrVZTjs7u`krV.W3p@e1Po^qbGo'u5]DK5@]D/u9]CWZ;]tV7spV6O>o>11Z[C?HLkpnEMMd=NN/`jYO-#KeP*;/rQC!u,R[]e;St;UK +TqeEZVPgAlWiN8(YHY:;Za@0L\@K2_]Y;.r_8=+/`Q-'Ab0/#ScHstee'uq"f@\g2gYL]Bi8ESR +j5f=ak3(sml0@U$m-X60n*olHncJFTo`"O`p&Ojcq#:*hqYU0hr;?Nardk*Ss*t~> +JcC<$JcFC&o`"jgrVZTjs7u`krV.]5p@e1Po^qbGo'u5 +JcC<$JcFC&o`"jgrVZTjs7u`krV.c7p@e1Po^qbGo'u5WKN4755o4TS>TpeU`_s%iVjr_`Mgs&&bnqb[>iqH!Sqr)DoZ +s&Anrqc*GkrBpBKr^HfUr($cX!Bi^H3WV6&r]M#Z4Zb_g5!M;"6:"".7R]m>84Q0A9MGC[nk]9^ +mSE@Lr_`\lqbR2f!)NPgo2#6[peUc^!DcP^;#jGk:]=2h;#jGk:/st\8kM`K8P2NC6q'F,5sROr +4Zkhf3B9#W3&NTM1c$sE0/5+85X7Ou5!;%i3Bo_n5!D%h3&W]Q1bUF%*@WKo/hJh93&!3J1Gq*O +3]oYn6UN^frAb*H4?GYd92%tW57p.J6UF1/7Rp!>7nH9F8kViPnkT3r!+btn?!+u4Cs(DIJ +C2Vh^VI\&_o9U8aN;TJbg+M\dF-Lne^rF*g=k<;h;7)JiSrnYjlY^g +kiq?slg4!*mdKW6nc&(\oCV\Sp&F^cp\jmdq>^ +JcC<$JcFC&o`"gfrqu]ks8)ckrqQNf!;?Eb*;&jno'u51Zcir=u6Mu&>$M#`G2Mj]^VKTYq7uU'PE:i_M26q@Jpr/sH?aRPE,0,s +?='"DF-ro3YH4=[Men0'?tVlJCjo)uI#3hV;,MUgL5M"UR[g$K:ese[:K:=m;,W^RVP]?6Ocu#p +Q^F23SXuFGVPU2jXf\b0o!#D!rK6inrl"iUs2P)Zr5e`VmE#U6fqu6NkrUTr=s0DZT~> +JcC<$JcFC&o`"gfrqu]ks8)ckrqQNf!;?Eb*;&jno'u5r1Nq&rbV=EoP=MEr+teN`rf%nVM2@%CK7JAuH?j^X +G'%bEE,9B+BP1pg@prbPra#P-:KUXs;c6G6ARTh4Kn+SpEGJ]kAkl)[9@mPQ-mIQ2Hs1 +QiEaihlPcHjkbdaZdtf@S^0g>(N?hr*GOj5]4^k2tmll0@U$m-X6? +mfDqJrpg-^o^r.U!quB_rV6EgrqcNhrqu]mo)=4?ZN#F~> +JcC<$JcFC&o`"gfrqu]ks8)ckrqQNf!;?Eb-M6p#o'u5f;#aDm;Z'Dl;#a>k +Y:JUX[r_W&ZnPK3^s%rSgr_NSjrD)r[qb[&`qb@/f;"7B_;#O/i;Z9ED9i"PX +8kVcJ8kMWG7R]d869dh#5X.Co4$#D^2`N]T2Dd6H1c$pC1G^a@1,(Qa1++e;5&3&pmt%6-O54$5Jn9M@uA5=%R66OlOQ7Rop;7nH9E9M.uP +:%D'YAcH<;Ac-0>B)lQCBE)WIBkhF"rb_[Q!c;gmrbVXQr,2UTEr0hWEc_5&"*Sm4GlE!gGlN$j +H@(#:HiSTn4oJ=Q;ZB\Q<<&3_Pl[2;rg41`R[]e:SXl@DT:hmOU8.^`"f8)oVl6ToWWB0%riH4( +YPtd+Ym%GC\[f;_rk&0Bs1JKJ]tOEZh,H)0X/`2!W2HPjV50l\TqS-OSt2C@S!ob4R$O#&P`q8n +OcYWbNfB!VMi*CKM26qBreCH,s+L?'rdsutrdalsrIY!#s+LE+re>0CLkpnEMMmCON/`jYO-#Ke +PE_>tQC!u,R[]h*YHY: +JcC<$JcFC&o`"gfrqu]ks8)ckrqQNf!;?Eb*q]'po'u5(nC +_u7LR`W!mW`V[XTa8X-h`l5m6_7mRm]=YVa[^Q1CDR?^QYH=e"US"-JSsbt6Q'@MrO,o<[LkUJ3 +J:)WfGH,_$CLq!^?!CK7=BS[OH[M-=G]&8)Ck#2mAUI6hHA7GU;,L5@KntbPR[g$H;,0h[=&i3t +<)TBbM2dUZP*D6!QC454SY2RJVPgAmriH1(nZ]4srK6rprPe]Qs2>&Za2e(ur5nBJ*0QMMQ'IZ$ +Q^F/.R[]e:SXl@DT:hmOU8+N[V5F6i&ZD\/WiN5&Xf\b0YHY79Z*L_(s7*qt_#D(K_#D)%X/`2! +W2HPjV50o^TqS-OSt;LBS!ob4R$X,(P`q8nOcYWbNfB!VMi3ILM26tCreCH,!/19&rdt*"pji9n +rdt*$s+LE+re:W4LkpnEMMqImAW;_2O-#NfPE_>tQC+&-R[]h*YHY:< +ZaI6N\[f>b]tV7s_Sa=2`lQ6DbKS5VcdC.heCE.%f\,!5gtgiEi8N\Uj5f@bkNM0plKdg'mI'H3 +nF5uIncA@Srq6 +JcC<$JcFC&o`"gfrqu]ks8)ckrqQNf!;?Eb*;&jno'u5[:TA?t!MSAnPdmCi=<6FERS,&UAbQIY!*'KS>29LkghG +N/`tuO8b7@O8Y+7O8b4@Ont1:Oo:IBOnt7:POat4Q26g;Qi*47Q^3u(Pa%>mO-#?]NK&mVMMd7E +LP18/I!U'_GBJ%LEcQ)9CMRTrARf4Y@:*;G>_-$\<`Dsp:JOSW91qkU>o[m%@9[D`='Ia]9jC%b +?"Ie=84Z6[A8,muF*;g+8,c4&928*+I;E_:D/XH8FEM_MG^+O]H@10jJUrE)KCOZp_Z.OP`;dgR +`qd[Ta9'K+bP]Qac2Prdc2Q#fci2;kdJhSoe,Ro$e^i='f\$2V!SZ<,g]H +JcC<$JcFC&o`"gfrqu]ks8)ckrqQNf!;?Eb,4tKto'u5Ve4$Z(r5smt*7RTX784WYM#>7Z_:/4MZ:Amuf;".9M;#X>l;#=&f:]O;i:@h9Y;#!i_:&n)[ +;$'He;#X5g8cVN`8h*A'7R]d86U3t(5X.Fr4$,J`3B&rW2`3KM1GUaC1,UjE6SUDS1GU^A1&`pa +0f(XC1H.0M2)I*A.2sQZ/h\\.2*d +7n-$@8k_fM9MP%Prac%?rabn;r+>tAs(;4B"DMUdCi')f"`A0oDJa4hD>nJQE;snXE;jhaEcZ>E +F`qqPG^+N4GR&M?H@(!dH[Ga>!'^BFmns-aiD^e[PE_>tQBml)R$jD4S"-%?St;RITqS3UUnjia +rhgL0WN)u!XK8P+Y-5%5Yd(I=ZadNV])92?]E#YE]`,SE^@>2%;t*a>X/`2!W2HPjV50o^TqS-O +St;LBS!ob4R$X,(P`q8nOcYWbNfB!VMi3ILM26tCreCH,!/19&rdt*"pji9nrdt*$s+LE+re:W4 +LkpnEMMqImAW;_2O-#NfPE_>tQC+&-R[]h*YHY:b]tV7s +_Sa=2`lQ6DbKS5VcdC.heCE.%f\,!5gtgiEi8N\Uj5f@bkNM0plKdg'mI'H3nF5uIncA@Srq6 +JcC<$JcF@%p&=pgrqu]ks8)ckrqQNf!;?Eb)t`amo'u5#ZqoA]U +!Q;nT_YM%J]DfDA]DfD>]CWW&\H04NrjE'=Za6m@YX:eR7/fXS7f5dU8H29[8g$cnO`#,ZF*DhS +I!pKmJ:rc:N006eQ'Rc(S=Q4CU7n=[V$EotWj/q<\%)CM!5/*_",>:_YM+J +`;ddV`rR$jA+rfRePNK/mPKnP#*H[0gY +Wi)fpU^='/UOrI"Ql3dZ=(8nWKB96PoG:Jt%eIY/[`Q#pVg^V@V%_o9U8aN;TJbg+M\dF-Lne^i@)g=k<;h;7&IiSrnYjlY^gkiq?slg4!*mdKW6 +naZ2@oCMVRp&Facp\jmeq>^ +JcC<$JcF@%p&=pgrqu]ks8)ckrqQNf!;?Eb*;&jno'u5\;BD>KIkPl$aFQN!6GQM-UDQM6I?OSk16NrP13Nr+eCN/NXP +M2@"CL-n?(7/fXS7f5dU8H29[8hE\ZF'DjT?=72N@V'.aBkqR%Df^#DG'A1VH[U,8 +LkpnHN/`p\rK$u=q2bN:rfR,?qiUi?rfR&?q31B6q3C`@ns;G(Q'IPrOcYWbNK&sWNJi[NMMHq@ +KRnW#I!L!]F`_\GE,]]2CMINrARo:Y?=$oB>_.HUIXQTiG]mWs9`Ia-?!^fB?=.)I?X7&H4A]9I +6<[i577g$@?tqLP +`;[aR`r=!Y`r3sXa8sE*rlbJfbfn90bl5ldcMl/hd/MGmdK%bqeGe%uf`0V)gA]k*g]cHfgYCQ; +rbhForK[>Gs-*JIs-jWW&n% +X/rG*Y-+u-YQV5:ZEpn,s4rejXK/A$WMl_lV50o^U7n9QSt;LCS"#h5R$X,(Q'@JqOcYWbNfB$W +N/NRMM26tCreCH,s+L?'rdt*"p43*mrdt*$s+LE+re:H/M#N6LMMmFPNK0'\OHG]hPE_>tQ^F/. +S"#q>StD^MU84T^Vl-MoX/rG+YctF>['d?P\[oDc]t_=u_Sa@3a2lBFbKS8Wd*^:jeCE.%f\5'6 +h;-rFi8N\UjQ5OdkNM0plKdg'mI'H3nF?&>o(2JFrq6 +JcC<$JcF@%p&=pgrqu]ks8)ckrqQNf!;?Eb)t`amo'u5n>rFGb9rFQ%BrFZ%A!GH6HD#.uKD#S;ODZaruE,bbqs)J*\rcJ-_rHJr]TsQq,@;ks&7uXs,mDHPl?pSQC!u+R@9V7S=TYN%A0;eTq\kWiN5'Y->.9Za@-K\@K2_]Y2(p_8=+/`Q-'Ab0/#S +cHstee'uq!f@\g2gYL]Bhr*JQj5f=ak3(sml0@U$m-X60n*ol;o()DDo`"O`pAamcq#C0iqYU0g +r;HTbrdk*Us*t~> +JcC<$JcF@%o`"jgrqu]ks8)ckrV-Tkp@e1Po^i(Q(@gn_n*TK.lg!`ukN:mej5T"ShVHu@r5eo[ +qoB/eb0/#Rd*pOugkq$cN:Mo+MY)c&MYN,.MYrD._#;(L_u@UR`W!mVa8X0Wa8X'[`Pf[n_YCt: +]CNQ(\HKFO\$`[DZi@<16hs.L7K,dS8,c'Z8c;9]9E.[=S8E1_EcZDLH$k!gIt<'&M2R@VPa%Gu +QBmu1StDUITq\B[VPg>lX0T+?[(!TUqmua(nC_u7MM`Q#d3_8=%& +]tV%d\\#G_[^WWMZE^["MrdQSMIt3*#J:iZ;OI;T2;G^2@JqAQ,L4tJBMkc>oOHPinQC454 +SY)LJVl$DmYH>"oYc[s*On6Kk`V[UR`W*sWa8tQC!u+R@9V7S=Q7CT:hmO +U8"EYUnsrdVl6SpWiN5&Xf\b0ricI/ZEjJ9nGi$prP8?Gr4r9Gs1Tq_WiE%sVl-DgUnaZXTqJ$L +SXc1=R[KP0QBd`"PEM)kOH5H_NJrgSMZ/G5Lkktas+UK+rIb*$rdjZkrdk'#rIb-'s+UH,!JcL1 +M.qj*N/WaVO,oBbP*2#nQ'Rc(R$sM6SXuFGTqS6WV5C/hWN*#$Xfnt6ZEppH[^`lZ]Y(tn^qmn+ +`Q#s>aihlPcHjkbdaZdsf@S^0g>(N?hr*GOj5]4^k2tmll0@U$m-X6/n*fc9rpg-^o^r.Us7QHe +rV6Bfs8)Wirqu]mo)=4?[/YX~> +JcC<$JcF@%o`"jgrqu]ks8)ckrV-Tkp@e1Po^i(Q(@gn_n*TK.lg!`ukN:mej5T"ShVHu@rg<;D +"dk^HS=Z>CCB&)CD#A)ED#/#EDYS)EPPLI?Q2[*KQhZm@Q2Hs@O8P+$G<=?=./O@q91bBPVF$Dfg/HG'A.TH[UBlIt<0&K7s5Ys+gl: +N/`dUOHKC#rfI#>s,d,?rK@/BqNCW;o9B'9pm1iE8sYa.P`q8mP)tcdO,f3[NK&mSM26tCKnb53 +J:2imH$OXYG&q\CE,KK.CM@HoA7]4[@U35C>ChtQC!u+R@9V7S=Q7CT:hmOU8"EYUnsrdVl6SpWiN5&Xf\b0 +ricI/ZEjJ9nGh=,.BBJKWMl_mVPU)`U7n9RT:VUDS"#k7R$X,(Q'@JqP*(ieO,f3YN/NSmM#iEf +reCH,s+L?'rdt-#o76gkrdt*$s+LE+re:H/M#N6FMMmFPNK0'\OHG]hPE_>uQ^F//S"#t?StMdN +USO``Vl6SpX0&M-Yd(L?['mEQ\[oGd^;%J"_SjF5a2lBGbK\>Yd*^:keCE1&g"P08h;-uHi8N_V +jQ5Odkiq?slg4!*mdBQ4nF?MK!qZ'Vrq6 +JcC<$JcF@%o`"jgrqu]ks8)ckrV-Tkp@e1Po^i(Q(@gn_n*TK.lg!`ukN:mej5T"ShVHu@rDW_o +!Du\m:]F2g9a=Eh:f1+h4?W0tq*+Rl;#=&e;#F,e;#*ob;"m`e:/=[a:'FEj:/F\]r_=/( +9hS,Q91hiL8k;ND7Ros<6:4(+r]q2^4Zkef3B0&[3]B#X1GpsF1bgfb1_N/A5tQC!u+R@9V7S=Q7CT:hmOU8"EYUnsrdVl6SpWiN5& +Xf\b0ricI/ZEjJ9s1/0@rO`*@rk&0B!57o%pf$lc.BBJKWMl_mVPU)`U7n9RT:VUDS"#k7R$X,( +Q'@JqP*(ieO,f3YN/NSmM#iEfreCH,s+L?'rdt-#o76gkrdt*$s+LE+re:H/M#N6FMMmFPNK0'\ +OHG]hPE_>uQ^F//S"#t?StMdNUSO``Vl6SpX0&M-Yd(L?['mEQ\[oGd^;%J"_SjF5a2lBGbK\>Y +d*^:keCE1&g"P08h;-uHi8N_VjQ5Odkiq?slg4!*mdBQ4nF?MK!qZ'Vrq6 +JcC<$JcF@%o`"jgrVZTjs7u`krV.N0p@e1Po^h\Fo'u53MYi51M#E2-MXcT+^qmkb_#D1M_>qLQ`;[aT`r=$XaSX$W +`WX9!_o'@b_="r(](ifD\@8rU['d(nG_[OK#^Vdn']t:nd\%'!J\Gip.[Bd*BZ*1=1XfJ=pU7e0OSsu4:Q^=#'PEV,lO,f0TLkUJ3 +IsQEbG'%]%VPL#\TV%a@F)7>A\$WH3PDj=6S:#Qd7<<0kIt@TK"b(rOJUr@NJH^XVJqAW+rIQ&@ +K7el3KV>3:UQ:P"PEhE!S"6(@StW'ZW2d#&YNE'lrrA2G`;dgV`rF*EaT%>TOcklkPa.N"Q^F/. +R[]e:SXuFFTV8'RUSO]^VPg>jWMuntX/rG*Y-+t4Yd(I=rj2X3o)J6rrP83C!5SNIs1\N5-E3rA +Vl$;dUnaWWTV%gISXZ+;R@'A.Q'IStP*1rhO,o<\N/W[PreUo:LPLV=KnY25rIb-%rIONirIP!# +rIb-'s+UK-s+^T1reY0CMiU6fqu-HkrUTr=s0_lW~> +JcC<$JcF@%o`"jgrVZTjs7u`krV.K/p@e1Po^h\Fo'u5J/LD$#ocPl-aBPk^OCQN!6GQ3*>;QMd$DQLKt8OSt7)NrP(= +N;\Y:M26pSq*b3Nr^QfUr^d&\rC[)_s%NGe"*]W+>5hb=?!^uK@q94aBk_@#Df9]=Fa!b.)L6^X +I=?]tJV8`0L5(J;LkpnDMiNaOH,<\ +NrG#9N/NOJM2-h?KS+i*I=6HhG^+CTF`VPCDf'B.C2%FI!][HDfKf>FEi"SH$Xgc +IXcp"K7ej?L&Ssf_Z7XQ`Vd^Ua8X*Xa8a3aaihlObKKb+rltGfrm1Vkrm:eqe'nU6fqu-HkrUTr= +s0_lW~> +JcC<$JcF@%o`"jgrVZTjs7u`krV.N0p@e1Po^h\Fo'u5O,e;?'Ji:B=9fr_W#_qc*Sq +!*9)!qc*2d!`DrqrDEV_q*b3Nr^QfUr^d&\rC[)_s%NGe*^;hJ3B0#Y3]]>_2`a#^4?Yhi4$>_k +5X@Y#6:4%*r^6fW7nl;#=&e;#F,e;#*oc;"mcc:`W;,:JO\] +:/=MV8P)QJ8k_iM8kDNC77]p<6:4%+r]plV5!;"i3]f;^3B$jrs#'m71]B3I1GgmE1c%Ha5<_7n +4$#8a4[2+p4?GP^r\Y!b9qdoP7s(;LKBkqO$C]/&LD>\2PD/O92rc.sW"`\R'F*)O' +Fo?IdGBS1TGl2jfH2`-iHiABm4oJ=O;YF&Q<<&%5OcklkPa.N"Q^F/.R[]e:SXuFFTV8'RUSO]^ +VPg>jWMuntX/rG*Y-+t4Yd(I=rj2X3!4i*?!5&0?rk&3CnPo-Zq,IBo-E3rAVl$;dUnaWWTV%gI +SXZ+;R@'A.Q'IStP*1rhO,o<\N/W[PreUo:LPLV=KnY25rIb-%rIONirIP!#rIb-'s+UK-s+^T1 +reY0CMiU6fqu-HkrUTr=s0_lW~> +JcC<$JcF@%o`"gfrqu]ks7u`krV.Q1p@e1Po^h\Fo'u5 +GBeC[I"$QqJqSf3LPh(Rrfd_TQ^=)0StVjNU&LbkTqnT`VlH\pri6"$&$`LL[C2IK"KkF%(#FVkg)]TV.mGRs/jfS=ZdjU7.0eOI(c3DG+V^H$4RUIu9;@;MpB] +JVT,CP*qf2K7JN*KM5*><10>NTqnEXO,oHfrfmq]S"6.CSu/B`WiW>*YN)jjs8U"#`;[aU`rF*H +aT%;IOHG]hPE_>tQC!u+R@9V7S=Q7CT:hmOU8+N[V5C/gW2ZesX/u<&!NrX*YQ;#7rj2X3!4DCt +o"k:?o"Y4=/uu"PWMcYkV50o^U7n6PSt;LCS!ob4R$X,(P`q8nOcYWbNfB!VMi*CKM26qBre:K. +KS9;Vs+:6$mstCgs+:3%s+CB+reCH.EeoR/MMmCON/`jYO-#KePE_>tQC+&-R[]h['d?P\[oDc]t_=u_Sa@3a2lBFbKS8Wd*^:jeCE.%f\5'6h;-rGi8N\UjQ5Od +kNM0plKdg'mI'H3nF?&>o(2JFrq6 +JcC<$JcF@%o`"gfrqu]ks7u`krV.K/p@e1Po^h\Fo'u5@(WD@:FP*>m-s,d2? +r/CrANK&mTN/[(E8It2urI!g9c +G'7D+>^:[HKR%ZV?uBsr:/X)I='Ag9=CGfXAk?fU?t*_`D/OE:G\(DsAn4G$9MB\YH[L6hHu!P; +EH6,CG'A4WH@($gIt3+LKB%[c_Yq@P`;IUP`rF*Z`r3sXaTBW.bl5fbbQ?&5bl5ldcMl/iciDJm +df.]$eCE.$f@S[.g&9V)g&B_&g&KdmPl6mDPlI$JQLL7@O!TmMP*2#nQ'IZ%R$a;1S"#q=St;RI +TqS3UUnjiaVl-JmWiE,$riH4(YPta,Z*OA8s0Md6o)IO./uu"PWMcYkV50o^U7n6PSt;LCS!ob4 +R$X,(P`q8nOcYWbNfB!VMi*CKM26qBre:K.KS9;Vs+:6$mstCgs+:3%s+CB+reCH.EeoR/MMmCO +N/`jYO-#KePE_>tQC+&-R[]h['d?P\[oDc]t_=u_Sa@3a2lBF +bKS8Wd*^:jeCE.%f\5'6h;-rGi8N\UjQ5OdkNM0plKdg'mI'H3nF?&>o(2JFrq6 +JcC<$JcF@%o`"gfrqu]ks7u`krV.N0p@e1Po^h\Fo'u5rB1*C!'L6Vs%WPipeLW\r_WSkq,%#es%rJd +"&Mch;"7Qc<;oku<)rcor`/eop/Cle!(6QMr^HfUqa^ZWs%3/]s%EAcr_e2k:/+JZ:]=)j:eFF\8d%d\91qkU8,l*]6q0ZF6kD[Q5XRk(4?bni4?GVc3&itt +3!;,u1c.)h1BB?hr\P9E5X7Ou5!;%k3B9>h4[)(q4?5D"2EiiJ-Q=?`/MT+81c@BU2aBSa2)mZY +4?l(t3B0#[1cdW]4\JIC9MA)P5X.M"6psI56q9a:77g'C9M8&R:#f"KA,9a6AbTdGB5)*rCM[d$ +CM[g(Chs#d"E&-sE,khq!HN8ZFT6L\Fp<2:H$Xd^HN&3iHN&9kI/d+B;tEo\;sRE_O!TmMP*2#n +Q'IZ%R$a;1S"#q=St;RITqS3UUnjiaVl-JmWiE,$riH4(YPta,Z*OA8s0Ms;\[f;^\bir?]=beg +nl5*WrDYDMWiE%rVl$;dUnaZXTV%gISXc1hVd>NioB+]k2tjj +l07L!m-O--n*fc9nac8BoCW%Ts7ZKerV6Egs8)WirVZTlo)=4?[f:j~> +JcC<$JcF@%o`"gfrqu]ks8)ckrqI`4p@e1Po^qbGo'u5V"H^&>VD +]`>_E]`>_A]D];@]CEK0\HTIP['?m?q*b3Nr^QcTs%*/]rC[)_s%NDds%WPir_Ol,Zu9f"EcH2F +G'\L`I=?ZsK7nr5L5M%TPa.Q#R[KS6S=lIGrh'apUSFQZVP^8iW2ZetWiQ-#s/l:(s0)X2Za-mD +os=V)!joAErjMg5!42[1s0Dd6[C#q@s0Mj4Za9V9s0+#YYc=V!Wi2kkTqJ-QT:VL>Q^!c#P`q;n +OH>K^Mi*CHL4t/.IXH?`E,fdpV*^lKT:VU@RWrdfS#*Hf]!@rpNcKl8JT"pdF)-8"DgR1tMG$j) +H[gd.Nff]uTV.d?:/4MW2tM2@%E +L]3#0KnP-XKE$Q&JaS'fJcC?#KE$T)L&Qi,LBNEiM2I5jN+@p.O-#KeP*;,qQC!u+R@B\9St;RJ +TqeEZVPgAlWiN8(YHY:;Za@0L\@K2`]Y;.r_8=.0`lH0BbKJ/Ucd:(feC<%#f@em3gtgfDi8ESS +j5f=ak3)!nlKdg'mHs?1n*olHncJFTo`"O`pAamcq#C0iqYU0gr;HTbrdk*Xs*t~> +JcC<$JcF@%o`"gfrqu]ks8)ckrqI`4p@e1Po^qbGo'u5\5BPlI$JQMd$HQN!6DQN*6AQKF5.OSk1/NrP(@MM[1F +q*b3Nr^QcTs%*/]rC[)_s%NDds%WPir_NuGMHX.f>[C`E@:E^FA,g0@B`DiYD/O<5FEMbNH$FU] +I!pHmrI5'&K7SZ/L4tB[L]*#7M26tFM2I.IN;\b4Nr+h4NW>((=atmJI!^3cG]e.> +?sJ#+Km\Z*G&hG(Bkq0[8NBgJ?UIgu@VTRD7r2RCASZ.$F*)\QF`U&D7n-3IDL?eXI=-EXDJa?4 +EccGJG'S=YH[L9lJ:N6(KAM=]_uI[Q`VdaT`rO-X`rO3Zb5TT`bl5lec2c,gcMl,kd*^8?df.\s +eCE+Kf)s[Yg"QDXqq1o$s4Z@prg!MLns;+lO,oBbP*2#nQ'IZ%R$a;1S"#q=St;RITqS3VUnsrd +Vl6PnWiE,$Xf\b0YHY79ZEjJ9!joACo)IO.s/I6AW2HPiUnjc[TqS-NSt2C@S!fY2Q^3o%P`q8m +OH5H_NW+k@Mi*@JLkpicL'!'^K`-Q'K)U>hJGt-"K)L?%KE-`*LB!#3Ll$tGMuJZGNK0']Ocklk +Pa.Q$R$a;2S"-(AT:qsRUnjlcW2ZetXf\e2Z*L^C[^N]V]"G\i^VI\&`5Ta:aN;WKc-FY^dF-Oo +e^rF+g=k?^ +JcC<$JcF@%o`"gfrqu]ks8)ckrqI`4p@e1Po^qbGo'u58c)-Y9DV?^:&n#d:AI]^:*`V09MJ2U:/+DS91qfK +8kDWJ9M8#N8Ol6A84c\3''#X2`nm5J]2)[NfT6_OcklkPa.N"Q^F/.R[]e:SXuFF +TV8'RUnjiaVl-JlWN)u!XKAV-YHP17Z*L\7ZN@MA[Jm]@]",A_]=PTP])]D4<:s/i<;fbo<<&sA +WMl_mV50o^U7n9RSt;LCS"#h5R$X,(Q'@JqOcYWbNfF$s#)e@qM26tCre:K.KS9;Vs+:6$mXY:f +s+:3%s+CB+reCH."GhnkMMqImA;uV1OHG]hPE_>uQ^F/.S"#q>StD^MUSO]_Vl6SpX0&M-Yd(L? +['mEQ\[oGd^;%J"_SjF5a2lBGbK\>Yd*^:keCE1&g"P08h;-uHi8N_VjQ5OdkNV6rlg4!*mI'H3 +nF?MK!qZ'Vrq6 +JcC<$JcF@%o`"gfrqu]ks8)ckrqI]3p@e1Po^qbGo'u5h:N +^\tkJ]tV5Y^&5VE^&PbB]D]>=\H0:Pr4;g:"h2"M[^EL<7/fXS7f5dU8H29[9)hQa9`@cd:&n)h +;#aBP;H)tID/O?6FEMeNGC+U\I=?`uJqSi4L5:kMO->lsQ^XA4S=H1AStVjNTqS6UUSFW^V5L8j +VuEOsVlQkuWiZ0$s/u7&s0)L.r3-1)ricU3ZEpjAZ*4/2s0!HGYdCgFXf&+oVPpAfU7n6QStMO< +Q^F&'QBm`!P5^PZO,f0TLl$q?KS+o,IslWcF`MA8VPU#\St2=:QZd=`R\@?mZD3kPN,k#>Q[Na[ +1es+:3%s+CB+re>-BLkpnEMMmFP +NK0'\OHG]hPE_>uQ^F20S"#t?StMdOUSO``Vl6VqXKAY/Yd(O@[C3QT\\#Mf^;%J#_o0O6aN2NI +bg"GZdF$Fme^i@)g"P39h;7&IiSrnXjQ5Oekiq?slg4!*mf)YUnF?MK!qZ'Vrq-?dp\4X]s7uZj +qtp?irVc +JcC<$JcF@%o`"gfrqu]ks8)ckrqIQ/p@e1Po^qbGo'u5,5re:T1LPL\AL\Zc$M>W82M$AcnMM[.FL]3*FLPCS? +Lkgb?K7ec,JV&B"I=$$+jUI=6KgGBS(L +A7&SeI#*3%H$!t??#==o?r]ca4&K'b>?>3ECh?7>D.7!gCi+06G'\@Sr^R\m9MAc?H[L6hHu!S: +EH-)CF`qtSH2`*mI"-WrJc:;eL&\OYFS:Ci_o0Lk`V[XVa2Z-ua8a6Zb5TT`bl,fdcMu2jcMl/h +dJhSne,Ro(e^i='f\+s1f[p&R!8%5&rn.;*gm%i(s-E;D.#j7JO-#KeP*;,qQ'Rc(R$jD4S"-%@ +T:hmOU8+N[V5C/gW2ZesX/u<&#-P/6Yd(I=rj2X3s0Vj8o`*a0s/ITKW2HPjV50l\TqS-OSt2C@ +S!ob4Q^3o%P`q8nOcYWbNfB!VMi*@JLkpicL'!'^K`-Q'K)U>gJGt-"K)L?%KE-`*L1uF!Ll$tG +MiU6fqu-HkrUTr=s0r#Y~> +JcC<$JcF@%o`"gfrqu]ks8)ckrqI]3p@e1Po^qbGo'u5h:]OAi;"[W_;#=;i +M4$#Ga4$>\j5sX8-):Qr^d)\r^m2a9);3X9E@d[ +r(@Sn91qfF84Z5^\Z:AeZ"Abfp>B4u&Y +C]A/KC]8,MD>nGQE;a_TE<:0&FT-@\F9$I_G5ZXdH$K12s*FZk!IRi0;ZBVj;ZB\b<%*`dO,oBb +P*2#nQ'IZ%R$a;1S"#q=StD[LTq\ +JcC<$JcF@%o`"gfrqu]ks8)ckrqQNf!;?Eb*VAsoo'u5h=H^\Y\E^\PSF]tD#T]DfD@\c98@]DfDA\H'/=\,Wf8Zhd)h7K,dR8,l-[8c;9]9E.]b:&dug +:]=0C;,U:j;cK$(QY^PZEHH;GGBeIZH[:-jJUrE)KS>/8LkpqKOHG`kQ'n)/R[p&KT*h6`T:qpN +T:qsSV>[:iVuEXnWVrh0WN)qtX/rJ0YcOk(W2HSmVl$aN4A$q8b+GNK0'\OHG]iPa.N"Q^F/.R[]e;St;RITqS3UUnjia +Vl-JmWiE,$Xf\b0ricI/ZEjJ9"LPSE[^Pi.o>1C@n\>+.9Za@-K\@K2_]Y2(p_8=+/`Q-'Ab0/#S +cHstee'uq!f@\g2gYL]Bhr*JQj5f=ak3(sml0@U$m-X60n*oi:o()DDo`"O`pAamcq#C0hqYU0h +r;?Nardk*Zs*t~> +JcC<$JcF@%o`"gfrqu]ks8)ckrqQNf!;?Eb)"dFjo'u5B +rf@,@rfI/Br/^u@OHAmkr/U`8!fMqnqF($5-8>[(N@?X[DQA7K.]AnYmnC27[(DZ4VTEs6]0G'J7WrHeKk!e#NHrdP*%JUrE)Jc:8tKDL6* +KnP/5Knb?]LBE9aJqO#Q!.t)urd=ipH$K:3(NaeAF)l;@E,TZ4DJX0+C1qL`@fBau?X6r@ +>$5!0IXQZmH?a[VF(AT^H$kEqJU)&f[naSf_a>)g6@heQ/7c*Q1U@nN/`jYO-#KePE_>t +QC!u+R@9V7SXuFFTV8'RUSO]^VPg>jWN)u!XKAV-YPta-Z*L\7ZNRYC[C3O9s4regWi;qpVl$;d +UnXQVTV%gHS=?":R@'>,Q'IStP*1rhO,o<\N/W[PM2@%EL]3#0KnP-XKE$Q'Ja.dcJcC?#KE$T) +L&Qf-LPYqdDMj@2N/`jYO-#KePE_>tQC+&-R[]h['d?P\[oDc +]t_=u_Sa@3a2lBFbKS8Wd*^:jeCE.%f\5'6h;-rFi8N\UjQ5OdkNM0plKdg'mI'H3nF5u=o(2JF +rq6 +JcC<$JcF@%o`"gfrqu]ks8)ckrqQNf!;?Eb-hR$$o'u5!`f;,C%b +pJ:]`r)Nbts&Jtr!)rkrlVdmb;c?Zk;uT\k7/fXS7f,^U8H29[9)hQa9`@cd:B+,h:`iP4;H$Ln +5;,)W2)dKS2`NcW3]T5]3]fDc4Zkeg4$!:%!BiOD56=):5lFrCHlWs%*,Z% +7W`R779O4779O26pa3=6iTOX6UF+)5=594*BcMI3BB,[4#o>`3B9,[2DmBN1c.'I2`!9H1c7/i1 +f6%n5X.Lu4ZYYc5X%=q4[)"k3]T,U2)I0E/Lqq`,qUW$0K(R>2)mZP2EsGb2`j/c5X@b)76!:g3 +BoYj7SHEJ92%W95X@e+77B^87Rom;r^[2b9M8&R:$>@N=o^b_5P\(PAGg$:Ad`6`AnPdlCMR[#C +23``rbMROrbhaS!,hdSs)A-]F)uC$F8g:[G5HLcH$FT4H2i3iHN8Hk;sI9X;>sJn;ttQC!u+R@9V7SXuFFTV8'RUSO]^VPg>jWN)u!XKAV-YPta-Z*L\7ZN[_D[C3NQrji$>" +hV@U[^ER1<;TVh<%P&KW2HPjV50o]TqS-OSt2C@S!ob4Q^3o%P`q8nOcYWbNfB!VMi*@JLkpicL +'!'^K`-Q'K)^DeJH(3#K)L?%KE-`*L&m'creYNMMihV[8MioB+]k +2tjjl07L!m-O--n*fc8nac8BoCW%Ts7ZKerV6EgrqcNhrqu]mo)=4?\Gq'~> +JcC<$JcF@%o`"gfrqu]ks8)ckrqQNf!;?Eb(\I=io'u5V@ +^&bp[qn)d;r4<0E\[T#T['TWtr^HfUqa^ZWs%3/]s%EAcrCm>g:J^sd!`;inr_kdUSXuFGrLj4cr1O"^s.]Xk +USIg_!i)H^rgsLgT:VUES!f\2Qi<:sP`qAsPEM#gP*(c`NfB!WMi!CMM26q?L4b&-IXQTjG'.eC +E,TWiUnscXSt)=?QBuW0B:>?qYH41WNHV1ZQ?RI]8o/V1=^F6grWMl_mVPU)aUS=HTT:VXFS"#k7R$a5*Q'@JqP*(ieO,f3YN/NSm +M#iEfre:K.KS9;Vs+:9%q1/9jq1/Krs+:3%!ec8]re>9FLl$tGMMmFPNK0'\OcklkPa.N#R$a;2 +S"-(AT:qsRUnjlcW2ZetXf\e2Z*L^C[^WcW]"G\i^VI_'`5Ta:aN;WKc-FY^dF-Oof%8O,g=k?< +h;@/KiT&tZjlY^gl07L!m-O-,mdKW6nc&(\oCV\Sp&Facp\jmeq>^ +JcC<$JcF@%o`"gfrqu]ks8)ckrqQNf!;?Eb(\I=io'u5eAID>'4eQ2?mBQNWV@Q^4!-QMm'KP4k%:OT1I8ORS;3NfF$rs,-\Ar^HfU +qa^ZWs%3/]s%EAcrCm>g:J^sd!`;inr_j,&=BJ^0>5h_1>[C]C?t*RDA,g'AAS5Ufrb2^T +D/O60DfB]9F*.D)s*"HgrceTlH[:!bI/SKnHiSTjI/A?hI/eKmH2`'gH2i'iG'.s+F96K&ErKtZ +DJa9.rbMOJs(D@CBOk[b@prbR?=$lB>$+j,=FP^HI!^0aG^":O@U3/_HA$cqF`D5*Hu!S(=\CeR +<*3Eo='T3JChH1088VdGAnc("EclVPG"G4p7n-0G94rU"I=-E[DK'T9F`qqPGBnI]H@13mJV*lR +k(WiArj2[3rc8!ZqfMdj!iMp6r5JHNs2Y/\!6P5_rQG2arltJg!6tMgrm1Vk!7CeormLr!f%0fO +!S5g#f)=5#f`Km[f`'P(g=VYhQ1pUEN$aOEO,oBbP*;,qQ'Rc(R$jD4S=Q7CT:hmOU84T]VPg>j +WN)u!XT#=+Y-5(6Z*CV6Zi@B4[JmW,s5&kcWi;qpVl$;dUnaZXTV%gISXZ+;R@'A.Q'IStP*1rh +O,o<\N/W[PreUZ3L]3#0KnP-XKE$Q'JbailJ,+WpJcC?#K*$^[L&QgDLPUeDMMd=NN/`jYO-,Tg +PE_>tQ^F/.S"#q>StD^MUSO]_Vl6SpX0&M-Yd(L?['mHR\[oGd^;%J#_SjF5a2lBGbK\>Yd*^:k +eCN7'g"P08h;-uHi8N_VjQ5OdkNV6rlg4!*mI'H3nF?MK!qZ'Vrq6 +JcC<$JcF@%o`"gfrqu]ks8)ckrqQNf!;?Eb(\I=io'u5sAl:[pRC4o7A83rhDA4nh,A4[)(,4TI\C4TJ=W:Adob:ARc`;#X>d;#aDl:]O;j;#3ub +:]aZtg:J^sd!`;inr_jD.J]1c@EP +1+b""*%!6g0eY(11c@BU1,h0W1c@3P4Zu"q6:=:&3]K,[5<_4u9h\5R9Kka.6psI47n#m;7S$$@ +7nZNK9MJ7D:A\5o56*nC5Q+=XVl'H(qdfe@B)H9EBPD0rC]%rIC]8/MD>\;ODZFbUEW1"XF8p=^ +FoHOdGBe@VrcnBeqg/9h!.=T@p/:feqbmDjr_N_p;GpFloMkjL-B4%HO-#KePE_>tQC!u+R@9V8 +SXuFFTV8'RUnjiaVl-JmWiE,$riHC-YHY79Z*OA8s0Md6rjMj:rOE-D\@&]O\%([%s&8kq!*/ts +-`X/EVl-DgUnjc[TqJ$LSt2@?R[KP1Q^*i#PEM)kOH5H_NJrgSMZ/G5Lkkta!el;\rIb-%s+0ur +q1&3js+13%rIY0)Kn]M\D23q(M2I1KN/WaVO,oEdP*;,qQ'[l*R@B\9St;RJTqeEZVPgAlWiN8( +YHY:;Za@0M\@K2`]Y;.r_SX71`lH0BbKJ/Ucd:(feC<($f@em3gtgfDi8ESSj5f=ak3)!nlKdg' +mHs?1n*olHncJFTo`"O`pAamcq#C0iqYU0gr;HTbrdk*Zs*t~> +JcC<$JcF@%o`"gfrqu]ks8)ckrqQNf!;?Eb)>*Oko'u5#s2k8]m>L(`k_fG[ou-XE!64rWp;dEX`lH*;_u@OF_$7]i^V7Cs^uiE/^AknH]`#JB])B8@ +\H9:L[eiJl7K,dR8,l-[8c;9]9E.]a9`e'c:]=/l;,U4LI=HctJV/Q.LPUbCr/1W8NK!js!K`HCP5UUAPQ6p?PR3\\=U@jWN)u!XKAV-YPta3Z*L[AZa@*I[JdQ-s8Be4_#2%I_"5>=^+64_ +Vl-DgUnjc[TqJ$LSt2C@R[KP1Q^3o%PEM)kOH5H_NJrgSMMd7ILkktas+LH+rIb-%s+1#sp4)ph +s+13%rI]!@KnY89LPL\BM2I4MN/`jYO-#KeP*;,qQC!u,R[]h*YHY:< +['d?O\[f>b]tV7t_Sa=2`lQ6DbKS5VcdC.heCE.%f\,!5gtgiEi8N\Uj5f=akNM0plKdg'mI'uB +!V#XYncJFTo`"O`p&Ojcq#:*hqYU0gr;HTbrdk*[s*t~> +JcC<$JcF@%o`"gfrqu]ks8)ckrqQNf!;?Eb)>*Oko'u5nGND>ogqPkLC?QL^C2QMm'KPk:+$OS=h9N<5&sMu,pA7K,dR8,l-[8c;9] +9E.]a9`e'c:]=/l;,U,=BToJ='/R->5hb+>manD?t*MO@:E\UAH$-EAnPaiBkqJ^ +C]A2UD/O91E,]i;r,MgZFSp7]FS'VVFE;JBqf)RQ!,qjS#]+?oCMRa%BkmTZ"D)+T@q5LI#@V"I +?5hVI-jL4=;`CM$shA5?Do4&Z&B(1CEUBP_ +Er:"VF9AA8Undk,q8WHTrlG&\rlb;brltGf!mf0;rm1Vk!7CeormUks"4l)Tf)F5!f)OA%f_aA% +g=;GfQ2HsIPq@oQN/`jYO-#KePE_>tQC!u+R[]e:SXuFFTqS3UUnjiaVl-JmWiE,$Xf\b0ric[5 +ZEggC['[6KrO2G"rK7&?lB2(-/Wl-pWMcYkV50o^U7n6PSt;LCS!ob4R$X,(Q'7AoOcYWbNfB!V +Mi*CKM26rdLAur-K`-Q'K)^DuJG+KhJH(3#K)L=>KS>,7L51P?M2@+JN/WaVO,oBbP*2#nQ'Rc( +R@9V8SXuIHTq\ +JcC<$JcF@%o`"gfrqu]ks8)ckrqQNf!;?Eb*q]'po'u5s%iSgr(m>fpJ:]`r_`Acs&&Vh!`;cjr(m2d!`)it +r`/ttku7RZmo06aqaCEPr^QcTs%*/]rC[)_s%NAc!_uNer_NYn;H!Km!E<(us2DmBO +2E<]U2`WiX3B0(u3<2,>497N+r]('A3BB1u3WV?)r&jsAs$-?Ds#ps#p?D%Qum83]fDa +3]fAa3]]>_r\sp92Z>WA2)[9I1GpsF1Go%f>r4>n1,M6[5!M1m4?>M_3']Vi5o=opfL54^uBV50o^A7YXM!bQ(Yqe#qCC&2TDC]8/KD>nGPDZXltEW1"YEr^=] +FT?U^GQ)jcH2`-hHiJKf;ta,e;u0Dl;>j;o;,U:j;tj6CMi3S"-%@ +StD^MU8+N[V5C/gW2ZesX/rG*Y-7i/#dL\@Za7$G[C,tAs1&3@\[VRF!k#JHrD`_oj]!b1WMcYk +V50o^U7n6PSt;LCS!ob4R$X,(Q'7AoOcYWbNfB!VMi*CKM26rdLAur-K`-Q'K)^DuJG+KhJH(3# +K)L=>KS>,7L51P?M2@+JN/WaVO,oBbP*2#nQ'Rc(R@9V8SXuIHTq\ +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb+nYBso'u5$GNGCM[g&Df0K2 +F)uJGF`qqQGBeCZH@(!dIXZcqJGt*#KnKAXs+LZ4L51S?M2D4hrep`6rf%/ANK&mTMi*GlMZ8P4 +L]`EgM2D4e#Dn1hKS4u2Jc:00IXHKiH?XOQFE)8;Df0CjU0aLbS=H(;P`g'+BpG0aVOaolS +r4X\]WMcYkV50o^U7n6PSt;LCS!ob4R$X,(Q'7AoOcYWbNfB!VMi*CKM26rdLAur-K`-N'K)U>u +JFe9fJH(3#K)L=CKS>,7L51P?M2@+JN/WaVO,oBbP*2&pQ'Rc(R@9V8SXuIHTq\?YV5L5jWiN5' +Y->.9Za@0L\@K2_]Y2(q_8=+/`Q-'Ab0/#ScHstee'uq!f@\g2gYL]Bhr*JQj5f=ak3(sml0@U$ +m-X60n*oi:rpg*]o_nFap@n=[q#C0hqYU0hr;?Nardk*\s*t~> +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb(A.4ho'u5 +rg*ML!1)\^lYH*.qJ?7ND>BIrPk:7@QLC1/QMm'KPkgI)OReG4NrG%$F]t>ZY$0>$G37>?b?:>[:Y7?OU=N@prhVA7]@a +AnPcUB)cKIBkV3oBPR>5_PcIXQTkH?j^YG&qY4?<_VuI=?KlI!0OJCKjhQ>?=]t8OPm05X/CI?=[ec6qU'g@Us(e +DK'Z>G'S@O8H)-Z7fQ.&93Q[hI!pBiD/XB5F*2VLG^+L[I!U3jJ:`B*K7r<>rNZC.rNlKDqf2UU +r,_gY!29A1r5JiZ`l?'uaT'?^b5BH^bl,fcc2l8:rm(YmdF%sArmUks!S#]uec"(ufE0aYf`'S( +g=__fP6-u6Q2[*LPpqTKN/WaVO,oBbP*;,qQ'Rc(R@9V7S=Q7DTV8'RUSO]^Vl-JmWiE,$riHC- +YHY79Z*OA8s0Md6r3l>!rfR#;LPUeDMMmFPNK0'\OHG]hPa.N" +Q^F20S"-%@T:hmPUnjibVl?\sXKAY0Yd1UB[^N]V]">Vg^VI\&_o9U8aN;TJbg+M\dF-Lne^i@) +g=k<;h;7&IiSrnYjlY^gkiq?slg4!*mdKW6nF?MK!V>s^o`Fj]p\jmeq>U6fqu6NkrUTr=s185\~> +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb(\I=io'u54T%A>55m_?4T@PE:\miV:]F8g;>O,h:\[cc;?'Jk:]F5k;>j;k:]4>n +J`3]T/Y3]T8^3&rrZ48V&33r_5>3X.T*3BB2]3W1o> +3]AuUr\jg8r\YHJ1GgsE2)I*I2`EQO2`3EK1,LaB5X5638if's4#f2a4Zu"n5!M1m3]T/Y2)[jrD;LPUeDMMmFPNK0'\OHG]hPa.N"Q^F20S"-%@T:hmPUnjib +Vl?\sXKAY0Yd1UB[^N]V]">Vg^VI\&_o9U8aN;TJbg+M\dF-Lne^i@)g=k<;h;7&IiSrnYjlY^g +kiq?slg4!*mdKW6nF?MK!V>s^o`Fj]p\jmeq>U6fqu6NkrUTr=s185\~> +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb(A.4ho'u5?b?;?!^lpBonNpD/K8is)7mVs)\lpGBe@VG'8(SH$O^_I!^6gI=M*Es+1<'J:RWMrIXlu +rdc/?J:N3'J:N)tI=-HjI=6HeG]n7NEH#l8EGfW1CM]^DTO+.\SXc1?PEL!+C6k?\]Ul+'Q][/K +CPdb5I[Y[f9PJB]I=#g[:k+@bM,$uHN.?S=NffWsS=uUD;,0e[9h\Pd:lqNaYl=(fn,DhSQ2d'MQ'@O4Q1pUFQFd+k`;[[G`9tPC`;dgS`rClHMijWN)u!XKAV-YPta3Z*L[AZa@*I[JdN6\+]k% +_>(hG^])%@^\b`!WMl_lV50o^U7n9QSt;LCS"#h5R$X,(Q'@JqOcYWbNfB!VMi3ILM26qBL5(D9 +K`-Q'K)^E!JF\3eJH(3#K)UE&KE-`*L&m'creY!>MiaihlPcHjkbdaZdtf@S^0g>(N?hr*GOj5]4^ +k2tjkl0@U6ljN4Kn*fc9nac8BoCW%Ts7ZKerV6Egs8)WirVZWmo)=4?])R9~> +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb(\I=io'u5?b98r`fb9?XR2J?sd8L@K'a9@0'hIqIKS:!b>eNrac%?s'uLKA7]=_AS#C`A7K-I@UEPQ +?sd;L@:?b64=]eg0=&s]rH[L0cG^":RFE1kt>Bb@=LO"5nFDkr&=__Se@")e#LC]@cd0tc +dJ_Mme,Iksec4.uec42#fDaD(f@\aSf`9b'PQ7!)Pl$[DPlI$KM(FRDN/`jYO-#KePE_>tQC+&- +R[]e;St;RITqS6WUnsrdVl6SpWiN5'Xfel,YR%M>ZEpmE['d=?[K*f1s8S5TOR\J1O>*Z4Vl$;d +UnaZXTq@pJSXc1=R@'A.QBd`"PEM&iO,o<\N/W[QMM[1GLPLV=KnY3YKE$Q'JbsugJ,=crJcC?$ +KE$T)L&Qf-LPYqd?]'c#N/`jYO-#NfPE_>tQ^F//S"#q>StMdNUSO``Vl6SpX0&M-Yd(O@[C3QS +\[oGe^;%J#_SjF5a2lBGbK\>Yd*^:keCN7'g"P08h;-uHi8N_VjQ5OdkNV6rli-5YmI'H3nF?&> +o(2JFrq6 +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb(A.4ho'u53&pmr!B<+= +2\J#*2DdFC-5!;"j4$,D]5Wq7p5!;7q4#o>\ +2`di_KMWqcWl$s#pEGrB1*C!'^!=s(24Bs(;=Fqe#qCC&VlICB/,KC]/)K +D>nGPDuObUEWC1[FS^.ZGQ)jcH2`-hHN8Hmj>k;?'Pn;u]hsM(FRDN/`jY +O-#KePE_>tQC+&-R[]e;St;RITqS6WUnsrdVl6SpWiN5'Xfel,YR%M>ZEpmE['d=?[f3S"-(A +TV8'SUnsrdW2ZetXf\e2Z*UdE[^WcW]"G_j^VI_'`5Ta:aN;WKc-FY^dF-Oof%8O,g=k?^ +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb(%h+go'u54=^#!5>[1Q@ra-:GLgFq_ +P%ff7P%ncLDf'B1DK,Sp$?1!*F`VYHF`qtPr-/9gG^045r-/NnG^+LZG^=UZGQ)h+GBS1RGBe:S +F`_VDE,KT5D/F')Cn@5jSXZ.?rgH$AP`h/lO,]*VL4b)LT<#/^OGS*pK85Y4DIud>G"[(/;LhP@ +KoM0k:K17iKR\T/NKB?lSY)RICJdi%9MPLc&;HdKTVJ]jQ'IZ%R\'ML#bRcaUo:5mY,qW+ +iNN=LrU0UPrU9fOr0@2Er078JqNh2J])Us3m)/kAs2G#X08PIAMMmFQNfT6_OckomQ'IZ&R$jD4 +S=Q7CT:hmPUSO]^VPg>jWN)u!XKAV-YPta,Z*OA8s0Vg6rO2a8q#CB1pqZ=4qn=2OVl$;dUnaZX +TqJ!KSXc1=R[BJ/QBd`"PEM)jO,o<\req5CMM[1GLPLV=KnY3ZKE$Q'JbsuqJ,4WlJ,=crJcC?$ +KE$T)L&Qg?LPUeDMMmFPNK0'\OHG]hPEhE!Q^F20S"-%@T:hmPUSO`aVl?\sXKAY0Yd1UB[C3QT +\\#Mf^V@V%_o0O6aN;TJbg+M[dF$Fme^i@)g"P39h;7&IiSrnXjQ5Oekiq?slg4!*mf)YUnF?MK +!qZ'Vrq6 +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb(%h+go'u5$G6:?!dM;&7B6I=`edkDK9i#=BJ^.>$Ci. +!a8f4r*0G3>[1TA?XNe="'o5>@/OC3@/XI4?jC%F?[@;5s',M,r`T)"#(1cEH$Xa\rcV.] +F)c2dgeYH[o/rj)O0!H<&WEr9qWErL(X +Er0qX`;IXR`rO3[ao0E_b5TQabl5lacMu2pd*^:ie'c\De,%Snec45#f)jUVfDaG%g&KdVPkpUD +PV7iLM2I4MNK0'\OHG]iPa.N"R$a;1S"-%@StD[LU8+N[V5C/gW2ZesX/rG*Y-7i/!O8s0Zi@E4 +[JdQ6\+p"'On+V+Oo(4_W2HMhUnjc[TqS-NSt2C@S!o_3Q^3o%P`q8nOH5H_NW+kEMi*@JLkgb? +L4t>7re(6&s+1&tr."Qlr."Tos+13%re(6(!/:E,BSVD#M2I4MN/`jYO-#KeP*;/rQC!u,R[]h< +StD[LU8+N\Vl-MoX/rG+YctF>['d?O\[f>b]t_=u_Sa=2`lQ9EbKS8WcdC.heCE.%f\,!5gtgiE +i8N\Uj5f=akNM0plKdg'mI'uB!V#XYncJFTo`"O`p&Ojcq#:*hqYU0gr;HTbrdk*]s*t~> +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb(A.4ho'u54=^#!5 +>[1Q@ra-7F4"rNS5!M+l4?#,U2Dd9N2Z5W82@)0!2E<]S2`Q.h'=oMS)>P^M`4oRPE4[/O'!G,mBB*2g[AnM$T#\[pdC2.O"C23``rbVOMs).gSrc.pX +!-A-]s)n?`rcJ9cGBa"1rd"Hgs*Ocn!*9)!pf.5koMYWdqGR)cs&/kq08PIAMMmFQNfT6_Ockom +Q'IZ&R$jD4S=Q7CT:hmPUSO]^VPg>jWN)u!XKAV-YPta,Z*OA8s0Vg6rO2a8s02j8['d.9Za@-K\%0&]]Y2(p_8=+.`Q$!@b0/#ScHjnce'uq!f@\d1gYCWAhr*JQj5]4^ +k3(sml0@U$m-X6?mfDqJrpg-^o^r.Us7QHerV6Bfs8)WirVZWmo)=4?]DmB~> +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb)>*Oko'u5`>'MrT]hMuLcs`qm[O`r*dU`r=$YaSa0Zb5KH^aSs6[`<=)q_ns:`_=rohNqeV2 +^Z<-.]`c![]=GKO7/fXS7f,^U8H)3Z9)hQa9`@cd:B+,h:^9iq;H$Ln<)rou!EWD&=TM]1r`gON +?=.&I@:E\UHWjR1NejgBQ\:StD^NVQ$Pq +XKA\0Yd",1iirIMr9jOPr:'WKs-3\NQ'@O/Q2d0IQb<@\`9Y>?`&>SiLl$tGMi[f,Q'IStP*1rhO,o<\N/W[PM2@%DLPCP;KnTDW!ePuSqgeWppO<$i +r.+fus+:6&F+f7$L5(J=Ll$tGMiaihlPcHjkbdaQ^rf@S[/g=tH>hVd>NioB+]k2tjjl07L!m-O-- +n*fc8nc&(\oCV\So`Fj]p\jmeq>U6fqu-HkrUTr=s1JA^~> +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb(%h+go'u5 +Q'LrVj)"!rpMBMgrg3YNqj%,GrKmPO!13SMqNq#Dr0@2GrGD(@hN7_trf7#;r^?`Sr^QcTs%*,\ +rC[)_s%NDds%`Sir_Nhs;GpFl<)clsQ.kO?!^lF?t!MR@q/2'Anu(-Jp1pIEH?5F +GBd.j=BSd1=]nr-=U826=^#$7>?Y2+>5qe6>[(E8=^"s1=BSc('G7;H@gTqJp^j.=]ng-EcH*qEWC+Y +Er:"Y`W!mU`rO3[ao9K^b5TQcbg"E0cMu2kd*_d>rR:er!7UqsrRLo!!nc,Vrn.5's4Yncqi`mm +Ll$tGMi +[f!Q1Vkp2bUS=HUTV%gHS=?":R@'>,Q'IStP*1rhO,o<\N/W[PM2@%DLPCP; +KnTDW!ePuSqgeWppO<$ir.+fus+:6&F+f7$L5(J=Ll$tGMiaihlPcHjkbdaQ^rf@S[/g=tH>hVd>N +ioB+]k2tjjl07L!m-O--n*fc8nc&(\oCV\So`Fj]p\jmeq>U6fqu-HkrUTr=s1JA^~> +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb(\I=io'u57rIY0'JV!]KrI=Qjr."Wps+13%re#9FKnY89 +LPL\BM2I4MN/`jYO-#KePE_>tQC+&-R[]hYd*^:jeCE1&f\5'6h;-rGi8N\UjQ5OdkNM0plKdg'mI'H3nF5uIncJFTo`"Lb +p@n=[q#C0hqYU0gr;HTbrdk*^s*t~> +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb)"dFjo'u5E,)Mr]cjM[.AFaN)?b?;?!^lF?smDP@Uiq[AWNX7>CT^^BRtAKI%-:^SnMeOMi<[WOcu"*Q2R!KQi=?^VPL#_ +U7n9RT:VUDS"#k7R$X,(Q'@JqP*(ieO,f3YN/NRMM26tCL5(D9K`-N)Jq8LMJGt&jIf4coJH(3# +K)UC:KS>,7L51S@M2@+JN/WaVO,oEdP*;,qQC!u+R[]e;St;UKU8+N\VPgAmWiW>*YHY:b]tV7s_Sa=2`lQ6DbKS5VcdC.geC<($f@em4gtgfDi8ESSj5f=ak3(smlKeH9$gmBNn*ol; +o()DDo`"O`pAamcq#C0hqYU0hr;?Nardk*_s*t~> +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb(A.4ho'u5?kE=?=.&I?t!MR@q9.^E-u4i +@7NphAQ`5FG]\(T>?tHNDK'T:rcS'\q02a]20jCiG^"@TG'$__<)Zap;cH\#>$G3TG'/%WGDCHl +I!BaOCM@!TCM.L%@8L'*7m0C57R]fG70,kHr^7MhAm]7iDI[9lCi434FEMnTH$*"T7n3JJ*DK1$ +?@.'GH[L6gD/aE7F*2VLGBnI[I!^0hIt3.LKA)%ZXoP[)YkkX(ZN%92Du4MQEV"5MF8j/Y`r=!c +aN;QHb0.rLai_d*b6H28c-FY\c2Q#gciVVCdJ_Joe'e6E!7Lhqs4%,#qUbc"rRh2)c]nHn0p79H +Ll$tGMi7rIY0' +JV!]KrdXQhrI=`qs+13%re"puQ^F//S"#t?StMdOUSO`` +Vl6VqXKAY/Yd(O@[C3QT\\#Mf^;%J#_o0O6aN2NIbg"GZdF$CleCN7'g"P39h;-uHi8N_VjQ5Od +kNM0qli-5YmI'H3nF?&>o(2JFrq6 +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb(\I=io'u5EBR4RP<+4PMsn:A@Zb:\mic:\R]`:\moc;>a5j;>WTU4p!lB:B";m4T7GB49.P";uT\p7/]RR +7f5dU8H29[9)hQa9`7Ze:/=[b;#aAm;Z9TB<)lq!<``C*=]np4>?kE=?=.&I?t!MR@q9.^6q0Bn +1FFA!2(UL?r]U]T5!;(h3]]>a4Zu"+4TI\E5Q*eG5Q3nJ5Q3eT5!;(l4>erP2)R0G1c5.os$%Pg +5WhgFs$$BG +r]U?I55@GCB)uUWral.Crb2.CrbMOMs)%dR!,_^Q!cN$src.sZs)\uQ^F//S"#q>StD[LTqeEZV5C/gW2Zes +X/rG*Y-7i/!O8s0Zi@E4[J[K5\,Wi8[KO"H[^Wa;;uK\jKnY3YK*$XUJbsusJ+S3gJ,FisJcC?$K5$!mKnb>;LkpnE +MMmFPNK0'\OcklkPa.Q$R$a>3S"6.BTV8*TUnsrdW2cl!Xfek3Z*UdE[^WfX]=bhk^VI_(`5Ta; +aND]Mc-FY_dF-Oof%8O,g=tE=h;@/KiT&tZjlY^gkiqBurp1$[mdKW6naZ2@oCMVRp&Facp\jme +q>U6fqu6NkrUTr=s1SG_~> +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb,4tKto'u5'1aiMNn`W4!V`rF*Za8j?Uap#o.a2l<@rl+oUs2+iRqnWJo +Mi3OQNK*gqrOr?C^VBc^p5S(Gs1AHG\O8ja7K,dS8,c'Z8c;9]9E.]a:&drg:]=2j;#jMn;u]es +[:ZB?XI2L@U`hXrad*^B5!p-<*G9$QMI^U^Oe/_OVRi+iRJN3J +Pk^LSPa7]+Un*m^XIZGDJRDhlrE_^?DJX#tObAaTKkPgX?rB`pE)()"G]/+/;M9sgP)b +N)>%]NKKEnS"6:IT:8YQ91qrP<)ZeXSt2JPT`:epUPt>!Q'@T$Q_'cISd:s^Uo12kXKAVpYNN.h +m/QJKmf2bQnG\UNPQ$dHQ2?gDQ2R$KQ2d0MQbWR^`9>)sKnbA=M2@+JN/`jYO-,TgPEhE!Q^F20 +S"-%@StD^MU8+N[V5L5iWN)u!XKAV-Y-5(6Z*CV6Zi@E4[J[K5\,$(!_!&Nd^8Im+Unjc[TqS-O +St2C@S!ob4R$O#&P`q8nOcYWbNfB!VMi*@JLkph@L4t>7re(6&s+1)urdXKfrI=`qs+(0%rIY-( +L&Qg?LPUeDMMmFPNK0'\OHG]hPEhE!Q^F20S"-%@T:hmPUnjlcVl?\sXKAY0Yd1UB[^N]V]">Vg +^VI\&_o9U8aN;TJbg+M\dF-Lne^i@)g"P39h;7&IiSrnXjQ5Oekiq?slg4!*mf)YUnF?MK!qZ'V +rq6 +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb(A.4ho'u5$G6:?!^iE?XR;O@UisJAKPMs +BRG+u9Q+6V8RPXn:1\!O<*O'RFF8@[Lj",iG'3A!s*+Kd$?p`CH$>!nH$s%/rD`#W>$"X= +B52-j<*`X!5@KrfA7oXpCM7G'\IZG">+m7RomB9MKJQH[L-d +H[UKnY3ZKE$Q' +Jc(&tJ+A'eJ,FisJH1<#K)pXZre>*ALl$tGMi^ +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb)"dFjo'u5h!)`\Xr]^3DrD!>lr)Ne[r]C-@s#^3B +hbsSS6q$uBr^QfUr^d&\rC[)_s%NAcs%WPir_WVl!)ieps&8tur`0&$=T2G5>$G6:?!^iE?XR;O +@UisJAJJfiBM(rT1dF#]/2Jq./i,=B1c@6Or]10E5s7Fsr]^r]^?Fs$$HF4Y\TH1c$jA +1G^jG2Dm7n?9F8P;`M9MFtNk=u"\qHNi#$X$Y:>?Y694Ztnj4S_/? +55RPE55@DGAnPagB)ZHDC&2QNCM[d&Ci+$,DJfAj!cN$src%pZr,hmYs)e9`!d8d3rHS['mEQ\[oDc]t_A!_Sa@3a2lBF +bKS8Wd*^:jeCE.%f\,!5gtgiEi8N\Uj5f=akNM0plKdg'mI'uB!V#XYncJFTo`"O`pAamcq#C0i +qYU0gr;?Nardk*`s*t~> +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb+nYBso'u5fmcHjh`da?Fg +cd'c*MXu\cM?&M#M@#3bbfe/NaN2EBn](OJ!Q`C\b5TQrb0.uNb/q`Fa2Z*;`l5m6_SZ8fs,-c5 +s,?f6r4W32[Jmu@^]2%CN<#""^AkkI^-qogr^QfUr^d&\r(?u^!)3>cs%WPirD3_r;GpFl<)cls +Q.k_?!^lF?t!JQ@Uiq[AS,RgBPD3s$4p-<-;2A@=NoUML^;4 +Lj=:EH/8Ll$tGMi7re(6&s+1)urdXfor-eHkrdXls +s+13%re(6(EJ9.%LPL\BM2I4MN/`jYO-#NfPE_>tQ^F//S"#t?StMdNUSO``Vl6VqXKAY/Yd(O@ +[C3QS\[oGe^;%J#_SjF5a2lBGbK\>Yd*^:keCE1&g"P08h;-rGi8N\UjQ5OdkNM0plKdg'mI'H3 +nF5uIncA@SrUg6cp\4X]rqZTjqtp?irVc +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb'D1neo'u5Er0R>Iqj%1sqeZ+Gr/q)5N;f">OoLO5OT1@BO@9%9 +r^QfUr^d&\r(?u^!)3>cs%WPirD3_r;GpFl<)clsQ.kE?!^lF?t!JQ@Uiq[AS,Rg +BPD3s9hKbPD>m0CDdIHV8k;QD7Ti)G93c"5B4PUfBjLXCs(`ZrM33gQMfrrT;NY[*BPqTu?s-3- +@:3MP@q/;0:."qI%V&jN?:77P77M01Bi.N7re(6&s+1)urdXfor-eHkrdXlss+13%re(6(EJ9.%LPL\BM2I4MN/`jYO-#NfPE_>tQ^F//S +"#t?StMdNUSO``Vl6VqXKAY/Yd(O@[C3QS\[oGe^;%J#_SjF5a2lBGbK\>Yd*^:keCE1&g"P08h +;-rGi8N\UjQ5OdkNM0plKdg'mI'H3nF5uIncA@SrUg6cp\4X]rqZTjqtp?irVc +JcC<$JcF=$o`"jgrqu]ks8)ckrqQNf!;?Eb)>*Oko'u54T7DB4RbH-4Qnm+:]!le:]=2f:]=,f:]=,h:]+&g;$'Qk;>EBO55n=W:B=9j +q,[>Qs#U3CiDT_ErC-]Tr($`Ws%3,\s%<>crD!;e!)NPi#>nAs;c?XpVKGi +?XI2L@:E\UA7]=aB4tsmC25pn912*)1c.EU3\2m:0.82!+sA0\0eP4:2)I2i1&`jB2Dm?Y7n#X2 +3]K,U7l<+Y1bpa;/M&IP0c)Mu0f1dH,pjre0JPFB.kE8(0020V2)kIu#r"(i1,:pS5<_@35nZUR +7RT3s3]K/[5XJ"78kViO:&[id56""M7/fXT7LVgX7n?0C8P2WL91qtF:$GFQ>52>%=q4b?>$G07 +>?kB;5!D1q55m\I5!;%mrB:0EoKN=frb)4Ds(VLJ!,;FI!,MRMrG;p[D/F0.DfBZ8EH6."FT6C^ +ErL+[FT$@]GQ)jcH2i0nH$Xd`Hhg_B/8Ll$tGMiKnY3ZKE$Q'Jc(&tJ,=]mIJ\KmJ,Oot +JcC?$KE$UEKnb>;LPUeDMMmFPNK0'\OHPcjPa.N#R$a>3S"6.BTV8'SUnsrdW2cl!Xfek3Z*UdE +[^WcW]"G_j^VI_'`5Ta:aN;WKc-FY^dF-Ooe^rF+g=k?s^o`Fj]p\jmdq>^ +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb)YEXlo'u5imc-O__rmLhn +!mc^[mu$UkeVaCN"O506b/sY(r5\NNrl5)]aiXG's31Mds2tA`!m&F&rPeoX`5DPjr/1H2s,?l8 +qnE*D"/`E?_>D%J^\a#iNrP1&^&YhE7K,dR8,l-[8c23\9E.]b:&dug:]=/l;,U$G39>[:\8?T);#@U`hXAS#IcB4tsmC27U$D,XG6S:6HXO.96N=H\_rHZN.d,7L51TaM-l-uN/WaWO-#KeP*;/rQC!u,R[]h['d?O +\[oDc]t_=u_Sa=2`lQ6DbKS5VcdC.heCE.%f\,!5gtgiEi8ESSj5f=ak3(smlKeH9$gmBNn*ol; +o()DDo`"O`pAamcq#C0hqYU0hr;?Nardk*as*t~> +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb'D1neo'u5reY!>Mi.9Za@-K\%0)^]Y2(p_8=+.`Q$!?b0/#RcHjnce'uq!f@\d1gYCWA +hr*GOj5]4^k2tjjl0@U6ljN4Kn*fc9nac8BoCW%Ts7ZKerV6EgrqcNhrqu]mo)=4?^]/f~> +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb(%h+go'u5F&_;>*0N56"CS:BFEo?kE=?N+:_?t!MR@q9.^ +AnG[hBPD3sCM[iO4?H7r6UF101c.!R5sILn0JY76/M/M32>K$-.0V1M-o*S5r\=U20JP=rA+d;2)dW[3\rcU3]m7#.6'RX5sIk391qrQ9MA)E5sn%. +77BU67Rp!>7n?6D8kM`M91qrQ9hnIK:$bUT>Q.h)>6%q)>6%k+>6.u5rET:a!'^BHpce^@s$$*? +rau4Erb;=GrbMIKrbW*^D/F0.DfBZ8EH6,BFT-=]ErL.[FT6L`G5HL`GQW5;H?oL9!.=NAs&K(u +oMbQ`p/1]b14t76L5(M@M2I7NNK0']OckomQ'I]'R$sM6S=Z=ETV8*TUnjiaVl-JnWiN2%Xf\b0 +ricI/ZEjJ9s0Vg6qR-C5rO)X5oi(fgpJq/krDP;FV50o^U7n9RT:VUDS"#k7R$a2)Q'@JqP*(ie +O,f3YN/NRMM26tCL5(D9K`6W(K)^E"JGt&sIe\?hIf=iqJH(3#K)UB,KS>,7L51TaM-l-uN/WaW +O-#KeP*;/rQC!u,R[]h['d?O\[oDc]t_=u_Sa=2`lQ6DbKS5V +cdC.heCE.%f\,!5gtgiEi8ESSj5f=ak3(smlKeH9$gmBNn*ol;o()DDo`"O`pAamcq#C0hqYU0h +r;?Nardk*as*t~> +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb'_M"fo'u5N2. +MuSb8NVpNg]`XOoYe9nMqnN9JNK*gq!KW?-^AknG7K,dR8,l-Z8c;9]9E.]b:&dug:]=/l;,UT)PAkU84KFP*D5sQC+#/Sc52cTV%pPVPpJpri?1)Y--cfm]c`V!:0LJ +s6]gR!:TpTrpTmVrp^!XrK?r>r0.8JPa(j+!1(M%ou-L?rP\NLotp^Gs+<4_KnbA=M2@+KN/`mZ +OHG]iPa.Q$R$jD4S=Q7CT:qsQUSO``Vl-JmWiE,$Xf\b/YHY79Z*O>7s0Vg6q6p2#qS;7./\\'W +UnaZXTqJ$LSXc1=R[KP1Q^*i#PEM)kOH5H_NJrgSMM[1GLkg_>KnY3ZKE$Q'Jc1,uJ,OihIJnWo +J,OotJH1<$KE$T)L&Qg?LPUeDMMmFPNK0'\OHG]iPa.N#R$a>3S"-(ATV8'SUnsrdW2ZetXf\e2 +Z*UdE[^WcW]"G\i^VI\&`5Ta:aN;WKc-FY^dF-Lne^i@)g=k<:h;7&IiSrnXjQ>Ufkiq?slg4!* +mf)YUnF?MK!qZ'Vrq6 +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb'D1neo'u5;ERJ`NJD#8)J +D"2<>D"MTDD#A/ID";BAR0&bBR/NBLQMHmFQMm0@R/<6JQN*6AD#S8RPEM,nr/q2HGCPC0r0./D +rK./CCi&oalB)%,r^HfUqa^ZWr^m&\s%EAcr_:>[1Q? +?=.&I@K'^e@q9.^AnPdjBkhF!Ci!s+DJr3B9h\3+@nM&cDK9rHHsTB:91hiM8kVcKE;XVPD>nAM +C]8&XBl%a-Df8-:8P2QHU9i5YPH[>[ +s+<4_KnbA=M2@+KN/`mZOHG]iPa.Q$R$jD4S=Q7CT:qsQUSO``Vl-JmWiE,$Xf\b/YHY79Z*O>7 +s0Vg6q6p2#nW<1$/>]/*ALl$tGMiaihlPcHjkbdaQ^rf%8R.g=tE=hV[8M +ioB([k2tjjl07L!m-O--rpKmWnc&(\oCV\Sp&Facp\jmeq>^ +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb(A.4ho'u5:>[1Q??=.&I@K'^a@q9.^AnPdjBkhF!Ci!s+DJq^&4?Ybu3''Z"6:=:46T[._1G^jE1B''4 +5X.M!5Q!eH5PIDs5?Y5/>Q7t->6%q->6.u5qHWhZ!^8h5 +oKN"6s(D@Fs(VFH!,MIJqeZCPDf>Vo"`e[*FEDU&ErU4\F9$I_Foll2G5c[lG^4R\H$O^^H[PKe +s&K(uoMbQ`ohk]ds+<4_KnbA=M2@+KN/`mZOHG]iPa.Q$R$jD4S=Q7CT:qsQUSO``Vl-JmWiE,$ +Xf\b/YHY79Z*O>7s0Vg6q6g@3[C-"Boi(fgpJq/kr)5/CUnjc[TqS-OSt2C@S!ob4R$X)'P`q8n +OcYWbNfB!VMi*@JLkph@L4t>7re(6&s+1-!rdXlqomQdfrdXlss+(0%re(6(!/:E,BSVD#M2I4M +N/`jYO-#KePE_>tQ^F//S"#q>StMdNUSO``Vl6SpX0&M-Yd(O@[C3QS\[oGd^;%J"_SjF5a2lBG +bK\>Yd*^:jeCE.%f\5'6gtgiEi8N\Uj5f@bkNM0plKdg'mI'uB!V#XYncJFTo`"O`pAamcq#C0i +qYU0gr;HTardk*bs*t~> +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb'(kedo'u5`8.M=uhuM<'QkM>W5=da6=cc-=JVbK7iHr5\TPrPo,`ai_fMbfp%1s3(Pfb0'_*s2Y2\rl4uW +!6"knqMP<2r/:W8r4`$@"GN&4XLeAIr5&$Lu2!F9%2?NjhG@U`hXracXQB4tsmC27U$D/O60E,flZ[RJrW]N/`m[OH,HgR@EfBq4mta%\]MbS=#V-P`UlbNK0!Xr/:l=R@0M5S"-,KSc>8^ +TTK/;'9e]JR$aA5SXuFFSt;UKU8=ffWrB(%Xfek1bch34kiqC3lhp,Jm/ZSRmf;eSn,DeWnaQO? +!KrTEP5(7=Pl?pJQM6Z^s7=2$_u@UK_tLtI_uG?IKS>/9Ll$tHN/WdXO-#NfPEhE!R$a;1S"-%@ +T:hmOU84T]VPg>jWN)u!XKAV-YHP17Z*CV5Zi@E3[J@9/s80Un^EUCfUnaZXTqJ$LSXc1=R[KP1 +Q^*i#PEM)kOH5H_NJrgSMZ/G:Lkg_>KnY3ZKE$Q'Jc1,uJ,OigIJnWpJ,FfuJV&LQK*I!_Knb>; +M#N6FMMmFPNK0']OcklkQ'IZ%R$jD4S=Q7DTV8*TUnsueWN*##Xfen4ZEppG[^WfX]=bhl^VRe) +`5Ta;aND]Mc-FY_dF-Oof%8O,g=k? +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb'_M"fo'u5R/`NQR/`NNQMt_$DZ+GIC]\I;Pl?mG +P5URID0:5[Nr"t>P5LFBDYJ#9OT1CA7K,dR8,l-Z8c;9]9E.]a9`e'c:]=2j;#jMn;u]esL'YPtd)Z21d+Zi4h>DYJ)JE;aeVE;jkTEWX>&a83mVap-&5 +bg"GYc2>lecN)>hd/_PmdJ_Jne,7_peH"2"fDjJ+f@\a/g$t=#POt+5PQ-mIK/SC:L51SAM2R=O +NfT6_P*2#oQ'Rf)R@9V8SXuIHTqS3VUnsrdVl6SpWiN5'Xfek2YctC;ZMh-0[/RK/[f$0rOR821 +U`ZA+TqS-OSt2C@S!ob4R$X)'P`q8nOcYWbNfB!VMi.Lj#)J%hL4t>7re(6&s+1-!rdXlqoR6[e +s*srs!eGrTrdtE.KnY89LPYqdBo7h-N/`jYOHG]hPEhE!Q^F20S"-%@T:hmPUSO`aVl?\sXKAY0 +Yd1UB[C3QT\\#Mf^V@V%_o0O6aN2NIbg"GZdF$CleCN7'g"P08h;-uHi8N\UjQ5OdkNM0plKdg' +mI'H3nF5uIncJFTo`"O`p&Ojcq#:*hqYU0gr;HTardk*cs*t~> +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb'(kedo'u5Q.k.?!dM;"^kbJ@UisJAIrHdBP;*p +CMRa'DJjB3EH-$u4TIVD3s7Z-3(lpC9)hVo!-8!Y!-8$ZrcA-_ +qf_s_qKW-hI!kNds&K(upeq/lr_rSip/1ifs+<4_KnbA=M2@.LN/is[OHPcjQ'IZ&R$jD4S=Q7D +TV8'RUnjiaVl-JmWiE,$Xf\b0YHY79Z*O>7s0Vd5q6p:1!OfE0;uK\ireY?HMi.9Za@-K\%0&] +]Y2(p_8=+.`Q$!?b0/#RcHjncdaZdtf@S^0g>(N?hr*GOioB+]k2tjjl07L!m-O--n*fc8nc&(\ +oCV\Sp&F^cp\jmdq>^ +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb'(kedo'u5c"jYH@d>3VS +M=uc(M><%tM>c3DP;bf\&KaSa*X`r!gUaT'?_b00Y+!mJj2rlY8_s2Y;_`lH*r +M?&M4MZ/M6MZ/P4N;gQc]a&_6OI`D]_o)AgqnW?L_85l,o"G4>^:Zo67f,^T8H29[9)hQa9`7]c +:&n)g:]aKl;Z9Sq<)rous&T\4=]np3>?kE=?!^lF?t'%D"_2(SAS,TSBFeflCMRa'DJjB3EH-#? +FEI@Y!EN+s;Zp'"T:__SSHG@MS"&W0!1NnV"eD9XSt;MPSd:sZSt;RGStM2EPQmD>R$a>4SGo)c +T:VXITqS9[WW&psX8o=#Y5k`GYQa.NkNM0qrp0LKrU'CKr:'`Lr/q#B!L&]APPgXFQ2HsEQ,N\& +_t1h=_uI[K_tLr'JV/T.KnbA=M2I4MNK0']OckllQ'I]'R$sM6S=Z=ETV8*TUnjiaVl6SpWiN5& +Xf\b0rilF-!4)R0s0Vd5q6p5$r4qC.s.ga3U7n9RSt;LCS"#k7R$a5*Q'@JqP*(ieO,f3YN/NSm +M#iEfre:H-K`6W(K)^E#JGt&tIe%pdIf=iqJH(3#K)UB'KSBD[A;>ttM2I4MN/`jYO-#NfPE_>t +Q^F//S"#t?StMdNUSO``Vl6VqX0&M-Yd(L?[C3QS\[oGd^;%J"_Sa@3a2lBFbKS8Wd*^:jeCE.% +f\,!5gtgiEi8EVTj5f=ak32'olKeH9$gmBNn*ol;o()DDo`"O`pAamcq#C0hqYU0gr;HTbrdk*c +s*t~> +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb'_M"fo'u5"IY^ICi&rb +qJ>8/qJ>YQggCAQN3?JD>nGMD>\5MPl?jHP5:@I@r$.4K8YnUqigo? +rfR1tqeZ=LnrNs7OH2j07f,^T8H29[9)hQa9`7]c:&n)g:]aKl;Z9Sq<)rous&T\4=]np3>?kE= +?!^lF?t'%D"_2(SAS,TSBFeflCMRa'DJjB3EH-#?FEI@Q!DQ2b9E@d\r-JEkrH\Hhl[&SVrH\]q +I!g9eH@(#;cHXY[c2Q#gchu2j +d/DAkdK%bneGn)!f)O>'f[naSf`0V)POk%2POt+5P;@cBK7nr5LPUeEMiStD[LU8+N[V5C/hWN)u!XK8P+Y-7i/s02R0rNlO2rjDR1r;ZAMm?.FE+/>R(TqJ!KSXc1= +R[KP1Q^*i#PEM)kOH5H_NJrgSMZ/G5Lkkta!JQ4+KE$Q'Jc1,uJ,XofIK"]pJ,OotJcC?$K)pXZ +re=s=Ll$tGMiU6fqu-HkrUTr=s2"_c~> +JcC<$JcF=$p&=pgrqu]ks8)ckrqQNf!;?Eb'(kedo'u5?kE=?!^lF?t'%D"_2(SAS,TS +BFeflCMRa'DJjB3EH-#?FEICC!BrXE3s%H)3VuGL9)_KI9)M<`9M8"S9E%Wb9ajZ^6psI377B[7 +6UXBB8H20\8P8tR"%l3Z9`@]_9ug$.=8uA(=^##)>P_V)>Pqb+>Q6k_497T-qE=[=!^Ak4pcemF +B4kmkrb;FKqeZ.HrGM^UEW1"]EcZ8ArH%s[!-S0^s*+Kf"aP?;H$O`7HiR1<R(TqJ!KSXc1=R[KP1Q^*i#PEM)kOH5H_NJrgSMZ/G5 +Lkkta!JQ4+KE$Q'Jc1,uJ,XofIK"]pJ,OotJcC?$K)pXZre=s=Ll$tGMiU6fqu-HkrUTr=s2"_c~> +JcC<$JcF@%o`"gfrqu]ks8)ckrqQNf(&%=no^qbGo'u5h.?PdJhJlc3;J:bK@rJouI!Os2b;abkfQcbfe3/b5]Q`aSs3^Mi*CMpko$. +rf$l8rP%s<"`f0SS>`mq_u%=F_>]JnO8b4@OnZTi^&PbD7f5dU8H29Z9)hQa9`@cd:B+,h;#aAm +;Z9Sr<)lrtQ.k.?!dM;"^kbJ@UisJAI2s]BP;*pCMRa'rb`']E,flqLK_CpFjK7ei2L51SAMMmFQNfT9aP*;,qQC!u,R[]h7re(6&s+1-!s*surnU:CcrdXlss+(0%re(6("GMSbLPYqdA;Z;(N/`mZOHG]hPEhE! +Q^F20S"-%@T:hmPUnjibVl?\sXKAY0Yd1UB[C3QT\\#Mf^V@V%_o0O6aN2NIbg"GZd*^:keCE1& +g"P07h;-rGi8N\Uj5oFckNM0plKdg'mI'uB!V#XYncJFTo`"O`pAamcq#C0iqYU0gr;?Nardk*d +s*t~> +JcC<$JcF@%o`"gfrqu]ks8)ckrqQNf(A@Foo^qbGo'u5>b%:QqjIMQrKuo;pm;&Lqj@ALrbhFH!,h[N!,VUuoofSgC3"WOM37_!qih#B +rK6nmrbV7hs,[+Jr($`Ws%3,\s%EAcr_RM$"dg`BPD3sCM[keD@1<$EH-#?FEDYKGP+Z/9)qZ`9*e6b9M.rN9M8"W9DqK^8bu$f +8P;ZJ8P)QJ9j;:SH2)^bHiJBlIJnWpJc13#KE$T)K><3=WWK6&XST%!Y5PR$Z1tWtDZ=YTE;=GF +E!(*DP/dF@!6P5_#Kt?8c-=PYcMl)gcMu2nd*^7fdJhMldJqYpe,Rnte,Ihsebn"sfDjM'g&@3- +Pk1+8Pl-^FPk^FqJ:W?*KS>/9Ll%"IN/`jYOHG]iPa.Q$R$jD4S=Q7CTV8'RUSO``Vl-JmWiE,$ +riH4(YPtd+YlM*.Zi7?1[JRE2s7;?=OW^HpU7n9QSt;LCS"#k7R$a5*Q'@JqP*(ieO,f3YN/NSm +M$AckL5(D9K`6W(K)^E#JH(,tIdqjcIf=iqJH(0#K)UE&KER!`L51TaM.DL%N/WaWO-#KeP*;/r +QC!u,R[]h['d?O\[f>b]t_=u_Sa=2`lQ6DbKS5Vcd:(feC<%# +f@em3gYL]Bi8ESRj5]7`k3(sml0@U$m-X6?mfDqJrpg-^o^r.Us7ZKerV6Egs8)WirVZTlo)=4? +_Z,,~> +JcC<$JcF@%o`"gfrqu]ks8)ckrqQNf(&%=no^qbGo'u5RM +$"dg`BPD3sCM[keD@1<$EH-#?FEDYKGP=6(5*q-3Z"!*fD,r`f1]rB1*Cs$$9Br''m? +s%WN+"DDLaC2T. +rilF-!4)R0rj;X3qmQI1q,7;n;uK\i['d?O\[f>b]t_=u_Sa=2`lQ6DbKS5Vcd:(f +eC<%#f@em3gYL]Bi8ESRj5]7`k3(sml0@U$m-X6?mfDqJrpg-^o^r.Us7ZKerV6Egs8)WirVZTl +o)=4?_Z,,~> +JcC<$JcF@%o`"gfrqu]ks8)ckrqI<(p@e1Po^qbGo'u5]AUTK(V6e#:`;[XK_>M+JNW>.>OT(C<^&l!\]`(Cu8,c'Z8c23\9E.]a9`e'c:]=2j +;#jMn;u]es[1Q@?=.&I@K'^>@q9.^AnV*V(27N!CM[j*DJsK5EH-#?FEDYK +GB\:Wn5L*%<)lms;,L7i;H$Ik;c?[s<`N*srDESm#@;+fLR=m6VuEXpWW0"!Wr/suWrfB)Y5PQ5 +Yl<_`jo4BGkNV6rlKeH9qs=COq="7NqNCl@"-Se0P5UUDPkpUBPQI,9Qi5#*`rO3$s89e2`9+u0 +_Z,-BJV/T.L5(J>M2I4MNK0']OckonQ'Rc(R@9V8SXuIHTqS6WUnsrdVl6SpWiN5'Xfeh1rilF- +!4)O/rj;U2rO2\)ot]t0s1TVOUS=HTT:VXFS=?":R@'A-Q'IStP*1rhO,o<\N/W[PreUZ3L]3#/ +KnTGXs+:9%rIFotrdO^ +JcC<$JcF@%o`"gfrqu]ks8)ckrqIB*p@e1Po^qbGo'u5J)6 +C[l6:D>%cK?nGED#eJQD>]XkP6dCS=D2YuIts*]P5(7@ +P5^U@D>e;GOT1C@7f5dU8H29Z9)hQa9`7Ze:/=[b;#aAm;Z9Vp;ufqt7=BSd1>$G6:?!^iE +?XR=A@Kg7PAS#Idrb*']C27U$D/O60E,]f:EcZ>EF`qtQG^8dP"AMQa9M>@Ys%E8`rCm;d9)D0a +;-.+?G^b,@J,artJGt,rK)L?$KXZ[3WWB0%q5jY"ric@+r3?%&oPXVGrc%^PqJcCsrfR?(aiOJ' +s2tAbrlkSkc-FSXrlkPjd*U2;d/D>ldehMne,\%rf)F;$f`0Y&PPUOM2I4MNK0']OckonQ'Rc(R@9V8SXuIHTqS6WUnsrdVl6SpWiN5'Xfeh1rilF-!4)O/rj;U2 +rO2\)q2kQ;!0HW2s,\A!US=HTT:VXFS=?":R@'A-Q'IStP*1rhO,o<\N/W[PreUZ3L]3#/KnTGX +s+:9%rIFotrdO^ +JcC<$JcF@%o`"gfrqu]ks8)ckrqI<(p@e1Po^qbGo'u5Yn8n;>j>W:]F8d;>F&g4oRY84o[_7:]Eie8P;cQ;H36fqH!SYqEF^Ts&8tsr^QfU +r^d&\r(?u^s%NAc!_uNer_WVl!)ieps&8tur`0S3=BJ^/>$>-8>[:ZB?XI2LraH%@A7]=aBDuQ[ +BkhF!Ci+'-DfBZ8EH6,BFEMbNGBeE&4T[l355[MB3rD&B4[2.p4o.5E4[;>%7nH;M8cVN`9`%H_ +9_D,m:AIrk=T2G'>52=p>lIss4oRYA4oISD5Pn+[9k\6UC27X$C]/)HD>nGUE,ou?qf;XV!-J*\ +s)nBdrcnEfrHeKj!.=]Do2YchpJV&kr_rPhqbdBD1P(12KSG5:Ll%"IN/`jYOHG]iQ'IZ%R$jD4 +S=Q7DTV8'SUnjiaVl-JmWiE,$Xf\b/YPtd+YlM*-Zi7?0[JdN6Zi7?.;uTbr<<-"m +JcC<$JcF@%o`"gfrqu]ks8)ckrqI9'p@e1Po^qbGo'u5amYUIk +(1:KU?!Pt2e^W$pd*U+acHXSVbK@rJpW*-P!QrX_c2YufbPoZ`ao..tMY;u.N;S\4^@o5?^AbnH +@g$t9U9D9.`;[[R_YCtH^]9DoO8G(:^&YhF7f,^U8H)3Z9)hQa9`7]c:&n)g:]aKl;Z9T"<)lq! +<``@)r`K8*>Q.k.?!dM;-X^@l@UiqZAS#IdBP;*pC27U$D/O60E,fl;M2@+KN/is[OckllQ'I]'R$sM6S=Z=ETV8*TUnjiaVl6To +WWoN*Xf\b/YPtd+Z2_-.Zi.9,[Jg-u_!\u:^)s)CTqJ$LSt2C@S!ob4Q^3o%P`q8nOcYWbNfB!V +Mi.Lj!JlO1L&m!]re(6&s+1-!s*t#smX>(`s*suts+(0%re#KLKnY89LPUeDMMmFPNK0'\OHG]h +Pa.N"R$a;1S"-%@T:hmPUnjlcVl?\sXKAY0Yd1UB[C3QT\\#Mf^;%J#_SjF5a2lBGbK\>Yd*^:j +eCE1&f\5'6gtgiEi8N\Uj5f=akNM0plKdg'mHs?1n*ol;o()DDo`"O`pAamcq#C0hqYU0hr;?Na +rdk*es*t~> +JcC<$JcF@%o`"gfrqu]ks8)ckrqI9'p@e1Po^qbGo'u5s).^upQPQ?!0dC_"ClJ$L5l"loooB$Lu2!F9%2?RK5i@U`hX +A7]=aB4tsmC2.O"Ci+'-DfB]9EcZ;DFEMbNGBeCZH@,9Xnk0Hd:K(:t?=IM\D/j]DI=_3 +S"-(AT:hmPUSO]^VPgAlri-1'XKAV-Y-7i/s0;U0rNlI0q6g2$qN0s(rfA4rTqS-OSt;LCS"#k7 +R$X,(Q'@JqP*(ieO,f3YN/NSmM#iEfre:H-K`6W(K)^E#JH(,uIdVX`IfForJH(0#K)UCJKS>,7 +L51SAM2I4MN/`jYO-#KeP*D5sQC+&-R[]h['d?O\[f>b]tV7s +_SX71`lH0BbKJ/Ucd:(fe'uq"f@\g2gYCWAhr*JQj5]4^k3(sml0@U$m-X3.n*fc9nac8BoCW%T +s7ZKerV6EgrqcNhrqu]mo)=4?_uG5~> +JcC<$JcF@%o`"gfrqu]ks8)ckrqI?)p@e1Po^qbGo'u5$Lu2!F9%2?RK5i@U`hX +A7]=aB4tsmC2.O"Ci+'-DfB]9EcZ;DFEMbNGBeCZH@,9IniRCF5!M:u6:4./77Kg>8ke5=^J=c/ +q,dMts'#5&pfmf)r`oJ-lokA4q)n^ApItU$rbDFJrbMaTCi!s*DZ4PSE;OYRErL+^FEM_JrcJ9c +GB`n.rd"Nj!.=WBo2YchpJV&kr_rPhrD>+qJ:N6(K8#&7LP^kFN/WdXO-,TgPa.N#R$a>3S"-(A +T:hmPUSO]^VPgAlri-1'XKAV-Y-7i/s0;U0rNlI0q6g1-qc!JnoMtfgrDW\n+/5I&TV%gISXc1= +R[KP0QBd`"PEM)kOH5H_NJrgSMZ/G5Lkkta!JQ4+KE$Q'Jc1-!J,XobIK"]qJ,OotJH1<$K6`-( +Knb>;Ll$tGMio(2JF +rq6 +JcC<$JcF@%o`"gfrqu]ks7u`krV.3'p@e1Po^h\Fo'u5!rlFrX!R&^`bm)D8bKA#NanUem +MYW21Muo!!^\bbE^&PhF^&G_J^V7Itrac%=")j!f\Ga>D`;RUQ_YCtI_#KJpO8tFBO9L]Z]tHm) +qa^ZWr^m&\s%EAcrD!;es%iVjs%rbor_rhr!*0#!.p#hT=]np4>?kE=?=$uG?t!JQ@Uiq[AS,Oe +BP;*pCMRa&D/O60E,fljWN)u!X/rG*Y-+u-YlD!.ZMV!%[/^1!_!\u9 +^AjlHTV%gISXc1=R[KP0QBd`"PEM)kOH5H_NJrgSMZ/G5Lkkta!JQ4+KE$Q'Jc1-!J,XobIK"]p +J,XuuJcC?%KE$UAKnb>;LPUeDMMmFPNK0']OcklkPa.Q$R$jD4S=Q7DTV8*TUnsrdW2cl!Xfek3 +Z*UdE[^WcW]"G\i^VI\&_o9U8aN;TJbg+M[dF$FmeCN7'g"P08h;-uHi8N\UjQ5OdkNM0plKdg' +mI'uB!V#XYncJFTo`"O`pAamcq#C0hqYU0hr;?Nardk*fs*t~> +JcC<$JcF@%o`"gfrqu]ks7u`krV.3'p@e1Po^h\Fo'u5S,\rVRJLacD>\5= +C\_fFD>e;BD$49T?X@%6SGSfURK/cOR/`N>QiNQQR/Uq&DZ4MMD"_]GDYfUsPQ-mHPPLFL=B8F% +?kE=?=$uG?t!JQ@Uiq[AS,OeBP;*pCMRa&D/O60E,fl$W;`dmWrK+"XSJsuY5YX(Yl1j&ZMSS4DYJ)IPl?mDOoWZ(aTK]/ +bKTn/rlkAdqTo,es3Uqse'lbDe,.\pf)=2&f\+s3q31Z>q31]=qigl@pldXcIt3'$K7el4L5:\C +MiuQ^F20S"-%@StMdNU8+N\VPg>jWN)u!X/rG*Y-+u-YlD!.ZMV!%[/^1&OQho+ +OT2!oTV%gISXc1=R[KP0QBd`"PEM)kOH5H_NJrgSMZ/G5Lkkta!JQ4+KE$Q'Jc1-!J,XobIK"]p +J,XuuJcC?%KE$UAKnb>;LPUeDMMmFPNK0']OcklkPa.Q$R$jD4S=Q7DTV8*TUnsrdW2cl!Xfek3 +Z*UdE[^WcW]"G\i^VI\&_o9U8aN;TJbg+M[dF$FmeCN7'g"P08h;-uHi8N\UjQ5OdkNM0plKdg' +mI'uB!V#XYncJFTo`"O`pAamcq#C0hqYU0hr;?Nardk*fs*t~> +JcC<$JcF@%o`"gfrqu]ks7u`krV.0&p@e1Po^h\Fo'u5V@Xs&/nsr_ql@pcS44 +r]L$=rB1$?o/m.a?sd5Gr)!)as%rPfr_WAcs%i_n;#*ue;"m'N4S:l;:@h9[;#X5j7K#UV77g3N +rDW\pp/Uujs&JeWr`/tfqa^ZWr^m&\s%EAcrD!;es%iVjs%rbor_rhr!*0#!.p#hT=]np4>?kE= +?=$uG?t!JQ@Uiq[AS,OeBP;*pCMRa&D/O60E,flPMJ'?2n10>Q6hJ4oA%L9`Jf0C2%EuC]8,RD/=$*D/T>k +qJlISs)\3^!d/U,rcJ3arceBe!-eEercnKjrd=N@s&B%up/V)kpJV&kqc!8f2h$7,J:`E+Knb>< +M2@.LNK0']OckomQ'Rc(R@9V8SXuFGTqS3UUnsrdVl6SpWiN2%Xf\b/YPtd+Z2_-,ZhCd+ZM[Z" +<:j2g<;fbo;ZEF1TV%gISXc1=R[KP0QBd`"PEM)kOH5H_NJrgSMZ/G5Lkkta!JQ4+KE$Q'Jc1-! +J,XobIK"]pJ,XuuJcC?%KE$UAKnb>;LPUeDMMmFPNK0']OcklkPa.Q$R$jD4S=Q7DTV8*TUnsrd +W2cl!Xfek3Z*UdE[^WcW]"G\i^VI\&_o9U8aN;TJbg+M[dF$FmeCN7'g"P08h;-uHi8N\UjQ5Od +kNM0plKdg'mI'uB!V#XYncJFTo`"O`pAamcq#C0hqYU0hr;?Nardk*fs*t~> +JcC<$JcF@%o`"jgrqu]ks8)ckrV-EfpAX^co^i(Q&+T/Xmd9B-lg!`ukKhGuc2Poec1QtjM#`G/ +M><&/MscJuM=6<*@UWYO?]MpOSt4?7f,^T8H29Z9)hQa9`@cd:B+,h +;#aAm;Z0Mp<)rous&T2&r`K8*>Q.k.?!dM;$=I:O@UinYAS#Idrb)ILC27U$D>nDkDfB]9EcZ>E +F`hkOGBeCZH@($eI=6QoJ:LVh;[uo:ASZ:1I=mE=QCXbKYGnc+WrCrViVqg:j8S->jo=KBk61#5 +lK[^5m/QGRmd:#AqsXLQmudR3r0-uts2auUb5_4RqS_g>!5eTMqSG4?IXcm!JqJ`1L51SAMMmFQ +NfT9bP*;/rQC+&-S"#q=StD[LTqeEZV5C/gW2ZesX/rD)Xfek2rilF-rj)C,q6U40s8Vf.m_A_7 +s.LF*T:VXFS=?"9R$a5+Q'IStP*1rhO,o<\N/W[PreUi8LPCP;KnTGXs+16%rIFlsrdO6_rdOls +rI=s#JqEuS!JH1+L2Vj'M2@+JN/WaVO,oBbP*;,qQ'[l*R@B\9St;RJTqeEZVPgAlWiN5'Y->.9 +Za@-K\%0&]]Y2%o^r!t,`Q#s>aihlPcHjkbdaQ^rf%8R-g=tE=hV[8LioB([jlY^gkiq?slg4!* +mdKW6nF?MK!qZ'Vrq6 +JcC<$JcF@%o`"jgrqu]ks8)ckrV-EfpAX^co^i(Q&Fo8Ymd9B-lg!`ukF7s0R[a;Fs)%aOr+uFO +q/$+Lmqr#>rbMOMoP=A@mqi5;@:3GK>kjfhS,SrXS,\oWRH0b7RK&ZJDZ+GMD#/#FPQ6pGPQ6pA +PlI$K=T;J&<Q.k.?!dM;$=I:O@UinYAS#Idrb)ILC27U$D>nDkDfB]9EcZ>EF`hkOGBeCZH@($e +I=6QoJ:L>`9+F]p?>cHcC7rQkVndaJ-DrmV"ueC=KJrRUu#rn7A,pQPH.9Za@-K\%0&]]Y2%o^r!t,`Q#s>aihlPcHjkbdaQ^rf%8R- +g=tE=hV[8LioB([jlY^gkiq?slg4!*mdKW6nF?MK!qZ'Vrq6 +JcC<$JcF@%o`"jgrqu]ks8)ckrV-EfpAX^co^i(Q%IrrVmd9B-lg!`uk>YCY;?9]qmQCP6of_q0 +p-%P#"_(nJ?X@"7;#O5k;Ys>k;#=#j:f1(dpJ:fcpeh&f!'Kg6rB0p>r_E,^rDs[ +qG[Amoi:ojpHARHqa^WVs%3,\s%EAcr_V.r]U3Bm61DCr([2ds%WDb"DVXbC23``rbMmX +DJjB2E,fl:E;abVErL.ZFT-F]FoZabGQ;seGQrG>H[L3hIJ6\><;'>k<;0;k<;TVj;E0)RIt3*% +K7nr5LPUeEMijWN)u!XK8P+Y-5&.YlD!-ZMLp' +Zi[S=Z2IW#<:a,g<;]\n;ZEF1TV%gISXc1=R@'A.QBd`"PEM)kOH5H_NJrgSMZ/G:Lkg_>KnY3Z +KE$N'Jc1,uJ,XoaIK"]qJ,Om!JV&LQK)pXZre>?HLl$tGMi +JcC<$JcF@%p&=pgrqu]ks8)ckrqQNf!;?Eb(\I=io'u5E,0 +M>2u)Mti/0Mu&>.M=ZT=A7K(W?XI,Ef\"g-f%&@$e'cXjd/MAkc2u54ans-WaSO!ab0/#RcHa\[ +cMl&gbjLDgMYi;8^q[Uu^;'NY!58!fPr7K,dR8,c'Z8c23\9E.]a +:&drg:]4)k;,U[1Q??=.&I@:RM.qWF-BPD3rCMRa'DJjB2 +E,flM2I7NNK9-_P*2&pQ'[l*R[]e;St;RITq\reYBIMi +JcC<$JcF@%p&=pgrqu]ks8)ckrqQNf!;?Eb&+oJao'u5$G39>[:WA?XI2L +@:E\UAH$-jAnPdjBkhBuCM[j*DJsH4EH-#?FEDYKG'A.TH$Xd`I!g?jIXcluJUrE*p.Glj;H?t- +@:j4jEHQPTJV:4\s/H!rrMKUmri#dpql0^uXK;3!s/u@)rNH:,q6L!;r,;:Hs)%^Prg!)>rK@9* +b5TTac25`bc2Z&jcd'i7ci)5idf%VteC2mreG[qtecXOVf\-5Wooo9;qigfM2I7NNK9-_P*2&pQ'[l*R[]e;St;RITq\reYBIMi +JcC<$JcF@%p&=pgrqu]ks8)ckrqQNf!;?Eb'D1neo'u5?b?;?!UcD?XR;N@U`hXradTlB4tsmC2.O"Ci+'-Df9T7EH6,BFEMbMGB\:WH?spcI!pEl +It3'#JV&OJ4:XM<552=s>Qe>;>[(G04o7A6 +4oS7R:&n#c:B+&g9`Jc,BkmW_rbMmXDJjB2E,]f9E;abVErC(YFT-F^FoZacGlN!eGQE)9rd=`o +s&A_kr`&Skr`&Acr)3QC0n+V&JV&N-KnbA>M2I7NNK9-_P*2&pQ'[l*R[]e;St;RITq\7re(6&!.k*!rdXrsm!\k^s*suts+(0%re(6("GMSbLPYqdC5Rq.NK0'\ +OHG]hPa.N"Q^F20S"-%@T:hmPUSO`aVl6VqXKAY/Yd(O@[C3QS\[oGd^;%J"_Sa@3a2lBFbKS5V +cdC.heC<($f@em3gtgfCi8ESRj5]7`k3(sml0@U$m-X6/n*fc9rpp*\!;-9`s7ZKerV6EgrqcNh +rqu]mo)=4?`W(G~> +JcC<$JcFC&o`"gfrqu]ks8)ckrqQNf!;?Eb(A.4ho'u5@KUS)TXaF-s2+TJr^QcTs%*,\rC[)_s%NAcs%`Si +r_WVl!)ieps&8tur`9&#!*K5'!Er_,>QJ,:ra,\6@K'^C@q9.^AnG[hBPD5\CB\NkDJjB3rc&*^ +F*)MHG5c[mG^4U]H[L3hI=?\FJ-LRVK7ei1L&=jZ=C5WTEHlnaMNF-pU8Y9'YkY-nhuDX6iW%p; +j8S->jo4EAkl9lKlKdd7m/?>MmeuVQnElA3>2I=6QpJ:W?*KSG5;M2@.L +NK0']OckomQ'Rc(R@9V8SXuFGTqS3UUnjibVl6PnWiE,$riQ4'!3c@*riuI.o<\JspqZ=4qn=&B +St;LCS"#k7R$a5+Q'IStP*1rhO,o<\N/W[PreUi8LPCP;KnTGXs+16%rIFotrdO0]rdOlsrI=s# +JqEuSDhNh!L51P?M2@+JN/WaVO-#KeP*;,qQC!u,R[]e;St;UKTqeE[VPgAlWiN8(YHY:;Za@0L +\@K2_]Y2(p_8=(-`Q#s>aihlPcHjkbdaQ^rf%8R-g=tE=hV[8LiT&tZjlY^gkiq?slg4!*mf)YU +nF?MK!qZ'Vrq6 +JcC<$JcFC&o`"gfrqu]ks8)ckrqQNf!;?Eb&+oJao'u5XARo:[@:*AJ>kX`eSH#&[R[KT.R/<%l?D#fjfPkgUC=8uD&b1Mrfd>GlBD3: +qa^ZWr^m&\s%EAcrD!;es%iVjs%rbor_rhr!*0#!s&T2&r`K8*>Q.k.?!dM;!FT@8@L?UUAS#Ic +B4tsmCAquPCi+'-DfG\q"`e[+FEMd+G7&S?H?spcI!pElJ,Xs&JV&N,KS5'W9+F]pKnY3ZKE$N'Jc1-!J,Xo_ +IK"]qJ,Om!JV&LQK5ZEsL5(J=Ll$tGMi +JcC<$JcFC&o`"gfrqu]ks8)ckrqQNf!;?Eb&+oJao'u5l7Ft;>a>i;?'Ji:BOEj;,I3es%rVh"&Mil;#F/j4oIM548qA?4oA(N +:]+&b:]4&g6i04M6N]_J9i(ac!)iSjr`&Sks&T+gqa^ZWr^m&\s%EAcrD!;es%iVjs%rbor_rhr +!*0#!s&T2&r`K8*>Q.k.?!dM;!FT@8@L?UUAS#IcB4tsmCAquPCi+'-DfG\q"`e[+FEMd+G7&S? +H?spcI!pElJ,Xs&JV&N,KS5'W4:XM<55MM) +>[.,2!*fA+r`f1]q)nU=s#pHH:AI]W:'OF+BPD3sC]8,PD/O60qf)LR!-8$ZrcJ-^s*"Ed!-nEc +"*f*;HiAElI0*DJ<;0>f<;KVo<:*U@H[U/8 +LPL\BM2I4MN/`jYOHG]hPE_>uQ^F20S"#t?StMdNUSO``Vl6SpX0&M-Yd(L?['mEQ\[oDc]t_=u +_SX71`lH0BbKJ/Ucd:(fe'uq!f@\d1gYCWAhr*GOj5]4^k2tjjl07L!m-O--rpKmWnc&(\oCV\S +p&Facp\jmeq>^ +JcC<$JcFC&o`"gfrqu]ks8)ckrqQNf!;?Eb(%h+go'u5rMZA_6Mt;f+M>W80MuS_EAn>L_@UWVN?_Y1nD_Yh7J +8,l-Z8c;9]9E%Wa:&dug:]=2j;?'Pn;Z]ou[1Q??=.&I?t!MR@q0%\AS,TS +BF8HgCMRa&D/O60E;jhoEcZ>EF`qqPGBeCZH@(!dI=6QoIt3'#K)UB'KSBD[%YojsM/dcgK8PbV +SYE'd^T[^7o;2SchVS.erS[\6s5O"kWiN5'Y->.8Za7'J\%&u[]Y(tn^qmn*`Pom=ai_fNc-FY_dF-Oof%8O, +g=k<;h;7&IiSrnXjQ5Oekiq?sli-5YmI'H3nF?&>o(2JFrUg6cp\4X]rqZTjqtp?irVc +JcC<$JcFC&o`"gfrqu]ks8)ckrqQNf!;?Eb&+oJao'u5S5FD?#n#PQ7!>PkgUCQMsq`=8uD&$G39>[:WA?XI2K@:E\U +@q9.^AnV*V$>F6jCM[g(DJjB3rc&cqF*)MHG'8(RG^4U]H[C-gI=?ZqJ:N3&rdt6)L&Qf:LPUeD +?=@G[D/j]DI=['dK`It@V?!IlV?!IkVZ!FlW;ijoWWB0%rN-(&qlTn$qlg%(!3uC+rbqIIrbqdR +q3:cAo9B3trQG5b!6tMg!6tMgrQbPldF%sArR:bo!n5ZKrm_,%f@S[Sg&Kb,g"PnZqig]9nrl._ +I=6TqJ:`E+KnbA=M2I4MNK0']P*2#oQ'Rf)R@B\9SXuIHTqS3UUnsrdVl6SoWiE,$XKAV-Y-5&- +Yl:p*ZMLp+Z3(&fOT(CtQ^F/.S"#q> +StD^MU84T^Vl-MoX/rG+YctC=ZaI6N\@K2`]Y;.r_8=+/`Q-'Ab0/#RcHjncdaZdtf@S^0g=tH> +hV[8MioB([jlYail07L!rp1$[mdKW6naZ2@oCMVQo`Fj]p\jmdq>^ +JcC<$JcFC&o`"gfrqu]ks8)ckrqQNf!;?Eb&+oJao'u5l7Cu;>F,f;?'Ji:BF?i;>X2e:]4,i;#jGh4oRS63rhDB4oA(O:\mob:\dca +6iKFP62s7S6UsgG;Z0Jm;YX2i<;'>i8,l-Z8c;9]9E%Wa:&dug:]=2j;?'Pn;Z]ou[1Q??=.&I?t!MR@q0%\AS,TSBF8HgCMRa&D/O60E;jhoEcZ>EF`qqPGBeCZH@(!dI=6Qo +It3'#K)UB'KSBD[%YojsM*XKs6q'R98P2WLj%\?)!2]:a!2]WnrDiVnrDs)'='/T&=oV\&>Ph\) +>Q.n+>P:5T49.P?:ARcY:&o#-CB&,MD?"JRDuO\UDuO_UEW:(XF8g:\FoQX`G5ugcG6<)9H[GX; +"BJN&<)iTjqGd;kr`&;a4+)I)It3'$K7el4LPUeEMijWMuntX/rD)Xfeh1YPk^)Z2Cp(Zi.03Y>\D"r`/eqr)NYor)7re(6&!.k*!s*t#sl[Ab]s*suts+(0%rdt6)L&Qg=LPUeD +MMmFPNK0'\OHG]iPa.N#R$a;2S"-(AT:qsQUnjlcVl?\sXKAY0Yd(O@[C3QS\[oGd^;%J"_Sa@3 +a2lBFbKS5VcdC.geC<($f@em3gYL]Bhr*JQj5]4^k3(sml0@U6ljN4Kn*fc9nac8BoCW"S!quB_ +rV6Bfs8)WirVZWmo)=4?`rCP~> +JcC<$JcFC&o`"gfrqu]ks8)ckrqIE+p@e1Po^qbGo'u5h[obg&BY(f*9gVeC;sqdJhJrcd'bW +aN=8!s2k5^s3(Dc"3o-:ch!+bMuUWp_8-&drP/]T^qd_#^q[Y"rkJHH!l)OdrPANL!P`+CA,Ts< +AcH9DAUKZ@_Z%IM_YV1K_>qFL_>qFO8,c'Z8c23\9E.]a:&drg:]4)k;,UOn,;_UOo:C>Oo:I?On?ZoaRR3S"-(AT:hmPUSO]^VPg>jWW&n!X/rE%XTGZ/YPbX'Z1bL%Z1l'4^]2%A^\Y\ESg0er +S"#k7R$a5+Q'IStP*1rhO,o<\N/W[PM2@%ELPCP;KnTGXs+16%rIFotrdO-\s*jutrIFp!!.t3& +E.iq!L5(J>M2@+JN/WaVO,oBbP*2&pQ'Rc(R@9V8SXuIHTq\ +JcC<$JcFC&o`"gfrqu]ks8)ckrqI9'p@e1Po^qbGo'u5>s,phfhEphfY> +s(DdPARo7Z@:*AI>b7P\Sc5/ZS,\rVRI$=>RJh$mD>J/LD>oe#Pl?sHPQ7!GPkLC=QMOY^=8c5' +B6Aiinrrj3rf[>Fr^ZrYs%3,\s%EAcrD!;e!)NPi!`;inr_rhr!*0#!s&T2&r`K8*>Q.k8?!^iE +?XR;N@U`hXrac+BBDuQOBkhF!Ci+$,DJsLnE=-`-FEDYKG'A.TH2`+)H[L6iIXZcsJ:W9'K7ei2 +Knb>;LPYqd!K)g7MueH]aFsMem\KlZs/,gmrhfUkrhogrqPjRsXSo:$Y5GF$Y5>C(Yd(J2Z2q:L +r,;7Gs)7Oo!1!)=!mJj3rQG5b"O56;c-?75rQbJjrmC_n!n5TFrmLhq!S#[!f)F;#f_sLkPl$[; +P4OkkH[L6jIt3*%K7nr5LPUeEN/WaWO-,TgPa.N#R$a>3S"-(AT:hmPUSO]^VPg>jWW&n!X/rE% +XTGZ/YPbX'Z1bL%Z2Kg\P4Fb3OT1msSXc1=R[KP1Q^3o%P`q8nOcYWbNfB!VMi*@JLkph@L4t>7 +re(6&!.k*!s*t#sl@&\]s*suts+(0%re#0CKnY89LPUeDMMmFPNK0'\OHG]hPa.N"Q^F20S"-%@ +T:hmPUSO``Vl6VqXKAV.Yd(L?['mEQ\[oDc]t_=u_Sa=2`lH0BbKJ/UcHstee'uq!f@\d1gYCW@ +hr*GOioB+]k2tjjl07L!m-O--rpKmWnc&+Zo)SF^p&Facp\jmeq>U6fqu6NkrUTr=s2Y.i~> +JcC<$JcFC&o`"gfrqu]ks8)ckrqI9'p@e1Po^qbGo'u5Z"As:]OAf;Z0Jl;#F)j:f1*e;#*lh:f1%Or]C'@q`Xm?oK3"Hq+pf_r(m&^ +!DPoX6iTLP5mBYE8ki2^;Z9Pl;YX2i<;KVo8,c'Z8c23\9E.]a:&drg:]4)k;,UPqb)>Q.n, +>Ot#T4S2DF:]F2f:]=,gCB&,MD?"JRDuFYTE<'tVE<(%YF8g:[FTQc1FoHR`G5upfHN&9jI/[1H +tq<;]\k;ZE=5SXc1=R[KP1Q^3o%P`q8nOcYWb +NfB!VMi*@JLkph@L4t>7re(6&!.k*!s*t#sl@&\]s*suts+(0%re#0CKnY89LPUeDMMmFPNK0'\ +OHG]hPa.N"Q^F20S"-%@T:hmPUSO``Vl6VqXKAV.Yd(L?['mEQ\[oDc]t_=u_Sa=2`lH0BbKJ/U +cHstee'uq!f@\d1gYCW@hr*GOioB+]k2tjjl07L!m-O--rpKmWnc&+Zo)SF^p&Facp\jmeq>U6f +qu6NkrUTr=s2Y.i~> +JcC<$JcFC&o`"gfrqu]ks7u`krV.9)p@e1Po^qbGo'u51MZ8SHC1q6lARo7Z?sd8H>hdudg"HAWs47J+e^W*tdaA'@"jbH;b/qd%aT'B\b5]Za +bl>ofcKgG_MZL`4qnW9Jrk\WMs2"WKr4`6Ir5&BJ$,=9k@:3JP@q0'GAHR.9Uq6NBpqm$JrkeQK +!l@Gtr^d&\r(?u^s%NAcs%`Sir_WVls&/hp!`W0"r`08*=BJ^/>$>/0>QJ,:ra,\6@K'^:@q>RM% +q]HfBPD0qCMRa'D/O60E;jhaEcZ>EF`qqPGBeE4H3&A?rd=frJ,Xs!JV*lR!JH1+L'NKiLl$tGM +MqIm!f`5#rf7,BOcfX+s-!GIlE:2Yr1uQ^F20S"-%@StMdNU8+N[V5C/gW2]cr!irE(riQ4's0)=(oWeA!pqZmDqS)g@qS"8IS +Xc1=R[KP1Q^3o%P`q8nOcYWbNfK*XN/NRMM26tCL5(D9K`6W(JcLB#JH(,uId2@]If=irJH(0#K +)UE&KER!`L51TaM/8'-N/WdXO-#KeP*;/rQC!u,R[]e;St;UKTqeE[VPgAlWiN8(Y->.9Za@-K\% +0&]]Y2%o^qmn*`Pom=ai_fNc-FY_dF-Ooe^rF*g=k<;h;7&IiSrnXjQ5OdkNV6rlKdg'mI'H3nF +5uIncJFTo`"O`p&Ojbq#C0iqYU0gr;?Nardk*js*t~> +JcC<$JcFC&o`"gfrqu]ks7u`krV.9)p@e1Po^qbGo'u5bKqjd\Us-a"WR[X5Dqj7AOpmD#JphoM:r,2=q!0mJJr06r@qN_;O +QC!q?=8Gts=8uA)A9*6^nWWa2!g?,Er^d&\r(?u^s%NAcs%`Sir_WVls&/hp!`W0"r`08*=BJ^/ +>$>/0>QJ,:ra,\6@K'^:@q>RM%q]HfBPD0qCMRa'D/O60E;jhaEcZ>EF`qqPGBeE4H3&A?rd=fr +J,Xs!JV*lR!JH1+L'NKiLl$tGMMqIm!f`5#rf7,BOcfX+s-!GIl@]/.r1L$XoGR$Y5kg+Z2V'/ZN=u]DYe;IDW$cZb5f]abQ#fdblZ28 +c2Q#eci)5fdJhPre'upurRV##rn.2&mZdU4o9/d10m\1oI=?ZrJV/T.L5(M@M2R=PNfT9aP*;,q +QC!u,R[]h7re(6&!.k*!s*t#sl@&\]rdXots+(0%re(6("GMSb +LPYqdCl4.0N/is[OHG]hPEhE!Q^F20S"#t?StMdNUSO``Vl6SpX0&M,YctF>['d?O\[f>b]tV7s +_8=+/`Q-'Ab0/#RcHjncdaZdsf@S[/g=tH>hV[8MioB([jlY^gl07Kulg4!*mdKW6nF?MK!qZ'V +rq6 +JcC<$JcFC&o`"gfrqu]ks7u`krV.9)p@e1Po^qbGo'u5B4b^c@U`_P?X6o5qbd)cs&&\jr_NPjr_`SirD3>d!`(p@pH/@:qE=g?q)eRNrD*Di +rD38dqbQr]"&2Nc62j4I6OlFK5sn1::f:4j;Gg:h;Y*idAIiBcBP;*oC27U$D/F0.DfG\q$?C30 +FEMbMGB\:Wrd"TlI/\NpIXh?I!J,k%K)pXZre:Z5LkpnEMMd>kMuo!!NrG(@OHG\)P5g^GPj1sC +Sc#)XTDkMXU%>#P<<#to5DJ&>QA(->Q7t,>Q-bV4TIV4:@qKnY3ZKE$N'Jc1-!J,Xo^ +IK+cqJ,XuuJH1<$KE$T-Knb>;M#N6IMMmFPNfT6_OcklkQ'IZ%R$jD4S"6.BTV8'SUnsrdW2Zet +Xf\b1Yd1UB[C3QT\\#Mf^;%J"_Sa@3a2lBFbKS5VcdC.geC<%#f@\g2gYL]Bhr*JQj5]4^k2tjk +l0@R"m-O--n*fc8nc&(\oCV\Sp&F^cp\agdq>^ +JcC<$JcFC&o`"jgrqu]ks8)ckrV.6(p@e1Po^h\Fo'u5XqMX^!qMX*eqMPiB +CM@HpAn>L^@UNPL?!R?^s4RD(s47h5e^W*tda?Fgcd0k[bK@uLqoJfZrlP5arQP;dqi0m"r/:Ql +s2+TJ!5STM!PlPN_#M1K_#(tD_#%OC@Uiq[Ac?9FATETu[)2dZoYULAs%!)[r^m&\r_*8brCm>g +:J^pc!`;inr_rhr!*0#!s&T2&r`L=H>?b?;?!UcD?XR8M@U`hWA7]=aAnPdjBkhBuCM[keD?4Zp +rc'$#F*)MHF`qtQG^4R\H@($eI=6QoIt3'#JqAW-KS5'YL&m'cre^Z4!/pi8!f`5#rf@)@!0R8D +s-*JIrg!MLs-N\Os-`kTrLr9aCLs6p!W!:fuLpQ,B;rQ+WOq8W-Kci +S"#k7R$a5+Q'IStP*1rhO,o<\NJrgSMM[1GLPLV=KnY3ZKE$N'Jc1-!J,Xo^IK+cqJ,XuuJH1<$ +KE$UNKnb>;LkpnEMMmFPNK0']OcklkPa.Q$R$a>3S"-(AT:qsQUnjlcVl?\sXKAY/Yd(O@[C3QS +\[oDc]t_=u_Sa=2`lQ6CbKJ/UcHstee'uq!f@\d1gYCW@hr*GOioB+]k2tjjl07L!m-O-,mdKW6 +naZ2@oCMVQo`Fj]p\jmdq>^ +JcC<$JcFC&o`"jgrqu]ks8)ckrV.'#p@e1Po^h\Fo'u5J/FD%18p +BP1pgA7B"U?X@#CrLWhUqjd\Ur0mVQs-WhQs-WbQrL!POrb_:Fmqq]^s-3;Ds-[1Q??=.&I?t!MR@q0%\AS,OeBP;*pC27U$D>nDRDfG\q+*)FEFEM_LGB\:WH$Xd`I!g?jIXcit +J:W<(K7ei1L&Qf-LPYqds,$f7repoj-nr`^/,b:Hp +S!ob4R$X,(Q'@JqP*(ieO,f3ZN/W[PM2@%DLPCP;KnTGXs+16%rIFotrdO-\s*jrsrdb$"!.t3& +s+G]PL5(J>Ll$tGMiVg^V@V%_o0O6aN2KHbK\>Xd*^:jeCE.%f\,!5gtgfDi8ESRj5f=ak3(sml0@U$m-X3.n*fc9 +nac8BoCW"S!quB_rV6Bfs8)WirVZWmo)=4?aT$b~> +JcC<$JcFC&o`"jgrqu]ks8)ckrV.'#p@e1Po^h\Fo'u5?kE=?!^lF?smDP@UinYAS#IcB4tsmC2.O"Ci0/h!H2rVE?B4BFEDYJG'A.TH$O^^ +H[L3hI=?ZqJ:N3&JqJ]/KSBD[!JcL1M>rG5MuJY:NK0%uO8k:AOoCODPQ-mHQ2d0MQi3Ph\'>6%q,>PpVW4TJ:B:A@Wb:]YLl$tGMiVg^V@V%_o0O6aN2KHbK\>Xd*^:jeCE.%f\,!5gtgfDi8ESRj5f=ak3(sm +l0@U$m-X3.n*fc9nac8BoCW"S!quB_rV6Bfs8)WirVZWmo)=4?aT$b~> +JcC<$JcFC&p&=pgrqu]ks8)ckrqQNf!;?Eb%J98_o'u5u`!lDdirkJTM^qfla!5e`OrkSKKs2+eFs'bq8s'bq:!Fo[=Ad!%)RBOI) +_Z.OJ_Yh7L8H29Z9)hQa9`7]c:B+,h;#aDm;Z9Sr<)lrt$Lu2!F9%2?P$UR@:E\U +A7T7_AnPaiBPD5\CB86grb_aTE;jhlEcZ>EF`hkOGBe@XH?spbI!pElIXh?I!J,k%K*R'`Knb>; +LPYqd!fDnorepolI0 +i;_d6irnH)jlY_(kPscFl2KrKlg4N9r9jRQ!q>aMrfI2BqiUf3S"-(AT:hmOU8+N[V5C/gW2Zbr +WiN2%rN6(%ribjrrNH7(rN-(8rkIa4'V(Y^R[KP1Q^3o%P`q8nOcYWbNfF$s$]Bn!M26qBL5(D9 +K`6W(JcLB#JH(,uId2@\IfFosJH(3#K)^K'KQ)X"L51P?M2@+JN/WaVO,oBcP*;,qQ'[l*R@B\9 +SXuIHTq\ +JcC<$JcFC&p&=pgrqu]ks8)ckrqQNf!;?Eb%J98_o'u5C_1H"CM@Hp +AS#@\@:3GK?([_]SbnrVS,JfTR/iWRQiEHQRJWBORJ1RjDY7iKQC!o'm?RI4pQklGr`8quqc<_u +"'o\gM#EV5PPC=?8H29Z9)hQa9`7]c:B+,h;#aDm;Z9Sr<)lrt$Lu2!F9%2?P$UR +@:E\UA7T7_AnPaiBPD5\CB86grb_aTE;jhlEcZ>EF`hkOGBe@XH?spbI!pElIXh?I!J,k%K*R'` +Knb>;LPYqd!fDnorepo3S"-(AT:hmOU8+N[V5C/gW2ZbrWiN2%rN6(%ribjrrNH7(rN6*_nr`[.'V(Y^R[KP1 +Q^3o%P`q8nOcYWbNfF$s$]Bn!M26qBL5(D9K`6W(JcLB#JH(,uId2@\IfFosJH(3#K)^K'KQ)X" +L51P?M2@+JN/WaVO,oBcP*;,qQ'[l*R@B\9SXuIHTq\ +JcC<$JcFC&p&=pgrqu]ks8)ckrqQNf!;?Eb%eTA`o'u53ug;=76\:]4&\4S1`74Sq;A:Adoe:Amuc;#3ud:'"-crD*DgqbI2Y +r^$QL!($TNqa1ZX7nZTS:f1(f;Y!cd<;oGg8c23\9E.]a:&dug:]=2j;?'Pn;Z]ou,7L51P?reU]6Mi7Rn!f`5#rf@)@s,m;Ds-*JIrg!MLrg3SNs-`kTqj[ST +rLN\Sr1l7h*>lIt'4Sh2@;>sDl:[V!Q:]+&gD#eJQ +DuXeVDuO_SEW'qWF8g=\G5c[eG^4T5HN&6mI!^8:uQ^F//S"#q>StD[LTq\tq +<;]\h;A>XjS!ob4R$X,(Q'@JqP*(ieO,f5!N!kQ$M2@%DLPCP;KnTGXs+16%rIFotrdO-\rdOls +rdb$"s+:9's+G?FL5(J=Ll$tGMiU6fqu6NkrUTr=s2k:k~> +JcC<$JcFF'o`"gfrqu]ks8)ckrqQNf!;?Eb%J98_o'u52NW+n6NW+n6 +NW+n-N=p,GCMRWtB4YXa@UWYO?d(*8c;9]9E.]a:&dug:]4)k;,U?kE=?!dM; +!FT@8@KBtLrac+BBDuQFBkmW_!GlWPD?4Zprc%sZF8g7^Fa!b.!I/nhH3&A?rd=frJ,Xs"JV&LQ +K)pXZreCH.!/UW2s,$f7rf$l:!07#=s,[5CrK@2Es-3JIs-EYNr0[MPrgN\Qr1*YTp=fN#!o2Vf +rn[Y4qr%M5!94"L$YPGF#YPt^&XoGL&WrTp"^*B/;S!ob4R$X,(Q'@JqP*(ieO,f3YN/NUOM2@%DLPCP; +KS9>W!ePuSrIFotrdOQhs*XQhrdOlsrI=s#JqEuS!JH1+L1l?uM2@+JN/WaVO,oBbP*;,qQ'Rf) +R@9V8SXuIHTq\Yd*^:jeCE.% +f\,!5gtgfCi8ESRj5]7`k3(sml0@U6liukFn*fc9nc&([oCW"S!quB_rV6Bfs8)WirVZWmo)=4? +ao?k~> +JcC<$JcFF'o`"gfrqu]ks8)ckrqQNf!;?Eb%J98_o'u5ZDr`B"ur`B&!s&T>+BQf)nrKRAIp65H9>[1Q??N+:4?t'%D!Fo[>AH?CUrb)=HCAquLCi0/h!H2rVE<1*$rcA0`G5c[dG^9:7 +!IK4nI0"eHrdY'$JqEuS!JH1+LB!#/M#N82M?&S6N;nk;Nr>%=O8tFAP5gaGPl6mIQN!6KR/`TR +ReiNOSGSlNU\pqaV>d@kVZ<[pWW0!qX8T."XoGR&XoGR$YPta+Z2V'/ZN.B-D#eJQDu,a\PlI$H +PlAo*blZ28c2Q#echl)fdJq\qeGn)!f)O;#ec=>$fE9gZf\-7go990['d?O\@K2`]Y;.r_8=+.`Q$!?aihlPcHjkbdaQ^rf%8R-g=tE=h;7)J +iSrnXjlY^gkiq?sli-5TmI'H3nF?&JncA@SrUg6cp\4X]rqZTjqtp?irVc +JcC<$JcFF'o`"gfrqu]ks8)ckrqQNf!;?Eb&bP\co'u5b!`)Qdp,r48r]Kg7r]C6V:/:dar(d2drD3Pm:f.$b +s%`Mgs%rDb"[YRC6:!p:5QF+J6N9CV6qBsG;,[Bjs&/Ges%*,\rC[)_s%NAcs%`SirD3Pm;H!Km +s&8tur`9&#!*K5'#?k>9>[1Q??N+:4?t'%D!Fo[>AH?CUrb)=HCAquLCi0/h!H2rVE<1*$rcA0` +G5c[dG^9:7!IK4nI0"eHrdY'$JqEuS!JH1+LB!#/M#N82M?&S6N;nk;Nr>%=O8tFAP5gaGPl6mI +QN!6KR/`TRReiNOSGSlU;ufko;ufqm<;onr5qb'>5hb)>kqV&>QJ&6pH8FVorGhdVs)\3^rcS3`rce?ds*=Tir-S0=r`/GeqGm/e20aCmH[L6j +It3*&K7nu6Ll%"IN/`jYOHG]iPa.Q$R$jD4S=Q7CT:hmPUSO]^V5C/gW2ZcqWWK6&XSo:#Y5GL! +Yl(^(Y5GF%XT,@"['d?O\@K2`]Y;.r_8=+.`Q$!?aihlPcHjkbdaQ^rf%8R-g=tE= +h;7)JiSrnXjlY^gkiq?sli-5TmI'H3nF?&JncA@SrUg6cp\4X]rqZTjqtp?irVc +JcC<$JcFF'o`"gfrqu]ks8)ckrqI0$p@e1Po^qbGo'u5V7L_>h@P_=teJ@UNUC +@JjL5@K'^@A7]>!Oeo\,rPAKM!5\HI!(d)\r(?u^s%NAcs%`Sir_WVls&/hp!`W0"r`0)%=BPQ* +#?k>9>[1Q??N+:4?t'%D!Fo[>AH?CUrb)=HCAquLCi0/h!H2rVE<1*$rcA0`G5c[oG^4R\H@($e +I=6QnJ,Xs'JV&K+K7no3reCH.!/UW2s,$f7rJUf;NfO+"s,d8CrK@2Es-3GHs-EYNqj@ANrL3SP +rRpu"rS%D/h;/(es53e5s5Et:!9="g@? +e,SjSm)/_;rPLO;G^=[_I=6TqJ:`E,KnbA=M2I7NNK9-_P*2&pQ'[l*R@B\9SXuIHTqS3UUnjia +VPg>jWN#lss/Z1$r2oq#pTOLtr2p"#s/Z*u!NE$g^AY_d^:g#)R@'A.QBd`"P`q8nOcYWbNfB!V +Mi*CKM26rdL'!'^K`6T*Jq8LOJH(,uId2@\IfForJ-(:RK)UB'KSBD[D23q(M2I4MN/`jYO-#Ke +P*D5sQC!u,R[]hkWiN5'Y-5(7Za7$I[^`lZ]=bhk^VI_'`5Ta:aN;TJbg+M[ +dF$CleCE1&f\5'6gtgiEi8EVTj5f=ak3(sml0@U$m-X6?mfDqJrpg-^o^r.Us7ZKerV6EgrqcNh +rqu]mo)=4?b5Zt~> +JcC<$JcFF'o`"gfrqu]ks8)ckrqI0$p@e1Po^qbGo'u5$G39>[:WAra,\6@K'^:@q>RM!G6!DBE;g^rbDOND>nDRDfG\q!HN8\F9-N-rc\cqH$O^^ +H[L3hI=?WprdY6)JqAW-KS5'YLB!#/M#N82M?&S5Muo!!NrG+>OT1IAP5gaGPl-gHQN!6JR/WNP +ReiNPUA1M]V"gedVZ*LnVuWgrWr/prXT#=%Y5GF$Y5PR&YQD)8ZMq03ZtsRQD$#ugQM6[0Pl$aG +PlJu+c2Z&hc2Grechl)gd/_Voe,@eqeH4=RfDaD)f@\a/r06f:s-3DEnWNm8rKK3aG^=[_I=6Tq +J:`E,KnbA=M2I7NNK9-_P*2&pQ'[l*R@B\9SXuIHTqS3UUnjiaVPg>jWN#lss/Z1$r2oq#pTOLt +r2p"#s/Z*u!NE$lOo1=>NujCDS!ob4R$X,(Q'@MsP*1rhO,o<\N/W[PMM[1GL]3#0KnP-YK*$XU +Jc1-!J,Xo^IK"]qJ,Om!JV&LQK)pXZre>9FLl$tGMi +JcC<$JcFF'o`"gfrqu]ks8)ckrqI-#p@e1Po^qbGo'u5c;#a>h4o%564oRS<49&%T:&n)d:Amub;#=#g:Amuf;"[Wa +:B*WZ63'=L5QF+I63B_M9i1ge!)`_np/:r^r^m#[s%EAcrD!;es%iVjs&&eor_ikt?b?;?!Ue9?NFPCraGnPVJ%>Q%e->?^r/r`fP2>[1S-4S2MN;#a>c:A@W\;#bD3 +DZ"GPE;jkUEWC1[FT-F^G5c^aGl;pkH[:!bHhCG=/9Ll%"J +N/`mZOckllQ'I]'R$jG5S=Q7DTV8'RUSO]^VP^8hW2ZcqWrK."XSf4!Y4o-tY5GF%XT,@"WWB)t +r)ESmr)3Jj*`>k)R[KP1Q^3o%Pa%ApP*(ieO,f3YN/NRNM2@%Dre:K.KS9>W!ePuSrIFotrdO-\ +rdOlsrI=s#JqEuS!JH1+L2D^%M2@+JN/WaVO,oBbP*2&pQ'Rc(R@9V8SXuFGTqS6WUo(&fWN*## +Xfek3Z*UdD[^N]V]">Vg^;%J#_SjF5a2lBFbKS8WcdC.geC<%#f@\g2gYCWAhr*GPj5]4^k2tjj +l07L!m-O--rpKmWnc&(\oCV\Sp&Facp\jmeq>U6fqu6NkrUTr=s2t@l~> +JcC<$JcFF'o`"jgrVZWkrqZWjrV.-%p@e1Po^h\Fo'u5g=k65r7M&$&D#C]daHOjd*L%_bfe/PbK9\'s2b>b +bKTmF!0I/?oT&s4qi:W7rJ^`p"ieO#`5BIk_uIUQ_Z7RQ_Z[im_8*n^_>qFC_?.Qj^&DL@@/j[5 +@/jX?@UinYGDr9)rPJQM!5e`Os2+cO!_>mSr(?u^s%NAcs%`SirD3Pm;H!Kms&8turDir#=T2J' +=o_e+>R+P@?=.&I?t'%D!Fo[>AH?CUrb)=HCAquLCi0/h!H2rVE<1*$rcAQkG'8(RG^+L[H@(!d +rd>$#It*!!JUrFPKE$T)L&Qi,LB*/0M>rJ5MuJ\8NW5%F%X8T%"WMlcpVZW!ePuSrIFotrdO-\rdOlsrI=s#JqEuS!JH1+L1uF!M2@+JN/WaV +O,oBbP*2#oQ'Rc(R@9V7SXuFFTqS3VUnsueWN)u"Xf\e2Z*L^C[C3QT\\#Mf^;%J"_Sa@3`lQ6D +bKS5Vcd:(fe'uq!f@\d1gYCW@hVd>NioB([jlYail07L!rp0jVmdKW6nF?MK!qZ'Vrq6 +JcC<$JcFF'o`"jgrVZWkrqZWjrV.-%p@e1Po^h\Fo'u5.rBD>S/JD>.rB +D&./3Df0E-C2%?oARo:[@:3GK?(dj_T(JTOSGerVRf8]VR$X0=R/`TRR.tLqD>8#KDtn5KD#eJP +QiEBDQ2R$KQi36FQiEBKQi*0LPlQjCRM!G6!DBE;g^rbDOND>nDR +DfG\q!HN8\F:<;8G'A.TG^4U]H[C/>I0Y4NIt3'#JV*lRs+CB+reCH.!/UW2s,-i7rf$l:s,R)> +s,d8CrK@/Ds-3GHrg*PMq3_2Ms.T=aqP3q`pndqds/5mq!3,strN#mup9"@t!3c:(s0;U0rj2Q? +!,VLKr0Hu?l]h:3!6kDd!m]'8rQbAf!mo9>rm:\m!7Lhprm^qtrRV,'f@U#S!86Lun<3d7rffjW2]`qs/Z1$ +qQ9IoqQ9aus/Z*u!i`,srhfanqiUi=q2Z;[R@'A.QBd`"PEM)kOcYWbNfB!VMi.Lj!JlO1L'!'^ +K`6T*Jq8LOJH(,uId2@\IfForJ-(:RK)UB'KSBD[BnqM$M2I4MN/`jYO-#KeP*;/rQC!u,R[]e; +St;RJTq\?YV5L5jWiE/&Xfnt6ZEppG[^WfX]=bhk^VI\&_o9U7aN2NIbg"GZd*^:jeCE.%f\,!5 +gtgfCi8ESRj5]4^k3(sml0@U6liukFn*fc8nc&(\oCV\Sp&Facp\jmeq>^s2t@l~> +JcC<$JcFF'o`"jgrVZWkrqZWjrV.$"p@e1Po^h\Fo'u5%r_WAeq+q&gp/(cbs#p9Dr&t'Bpc\X@q`Xm?rB($RpJ1W^"&Mci;"d]_ +;"d]^:AmKX63]_@5X.Iu62a+P7S-9Mpepre!_>mSr(?u^s%NAcs%`SirD3Pm;H!Kms&8turDir# +=T2J'=o_e+>R+P@?=.&I?t'%D!Fo[>AH?CUrb)=HCAquLCi0/h!H2rVE<1*$rcAQkG'8(RG^+L[ +H@(!drd>$#It*!!JUrFPKE$T)L&Qi,LB*/0M>rJ5MuJ\8NW5%?gu.r`f>+r*0,)s'5k74?Pbi4?Yk*4RZ/I;#X5m +:/=V[peUW\!,_[PrGV[SrGhgW!-A-]rcS3`rHJ9d!."Ee!dfjW2]`qs/Z1$qQ9IoqQ9au +s/Z*u!i`,srhfdo<;]\n;Ya0*R[KP1Q^3o%P`q8nOcb`dO,f3YN/NSmM#iEfre:K.KS9>W!ePuS +rIFotrdO-\rdOlsrI=s#JqEuS!JH1+L1uF!M2@+JN/WaVO,oBbP*2#oQ'Rc(R@9V7SXuFFTqS3V +UnsueWN)u"Xf\e2Z*L^C[C3QT\\#Mf^;%J"_Sa@3`lQ6DbKS5Vcd:(fe'uq!f@\d1gYCW@hVd>N +ioB([jlYail07L!rp0jVmdKW6nF?MK!qZ'Vrq6 +JcC<$JcFI(o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nd"^Sn*fZ1m-FYoj,EPgn;d=*r/MSSNfK0A +EcH#8D/3m#BP(gd@q&kR?X@":h>c7/gAfk(f`0P6f%&9uda?Ihcd'h\bfe2Pr5f&^aiV^#O8b7? +O8+b2O8=kCNQ/rV`l?!:`5M;cs2"cPiPGT.r*o\6s'bn7rF,_8"*'*eZMVN8_>hCP8c;9\9E.]a +:&dug:]=2j;?'Pn;u]esQ.k.?!dM;#@LtK@U`hWAH$-@AnV*V!GQOmK)_CqsORTnb81=an3S"-(AT:qsQUSO``Vl6VqX0&M- +YctF>['d?O\@K2`]Y2(p_8=+.`Q#s>aihlOcHab`dF-Ooe^rF*g=k<:h;7&Ii8WeWjQ5OdkNM0p +lKdg'mI'uB!V#XYo)J:]o`"O`pAamcq#C0hqYU0gr;HTbrdk*ms*t~> +JcC<$JcFI(o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nd"^Sn*fZ1m-FY>q/5M8pMT_BokaPCqel:J +'6A26Df0E-C2%?nARo:[@:*AJ>lLAsT:Y\Gr1*bUrL3_Rqj7GQR$d_eph]qHr,2=KqelFNr0RGL +!L8uGQ2R$IQiEBGQi<$G51>QJ,:ra,n<@:Gqj%/Hrg*VXrLs(^qkO%aq5+%erMT[pri5sur2fUos/l@*r361*rj)R1pMK_lnWiF) +rg!?)rQb8crm1YmrmLeprm^tus47)!"PD>YfTbQ_mZRR51R**.H$XgbI=?]sJqJ]0L51SAMMmFQ +O,oBcP*;/rQC!u,R[]e;St;RITqS3UUnji`VZ*IpW2ZcqWrB(!XR*(gXT,@"WrK'uW;`\!VPU,b +Ulgf;OSOq;RJrQdQ^3o%P`q8nOcYWbNfK*XN/NSmM#iEfre:K.KS9>W!ePuSrIFotrdO-\s*jrs +rI=s#JqEuS!JH1+L2Md&M2@+JN/WaVO,oBbP*2#oQ'Rc(R$sM6S=Z=ETqS3UUnsrdW2ckuXf\e2 +Yd1UB[C3QS\[oGd]t_=u_Sa=2`lH0BbKJ,TcHjncdaZdsf@S[/g=tE=hV[8LioB([jlY^gkiq?s +lg4!*mf)YUnF?MKs766_rq6 +JcC<$JcFI(o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nd=pVn*fZ1m-@VL<:)jL4nq5.4nUr-4VU)$ +EcH#8D/3m#BP(gd@q&kR?X@"8:]4#g:]=2j;?h)3!F9%2?O'tI@:E\U@q>RM!G6!DBE;g^rbDOND>nD]DfBZ8EH6,AFEDYJG5c[dG^9:7 +#CCiGI=6QnJ,XuuJH1<$K*$^[L&Qi,LB*//M#rQmMuAV7N<#";O8k=@Oo:IBPQ$gDQ2[*KQiC"b +;ttt>5VV&>5hb)>l@n)>lJ%.4T7MB53YrC;#!iZ;#P;1DuO_SEW0tYF8g:[ +FoHR`G63#7H2`*iH2`-iHN8HaW!ePuSrIFotrdO-\s*jrsrI=s#JqEuS +!JH1+L2Md&M2@+JN/WaVO,oBbP*2#oQ'Rc(R$sM6S=Z=ETqS3UUnsrdW2ckuXf\e2Yd1UB[C3QS +\[oGd]t_=u_Sa=2`lH0BbKJ,TcHjncdaZdsf@S[/g=tE=hV[8LioB([jlY^gkiq?slg4!*mf)YU +nF?MKs766_rq6 +JcC<$JcFI(o`"gfrqu]ks8)ckrqQNf!;?Eb%eTA`o'u595rK-r< +'m+M:EGo`2CMINrAn>L_@UWVN?c7/g&Th'f`0P6f%&9uda?Ihd*L"^bfn8QqT8,cqi:<0 +s,I*"r5S`T!6"NIrke]Qrk\ZQrke]Qm_\q?!PZ5G@K9j9@f9a6@/aR:DM+=Zq8*-Jrk\]P8c23\ +9E.]a:&dug:]4)k;,U?kE=?!dM;#@LtK@U`hWAH$-@AnV*V!GQrJ5 +MuAV7NW5%;O8k=@Oo1CAPQ$gEQ2fG7fDaG"g&'M$g]$".h#cHjhu;R4iVhg9j9+N+kNDg-rosIJ +rp'RNrU'ROq/9M2@.LN/is[OckllQ'I]'R$jD4S=Q7CT:hmOU8+N[V5:'gVuN[qWVrjrX8T-lXo5@#X8K!t +WW/prVZN`lV>d7mUS=HUrkA0@s-NhRQN!-UP`q8nOcYWbNfF$s!K2j7M#iEfre:K.KS9>W!ePuS +rIFotrdO0]rdOlsrIFp!s+:9's+CB+re>?HLl$tGMi3S"-(AT:hmP +USO``Vl6SpX/rG+YctC=ZaI6M\@K2_]Y2%o^r!t,`Pom=ai_fNc-FY^dF-Lne^i@)g"P39h;-rG +i8N\Uj5f=akNM0plKdd&m-X6?mfDqJrpg-^o^r.Us7ZKerV6EgrqcQirVZTlo)=4?bl<1~> +JcC<$JcFI(o`"gfrqu]ks8)ckrqQNf!;?Eb&+oJao'u5.r1D>8#DD=_TBD>e>e +D00i=EGo`2CMINrAn>L_@UWVN?tUSc##WS,SlTRJNeAOD>J)ID#eJHDuOYOQi36H +Q2?mHQN3?GQiE?OQ2[*IQi<pQbcC!L$+Q9)hQa9`7]c +:B+,g:]aKl;Z9Vp<<#tt$G39>[:WAra,n<@:F8g7^Fa!b.!dK!9rd"TlI/\QoIK4lsJ-(:RK)UE&KE-`*LB!&/M#N82MZ8V5N;nn; +Nr>%=OT(C?P5^[EPl-dIT:l+UqP*k^r1s@h!2TUjr20Fj!N/9M2@.LN/is[OckllQ'I]'R$jD4S=Q7CT:hmOU8+N[V5:'gVuN[qWVrjrX8T-l +Xo5@#X8K!tWW/prVZN`lV>d7mUS=HUrfHo9s-NhRQN!-UP`q8nOcYWbNfF$s!K2j7M#iEfre:K. +KS9>W!ePuSrIFotrdO0]rdOlsrIFp!s+:9's+CB+re>?HLl$tGMi3 +S"-(AT:hmPUSO``Vl6SpX/rG+YctC=ZaI6M\@K2_]Y2%o^r!t,`Pom=ai_fNc-FY^dF-Lne^i@) +g"P39h;-rGi8N\Uj5f=akNM0plKdd&m-X6?mfDqJrpg-^o^r.Us7ZKerV6EgrqcQirVZTlo)=4? +bl<1~> +JcC<$JcFI(o`"gfrqu]ks8)ckrqQNf!;?Eb$hX&]o'u59>[1Q??N+::?t!JQ@UinYrac+BBDuQFBkmW_$uBctDJjB3E,flGm8Wm]r`&hr +s&T,#q,dW"r`]8)qca#(qcj,*q-gH@1-hIt3*%K7nr5LP^kGN/WdXO-,TgPa.N#R$a;1 +S"-%@StD[LTq\sss/H$srhfgpV5=0e"/DTaU&Isb;?*!a +Q^7W9$'^X:P*(ieO,f5!MueioreUZ3L]3#0KnP-YK*$XUJc1-!J,Xo_IK"]qJ,OotJcC?%KE$T) +L&QgFLPUeDMMmFPNK0'\OHG]hPE_>uQ^F//S"#q>StD[LU8+N\VPgAlWiN5'Y->.8Za7'J[^`lZ +]=bhk^VI_'`5T^9aN;TJbg"GZd*^:jeCE.%f\,!5gtgfCi8ESRj5]4^k3(sml0@U#m-O--rpKmW +nc&(\oCV\Sp&Facp\jmeq>U6gqu-HjrUTr=s31Ln~> +JcC<$JcFI(o`"gfrqu]ks8)ckrqQNf!;?Eb%J98_o'u5.:ObrD!;es%iVjs&&eor_rhr!*0#!s&T2&r`T8)!*fG-s'5V2ra,\6@K'^@@q9+] +AS,Oerb)=HCAquRCi+$,DJsH4rc%sZF8g7_F`qs-G6)r6rd+Tk!.=co!e,WKrdY'$JqEuSs+CB+ +rJ(?-!/UT1s,-i7rJ^c9s,R#uQ^F//S"#q=St;RITqS3UrhKRkVZ*LnW;ijp +Wr9!iXSo3tWrK'uW;WUqVPU-gU]I6brh0FeT:VYL]`sjjQBd`"PQ$^KOcYWbNfF$s#)e@qM26tC +re:K.KS9>W!ePuSrIFlss*j9^rdOlsrIFp!s+:9's+CB+re>`SLl$tGMic2W:~> +JcC<$JcFI(o`"gfrqu]ks8)ckrqQNf!;?Eb&+oJao'u5t\Sb8NPS,8WSRJ`HPDY7lGD?=`oDYe5HDY\5IQi36J +Q2$[T9E%W`:&dug:]=2j;?'Pn;u]es +Q.n->l\41?NFPCraH+BA7T7_AnG]TBE;g^rbDaTD/F0.Df9UoE<1*$rcA3a +G'P5UUE +PlIESU&1S\U\^ecV>d@iVZNfrWVrgsX7r^mXo5C&YPYR'Z2M!,D#J5DQKsh8PQ7!=PQB"QrlkDe +"4#6=cMc)gd/MGkdf%YoeH4=Pec+,&f@JO)fDUs#PPC=>Ont7>P:q*'G^4U^I!pHoJ:W?*KnbA= +M2I4MNK0']OckomQ'Rc(R$sM6S=Q7CT:hmOU8.^`!Mu[mVuN^qWVidpX7NFkX8K!tWW/pqVZN`l +V>d7kUS@a]"/)9XT(n?NR$X,(Q'@L3Op-u0O,o<\req&>MM[1GLkkta!el;\rdt9(JV!cMrdXrs +l[Ab]s*suts+13%s+C?)!/:E,HA@<5M2I4MN/`jYO-#KeP*;,qQC!u+R@B\9SXuIHTq\o(2JFrUg6cp\4X]rqZTjqtp?irVc9cJcF!pJ,~> +JcC<$JcFI(o`"gfrqu]ks8)ckrqQNf!;?Eb&+oJao'u5L^@UNPM?!L3&r(m8d!)NDer(m5e!)NAdpceL:q`a^:q`b$CpeL`]s%`#Y +!)WVir(d/cnkK0Zqa(brD!;es%iVjs&&eor_rhr!*0#! +s&T2&r`T8)!*fG-s'5V2ra,\6@K'^@@q9+]AS,Oerb)=HCAquRCi+$,DJsH4rc%sZF8g7_F`qs- +G6)r6rd+Tk!.=co!e,WKrdY'$JqEuSs+CB+rJ(?-!/UT1s,-i7rJ^c9s,R#F_m8<^VqGI5g!)`8_!,_[Ps).mVrG_gX +rH%s[!d/U,rcJEgGB\:WG^045rHeKj!.=69qGm/ep/NbhGBeCZH[L6jJ:N3'K8#&8Ll%"IN/`jY +OHG]iPa.Q$R$a>3S"-%@StD[LTq\=]U]I^S#+1aCQ'IStrfRGIOH5H_NW+k@Mi*@JLkpicL'!'^K`6T*Jq8LOJGt&uId;F]IfFor +JH(3#K)^K'KE-`*L3eW2M2@+JN/WaVO,oBbP*2#nQ'Rc(R$jG5S=Q7DTV8*TUnsrdW2ZetXKAY/ +Yd(L?['mEP\[f>b]Y;.r_8=+.`Q$!?aihlPcHaeadF6Upf%8O+g=k<:h;7&Ii8N_VjQ5OdkNM0p +lKdg'mI'E2n*ol;o()DDo_nFap@n=[q#:*hqYU0gr;HTardk*os*t~> +JcC<$JcFI(o`"jgrqu]ks8)ckrV.$"p@e1Po^h\Fo'u5L^@UNPM?!Q:DhVJ1d"l%bag"=sTfDa>%e^OKF#gq#FcHa\Yb0'_*q2PN9NfNss +plPH8qi:W9s,d9'!QiCZ`W=&skJR)3rPSKKrPSTNs1o7V@:3GM?t!JO?t!PT@U`bSrEo_FMPn,] +_Z!1-9E.]a:&dug:]4,i;#jMm;Z]ouQ.k/?!^k:?NFPCraGq=A7Y[N!G6!D +BEr6dC27U$Ci0/h!H2rVE<:0%F8g7^Fa!b.s*+Nhrd"WmI!kpA!e,WKrdb$"!.t0%!ec8]rItB/ +Lku"ds,-i7r/CZ8s,R#n]1[LfDkWarPeWQs2G#VrknBF!5n]Ns2-O5GB\:X +H@('gIt3*%K7nr5LP^kFN/WaWO-#NfPEhE!Q^F20S"#q=St;RITqS3UrhKUlVPa?js/>ssql94f +qPsRpri#gos/,gmrhKRiUAghmTV%jJSt2CA]Y+3V$C@'EQ'IStP*1rhrf7GINJrgSMi*@JLkpic +L&m!]rIY0'JV!cMrdXorm!\k^s*suts+(0%re(6(FG5I(LPL\BM2I4MN/`jYO-#KeP*;,qQC!u+ +R@B\9SXuIHTq\ +JcC<$JcFI(o`"jgrqu]ks8)ckrV.*$p@e1Po^h\Fo'u5L^@UNPM?!O+tU&L\cT:YqNopl#Nr0mYRrg&!HiSbGQ2mfH2`*kH[L5?I0+kIJ,XuuJH1<#K*$^[L&H`-LPUcbM>rJ5Mu8P6NW5%:O8b[M +DZ4SNP5CsOUA:S\V#I4jVYm@lVuWgpWrK-qX8o=!Xo5F%YPYR(Z2M!*C]\I>Qh?[/Q1't9bQ,ob +cMl/hd/DAjdf7bueCE'urmgnss4@.4m$%:/qiU`ssql94fqPsRpri#gos/,gmrhKRiUAghm +TV%jJSt2CANfO(!$C@'EQ'IStP*1rhrf7GINJrgSMi*@JLkpicL&m!]rIY0'JV!cMrdXorm!\k^ +s*suts+(0%re(6(FG5I(LPL\BM2I4MN/`jYO-#KeP*;,qQC!u+R@B\9SXuIHTq\ +JcC<$JcFI(o`"jgrqu]ks8)ckrV.0&p@e1Po^h\Fo'u5b>4?W=#qEFg?n3$M0!'K^5 +!'L*@(3anCF)c/:DJX*'BP1pgA7B"U?XI)Dr_WMgrD!>gq,$c\qG?uOr]U0Cs#p!Q.k/?!^k:?NFPCraGq=A7Y[N!G6!DBEr6d +C27U$Ci0/h!H2rVE<:0%F8g7^Fa!b.s*+Nhrd"WmI!kpA!e,WKrdb$"!.t0%!ec8]rItB/Lku"d +s,-i7r/CZ8s,R#d7kUS@a]#G@]]St;LCSGQ.jQ^3r&Q'@JqP*(k*Nsgu-N/W[QMM[1GLkkta!JQ4*K*$XUJc1,u +J,Xo`IK"]qJ,OotJH1<$KE$UHKnb>;LPUeDMMmFPNK0'\OHG]hPE_>uQ^F/.S"#q=StD[LU8+N[ +VPg>kWiE/&Xfnt6ZEppG[^WcW]"G\h^V@V%_SjF5a2lBFbKS5Vcd:(fe'uq!f@\d1gYCW@hVd>N +ioB([jlYail07Kulg4!*mf)YUnF?MK!qZ'Vrq6 +JcC<$JcFI(p&=pgrqu]ks8)ckrqQNf!;?Eb!VH!_nd"^Sn*f]2m)]0b!0,ThrJg`8lAla-G^":P +F)c/:D/=!%BP1pgA7B"U?X@%;huDO5h>Z12gY1?[f_jA#ec=8!dgFONcd0n_c-+8Pao.;!Nqn\7 +Nr4t4OS=e@ONbnjaiMQDrPelW`9>,7_Y_7H_>qLM_Yq:QAn#4Xra5S2!+Pq;#\%4N?smDkR'lb, +s%<;ar_38bs%`Sir_WVls&/hps&B"ur`0)%=BPQ*!a8f4r`f\6?=$uG?smFB@L$CRA7]=aAnV*V +#AIpfCMRa&D>nDXDfBZ8EH6)@rcA3aG'Ll$tGMiYd*^:jeC<($f@em3 +gYL]Bhr*GPj5]4^k2tjjl07L!m-O--mdKW6naZ2@s766_rUp3a!;HEds7u]kqtp?ir;H3cJcF$q +J,~> +JcC<$JcFI(p&=pgrqu]ks8)ckrqQNf!;?Eb!VH!_nd=pVn*f]2m$Va.D=MN.D=)63D&7MCGBJ"K +EH#f4Chm`uB4b^c@U`_P?=!Q)s.TFb!M>t\Sb8NQS,Si\S!oe6R@%jaDYJ#GDXhZFRK&ZOQiE?O +Q1gO:QiEBKQ2[*KQiEBNQ2HmCPlR-KPlk)g=',2uq,dSs!bZe:r0.,Es%<;ar_38bs%`Sir_WVl +s&/hps&B"ur`0)%=BPQ*!a8f4r`f\6?=$uG?smFB@L$CRA7]=aAnV*V#AIpfCMRa&D>nDXDfBZ8 +EH6)@rcA3aG'ldJ_Mje,Ro!e^i=Mec44rPjFV2P5:=;Oth*&GBeCZH[L6jIt3*&K8#&7Ll%"I +N/`jYOHG]iPa.N#R$a;1S"#q=St;RITqS3UrhTRj!2f^ms/>prl`0r`ri#dns/#dmrhTRh!2BId +,+tR#St;LDS=?":R@'"pO-Z&rP`q;oP*(ieO,f3ZN/W[PreUl9LPLV=KnY3ZKE$Q'Jc1,uJ,Xoa +IK"]pJ,Om!JV&LQK78K-Knb>;LkpnEMMmFPNK0'\OHG]hPE_>uQ^F/.R[]hj +WiE,%Xfnt5ZEpmF[^WcW]">Vg^;%J#_Sa@3a2l?EbKJ/Ucd:(fe'umuf@S^0g=tH>hV[8LioB([ +jlY^gkiq?slg4!*mdBQ4nF?&>o)J:]o_nI_p&Ojbq#C0iqYU0gr;?Nardk*ps*t~> +JcC<$JcFI(p&=pgrqu]ks8)ckrqQNf!;?Eb!VH!_nd"^Sn*f]2lr3mFq)n@6!'^L^@UNPL>u1Dqr(m8d!)NDep.tT_q*+O9kbpJ(]a +r(d)alV7IE62WtJ62j1[6UF()6:4(*5sIM"8l>Rd!E<"s;ZBAh9E%W`:&dug:]=2j;?'Pn;u]hs +Q.k4?!^iE?XR8MraH+BA7T7_AnG]TBEr6dC27U$Ci0/h#B+R#EH-#>F8g7_ +F`qs-G63#7H2`*kH[L5?I0+kIJ,XuuJH1<#KE$T)L&Hc+L]<2/M>rJ4MuAV2;ZJrZ49%GA4oUT> +<;]\m<;BPk5qe.>$5#->5qh,>l@t&>QJ,:q`FjUqGQu`pe^lar_NSlm83h#!H2rV +EW'qVF8Bt^F`qqPG^'+2rd"Khs*FcoGBeCZH[L6jIt3*&K8#&7Ll%"IN/`jY +OHG]iPa.N#R$a;1S"#q=St;RITqS3UrhTRj!2f^ms/>prl`0r`ri#dns/#dmrhTRh!2BId%%s5b +St;LDS=?":R@*tN&sefJP`q;oP*(ieO,f3ZN/W[PreUl9LPLV=KnY3ZKE$Q'Jc1,uJ,XoaIK"]p +J,Om!JV&LQK78K-Knb>;LkpnEMMmFPNK0'\OHG]hPE_>uQ^F/.R[]hjWiE,% +Xfnt5ZEpmF[^WcW]">Vg^;%J#_Sa@3a2l?EbKJ/Ucd:(fe'umuf@S^0g=tH>hV[8LioB([jlY^g +kiq?slg4!*mdBQ4nF?&>o)J:]o_nI_p&Ojbq#C0iqYU0gr;?Nardk*ps*t~> +JcC<$JcFL)o`"gfrqu]ks8)ckrqQNf!;?Eb$hX&]o'u5qFOQ2R$J@/s^7?i=@@@:NeX +@q/tV?uV%$_>D(P8kVfN9`7]c:B+,g;#aDm;Z9Vp;ufqt$G51>QJ,:ra5\5!+Gk9 +!b5bOrac+BBDuQGBkhD^CB86grbhaS!-%pW!ci@'rcABfG'8(RG^+N4H3/G@I/\NqIXckHJH(3# +K)L<'KS>-YLB!&/M#E2'cMWh%OT(FCfDX@qgAK\/gtgfChV\7h!TE&9j8\0CjlY^gkl'cGlMp2K +li?GPmf)SSmd9u@s7$'Yr/^p#oud$No#U:?rl+qFg&L]_rPeWQs2G#Vrkn0@.!9]WG^=[_I=6Tq +JV&N-KnbA=M2I7NNK9-^P*2#nQ'Rc(R$jD4S=TYN#+qQ^Tq\ +JcC<$JcFL)o`"gfrqu]ks8)ckrqQNf!;?Eb$hX&]o'u5\;MDu4GDD&IYFG^":P +EcH&9D/3p$BP1mf@q&kS?X@$3rhBFds.KCa!1s(Ypmh>S!1a"WrgEhTq/,nEqJH.JpMU%LqeuM& +s-W\MoTo3;rg*DGrg*SNs-EYLqNUoCrg!PLqJlO9s&]/"oiD3&E.[qM"A2<[9MGCZs%`SirDnGQDZFbU +E<:0%F8g7dF`qqPGBe@XrH\NlI!kpA!e,WKrdb$"s+:3%!ec8]rJ(?-s+pW1!1j%Xqjd_'rGDFL +"E/0qTqVFZp7qM\rh]Xls/5jn"/i)sWViarX8B!tWrfB)Xo5F!Y6(r3YPtd)ZM\M=QM-[BQL0t( +PQkL=c-FVZc2,`bcN;J@dJ_Mndfe+JdaHVBeG[ntf(YErPP^O=Oo(:iF`qtRH?spdI=HcuJqJ`1 +L51SAMN!LRO,oBcP*;,qQC!u+R@9V8Sc52bT:hmOU8+L_U]RBiVZ!FlW;W^dWrB!sW;NRnVZ3Ll +V#R1iUAgkdTE(V`ScPCPrgORiR@'A.QBmf$P`q8nOcb`dO,f5!MueioreUZ3L]3&.K`Hf*KE$Q' +Jc1,uJ,XoaIK"]qJ,OotJcC?$K)pXZre:H/M#N6JMMmFPNK0'\OHG]hPE_>uQ^F/.R[]h +JcC<$JcFL)o`"gfrqu]ks8)ckrqQNf!;?Eb$hX&]o'u5r&sC1s%iSgq+^la +peUBSqG6]Xs%WDdr]^9F!CB*M5QF+L63'CP5lsA?6N07O7nrhY"A2<[9MGCZs%`SirDnGQDZFbUE<:0% +F8g7dF`qqPGBe@XrH\NlI!kpA!e,WKrdb$"s+:3%!ec8]rJ(?-s+pW1oi(cO"$AY,4T%A><;TVl +<;KVp5h\)>5_\(?2.\(>l\4/49/7O;Yj8c;"RQQ:]k'CE,bbqrc7sY!d&L) +rH/'_qKDpard"Hgs*XfGlrNs_oMk]f.!9]WG^=[_I=6TqJV&N-KnbA=M2I7NNK9-^P*2#nQ'Rc( +R$jD4S=TYN#+qQ^Tq\ +JcC<$JcFL)o`"gfrqu]ks8)ckrqI*"p@e1Po^qbGo'u5ohs +Pm*Jj_82G'ra>k9?XN_=$=[LTA7K+YAUp8Yr4rA+r_38bs%`SirD3Pm;H!Hl!`W0"r`9&#!*K5' +s&oD,r`oJ/!+,Y3s'Ph8raGq=A7Y[N!G6!DB`DcHCAquMCi+%gD?4Zprc.sY!-A-]s)e(`rdXlss+(0%re(6(!/:E,!JcL1M0Oo9N/WaVO,oBbP*2#n +Q'Rc(R$jD4S=Q7CTV8'RUnjiaVl6SpX/rG+YHY:;Za@0L\%0&\]Y(tn^VRe(`5Ta:aN;TJbg"GZ +d*^:jeCE.%f\,!4gYL]Bhr*GPj5]4^k2tjjl07L!m-O--mdKW6naZ2@oCMVQp&F^cp\agdq>^ +JcC<$JcFL)o`"gfrqu]ks8)ckrqI*"p@e1Po^qbGo'u5nGLDuX_JD&[kKH$=IT +FE2A?DJa0)BkV-jARf1X?sd5GTqVI[s.TIcs.9:_r13YRr1*hXrLQ.n->l\41?iOL6@K'^;@q9-LAH?CUrb2=G!,DLK!c2^jrb_aT +E;jkWEWC1[FT6I`G5c^cGQ<$gHN/?lI/\QoIK4lrJH(0#K)L?%K`?c)LB!eCSc##TScmCmVufdo +Qi!*9Q0jh9?3AErbfoq.rQbDhrQt\pdF%sA!7Ukq!7h(us4-1oqi^]9rK8UOG'A1VH@($fIXcm! +K7ei3L5:\CMi(`rdXlss+(0%re(6(!/:E,!JcL1M0Oo9N/WaVO,oBbP*2#nQ'Rc(R$jD4S=Q7C +TV8'RUnjiaVl6SpX/rG+YHY:;Za@0L\%0&\]Y(tn^VRe(`5Ta:aN;TJbg"GZd*^:jeCE.%f\,!4 +gYL]Bhr*GPj5]4^k2tjjl07L!m-O--mdKW6naZ2@oCMVQp&F^cp\agdq>^ +JcC<$JcFL)o`"gfrqu]ks8)ckrqI*"p@e1Po^qbGo'u54T@M04Sh5444o7A@4nh/?4o@MC +:]4&a:%__:Amod:&mKS57'SO:JX5@6:!k&r]gHLrBgKL#!t[D6:OREr)3Sgr_38b +s%`SirD3Pm;H!Hl!`W0"r`9&#!*K5's&oD,r`oJ/!+,Y3s'Ph8raGq=A7Y[N!G6!DB`DcHCAquM +Ci+%gD?4Zprc.sY!-A-]s)e5h\)>5_Y*>lJ%(>l@q.?N*(c;=[W];>j>Z:\@Qa +?Mnd@E<(%XF8p:\ErpH+G5ZXbG5ladGl;peHN&9iai_fNc-FY^dF-Lne^i@)g"P07h;-rF +i8EVTj5f=ak3(sml0@U$m-X6/n*fc9nac8BoCW"Ss7QHer:p +JcC<$JcFL)p&=pgrqu]ks8)ckrV-rup@e1Po^h\Fo'u5bK@rKaSj0Z`rF![`l5m7qnrBN!5ncRr58NNpVZR=qj%)F +qSE;sQBq8Q!b#PIrF5nPO/i2q!_Z3\rD!;es%iSis&&eor_rhrs&K&!s&T2&r`T8)!*fG-s'5V2 +ra5\5!+Gk9s'l%>rac.CB4q3W!GQnDSDfB[pE<:0%F8g7_F`qs-GQ2mfH2W$jH[L5? +IK+crJ,XuuJcC?$KDj'hcMu/ecM`juOTLWsf`'S$gA0M'g]610hZ)L4i;_d9ir8!Y0g].;mn&5(Arl"cQo"lkuFa&%SH?spd +I=HcuJqJ`1L51SAMMmFQNfT9aP*;,qQ'Rc(R@9V7S=TYN!M?%aT`Us`U].(hV>mFhVt-e_VuNXn +V>d:jU]7(fU&UbcTDkDnSXc4>S!ob5R$a5+QBd`"PQ$^VOcYWbNfK*XN/NUOM2@%EL]3#0KnP-Y +KE$Q'Jc(&uJ,OicIJnWpJ,OotJcC?$KE$T)L&QgALPUeDMMmCON/`jYO-#KeP*D5sQC!u+R@9V8 +SXuFGTqS3VUnsrdW2ZetXKAY/Yd(L?['d?O\@K2_]Y2(p^r!t+`Pom=aND]Lc-FV]dF$FmeCE1& +f\,!5gtgfDi8ESRj5]4^k3(t-klpA^ +JcC<$JcFL)p&=pgrqu]ks8)ckrV-rup@e1Po^h\Fo'u5DJa0(BkV-jA7K(W?sd5GTV8(YUA^bdTV)+Pq4.AR!1a"Ws).[Omr&,Ar,2CMqJQ>%s-`nS +r0Qu?pm:oErg!>Grg!>ErK[>Ip2U+tr0@G&EH,%LQ.n->l\41?iOL6@K'a9@fU'=AHHIVBDuQFBkmW_s(h[Prb_dUE,ber!ci@' +rcA3aG'ofbl,fc +c2c2hd/25hdf7ereGn"se,e+Nj-0A'p6#B<.WffWGBeF[H[U/9Ll%"IN/`jYOHG]i +Pa.N"Q^F20S"#q=rgj._T`1VdU8+L_V#R:kVY[4]W;Vg^V@S$_Sa@3a2l?EbKJ/UcHstde'umtf@S[.g=tE=h;@/KiSrnXjQ5Oekl0fM +lKdg'mI'uB!V#XYo)J:]o`"O`pAamcq#:*hqYU0gr;HTbrdk*qs*t~> +JcC<$JcFL)p&=pgrqu]ks8)ckrV-rup@e1Po^h\Fo'u5DJa0(BkV-jA7K(W?sd5Gr_EGgs%r_kqG%#do2,B]r]^!O +D?=`qE;jhYEcZ=$F96T.G5c^cGQ<$fH3/G@I/\QoIfFosJH(3#K)UE$;#X>k;YF&]4o[\G4nhkT +<;BPos(7E;>*o];>j>Z:\die?2n1/E;abXEcZ=# +EWpN+F`hnPr-&'`rceEgrd+Tk!.=ZDlrNs_oMkij.WffWGBeF[H[U/9Ll%"IN/`jY +OHG]iPa.N"Q^F20S"#q=rgj._T`1VdU8+L_V#R:kVY[4]W;Vg^V@S$_Sa@3a2l?EbKJ/UcHstde'umtf@S[.g=tE=h;@/KiSrnXjQ5Oe +kl0fMlKdg'mI'uB!V#XYo)J:]o`"O`pAamcq#:*hqYU0gr;HTbrdk*qs*t~> +JcC<$JcFO*o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nceRQn*fY`r/C]:q2GB5oSr^+m>_+*qN(B4 +s,e=NI=$9cGBS(LEH,o7Chmd!BP(gd@q&kR?X@!ohYc:2hZ)C8gtUQ9f\$&Prmq,"rmV"uda7HE +p5f66pQ,-3s3Ctrc-+;QaiMNDrl=uWs2=uVr586Ho#("7s-0 +T"2\R9`7]c:B+,g;#aDm;Z9Vp<<#ttlS(0?N+=3?iXX7@fKp&!d/[0rceBe!."Nh!dfOSP%=OT3u4g&'M#g]-(.h>c@2hZi#tiSrkWj8S->jo=KBk61#5l0@U5m.B]Emf)\VnrWIb +qo\ZTlcB"Eqo8V?s'+:Yo#:IDqSiHPrPSd@WVuERnV>R.hU]7(fT`UmZTDkDsSXc4>S!oe6 +R$a5,QBd`"PEV/mOc]R'!KN0=MueioreU]4LPPk`!el;\re(6&s+1)urdXornU:@bs*srss+13% +rdt`7KnY89LPUbCM2I4MN/`ksO)0o@P*;,qQ'Rc(R$jG5S=Q7CTV8'RUnjiaVl6SpX/rG+YHY:; +Za@-K\%&u[]=bhk^VI\&_o0O6aN2KHbKS8WcdC.ge'uq!f@\d1g>(N?hV[8MioB([jlY^gkiq?s +lg4!*mI'H3nF?&JncJFTo`"O`pAamcq#C0hqYU0hr;?Nardk*rs*t~> +JcC<$JcFO*o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nceRQn*fY3r,(\9kABO&++AWbH?j^XFE;GA +Df0B,C1q9mARo:[@:*AJ>bIa`U&LebT`LgYr13VQr1*nZS"'1jqJY;0rL*eUR$dl>nWrm8r0@>J +pm1c@rK[;Hp2U+tr0I;Hs-3P'r`8eqs&T/$#$l(oNg#Z#rD!;es%iSis&&eor_rhrs&K&!!`rK+ +r`T8)!*fG-s'5V2ra5\5!+Gk9s'l%>rac.CB4q3W!blCarbDROD/K8i!H2rUE<:0%F8g7_F`qs- +GQ2mfH2W$jH[L5>I0+kIJ+]?0Sc>5USc3L+DYn;KD#\>PUA(G^V#7"eV#R:gVZ3RoW;`grX8]4! +X8f:#XT5O&YPt^$YQ(j+YlV.Io9T<@qj-B0p6>P]s',EFrQY>erQkJirR(VmqpYPos4-+mqi^`: +rfSdRF`qtRH$XgbI=?ZrJV/T.L5(M@M2R=ONfT6_P*2#nQ'Rc(R$jD4S"-&KScPIVrh9@d!2KLg +s/#^llDOWYs/#Xhs.fUgrh0CdT:c+S'qLkbS"#k8R@'A.Q^3o%P`q;oP*(k*Nrb9#repl9MZ/G6 +LkgcbL'!'^K`6W(K)^E"JGt&tIdqjbIfFoqJH(3#K)UB5KS>,7L51S@M2@+JN/WaVrf:lWP*2#n +Q'IZ%R$a;2S"-%@StMdNU84T]VPgAlWiN5'Y-5(7ZEppG[^WcW]">Vg^;%J"_Sa=2`lQ6CbKJ,T +cHjncdaQ^rf%8R-g=k? +JcC<$JcFO*o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nceRQn*fXCr&`q$niQ5$r&ap@)h*3^H?j^X +FE;GADf0B,C1q9mARo:[@:*AJ>l@Fs:]F8k:]!oe:\dib;$'Qi:\m9/4oRPE:JUmbrD*;cr_E2` +!`2ZgoM5E^r_WMgpJ(``:Amoe5PRM@;#3uf5llS(0?N+=3?iXX7@fKp&!d/[0rceBe!."Nh!dfQ8[AEW'nXEW0t[F*)O%FoHR_G63#7H2W$iH[PWhlrNs_ +oMd>_F`qtRH$XgbI=?ZrJV/T.L5(M@M2R=ONfT6_P*2#nQ'Rc(R$jD4S"-&KScPIVrh9@d!2KLg +s/#^llDOWYs/#Xhs.fUgrh0CdT:c+S'qLkbS"#k8R@'A.Q^3o%P`q;oP*(k*Nrb9#repl9MZ/G6 +LkgcbL'!'^K`6W(K)^E"JGt&tIdqjbIfFoqJH(3#K)UB5KS>,7L51S@M2@+JN/WaVrf:lWP*2#n +Q'IZ%R$a;2S"-%@StMdNU84T]VPgAlWiN5'Y-5(7ZEppG[^WcW]">Vg^;%J"_Sa=2`lQ6CbKJ,T +cHjncdaQ^rf%8R-g=k? +JcC<$JcFO*o`"gfrqu]ks8)ckrqQNf!;?Eb%eTA`o'u5L_@UWVN?!RBdro!h6s5*e3"l.kdg"=sRfDaA"eH47Le*E+` +O84n:cNMPral+A!,):Es(MIJ +rbMOM!,_^Qs).mVrc.sY!-A*\!d/[0rceBes*=Ti!.4Xe!6Y;arQP2arQb8arQb>%!0I2@rfI&? +s,d95s4R;'rS.>,rS@M1rnmb7s5O(=s5a.?!9X:Ds6'XNlKdd&m/?>Om.fuJmf2_WnF?,KaR[FQ +b4Wm?aSNm[>[(E9>$9Y\!64TKo>L:=r5/JU.WorZG^=[`I=6TqJV&N-KnbA=M2I4MNK0']Ocklk +Q'IZ%R$a;1S"#q=rgj1`TV2:X!huHbr1s=grMK4br20Iir1s@fs.]Lds.KCargj@cS=H(rfmMKPQ$^LOcYWbNfK+uMueioreU]4LPPk`!el;\re(6&s+1)urdXlqo6pRdrdXlss+13% +re(6(!/:E,!JcL1M/\?1N/WaVO,oBbP*2#nQ'IZ%R$a;2S"-%@StMdNU84T]VPgAlWiN5'Y-5(6 +ZEpmF[^N]V]">Vg^;%J"_Sa=2`lH0Bb0/#RcHjkbdaQ^rf%8O,g=k<:h;7&Ii8N\UjQ5OdkNM0p +lKdd&m-X6?mfDqJrpp*\!;-9`s7ZKerV6EgrqcNhrVZWmo)=4?d/SU~> +JcC<$JcFO*o`"gfrqu]ks8)ckrqQNf!;?Eb%eTA`o'u5lLGpUA^bdTV).QpmhATr1*V$no*Z.r0dYSR/NBCQLpO8QN*6J +Pl6mGQLo.sQ26gHQ26^HD/jRkQ.n->l\41?iOL6@K'a9@fU'=AcH?BBDuTEB`MoIC]A2ND>nGQDZFbUEW:%ZF8^1^F`qs-GQ2pf +H2`*iHi'<*SFW6KD"VZFD"j_)V#-qdV#I4hVZ3OrW2Zbrr2]gu!3?+#rN-(&ric4%qQKq's02R1 +mZmj>qNg0,qNM1h>?b97=j-fgrQY>erQkGhrmCVkrmUboj-/qps)]`5GB\:XH@1-hIt3*%K7nr5 +LPUeEMiWs+:9%r.+cr +rI4?drI4`qrIFp!s+:6&s+CB+re:H/M#N6MMMmFPNK0'\OHG]hPE_>tQC!u+R@B\9SXuFGTqS3V +UnsrdW2ZetXKAY/YctF>ZaI6M\@K2_]Y2%o^qmn*`5Ta:aN;TJbg"GZd*^:jeCE.%f@em3gYCWA +hr*GOioB+]k2tjjl07L!lg4!*mf)YUnF?MKs766_rq6 +JcC<$JcFO*o`"gfrqu]ks8)ckrqQNf!;?Eb%eTA`o'u5i:B+,a;#F2j;"d*04oRPH:JOY\:]!le:&[oa +:]F/i:]=2i:\@K^:B45h:\7E^:%U^J;"dZf4?u.u62j1[5sR\$6:4()5X@n5:fIjs&&Vhr_`Ympf%,Qr&j^:q,@;mrDihtoN1unqcWr$ +s&oA*rEK5*s',>)"']#7>Q%e,?1(Pi;X73Y;"%0g>[(E9>$5f`EH6)>ErL%_EcZ;DF`hg*Fo?L_ +GPugdHN&9e +JcC<$JcFO*o`"jgrqu]krqZWjrV.?+p@e1Po^qbGo'u5%=O8t@9O<9++J:;onH?aXVFE;G@DJj9+C1q6lARo7Z?sd8HhV\=js5=+=hr!;IrnR_3 +g=b-2qUbYrs4%,!muRO3qN1**rK.!(s3:Sf"3\j0ao0<[a8a-Z`UCbA_u@UO_u%:N_u@OEQMA>m +_>;"LQBhASrEoS4$=RCbNM]EE:/4S\rDlI4i;_g9irJ0=jo4EBk6C/7lK[^$m/?>N +m.fuImK;qInauXukfN,2r5\iWs',M,rE7tVrl4NJo>L=>rPC@3FEMbNG^4U^I!pHoJ:W?*KSG5: +M2@+KN/`mZOHG]iPa.N"Q^F/.R[]e:SXl@DT:_eUU&UkeU\gkcV=^Y`V>I(fU]7(eU&UbcTDb>d +SXc4>S!oe6rg3_QQN!-MP`u*0%$?X5O,o<\NJrgSMMhCi!JlO1LAuu-K`6W(K)^E"JGt&rIeA-f +If=ipJH(3#K)UCPKS>,7L51P?M2@+IMib]Y;.q_8=(-`Pom=aND]Lc-FV]dF$FmeCE1&f\,!5gtgfCi8ESR +j5]4^k2tjjl07L!m-O--mdKW6s7-*Z!qZ'Vrq6 +JcC<$JcFO*o`"jgrqu]krqZWjrV.?+p@e1Po^qbGo'u5lS(0?N+=3?iXX7@fKp,s',M,rE9-D!mSs5rQY;drQkJirmC_nrR1o!e'ujqifikp1NRY\ +G'A1VH@($fIXls"K7ei3L51VBMN!LRO,oBbP*;,qQ'Rc(R$jD4S"-%?St;RHT`1YbUAq"cV#@.^ +VZ!@gV#I.hUA^ecTE(V_Sd1gVS=?":R[O/B!LK,OPl[,5rfR\POH>NaNfB$WN/NRNreUZ3L]3&. +L&Zi*KE$Q'Jc(&tJ,FcgIJnWoJ,FisJcC?$K7AQ.Knb>;LPUeDMMd=NN/`jYO-#KeP*;,qQ'Rc( +R@9V7S=Q7DTV8'RUnjiaVl6SpX/rG*YHY7:Za7'J[^`lY]=bej^V@V%_SjF4a2l?EbKJ/UcHstd +e'umtf@S[.g=tE=h;7)JiSrnXjQ5OdkNM0plKdg'mI'E2n*pAIrpg-^o^r.Us7ZKerV6Egs8)Th +rqu]mo)=4?dJn^~> +JcC<$JcFO*o`"jgrqu]krqZWjrV.?+p@e1Po^qbGo'u5 +9heAX:J^pcs&&eorDNbsral+A!,)7D!blCa +rbDROD/K8i!cN$src.sY!-A*\"Eem2GBa$a!Du\i;>jDm;>X2h;>sJg;u/TO4T%A=;uTbr"=oDG&=oDP(>Q%h+>Pqb&>6A,7>[>fUrD<,^s',M,rE08BEH6&rfmMK +PQ$^ROcYZcO,f3ZN/W[PMZ/G5Lkktas+UK+re(6&s+1)urdXipomQdfrdXirs+13%re#]RKnY89 +LPL\BM2I1KN/WaVO,oBbP*2#nQ'IZ%R$jD4S"-%@T:hmOU84T]VPgAlWiN5'Xfnt5ZEpmF[^N]V +\\#Me^;%G!_SX71`Q-'@b0.uQcHaeadF6Upe^rF*g"P39h;-rGi8N\Uj5f=ak3(sml0@U$m-X6/ +n*fcGnc&(\oCV\Sp&Facp\jmeq>^ +JcC<$JcFR+o`"gfrqu]ks8)ckrV-EfpAX^co^i(Q)=d4bn*]T0lg!a!kN:pfj5T%Uhqd,Cg=_J[ +NpVi(Nr+n0OL^@UNPM?/OPtro*n:%,p.&hqm2FgtUQ9 +g"?/Qqpt_,rfI#3::J^pcs&&eor_rhrs&K&!s&]5&r`T8)!*fG-s'5V2rEfV6@:B.E +!b5bOrac.CB4q3Ws(MIJrbMOM!,_[P!cN$src.hWrQG/`!6b2\s3(AbrQP>drltAbrltJgqiUf< +q2YW>YcudZg&0P*gYCT\h>c=7hr*GOir.p:jo4EAk5sl3l2KuJlh]uCmJlVSmfN"Lo^p5kam@+E +a8]?A=oVS(=5NuF`r3mM`:q1K_Z.ORF=_TZGBnL\I!pHnJ:W<)KS>/9Ll%"IN/`jYO-#NfPE_>t +QC!u+R@9V7S=H/LScYOWT`1YbUAgqaV"CMZV#I.hUA^ecT`:Y`T)Y>]SGo#XRK/cTQk>[NQBd`" +PEV/mOcb`dO,f6[repl9MZ/J4L]E50LAur-K`-Q'K)^E"JGjuqIeeEhIf=ipJH(3#K)UE&KE-`* +L'EEhLl$tGMuJZPNK0'\OHG]hPE_>tQC+&-R[]e:SXuIHTqS3VUnsrdW2ZetXKAV.YctF>Za@0L +\%0&\]Y(qm^VI_'_o9U7aN2KHbKS8WcdC.ge'uq!f@\d1g=tH>hV[8LiSrnYjlY^gkiq?slg*p( +mI'uB!V#XYo)J:]o`"O`pAamcq#:*hqYU0gr;HTbrdk*ss*t~> +JcC<$JcFR+o`"gfrqu]ks8)ckrV-EfpAX^co^i(Q)"I+an*]T0lg!a!kN:pfj5T%Uhqd,Cg=c"6 +m;;9/+bPAsIsufmH?aXVFE;G@DJj9+C1q6lARo7Z?sd8HTV/"XUAUbeU7qRZ!1s+Zpmh>SrGV[Q +iG\@+rL3bSqj.;KrKmDIn<`j7q3:rGrKm%oqNh/HqNUrDrg*MJrKR:]q,R]*CJ@Q!:J^pcs&&eo +r_rhrs&K&!s&]5&r`T8)!*fG-s'5V2rEfV6@:B.E!b5bOrac.CB4q3Ws(MIJrbMOM!,_[P!cN$s +rc.\$p7)&O!1WbRoUYkrr+u@JrG;LNs+U?FrM'1arhTRjrMKRms/Gjqs/Z4&n#lVmr3-7-ZEsIq +l'C4ls'#A(s&]>(bKKk.rQY>erQkJir6bPm!7Ukos3okhoTK6rgj1`TV2:Xs.]LfqP +JcC<$JcFR+o`"gfrqu]ks8)ckrV-EfpAX^co^i(Q)"I+an*]T0lg!a!kN:pfj5T%Uhqd,Cg=c?c +s#^$=m5sl$rAu0TJq/?"I=$9bGBJ"KEH#f5Chmd!B4b^c@U`_P?X6B#:AI]c;#X8i:B+,b:]OAl +;Wg744o%5=:%V3[:]=,h:]+&e:\RW]:\[]`:\R*S5Q!eE;"@EV:]aEY62j1N62j.K6Np"T:/4S\ +rD* +r`T8)qHNo's',M,qca)+?-cCH;#!id>5_V(=92KCrc%jV!ci@'piHR[G'/9Ll%"IN/`jYO-#NfPE_>tQC!u+R@9V7S=H/LScYOWT`1Yb +UAgqaV"CMZV#I.hUA^ecT`:Y`T)Y>]SGo#XRK/cTQk>[NQBd`"PEV/mOcb`dO,f6[repl9MZ/J4 +L]E50LAur-K`-Q'K)^E"JGjuqIeeEhIf=ipJH(3#K)UE&KE-`*L'EEhLl$tGMuJZPNK0'\OHG]h +PE_>tQC+&-R[]e:SXuIHTqS3VUnsrdW2ZetXKAV.YctF>Za@0L\%0&\]Y(qm^VI_'_o9U7aN2KH +bKS8WcdC.ge'uq!f@\d1g=tH>hV[8LiSrnYjlY^gkiq?slg*p(mI'uB!V#XYo)J:]o`"O`pAamc +q#:*hqYU0gr;HTbrdk*ss*t~> +JcC<$JcFR+o`"gfrqu]ks8)ckrqQNf!;?Eb,kU^!o'u5inb/qcHaiMQD +a2Z-u`ULhG_t_1I_Z7RQ_siuj_u@OK_=b\;_>dgA?2e.5A55lq:]4,i;?'Pn;u]hsQ.n-?2n71?NOVD@K'a9@fU'=AcH?BBDlKFBkhD^CB/2HaSX*Zb5TT`bQ,ibb5]T^aoKW` +bl>rebQ,o`bl>rfcMN_%Oo(7:Yl38TgA]k%h>c=9hr*GOioB(uj8e<@k5OQCkQ'lGlMp2Im.fuJ +mf2_WnF?/?aR@7=aSai_fNc-FY^dF-Lne^i@(f\5'6gtgiEi8ESRj5]4^ +k2tjjl07L!m-O--rpL*]naZ2@oCMVQp&F^cp\agdq>^ +JcC<$JcFR+o`"gfrqu]ks8)ckrqQNf!;?Eb,kU^!o'u5Q.n-?2n71?NOVD@K'a9@fU'=AcH?BBDlKFBkhD^CB/2H +RJ**?S+rNGSbm7%D>S/GL&IeEUAL_cV#R:iVZ3RoVuiruWr&h(XKAV-Y-5%3Y-"i#Y5GL%YlCs0 +Z^-pRQgC$rQ2Okc=T2A'lci2;kdJ_MmdJ_MMPOt"fF*)PJGBeCZH[Uai_fNc-FY^dF-Lne^i@(f\5'6gtgiE +i8ESRj5]4^k2tjjl07L!m-O--rpL*]naZ2@oCMVQp&F^cp\agdq>^ +JcC<$JcFR+o`"gfrqu]ks8)ckrqQNf!;?Eb,kU^!o'u5u"*g:AI]c;#*o^ +:]XEkl9522ofi::s$$fp.kK\qG.#cr]g?HpHSRPnk]*Ys%`VkpJ:fU +#XCU=5XS:A:J^pcs&&eor_rhrs&K&!s&]5&r`T8)!*fG-s'>Y2ra,_7@:B.Es'l%>ral+A!,)7D +!blCarbDLMr)!Gjqbd,dnko6[!)`YlqGZuIs#g-K!*&nqs&B"us&T,#qc5MP(>lIt,>5DG'?-?+D;#F,f=oVV'-ZL&m'creUf9Miu +Q^F/.R[]e:SXuIHTqS3VUnsrdW2ZesXKAV.YctC=Za@0L\%0&\]=bhk^VI\&_o0O6a2lBFbKS5V +cd:(fe'uq!f@S[/g=tE=hV[8LiSrnXjQ5OdkNM0plKdg'mI'uB#Oq9Ro()DDo_nI_p&Ojbq#C0i +qYU0gr;?Nardk*ts*t~> +JcC<$JcFR+o`"jgrVZTjs8)ckrqJ5Bp@e1Po^qbGo'u5qLQ;#aDm;Z0Po<<#ttlS+0?N+:5?t!LC +@fKp=A7bbZr5S]Up;m0Rs2t2]!6Y5]qo\r^!R/adbl>l^bl5iecM3M"OnQ!Zg&B_)g]-()h>c=8 +hr*JPioC%!#3G"0kNM-orojCHrTaCJr9X1Fs6fpU!qGp)mE"k?nAt@Es&oA(s&],!huE#^rPeNL +pr!*J.s#fTG'A1VH@($fIXcm!JqJ`1L51SAMMmFPNK9-^OcklkPa.N"Q^F/.Rf8cXS=Q5MScYOW +T_tM^UAUe]V#-qcUAU_bT`1S_T)YA]SGo#XRK/cTQi`V?QN!-MP`u*0#Eb+0O,o<]NW+kAMi*CK +M26tCrItB-KS9;Vs+:9%qgeWpnp^Oeqge]ts+:6&s+CB+re>NMLkpnEMMmCON/`jYO-#KeP*;,q +Q'Rc(R$jD4S"6.BT:hmOUSO]^VPgAlWiE/&Xfen4Z*UdD[C3QS\[oDc]tV7s_8=+.`Q#s>ai_fN +c-FV]dF$FmeCE1&f\,!5gtgfChr*JQj5]4^k2tjjl07L!rp0[Qmf)YUnF?MK!qZ'Vrq6 +JcC<$JcFR+o`"jgrVZTjs8)ckrqJ5Bp@e1Po^qbGo'u5Q.n-?2n71?NOVD@K'a9@f^+OrgEPKp6kWCnsfWK!1WnV +pRV>Uph]nGr.b*&!2K@ar1j:f!2]XkrhfjsWN)uqX8f7%XfhW+!3Z='pTFCsrNH=-Zhp'bQg^7! +Q2b"e=T;J#dbU,[Ot1TqF`qtRH$XgbI=?ZrJV&N- +KnbA=M2I4MN/`mZOHG]hPE_>tQC!u+R@=,E!h>gPrgj1`TV24VrM'4bpn[e^rM'4`s.K@`rgs.\ +s.'(Xs-`qUrg3bRQBqN8!L/fIOp@,2OH5H_NfF$s#E+IsM2@%EL])r/KnP-XKE$Q'JbsurJ+A'e +J,=crJcC?$KE$T)L&QgKLPUbCM2I4LN/WaVO,oBbP*2#nQ'IZ%R$a;1S"#t?StD[LTqeEZV5C/h +WN)u"Xf\b1Yd(O@['d?O\@K2_]Y2%o^qmn*`5Ta:aN;TJbg"GYd*^7ieC<%#f@\d1gYCW@hV[8M +ioB([jlY^gkiq?sli-5OmI'uB!V#XYncJFTo`"O`pAamcq#C0hqYU0gr;HTbrdk*ts*t~> +JcC<$JcFR+o`"jgrVZTjs8)ckrqJ5Bp@e1Po^qbGo'u5u1Dor_NJf +!`)Whr(lu^cT_=k!Ba-T:%D$Z:]4&g:]+&h:\.?Y:]4&e:]ETX4odhH55meC55e=P:\IWK:]+&h +;?'Pm;u]hsQ.n-?2n71?NOVD@K'a9@f^+Oohb?Zp/:BWr)!Djs&/Vj!*&SP +rC?]Ts&B"ss&8tur`9&#qH!Jps&]8(pK7;qr`]5(rET>+!*]5'!*mQAr)!Drs&f;&r)Wf9s)S-\ +"a"g,FE;O&F9$I^G5c^aGQN2tQC!u+R@9V7SXuFFTV8'SUnjiaVl6SpWiW>)Y->.8Za7$H +[^WcW]">Vg^;%J"_Sa=2`lH0Bb0/#RcHaeadF6Upe^rF*g"P39h;-rFi8N\Uj5f=ak3(sml0@U6 +liHMArpKmWnc&(\oCV\Sp&Facp\jmeq>U6fqu-HkrUTr=s3gpt~> +JcC<$JcFU,o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nh'D$n*f]3m-Es$l0%3kjQ#:Zi8OT(C@P5:=7bK@rKr5eoY"NJL%`PprWr58N!rKdJMpQk]orkeTLrPJQOrPIp;r5/3Gn&56t!*fD,!+#N@ +rl+fRrl+fTrQ"cU!6P5]r5nu]s3(Gbs3(Gbr5niY"O"s2bKTq.prrc_rK$f:!3u."rn7A,r7q5+ +rS@Y6i8NYoj8\3Ek3(pkl0A01s6BXMq<[nDs6^$YnF5u?r5n?IouZgHouI)7s&](us&J"Ws2FtQC!u+R@9V8SXuFFTV8*TUnjiaVl6SpWiW>)Y->.8ZEppG[^WcW]">Vg^;%J"_Sa=2`Q-'@ +b0.uQcHab`dF-Lne^i@)g"P07gtgiEi8ESRj5]4_k3(sll07L!m-O--rpL-^naZ2@oCMVHrq6 +JcC<$JcFU,o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nh9P&n*f]3m-Es$l0%3kjQ#:Zi8Q%e,?2U)`RJ<0GR/i]TRJ**? +RfJuXS,AfNSH,8TC]K7cLAZc#UA^hiUnsobVZ!CoW2ZcmX8]1%Xfel,Y5PKsY55@$YQ;#8p6P`F +mZujts&f;&qc<_s!mJj2rQP8d!6tMgrQkMjs3^bkrmC_ngQVAp,B@mJFa&%SH?spdI=HctJqJ]/ +L5(J?M2I4MNK0'\OHG]iPl?pOQC!u+R@=,Es-s([rLX%]s.K7_qkEq^qP*h[s.K@`rLX%[!1a"W +!h,OFrg3bRQBqN8#F(F9P*1riOT(:ANfF$ss,-l7re^Z2!/LQ.s+UK+rIb-%s+1&trI=EfrI=]p +s+13%re(6(s+UK-s+^T1reY`SMitQC!u+R@9V8SXuFFTV8*TUnjiaVl6Sp +WiW>)Y->.8ZEppG[^WcW]">Vg^;%J"_Sa=2`Q-'@b0.uQcHab`dF-Lne^i@)g"P07gtgiEi8ESR +j5]4_k3(sll07L!m-O--rpL-^naZ2@oCMVHrq6 +JcC<$JcFU,o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nh'D$n*f]3m-Es$l0%3kjQ#:Zi8u+8o:B+,g:'+3f;#=&`:ujh=5O1K6:JUj_o1o6[!)EMhqG?]WqbR5er_NJVr'(6H5.q,-WXqG@5jr_`GgmSWs[rDE8erAsd:njiXXs&J_mqcESqs&o>' +rE9/(r*'5+>?h#1s'#J,qHEr)_GU>8s&](us&B,>EH:hqs)e6_rc\6as*+QiHN&9kI,7oro(2JFo`"O`pAamcq#C0hqYU0h +r;?Nardk*us*t~> +JcC<$JcFU,o`"gfrqu]ks8)ckrqQNf!;?Eb47r.8o'u5=n*]T0m-Es$ki_*ijQ#7Yi8L4k21J:;onH?aXWFE;GADf0B,C2%?n +ARo:[@:3GK?012/j8@m8iWA)shu;I9h;$c=g=cATooT39r/gr>!K`BAOT(C:P5LIBOSY+=OT*W, +ci22pcd'h\c-4ARrlP)ZrPnuZ`PqbnrPe3Cs24`"q3UuEqnr[76Grl+fRrl+fTrQ"WQr5eu^ana*WanNsTbP03\OSb+=OS5sUYlEDWg\oq)h>Z7>hr*JQioB([ +jlYail29iGl2U#KlhBc@m/ZSRmfW(Lou[3Sr5n?IprW3MoZ-u5r)Wesr`%hU!lW'slc/nBpVcsH +s2$C/F*)PJGBeCZH[L6jIt3*%K7nr5LPUeDMigPrLX%] +rh/GJrh07_r1-ZL(B&qLl$tGMi3OQNK0'\OHKO*A!<.BQ'Rf)R@9V7 +S=Q7CT:hmPUSO]^Vl-JmWiN5'Xfen4Z*L^C[C3QS\[oDc]tV7r_8=(-`PojNioB([jlY^gkiq?sli-5TmI'H3nF5uIncJFTo`"O`pAamcq#:*hqYU0g +r;HTardk+!s*t~> +JcC<$JcFU,o`"gfrqu]ks8)ckrqQNf!;?Eb3V;q6o'u5=n*]T0m-Es$ki_*ijQ#7Yi8lC&fR/i]RRJ<0CRJ**;S,8`N +SH,8VD#/qaLAZc%UAUbgUnsobrhoaori5jrri?.&Y5,3oY5GL$YQ;#8i0NDgs&],!r`/qsrlb>c +s31Vjc-?75rQk8crm:_ormBG`q3!@NF*)PJGBeCZH[L6jIt3*%K7nr5LPUeDMigPrLX%]rh/GJrh07_r1-ZL(B&qLl$tGMi3OQ +NK0'\OHKO*A!<.BQ'Rf)R@9V7S=Q7CT:hmPUSO]^Vl-JmWiN5'Xfen4Z*L^C[C3QS\[oDc]tV7r +_8=(-`PojNioB([jlY^gkiq?sli-5TmI'H3nF5uI +ncJFTo`"O`pAamcq#:*hqYU0gr;HTardk+!s*t~> +JcC<$JcFU,o`"gfrqu]ks8)ckrqQNf!;?Eb3V;q6o'u5=n*]T0m-Es$ki_*ijQ#7Yi8u4An:]*uc:\R]H55%524p4\X:/+IY:&n)c:A[ia;#X8\:AI]b55meC5lO"H55nCQ +:\@QJ:\IWR;#ir[62t3d;=IEU;>X8W;?'Jm;>jDe;u/QT47>]><;onk5VV(>5qh*>lS%.=o_e*>5haC;?'_qFG'A1VH@($fIXcm!JqJ`1L51SAM2R=ONK0'\OcklkPa.N"QC!u+R@9TDRf]+NSc,/[ +TDkMHU&L_aTDY;\Sc>5ZS,\rWRJrQTQ^3s:PmeGk%~> +JcC<$JcFU,o`"gfrqu]ks8)ckrqQNf!;?Eb5kO[=o'u5!7Cems3C\j +rQbVlc-=JUrQ>/^s2b)X#0+X$`5KX6rl4uWr58TSou-cps-EAFrKdE"oYUUFrPIsrj(ss"5;Mah"]_*hZ;Zoro3t< +#j(43kih9rlKeB5s6KCFq!A@Tn*fc9o(C,HqoJZVo#URIpW3!I!*B)!r`/qsr_qeUs2=oUqSr!C +p;HgF,]e'LG'A.UH?sseI=HctJqJ]/L5(J>M2I4MN/`mZOHG]hPEc'3!LB)OQiWVDrgWqXs.0(Z +rh'.^nY,oSrLa"Zs.0.ZrgWqVs-`kRs-NbOrfm_QPEV/mOcbb)O8k4?NW+n:MZAY6M>rA3L])r/ +KnP-XKDpK&JbjomJ,aunJ,4]qJcC?#KE$T)L&Qi,LO+c5M2I1KN/WaVNfT6_OcklkPa.N"Q^F/. +R[]e:SXuFGTqS3UUnjlcVl6SpX/rG*Y->.8ZEppG[^WcW]">Vf^;%G!_SX40`Q$!?ai_fNc-FY^ +dF$FmeCE1&f\,!5gtgfChr*GPj5]4^k2tjjl07Kulg4!*mf)Y[nF?&>o(2JFrUp3a!;HEds7uZj +qtpBjr;H3cJcF7"J,~> +JcC<$JcFU,o`"gfrqu]ks8)ckrqQNf!;?Eb5kO[=o'u5M2I4MN/`mZOHG]h +PEc'3!LB)OQiWVDrgWqXs.0(Zrh'.^nY,oSrLa"Zs.0.ZrgWqVs-`kRs-NbOrfm_QPEV/mOcbb) +O8k4?NW+n:MZAY6M>rA3L])r/KnP-XKDpK&JbjomJ,aunJ,4]qJcC?#KE$T)L&Qi,LO+c5M2I1K +N/WaVNfT6_OcklkPa.N"Q^F/.R[]e:SXuFGTqS3UUnjlcVl6SpX/rG*Y->.8ZEppG[^WcW]">Vf +^;%G!_SX40`Q$!?ai_fNc-FY^dF$FmeCE1&f\,!5gtgfChr*GPj5]4^k2tjjl07Kulg4!*mf)Y[ +nF?&>o(2JFrUp3a!;HEds7uZjqtpBjr;H3cJcF7"J,~> +JcC<$JcFU,o`"gfrqu]ks8)ckrqQNf!;?Eb5kO[=o'u5k;#aAm;"@Ha:f7-g +pJ^rMr^luXoLJj[r`0##r)Wbtr`9&#r)ir$!*]>(!*];)s'#D)!*]A+!aJr6p0%H$_bgD8r)Wes +r`&kq"EJR(Ec_5#s)\3^#'G$0F`hkNrceHcoi38YFED\MGBnL\I!pEmJ:N6( +K7nu6LPUeEMi(jWN*## +Xf\b1Yd(L?['d?O\@K2_]Y(tn^VRe(_o9U7aN2KGbKS5Vcd:(ee'umtf@S[.g=tE=h;7&Ii8WeW +jQ5OdkNM0plK[^%m-X6?mg&@Pnac8BoCW"Ss7QHer:p +JcC<$JcFU,o`"jgrqu]ks8)ckrV0+]p@e1Po^h\Fo'u5jWN*##Xf\e2Yd(L?['d?O\@K/^]Y(tn^VI_'_o9U7a2lBFbKS5VcHstddaZdsf%8R- +g=k<;h;7&Ii8N\Uj5f=ak3(sml0@U$m-X6/n*fc8nc&(\oCV\Sp&Facp\jmeq>U6fqu-HkrUTr= +s4%(!~> +JcC<$JcFU,o`"jgrqu]ks8)ckrV0+]p@e1Po^h\Fo'u5\SFUXmE<'tNEVj_JDuQ7( +RerNPR/`TKR/!$JR/`NPR/EAicHc11o98a.rKHf8-$"*LFa&%SH?spdI=?ZrJV&N-KnbA=M2@+J +N/`jYO-#KeP*;.0Pl[2;rg3bTR[X5Fs.'+[qk!bYnY#iQqO[_Xrg`qVs-itUrg<_P!1*SK!gJn4 +rfRMKOH>NaNfK+uN;ne9MZ/J4M#W80LAuu-K`-Q'K)U>tJFJ'bJH(3#K)L?%KE-`*LB!#/M#N53 +MMqImG`@`EO-#KdP*2#nQ'IZ%R$a;1S"#t?StD[LTq\ +JcC<$JcFU,o`"jgrqu]ks8)ckrV0+]p@e1Po^h\Fo'u5Y2J:\diN:\[cS;>!5q_,>$G51>5_V">5qb%>5qe->Z:W"!`;in +b#/+Neoi3;YFEDYLGBeF[H[UrD3L]3&.L&Zi)KE$Q&JbjodJ,4]qJcC?#KE$T)L&Qi, +LB*/0M#iKlreu)]NfT6_OcbfiPE_>tQC!u+R@9V7SXuFFTV8'RUSO``Vl-JmWiN5'Xfnt5Z*L^C +[C3QS\[f>b]Y;.q^r!t+`Poj;aN;TJbg"GYd*^7heC<%"f@\d1g=tH>hV[8LiSrnXjQ5OdkNM0p +lKdg'mI'E2n*oi:rpg-^o^r.Us7ZKerV6EgrqcNhrVZWmo)=4?eGk%~> +JcC<$JcFX-o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_no=3hn*fZ1m-Es$ki_*ijQ#7Yi8f[n`;Ockn$Om8+u +OoCFDda?J>d/2,gc2Z#dbQ#]daiMR$a8X*Va8a0T`VROQQg9t:_tCnD_Z7R?_>M1H_uI[L`VIIE +T)Q\-`W*mS`V[[Oa83mFan3aRbPB?`NK0(s[/@9.ZLtI(gYCT]h>c=4hr+Im"QSS*kNMp0s6BCF +p?_VB#O_'Lnac;Ep?Tj!aR[ICaSa*YtQC!u+R@9V7S=Q7CT:hmOU84T]VPg>j +WiE,$Xf\e2Yd(O@['d?O\@K/^]Y(qm^VI_'_o0O6a2lBFbKJ/UcHjncdaQ^rf%8O,g=k<:h;-uH +i8N\Uj5f=ak3(sml0@U6liHMArpKmWnc&+Zo)SF]o`Fj]p\agdq>^ +JcC<$JcFX-o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_no=3hn*fZ1m-Es$ki_*ijQ#7Yi8cH8q/?8% +qjR2G!goCDqj@8IpmCrFqNh&"p2TqL!-.b!rg!8EkEYn0n>hP4Fh.P5UU9OsY3jFEMbNG^4U^I!pHnJ:N6(K7nu6LPUeE +MitQC!u+R@9V7S=Q7CT:hmOU84T]VPg>jWiE,$Xf\e2Yd(O@['d?O\@K/^ +]Y(qm^VI_'_o0O6a2lBFbKJ/UcHjncdaQ^rf%8O,g=k<:h;-uHi8N\Uj5f=ak3(sml0@U6liHMA +rpKmWnc&+Zo)SF]o`Fj]p\agdq>^ +JcC<$JcFX-o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_no=3hn*fZ1m-Es$ki_*ijQ#7Yi8coM5sJFn?eJGt-"K)L?%K`?c*L3\Q1Ll$tG +MMmFPNK0$[O-#KeP*;,qQ'Rc(R$jD4S"-%@StD[LTq\?YV5C/gW2ckuXKAV.YctC=Za@-K\%&uZ +]=bei^V@S$_Sa=2`lH0Bb0.uQcHab`dF-Lne^i@(g"P07gtgfDi8ESRj5]4^k2tjjl07L!rp0[Q +mf)YUnF?MKs766_rUg6cp\4U\s7u]kqtp?ir;H3cJcF:#J,~> +JcC<$JcFX-o`"gfrqu]ks8)ckrqQNf!;?EbFS,1qo'u5ro+:Di8j5f=bkl0iGlM0]=m/$)VmdKW7 +o(2PJpWCY3amR4Ma8T*=<;KPl;Z9PSs8Tt@`5BL2`5T^k`pC\?`$iNDF*)PJGB\=YH@1-hIXls" +JqJ`1L5(M@M2I4MN/`jYO-#KeP*;.0Pld8rD3L])r/KnP-WKDpK%JbXcjJ,"QnJcC?#KE$W)L&Qf3 +LPUbCM2I1Kreq#?NfT6_OoCMZPE_>tQC!u+R@9V7S=Q7CT:hmPUSO]^VPg>kWiE,$Xfek3Yd(O@ +['d?O\@K/^]Y(qm^VI\&_o0O6a2lBFbKJ/UcHjkbdaQ^rf%8O+g"P39h;-rFi8N\Uj5f=ak3(sm +l0@R"m-O--rpL-^naZ2@oCMVHrq6 +JcC<$JcFX-o`"gfrqu]ks8)ckrqQNf!;?EbFS,1qo'u5q3h2Mk*u:=qOIYYD!-TOLAI\FV#R7rVPgAk +WMuntrN#gsqlTe!p94@ts02X2ZaKb!qj6H2nWip9!1!O`s&AhnrDNVls3(Dcrlkbnc-=JWbfn>V +bl5lecMc#fcMs'uPOjt:POt"cEcZ>FG'A.UH?sseI=?]sJV&N-Knb>o(2JFo`"O` +pAamcq#C0hqYU0hr;?Nardk+"s*t~> +JcC<$JcFX-o`"gfrqu]ks8)ckrqQNf!;?EbFS,1qo'u5bpe^-LqG@,fr)35co0`OUr_`Jhs&&Meqbco\mnj5;=s>5h\%>5qh-?2[^q;WCXM:]OAl;#F2irg3bTR[X/Ds.'%Yl^n'Grg`kTs-itUrL!VOs-EYLs-*MI +rK75EOHBI&!fi8"rf$l8!/gc4s+p]1rItB-KS98Urdt-#pji-hpji?ps+:3%s+LE+re:Z5LkpnE +MMd>kN!53$O,oBbrfV&\Pa.N"Q^F/.R[]e:SXuFFTV8*TUnjiaVl-MoWiN5'Y-5(6Z*UdD[C3QS +\[f>b]Y2(p^qmn*`5Ta:aN;TJbK\>Xcd:(fe'uq!f@S[.g=tE=h;7&IiSrnXjQ5OdkNM0plK[^% +m-X6?mg/FQnac8BoCV\Sp&Facp\jmeq>U6fqu6NkrUTr=s4.."~> +JcC<$JcFX-o`"jgrqu]ks8)ckrV1^5p@e1Po^qbGo'u5ro+1Ai8EMLh;$caOnY%3OnFn%OTO(^ +e,7YodJ_Glchu)gc2PojbK@uLaN4%ps2OiQ!6"Jqrg*>Er58BJs24iSqnrZ:2hu;Rjr)!Gjjo>4qrl"iUq8VjApr"e)F*)MHGB\:XH@($fIXcm! +JqJ]/L5(J>M2@+JN/WdWO,oBbP*2#nPa.N"QC%Q;s-`nUr1!\UqORGRqORSTqj[VSrgE_Ps-NbO +rg!MJs-*GFs,m>Crf7,@NK*prs,-l7rJ:T3LPPh_s+UK+r.G$$rdj3^s+10$rIb-'s+UH,s+^T1 +reUZ5MuJY9NK4"!G*%iLP*;,qQ'Rc(R$jD4S"-%@StD[LTq\aND]Lbg"GZd*^:jeC<%#f@\d1g>(N?hV[8LiSrnXjQ5OdkNM0p +lKdg'mHs?1n*oi:rpg-^o^r.Us7ZKerV6Bfs8)WirVZWmo)=4?ec1.~> +JcC<$JcFX-o`"jgrqu]ks8)ckrV1^5p@e1Po^qbGo'u5r1s@is/,mr +WW&prX8B!rXo#9pYPk[2Z*L^B['[6-Qi!0LQhZmEQ1L=5Q2$XHt +QC!u+R@9V7S=Q7CT:hmOU8+N[V5C/hWN)u!XKAY/YctC=Za@-K\%&uZ]=bei^V@S#_Sa=2`lH0A +b0.uPc-FY^dF-LneCE1&f\,!4gtgfChr*GOioB([jlY^gkiq?slg4!*mI'H3nF5uIncJFTo`"O` +pAamcq#:*hqYU0gr;HTbrdk+"s*t~> +JcC<$JcFX-o`"jgrqu]ks8)ckrV1a6p@e1Po^qbGo'u5i;#a>j;#a>` +:AI]^:@g[L4TI\@4oA.P:\mo`:B45Z:\mod;>a>d;#j&U7.jIX;>3oa;=[QQ;?'Pj<;]Yp8`<;? +4u+r>5VP&>5h_->[:Y2;tX&R;=@<`;,pRpqG[>jr)!Gjrc8'[rc8']rcS3` +!-eEe!."Hd!d]3?rD`Vnq,[)erDrYm/obrSFEMeOG^=[_I!pHnJ:W<)K7nu6LPUeDMMmFPNfK0] +OHG]hPE_;sQ'R`&rL!VQs-ikTrg`hUq4@GRrLEbSs-iqTrL!VOs-EYLs-3PIrf[;Ds,d5@!fi8" +rf$l8!/g`3!f2VerJ(?+s+L<&s+:6$k(*J_rdt*$s+LE+reCH.!/UW2!K)g7Mueourf;5aOcklk +Pa.N"Q^F/.R[]e:SXuFFTV8'RUSO]^VPgAlWiE,$Xfek3Yd(O@['d?O\@K/^]Y(qm^VI\&_o0O6 +a2l?EbKJ,ScHjkbdaQ^qe^rF*g"P08h;-rFi8ESRj5]4^k2tjjl07L!m-O-,mdKW6nF?MK!qZ'V +rq6 +JcC<$JcF[.o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_no+'fn*f]2m-Es$ki_*jjQ#7Yi8rd[J7--[JR?-Zi.30h>Q41i;_a>ioB+] +kNMp0r9F"A!:'RLr9X@K$L[BPnalDGp@n@XrQ/8LP^kFMirD3L]3&.L&Qc(KDpK$Ja%^aJc:9" +KE$W)L&Qi,LB*/0M$o3!Mi +JcC<$JcF[.o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_no+'fn*f]2m-Es$ki_*jjQ#7Yi8"qNgoC!1*DHrHIpXopPH>qO.>OjI?(;qjd_YrJ:6(rJ:K/!/U6%s.fOg +s/#ams/,stWN)uqX8K'uXnf-nY6D/8Z*L^Brj;^5qj7/Hs-N_Nop,9;o9K0;M2@+JN/WaVO,oBa +OcklkPa)04!g]1>rL!VQs-ieRqOIGRqOIANrgNkTr0[MNs-EVKs-3PIrf[;D!0I/?!fi8"rf$l8 +s,-f4s+p]1reCH,re16&rdt*"l%&bardt*$s+LE+reCH.!/UW2$]9k#N/WaVNfT6_OoCMWPE_>t +QC!u+R@9V7S=Q7CT:hmOU8+N\VPg>jWN)u!Xf\b0YctF>Za@-K\%&uZ]=bei^V@S#_Sa=2`Q-'@ +aihlOc-FY^dF$FmeCE.%f\,!4gYCWAhr*GOioB([jlY^gkiq?sli-5OmI'uB!V#XYo)J:]o_nI_ +p&Ojbq#C0hqYU0hr;?Nardk+#s*t~> +JcC<$JcF[.o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_noF9in*f]2m-Es$ki_*jjQ#7Yi8a:A@W_ +:A@$H5PdSB;#3u`;#3ub;"@EY;#O8h;YO&Y7J0RY;>*ic;=IEQ;?'Po;u0Jk;tN]\9DV9X9DqK^ +4bts>5;>$>5qh)>kCtg;XdQM;#aMl;uKVl;>j;qF)l;BF*)O&FTQ`1 +GQ)ggGBe?1GlE$d<;KVk;M2@+JN/WaVO,oBa +OcklkPa)04!g]1>rL!VQs-ieRqOIGRqOIANrgNkTr0[MNs-EVKs-3PIrf[;D!0I/?!fi8"rf$l8 +s,-f4s+p]1reCH,re16&rdt*"l%&bardt*$s+LE+reCH.!/UW2$]9k#N/WaVNfT6_OoCMWPE_>t +QC!u+R@9V7S=Q7CT:hmOU8+N\VPg>jWN)u!Xf\b0YctF>Za@-K\%&uZ]=bei^V@S#_Sa=2`Q-'@ +aihlOc-FY^dF$FmeCE.%f\,!4gYCWAhr*GOioB([jlY^gkiq?sli-5OmI'uB!V#XYo)J:]o_nI_ +p&Ojbq#C0hqYU0hr;?Nardk+#s*t~> +JcC<$JcF[.o`"gfrqu]ks8)ckrqQNf!;?EbFS,1qo'u5M1K +_uI[S_uI[R`W!mP`VH2&TDtM^`;[aM`rF*OaR@7Ab5KN_bl>ogcF3DRrj;F-qm?=.s5!_3s53k8 +s5F.@jQGb+l20c@li$,Ili-8LmJlYTnH\XWp%S7Wq>1$3pW<6Pn]C[L!6OfQ!*&horDNPjqG?>S +pr!-Mrl+`RkJ\okF*)PJGB\=YH@('gIXcm!JqJ]/KnbA=M2@+JN/WaVO,oBaOcklkPEc'3s-E\O +rL!VQrgNJK!1`YMrL3_Rr0[MNs-EVKs-3PIrK75EOHBF%!fi8"rf$l8s,-f4s+p]1rJ(?+s+L<& +rdt*"l[\qbrdt*$s+LE+reCH.!/UW2(lF60N/WaUNfT6_OcbfiPE_>tQC!u+R@=,E=IbqRT:hmO +U8+N[V5C/gW2ZetXKAV-YHY:;Za7$H[^WcW\\#Me]t_=t_8=+.`Pom=aN;TJbg"GZd*^7heC<%" +f@S^0g=tE=h;7&IiSrnXjQ5OdkNMp0$gR'Em-X6/n*fc9nc&(\oCV\Sp&Facp\jmeq>U6fqu-Hk +rUTr=s474#~> +JcC<$JcF[.o`"gfrqu]ks8)ckrqQNf!;?EbFS,1qo'u5Er'bUQfaV'Q2d0KQi<<>Qi21-GP?:SRIlmCRJrZ8S,JlSSc"??M#N2+M"HK&U]%"g +VZ3RoVu`ltq5aIqs/l(!pTOV$!jT&;rj;[4!4Mlmq3V&Is-NVKp6GK?n!LHd_;uKVl;>O,h +b5TTab5]Qbb/qd)b5]Wkb0.uNb0.uPbKKdGnrr7".WTTPF`qtQH$Xd`I=6QoJ:W<)K7nr5LPUeD +MMmFPNK0'\OH>TfP*;)org!MLs-N\Os-`kToU>iNo:,]IrgE\Os-NbOrK[DIs-*DE!g/S+rJq#? +NK*prs,6o7re^Z2s+gQ-s+UK+r.G!#rIO9brIOs"rIb-'s+UH,s+^T1reVJLMi3OQNK&sZO-#Kd +P*2#nQ'IZ%R$a;1rgR#[SXuIHTqS3UUnjiaVl-JmWiN5'Xfek3Z*L^B['d?O\@K/^]Y(qm^VI\& +_o0O5a2l?Db0/#RcHjkbdF-Ooe^i@(g"P07gtgfChr*JQj5]4^k2tjjrojgUlg4!*mdBQ4nF?&J +ncJFTo`"O`pAamcq#C0hqYU0gr;HTbrdk+#s*t~> +JcC<$JcF[.o`"gfrqu]ks8)ckrqQNf!;?EbGkCUuo'u5K`rDEPjrDEJjpegKKp/:ofpe^ibnPJmUrDNSmrD`YmpIbEX +r^uQNqc<;is&f8'!a&T-rE05+=^##.=TDY"=oV\*>Pqb*;YO,h +Er^=YFoHUbGlMsdGQ2pfGli;;H2CS:jWN*##Xf\b0Yd(L?Za@-K\%&uZ]=bei^V@S# +_Sa=2`Q-'@ai_fNc-FY^dF$CleCE.%f@em3gYCW@hV[8MioB([jlY^gkl0fSlKdg'mI'E2n*ol; +rpg-^o^r.Us7ZKerV6EgrqcNhrVZWmo)=4?f)L7~> +JcC<$JcF[.o`"jgrqu]ks8)ckrV1^5p@e1Po^qbGo'u5'd*L"_c-=JUb/qcHoZ-mLqO%8MqO%#Drg*N$qSVjA!5nfQqSE'GrPSQOqo/QSpr2Zo +rl"iUpW!6Ro>p=@oud3UrQP>fqmPUos0Vd]s53k7s5F.@jQ5V)l2']AlhTiElN$;Nm0rFOnF?,B +p%S7WqYU3fb4s*OaS*a@aS]!8;Z0Jd;!7lP_uI[S`VRU=`?oVHFED\MGBeF[H[L6jIt3'#JqJ`1 +L5(J>M2@+JN/WaVO,oBaOoCLFPE_=2Q2d0MQi*6MRJiTCS,JfSRJWBNQiEBMQ2d*KPPp[EOoLOB +O8k7?NW+n:MuS\5M#rKgL])u,L&Zi(KDpK$Ja@pdJc:9!KE$W)L&Qi,LB*/0M>rG5MuJY9NK4"! +"d"k0P*;.0Q"H>KR$a;1S"#q=St;RITqS3UUnjiaVl-MoWiN5'Xfek3Z*L^B['mEP\@K/^]Y(qm +^VI\&_o0O5`lQ6Cb0/#RcHaeadF-Lne^i@(f\,!5gtgfChr*GOioB([jlY^gkiq?sli-5OmI'uB +!V#XYo)J:]o_nFap@n=Zq#C0iqYL*gr;?Nardk+$s*t~> +JcC<$JcF[.o`"jgrqu]ks8)ckrV1^5p@e1Po^qbGo'u5R.gU]7(eEr'eME92*2DuuZ'T)G5[SG&HG +RK/cAR/1k&F7OALEW)1'Q0Xb0Q2-a0Qi;7"GP@NtR/36MRdusIRe<0JSG\rTMZ8P'M"QQ&U]7.i +V>dCmVu`ltq5aIq!3Q.$!3Q7'!3c@(r3$L4Z*L^B['[6L[^WaBQLgI?QM-UAQLU7?QMa\[;Z0Jd +:]nk`b0'V'!6G/]rlP5aqo\r^q3(<4l&mB6F*)MIGB\:XH@($fIXcluJV&N-Knb>;Ll$tGMiCrf@)>s,I#:s,6o7 +rJ:T3LPPh_re:B*r.G!#rIOkWiE,$Xf\b0Yd(L?Za@0L\%&uZ]=bei^V@S#_Sa=2`Q$!? +ai_fNc-FV]dF$CkeCE.%f@\d1gYCW@hV[8LiSrnXjQ5OdkNM0plKeH9!U]=SmfDqJrpp*\!;-6_ +!quB_r:p +JcC<$JcF[.o`"jgrqu]ks8)ckrV1m:p@e1Po^qbGo'u5*rET1sq,?`[p/1fcq+pud +r_NGjrDNSkp.u':FEM_JFEM_LGPcR_G5umdGl`/6q,I/iqGui\-?=0LFEVkPG^=[_I!pHnJ:N3& +K7nr5L51SAM2I4MN/`jYO-#HcrfR>HPa)04s-E\Or0[JOrL32ErL3\Qqj@ALs-EVKs-3PIrK@2C +s,d5@s,R,=rf$l8s,-c3!f2VerJ(<*s+L<&rdt*"m"#(drdt'#s+LE+reCH.!/UW2s,$f7repl; +NrG(COHG]hPEc'3AsSdNR$jD4S"-%@StD[LTq\b +]Y2(p^qmn*`5T^8aN2KGbKS5VcHstddaQ^rf%8O+g"P39h;-rFi8ESRj5]4^k2tjjl07L!rp0[Q +mf)YUnF?MKs766_rUg6cp\4U\s7u]kqYU9ir;H3cJcF@%J,~> +JcC<$JcF^/o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_no4-gn*f]2m-Es$l0%3kjQ#7Yi8EFa&%S +H$XgbI=6QoJ:W<)K7nr5L51SAM2I4MN/`ksNrb?)rf[;F!0mGIs-E\Oqj@;LnXBBDqO%8Krg*MJ +s-3MHrK75EOHBF%s,R,=rf$l8s,-c3s+p]1rJ(?+s+L9%rdt'!n::Ffrdt'#s+LE+reCH.!/UW2 +s,$f7repl;NrG)YOHG]hPEV5rQ'Rc(R$jD4S"-">St;RITqS6WUnsrdVl6SpWiN5'Xfnt5Z*L^B +[C3NQ\@K2_]Y(qm^VI\&_o0O5`lQ6Cb0/#RcHab`dF-LneCN7'f\,!4gtgfChr*GOioB([jlY^g +kiq?sli-5OmI'uB#k7BSo()DDo^r.Us7ZKerV6EgrqcNhrVZWmo)=4?fDg@~> +JcC<$JcF^/o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_no4-gn*f]2m-Es$l0%3kjQ#7Yi8=qEWC1WEWC+XQMm*:QM-U>QMHjIR.?U>GkH:TR/iWQRJE6HRK&`IS,A`IS,JlTSb\0= +M>)i"LBjTMUnsobVl0Nm!NE*sWr]<&r2]n#r3$%$q6'\"s02R1rj;^5"1G\K\G) +Q2X_\;Z0Ja;#AB7a8j9ZaSX*Yao]]-bP.1jPO"AUEcZ>EFa&%SH$XgbI=6QoJ:W<)K7nr5L51SA +M2I4MN/`ksNrb?)rf[;F!0mGIs-E\Oqj@;LnXBBDqO%8Krg*MJs-3MHrK75EOHBF%s,R,=rf$l8 +s,-c3s+p]1rJ(?+s+L9%rdt'!n::Ffrdt'#s+LE+reCH.!/UW2s,$f7repl;NrG)YOHG]hPEV5r +Q'Rc(R$jD4S"-">St;RITqS6WUnsrdVl6SpWiN5'Xfnt5Z*L^B[C3NQ\@K2_]Y(qm^VI\&_o0O5 +`lQ6Cb0/#RcHab`dF-LneCN7'f\,!4gtgfChr*GOioB([jlY^gkiq?sli-5OmI'uB#k7BSo()DD +o^r.Us7ZKerV6EgrqcNhrVZWmo)=4?fDg@~> +JcC<$JcF^/o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_no4-gn*f]2m-Es$l0%3kjQ#7Yi8F&T4oIS:5Nb61;>!cY;>a8j:\[]X +:\$gK5QF+H5QF%I;#O2b;#*oa;#3u`;#*ri;Gg +M2@+JN/WaVrf7)AOoCODP5pjGQ2d0MQi!0JRIQaDRJNrD3L])u-L&Zi'KDpK#Jae3fJc:9!KE$W)L&Qi,LB*/0M>rG5MuJY9NK4"!E0-3FP*;)o +Q'IZ%R$a;1S"#q(N?hV[8LiSrnXjQ5OdkNM0plKeH9!U]=Smg/FQnac8B +oCV\Sp&Facp\jmeq>U6fqu-HkrUTr=s4@:$~> +JcC<$JcF^/o`"gfrqu]ks8)ckrqQNf!;?EbG4bCso'u5YgR/Ou"_t(bE_uIUN_>M1K_u%CD`W!mDT`2q*`rF*VaSX$VaT'B^aSEsX +aSX*Qb5]Zabl>rdc2b?L[d1?u[LBS#hr*JPioB+^kih:+lMTrKlKS'.s6C9`mI'E2nac;Ep\=R\ +qu$EkbO`mPan3[Janj*Wa8X-[;uKVl;=RKHs7jM3_Z.OQ`;dgP`pCYbEccDGG'A1VH?spdI=?Zr +J:W<)KS>/8LPUeDMMqIm!KE-=Nrb?)rf[;Fs-3JIs-EYNpmC]ApR(oGrg*JIs-3MHrK@2Cs,d2? +!fi8"rJ^c7s,-c3s+p]1rJ(?+re13%rIXrunppXhrdt'#s+LE+rJ(?-!/UW2s,$f7repl;NrG(? +OHKO*"d>19Q'Rd9Qu8=\S"#q=St;RITqS3UUnjiaVl-JmWiE/&Xfek3Yd(L?['d?N\%&u[]=bei +^V@S#_Sa=2`Q$!?ai_fNc-FV\dF$CkeC<%#f@\d1g=tE=hV[8LiSrnXjQ5OdkNM0plK[^%m-X6/ +n*fc9nc&(\oCV\Sp&Facp\jmdq>^ +JcC<$JcF^/o`"gfrqu]ks8)ckrqQNf!;?EbFnG:ro'u5d=qVl6PnWN,ls!N`F%XT,F%Y5>@"Y5bX(Y5b[7Yd(I>['dM2@+Jrepl;NrG(?OHKO*s-*JIrK[DKrg3DIoU5H@rKmMLr0@;Hrfd;Ds,m>CrJq#?NK*mq +s,6o7rJCQ1s+gQ-s+UH*r.Fs"r.4Ehr.4j!r.G$&s+UE+s+^T1re^Z4!/pi8!KE-=Nrb?)rfRGK +Pa.N"Qi<@iR@9V7S=Q7CT:hmOU8+N[V5C/gW2ZesXKAV-YHY79ZEppG[^NZT\[oDc]Y2(p^qmn* +`5T^8aN2KGbKS5VcHjncdaQ^qe^rF*g"P07gtgiEi8ESRj5]4^k2tjjl07Kulg4!*mdBQ4nF?&J +ncJFTo`"O`pAamcq#:*hqYU0gr;?Nardk+%s*t~> +JcC<$JcF^/o`"gfrqu]ks8)ckrqQNf!;?EbFnG:ro'u54o.>B;=RKV;?'Jk +:\dcZ:]EZX5kmY=5lX(J5lFOY:\R]^:]!u`:\mo];=mcQ7/0[R;>j>g:\@Q[;?'Pj;ts8h;uK;g +9DqKY8cD?Z9D)!X6J,4=]ei*=Su;&>$Ll/s'>Funl,B_l;@RXqbI2j +rDNPjnPK1+rH/0bF`mY+!-eBd!-\?c!-n3:qGm>llr>'HFEDYKGBeCZH@('gIXcluJV&N-Knb>; +Ll$tGMuJY9NK4"!!K`HCP5gaGPl6mIQN!6GR.Qg@R/NBNQMd$JPl?mFP5g[EOSt4ANfB%sN;nh9 +MZ&D3M#W8/LAuu,K`$K$K)C2jJGautK)C9$K`?c)LB!#/M#N82M?&S6Mueourf7)AOoCLIPE_>t +QC%T)Y-5(6Z*L^C[C3NQ\@K2_]Y(qm^VI\&_o0O5 +`lQ6Cb0/#RcHab`dF-LneCE1&f\,!4gYCWAhr*GOioB([jlY^gkiq?slKdg'mI'E2n*ol;rpg-^ +o^r.Us7ZKerV6Bfs8)WirVZTlo)=4?f`-I~> +JcC<$JcF^/o`"jgrqu]ks8)ckrV1a6p@e1Po^qbGo'u5:ciW\B'jlYdkpZh_Cs69UKq!.kE&FAfPn*ol= +p%A(Tq>:*frVl`/8LPUeDMMqIm!KE-=NrkE*OoCODPQ-mFQ2d0KQg'n9Qi36JQ2[$JPPgUDOoLOA +O8k7?NW"h9MuS\5M>rD3L])u,L&Zi'KDgE!Jb=QkJc12uKE$W)L&Hc+LB*/0M>rG5MuJYCNK0$[ +O-#KdP*2#nrfqAeQ^F/.R[]e:SXuFFT:hmOU8+N[V5L5iWN)u!XKAV-YHY7:Za7$H[^NZU\[oDc +]Y;.q^qmn*`5T^8aN2KGbKJ/UcHjkbdaQ^qe^i@)g"P07gtgfCi8ESRj5]4^k2tjikiq?slg4!* +mI'uB!V#XYo)J:]o_nI_p&Ojbq#C0hqYU0hr;?Nardk+%s*t~> +JcC<$JcF^/o`"jgrqu]ks8)ckrV1^5p@e1Po^qbGo'u5oni3ps/#am!2ogp +s/?!urMoq"riQ4%riQ4'qQ9b"rN6+&$*US;ZEppG[^N[E\,a);QN3?5Qi!*8Q2X\Z;=79\a8;Ll$tGMuJY9NK4"! +!g&P,rf[;Fs-3GHs-EVMl'VF9rKdAHrfmGHr0%)Bs,d2?s,R,=rJ^c7s,-c3s+p]1rJ(<*s+L9% +rIXotomlskrIXs"s+LE+rJ(?-!/UW2s,$f7req5ENfK0]OHGZgP*;.0Q#;nSR$a;1S"#q=St;RH +TV8'RUSO]^Vl-JmWiE,$Xf\b0YctF>Za@-K[^WfX]">Vf^;%Fu_8=+.`PojXcd:(f +e'umtf%8R-g=k<:h;-rGi8N\Uj5f=ak3(pkl07L!m-O-,mf)YUnF?MKs766_rUp3a!;HEds7uZj +qtpBjr;H3cJcFC&J,~> +JcC<$JcF^/o`"jgrqu]ks8)ckrV1^5p@e1Po^qbGo'u55_Y,>$5#,=T;J&=T)A(>$G51>Q\8/8LPUeDMMqIm!KE-= +NrkE*OoCODPQ-mFQ2d0KQg'n9Qi36JQ2[$JPPgUDOoLOAO8k7?NW"h9MuS\5M>rD3L])u,L&Zi' +KDgE!Jb=QkJc12uKE$W)L&Hc+LB*/0M>rG5MuJYCNK0$[O-#KdP*2#nrfqAeQ^F/.R[]e:SXuFF +T:hmOU8+N[V5L5iWN)u!XKAV-YHY7:Za7$H[^NZU\[oDc]Y;.q^qmn*`5T^8aN2KGbKJ/UcHjkb +daQ^qe^i@)g"P07gtgfCi8ESRj5]4^k2tjikiq?slg4!*mI'uB!V#XYo)J:]o_nI_p&Ojbq#C0h +qYU0hr;?Nardk+%s*t~> +JcC<$JcFa0o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_no4-gn*f]3m-Es$l0%3kjQ#:Zi8/8LPUeDMMqIm!KE-=O8k:AOo:ICPQ-mEQ2R$FQhm*FQi*0HQ2[$IPPgUD +OoLOAO8b1>NW"h9MuS\5M>rD3L\uo,L&Qc&KDgDtJbsuoJc12tKE$W)L&Hc+LB*/0M>rG5MuJZ\ +NK0$[O-#KdP*2#nPa.N"Q^F/.R[T_8S=Q7CT:hmOU8+N[V5C/gW2ZesX/rG*Y->.8ZEpmE[C3QS +\[f;`]Y2%o^VI\&_o0O5`lQ6Cb0.uQcHab_dF-LneCE.%f\,!4gYCW@hV[8LiSrnXjQ5OdkNM0p +lKeH9!U]=Smg/FQnac8BoCV\Sp&Facp\jmeq>U6fqu-HkrUTr=s4I@%~> +JcC<$JcFa0o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_no4-gn*f]3m-Es$l0%3kjQ#:Zi8E8P[4T`1S^T)G5USGScURf&TFR/V-c +Erq\oQMZsGQMZs?QM6[DQL1%;R/D3tGOV$uR/EBLReWBJRfAlWReiNNSGo)ZMtW&#M=QK&V$Elq +Vl6PnWN,ru!3H!us/u$s!3H1%s/u^4Z*L^C[C3QRrjVs=g6_`'n&Z +s2P;aaihoRd-HkcPP^OAOWSUbFEMbNGBeCZH[L6iIXcluJV&N,KS>/8LPUeDMMqIm!KE-=O8k:A +Oo:ICPQ-mEQ2R$FQhm*FQi*0HQ2[$IPPgUDOoLOAO8b1>NW"h9MuS\5M>rD3L\uo,L&Qc&KDgDt +JbsuoJc12tKE$W)L&Hc+LB*/0M>rG5MuJZ\NK0$[O-#KdP*2#nPa.N"Q^F/.R[T_8S=Q7CT:hmO +U8+N[V5C/gW2ZesX/rG*Y->.8ZEpmE[C3QS\[f;`]Y2%o^VI\&_o0O5`lQ6Cb0.uQcHab_dF-Ln +eCE.%f\,!4gYCW@hV[8LiSrnXjQ5OdkNM0plKeH9!U]=Smg/FQnac8BoCV\Sp&Facp\jmeq>U6f +qu-HkrUTr=s4I@%~> +JcC<$JcFa0o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_noF9in*f]3m-Es$l0%3kjQ#:Zi8<;onr;#jGj:]=,_:Z"A: +;#O2V;#X>l;"mcb;"[]Y;ZB2_7.`kH7/9^\;>j>i;?'Gm:]*ub:\[cb;>O/j;uBPn;>*oa9DM9[ +9DhE\8cD?\9D_E_Q7k0=]ed-=Su8"=T;P(>5qh+?2e.1;tW;?'Pm +;/8LPUeDMMqIm +!KE-=O8k:AOo:ICPQ-mEQ2R$FQhm*FQi*0HQ2[$IPPgUDOoLOAO8b1>NW"h9MuS\5M>rD3L\uo, +L&Qc&KDgDtJbsuoJc12tKE$W)L&Hc+LB*/0M>rG5MuJZ\NK0$[O-#KdP*2#nPa.N"Q^F/.R[T_8 +S=Q7CT:hmOU8+N[V5C/gW2ZesX/rG*Y->.8ZEpmE[C3QS\[f;`]Y2%o^VI\&_o0O5`lQ6Cb0.uQ +cHab_dF-LneCE.%f\,!4gYCW@hV[8LiSrnXjQ5OdkNM0plKeH9!U]=Smg/FQnac8BoCV\Sp&Fac +p\jmeq>U6fqu-HkrUTr=s4I@%~> +JcC<$JcFa0o`"gfrqu]ks8)ckrqQNf!;?EbFnG:ro'u5)^!6k2^!7(SRp:'h*q6g./qmQdhjQ5Oekiqg+!:0LHrTjFIrp(-_mdKZ9o(;YM +q"adarVlisrlk>am)o1Ho>pjOrQ+uYrDDcTlMpb"!5nKJrl+KKr5JTP)fg"AFEMeOG^4U]H[L6j +It3'#JqJ]/Knb>;M#N53MMqIm!f`5#rf7,BOcfU*s-*GHqN^E5pm(iCrfd8CrfR5Br/^lVg^;%Fu_SX4/ +`Pom=aN;TJbK\>Xcd:(fe'umtf%8O,g=k<:h;-rFi8ESRj5]4^k2tjjl07L!lg4!*mdBQ4nF?&J +ncJFTo`"O`pAamcq#:*hqYU0gr;?Nardk+&s*t~> +JcC<$JcFa0o`"gfrqu]ks8)ckrqQNf!;?EbG4bCso'u5TDrg3VOpj)CSnjWMuntX/rDtXT5NuXo,7-Xfeh1Z*CXA[C*IB[fX(M\^m,EQM$OA;s,R,=rJ^c7s,-c3reUT0rJ(<*re10$r.=?f +r.=j!re1<*rJ(?-!/UW2s,$f7reqDJNfK0]OH>TfP*;,pQ'IZ%rg7\nR[]e:SXuFFTV8'RUSO]^ +V5C/hWN)u!XKAV-YHY79ZEpmE[^NZT\[f;`]Y2%o^VI_'_o0O5a2l?Db0.uQcHab_dF-LneCE.% +f@em3gYCW@hV[8LiSrnXjQ5OdkNM0plKdd&m-X6/n*fc9nc&(\oCV\Sp&Facp\jmdq>^ +JcC<$JcFa0o`"gfrqu]ks8)ckrqQNf!;?EbGkCUuo'u5;cN`rrD`eq!)iPggHFR\l;7:R!)WShs%`8`hEV!8 +lVRRXrD<;cr_W8bp/:ZSr^?BGq,.)er)!Jk:]!ob:\moe;#sQlp/:fcp/:WXoM#9Xp.G3U!`iB( +qc<\tpK.c*>$>-6>$4s0=',?$r`B)$s&oA*s'5S0ra#S'mSa$_r)3Aiq,6NUkYV;$rH/0bGBWq/ +!HrVaFour6H[Y3[nQ,Hc)fg"AFEMeOG^4U]H[L6jIt3'#JqJ]/Knb>;M#N53MMqIm!f`5#rf7,B +OcfU*s-*GHqN^E5pm(iCrfd8CrfR5Br/^lVg^;%Fu_SX4/`Pom=aN;TJbK\>Xcd:(fe'umtf%8O,g=k<: +h;-rFi8ESRj5]4^k2tjjl07L!lg4!*mdBQ4nF?&JncJFTo`"O`pAamcq#:*hqYU0gr;?Nardk+& +s*t~> +JcC<$JcFa0o`"jgrqu]ks8)ckrV1a6p@e1Po^qbGo'u5K7\W' +I=-?eG^":PF)c/;DJX*'BkV-jARf1X?sd7:klBrCkPOEAP5CCAO8tF*P5CI,P4mQ*fDF.ueHF@L +da?D?c3MV%8k"u'Vrr2utrVllsp](*.s24QKrPeEKrPe]Q*--+BFEMbNGBnL\ +H[L6iIXcluJV&N,KS>/8LPYqd!K)g7Muo!!NrG+>OT1IAP5^[EPiJ&-Pl?mDP5g[DOSk1>NrP+; +N;eb8MZ&D3M#N2.LAlo+K_g?!K(+?hK):3#K`6])LB!&/M#N82M?&S6N"Cu/NfT6_OHG]hPEV5r +Q'Rd9Qj&nHS"#q=rgm;cTV8'RUSO]^VPg>jWN)u!XKAV-YHY79Za7$H[^NZT\[f>b]Y2%o^VI_' +_o0O5a2l?Db0.uQcHab_dF$FmeCE.%f@\d1gYCW@hV[8LiSrnXjQ5OdkNMp0$gR'Em-X3.n*fc8 +nc&+Zo)SF]o`Fj]p\agdq>U6fqu6NkrUTr=s4RF&~> +JcC<$JcFa0o`"jgrqu]ks8)ckrV1g8p@e1Po^qbGo'u5K7\W' +I=-?eG^":PF)c/;DJX*'BkV-jARf1X?sd6'Xfek3Z*L^C[C*IB[fX(M]@<2FQM6[C +;EF`qtQH$Xd`I!pElIt3'#JqJ]/Knb>; +M#N53MMqIm!f`5#rf@)@s,m8Crfd>Gj-BS-rfd5Bs,m;Br/^ltQC%T<"dtgKS"-&KSm%bZ +TqS3UUnjiaVl-JmWiE,$Xf\b0YctC=Za@-K[^WcW\\#Me]tV7r^r!t+`5T^9aN2KGbKJ/UcHjkb +dF6Upe^i@(f\,!5gtgfChr*GOioB([jlY^gkl0fSlKdg'mHs?1n*oi:rpp*\!;-6_!quB_r:p +JcC<$JcFa0o`"jgrqu]ks8)ckrV1a6p@e1Po^qbGo'u5K7\W' +I=-?eG^":PF)c/;DJX*'BkV-jARf1X?sd7>;ZKeri;?0Ym +;X[9R9`7W\9)M?^=8Q%u=8#_t=^##.=TMW+r`9&!r`9#"s&f;(#[1G:>[1Q@?=2YhqG[2fn58=E +!-J0^rH8TfP*;)oQ'IZ%rg3kWR[]e:Sc53aT:hmOU8+N[ +V5C/gW2ZesX/rG*Y-5(6Z*UdD[C3NQ\@K/^]Y(ql^V@S$_Sa=2`Q-'@ai_fMc-FV\d*^7ieC<%" +f@S[.g=tE=h;7&Ii8N\Uj5f=ak3(t-kmQeBm-O-,mdKW6nF?MKs766_rUg6cp\4U\s7uZjqtpBj +r;H3cJcFF'J,~> +JcC<$JcFd1o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_noF9in*f]3m-Es$l0%3kjQ#:Zi8q6QBdYsOH5B[MM[+CKS+i+ +Isl]jH$=ITFE2A?DJj9+C2%?nAS#@\@:3GKkkaNDkkO??joCSq8E6Lr5ANPn=fTLou?gJn]:RK +rlY2_q9/i`rm(GdqRH7.k-bKVkNM0plKe92rp0IHs6K^Ms69RKs6C0^mdTc;oCV_Lq"ad`rVlcq +rltGdrlaKIqT86Js&%fQ"T85srr)iq"9&5trqHHi`;RUI`;R[J`r3mS`#!K:FEMbNGBeCZH[L6i +IXcluJV&N,KSBD[!JcL1M#iKlrf$l:!07#=s,d8Cr0%&Cr06W7r07/DqNCi?s,d,=s,R,=r/CZ6 +s,-`2s+p]1r.b3)re1-#qh"Bir.=fure1<*rJ(?-s+pZ2s,$f7reu8bNfK0]OH>TfP*;)oQ'IZ% +Q^F/.R[]e:S=Q7CT:hmOU8+N[V5C/gW2ZesX/rG*Y-5(6Z*L^B['d?N\%&u[]=bei^;%J"_SX4/ +`Q#s>aN;TJbg"GYcd:(ee'umtf%8O+g"P39h;-rFi8ESRj5]4^k2tjjkiq?sli-5OmI'uB!V#XY +o)J:]o_nI_pAamcq#C0hqYU0gr;HTbrdk+&s*t~> +JcC<$JcFd1o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_noXEkn*f]3m-Es$l0%3kjQ#:Zi8q6QBdYsOH5B[MM[+CKS+i+ +Isl]jH$=ITFE2A?DJj9+C2%?nAS#@\@:3GKVPg?bVYd4%EV?(*TDY8\SbelQRfJoRRJrQUR@'A0 +rH.jVqK2XXpN6CUqj72Gp6GE=qN^ZoUGlLrgW\OrL3eWrgj%Ys./b> +qMP$(o8*FF!3,sts/Q.$or\(lqlBb!s/uU1ZEpmE[JmT8\@MRLerD3L\uo+L&Qc%KDU8kJc(,sKDpQ( +L&Hc+L]<20M>rG5MuJZ`NK0$[O-#HcP*2#mPa.N"Q^=),R@9V7S=H.AStD[LTq\Vf]tV7s_8=(,`5Ta:aN2KGbKS5VcHjkbdF6Upe^i@(f\,!5 +gtgfChr*GOioB([jlY^gkih9qlKeH9!U]=SmfDqJrpp*\!;-6_s7ZKerV6EgrqcNhrVZWmo)=4? +g&HR~> +JcC<$JcFd1o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_no=3hn*f]3m-Es$l0%3kjQ#:Zi8q6QBdYsOH5B[MM[+CKS+i+ +Isl]jH$=ITFE2A?DJj9+C2%?nAS#@\@:3GKrDW_qs&Jtr!E2nn;#icP53b;g55S.K:]OAg;#=)i +;"RNa:dFJ6nj*1=s%hcRs%rbml;@:Ro1&^Js$ZZM!)`GdrD![1Q??=.&Gr_qcRqG[2fp/0jH!-J3_ +s*+Hc!HiM`FoQUgG^=^aI=:%=OT1I@P5^[CPjXh7Pl6gBP5^UDOSb+=NrP+:N;nh9MYr>2M#W8.LAlo+K_g>uK(=Kj +K):3"K`?c)LB!&/M#N82M?&S6N.$\GNfT6_OHG]hPEV5rQ'Rc'R$a;1S"#qjWN)u!XKAV-YHY79ZEpmE[C3NQ\@K2_]Y(ql^VI\&_Sa=2`lH0Aai_fNc-FV\d*^7ieC<%" +f@S[.g=tE=h;7&Ii8N\Uj5f=ak3(sll07L!rp0[Qmf)YUnF?MKs766_rUp3as7cKes7uZjqtp?i +rVc +JcC<$JcFd1o`"gfrqu]ks8)ckrqQNf!;?EbGkCUuo'u5q6QBdYsOH5B[MM[+CKS+i+ +IXQTiH$=FSFE2A?DJj9+C1q9mARo:[@:3I)kNDd,s60OIpu_Y>nWEg4r/pK3p64p-s4RJ+p"9/n +r72J1eC;sqdEp4ccHXVXbKJ&Mao0<\SGJ`QRfAlURdZ[>`;mjP_tCn>_th7L_tV+2U%ZM'a7%+G +ao9H^bPKH_c2Grcc2"m@\*:='kNV6rrp0FGrp0IH!pf.:rTOjYm-X3/nFH2Cp@e7UqYU6gs8("> +bl5fGb5KH^a8j?WaP]kpqu-EqrVZWlrV$9g_Z[oq_o0L``V7CM`Vm^lEccDGG'A.TH$Xd`I!pEl +It3'#JqJ]/L&Qf-LPYqd!K)g7N;nn;Nr>%=OT1I>P5LO6Pl$[?P5UOCOSb+=NrG%9N;nh9MYr>2 +M#N2-LAlo+K_g>uK(FQkK)1-"K`6](LB!#/M#E/3MMmDlN"q>4NfT6_OHG]hPEV5rQ'Rc'R$a;1 +rgR/_SXuFFTV8'RUSFW\V5C/gW2ZesX/rG*Y-5(6Z*L^B['d?O\@K/]]=bei^;%J"_SX4/`Q#s> +aN;TJbg"GYcd:(ee'umtf%8O+g"P07h;-rFi8ESRj5]4^roOCIkiq?sli-5OmI'uB!q>aMrpg-^ +o^r.Us7ZKerV6Bfs8)WirVZWmo)=4?g&HR~> +JcC<$JcFd1o`"gfrqu]ks8)ckrqQNf!;?EbG4bCso'u5q6QBdYsOH5B[MM[+CKS+i+ +IXQTiH$=FSFE2A?DJj9+C1q9mARo:[@:3H=rMKRlpnn"dqf'>jpRqGVrgs+[r1*SP!1NbP!1<\P +s)n0[r,_jZqK;COpm:lDqN^*,s-NJIpj2X\q0MV"rL3bSr0m)DpmV5Ps.'%Ys.'(Zq2561p5Ad) +qhb*(rJ:TSWiH'!s/c$u!j&N+r2fmuri,t!ri?7*YHY:;rj2g9[^WcWr4:UK!1%=OT1I>P5LO6Pl$[?P5UOCOSb+=NrG%9N;nh9MYr>2M#N2-LAlo+K_g>uK(FQk +K)1-"K`6](LB!#/M#E/3MMmDlN"q>4NfT6_OHG]hPEV5rQ'Rc'R$a;1rgR/_SXuFFTV8'RUSFW\ +V5C/gW2ZesX/rG*Y-5(6Z*L^B['d?O\@K/]]=bei^;%J"_SX4/`Q#s>aN;TJbg"GYcd:(ee'umt +f%8O+g"P07h;-rFi8ESRj5]4^roOCIkiq?sli-5OmI'uB!q>aMrpg-^o^r.Us7ZKerV6Bfs8)Wi +rVZWmo)=4?g&HR~> +JcC<$JcFd1o`"gfrqu]ks8)ckrqQNf!;?EbGP(Lto'u5q6QBdYsOH5B[MM[+CKS+i+ +IXQTiH$=FSFE2A?DJj9+C1q9mARo:[@:3G@;uTYt;cH^rCtOn4*@FqF($RrDEMiq+plas&&bns&&Si!`MuprDESm +rDWVlh+RK7qc<_unQ5rr<`N.!<;ff"<``C+=oMS,>?kH>ra#Y5?=*J,iDTJMqGR5gi(sDrqfWEk +F*)MHF`r"UH[C-gIJ-Y1]auFEMbNGBeCZH@($fI=?ZrJ:W<)K7nsXL&m'creUZ5MuJ\8 +NW5%;O8k=AOnt7=POXn7PPLC?OoLO?O8k7>NVnb8MuS\4M>rD2L\uo+L&Qc%KDU8lJc(,rKE$W( +L&Hc+LB*//M#rQmMuJYMNK0$[O-#HcP*2#mPa.N"Q^=),R@=,E>b%@VStD[LTq\hV[8LiSrnXjQ6C'"m>+6l0@U6liHMArpKpXnaZVL!qZ'Vrq6 +JcC<$JcFd1o`"jgrqu]ks8)ckrV1m:p@e1Po^qbGo'u5&]rQP/`rQbAdpUKV"n?rD_lK\?6qs+.GqWe(Es6:*[mI'H4o(2MHpA"I[r;HKlp4NfT6_OHG]hPEV5rQ'R`&R$a;1rgO(]SXuFFT`1WuU8+N[ +V5C/gW2ZesX/rG*Y-5(6Z*L^B['d?N\%&uZ]">Vg^;%Fu_8=(,`Poj;aN2KGbKS5VcHjkbdF6Up +e^i@(f\,!4gYCWAhr*GOioB([jQ5OdkNM0plKdd&m-X6/n*fc8nc&(\oCV\Sp&Facp\agdq>^ +JcC<$JcFd1o`"jgrqu]ks8)ckrV1g8p@e1Po^qbGo'u5[:jVu!:gV=nlIEV?(&TDkG^Sc##RRfJoNRJM's +FSU(SFT.[%Qi*0JQ/e21QhZsCHMr3dI/&'_RJ!$7S,/QRS,AfTSH,2ZSc4NDMtr8.Mtr8,M#`A, +M#aRTX8]4#XoGL%XoGI&Xo,7%X/`6!WXc)2Xfek4Z*L^C[C*HP\GWo=\[p(QqN_,HhbapQPH:'p3NXFED\MGBeCZH@($fI=?ZrJ:W=OK*I!_L5(J=M#N54MMmDl +N;nk;Nr4t4NfT6_OHG]hPEV5rQ'R`&R$a;1rgO(]SXuFFT`1WuU8+N[V5C/gW2Zes +X/rG*Y-5(6Z*L^B['d?N\%&uZ]">Vg^;%Fu_8=(,`Poj;aN2KGbKS5VcHjkbdF6Upe^i@(f\,!4 +gYCWAhr*GOioB([jQ5OdkNM0plKdd&m-X6/n*fc8nc&(\oCV\Sp&Facp\agdq>^ +JcC<$JcFd1o`"jgrqu]ks8)ckrV1j9p@e1Po^qbGo'u5`QU4oRYB5Q3k14m,$( +:\dib;>F#g;>jAm;>j>f:\d9P5NtGp;"@K^;Yj8c;Y3HS8,c!T7JBXW;>j>i:\IW\;>X5n;c6Lj +qbmAkrDM3>rC[#hs&\_m!EN4t<;ol)<`iL->$>-7>[:Y6?34J??1q4U;Ya8e;Vt=NFoul1F`dV( +rcJHiG^=^aI!pD7<:X&]r3EcZ>EG'A.TH$Xd`I!pElIt3'#K)UB,KS>/8LPL]bM#rQmMuJ\8 +N<#":O8k=@Onb+0PP:7=OoCI>O8b1=NVnb8MuJV4M>i>2L\li*L&Qc$KDU8oJbjupKE$W(L&Hc+ +LB*//M#rQmMuJYMNK0$[O-#HcP*2#mPa.N"QC!u+R@=,E"e;-TStD\TTkL0qUnjiaVl-JmWiE,$ +Xf\b0YctC +JcC<$JcFg2o`"gfrqu]ks8)ckrV-EfpAX`1o^h\Fo'u5Orl+oWrPefTqSW9Ks24`Np;?[DoY]mdr1Nf( +qoA9K!6P,\q9/`\qT\uas3:Shp:07oqR6F5!pT"8r9O=Hqs4:I!pT"8rok!Zlg4!*n+#u?o_/%S +qYU3iq>^-4s31DahTGc<+It3'# +JqJ]/KS>/8LPL]bM#rQmMuJ\8NW5%:O8b7>Olqo*Oo:C=O8b1=NVe\7MuJV3M>rD2L\uo+L&H]# +KDC,pJbjupKDpQ(L&Hc+L]<20M>rJ5MuJY9NK4"!IuoeTP*2#mPa.N"QC!u+R@9S6S"-%@StDXJ +TqS3UUnjiaVPg>jWN)u!XKAV-YHY79ZEpmE[C3NQ\@K/^]Y(ql^V@S#_SX71`Q#s>aN;TJbg"GY +cd:(edaZdsf%8O+g"P07gtgfChr*GOioB([jlY^gkiq?slKdg'mJlVSn,MkWnc&+Zo)SF]p&Fac +p\jmeq>U6fqu-HkrUTr=s4[L'~> +JcC<$JcFg2o`"gfrqu]ks8)ckrV-EfpAX`1o^h\Fo'u5RerTQSGeuY +SGo)WMYi=oMY`20MZ0[UXT,F%XT,F!XT,@!WrB%,XKJb2Z*L^C[C3NRrODp>rOL%:rg)G2M#N2-LAlo*K_^8rK)'uoK)1-!K`?c)LB!&/ +M#N82MZ8V6Mueourf;PjOcbfiPEV5rQ'R`&R$a;1R[]e:SXuFFT:hmOU8+N[V5C,fVl6SpWiN5' +Xfek3Yd(L?Za@-K[^WcW\\#Me]tV7r^qmn)`5T^8a2l?Db0/#RcHab_dF$CleCE.%f@\d1g=tE= +h;7&Ii8N\Uj5f=ak3(sml0@R"m-O->mf2bUn,W"Xo)J:]o_nI_pAamcq#C0hqYU0gr;HTbrdk+' +s*t~> +JcC<$JcFg2o`"gfrqu]ks8)ckrV-EfpAX`2o^h\Fo'u51=BSg3>?kE=?N+=2?N4=&;rCRH;r:FMFo?C]F9Hc2 +G^4W4Hh15-;LPYqd!fDnorf$l:s,R#< +rfI)@kE>b*rK-o;rf6u;qi(Q5regW1s+pZ0r.b3)rIk!!q1AEnqL\Qrre1<*rJ(?-s+pZ2s,-i7 +repl;NrG)hOHGZgP*;)oQ'IZ$Q^F/.R[T_8S=Q7CT:_dMTq\b]Y2%o^VI\&_SjF4`lH0Aai_fNc-FV\d*^7heC<%"f@S[.g=k<:h;-rFi8ESR +j5]4^k2tjjl07Kulg4!*s6fpUs6p$Yrpp*\!;-6_s7ZKerV6EgrqcNhrVZWmo)=4?gAc[~> +JcC<$JcFg2o`"gfrqu]ks8)ckrqQNf!;?EbHM$h"o'u5q6QBdYsOH5B[MM[+CKnFu- +Isl`lH?aXWFE;JBDf0E-CM@HpAn>L_@UWYOjQ5Lcr9*t@rTEL0r/pT6o99-;o99.+n_!ckrRV#!% +b/tVda?Fgcd0n]c-4ARpRCuKpm_/Lq3qB'rl4oUs2=ZLrl"?EpVcaBjIuRG!6+cRrQ"NN"3J^.b +Po`^bPKHXc2>iechb3K\DF^olN-Ap%J.UqYU6jrqcWprq=V5bl5f?b +2H1r;?-Fpq"agbrq-6__u@UF`VRUM`?0/CFEMbNGBeCZH@($fI=?ZrJ:W9'K7ei2Knb>;LPYqds +,-i7rf$l:rf6l:rK-l'p+Q?P*2#mPa.N"QC!u+R@9S6S"-&KSctaZTqS3UrhNSkVPg>jW +N)u!XKAV-YHY79ZEpmE[C3NQ\@K/]]=bei^;%Fu_8=+.`Poj;aN2KHbKS5VcHjkbdF-Ooe^i@(f +\,!4gYCW@hV[8LiSrnXjQ5OdkNMp0!UB"MliHMArpKpXnaZVL!qZ'Vrq6 +JcC<$JcFg2o`"gfrqu]ks8)ckrqQNf!;?EbHM$h"o'u5q6QBdYsOH5B[MM[+CKnFu- +Isl`lH?aXWFE;JBDf0E-CM@HpAn>L_@UWYOUSFW]r20Cir20%(kAg<"MZ8P(MXRYHWr]6"r2L1,Xfek4Z*L^C[C3QSrOMs<"1PeM\'UKAQN*;%(7W_SX4/ +`lH3Ebg$(3!n#HEifa,$qN;qAFEDYKGB\:WH?spcI=6QoJ:N3%JqJ]/KnY89LPL]bM>rJ5MuJ\8 +NW+t8O8Y1:Onb+8Oo1=:O8b1=NVe\6MuS\3M>rD2L\li*L&Qc#KDC,rJbaonKE$W(L&Hc+L]<20 +M>rG5MuJ\8N<#"tQBml)R$jD3S"#q=rgj:cTV8'RU].&iV5C/gW2ZesX/rG* +Y-5(6Z*L^B['d?N\%&uZ]">Vf]tV7r^qmn*`5T^8a2l?DbKJ,ScHab_dF$CleCE.%f@\d1g=tE= +h;7&Ii8N\Uj5f=ak3(t-klL)8rp0[Qmf)YVnF?&JncJFTo`"O`pAamcq#:*hqYU0gr;HTbrdk+' +s*t~> +JcC<$JcFg2o`"gfrqu]ks8)ckrqQNf!;?EbHh?q#o'u5q6QBdYsOH5B[MM[+CKnFu- +Isl`lH?aXWFE;JBDf0E-CM@HpAn>L_@UWYO;c6Ll;uKSp;cN`rr)E5Lk<8E#o0<1;q+pZ[r)*;e +s%rbor_j&";,C(d:esm_5lX(G5kdM>5l!_6;#O8i;"IQO;XHsK8,c!R;#4&Z;#!oc;?0Yh;Z9Vo +;Z9A=9Dqrm=85nt=8uA*=&r=#<;fbq$P<[6_ri)9ALiDBMN%;LPYqd +s,-i7rf$l:rf6l:rK-l'p+Q?P*2#mPa.N"QC!u+R@9S6S"-&KSctaZTqS3UrhNSkVPg>j +WN)u!XKAV-YHY79ZEpmE[C3NQ\@K/]]=bei^;%Fu_8=+.`Poj;aN2KHbKS5VcHjkbdF-Ooe^i@( +f\,!4gYCW@hV[8LiSrnXjQ5OdkNMp0!UB"MliHMArpKpXnaZVL!qZ'Vrq6 +JcC<$JcFg2o`"jgrqu]krqZWjrV1j9p@e1Po^qbGo'u5q6QBdYsOH5B[MM[+CKS+l, +Isl]jH?aXVFE;GADf0E-CM@HpAn>L_@UW['j5g7%!9X4Bqrn(CrKHi9rfcf6o98p5p65F-nCRcn +f`'M$edp<\eC2jndEp7dcd'eZS"&`6qO@GPqO@H'rl+fRq8;mDqSW'Gou$U"l(J*Mq8WBRprNEU +s2tAbnBCXO!7(Mgs18!9rODR1rj_=(s6B^PlhfuElN$5Jkn*.Glg4$.nac;Dp@nCZqu-Nks8W)u +rV4Y3bl5f@b2Q7q;$?XgqYL0^s74)-`::hD`qmX_F*)MHG'A.TH$Xd`I/\NtIXcluJV*lR#D@eb +L5(J=M#E/3MMmDkN;eh:Nqnb2OSk78OSFn8NrG%8N;eb7MYi81M#N2,LAlo*K_U2dK)(&uK`?c( +LB!&/M#N82M?&S6N;nk;NrG(SOHGZgP*;,pQ'IZ%Q^F/.R[T_8S=TYN%\KDfTq\ +JcC<$JcFg2o`"jgrqu]krqZWjrV1m:p@e1Po^qbGo'u5q6QBdYsOH5B[MM[+CKS+l, +Isl]jH?aXVFE;GADf0E-CM@HpAn>L_@UWZ=U8+IaUo"!dr29OkrGhFJluD--qJcM-oUu#Ps.94\ +opc&PRf8cVRd"t`FT.[.R.Zg?QN!6MQiNKKQN!0GQN*i0*u$qN;8.FEDYKGB\:WH?spcrd=s!It3'#K)UB-KS>,7L51P?rJ:T5Mi7Om +rf-rai_fMbg"GYcd:(ee'umtf%8O+g"P07gtgfChr*GO +ioB([jlY^gkih9qlKeH9!U]=SmfN"Knc&(\oCV\Sp&Facp\jmdq>^ +JcC<$JcFg2o`"jgrqu]krqZWjrV1j9p@e1Po^qbGo'u5q6QBdYsOH5B[MM[+CKS+l, +Isl]jH?aXVFE;GADf0E-CM@HpAn>L_@UWYE<)`fps&8ko!E2tsO)i;,[Bl!)ibm!)WPXr^$6Cp-8L@qEaRHl;?qHq+'sEq*tESqG7/hrDNYmp/(H[m8Em]s&/\f +rCm2`!)26Br`B/%q,mVt"^"i,<)Z]m;[ZQ*<``C+>$>-8?!dM;!+,Y1s'5S.r`&;ahbsGPi_]PM +rGqmZ"Eo!6H$T=6s*O67nQ#?brDa8IFEDYKGB\:WH?spcrd=s!It3'#K)UB-KS>,7L51P?rJ:T5 +Mi7Omrf-rai_fMbg"GYcd:(ee'umtf%8O+g"P07gtgfC +hr*GOioB([jlY^gkih9qlKeH9!U]=SmfN"Knc&(\oCV\Sp&Facp\jmdq>^ +JcC<$JcFj3o`"gfrqu]ks8)ckrV-EfpAX`5o^h\Fo'u5L_@UW[&iT'"\jlZL(r9+1EPk^I?P4Xt5P5:CAPl6g9PkgO@ +g$IAifDjD+e^W*tdaHPAciDDfS*QUBS,\rRS,C8+`VmaI_t_1J_tM%B_Z6IoUALVa`VRUQ`rO3V +ao0B\bPfWbc25`Wc2Greci;Aj](ro1\G`o2\F[3.lhp&Hli-2Jkn!(Flg4'.nFH5Ep\=U^r;HWo +#ljo(rr2lpr;HK:qTSu_!6k5]il_;Cj\YkPrDE^mqu-'bs2=WK!5e]Pq8E-Kqo8NP&T`&9F`qtQ +G^4R\H@($fI=?\FJ,t4Qrdt6)L&Qi,LB*//M>rJ5Mu8P6NW"mrO8P%;NV\V5MuJV2M>i>1L\li* +L&Qc#KDC,pJbaooKDpQ(L&?Z,LPUcbM#rQmMuJY:NK0%uNrb?)rfRYQPa%GuQC!r*R$jEBRfT%M +rgm_oTV8'RUSFW\V5C/gW2Q\qWiN5'Xfek3Yd(L?Za@-K[^WcW\[oDc]Y2%o^VI\&_Sa=2`Q-'@ +ai_fMbg"GYcd:(fe'umtf%8O+g"P07gtgfChr*GOioB([jlY^gkNM0plKeH9!U]=Sn,MkWnc&+Z +o)SF]o`Fj]p\agdq>U6fqu6NkrUTr=s4dR(~> +JcC<$JcFj3o`"gfrqu]ks8)ckrV-EfpAX`5o^h\Fo'u5L_@UWZQ'IZ%Q^F/.Rf8cWS=TYNAtP`i +Tq\ +JcC<$JcFj3o`"gfrqu]ks8)ckrV-EfpAX`7o^h\Fo'u5L_@UWYFr^$9TrD3>flr!1Kj[]2;qb[;irDNPj +rDQ'IZ%Q^F/.Rf8cWS=TYNAtP`iTq\ +JcC<$JcFj3o`"gfrqu]ks8)ckrqQNf!;?EbJ+W@'o'u8>n*]T0m-Es$ki_*ijQ#7Yi8Gp\F^arVcTls8Drp +!<)i?qTSfZ!6Y&ZjN?X^qbd;is&/srrpg$e`;%7L_YqCK`;.CN`r!^aF*)MHG'8(RG^4U]H[Pg@ +#(D&PJ:W9'rdt6)L&Qi,L]<2/M>rJ5Mu8P4NW"n'O8Ft9NVSP4MuJV1M>i>1L\li*L&H]"KD0ur +JbXinKDpQ'L&Hc+L]<20M>rJ5MuJY?NK0$[O-#HcrfR;GPl?pKQC%TaN;TJbKS5V +cHjncdaQ^qe^i@(f\,!4gYCW@hV[8LiSrnXjQ6C'&Ei9Al0@U#m-O--mdKW6nF?MKs766_rUp3a +s7cKes7uZjqtp?irVc +JcC<$JcFj3o`"gfrqu]ks8)ckrqQNf!;?EbGP(Lto'u8>n*]T0m-Es$ki_*ijQ#7Yi8[:hVt"d+E;OYDEqaYMEqFANTD5)O +TDY;\SbJZSS,RQpFSU(SFT.^)R/NBDQM$RFQBh62s-NSLid:WMqO.;Nn!j?Im[O6HrLEq[rLND7 +pP\g(nqm@Hq5jUsri5pr$EC/.Xfnt6ZEpsHrjDj:\Giu;[K*`5[ca"UR-p=9Q2m35;#=,g;ZBZ' +_o9[V(Oo^c2rfmMMQiU6fqu-Hk +rUTr=s4dR(~> +JcC<$JcFj3o`"gfrqu]ks8)ckrqQNf!;?EbHM$h"o'u8>n*]T0m-Es$ki_*ijQ#7Yi8?kJ3?4'tC>?kB:>$>-7$jq-_>l07L!lg4!*mdBQ4nF5uIo)J:]o_nI_pAamcq#C0h +qYU0gr;HTbrdk+(s*t~> +JcC<$JcFj3o`"jgrqu]krqZWjrV1F-p@e1Po^qbGo'u5PQ7!EPlKG7gAfjlf`0P*f%&="rmLho!7:>,qjdPSopklJr5SZR!6"9BnAP%rp0LI$L@'Hn+#u@pA"I\rVc]orr)cm +!;lc?!R/gdbkfNZb4s0Db32\!;>jDj;t0h]`:_%E`;.CO`r!aSF;/k@GB\:WH?spbI!pElIt*!! +JV&LQK*$^[L&Qi,LB*//M>iD4Mu&D1NU2]&NVSP3MuJV1M>i>1L\cc)L&H]"KDC,pJbaooKDpQ' +L&Hc+L]<20M>rJ5MuJY?NK0$[O-#HcrfR;GPl?pKQC%T$jpUA9l07Kulg4!*mI'uB!V#XYo)J=]o`"O`pAamcq#:*h +qYU0gr;HTbrdk+(s*t~> +JcC<$JcFj3o`"jgrqu]krqZWjrV1m:p@e1Po^qbGo'u5Vg^;%Fu_8=(,`5T^8a2l?Db0.uPc-FY^dF$CkeC<%"f@S[.g=k<:h;-rF +i8ESRj5]4^roOUOkiq?slKdg'mHs?@mfDqJrpp*\s7H<`s7ZKerV6Bfs8)WirVZWmo)=4?g])d~> +JcC<$JcFj3o`"jgrqu]krqZWjrV1m:p@e1Po^qbGo'u5Vg^;%Fu_8=(,`5T^8a2l?Db0.uPc-FY^dF$CkeC<%"f@S[.g=k<: +h;-rFi8ESRj5]4^roOUOkiq?slKdg'mHs?@mfDqJrpp*\s7H<`s7ZKerV6Bfs8)WirVZWmo)=4? +g])d~> +JcC<$JcFm4o`"gfrqu]ks8)ckrV-EfpAX`7o^h\Fo'u5q6QBdYsOH5B[Mi!7EKnFu. +J:;onH?j^XF`_YDE,TW2CMIQsB4b^c@q&lsf%Ss:i8N_V!p&J*r9*g?rg!MLp6F[&mZmg:ptGc$ +lIZ6kf%&:!rmCeorLEGJqjdPSpRM/Ns2P)Zs2P)Xs2=a +rQONNq9B&fd*VR"rOVp;o=4e1m^W;_s6KaQqs4m[m-Es&m-O-.nF?,Bp\=R]rqu`orVc`nrqc]l +p<^gurJUW3qMG3-rJ19)rIt6(pOi9npjr6mqLed#s+UB*s+gW1 +re^Z4!/pi8s,@#=rf7,BOcfX+!L&cIPl[2;rg3_SRf8cWS=TYNDkE\rTq\9VUnjiaVPg>jWN)u! +X/rG*Y-5(6Z*L[AZa@-K[^WcW\[oDc]Y2%o^VI\&_Sa=2`Q#s>aN;TJbg"GYcd:(edaQ^qe^i@( +f\,!4gYCW@hV[8LiSrnXjQ5Lck3(sml0@R"m-O-,mf)YVnF?&JncJFTo`"O`pAamcq#:*hqYU0g +r;?Nardk+)s*t~> +JcC<$JcFm4o`"gfrqu]ks8)ckrV-EfpAX`3o^h\Fo'u5q6QBdYsOH5B[Mi!7EKnFu. +J:;onH?j^XF`_YDE,TW2CMIQsB4b^c@q&l8S=ZCIr1X4eV#7+EEVskUEVjePF7XGPEVQ3pTDP2[ +Sc5,^SXc7ASG%*fFSU%ZR/WNNR.cmAQMm0JQiNKKQN!6JR/MEjHh*W^S,]#TS`,J*Mu/D(M>sXR +XT,=$XT#:#WrK+*XKAY/YctF>[/IB4[f3c9[f<`8[/78nQhQm:Qi369;#=,f;Yj;l<;joDb0/#Q +c-FV\r6bD*rK?i9q3(K9r/q>,FEDYKGB\:Wrd"TlI/\NpIXh?I#_@SZK7ei1Kn]M\s+gW1rJCN2 +repQ1m>^gurJUW3qMG3-rJ19)rIt6(pOi9npjr6mqLed#s+UB*s+gW1re^Z4!/pi8s,@#=rf7,B +OcfX+!L&cIPl[2;rg3_SRf8cWS=TYNDkE\rTq\9VUnjiaVPg>jWN)u!X/rG*Y-5(6Z*L[AZa@-K +[^WcW\[oDc]Y2%o^VI\&_Sa=2`Q#s>aN;TJbg"GYcd:(edaQ^qe^i@(f\,!4gYCW@hV[8LiSrnX +jQ5Lck3(sml0@R"m-O-,mf)YVnF?&JncJFTo`"O`pAamcq#:*hqYU0gr;?Nardk+)s*t~> +JcC<$JcFm4o`"gfrqu]ks8)ckrV-EfpAX`5o^h\Fo'u5q6QBdYsOH5B[Mi!7EKnFu. +J:;onH?j^XF`_YDE,TW2CMIQsB4b^c@q&kE;H-[tsGn;tWHQ5kRGB5kRA9;#F,h;".?I;VXbB;=dWS;=%3Y;u]bP9^YOR +=8l>#=8l5%?kE=?N+44>[(B9r*',)oi1K\pJh&hnP\[Lqbd8hqGRGp +F`m\,s*"QiH$OZ6H2`-el<=!YfFEMbNGBeE4H3&A?rd=frJ,Xs(JV&K+K7no3L&Qi, +L]<2/M>iD3Mti7uNV8>0MuAP0M>i>0L\li)L&Qc"KDC,oJbaooKDpQ(L&?]*L]<20M>rG5MuJ\8 +N<#"Vf]tV7r^qmn)_o0O5`lH0Aai_fNc-FV\d*^7he'umtf%8O+g"P07gtgfC +hr*GOioB([jlPXekNM0plK[^%m-X3.rpKpXnaZVL!qZ'Vrq6 +JcC<$JcFm4o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_npU&tn*f]2m-Es$l0%3kjQ#7Yi8 +UA:MXUAU_^a8*jWb5TT^bj3OKcMl2h])0,9])B24\G*Q,\-20cmd9E>li?GOlj<(InF?)@p%S7W +rqc]nr;?ZorVcWuqtg0bq9-tVbl#ZTb4j*Kb3i+';>a>f;uT_r-ZLB!&.M#<,/MZ/OmN;SV4MYW,.M#E,+LAci)K_U2r +K(OWjK)1-!K`?c)LB!&/M#E/3MMmDlN;nk;NrG(JOHGZgP*;)oQ'IZ$QiU6fqu-HkrUTr=s4mX)~> +JcC<$JcFm4o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_np0cpn*f]2m-Es$l0%3kjQ#7Yi8hr_s5)aiMTHbK\8T +cHlI9s3^Y+rK?i9qNCT:rK7;)FEDYKrc\`pH$Xd`I!g?jIXZeGJ,t4QrIY0)Kn]M\s+gT0r/(E1 +reo`or/:N2q2,*,rJ19)rIt3'pk/EpoRZjjqLed#s+UE+s+gW1rJ:T5Mi7Rns,@#=rf7JLOcbfi +PEV5rQ'R`&rg3_SRf8cjS=Q7CT:_dMTq\9VUnjiaVPg>jWW&n$X/rG*Y-7i/$*geBZa@-K[^WdG +\NRO9]Y(ql^V@S#_SX4/`Q#s>aN;TJbKS5VcHjkbdF-LneCE.%f@\d1g=tE=h;7&Ii8N\Uj5f:_ +k2tjjrojIKli-5OmI'uB!q>aMrpg-^o^r+T!quB_r:p +JcC<$JcFm4o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_nosWnn*f]2m-Es$l0%3kjQ#7Yi8l@t.>PhV&>P1t`;tj8h;tX&V;#=,f;Ya8jjWW&n$X/rG*Y-7i/$*geBZa@-K[^WdG\NRO9 +]Y(ql^V@S#_SX4/`Q#s>aN;TJbKS5VcHjkbdF-LneCE.%f@\d1g=tE=h;7&Ii8N\Uj5f:_k2tjj +rojIKli-5OmI'uB!q>aMrpg-^o^r+T!quB_r:p +JcC<$JcFm4o`"jgrVZTjs8)ckrqLs:p@e1Po^qbGo'u53s4R/!qq1u%rn.J-f@JL%e+B1.S,/Z@RfSttrl=uWrPeQMqnr3IqSiEOpquNo!28nVs.T>2 +qoSl\s3(;`rltJg!71SgoZd?[r6PAhpU^C:pU^@7ppfh(r4)dprpBaPs6TjTmJcMYn*ol=o_%qQ +rVH6c#5e8mqYBp]qoel\r6+QOpWN3OnPK'Zr)3>hr`&ks!*8[j!5nQLkemG=qS`SYFEDYKrc\Bf +H2`*jH[Pg@#C_/PJ:N3%K)L<'KS>-YLB!&.M#<,.MYrD"N;AJ1MYW,-M#N2+LAci)K_U2rK(4Eh +K)1-!K`?c)LB!&/M#E/3MMmDlMuo!!NrG(?OHKO*,a4IWQ'IZ$Q^F/.R@9V7S=H.AStDXJTqS3U +USO]^VP^8hW2]cr<3*+&Xfek2YctC +JcC<$JcFm4o`"jgrVZTjs8)ckrqLm8p@e1Po^qbGo'u5hr`&ks +"'3Lbb5TQdbg+P\rm:\m!0[/ArK?u=rK?]7rK7;)FEDYKrc\BfH2`*jH[Pg@#C_/PJ:N3%K)L<' +KS>-YLB!&.M#<,.MYrD"N;AJ1MYW,-M#N2+LAci)K_U2rK(4EhK)1-!K`?c)LB!&/M#E/3MMmDl +Muo!!NrG(?OHKO*,a4IWQ'IZ$Q^F/.R@9V7S=H.AStDXJTqS3UUSO]^VP^8hW2]cr<3*+&Xfek2 +YctC +JcC<$JcFm4o`"jgrVZTjs8)ckrqLm8p@e1Po^qbGo'u5!6I6MNk=5QF%?;"%9G;Z&u\7d!;A7K??kH=>[(E9=oDM)>?q/3nPnpTpJh)ipepWYqGI/gq,@8lr`';+FEVkQ +GB\=XG^045!d]2mq,QranQ#Qh"]]VcFEMd+G6)r6rd"TlI/\O!IXcitJ:W9'rIY0)Kn]J[s+gT0 +r/(B0r/9s$qMY9/q2,'+reL?)rIt3'pk/EpnU^RhqLed#s+UE+s+gW1rJ:T5Mi7Rn!f`5#rf7)A +OoCLhPE_;sQ'R`&R$a;0R[]e:S=Q7CT:_dMTq\jWW&nsX/rG*Y-5%5Yd(L?Za@-J +[^NZT\[f;`]Y(ql^V@S#_SX4/`Poj;aN2KGbKJ,ScHab_dF$CkeC<%"f@S[.g=k<:h;-rFi8ESR +j5]4]jlY^gkl0fIlKeH9!U]=SmfN"Knc&+Zo)SF]p&Facp\jmeq>U6fqu-HkrUTr=s4mX)~> +JcC<$JcFp5o`"gfrqu]ks8)ckrV1d7p@e1Po^h\Fo'u5Z[Bm0CYH=n+WMcVhUS4?PSXZ(8Q^*euOcPN^N/EIIL4k22 +J:DuqH[9p\G'%hHEH#f5Chmd"BP1pgA7K(WrmM8)e^iF.h;7)Lj5f>#QL^CX8e;uTbpSt;RITV8'RUSFW\V5C,fVl6To +WWB0%riH@,YHY79ZMq0:['d?N\%&uZ]"@sS3k`8B^VI\&_Sa=2`Q#s>aN;TJbKS5VcHjkbdF-Ln +eCE.%f@\d1g=tE=h;7&Ii8N\Uj5f:_k2tjjrojIKli-5OmI'uBs6p$Yrpp*\!;-6_s7ZKerV6Eg +rqcNhrVZWmo)=4?h#Dm~> +JcC<$JcFp5o`"gfrqu]ks8)ckrV1d7p@e1Po^h\Fo'u5Z[Bm0CYH=n+WMcVhUS4?PSXZ(8Q^*euOcPN^N/EIIL4k22 +J:DuqH[9p\G'%hHEH#f5Chmd"BP1pgA7K(WrgNtXS"9MN!29@crGhXRlZ)lBol9hKqJl.Jr^$1L +l_"0Js./V%ol]\Es-`ADqNq5L!1EDFqj75Jr-eEhp3Z:Ts-rbOqj[MPqO@MT!hGjOqO@DQpRU/u +rJU-%s/c.!"g"i.Y-+u-Xobf2ZMh-,[/dZ5[0!_C[J[K-R/30LR-p=8R/**KQM")M;>X8e;uTbp + +JcC<$JcFp5o`"gfrqu]ks8)ckrV1d7p@e1Po^h\Fo'u5Z[Bm0CYH=n+WMcVhUS4?PSXZ(8Q^*euOcPN^N/EIIL4k22 +J:DuqH[9p\G'%hHEH#f5Chmd"BP1pgA7K(Wr`&nr!*&qus&K"srB':,p-%h-mlg\7r^$?Uqb[)c +q,%#es&/em!(-2Aqbd>hs&&2^r)*G'8(RG^4R\H@($eI=6QnJ,XuuJH1<#KE$W)L&Hc+L]3,+ +M>W7uMu/D+M>`8/L\cc(L&H]"KDU8fJc(,rKDpQ(L&Hc+L]<20M>rJ5MuJY:NK0%uNrb?)rfSOj +Pa%GuQC!r*R$jA2S"#qU6fqu-HkrUTr=s4mX)~> +JcC<$JcFp5o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_noO?jn*f]2m-Es$l0%3kjQ#:Zi8R$X)&P*(fcN/NRMLPCJ7 +Jq/?!I!^0aGBS(MEcH&9DJX*'BkV-kARo:[daJ*C#h7DVg"Y?>ioBQqq3LiAl]g\"rB^/2kLfmg +fC>EjSH#)Ya8*aQ`VmaP_u@UC`;mjQ_sa?"U[b)WUBRC5aN;QHrlG2`bP06\blH&gci;;bchG`] +ci;Ab])K>:]&1'umeuS`nF,l9nac8Bo_/"Qq>(!crVQQk!rMiiqY9^+!6kDbn&k1Dqo\b3pJLfc +pf%/krDibr!*Adl!5e`QqS_O6rl"cSs)e9`"a5*6G^+N5H3&A?rdFfq!.Xuus+(0%rIb-'s+UB* +s+gQ/pkeBqp5/^'rJ13'rIt3'pk/Hql@JncqLed#s+UE+s+gW1re^Z4s,6l8#E=b(O,oBaOoCLE +PEc'3)O?_VR$a;1R[]e:SXl@DT:hjNTq\Za7$H[^NZT +\@K/]]=bei^;%Fu_8=(,`5T^8a2l?Db0.uPc-FV\d*^7he'umtf%8O+f\,!4gYCW@hV[8LiSrnX +jQ,Fbk3(t-klL)8rp0[Qmf)\Tn,W"Xo)J:]o_nI_pAamcq#C0hqYU0gr;HTbrdk+)s*t~> +JcC<$JcFp5o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_no=3hn*f]2m-Es$l0%3kjQ#:Zi8R$X)&P*(fcN/NRMLPCJ7 +Jq/?!I!^0aGBS(MEcH&9DJX*'BkV-kARo:[qjRYWSY#hQ!hc9^nT+/>oPjSFl>lhhp7UT@s.8M! +k]QoIs-`ADqj7;Lr0d/Drg3SNpjN$eom?:Vs-rhQr1!MNqj[PSr13VQqOI_YSXk\qMYrD%MYsRT +XoGR&Y6D/8Z*L^BrNuO2s0hd3r3l6bs-NPKoU#-9qj.;KqG?o`qbm2fr`&hrr)O#'b0/#Qc-H75 +s3LbnrK?u?rK@#>rK?`8rf[;'s)eKgGB\:VH2`*jH[Pg@s*artrdb$"!.t0%s+LE+r.b6,rJ:6* +m>CUor.t<,q1ej%rIjruqh"*arIXlure1<*rJ(?-s+pZ2s,-i7req)ANfK0]OH>V(Oo^c2rfnCf +Q^=),R@9S6S"-%?St;RITV8'RUSFW\V5F6i!NaN;TJbKS5VcHjkbdF-LneCE.%f@\a/g=k<:h;-rFi8ESRj5]4]jlY^g +kl0fIlKeH9!U]=Sn,MkWnc&+Zo)SF]p&Facp\jmeq>U6fqu-HkrUTr=s4mX)~> +JcC<$JcFp5o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_no=3hn*f]2m-Es$l0%3kjQ#:Zi8R$X)&P*(fcN/NRMLPCJ7 +Jq/?!I!^0aGBS(MEcH&9DJX*'BkV-kARo:[q,@Gr<`W6"<9ZOA4TI\<4nLr+4oI\C:\[c^;>a8f +;#jMn;>`cO62j4I6i04C62s4G;!h-C;Y3EU7dKbqG[Mp<)i`e +qb-BOn4iUMr`Attr)Eo$='&L,=oDM(>Q.n+>Q7n'>6%pn<:j,Z<;]Yp;Yj5a;>X8d;uTbpZa7$H[^NZT\@K/] +]=bei^;%Fu_8=(,`5T^8a2l?Db0.uPc-FV\d*^7he'umtf%8O+f\,!4gYCW@hV[8LiSrnXjQ,Fb +k3(t-klL)8rp0[Qmf)\Tn,W"Xo)J:]o_nI_pAamcq#C0hqYU0gr;HTbrdk+)s*t~> +JcC<$JcFp5o`"jgrVZTjs8)ckrqQNf!;?EbG4bCso'u51WDm?[g=pQb33!0d5Cn!3f:pY+`^ +!8-t7qOQW9s2XfPrl+fRl,EY?r58$!rLs:en=ooWrlP,]!6b)[s3:DcrQkDgnBV*]qRcU8rk%p9 +iOT!W!q>aMrU:6co()DEp@n=Vq>'m`rVQQk!rMiirV-BerqHKfm`Y1Dlc]=Nr_W;cqbm2frD`br +qc<\t!*Jmnrke]QqS_L5s2=oUs)e9`!-\?c!I/nhH3/G@I/\NqIXckHJH(0#K)L?%K`6]'LAlu, +LuF3fM#E,)LAci(K_U2tK)'ukJGFcpK):3"K`?c)LB!&/M#N82MZ8V6Mueourf@)@!0R8D!L&cI +Pl[2;rg3_SRf8cWS=TYN!M?%aT`Lm_rhKRkVZ*IoW2]cr!NW=$XU;57YctC;ZEpmE[JmTe\%&uZ +]">Vf]tV4q^VI\&_Sa=2`Q#s>aN;TJbKS5VcHjkbdF-LneCE.%f@\dUg'QNhh;-rFi8ESRro4RN +jlY^gkih9qlKdd&m-X6/rpKmWnbr"[oCV\Sp&Facp\agdq>U6fqu6NkrUTr=s5!^*~> +JcC<$JcFp5o`"jgrVZTjs8)ckrqQNf!;?EbG4bCso'u5Vf]tV4q^VI\& +_Sa=2`Q#s>aN;TJbKS5VcHjkbdF-LneCE.%f@\dUg'QNhh;-rFi8ESRro4RNjlY^gkih9qlKdd& +m-X6/rpKmWnbr"[oCV\Sp&Facp\agdq>U6fqu6NkrUTr=s5!^*~> +JcC<$JcFp5o`"jgrVZTjs8)ckrqQNf!;?EbG4bCso'u5EQM62O"F6iKFF62FFJ;>jAm;g<;]Yp<;9)` +9Bo4C:&%E[=8l7u<`!~> +JcC<$JcFs6o`"gfrqu]ks8)ckrV1d7p@e1Po^qbGo'u5g +r6bGh!mf6?r6P>Rqn2m>s183Apq#Fp!V,a[nc/+YnI"m[p@n=Vq"aa^qY9phqYBp]p]&D)bOis@ +bP+m1;YX2h<;fhoaMrpg-^o^r.Us7ZKer:p`!~> +JcC<$JcFs6o`"gfrqu]ks8)ckrV1d7p@e1Po^qbGo'u5:[qr.k'%rIt0&pk/KrqLS*cr.4fuqh+m$s+UE+s+gW1re^Z4!/pi8s,@#=rf7;G +OcbfiPEV71Pl[2;rg3_SRf8cWS=TYN!M?%aT`Lm_rhKRkVZ*IoW2]cr!NW=$XWXdMYctC;ZEpmE +[C*HO\%&uZ]">Se]Y2%o^VI\&_Sa=k`?rUFaN2KGbKJ,ScHab_dF$CkeC<%"f@S[.g=k<9gtgfC +hr*GOir7sLjQ5OdkNM-ol0@U#m-O--mf)YVnF?&JncJFTo`"O`pAambq#C0hqYU0gr;HTbrdk+* +s*t~> +JcC<$JcFs6o`"gfrqu]ks8)ckrV1d7p@e1Po^qbGo'u55hb)>l@k,>5DJ'>lRa`<<#n\<;08d;YX2h<;fho^3 +!HiSbG63#7H2`*jH[Pg@s*jutrdb$"s+:3%s+LB*r.b0*qhXWrqM>')pkJa$r.Oitr.=crmst=e +rIXp!re1<*rJ(?-s+pZ2s,$f7rf$l:!07&>#EY(1P*2#mPl?pKQC%Th;7&Ii8N\pit1;5k2tjjkiq?slg*p(mI'EAmfN"K +nc&(\oCV\Sp&Facp\agdq>U6fqu-HkrUTr=s5!^*~> +JcC<$JcFs6o`"gfrqu]ks8)ckrqQNf!;?EbGP(Luo()>?n*f]3m-Es$l0.9ljl>C[i8EJJgtLK7 +f@JI$da?Cdc-+8NaMu3:_SEq"]Xt_a[^EHIYck11Wi;nnUnaWVSt2C@R@';*PEM#gNJrdPLk^V: +K7SQ&I=-?eG^"=QFE2A?DJj9+CM@HpAn>L_@fFdWe'c\BdfJ"Mqj6i=m$7=0lBM?9qa'i-q:YMr +r7U>)rgi5Bs2b8^r5nu[pW*-Orl>#XrPe]Srl+lTrke`Srh\qVm\Bg(!6Y8`qTSuapWi``qU#/f +p!EKGq7Q[Oqs76-Y#4qK[p\4IXrV6HiqtpEis7u]ip\4R-o#p[Jl-&s$qGR#crD`brqH!Ss +r`K/&o`+s-rke]Qr5@U4s2=qZ#Bb35GB\:VH2`*kH[L5?IK+`rJ,OotJcC?#KDpQ'L&-Q%L[9in +L\HQ$L&H]"KD^>uJa%^`Jc12tKE$W)L&Hc+L]<20M>rG5MuJ\8N<#"Vf +]tV7r^qde'_Sa=2`Q#s>aN;TJbKS61c4SCLdF$CkeC<%"f@S[.g=k<:rnSIKhr*GOioB([jQ5Od +kNM-ol0@U#m-O--mf)YVnF?&JncJFTo_nFap@n=Zq#C0hqYU0gr;HTbrdk+*s*t~> +JcC<$JcFs6o`"gfrqu]ks8)ckrqQNf!;?EbGP(Luo()>?n*f]3m-Es$l0.9ljl>C[i8EJJgtLK7 +f@JI$da?Cdc-+8NaMu3:_SEq"]Xt_a[^EHIYck11Wi;nnUnaWVSt2C@R@';*PEM#gNJrdPLk^V: +K7SQ&I=-?eG^"=QFE2A?DJj9+CM@HpAn>L_@fDhsSGScWS=Q5BEr:"SEq+/DE9_HD6Mj(JTD"rR +TD>/VTAOh[FoRlkR.ZmAR/VU3Ie\?gI-u@XRL,IPR[]e8R[]e:rL<_Ts.01]oq2/RqOR,7l&,Cs +nr!INr2p4,Yd(L>Zi.9%[/dT1[J6-dRG4,,QhsYV;YF&f<;ono6BI=lP*2#nPa.N"QC!u+R@0M5S"-"> +St;RHTV8'RU8+N[V5:&eVl6PnWiE,#XKAV-Y-5(6Z*CU@Za@-J[^NZTrj`rY]=bei^;%Fu^qmn) +_o0O5`lH0Aai_fMbg$.4&^ShOdF-LneCE.%f@\d1g=tE^h&5),i8ESRj5]4]jlY^gkih9qlKdd& +m-X6/rpKpXnaZVL!qZ'VrUg6cp\4U\s7uZjqtp?irVc +JcC<$JcFs6o`"gfrqu]ks8)ckrqQNf!;?EbGP(Luo()>?n*f]3m-Es$l0.9ljl>C[i8EJJgtLK7 +f@JI$da?Cdc-+8NaMu3:_SEq"]Xt_a[^EHIYck11Wi;nnUnaWVSt2C@R@';*PEM#gNJrdPLk^V: +K7SQ&I=-?eG^"=QFE2A?DJj9+CM@HpAn>L_@fB=,F&Z;:7i26N0:L;!V!A;Z9/Z7H6i<;Gm*`r)!Gjqbd&bn5JgLrCZr[mS*@Lr(I2o<`N3"<uJa%^`Jc12t +KE$W)L&Hc+L]<20M>rG5MuJ\8N<#"Vf]tV7r^qde'_Sa=2`Q#s>aN;TJ +bKS61c4SCLdF$CkeC<%"f@S[.g=k<:rnSIKhr*GOioB([jQ5OdkNM-ol0@U#m-O--mf)YVnF?&J +ncJFTo_nFap@n=Zq#C0hqYU0gr;HTbrdk+*s*t~> +JcC<$JcFs6o`"jgrVZTjs8)ckrqQNf!;?EbGP(Lto'u5R$X,(PEM#gNJrdPLk^V: +K7SQ&I=-?eG^"=QFE2A?DJj9+CM@HpAn>L_e,7Yje,Pd)QJ@c'Pjt%<6Ms.>gAT^pg&Th)S`u[E +SbnrHS,15,b5KH^aRmURaSs6R`rm@fV=CA]aTBW.bPKH_c1oT_chGf]dJhMk +dIFjK]_oD<]&C1+o(2GDo_%qPq"Xg`rqcQi!W)Wkq#C*gpA+IXb4NmIb3dCO;>F,a;uK\o"=TDXts8Kk7_Z%IO`8SW6F96T.G5c[dG^9:7s*OcnrdFfq!.Xrts+13%r.G!%re:-%lA,%e +rIt0&pk/Krr.3pZrIOp!r.G$&re:?+s+gW1re^Z4!/pi8s,@#=rf7)AOoCM,PE_;sQ'Rc'R$a;1 +R[]e:SXl@DT:hjNTq\jWMuntX/i>(Xfeh1YctC;ZEpmE['d?N\%)FJ%_B9b]Y2"m +^V@S#_SX4/rl$t=a2l?Db0.uPc-FV\d*^7he'lgre^i@(f\,!4gYCW@hVR/Ji8N\Uj5f:_k2tjj +kiq?slg*p(mI'EAmfN"Knc&(\oCV\Ro`Fj]p\agdq>U6fqu-HkrUTr=s5!^*~> +JcC<$JcFs6o`"jgrVZTjs8)ckrqQNf!;?EbG4bCso'u5R$X,(PEM#gNJrdPLk^V: +K7SQ&I=-?eG^"=QFE2A?DJj9+CM@HpAn>L_qj[GP!-.%>jDj^1r^-NKr1E_Vpn.5P!2&(jqK;OS +q3gH6p6k`Dqg\HknU9qTr0mYTs-ikTrgWtXr1*eXs.8tWr1O"\qO[/7qhsp#qht''riZ[3YHY79 +ZEggC[']D3rj;O0pmCfDhO+8.r_`JhpJ_#irDi\pr`B)$r)j&(bPfZdcHlI9s3^Y*q31c?oo\p1 +s)\ +JcC<$JcFs6o`"jgrVZTjs8)ckrqQNf!;?EbG4bCso'u5R$X,(PEM#gNJrdPLk^V: +K7SQ&I=-?eG^"=QFE2A?DJj9+CM@HpAn>L_qc*Mor`&h[r]U6Cr]S[nr'1$ArB:-Hr'C6Vp/1W^ +oMOF3n3R1Q;,R6hmSW1Ge40I8r)!Dhr_WMi!)WPioMY3Xmn<@Hqb-?Nr_<;a$!(&,5DG'>lIt+=o__&>5hb$;p\MC;>F,a;uK\o"=ThoPG^+N5GQ<$fHN8Hl;uK\k!K`HCP!,"nPa.N"Q^=),R@9S6S"-%?St;RITV8'RUSFW\ +V5C,fVl6SoWiE,#XKAV-Y-5(6Z*CU@Za@*I[^NZTrj`NM]=bei]tV7r^qmn)_o2Pn43#=^aN;TJ +bKS5VcHjkbdF-LmeC<%"f@S[.g=k<:h;-rEhr*GOioB([jQ5OdkNM-ol0@U#m-O--mf)YVnF?&J +ncJFTo_nFap@n=Zq#C0hqYU0gr;HTbrdk+*s*t~> +JcC<$JcG!7o`"gfrqu]ks8)ckrV1d7p@e1Po^qbGo'u5R$X)&P*1ofNJraOLk^V9 +K7SQ%I=-?eG^"=QFE2A?DJj<,CM@HqAn>O`rmUhoqpPP4r0R/Df9Q?"o9K5?rBUG.s2jQKrQ,&\rQ"WOr5JZ6q5=%cqPF"b!2]Cbs2k;aq98f_"4,9=cMZ#]d.bofd/;;T]DB,! +\Hqj#p%J+Rp\=O]q>C'jqtg-fq#C*epA"CTb4s0Ib43[O;YF&e<;ono5qh"s8Be5 +_Z%IQ`8SW6FT6I`G5c[eG^4T6HN/
  • Q'IZ%Q^F/.Rf8cWS=TYN!M?%aT`Lm_ +rhKRkVZ*J8W2ZbrWiN5&Xf\b/YHY79Z*L^B['[6L[^WcV\[f;`rk&EJ^;%Fu_>_:X_o0O5`lH0A +aiaV+%F!)BcHjkbdF-LneCE.Lf-8l#g=k<:h;-rFhr*GOioB([jQ5OdkNM-ol0@U#m-O-,mf)YV +nF?&JncJFTo_nI_pAamcq#C0hqYU0gr;HTbrdk+*s*t~> +JcC<$JcG!7o`"gfrqu]ks8)ckrV1g8p@e1Po^qbGo'u5R$X)&P*1ofNJraOLk^V9 +K7SQ%I=-?eG^"=QFE2A?DJj<,CM@HqAn>O`SGSfQS,dX/EWC1VErU4MEoh<4Er89&62mMNT_P/N +T_Wd*Fm=/IFnp.VRf&T=R.csGR.,UrIKFqHIJ/'fRf/`URf/`RS-,=PSXobOoq2/Tr1EkXlAYOs +onrX)oSWXOs02O.s0D[2rj;^5rj2a7[']b=r3Z:-opGKAiL'V2qGR#cr)EYqqH!Ssr`K&#s'#G, +"O#'7cHc@7!R]?iP51=?P4k%3P5fY(FT?UaG63#7H2`-iHN8HlIK+`rJ,OosJcC?"KDpQ&L#%L] +L&?W!KD^?!J`)(WJc:8uKE$W)L&H`-LPUccM>rG5MuJ\8N<#"U6fqu-HkrUTr=s5!^*~> +JcC<$JcG!7o`"gfrqu]ks8)ckrV1d7p@e1Po^qbGo'u5R$X)&P*1ofNJraOLk^V9 +K7SQ%I=-?eG^"=QFE2A?DJj<,CM@HqAn>O`qGdDns&8t_pceX>b!,\cr'L?Jr(m>hp/1cbo25*Wl:^bAqFgHSr_Q.h*=o;J'>Q.n#;q+eC;YF&e<;ono5qh,GQ`58G^4W5HhUM8 +Q'IZ%Q^F/.Rf8cWS=TYN!M?%aT`Lm_rhKRk +VZ*J8W2ZbrWiN5&Xf\b/YHY79Z*L^B['[6L[^WcV\[f;`rk&EJ^;%Fu_>_:X_o0O5`lH0AaiaV+% +F!)BcHjkbdF-LneCE.Lf-8l#g=k<:h;-rFhr*GOioB([jQ5OdkNM-ol0@U#m-O-,mf)YVnF?&Jn +cJFTo_nI_pAamcq#C0hqYU0gr;HTbrdk+*s*t~> +JcC<$JcG!7o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_noO?jn*f]3m-Es$l0.9ljl>C\i8EJJgtUQ8 +f@JI$da?Fec-+;PaMu3:_SO"$]Xt_a[^EHJZ*:C5X/`+rV50iZT:VUCR[BG,P`h/jO,]*UM26n? +K7\Z)IXQTiH?aXWFEDPCE,TW2CMRWtBP(geACUV-rR1Yns-WMHpm0-hq*P*I!o;Ydo@j2u!SZ<) +gA9RbSGA`MSGAZLb43[Tb5TN_aSa*N`W3%:WV`XmVt?k^Vtm4iV#e]]qTSuas3CSh!RT0jd/VMk +d-]6B]Cic"\c;C'p]($`q>^^6gp\aa[p[QE'bNd7CbPb?4;uBVn!=oV\)>Q7t% +s8'V2_uI[8_uIXWFEM_LrceBe!."Nh!dfSe]Y2&Y^F[1:_SX4/ +`Poj:a2l?Db0.uPc-FV\cd:(edaQ^qe^i@(f\+s3g=tE=h;7&gi!SH&j5]4^jlY^gkl0fOlKdd& +m-X3.rpKpXnaZVLs766_rUp3as7cKerqZTjqtp?ir;H3cJcFU,J,~> +JcC<$JcG!7o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_noXEkn*f]3m-Es$l0.9ljl>C\i8EJJgtUQ8 +f@JI$da?Fec-+;PaMu3:_SO"$]Xt_a[^EHJZ*:C5X/`+rV50iZT:VUCR[BG,P`h/jO,]*UM26n? +K7\Z)IXQTiH?aXWFEDPCE,TW2CMRWtBP(geA=T1eS,JlOF8g:VF7OAq3^fBs-Wb8nUL+YomQk/rL3eUrL<_Trgj%[pn%PZm[rKtreofos02O.s0DU0 +p9ae+qm?1,nX0-?j-]h4rDN>fr)EVpqH!Ssr`K&#s'#D+s',ZNcHji7ciMPBp6,68q3(91s,mJ+ +F`hm,GQ2mfH2W$jH[L5>IK+`rJ,FisJc:9!KDgK$L$49fL&?VuKD^?!Jb"?bJ+\?kJc:9!KE$W) +L&Hc+LB*//M$JorMi^ +JcC<$JcG!7o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_noF9in*f]3m-Es$l0.9ljl>C\i8EJJgtUQ8 +f@JI$da?Fec-+;PaMu3:_SO"$]Xt_a[^EHJZ*:C5X/`+rV50iZT:VUCR[BG,P`h/jO,]*UM26n? +K7\Z)IXQTiH?aXWFEDPCE,TW2CMRWtBP(geAGK4';"557;:6N9=O;#=#g;"[Zc;#!of;#aDm +;!LC36hs%K;W:RC;?0Y\7d3GC;#jGj:B45e;#jMm;>=&V;rUIG9)D9L9`J,q='/R-o3),urEB2' +rEB5*r*8bjfMqfIp/ClgrDi\pr`B)$qcWr&r`fD-s*+Kgrd+NiqGd,fk>VP*F`hm,GQ2mfH2W$j +H[L5>IK+`rJ,FisJc:9!KDgK$L$49fL&?VuKD^?!Jb"?bJ+\?kJc:9!KE$W)L&Hc+LB*//M$Jor +Mi^ +JcC<$JcG$8oD\afrVZTjs8)ckrqQNf!;?EbH1^_!o'u8>n*f]2m-Es$l0%3kjQ#:Zi8QMQmDQLg@A6hitJ62o[@ +gtVSWr7h8,s4[P-pY5\:ka_:9p72)N!6k;_s31&Wr6#&]!6G#W!QN1V`rE%;Wr/joW:-YZW;ELl +bPo``c2Gued,EC5]C3?"\H;O#q"+:]q#0s`pA4Lap@msss3(;^!6OiTo?6f*r)EVpqH!Ssr`K&# +r`];*r*8sqq83*J!6!m7"*A[.G5ZUdG^4T6HN/?lI/\QoIf=iqJGt-"K)1,tK_L2tLA$>uK_L,s +K)C2lJF.j\JGt-!K)C9$K`?c*LB!#/M#E/8MMmCON/`gWrf7)AOoCLEPEc'3!LB)OQiWVDrgOIh +SXuFFT:hmOU8"EYUnsobrhfdqWW&muX/u<&)Qp9IYctClg4!*mI'uB!q>aMrpp*\!;-6_s7ZKerV6Bfs8)WirVZTlo)=4?hZ&*~> +JcC<$JcG$8oD\afrVZTjs8)ckrqQNf!;?EbGP(Lto'u8>n*f]2m-Es$l0%3kjQ#:Zi8;]T)bJ]TDG5LTAGP*Ms#s!Z*L\4ZhCd+ +[J@00[JmW5[I'@]RGaJ4Qh=;T<;fhn5hb(>lE"Kd/MDndaRlPq31W;nWuKD^DsL&6VuL&6PtKD^?!Jb4K[J+nKmJc:9!KE$W)L&Qi, +LB*//M$JorMi +JcC<$JcG$8oD\afrVZTjs8)ckrqQNf!;?EbGP(Lto'u8>n*f]2m-Es$l0%3kjQ#:Zi8sGq;,U:hqGQWX!)2-?s%<2^mS!ab +=BJ^/n65`mr`T;+ra#J-m8Me>oi(cfrDi\pr`B)$qcWo%r`f;*!I/ngHN&9kI/R%7Za7$G[C3NQ\%&uZ]">Se]Y2&Y^CJ&q_SX4/`5T^8a2l?Db5TQsbg"GY +cd:(edaQ[peCE.%f@\dUg'-6dh;-rFrnn.BioB([jlPXekNMp0#O:X@m-O-,mf)YVnF?&Jo)J:] +o_nI_pAamcq#:*hqYU0gr;?Nardk++s*t~> +JcC<$JcG$8o`"gfrqu]ks8)ckrV1m:p@e1Po^qbGo'u5 +K7\Z)IXQTiH?aXWFEDPCE,TW2CMRZuBP1mfeCE(LeG@YmR.?U6Q2m33QM-UC6hj"Gh#Z!=oMV( +>Pqb+>l\4*s89am_tq=OF96T.G5c^cGQ<$fHN/?lI/SKnIfFoqJGt-!K)(&oK_U8qK_9uqK)C2m +JG4QhIe\EgJGt-!K)L?%K`?c)L'!-dM#N59MMmCON/`gWrf7)AOoCLEPEc'3!LB)OQlh`bS"#q< +SXuFFTV/!PU8+KZUnsrcVl-JmWN)u!X/u<&!NrX*YQ;#7rj*?H[C*HO\$rlX\[oAa]Y(ql^;%Fu +_>_:]_o0O5`lH-@aN;TJbKS61c6^f`dF$CkeC<%!f%8O+g"P07gt^`AhV[8LiSieVj5f=`k2tjj +roj[Qlg*p(mHs?@mfN"Knc&+Zo)SF]p&Facp\jmdq>^ +JcC<$JcG$8o`"gfrqu]ks8)ckrV1d7p@e1Po^qbGo'u5 +K7\Z)IXQTiH?aXWFEDPCE,TW2CMRZuBP1mfp72,'nT=;B!HN89ErJH$6MR5ATDP;>FmaGNFn(pi +RK&ZHR/iWKJE24ZIenKmRKAtIRf/`USGo)ZT)##ST^SN/N;JOtMYXUP[/RK1[/[N6[emK#R/E!=oMV(>Pqb+>l\41cN)>kdJhSdP4=b7P4k%_:]_o0O5`lH-@aN;TJbKS61c6^f` +dF$CkeC<%!f%8O+g"P07gt^`AhV[8LiSieVj5f=`k2tjjroj[Qlg*p(mHs?@mfN"Knc&+Zo)SF] +p&Facp\jmdq>^ +JcC<$JcG$8o`"gfrqu]ks8)ckrV1d7p@e1Po^qbGo'u5 +K7\Z)IXQTiH?aXWFEDPCE,TW2CMRZuBP1mfr)EPnmQU>-q`aO7q*+@4r^6HIr)!;es%r8`qG@,X +j?i)uiDKDKr_r_m!)q]CoLAs[:f%$drDE8drDN\ol;I[XrD!5ag.Um.rE8SmrE08,>?kH>qcrAa +n5KBdnl5B_r)EVpq,[Jrr`K&#r`];*r*98-!FC'LH38MAI!bcjkuI:Rs)\jWMuntX/i?$XT>T. +ricF.ZMq0F['d +JcC<$JcG$8o`"gfrqu]ks8)ckrqQNf!;?EbI.[%%o()>?n*f]3m-O'&l0.q"FLhqYBp]p\+=Tp\X[`p\XXapZ0KmanX$QbPG08<;fhm5qh( +>lS+/?3"@-s8'Uk_u%@SFEMbMrceBes*=Qh!df+g"P07h#?+:hV[8LiSrkWj5f>$joOZ/roj[Q +lg*p(mHs?@mfN"Knc&+Zo)SF]p&Facp\jmdq>U6fqu6NkrUTr=s5*d+~> +JcC<$JcG$8o`"gfrqu]ks8)ckrqQNf!;?EbGP(Luo()>?n*f]3m-O'&l0.5qh(>lS+/?3"@2d/D>ld.3@iPPp[=OTT]JG' +JcC<$JcG$8o`"gfrqu]ks8)ckrqQNf!;?EbGP(Luo()>?n*f]3m-O'&l0.5P[M34o@\C6MaOV:]F8a;>F&c +6gmA!6iL!C;>a>i;uTYp;q=G78,Z9_;>3ub;ZK_\;ZTWhqG-u`r_2HIs%NAan4Wgar`T#"s&o5& +rE08,>?kE=qHW,\p/LlepJgufr)EVpq,[JrrE/r"r`]>+qcs/,ra#S3rHeEh!.+K@kuI=S"*A[/ +G5c^cGlN'fH3/G@I/JEmIfFopJGt-!K(XcfK^scnK)C2nJGF]]If+]lJGt-"K)C9$KE-`)L'!-d +M#N54MMmDlMueourf7)AOoCLEPEc'3$C7$GR$jA2S"#q=rgj._T`1VcU8.^`!Mu[mVZE`qri-4( +XK8P+Y-+u-YQ;#7rj*NM[C*HO\%&rY\[oAa]Y(ql^;%Fu_84"*_o2Pn"ieU(aN;U(b6?,7cHab_ +rm:nte'umtf)F8)f\,!4gYDea$Js[ui8N\Tj5]4^roO7Ekl0fOlKdd&m-X3.rpKpXnaZVLs766_ +rUp3as7cKerqZQiqtpBjr;H3cJcFU,J,~> +JcC<$JcG$8o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_np']on*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-4AQaMu3;_SO"$]Y(hd\$iZMZ*:C5XK&7tVPKu\TV%gGS!fY0Q'@GoO,f0XMM[+C +KnFu.J:;ooH?sg[G'.nJEH,o7D/=!&BkV-kA^o2Ye^`1Je+]7"Qdh?#Q23lE6MT@:h##k$h"f_" +SGAZPSE$1:SGph7cMl)ebQ,o]bkoTZb5]T`aSs6ZaRuLuWUHecbl>recMl/hd/VMldf._qde_Dn +eC4tQBml)R$jD3S"#q= +rgj[nTV8'RU8+N[V5:&eVl6Pnri-""XT#=,Y-5%5Yd(I=rj)X4[JmTQ\%&rY\[oAa]Y(qk^;%Fu +^qmn)_o0L4`Q#sta9B].bKJ,Srlt\nd*^7he,Ii#e^i@(f\-8X$JX@lh;7#Gi8ESRro4%?jo4BC +kNMp0#O:X@m-O-,mf)YVnF?&Jo)J=]o`"O`pAambq#C0hqYU0gr;HTbrdk++s*t~> +JcC<$JcG$8o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_noO?jn*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-4AQaMu3;_SO"$]Y(hd\$iZMZ*:C5XK&7tVPKu\TV%gGS!fY0Q'@GoO,f0XMM[+C +KnFu.J:;ooH?sg[G'.nJEH,o7D/=!&BkV-kAY/[ekB-06j)Xu`qEjtMm@X?MlZM!+r0d>Ki0j+c +k(!2UrgNeT!h>gQr1EqZj.G%aoS`@!s,$WZosF_+s0VR/!4;a5nOTT]JFa!_-s*+NhrHeKjs*X`ms*jrsr.+`srIWs[ +qh"`sp43$ipjVmaq0r9lqgeZss+:3%s+LE+reCH.!/UW2s,$f7repl;NrG(?OHKO*&!N6CQ'R`& +R$a;1R[]e:Sc52lT:hmOU8"EYUnsobVl-JlWW&muX/u<&#Hk86YctC;ZMq02['fnA)Rm5d\[f;_ +]=bei]tV7r^qde'_Sa=1`Poj;rl>8bb0.uPc2Pulcd:(edaS3F"kD2Uf@\dUg'ZTih;-rEhr*GO +ir7s=jQ6C'!U&\Gkm-M>lg4!*mI'uB!q>aMrpp*\s7H<`s7ZKer:p +JcC<$JcG$8o`"gfrqu]ks8)ckrqQNf!;?Eb!VH!_noO?jn*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%da?Fec-4AQaMu3;_SO"$]Y(hd\$iZMZ*:C5XK&7tVPKu\TV%gGS!fY0Q'@GoO,f0XMM[+C +KnFu.J:;ooH?sg[G'.nJEH,o7D/=!&BkV-kAQAS+s&J5GnNHV1lTP)3qEjsRs%iPhoMPQ`pI"U? +gdD'=i_fMLr);$5rC?larDEMk!)rhonP]Eep/Cifs%`AcqbI)ar_2WNr(R,bnkB'dp0%H!qH$LZ)k>V(RoMbWdr_r\nrDiYor`B&#qcWo%r`f;*ra#M0ra,YNrH\TlH?sdZqGc]ZoMbp7F`hm+ +GQ2mfH2W'hHiJKkIK+cqJ,FiqJc12YKDU8uJbFWkJ,"KcIJJ?jJ,=cqJcC?#KE$W)L&Qi,LB*/0 +M>rG5MuJY9NK4"!!K`HCOq3b@Q'IZ$Q^F/.R[T_8S=TYN&>,VhTq\9VUnji`VPg>jW2]cr!NW=$ +XTu#4YHY79Z*OA8!OT96[MlWb\@K/]]">Vf]tM.p^VIY$_SX4/`5T^8a8X-`ai_fMbg$.4"jbQC +dF-MCe-4CRf@S[.rn7_6gtgfChV[8LiSsjs!T`AAjoOZ/roj[Qlg*p(mHs?@mfN"Knc&+ZoDeI^ +p&Facp\agdq>U6fqu-HkrUTr=s5*d+~> +JcC<$JcG'9o`"gfrquZjs8)ckrqQNf!;?EbGP(Lto'u5=n*]T0m-Es$l0%3kjQ#:Zi8#f*gY;JX +rn@G.r7gq8pRD)Njdl=>s3Uel!m]'9n]gsSp<*EWr5e]5or%kirM\kXrltJgs3L_lrmC_nqpPPp +rmU_no$m`kl+R#-q7HX;s1A$:qRcR7!*&gjrV6Bdrq?9as7QHcrV$-]oZI0Vo#gRGpr`W[!)rep +rDiYorE&u#qHkMueourf7)AOoCLNPE_>t +QBml)R$jEBRi7ffSt;RHTV8'RUSFW\V5C,fVl6SoWiE,#XT#=&Y-7i/#I1S?Za7$G[JmT8\%)FJ +)S3Pm]Y(qk^;%Fu^qmn)_o'F3`Q#s=aN2KGrlYJhc-FV\d/ME+daQ^qe^i='f@\d1g=tB;h;-rF +rnmh9ir7s=jQ6C'!U&\GklL)8rp9[P!:KjT!q>aMrpp*\s7H<`s7ZKer:p +JcC<$JcG'9o`"gfrquZjs8)ckrqQNf!;?EbH1^_!o'u5=n*]T0m-Es$l0%3kjQ#:Zi8gQrL`tYj.G"`s,Hu9oS`O&!*&m&osFS's0Vd5rNlU3[.KabRJ`H1 +QiEEQ;uBVnPqb*?2e1.?N=L3cihY?cHqdFP4=b7P5::DFEM_LG5c^cGlN'f +HN/?lI/JElIfFooJGk&rK'S'cK):,nJGXimId;FZIf=ioJGt-"K)L?%KE-`)L'NKiLl$tGMMqIm +!KE-=Nrb?)rfRVPPa.N"QC!u+R@=,E)P!@iStDXJTqS3UUSO]^VP^8hW2ZbrWiN2%riH4(YPta2 +Z*L[AZa@*IrjDj:\Gj#W]">Se]Y2"m^V@S"_8=(,_o0O5`lH-@aN;U(b6?,7cHab_rm;D-e'umt +f%/I)f\,!4gY:N>h;7&ghuVfrro4%?jo4BCkNMp0!UB"Mm/QGQmf)YVnF?&Jo)J=]o`"O`pAamb +q#C0hqYU0gr;HTbrdk++s*t~> +JcC<$JcG'9o`"gfrquZjs8)ckrqQNf!;?EbH1^_!o'u5=n*]T0m-Es$l0%3kjQ#:Zi8`rDN8bpeq,jq+'%+s%!&crDNVns&/;a!*&Vir)EShpJ:QZrD!8bpe1W\rCd#] +qG$cZ!E<4i=o_e+>lS%)>lS%#;uTbl;t3iY;u]es;uBVnPqb*?2e1.?N=L5 +HN/6mG^"=Tn5SpXp/D0:F`hkNrceBes*=Qhs*Ocnr-eQns*slqrIOitl\#%cqgnKlqg\Hkl[AYZ +rdXfqrdk*$rIb-'!/:B+#D\+kM2@+IMuJY9NK4"!!K`HCOp[D;Q'IZ$Q^F/.Rf8cpS=Q7CT:_dM +Tq\jWMuntX/i?$XT>T.ricX4ZEggC['[7?[K3kIrj`rY]=Y_g]tM.p^VIY$_SX4. +`5T^8a2c9BaiaV+"jG6:cHjl:d1asWeC<%"f%8O+g"P07gYCW@hV\=j!TE&;irS6&roO7Ekl0fI +lKeH9s6TgSrpKpXnaZVLs7?9_rq6 +JcC<$JcG'9o`"gfrqu]ks8)ckrV1j9p@e1Po^qbGo'u5IpQk`DrC$KLr'LG>rndJ, +ptPl(rS7>*!1i_OqO@8Mk+2LAs3^kn!71GcrltJgrltGdrlaoUs2b8^ql'7goVhefpSdba#L1Q> +cd0tbdJ_Mle,Ikse,.Yaec+.h^&G\<^&5PA]DoJ<]D]>6])]GA<;uXqq=saZq"a[`q#C'hp@\CX +rq-9`rq6$.pWN6PrQ5&[prW?Ss&Anrq,[Gqr`K#"r`];*qcs/,ra,M0ra>b7q#C-+iPYZ5s)n?b +rHJ9ds*=Qhs*Ocnr-eQnrdXcpqgms_qLS?jr."Tmj*giSrdXirrdk*$re(6(s+UH,s+^T1reV2D +Mi3OQNK0$[O-#KdP*2#nrfmYQQ^F/.Rf8c`S=Q7CT:_dMTq\=]U]I +JcC<$JcG'9o`"gfrqu]ks8)ckrV1j9p@e1Po^qbGo'u51MZ-TRZh_!-[0V1r*TG2s'Z5[cHje\c-OhfPOXh+ +PPgU@OoKS(G5ZXbGlN'fHN/?lI/JElIf=inJGXo]K)1&lJGaooIcGkSIf=ipJGt-"K)UE&K`?c* +LB!#/M#N5BMMmCON/`jXO,oBbOcklkPl?pOQC!u+R@=,E$CmZYStDXJTqS3UrhKRkVZ*IoW2]cr +#HOr-Xf\b/YPta,Z*OA8!joACrjDj:\Gj#\]">Se]Y2"m^V@S"_8=(,_o0O5`l?'?aN;TIbKJ,S +rlu2'd*^7he'lgre^i@(f\"m2g=tE^h#ZBirnn1CioB([jQ5OdkND(.klL)8rp0^RmdC)C!q>aM +rpp*\s7H<`s7ZKer:p +JcC<$JcG'9o`"gfrqu]ks8)ckrV1d7p@e1Po^qbGo'u5qEt0Is%r\lq,$i`qG@/gp-S[E +nj;A(n59*]o25?^s&82Q!(QfTlULbLjAYqRs&8kqo1o9\nP9'Xr_3;an4`XPr`&Jm"'\r5>Q.n+ +>Pqb)>PD(j;ufk^<:s2i<;]bl5hb'>lS+/?Mn10@/jX8H2`'gFoll5Hgk#) +JcC<$JcG'9o`"gfrqu]ks8)ckrqQNf!;?EbGkCV!o()>?n*f]3m-O'&l0.DJj<,CMINrB@?e.rR:htm$Q%ar'^?JrBgA;q;(c"qqM%>qj[YW +lC@(/"J!rhdEqU5!RAsfcMl)bbOis9W:Qq`W!Bk.CUks7l9]rV6Ee"SVN]p@eLYrq-3_q9&6Nqo\cWqoJQSrQ>(=q,[Gqr`K#"r`];* +qcs,+ra,M0ra>b7raP^'f#%X/F`hkNrHJ9ds*=Ngs*OcnqgJKnrI=Tmq186kpjr'fr."TmhL5?O +rdXirs+13%rIb-'!/:E,s+^T1re^Z4%Z?:)NK&sZO-#KdP*2#nrfmYQQ^F/.Rf8c[S=Q7CT:l1W +!MZ@gU]IaMrpp*\s7H<`s7ZKer:p +JcC<$JcG'9o`"gfrqu]ks8)ckrqQNf!;?EbGP(Luo()>?n*f]3m-O'&l0.DJj<,CMINrBDnD$T)P;/FQ[`C7/94K6MdDOT^n`TT\ahSG5[p( +RcBh9JFJ-eJE24[SH#,[T)G;XT&ZIANRWpbNVe\3MZAY6;uX-"[/IE2[f5hb'>lJ%.?Mn10@/j[7@f=ORd*gIrrfcl8nWWp7r/q#%s*"?bs*4Qh +r-JBis*X]ls*jorpji0kp4E'joRQjhqgRCMrI4`qr.+fus+:3%s+CB+reCH.!/UW2s,%;EN/WaU +NfT6_OcbfiPEc'3"dYLBR$jEBRg#=QSt;RIrh0@eU].%iV5F6i!NGgb0.uPbg"GYcd;[=&(8qVeCE+# +f@S[.g"P07h#?+@hV[8LiSieVj5f:_k2tjikl0fIlKeH9s6TgSrpKpXnaZVLs7?9_rq6 +JcC<$JcG'9o`"gfrqu]ks8)ckrqQNf!;?EbGkCV!o()>?n*f]3m-O'&l0.DJj<,CMINrB2ne/r`$Zsq*"XDq*Y*IqGI2fpJLibr_NPj!)`JV +r'LBMn3Z;*n59*]o25B_r_rhdkXYA)q,>sGq,@5lq,[Gqr`K#"r`];*qcs,+ra,M0ra>b7raGkOrcSBgH$au-<:Nu` +<<%+@G5ZXbGlN'eHN/?lI/A?lIf4ckJGFciK(sohJGaooIboMOIf=ipJH(3#K)L?%KE-`*LB!#/ +M#N82M@PQ'N/`gWO,oBbOcklkPl?pOQC!u+R@=,E"e;-TStD\TT`Lm_rhKRkVZ*IoW2]cr!NW=$ +XTu#4YHY79Z*OA8#ILnH[^NZS\Gj#I]">Se]Y2"m^V@S"_>_:P_o2Pn!QN1Za9p&3bKJ,Rc-FV\ +d/ME'daQ^qe^`7&f@\d0g=k<:rnS.Bhr*GOiSrnXjQ,Fbk3(pkrojIKli-8Nm/ZSRmfN"Knc&+Z +oDeI^p&Facp\agdq>U6fqu-HkrUTr=s5*d+~> +JcC<$JcG*:oD\afrVZTjs8)ckrqQNf!;?Eb!VH!_nosWnn*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%e'ZOfcHOJRaN)9<_SX+']tCqe\@/fOZEUO8XfJJ#Vkp2aTqJ!JS!ob4QBdYsOcPN]N/EIJ +L4t84JUi5uI=$9cGB\1OF)l8>Df0E.CMIQsB@>8We'n5hb'>lJ%.?Me+0@/aU4@K9p7s6[_l +_Z%IQ`;au[G5ZXaGlN'fHN&9kI/A?kIf4chJFS3]JGaooIe/!WI.r'fIf=iqJH(3#K)L<'KS>-Z +L'!-dM#N53MMqIm$B:(,O-#HcP*2#nrfmYQQ^F/.Rf8c[S=Q7CT:l1W'r%J!UnsobVl-JmWN)u! +X/rG*Y-+u-YQqG=ZEpmE['fnA#Ih4Q\[f;_]DfGJ]tV4q^VIY$rk\]R`;[^V`lJ)"&';u;bKS2T +cHab^d*^7he,Ihte^j`O+5#9#g=tB;h;-rFhr*GOio9"YjQ5Lck3(sll07Kuli-5PmI'EAmfN"K +nc&+ZoDeI^p&Facp\agdq>U6fqu-HkrUTr=s5*d+~> +JcC<$JcG*:oD\afrVZTjs8)ckrqQNf!;?Eb!VH!_noO?jn*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%e'ZOfcHOJRaN)9<_SX+']tCqe\@/fOZEUO8XfJJ#Vkp2aTqJ!JS!ob4QBdYsOcPN]N/EIJ +L4t84JUi5uI=$9cGB\1OF)l8>Df0E.CMIQsB:Spks.04]c?/AnqF(0IrBg.MrLihUs.K=6kB5a, +rLPh\)?2e1-?iOO5@JjR>A'NTfP*;.0Pm*J?R$a;1rgO(]SXuFFT`1W"U8+N[V5:&eVl6So +WiE,#XKAV-Y-7i/#I1S?Za7$G[JmT>\%&rY\[oAark&KL^:q@s^qdec_?%Qmrl"oXa8X-jai_fM +bfn>WcHjh`dF$CkrmUu!f)F8Cf\,!4gY:N>h;7&Hi8ESRioB([jlPXekNM-ol0@R"rp0^RmdC)C +!q>aMrpp*\s7H<`s7ZKer:p +JcC<$JcG*:oD\afrVZTjs8)ckrqQNf!;?Eb!VH!_noaKln*f]3m-Es$l0.9ljl>C\i8EJJgtUQ9 +f@JL%e'ZOfcHOJRaN)9<_SX+']tCqe\@/fOZEUO8XfJJ#Vkp2aTqJ!JS!ob4QBdYsOcPN]N/EIJ +L4t84JUi5uI=$9cGB\1OF)l8>Df0E.CMIQsB2hl1rD`hs`'3u[rB0pEqEt3Js%r/]rD<>dnj31? +!(6NJiBuEur)3JlqaT[;n4br_iMiqGR5ir`%9?rCuiVrDWDns'#J.ra#P/r`fA,!+#G* +r);*EqbmJpq,[Gqr`K#"r`];*qcs,+ra,J/s'Yh7r*fn@F`qtSH[U>0<;9Ja<<%+@G5ZXaGlN'f +HN&9kI/A?kIf4chJFS3]JGaooIe/!WI.r'fIf=iqJH(3#K)L<'KS>-ZL'!-dM#N53MMqIm$B:(, +O-#HcP*2#nrfmYQQ^F/.Rf8c[S=Q7CT:l1W'r%J!UnsobVl-JmWN)u!X/rG*Y-+u-YQqG=ZEpmE +['fnA#Ih4Q\[f;_]DfGJ]tV4q^VIY$rk\]R`;[^V`lJ)"&';u;bKS2TcHab^d*^7he,Ihte^j`O ++5#9#g=tB;h;-rFhr*GOio9"YjQ5Lck3(sll07Kuli-5PmI'EAmfN"Knc&+ZoDeI^p&Facp\agd +q>U6fqu-HkrUTr=s5*d+~> +JcC<$JcG*:o`"gfrqu]ks8)ckrV-Hgp@eLYHh?q#o'u55hb'>lJ%/?Me+/@/aU4@fBj; +AGZ>n_sP>@_Z7XSFoQX`GQ2peH2W'gHiAEiIJnWnJ)5_QJ,FcfIHQ"RIK"]pJ,OotJcC?$KE$W) +L&Qf-LPYqd#)\=sN/WaVrf75EOcklkPl?pOQC!u+R@=,E':bVbStD[LTq\9VUnjiaVPg>jWW&mu +X/u<&#Hk86YctC;ZMq03['d=@[K3kIrji'?!5&6C#JIjc^V@S"_>_:P_o2Pn!QN1Za8sE*rlY>d +c2Puhcd;[=&(8qVeCE+#f@S[.g"P07h#?+1hV\=j!TE&;irS6&roOIKkih9qlK[^7liQSBmf)YV +nF?&Jo)J=]o`"O`pAambq#C0hqYU0gr;HTbrdk++s*t~> +JcC<$JcG*:o`"gfrqu]ks8)ckrV-Hgp@eLYHh?q#o'u51raG_6raQ1D +d*gLtf\,$?POjt:FoQX`GQ2peH2W'gHiAEiIJnWnJ)5_QJ,FcfIHQ"RIK"]pJ,OotJcC?$KE$W) +L&Qf-LPYqd#)\=sN/WaVrf75EOcklkPl?pOQC!u+R@=,E':bVbStD[LTq\9VUnjiaVPg>jWW&mu +X/u<&#Hk86YctC;ZMq03['d=@[K3kIrji'?!5&6C#JIjc^V@S"_>_:P_o2Pn!QN1Za8sE*rlY>d +c2Puhcd;[=&(8qVeCE+#f@S[.g"P07h#?+1hV\=j!TE&;irS6&roOIKkih9qlK[^7liQSBmf)YV +nF?&Jo)J=]o`"O`pAambq#C0hqYU0gr;HTbrdk++s*t~> +JcC<$JcG*:o`"gfrqu]ks8)ckrV-Hgp@eLYH1^_!o'u5j>f:[ULK +6IeH[;>jDk;tic88,>dJ;u0De;u]bk;uBVk:AIW;:Amo`9`%ce>5MP'>QA(&>l.b);sI?Z;t3i_ +;u9Vo=8c7u=oDP'>Ph\)?2n7.?iFI4@JjU6@g?OhH$apdIXUQ^q,R#crcS6arHJ9drd"Hgrd4Wl +qgJElrI<[Sqg\NmoR5nMq0i6krdXlss+13%re(6(s+UH,!JcL1M$AiqMi,^b5TQbbg$.4!RK-ld1=[SeC<%!f%8O+g"G*5gYDea +!T)`5huVfrro4%?jo4BIkNM-ol0@R"rp0^RmdC)C!q>aMrpp*\s7H<`s7ZKer:p +JcC<$JcG*:o`"gfrqu]ks8)ckrV1j9p@e1Po^qbGo'u5WT^;WWVEFd +VZ>0Ee+M5gebI_nfDjM&g&B_*g\S\]^@],0]`#J4]`#J>;Z6@ep]1'fp&OdboEb'\o^h\Ho^h\P +o_Q`#bOs$Uan*URao5?>=8c7u=oDP'>Ph\)?2e1.?iFI4@JaO6A,^!=AbuGo_sG8>_uFlZG5QRa +GlN'eHN&9jI/89iIf"WYJGOcmIeA-cI-l:XI/89kIf=iqJH(3#K)UE&KE-`*L)l&*Ll$tGMMmFP +NK0$[O-#KeP*;)oQ'IZ%R$a;1rgOCfSXuFFTV8'RU8+N[V5F6i!N +JcC<$JcG*:o`"gfrqu]ks8)ckrV1j9p@e1Po^qbGo'u5r3H@/rNcF/!1DT/rg3;Ds-N^crE&r"qcWl$r`f8)ra#M0r*TG2raG\5s'u%= +"D-*6f\-8Yo9/U,oTK5ss*" +JcC<$JcG*:o`"gfrqu]ks8)ckrV1j9p@e1Po^qbGo'u5Q7t. +?1qM'>Q.n(>P_:g<:s2`<;0>j5hb'>lJ%.?Mn10@/aU3@fKs;A--=hI/\NpIXUfe +n5]9`r) +JcC<$JcG*:o`"gfrqu]ks8)ckrqQNf!;?EbIe<7'o()>?n*f]3m-O'&l0.fNq47#Hm%+1+s3q"rr6Y,_rlt>ar6+u[r2At]q5F4jp8Ihc!7USi +s4-enrR_)%rn.;*qqLt]!5J?DotBq/rO_^7r4Vo(s7cHd!Vc5hb'>lJ%.?Me+/@/aU4@fBm:AGp*9s6[_i_?@c!F`qs+GQ2peH2N!fHiAEgIJeQj +J+A-bJ,=]gIJS?dHhMd]Hi8?hIK"]qJ,OotJcC?$K*$^[L&Qf-LPYqd!K)g7N"V,1O,oBbOcklk +Pa.N"Q^F/.Rf8csS=Q7CT:hmOU8+KZUnsrdVl6PnWiE,#XKAV-Y-7i/!O8s0Zi@B4[JmT9\%&sI +\H0:Rrk/9E!5AHI!l2Xgrk\]R`;[_4`lH-@aN;TIbKJ,Rc-FV\cd:(edaHUoeCE+#f@S[-g"P07 +gYCW@hVR/Ji8NYSj5]4]jo4BCkNMp0!p]+;rp0^RmdC)C!q>aMrpp*\!;-6_s7ZKer:p +JcC<$JcG*:o`"gfrqu]ks8)ckrqQNf!;?EbGP(Luo()>?n*f]3m-O'&l0.\Ar,_^V!(HTLqEk6Lm@jKO +!M?%aTDNj!G49_BG5n*0S+<$IRJiTSRJ`NNRJ_TuJaS'bJ+fK2TD"rQT`ChaU\]uNO84h)NV&1u +Mtp9M[/dZ7[fNqFrj2[3pp0q)rNcF/!1DK,s-NGF!13XcrE/o!r`];*qcs,+ra,J/ra>_6r*oY8 +rabt="4u5\g]#q#P3nJ+P5f\)G5QRaGlE!dHN&9jI//3gIenQbJG=WkIeJ3dI/&'^HMMpdI/A?k +IfForJH(3#K)UB(KS>-ZL&m'creUZ5MuJYJNK0'\OHGZgP*;,qQ'Rc(R$jEBRiS#iSt;RITqS3U +USO]^VPg>jW2ZesX/i>(Xfeh1ricF.ZMq31ZiIN5[K]"@sSs1JEHrkANM_86,f!Q2kT +`AGTTa2l?Db0%oNbfn>WcHjh`dF$Cje'umte^i@(f\"m2g=tB;h;-rEhr*GOiSrnXjQ,G%joOZ/ +rojLLlg+Q:!q#FDrpKpXnaZVLs766_rUp3as7cHds7uZjqtp?ir;H6dJcFU,J,~> +JcC<$JcG*:o`"gfrqu]ks8)ckrqQNf!;?EbGP(Luo()>?n*f]3m-O'&l0.q`Xj@pHS:6krf#8p-eaE!(-KX +nPT<_r_N5SnO)e6oL&F@jAG\Mr)6Wkt_(Lq,72r +s'5P/!aJr6qHX#("'f&7>l@n,>kV+j<:Ph\)?2e1-?iFI4@JjU6A,^$; +Ac@)[I!^6gnl5-Zq,I;ks)n?br-/0crd"Efrd4Wlq0i0iqLA'dpj`0ip3ldbpj;^\q0W'fqgJHm +s*suts+13%rdt9*Kn]M\!JcL1M#iKlreqJLNfT6_OcbfiPE_>tQC!u+R@=,E*Lr[lStD[LTq\eG^B23e_>_:P_o2Pn +1rdSVaN2KGb0.uPbg"GYcd0tcdF-IleC<%!f%8O+f\,!4gY:N>h;7#Gi8ESQioB([jQ6C'!U&\G +klU/9li-5PmI'EAmfN"Knc&+Zo)SF]p&Facp\agdq>U6fqu-HjrU^#>s5*d+~> +JcC<$JcG-;o`"gfrqu]krqZWjrV6Ee!;?EbIe<7&o'u8>n*f]3m-Es$l0.9ljl>C\i8EJJh:pZ: +f@SR&e'ZRhcHOJSaN)<>_ns7)^:_(g\[T#SZa$acrm(PgrQP)\s2t5< +ri"_Ror.kfo[Nokpt#Dqrn.8(rS%2(!8R@`qS2g>qn;p?!580?pq-C8rOr&)s&&jkrqHNfp&=Rb +oCDJMoD8%XoD\C^oD?](b5fcabOisSan3XS=8c7t=oMV(>Ph\)?2e1-?iFI4@JaO5A,g*:AcHB> +s8'V(_s>2>FoQX_GQ)jdH2N!eHiAEgIJSE[J,+QdIJ\EgHg?"UHi8?hIK+crJ,OotJcC?$K+N]i +Knb>;LPUeDMMd=NN/`ksNuF+BP*2#nQ'IZ%R$a;1R[]e:SXuFFTV8'RU].%rV5C/gW2ZbrWiN6# +XTu#4YHY79Z*OA8#ILnH[^NZS\Gj&=\cBAA]E5d\^AbkP^qmk(_Sa:0rl#,^a2c9BaiV^)b5oi3 +rltPjd/MDndaS3F!S,d#f)aOWrn7D-h#?+1hV\=j!TE&;is4Z,jlY^gkNMp0#O:X@m-O-,mf)\T +nGi%Xo)J:]o_nI_pAambq#C0hqYU0gr;?Nardk+,s*t~> +JcC<$JcG-;o`"gfrqu]krqZWjrV6Ee!;?EbGkCUuo'u8>n*f]3m-Es$l0.9ljl>C\i8EJJh:pZ: +f@SR&e'ZRhcHOJSaN)<>_ns7)^:_(g\[T#SZa$aPh\)?2e1-?iFI4@JaO5A,g*: +AcH?Cg=cGYqN:]=m$%1,s)n?br-/-brd"EfrHnNkq0i*gm=4q\omQ^bqKqOSr-SBiqgJKns*sut +s+13%rdtc8KnY89LPL\BM2I1KN/WaVrf7tZOcklkPa.N"Q^F/.R[T_8S=Q7CT:hmOU8.^`$DjVt +Vl6SoWiE,$riHF.YHP17Z*CV6ZNmkF[C3NQ\%)FJs1/3Brk&dc2Puhcd;[=!RfHre,e+Nrmq2'g&B\+gYDea!T)`5huVfrro47EjlPXekND(.km-M> +lg4!*mI'uBs7$'Yrpp*\!;-6_s7ZKer:p +JcC<$JcG-;o`"gfrqu]krqZWjrV6Ee!;?EbG4bCso'u8>n*f]3m-Es$l0.9ljl>C\i8EJJh:pZ: +f@SR&e'ZRhcHOJSaN)<>_ns7)^:_(g\[T#SZa$am">9>?_#1r`oJ-s'#8'rEK>.o2GTegf"2SrE/o!r`];*qcs,+ra,J/ra>_6 +qdTP7s()";LPUeDMMd=NN/`ksNuF+BP*2#nQ'IZ%R$a;1R[]e:SXuFF +TV8'RU].%rV5C/gW2ZbrWiN6#XTu#4YHY79Z*OA8#ILnH[^NZS\Gj&=\cBAA]E5d\^AbkP^qmk( +_Sa:0rl#,^a2c9BaiV^)b5oi3rltPjd/MDndaS3F!S,d#f)aOWrn7D-h#?+1hV\=j!TE&;is4Z, +jlY^gkNMp0#O:X@m-O-,mf)\TnGi%Xo)J:]o_nI_pAambq#C0hqYU0gr;?Nardk+,s*t~> +JcC<$JcG-;o`"gfrqu]ks8)ckrV1d7p@e1Po^qbGo'u5C\i8EJJgtUQ9 +f@SR&e'ZOgcHOJSaN)<>_ns4(^:_(g\@8oRZa$adM7/B7Pio/ko +i:Z"'hWUR,SaE$?Sc71=eGn"rdK%\md/MAicMPidbkTB]XSJpsWW9*nWp?YWVuWaheGe"qf)F;# +f_sJ'gAK_&h"\VS^\PVB^&PhE^&>V6]DfJ;;$-Lcp&=O_o)A1Znc84Snc8:ZoE=d/bKA!$bQ#f\ +bP00SanWsW=Sc2">5hb'>lJ%.?Me+/@/aU3@fBm:AG]s;B)cNAs7aD(_s5)=FoHR^GQ)jdH2Dpe +Hi8?dIHQ(OIJeKhHfTMNHiAEjIK+crJ,OotJH1<$KE$T)L&Qf-LPYqd!K)g7N!YK(O,oBbP*2#n +rfn(]Q^F/.R[]e:SXuFFTV8'RU].%mV5C/gW2]cr!NW=$XT>T.ricX4ZEggC['[7?[KTR]E,^[rkJKK!5\ZOs2+iTrl#,^a2c9BaiV^)b5oi3rltPjd/ME.daQ[peCE.$f@S[.g"P07 +gYCW@hVR/hhuVfrro4%?jo4BDkNM./klL)8rp9[P!:KjTs7$'Yrpp*\!;-6_s7ZKer:p +JcC<$JcG-;o`"gfrqu]ks8)ckrV1d7p@e1Po^qbGo'u5C\i8EJJgtUQ9 +f@SR&e'ZOgcHOJSaN)<>_ns4(^:_(g\@8oRZa$ao61#$rgWGHqj[>Ks+9*Ym!o(cpn%AToq;;X!2B1^iK!DeqMb0,pJD1'[^EKL +Za-n8Yl_/7YkbR'ZMh-0RGF8"QiC1a=oMV(>Ph\)?2e1-?iFI4@JaO5A,^$9Ac? +JcC<$JcG-;o`"gfrqu]ks8)ckrV1d7p@e1Po^qbGo'u5C\i8EJJgtUQ9 +f@SR&e'ZOgcHOJSaN)<>_ns4(^:_(g\@8oRZa$adpeLWZrCm&^qbHWTpJD&u?!LT1 +raG\5raYqjWW&muX/u<&!NrX*YQqG=ZEpmE['fnA!k5\Lrj`*A]=\'T!PQ5H^]2(L_>_=O_Z7XS`fbbNc2+X8]-gWV3:aeGn(tec=>$f_aA$g&Tn& +h#H4)^?WK0^AGV@]^rc0;$?L]nac5Kn,i.LnG_tTo)A7XoDm,.bPBB[bOs$Nao'6W=oMV(>P_V( +?2e1-?iOO5@JaO5A,^$9Ac?<@BDuTBs7aD(_s>2>FoQX^GQ)jdH2DpdHi8?aII_jXIJ\EhHes)J +HiAEjIK+crJ,OotJH1<$K+rumKnb>;LPUeDMMd=NN/`jYO-#M'OtDl^Q'IZ%R$a;1S"#q=St;RI +TqS3UUnji`VPg>jWN)u!X/rG*Y-+t4Yd(I=rj)X4[JmW7[fEr;\c95@]DfJC]`>eG^B23e_>_:Q +_o0Lm`<"!!rlG,]!6Y;a!R/gfc4&%Gd*^7hdaQ^qe^`7Mf)aOWrn7D-h#?+7hV[5Ki8NYSro4%? +jo4BIkNM-ol0@R"rp9[P!:KjTs7$'Yrpp*\!;-6_s7ZKer:p +JcC<$JcG0?n*f]3m-O''l0.5XS,/TNRfJuVS+iBFK&hLMJGl)2TD>/[U&Uk[UYLn%NV\V/Mt^'K[/RB8ZE^[= +Yd+,1qm$()rNcQmR@3!#m[*fRr`];*qHX#*ra,J/s'Yh7qdTP7rabn;rau.Brb);brS%".rK@,C +pltT +JcC<$JcG0?n*f]3m-O''l0.g7r^-NMqaCBMpHnRNo2>TcoMY]Xm7-k@rCHiVr(-BKr_iPhqGR,fpf./is&/hkqG7)e +pJ:NYoM,3Xo1esV!aJr6rEB,'qc`u'q-3o*oMbQbk>V@Zr)i)K`!s*"9`rcnEfqg/3frI"6cnp^.XqgA9fhKo0Jrd=Wls*jutrIFp! +!.t3&'SM0oL5(J=Ll$tGMMmFPNK0'\OHKO*/X)EaQ'Rc(R$jD4S"-%@StD[LTq\ +JcC<$JcG0Df0E.c-H:6o:,]Ko:,61raG_6raYqjWN)u!XK8P+Y-7i/#I1S?Za7$G[JmT9\%&sI\H9@S]DfGE]tV5[^B23e +_>_:V_o0L4`Q#p!9O4B!U&\Gl2U#Kli-8Nm/ZSRn,MkWnbr%Yo)SF]p&Facp\agdq>U6fqu-HjrUTr=s53j,~> +JcC<$JcG0Df0E.R@4#Bj`LKEfQ@']rC-HKqa:1Q!2B=`p7hG.rHS!Z +m<85JnTOo's./eO!1`\Nq3pu-!.sThrdsutmst8,s.9%YqOmk^rM'"\fT,T`qi(H2pe^re!OB!* +YQ1m)YlD!*ZMh,eR-^1==oMV(>P_V(?2e1-?iFI4@JjU6A,^$8Ac?<@BDcECg&9XtOnk11PPUIB +FoHR^GQ)jcH2DpdHi/9HIJ\EhHh2RRH1uXaHiAEjIK+`rJ,Om!JV&LQK0FsBKnb>;LkpnEMMmFP +NK&sZO-#KeP*;,qQ'Rc(R$jD4S"-%@StD[LTq\ +JcC<$JcG0Df0E.r`'#!;cETXg-,?tp-8I=qE=dHrC-HKqa9OC!)NJY +!(6_6r*oY8rabk:rau.Br+Q"TiD]GL +s)njWN)u!XK8P+Y-7i/#I1S?Za7$G +[JmT9\%&sI\H9@S]DfGE]tV5[^B23e_>_:V_o0L4`Q#p!9O4B!U&\Gl2U#Kli-8Nm/ZSRn,MkWnbr%Yo)SF] +p&Facp\agdq>U6fqu-HjrUTr=s53j,~> +JcC<$JcG0+P`h2kO,f0W +MM[+CKnP)1J:E#rI!U*`GB\1OF)l8>Df0H/bfn>Wcd2EVnsoECpR:HSs4RP-f[p,Rr71_prmLenq9]/fs3CYhs312c=3htFeH^\tn6^&G\;:]OAkmf;eSn,2\Tnc&+YoDA1Abl5f\ +b4NgUaSoBA>Ph\)?2e1-?iFI4@JaO5A,^$9Ac?<@BDQn`XG5HL_Gl;paHMi-f +I,o_PI/A9`HK]YMHN&9kI/JEmIfFosJ-(:RK)UB'KSBD[!JcL1M(X[DN/WaVO,oBbP*2#nQ'IZ% +R$a;1S"#q=St;RITqS3UUnjiaVPg>jWN)u!XT#=&Y-7i/!O8s0ZNmkF[C3NQ\%)FJs1/3Brk/9E +!5AHIs1eWNrke]Q!6"lUs2G&Zrl>/_b0'_,!R/gfcMu2jd/MDndaS3F#M%DVf@S[-g&B\+gYDea +#N"@qi8ESQir7sCjQ5Lck3(pkrojLLlg+Q:!q#FDrpTmV!:g$Y!qZ'VrUp3as7cHds7uZjqtp?i +r;H3cJcFX-J,~> +JcC<$JcG0+P`h2kO,f0W +MM[+CKnP)1J:E#rI!U*`GB\1OF)l8>Df0H/r0[PR\odsBrC6`SpI+pHqP!n_pn@MXom$(Pm<85J +olg>+s./tUrLTXqLS0erLa%[pn.DUs.T@bpS6)qoSrj/ohYZdYPta+YPtd*YPbX( +Z2M!-Zi@>cR.?UDQMt(d>Ph\)?2e1-?iFI4@JaO5A,^$9Ac?<@BDQtQC!u+R@9V7S=Q7CT:hmOU8+N[V5C,fVl6SpWiN6#XT>T.ricF.ZMq08['d)[!m/U-rlY>dc2Q#gcN)>kd/h\ErmV2' +f%/I)f\"mVg&]s`rnRh9hr!AMiSieqis4Z,jlY^gkNMp0!p]+;rp0^RmdC)Cs6p$YrUL$]o^r+T +s7ZKer:p +JcC<$JcG0+P`h2kO,f0W +MM[+CKnP)1J:E#rI!U*`GB\1OF)l8>Df0H/<)cjt<)h4-q`amArBC*As%!#WrC-HKr'LN^:J^4O +p-\C=qEs^jr)1raG\5raYqh!-S9aqfi$arH\6cr-S?hjF-lPqg8!^k]uuMrd4Zmr-eTos*t#u!eGrTrdt6)L&Qf-LPYqd +/rGRGN/`jYO-#KeP*;,qQ'Rc(R$jD4S"-%@StD[LTq\U6fqu-HjrUTr=s53j,~> +JcC<$JcG3=oD\^erqu]ks8)ckrV-Hgp@eLYHh?q#o'u5=n*f]2m-Es$l0.9ljlGI]iS`VLh:pZ: +f[n^(e'cXicHXPUaiMNA`59C,^V.:l\[])V['R$AYH=n+WMl_kUnaWVSt;IAR@'>+P`q8lO,f0X +MM[.DL4k22J:N)sI!^0bG^"=QFE;GAE,KQ1bKS2TcMjdM7/]LQj7qX3 +i<&#tiVVO5htE]*T(\`IT(ni_gY1?6f\"g-f%0`Ks3q%trmLbms3U_lrm1_mcHb1HqQ0LnpT"&> +!nPuTrn.5'rn@A+rS7>,#N"@qi8ESQir6^g^?*--^?iQ*;#g"^melPRnG_tXo)J:^o_&.Ss3:Md +!6slSrQG#Zp_6qdTP7rabn;rau.BqIokBrbDE3kJI26oYLTNrHA'^ +rcnBeq0MscqL%[Yq0`'dom6FZnTaqVq0N'frd=Zms*artrI?_UJqAW-KS5&6L51P?M2@+JN/WaV +NfT6_OcklkPa.N"Q^F20S"#q=St;RITqS3UUnjiarhfpuWN)u!XT#=+Y-5(6Z*CV6ZN7G@rjDm; +\@DOK!kQ"Urk&/_b0'_,#L(H;cHab^d/MDtdaQ[peCE+# +rmq2'g&B_*gAp%.h#ZBirnn%?io9"YjQ,G%joX`0kl0fJlKdd8liQSBmf)\Tn,W"WncJFTo_nI_ +pAambq#C0hqYU0gr;?Nardk+,s*t~> +JcC<$JcG3=oD\^erqu]ks8)ckrV-Hgp@eLYG4bCso'u5=n*f]2m-Es$l0.9ljlGI]iS`VLh:pZ: +f[n^(e'cXicHXPUaiMNA`59C,^V.:l\[])V['R$AYH=n+WMl_kUnaWVSt;IAR@'>+P`q8lO,f0X +MM[.DL4k22J:N)sI!^0bG^"=QFE;GAE,KQ1r0dP,]QF-CrC6`SpI+sIs.]@`rhB1]r1X18np'_L +n94GJpicV-s./\Mp7(uKd=Lk=rLa(\qOd_Zr1Wt]qkO+crf>EdoSrK>!O&a+Y5ka(YPtd(Z2_-/ +Zi.3'QiNK5R.lsHQ2k+f>Ph\)?2e1-?iFI4@JaO5A,^$9Ac?<@BDQ<@C&VlGg@UO&P4=b6OoTY' +G5HL_Gl;p`HMi-dI-l@XI/A9`HMMjVGl)d^HN/?kI/SKnIK4lrJ2Dh/JqJ]/KS>/8LPL\BM2I4M +N/`jXO,oBbP*2#nQ'IZ%R$jD4S"-%@StD[LTq\TR]E5d\^AbkK^qmkd_?.Wn`;[^W`lH.!a9'K+b5TQhbg"DXcHjh`rm:u!e'lgr +e^`7Mf)aOWrn@D,!8RS0!T)`5i!86#ioB([jQ6C'!pAe2rojLLlg+Q:!q#FDrpTmV!:g$Y!qZ'V +rUp3as7cHds7uZjqtp?ir;H3cJcFX-J,~> +JcC<$JcG3=oD\^erqu]ks8)ckrV-Hgp@eLYHh?q#o'u5=n*f]2m-Es$l0.9ljlGI]iS`VLh:pZ: +f[n^(e'cXicHXPUaiMNA`59C,^V.:l\[])V['R$AYH=n+WMl_kUnaWVSt;IAR@'>+P`q8lO,f0X +MM[.DL4k22J:N)sI!^0bG^"=QFE;GAE,KQ1;cH^rX8g;uTbi;u9Jc:@1jR:@1dQ:@q?_>Q.h*>P_P'>Pqb+ +?2e(0?!d2&nPndPrDWc#r`f8)ra#M0qd9>1raG\5raYqG5HL_Gl;p`HMi-dI-l@XI/A9`HMMjVGl)d^HN/?kI/SKnIK4lrJ2Dh/JqJ]/KS>/8LPL\B +M2I4MN/`jXO,oBbP*2#nQ'IZ%R$jD4S"-%@StD[LTq\TR]E5d\^AbkK^qmkd_?.Wn`;[^W`lH.!a9'K+b5TQhbg"DXcHjh`rm:u! +e'lgre^`7Mf)aOWrn@D,!8RS0!T)`5i!86#ioB([jQ6C'!pAe2rojLLlg+Q:!q#FDrpTmV!:g$Y +!qZ'VrUp3as7cHds7uZjqtp?ir;H3cJcFX-J,~> +JcC<$JcG3=oD\afrVZTjs8)ckrqQNfs7ZKcs7CU.o()>?n*f]3m-O''l07Bnk2kX`io&bOh;-i> +g"4j+eC2jncd'eYbK7iF`PfX0^q[Rq]=GG[[C!9FYck11Wi;qpV50l[TUqaFS!fY1Q'IPrOcPN^ +N/EIJLPCJ7Jq8H%I=6HgH$FOVF`_\FEH#i6D9L,Hbh\fFS,>eT7f>dN7/]LOj7hO5j8J!;iV_X& +TBr0HSaE$HSc@IJgY1B6f`'M%f)F5"eGn"tde(reciDDFXno-hX8UWLeH4=RfDXD$g&Tn)h#?+8 +hV[5Ki8NYSir7s_6qdTP7rabn;rau+Aqe5qBrbDFJrr;,trPA0Ds)n;M#N5VMMmFPNK0'\OHG]hPE_>tQC!u+R@9V7 +S=Q7CTV8'RUSO]^VZ*J2W2ZesX/rG*Y-+t4Yd(L>Za7$H[C3NQ\%)FJs1/3Brk/9E!5AHIs1eWN +rke]Qs2=oU!li:$rl>/_b0'_,#L(H;cHab^d/MDodaQ\Ee,e+Nrmq5(g"HAY!ScE/h#cHjhu;O7 +iSsjs!p&J)roOIKkih9qlK[^7m/QJQmf)YVnF?&Jo)J=]o_nI_pAambq#C0hqYU0gr;?Nardk+, +s*t~> +JcC<$JcG3=oD\afrVZTjs8)ckrqQNfs7ZKcs7CI*o()>?n*f]3m-O''l07Bnk2kX`io&bOh;-i> +g"4j+eC2jncd'eYbK7iF`PfX0^q[Rq]=GG[[C!9FYck11Wi;qpV50l[TUqaFS!fY1Q'IPrOcPN^ +N/EIJLPCJ7Jq8H%I=6HgH$FOVF`_\FEH#i6D>fn"Fh`%r8,YpU7JK:L6iEbWU&1S[U&UheU&9-, +Gg^g6G5e*0Sa`0FS,Sl&Jb4KkTDtM\TDYA]U%Y2\U\pqdV=ou3Nqe\5NqSJ';#[ZqXoP[(YlD!. +ZMq01ZMq31ZLsU`QfFJ.QN17e>lJ%.?Me+/@/aU3@fBm:AG]s;B)QB>B`2ZECAr#Jg@UO%P4Xt7 +P5f\(G5?F^Gl;p_HM`'OI/83_HMVpNGl;pbHN&9kI/SKnIfFosJ.$p[JqJ]/KnY89LPYqd,`7M= +N/`jYO-#KeP*;,qQ'Rc(R$jD4S"-%@StMdNU8+N[V5F6i)5sO7WiN5'Xfeh1YctCeG^]2(L_>_=O_uI[S`<+'"a8X-]ai_d*b6Q89c-FV\cd;[=!n,QHrmUu! +f)F8&f\+sWg&]s`rnRY4hr"Fk!TE&;ir\<'jo4BIkNM-ol0@R"rp9[Ps6fmT!q>aMrpp*\s7H9_ +s7ZKer:p +JcC<$JcG3=oD\afrVZTjs8)ckrqQNfs7ZKcs7CU.o()>?n*f]3m-O''l07Bnk2kX`io&bOh;-i> +g"4j+eC2jncd'eYbK7iF`PfX0^q[Rq]=GG[[C!9FYck11Wi;qpV50l[TUqaFS!fY1Q'IPrOcPN^ +N/EIJLPCJ7Jq8H%I=6HgH$FOVF`_\FEH#i6D,XA4<5h#s55[SA8,YpU7JK:L6h=+H:sMH'6MEk= +;<_!E7f5dM8GbpL7f,^S;Z9Pl;X.3\;Z0P]:Adod:B"&Z:A.E[:@_6\>5MP(>5_\)>l7n+?L^tg +<9R9Z;ug/">lJ%.?Me+/@/aU3@fBm:AG]s;B)QB>B`2ZECAr#KH2r<\;tNu_;uTbrFoHR\GQ)jc +H2)^_Hff_PHhD^]H0BMOH2DpeHiJKlIK+crJ,Xs+JV&K+K7nr4L5(J>reVnXMijQ5M&jp1)5kiq?slKeH9s6]jSrpKpXnaZVLs7?9_rUp3as7cHds7uZj +qtp?ir;H3cJcFX-J,~> +JcC<$JcG3=o`"gfrquZjs8)ckrqQNf!;?EbHh?q$o()>?n*f]3m-O''l0.jk%9?^@o81;#BYYmKE"Jnac;Mo`"O^oDm/2cMYrXbl#Z\b5BBWaSfBC?2e1- +?iFI4@JaO5A,^$9Ac66?BDQ<@C&MfDC]=@r_Yh7D_>n`XG5?F]Gl;p^HMMpVI//-]HM`!aGjoqS +Gl;pbHN/?lI/SKnIK4lsJH(0#K)UB'KSBD[22@!EM2I4MN/`gWO,oBbP*;,qQ'Rc(R$jD4S"-%@ +StD[LTq\U6fqu-HjrUTr=s53j,~> +JcC<$JcG3=o`"gfrquZjs8)ckrqQNf!;?EbHh?q$o()>?n*f]3m-O''l0.[:YO7\J0NrY43O8b18NU]j@Y5b[. +Yd(I=ZMq30Z2h60ZLjO\QfOP2Qi11g?2e1-?iFI4@JaO5A,^$9Ac66?BDQ<@C&MfDC]<&[OnY%2 +PPUFBFoHR\GPudbH1uX\Hgc@XHh;X]H2;dTGPcX`H2DpfHiJKlIK+`rJ,XuuJH1<$K)pXZre<:c +Ll$tGMijWN)u!XKAV-YPta,Z*OA8 +!OT96[K]"@sSs1JEHrP&EL_86,f!lMsprl+oW!6>)[s2b8`rlb>c!6tMgs3C\lrmCbo +!7Uqs#M%DVf@S[-g&B\1gYCT?h;7#Grnmk:io9st!T`AAk5XTEkl0iHl2^/Lm/QGQmf)\TnGi%X +o)J=]o_nI_pAambq#C0hqYU0gr;?Nardk+,s*t~> +JcC<$JcG3=o`"gfrquZjs8)ckrqQNf!;?EbG4bCto()>?n*f]3m-O''l0.1 +raG\5raYqB_r_rl?rc\-^rHS9dpNlX^msOqXoQpC[qKVLR +qfr'bqg/9hs*Xcns*artrdb$"!.t3&!JH1+L,FaBM2@+JN/WaUNfT6_OckomQ'IZ%R$a;1S"#q= +St;RITqS3UUnjiaVl-JmWiE,$Xf\b0ricF.ZMq02['fnA!k5\Lrj`'@]DfJC]`>eF^B23e_>_:Q +_o0Lm`W*pXa8X0[aT0K_bQ#cdc2Q#gcN)>kdJqVpe,Ii%e^i='f@\a/rn7V3gt^`AhVR/hhu_ls +ir7s=jQ6C's5sCGrosIJ!:0XNs6TgSrpTmVs7-*Zs7?9_rUp3as7cHds7uZjqtp?ir;H3cJcFX- +J,~> +JcC<$JcG6>oD\^erqu]ks8)ckrV-Hgp@eLY!VH!_no=3hn*f]3m-O'&l0.Z[C!9FYck11WiE"qV50l[TV%gGS!o_3QBd\tOcYW` +N/NRMLPCM9K7\W(IXQTjH?jaZG'%hIEcH&:rQsuordtim]?H?s4I>(rn7A,r7q>. +s5!n9i8ESQro3k9roF+@d_GUlpV$)ns6TgQr9XXTn*ol1s'be6raYq;LPUeDMMmFPNK0'\OHG]hPE_>tQC!u,R[]e: +SXuFFTV8'RUSO]^VPg>jWN)u!XKAV-YPta1Z*L^B['[7?[K3kIrj`*A]=\'T!kl=^rkJKK!5\ZO +s24lTrl"rYa2e2#s2b8`rlb>c!6tMgs3C\lrmCbo!7Uqs!nGlQrmq2'g&B_*gAp%.h$;fohr*GO +iSsjss5X1AroO:Fkii$1!p]+;rp0^RmdC)Cs7$'Yrpp*\s7H9_s7ZKerV6BfrqcNhrVZTlo)=4? +huA3~> +JcC<$JcG6>oD\^erqu]ks8)ckrV-Hgp@eLY!VH!_noF9in*f]3m-O'&l0.Z[C!9FYck11WiE"qV50l[TV%gGS!o_3QBd\tOcYW` +N/NRMLPCM9K7\W(IXQTjH?jaZG'%hIEcH&:R/WHEFmF/GFmjGGFoP#/8,c!V7JB4M6h[8QU]7(b +U$-aLGQ4<3T)5)QSG/NQR`^3UJH)8>T_P5YUA^kdV#."gVZ3RTO8P%7O8G%7O8Ft9NU]jFY5PL& +Xotr4Yd(J3ZhUj*RJ*$CQfFJ5QiC=i?2e1-?iFI5@JaO5A,^$8Ac?<@BDQ<@C&MfCC]A5Mg&R_=O_uI[S`<+'"a8X0[aT0K_bQ#cdc2Q#gcN)>kdJqVp +e,Ihue^i=Nf)aOWrn@D,!8RS0#N"@qi8ESQir8! +JcC<$JcG6>oD\^erqu]ks8)ckrV-Hgp@eLY!VH!_noaKln*f]3m-O'&l0.Z[C!9FYck11WiE"qV50l[TV%gGS!o_3QBd\tOcYW` +N/NRMLPCM9K7\W(IXQTjH?jaZG'%hIEcH&:<)cdphEC^!mlgA.s%)uVr^QiTpI,$K"Aqul:J^sd +p.tT_fgGmnWCLs'#,#s'5P/q-O&"bu=XIra#M0 +qd9>1s'be6raYqmo/dTpeq2mFo?L[GPudbH1cLGHh;X]H2;dM +GPudbH2N!gHiJKlIK+`rJ,XuuJH1<$K/nU=L5(J=Ll$tGMi_=O +_uI[S`<+'"a8X0[aT0K_bQ#cdc2Q#gcN)>kdJqVpe,Ihue^i=Nf)aOWrn@D,!8RS0#N"@qi8ESQ +ir8! +JcC<$JcG6>oD\^erqu]ks8)ckrV-Hgp@eLYG4bCso'u8>n*f]3m-O$%l0.Cn=06D!(m/\qFCNSrC-HK!(658qr62! +j.6V:i8EMLh;$c>g"HAW#1qGWe^W'rqpG5f!7CYFriZ:'ordqjpoaLro;qrFrnID,s5!_3rnm_5 +s5B`;`ECADZDC]J>Os4>-fFoHR[GPl^aH1Q@MHh2R\H2DjIGPudcH2N!f +HiJKmIK+`rJ,XuuJI-p\K7no3L5(J>reWgrMiU6fqu-HjrUTr=s53j,~> +JcC<$JcG6>oD\^erqu]ks8)ckrV-Hgp@eLYG4bCso'u8>n*f]3m-O$%l0.B`;`ECADZDC]J>O +g@UO%P4Fh8P5f\(G56@[Gl;pZHL?.OHM`!bGiX)IGlE!dHN&9kI/\QoIK4lsJH(0,JqJ]/KS>/8 +LPYqd5)P8WN/`jYO-#KePE_>tQC!u+R@9V7SXuFFTV8'RUSO]^VPg>jWN)u!XKAV-YHY79Z*L^B +['deG^]2+L_>_:Q_o0Lm`W*pXa8O'\ai_d*b6#o4c2Q#gcN)>kdJqVp +e,Ihue^i=Nf*Bs]g"P07gYDeas5!b5rnmk:io9st#NY".k2tjikl0iHl2^/KliQSBmf)\Tn,W"W +o)J=]o`"O_pAamcq#:*gqYU0gr;?Nardk+,s*t~> +JcC<$JcG6>oD\^erqu]ks8)ckrV-Hgp@eLYG4bCso'u8>n*f]3m-O$%l0.Ls$#!sq*"dMr^clUr^QiTpI#!Kr_`Ph!`;cj +pJ:fcj?rN*p-JUC!(6BFr_i>bpJUfc!)hoJkst>7pJUleqGd&bfM;9=nP8OLs',A(s',G,!+#M/ +rE]G0qc(sAs'>V1qd9>1raG_6raYqreWgrMiU6f +qu-HjrUTr=s53j,~> +JcC<$JcG6>o`"gfrVZTjs8)ckrqQNfs7ZKcs7?Hco()>?rpO^lm-O''l07Epk2k[aio/hQhVHu@ +g=Y$.e^W$pd*L"]bK@oI`l5m5_8!au]Xt_a[^NQLZ*:F6XK/A"Vl$8bU7n3NSXZ+:R$X)&PEM#g +NfB!TM26qAKnG#/J:E#rI!U*aGB\4PFE;GAao9H]SGA`UT(\`>SG/NHSGl+Z8GbpU7f>dN6ioa8 +ipYq,iqoA;T'DsFT)YAKT)[gMi&!;?#nemI'H4o()DDqt'm]rq-0^pWrc_r6=iW +r6,&]qT8]Ws'GS0ra>_6qdTP7rabn;rau.BqIokBrG).DrG;FL!cJ& +qfq"BrcnEfr-JBis*Xfos*artrd[IhJqAW-KS>,7L51SAM2I4MN/`jYO-#KeP*;,qQ'[l*R@9V7 +S=Q7DTV8'RUSO]^VPg>jWN)u!XKAV-YHY79ZEggC['fnA!OoT<\c95@]DfGE]tV5[^B23e_>_=O +_Z7XR`<+'"a8X0[aT0K^b6#o4c2Puicd:&aMrUL$]o^r+Ts7ZHdrV6BfrqcNhrVZTlo)=4? +huA3~> +JcC<$JcG6>o`"gfrVZTjs8)ckrqQNfs7ZKcs7?Hco()>?rpO[km-O''l07Epk2k[aio/hQhVHu@ +g=Y$.e^W$pd*L"]bK@oI`l5m5_8!au]Xt_a[^NQLZ*:F6XK/A"Vl$8bU7n3NSXZ+:R$X)&PEM#g +NfB!TM26qAKnG#/J:E#rI!U*aGB\4PFE;GArKuekhfSR7r^m)[qa^TSrC-KL!^iZTo:l5Z!2BId +ics@)piue3#G@]]TV%jJT(nlUSG/NPSEGIcK)1&qJGl2@UA^kdV#."fVYR.fVuWgHO8"b4O8k71 +;#X>lXTkr3YHY79Z1YF$Zh^$cR.?U.R/^Li?iFI4@JaO5A,^$9Ac?<@BDQ<@C&MfBC]/)JD$+\0 +g62,kpQG97!0mDFrK7/'rHA!\r-8-bf6[=>qfq"BrcnEfr-JBis*Xfos*artrd[IhJqAW-KS>,7 +L51SAM2I4MN/`jYO-#KeP*;,qQ'[l*R@9V7S=Q7DTV8'RUSO]^VPg>jWN)u!XKAV-YHY79ZEggC +['fnA!OoT<\c95@]DfGE]tV5[^B23e_>_=O_Z7XR`<+'"a8X0[aT0K^b6#o4c2Puicd:&aM +rUL$]o^r+Ts7ZHdrV6BfrqcNhrVZTlo)=4?huA3~> +JcC<$JcG6>o`"gfrVZTjs8)ckrqQNfs7ZKcs7?Hco()>?rpO[km-O''l07Epk2k[aio/hQhVHu@ +g=Y$.e^W$pd*L"]bK@oI`l5m5_8!au]Xt_a[^NQLZ*:F6XK/A"Vl$8bU7n3NSXZ+:R$X)&PEM#g +NfB!TM26qAKnG#/J:E#rI!U*aGB\4PFE;GArD`GQoKM.qp-/IIr^coVrC6`Spd>0N:f.-gs%rVj +s%rJdr^,U3r'Kd:nj<1NpJL]`!`MupqGZQHiCE]5peq#gq,Ho`e5#s/pJf[As'GS0ra>_6qdTP7rabn;rau.BqIokBrG).DrG;FL!cE=0mo/dTpJV'7rHA!\r-8-b +f6[=>qfq"BrcnEfr-JBis*Xfos*artrd[IhJqAW-KS>,7L51SAM2I4MN/`jYO-#KeP*;,qQ'[l* +R@9V7S=Q7DTV8'RUSO]^VPg>jWN)u!XKAV-YHY79ZEggC['fnA!OoT<\c95@]DfGE]tV5[^B23e +_>_=O_Z7XR`<+'"a8X0[aT0K^b6#o4c2Puicd:&aMrUL$]o^r+Ts7ZHdrV6BfrqcNhrVZTl +o)=4?huA3~> +JcC<$JcG6>o`"gfrquZjs8)ckrqQNf!;?EbH1^_"o()>?n*f]3m-O''l07Eok2k[aio/hQh;-l? +g=Y$.e^W$pd*L"]bK@oI`l5m5_8*h!]Xt_a[^NQLZEUO7XfJJ$Vl$8cU7n6OSXc1;R$X)'PEM&h +O,]*VM2@"BKnP)1J:N)sI=$9cG^"=RFE;JBaiV^'SG\rPT)5)ASH#)RSGA]U9)_E]8GbpU7fGjN +7/c-5irG_7T(elHT)G5ST)>,Z62omBiW%d=hVHuBg=lPZs4IA'"kM5ReC2nCdf$BLY3N4eYjnpp +Y5>@!XT.,UhZ)L4i;_d8iW/$;jSn9?k5XWEkQ'lHlMp1u^\bbE^\PV6;#X;tm-X60nF?)@oD/%S +p%6Q1cM5ZWbl#Z_b4s'YaS]EE@/aU3@fBm:AG]s;B)ZH>B`;`ECADZDD#J5KD?0_(_YqC?_>n`W +G5-:ZGl)dBHMVpbGk-(NG4p.ZGlE!eHN/?lI/\QoIK4lsJ-LRVJqJ]/L&QfgLPUeDMMmFPNK0'\ +OHG]iPa.N"Q^F/.S"#q=St;RITqS6WUnsrdVl6SpWiN5'Xfek3Yd(L>Za7$HrjDj:\Gj#>]"@sS +s1JEHrkJKK!5\WN!lMsprl+oW!6>&Z!m/U-rlb>c!6tJf!mf6?rm:eqe'n +JcC<$JcG6>o`"gfrquZjs8)ckrqQNf!;?EbG4bCto()>?n*f]3m-O''l07Eok2k[aio/hQh;-l? +g=Y$.e^W$pd*L"]bK@oI`l5m5_8*h!]Xt_a[^NQLZEUO7XfJJ$Vl$8cU7n6OSXc1;R$X)'PEM&h +O,]*VM2@"BKnP)1J:N)sI=$9cG^"=RFE;JBrg_6qdTP7rabn;rau.BqIokBrG).DrG;FL +r,)PhP4Xn2P4Fh8OoTY'G5-:ZGl)dBHMVpbGk-(NG4p.ZGlE!eHN/?lI/\QoIK4lsJ-LRVJqJ]/ +L&QfgLPUeDMMmFPNK0'\OHG]iPa.N"Q^F/.S"#q=St;RITqS6WUnsrdVl6SpWiN5'Xfek3Yd(L> +Za7$HrjDj:\Gj#>]"@sSs1JEHrkJKK!5\WN!lMsprl+oW!6>&Z!m/U-rlb>c!6tJf!mf6?rm:eq +e'n +JcC<$JcG6>o`"gfrquZjs8)ckrqQNf!;?EbG4bCto()>?n*f]3m-O''l07Eok2k[aio/hQh;-l? +g=Y$.e^W$pd*L"]bK@oI`l5m5_8*h!]Xt_a[^NQLZEUO7XfJJ$Vl$8cU7n6OSXc1;R$X)'PEM&h +O,]*VM2@"BKnP)1J:N)sI=$9cG^"=RFE;JBr`&VTlosr&r'(-DpceLPh\(?2n7->le8=oMjIAr*TG2raG\5raYq[K3kIrj`'@ +]DfJC]`>eG^]2(L_>V4P_o0Lm`W*pXa8O'\ai_d*bQ#cdc2Gohcd:&^ +JcC<$JcG6>o`"gfrqu]krqcZjrqQNf!;?EbGkCV!o()>?n*f]3m-O''l07Bnk2kX`io&bPh;-i> +g=Y$.eC;pod*L"]bK@oI`l5m5_8*h!]Xt_a\$iZMZEUO8XfJJ$Vl$;dU7n6OSt):=R$X,(P`h/j +O,f0WMM[.DL4k22JUi6!I=-?eH$=IUFEDSEaiX=JoUc#PoUPTDr1*eVoUYtRr^m,\qFCNSrC-KL +qr7/+rL`2CpRguInt#eHr8RkF%hu)C8iSrkWj8A!!^[]&0;#=)nmdKZ8o(2VJqXjj\pWr]]r6=iW +r6+u[qT8_Ds'Yh7qdTP7rabn;rau.BqIokBrG).DrG;FLq/664n\Y.?mD8jGrH@s[qfr!`id1HH +qfqaWmWSALrcnEfrHeKjs*Xfos*artrdY$#K)UB`KS>/8LPUeDMMmFPNK0'\OHG]hPE_>tQ^F/. +R[]e:St;RITqS3UUnjlcVl6SpWiN5'Xfek3Yd(M5ZO=.J[^NZS\@K/]]"@sS!kl=^rkANM_86,f +s2+iTrl+oWs2Y,[s2b8`rQ>8dc-?75s3L_lrm:eqe'n!9O4Bs5sCGrosIJ!:0UM!q#FDrpTmVs7-*Zs7?9_rUp3as7cHdrqZTjqYU6hrVc9c +JcFX-J,~> +JcC<$JcG6>o`"gfrqu]krqcZjrqQNf!;?EbGkCV!o()>?n*f]3m-O''l07Bnk2kX`io&bPh;-i> +g=Y$.eC;pod*L"]bK@oI`l5m5_8*h!]Xt_a\$iZMZEUO8XfJJ$Vl$;dU7n6OSt):=R$X,(P`h/j +O,f0WMM[.DL4k22JUi6!I=-?eH$=IUFEDSER$dYkqKDUUoQ9MDoQL4+r^m,\qFCNSrC-KLqkm$RcZs'Yh7qdTP7rabn;rau.BqIokBrG).DrG;FLq/65d!0[#;pQG97 +!0mDFrK7/'rH@s[qfr!`id1HHqfqaWmWSALrcnEfrHeKjs*Xfos*artrdY$#K)UB`KS>/8LPUeD +MMmFPNK0'\OHG]hPE_>tQ^F/.R[]e:St;RITqS3UUnjlcVl6SpWiN5'Xfek3Yd(M5ZO=.J[^NZS +\@K/]]"@sS!kl=^rkANM_86,fs2+iTrl+oWs2Y,[s2b8`rQ>8dc-?75s3L_lrm:eqe'n!9O4Bs5sCGrosIJ!:0UM!q#FDrpTmVs7-*Zs7?9_ +rUp3as7cHdrqZTjqYU6hrVc9cJcFX-J,~> +JcC<$JcG6>o`"gfrqu]krqcZjrqQNf!;?EbGkCV!o()>?n*f]3m-O''l07Bnk2kX`io&bPh;-i> +g=Y$.eC;pod*L"]bK@oI`l5m5_8*h!]Xt_a\$iZMZEUO8XfJJ$Vl$;dU7n6OSt):=R$X,(P`h/j +O,f0WMM[.DL4k22JUi6!I=-?eH$=IUFEDSE<)iWUjZ`2tr''a;r_!/]s%)uVr^QiTpdG*Wr_W;c +s%r_k!Dl&Z62O">6g[5<61@8?6N9@.;TM?'8,c!P;u]hs;u0Ja;o)6#;#=,d>l@q.>k_P(?M@FL +;uU/(@/aU3@fBm:AG]s;B)ZH>B`;`ECADZDD#J5HDZ>"N;t;Ll$tGMi +StD[LTq\_=O_Z7XS +`W*sXa8X0[aT0K^b6#o4c2Q#gci;Akd/qbFe,IkseH"2"fDjJ'g&B_*gAp%.h>c=3hu;R6i;hm: +j8\0?jo4EBk5a`Fl2U#Kli$/OmI'EAn,MnWnc&+ZoDeI]p&Facp\agcq>^ +JcC<$JcG9?oD\^erqu]ks8)ckrV-Hgp@eLY!VH!_no4-gn*f]3m-O''l0. +g"=p-eC;pod*Bq\bK@oI`l5m5_8*h!]Xt_a\$iZMZEUO8XfJJ$Vl-AeUS4?QSt):=R$a2)P`h2k +O,f0XMM[.EL4t84JUi9"I=-BfH$FOVF`_^(anhP*Sb\lRSar_6r*oY8rabn;rau.BqIokBrG)1Er+u=KpMU"L!<;Z-pVZF9!-S3_pNQO[q0D4N +q0Dj^oQU"PrH7jXqKMp`s*=Qhs*OcnrdFfq!.Xuu!J,k%K/nU=L5(J>M2@+JN/WaVO,oBbP*2&p +Q'Rc(R$jG5S=Q7CT:qsQUSO]^VPgAlWiE,$Xf\b0YctCSe]Y2"mrkJKK +!5\ZOs24lTrl"rYa2e2#s2k;`rlb>cs3:Pgs3C\lrQt\pe'n +JcC<$JcG9?oD\^erqu]ks8)ckrV-Hgp@eLY!VH!_no4-gn*f]3m-O''l0. +g"=p-eC;pod*Bq\bK@oI`l5m5_8*h!]Xt_a\$iZMZEUO8XfJJ$Vl-AeUS4?QSt):=R$a2)P`h2k +O,f0XMM[.EL4t84JUi9"I=-BfH$FOVF`_^(R/1t"G5$.MFR4/HG5Ou38cD9X8,c!V7JT@IU&:Yb +U&(MSGjp"YGkH@FGl9r+U\gb`TE(V[T)"rWSA0XTJG,i;V?!OiW;[Wo +ZMV!.Z2h0*RIlm@Qg0t;@/aU4@fBm:AG]s;B)ZH>B`;`ECAM`DD#J5FDZ=VUg62)jpQG*2rK7/' +r-%gYr-8$_l$E/NqfqaWp3-CWpNHCWrcnHgrHeKjs*Xfos*artrdY$#K)UB_KS>/8LPUeDMMmFP +NK0'\OHG]hPa.N"Q^F/.S"#q=St;RJTq\as31Mfrm(Pi!7:\l!n,QHrmV#"f%0iPs4@>) +rn@D,!8RS0s5!b5ro!h8!93t;!p&J)roO:Fkii$1!p]+;rp9[Ps6fmTs6p$YrUU![s7H9_s7ZKe +r:phuA3~> +JcC<$JcG9?oD\^erqu]ks8)ckrV-Hgp@eLY!VH!_no4-gn*f]3m-O''l0. +g"=p-eC;pod*Bq\bK@oI`l5m5_8*h!]Xt_a\$iZMZEUO8XfJJ$Vl-AeUS4?QSt):=R$a2)P`h2k +O,f0XMM[.EL4t84JUi9"I=-BfH$FOVF`_^(<;Jc754Lf655IMA9)_E]8GbpV7f>dO7/9[Q;>sDd +62X(>6g-l,6iB=.;Y3H07J0+M;u9Ji;uK\`;o2<#;#4#h?2.[u?2n7,<7=eF@/aU4@fBm:AG]s; +B)ZH>B`;`ECAM`DD#J5FDZ=VTH1"W%;YX/jFo6FWGPl^]H0KYNH2DjYGP64YFn^(UGQ)jeH2W'h +HiJKmIK+`rJ,Xs!JV*lR3J<*@L51SAM2I4MN/`jYO-#KeP*D5sQC!u+R@B\9SXuFFTqS3UUnjia +Vl6SpWiN5'Xfek3Yd(M5ZOjLO[^NZT\@K/]]=Y_g]tM/Z^]2(L_>_=O_uI[S`<+'"a8X0[aoBN_ +bQ#fdc2Q#gcN)>jd/qbFe,Ihue^i=NfDjJ'g&B_*gAp%.h>c=3hu;R6i;hm9ir\<'jo4BDkNM./ +klU/9li-8NmJlVRn,MkWnbr%YoDeI]p&Facp\agdq>U6equ-HkrUKl +JcC<$JcG9?o`"gfrVZTjs8)ckrV-Hgp@eLYGP(Lto'u8>n*f]3m-O'&l0. +g"=p-eC;pod*Bq\bK@oI`l5m5_8*h!]Xt_b\$iZMZEUR9XfSP%W2HJfUS4BRSt2@?R@'>+P`q8m +O,o9ZMi*@HL5(A6Jq8H%I=6KhH?j^YG'%iJanqV&Sc55WSa2gDS+)sJ9DhE]8cM?X8,c!V7J]CR +hr*GliVhd9j87j8j7f2@T&H=/T)YA[62TaBj8\-C%i;V^8ir.s7k5OQDkl9oHlhp,Km/Y$$_>(h&^\#84;#4&h;ZH7go(2JJo_nI_o`"I[ +chPccchu&gc1&sRbPTH]ao5`G@fBm;AG]s;B)ZH>B`;`ECAM`ED#A/EDZ"DRE<#RIpVZgDrknQK +!-S3_p36@XpNc@VpNcX\olp4TnoaePqfi$as*=Qhs*Ocnrd>0'It*!!JUrE*K7nsXL,=[AM2@+J +N/WaWO-#KeP*;,qQ'[l*R@9V8SXuFFTV8*TUnjiaVl-JmWiN5'Xfek3Yd(M5ZN[_D[^NZTrj`'@ +]DfGE]tV5[^B23e_>_:Q_o0Lm`W*pXa8O*ZaT0K^b6#o4c2Q#gci;AkdJqVpe,@bte^i=NfDjJ' +g&B_*gAp%-h#cHjhu;O8iSrkrir\<'jo4EBk5a`Fl2U&Kli-5PmI'EAn,MnWnbr"[oCV\Rp&=[b +p\agdq>U6equ-HkrUTr=s5*d+~> +JcC<$JcG9?o`"gfrVZTjs8)ckrV-Hgp@eLYGP(Lto'u8>n*f]3m-O'&l0. +g"=p-eC;pod*Bq\bK@oI`l5m5_8*h!]Xt_b\$iZMZEUR9XfSP%W2HJfUS4BRSt2@?R@'>+P`q8m +O,o9ZMi*@HL5(A6Jq8H%I=6KhH?j^YG'%hnR/;$uG5$.KFQmrJ9DhE]8cM?X8,c!V7J]FHU&Uka +U&Le]GkZLYHKoeCGlN!d5ldb[U]@1fUA^ecT_Y5UT"KUSJG5o:Vu!@fWW&mtOSFn/NnKKc;#4&h +;Z!a!ZMq01ZMq05ZEpmCZMq-,RI-C@Qfjb8@JaO5A,g*:Ac?<@BDQ<@C&MfCC]/)ID>.rGDZXn3 +P4at3P51=@Pl-aEOoTY&G4p.VGkZLTHM;^^GkH:VG4KePG5HL_GlN'fHN/?lI/\O%IXcitJ:W9' +K7ei2re<7bLl$tGMijWN*##Xf\b0YctC< +rj)d8[C3NQ\Gj#>]"@sS!kl=^rkANM_86,f!lMsprl+oW!6>&Zs2b8`rQ>8dc-?75s3L_lrmCbo +!7Unr!nGlQrn%2&!87A*s4[P/rS7P3hr"Fk!o`.uro4(@jlQL(s5sCGrosIJs6K[N!q#FDrpTmV +s7-'Y!qZ'VrUp0`s7cHds7uZjqYU6hrVc +JcC<$JcG9?o`"gfrVZTjs8)ckrV-Hgp@eLYGP(Lto'u8>n*f]3m-O'&l0. +g"=p-eC;pod*Bq\bK@oI`l5m5_8*h!]Xt_b\$iZMZEUR9XfSP%W2HJfUS4BRSt2@?R@'>+P`q8m +O,o9ZMi*@HL5(A6Jq8H%I=6KhH?j^YG'%h*<;Si155@A556":R9)_E^8GYjU7f>dP6i^*Z;"dcW +62a+M6hWqG6g-l26iTLO62a^_<)`!Ys&8qdo1%h1njN1?qbm;i!*&8_!)LL-oMGB]s&/Srp0I]) +r)EGi!*%ZNraG\5raYt=qdob=rb)(@rb;=GqJ6%Gr,)1Gr,2UTHLFf);YF#hFo6FVGPZRYH1Q@V +H2DjZGPQFQFo$:YGQ)jeH2W'hHiJKmI1(LRIt3'#JV&N,KSBD[1l$mDM2I4MN/`mZOHG]hPE_>t +Q^F/.R[]h)rn@D,!8RP/!oDhl +rnmk:io9st!p&J)roX7D!9jFHs6BXMrp0^RmdC)Cs7$'YrUL$]o^r+Trq?Bdr:p +JcC<$JcG9?o`"gfrquZjs8)ckrqQNfs7ZKcs7CI*o()>?nF,i6mHj3)l07Epk2k[aj5JqShVHuA +g=b-1f$r3tdEp1abfe/MaMu3;_SO%&]tCtf\[T#TZa-j?Y-"e*Wi2hmUnaZXT:VUDS!fY1QBdYs +OcYWaN/WXNLkg_=K7e`*IsufnH[9s^GBS,Nao%\#SH,2XS`H=8SbnrW9`Ic`9)_E^8GYjU7f>dQ +6ic-AhuMa/iW/$3T)bJ1TD"lS63$!?jT"9?iWA)si;VU6hYu@2h#H./gAfh(Yhu__Yl(]pY5PI& +XT%8YjT"?>k5FKCkQL/8lKdd5m/HDP_Xt\>^u`?(^@b>";>a;lo)A7Zo_nF_o`"Leo^h\FoCDn, +m`tgVo?@!Q!6Y5]qdTP7rabn;rau.Bqe5tCrG)1ErG;CKphotIr,D8EpVZsHqnr3G!-S3_p36=W +jE^THolp7Ului5Lqfi'brd"Hg!dfrecMu2jd/DAldK%bpe,n1Of)F;$fDsV'g&g$ah#?+2hV[5i +i;_a9ir8! +JcC<$JcG9?o`"gfrquZjs8)ckrqQNfs7ZKcs7CI*o()>?nF,i6mHj3)l07Epk2k[aj5JqShVHuA +g=b-1f$r3tdEp1abfe/MaMu3;_SO%&]tCtf\[T#TZa-j?Y-"e*Wi2hmUnaZXT:VUDS!fY1QBdYs +OcYWaN/WXNLkg_=K7e`*IsufnH[9s^GBS+rR/D*uG4]qLFRjSQG5HF^9`Ic`9)_E^8GYjU7f>dQ +7.$ZLU3LqVH16.?H1cF[62[SXV#R1iUALY\T`:Y]T(moUJc;MCVYm@eW;3CqWiN1^OS=h&NoH,m +;#=,f;Z*d$ZEpn9Zim_@ZEpk7Z2U0:R/:@lA,^$9Ac?<@BDZBAC&MfCC]/)ID>8#GDu=PSP4Xn2 +P5UUAPl-aDOoTY&G4p.UGiX/HGkH:WG3jALG5HL`GlE!eH3/G@I/\OeIXcitJ:W9'K7ei2L5(J> +M2@+JN/WaVO,oBbP*2&pQ'Rc(R@9V7S=Q7DTV8'RUSO``Vl-JmWiE,%Xfek3Yd(L?Za@*I[^NZT +rj`'@]DfGD]tXK\s1eWNrke]Q!6"lUs2P)ZrlG,]s2t>as31Mfrm(Pi!7:\ls3^nrrR:o!f%0iP +s4@>)rRq>-gt_nb!oDhlro!h8!94" +JcC<$JcG9?o`"gfrquZjs8)ckrqQNfs7ZKcs7CI*o()>?nF,i6mHj3)l07Epk2k[aj5JqShVHuA +g=b-1f$r3tdEp1abfe/MaMu3;_SO%&]tCtf\[T#TZa-j?Y-"e*Wi2hmUnaZXT:VUDS!fY1QBdYs +OcYWaN/WXNLkg_=K7e`*IsufnH[9s^GBS+.<;\oA55[Y155d_C56"=V9DhE]8cM?X8,c!V7JfLP +;>a>f>lS+0 +?MRk-?=3\2c;XULraYq;Ll$tGMijWN)u!Xf\b0YctC]"@sS!PQ5H^]2(L_>_=O_Z7XS +`W*sXa8X0[aoBN_bQ#fdc2Q#gcN)>jdJqVpe,@bte^i=NfDjJ'g&9V+gYCT`h#cHjhu;R6i;hm: +j8\0?jo+U6fqu-HjrUTr=s5*d+~> +JcC<$JcG<@oD\^erqu]krqcZjrqQNf!;?Ebs7?Hco()>?rpO^lmHj0(l07Epk2k[aj5JqShVHuA +g=b-1f$r3tdEp1abfe/MaMu3;_SO%&^:_(h\[T#TZa6p@YH=n,Wi2hmUnj`YTUqaFS!o_3QBd\t +P)t`bNJrdPM2-h>KS+l-J:DuqI!U*aGB\5PanqV%S_BV+SH>dR7/l*> +i;_d4ipr`@T')aDT^n`PT)YG[62BR?jSe-Z40g\J)4Z2:d'YOSdqXoCcjjQ5M% +k54??kl'fGlN$;ImHVO`_!Ac0^@kD";>a>l;ucIgo_nI^oDnR`o`"C^naPbfrQY)\qTJcYs2k7L +raYq;Ll$tGMi)rRq>-gt_nbs5!b5ro!h8s5O%< +!p&J)roX7D!9jCG!p]+;rp9[P!:KgSs6p$YrUU![s7H9_s7ZHdrV6BfrqcNhrVZTlo)=4?hZ&*~> +JcC<$JcG<@oD\^erqu]krqcZjrqQNf!;?Ebs7?Hco()>?rpO^lmHj0(l07Epk2k[aj5JqShVHuA +g=b-1f$r3tdEp1abfe/MaMu3;_SO%&^:_(h\[T#TZa6p@YH=n,Wi2hmUnj`YTUqaFS!o_3QBd\t +P)t`bNJrdPM2-h>KS+l-J:DuqI!U*aGB\4tR/;%"G4B_LFRsYJFole[9`@]_9)hK^8GYjU7f>dR +7.HuLU@3BuHK0;GGl'f#V>d7gU&gs^qkM2@+JN/WaVO,oEdP*;,qQ'[l*R@9V8SXuFFTV8*TUnjibVl6SpWiN5'Xfen4Z*OA8 +&%&aQ[^WcW\[oAa]Y(qk^AbkK^qmkd_?.Wn`;[^W`lH-ua9'K+b5KKbbg"E2c2u>=d/D>ndaQ\E +eGn)!f)F;$fDsV'g&g$ah#?.0h>lI4i;_d9ir7s>jQ5M&k5XTEkl'`IlKdd8m/QGQmeuVSn,W"W +o)J=]o_nI_pAXgbq#:*gqYU0gr;?Nardk++s*t~> +JcC<$JcG<@oD\^erqu]krqcZjrqQNf!;?Ebs7?Hco()>?rpO^lmHj0(l07Epk2k[aj5JqShVHuA +g=b-1f$r3tdEp1abfe/MaMu3;_SO%&^:_(h\[T#TZa6p@YH=n,Wi2hmUnj`YTUqaFS!o_3QBd\t +P)t`bNJrdPM2-h>KS+l-J:DuqI!U*aGB\41<;SiC557A@55[Y?54q,A5"nZL9DhE^8cD9W8,c!V +7JoRO;>roQ62X(L6iKFB6fgZ362":I;uT\p;sm-:7I`eC7K5dT<;KPm<:*WD:A7KK:A.N\ +;>a>l;uBnm?2n43?W>6JraPk:rabn;rau.Bqe5tCrbD7ErG;FLpMTnIqJcIS!.+*4qbll]!-S0^ +olp1UlZr;Nolp7Up3$:TpiZOYqfi$as*=Qh!dftQ^F/.R[]h.8ZMq0@['d?N\%&uZ]"5Md]Y2"m +rkANM_86,f!lMsprl"rYa2e/"!m/U-rQ>8dc-?44!mf6?rQt\pe'n)!o)Mc +rn[V2!8me6s5F";ro4(@jlQL(s5sCGrTOCKlg+Q:s6TgSrU9dU!:g$Ys7?9_rUp3arqHBdrqZQi +qtp?ir;H3cJcFU,J,~> +JcC<$JcG<@oD\^erqu]ks8)ckrV6Ee!;?EbGP(Luo()>?n*f]3m-O''l07Epk2k[aio/hQhVHuA +g=b*0f$r0sdEp1abfe/MaMu3;_SX+'^:_(h\[T#TZa6p@YH=q-Wi;nnV50l[TV%gHS!ob4Q^*i" +P*(fdNJrdQM26n@KnG#/J:N)sI!^0bG^"ARSbS`PS`cLCSb/HDSc;Fa9`@]_9)hK^8GbpU7f>dS +7/YpCi8=IjrSd_7q4@Y[pn.PWl_!pEo:PuQq*FW4qVqP6ro!e5"5_k3sYj/LkYj\doY5^oh +k5"3>kl0iFli$2LmJZAQmD6X;_!&T7_!8]1^@tJ$;>a>j;uZFfp%n:boCDG@n*]W-c2c2icMl)a +bkoTZb5PoMAG]s;B)ZH?B`;`FCAM`ED#J5FDYnALE;+AG_X58:_Z+cUG4^"PGk?:TGkH:WG56:P +FSg4ZG5HL`GlN'fH3/G@I/\NuIXcitJ:W=OK2.)RL5(J>M2@+JN/WaVO-#KeP*;,qQC!u+R[]e: +SXuIHTqS3VUnsrdVl6VqX/rG*Y-5(6Z*L^B['d?N\%&uZ]"5Md]Y2%n^V@S"_>_=O_Z7XS`W*sX +a8X0[aT0K^bQ#cdc2Grfci;AkdJqYpe,Iksec45"fDjJ'g&9V+gYCT`h>c=3hu2I7iSrkrj8\0? +jo4EBkPscFl2U#Kli$/OmI'E@mfN"Knbr%YoDeI]p&Facp\agcq>U6fqu-HjrUTr=s5*d+~> +JcC<$JcG<@oD\^erqu]ks8)ckrV6Ee!;?EbG4bCto()>?n*f]3m-O''l07Epk2k[aio/hQhVHuA +g=b*0f$r0sdEp1abfe/MaMu3;_SX+'^:_(h\[T#TZa6p@YH=q-Wi;nnV50l[TV%gHS!ob4Q^*i" +P*(fdNJrdQM26n@KnG#/J:N)sI!^0bG^"A!pN?@VmWJAJo6'YJs%WMer_*/]s%32\qa^TSrC-ZQ +pS%>Uq0D(Jja$]Iq*FYLrhK+[!MQ1XKBRpWJb4QoJcA.;Vtm:_WVNRiOSb*uNpi&';#=,f;Z0Po +ZNRS?Za@+rf[;(qf_UUp3?4Tp3?7SqKD[Wo5skPrHA'^s*4QhrH\NlI!kpA#(D&OJ:N3&re!t!Knb>; +Ll$tGMi)!o)Mcrn[V2!8mb5!o`.uro=%>!9O4Bs6'FGrosIJ!:0UM!q#FDrU0gWnaZSKs7?9_rUp3a +s7cHdrqZQiqtp?ir;H3cJcFU,J,~> +JcC<$JcG<@oD\^erqu]ks8)ckrV6Ee!;?EbG4bCto()>?n*f]3m-O''l07Epk2k[aio/hQhVHuA +g=b*0f$r0sdEp1abfe/MaMu3;_SX+'^:_(h\[T#TZa6p@YH=q-Wi;nnV50l[TV%gHS!ob4Q^*i" +P*(fdNJrdQM26n@KnG#/J:N)sI!^0bG^"@3pH@q.oKN=@pcn^@o0<7Ls%NDbr(?u\r^coVrC6`S +rC$N[qb[/es&/h`rB^KMhEps(mm?h9oMk9XlUKu)nO3=Es$ZW\s&A;_qb?9LqG$u`peC?TpJC`a +r)3Jls'5V0p0IZ("'o5=?2R[h;ZKeY;uU;+AG]s;B)ZH?B`;`FCAM`ED#J5FDYnALE;+AB;u]b^ +;u_";G4^"PGk?:TGkH:WG56:PFSg4ZG5HL`GlN'fH3/G@I/\NuIXcitJ:W=OK2.)RL5(J>M2@+J +N/WaVO-#KeP*;,qQC!u+R[]e:SXuIHTqS3VUnsrdVl6VqX/rG*Y-5(6Z*L^B['d?N\%&uZ]"5Md +]Y2%n^V@S"_>_=O_Z7XS`W*sXa8X0[aT0K^bQ#cdc2Grfci;AkdJqYpe,Iksec45"fDjJ'g&9V+ +gYCT`h>c=3hu2I7iSrkrj8\0?jo4EBkPscFl2U#Kli$/OmI'E@mfN"Knbr%YoDeI]p&Facp\agc +q>U6fqu-HjrUTr=s5*d+~> +JcC<$JcG<@o`"gfrVZTjs8)ckrV-Hgp@eLY!VH!_no4-gn*f]3m-O''l07Eok2k[aio/hQhVHuA +g=b*0e^W'rdEp1abfe/MaMu3;_SX+'^:_+i\[])U['R$AYHG".Wi;noV50l[Tq@pIS"#h5Q^3o$ +P*1ofNfB!UM2@"BKnP)1JUi6!I=-BfH$II0SbJWSS`ZI?Sb\fHSc):_9`@]`9)_E]8GbpU7f>dT +7/5[>i;)@1T)bP\TC\ZETCJTITDtMY60mP2ir%d8huM[5Yj\dgYkG@"YjS^n7/l?Gk5a`Fl2U&K +lhg&Klhg#Kli+`s_"tnE_YM%E_!f&7^A1V&;>a>g;ucLip&4LkoCV\Ho'u2f] +bP]N^AG]s;B)ZH?B`;`FCAM`ED#J5GDYnALE:IrHErcs3:Pgs3L_lrQt\pe'n9Fs4%,#rR_)%!87>)!o)Mcrn[V2s53h6!o`.uro=%>s5j7Bs5sCG +rosIJs6K[Ns6]jSrpTmVs7-'Ys766_r:U*`s7cHdrqZQiqtp?ir;H3cJcFU,J,~> +JcC<$JcG<@o`"gfrVZTjs8)ckrV-Hgp@eLY!VH!_no4-gn*f]3m-O''l07Eok2k[aio/hQhVHuA +g=b*0e^W'rdEp1abfe/MaMu3;_SX+'^:_+i\[])U['R$AYHG".Wi;noV50l[Tq@pIS"#h5Q^3o$ +P*1ofNfB!UM2@"BKnP)1JUi6!I=-BfH$G_JFT?UNFo6@RFn0_S:&dod9DqK^8cD9X8,YpU7K,^C +UA]B!HLlC^GjBYSGkjYtV>d:fU\LSWK]n'HK)J+:Vu!@_WW0!rWW/+WORnP!Npi&);#=,f;Yj>f +ZN.8#GDu4MDEW'qUOo1C?PP17=PQ$^F +Fo-@QGN=#?GPcR[FmX;KFo?L]GQ2pfH2W$jH[L5?I0"eHrd[[nJqJ]/KnY89LPUeDMN!LRNfT6_ +OckomQ'IZ&R$jD4S=Q7CT:qsQUSO]_Vl-JmWiN5'Xfek3Yd(L?Za@-K[^WcW\[oDb]Y(qlrkANM +_86,f!lMsprl"rYa2e2#s2k;`rlb>cs3:Pgs3L_lrQt\pe'n9Fs4%,#rR_)%!87>)!o)Mcrn[V2 +s53h6!o`.uro=%>s5j7Bs5sCGrosIJs6K[Ns6]jSrpTmVs7-'Ys766_r:U*`s7cHdrqZQiqtp?i +r;H3cJcFU,J,~> +JcC<$JcG<@o`"gfrVZTjs8)ckrV-Hgp@eLY!VH!_no4-gn*f]3m-O''l07Eok2k[aio/hQhVHuA +g=b*0e^W'rdEp1abfe/MaMu3;_SX+'^:_+i\[])U['R$AYHG".Wi;noV50l[Tq@pIS"#h5Q^3o$ +P*1ofNfB!UM2@"BKnP)1JUi6!I=-BfH$E<[4nCkh5Q+=V9`@]`9)_E]8GbpU7f>dT7/9^[;#=,h +;Z/o^6e=Zu6h`:%1pS:%h9U:&Ic^;#=,f;Yj>j +?2n1+>l\4-?2@OL;uU>)Ac?<@BDZBAC&VlDC]/)JD>8#GDu4MDEW'q8;ZLt;G4KkM2@+KN/`jYO-#KePE_>tQC+&-R[]h< +St;RJTq\as31Mfrm(Pis3U_l!n,QHrRCkt!7q,#s4@>)rRq>-gt_nbs5*e5rnmk:io9sts5a4A +roX7D!9jFHs6BXMrp9[Ps6fmTs7$'YrUU![!;-3^s7ZKer:p9erqcNhrVZTlo)=4?hZ&*~> +JcC<$JcG<@o`"gfrVZTjs8)ckrV-Hgp@eLY!VH!_no4-gn*f]3m-O''l07Eok2k[aio/hQhVHuA +g=b*0f$r3tdEp1abfe/NaMu3;_ns4(^:_+i\[])V['R'BYcb+0Wi;qpVPKu]TqJ!KS=>t7R$O#% +PEM&hO,]*VMM[.DL4t84JUi9"I=6HgH?dR0Sb\fSSa)a>Sc5/LSc;I`:&doe9DhE]8cM?X8,c!V +7K,^JhuDU7iVqa8iUic4T(&BBT_P/S63$!EjS@j9j8e6:j8e6h=I_=PMD_>:t9^\bbA;#F2f;Ya8ko`"O`o`"Feo'l,:mdBK/rp'R1 +im.MIr64lX!QnsNAc?<@BDZBAC&VlDC]/)JD>8#HDu4MDEV=GPF7$m@_Z+cTG4BeAGk-(UG5?@H +FT$@\G5QRaGlN'fH3/G@I/\NpIXh?I7Y-/DK7nr5L51SAM2I4MN/`jYO-,TgPE_>uQ^F/.S"#q= +StD[LTqeEZV5C/hWN)u!XKAY/YctC)[ +s2k;`rlb>cs3:Mf!mf6?rR(Yns3ptss4./#rn%2&s4RD*s4dS/rn[V2!8mb5!o`.uro=%>s5j7B +s5sCGrTOCKlg+N9!q#FDrU0gWnaZSKs7?9_rUp3arqH?cs7uZjqYU6hr;H3cJcFU,J,~> +JcC<$JcG<@o`"gfrVZTjs8)ckrV-Hgp@eLY!VH!_no4-gn*f]3m-O''l07Eok2k[aio/hQhVHuA +g=b*0f$r3tdEp1abfe/NaMu3;_ns4(^:_+i\[])V['R'BYcb+0Wi;qpVPKu]TqJ!KS=>t7R$O#% +PEM&hO,]*VMM[.DL4t84JUi9"I=6HgH?bkMFo?LMFoQR\Fo?L_Fn'YT:Amoe9`Ic`9)_E^8GYjU +7f>dT7.-fFH0]eEH2i-gH16(R63!e\VY?neV#7(hV"peXK[,5JK)J+:Vu3LfWW&grWW&jmWW&%V +OR/&!Npr,+;#F2f;Ya8iZO!qEZa$d>Z*:J1Y62#4Y*n[Ep6Y-5!+c"=rau.Bqe5tCrbD:FrG;FL +php"Jqf)(Fp2^.Rr0$uApQYT>rf[;(qKDCQl?MlDqf_gYl?)uIrHA*_s*4QhrH\NlI!kpA!IfOt +J4>*AK7ei2L5(J>M2@+JN/WaVO,oEdP*;,qQC!u+R@B\9SXuIHTqS6WUnsrdW2ZesX/rG+YHY79 +ZEpmE[C3NQ\@K/]]DfGD]tXK\!PlPN_Z.LR`;[aU`W4'YaT'B^b5TTabl>rdc2u>=d/DAldf7eq +eGn)!f)F;$f`0Y(gAfq-h#?.0h>lI3hu_lsir8! +JcC<$JcG<@o`"gfrVZTjs8)ckrV-Hgp@eLY!VH!_no4-gn*f]3m-O''l07Eok2k[aio/hQhVHuA +g=b*0f$r3tdEp1abfe/NaMu3;_ns4(^:_+i\[])V['R'BYcb+0Wi;qpVPKu]TqJ!KS=>t7R$O#% +PEM&hO,]*VMM[.DL4t84JUi9"I=6HgH?`H^4nLqh5Q=LW:&doe9DhE]8cM?X8,c!V7K,^H;>a;l +6-hms6h!G;62XaZ<;fbd<4k^!7/Bj]<;BJh;Yj>X:%qEZ:%(dQ:&7]a;>X8e;tOAp>l7n$<7b%K +AGg$uQ^F/.S"#q=StD[LTqeEZV5C/h +WN)u!XKAY/YctC)[s2k;`rlb>cs3:Mf +!mf6?rR(Yns3ptss4./#rn%2&s4RD*s4dS/rn[V2!8mb5!o`.uro=%>s5j7Bs5sCGrTOCKlg+N9 +!q#FDrU0gWnaZSKs7?9_rUp3arqH?cs7uZjqYU6hr;H3cJcFU,J,~> +JcC<$JcG<@o`"gfrquZjs8)ckrV-Hgp@eLY!VH!_no+'fn*f]3m-O''l07Bnk2k[aio/hQhVHuA +g=b*0f$r3tdEp4bbfe/NaN)9<_ns7)^:h1k\[],W['R'CYcb+0X/`+rVPU)`TqJ$LSXZ+:R$X)' +PEM&iO,f3YMi!:GL4t;5Jq8H%IXQTjH?o@Xr1*PQn!rF/!`)Qdr([2bs%E8^r^m,\qa^TSrC-`S +s5*A)s5UnXfHHm%F9KpH\f>qW.Y9qrI\:rT*trpC!Xm-Es&lg!ER +rQY8ap<3DGs(;7Cqe5tCrbD:FrG;IMphp"Jqf)+Gp2]hIs)dhLqSN8Tq0)1Mnp'YJqf_gYkB-ZF +rc\3`s*4QhrH_:eI!g?jIXZcsJ:W9'K7ei2L5(J>M2@+JN/WaWO-#KeP*;/rQC!u,R[]e;St;RJ +Tq\8dc-?44s3L_lrmCbos3pqrs4./#rn%2&s4RD*s4dS/rn[V2s53h6s5 +JcC<$JcG<@o`"gfrquZjs8)ckrV-Hgp@eLY!VH!_no+'fn*f]3m-O''l07Bnk2k[aio/hQhVHuA +g=b*0f$r3tdEp4bbfe/NaN)9<_ns7)^:h1k\[],W['R'CYcb+0X/`+rVPU)`TqJ$LSXZ+:R$X)' +PEM&iO,f3YMi!:GL4t;5Jq8H%IXQTjH?o1+pibnEqKDm_nob(1:/:^]s%NGcr(?r[s%*#WrC6`S +s$Zm\nY4oems4>GpH\eUqPO+cqPO4frM/n9c\)4Kqa:L`W2TKjoVhbgri#gZs,m2?hN.\uo8icF +r)*AipJ_)krNlO0!3uO-q6'h%Xo4[VR.Qa6R/LUrB)ZH?B`;`FCAM`ED#S;HDZ"GME:S#BEqOMR +FT%EsPl-aFP5f\#G4'SFGjoqSG5?@EFT$@]G5QRaGlN'fH;Js9I!pElIXcluJUrE*K7nr5L51SA +M2I4MN/`mZOHG]hPEhE!Q^F20S"#t?StD^MU8+N\VPg>jWiE,$Xf\b1Yd(L?Za@-K[^WcW\[oEP +]E,^[rkAKL_>_:Q_o0Lm`<+'"a8X0[aT0K^b6#o4c2Grfci;AkdJqYpe,@erec45"fDjM'g&B_* +g]-(.h>c@3hu;R6i;hm9j8\0?jo+U6equ-HjrUTr=s5*d+~> +JcC<$JcG<@o`"gfrquZjs8)ckrV-Hgp@eLY!VH!_no+'fn*f]3m-O''l07Bnk2k[aio/hQhVHuA +g=b*0f$r3tdEp4bbfe/NaN)9<_ns7)^:h1k\[],W['R'CYcb+0X/`+rVPU)`TqJ$LSXZ+:R$X)' +PEM&iO,f3YMi!:GL4t;5Jq8H%IXQTjH?o0HqEFpDrBAar!`)Qdr([2bs%E8^r^m,\qa^TSrC-`S +nPTB[qb[2fr)38fs&A_u +r*05-ra#S1o2OFBrFQ"@rb)+Arb;@HqJ6%Grb_FJr,;IOno=ADolL.TlVmh+q0)1Mnp'YJqf_gY +kB-ZFrc\3`s*4QhrH_:eI!g?jIXZcsJ:W9'K7ei2L5(J>M2@+JN/WaWO-#KeP*;/rQC!u,R[]e; +St;RJTq\8dc-?44s3L_lrmCbos3pqrs4./#rn%2&s4RD*s4dS/rn[V2s53h6s5 +JcC<$JcG?AoD\^erqu]krqcZjrqQNfs7ZKcs7CC(o()>@nF,i6mHj3*lKRNqk2tddj5T%Uhqm2E +gY1?4f@JI$da?FfcHOJSaiMNA`P]R/^V@Ip]=GJ][^EHJZ*:F6XfJJ$Vl-AeUS4BRSt2C@R[BJ. +Q'@JqOcPQ_N/NRMLkg_=K7ec+J:DuqI!U,7Sc>5OSbnrWSc##:Sc;Lc:Adid9`Ic`9)hK^8GbpU +7f>aU7/c!6hts&?T_kAOT(elBT_C_QjQ6:"!9_#1qK^;%G\;#F2g;YX2h;ufqtoE=aTnaGrFm/ZMNl2p4p +c/R%Hc25`[b5c,QB)ZH@B`;`ECAVfFD#S;IDZ"GME:\)BEq=AHFSNcL_Z+cSG0tO2G5?@CFT$@] +G5QRaGlN'gHN/
  • M2@+KN/`jYO-#KePE_>tQ^F/.R[]h_:P_o2Pns2G&ZrlG,]s2t>a +s31Mfrm(Pis3U_ls3^nrrRCkts47/#s4@>)rS%;+s4mV0s5*e5ro!h8s5O%hZ&*~> +JcC<$JcG?AoD\^erqu]krqcZjrqQNfs7ZKcs7CC(o()>@nF,i6mHj3*lKRNqk2tddj5T%Uhqm2E +gY1?4f@JI$da?FfcHOJSaiMNA`P]R/^V@Ip]=GJ][^EHJZ*:F6XfJJ$Vl-AeUS4BRSt2C@R[BJ. +Q'@JqOcPQ_N/NRMLkg_=K7ec+J:DuqI!U,5Fn9eRFT?UWFo-@YGP-.Z:]F2f:&doe9DhE^8cD9X +8,YpU70#aSU%>#5HLZ:MGkXN#V#[CdV>R4iV>m=kU\f_^K)gN#7/j.bWV3:fVuN[qVuEXpVZa>e;uKYq;Ll$tGN/WaVO,oBbP*;,qQ'[l*R@9V8SXuIHTqS6WUnsrdW2ZesXKAV-YHY79 +Za7$H[^NZT\[f;`rk&HK^;%Fu^qp#e!Q2kT`W*pXa8X0[aoBN_bQ#fdc2Q#gci;AjdJqVpe,@er +ec45!fDjJ'g&9Y)g]-(.h>c@3hu;R6iW%p:j8\0?jo+?Ak5a`EklU/9li$/OmI'E@n,MnWnc&+Z +oDeI\p&Facp\agcq>U6fqu$BjrUKl +JcC<$JcG?AoD\^erqu]krqcZjrqQNfs7ZKcs7CC(o()>@nF,i6mHj3*lKRNqk2tddj5T%Uhqm2E +gY1?4f@JI$da?FfcHOJSaiMNA`P]R/^V@Ip]=GJ][^EHJZ*:F6XfJJ$Vl-AeUS4BRSt2C@R[BJ. +Q'@JqOcPQ_N/NRMLkg_=K7ec+J:DuqI!U,54o.A>56*tG5Q="(5Q=OZ:Adid9`Ic`9)hK^8GbpU +7f>aV6rNMOqa&"apH\dYqGmPppf$oe!*$U#qaC?\r)EVnpJUidiD&l!"It*!!JV*lR5_OiGL51SAM2I7NNK0'\OHG]iPa.N#R$a;1 +S"-%@T:hmOUSO]^VPgAlWiE/&Xfek3Yd(O@['d?N\%&uZ]"@sS#/.ac^VIY$rk\]R`;[aU`W4'Y +aT'B^b5TTabl>recMu5jd/DAldK%bpeGn)!f)=5#fDsV'gAfq-h#?.0hZ)L4i;_d9ir8! +JcC<$JcG?AoD\^erqu]krqcZjrqQNf!;?Ebs7C^1o()>@nF,i6mHj3*lKRNqk2tddj5T%Uhqm2E +gY1?4f@JI$da?FfcHXPUaiMNA`P]R/^V@Ip]=PP^[^EKKZ*:F7XfSP%W2HMgUnXQUSt;IAR[KP0 +Q'IPrOcYWaNJrdPM2-h?KS+l-J:E#rI=$9dG^"@TF`_\Fn!sHKfq&.>s%iYirD!8bs%E8^s%32\ +qa^TSrC-V?p>>e>pRh>Urh'4`qk*VSp7LfHog/W?r8m_7r8me;!9NmXs0)=(p9F:ppTa:nq*b5F +s60FG!pJn5rTF:Fkl0`Fkl'ZHk3(mhrPe9DnA=h6r4r3Er_WMir)3;grD`br$MA)IDu=SGEV=GCF7+/K_tq7LFnp41 +GPcR[FlINAFoQX_GQ2pfH2`-iHN8HmI0P.MIt3'#K)UBtKS>/8LPUeEMic@3hu;R6iW%p:j8\3? +jo4EBkPscFl2U&Kli-8NmJlVRn,MnWnbr%YoDeI]p&=[bp\agcq>U6fqu-HjrUKl +JcC<$JcG?AoD\^erqu]krqcZjrqQNf!;?Ebs7C^1o()>@nF,i6mHj3*lKRNqk2tddj5T%Uhqm2E +gY1?4f@JI$da?FfcHXPUaiMNA`P]R/^V@Ip]=PP^[^EKKZ*:F7XfSP%W2HMgUnXQUSt;IAR[KP0 +Q'IPrOcYWaNJrdPM2-h?KS+l-J:E#rI=$9dG^"@TF`_\Fmre\Rr-%jXqf_XVq0)d7s%iYirD!8b +s%E8^s%32\qa^TSrC-UWp7hS5oQfSFnTjbOog.uArhfUi!2K@C`ImtSqksFlrho[k!2odm!2ogn +rMBIUplYB6p5f*4!0?u?7r_WMir)3;grD`br!jf/9pTFV#YPt[)XSS@TR-p=7QiLatBDZBA +C&VlEC]/)KD>A)IDu=SGEV=GCF7+/KPl-aFP5]V"G1:a5G5?@@FT$@^G5QRaGlN'gHN/
  • M2I4MN/`jYO-,TgPE_>uQ^F//S"#q>StD[LU8+N\VPg>jWiE,$Xfek3 +Yd(L?Za@-K\%&uZ]">Se]Y2%o^VIY$_SX4.`;[^W`lH.!a9'K+b5TTabl>recMu5jd/DAldf7ep +eGn&!f)=5#f`0Y'gAfn-h#6(/hZ)L4i;_d9ir8! +JcC<$JcG?AoD\^erqu]krqcZjrqQNf!;?Ebs7C^1o()>@nF,i6mHj3*lKRNqk2tddj5T%Uhqm2E +gY1?4f@JI$da?FfcHXPUaiMNA`P]R/^V@Ip]=PP^[^EKKZ*:F7XfSP%W2HMgUnXQUSt;IAR[KP0 +Q'IPrOcYWaNJrdPM2-h?KS+l-J:E#rI=$9dG^"@TF`_\Fq`amAq`k-GqEWt's%r_ks%`Mer_3>b +r(?u\r^coVrC6`Sr_i>bnj1Aaog/FSs&A\jr_rktr)CF#s$ulQr_r\n!)rShpf%,dj\=u7qb@&d +r)*Aipf%,jr`&r(r`oG.rET;,ra#S1qGdDlp/L$M!+u4Cqe5tCrbD=GrG;IMq/6+Kr,D7Ip2]\E +mWA/$rcS$[e9Ce5qK:e>rH8-`r-/0cs*=Tis*F`nrd>!"It*!!JV*lR:5"=UL51SAMMmFPNK0'\ +OcklkPa.Q$R$a>3S"-(AT:hmPUSO``Vl-JnWiN5'Y-5(6Z*L^B['d?O\@K/]]=Y_g]tV7r^qde' +_Sa:0rl"rYa2e2#!m/U-rlb>cs3:Pgs3L_lrR(Yns3pqrs4%,#rR_)%s4RA)s4[P/rS@M1s53h6 +s5F";ro=%>s5j7Bs6'FGrosIJs6K[Ns6]jSrpTmVs7-'Ys7?9_rUp0`s7cHdrqZQiqtp?ir;H0b +JcFU,J,~> +JcC<$JcG?Ao`"gfrVZTjs8)ckrV6Ee!;?Eb#5%NYo()>?rpP:'mHj3*lKRNqk2tdcj5T%Uhqm2E +gY1?5f@JI$da?FfcHXPUaiMNB`P]R/^q[Ur]=PP_[^NQLZEUR9XfSP&W2HMhUnaWWT:VUCS!fY1 +QBd\uP*(fdNJrdQM26qAKnP)1JUi6!I=-BfH$FOWG'%hIEcH)sDl:]F2g:&[id +9DhE^8cD9X8,YpV70)0?hY?"(T(\fHT^/6BT_(PGk5OHBjS@p5k4>hVYPYQ_Z1G3q7/lBIkksWA +k5FKBk5XQCjS[!m`:1\5_Yh7E^]74/;>jDf;uBVnA)JDu=SIEVFMEF5h;Ll$tGMi= +d/DAldf7epeGn)!f)=5#f`0Y(gAfq-h#6(/h>lI3i;_d9ir8! +JcC<$JcG?Ao`"gfrVZTjs8)ckrV6Ee!;?Eb#5%NYo()>?rpP:'mHj3*lKRNqk2tdcj5T%Uhqm2E +gY1?5f@JI$da?FfcHXPUaiMNB`P]R/^q[Ur]=PP_[^NQLZEUR9XfSP&W2HMhUnaWWT:VUCS!fY1 +QBd\uP*(fdNJrdQM26qAKnP)1JUi6!I=-BfH$FOWG'%hIEcH)sDl +:]F2g:&[id9DhE^8cD9X8,YpV70'"WU%kA]HLZ:WHMDj\HLlFXGlN![60>!DV"TJ^KD@q8Vu!:d +V>R4eV=]rGOnk+jDf;uBVnA)JDu=SIEVFMEF5hVf]tV7r^qmk(_Sa=1`Poj:a8X0[aT0K^b6#o4c2Gohcd:&;dJqYpe,@erec45! +fDjM'g&B_*g]-(-h>c=3hu2L5iW%p:j8\3?jo4EBkPscFl2U&Kli-8NmJlVQn,MnWnbr%YoDeI] +p&Fabp\agdq>U6equ-HjrUKl +JcC<$JcG?Ao`"gfrVZTjs8)ckrV6Ee!;?Eb#5%NYo()>?rpP:'mHj3*lKRNqk2tdcj5T%Uhqm2E +gY1?5f@JI$da?FfcHXPUaiMNB`P]R/^q[Ur]=PP_[^NQLZEUR9XfSP&W2HMhUnaWWT:VUCS!fY1 +QBd\uP*(fdNJrdQM26qAKnP)1JUi6!I=-BfH$FOWG'%hIEcH)sDl:]F2g +:&[id9DhE^8cD9X8,YpV7Jp'V;=6aH6MNq)6M*S@F,d;uBDP:#etK +;#F2h;YX2g<;fhsVf]tV7r^qmk(_Sa=1 +`Poj:a8X0[aT0K^b6#o4c2Gohcd:&;dJqYpe,@erec45!fDjM'g&B_*g]-(-h>c=3hu2L5iW%p: +j8\3?jo4EBkPscFl2U&Kli-8NmJlVQn,MnWnbr%YoDeI]p&Fabp\agdq>U6equ-HjrUKl +JcC<$JcGBBoD\^erVZTjs8)ckrV6Ee!;?Eb#5%NYo()>?rpP=(mHj3*l07Epk2tdcj5T%Uhqm2E +gY1?5f@JI$da?FfcHXPUaiMNB`PfX1^q[Ur]XkY`\$iZMZE^X;Xf\Y(WMcYjUnaZXTUqaFS!ob4 +Q^*i"P*(ieNfB!UM2@%CL4t84JUi9#I=6KhH?jaZG'.nKF)l8?E,TW3D/B5f"_qabBP1r2SH2Vc +rDQ4.htiuFT(8NDT^8-u +YP#-_Z1bEs7/c9IkPXKAjo=HDjlZO's5a.=rPeiVn\jn6pqlpEq7uo*r)3;grD`_qrDipfrpTmS +s6TdO!:'RJ"mG+1jiu'Bbl5l`cLoHXbk]H[B`;`FCAVfGD#S;IDZ+MOE;";IEq=A,FS^+[_Z"]Q +G2%6:G5HF=FT-F^G5QRaGlN'gH3/G@I/\OjIXcluJUrE*K7nr5L51SAM2I4MNK0'\OHG]iPa.Q$ +R$a;2S"-(AT:hmPUSO``Vl-MoWiN5'Y-5(6ZEpmE[C3NQ\@K/]]=bei^;%Fu_>_:P_o2Pn!li:$ +rl>/_b0'_,s3(JfrQbGhs3U_l!n,QHrRCkts47/#s4IA)rS%;+s4mS/s5!b5rS[_7s5O%`!~> +JcC<$JcGBBoD\^erVZTjs8)ckrV6Ee!;?Eb#5%NYo()>?rpP=(mHj3*l07Epk2tdcj5T%Uhqm2E +gY1?5f@JI$da?FfcHXPUaiMNB`PfX1^q[Ur]XkY`\$iZMZE^X;Xf\Y(WMcYjUnaZXTUqaFS!ob4 +Q^*i"P*(ieNfB!UM2@%CL4t84JUi9#I=6KhH?jaZG'.nKF)l8?E,TW3D/B5f"_qabBP1rGG3jDR +;GmBhs%iYirD!;cr_*2^r^m)[qa^TSs$cdWrLs.`qKhXVr-J'`pNlIWq0;NtjeVs2on:J?pdG+X +!2TUjrM0FirhT:brM8eCplYN:r/q#@m#h3Cr)3;grD`_qrDrs&qlg%&s/c@*Xf_T'q3g`>lBhF9 +r+Q(DrbD=GrbVRNq/6.Lr,D@Lq/Z(JgN<:7!0[>(pibD9q0)XXhK8a>rc\3`s*4Qhrd"WmI!kpA +:k!nEJ:W9'K7ei2L5(J>M2@+JN/`jYO-#KePE_>uQ^F/.S"#q>StD[LU8+N\VPg>kWiE,$Xfek3 +Yd1UA['d?N\%&uZ]">Vf]tV7r^qp#e!Q2kT`<+'"a8X-]ai_d*bQ#cdc2Grfci;Ajd/qbFe,@er +ec45!fDjM'g&9Y)g]-(-h>c=3hu2L5iW%p:j8\3?jo+U6equ-HjrUTr=s5!^*~> +JcC<$JcGBBoD\^erVZTjs8)ckrV6Ee!;?Eb#5%NYo()>?rpP=(mHj3*l07Epk2tdcj5T%Uhqm2E +gY1?5f@JI$da?FfcHXPUaiMNB`PfX1^q[Ur]XkY`\$iZMZE^X;Xf\Y(WMcYjUnaZXTUqaFS!ob4 +Q^*i"P*(ieNfB!UM2@%CL4t84JUi9#I=6KhH?jaZG'.nKF)l8?E,TW3D/B5f"_qabBP1rN5l*_D +54Cc;;GmBhs%iYirD!;cr_*2^r^m)[qa^TSs$cc^peg9Ar'L*Ej$E`5oKiFTs&K"smo'3V_++Do +pdFsWrDNSkr_iGgr(cY(nPf-\mSj$_r+Q(DrbD=GrbVRN +q/6.Lr,D@Lq/Z(JgN<:7!)rl>pibD9q0)XXhK8a>rc\3`s*4Qhrd"WmI!kpA:k!nEJ:W9'K7ei2 +L5(J>M2@+JN/`jYO-#KePE_>uQ^F/.S"#q>StD[LU8+N\VPg>kWiE,$Xfek3Yd1UA['d?N\%&uZ +]">Vf]tV7r^qp#e!Q2kT`<+'"a8X-]ai_d*bQ#cdc2Grfci;Ajd/qbFe,@erec45!fDjM'g&9Y) +g]-(-h>c=3hu2L5iW%p:j8\3?jo+U6equ-HjrUTr=s5!^*~> +JcC<$JcGBBoD\^erquZjs8)ckrV-Hgp@eLYJ+W@(o()>?n*f]4mHj3)l07Epk2tdcj5T%Uhqm2E +gY1?5f@JI$da?FfcHXSVb/hWC`PfX1^q[Us]Xt_a\$i]NZa$aj>k:]F2g:&doe9DhE]8cD9X8,YmW7K)!@h#?..hYuF+TE(VDT^/6JT^tJLjm;.0 +k5sf/kPhaWYl:iWYl1d#6i][Rk5=?9jSe-;iW.s8`qdUC`:h+F_YV+F_#@4/;Ya8i<;fhmM2@.LN/`jYO-,TgPE_>uQ^F20 +S"#t?StD^MU84T]VPgAlWiN5'Xfen4Z*L^B[C3NQ\@K/]]=bei^;%Fu_84"*_o2Pn#KFg)aN2KF +b5KKbbg"E3cMu5jd/DAldf7epeGn)!f)=5#f`0Y'gAfn-h#6(/hZ)L3i;_d9ir8! +JcC<$JcGBBoD\^erquZjs8)ckrV-Hgp@eLYJ+W@(o()>?n*f]4mHj3)l07Epk2tdcj5T%Uhqm2E +gY1?5f@JI$da?FfcHXSVb/hWC`PfX1^q[Us]Xt_a\$i]NZa$ak:Amoe9`Ic`9)_E]8GbpU7K>mPT`(S`U@rm5H/a/9H2MpY604sBL#n!C +KD7h77Jrt]U\^eaV>-kbPNS+fOoA5U;Ya8i<;fhmG5HF.8ZEpmF[^NZT\[f;` +]Y(ql^V@S#_8=(,`;[^\`lH-@aN;QHrQ>8dc-?75s3L_lrR(Yns3pqrs4./#rR_)%s4RA)s4[P/ +rS@M1s53e5s5F";ro=%>s5j4A!pAe2rTX@Is6K[Ns6]jSrU9dUs7-'Ys7?9_rUp3arqH?crqZQi +qYU6hr;H3cJcFR+J,~> +JcC<$JcGBBoD\^erquZjs8)ckrV-Hgp@eLYJ+W@(o()>?n*f]4mHj3)l07Epk2tdcj5T%Uhqm2E +gY1?5f@JI$da?FfcHXSVb/hWC`PfX1^q[Us]Xt_a\$i]NZa$aj>k:]F2g:&doe9DhE]8cD9X8,YmW7J'LW;>!6B6MjDe;tNiK:$GFP;>a>f;uK\ol7k2?ZCGrqbm>jpJg`_qGdK. +rb;@HqeQ1Irb_LLrGVUQpMp"Lp2eW'p3$+Qhfnm>qfU_:rcS3`r-/0c!."Nh>'kXEI=6QnIt3'# +JqAW-KS>/8LPUeDMic@3hu2L5iW%p:j8\3?jo+U6equ-HjrUTr=s5!^*~> +JcC<$JcGBBoD\^erqu]krqcZjrV-Hgp@eLY!VH!_np^,un*f]3m-O''l07Epk2tabj5T%Uhqm2E +gY1?5f@JI$e'ZRhcHXSVb/hZD`Pf[2_8!au]Xt_b\$i]OZa-g>Y-"e+Wi;noV50l\TqJ!KS=>t8 +R$X)'PEM)jO,f3YMi*@ILPCM9K7\Z)IsufnH[:!_GB\4QFEDSDE=Qr+DJj<-CMR["BkV0mB)Z?B +A7PUJ!F]C8?iOF5?!Qfgs&8qq!)`\ks%iYirD!;cs%E8^r^m)[qa^TSqqM/+rS@M1!8[1hrD`_qq,[Jr!q#@?rTX^Rkih0kjlGL^iVq+!bk]HYbkfTTbkoT`C&VlEC]/)KD>J/KDuFYL +EVa_NF3A\!FnU"M2@+J +N/WaVO-#KeP*D5sQC+&-R[]hjWiE,$Xfek3Z*L^B['d?O\@K/]]=bei^;%Fu +_84"*_o2Pn!QN1Za9'K+b5TTabQ,odc2u>=d/DAldf7epeGn)!f)=5#f`0Y'gAfq-h#6(/hZ)L3 +i;_d9ir8! +JcC<$JcGBBoD\^erqu]krqcZjrV-Hgp@eLY!VH!_np^,un*f]3m-O''l07Epk2tabj5T%Uhqm2E +gY1?5f@JI$e'ZRhcHXSVb/hZD`Pf[2_8!au]Xt_b\$i]OZa-g>Y-"e+Wi;noV50l\TqJ!KS=>t8 +R$X)'PEM)jO,f3YMi*@ILPCM9K7\Z)IsufnH[:!_GB\4QFEDSDE=Qr+DJj<-CMR["BkV0mB)Z?B +A7PUJ!F]C8?iOF5?!QfAs&8qq!)`\ks%iYirD!;cs%E8^r^m)[qa^TSoq;>Y!20:9eU$S-!-n'# +qkj4dr207ciJ$WOnq6[)!(Hj^s.enUrKI;Gi0*hsqNC];!)`Ylq,@5krDiYor`B-&#Ht;5Xf\\+ +Xo5="WrAIaRIHU6QhQmIC&VlEC]/)KD>J/KDuFYLEVa_NF3A\!FnU"M2@+JN/WaVO-#KeP*D5sQC+&-R[]hjWiE,$Xfek3Z*L^B['d?O\@K/]]=bei^;%Fu_84"*_o2Pn!QN1Za9'K+b5TTabQ,odc2u>= +d/DAldf7epeGn)!f)=5#f`0Y'gAfq-h#6(/hZ)L3i;_d9ir8! +JcC<$JcGBBoD\^erqu]krqcZjrV-Hgp@eLY!VH!_np^,un*f]3m-O''l07Epk2tabj5T%Uhqm2E +gY1?5f@JI$e'ZRhcHXSVb/hZD`Pf[2_8!au]Xt_b\$i]OZa-g>Y-"e+Wi;noV50l\TqJ!KS=>t8 +R$X)'PEM)jO,f3YMi*@ILPCM9K7\Z)IsufnH[:!_GB\4QFEDSDE=Qr+DJj<-CMR["BkV0mB)Z?B +A7PUJ!F]C8?iOF5?!R.gpHS[Vs&&horDhq,@5k!)rhln4r1AnP0']r)3>hrD`_qq,[JrqHWr(r*95# +qc!5er)<;gqG[,fs(VIIqeQ.Hrb_LLrGVXRpMp%MpiFW#p3$(Pick3AqK;:Lq/c4NrH8-`r-/0c +!."Nh!IK4nI8kZFIt3'#JqJ]/Knb>;Ll$tGMiVf]tV7r^qmk(_Sa=k`<"!!rl>/_b0'_,s3(JfrQYJjd*Va= +s3gqrrRCkts47/#s4IA)rS%;+s4mS/s5*e5rS[_7s5O%h>`!~> +JcC<$JcGBBoD\^erqu]krqcZjrqQNfs7ZHb!VH!_npg3!n*f]3m-O''l07Epk2tabj5T%Uhqm2E +gY1?5f@JL%e'ZRhcHXSVb/hZD`Pf[2_8!au]Xtbc\@/iQZa-j?YH=q-Wi;qpVPL#^TqJ$LSXZ+; +R$a2)P`q8mOH5E\N/NOLLk^Y@KBnFra5\3!+#S/!aAi3r`T#erDNbq;,R9gs%iYirD!;cs%E8^s%32\qFCNSq:kr)s5!_1 +!8ZP+rLibUn"B2:!9i\1!9ipWgT^=RpdG*MroF%lg!`uroXLJjlGI]i8FIVr64lXlHK.KrbD=GrbVRNqJQ7MrG_OOqf;LR`H:`p +olfPCpicLVn9"AFp2p:Vrc\6as*4Qhrd+Tk!.=co!IfOtJ51ZIK7ei2L5(J>M2@+JN/WdXO-#Ke +PE_>tQ^F//S"#q>StD^MU8+N\VPgAlWiN5'Xfnt5Z*L^C[C3NQ\@K2_]Y(ql^V@S#_8=(,`;[^V +`lJ)"#g(63bKJ,Rc-?75s3C\lrR(Yns3pqrs4./#rR_)%s4RA)s4dS/rS@J0s53h6s5F";rT!q= +s5j4As6'FGrosIJs6KXMs6]jSrU9dUs7-'Ys7?9_rUp0`s7cHdrqZQiqYU6hr;H0bJcFR+J,~> +JcC<$JcGBBoD\^erqu]krqcZjrqQNfs7ZHb!VH!_npg3!n*f]3m-O''l07Epk2tabj5T%Uhqm2E +gY1?5f@JL%e'ZRhcHXSVb/hZD`Pf[2_8!au]Xtbc\@/iQZa-j?YH=q-Wi;qpVPL#^TqJ$LSXZ+; +R$a2)P`q8mOH5E\N/NOLLk^Y@KBnFra5\3!+#S/!aAi3r`T#?rDNbq;,R9gs%iYirD!;cs%E8^s%32\qFCNSoq;>W!2016 +e9^S/nNl?8b(]MA!/(&7r^Hg^s.eqV!2]UXqNKg"rfQi9rDNGirD`_qq,[Jrs&f3%s/l4#"KSQ& +WN#`_r0d/DoU#3;rbD=GrbVRNqJQ7MrG_OOqf;LR`H:`polfPCpicLVn9"AFp2p:Vrc\6as*4Qh +rd+Tk!.=co!IfOtJ51ZIK7ei2L5(J>M2@+JN/WdXO-#KePE_>tQ^F//S"#q>StD^MU8+N\VPgAl +WiN5'Xfnt5Z*L^C[C3NQ\@K2_]Y(ql^V@S#_8=(,`;[^V`lJ)"#g(63bKJ,Rc-?75s3C\lrR(Yn +s3pqrs4./#rR_)%s4RA)s4dS/rS@J0s53h6s5F";rT!q=s5j4As6'FGrosIJs6KXMs6]jSrU9dU +s7-'Ys7?9_rUp0`s7cHdrqZQiqYU6hr;H0bJcFR+J,~> +JcC<$JcGBBoD\^erqu]krqcZjrqQNfs7ZHb!VH!_npg3!n*f]3m-O''l07Epk2tabj5T%Uhqm2E +gY1?5f@JL%e'ZRhcHXSVb/hZD`Pf[2_8!au]Xtbc\@/iQZa-j?YH=q-Wi;qpVPL#^TqJ$LSXZ+; +R$a2)P`q8mOH5E\N/NOLLk^Y@KBnFra5\3!+#S/!aAi3r`T4aq`k$X!`DlmrD/8LPUeDMMmFPNfT6_OckomQ'I]'R$sM6 +S=Z=ETqS3UUnsrdW2ZetXKAV.YctCVf]tV7r^qmk(_Sa=k`<"!!rl>Aeb0%oN +bfn>Vrm(Pi!7:\ls3gqrrRCkts47/#s4IA)rS%;+s4mS/rnd\4ro!h8s5O";s5a4ArT=.Cs60IH +s6BXMrTsROs6fjSs7$'YrUU![s7H9_rq?Bdr:p9erqcKgrVZTlnc"+>h>`!~> +JcC<$JcGBBo`"gfrVZTjs8)`jrqQNfs7ZKcs7?<_rpkO.nF,i6mHj3*lKRQskN:pfj5].Xi8\2r`fM/>$Co.!a&N*r`9&!!*&nq!`DlmrDbr(?u\r^coV +r^QqAq:c&+gY:Ns6/^Oq60"dpTO/8 +LPUeDMN!LRNfT6`P*2#nQ'Rc(R@9V8SXuFGTqS6WUo(&fW2ckuXKAY/Yd(L?Za@0L\%&uZ]">Vf +]tV7r^qmn)_o0O5`l?'ua8sE*rlb>c!6tMgs3L_lrmCbos3pqrs4./#rR_)%s4R>(s4dS/rS@M1 +s53e5s5F";rT!q=s5j4As6'FGrTOCKlg+N9s6]jSrU9dUs7-'Ys7?9_r:U*`rqH?crqZQiqYU6h +r;H0bJcFR+J,~> +JcC<$JcGBBo`"gfrVZTjs8)`jrqQNfs7ZKcs7?<_rpkO.nF,i6mHj3*lKRQskN:pfj5].Xi8\2r`fM/>$Co.!a&N*r`9&!!*&nq!`DlmrDbr(?u\r^coV +r^Qp[q4RYXpNb87r-89gq0DHqrMKRlm\\'ZpOr9/r^H(Irh]XYrfm5Bd?=K,q,@5krDi\prE&r" +"^/%4Y-"i)XT#:"WW9$lRf8`IR.?U,^b5TTabQ,oe +cMu5jd/MGmdf7epeGn)!f)=5#f`0Y&gAfq-h#6(/hZ)L3i;_d9ir.p;jT"??k5XWEkl'`IlKdd7 +m/QJQmeuVSnGi%Wo)J=]o_eC^pAXgaq#:*gqYL*fr;?N`rdk+*s*t~> +JcC<$JcGBBo`"gfrVZTjs8)`jrqQNfs7ZKcs7?<_rpkO.nF,i6mHj3*lKRQskN:pfj5].Xi8\2r`fM/>$Co.!a&N*r`9&!!*&nq!`DlmrDbr(?u\r^coV +r^Qibqbm>hs$HNKogI_,o0i(6qGcu`r`&DXmmcS4pI=mFr^?fbr_rMgrDWMks%`PhiD/W3r_iPj +rD`_qqH!PrrE',(>[786p0@;jr)hqeQ1Irb_LLrbqaSpi64PqK'DnoQBbKm/8LPUeDMN!LRNfT6`P*2#nQ'Rc( +R@9V8SXuFGTqS6WUo(&fW2ckuXKAY/Yd(L?Za@0L\%&uZ]">Vf]tV7r^qmn)_o0O5`l?'ua8sE* +rlb>c!6tMgs3L_lrmCbos3pqrs4./#rR_)%s4R>(s4dS/rS@M1s53e5s5F";rT!q=s5j4As6'FG +rTOCKlg+N9s6]jSrU9dUs7-'Ys7?9_r:U*`rqH?crqZQiqYU6hr;H0bJcFR+J,~> +JcC<$JcGBBo`"gfrVZTjs8)`jrqQNf!;?Ebs7?<_rpkR/nF,i6mHj3*lKRQskN:pfj5].Xi8?Y50=TV],=8l8#<<-"s;Z]io;>j;m:JO[`:&dod9DqK^8cD9W +7fZ$WgATb+gAK^rU$eZ3U$k;@kl0i?kQ'l1YkP?dYkbKt7/TLFiq_R3i:b.Z`q77J`:CeG;Ya8i +<;fhnFrQG1UrbVOMqel@Nrc%XPr,V[U]QE^e +nTOJIolg.RnT=DEp2p:Vs*")YHY79ZEppG[^NZU\[oDc]Y2%o^VI\&_Sa=2`Q#p< +aN2KFb5TQcbg"E3cMu2jd/DAldK%bpeGn)!f)=5"f`0Y'gAfq-h#-".hZ)L3i;_d9ir.p;jT"?? +k5XWEkl'cGlMp2Km/QGQmeuVSnG_tVo)J=]o_eC^pAamaq#:*gqYL*fr;?N`rdk+*s*t~> +JcC<$JcGBBo`"gfrVZTjs8)`jrqQNf!;?Ebs7?<_rpkR/nF,i6mHj3*lKRQskN:pfj5].Xi8?Y50=TV],=8l8#<<-"s;Z]io;>j;m:JO[`:&dod9DqK^8cD9W +7fZ$WTDbG[TCR9bHL6"H62mbWVt6bcVoFGdK_Rt57IR&NV>[:hPP^OCPL5Nn;Ya8i<;fhnVf]tV7r^qmn)_o0O5`l?'?aN;QHrlYAec-?75 +s3C\lrR(Yn!7Unrs4./#rR_&$s4RA)s4dS/r8%D0s53e5s5F";rT!q=s5j4As6'FGrTX@Is6KXM +s6TgSrU9dUrpfsXs7?9_r:U*`s7cEcrqZQiqYU6hr;H0bJcFR+J,~> +JcC<$JcGBBo`"gfrVZTjs8)`jrqQNf!;?Ebs7?<_rpkR/nF,i6mHj3*lKRQskN:pfj5].Xi8?Y50=TV],=8l8#<<-"s;Z]io;>j;m:JO[`:&dod9DqK^8cD9W +7fZ$U;uBPm;>W`U7+Og#7.3G<<:Wud<:EEG7d7efCL7K-6Y;Z0Pj<7F\59`S)e;uK\o#=oM_,>lS%'>lI\&S5LDuO_NEVskSF1cVcFn'YGGP-.TFn'SG +F7s_TFoQX_GQ2pfH2`*tH[L3hI=?WpJ:N3&re"+%Knb>;M2@+JN/WaVO-#KeP*D5sQC+&-R[]h< +StD[LU8+N\VPgAlWiE/&Xfnt5Z*L^C[C3NQ\[f;`]Y(ql^V@S#_SX4/`Poj:a2l?DaiaV+!mJp6 +rm(Pi!7:\ls3^nrrRCkts47/#rn.8(rS%;+s4mP.s5*e5rS[_7s5O";s5a4ArT=.Cs60FGs6BXM +rTsRO!:KgSs7$$XrUU![s7H6^s7ZKeqtU0drqcKgrVZTlnc"+>h>`!~> +JcC<$JcGECoD\^erVZTjs8)ckrV6Ee!;?Ebs7?<_rpkO.nF,i6mHj3*lKRQskN:pgj5].Xi8Z[^@L$=L?sd8I?=!P8!aAi3r`K;)=',B%!``3!r_rhps&&bls%iYirD!;cr_*2^r^m)[ +qFC55s4Zq8n"TKKrM&kVs.\sJroj7D!9j%=!9iOKp93bcr3,i_r'^VEqVq;/rS[_5ro!4`n](FE +qS`'EqG[>lrDi\prE&u#qHiSa[ZrlbAepWVO/8LPUeDMMmFPNfT6_ +OckomQ'I]'R$sM6S=Z=ETqS3VUnsrdW2ZetXKAY/Yd(L?Za@0L\%&uZ]=bei^;%Fu_8=(,`;[^[ +`lH0AaiV^)b5oi3rQYJjd*Vd>s3gqrrm^tus47,"s4IA)rS%;+rnRJ.s5*e5rS[\6s5O";s5a4A +rT=.Cs60FGs6BXMrTsROs6fjSs7$'YrUU![rq-0^rq?Bdr:p9erqcKgr;?Kknc"+>h>`!~> +JcC<$JcGECoD\^erVZTjs8)ckrV6Ee!;?Ebs7?<_rpkO.nF,i6mHj3*lKRQskN:pgj5].Xi8Z[^@L$=L?sd8I?=!P8!aAi3r`K;)=',B%!``3!r_rhps&&bls%iYirD!;cr_*2^r^m)[ +qFCFTrLj+]s*F3\hg4d;mm6`G!2oCb!/AFGr.Of4r'gX\p8%Y`pnmtQaccL!rD`_qqH!Prr`K#" +riQ1$"Kec,X/l6"!3,g_!1NYMp6b66rg3\$rbVRNqJQ:NrG_RPr,V^VmW@T6k&g*8g3376n9">E +p2p:Vrc\6as*4Qhrd+Tk!.=co;1="EJ:N3&K7ei2L5(J>M2@+JN/WdXO-#KePE_>tQ^F//S"#q> +StD^MU84T]VPgAlWiN5'Y-5(7ZEpmE[^NZT\[f>b]Y2%o^VI\&_Sa=k` +JcC<$JcGECoD\^erVZTjs8)ckrV6Ee!;?Ebs7?<_rpkO.nF,i6mHj3*lKRQskN:pgj5].Xi8Z[^@L$=L?sd8I?=!P8!aAi3r`K;)=',B%!``3!r_rhps&&bls%iYirD!;cr_*2^r^m)[ +qFC?[qbllNf1#I&mm6eLo2GTehadT6l::bApI+pJ!)rJes&8\lcqa7.qG[>lrDi\prE&u#qH/8LPUeDMMmFPNfT6_OckomQ'I]'R$sM6S=Z=ETqS3VUnsrdW2Zet +XKAY/Yd(L?Za@0L\%&uZ]=bei^;%Fu_8=(,`;[^[`lH0AaiV^)b5oi3rQYJjd*Vd>s3gqrrm^tu +s47,"s4IA)rS%;+rnRJ.s5*e5rS[\6s5O";s5a4ArT=.Cs60FGs6BXMrTsROs6fjSs7$'YrUU![ +rq-0^rq?Bdr:p9erqcKgr;?Kknc"+>h>`!~> +JcC<$JcGECoD\^erVZTjs8)ckrV6Ee!;?Ebs7C^1o()>@nF,i6mHj3*lKRQskN:pgj5].Xi8[[^EKKZEUR9XfSS'WMl_lUnj`YTq@pI +S=>t8R$X)'P`h2kO,o9ZN/EIKLPCP:K7ec+J:E#rI!^0c)0pING'.nKF)l8?E,TW3D/=!'C2.Hr +BP1rVAH?=OraH+@?sm>K?=$q:>QS,5>5hY+=BAT'k:Amoe9`Ic`9)_E] +8Gl!Vg]-"*g]#q"U#r*HU$8<>60RS5Z/r4`YNN.b7/KFOiq_R3i;2@1i9eMS`qdUN`:_%G;uK\o +S5MDuFYNEW'qUF7FA,Fm*r: +Fl%<:FmsMEF7s_TFoHR_GQ2pfH2`*kH[L5?I8GBBJ:N3%JqJ]/Knb>;Ll$tGN/WaVO,oBcP*;,q +QC!u,R[]hkWiE/&Xfen4Z*L^C[C3NR\[f;`]Y(qm^VI\&_Sa=k`=']+aN2KF +b0.uPbg$.4s3C\lrmCbos3pqrs4./#rR_)%s4RA)rnIJ.rS@M1rnm\4s5F";r8[h +JcC<$JcGECoD\^erVZTjs8)ckrV6Ee!;?Ebs7C^1o()>@nF,i6mHj3*lKRQskN:pgj5].Xi8[[^EKKZEUR9XfSS'WMl_lUnj`YTq@pI +S=>t8R$X)'P`h2kO,o9ZN/EIKLPCP:K7ec+J:E#rI!^0c)0pING'.nKF)l8?E,TW3D/=!'C2.Hr +BP1rVAH?=OraH+@?sm>K?=$q:>QS,5>5hY+=BAT'k:Amoe9`Ic`9)_E] +8Gl!TTD>/XHMVp?HLQ4J62meJVZ)=dL%n(570'+VV":J]PKB!c;uK\o/8LPUeDMN!LRNfT6_P*2#nQ'Rc(R@9V8SXuIHTqS6WUo(&fWN)u"Xf\b1 +Yd(L?['d?N\@K/]]=bei^V@S#_SX4/rl#8ba2l?Dai_fMbfn?2cMu2jd/MGmdf7epeGn)!f)=5# +f`0Y'gA]k,h#6(/hYuF2i;_d9ir%j:jT"??k5XWEkl'cGlMp2Km/QJQmeuVSnGi%Wo)A7\o_nI^ +pAamaq#:*gqYL*fr;?N`rdk+)s*t~> +JcC<$JcGECoD\^erVZTjs8)ckrV6Ee!;?Ebs7C^1o()>@nF,i6mHj3*lKRQskN:pgj5].Xi8[[^EKKZEUR9XfSS'WMl_lUnj`YTq@pI +S=>t8R$X)'P`h2kO,o9ZN/EIKLPCP:K7ec+J:E#rI!^0c)0pING'.nKF)l8?E,TW3D/=!'C2.Hr +BP1rVAH?=OraH+@?sm>K?=$q:>QS,5>5hY+=BAT'k:Amoe9`Ic`9)_E] +8Gl!N;u]bg7*\6u7.*A?lIso<;BJl<:*WaD#S;KDZ4SQE;=MPEr:"KFPCs%FRXG0G5-4LFRsSIFT-F^G5ZXbGlN'gH3/G@ +I/\OjIXcluJUrE*K7nr5L51SAM2I7NNK0'\OHPcjPa.Q$R$jD4S=Q7DTV8'SUnjlcVl?\rXKAV- +YctCVf]t_=t_8=(,`;[^``lH0AaiV]KbKS2Trm(Pi!7:_ms3gqrrRCkts47/# +s4IA)rS%8*s4mS/s5*b4rS[_7s5Nt:s5a4ArT=.Cs60FGs6BXMrTsROs6fjSs7$'YrUTsZs7H9_ +rq?BdqtU0drqcKgrVZTlnc"+>h#Dm~> +JcC<$JcGECoD\^erquZjs8)ckrV6Ee!;?Ebs7Cd3o()>@nF,i6mHj3*lKRQskN:pgj5].Xi8$Co.!a&N*r`0)#<)iiqs&/kor_WVjs%`Mes%NGcr(?r[ +r^cuXq:Yi'r7]bsqkqHoQ0_JrH8-`r-/0c!."Nh$[[8KI=6QnIt3'#K)UC&KS>/8LPUeEMi +JcC<$JcGECoD\^erquZjs8)ckrV6Ee!;?Ebs7Cd3o()>@nF,i6mHj3*lKRQskN:pgj5].Xi8$Co.!a&N*r`0)#<)iiqs&/kor_WVjs%`Mes%NGcr(?r[ +r^cuXq4IPWgj7t*lp:ZLl_aN5`eF.TqF14Urh]=crh]LUerouqqNCeUrD`_qqH!SsrE/r"rEB5* +s/l:%rN#jrl'_74nWsqHoQ0_JrH8-`r-/0c +!."Nh$[[8KI=6QnIt3'#K)UC&KS>/8LPUeEMi +JcC<$JcGECoD\^erquZjs8)ckrV6Ee!;?Ebs7Cd3o()>@nF,i6mHj3*lKRQskN:pgj5].Xi8$Co.!a&N*r`0)#<)iiqs&/kor_WVjs%`Mes%NGcr(?r[ +r^cuXo2EFnr^?*=!*/tsoi(`e!)r_b`^fbkqF1-VrDWDhbYJ"/rDWYorDi\pr`B&#qcWl$s',G, +!*f5'kYqO\pf-`]s)%XNrGV[Sq/Q@Rr,_LPo6'_Lk]Q?9mWIN4pN>qHoQ0_JrH8-`r-/0c!."Nh +$[[8KI=6QnIt3'#K)UC&KS>/8LPUeEMi +JcC<$JcGECoD\^erquZjs8)ckrV6Ee!;?Ebs7Cg4o()>@nF,i6mHj3*lKRQskN:pgjQ#7Yi8EJJ +h;$``59C-^V@Ip]=PP_\$i]NZa-g>Y-"e+Wi;qpVPU)`TqS*M +St):=R@'>,Q'@JqOcYWaNJrdQM26qAKnP)1JUi9#I=6KiH?si9G7A_?Y50=TV],=8l5%j>k:]F2g:&doe9DhE] +8cD9[8+bNbUA:MQU?k22l1hOHYi2e\7/B=P7fM?Hi:,Y'i9\GR`qICC`;W^7<;fhn5_\*>lNjmjlGL^ioB%WiS`Ygbj`gLbk]H[b56)UDuFYOEW'qUF7s_MFlml7FmaA=Fm!rAFmaAD +F7s_TFoHR_GQ2pfH2`-iHN8HmI9qAPIt3'#JqJ]/Knb>;Ll$tGMiaN;QHbKJ,Rc2Pui +cd:&c@3hu)F4iW%p8j8\3?jo"9@kPscEl2U&Kli$2L +mJlVQn,MnWnbr%XoDeI\p&Fabp\agcq>U6equ$BirUKl +JcC<$JcGECoD\^erquZjs8)ckrV6Ee!;?Ebs7Cg4o()>@nF,i6mHj3*lKRQskN:pgjQ#7Yi8EJJ +h;$``59C-^V@Ip]=PP_\$i]NZa-g>Y-"e+Wi;qpVPU)`TqS*M +St):=R@'>,Q'@JqOcYWaNJrdQM26qAKnP)1JUi9#I=6KiH?si9G7A_?Y50=TV],=8l5%j>k:]F2g:&doe9DhE] +8cD9[7f]4VTDtS`HeWl.H0dimVt-_[L<##C7/B=P7erkYV>R4eV>leWPLkukPQ"M[<;fhn5_\*>l1T-X/`2!WiE%tl'_.1oU#GmrbqaSqJlISr,_RRpN>VAm<.i=m<.T8p3#eFoQ0_J +rcS3`rHJ9ds*=Tis*F`nrdA+%It*!!JV&N,KS>/8LPUeDMMmFPNK9-^OckomQ'I]'R$jG5S=Z=E +TqS3VUnsueW2ckuXf\b0Yd(L?['d?N\@K/]]=bhk^V@S#_SX4/`Poj;aN2KFb0.uPbg$.4!mf6? +rm:eqe'n(s4dS/r8%D0s53b4s5F";r8[h +JcC<$JcGECoD\^erquZjs8)ckrV6Ee!;?Ebs7Cg4o()>@nF,i6mHj3*lKRQskN:pgjQ#7Yi8EJJ +h;$``59C-^V@Ip]=PP_\$i]NZa-g>Y-"e+Wi;qpVPU)`TqS*M +St):=R@'>,Q'@JqOcYWaNJrdQM26qAKnP)1JUi9#I=6KiH?si9G7A_?Y50=TV],=8l5%j>k:]F2g:&doe9DhE] +8cD9[7fZN];nYU"7-m2>5_\* +>lIt$>h`6M;u:J3DuFYOEW'qUF7s_MFlml7FmaA=Fm!rAFmaADF7s_TFoHR_GQ2pfH2`-iHN8Hm +I9qAPIt3'#JqJ]/Knb>;Ll$tGMiaN;QHbKJ,Rc2Puicd:&c@3hu)F4iW%p8j8\3?jo"9@kPscEl2U&Kli$2LmJlVQn,MnWnbr%XoDeI\p&Fab +p\agcq>U6equ$BirUKl +JcC<$JcGECoD\^erquZjs8)ckrV6Ee!;?Ebs7C[0o()>@nF,i6mHj3*lKRQskN:pgjQ#7Yi8EJJ +h;$`j;m:JO[`:&[id9DhE] +8cD9\8+bN`UA1GTU?b,1l1V@KZ21]cYPCT_7K,dTi;2=2i;2@1huMa&`U_%A`Uq+I<;fhn5hb(>lWpojlGL_j5T+ZiSi_Qrlt;`mE>4Irlb/\rGMUQrc%^RrGqgWpN61QhKJ@1m<%`< +l?;lDm<&#Bp2p7Us*"M2@+JN/`jYO-#NfPE_>u +Q^F20S"#t?StMdNUSO]_Vl-MoWiW>)YHY79Za7$I[^WcW]">Vf]tV7s_8=(,`5T^8a8X-fai_fM +bfn>WcHjh`rmCbo!7Unrs4%,#rR_)%s4R>(s4dS/r8%D0s53b4s5Et:rT!n +JcC<$JcGECoD\^erquZjs8)ckrV6Ee!;?Ebs7C[0o()>@nF,i6mHj3*lKRQskN:pgjQ#7Yi8EJJ +h;$`j;m:JO[`:&[id9DhE] +8cD9\8,f1VT)bP^He`r1H0[cdVu!:dLAlnhL?+'a7/B@O7fB.ZV#[CdV>c_VPLYilPPnJZPqb(XT,@!WrK'^RIQ[=Qi1h$DuO_PEW'qUF8'eOFl%<1FmX;;Ll$tGMikWiE/&Xfnt5Z*UdD[^NZT\[oDc]Y2%o^qmn)_o0O5`lJ)"$d$Q7bKS2TcHab^d/MGm +dK%bpeGn&!f)=5#f`0Y&gAfq-h#-".hZ)L2i;_d8ir.p:jT"??k5XWEkks]FlMp2Km/QJPmeuVS +nGi%Vo)J=]o_eC^pAXgaq#:*fqYL*fr;?N_rdk+)s*t~> +JcC<$JcGECoD\^erquZjs8)ckrV6Ee!;?Ebs7C[0o()>@nF,i6mHj3*lKRQskN:pgjQ#7Yi8EJJ +h;$`j;m:JO[`:&[id9DhE] +8cD9\8,cK^;nYWc62adV;u'Dd8*3A'8,5RL7K,dA<5_Q1<;fhn5hb(>lIt$>hE$M +;uLV5DuO_PEW'qUF8'eOFl%<1FmX;;Ll$tGMikWiE/&Xfnt5Z*UdD[^NZT +\[oDc]Y2%o^qmn)_o0O5`lJ)"$d$Q7bKS2TcHab^d/MGmdK%bpeGn&!f)=5#f`0Y&gAfq-h#-". +hZ)L2i;_d8ir.p:jT"??k5XWEkks]FlMp2Km/QJPmeuVSnGi%Vo)J=]o_eC^pAXgaq#:*fqYL*f +r;?N_rdk+)s*t~> +JcC<$JcGECoD\^erquZjs8)ckrV-Hgp@eLYIe<7'o()>@nF,i6mHj3*lKRQskN:pgjQ#7Yi8EMK +h;$c=g"=p-e^W'rdEp4bc-4ARaN2E@`P]R0^q[Us]Xtbc\@8oSZa6sAYcb+1X/`.tVl$;dUS=HT +T:VUCS!o_3Q^*i"P*1ofO,]*WMM[1GL5(D8K7\Z)Isufo'RY7RH$FOWG'.nKF)l8?E,TW3D/B2e +'l%GrBP1phAS#C^@q&nU?sm>K?=$q:>QS,5>5hY*=BGK&s&K(ur_ikr;,R9gs%`VirD!8bs%E8^ +r^m)[!(Z_9c_C0-r1a.blTt++r94.EoW[_fnZ_Mdq*b'JrC-eGp>Gu.qV_D4!64EFlc/h@ou-l0 +rDi\pr`B&#qcWo%r`f8)s'5Zfjo4??irnB#i8ESjc2GlObPKH]bPTE^DZ4SQE;FSREr:"QFS^.R +G4BeGG4B_BFR"#?G4TkDFS0_JFT-F^G5ZXbGlN'fH4,(II!pElIXcluJV*lR=G2B_L51SAM2R=O +NK0'\OcklkQ'IZ%R$jD4S=Q7DTV8*TUnsrdW2ZetXKAY/Yd(L?['d?N\@K/]]=bhk^V@S#_SX40 +`Q#s=aN2KGbKJ,Sc-FV\cd;[=!n,QHrm^tus472$s4IA)r7_2*s4mP.s5*e5r8@S5s5Nt:s5a4A +r9"%Bs60CFs6BXMrTsONs6fjSs7$'Yr:9mZrq-0^rq?BdqtU0drqcKgr;?Kknc"+>g])d~> +JcC<$JcGECoD\^erquZjs8)ckrV-Hgp@eLYIe<7'o()>@nF,i6mHj3*lKRQskN:pgjQ#7Yi8EMK +h;$c=g"=p-e^W'rdEp4bc-4ARaN2E@`P]R0^q[Us]Xtbc\@8oSZa6sAYcb+1X/`.tVl$;dUS=HT +T:VUCS!o_3Q^*i"P*1ofO,]*WMM[1GL5(D8K7\Z)Isufo'RY7RH$FOWG'.nKF)l8?E,TW3D/B2e +'l%GrBP1phAS#C^@q&nU?sm>K?=$q:>QS,5>5hY*=BGK&s&K(ur_ikr;,R9gs%`VirD!8bs%E8^ +r^m)[!(Zs[r1F"^q0V@Pi-G9IlTt*>q53n@re90_n:g[+qF1?PrM9CgrMK:brKR/Bc]\<-rDi\p +r`B&#qcWo%r`f8)s'>Z+r2]gsri,@S!1NeQm?md;!,hdSrG_UQrc7pXpN67Sp3,tMn94>Em<%W9 +o60_Jm<&#BolU1Urc\6as*4QhrH\iuI!g?jIXZcsJ:W=OK33e\L5(J>M2@.LN/`jYO-,TgPEhE! +Q^F20S"-%@T:hmPUSO``Vl6SpX/rG+YHY:;Za@-K[^`lY]">Vg^;%Fu_8=(,`Poj;a2l?Db0.uP +c-=PZcd0u;d/qbFe,Iksec45"fDjM'g&0S(g]-(,h>c@3hu)F3iW%p8j8\3?jo"9@kPscDl2U&K +li$2LmJlVQn,MnWnbhtXoD\C\p&=[bp\Xabq>U6equ$BirUKl +JcC<$JcGECoD\^erquZjs8)ckrV-Hgp@eLYIe<7'o()>@nF,i6mHj3*lKRQskN:pgjQ#7Yi8EMK +h;$c=g"=p-e^W'rdEp4bc-4ARaN2E@`P]R0^q[Us]Xtbc\@8oSZa6sAYcb+1X/`.tVl$;dUS=HT +T:VUCS!o_3Q^*i"P*1ofO,]*WMM[1GL5(D8K7\Z)Isufo'RY7RH$FOWG'.nKF)l8?E,TW3D/B2e +'l%GrBP1phAS#C^@q&nU?sm>K?=$q:>QS,5>5hY*=BGK&s&K(ur_ikr;,R9gs%`VirD!8bs%E8^ +r^m)[!_63hpJ\^nlTtJKpf$od!(ccQh+7$*q*b'JrC6'O`(p>3rDi\pr`B&#qcWo%r`f8)s'5Y1 +>PVP(>6%pX<;TSoDZ4SQE;FSREr:"QFS^.RG4BeGG4B_BFR"#?G4TkDFS0_JFT-F^G5ZXbGlN'f +H4,(II!pElIXcluJV*lR=G2B_L51SAM2R=ONK0'\OcklkQ'IZ%R$jD4S=Q7DTV8*TUnsrdW2Zet +XKAY/Yd(L?['d?N\@K/]]=bhk^V@S#_SX40`Q#s=aN2KGbKJ,Sc-FV\cd;[=!n,QHrm^tus472$ +s4IA)r7_2*s4mP.s5*e5r8@S5s5Nt:s5a4Ar9"%Bs60CFs6BXMrTsONs6fjSs7$'Yr:9mZrq-0^ +rq?BdqtU0drqcKgr;?Kknc"+>g])d~> +JcC<$JcGECo`"derqu]krqcZjrV-Hgp@eLYJ+W@(o()>@nF,i6mHj3*lKRQskN:pgjQ#7Yi8EMK +h;$c=g"=p-e^W'rdEp4bc-4ARaiMNB`Pf[2_8!b!]Y(hd\[T#U['R'CYck43XK/A#W2HMgUnaWW +T:VXES"#h5R$O#%PEM&iO,f3YMi*@JLPCP;K7ec,J:E#rI2%'UH?jaZGBS+NFE;JBEH#i6DJa4h +CDCSuBP;$kAn>Oa@q/tW@:3JM?X@&Er`f\4>$>'3=BJZ(k:Amoe9`@]_ +9)_E]8-.N#pY*HXrM/XDo'-/;rTWjVm]l8cnuqjWqaLEPq;D20rS[S3s2P#Vq8W9Ml,NV>pr!/3 +rDi\pr`B&#qcWo%r`f8)ra#P1rT++Aj5L!q!T2i2c2GlMb5fc\bPoZaDuO_PEW'qVF80kRFnp4@ +GP$(KFmjG8Fo-@OFm=)EF7aSRFoHR^GQ2pfH2`-iHN8HmI0"eHrd\7)JqJ]/Knb>;Ll$tGMiWcHjh`rm:eqe'n +JcC<$JcGECo`"derqu]krqcZjrV-Hgp@eLYJ+W@(o()>@nF,i6mHj3*lKRQskN:pgjQ#7Yi8EMK +h;$c=g"=p-e^W'rdEp4bc-4ARaiMNB`Pf[2_8!b!]Y(hd\[T#U['R'CYck43XK/A#W2HMgUnaWW +T:VXES"#h5R$O#%PEM&iO,f3YMi*@JLPCP;K7ec,J:E#rI2%'UH?jaZGBS+NFE;JBEH#i6DJa4h +CDCSuBP;$kAn>Oa@q/tW@:3JM?X@&Er`f\4>$>'3=BJZ(k:Amoe9`@]_ +9)_E]8-#@\TE(V_T_EfsHK9AMHKmfeVu!:`LAch^L@U&o7/KFN7f9(]V>R4hV>R1jV>QSQPLGZp +<;fhn5hb'>lJ%/?N$r+X/c&rnX9?EqO-];rg3Y'rc%^RrGqjXpiQ@Tq0(eBoQKbI +mr[`8qf_IOl?)iCoQ:(Trc\3`s*4Qhrd+Tk!.=co!IfOtJ6[YWK7ei2L5(J>M2@+JN/WaWO-#Ke +P*D5sQC+&-S"#q>StD^MU84T]Vl-JnWiN8(Y->.8ZEppG[^WcW]">Vf]tV7s_8=(,`5T^8a2l?D +b0.uPbg"GYcd0u;d/qbFe,IkseH"2!fDjM'g&9Y)g]-(,h>c@2hu2L4iW%p8j8\3>jo+?@kPscE +l2KuJli$2LmJlVQn,MnVnbr%XoDeI\p&Fabp\agcq>L0dqu-HirUKl +JcC<$JcGECo`"derqu]krqcZjrV-Hgp@eLYJ+W@(o()>@nF,i6mHj3*lKRQskN:pgjQ#7Yi8EMK +h;$c=g"=p-e^W'rdEp4bc-4ARaiMNB`Pf[2_8!b!]Y(hd\[T#U['R'CYck43XK/A#W2HMgUnaWW +T:VXES"#h5R$O#%PEM&iO,f3YMi*@JLPCP;K7ec,J:E#rI2%'UH?jaZGBS+NFE;JBEH#i6DJa4h +CDCSuBP;$kAn>Oa@q/tW@:3JM?X@&Er`f\4>$>'3=BJZ(k:Amoe9`@]_ +9)_E]8H2Z`;sd$:7fPpU7e&q462adY;tj8i8G,L/8Ff:H7/KFN7ep$]Ph\)?2n42>Ph\(>6%pU<;ohrDuO_PEW'qVF80kRFnp4@GP$(KFmjG8Fo-@OFm=)E +F7aSRFoHR^GQ2pfH2`-iHN8HmI0"eHrd\7)JqJ]/Knb>;Ll$tGMiWcHjh` +rm:eqe'n +JcC<$JcGECo`"gfrVZTjrqcZjrV-Hgp@eLYIe<7'o()>@nF,i6mHj3*lKRQskN:pgjQ#:Zi8EML +h;$c=g"=p.e^W*sdF$:ccHOJTaiMQC`Pf[2_8*h"]tCtg\[],W[Bm3FYct=5XfSP&W2HPiUnj`Y +TV%gHS=>t8R$X,(P`q8mOH5E]N/NRMLkg_>KS+o/JUi6!s*YT/H?sj]GB\4QFEDSEEH,r9DJj<- +rbE6`BkV0mB4b^dA7K+Y@UWYP?XI,G?2e(0>?_#/s&]8&r`9&!!*&qrs&/kor_WVjs%`Mes%NDb +r(?u\r^d%Ds4dG)j.bq9n"T&4rTNq=!9j@Fj0AWir3>=eq*b'JqaUMAnDX>cs2FQK!6=]Nr5\`T +oYggKr`/eqr`B&#qcWo%r`f8)ra#M0"CL;Ll$tGMikWiE/&Xfnt5ZEpmE[^NZU\[oDc]tV7r^qmn*`5T^8a2l?Db5TQg +bg"GYcd0u;d/qbFe,Ihue^i=NfDjM'g&9Y)g]$",h>Z:2hu)F4iVqj7j8\3?jo"9?kPscEl2KuJ +li$2LmJlVQn,DhVnbhtXoDeI\p&=[bp\Xabq>U6dqu-HjrUBf;s4dR(~> +JcC<$JcGECo`"gfrVZTjrqcZjrV-Hgp@eLYIe<7'o()>@nF,i6mHj3*lKRQskN:pgjQ#:Zi8EML +h;$c=g"=p.e^W*sdF$:ccHOJTaiMQC`Pf[2_8*h"]tCtg\[],W[Bm3FYct=5XfSP&W2HPiUnj`Y +TV%gHS=>t8R$X,(P`q8mOH5E]N/NRMLkg_>KS+o/JUi6!s*YT/H?sj]GB\4QFEDSEEH,r9DJj<- +rbE6`BkV0mB4b^dA7K+Y@UWYP?XI,G?2e(0>?_#/s&]8&r`9&!!*&qrs&/kor_WVjs%`Mes%NDb +r(?u\r^d$^q4RA,n9Y%[qg.@Lks>9For%\ao7m6ugkPKUq*b'JqaUL[n>?)InWWR-r0-Q3r`/eq +r`B&#qcWo%r`f8)ra#M0#[a[6X/`2!WiH#sm[=*DpmLH8s)@jTrGqjXpiQFVq0(M:p3,tKmrZs" +eo^n6rc\3`s*4Qhrd+Tk!.=cos*dstJ:N3&JqJ]/Knb>;Ll$tGMikWiE/&Xfnt5ZEpmE[^NZU\[oDc]tV7r^qmn*`5T^8a2l?Db5TQgbg"GYcd0u; +d/qbFe,Ihue^i=NfDjM'g&9Y)g]$",h>Z:2hu)F4iVqj7j8\3?jo"9?kPscEl2KuJli$2LmJlVQ +n,DhVnbhtXoDeI\p&=[bp\Xabq>U6dqu-HjrUBf;s4dR(~> +JcC<$JcGECo`"gfrVZTjrqcZjrV-Hgp@eLYIe<7'o()>@nF,i6mHj3*lKRQskN:pgjQ#:Zi8EML +h;$c=g"=p.e^W*sdF$:ccHOJTaiMQC`Pf[2_8*h"]tCtg\[],W[Bm3FYct=5XfSP&W2HPiUnj`Y +TV%gHS=>t8R$X,(P`q8mOH5E]N/NRMLkg_>KS+o/JUi6!s*YT/H?sj]GB\4QFEDSEEH,r9DJj<- +rbE6`BkV0mB4b^dA7K+Y@UWYP?XI,G?2e(0>?_#/s&]8&r`9&!!*&qrs&/kor_WVjs%`Mes%NDb +r(?u\r^crdqc!5XqF:KTp.#!Nl:1J9ks>;Jq,?udqagENgdq*.q*b'JqaUK_n5[G&r`/eqr`B&# +qcWo%r`f8)ra#M0!FK(0>l._*?-Q@KE;OYRErC(SFSp:WG2%67G4B_DFO>6^FT-F^G5QRaGlN'g +HN/
  • M2@+JN/`jYO-#KePE_>uQ^F//S"#t?StMdNUSO]_Vl-Mo +WiW>)YHY7:Za7$I[^WfX]">Vg^;%Fu_8=+.`Poj;aN2KGrlYMic-FV\cd;[=!n,QHrmV#"f%0iP +s4IA)rS%;+rnRJ.rnd\4r8@V6ro3k9s5a4Ar9""As60FGrp'OLrTsONs6fjSrp]sXr:9mZs7H6^ +rq?BdqtU0drqcHfrVZTlnG\"=g])d~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYJ+W@(o()>@nF,i6mHj3*lKRQskN:pgjQ#:[i8EML +h;$c=g=Y$/f$r3udF$=dcHXPUb/hZE`Pod4_SO"%^:_+j\[f2X[^,Q'@JqOcYWaNJrdQM26qAL4k23Jq/B$IfFg1I!U*aG^"@TF`__HEcH)sDl:]F2g:&doe +9D_?\8H;5hb'>lJ%.?N"43jlHF$s5Et8!9*^tr63p=qJlLTrH%aUr,qjZf6?q3noa;@ +eTKGbrH8*_r-/0c!."Nh!df,7L51SAMMmFPNK0'\OcklkPa.Q$R$jD4 +S=Q7DTV8*TUnsrdW2ZetXKAY/Yd(L?['d?O\@K/^]Y(ql^VI\&_Sa=2`Q#s>aN;TJbKS5VcHjh` +rm:bpe,IkseH"2!fDjJ'g&9Y)g]$",h>c@2hu)F4iVqj7j8\3>jo"9@kPscDl2U&Jli$2LmJlVQ +n,DhVnbhtXoD\C[p&Fabp\agbq>U6equ$BirUKl +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYJ+W@(o()>@nF,i6mHj3*lKRQskN:pgjQ#:[i8EML +h;$c=g=Y$/f$r3udF$=dcHXPUb/hZE`Pod4_SO"%^:_+j\[f2X[^,Q'@JqOcYWaNJrdQM26qAL4k23Jq/B$IfFg1I!U*aG^"@TF`__HEcH)sDl:]F2g:&doe +9D_?\8H;sVV=:AZPj">/P4Xt3OoSMY5hb'>lJ%.?N"72X8f3rW;r=ERI6I=EW1"WF80kTFo$:5GP64NFmO5#Fk1[5FoHR^GQ2mf +H2W$jH[L5?I0"eHrd\4(JqJ]/KnY89LPUeEMib]Y2%o^qmn)_o0O5`lH0Aai_fMbg"GYcd0u;d/h\Erm^tu!7q,# +s4@>)rS%;+rnRJ.s5*b4r8@V6ro3k9s5a1@r9"%Bs60CFs6BULrTsONs6fjSrp]sXr:9mZrq--] +s7ZHdr:p6drqcKgr;?Kknc"+>gAc[~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYJ+W@(o()>@nF,i6mHj3*lKRQskN:pgjQ#:[i8EML +h;$c=g=Y$/f$r3udF$=dcHXPUb/hZE`Pod4_SO"%^:_+j\[f2X[^,Q'@JqOcYWaNJrdQM26qAL4k23Jq/B$IfFg1I!U*aG^"@TF`__HEcH)sDl:]F2g:&doe +9D_?\8H;7Hd&;<;KPd<52!#7/B@L7K>sW<:Elf<5hT4Ph\)?2e1/?i"%->68&8;pJA=EW1"WF80kTFo$:5GP64NFmO5#Fk1[5FoHR^GQ2mfH2W$jH[L5? +I0"eHrd\4(JqJ]/KnY89LPUeEMib]Y2%o^qmn)_o0O5`lH0Aai_fMbg"GYcd0u;d/h\Erm^tu!7q,#s4@>)rS%;+ +rnRJ.s5*b4r8@V6ro3k9s5a1@r9"%Bs60CFs6BULrTsONs6fjSrp]sXr:9mZrq--]s7ZHdr:p6d +rqcKgr;?Kknc"+>gAc[~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYIe<7'o()>@nF,i6mHj3*lK[WtkN:pgjQ#:[iS`VM +h;-i>g=b*0f%&:!da?FfcHXSVb/q`F`l5m6_SO%&^:h1k]",>[[^EKKZE^X;Y-"e+Wi;qpVPL#_ +TqS-NSt2@?R[BJ/Q'ISsP*(fdNf8pTMM[.EL4t;5K7\W(0n4Y#I=-?eH$FOWG'.nKF)l8?E,TW3 +D/=$(CMIQsBP1siAS#C^@q&nU?sm>K?=$q:>QJ&4r`K;)=',B%!``3!r_rhp!)`\ks%iYirD!;c +r_*/]r^lqAs4mOIoV1-9oV1M7qrdk?q!#T"qF(0KqaUTUlf%larPmU4oZ$mLqc<\trE/r"r`];* +qcs,+ra,J/"Qe_)ioC!rs5rGhgWrH%dVr,qm[cZf,,oQBD?fQGefrH8*_r-/0cs*=Ti +s*F`nrdFfq=atsPJUrE*K7nr5L51SAM2I4MN/`jYOHG]hPa.N"R$a;1S"-%@T:hmPUSO``Vl6Sp +X0&M,YctC=Za@-K\%&u[]=bej^V@S#_Sa=2`Q#s>aN;TJbKS61c2l8Z:2hu)F4iVqj7j8\3>jo"9@kPj]Cl2U&Klhp,LmJcPPn,DhVnbhtXoD\C[p&Fab +p\Xabq>U6dqu-HjrUBf;s4[L'~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYIe<7'o()>@nF,i6mHj3*lK[WtkN:pgjQ#:[iS`VM +h;-i>g=b*0f%&:!da?FfcHXSVb/q`F`l5m6_SO%&^:h1k]",>[[^EKKZE^X;Y-"e+Wi;qpVPL#_ +TqS-NSt2@?R[BJ/Q'ISsP*(fdNf8pTMM[.EL4t;5K7\W(0n4Y#I=-?eH$FOWG'.nKF)l8?E,TW3 +D/=$(CMIQsBP1siAS#C^@q&nU?sm>K?=$q:>QJ&4r`K;)=',B%!``3!r_rhp!)`\ks%iYirD!;c +r_*/]r^m'_rLs7agjAsFkBZ5Vqkiq^pP8$giJ77tqF19Ns$us_s/,[iq54%RplkTaN;TJbKS61c2l8Z:2hu)F4iVqj7j8\3>jo"9@kPj]Cl2U&Klhp,LmJcPPn,DhVnbhtXoD\C[ +p&Fabp\Xabq>U6dqu-HjrUBf;s4[L'~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYIe<7'o()>@nF,i6mHj3*lK[WtkN:pgjQ#:[iS`VM +h;-i>g=b*0f%&:!da?FfcHXSVb/q`F`l5m6_SO%&^:h1k]",>[[^EKKZE^X;Y-"e+Wi;qpVPL#_ +TqS-NSt2@?R[BJ/Q'ISsP*(fdNf8pTMM[.EL4t;5K7\W(0n4Y#I=-?eH$FOWG'.nKF)l8?E,TW3 +D/=$(CMIQsBP1siAS#C^@q&nU?sm>K?=$q:>QJ&4r`K;)=',B%!``3!r_rhp!)`\ks%iYirD!;c +r_*/]r^lobs&8eai^`K-o0qh.lr;"rqFUNOqF19Ns$uTZqc(O0qc<\trE/r"r`];*qcs,+ra,J/ +!aK#:qHO#+rDV*CrGhgWrH%dVr,qm[cZf,,oQBD?fQGefrH8*_r-/0cs*=Tis*F`nrdFfq=atsP +JUrE*K7nr5L51SAM2I4MN/`jYOHG]hPa.N"R$a;1S"-%@T:hmPUSO``Vl6SpX0&M,YctC=Za@-K +\%&u[]=bej^V@S#_Sa=2`Q#s>aN;TJbKS61c2l8Z:2 +hu)F4iVqj7j8\3>jo"9@kPj]Cl2U&Klhp,LmJcPPn,DhVnbhtXoD\C[p&Fabp\Xabq>U6dqu-Hj +rUBf;s4[L'~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLY$hX&^o()>@nF,i6mJcI%lg!a!kiV$hjQ#:[iS`VM +h;-l?g=b-1f%&:!da?IgcHaYWbK7iH`l5p7_SX+'^V.:m]",A\[^NQLZa$a=Y-"h,WiE"qVkp2b +U7n9QSt;IAS!fY2QBd`!P*1ofO,f0XMi!:HLPCM9K7e`*J:E#rI=-?eH$FOWG'.nK-ZaOa@q/tW@:3JM?X@#D>[1K;>5hY+=BAT'k:Amoe +9`Ic_9)hH_h>?(.h>3o;U=U?4c=kP=?=l2@sVZMLojZM1^&7/B@L7f>jWir7m:iqhX4iW.s: +imc$>`r&m:=8l>!=oMV(>Ph\)?2e1-?iFF5j8S';i;hg8iV1Umbi$\EEW1"WF89qVFo-@KGPQLI +GPH@RFm!l#FkLm8Fo?L]GQ2pfH2W$jH[L5?I0"eHrd\1'JqJ]/KS>/8LPUeDMMmFQNfT6_Ockom +Q'I]'R$sM6S=Z=ETqS3VUnsueW2cl!Xf\e2Yd1UA[C3NQ\[f;`]Y2%o^qmn)_o0O5a2l?Db0.uP +bg"GYcd;[=!RfHreGn&!f)F;$f`0Y(gAfq-h#-".hZ)L2i;_d8ir%j9jT"?>k5OQDkks]ElMp2J +m/QJPmeuVRnGi%Vo)J=\o_eC]pAamaq#:*fqYL*er;?N_rdk+'s*t~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLY$hX&^o()>@nF,i6mJcI%lg!a!kiV$hjQ#:[iS`VM +h;-l?g=b-1f%&:!da?IgcHaYWbK7iH`l5p7_SX+'^V.:m]",A\[^NQLZa$a=Y-"h,WiE"qVkp2b +U7n9QSt;IAS!fY2QBd`!P*1ofO,f0XMi!:HLPCM9K7e`*J:E#rI=-?eH$FOWG'.nK-ZaOa@q/tW@:3JM?X@#D>[1K;>5hY+=BAT'k:Amoe +9`Ic_9)hKZUAgkcI.2LMHKKM861^uNVt>c=LAH]&L?"'d7/B@L7f>jKV>@(dPkUC7P2VW&5hb'>lJ%.?Me+/?im=+W;3FlR,+2(Qi`[qEW1"WF89qVFo-@KGPQLIGPH@RFm!l#FkLm8 +Fo?L]GQ2pfH2W$jH[L5?I0"eHrd\1'JqJ]/KS>/8LPUeDMMmFQNfT6_OckomQ'I]'R$sM6S=Z=E +TqS3VUnsueW2cl!Xf\e2Yd1UA[C3NQ\[f;`]Y2%o^qmn)_o0O5a2l?Db0.uPbg"GYcd;[=!RfHr +eGn&!f)F;$f`0Y(gAfq-h#-".hZ)L2i;_d8ir%j9jT"?>k5OQDkks]ElMp2Jm/QJPmeuVRnGi%V +o)J=\o_eC]pAamaq#:*fqYL*er;?N_rdk+'s*t~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLY$hX&^o()>@nF,i6mJcI%lg!a!kiV$hjQ#:[iS`VM +h;-l?g=b-1f%&:!da?IgcHaYWbK7iH`l5p7_SX+'^V.:m]",A\[^NQLZa$a=Y-"h,WiE"qVkp2b +U7n9QSt;IAS!fY2QBd`!P*1ofO,f0XMi!:HLPCM9K7e`*J:E#rI=-?eH$FOWG'.nK-ZaOa@q/tW@:3JM?X@#D>[1K;>5hY+=BAT'k:Amoe +9`Ic_9)hKZ<;ohk7drq97dEM*61%Xj8Gc!U7/B@L7f>jN!=oMV(>Ph\)?2e1- +?iFI.>lS++;q4kIEW1"WF89qVFo-@KGPQLIGPH@RFm!l#FkLm8Fo?L]GQ2pfH2W$jH[L5?I0"eH +rd\1'JqJ]/KS>/8LPUeDMMmFQNfT6_OckomQ'I]'R$sM6S=Z=ETqS3VUnsueW2cl!Xf\e2Yd1UA +[C3NQ\[f;`]Y2%o^qmn)_o0O5a2l?Db0.uPbg"GYcd;[=!RfHreGn&!f)F;$f`0Y(gAfq-h#-". +hZ)L2i;_d8ir%j9jT"?>k5OQDkks]ElMp2Jm/QJPmeuVRnGi%Vo)J=\o_eC]pAamaq#:*fqYL*e +r;?N_rdk+'s*t~> +JcC<$JcGHDoD\^erVZTjrqcZjrqQNfs7ZHb$hX&^o()>@nF,i6mJcI$lg!a!ki_*ijQ#:[iS`YN +h;-l@g=b-1f@AC#e'ZRicHa\YbK@rJa2Z*:_ns7*^V7Co]=PP_\$i]OZa-j?YHG"/X/`.tVl$;d +US=HTT:VUDS!ob4Q^3o$PEM&iO,o9ZN/NOLLkg_=KS+o.J:N,uI=6HgH?jaZGBS-/F=2-MEH,r9 +DJj<-Chmg$BkV0mB4b^dA7K+Y@UWYP?XI,F?!LW=>?_#/!a&N*r`0)#<)iiqs&&horD!=oMV'>Pqb*?2e1-?iFI5@0GWMj5T(ti;V^0c1]BA +bPlP\F8C"VFo6FQGO'M@GPH@SFlRT$FkLm8Fo?L]GQ2pfH2W'hHN8HmIK+b%It3'#JV&N,KS>/8 +LPUeDMMmFPNK0'\OcklkPa.Q$R$jD4S"6.BTV8'SUnjlcW2ZetXKAY/Yd(L?['d?O\@K2_]Y(tn +^VI\&_o0O5`lH0Aai_fMbg"GYcd;[=!RfHre,n1Of)F8&f\+sVgAfq-h#6(/hZ)L2i;_d8ir%j9 +jT"?=k5XWDkks]ElMp2Jm/QJPmelPRnGi%Vo)A7\o_eC]pAXg`q#:*gqYC$er;6H_rdk+&s*t~> +JcC<$JcGHDoD\^erVZTjrqcZjrqQNfs7ZHb$hX&^o()>@nF,i6mJcI$lg!a!ki_*ijQ#:[iS`YN +h;-l@g=b-1f@AC#e'ZRicHa\YbK@rJa2Z*:_ns7*^V7Co]=PP_\$i]OZa-j?YHG"/X/`.tVl$;d +US=HTT:VUDS!ob4Q^3o$PEM&iO,o9ZN/NOLLkg_=KS+o.J:N,uI=6HgH?jaZGBS-/F=2-MEH,r9 +DJj<-Chmg$BkV0mB4b^dA7K+Y@UWYP?XI,F?!LW=>?_#/!a&N*r`0)#<)iiqs&&horDb7rM]dsql/YErg;Ll$tGMiXs4dS/rS@M1s53b4s5Et:r8[e;s5j.?s6'CFr9=4Gs6KULs6]gRr9s[T +s7-$Xrq$0^r:U'_rqH:-gqu-'aJcFF'J,~> +JcC<$JcGHDoD\^erVZTjrqcZjrqQNfs7ZHb$hX&^o()>@nF,i6mJcI$lg!a!ki_*ijQ#:[iS`YN +h;-l@g=b-1f@AC#e'ZRicHa\YbK@rJa2Z*:_ns7*^V7Co]=PP_\$i]OZa-j?YHG"/X/`.tVl$;d +US=HTT:VUDS!ob4Q^3o$PEM&iO,o9ZN/NOLLkg_=KS+o.J:N,uI=6HgH?jaZGBS-/F=2-MEH,r9 +DJj<-Chmg$BkV0mB4b^dA7K+Y@UWYP?XI,F?!LW=>?_#/!a&N*r`0)#<)iiqs&&horD1s'b\-s'>@tfMqijrH%gWr,qp\nTX;DmKol];:hf[UorH8'^r-/0cs*=Qhs*F`nrdFfq +?%7BTJUrE*K7nr5L51SAM2I4MN/`jYO-,TgPE_>uQ^F20S"#t?StMdNUSO]_Vl6SpX/rG+YHY:; +Za@-K\%&u[]=bej^V@S#_Sa=2`Q#s>aN;TJbKS5VcHjl:d/h\ErmV#"f%0iP!nc2ZrS%;+s4mS/ +s5*e5r8@V6ro3k9roF+@qr[qAroj:Erp'OLr9XINrpK^Qs7$'Yr:9jYs7H6^rq??cqtU0drqcHf +rVZQknc"+>g&HR~> +JcC<$JcGHDoD\^erVZTjs8)`jrqQNfs7ZHbJ+W@(o()>@nF,i6mHs9,lg!a!ki_*jjlGI]iS`YO +hVHuAg=k32f@JI$e'cXjcd'eZbK@rJaMu3<_ns:,^V@Lq]Xt_b\@/iR['R'CYck43XK/A#W2HMh +UnaZXTV%gHS=>t8R$X,(P`q8mOH5E]N/WXNM26n@KnP)1JcC6@IsufoH[:!`G^"@TF`__HEcH)< +Df0H0D/=!'C2*Z\'k_,iARo:\@U`bR?sd8I?!U]?>?b;1=TV],=8l5%j>k:]F2g +:&dod9DhEWhY!Z6U>MaDU?+]>jne-8k5a`0[H=jgZhm/f7JfRN7f_TIj8e6:j9=T)jQ#:]qoA]W +rQ"`TqoJiZr5nrZs2k5\r5\KMs&T,#r`K#"r`];*qcs,+s'GS0ra>_6s'bufq;D>5pms"SNp3#87icWssrH8'^r-/0crd"Khs*Ocnrd=frJ,Xs!JV*lR=bMK` +L51SAM2I4MN/`mZOHG]hPa.N"Q^F20S"-%@T:hmPUSO``Vl6SpX/rG+YHY:;Za@-K\%&u[]=bhk +^V@V%_Sa=2`Q-'@ai_fMbg"GYcd0tcdF-MCe,n1Of)F8&f\+sWgAfq-h#6(/hZ)L2i;_d8ir%j9 +jT"?=k5XWDkks]ElMp2Jm/HDPmelPQnGi%Vo)A7\o_\=]pAXg`q#:*fqYL*er;?N_rdk+&s*t~> +JcC<$JcGHDoD\^erVZTjs8)`jrqQNfs7ZHbJ+W@(o()>@nF,i6mHs9,lg!a!ki_*jjlGI]iS`YO +hVHuAg=k32f@JI$e'cXjcd'eZbK@rJaMu3<_ns:,^V@Lq]Xt_b\@/iR['R'CYck43XK/A#W2HMh +UnaZXTV%gHS=>t8R$X,(P`q8mOH5E]N/WXNM26n@KnP)1JcC6@IsufoH[:!`G^"@TF`__HEcH)< +Df0H0D/=!'C2*Z\'k_,iARo:\@U`bR?sd8I?!U]?>?b;1=TV],=8l5%j>k:]F2g +:&dod9DhE\U\pk[I.M^UHKKM762dY\Vt-_TL\?JWL\jL:7JfRN7f]C`V?!IgVZ!CmW;)VPPP:79 +PPCC6PQ+\_=8l=u=oMV(>Ph\)?2n7.?iFI4@K0dM2@+JN/WaW +O-#KeP*D5sQC!u,R[]hVg^;%G!_SX4/`Pom= +aN;TJbKS5VcHjh`dF$CkrmV#"f%0iP!nc2Zrn@D,s4mS/s5*e5r8@V6ro3k9roF+@qr[qAroj:E +rp'OLr9XFMs6fgRrp]sXr:9jYs7H3]s7ZHdqtU0drVHBfr;?KknG\"=g&HR~> +JcC<$JcGHDoD\^erVZTjs8)`jrqQNfs7ZHbJ+W@(o()>@nF,i6mHs9,lg!a!ki_*jjlGI]iS`YO +hVHuAg=k32f@JI$e'cXjcd'eZbK@rJaMu3<_ns:,^V@Lq]Xt_b\@/iR['R'CYck43XK/A#W2HMh +UnaZXTV%gHS=>t8R$X,(P`q8mOH5E]N/WXNM26n@KnP)1JcC6@IsufoH[:!`G^"@TF`__HEcH)< +Df0H0D/=!'C2*Z\'k_,iARo:\@U`bR?sd8I?!U]?>?b;1=TV],=8l5%j>k:]F2g +:&dod9DhE\5hb'>lJ%/ +?Me+/@/aU7@ej70?!d/%iD]eUr)ms"SNp3#87icWssrH8'^r-/0crd"Kh +s*Ocnrd=frJ,Xs!JV*lR=bMK`L51SAM2I4MN/`mZOHG]hPa.N"Q^F20S"-%@T:hmPUSO``Vl6Sp +X/rG+YHY:;Za@-K\%&u[]=bhk^V@V%_Sa=2`Q-'@ai_fMbg"GYcd0tcdF-MCe,n1Of)F8&f\+sW +gAfq-h#6(/hZ)L2i;_d8ir%j9jT"?=k5XWDkks]ElMp2Jm/HDPmelPQnGi%Vo)A7\o_\=]pAXg` +q#:*fqYL*er;?N_rdk+&s*t~> +JcC<$JcGHDoD\^erVZTjs8)`jrV-Hgp@eLY!qc*UrpkO.nF,i6md9B-lg!a!ki_*jjlGI^iS`YO +hVI#Bg=k64f@JL%e'cXkcd'h\bKJ&LaN)<>`5BI.^q[Us]Xtbc\[T#U['R*EYct=5XfSP&WMcYk +UnjcZTqJ$LSXc1,Q'@JqOcYWaNJrgRM2@%CL4t;5Jq8H&It%EG,("W^H$FOWG'.nKF)l8? +E,TW3D/F*)CMIQsBP1siAS#C^raGn:@/aL6?=!P8#?tA8=]nj/=8l8#<<-"t;u]bq;>sDl:]F2f +:&doe9DqK[hYl?WU\U_]UZ=]BjQ5Lrk5OQ*[HFpoZhq'+7/KFM7eoRNjo4?>jT+HAjT4MbrQ"`T +rQ5#ZqT8WWqT8WUqT&NRrE&u#qcWo%r`f8)ra#M0r*TG2raGb7s5Nn6!93[rn]^UJq8rc^F*%/! +rH8$]olp"PqK_XVn9=\OpN>85j`TC$qfVm]qfi'brd"Khs*OcnrdAL0It*!!JUrE*K7nr5L51S@ +M2I4MN/`jYO-#KePE_>tQ^F/.S"#q>StD[LU84T]Vl-JnWiN8(Y->.9Za7'J[^WfX]"G\h^;%J" +_SX71`Q#s>aN;TJbfn>WcHjkbdF-LmeC<%"f)F8&f\+sWgAfn-h#6(/hZ)L2i;_d8ir%j9jT"?= +k5OQDkkjWElMg,Im/HDPmelPQnGi%Vo)A7[o_eC]pAamaq#1$fqYC$er;6H^rdk+&s*t~> +JcC<$JcGHDoD\^erVZTjs8)`jrV-Hgp@eLY!qc*UrpkO.nF,i6md9B-lg!a!ki_*jjlGI^iS`YO +hVI#Bg=k64f@JL%e'cXkcd'h\bKJ&LaN)<>`5BI.^q[Us]Xtbc\[T#U['R*EYct=5XfSP&WMcYk +UnjcZTqJ$LSXc1,Q'@JqOcYWaNJrgRM2@%CL4t;5Jq8H&It%EG,("W^H$FOWG'.nKF)l8? +E,TW3D/F*)CMIQsBP1siAS#C^raGn:@/aL6?=!P8#?tA8=]nj/=8l8#<<-"t;u]bq;>sDl:]F2f +:&doe9DqKWU[EO&HhD^\H1?4A5m!m[VYR.eV?!O_LXCkS7/KFM7eoRKVZNfpVu3LnWVht\Q26aB +PPC=:POFb6PPnS^=Sl8#>5hb'>lJ%.?Mn10@/aU5@fEA'WpZ;MR/WNLR/WNLQi`[sF89qVFo6FU +GOp(UH1H4LGPQFVFkh*#Fkq0:FoHR]GQ2peH2`-iHiJKmI;+.[It3'#JV&N,KS>/8LPUbCMMmFP +NK0'\OHG]iPa.N#R$a;2S"-(AT:hmPUnjibVl6VqX0&M,YctF>ZaI6M\%0&\]Y(ql^VI\&_SjF4 +`lH0Aai_fNbg"GYcd:(edaQ[peCE.$rmq5(g"HAYs4[P/rS@M1s53b4s5Et:r8[e;s5j.?roa=F +qs".Grp0LKrpBaRr9sXSs7-$Xrq$-]r:U'_s7cEcrV?Hhq>:-gqu-$`JcFF'J,~> +JcC<$JcGHDoD\^erVZTjs8)`jrV-Hgp@eLY!qc*UrpkO.nF,i6md9B-lg!a!ki_*jjlGI^iS`YO +hVI#Bg=k64f@JL%e'cXkcd'h\bKJ&LaN)<>`5BI.^q[Us]Xtbc\[T#U['R*EYct=5XfSP&WMcYk +UnjcZTqJ$LSXc1,Q'@JqOcYWaNJrgRM2@%CL4t;5Jq8H&It%EG,("W^H$FOWG'.nKF)l8? +E,TW3D/F*)CMIQsBP1siAS#C^raGn:@/aL6?=!P8#?tA8=]nj/=8l8#<<-"t;u]bq;>sDl:]F2f +:&doe9DqKWj<7eoLG7f>d:5lt%c<;onk;ufq58GkmQ7JfRM8+0FW!=oMV(>Ph\)?2e1.?iFI4@Js[4>lJ"/?LUnW<;BGo<-*-VFT$@[G4g(NGku^VGjoqQ +G5$.7FQIZ$FSg4[G5HL`GlE!fHN/?lI/\P.IXcitJ:W9'K7ei2L5(J>Ll%"IN/WaVO,oBbP*;,q +Q'[l*R@B\9St;RITq\?YV5L5iWiE,%Xfen4ZEpmF[^NZU\[oGd]tV7s_8=(-`Poj;aN2KGbKS2T +cHab_dF$Cke'umtf%0iP!nc2Zrn@D,!8RP/s5*e5r8@V6ro3k9roF+@qr[n@s60@Es6BULr9XFM +s6fgRrp]sXr:9jYrq--]rq?BdqtU-crqcHfrVZQknG\"=g&HR~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYs7?<_rpkR/nF,i6md9B-lg!a!ki_*jjlGI^io&bP +hVI#Cg=k64f@JL%eC2gmd*L"^bfe/NaN2B?`P]R0_8!b!]tCtg\[],W[C!9GZ*:I8Xf\Y(Wi2hn +VPL#_TqS-NSt2@?R[BJ/Q'IStP*(ieNfB!UMM[1GL5(D8K7\Z)J:E%JI1UaOH?jaZGBS+NFE;JB +EH#jqDA-l'CMR[!BP;$kAn>Oa@q/tW@:9(A!FB(2>R+J:>$5!1=BGK&s&B%ur_rhps&&bls%iYi +r([2br_*8`ptte@h4sP:r1i:roO"=roa0elF#c]qm6:-r'^BMqaUBOrT3q=s5sXLkND'l +kNM.-a8j?YaSO$Vb5TNZb4<[OaSs6[=8l>!=oMV(>Ph\)?2e1.?iFI4@JjU7@fYNciW%p0c0rmO +bP'*TFSp:[G4p.TGj9SKGk-(SG5$.3FR"#*FSg4ZG5HL`GlE!eH3/G@I/\QoIK4lsJ,t4Qre"O1 +Knb>;Ll$tGMib +]Y;.q^r!t+`5T^9aN2KGbKJ,ScHab_dF$Cje'umtf%0iP!SH*(g&g$ah#6(/hZ)L3i;_d8ir%j9 +jT"?=k5OQDkkjWDlMp2Im/QJPmelPQnGi%Vo)A7[o_eC]pAXg`q#:*gqYC$dr;?N_rdk+%s*t~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYs7?<_rpkR/nF,i6md9B-lg!a!ki_*jjlGI^io&bP +hVI#Cg=k64f@JL%eC2gmd*L"^bfe/NaN2B?`P]R0_8!b!]tCtg\[],W[C!9GZ*:I8Xf\Y(Wi2hn +VPL#_TqS-NSt2@?R[BJ/Q'IStP*(ieNfB!UMM[1GL5(D8K7\Z)J:E%JI1UaOH?jaZGBS+NFE;JB +EH#jqDA-l'CMR[!BP;$kAn>Oa@q/tW@:9(A!FB(2>R+J:>$5!1=BGK&s&B%ur_rhps&&bls%iYi +r([2br_*8`pnR/&o6]JCj$E[@r20Ikr20LlqhXj!e;!lhqF19Nq+(C]r2BRnqPsCWpltQ;rfZi9 +nWa&Tr`K&#r`];*qcs,+ra,M0ra>_6r*o\9!3,donX8s8!1E8BqK2XXrH@mYpiu(LpNZ7Qq0)LT +fQ?D$hK8X;rHA'^s*4NgrH\NlI!kpAs*artrdY$#K)UC/KS>/8LPUeDMMmFPNK0']OcklkPa.Q$ +R$a>3S"6.BTV8'SUnjlcVl?\rXKAV.Yd(L?['d?O\@K/^]Y(tn^VI_'_o0O5a2l?Db0.uPc-FV\ +d*^7hdaQ^qe^i=Nf)aOWrRq>-gt_kas5*e5rS[_7ro3k9roF+@qr[n@s60@Erp'OLqs=@MrpK^Q +rp]sXr:9jYrq--]rq??cqtU0drqcHfr;?KknG\"=f`-I~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYs7?<_rpkR/nF,i6md9B-lg!a!ki_*jjlGI^io&bP +hVI#Cg=k64f@JL%eC2gmd*L"^bfe/NaN2B?`P]R0_8!b!]tCtg\[],W[C!9GZ*:I8Xf\Y(Wi2hn +VPL#_TqS-NSt2@?R[BJ/Q'IStP*(ieNfB!UMM[1GL5(D8K7\Z)J:E%JI1UaOH?jaZGBS+NFE;JB +EH#jqDA-l'CMR[!BP;$kAn>Oa@q/tW@:9(A!FB(2>R+J:>$5!1=BGK&s&B%ur_rhps&&bls%iYi +r([2br_*8`pf75_oLI:u!(Gp6r`/ksqGdSr,1l?1s* +qfVj\qfi'brd"Hg!dfM2@+JN/WaVO-#KeP*;,qQC!u+R[]e; +St;UKTqeEZVPg>kWiE/&Xfnt6ZEppG[^WcW\\#Me^;%Fu_SX4/`Pom=aN;TJbKS5VcHjkbdF-Il +eC<%"f)F8%f\-5W!o)McrS@M1s53e5s5Et:r8[e;s5j.?roa=Fqs"+Fs6KRKs6]gRr9sXSs7-$X +rq$-]r:U'_rqH:*fr;H-aJcFC&J,~> +JcC<$JcGHDoD\^erquZjs8)`jrV-Hgp@eLYs7?<_rpg*[nG_m*md9B-lg!a!ki_*jjlGI^io/hQ +hVI#CgY1?5f@SU'eC2jnd*L"_bfe2PaN2EA`Pf[2_8*h#]tD"i\[f5Y[^EKKZE^X;Y-"e+Wi;qp +Vkp2bU7n9QSt;IAS!o_3Q^*i#P*1rhO,f3YMi*@JLPCP;KS+l-J:N,uI=6MCH4>.EGB\4QFEDSE +EH,r9rb`3_Chmg$BkV0mB4b^dA7PUJ!F]C8?NFJ=r`f\4>$>'3=BJZ(k +:Adid9`@Zd9&AG$ht3`.UZ\HQU]3[A62]^Bj8J';jo+?;[d(9t[-Y-qZM[,f7JfRK8,VQJkQgA9 +l07Kul08)dq8iWZqoSBNo?%$TqoJiZr`K#"r`]>+qcs,+ra,J/s'Yh7qdTS8s((rao?HXGr6+fV +qfMdZrH@mYq0:tGpiuCSq0)OUf6$8"j)k-?rHA$]s*4NgrH\NlI!kpAs*artrd\.&JqAW-KS>/8 +LPL\BM2I4MNK0'\OHG]hPa.N"Q^F20S"-%@T:hmPUSO``Vl6SpX/rG+YHY:;Za@-K\%&u[]=bhk +^VI\&_Sa@3`lH0Aai_fNc-FV\d/MDsdaQ^qe^`7Mf)aOWrn@D,s4mV0s5*e5rS[\6s5Nt:roF+@ +qr[n@roj:Erp'LKr9XFMrpK^Qrp]sXqssdYrq--]rq??cqtU0drVHBfr;?HjnG\"=f`-I~> +JcC<$JcGHDoD\^erquZjs8)`jrV-Hgp@eLYs7?<_rpg*[nG_m*md9B-lg!a!ki_*jjlGI^io/hQ +hVI#CgY1?5f@SU'eC2jnd*L"_bfe2PaN2EA`Pf[2_8*h#]tD"i\[f5Y[^EKKZE^X;Y-"e+Wi;qp +Vkp2bU7n9QSt;IAS!o_3Q^*i#P*1rhO,f3YMi*@JLPCP;KS+l-J:N,uI=6MCH4>.EGB\4QFEDSE +EH,r9rb`3_Chmg$BkV0mB4b^dA7PUJ!F]C8?NFJ=r`f\4>$>'3=BJZ(k +:Adid9`@Zd8tr'VU[W[%HN8BhHgZ4UHiHFn62[SOVYQ&>LXq4X7/KFM7e]FOW;W^mWr9!hQ2?g2 +PPUODQ26aE=Sc2">5qh(>lJ%.?Me+0@/aU3@fKs;LPUeDMMmFQNfT6_OckllQ'IZ% +R$jD4S=Q7DTV8*TUnsrdW2ZetXKAY/Yd(L?['d?O\@K2_]Y2%o^qmn)_o9U7a2l?Db0/#RcHab_ +rm:que'umte^j`O!SH*)gAfq-h#?.0hZ)L3i;V^8ir%j9jT"?=k5OQCkks]ElMg,Im/HDOmelPQ +nGi%Uo)J=\o_eC]pAXg`q#:*fqYL*er;6H^rdk+%s*t~> +JcC<$JcGHDoD\^erquZjs8)`jrV-Hgp@eLYs7?<_rpg*[nG_m*md9B-lg!a!ki_*jjlGI^io/hQ +hVI#CgY1?5f@SU'eC2jnd*L"_bfe2PaN2EA`Pf[2_8*h#]tD"i\[f5Y[^EKKZE^X;Y-"e+Wi;qp +Vkp2bU7n9QSt;IAS!o_3Q^*i#P*1rhO,f3YMi*@JLPCP;KS+l-J:N,uI=6MCH4>.EGB\4QFEDSE +EH,r9rb`3_Chmg$BkV0mB4b^dA7PUJ!F]C8?NFJ=r`f\4>$>'3=BJZ(k +:Adid9`@Zd8lSddf8^Bs)7fZ$V7/KFM7e]FE<;fh`:Amo^:B+,W:Amuf +=Sc2">5qh(>lJ%.?Me+0@/aU3@fKsVg^;%J"_SX40`Q#s>aN;TJbg"GYcd;[=#1CuM +eCE+#rmq2'g&B_*g]-(.h>c@3hu2L4iW%p8j8S->jnn3>kPj]Cl2KuIlhp,KmJcPOn,DhVnb_nW +oD\C[p&=[ap\Xabq>L0dqu$BhrUBf;s4I@%~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYs7?<_rpg*[nG_m+md9B-lg!a!ki_*jjlGI^io/hR +hqm2EgY1B7f@SU(eC2jndEp1ac-4ARaiMQC`Pod4_SO%&^:h1k]",A\[^NTMZa-g>YHG"/X/`.t +Vl$;dUS=HTT:VXES"#h5R$O#&P`h2lO,o<\N/NRMM2-h?KnP)1JUi9#IXQWks*>-"G^"@TF`__H +EcH)?_#/s&]8&r`0)#<)iiqs&/kor_WVj +s%`Jds%NDbq;:_3SrTO1D +qW\+IlM\j)aSEsBb4NgOb5PN?=oMV(>Ph\*?2e1-?iFI5@JaO5A,g'?A`E^J!T;u:iUkCZbl#Z[ +b5HG\Fo?LXGPZR@H22^WGPQFWFjtO!Fm!lBFo6FZGQ2peH2W'hHN8HlI:I_UIt3'#JV&N,KS5&6 +L51SAM2I4MN/`jYO-#KePE_>tQ^F/.S"#q=StD[LU8+N\VPgAlWiN5'Y->.8Za7$I[^WfX]"G\h +^;%J"_Sa=2`Q$!?ai_fMbg"GYcd:(edaS3F!S,d#f)aOWrn@D,!8RP/s5*e5rS[_7s5Nt:roF+@ +qr[n@roj:Erp'LKqs==Ls6fdQs7$$Xr:9jYrq--]rq??cqtU-crqcHfr;?KknG\"=fDg@~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYs7?<_rpg*[nG_m+md9B-lg!a!ki_*jjlGI^io/hR +hqm2EgY1B7f@SU(eC2jndEp1ac-4ARaiMQC`Pod4_SO%&^:h1k]",A\[^NTMZa-g>YHG"/X/`.t +Vl$;dUS=HTT:VXES"#h5R$O#&P`h2lO,o<\N/NRMM2-h?KnP)1JUi9#IXQWks*>-"G^"@TF`__H +EcH)?_#/s&]8&r`0)#<)iiqs&/kor_WVj +s%`Jds%NDbq4mM.mrhTIgr20"?q1mXXr'^ENqaU +PjFV1PkgUD=Sl8#>5hb'>lS+/?Me+/@/j[4@fBm;A-$8Ar2Tn!X/kfZhO+7`rH8'^pNQIYhKepA +oQU+SpiY).lZMB4q/uUYqKMsard"Hgs*F`nrI&1)It*!!JUrE*K7no3L5(J>M2@+JN/WaVO,oBb +P*;,qQ'[l*R@B\9SXuIHTq\c@3hu2L5iW%p8j8S->jnn3>kPj]Cl2KuIlhg&J +mJlVOn,MnVnbhtWoD\C[p&=[ap\Xaaq>U6dqu$BirUBf;s4@:$~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYs7?<_rpg*[nG_m+md9B-lg!a!ki_*jjlGI^io/hR +hqm2EgY1B7f@SU(eC2jndEp1ac-4ARaiMQC`Pod4_SO%&^:h1k]",A\[^NTMZa-g>YHG"/X/`.t +Vl$;dUS=HTT:VXES"#h5R$O#&P`h2lO,o<\N/NRMM2-h?KnP)1JUi9#IXQWks*>-"G^"@TF`__H +EcH)?_#/s&]8&r`0)#<)iiqs&/kor_WVj +s%`Jds%NDbq,QiQd74+%j[&oHr)EYqq,Z`OhFRQ7r'^ENqaUb7qdTP7s'u+@rETG/?2e*l;ta2_;uLh:Fo?LXGPZR@H22^W +GPQFWFjtO!Fm!lBFo6FZGQ2peH2W'hHN8HlI:I_UIt3'#JV&N,KS5&6L51SAM2I4MN/`jYO-#Ke +PE_>tQ^F/.S"#q=StD[LU8+N\VPgAlWiN5'Y->.8Za7$I[^WfX]"G\h^;%J"_Sa=2`Q$!?ai_fM +bg"GYcd:(edaS3F!S,d#f)aOWrn@D,!8RP/s5*e5rS[_7s5Nt:roF+@qr[n@roj:Erp'LKqs==L +s6fdQs7$$Xr:9jYrq--]rq??cqtU-crqcHfr;?KknG\"=fDg@~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYs7?<_rpg*[nG_k[md9B-lg"K6J*?(Xk2kX`io/hR +hqm2FgY1B7f[n^)eC;sqdEp4bcHOJTb/hZE`l5m6_SX+'^V7@n]=PP_\$i]OZa6p@Yck12XK/A# +W2HMhUnaZXTV%gHS=?"9R$a2)Q'7AoOcPQ`NJrdQM2@"BL4t;5Jq8H&IsufoH[:!`G^"@TFoQP" +F)l8?E,TW3D/F*)CMIQsBP1phAS#C^raGn:@/aL6?=!P8!F&b,=TV],=8l5%j>k +:]F2f:&doe9DRK6V#-qWV!=fUV#3RA62f[?hu;R5iVha9j5[TE[JdK1ZgP-t7/KFM7eT=R8EoC5 +lMKoEb506Cb4WmPaoGQ@=oMV(>Ph\)?2e1.?iFI4@JjU6A,g*aN;TJbg"GYcd:(edaHUoeCE.Lf)aOWrn@D,!8RP/!oDhlrS[_7s5Nt: +roF+@qr[n@roj:Erp'LKqs==LrpK^Qrp]pWr:9jYrq--]rq??cqY:'crqcHfr;?HjnG\"=fDg@~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYs7?<_rpg*[nG_k[md9B-lg"K6J*?(Xk2kX`io/hR +hqm2FgY1B7f[n^)eC;sqdEp4bcHOJTb/hZE`l5m6_SX+'^V7@n]=PP_\$i]OZa6p@Yck12XK/A# +W2HMhUnaZXTV%gHS=?"9R$a2)Q'7AoOcPQ`NJrdQM2@"BL4t;5Jq8H&IsufoH[:!`G^"@TFoQP" +F)l8?E,TW3D/F*)CMIQsBP1phAS#C^raGn:@/aL6?=!P8!F&b,=TV],=8l5%j>k +:]F2f:&doe9DP@OI-u@\HKTYQ6KUT6UApqbUAUedU]@7ZLt.:\LAaO;7JfRJ7fl5]Wr&jsWr9!s +XSeCSQ1gI8PPUO>PlOq`=oMV(>Ph\)?2e1.?iFI4@JjU6A,g*;LkpnE +MMmFPNK9-^OcklkPa.Q$R$a>3S"-(AT:qsQUnjibVl6VqX0&M,YctF>ZaI6M\@K/^]Y(tn^VI_' +_o0O6a2l?Db0/#RcHab_dF$Cje'umtf)F8%f\-8Xs4[P/rS7P3hr"Cjs5F";r8[e;s5j.?roa:E +r9=4Grp0IJrpB^Qr9sXSrpfpWrq$-]r:U'_rqH9arqZQiq>:*fqu-$`JcF@%J,~> +JcC<$JcGHDoD\^erVZTjrqcZjrV-Hgp@eLYs7?<_rpg*[nG_k[md9B-lg"K6J*?(Xk2kX`io/hR +hqm2FgY1B7f[n^)eC;sqdEp4bcHOJTb/hZE`l5m6_SX+'^V7@n]=PP_\$i]OZa6p@Yck12XK/A# +W2HMhUnaZXTV%gHS=?"9R$a2)Q'7AoOcPQ`NJrdQM2@"BL4t;5Jq8H&IsufoH[:!`G^"@TFoQP" +F)l8?E,TW3D/F*)CMIQsBP1phAS#C^raGn:@/aL6?=!P8!F&b,=TV],=8l5%j>k +:]F2f:&doe9)qrg<<-(i8*NMB8*WSA6KUT65hb'>lJ%.?Mn10@/aU4@fBm;AGp'@?!LV4>QA'j;ta2b;u^t=Fo6FXGPZRY +H1$"PH2;dXGPZLXFjkHpFn9_KFo-@YGQ)jeH2N!gHN8HlI0+kIJ,Xs!JV*lR?%dodL51S@M2@+J +N/WaWO-#KeP*;,qQC!u+R[]e:St;RJTq\?YV5L5iWiE,%Xfen4ZEpmF[^N]V\\#Me^;%Fu_SX4/ +`Q#s>aN;TJbg"GYcd:(edaHUoeCE.Lf)aOWrn@D,!8RP/!oDhlrS[_7s5Nt:roF+@qr[n@roj:E +rp'LKqs==LrpK^Qrp]pWr:9jYrq--]rq??cqY:'crqcHfr;?HjnG\"=fDg@~> +JcC<$JcGHDoD\^erquZjrqcZjrV-Hgp@eLYs7?<_rpg*[nG_m*md9B-lg*j#l0.OaA,]pA@:3GL?=$q:>QJ&4r`K;)=',B%!``3!r_rhp!)`\k +s%iYir([/aqVV1GpSHuIr2'%]rM9LiqEjC3rnIG-s5!V0!8me6iO8TjppBn(pp0idqF1; +Ll$tGMic@3hu2L5iW%p9j8S->jnn3> +kPj]Bl2KuIlhg&JmJlVOn,DhUnbhtWoD\CZp&=[ap\Xabq>L0cqu$BirU9`:s4@:$~> +JcC<$JcGHDoD\^erquZjrqcZjrV-Hgp@eLYs7?<_rpg*[nG_m*md9B-lg*j#l0.OaA,]pA@:3GL?=$q:>QJ&4r`K;)=',B%!``3!r_rhp!)`\k +s%iYir([/aqP3q8q0i'dmsG"Zl?i@okX#*=q4[h_!2Jq;eVF)kqF1;Ll$tGMic@3hu2L5iW%p9j8S->jnn3>kPj]Bl2KuIlhg&JmJlVO +n,DhUnbhtWoD\CZp&=[ap\Xabq>L0cqu$BirU9`:s4@:$~> +JcC<$JcGHDoD\^erquZjrqcZjrV-Hgp@eLYs7?<_rpg*[nG_m*md9B-lg*j#l0.OaA,]pA@:3GL?=$q:>QJ&4r`K;)=',B%!``3!r_rhp!)`\k +s%iYir([/ar`&hrm76D1s$uEFqEjC3o2P]hg.CL!rC$KNr'pBMr^cugrE&bpoM,-Vj%]>EqcWr& +r`f8)ra#M0qd9A2raG\5s'u%=r+5k3s',V2?=)Pgp/LofrH8'^pilU[q0D+Kpj)^\oQU1Uq/su) +drkP2q02g_s*=Ngs*F`nrI"`rIt.HJ@Y',_K7ei2Knb>;Ll$tGMic@3hu2L5iW%p9j8S->jnn3>kPj]Bl2KuIlhg&JmJlVOn,DhUnbhtW +oD\CZp&=[ap\Xabq>L0cqu$BirU9`:s4@:$~> +JcC<$JcGHDoD\^erVZTjrqcZjrV6Ee!;?Ebs7?<_rpg9`nF5o8md:#?J*ZCal0..EGB\4Q +FEDSEEH,r9rb``nChmg$BkV0mAnGUcA7K(X@:[1K;>5hY+=BAT'k:Adid9`!Z8V:).>V>*CA62oR:gA'G&gu,X.[JdK3Zi.3.7/KFM7e]FO8GqiIlhJ]ubQ#`] +bO`mOana*X=oMV(>Ph\)?2e1.?iFI4@JjU6A,g*:AcHBBhuMa7ipk:abkBifb&qk*G5-:Z +GklXDHMMj_GkH:XG56:*FOt[3G56@]GlE!dHN/?lI/\QoIK4lsJH(0,JqJ]/KS>/8LPYqd:Pt'h +N/`jYOHG]hPE_>tQ^F/.R[]hVg^;%J"_Sa=2 +`Q-'@ai_fMc-FV\d*^7he,Ii)e^i@(f\+s3g=tB;rn[V2s53h6s5F";r8[h:*fqu-$`JcF=$J,~> +JcC<$JcGHDoD\^erVZTjrqcZjrV6Ee!;?Ebs7?<_rpg9`nF5o8md:#?J*ZCal0..EGB\4Q +FEDSEEH,r9rb``nChmg$BkV0mAnGUcA7K(X@:[1K;>5hY+=BAT'k:Adid9_tORIJJ9gHi8?OHN8Hg6Kpf*T^.EcL]'X<7JfRK8,Z!TXSo3sXSA+LQ0OV0Q2Okb +>5hb'>lJ%.?Mn10@/aU4@fBm;AG]s/8LPYqd:Pt'hN/`jYOHG]hPE_>tQ^F/. +R[]hVg^;%J"_Sa=2`Q-'@ai_fMc-FV\d*^7h +e,Ii)e^i@(f\+s3g=tB;rn[V2s53h6s5F";r8[h:*fqu-$`JcF=$J,~> +JcC<$JcGHDoD\^erVZTjrqcZjrV6Ee!;?Ebs7?<_rpg9`nF5o8md:#?J*ZCal0..EGB\4Q +FEDSEEH,r9rb``nChmg$BkV0mAnGUcA7K(X@:[1K;>5hY+=BAT'k:Adid9`%chnh:%D'E +:&.Q_=oMV(>Ph\)?2e1.?iFI4@JjU6A,g*:AcHBB>6J2:?=.(=<8^^K<;ohrFo?LYGPl^]H/X)F +H2;dYGPcRZFj5$[Fo$:WGQ)jdH2N!gHiJKmIK+`rJ,XuuJI-p\K7no3L5(J>reXF.Mi +JcC<$JcGHDoD\^erVZTjrqcZjrV6Ee!;?BaJ+W@(o()>@nF,i6mHs9,lg!a!ki_*jjlGI^io/hR +hqm2FgtLK8f[na+eC;sqdF$:ccHXSVb/q`Ga2Z*:_ns:+^V@Lr]Xtbc\[T#U[Bm3FZ*:F7XfSS' +Wi2hnV50o^TqS-NSt2C@R[KP0QBd\uP*1ofO,f0XMi*@IL]<)WKnP)1JUi9#IXQWkH?sj]GB\4Q +FEDSEEH,r9DJj<.Chmg$BkV0mB)Z?QA7K(X@:[1K;>5hY*=BGK&s&B%urDW_o!)`\k +s%iYir(R/bqqq%Bs/,[ie"l_)ks>7"rRq&$hR;j[r3ZC.r^?WPqaUr`]>+qcs,+ra,J/s'Yh7r*oY8rabqStD[LU8+N\VPgAlWiN5'Y->.8Za7$I[^WfX]"G\h^V@S$_Sa=2`lH0AaihlO +c-FV\d*^7he'umtf%8O+f\-8X!ScE/h>c=3hu2L5iW%p9j8\3>jo"9?kPscCl2BoHlhg&JmJcPN +n,DhUnb_nVoD\CZp&=[ap\Xaaq>U6cqu-HirU9`:s474#~> +JcC<$JcGHDoD\^erVZTjrqcZjrV6Ee!;?BaJ+W@(o()>@nF,i6mHs9,lg!a!ki_*jjlGI^io/hR +hqm2FgtLK8f[na+eC;sqdF$:ccHXSVb/q`Ga2Z*:_ns:+^V@Lr]Xtbc\[T#U[Bm3FZ*:F7XfSS' +Wi2hnV50o^TqS-NSt2C@R[KP0QBd\uP*1ofO,f0XMi*@IL]<)WKnP)1JUi9#IXQWkH?sj]GB\4Q +FEDSEEH,r9DJj<.Chmg$BkV0mB)Z?QA7K(X@:[1K;>5hY*=BGK&s&B%urDW_o!)`\k +s%iYir(R/bqkNe3s*jinnU0ePomHL#ks=j4lA4)Jr^?WPqaU+qcs,+ra,J/s'Yh7r*oY8rabqlI3i;_d9ir.p;jSn9=k5OQDkkjWClMg,Hm/HDOmecJPnG_tTo)A7[ +o_\=\pAXg`q#1$fqY9sdr;6H]rdk+#s*t~> +JcC<$JcGHDoD\^erVZTjrqcZjrV6Ee!;?BaJ+W@(o()>@nF,i6mHs9,lg!a!ki_*jjlGI^io/hR +hqm2FgtLK8f[na+eC;sqdF$:ccHXSVb/q`Ga2Z*:_ns:+^V@Lr]Xtbc\[T#U[Bm3FZ*:F7XfSS' +Wi2hnV50o^TqS-NSt2C@R[KP0QBd\uP*1ofO,f0XMi*@IL]<)WKnP)1JUi9#IXQWkH?sj]GB\4Q +FEDSEEH,r9DJj<.Chmg$BkV0mB)Z?QA7K(X@:[1K;>5hY*=BGK&s&B%urDW_o!)`\k +s%iYir(R5d+qcs,+ra,J/s'Yh7r*oY8rabq[:WA?=.+:<8^^P<;]\oG5-:ZGku^AHMMj`GkH:X +G5?@)FPM$7G5-:[GlN'eHN/?lI/SKnIK4lsJH(0#K)UB'KSBD[?&+5mM2I4MN/`jYO-#KeP*;/r +QC!u+R[]e:St;RITq\aN;WKbg"GY +cd:(edaQ^qe^i@(f\"mVg&]s`rn[V2!8mb5s5F";rT!q=roO(?roa=Fqs"(Erp0IJrpB^QqsXOR +rpfmVrq$-]qt9s^rqH +JcC<$JcGHDoD\^erVZTjrqcZjrV6Ee!;?BaHh?q$o()>@nF,i6md9B-lg!a!ki_*jjlGI^io/hR +hqm2FgtUQ:f[na+e^W*sdF$=ecHaYWbK@rJa2Z*;`5BI.^q[Xt]Y(kf\[],W[^$Co.!E`G&j:Amoei;MR&VYd4@V"@">5lfL6fDXA$g&Kd][edE([K*`4[/NJj7JfRK8,PpX8HA/Vm.TcC +bQ,oUbk'$Tb595hb'>lJ%.?Mn10@/aU4@fBm;AG]sZaI6M\@K/^]Y(tn +^VRe(_o9U7a2lBFbKJ,ScHjkbdF-LneCE.$f@S[.rn7D-h#?.0h>lI3i;_a9ir.p:jT"?>k5OQD +kkjWDlM^&Gm/HDOmeZDOnG_tTo)A7[o_\=\pAXg_q#:*fqYC$dr;6H^rdk+"s*t~> +JcC<$JcGHDoD\^erVZTjrqcZjrV6Ee!;?BaHh?q$o()>@nF,i6md9B-lg!a!ki_*jjlGI^io/hR +hqm2FgtUQ:f[na+e^W*sdF$=ecHaYWbK@rJa2Z*;`5BI.^q[Xt]Y(kf\[],W[^$Co.!E`G&j:AmoeV#@(WIe8'FI.Tbk62RANT]_."L\$?!L]0^=7JfRK8,PpX8boF_XT+XPQL0t7Pkp[F +=oMV(>Ph\)?2e1.?iFI4@JjU6A,g*:AcHBAB)lWEX8]3ZRJ3*DQN24(GPl^^H.dN@H2DjZGPcR[ +FingcFn^(RGPudcH2N!gHiJKlIK+`rJ,XuuJH1<$K)pXZre:T3Ll$tGMuJZ7NK0']OcklkPa.N" +R$a;1S"-%@StMdNU84T]Vl-JnWiN8(YHY7:Za7'J[^`lY]=bej^V@V%_Sa@3`lH0Bb0.uPc-FY^ +dF$CkeC<%"f%8O+g&B\+gYDeas5!b5rS[_7!93t;roF+@r9""As60@Erp'IJqs==LrpKXOrp]pW +qssaXrq-*\rq??cqY:'crVH?er;?HjnG\"=ec1.~> +JcC<$JcGHDoD\^erVZTjrqcZjrV6Ee!;?BaHh?q$o()>@nF,i6md9B-lg!a!ki_*jjlGI^io/hR +hqm2FgtUQ:f[na+e^W*sdF$=ecHaYWbK@rJa2Z*;`5BI.^q[Xt]Y(kf\[],W[^$Co.!E`G&j:Amoe)r`f8)ra#M0r*TG2raG_6raYt=qdoe>rau4Era,V3!+>P#fM_cn +pilX\qK^b?qg&'`olp:VqK9r&icY!=pNQR\rd"Efs*OcnrI+]p!.Xuus+(0%rdt6)L&Qf1LPUeD +MMqImtQC+&-R[]hai_fMbg"GZd*^7he'umtf%/I)f\-8X!ScE/h>c=3hu2L5i;hm9j8S->jo"9?kPscC +l2KuHlhg&JmJcPMn,DhUnb_nVoD\CZp&=[ap\O[aq>L0cqu$BhrUBf;s4.."~> +JcC<$JcGHDoD\^erVZTjrqcZjrV6Ees7ZHb#P@WZo()>@nG_m+md9B-lg!d"l0.`P]R0_8*h"]tD"i\[f5Z[^EKKZa-g>YHG"/ +X/`.tVl-AeUnXQVTUqaGS=>t8R$X,(P`q8nOH5H_N/W[PM26qAL4t;5Jq8H&+b+rhI=-BfH$FOW +G'.nKF)l8?E,TW3D/F*)CMIQsBP1rVAI;sX@U`bR?sd8I?2e(6>?Y35=]ed-r`9&!!*&nqs&&ho +rD%[f*Vk[edE([f!Q57/B@M7eT@N8H)0\ +mJQ>Flho!%c0`aPbOPqb*?2e1-?iOO5@JjU6A,^$:Ac?G4p.YGlE!cHN/?lI/SKnIK4lsJH(0#K)UC>KS>,7L51S@M2@+J +N/WaVO,oBbP*2#nQ'Rc(R$jD4S=Q7DTV8'SUnjlcVl?\rXKAV.Yd(L?['d?O\@K2_]Y2%o^qmn* +`5T^9aN2KGbKS5VcHjkbdF-LneCE.%f@\d0g=k<:gtgfChV\:i!o`.urT!q=s5j1@roa=Fqs"+F +rp0FIrpB^QqX=FQrpfmVrq$-]qXsj]rqH9arqZNhq>:*fqu-!_JcF:#J,~> +JcC<$JcGHDoD\^erVZTjrqcZjrV6Ees7ZHb#P@WZo()>@nG_m+md9B-lg!d"l0.`P]R0_8*h"]tD"i\[f5Z[^EKKZa-g>YHG"/ +X/`.tVl-AeUnXQVTUqaGS=>t8R$X,(P`q8nOH5H_N/W[PM26qAL4t;5Jq8H&+b+rhI=-BfH$FOW +G'.nKF)l8?E,TW3D/F*)CMIQsBP1rVAI;sX@U`bR?sd8I?2e(6>?Y35=]ed-r`9&!!*&nqs&&ho +rD7JoXK8,Z!X8c#L_ +X8nODQKaY7=oMV(>Pqb*?2e1-?iOO5@JjU6A,^$:Ac?G4p.YGlE!cHN/?lI/SKnIK4lsJH(0#K)UC>KS>,7L51S@M2@+JN/WaVO,oBb +P*2#nQ'Rc(R$jD4S=Q7DTV8'SUnjlcVl?\rXKAV.Yd(L?['d?O\@K2_]Y2%o^qmn*`5T^9aN2KG +bKS5VcHjkbdF-LneCE.%f@\d0g=k<:gtgfChV\:i!o`.urT!q=s5j1@roa=Fqs"+Frp0FIrpB^Q +qX=FQrpfmVrq$-]qXsj]rqH9arqZNhq>:*fqu-!_JcF:#J,~> +JcC<$JcGHDoD\^erVZTjrqcZjrV6Ees7ZHb#P@WZo()>@nG_m+md9B-lg!d"l0.`P]R0_8*h"]tD"i\[f5Z[^EKKZa-g>YHG"/ +X/`.tVl-AeUnXQVTUqaGS=>t8R$X,(P`q8nOH5H_N/W[PM26qAL4t;5Jq8H&+b+rhI=-BfH$FOW +G'.nKF)l8?E,TW3D/F*)CMIQsBP1rVAI;sX@U`bR?sd8I?2e(6>?Y35=]ed-r`9&!!*&nqs&&ho +rDPqb*?2e1-?iOO5@JjU6A,^$:Ac?;LkpnE +MMmFPNK0'\OHG]hPE_>uQ^F/.R[]hkWiE/&Xfnt6ZEppG[^WcW]">Vg^;%J" +_Sa=2`Q-'@ai_fNc-FV\d*^7he'umtf%8O+g"G*5gYCT?h;7#GrSRb9io9pss5a4Ar9""As60@E +rp'LKqX"4KrpKXOrp]pWqssaXrq-'[rq??cqY:'crVH?er;?Hjn,@n +JcC<$JcGKEoD\[drquZjrqcZjrV6Ee!;?Ba#P@WZo()>@nG_m*md9B-lg!d"l0.,Q'@JqOcYWbNf8pTMM[.EL5(D8K7\[SJ/EcbI=6KhH?jaZ +GBS+NFE;JBEH#i6DJa4hCCY)nBP;$jAS#C_@q&nU@/aL6?=!P8!F&b,=oVS(=8l8#<<-"s;Z]io +;>j>j:]F/o:"n@Wh;7&dV=CGXV;A$H6hNe562&n.fDi;1[K!W6[J%'.[JiSk7JfRK8,Z!V8HA,R +li68Jli#&rc1B0VbONaS>5qh(>lJ%.?Mn10@/aU4@fBm;AG]s:*fqu-!_JcF7"J,~> +JcC<$JcGKEoD\[drquZjrqcZjrV6Ee!;?Ba#P@WZo()>@nG_m*md9B-lg!d"l0.,Q'@JqOcYWbNf8pTMM[.EL5(D8K7\[SJ/EcbI=6KhH?jaZ +GBS+NFE;JBEH#i6DJa4hCCY)nBP;$jAS#C_@q&nU@/aL6?=!P8!F&b,=oVS(=8l8#<<-"s;Z]io +;>j>j:]F/o9qS)OTq\=ZIHl:XIH>kVIJlP+6L@)4T`(SFM!p,hM#Kg>7JfRK8,Z!V8c5XgXT,@! +XSnF\Q2m31QLU7>>5qh(>lJ%.?Mn10@/aU4@fBm;AG]s;LPUeDMMmFPNK0$[ +OHG]hPE_>tQC!u,R[]e:St;RITq\ +aN;WKbg"GYcdC.ge'umtf)F8*f\,!4gY:N_h#ZBirSRb9io9pss5a4ArT=+Bs60@Erp'LKqX"4K +rpKXOrp]mVqssaXrq-*\rV$6bqY:'crVH?er;?Hjn,@n +JcC<$JcGKEoD\[drquZjrqcZjrV6Ee!;?Ba#P@WZo()>@nG_m*md9B-lg!d"l0.,Q'@JqOcYWbNf8pTMM[.EL5(D8K7\[SJ/EcbI=6KhH?jaZ +GBS+NFE;JBEH#i6DJa4hCCY)nBP;$jAS#C_@q&nU@/aL6?=!P8!F&b,=oVS(=8l8#<<-"s;Z]io +;>j>j:]F/i:&\#n;cHad7f>jL8GbpS7dieC7fGpR7f>^I6L@)=<;onp<;fbm8``M18c)'X8,bpR +7JfRK8,Z!V8buQg=8Z2!9_hEY:@_3V:@_-Y>5qh(>lJ%.?Mn10@/aU4@fBm;AG]s:*fqu-!_JcF7"J,~> +JcC<$JcGKEo)AUdrquZjrqcZjrV6Ees7ZHb!qc*Urpg*[nG_kWmd:#?Id?:`l0.Oa@q/tW@:9(A!FB(2>QJ&4r`T8'!*B/#s&B%urDW_o +!)`Yjs%iYi"k_M]g=tE^V5hb'>lJ%/?Me+/@/j[4@fKs;AGg$ +k5XWDkks]ElMg,Gm/HDNmecJOnG_tSo)A7[o_\=[pAXg_q#1$fqY9scr;6H]rdk+!s*t~> +JcC<$JcGKEo)AUdrquZjrqcZjrV6Ees7ZHb!qc*Urpg*[nG_kWmd:#?Id?:`l0.Oa@q/tW@:9(A!FB(2>QJ&4r`T8'!*B/#s&B%urDW_o +!)`Yjs%iYirgj1`TV2:4k'm,Sm1s'be6s'u%=r+5k>rb).B!,;A4!3Q'c!L]D=RJN +k5XWDkks]ElMg,Gm/HDNmecJOnG_tSo)A7[o_\=[pAXg_q#1$fqY9scr;6H]rdk+!s*t~> +JcC<$JcGKEo)AUdrquZjrqcZjrV6Ees7ZHb!qc*Urpg*[nG_kWmd:#?Id?:`l0.Oa@q/tW@:9(A!FB(2>QJ&4r`T8'!*B/#s&B%urDW_o +!)`Yjs%iYiqbdJa7Rm8FoLSsOpdY0MoLAXHr'pQNoKr"4o2Pciq+9[=mRd4Fs$Z`QqaUPh\)?2n7.?iFI5@JaO6A,^$:Ac?<@BDcECC&VK>?iXX0 +<7t4JGPl^`H0KVTHg,kRH2Mp\GPlX]FiSUnFnBkLGPl^bH2DpeHiJKlIK+crJ,XuuJH1<$KE$T) +L&Qg4LPUeDMMd=NN/`jYO-#KeP*;,qQ'[l*R@9V8SXuFFTqS3VUnsrdW2ZetXKAY/Yd(L?['mEP +\[f;a]Y2(p^r!t+`5Ta:aN;TJbKS5Vcd:(edaQ^qe^i@(f\-8X!ScE/h#cHjhu;O8iSrkrj8\3? +jo"9@kPj]Cl2KuIlh]uImJZJMn,;bTnbVhUoD\CZp&4U`p\O[`q>U6cqu$BhrU9`:s4%(!~> +JcC<$JcGKEo)AUdrquZjrqcZjrV6Ees7ZHbs7?<_rpkO.nF5o8md9E.m-Es$l0.?ok2tddj5].X +i8EMLh;-l?g=b-1f@JL%eC2jnd*L"_c-4ASb/hZE`l5p8_ns7*^V@Lr]Xtbc\[])V[C!9GZ*:I9 +Xf\\*Wi;qpVPU)`U7n9QSt;LBS!ob4Q^3o$PEM&iO,o<[N/NRMLkl"b+,,B#Jq8H&IsufoI!^0b +G^"@TF`__HEcH)5h\)=9)G%eb@Yl[dLQWZiEMj7JoXL8,PpV8cMEYlMp2M +m/HG2c2>fQbPk`D>lJ%.?Mn10@/aU4@fBm:AGg$=B)ZH@B`;]HC?,9RqTe`Xj37LHr-8-bn9XPM +n9Y"Xr-7pZr-%s[`cUfpolfqNr-83dqKi0grd=Zms*jutrdb$"!.t3&s+CB+re:H/M#N61MMmFP +NK0'\OHG]hPE_>tQC!u+R[]e:SXuIHTqS6WUo(&fW2ckuXf\b1Yd(O@[C3NR\[f>b]Y;.q_8=(- +`Poj +JcC<$JcGKEo)AUdrquZjrqcZjrV6Ees7ZHbs7?<_rpkO.nF5o8md9E.m-Es$l0.?ok2tddj5].X +i8EMLh;-l?g=b-1f@JL%eC2jnd*L"_c-4ASb/hZE`l5p8_ns7*^V@Lr]Xtbc\[])V[C!9GZ*:I9 +Xf\\*Wi;qpVPU)`U7n9QSt;LBS!ob4Q^3o$PEM&iO,o<[N/NRMLkl"b+,,B#Jq8H&IsufoI!^0b +G^"@TF`__HEcH)5h\)=9)G%Pqb*?2e1.?iFI4@JjU6A,^$:AcHBABDcHBB`VtMrN5pbigKY1 +r0RD,r-8-bn9XPMn9Y"Xr-7pZr-%s[`cUfpolfqNr-83dqKi0grd=Zms*jutrdb$"!.t3&s+CB+ +re:H/M#N61MMmFPNK0'\OHG]hPE_>tQC!u+R[]e:SXuIHTqS6WUo(&fW2ckuXf\b1Yd(O@[C3NR +\[f>b]Y;.q_8=(-`Poj +JcC<$JcGKEo)AUdrquZjrqcZjrV6Ees7ZHbs7?<_rpkO.nF5o8md9E.m-Es$l0.?ok2tddj5].X +i8EMLh;-l?g=b-1f@JL%eC2jnd*L"_c-4ASb/hZE`l5p8_ns7*^V@Lr]Xtbc\[])V[C!9GZ*:I9 +Xf\\*Wi;qpVPU)`U7n9QSt;LBS!ob4Q^3o$PEM&iO,o<[N/NRMLkl"b+,,B#Jq8H&IsufoI!^0b +G^"@TF`__HEcH)5h\)=9)G%UF6L[;4Pqb*?2e1.?iFI4@JjU6A,^$:AcHBABDcHBBa/jWiE,%Xfen4Z*UdE[^N]V\\#Me^;%G! +_SX71`Q$!?ai_fNc-FV\d*^7ieC<%"rmq>+g"P07h#?+2hV[5ihu_lsir8! +JcC<$JcGKEo)AUdrVZTjrqcZjrV6Ees7ZHbs7?<_rpgHenF5o8mdBK/m-Es9l$_dYk2tddj5].X +i8EMLh;-l@g=k64f@SR&eC2jndEp4bcHXPUb/q`Ga2Z*;_ns:,^q[Xu]Y(kf\[f2X[^EKKZE^X< +Y-"h-WiE%sVl$;dUS=HUT:VXFS"#k6R$X,(P`q8mOH5H_N/W[PM26qAL4t;5Jq8H&Isufo+aeW_ +H$FOWG'.nKF)l8?E,TW3D/=!'C2.HrBP1pgARo?_#/s&]8&r`9&!!*&nq +s&/korDPqb*?2e1.?iFI4@JjU6A,g*:AcHBABDcHBC&_rJjSn3bl;nc +Gl)dWHKokJHM`!cGkZF[G5HFIFT-@?FS0eMG4KkTGl;paHN/?kI/SKnIfForJH(0#K)UE&KE-`* +L&m'creXd8MitQ^F/.R[]e;St;RITq\NnGVnSo)81Zo_S7[pAOa^q#1$eqYC$dr;6H\rdk*us*t~> +JcC<$JcGKEo)AUdrVZTjrqcZjrV6Ees7ZHbs7?<_rpgHenF5o8mdBK/m-Es9l$_dYk2tddj5].X +i8EMLh;-l@g=k64f@SR&eC2jndEp4bcHXPUb/q`Ga2Z*;_ns:,^q[Xu]Y(kf\[f2X[^EKKZE^X< +Y-"h-WiE%sVl$;dUS=HUT:VXFS"#k6R$X,(P`q8mOH5H_N/W[PM26qAL4t;5Jq8H&Isufo+aeW_ +H$FOWG'.nKF)l8?E,TW3D/=!'C2.HrBP1pgARo?_#/s&]8&r`9&!!*&nq +s&/korDt_TDa63J*qdGI/l\26hE_862mJPTDbGSM>N2,MPqb*?2e1.?iFI4@JjU6A,g*:AcHBABDcHBC&_rGXo4^FRJ<0LQiD:. +Gl)dWHKokJHM`!cGkZF[G5HFIFT-@?FS0eMG4KkTGl;paHN/?kI/SKnIfForJH(0#K)UE&KE-`* +L&m'creXd8MitQ^F/.R[]e;St;RITq\NnGVnSo)81Zo_S7[pAOa^q#1$eqYC$dr;6H\rdk*us*t~> +JcC<$JcGKEo)AUdrVZTjrqcZjrV6Ees7ZHbs7?<_rpgHenF5o8mdBK/m-Es9l$_dYk2tddj5].X +i8EMLh;-l@g=k64f@SR&eC2jndEp4bcHXPUb/q`Ga2Z*;_ns:,^q[Xu]Y(kf\[f2X[^EKKZE^X< +Y-"h-WiE%sVl$;dUS=HUT:VXFS"#k6R$X,(P`q8mOH5H_N/W[PM26qAL4t;5Jq8H&Isufo+aeW_ +H$FOWG'.nKF)l8?E,TW3D/=!'C2.HrBP1pgARo?_#/s&]8&r`9&!!*&nq +s&/korDrb).Brb;CIs'Yk8!+Pn,r)DVg +^;%J"_Sa=2`Q-'@aihlOc-FV]dF$CkeC<%"f@S[.rn7S2gtgfChV\=j!o`.uro=%>s5j4As6'FG +qs".Grp0FIrpB^Qq="=PrUKdUrU^$\qXsj]rV-0`rV?Egq>:*fqu,s^JcF4!J,~> +JcC<$JcGKEo)AUdrVZTjrqcZjrV6Ees7ZHbs7?<_rpp*Z!:^!VI.$Cgm-F!&l07Epk2tddj5].Y +iS`YOh;-l@g=k64f@SU(eC;sqdF$=dcHXSVbK@rJaN)<>`5BI/_8*h#]tD"i]",>[[^NTNZa-j? +Ycb+1XK&;"W2HMhUnaZXTq@pJS=?":R$a5+Q'@JqOcYWbNf8pTMM[.EL5$q,KS+l-J:N,uI=6Ki +H?jaZGBS+NFE;JBEH#i6DJa3*CMIS_BE`$\AS#C^raH(??sd8I?=!P8!F&b,=TV],=8l8#<<-"s +;u]bq;>j;k:]8uBVY-k[VWalOU]lJ%.?Mn10@/j[4@fKs;AGg$tQC!u+R@9V8SXuFGTqS3UUnsrdW2ZetXKAY/Yd(L?['d?O\@K2_ +]Y2%o^qmn*`5Ta:aN2NIbKS5Vcd:(edaQ^qe^i@(f\,!4gYDea!T)`5hu_lsir8!NmeZDNnGVnRo)A7Zo_S7[pAOa^q#1$eqY9scr;6H]rdk*ts*t~> +JcC<$JcGKEo)AUdrVZTjrqcZjrV6Ees7ZHbs7?<_rpp*Z!:^!VI.$Cgm-F!&l07Epk2tddj5].Y +iS`YOh;-l@g=k64f@SU(eC;sqdF$=dcHXSVbK@rJaN)<>`5BI/_8*h#]tD"i]",>[[^NTNZa-j? +Ycb+1XK&;"W2HMhUnaZXTq@pJS=?":R$a5+Q'@JqOcYWbNf8pTMM[.EL5$q,KS+l-J:N,uI=6Ki +H?jaZGBS+NFE;JBEH#i6DJa3*CMIS_BE`$\AS#C^raH(??sd8I?=!P8!F&b,=TV],=8l8#<<-"s +;u]bq;>j;k:]6p]IeA3ZIcYtX7/0.B6L[;9TDbGRM>N2%M=-2pM#]s@7JfRL8,PpV8c23ZWr8t% +XKAV-Y-7VeqNgN6m$@ZUr*95,ra,M0ra>b7qdTS8rabq;pN?4RnTXnUrH\6crd4Zmr-eTos*suts+(0%re(6(!/:E, +@u#krM2@+JMiaND]Lbg"GZd*^7he'umtf%8O+g"P07h#?+1hV\=j!o`.uro=%>s5j7B +roa=Fr9=7Hrp0IJrU'UPqX=CPrUKaTrq$*\qXsj]rV-0`rV?Egq"t!equ-!_JcF0uJ,~> +JcC<$JcGKEo)AUdrVZTjrqcZjrV6Ees7ZHbs7?<_rpp*Z!:^!VI.$Cgm-F!&l07Epk2tddj5].Y +iS`YOh;-l@g=k64f@SU(eC;sqdF$=dcHXSVbK@rJaN)<>`5BI/_8*h#]tD"i]",>[[^NTNZa-j? +Ycb+1XK&;"W2HMhUnaZXTq@pJS=?":R$a5+Q'@JqOcYWbNf8pTMM[.EL5$q,KS+l-J:N,uI=6Ki +H?jaZGBS+NFE;JBEH#i6DJa3*CMIS_BE`$\AS#C^raH(??sd8I?=!P8!F&b,=TV],=8l8#<<-"s +;u]bq;>j;k:]45f7eK:?7cd,?7/0.B6L[;5\b8``M18cM<]7/KFM7efLO8Gu-X9)2Ng=Su7j +:@1dO:@q9\>Pqb*?2e1.?iFI5@JaO6A,^$:Ac?<@BDcHCC&VlIC]7`C@TE)#h,=;Qr-8-bo6TPG +np:4Zr-7s[r-&!\m<&&Cj`L6>pNH(Nr-80cqKi-fs*X`ms*jutrIFp!!.t3&s+CB+re=p +JcC<$JcGKEo)AUdrVZQis8)ckr:g?fp@eIX!qc*Urpg*[nG_kWmd:#?J*ZCal0.[[^NTMZa-j? +YHG"0XK&;"W2HMhUnaZXTV%gIS=?":R$a5+Q'@JqOcYWbNf8pTMM[.EL5(D8K7\Z)J/j&fI=6Kh +H?jaZGBS+NFE;JBEH#i6DJa3*CMIS_BE`$\AS#C^raH7D?sd8I??b;1=TV],=8l8#j>jfDsY!VY-k\VWXfRV#<^W6hE_962f=.ea^-2[e@-(ZiEMk7JoXL8,PpV8c23\m/HDP +mf2bUn,i.No'aj#cLfBSbk]E^>Pqb*?2e1.?iFI5@JaO6A,^$:Ac?<@BDcHCC&VlHC]*5fblH&_ +c/m1JGl2jYHK9GEHMi'dGkcL\G5HFOFRO;9FSBqQG4KkTGl2j`HN&9jI/JEmIfForJ-(:RK)UE& +KE-`*L'rcmLl$tGMMmFPNK4"!?]^D5P*;,qQ'Rf)R@9V7S=Q7DTV8'SUnjibVl6VqX0&M,YctC= +Za@0L\%0&\]Y(qm^VI_'_o0O6a2lBFbKJ/UcHjkbdaQ^qe^i@(f\,!4gYCT?h;7&Hi8ESQir8!< +j8e +JcC<$JcGKEo)AUdrVZQis8)ckr:g?fp@eIX!qc*Urpg*[nG_kWmd:#?J*ZCal0.[[^NTMZa-j? +YHG"0XK&;"W2HMhUnaZXTV%gIS=?":R$a5+Q'@JqOcYWbNf8pTMM[.EL5(D8K7\Z)J/j&fI=6Kh +H?jaZGBS+NFE;JBEH#i6DJa3*CMIS_BE`$\AS#C^raH7D?sd8I??b;1=TV],=8l8#j>jT)bPXIeA3ZId):Z7/94B6LmG;TDbGPM>N1`M#]s@7JoXL8,PpV8c23\X8]4#Xo5F& +Y5kg+R/30@QLL10Q2k.e>lJ%.?Mn10@/j[4@fKs;AGg$ai_fMc-FV\d*^:jeC<%"f@S[.g=k<:gtgfChr!AMiSieqj8\0?jo+?A +kPscDl2U&Jlhg&JmJZJLn,;bTnbMbToDS=Xp&4U`p\FU_q>L0bqu$BhrU9`:s3^js~> +JcC<$JcGKEo)AUdrVZQis8)ckr:g?fp@eIX!qc*Urpg*[nG_kWmd:#?J*ZCal0.[[^NTMZa-j? +YHG"0XK&;"W2HMhUnaZXTV%gIS=?":R$a5+Q'@JqOcYWbNf8pTMM[.EL5(D8K7\Z)J/j&fI=6Kh +H?jaZGBS+NFE;JBEH#i6DJa3*CMIS_BE`$\AS#C^raH7D?sd8I??b;1=TV],=8l8#j>j;ZKej7eK:B7cm5>7/94B6LmG7lJ%.?Mn10@/j[4@fKs;AGg$H1Q@CHh2R] +H2Mp^GPlX]FmsMAF6[lAFng.NGPl^`H2;jdHiAEjIK+crJ,Om!JV&LQKE$T)L&Qf7LPUbCM2I1K +N/WaVrf:EJOcklkPa.N"R$a;1S"#q=StD[LTqeEZV5L5iWiE,%Xfen4Z*UdD[^NZU\[oGd]t_=t +_SX4/`Q#s>ai_fMc-FV\d*^:jeC<%"f@S[.g=k<:gtgfChr!AMiSieqj8\0?jo+?AkPscDl2U&J +lhg&JmJZJLn,;bTnbMbToDS=Xp&4U`p\FU_q>L0bqu$BhrU9`:s3^js~> +JcC<$JcGKEo)AUdrVZQis8)ckr:g?fp@eIX!qc*Urpg*[nG_k\md9E.m-Es9l$qp[k2tddj5].X +i8EMLh;-l@g=k64f@SU(eC;sqdF$=ecHa\YbK@rJaN)<>`Pf[2_SO"%^:h1l]=PP_\$i`QZa6sB +Yck43XfJJ%WMcYkV50l\TqJ$LSt):>R[BJ/QBd\uP*(ieO,]*WMi*@ILPCP;KS+l-J:N,uI=3er +H?sj]GB\4QFEDSEEH,r9DJj<-CMR[!BP;$jAn>Oa@q&nU@:3GL?[(E9r`K;)=',B%s&K(u +r_rhps&&bls4IA)oVV8YpSR)Ls.oQ\q*Xd@o0NE,s4$kpqmYk#n[JD(qR-7.!(?ZPr'pENrCHiX +qapkWrp]sXs7-1s'be6s'u%=r+5k>s(D7Crb;@Hr+l8k +lcnS9s*4EdoQoJCoQpF\r-8!\r-&!\noX,;m<&,Gq0)@Rr-8-bq0N$erd=Wls*jutrIFp!s+:6& +s+CB+re=s=LkpnEMMd=NN/`gWO,oBbP*2#nQ'IZ%R$a;1S"-%@StD[LU8+N[VPg>kWiE,%Xfen4 +Z*UdD[^NZU\[oGd]t_=t_SX40`Q$!?ai_fNc-FV\dF$CkeC<%"f@S[.g=k<:rnRV3hu;O7iSsjs +s5a4AroX7Ds60CFs6BULr9XCLrpKXOrUBdUqXXUVrUfsZrq? +JcC<$JcGKEo)AUdrVZQis8)ckr:g?fp@eIX!qc*Urpg*[nG_k\md9E.m-Es9l$qp[k2tddj5].X +i8EMLh;-l@g=k64f@SU(eC;sqdF$=ecHa\YbK@rJaN)<>`Pf[2_SO"%^:h1l]=PP_\$i`QZa6sB +Yck43XfJJ%WMcYkV50l\TqJ$LSt):>R[BJ/QBd\uP*(ieO,]*WMi*@ILPCP;KS+l-J:N,uI=3er +H?sj]GB\4QFEDSEEH,r9DJj<-CMR[!BP;$jAn>Oa@q&nU@:3GL?[(E9r`K;)=',B%s&K(u +r_rhps&&bls.B=aoR?.VpO;IWr'^?JoKr.8qOd\YqhaTqhh_>$qF11s'be6s'u%=r+5k>s(D7Crb;@Hr+l85fU;Q&s*4Ed +oQoJCoQpF\r-8!\r-&!\noX,;m<&,Gq0)@Rr-8-bq0N$erd=Wls*jutrIFp!s+:6&s+CB+re=s= +LkpnEMMd=NN/`gWO,oBbP*2#nQ'IZ%R$a;1S"-%@StD[LU8+N[VPg>kWiE,%Xfen4Z*UdD[^NZU +\[oGd]t_=t_SX40`Q$!?ai_fNc-FV\dF$CkeC<%"f@S[.g=k<:rnRV3hu;O7iSsjss5a4AroX7D +s60CFs6BULr9XCLrpKXOrUBdUqXXUVrUfsZrq? +JcC<$JcGKEo)AUdrVZQis8)ckr:g?fp@eIX!qc*Urpg*[nG_k\md9E.m-Es9l$qp[k2tddj5].X +i8EMLh;-l@g=k64f@SU(eC;sqdF$=ecHa\YbK@rJaN)<>`Pf[2_SO"%^:h1l]=PP_\$i`QZa6sB +Yck43XfJJ%WMcYkV50l\TqJ$LSt):>R[BJ/QBd\uP*(ieO,]*WMi*@ILPCP;KS+l-J:N,uI=3er +H?sj]GB\4QFEDSEEH,r9DJj<-CMR[!BP;$jAn>Oa@q&nU@:3GL?[(E9r`K;)=',B%s&K(u +r_rhps&&bls&8qsoL@(qr'^?JoKr.8oi:WVnO`IGqap6I!(?ZPr'pENrCHiXqb$K_k>(;:r_EAc +r*95,s'GS0ra>b7qdTS8rabqqg%g[iHt3Cr-A3bpilXZ +r,qRPl#Z66piZCUo6:+Wr-A*ard4Wlr-eTos*suts+13%re(6(!/:E,A;>tsM2@+IMitQC!u+R@9V8SXuFFTV8*TUnjlcVl?\rX0&M,YctC=Za@0L\%0&\]Y(qm^VI_'_o9U7 +aN2KGbKS5VcHjncdaQ^qe^i@(f\,!4gYDea!T)`5huVfrro=%>s5j7Bs6'FGr9=7Hrp0LKrU'UP +qX=CPrUKaTrU^![qXsj]rV--_rV?Egq"t!equ,s^JcF-tJ,~> +JcC<$JcGKEo)AUdrVZQis8)`jrV6Ee!;?Ba!qc*UrpkL-nF5o8mdBK/m-Es%l07Epk2tddjQ#:[ +iS`YOhVI#CgY1B7f[na+e^W*tda?Ihcd'eZbKJ&MaN2EA`Pod5_SX+'^V7Co]Xt_b\@8oT['R*E +Z*:F7Xf\Y(Wi;noVPU)`U7n6PSt;IAS!o_3Q^3o$PEM&iO,o9ZN%U$GM26qAL4t;5Jq8H&Isufo +H[:!`G^"@TF`__HEcH)[1K;>5hY+=BAT'tQC!u+R@9V7S=Q7DTV8'RUnjiaVl6SpX/rG*YHY7:Za7'J +[^`lY]=bej^V@V%_SjF4a2l?DbKJ,ScHjkbdF-LneCE1&f\-8X"l%hgh;7&ghu_lsir7s>jQ5M& +k5XWEkl'cFlMp2Im/HDOmeZDNnG_tRo)81Yo_S7ZpAOa]q#:*eqY9scr;6H\rdk*rs*t~> +JcC<$JcGKEo)AUdrVZQis8)`jrV6Ee!;?Ba!qc*UrpkL-nF5o8mdBK/m-Es%l07Epk2tddjQ#:[ +iS`YOhVI#CgY1B7f[na+e^W*tda?Ihcd'eZbKJ&MaN2EA`Pod5_SX+'^V7Co]Xt_b\@8oT['R*E +Z*:F7Xf\Y(Wi;noVPU)`U7n6PSt;IAS!o_3Q^3o$PEM&iO,o9ZN%U$GM26qAL4t;5Jq8H&Isufo +H[:!`G^"@TF`__HEcH)[1K;>5hY+=BAT'``pP8f;qaLBOpdb6QrCQiXril@+s0D[2 +s0VfnpQtK;ns0$:q3V%bs'>V1qd9A2raG_6raYqs(D4Bs(VIIr+c:KrN4_?pmCu)oQp+U +qL%p^oQpF\r-8!\rHA*]o5s)8mr\AJqKDISr-8-bq0N$erd=Wls*jrsrIFp!!.t0%!ec8]re=g9 +LkpnEMMd=NN/`gWO,oBbP*2#nQ'IZ%R$a;1S"#q=StD[LTq\?YV5C/hWN*##Xf\e2Yd1UA[C3NR +\[f>b]Y;.q_8=(-`Pom=aN;WKbg"GZd*^7he'umtf@S[.rn7P1gtgfChu;O8iSrkrir\<'jo4EB +kPscEl2KuJlhg&JmJcPMn,;bTnbMbSoDS=Xp&4U_p\FU`q>C*aqu$BhrU0Z9s3Udr~> +JcC<$JcGKEo)AUdrVZQis8)`jrV6Ee!;?Ba!qc*UrpkL-nF5o8mdBK/m-Es%l07Epk2tddjQ#:[ +iS`YOhVI#CgY1B7f[na+e^W*tda?Ihcd'eZbKJ&MaN2EA`Pod5_SX+'^V7Co]Xt_b\@8oT['R*E +Z*:F7Xf\Y(Wi;noVPU)`U7n6PSt;IAS!o_3Q^3o$PEM&iO,o9ZN%U$GM26qAL4t;5Jq8H&Isufo +H[:!`G^"@TF`__HEcH)[1K;>5hY+=BAT'3OqaLBOpdb6QrCQiXqH3`"r`J>Yl:q(L +rETA.ra,J/s'Yh7r*oY8rabqtQC!u+R@9V7S=Q7DTV8'RUnjiaVl6SpX/rG*YHY7:Za7'J[^`lY]=bej^V@V% +_SjF4a2l?DbKJ,ScHjkbdF-LneCE1&f\-8X"l%hgh;7&ghu_lsir7s>jQ5M&k5XWEkl'cFlMp2I +m/HDOmeZDNnG_tRo)81Yo_S7ZpAOa]q#:*eqY9scr;6H\rdk*rs*t~> +JcC<$JcGKEo)AUdrVZQis8)`jrV6Ees7ZHbs7?<_rpp*Z!:^!V!Uf@Slk\pPl07EpkN:pgjQ#:[ +iS`YOhVI#Cg]#oUg"=p.f$r3uda?Ihcd'h\bfe2PaiMQD`l5p8_ns7*^V@Lr]Y(ke\[],W[^EHJ +ZE^X;Y-"h,WiE%rVl$;dUS=HTT:VXES"#k6R$X,(P`q8mOH5H^N/W[PM26qAL4t;5Jq8H&Isufo +H[:!`G^"@TF`__HEcH)?_#/!a&N*r`9&! +s&Aqqs&&tsf%/I)qPN\YnttZJq*b!FoKr7;qpbMne[YOdr3lF/!(?]QqaU?Nr(-cXq+:\[p&=Xh +p\=R[qYL*Xc1TBUc1&sV>lJ%/?Me+0@/aU4@fBm:AGg$aND]Lbg+M[d*^7ieC<%"f@S[.g=k<:h;-rEhr*GOiSsjs!p&J) +roX7Ds60FGs6BXMqs=@MrU0ONrp]mVq==LUrUfpYrV$3aq=sparVH +JcC<$JcGKEo)AUdrVZQis8)`jrV6Ees7ZHbs7?<_rpp*Z!:^!V!Uf@Slk\pPl07EpkN:pgjQ#:[ +iS`YOhVI#Cg]#oUg"=p.f$r3uda?Ihcd'h\bfe2PaiMQD`l5p8_ns7*^V@Lr]Y(ke\[],W[^EHJ +ZE^X;Y-"h,WiE%rVl$;dUS=HTT:VXES"#k6R$X,(P`q8mOH5H^N/W[PM26qAL4t;5Jq8H&Isufo +H[:!`G^"@TF`__HEcH)?_#/!a&N*r`9&! +s&Aqqs&&horLW8'q1/*eqgS-bq*b!FoKr7;qk*bYd>IgXq1o#=qaLBOpdb6QrCQfWrNcI0rj;^5 +!4Mlop6Y<8op,B>pm:tbra#P1qd9A2raG_6raYqs(D7Crb;@Hr+l:Js/c=)R+Ri&R/M=& +HM)XXI._jZHMi'eGkcL\G5QLTFQ7H3FS^.VG4g(WGl2j_HMr3iI/JEmIf=iqJH(3#K)UE&K`?c* +L'NKiLl$tGMMqImA;uV1O-#KdP*2#nQ'IZ%R$a;1S"-%@StD[LU8+N[V5L5iWN*##Xfek3Z*L^C +[C3QS\[oDc]tV7s_8=+.`Q#s>aND]Lbg+M[d*^7ieC<%"f@S[.g=k<:h;-rEhr*GOiSsjs!p&J) +roX7Ds60FGs6BXMqs=@MrU0ONrp]mVq==LUrUfpYrV$3aq=sparVH +JcC<$JcGKEo)AUdrVZQis8)`jrV6Ees7ZHbs7?<_rpp*Z!:^!V!Uf@Slk\pPl07EpkN:pgjQ#:[ +iS`YOhVI#Cg]#oUg"=p.f$r3uda?Ihcd'h\bfe2PaiMQD`l5p8_ns7*^V@Lr]Y(ke\[],W[^EHJ +ZE^X;Y-"h,WiE%rVl$;dUS=HTT:VXES"#k6R$X,(P`q8mOH5H^N/W[PM26qAL4t;5Jq8H&Isufo +H[:!`G^"@TF`__HEcH)?_#/!a&N*r`9&! +s&Aqqs&&horDNJ]a%,qnpd=[?p-J@Ope'73qagNQ!(?]QqaU?Nr(-cXq+C<_s%h`OmS3IOr`oG. +s'GS0s'Yh7r*oY8rabqkN+@p.O,oBb +OcklkPa.N"Q^F/.R[]hL0bqtp +JcC<$JcGKEo)AUdrVZQirqcZjrV6Ees7ZHbs7H?_s763[!:^!V#4CmGm-O''rojUMkN:pgjSn1h +io/hRhqm2FgtUQ:g"=p.f%&:"e'cXkd*L"_c-4ASb/q`Ga2Z*;`5BI.^q[Xu]tD"i\[f5Z[^NQL +Za-j?YHG"0X/`2!Vl-DgUnaZXTV%gIS=?":R$a5+Q'@JqOcYWbNf8pTMM[.EL5(D8K7\Z)J:E#r +I=$9dH$FOW'm=_AFE;JBEH#i6DJa3*CMIQsBP1rVAIrB^@U`bR?sd8I?!U]?>?b;1=oVS(=8l8# +[:b7/94@6MWq?eC;#*\,<]3[JNDi7e]FO8Gu-U9)hNcpA"F^q>U6l +r;H*/n]psTn]_#kMueourf:6EOcklkPa.N"Q^F/.R[]e:SXuFGTqS3UUnsrdVl?\rX0&M,YctCC*aqtp +JcC<$JcGKEo)AUdrVZQirqcZjrV6Ees7ZHbs7H?_s763[!:^!V#4CmGm-O''rojUMkN:pgjSn1h +io/hRhqm2FgtUQ:g"=p.f%&:"e'cXkd*L"_c-4ASb/q`Ga2Z*;`5BI.^q[Xu]tD"i\[f5Z[^NQL +Za-j?YHG"0X/`2!Vl-DgUnaZXTV%gIS=?":R$a5+Q'@JqOcYWbNf8pTMM[.EL5(D8K7\Z)J:E#r +I=$9dH$FOW'm=_AFE;JBEH#i6DJa3*CMIQsBP1rVAIrB^@U`bR?sd8I?!U]?>?b;1=oVS(=8l8# +61pl+MY)btM#0X<7e]FO8Gu-U9)hNaZM_*/[flJ%/?Me+0@/aU4@fBm:AGg$=B)ZH@B`;`FCA_lHC]J>OY5XgARJNtQC!u+R@9V7S=Q7CTV8'RUSO``Vl-MoWiN8(Y->.8ZEppG[^WcW +]">Vg^;%J"_Sa=2`lH0Bb0.uQcHab_dF-LneCE.%f@\d1g=tE=h;7&ghuVfrro=%>!9O4Bs6'FG +rTX@Is6KULrpB^QqX=FQrUK^SrU^![q=X^[rV--_rV?Bfq"ssdqu,s^JcF'rJ,~> +JcC<$JcGKEo)AUdrVZQirqcZjrV6Ees7ZHbs7H?_s763[!:^!V#4CmGm-O''rojUMkN:pgjSn1h +io/hRhqm2FgtUQ:g"=p.f%&:"e'cXkd*L"_c-4ASb/q`Ga2Z*;`5BI.^q[Xu]tD"i\[f5Z[^NQL +Za-j?YHG"0X/`2!Vl-DgUnaZXTV%gIS=?":R$a5+Q'@JqOcYWbNf8pTMM[.EL5(D8K7\Z)J:E#r +I=$9dH$FOW'm=_AFE;JBEH#i6DJa3*CMIQsBP1rVAIrB^@U`bR?sd8I?!U]?>?b;1=oVS(=8l8# +mu4<:NoW<;q18HM2^UI.r!\HMi'eGkcL\ +G5ZRUFQ.B3FS^.WG4g(WGl2j_HN&9jI/A?kIfForJH(3#K)L?%KE-`)L'NKiLl$tGMMqIm!KE-= +O'7X-P*2#nQ'IZ%R$a;1S"#q=St;UKTq\Xcd:(fe'umtf%8O+g"P07gtgfChu;O7iSsjss5X1AroX7Ds60FGs6BXMr9XFM +rpKXOrp]mVq==LUrUfpYrV$3aq=spar;-3cqu$?imf%e;ci8L~> +JcC<$JcGKEo)AUdrVZQirqcZjrV6Ees7ZEa!qc*UrpgWjnF5o8mdBK/m-F!&l07EproS[kjQ#:[ +iS`YOhVR)EgtUQ:g"=p.f%&:"e'cXkd*L"_c-4ASb/q`Ga2Z*;`59C-^q[Xu]tD"h\[f5Z[^NQL +Za-j?YHG"0X/`2!Vl-DgUnaZXTV%gHS=?"9R$a5*Q'@JqOcYWbNJrgSMM[.EL5(D8K7\Z)J:E#r +I!bm>/U;SbGBS+NFE;JBEH#i6DJa3*CMIQsBP1pgARo=]@U`bR?sd8I?!U]?>?b;1=oVS(=8c/$ +rG5MuJY9NK4"!"d"k0P*;.0PtdR2R$a;1S"-%@StD[LTqeEZV5C/hWN)u"Xf\e2Yd(O@ +['mEP\[f;a]Y2(p^r!t+`Poj;aN;TJbg"GYcdC.ge'umtf@S[.g=k<:rnRt=hr*GOio9"YjQ,G% +k5XWEkl'cGlMp2Jm/QJPmecJOnGVnQo)81Yo_J1YpAF[\q#1$eqY0mbr;-B[rdk*ps*t~> +JcC<$JcGKEo)AUdrVZQirqcZjrV6Ees7ZEa!qc*UrpgWjnF5o8mdBK/m-F!&l07EproS[kjQ#:[ +iS`YOhVR)EgtUQ:g"=p.f%&:"e'cXkd*L"_c-4ASb/q`Ga2Z*;`59C-^q[Xu]tD"h\[f5Z[^NQL +Za-j?YHG"0X/`2!Vl-DgUnaZXTV%gHS=?"9R$a5*Q'@JqOcYWbNJrgSMM[.EL5(D8K7\Z)J:E#r +I!bm>/U;SbGBS+NFE;JBEH#i6DJa3*CMIQsBP1pgARo=]@U`bR?sd8I?!U]?>?b;1=oVS(=8c/$ +rG5MuJY9NK4"!"d"k0P*;.0PtdR2R$a;1S"-%@StD[LTqeEZV5C/hWN)u"Xf\e2Yd(O@ +['mEP\[f;a]Y2(p^r!t+`Poj;aN;TJbg"GYcdC.ge'umtf@S[.g=k<:rnRt=hr*GOio9"YjQ,G% +k5XWEkl'cGlMp2Jm/QJPmecJOnGVnQo)81Yo_J1YpAF[\q#1$eqY0mbr;-B[rdk*ps*t~> +JcC<$JcGKEo)AUdrVZQirqcZjrV6Ees7ZEa!qc*UrpgWjnF5o8mdBK/m-F!&l07EproS[kjQ#:[ +iS`YOhVR)EgtUQ:g"=p.f%&:"e'cXkd*L"_c-4ASb/q`Ga2Z*;`59C-^q[Xu]tD"h\[f5Z[^NQL +Za-j?YHG"0X/`2!Vl-DgUnaZXTV%gHS=?"9R$a5*Q'@JqOcYWbNJrgSMM[.EL5(D8K7\Z)J:E#r +I!bm>/U;SbGBS+NFE;JBEH#i6DJa3*CMIQsBP1pgARo=]@U`bR?sd8I?!U]?>?b;1=oVS(=8c/$ +5qJ!;"mcF +:B!u`:B+Su?2n7.?iOO5@JjU6A,^$:AcHBABDcHBC&_rFC]A5MD#eJQ@I@+e;t*cdH1cLXHgH.T +HhMd`H2Mp_GPu^_FnKkLF89kJF7XMNFo-@UGPl^aH22dbHiAEiIK"]qJ,FisJcC?$KE$W)L&Qi, +LB*/0M>rG5MuJY9NK4"!"d"k0P*;.0PtdR2R$a;1S"-%@StD[LTqeEZV5C/hWN)u"Xf\e2Yd(O@ +['mEP\[f;a]Y2(p^r!t+`Poj;aN;TJbg"GYcdC.ge'umtf@S[.g=k<:rnRt=hr*GOio9"YjQ,G% +k5XWEkl'cGlMp2Jm/QJPmecJOnGVnQo)81Yo_J1YpAF[\q#1$eqY0mbr;-B[rdk*ps*t~> +JcC<$JcGKEo)ARcrquZjrqcZjrV6Ees7ZEa!qc*Urpg-\nF6GG!Uf@SliHG;rojUMkN:pgjSn1g +io/hRhqm2FgtUQ:g"=s/f@JL%eC2jndEp4bcHXSVbK@rJaN)<>`P]R0_8*h#^:h1l]=GJ^\$i`P +Za6sBYck43XfJJ%WMcYkV50l\TqJ$LSXc1=R@'A.Q'IStP*(ieO,]*WMi*@ILPCP;K7ec,J:N,u +I=-BfH?jc8G91pMFEDSEEH,r9DJj<-CMR[!BP;$jAS#C^@q&nU@/aL6?=!P8s'#J,r`T8'!*B," +!``3!rDWaIoqq#Po;;A\pnn'[oL/IAmR$Wsk.'igrj_[2s0henqaUb7qdTS8rabq!."6` +pNu1Qpj;^\rH\L0aqtp +JcC<$JcGKEo)ARcrquZjrqcZjrV6Ees7ZEa!qc*Urpg-\nF6GG!Uf@SliHG;rojUMkN:pgjSn1g +io/hRhqm2FgtUQ:g"=s/f@JL%eC2jndEp4bcHXSVbK@rJaN)<>`P]R0_8*h#^:h1l]=GJ^\$i`P +Za6sBYck43XfJJ%WMcYkV50l\TqJ$LSXc1=R@'A.Q'IStP*(ieO,]*WMi*@ILPCP;K7ec,J:N,u +I=-BfH?jc8G91pMFEDSEEH,r9DJj<-CMR[!BP;$jAS#C^@q&nU@/aL6?=!P8s'#J,r`T8'!*B," +!``3!rDN`hT&tP%JFJ'WIfDk/7/0.;6M@&7Mu&=uM>2o(7JfRK8,Z!W8bl!X9)u?t[0O.J[C3KN +R@3ls(D7Crb;@Hr+l:Js)%dRriZ0dgR7r+!."6` +pNu1Qpj;^\rH\L0aqtp +JcC<$JcGKEo)ARcrquZjrqcZjrV6Ees7ZEa!qc*Urpg-\nF6GG!Uf@SliHG;rojUMkN:pgjSn1g +io/hRhqm2FgtUQ:g"=s/f@JL%eC2jndEp4bcHXSVbK@rJaN)<>`P]R0_8*h#^:h1l]=GJ^\$i`P +Za6sBYck43XfJJ%WMcYkV50l\TqJ$LSXc1=R@'A.Q'IStP*(ieO,]*WMi*@ILPCP;K7ec,J:N,u +I=-BfH?jc8G91pMFEDSEEH,r9DJj<-CMR[!BP;$jAS#C^@q&nU@/aL6?=!P8s'#J,r`T8'!*B," +!``3!r)3Snr'gHOmmm%?l::kCoL/IAmR$VHk"4K%s$urTqaUb7qdTS8rabqL0aqtp +JcC<$JcGKEo)ARcrquWis8)ckr:pKnG#0JUi9# +IXQTjH?sj]GB\4QFEDSEEH#jqDA$f&CMR[!BP;$jAS#C^@q&nU@/aL[(E9r`T8's&]2# +s&K(us&/sLfCPm*VrafS7J'"B6h!G>ebmqY\F$d)\G!E/7JoXL8,PpV8bl!X9DSDdq>0p4e]md2 +ra#M0r*TG2s'be6s'u%=r+5k>s(D4Bs(VIIr+l:Jrb_XPs5X"#n'1(?!."6`pj;4Pq0Vg]rH\Vg^;%J"_SX71`Q-'@aihlOc-FY^dF$FmeCE.%f@\d1g=tE=h;7&Ii8N\Tj5]4]jo4BDkNM./ +l2U&Klhp,LmJcPNn,DhUnbMbSoDJ7Up&4U_p\=O^q>C*`qu$BgrU0Z9s31Ln~> +JcC<$JcGKEo)ARcrquWis8)ckr:pKnG#0JUi9# +IXQTjH?sj]GB\4QFEDSEEH#jqDA$f&CMR[!BP;$jAS#C^@q&nU@/aL[(E9r`T8's&]2# +s&K(us&8rik'mA]m=4YTrC-?HpI"F:qk3kZ!/frtq24Tsq2"o:r'pENr(-cXq+CWZq6^1.!OA-f +R.ls8QN*nGQY5=U@RJ`EPH1cLY +Hg#kQHhMdaH2Mp_GPu^`FnTqQF6mrBF7jYQFo6FWGPudbH22dcHi8?hIK+cqJ,FisJcC?#KE$W) +L&Qi,L]<20M#rQmMuJY9NK4"!!K`HCP$sQ=Q'IZ%R$a;1S"#q=St;RITqS3UUnsrdVl?\rX0&M, +YHY:;Za@-K\%&u[]=bhk^VI\&_SjF4a2l?DbKJ,ScHjkbdF6Upe^i@(f\,!4gYCW@hV[8LiSrkW +j5f:_roO:Fkii$1s6BXMr9XINrpK[Prp]pWq==LUr:KdWrV$3aq"Xg`r;-0br;?Eimf%e;bl<1~> +JcC<$JcGKEo)ARcrquWis8)ckr:pKnG#0JUi9# +IXQTjH?sj]GB\4QFEDSEEH#jqDA$f&CMR[!BP;$jAS#C^@q&nU@/aL[(E9r`T8's&]2# +s&K(urDWS^q*ssGnj_t9rC-?HpI"F:s&8\lj[n?#qaLEPpIG-PrCQfWr_*2ms&f2#!)`,[p.smI +ra#M0r*TG2s'be6s'u%=r+5k>s(D4Bs(VIIr+l:Jrb_XPs'k=opf$T[!."6`pj;4Pq0Vg]rH\Vg^;%J"_SX71`Q-'@aihlOc-FY^dF$FmeCE.%f@\d1g=tE=h;7&Ii8N\Tj5]4]jo4BDkNM./ +l2U&Klhp,LmJcPNn,DhUnbMbSoDJ7Up&4U_p\=O^q>C*`qu$BgrU0Z9s31Ln~> +JcC<$JcGHDoD\[drVZQis8)`jrV6Ees7ZHbs7H?_rpg_%PbKJ&MaN2E@`Pf[2_SO%&^V7Co]XkYa\@8oT +['R*EZ*:F7Xf\Y(Wi;noVPU)`U7n6PSt2C@S!fY2Q^*i#PEM&iO,o9ZN/NRMLkg_>KnG#0JUi9# +IXQTjH?sj]GB\4QFE;JBEH#i6DJa4hCCY)nBP;$jAS#C^@q&nU@/aL[(E9r`T8's&]2# +s&K(u!`Rb(oqprNk,/&Fo0i=?nO!6+qUP,HoXO:trj_s:!4_p8r'gKPpIG0QrCQfWrC[,aqYC0d +!;H96gs,Q:s'>V1r*TG2s'be6s'u%=r+5k>s(D4Bs(VIIr+l:Jrb_UOs5a""n]g:Ap3QL\k'ZuO +p3Q[_rHS-^r-&$]pN67Ql#QT@olU+SrH@s[rHS9dq0N$erd=TkrdOirr.+fus+:3%s+LE+rJ(?- +!/UW2s,$f7rf$l:!07&>!K`HCOp.&6Q'IZ%rg6WPR[]e:SXuIHTqS3UUnjibVl6SpX/rG*YHY79 +Za7$H[^WcW]">Vg^;%J"_Sa=2`lH0Bb0.uQcHab_dF-LneCE.%f\,!4gYCW@hV[5Ki8N\pirS6& +roX7D!9jCGs69UMr9XINrpK^Qrp]mVq==LUrUfmXr:^*`q"Xd_rVH9cqu$?imJ_\:bl<1~> +JcC<$JcGHDoD\[drVZQis8)`jrV6Ees7ZHbs7H?_rpg_%PbKJ&MaN2E@`Pf[2_SO%&^V7Co]XkYa\@8oT +['R*EZ*:F7Xf\Y(Wi;noVPU)`U7n6PSt2C@S!fY2Q^*i#PEM&iO,o9ZN/NRMLkg_>KnG#0JUi9# +IXQTjH?sj]GB\4QFE;JBEH#i6DJa4hCCY)nBP;$jAS#C^@q&nU@/aL[(E9r`T8's&]2# +s&K(u!`P_`l@8Y\mXOeVr'g3FpI"I;pRqPDo8E!nm>:^rr'gKPpIG0QrCQfWrC[,arj2X1s02[1 +Z*9YiR.-I9QLL7@?2e1.?iFI5@JaO6A,^$:Ac?eAPY5+I@RJ`HGHMDjL +I//-_HMr-fGklR]G5ZRXFS^(CEqseLFSp:[G5-:[Gl;p`HN&9jI/A?kIf=ipJH(3#K)L?%K`?c) +LB!#/M#N82M?&S6N;nk;NrG(?OHKO*"d>19Q'Rd9QrBEAS"#q=StD[LTq\ +JcC<$JcGHDoD\[drVZQis8)`jrV6Ees7ZHbs7H?_rpg_%PbKJ&MaN2E@`Pf[2_SO%&^V7Co]XkYa\@8oT +['R*EZ*:F7Xf\Y(Wi;noVPU)`U7n6PSt2C@S!fY2Q^*i#PEM&iO,o9ZN/NRMLkg_>KnG#0JUi9# +IXQTjH?sj]GB\4QFE;JBEH#i6DJa4hCCY)nBP;$jAS#C^@q&nU@/aL[(E9r`T8's&]2# +s&K(ur_rY^r'p-Fo1&+;r'g3FpI"I;peq/lj@SN*!(m&Yr'gKPpIG0QrCQfWrC[,aqcNi!!*8kl +m83LPn4s!hra,M0ra>b7qdTS8rabqtQC%T<;jj)DS"-%@T:hmOU8+N[V5L5iWN*##Xf\e2Yd(O@ +['d?O\@K2_]Y2%o^qmn*`5Ta:aN;TJbK\>Xcd:(fe'umtf%8R-g=k<:h;-rFhr*GOir7s=jQ6C' +s5sCGrTX@I!:0RLs6]gRr9sXSrUK^SrU^![q"=RYrV-*^r;$ +JcC<$JcGHDo)AUdrVZQirqcZjrV6Ees7ZEa!qc*Urpg-\nF6GG!Uf@SliHG;rojIIkPjTIjlGI^ +io0mpIG`o;h;$c=g=b03f@SU(eC;sqdF$=ecHa\YbKJ&MaN2EA`Pod5_SX.)^V@Lr]Y(hd\[],W +[^?_#/s&f;& +r`9&!!`[h)pnm)LrhfXln#$(Rr'g6Gp-\Ff`bPtlJ?Me+0@/aU4@fBm;AG]s +JcC<$JcGHDo)AUdrVZQirqcZjrV6Ees7ZEa!qc*Urpg-\nF6GG!Uf@SliHG;rojIIkPjTIjlGI^ +io0mpIG`o;h;$c=g=b03f@SU(eC;sqdF$=ecHa\YbKJ&MaN2EA`Pod5_SX.)^V@Lr]Y(hd\[],W +[^?_#/s&f;& +r`9&!!`YeapjW9opODjdmsjqXr^QfSoL/C?o0W5Fg5>0Pr'gKPpIG0Qr(6`WrCd/a$F-h>YHY46 +Y-"goopFs0s-E/@s'>Y2qd9A2raG_6raYt=qdoe>rb).Brb;CIqeQ4Jrb_RN!NrR"R,+2/R.bk% +HfTSNHhMdaH2W!`GPu^`Fn^"SF6@T>F8'eSFo6FYGPudbH2;jdHiAEiIK"]pJ,FisJcC?"KE$W) +L&Qi,L]<20M>rG5MuJ\8N<#"jWiE,$ +Xfek3Yd1UA[C3NQ\[f;a]Y2(p^qmn*`5Ta:aN;TJbg"GYcdC.ge'umuf@S[.g=k<:h;-rFi8ESR +ioB([jlQL(!pAe2rosIJ!:0UMrpBaRr9sXSrUKaTrU]sZq"=UZr:g!]r;$ +JcC<$JcGHDo)AUdrVZQirqcZjrV6Ees7ZEa!qc*Urpg-\nF6GG!Uf@SliHG;rojIIkPjTIjlGI^ +io0mpIG`o;h;$c=g=b03f@SU(eC;sqdF$=ecHa\YbKJ&MaN2EA`Pod5_SX.)^V@Lr]Y(hd\[],W +[^?_#/s&f;& +r`9&!!`W)sqaLHQlppS8n43IIr'g6Gp-\FY2qd9A2raG_6raYt=qdoe>rb).Brb;CIqeQ4Jrb_RN!FfL%<;fb^<;(Y6 +HfTSNHhMdaH2W!`GPu^`Fn^"SF6@T>F8'eSFo6FYGPudbH2;jdHiAEiIK"]pJ,FisJcC?"KE$W) +L&Qi,L]<20M>rG5MuJ\8N<#"jWiE,$ +Xfek3Yd1UA[C3NQ\[f;a]Y2(p^qmn*`5Ta:aN;TJbg"GYcdC.ge'umuf@S[.g=k<:h;-rFi8ESR +ioB([jlQL(!pAe2rosIJ!:0UMrpBaRr9sXSrUKaTrU]sZq"=UZr:g!]r;$ +JcC<$JcGHDo)AUdrVZQirqcZjrV6Ees7ZEas7?<_rpp*Z!:^!V,4=jcm-O'(lKRQski_*jjlGL_ +j5T%Ui8(rjh+"!4hC)rjVm:r'gKPpIG0QrCQfWrCd/a$2*r^ +oCDJBnaQ#Fc0imLc1oK_c25``b5tsU?Me+0@/aU4@fBm;AG]sb]Y2(p^r!t+`Poj;aN;TJbg"GYd*^7he'uq!f@S[. +g=k<:h;-rFi8ESRro4%?jo4BDkNM./l2U&Kli-8MmJlVPn,DhUnbVhToDS=Up&4U^p\4I]q>C*_ +qu$BgrU'T8s2t@l~> +JcC<$JcGHDo)AUdrVZQirqcZjrV6Ees7ZEas7?<_rpp*Z!:^!V,4=jcm-O'(lKRQski_*jjlGL_ +j5T%Ui8S2ODlrc$hO4;/pNlX^ +ja?lNpNla_rHS-^rHA-^piQ@Rj`:3=pN6=UrHA!\rcnBeqKi-frd=TkrdOirr.+fus+:0$s+LE+ +rItB/Lku"d!fDnorepob]Y2(p^r!t+`Poj;aN;TJbg"GYd*^7he'uq!f@S[.g=k<:h;-rFi8ESR +ro4%?jo4BDkNM./l2U&Kli-8MmJlVPn,DhUnbVhToDS=Up&4U^p\4I]q>C*_qu$BgrU'T8s2t@l~> +JcC<$JcGHDo)AUdrVZQirqcZjrV6Ees7ZEas7?<_rpp*Z!:^!V,4=jcm-O'(lKRQski_*jjlGL_ +j5T%Ui8VF[l;[M( +q0V4Nq0Vj^r-A6cq02d\rH7mWqK(b=qK)CQr,qs]q02g_rH\6crd4WlqgJHmrdXirs+13%r.G$& +s+UE+!f)SfrJ:T5Mi7Rn!f`5#rf7)AOoCLEPEc'3=I,;@R$jD4S"-%@StD[LTq\ +JcC<$JcGHDo)AUdrVZQirqcZjr:p?2e(1>?Y50=oVV( +=8l5#f`%btVt$Ya8,YpS7J'"@6h`nIh>H(-g\eVC\F7!&\GSen7e]FN8Gu-V9)VE^9F=M_nF,f5 +mHs9,cMGfVcM>`bbl5labl>lcbkK<[?Mn10@/j[5@fBm:AGg$=B)ZH@B`;`FCA_lHD#\ALDZ=YT +j8R6tbk'*DbkQMZHf]YNHhVjbH2W!`GPu^`Fng(UF8'_KEVFMMF80kUFo?LZGQ)jcH2DpeHiAEi +IK"]pJ,FisJcC?"KE$W)L&Hc+L]<20M>rG5MuJ\8N<#"Vg^;%G!_SX71`Q-'@aihlOc-FY^dF$Fm +eCE.%f@\g2gYCW@hV\=j$fU+*j5f=`k2tjikl0iHlMp2Lm/HDPmelPRnG_tSo)81Yo_A+WpAF[Z +q#'scqY0mar;-BZrdk*ks*t~> +JcC<$JcGHDo)AUdrVZQirqcZjr:p?2e(1>?Y50=oVV( +=8l5#TDj?7J,k)cJFA!]IfDq:7f,XH7.iqA6MR8RMW0KhMX62t7JoXL8,PpV8bu'X9E%Tc9rn8n +ri#psWUcG.Qi:=h?iFI5@JjU6A,^$:AcHBABDcHBC&VlFC]8/MD>S5NDZQrAp6ad+r0[8*pj;+M +q0Vj^rH\?dq02d\rH7mWqfDLPp2ThIqK)FRrH8'^q02g_rH\9drd4WlqgJHmrdXirs+13%r.G$& +s+UE+s+gW1re^Z4!/pi8s,@#=rf@)@!0R8D!L&cIPuO'9R$a;1R[]e:SXuFFTV8'RUnjiaVl-Jm +WiN5'Xfnt5Z*UdD[C3QS\[oDc]tV7r_8=(-`Pom=aN;WKbg"GZd*^7ieC<%"f@S[/g=tE=h;7&g +i!\N'j5]4^jlY^gkNMp0s6BXMrp9XOs6fgRs7$$XqXXUVrUfmXr:^'_p\=[^r;-0bqu$ +JcC<$JcGHDo)AUdrVZQirqcZjr:p?2e(1>?Y50=oVV( +=8l5#;uT5a7dik27f#XO7fQ!W7f,XH7.iqA6MOR[9&iJC8EEG@7JoXL8,PpV8bu'X9E%Tc9i_!g +oMGQbg/.cEra,M0ra>b7r*oY8rabqs,[5CrfR;GPl?qIQC!u+R@9S6S"-%@StD[LTq\?YV5C/gW2ZetXKAV. +YctC=Za@-K\%&u[]=bhk^V@V%_SjF4a2l?DbKJ,ScHjkbdF6Upe^i@(f\5'6gtgfChu;OAiSrnX +jQ5Lck3(pkrosIJs6K[NrpBaRr9s[TrpfjUrU^![q"=RYr:fs\r;$9ep\XjcqYfg\JcEjlJ,~> +JcC<$JcGHDo)ARcrquWis8)`jrV6Ees7ZEa!qc*Urpp*Z!:^!V(%1JVm-O'(lKRQski_*jjlGL_ +j5T%si.'Y@h;-l@gY1B7f[na+e^`1!e'cXkd*L"_c-4ASb0%iIaN)<>`P]R0_8*h#^:h1l]=GJ^ +\$i`PZa6sBYck43XK/A$W2HPjUnjc[TqJ$LSXc1=R@'A.Q'IStP*(ieNfB!VMi!:HLPCM9K7ec, +J:E#rI=-BfH?jaZG'3h,%QS,5>5h\) +=T;J&R4i8,PjS7Irq@6hj"Ch#P%a\`C9h\bWc57JfRK8,Z!W8bl!X9DqNa:&XDX +lMg&JcMYrWcM>`\bjWaT?Mn10@/aU4@fKs;AGg$qTSTV +l-/pKpj;+Mq0Vj^rH\?dq02g]rH7mWqfDRRn8\8EqfDOSrH8'^qKMp`rd"BerHnQlqgJHmrdXir +s+13%r.G$&s+UE+s+gW1re^Z4s,6l8s,@#=rf@)@!0R8D!L&cIQ!'E>R$a;0R[]e:SXuFFTV8'R +USO]^VPgAlWiE,$Xfek3Yd1UA['mEP\@K2_]Y2%o^qmn*`5T^9aN2NIbKS8Wcd:(fe'umtf%8R- +g=k<:h;-rFi8ESRro4%?jo4BDkNM./klU/9li$/MmJcPPn,DhUnb_nUoDS=Vp&+O]p\4I\q>C*_ +qtp +JcC<$JcGHDo)ARcrquWis8)`jrV6Ees7ZEa!qc*Urpp*Z!:^!V(%1JVm-O'(lKRQski_*jjlGL_ +j5T%si.'Y@h;-l@gY1B7f[na+e^`1!e'cXkd*L"_c-4ASb0%iIaN)<>`P]R0_8*h#^:h1l]=GJ^ +\$i`PZa6sBYck43XK/A$W2HPjUnjc[TqJ$LSXc1=R@'A.Q'IStP*(ieNfB!VMi!:HLPCM9K7ec, +J:E#rI=-BfH?jaZG'3h,%QS,5>5h\) +=T;J&s,[5CrfR;GPl?qNQC!u+R@0M5S"-%@StD[LTq\Vg^;%J"_Sa=2`Q-'@b0.uPcHab_dF-LneCE.%f\,!4gYCW@hV[8LiSsjs +!T`AAjoX`0kl0fJlKdd7li?GPmeuVRnG_tTo)81Yo_A+WpAF[Zq#'scqY'g`r;-BYrdk*ks*t~> +JcC<$JcGHDo)ARcrquWis8)`jrV6Ees7ZEa!qc*Urpp*Z!:^!V(%1JVm-O'(lKRQski_*jjlGL_ +j5T%si.'Y@h;-l@gY1B7f[na+e^`1!e'cXkd*L"_c-4ASb0%iIaN)<>`P]R0_8*h#^:h1l]=GJ^ +\$i`PZa6sBYck43XK/A$W2HPjUnjc[TqJ$LSXc1=R@'A.Q'IStP*(ieNfB!VMi!:HLPCM9K7ec, +J:E#rI=-BfH?jaZG'3h,%QS,5>5h\) +=T;J&s,[5CrfR;GPl?qNQC!u+R@0M5S"-%@StD[LTq\Vg^;%J"_Sa=2`Q-'@b0.uPcHab_dF-LneCE.%f\,!4gYCW@hV[8LiSsjs!T`AAjoX`0 +kl0fJlKdd7li?GPmeuVRnG_tTo)81Yo_A+WpAF[Zq#'scqY'g`r;-BYrdk*ks*t~> +JcC<$JcGHDo)ARcrquWis8)`jrV6Ees7ZEas7?<_rpp*Z!:^!Vs6]mSrp0[OlMg#Kki_s-!TiDA +isOf)i8EMMhVI#Cg]#n1g"=p.f%'cLJ()indEp4bcHXSVbK@rKaN2EA`Pf[2_SO%&^V7Co]Xt_b +\@8oT['R*EZ*:F7XfSS'Wi2hnVPL#_U7n6PSt2C@S!fY2QBd`"PEM&iO,f3YN/NOLLkg_=KS+o/ +JUi6!I=6KiH?sg[GBS+NFE;JBEH#i6DJa3*CMIQsB`D]JAn>OaA,]p<@:9(A!a]/$Co. +s&f;&!ERdtVu*@iV>d@i8,PjS7Irq?6i'+MhVJ(crOV^5laZAnqmcPmr'pENr(-cXqF^]Zr_3>d +r941Fs60I-rQY2a!71Meq9A`Zq9/`Zqof"Gqd9A2raG_6raYt=qdoe>rb).Brb;CIqeQ4Jrb_OM +rbhgVj87$qbk96GbkQMZHff_OHhVjaH2W!aGPu^`Fnp.WF8BqCEVa_RF80kVFo?L[GQ)jdH2Dpe +HiAEjIK"]pJ,FisJcC?"KE$W)L&Hc+L]<2/M#rQmMuJ\8NW5%X +cd:(fe'umuf@S[.g=k<:h;-rFi8ESRj5]4]jlY^gkNMp0s69UMrTsROs6fjSrp]sXqss^WrUfmX +r:^'_pA"R]r;--aqY^3gmJ_\:aT$b~> +JcC<$JcGHDo)ARcrquWis8)`jrV6Ees7ZEas7?<_rpp*Z!:^!Vs6]mSrp0[OlMg#Kki_s-!TiDA +isOf)i8EMMhVI#Cg]#n1g"=p.f%'cLJ()indEp4bcHXSVbK@rKaN2EA`Pf[2_SO%&^V7Co]Xt_b +\@8oT['R*EZ*:F7XfSS'Wi2hnVPL#_U7n6PSt2C@S!fY2QBd`"PEM&iO,f3YN/NOLLkg_=KS+o/ +JUi6!I=6KiH?sg[GBS+NFE;JBEH#i6DJa3*CMIQsB`D]JAn>OaA,]p<@:9(A!a]/$Co. +s&f;&!EPiIJFS-aIf)_67f5^H7.iqD63*hZU]7%gMt;hlM><%uM>Tg?7e]FN8Gu-V9)VE^9`Iid +Vu*F^R,jV4QM[$K?Me+0@/aU4@fBm;AG]s#EY(1P*2#mPl?pKQC%Tai_fMc-FV\d*^:jeC<($f@\d1g=tE= +h;7&Ii8N\Uj5f:_k2tjikl0iHl2^/Km/QJQmeuVRnGi%Uo)81Yo_A+WpAF[Yq#'scqY'g_r;-BZ +rdk*js*t~> +JcC<$JcGHDo)ARcrquWis8)`jrV6Ees7ZEas7?<_rpp*Z!:^!Vs6]mSrp0[OlMg#Kki_s-!TiDA +isOf)i8EMMhVI#Cg]#n1g"=p.f%'cLJ()indEp4bcHXSVbK@rKaN2EA`Pf[2_SO%&^V7Co]Xt_b +\@8oT['R*EZ*:F7XfSS'Wi2hnVPL#_U7n6PSt2C@S!fY2QBd`"PEM&iO,f3YN/NOLLkg_=KS+o/ +JUi6!I=6KiH?sg[GBS+NFE;JBEH#i6DJa3*CMIQsB`D]JAn>OaA,]p<@:9(A!a]/$Co. +s&f;&!EN.p7efL&7f5dS7f5^H7.iqD6MX[W9&S5MDZOfacrBddpj;.Nq0Vj^ +r-A6cqKMm]rH7pXr,_^TlZ)cAr,_XTrcS0_qKMp`rd"Berd4Wlr-eQnrdXirs+13%r.G$&s+UE+ +s+gW1rJ:T5Mi7Rns,I&=rf7;GOcbfiPEV71Pl[2;rg7&\R[]e:SXuFFTV8'RUSO]^VPg>jWN*## +Xf\b0Yd(L?['d?N\@K/]]Y(ql^VI\&_o0O6a2lBFbKJ/UcHjkbdaQ^qf%8O+g"P07gtgfChr*GO +ioB([jQ5OdkND(.l2U#Kli$2MmJlVQn,DhVnb_nUoDS=Vp&+O]p\+C[q>C*_qtg6erU'T8s2b4j~> +JcC<$JcGHDo)ARcrVZQirqcZjrV6Bd!;?Bas7H?_rpg-\nF6GG!Uf@Sm/QAblKRQski_*jjlPR` +j5T(Wi8EMLrnRq:gY1B7g"=p.f%'cLJ()indEp4bcHXSVbK@uLaN2EA`Poa3_SO%&^V7Co]Xt_b +\@8oT['R*EZ*:F7XfSS'Wi2hnVPL#_U7n6PSt2C@R[KP1QBd`"P*1rhO,f3YN/EIKLkg_=KS+o/ +JUi6!I=6KiH?jaZGBS+NFE;JBEH#i6DJa3*CMIQsB`D]JAn>OaA,]pB@:3JM?X@&Er`oJ-!*]>( +s&]8&d\lf9rMBOkqa^QRr'g0EnjEFDq;1kWo""D&m^`;+r'gKPpIG0Qr(6`WrCd,`r_s,[5Crf[;F!0mJJ!LB)OQr09?S"#q= +SXuFFTV8'RUSO]^VPgAlWiE,$Xfek3Yd(O@['d?O\@K2_]Y(tn^VI_'_o9U7a2lBFbKS5VcHstd +daQ^rf%8O+g"P07h;-rFrnmt=ioB([jo4BJkNM-ol0@R"li-8NmJlVQn,MnVnb_nVoDS=Vp&+O] +p\4I[q>C*^qtp +JcC<$JcGHDo)ARcrVZQirqcZjrV6Bd!;?Bas7H?_rpg-\nF6GG!Uf@Sm/QAblKRQski_*jjlPR` +j5T(Wi8EMLrnRq:gY1B7g"=p.f%'cLJ()indEp4bcHXSVbK@uLaN2EA`Poa3_SO%&^V7Co]Xt_b +\@8oT['R*EZ*:F7XfSS'Wi2hnVPL#_U7n6PSt2C@R[KP1QBd`"P*1rhO,f3YN/EIKLkg_=KS+o/ +JUi6!I=6KiH?jaZGBS+NFE;JBEH#i6DJa3*CMIQsB`D]JAn>OaA,]pB@:3JM?X@&Er`oJ-!*]>( +s&]8&fmrUBq0r32r'pTQnjN%9s$HOWpP\-j!/p0#r'gKPpIG0Qr(6`WrCd,`r_3BjqPa"Qrg*VP +jd5_-s'GV1ra>b7r*oY8rabqs,[5Crf[;F!0mJJ!LB)OQr09?S"#q=SXuFFTV8'RUSO]^VPgAlWiE,$ +Xfek3Yd(O@['d?O\@K2_]Y(tn^VI_'_o9U7a2lBFbKS5VcHstddaQ^rf%8O+g"P07h;-rFrnmt= +ioB([jo4BJkNM-ol0@R"li-8NmJlVQn,MnVnb_nVoDS=Vp&+O]p\4I[q>C*^qtp +JcC<$JcGHDo)ARcrVZQirqcZjrV6Bd!;?Bas7H?_rpg-\nF6GG!Uf@Sm/QAblKRQski_*jjlPR` +j5T(Wi8EMLrnRq:gY1B7g"=p.f%'cLJ()indEp4bcHXSVbK@uLaN2EA`Poa3_SO%&^V7Co]Xt_b +\@8oT['R*EZ*:F7XfSS'Wi2hnVPL#_U7n6PSt2C@R[KP1QBd`"P*1rhO,f3YN/EIKLkg_=KS+o/ +JUi6!I=6KiH?jaZGBS+NFE;JBEH#i6DJa3*CMIQsB`D]JAn>OaA,]pB@:3JM?X@&Er`oJ-!*]>( +s&]8&pI>'Ncpmn&r'pTQnjN%9s$HN^pIa:6nOWRHqaUVf^;%Fu_SX40`Q#s>ai_fNc-FV]dF$CkeCE.%f@\d1g=tH>hV\=j"l\J$j5f>$ +jp:/6kiq?slKdd8m/QJQmeuVSnG_tTo)A7Zo_A+WpAF[Zq"smbqXsa_r;-BYrdk*is*t~> +JcC<$JcGHDo)ARcrVZQirqcZjr:pQ7n+ +=oVUTVt-__V#[Cg8,YpS7Iik;6i#R=]BHia\c92<7JfRK8,PpV8bl!X9DqQ`:&jAUjo=KCjo!C( +c2#ZUc2#TZbP''Y?Me+0@/aU4@fBm;AGg$ErC(TFT$@]G5HL_GlE!dHN&9kI/A?lIf=iq +JGt-"K)C9$K`?c)LB!&/M#E21MZ8V6N;nn;NrG(@OHG\)Op@28Pa.N"QC%T<St;RI +TqS3UUnjiaVl-JmWiE/&Xfek3Z*L^B['mEP\@K2_]Y2%o^VRe(_o9U7aN2KGbKS5VcHstddaQ^r +f%8O+g"P39h;-rFi8ESRro4%?jo4BCkNMp0!p]+;rp9[Ps6fjSs7$$Xr:9gXrq-!YrV$-_p\=X] +qtg$`qY^3gm/DS9`rCP~> +JcC<$JcGHDo)ARcrVZQirqcZjr:pQ7n+ +=oVUVJFS-cIecM47f,XF7.N_@UrSDmMZ$!@7e]FN8Gu-U9)_K^9`@c`W;ideR,XJ+Q2k7g?iOO5 +@JjU6A,g*;Ac?<@BDcHBC&_rFC]A5MD>S5MDuO\UQgpI(RJrTKHM;dMI//-_HMr-fGkuX_G5ZRZ +FSp4WEp%H>ErC(TFT$@]G5HL_GlE!dHN&9kI/A?lIf=iqJGt-"K)C9$K`?c)LB!&/M#E21MZ8V6 +N;nn;NrG(@OHG\)Op@28Pa.N"QC%T<St;RITqS3UUnjiaVl-JmWiE/&Xfek3Z*L^B +['mEP\@K2_]Y2%o^VRe(_o9U7aN2KGbKS5VcHstddaQ^rf%8O+g"P39h;-rFi8ESRro4%?jo4BC +kNMp0!p]+;rp9[Ps6fjSs7$$Xr:9gXrq-!YrV$-_p\=X]qtg$`qY^3gm/DS9`rCP~> +JcC<$JcGHDo)ARcrVZQirqcZjr:pQ7n+ +=oVU?7eoRQ7f,XF7.N_@S5MDuO\UErC(TFT$@]G5HL_GlE!dHN&9kI/A?lIf=iqJGt-"K)C9$K`?c)LB!&/M#E21 +MZ8V6N;nn;NrG(@OHG\)Op@28Pa.N"QC%T<St;RITqS3UUnjiaVl-JmWiE/&Xfek3 +Z*L^B['mEP\@K2_]Y2%o^VRe(_o9U7aN2KGbKS5VcHstddaQ^rf%8O+g"P39h;-rFi8ESRro4%? +jo4BCkNMp0!p]+;rp9[Ps6fjSs7$$Xr:9gXrq-!YrV$-_p\=X]qtg$`qY^3gm/DS9`rCP~> +JcC<$JcGHDnc&LcrVZNhs8)`jrV6Ees7ZEas7?<_rUL$[nF6GG#O_!Hm-O'(lMg#Kki_s-!TiDA +irS/urnmh7hYu=*j\A7K+Y@UWYPra,_5?![G7!aAi3 +rE9/&s&T2$go'Y=rMBNbq+(?Pr'g-DoL&N4s53gfl+5f`!4_trqaUs(D7Crb;@Hr+l:Jrb_RNrbqdTqf)UVrQG#\ +ps&ESqTAl_pNlU]k^<2Qp3Q[_rHS0_rHA0_q/lOUqf:h=qf;UUqK2^Zrc\0_rcnEfr-J?hs*X`m +rdOlsr.+fus+:0$s+LE+rJ(?-s+pW1s,-i7rf$l:s,R)>s,[5Crf[;F!0mJJs- +JcC<$JcGHDnc&LcrVZNhs8)`jrV6Ees7ZEas7?<_rUL$[nF6GG#O_!Hm-O'(lMg#Kki_s-!TiDA +irS/urnmh7hYu=*j\A7K+Y@UWYPra,_5?![G7!aAi3 +rE9/&s&T2$gjnpErdOlss%)rUr'pTQnO3":rM0=e`/FR_qaUs(D7Crb;@Hr+l:Jrb_RNrbqdTqf)UVopFg.s-WP,pj;4P +q0Vg]rH\?dqKMm]rcS$Yr,_aUk&L9=r,_^VrcS3`qfi$ard"Efrd4Zmr-eQns*srss+13%r.G$& +s+UE+s+gW1rJCQ3s,6l8s,I&=rf@)@!0R8Ds-!GIrg!ML!13\PAso*WS"-">St;RITqS3UUnjia +Vl-JmWiE,$Xf\e2Yd(L?['d?N\%0&\]=bhk^VI\&_o0O5a2l?DbKJ,ScHjkbdF6Upe^i@)g"P07 +gtgfChr*GOioB([jlPXekNM-ol0@R"rTjUQmdC&Bs7$$Xr:9jYrUfpYrV$0`p%\I\qtg!_qY^3g +m/DS9`W(G~> +JcC<$JcGHDnc&LcrVZNhs8)`jrV6Ees7ZEas7?<_rUL$[nF6GG#O_!Hm-O'(lMg#Kki_s-!TiDA +irS/urnmh7hYu=*j\A7K+Y@UWYPra,_5?![G7!aAi3 +rE9/&s&T2$a%$)"q+(?Pr'g-DoL&IU!*B"gqapi[oLeLBo18gKqaUb7qdTS8rabqs,[5Crf[;F!0mJJs- +JcC<$JcGECo)ARcrquWirqcZjr:p[[^NTMZa-j?YHG"/X/`1uVl-DfUnaWWTV%gHS=>t8R$a2)Q'@GpOcYWaNJrdQM2@%DL4t;5 +K7\W(IsufoI!^0bG^"@TF`__HEcH)lS". +>5_V(=T;J#a$\8,YpS7I`e>6i,[;]@a^c\c"to7eT@N8Gu-U9)_K^9`.W^ +ir\;fch>ZTc2#TZbOs$T?iOO5@JjU6A,g*;Ac?<@BDcHCC&VlFC]8/LD>S5MDuXeQEW1"XF8^4Z +bkTHUbkK"?OHG\)P5g^GPl?pZQC!r*R$jA2S"#q< +SXuFFT`1W[U8+N[V5C/gW2ZetXKAV-YHY7:Za7$H[^WcW\\#Me]t_=t_8=+.`Q#s>aND]Lbg+M[ +d*^:jeC<%"f@\d1g=tE=h;7&Ii8N\Uj5f>$joOZ/rojLLlg+Q:s6]jSrpTmVrpfpWrq$-]q=X^[ +r:fp[qt^-co_\O`q>K[ZJcE[gJ,~> +JcC<$JcGECo)ARcrquWirqcZjr:p[[^NTMZa-j?YHG"/X/`1uVl-DfUnaWWTV%gHS=>t8R$a2)Q'@GpOcYWaNJrdQM2@%DL4t;5 +K7\W(IsufoI!^0bG^"@TF`__HEcH)lS". +>5_V(=T;J#"?OHG\)P5g^GPl?pZQC!r*R$jA2S"#qaND]Lbg+M[d*^:jeC<%" +f@\d1g=tE=h;7&Ii8N\Uj5f>$joOZ/rojLLlg+Q:s6]jSrpTmVrpfpWrq$-]q=X^[r:fp[qt^-c +o_\O`q>K[ZJcE[gJ,~> +JcC<$JcGECo)ARcrquWirqcZjr:p[[^NTMZa-j?YHG"/X/`1uVl-DfUnaWWTV%gHS=>t8R$a2)Q'@GpOcYWaNJrdQM2@%DL4t;5 +K7\W(IsufoI!^0bG^"@TF`__HEcH)lS". +>5_V(=T;J#6i'jY8c)-@8cM?[8bP^R7JfRJ8,Z!W8bl!X9DqQ^ +:&e5ke;YEu[;"[W]?iOO5@JjU6A,g*;Ac?<@BDcHCC&VlFC]8/LD>S5MDuXeQEW1"XF8^4; +<;:e6Hg6"RHhVjaH2`'aGQ)daFnp.XF8U(=EVjeTF8C"XFoHR]GQ2peH2N!gHiAEjIK+crJ,Fis +JcC?"KE$W)L&Hc+L]<2/M>rJ5MuAS9NK0%tNrkE*OoCODP5pjHPn97JQ^F/.R@9V7S=H.AStD\T +Th_>WUnjiaVl-JmWiN5'Xfek3Yd1UA['d?O\@K/^]Y(qm^VI\&_o0O6a2l?EbKJ,TcHjkbdaQ^q +e^i@)g"P07gtgfChr*GOioB([jo4BCkNMp0!p]+;rp9[Ps6fmTs7$$Xr:9jYrq-$ZrV$0`pA"O\ +qtfs^qu$9gm/DS9`;b>~> +JcC<$JcGECo)ARcrVZQirqcZjr:p[[^NQLZa-j?YHG"/X/`1uVl-DfUnaWWTV%gHS=>t8R$X,(Q'7AoOcYWaNJrdQM2@%CL4t;5 +K7SQ'IsufoI!U*aG^"@TF`__HEcH)s(D7Crb;@Hr+l:Jrb_RNrbqdT +qf2RTrc@pXrH8*_rlt/\p<35WpNu1Qq0Vg]rH\?dqKMm]rH7sYrH%jVic4m:rH%jXrH8-`qfi'b +rd"Efs*O`mrI+]prdXlss+10$rIb-'s+UE+s+gW1rJCQ3s,6i7s,@#=rK$u?!0R8Ds-*JIrfmMM +QiSt;RITV8'RUSO]^VPg>jWN)u!XKAV-YctCVf^;%Fu_SX4/ +`Q#s>ai_fMc-FV\d*^:jeC<($f@\d1g=tE=hV[8LiSrkWj5f=ak3(pkrojIKli-8NmJlVRn,MnV +nbhtXoD\CXp&4U^p\+CZq>:$\qtg6drTjH6s2=qf~> +JcC<$JcGECo)ARcrVZQirqcZjr:p[[^NQLZa-j?YHG"/X/`1uVl-DfUnaWWTV%gHS=>t8R$X,(Q'7AoOcYWaNJrdQM2@%CL4t;5 +K7SQ'IsufoI!U*aG^"@TF`__HEcH)b7qdTS8rabq +St;RITV8'RUSO]^VPg>jWN)u!XKAV-YctCVf^;%Fu_SX4/`Q#s>ai_fMc-FV\ +d*^:jeC<($f@\d1g=tE=hV[8LiSrkWj5f=ak3(pkrojIKli-8NmJlVRn,MnVnbhtXoD\CXp&4U^ +p\+CZq>:$\qtg6drTjH6s2=qf~> +JcC<$JcGECo)ARcrVZQirqcZjr:p[[^NQLZa-j?YHG"/X/`1uVl-DfUnaWWTV%gHS=>t8R$X,(Q'7AoOcYWaNJrdQM2@%CL4t;5 +K7SQ'IsufoI!U*aG^"@TF`__HEcH)b7qdTS8rabq +JcC<$JcGECo)ARcrVZQirqcWirV6Ees7ZEas7H?_rpp*Z!:^!Vs6]mSrp0^PlK\B5!U/_Gjr3@B +jQ#:[iSi_Qhqm5Gh;$c>g=k64f[na+ec+&%e'cXkd*M^:FNr%QbK@rJaN)<>`Pf[2_SO"%^:h1l +]=PP_\$i`PZa6sBYck43XK/A$W2HPiUnjcZTqJ!KSXc1,Q'IPrP*(fdNfB!UMM[1GL5(D8 +K7e`*J:E#rI=$9dH$FOWG'.nKF)l8?E,TW3D/=!'C2*Z\#%qOZARo=]raGn:@/aO5?3":0>lS". +>5_V(=T2D#rb).Brb;CIqeQ4Jrb_OM +rbqdTqf2UUrH%gWrH8'^q02e]oum)Uom?.Tpj;^\r-A6cqKMp^rH7sYr,_gWi,S[8rH%jXrcS3` +r-/-bs*=Ngs*Ocnr-eTos*sutrdk*$rIb-'s+UE+s+gW1rJCQ3s,6i7s,I&=rf@)@s,m;D!gAk5 +rg!ML!13\PA!rdSS"#q +JcC<$JcGECo)ARcrVZQirqcWirV6Ees7ZEas7H?_rpp*Z!:^!Vs6]mSrp0^PlK\B5!U/_Gjr3@B +jQ#:[iSi_Qhqm5Gh;$c>g=k64f[na+ec+&%e'cXkd*M^:FNr%QbK@rJaN)<>`Pf[2_SO"%^:h1l +]=PP_\$i`PZa6sBYck43XK/A$W2HPiUnjcZTqJ!KSXc1,Q'IPrP*(fdNfB!UMM[1GL5(D8 +K7e`*J:E#rI=$9dH$FOWG'.nKF)l8?E,TW3D/=!'C2*Z\#%qOZARo=]raGn:@/aO5?3":0>lS". +>5_V(=T2D#rb).Brb;CIqeQ4J +rb_OMrbqdTqf2UUrH%gWrH8'^q02Fus-WP,om?.Tpj;^\r-A6cqKMp^rH7sYr,_gWi,S[8rH%jX +rcS3`r-/-bs*=Ngs*Ocnr-eTos*sutrdk*$rIb-'s+UE+s+gW1rJCQ3s,6i7s,I&=rf@)@s,m;D +!gAk5rg!ML!13\PA!rdSS"#q +JcC<$JcGECo)ARcrVZQirqcWirV6Ees7ZEas7H?_rpp*Z!:^!Vs6]mSrp0^PlK\B5!U/_Gjr3@B +jQ#:[iSi_Qhqm5Gh;$c>g=k64f[na+ec+&%e'cXkd*M^:FNr%QbK@rJaN)<>`Pf[2_SO"%^:h1l +]=PP_\$i`PZa6sBYck43XK/A$W2HPiUnjcZTqJ!KSXc1,Q'IPrP*(fdNfB!UMM[1GL5(D8 +K7e`*J:E#rI=$9dH$FOWG'.nKF)l8?E,TW3D/=!'C2*Z\#%qOZARo=]raGn:@/aO5?3":0>lS". +>5_V(=T2D#X2e:]+T"@/aU4@fBm;AG]srJ5MuAV7NW5%St;RITV8'RUSO]^VPg>jWN)u!XKAV-YHY79Za7$H[^N]V\[oDc]tV7s_8=(,`Poj; +aN;TJbg"GYd*^7he'uq!f@S[.g=tE=h;7&Ii8N\Uj5f:_k2tjjrojLLlg+Q:s6TgSrU9dUs7-$X +s7?6^qXsg\r:fp[qt^-coDAC^qYfaZJcEUeJ,~> +JcC<$JcGECnc&LcrVZNhrqcZjr:pg=k64f[na+ec+'He'cXkd*L%`cHXSVbK@rJaN)<>`Pf[2_SO%&^:h1l +]=PP_\$i`PZa6sBYck43XK/A$W2HPiUnjcZTqJ!KSXc1,Q'IPrP*(fdNfB!UMM[1FL5(D8 +K7\Z)J:E#rI=$9dH$FOWG'.nKF)l8?E,TW3D/=!'C2*Z\!G?$DAH?=OraGq;?srt@!a]/br_*;bqPO9brCQuZq+(?PqaKm?rBpJ=i4J-_rC-TQ +pIG-PrCQfWr_*2`qb@%Jro3q#qTJrarlbAeprr`^q98TVpWED@ra>b7qdTS8rabqf#~> +JcC<$JcGECnc&LcrVZNhrqcZjr:pg=k64f[na+ec+'He'cXkd*L%`cHXSVbK@rJaN)<>`Pf[2_SO%&^:h1l +]=PP_\$i`PZa6sBYck43XK/A$W2HPiUnjcZTqJ!KSXc1,Q'IPrP*(fdNfB!UMM[1FL5(D8 +K7\Z)J:E#rI=$9dH$FOWG'.nKF)l8?E,TW3D/=!'C2*Z\!G?$DAH?=OraGq;?srt@!a]/br_*;bqLAN;rCQuZq+(?PqaKm?rBgRZr1j1Jjc&_f +p58f;qaUs(D4Bs(VIIr+l:J +rb_OMrbqdTqf2UUrH%gWrH8'^pNQO[s*=L0!1f#~> +JcC<$JcGECnc&LcrVZNhrqcZjr:pg=k64f[na+ec+'He'cXkd*L%`cHXSVbK@rJaN)<>`Pf[2_SO%&^:h1l +]=PP_\$i`PZa6sBYck43XK/A$W2HPiUnjcZTqJ!KSXc1,Q'IPrP*(fdNfB!UMM[1FL5(D8 +K7\Z)J:E#rI=$9dH$FOWG'.nKF)l8?E,TW3D/=!'C2*Z\!G?$DAH?=OraGq;?srt@!a]/br_*;bqF:KWrCQuZq+(?PqaKm?rBpQ`r`/kfnk/"8 +ogo$MqaUb7qdTS8rabqf#~> +JcC<$JcGBBo)ARcrVZQirqcZjr:ph;-l@gY1B7f\"g-f%&=#eC2jndEp7dcHa\YbKJ&MaN2EA`Pod5_SX.)^V7Co +]Xtbc\@8oT['R*EZ*:F7XfSS'WMl_mV50o^TqS-NSt2C@R[KP0QBd\uP*1ofO,f3YMi*@JLPCP; +KS+l-J:N,uI=-BfH?jaZG7f"@FEDSEEH,r9DJj<-CMR[!rb)=FB)Z?BA7PUJ!b#JEra5\3!+#P. +s'#J,r)s&%s&],!r`/ttqc!Jlr_`Phr_NMgqb@&`r_*)[r^m&Zq+(?PqaKg=qqh7`jLaTdr^H]R +p.,'Pr(6`WrCd,`qFq#diSjdq!9 +s,d8Crf[;Fs-3MJs- +JcC<$JcGBBo)ARcrVZQirqcZjr:ph;-l@gY1B7f\"g-f%&=#eC2jndEp7dcHa\YbKJ&MaN2EA`Pod5_SX.)^V7Co +]Xtbc\@8oT['R*EZ*:F7XfSS'WMl_mV50o^TqS-NSt2C@R[KP0QBd\uP*1ofO,f3YMi*@JLPCP; +KS+l-J:N,uI=-BfH?jaZG7f"@FEDSEEH,r9DJj<-CMR[!rb)=FB)Z?BA7PUJ!b#JEra5\3!+#P. +s'#J,r)s&%s&],!r`/ttqc!Jlr_`Phr_NMgqb@&`r_*)[r^m&Zq+(?PqaKg=!2BCdhi.)`pPSr= +qaU9LrCHiXqF^]Zr_3/_!)EHh!2og`jHoV,p6YfFr*TJ3raG_6raYt=qdoe>rb).Brb;@Hr+l:J +rb_RNrbqdTqJlLTrH%gWrH8'^pNQO[qg%aYoR$7Yom?CYrH\?dqKMm]rcS'ZrH%mWhJrL7rH%jX +s)nVf^;%Fu_SX4/`Q#s>aND]Lbg"GZd*^7ieC<%"f@\d1g=tE=h;7&Ii8N\Uj5f=ak3(pkl07Ku +li-5PmI'E@mfN"KnbhtXoD\CZp&4U_p\+CZq>0sZqtg6drTjH6s1nYb~> +JcC<$JcGBBo)ARcrVZQirqcZjr:ph;-l@gY1B7f\"g-f%&=#eC2jndEp7dcHa\YbKJ&MaN2EA`Pod5_SX.)^V7Co +]Xtbc\@8oT['R*EZ*:F7XfSS'WMl_mV50o^TqS-NSt2C@R[KP0QBd\uP*1ofO,f3YMi*@JLPCP; +KS+l-J:N,uI=-BfH?jaZG7f"@FEDSEEH,r9DJj<-CMR[!rb)=FB)Z?BA7PUJ!b#JEra5\3!+#P. +s'#J,r)s&%s&],!r`/ttqc!Jlr_`Phr_NMgqb@&`r_*)[r^m&Zq+(?PqaKg=rD`eslq6>1pIP9P +qaU9LrCHiXqF^]Zr_3/_!)EJns&T1spJKR@r_`T#s'Yh7r*oY8s()"s,d8Crf[;F +s-3MJs- +JcC<$JcGBBo)ARcrVZQirqcWirV6Bds7ZEa!qc*UrUL$[nF6GGs6]mSrp0^PlK\B5!U/_Gk5XNC +jSn0?io0mp(#Rm)h;-l@gY1B7f\"g-f%&=#eC2kFd='BfcHa\YbKJ&MaN2EA`Pod5_SX.)^V7Co +]Xtbc\@8oT['R*EYct=6XfSS'WMl_mV50o]TqS-NSt2@?R[KP0QBd\uP*1ofO,f0XMi*@ILPCP; +KS+l-J:N,uI=-BfH?jaZGBS+NFE;JBEH#i6DJa3*CMIQtBP;$jrac=F@q/tW@:Q7n*=oMP'=8Z+uX2i:]=,d:&[ic9DV9[8c;3U8,PjR7I3G?hYFhG]BHj+7J]LJ +8,PpV8bl!X9DqQ]:&ducipP"hbi$\C?iFI4@JjU6A,g*;Ac?<@BDcHBC&_rFC]A5MD>S5MDuO_P +EW1"XF89qVFo?LXGPcX^H1H:=HhD^`H2W!`GQ)dbFnp.YF8U(MEVOMFEW'qVF8U.ZFoHR_GQ2pe +H2W'hHiJKlIK+crJ,OotJcC?#KE$W)L&Qi,L]<2/M>rJ5MuAV7NW5%dTV/!PU8+KZUnsrdVl6SpWiN5'Xfek3Yd(L?Za@-K\%&uZ]"G\h^;%G! +_SX40`Q#s>ai_fMc-FV\d*^:jeC<%#f@\d1g=tE=h;7)JiSrkWj5f=ak3(t-klU/9li-5PmI'EA +n,MnWnbr%YoD\CZp&4U_p\4I[q>:$Zqtg6crTjH6s1eSa~> +JcC<$JcGBBo)ARcrVZQirqcWirV6Bds7ZEa!qc*UrUL$[nF6GGs6]mSrp0^PlK\B5!U/_Gk5XNC +jSn0?io0mp(#Rm)h;-l@gY1B7f\"g-f%&=#eC2kFd='BfcHa\YbKJ&MaN2EA`Pod5_SX.)^V7Co +]Xtbc\@8oT['R*EYct=6XfSS'WMl_mV50o]TqS-NSt2@?R[KP0QBd\uP*1ofO,f0XMi*@ILPCP; +KS+l-J:N,uI=-BfH?jaZGBS+NFE;JBEH#i6DJa3*CMIQtBP;$jrac=F@q/tW@:Q7n*=oMP'=8Z+uX2i:]=,d:&[ic9DV9[8c;3U8,PjR7I3G?UYUmuMtr817J]LJ +8,PpV8bl!X9DqQ]:&ducVuN.DQhZm=Qi1:j@/aU4@fBm;AGg$OT1IAOogi3Pl?sJ +QN*G%R]TqS3UUSO]^VPg>jWN)u!XKAV-YHY79ZEpmE[C3QS\[f;a]Y2%o +^VRe(_o9U7a2lBFbKJ/UcHjkbdaQ^qe^rF*g"P07gtgfCi8ESRioB([jlY^gkl0fJlKdd8liQSB +mf)\TnGi%Wo)J=\o_\=[pAOa[q"smaqXXO[r:p6Vrdk*as*t~> +JcC<$JcGBBo)ARcrVZQirqcWirV6Bds7ZEa!qc*UrUL$[nF6GGs6]mSrp0^PlK\B5!U/_Gk5XNC +jSn0?io0mp(#Rm)h;-l@gY1B7f\"g-f%&=#eC2kFd='BfcHa\YbKJ&MaN2EA`Pod5_SX.)^V7Co +]Xtbc\@8oT['R*EYct=6XfSS'WMl_mV50o]TqS-NSt2@?R[KP0QBd\uP*1ofO,f0XMi*@ILPCP; +KS+l-J:N,uI=-BfH?jaZGBS+NFE;JBEH#i6DJa3*CMIQtBP;$jrac=F@q/tW@:Q7n*=oMP'=8Z+uX2i:]=,d:&[ic9DV9[8c;3U8,PjR7I3G?<9d*:8bbjV7J]LJ +8,PpV8bl!X9DqQ]:&dugS5M +DuO_PEW1"XF89qVFo?LXGPcX^H1H:=HhD^`H2W!`GQ)dbFnp.YF8U(MEVOMFEW'qVF8U.ZFoHR_ +GQ2peH2W'hHiJKlIK+crJ,OotJcC?#KE$W)L&Qi,L]<2/M>rJ5MuAV7NW5%dTV/!PU8+KZUnsrdVl6SpWiN5'Xfek3Yd(L?Za@-K\%&uZ]"G\h +^;%G!_SX40`Q#s>ai_fMc-FV\d*^:jeC<%#f@\d1g=tE=h;7)JiSrkWj5f=ak3(t-klU/9li-5P +mI'EAn,MnWnbr%YoD\CZp&4U_p\4I[q>:$Zqtg6crTjH6s1eSa~> +JcC<$JcGBBo)ARcrVZNhrqcZjr:plS%.>5_V(=T2D"S5MDuO_Q +EW'qWF89qVFo6FWGPl^_H16.>HhD^_H2W!aGQ)daFo$4YF8^.OEV+5CEW1"XF8L(YFoQX_GQ2pf +H2W'hHiJKlIK+crJ,Om!JV&LPKE$W)L&Hc+LB*//M>rJ5MuAV7NW5%KUXJcEIaJ,~> +JcC<$JcGBBo)ARcrVZNhrqcZjr:plS%.>5_V(=T2D"S5MDuO_QEW'qWF89qVFo6FWGPl^_H16.>HhD^_H2W!aGQ)daFo$4YF8^.OEV+5CEW1"XF8L(Y +FoQX_GQ2pfH2W'hHiJKlIK+crJ,Om!JV&LPKE$W)L&Hc+LB*//M>rJ5MuAV7NW5%KUXJcEIaJ,~> +JcC<$JcGBBo)ARcrVZNhrqcZjr:plS%.>5_V(=T2D"S5MDuO_QEW'qWF89qVFo6FWGPl^_H16.>HhD^_H2W!aGQ)daFo$4YF8^.OEV+5CEW1"XF8L(Y +FoQX_GQ2pfH2W'hHiJKlIK+crJ,Om!JV&LPKE$W)L&Hc+LB*//M>rJ5MuAV7NW5%KUXJcEIaJ,~> +JcC<$JcGBBnc&IbrVZQirqcWirV6Bds7ZEas7?<_rUL$[nF6GGs6]mSrp9[N!:'RJs6'IGroO:D +jQ-=#!TN);i.'Y@hVI#CgtUQ:g"G$0f@JO'eC;sqda?Ihcd'h\bfe2PaiVWE`l5p8_ns:,^q[Xt +]Y(kf\[],W[^ +KnG#0JUi9#IXQTjH?sj]GBXL>F`__HEcH)b7r*oY8rabqrg<_Rs-iqV!h>gPrgj._T`1VcU8.^`!Mu[mVb*hdWiE,$Xf\b0YctCKRWJcEF`J,~> +JcC<$JcGBBnc&IbrVZQirqcWirV6Bds7ZEas7?<_rUL$[nF6GGs6]mSrp9[N!:'RJs6'IGroO:D +jQ-=#!TN);i.'Y@hVI#CgtUQ:g"G$0f@JO'eC;sqda?Ihcd'h\bfe2PaiVWE`l5p8_ns:,^q[Xt +]Y(kf\[],W[^ +KnG#0JUi9#IXQTjH?sj]GBXL>F`__HEcH)[gXs,-hF +qF:0KrCHiXqF^]Zr_3/_s%`QjrhTU^l'MC:q3V#Fo9]D_ra>b7r*oY8rabqrg<_Rs-iqV!h>gPrgj._T`1VcU8.^`!Mu[mVb*hdWiE,$Xf\b0YctCKRWJcEF`J,~> +JcC<$JcGBBnc&IbrVZQirqcWirV6Bds7ZEas7?<_rUL$[nF6GGs6]mSrp9[N!:'RJs6'IGroO:D +jQ-=#!TN);i.'Y@hVI#CgtUQ:g"G$0f@JO'eC;sqda?Ihcd'h\bfe2PaiVWE`l5p8_ns:,^q[Xt +]Y(kf\[],W[^ +KnG#0JUi9#IXQTjH?sj]GBXL>F`__HEcH)C'el2H86^&NT~> +JcC<$JcGBBnc&IbrVZQirqcWir:p +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEEH,r9DJj<-rbD^QBkV0mB4h-S!G#^>@fKm:@/aO5?3":0 +>lS%.>5VP'=T2D"j:A[cb9`Ic^9)_E\8GG^Q7f#RE7/Ys8][=@k7J]LI +8,Z!W8bl!W9E%W]:&[ocir@6gb5fcHbPbfJ@/aU4@fBm;AG]s%=OT1IBP5gaGPl6jK +QC!s:Qi`\ERf8fVS,f,ZT)YD_T`1VcU8.^`!Mu[mVcfstWiE,$Xf\b0YctCb +]Y2%o^qmn)_o0O6a2l?EbKJ,ScHjkbdF-Ooe^i@(f\5'6gtgfChr*GOioB([jlY^gkih9qlKdd& +m-X3.rpTmVs7-'Ys7?9_r:U'_rV--_qt^-co)&4[q#0IVJcEC_J,~> +JcC<$JcGBBnc&IbrVZQirqcWir:p +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEEH,r9DJj<-rbD^QBkV0mB4h-S!G#^>@fKm:@/aO5?3":0 +>lS%.>5VP'=T2D"j:A[cb9`Ic^9)_E\8GG^Q7f#RE7/`n]V9k1pMuQ6B +7eT@N8Gu-U9)VE^9_qK_:AgsgR-U+:R-0h7?iOO5@JjU6A,g*:AcHBABDcHBC&VlFC]8/LD>\;M +DuO_QEW'qWF89qUFo?LWGPcX^H1$"CHh2R]H2W!aGQ)daFo$4ZF8^.QEUIf?EW1"XF8L(ZFoQX_ +GQ2pfH2`-iHiJKlIK+`rJ,OotJH1<#KE$W)L&Qi,L]<20M>rJ5MuAV7N<#";O8k=AOoCODPQ-mG +Pld8aND]Lbg"GZd*^7heC<%"f@S[/g=tE=h;7&Ii8N\Uj5f=ak3(sll07L! +lg4!*mI'uBs7$'YrUU![s7H6^rq? +JcC<$JcGBBnc&IbrVZQirqcWir:p +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEEH,r9DJj<-rbD^QBkV0mB4h-S!G#^>@fKm:@/aO5?3":0 +>lS%.>5VP'=T2D"j:A[cb9`Ic^9)_E\8GG^Q7f#RE7/U'K9(P^P9(PXS +7J]LI8,Z!W8bl!W9E%W]:&[oc\;M +DuO_QEW'qWF89qUFo?LWGPcX^H1$"CHh2R]H2W!aGQ)daFo$4ZF8^.QEUIf?EW1"XF8L(ZFoQX_ +GQ2pfH2`-iHiJKlIK+`rJ,OotJH1<#KE$W)L&Qi,L]<20M>rJ5MuAV7N<#";O8k=AOoCODPQ-mG +Pld8aND]Lbg"GZd*^7heC<%"f@S[/g=tE=h;7&Ii8N\Uj5f=ak3(sll07L! +lg4!*mI'uBs7$'YrUU![s7H6^rq? +JcC<$JcGBBnc&IbrVZNhrqcZjr:p9cs7ZEas7?<_rUU!Y!:]sU!q,ICrp0^PlK\B5!pJh1roOII +jQ,@]io8qri!8/rhVI#CgtVh^!SQ-)f)aIQrmV,#da?Ihci243c-4ASb/q`Ga2Z*:_ns:,^q[Xt +]Y(kf\[],W[^ +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEEH,r9DJj<-Chmg$C&VcHB4h-S!b>eNraGq;?srt@s'G_2 +rETA,s'#>'s&f8%r)Whtr`&eor_i_mr)!Ags%`Gcr_3;aqb$iZrCH]RqaUBMogJc9pq?Urc8!Z +r,hp\s*"?bs*4QhrHeKj!.=`ns*artrIFp!!.t0%!ec8]rItB/Lku"d!fDnorJ^c9!07#=s,d8C +rf[;Fs-3JIs-ai_fMc-FV\d*^:jeC<%"f@\d1g=tE=h;7&Ii8N\Uj5f=a +k3(t-klL)8rp0^RmdC)Cs6p$YrUU![rq--]rq??cq=sm`qYKd[q>C!cl2H86]DmB~> +JcC<$JcGBBnc&IbrVZNhrqcZjr:p9cs7ZEas7?<_rUU!Y!:]sU!q,ICrp0^PlK\B5!pJh1roOII +jQ,@]io8qri!8/rhVI#CgtVh^!SQ-)f)aIQrmV,#da?Ihci243c-4ASb/q`Ga2Z*:_ns:,^q[Xt +]Y(kf\[],W[^ +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEEH,r9DJj<-Chmg$C&VcHB4h-S!b>eNraGq;?srt@s'G_2 +rETA,s'#>'s&f8%r)Whtr`&eor_i_mr)!Ags%`Gcr_3;aqb$iZrCH]RqaUBMogAeUrh[kupko,@ +qF:0Kr(-cXq+CWZrCm)_r_rc8!Zr,hp\ +s*"?bs*4QhrHeKj!.=`ns*artrIFp!!.t0%!ec8]rItB/Lku"d!fDnorJ^c9!07#=s,d8Crf[;F +s-3JIs-ai_fMc-FV\d*^:jeC<%"f@\d1g=tE=h;7&Ii8N\Uj5f=ak3(t- +klL)8rp0^RmdC)Cs6p$YrUU![rq--]rq??cq=sm`qYKd[q>C!cl2H86]DmB~> +JcC<$JcGBBnc&IbrVZNhrqcZjr:p9cs7ZEas7?<_rUU!Y!:]sU!q,ICrp0^PlK\B5!pJh1roOII +jQ,@]io8qri!8/rhVI#CgtVh^!SQ-)f)aIQrmV,#da?Ihci243c-4ASb/q`Ga2Z*:_ns:,^q[Xt +]Y(kf\[],W[^ +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEEH,r9DJj<-Chmg$C&VcHB4h-S!b>eNraGq;?srt@s'G_2 +rETA,s'#>'s&f8%r)Whtr`&eor_i_mr)!Ags%`Gcr_3;aqb$iZrCH]RqaUBMogJaXk">5rc8!Zr,hp\ +s*"?bs*4QhrHeKj!.=`ns*artrIFp!!.t0%!ec8]rItB/Lku"d!fDnorJ^c9!07#=s,d8Crf[;F +s-3JIs-ai_fMc-FV\d*^:jeC<%"f@\d1g=tE=h;7&Ii8N\Uj5f=ak3(t- +klL)8rp0^RmdC)Cs6p$YrUU![rq--]rq??cq=sm`qYKd[q>C!cl2H86]DmB~> +JcC<$JcG?Ao)ARcrVZNhrqcWir:p +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEEH,r9DJj<-Chmg$C&VcHB4h-Ss'u+>raPn9!+>b4s'G_2 +rETA,s'#>'s&f;&qc<_sr`&eor_ibnr)!Agr_EAcr_3;aqb$fYrCH]RqaUBMpI,#=!T1Th^A#>' +]^NH47J]LH8,Z!V8bu'X9E%W]:&[lf:]05?bl,``biR%I?iFI4@JjU7A,^$:Ac?<@BDcHCC&VlE +C]A5MD>S5MDuFYPEW'qVF89qVFo6FVGPZR\H0]eKHgc:ZH2Mp`GQ)daFo$4ZF8^.REU.T=EW1"X +F8U.[FoHR_GQ2mfH2W'hHiJKmIK+crJ,XuuJH1<#K*$^[L&Qi,L]<20M>rJ5MuJ\8NW5%b]Y2%o^VI_'_o0O5a2l?Db0/#RcHab_dF-LneCE1&f\,!4gYCW@hV[8Mir7sA +jQ5OdkNMp0!UB"MliQSBmf)YVnF?&Io)J=]o_eC]pAXg^q#'scqXXOYr:g0Rrdk*\s*t~> +JcC<$JcG?Ao)ARcrVZNhrqcWir:p +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEEH,r9DJj<-Chmg$C&VcHB4h-Ss'u+>raPn9!+>b4s'G_2 +rETA,s'#>'s&f;&qc<_sr`&eor_ibnr)!Agr_EAcr_3;aqb$fYrCH]RqaUBMpI+tVnr;C_qMP>B +qF:-JrCHiXqF^]Zr_3/_r_Il'MBVra>_6r*o\9rabqs,d8CrK75G +Pa)-3s-gPrgs.^!20=bs.TLgrhKRkVZ*J`W2ZesX/i>(Xfek3Yd(L?Za@-K +[^WcW\\#Me]tV7r^r!t+`5T^9aN2KGbKS5VcHjkbdaQ^qe^rF*g"P07gtgfChr*JQro41CjlY^g +kl0fIlKeH9!q#FDrpKpXnaZSKs7?9_r:U'_rqH6`r;$9eo)&4[p\j=TJcE=]J,~> +JcC<$JcG?Ao)ARcrVZNhrqcWir:p +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEEH,r9DJj<-Chmg$C&VcHB4h-Ss'u+>raPn9!+>b4s'G_2 +rETA,s'#>'s&f;&qc<_sr`&eor_ibnr)!Agr_EAcr_3;aqb$fYrCH]RqaUBMpI+sZr_(d6oLT$O +qF:-JrCHiXqF^]Zr_3/_r_E;4GPErL.XFT6L_ +G5ZXbGQ<$fHN/?lI/\QoIfFosJH(0#K)L<'KS>-ZLB!&/M#N82MZ8V6N;nn;NrG+>OT1IAOogi3 +Pl6mIQ2m9MR/`QSRf/]WS=Q5MT)YD_T`1YbU&^tfU]IC*[qtU*`rTO63s185\~> +JcC<$JcG?Anc&IbrVZNhrqcZjr:p +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEEH,r9s).jR$>aKnC2%BqBP1phrac.A@q5LI!b#JErEfV4 +?![D6r`fD+rE9,%s&],!r`/ttqc!Mmr_`Sis%iVhqb@)ar_*)[r^m&ZpIG*MpI4sI!9*q8qS):/ +o=XS)q*t'Jr(-cXq+CWZrCm)_rD*Ags5F"9qp"HNk0*a2ra>b7qdTS8rabqs,d8C +rf[;Fs-3JI!g]1>rL!VQ!1NkUs-s([rgs.^s.K@b!MZ@gV#R7kVZ*JeW2ZesX/i>(Xfek3Yd(L? +Za@-K[^WcW\[oDc]Y2(p^qmn)_o0O6a2l?DbKJ,ScHaeadF-Lne^i@(f\,!4gYL]Bhr*GOioB([ +jo4BMkNM0plK[^%m-X3.rpTmVs7-*Zs7?9_r:U'_rqH9ar;$9eo)&4[p\j=TJcE7[J,~> +JcC<$JcG?Anc&IbrVZNhrqcZjr:p +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEEH,r9s).jR$>aKnC2%BqBP1phrac.A@q5LI!b#JErEfV4 +?![D6r`fD+rE9,%s&],!r`/ttqc!Mmr_`Sis%iVhqb@)ar_*)[r^m&ZpIG*MpI4sIrMAS7kD]=s +q*t'Jr(-cXq+CWZrCm)_rD*AgrM9=YkEtP$ra5Y4s'be6s'u%=r+5k>s(D4Bs(VIIqeQ4Jrb_OM +rbqaSqf2RTrH%dVr,qp\p36@Xq0C>5r-A3bqKMm]rcS'ZrcA$YpMotIqeu7Kq/QCSrcA!Zs)n?b +rHJ9ds*=Tis*OcnrdFfq!.Xrt!eGrTre(6(!/:B+!f)Sfre^Z4s,6l8s,I&=rf@)@s,m;Ds-*JI +rKRGMQ^@ZaN;WKbg"GYd*^7he'uq!f@S[.g=k<;h;7&Ii8N\Uj5f>$jpUA9 +l07Kulg4!*mI'uBs7$'Yrpp*\s7H6^rq??cqY:!ar;-!]q#'mbkl-/5\Gq'~> +JcC<$JcG?Anc&IbrVZNhrqcZjr:p +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEEH,r9s).jR$>aKnC2%BqBP1phrac.A@q5LI!b#JErEfV4 +?![D6r`fD+rE9,%s&],!r`/ttqc!Mmr_`Sis%iVhqb@)ar_*)[r^m&ZpIG*MpI4sI!*0"trCc3D +k"5Ara5Y4s'be6s'u%=r+5k>s(D4Bs(VIIqeQ4Jrb_OM +rbqaSqf2RTrH%dVr,qp\p36@Xq0C>5r-A3bqKMm]rcS'ZrcA$YpMotIqeu7Kq/QCSrcA!Zs)n?b +rHJ9ds*=Tis*OcnrdFfq!.Xrt!eGrTre(6(!/:B+!f)Sfre^Z4s,6l8s,I&=rf@)@s,m;Ds-*JI +rKRGMQ^@ZaN;WKbg"GYd*^7he'uq!f@S[.g=k<;h;7&Ii8N\Uj5f>$jpUA9 +l07Kulg4!*mI'uBs7$'Yrpp*\s7H6^rq??cqY:!ar;-!]q#'mbkl-/5\Gq'~> +JcC<$JcG?Anc&IbrVZNhrqcWir:pQ7n)=oVV(=8Z+uX2i:]=,e:&[ic9D_?[8c;3T8,>^J7K5dSiVC4R^%8o, +]D>"i8,Z!V8bu'X9E%W]:&[oe:]92Bc19*AbPklJ@/j[5@fBm:AGg$OT1IBP5gaG +Pl?sJQN*jW2ZesX/i>(Xfek3Yd(L>Za7$H +[^NZT\[oDc]Y2%o^VI\&_o0O5`lH0Bb0.uPcHab_dF$CleCE.%f@\d1gYCW@hV[8LiSrnXjQ5Od +kNM-ol0@U6liQSBmf)YVnF?&Inc8:\o_nI^pAXg_q#1$cqXaUZr:g0Rrdk*Xs*t~> +JcC<$JcG?Anc&IbrVZNhrqcWir:pQ7n)=oVV(=8Z+uX2i:]=,e:&[ic9D_?[8c;3T8,>^J7K5dSV;mQuN;\\2 +7eK:M8Gl'U9)VE^9_qK_:B"&fV":#BR-U+S5M +DuFYPEW'qVF80kTFo6FUGPcX\H.%$:H2Mp_GQ)dbFo$4YF8g4TEVXSHDu+GLEW1"XF8U.[FoQX` +G63#7H2W$jH[L5?IK+crJ,Xs"JV&LQKE$T)L&Qi,L]<20M#rQmMuJ\8NW5%:$[qtU*`rTO63s0hrX~> +JcC<$JcG?Anc&IbrVZNhrqcWir:pQ7n)=oVV(=8Z+uX2i:]=,e:&[ic9D_?[8c;3T8,>^J7K5dSOT1IBP5gaGPl?sJ +QN*jW2ZesX/i>(Xfek3Yd(L>Za7$H[^NZT +\[oDc]Y2%o^VI\&_o0O5`lH0Bb0.uPcHab_dF$CleCE.%f@\d1gYCW@hV[8LiSrnXjQ5OdkNM-o +l0@U6liQSBmf)YVnF?&Inc8:\o_nI^pAXg_q#1$cqXaUZr:g0Rrdk*Xs*t~> +JcC<$JcG?AnG`Cbr;?EgrqcZjr:p9cs7ZEas7H?_rUL$[nF6DF!q,ICrp9[N!:'RJs60LGroO:D +jQ-=##NF_$i8EMMhYu>\gtUT;g=b03f@SU)e^W*tdaHOjd*L"_c-4ASb/q`Ga2Z*;_ns:,^q[Xt +]Y(kf\[],W[C!9HZ*:I8Xf\\)Wi;noVPU)`U7n6PSt2C@R[KP1QBd`"P*1rhO,f3YN/EIKLkg_= +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEs)A6^Df9N2D/B2e!GZ?JBF&6_An>OaA7K-K@fKj:@/XI4 +?N4=0>lS%->5_V'=T;J#j:Adic9`@]^9)V?[8G>XM7eT:LiVC4Q^%8o. +]D>"i8,PpV8bl!X9DqQ\:&[oe:]9/9c2#TJbPbfJ@/aU4@fBm:AGg$=B)ZH@B`;`FCA_lHD#S;K +DZ4SQE;FSRErC(SFSp:YG4g(UGkcR8HM`!dGklR^G5cX\FT-@[EqjYOE:\#EE;FSRErL.YFT6L` +G5ZXbGlN'gHN/
  • -ZLB!#/M#N82M?&S5Muo!!NrG+>OT1IBP5gaG +Pl?sJQN*(Xfel,YXGb%Za7$H +[^NZT\[f;`]Y(ql^VI\&_Sa=2`lH0Aai_fNc-FV\d*^:jeC<%"f@S^0g=tE=h;7&Ii8N\Uj5f=a +k3(t-klL)8rp0[Qmf)\TnGi%Xo)J=]o_nI^pAXg_q#1$dqXaUZr:g0Qrdk*Ws*t~> +JcC<$JcG?AnG`Cbr;?EgrqcZjr:p9cs7ZEas7H?_rUL$[nF6DF!q,ICrp9[N!:'RJs60LGroO:D +jQ-=##NF_$i8EMMhYu>\gtUT;g=b03f@SU)e^W*tdaHOjd*L"_c-4ASb/q`Ga2Z*;_ns:,^q[Xt +]Y(kf\[],W[C!9HZ*:I8Xf\\)Wi;noVPU)`U7n6PSt2C@R[KP1QBd`"P*1rhO,f3YN/EIKLkg_= +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEs)A6^Df9N2D/B2e!GZ?JBF&6_An>OaA7K-K@fKj:@/XI4 +?N4=0>lS%->5_V'=T;J#j:Adic9`@]^9)V?[8G>XM7eT:LV;dKtN;nh4 +7eK:L8Gu-U9)_K^9_qK_:B"&fV!FHAR-g7=?iOO5@JjU6A,^$:AcHBABDcHBC&VlFC]8/LD>S5M +DuFYOEW1"WF80kTFo-@TGPZRZH.I<=H2W!`GPu^aFo$4ZF8^.SEVj_HDu+GLEW1"XF8^4\FoQX` +GQ2pfH2`-iHN8HlI0+kIJ,Xs"JV&LQK*$^[L&Qi,LB*/0M>rG5MuAS9NK0%uO8k=AOoCODPQ-mH +Q2d0MQi39QR@9TCS,\uYSc,/[T)bP`U&UkeU].%iV5F6i$`L&(WiE,#XKAV-YPtaoZ*L^B['d?N +\%&uZ]">Vf]tV7s_8=(,`5Ta:aN2KGbKS5VcHjkbdaQ^qe^i@(g"P07gtgfChr*GOioB([jlY^g +kl0fIlKeH9!U]=Sn,MnWnc&+ZoDeI]p&=[ap\O[`q>C*\qtU*`rTF02s0_lW~> +JcC<$JcG?AnG`Cbr;?EgrqcZjr:p9cs7ZEas7H?_rUL$[nF6DF!q,ICrp9[N!:'RJs60LGroO:D +jQ-=##NF_$i8EMMhYu>\gtUT;g=b03f@SU)e^W*tdaHOjd*L"_c-4ASb/q`Ga2Z*;_ns:,^q[Xt +]Y(kf\[],W[C!9HZ*:I8Xf\\)Wi;noVPU)`U7n6PSt2C@R[KP1QBd`"P*1rhO,f3YN/EIKLkg_= +KS+o/JUi9#I=6KiH?sj]GB\4QFEDSEs)A6^Df9N2D/B2e!GZ?JBF&6_An>OaA7K-K@fKj:@/XI4 +?N4=0>lS%->5_V'=T;J#j:Adic9`@]^9)V?[8G>XM7eT:L-ZLB!#/M#N82M?&S5Muo!!NrG+>OT1IBP5gaGPl?sJ +QN*(Xfel,YXGb%Za7$H[^NZT +\[f;`]Y(ql^VI\&_Sa=2`lH0Aai_fNc-FV\d*^:jeC<%"f@S^0g=tE=h;7&Ii8N\Uj5f=ak3(t- +klL)8rp0[Qmf)\TnGi%Xo)J=]o_nI^pAXg_q#1$dqXaUZr:g0Qrdk*Ws*t~> +JcC<$JcG<@nc&IbrVZNhrqcWir:pS.s',J+rE9,%s&],!s&K%trDW\ns&&\jr_NPhqb@)ar_*)[rCQrYpIG!Jq*k;ApV,FroXt&j +oLJjNr(6]Vr_*2`qb@#ar_NRNs4un`qon?KrEoS4raG_6raYqqg&*aqKMm]rcS'ZrH%sYpi61MnSe;DqJlLTs)\*[s)n?b +rHAaND]Lbg"GYcdC.ge'umtf@S[.g=k<:h;-rFi8ESRj5]4^ +k2tjjrojIKli-5OmI'uBs6p$YrUU![s7H9_s7ZHdqY:$brVH0`q#'jak5Kr3[/YX~> +JcC<$JcG<@nc&IbrVZNhrqcWir:pS.s',J+rE9,%s&],!s&K%trDW\ns&&\jr_NPhqb@)ar_*)[rCQrYpIG!Jq*k:Zb`2IXqaU3J +rCHiXq+CWZrCm)_rD*>frM8PCqO$];rEoS4raG_6raYqqg&*aqKMm]rcS'ZrH%sYpi61MnSe;DqJlLTs)\*[s)n?brHAaND]Lbg"GYcdC.ge'umtf@S[.g=k<:h;-rFi8ESRj5]4^k2tjj +rojIKli-5OmI'uBs6p$YrUU![s7H9_s7ZHdqY:$brVH0`q#'jak5Kr3[/YX~> +JcC<$JcG<@nc&IbrVZNhrqcWir:pS.s',J+rE9,%s&],!s&K%trDW\ns&&\jr_NPhqb@)ar_*)[rCQrYpIG!Jq*k9_qFf%)qaU3J +rCHiXq+CWZrCm)_rD*>frE//[k>M7cs'Yh7r*oY8rabqVf]tV7r^qmn*`5T^8a2l?EbKJ,ScHab`dF-LneCE1&f\,!4gYCW@hV[8LiSrnXjQ5OdkNMp0 +!UB"MliHMArpTmV!:g$Ys7?9_rUp3arqH9arV?Ego_\F]pAO.QJcE+WJ,~> +JcC<$JcG<@nc&FarVZNhrqcZjqtU3cs7ZEas7H?_rUU!Ys7$$Vs6fpSrp9[N!:'OI!pJh1roO:D +jQ-=#!oi1trnn%=hVR)Egt^Z`g&]mZrmq2%ec+'Ie'cXkd*L"_c-4ASb/q`Ga2Z*;`59C-^q[Xt +]Y(kf\[],W[C!9GZ*:I8Xf\Y(Wi;noVPL#_TqS-OSt2C@R[KP0QBd`!P*1rhO,f3YN/EIKLkg_= +KS+o/JUi9#IXQTjH?sj]GB\4QFEDSEEcH)+\@K/]]=bej^V@S#_SX4/`PojL0^qt^0`rT4$0s0M`U~> +JcC<$JcG<@nc&FarVZNhrqcZjqtU3cs7ZEas7H?_rUU!Ys7$$Vs6fpSrp9[N!:'OI!pJh1roO:D +jQ-=#!oi1trnn%=hVR)Egt^Z`g&]mZrmq2%ec+'Ie'cXkd*L"_c-4ASb/q`Ga2Z*;`59C-^q[Xt +]Y(kf\[],W[C!9GZ*:I8Xf\Y(Wi;noVPL#_TqS-OSt2C@R[KP0QBd`!P*1rhO,f3YN/EIKLkg_= +KS+o/JUi9#IXQTjH?sj]GB\4QFEDSEEcH)jMuo!!NrG(@OHG\)P5gaGPl?sJ +QN* +JcC<$JcG<@nc&FarVZNhrqcZjqtU3cs7ZEas7H?_rUU!Ys7$$Vs6fpSrp9[N!:'OI!pJh1roO:D +jQ-=#!oi1trnn%=hVR)Egt^Z`g&]mZrmq2%ec+'Ie'cXkd*L"_c-4ASb/q`Ga2Z*;`59C-^q[Xt +]Y(kf\[],W[C!9GZ*:I8Xf\Y(Wi;noVPL#_TqS-OSt2C@R[KP0QBd`!P*1rhO,f3YN/EIKLkg_= +KS+o/JUi9#IXQTjH?sj]GB\4QFEDSEEcH)jMuo!!NrG(@OHG\)P5gaGPl?sJ +QN* +JcC<$JcG<@nG`@arVZNhrqcWir:ps5F%;ro!h6!8d_2!SlH/g'66_f[na+ec+'6e'cXkd*L"_c-4ASb/q`Ga2Z*;`59C-^q[Us +]Y(ke\[],W[C!9GZ*:F7Xf\Y(Wi2hnV50o^TqS-NSt2C@R[KP0QBd`!P*1rgO,f3YN/EIKLkg_= +KS+o/JUi9#IXQTjH?sj]GB\4QrcAlS%.>5VP'=T;J#j:Adic9`@]]9)_E[8G,LG7fMB?^>-Eq]_b1j +8,PpV8bl!W9E%W]:&[oe:]F8kguclSbjimT?iOO5@JjU6A,^$:AcHBABDcHBC&VlFC]8/LD>S5L +DuO_PEW'qUF80kSFo-@RGPHFWH/a/HH2Mp^GQ)daFo-:ZF8g4TEVj_DDu=SNEW:(YF8^4\FoQX` +G63#7H2`-iHN8HmIK+`rJ,XuuJH1<$K*R'`Knb>;LPYqds,$f7rf$l:!07&>s,[5CrK75GPa)04 +s-E\Org<_Rs-inU!h>gPrLX%]!20:as.TLgrM0LkVPa?j!iW)tri-""XT#=&Y-7i/9aN;TJbg"GYcd:(ee'umtf%8O+g"P39h;-rFi8ESRj5]4^ +k2tjikiq?sli-5VmI'E2n*oi:nc&+ZoDeI]p&Fabp\Xabq>C*^qt^0`rT4$0s0;TS~> +JcC<$JcG<@nG`@arVZNhrqcWir:ps5F%;ro!h6!8d_2!SlH/g'66_f[na+ec+'6e'cXkd*L"_c-4ASb/q`Ga2Z*;`59C-^q[Us +]Y(ke\[],W[C!9GZ*:F7Xf\Y(Wi2hnV50o^TqS-NSt2C@R[KP0QBd`!P*1rgO,f3YN/EIKLkg_= +KS+o/JUi9#IXQTjH?sj]GB\4QrcAlS%.>5VP'=T;J#j:Adic9`@]]9)_E[8G,LG7fK7,NW"h57eB4K +8Gu-U9)VE^9_qK_:B"&h;#d?ORJ<0>Qi1:k@/aU4@fBm:AGg$=B)ZH@B`;`FCA_lHD#S;KDZ+MQ +E;FSQEr:"RFSg4XG4TqQGkZLCHMVpbGkcL^G5ZR\FT$:[EqjYOE:7`CE;FSSErL.YFT6L`G5ZUd +G^4T6HN/
  • ,7L51P?re^Z4!/pi8s,@#=rf@)@!0R5C!gAk5rg!ML +s-N_Ps-`nUrL3kYSXo_Ns.9:arLs7c!2KLg!i;ckrhfgrWN#ls!NW=$XT>T.rif&#ZEpmE['d?N +\%&uZ]">Vf]tV7r^qmn)`5T^8a2l?Db0/#RcHab_dF$FmeCE.%f@\d1gYCW@hV[8LiSrnXjQ5Od +kND'nl0@U6lj3"HmdKW6nF?&Jo)J=]o_nI_pAXg`q#:*eqXsa]r:^*Nrdk*Ss*t~> +JcC<$JcG<@nG`@arVZNhrqcWir:ps5F%;ro!h6!8d_2!SlH/g'66_f[na+ec+'6e'cXkd*L"_c-4ASb/q`Ga2Z*;`59C-^q[Us +]Y(ke\[],W[C!9GZ*:F7Xf\Y(Wi2hnV50o^TqS-NSt2C@R[KP0QBd`!P*1rgO,f3YN/EIKLkg_= +KS+o/JUi9#IXQTjH?sj]GB\4QrcAlS%.>5VP'=T;J#j:Adic9`@]]9)_E[8G,LG7fHE`9@$319D_3N +8,PpV8bl!W9E%W]:&[oe:]F8k=PHdD;Z0u&@/aU4@fBm:AGg$=B)ZH@B`;`FCA_lHD#S;KDZ+MQ +E;FSQEr:"RFSg4XG4TqQGkZLCHMVpbGkcL^G5ZR\FT$:[EqjYOE:7`CE;FSSErL.YFT6L`G5ZUd +G^4T6HN/
  • ,7L51P?re^Z4!/pi8s,@#=rf@)@!0R5C!gAk5rg!ML +s-N_Ps-`nUrL3kYSXo_Ns.9:arLs7c!2KLg!i;ckrhfgrWN#ls!NW=$XT>T.rif&#ZEpmE['d?N +\%&uZ]">Vf]tV7r^qmn)`5T^8a2l?Db0/#RcHab_dF$FmeCE.%f@\d1gYCW@hV[8LiSrnXjQ5Od +kND'nl0@U6lj3"HmdKW6nF?&Jo)J=]o_nI_pAXg`q#:*eqXsa]r:^*Nrdk*Ss*t~> +JcC<$JcG9?nc&IbrVZNhrVHQiqtU3cs7ZB`s7H?_rUL$[nF6DFs6]mSrTsRM!:'OI!pJh1roX7B +!9F.>s5F%;ro!h6!8d_2G21j,g=k65f[na+f%&:"e'cXkd*L"_c-4ASb/q`Ga2Z*;`59C-^q[Xt +]Y(ke\[],W[C!9GZ*:F7XfSS'Wi2hnV50o^TqS-NSt2C@R[KP0QBd`!P*1rgO,f3YN/EIKLkg_= +KS+o/JUi9#IXQWlH?sj]rc\ZlF`__HEcH)lS%.>5VP'=T;J#-Er]_t=k +8,PpU8bl!X9DqQ\:&[oe:]F8kgZ?]MbkB6Y?iOO5@JjU6A,^$:AcHBABDcHBC&VlEC]A5MD>J/L +DuO_OEW'qVF8'eRFo$:PGPHFVH0KYMH2Mp^GPu^aFo$4ZF8^.TEVj_CDu=SOEW1"YF8U.[FoQXa +GQ2mfH2W$oH[L3hI=?Wprdb$"!.t3&!JH1+LB!#/M#N54MMmDlMueourf@)@s,m;D!gAk5rg!ML +s-N_Ps-`nUrgWqXs.0+[!hZ-YrLs7c!2KLgs.o^mrhodp!3,sts/Q.$riH4(YPta,Z*OA88$o\4 +[^WcW\[oDc]Y2%o^VI\&_Sa=2`Q#s>aND]Lbg"GYcd:(fe'umtf%8O+g=k<:h;-rFi8ESRj5]4^ +k2tjjkiq?sli-5OmI'uBs6p$YrUL$]o^r+Trq?BdqtU0dr;--aq>BsbjSj`1YlB4~> +JcC<$JcG9?nc&IbrVZNhrVHQiqtU3cs7ZB`s7H?_rUL$[nF6DFs6]mSrTsRM!:'OI!pJh1roX7B +!9F.>s5F%;ro!h6!8d_2G21j,g=k65f[na+f%&:"e'cXkd*L"_c-4ASb/q`Ga2Z*;`59C-^q[Xt +]Y(ke\[],W[C!9GZ*:F7XfSS'Wi2hnV50o^TqS-NSt2C@R[KP0QBd`!P*1rgO,f3YN/EIKLkg_= +KS+o/JUi9#IXQWlH?sj]rc\ZlF`__HEcH)lS%.>5VP'=T;J#HPa)04s-E\O +rg<_Rs-iqVs.'+[rLO(_TV27Ws.TLgrM9Ii!2fans/5psri6"!!3H1%!NrX*YQ;#7rj,,%[C3NQ +\@K/]]=bei^;%Fu_8=(,`5T^8a2l?EbKJ,ScHab_dF-LneCE.%f@\g2gYCW@hV[8LiSrnXjQ5Od +kNM-ol0@U6liHMArpTmV!:g$Y!qZ'VrUp0`s7cEcrqZKgpA=[`pAO(OJcDtSJ,~> +JcC<$JcG9?nc&IbrVZNhrVHQiqtU3cs7ZB`s7H?_rUL$[nF6DFs6]mSrTsRM!:'OI!pJh1roX7B +!9F.>s5F%;ro!h6!8d_2G21j,g=k65f[na+f%&:"e'cXkd*L"_c-4ASb/q`Ga2Z*;`59C-^q[Xt +]Y(ke\[],W[C!9GZ*:F7XfSS'Wi2hnV50o^TqS-NSt2C@R[KP0QBd`!P*1rgO,f3YN/EIKLkg_= +KS+o/JUi9#IXQWlH?sj]rc\ZlF`__HEcH)lS%.>5VP'=T;J#HPa)04s-E\O +rg<_Rs-iqVs.'+[rLO(_TV27Ws.TLgrM9Ii!2fans/5psri6"!!3H1%!NrX*YQ;#7rj,,%[C3NQ +\@K/]]=bei^;%Fu_8=(,`5T^8a2l?EbKJ,ScHab_dF-LneCE.%f@\g2gYCW@hV[8LiSrnXjQ5Od +kNM-ol0@U6liHMArpTmV!:g$Y!qZ'VrUp0`s7cEcrqZKgpA=[`pAO(OJcDtSJ,~> +JcC<$JcG9?nG`@arVZNhrqcWir:p9cs7ZEas7H?_rUU!Ys7$!Us6]mSrTsRM!:'OI!pJh1roX7B +!9F+=!oi1trnmh7hYu@2g]6+.g&]mZrmuVMe^W*tda?Ihd*L"_c-4ARaiMQD`l5p8_SX.)^V@Ip +]Xt_b\@8oS['R'CYck43XK/A$W2HPiUnj`YTqJ!KSXZ+;R@'>,Q'@JqP*(fdNfB!VMM[1GLPCP: +K7ec,J:N,uI=6KiH?sj]GB\4QFEDSEEH,r:Df0H0D/B5fs(VOJrb2=E!+u4As().>raPn9s'Ye4 +s'G_2rET>+s'#A(r`K2%rDrnts&Aqqr_ibnr)!Dhr_EAcr_3;aqF^]Xr(-ELqaUVDoY0+opUpJp +njiUKr(6]Vr_*2`qb@#ar_NPjs4ZSZm*,@MrEoS4raG_6raYq$#It*!!JUrFPK*R'`Knb>;LPYqd!K)g7N;nk;NrG(@OHG\)P5g^GPl?sJ +QN* +JcC<$JcG9?nG`@arVZNhrqcWir:p9cs7ZEas7H?_rUU!Ys7$!Us6]mSrTsRM!:'OI!pJh1roX7B +!9F+=!oi1trnmh7hYu@2g]6+.g&]mZrmuVMe^W*tda?Ihd*L"_c-4ARaiMQD`l5p8_SX.)^V@Ip +]Xt_b\@8oS['R'CYck43XK/A$W2HPiUnj`YTqJ!KSXZ+;R@'>,Q'@JqP*(fdNfB!VMM[1GLPCP: +K7ec,J:N,uI=6KiH?sj]GB\4QFEDSEEH,r:Df0H0D/B5fs(VOJrb2=E!+u4As().>raPn9s'Ye4 +s'G_2rET>+s'#A(r`K2%rDrnts&Aqqr_ibnr)!Dhr_EAcr_3;aqF^]Xr(-ELqaUU]c].[Xr^QHK +r(-`Wq+CWZrCm)_rD*>fs%r`kigK8&qj77gs'Yh7r*oY8rabq,7L51P?reUZ5MuJ\8N<#"aMrpp*\s7H9_s7ZKeqtU-crqc?cq>Bsbj8OW0YQ'+~> +JcC<$JcG9?nG`@arVZNhrqcWir:p9cs7ZEas7H?_rUU!Ys7$!Us6]mSrTsRM!:'OI!pJh1roX7B +!9F+=!oi1trnmh7hYu@2g]6+.g&]mZrmuVMe^W*tda?Ihd*L"_c-4ARaiMQD`l5p8_SX.)^V@Ip +]Xt_b\@8oS['R'CYck43XK/A$W2HPiUnj`YTqJ!KSXZ+;R@'>,Q'@JqP*(fdNfB!VMM[1GLPCP: +K7ec,J:N,uI=6KiH?sj]GB\4QFEDSEEH,r:Df0H0D/B5fs(VOJrb2=E!+u4As().>raPn9s'Ye4 +s'G_2rET>+s'#A(r`K2%rDrnts&Aqqr_ibnr)!Dhr_EAcr_3;aqF^]Xr(-ELqaUTcp.Nb)r^QHK +r(-`Wq+CWZrCm)_rD*>fs%r_tgJdT>rEoS4raG_6raYq$#It*!!JUrFPK*R'`Knb>;LPYqd!K)g7N;nk;NrG(@OHG\)P5g^GPl?sJQN* +JcC<$JcG6>nc&Ibr;?EgrqcWir:p)e^W*tdf.X0d*L"_c-4ARaiMQD`l5p8_SX.)^V7Co +]XkYa\@/iR['R'CYck43XK/A#W2HMhUnj`YTq@pJSXZ+;R@'>,Q'@JqP*(fdNfB!UMM[1GLPCP: +K7ec,J:N,uI=6KiH?sj]GB\4QFEDSErc%sXDuOVTD/B2e!buF`rb)@GAnM$Rs'u+>rF5e8s'Ye4 +s'G_2rET>+s'#A(s&f8%rDrqus&Anps&/kor)!Dhr_EAcr_3;aqF^ZWr(-S5M +DuFYNEW'qUF7s_QFo$:NGP?@>H2;d\GPu^`Fo$4ZF8^.TEVseBDuFYOEW:(YF8^4\FoQXaGQ2mf +H2`-iHN8HmIK+`rJ,Xs!JV*lR#D@ebL5(J=M#N53MMqIm!f`5#rf7)AOoCODP5pjGPld8mFlVuN[qWW&ptWrT7#XoGO(YPta,Z*OA8::.F;[^WcV +\[f;`]Y(ql^V@S#_SX4/`Poj;aN2KGbKS5VcHjkbdF-Lne^i@(f\,!4gYCW@hV[8LiSrnXjQ5Od +kNM0plK[^%m-X3.rpKpXnaZVLs766_rUp0`s7cHdrV?Egp\Xgbp\j+NJcDkPJ,~> +JcC<$JcG6>nc&Ibr;?EgrqcWir:p)e^W*tdf.X0d*L"_c-4ARaiMQD`l5p8_SX.)^V7Co +]XkYa\@/iR['R'CYck43XK/A#W2HMhUnj`YTq@pJSXZ+;R@'>,Q'@JqP*(fdNfB!UMM[1GLPCP: +K7ec,J:N,uI=6KiH?sj]GB\4QFEDSErc%sXDuOVTD/B2e!buF`rb)@GAnM$Rs'u+>rF5e8s'Ye4 +s'G_2rET>+s'#A(s&f8%rDrqus&Anps&/kor)!Dhr_EAcr_3;aqF^ZWr(-s(D4Bs(VIIqeQ1Irb_OMrbqaS +q/Q@Rr,_RRqfVaYn9=VOhg,'Cpil[[rH7sYrcA$Yq/Q=Olu2iAqJlOUrcA$[s)n?brceBe!."Qi +s*F`nrdFfq!.Xuu!J,k%K*R'`Knb>;LPYqd!K)g7Muo!!NrG(?OHKO*s-!GIrKRGMQ^@]=s-`nU +rgWqXs.0.\s.B=arLs7c!2KLgs/#amrhodp!3,sts/Q.$riQ4'!3cC+!O8s0ZVIm8[^NZT\@K/] +]=bei^;%Fu_8=(,`5T^8a2l?Db0/#RcHab_dF$CkeCE.%f@\d1g=tE=h;7&Ii8N\Uj5f=ak3(sm +l0@R"m-O-,mf)YVnF?&Jo)J:]o_nI^pAambq#1$eqY0m`r:g0Lrdk*Os*t~> +JcC<$JcG6>nc&Ibr;?EgrqcWir:p)e^W*tdf.X0d*L"_c-4ARaiMQD`l5p8_SX.)^V7Co +]XkYa\@/iR['R'CYck43XK/A#W2HMhUnj`YTq@pJSXZ+;R@'>,Q'@JqP*(fdNfB!UMM[1GLPCP: +K7ec,J:N,uI=6KiH?sj]GB\4QFEDSErc%sXDuOVTD/B2e!buF`rb)@GAnM$Rs'u+>rF5e8s'Ye4 +s'G_2rET>+s'#A(s&f8%rDrqus&Anps&/kor)!Dhr_EAcr_3;aqF^ZWr(-rEoS4raG_6raYqs(D4Bs(VIIqeQ1Irb_OMrbqaS +q/Q@Rr,_RRqfVaYn9=VOhg,'Cpil[[rH7sYrcA$Yq/Q=Olu2iAqJlOUrcA$[s)n?brceBe!."Qi +s*F`nrdFfq!.Xuu!J,k%K*R'`Knb>;LPYqd!K)g7Muo!!NrG(?OHKO*s-!GIrKRGMQ^@]=s-`nU +rgWqXs.0.\s.B=arLs7c!2KLgs/#amrhodp!3,sts/Q.$riQ4'!3cC+!O8s0ZVIm8[^NZT\@K/] +]=bei^;%Fu_8=(,`5T^8a2l?Db0/#RcHab_dF$CkeCE.%f@\d1g=tE=h;7&Ii8N\Uj5f=ak3(sm +l0@R"m-O-,mf)YVnF?&Jo)J:]o_nI^pAambq#1$eqY0m`r:g0Lrdk*Os*t~> +JcC<$JcG6>nc&FarVZNhrqcWir:p9cs7ZB`s7H?_rUU!Ys7$!Us6]mSrTsRM!:'OIs6'IGrT41C +jQ-=#s5F%;ro!h6!8d_2!SlH/g&]mZrmuYNe^W*tdaHOjd*L"_c-4ARaiMQD`l5p7_SX.)^V7Co +]XkYa\@/iRZa6sBYck43XK/A#W2HMhUnaZXTq@pJS=?":R$a5+Q'@JqP*(fdNfB!UMM[1GLPCP: +K7ec,J:N,uI=6KiH?sj]GB\4QFEDSFEcH)Q7n)=oVV(=8c2!j>j:]F2e:&[ic9DV9Y8c2-L8,qN=^>-Et]DtFk +8,GjU8bbpW9DqQ\:&[oe:]4)ifAt3>bl1uK@/aU4@fBm:AGg$;LkpnEMMd>kMueourf7,BOcfX+!gAk5rfmPNQ^@]=s-WkU +rL3kYSXo_Ns.B=arh9@ds.fOgs.o^mrMT[o!3,ps!irE(riHF.YHP17Z*CV6ZVRs9[^NZS\@K/] +]=bei^;%Fu_8=(,`5T^8a2l?Db0.uPc-FV\dF$CkeC<%"f@S[.g=k<;h;7&Ii8N\Uj5f=`k2tjj +l07L!lg4!*mdC)C!V#XXncJFTo_nI_pAXgaq#:*fqY0m`r:g0Lrdk*Ns*t~> +JcC<$JcG6>nc&FarVZNhrqcWir:p9cs7ZB`s7H?_rUU!Ys7$!Us6]mSrTsRM!:'OIs6'IGrT41C +jQ-=#s5F%;ro!h6!8d_2!SlH/g&]mZrmuYNe^W*tdaHOjd*L"_c-4ARaiMQD`l5p7_SX.)^V7Co +]XkYa\@/iRZa6sBYck43XK/A#W2HMhUnaZXTq@pJS=?":R$a5+Q'@JqP*(fdNfB!UMM[1GLPCP: +K7ec,J:N,uI=6KiH?sj]GB\4QFEDSFEcH)Q7n)=oVV(=8c2!j>j:]F2e:&[ic9DV9Y8c2-L8,oC1NV\S7Mam5, +qagZWpe(NYrCm&^r_EGgrD3KhiL/tura5Y4raG_6raYqs(D4Bs(VIIqeQ1Irb_OMrGV[S +q/Q=Qr,_RRqK;UWn9=VOjE^THpNQRZrH7sYrcA$Yq/Q=OlYl]?qf2XVrcA$[s)eLl$tGMMqIm!KE-=NrkE*OoCLFPE_=2Pld8hV[8LiSrnXjQ5Lck3(sm +l0@U#m-O--mf)YUnF?JJ!qZ'VrUp3arqH?crqZNhp\Xgbp\j+NJcDhOJ,~> +JcC<$JcG6>nc&FarVZNhrqcWir:p9cs7ZB`s7H?_rUU!Ys7$!Us6]mSrTsRM!:'OIs6'IGrT41C +jQ-=#s5F%;ro!h6!8d_2!SlH/g&]mZrmuYNe^W*tdaHOjd*L"_c-4ARaiMQD`l5p7_SX.)^V7Co +]XkYa\@/iRZa6sBYck43XK/A#W2HMhUnaZXTq@pJS=?":R$a5+Q'@JqP*(fdNfB!UMM[1GLPCP: +K7ec,J:N,uI=6KiH?sj]GB\4QFEDSFEcH)Q7n)=oVV(=8c2!j>j:]F2e:&[ic9DV9Y8c2-L8,lT^9@?E47e'"G +8Gu-T9)_K^9_qK_:B"&f:]OSN;t3cb?iFI4@JjU6A,^$:Ac?S5LDuO_O +EVskTF7s_PFnp4MGP?@CH2;d[GPu^`Fo$4ZF8^.TEVseADu=SOEW:(YF8^4\FT?U`G63#7H2`*p +H[L3hI=?WprdY$#K)UB2KS>,7L51S@M2@+IMuJY9NK4"!!g&P,rfR>HPa)04!g]1>rg<_R!1NkU +!h>gPrLX%]s.K@bs.]OgrM9Ii!2f^ms/5psrMfq"XK;E'#Hk86YctC;ZMq1+['d?N\$rlX\[oDc +]Y2%o^VI\&_Sa=2`Q#s>aN;TJbKS5VcHjncdaQ^qe^i@(f\,!4gYL]Bhr*GOioB([jlPXekNM0p +lKdd&m-X6/rpKmWnbr"[oCV\Rp&Fabp\agcq>L0aqtg6brSmg-s/c6N~> +JcC<$JcG6>nG`@arVZKgrqcWir:p9cs7ZEarq-6^rUU!Ys7$!Us6]mSrTsRMs6BUJs60LGroX7B +!9F.>s5O(;rnmh7hYu==gtUT;g=b03f@SU(rmY`4da?Ihcd'h\bfe2OaN2EA`Poa3_SO%&^:h1l +]",A\[^NTMZa-g>YHG"/X/`.tVl$;dUS=HTT:VXES"#k6R$X,(P`q8nOcPQ`NJrgRM2@%DL5(D7 +K7\Z)J:E#rI=-BfH?jaZGBS-.F:3/1EH,r:Df0H0D/B2e!buF`rb)@GAnM$Rs().>rF5e8s'Ye4 +s'G_2rETA,s'#A(r`K2%rDrqus&Anps&/kor)!Dhr_EAcr_3;aq+CTWqag9J!9!F^h7`WsnONII +r(6]VrCd,`qG$rarD3Ag!7g,Skfj!4s'Yh7r*oY8rabq/8LPL\BM2I1Krepl;NrG(EOHGZgP*;)org!ML!13\Ps-WkU +rLVf]tM.p^VI\&_Sa=2`Q#s>aN;TJbg"GYcd:(edaQ^qe^i@(g"P07gtgfChr*GOioB([jo4BG +kNM0plKeH9!U]=Sn,MkWnc&+ZoDeI]p&Facp\agcq>L0bqtg6crT!m.s/>sJ~> +JcC<$JcG6>nG`@arVZKgrqcWir:p9cs7ZEarq-6^rUU!Ys7$!Us6]mSrTsRMs6BUJs60LGroX7B +!9F.>s5O(;rnmh7hYu==gtUT;g=b03f@SU(rmY`4da?Ihcd'h\bfe2OaN2EA`Poa3_SO%&^:h1l +]",A\[^NTMZa-g>YHG"/X/`.tVl$;dUS=HTT:VXES"#k6R$X,(P`q8nOcPQ`NJrgRM2@%DL5(D7 +K7\Z)J:E#rI=-BfH?jaZGBS-.F:3/1EH,r:Df0H0D/B2e!buF`rb)@GAnM$Rs().>rF5e8s'Ye4 +s'G_2rETA,s'#A(r`K2%rDrqus&Anps&/kor)!Dhr_EAcr_3;aq+CTWqag9J!2Ro"qMYE4nONII +r(6]VrCd,`qG$rarD3Ag!2JJ?l^7WXs'Yh7r*oY8rabq/8LPL\BM2I1Krepl;NrG(EOHGZgP*;)org!ML!13\Ps-WkU +rLVf]tM.p^VI\&_Sa=2`Q#s>aN;TJbg"GYcd:(edaQ^qe^i@(g"P07gtgfChr*GOioB([jo4BG +kNM0plKeH9!U]=Sn,MkWnc&+ZoDeI]p&Facp\agcq>L0bqtg6crT!m.s/>sJ~> +JcC<$JcG6>nG`@arVZKgrqcWir:p9cs7ZEarq-6^rUU!Ys7$!Us6]mSrTsRMs6BUJs60LGroX7B +!9F.>s5O(;rnmh7hYu==gtUT;g=b03f@SU(rmY`4da?Ihcd'h\bfe2OaN2EA`Poa3_SO%&^:h1l +]",A\[^NTMZa-g>YHG"/X/`.tVl$;dUS=HTT:VXES"#k6R$X,(P`q8nOcPQ`NJrgRM2@%DL5(D7 +K7\Z)J:E#rI=-BfH?jaZGBS-.F:3/1EH,r:Df0H0D/B2e!buF`rb)@GAnM$Rs().>rF5e8s'Ye4 +s'G_2rETA,s'#A(r`K2%rDrqus&Anps&/kor)!Dhr_EAcr_3;aq+CTWqag9J!*/\bdRs%"qagWV +q+CTYr_3/_r_EDfrD3Jqfi.H>rEoS4raG_6raYqs(D4Bs(VIIqeQ1Irb_LLrbqaSq/Q@R +qfDFPqK;UWms"GLlZr;Np36IYrH7sYrcA$Yq/Q=Op29qKpM^"Lqf2UUs)\-\s)n?brceBe!."Qi +s*F`nrd>Q2It*!!JV&K+K7no3L5(J=Ll$tGMMqIm!KE-=NsCc/OcklkPEc'3s-ssri6"!!3H1%s/l@*rientZEggC['[6L[^W`U\[f;` +]Y(qk^;%Fu_8=(,`5T^8a2l?Db0/#RcHab_dF$CkeC<%"f@S^0g=tE=h;7&Ii8N\Uj5f>$josr3 +l07L!rp0[Qmf)\Tn,W"Xo)J=]o_nI_pAambq#:*fqY9sar:p6Nrdk*Js*t~> +JcC<$JcG6>nG`=`rVZNhrVHNhr:p!oi1trnn%=hVR)Egt^Z`g2P`tf@SU(e^W*tda?Ihcd'h\bfe2OaN2EA`Poa3_SO%&^:h1k +]",A\[^NTMZa-g>YH=q.X/`.tVl$;dUS=HTT:VXES"#k6R$X,(P`q8nOcPQ`NJrgRM2@%DL5(D8 +K7\Z)J:E#rI=-BfH?jc7G6N/4FEDSErc%sXDuOVTD/B2es(VOJrb2=Es(;7As().>raPn9s'Ye4 +s'G_2r*98+s'#A(s&f;&rDrqus&Anps&/kor)!Dhr_EAcrCm2`q+CQVqFLrG_XRrc8$[rH/'^!-\;LPUeDMMd=NN/`gWrf7)AOoCLKPE_;sQ'R`&rg<_Rs-iqV!h>gP +rLO(_TV27Ws.]OgrhTRjs/,ams/>ssri6"!!3H.$!j8`1ricF.ZMq0<['daMrpp*\s7H<`s7ZHdr:p9erqcEequ$6fiVnE.W;hA~> +JcC<$JcG6>nG`=`rVZNhrVHNhr:p!oi1trnn%=hVR)Egt^Z`g2P`tf@SU(e^W*tda?Ihcd'h\bfe2OaN2EA`Poa3_SO%&^:h1k +]",A\[^NTMZa-g>YH=q.X/`.tVl$;dUS=HTT:VXES"#k6R$X,(P`q8nOcPQ`NJrgRM2@%DL5(D8 +K7\Z)J:E#rI=-BfH?jc7G6N/4FEDSErc%sXDuOVTD/B2es(VOJrb2=Es(;7As().>raPn9s'Ye4 +s'G_2r*98+s'#A(s&f;&rDrqus&Anps&/kor)!Dhr_EAcrCm2`q+CQVqFLs(D4Brb;CIqeQ1Irb_LLrbqaSpi67Q +qfDCOqK;RVmW\2Gq0DUWp36IYrH7sYrH%sYq/Q:NlYl`@qf2UUs)\-\s)eaN;TJbKS5VcHjkbdF-Lne^i@(f\,!4gYCW@hV[8LiSrnXjQ5OdkNM-ol0@U6 +liHMArpKpXnaZVLs7?9_rq6 +JcC<$JcG6>nG`=`rVZNhrVHNhr:p!oi1trnn%=hVR)Egt^Z`g2P`tf@SU(e^W*tda?Ihcd'h\bfe2OaN2EA`Poa3_SO%&^:h1k +]",A\[^NTMZa-g>YH=q.X/`.tVl$;dUS=HTT:VXES"#k6R$X,(P`q8nOcPQ`NJrgRM2@%DL5(D8 +K7\Z)J:E#rI=-BfH?jc7G6N/4FEDSErc%sXDuOVTD/B2es(VOJrb2=Es(;7As().>raPn9s'Ye4 +s'G_2r*98+s'#A(s&f;&rDrqus&Anps&/kor)!Dhr_EAcrCm2`q+CQVqFLrEoS4raG_6raYqs(D4Brb;CIqeQ1Irb_LLrbqaSpi67Q +qfDCOqK;RVmW\2Gq0DUWp36IYrH7sYrH%sYq/Q:NlYl`@qf2UUs)\-\s)eaN;TJbKS5VcHjkbdF-Lne^i@(f\,!4gYCW@hV[8LiSrnXjQ5OdkNM-ol0@U6 +liHMArpKpXnaZVLs7?9_rq6 +JcC<$JcG3=nG`@ar;?EgrqcWiqtU3crq?<`rq-6^rUU!Ys7$!Us6fpSrp9[Ns6BRIs6'IGrT41C +jQ-=#s5F%;ro!h6!8d_2!SlH/g4.f.f@SU)e^W*tda?Ihcd'h\bfe2OaN2EA`Poa3_SO%&^:h1k +]",A\[^NQLZa$a=YH=q.WiE%sVl$;dUS=HTT:VUDS"#k6R$X,(P`q8nOH5H_NJrgRM2@%DL5(D8 +K7e`*J:E#rI=-BfH?jd\GB\4QFEDSFEcH)Yns(qaPrbDRMBkdQ[s(;=DrFQ">!+Yt:s'bq8 +rEoS2s'>S.s',M,r)s&%s&]/"s&K(urDW_or_`Vjr_NPhqb@&`rCcrYr(6]Tq+'qgh7`ZtnjiRJ +r(6]VrCd)_qG$rar_NGg!7TuQkfj!4s'Yh7r*oY8rabq;LPUeDMMd=NN/`jXO,oBbOcklkPEc'3!g]1>rg3bTR[X5F!h>gPrgs.^ +s.K=a!huHbrM9Iis/,ams/5psrMomus/c4%!j8`1rilF-!4)U1'XY9U[^NZT\@K/]]=Y_g]tV7r +^qp#e0Z1iJ`Q#s>aN;TJbKS5Vcd:(edaQ^qe^i@(f\,!4gYCW@hV[8LiSrnXjQ5OdkNMp0#3tO@ +m-X3.rpKpXnaZVL!qZ'VrUp3as7cHdrqZQiq"ssdq>K=PJcDSHJ,~> +JcC<$JcG3=nG`@ar;?EgrqcWiqtU3crq?<`rq-6^rUU!Ys7$!Us6fpSrp9[Ns6BRIs6'IGrT41C +jQ-=#s5F%;ro!h6!8d_2!SlH/g4.f.f@SU)e^W*tda?Ihcd'h\bfe2OaN2EA`Poa3_SO%&^:h1k +]",A\[^NQLZa$a=YH=q.WiE%sVl$;dUS=HTT:VUDS"#k6R$X,(P`q8nOH5H_NJrgRM2@%DL5(D8 +K7e`*J:E#rI=-BfH?jd\GB\4QFEDSFEcH)Yns(qaPrbDRMBkdQ[s(;=DrFQ">!+Yt:s'bq8 +rEoS2s'>S.s',M,r)s&%s&]/"s&K(urDW_or_`Vjr_NPhqb@&`rCcrYr(6]Tq+&YgqMau8qagWV +q+CTYrCm&^r_EGgr(mBehjNhurEoS4raG_6raYqrb).Brb;@Hr+l:JrGDFLrGVXRq/Q:P +r,_IOq/uIUm<@Q7olp@XrH7pXrcA$Yq/Q:Nlu2iAqJlOUs)\-\s)n?brceBe!."Qi!dfaMrpg-^o^r+Ts7ZKer:p9erqcEequ$9gir4N/V>l&~> +JcC<$JcG3=nG`@ar;?EgrqcWiqtU3crq?<`rq-6^rUU!Ys7$!Us6fpSrp9[Ns6BRIs6'IGrT41C +jQ-=#s5F%;ro!h6!8d_2!SlH/g4.f.f@SU)e^W*tda?Ihcd'h\bfe2OaN2EA`Poa3_SO%&^:h1k +]",A\[^NQLZa$a=YH=q.WiE%sVl$;dUS=HTT:VUDS"#k6R$X,(P`q8nOH5H_NJrgRM2@%DL5(D8 +K7e`*J:E#rI=-BfH?jd\GB\4QFEDSFEcH)Yns(qaPrbDRMBkdQ[s(;=DrFQ">!+Yt:s'bq8 +rEoS2s'>S.s',M,r)s&%s&]/"s&K(urDW_or_`Vjr_NPhqb@&`rCcrYr(6]Tq+($Ldn91$qagWV +q+CTYrCm&^r_EGgr(mApfMhB>rEoS4raG_6raYqrb).Brb;@Hr+l:JrGDFLrGVXRq/Q:P +r,_IOq/uIUm<@Q7olp@XrH7pXrcA$Yq/Q:Nlu2iAqJlOUs)\-\s)n?brceBe!."Qi!dfaMrpg-^o^r+Ts7ZKer:p9erqcEequ$9gir4N/V>l&~> +JcC<$JcG3=nG`=`rVZKgrqcWir:p9cs7ZB`s7H<^rUU!Ys7$!Us6fpSrTsRM!:'OIs60LGroX7B +!9F.>s5F%;ro!h6!8d_2!SlH/g&]mZrmu,?e^W*tda?Ihcd'h\bfe2OaN2EA`Pf[2_SO"%^:h1k +]",>[[^NQLZa$a=Y-"h-WiE%rVl$8cUS=HTT:VUDS"#h5R$X,(P`q8nOH5H_NJrgRM2@%DL5(D8 +K7ec,J:E#rI=-EhH?sj]GB\4QrcA0^ErL%ZE,Y_n#]4BoCMR["BkdQ[!bZ+WrFH%@@q5IHs'bq8 +rEoS2s'>S.s',M,rE9/&s&]/"s&K(ur)rb).Brb;@HqeQ1Irb_LLrbqaSpi61O +r,_FNpiZ@TlZ_Z>not%Ur,qjXrH%pXq/Q=OlYl`@qf2UUs)\-\s)eaN;TJbKS5VcHjkbdF-LneCE.%f@\g2gYCW@hV[8LiSsjs&*2j7k3(sml0@R"m-O-, +mf)YUnF?JJ!qZ'VrUp3as7cHdrqZQiq>:'eq>K@QJcDMFJ,~> +JcC<$JcG3=nG`=`rVZKgrqcWir:p9cs7ZB`s7H<^rUU!Ys7$!Us6fpSrTsRM!:'OIs60LGroX7B +!9F.>s5F%;ro!h6!8d_2!SlH/g&]mZrmu,?e^W*tda?Ihcd'h\bfe2OaN2EA`Pf[2_SO"%^:h1k +]",>[[^NQLZa$a=Y-"h-WiE%rVl$8cUS=HTT:VUDS"#h5R$X,(P`q8nOH5H_NJrgRM2@%DL5(D8 +K7ec,J:E#rI=-EhH?sj]GB\4QrcA0^ErL%ZE,Y_n#]4BoCMR["BkdQ[!bZ+WrFH%@@q5IHs'bq8 +rEoS2s'>S.s',M,rE9/&s&]/"s&K(ur)(kqi()9qagWV +pe(KXr_3/_r_EDfqb[<[iL0&"rEoP3s'be6raYt=qdoe>rb).Brb;@HqeQ1Irb_LLrbqaSpi61O +r,_FNpiZ@TlZ_Z>not%Ur,qjXrH%pXq/Q=OlYl`@qf2UUs)\-\s)eaN;TJbKS5VcHjkbdF-LneCE.%f@\g2gYCW@hV[8LiSsjs&*2j7k3(sml0@R"m-O-, +mf)YUnF?JJ!qZ'VrUp3as7cHdrqZQiq>:'eq>K@QJcDMFJ,~> +JcC<$JcG3=nG`=`rVZKgrqcWir:p9cs7ZB`s7H<^rUU!Ys7$!Us6fpSrTsRM!:'OIs60LGroX7B +!9F.>s5F%;ro!h6!8d_2!SlH/g&]mZrmu,?e^W*tda?Ihcd'h\bfe2OaN2EA`Pf[2_SO"%^:h1k +]",>[[^NQLZa$a=Y-"h-WiE%rVl$8cUS=HTT:VUDS"#h5R$X,(P`q8nOH5H_NJrgRM2@%DL5(D8 +K7ec,J:E#rI=-EhH?sj]GB\4QrcA0^ErL%ZE,Y_n#]4BoCMR["BkdQ[!bZ+WrFH%@@q5IHs'bq8 +rEoS2s'>S.s',M,rE9/&s&]/"s&K(ur)Nora>b7qdTP7s()"HLl$tGMMmFPNK0$[O-#KdP*2#nPa.N"QC%T +JcC<$JcG3=n,E7`r;?EgrqcWiqtU0bs7ZB`s7H?_r:9mXs7$!Us6fpSrTsRMs6BUJs60LGroX7B +s5a1>!oi1trnmh7hYu=8gtUT;g=b-Xf6,ZpeC;sqdF$=ecHa\YbKJ#KaN)<>`5BI/_8!b!]tCtg +\[],W[C!9HZ*:I8Xf\Y(Wi;noVPL#_U7n6PSt2C@S!fY2Q^3o$PEM)kO,o<\N/W[PM26qAL4t;5 +K7\Z)J:E#rI=-BfH?jaZGBS.PFEDSErc&0^Df9N2D/F+gC]A,LC&M]HB4bcTAcH<@A,Tm:@K0a6 +?iOI4?2\%.>Q7n*=oVV(=8c2"a8i:]F2e:&[ib9DD-U8bYdE^A#>?]^*9.]^nYi +8Gl'S9)_K^9_qK_:B"&c:u]aabl(oJ@/aU4@fBm:AGg$ssrMomus/c4%s/uC*rilF-!4)U1s0Md6rjE3D\@B)[]">Se]Y2&Y^Bq]l +_SX4/`Poj;rl?A,b0.uPc-FV\d*^:jeC<%"f@S[.g=k<:h;-rFi8ESRj5]4^roOdTkiq?slg*p( +mI'E2n*oi:rpp*\s7H<`s7ZKer:p9erqcHfqu$9gj8OW0UAo`~> +JcC<$JcG3=n,E7`r;?EgrqcWiqtU0bs7ZB`s7H?_r:9mXs7$!Us6fpSrTsRMs6BUJs60LGroX7B +s5a1>!oi1trnmh7hYu=8gtUT;g=b-Xf6,ZpeC;sqdF$=ecHa\YbKJ#KaN)<>`5BI/_8!b!]tCtg +\[],W[C!9HZ*:I8Xf\Y(Wi;noVPL#_U7n6PSt2C@S!fY2Q^3o$PEM)kO,o<\N/W[PM26qAL4t;5 +K7\Z)J:E#rI=-BfH?jaZGBS.PFEDSErc&0^Df9N2D/F+gC]A,LC&M]HB4bcTAcH<@A,Tm:@K0a6 +?iOI4?2\%.>Q7n*=oVV(=8c2"a8i:]F2e:&[ib9DD-U8bYd"NVe\+8,>dS8bbpW +9DqQ\:&[oe:\moaR-'h'R/LCk@/aU4@fBm:AGg$ssrMomus/c4%s/uC*rilF-!4)U1s0Md6rjE3D\@B)[]">Se]Y2&Y^Bq]l_SX4/ +`Poj;rl?A,b0.uPc-FV\d*^:jeC<%"f@S[.g=k<:h;-rFi8ESRj5]4^roOdTkiq?slg*p(mI'E2 +n*oi:rpp*\s7H<`s7ZKer:p9erqcHfqu$9gj8OW0UAo`~> +JcC<$JcG3=n,E7`r;?EgrqcWiqtU0bs7ZB`s7H?_r:9mXs7$!Us6fpSrTsRMs6BUJs60LGroX7B +s5a1>!oi1trnmh7hYu=8gtUT;g=b-Xf6,ZpeC;sqdF$=ecHa\YbKJ#KaN)<>`5BI/_8!b!]tCtg +\[],W[C!9HZ*:I8Xf\Y(Wi;noVPL#_U7n6PSt2C@S!fY2Q^3o$PEM)kO,o<\N/W[PM26qAL4t;5 +K7\Z)J:E#rI=-BfH?jaZGBS.PFEDSErc&0^Df9N2D/F+gC]A,LC&M]HB4bcTAcH<@A,Tm:@K0a6 +?iOI4?2\%.>Q7n*=oVV(=8c2"a8i:]F2e:&[ib9DD-U8bYdH9@ZZ+8,>dS8bbpW +9DqQ\:&[oe:\mo>;tNud?iFI4@JjU6A,^$:Ac?J/KDuFYMEVjeRF7OGJ +Fn^(DGOp(KGPlX_Fnp.YF8^.SEVseBDu=SOEW:(YF8g:]FoQXaGQ2mfH2`+$H[L3hI=?WpJ:N3% +JqJ]/L&Qf;LPUeDMMd=NN/`jXO,oBbrfR;GPl?pQQC!r*R$jA2rgWqX!1j+\s.B=arh9@ds.fRh +s/#amrMT[os/Gsss/Z1$riQ4's0)F+s02R0rj2X3!4Dg7$b*XU\[f;`]=bei^AbkR^qmn)_o0O5 +`lJ)",g"3PbKS5VcHjkbdaQ^qe^i@(f\,!4gYCW@hV[8LiSrnXjQ6C'&Ei9Al0@U#m-O--mdKW6 +nF?MKs7?9_rq6:'eq>K@QJcDJEJ,~> +JcC<$JcG0`5BI/^q[Xu]tCtg +\[],W[C!9GZ*:I8Xf\Y(Wi2hnVPL#_U7n6PSt2C@S!fY2Q^3o$PEM)kO,o<\N/W[PM26qAL4t;5 +K7\Z)J:E#rI=-BfH?ja[GBX(2FoHI`F)q8"!H;uVD?=ZkD#S2OC2%D]B`D`FB)ZBAAH-0<@fKm: +@/XF6?lS%.>5_V(=T;J$j:A[cb9`7WY9)2'U8FaFi^%o>,^&5P8 +8,>dS8bbpV9DqQ\:&[oe:]!rg;;odbbl(oJ@/aU4@fBm:AGg$aN;TJbKS5VcHjkbdF-LneCE.%f@\d1g=tE=h;7&Ii8N\Uj5f=ak3(pkl07L!rp0[Q +mf)YVnF?&Jo)J:]o_nI_pAambq#C0hqYC$dr;-BOrdk*Bs*t~> +JcC<$JcG0`5BI/^q[Xu]tCtg +\[],W[C!9GZ*:I8Xf\Y(Wi2hnVPL#_U7n6PSt2C@S!fY2Q^3o$PEM)kO,o<\N/W[PM26qAL4t;5 +K7\Z)J:E#rI=-BfH?ja[GBX(2FoHI`F)q8"!H;uVD?=ZkD#S2OC2%D]B`D`FB)ZBAAH-0<@fKm: +@/XF6?lS%.>5_V(=T;J$j:A[cb9`7WY9)2'U8B["jN:]X:8Gl'S +9)VE]9_qK_:B"&d:]OAcR-L+,R/LCk@/aU4@fBm:AGg$aN;TJbKS5VcHjkbdF-LneCE.%f@\d1g=tE=h;7&Ii8N\Uj5f=ak3(pkl07L!rp0[Qmf)YV +nF?&Jo)J:]o_nI_pAambq#C0hqYC$dr;-BOrdk*Bs*t~> +JcC<$JcG0`5BI/^q[Xu]tCtg +\[],W[C!9GZ*:I8Xf\Y(Wi2hnVPL#_U7n6PSt2C@S!fY2Q^3o$PEM)kO,o<\N/W[PM26qAL4t;5 +K7\Z)J:E#rI=-BfH?ja[GBX(2FoHI`F)q8"!H;uVD?=ZkD#S2OC2%D]B`D`FB)ZBAAH-0<@fKm: +@/XF6?lS%.>5_V(=T;J$j:A[cb9`7WY9)2'U8F]@(9(YXM8Gl'S +9)VE]9_qK_:B"&d:]OAE;tNud?iFI4@JjU6A,^$:Ac?J/KDuFYMEVjeQ +F7=;GFn^(,GPcR^Fnp.XF8^.TEVj_ADuFYPEW1"YF8^4\FT?U`G6`A;M#N57MMmFPNK4"!!K`HCOo^c2rfmMMQirgs.^s.K@bs.]OgrhTRj +s/,ams/>ssrMomu!3H.$s/uC*rilF-s0DX1!joACrjDj:\Gj#C]">Se]Y2&Y^H96I_SX4/`5T^8 +a2l?Db0.uPc-FV\d*^7he'umtf%8O+g"P07gtgfChr*GOioB([jlY^gkNM0plKeH9!U]=SmfN"K +nc&+Zo)SF]p&Facp\agdq>U6dqu$BgrSmg-s.KCB~> +JcC<$JcG-;nG`@ar;?BfrqcWiqtU0bs7ZB`s7H<^rUU!Ys7#sTs6fpSrTjUOlK\?4s60LGroX7B +!9F.>s5F%;ro!h6!8d_2EST=&g=b03f@SU(eC;sqdF$=ecHa\YbK@rJaN)<>`5BI/^q[Xu]Y(kf +\[],W[C!9GZ*:F7XfSS'Wi2hnVPL#_TqS-OSt2C@S!fY2Q^3o$PEM)kOH5E]N/W[PM2@"BL4t;5 +K7\Z)J:E#rI=-D@H3JS=GB\4QrcA0^ErL%`E,TZ4DJa6,rbMOKs(VIGs(;=DrFQ">s'u%;s'bq8 +rEoS2s'>S.s',M,r`T8's&]/"s&K(ur)_6r*oY8rabqreUf9Mi]"@sS!PQ5H^B)-drk^G. +`5T^8a2l?Db0.uPc-=PZcd:(edaQ^qe^i@(f\,!4gYCW@hV[8LiSrnXjQ5OdkNMp0!UB"MliHMA +rpKpXnaZVL!qZ'VrUp3as7cKerqZQiqYU0fqu,RSJcD>AJ,~> +JcC<$JcG-;nG`@ar;?BfrqcWiqtU0bs7ZB`s7H<^rUU!Ys7#sTs6fpSrTjUOlK\?4s60LGroX7B +!9F.>s5F%;ro!h6!8d_2EST=&g=b03f@SU(eC;sqdF$=ecHa\YbK@rJaN)<>`5BI/^q[Xu]Y(kf +\[],W[C!9GZ*:F7XfSS'Wi2hnVPL#_TqS-OSt2C@S!fY2Q^3o$PEM)kOH5E]N/W[PM2@"BL4t;5 +K7\Z)J:E#rI=-D@H3JS=GB\4QrcA0^ErL%`E,TZ4DJa6,rbMOKs(VIGs(;=DrFQ">s'u%;s'bq8 +rEoS2s'>S.s',M,r`T8's&]/"s&K(ur)rb).Brb;@HqeQ1Irb_LLrGVUQpMp(N +qK)+IpN?4ReT^n6rH7mWrcA$Ypi64Nlu2f@qf2XVrcA'\s)n?brceBe!."Qi$[[8KI=6QoIt3'# +K)UB+KS>/8LPYqd"cA4sN/`ksNt@D8P*2#mPa.N"QC!u+R@0NCRf]+NSc52^T:hkVU&UheU]%"g +V>mFkVZNfrWVrjsX8f:"XoGR(YPtd+Z2_-/Zi@B4[JmW7[fEr;\H0:Rrk&9F^AbkJ^qp#e1;h&L +`Q#s>aN;TJbKS5UcHab_dF$CkeC<%"f@S[.g=k<:h;-rFi8ESRj5]4^k2tjjrojIKli-5OmI'uB +!q>aMrpg-^o^r+Ts7ZKerV6BfrqcKgqu$?ij8OW0T)X<~> +JcC<$JcG-;nG`@ar;?BfrqcWiqtU0bs7ZB`s7H<^rUU!Ys7#sTs6fpSrTjUOlK\?4s60LGroX7B +!9F.>s5F%;ro!h6!8d_2EST=&g=b03f@SU(eC;sqdF$=ecHa\YbK@rJaN)<>`5BI/^q[Xu]Y(kf +\[],W[C!9GZ*:F7XfSS'Wi2hnVPL#_TqS-OSt2C@S!fY2Q^3o$PEM)kOH5E]N/W[PM2@"BL4t;5 +K7\Z)J:E#rI=-D@H3JS=GB\4QrcA0^ErL%`E,TZ4DJa6,rbMOKs(VIGs(;=DrFQ">s'u%;s'bq8 +rEoS2s'>S.s',M,r`T8's&]/"s&K(ur)rb).Brb;@HqeQ1Irb_LLrGVUQpMp(NqK)+I +pN?4ReT^n6rH7mWrcA$Ypi64Nlu2f@qf2XVrcA'\s)n?brceBe!."Qi$[[8KI=6QoIt3'#K)UB+ +KS>/8LPYqd"cA4sN/`ksNt@D8P*2#mPa.N"QC!u+R@0NCRf]+NSc52^T:hkVU&UheU]%"gV>mFk +VZNfrWVrjsX8f:"XoGR(YPtd+Z2_-/Zi@B4[JmW7[fEr;\H0:Rrk&9F^AbkJ^qp#e1;h&L`Q#s> +aN;TJbKS5UcHab_dF$CkeC<%"f@S[.g=k<:h;-rFi8ESRj5]4^k2tjjrojIKli-5OmI'uB!q>aM +rpg-^o^r+Ts7ZKerV6BfrqcKgqu$?ij8OW0T)X<~> +JcC<$JcG-;n,E7`r;?EgrVHNhqtU3crq?9_s7H<^rUU!Ys7#sTs6fpSrTsRMs6BUJs60LGroX7B +s5a1>#NF_$i8EMMhYu=3gtVh^B\D%if@JL%eC2jndEp4bcHXSVb/q`Ga2Z*:_ns7*^V@Ip]Xt_b +\@8oS['R'CYck43XK/A#W2HPiUnjcZTqJ$LSXc1=R@'A.QBd\uP*1rhO,f3YN/NRMM26qAKnP)2 +Jq8H&It%BF"akZCH?jc7G6W55FEDSFErL%ZE,Y_ns(qaPrbMOKs(VIGs(;=DrFQ">s'u%;s'bq8 +rEoS2s'>V/s',M,rE9/&s&]/"s&K(urDW_or_`Vjr_NMgqb@#_rCccToh"UCs1S9Alb380p.+pL +qapQTrCd)_qG$rarD3;er_`Ymqc!Jns&JR5m*,B7ra>_6qdTS8rabqtQC!r*R$jD3S"#qU6equ$BgrT4$0s.'+>~> +JcC<$JcG-;n,E7`r;?EgrVHNhqtU3crq?9_s7H<^rUU!Ys7#sTs6fpSrTsRMs6BUJs60LGroX7B +s5a1>#NF_$i8EMMhYu=3gtVh^B\D%if@JL%eC2jndEp4bcHXSVb/q`Ga2Z*:_ns7*^V@Ip]Xt_b +\@8oS['R'CYck43XK/A#W2HPiUnjcZTqJ$LSXc1=R@'A.QBd\uP*1rhO,f3YN/NRMM26qAKnP)2 +Jq8H&It%BF"akZCH?jc7G6W55FEDSFErL%ZE,Y_ns(qaPrbMOKs(VIGs(;=DrFQ">s'u%;s'bq8 +rEoS2s'>V/s',M,rE9/&s&]/"s&K(urDW_or_`Vjr_NMgqb@#_rCccToh"UCif3nqp.+pLqapQT +rCd)_qG$rarD3;er_`Ymqc!Jns&Jr`o9o'7r*TG2raG\5s'u%=r+5k>rb).Brb;@HqeQ1IrGDCK +rGVXRp2TqLq/btGpN?1QgirU;LPUeDMMmFPNK0$[O-#KeP*;)oQ'IZ%Q^F/.R[T_8S=H/LScYOWT`1Yb +U&^teV#R7kVZ!FmW;ijqWrK."XSo:$Y5b^)YlD!.ZMq31[/[Q5[K]"@sS#/.ab^V@S# +rk^J/`5T^8a2c9Bai_fMbg"GYcd:(edaQ^qe^i@(f\,!4gYCW@hV[8LiSrkWj5f=ak3(t-km$G= +m-O-,mf)YVnF?&JncJFTo`"O`pAambq#:*gqYL*er;-BRrdk*>s*t~> +JcC<$JcG-;n,E7`r;?EgrVHNhqtU3crq?9_s7H<^rUU!Ys7#sTs6fpSrTsRMs6BUJs60LGroX7B +s5a1>#NF_$i8EMMhYu=3gtVh^B\D%if@JL%eC2jndEp4bcHXSVb/q`Ga2Z*:_ns7*^V@Ip]Xt_b +\@8oS['R'CYck43XK/A#W2HPiUnjcZTqJ$LSXc1=R@'A.QBd\uP*1rhO,f3YN/NRMM26qAKnP)2 +Jq8H&It%BF"akZCH?jc7G6W55FEDSFErL%ZE,Y_ns(qaPrbMOKs(VIGs(;=DrFQ">s'u%;s'bq8 +rEoS2s'>V/s',M,rE9/&s&]/"s&K(urDW_or_`Vjr_NMgqb@#_rCccToh"UChFdK3q+1BSpe(KX +rCm&^r_EDfqb[8hr_iVlr`&nts&8kolr3UUr*TG2raG\5s'u%=r+5k>rb).Brb;@HqeQ1IrGDCK +rGVXRp2TqLq/btGpN?1QgirU;LPUeDMMmFPNK0$[O-#KeP*;)oQ'IZ%Q^F/.R[T_8S=H/LScYOWT`1Yb +U&^teV#R7kVZ!FmW;ijqWrK."XSo:$Y5b^)YlD!.ZMq31[/[Q5[K]"@sS#/.ab^V@S# +rk^J/`5T^8a2c9Bai_fMbg"GYcd:(edaQ^qe^i@(f\,!4gYCW@hV[8LiSrkWj5f=ak3(t-km$G= +m-O-,mf)YVnF?&JncJFTo`"O`pAambq#:*gqYL*er;-BRrdk*>s*t~> +JcC<$JcG*:nG`=`rVZKgrVHNhqtU3crq?9_s7H<^rUTsXs7$!Us6fpSrTsRMs6BRIs6'IGrT41C +jQ-=#s5F%;rnmh7hYu=3gtVh^G1kO"f@JL%eC2jndEp4bcHXSVb/q`Ga2Q$9_ns7*^V@Ip]XkYa +\@/iRZa6sBYck43XK/A#W2HPiUnjcZTqJ$LSXc1=R@'A.QBd\uP*1rhO,f3YN/NRMM26qAL4t;5 +K7\Z)J:E#rI=-BfH?ja[GB\4QrcA0^ErL(YDuahUD?=ZkD#S5MC&huHBEDgYB)Q9BA7K-J@fKm: +@/aO5?N4=0>lS%.>5h\)=T;J$j:AR]`9`.QT9(GR>8H)-K]`>_E^%b+m +8Gc!Q9)VE]9_qK_:B"&d;#O8j;YsDl<;onp_;8_o0O5`l?'?aN;TJbKS5VcHjh`dF$CkeC<%"f@S[.g=k<:h;-rFi8ESRj5]4^ +jlY^gkiq?slKdg'mHs?@mfDqJrpp*\s7H<`s7ZKer:p9es8)Qgr;?Hjk5Kr3Rf@m~> +JcC<$JcG*:nG`=`rVZKgrVHNhqtU3crq?9_s7H<^rUTsXs7$!Us6fpSrTsRMs6BRIs6'IGrT41C +jQ-=#s5F%;rnmh7hYu=3gtVh^G1kO"f@JL%eC2jndEp4bcHXSVb/q`Ga2Q$9_ns7*^V@Ip]XkYa +\@/iRZa6sBYck43XK/A#W2HPiUnjcZTqJ$LSXc1=R@'A.QBd\uP*1rhO,f3YN/NRMM26qAL4t;5 +K7\Z)J:E#rI=-BfH?ja[GB\4QrcA0^ErL(YDuahUD?=ZkD#S5MC&huHBEDgYB)Q9BA7K-J@fKm: +@/aO5?N4=0>lS%.>5h\)=T;J$j:AR]`9`.QT9(GR>8H)-KN<"q:NVH$= +8Gc!Q9)VE]9_qK_:B"&d;#O8j;YsDl<;onp_;8_o0O5`l?'?aN;TJbKS5VcHjh`dF$CkeC<%"f@S[.g=k<:h;-rFi8ESRj5]4^ +jlY^gkiq?slKdg'mHs?@mfDqJrpp*\s7H<`s7ZKer:p9es8)Qgr;?Hjk5Kr3Rf@m~> +JcC<$JcG*:nG`=`rVZKgrVHNhqtU3crq?9_s7H<^rUTsXs7$!Us6fpSrTsRMs6BRIs6'IGrT41C +jQ-=#s5F%;rnmh7hYu=3gtVh^G1kO"f@JL%eC2jndEp4bcHXSVb/q`Ga2Q$9_ns7*^V@Ip]XkYa +\@/iRZa6sBYck43XK/A#W2HPiUnjcZTqJ$LSXc1=R@'A.QBd\uP*1rhO,f3YN/NRMM26qAL4t;5 +K7\Z)J:E#rI=-BfH?ja[GB\4QrcA0^ErL(YDuahUD?=ZkD#S5MC&huHBEDgYB)Q9BA7K-J@fKm: +@/aO5?N4=0>lS%.>5h\)=T;J$j:AR]`9`.QT9(GR>8H)-G9)(pO8Gc!Q +9)VE]9_qK_:B"&d;#O8j;YsDl<;onp_;8_o0O5`l?'?aN;TJbKS5VcHjh`dF$CkeC<%"f@S[.g=k<:h;-rFi8ESRj5]4^jlY^g +kiq?slKdg'mHs?@mfDqJrpp*\s7H<`s7ZKer:p9es8)Qgr;?Hjk5Kr3Rf@m~> +JcC<$JcG'9nG`=`rVZKgrqcThqtU3crq?9_s7H<^rUTsXs7$!Us6fpSr9OLNlK\?4s60LGroX7B +!9F.>s5F%;rnn"rF5e8 +!+>b4s'G_2r`oJ-s'#A(s&f;&rDrqus&Aqqs&/kor)!Agr_E;arCm)]n4N1Am7?n?rkABFqFC9N +qapNSrCd)_qG$rar_NAer_`Ymqc!Jnr`/eqr`B)$qcWl$r`f'>qd9>1raG_6raYqrb).B +rb;@HqeQ1IrGDCKrGVUQol9eJpN,YBpN?1Ql$)oGr,qdVr,_gWpi61Mmr/,Cqf2UUs)\-\s)e;Ll$tGMuJYFNK0'\OHG]hPE_;sQ'Rd9Qj/tIS"#q< +Sc52cT:hjNTq\9VrM0LkVPa +JcC<$JcG'9nG`=`rVZKgrqcThqtU3crq?9_s7H<^rUTsXs7$!Us6fpSr9OLNlK\?4s60LGroX7B +!9F.>s5F%;rnn"rF5e8 +!+>b4s'G_2r`oJ-s'#A(s&f;&rDrqus&Aqqs&/kor)!Agr_E;arCm)]n4N1Am7?n?rf6u;qFC9N +qapNSrCd)_qG$rar_NAer_`Ymqc!Jnr`/eqr`B)$qcWl$r`f&_qd9>1raG_6raYqrb).B +rb;@HqeQ1IrGDCKrGVUQol9eJpN,YBpN?1Ql$)oGr,qdVr,_gWpi61Mmr/,Cqf2UUs)\-\s)e;Ll$tGMuJYFNK0'\OHG]hPE_;sQ'Rd9Qj/tIS"#q< +Sc52cT:hjNTq\9VrM0LkVPa +JcC<$JcG'9nG`=`rVZKgrqcThqtU3crq?9_s7H<^rUTsXs7$!Us6fpSr9OLNlK\?4s60LGroX7B +!9F.>s5F%;rnn"rF5e8 +!+>b4s'G_2r`oJ-s'#A(s&f;&rDrqus&Aqqs&/kor)!Agr_E;arCm)]n4N1Am7?n?r_*5_qFC9N +qapNSrCd)_qG$rar_NAer_`Ymqc!Jnr`/eqr`B)$qcWl$r`fD$pJUlqra>_6r*oY8rabq +JcC<$JcG'9nG`=`r;?BfrqcWiqtU0brq?9_s7H<^r:9mXs7#sTs6fpSrTsRMs6BRI!pJh1roX7B +s5a1>!TN);i,df4hVI#CgY:H9g"=p.f%&:"e'cXkd*L"_bfe2PaiMNB`Pod4_SO%&^:h1k]",A\ +[^NQLZa-g>YH=q.X/`.tVl$;dUnXQVTV%gHS=?"9R$a5+Q'@JqP*(ieO,f3YMi*@JLkg_>KnP)2 +Jq8H&It%BF"akZCH?jc7G6)l0rcABdEcQ/>E,]apDZ=PRD#S5MCB&#IB`D`FB)ZBAAH-0=@fKm: +@/aO5?N4=0>lS".>5_V(=T;J$5_\&>lJ%.?Me+/@/aU4@fBm:AGg$l;It3'#JqAW-KS>/8LPUeDMMd=NN/`jYO-#KeP*;.0Pn97JR$a;1R[]e:SXl@D +T:hkVT`Us`U].%jV5C-hVuN^qWVrguX/rE$XoGR(YPbX)Z2_-/Zi@E4[JdN8\%&sI\c95@]DfJC +]`>eG^B)-drk\]R`;[^c`lH0AaiV]KbKS5VcHjl:d2p`beC<%"f@S[.g=k<:h;-rFi8ESRioB([ +jlY^gkl0fIlKeH9!U]=SmfN"Knc&(\oCV\Ro`4^bp\jmdq>^ +JcC<$JcG'9nG`=`r;?BfrqcWiqtU0brq?9_s7H<^r:9mXs7#sTs6fpSrTsRMs6BRI!pJh1roX7B +s5a1>!TN);i,df4hVI#CgY:H9g"=p.f%&:"e'cXkd*L"_bfe2PaiMNB`Pod4_SO%&^:h1k]",A\ +[^NQLZa-g>YH=q.X/`.tVl$;dUnXQVTV%gHS=?"9R$a5+Q'@JqP*(ieO,f3YMi*@JLkg_>KnP)2 +Jq8H&It%BF"akZCH?jc7G6)l0rcABdEcQ/>E,]apDZ=PRD#S5MCB&#IB`D`FB)ZBAAH-0=@fKm: +@/aO5?N4=0>lS".>5_V(=T;J$5_\&>lJ%.?Me+/@/aU4@fBm:AGg$l;It3'#JqAW-KS>/8LPUeDMMd=NN/`jYO-#KeP*;.0Pn97JR$a;1R[]e:SXl@D +T:hkVT`Us`U].%jV5C-hVuN^qWVrguX/rE$XoGR(YPbX)Z2_-/Zi@E4[JdN8\%&sI\c95@]DfJC +]`>eG^B)-drk\]R`;[^c`lH0AaiV]KbKS5VcHjl:d2p`beC<%"f@S[.g=k<:h;-rFi8ESRioB([ +jlY^gkl0fIlKeH9!U]=SmfN"Knc&(\oCV\Ro`4^bp\jmdq>^ +JcC<$JcG'9nG`=`r;?BfrqcWiqtU0brq?9_s7H<^r:9mXs7#sTs6fpSrTsRMs6BRI!pJh1roX7B +s5a1>!TN);i,df4hVI#CgY:H9g"=p.f%&:"e'cXkd*L"_bfe2PaiMNB`Pod4_SO%&^:h1k]",A\ +[^NQLZa-g>YH=q.X/`.tVl$;dUnXQVTV%gHS=?"9R$a5+Q'@JqP*(ieO,f3YMi*@JLkg_>KnP)2 +Jq8H&It%BF"akZCH?jc7G6)l0rcABdEcQ/>E,]apDZ=PRD#S5MCB&#IB`D`FB)ZBAAH-0=@fKm: +@/aO5?N4=0>lS".>5_V(=T;J$5_\&>lJ%.?Me+/@/aU4@fBm:AGg$l;It3'#JqAW-KS>/8LPUeDMMd=NN/`jYO-#KeP*;.0Pn97JR$a;1R[]e:SXl@D +T:hkVT`Us`U].%jV5C-hVuN^qWVrguX/rE$XoGR(YPbX)Z2_-/Zi@E4[JdN8\%&sI\c95@]DfJC +]`>eG^B)-drk\]R`;[^c`lH0AaiV]KbKS5VcHjl:d2p`beC<%"f@S[.g=k<:h;-rFi8ESRioB([ +jlY^gkl0fIlKeH9!U]=SmfN"Knc&(\oCV\Ro`4^bp\jmdq>^ +JcC<$JcG$8nG`=`r;?BfrqcThqtU3crq?9_rq-6^r:9mXrp]mTs6fpSr9XIL!:'OIs60LGroO:D +jQ-=#IH'5Ei8EMMhVI#CgtUQ:g"=p.f%&:"e'cXkd*L"_bfe2PaiMNB`Pod4_SO%&^:h1k]",>[ +[^NQLZa$a=YH=q.WiE%sVl$;dUnXQVTV%gHS=?"9R$a5+Q'IPrP*(ieO,f3YN/NRMLkg_>KnP)2 +Jq8K'J:E#rI=-D@H3SY>GB\4RFoHI`F)q8"s)7sVrbhaQ!,VXMs(_RJrb2=E!+u1@s'u+>rF5e8 +s'Yh5s'G_2r`oJ-s'#A(!a&N*rDrqus&Anps&/koqb[8fr_E;aqb6l[k=Y58gdq95p.G9VrCm&^ +r_EDfqb[8hr_iSkr`&ksqc_6qdTP7s()"bKS5UcHab_dF$CkeC<%"rmqV3g"P07gtgfChr*GOir7sAjQ5OdkNMp0 +!UB"MliHMArpKpXnaZVL!qZ'Vrq6 +JcC<$JcG$8nG`=`r;?BfrqcThqtU3crq?9_rq-6^r:9mXrp]mTs6fpSr9XIL!:'OIs60LGroO:D +jQ-=#IH'5Ei8EMMhVI#CgtUQ:g"=p.f%&:"e'cXkd*L"_bfe2PaiMNB`Pod4_SO%&^:h1k]",>[ +[^NQLZa$a=YH=q.WiE%sVl$;dUnXQVTV%gHS=?"9R$a5+Q'IPrP*(ieO,f3YN/NRMLkg_>KnP)2 +Jq8K'J:E#rI=-D@H3SY>GB\4RFoHI`F)q8"s)7sVrbhaQ!,VXMs(_RJrb2=E!+u1@s'u+>rF5e8 +s'Yh5s'G_2r`oJ-s'#A(!a&N*rDrqus&Anps&/koqb[8fr_E;aqb6l[k=Y58gdq95p.G9VrCm&^ +r_EDfqb[8hr_iSkr`&ksqc_6qdTP7s()"bKS5UcHab_dF$CkeC<%"rmqV3g"P07gtgfChr*GOir7sAjQ5OdkNMp0 +!UB"MliHMArpKpXnaZVL!qZ'Vrq6 +JcC<$JcG$8nG`=`r;?BfrqcThqtU3crq?9_rq-6^r:9mXrp]mTs6fpSr9XIL!:'OIs60LGroO:D +jQ-=#IH'5Ei8EMMhVI#CgtUQ:g"=p.f%&:"e'cXkd*L"_bfe2PaiMNB`Pod4_SO%&^:h1k]",>[ +[^NQLZa$a=YH=q.WiE%sVl$;dUnXQVTV%gHS=?"9R$a5+Q'IPrP*(ieO,f3YN/NRMLkg_>KnP)2 +Jq8K'J:E#rI=-D@H3SY>GB\4RFoHI`F)q8"s)7sVrbhaQ!,VXMs(_RJrb2=E!+u1@s'u+>rF5e8 +s'Yh5s'G_2r`oJ-s'#A(!a&N*rDrqus&Anps&/koqb[8fr_E;aqb6l[k=Y58gdq95p.G9VrCm&^ +r_EDfqb[8hr_iSkr`&ksqc_6qdTP7s()"bKS5UcHab_dF$CkeC<%"rmqV3g"P07gtgfChr*GOir7sAjQ5OdkNMp0 +!UB"MliHMArpKpXnaZVL!qZ'Vrq6 +JcC<$JcG$8n,E7`r;?BfrVHNhqtU0brq?9_rq-6^r:9jWs7$!UrpKgRrTsRMs6BUJs60LGroX7B +!9F.>s5F%;rnr:`hVI#CgtUQ:g"=p.f%&:"e'cXkd*L"^bfe2PaiMNB`Poa3_SO"%^:h1k]",>[ +[^EKKZa$a=YH=q.WiE%sVl$;dUnXQVTV%gHS=?":R$a5+Q'IStP*(ieO,f3YN/NRMM26qAL4t;5 +K7\Z)J:E#rI=-EhH?sj]G^"?:G'.qLFE;MDrc&!YDf>Vm!c;airbMOK!,;CF!bZ+WrFH%@@q5IH +!b#JErEfV4?![D6s'#J,rE9/&s&]/"s&K(urDW\ns&&\jr_NJfq+^`[q+Kd@nO_k6pdt0OrCd)_ +q+^i`r_NAer_`YmqG[Amr`/hrrE&u#qcWl$r`f8)ra#M0qHs81raG\5raYqrb).Brb;@H +qJ6(HrGD@Jr,;LPnT"5BolKMBol]MBq/uCQr,_gWp2TnIpM]nIqJlLTs)\-\s)n?brc\ouH$O^^ +H[C-gI=?WpJ:N3&rdu8FKnb>;Ll$tGMieG^]2(L +_>_:P_o2Pn!QN1Za8sE*rlZ)$c-FV\d*^7hdaQ^qe^i@(f\,!4gYDea(uF0.i8N\Uj5f=`k2tjj +l07Kulg4!*mI'uB!V#XYo)J=]o`"O`pAamcq#:*gqYU0gr;6HZrdk*2s*t~> +JcC<$JcG$8n,E7`r;?BfrVHNhqtU0brq?9_rq-6^r:9jWs7$!UrpKgRrTsRMs6BUJs60LGroX7B +!9F.>s5F%;rnr:`hVI#CgtUQ:g"=p.f%&:"e'cXkd*L"^bfe2PaiMNB`Poa3_SO"%^:h1k]",>[ +[^EKKZa$a=YH=q.WiE%sVl$;dUnXQVTV%gHS=?":R$a5+Q'IStP*(ieO,f3YN/NRMM26qAL4t;5 +K7\Z)J:E#rI=-EhH?sj]G^"?:G'.qLFE;MDrc&!YDf>Vm!c;airbMOK!,;CF!bZ+WrFH%@@q5IH +!b#JErEfV4?![D6s'#J,rE9/&s&]/"s&K(urDW\ns&&\jr_NJfq+^`[q+Kd@nO_k6pdt0OrCd)_ +q+^i`r_NAer_`YmqG[Amr`/hrrE&u#qcWl$r`f8)ra#M0qHs81raG\5raYqrb).Brb;@H +qJ6(HrGD@Jr,;LPnT"5BolKMBol]MBq/uCQr,_gWp2TnIpM]nIqJlLTs)\-\s)n?brc\ouH$O^^ +H[C-gI=?WpJ:N3&rdu8FKnb>;Ll$tGMieG^]2(L +_>_:P_o2Pn!QN1Za8sE*rlZ)$c-FV\d*^7hdaQ^qe^i@(f\,!4gYDea(uF0.i8N\Uj5f=`k2tjj +l07Kulg4!*mI'uB!V#XYo)J=]o`"O`pAamcq#:*gqYU0gr;6HZrdk*2s*t~> +JcC<$JcG$8n,E7`r;?BfrVHNhqtU0brq?9_rq-6^r:9jWs7$!UrpKgRrTsRMs6BUJs60LGroX7B +!9F.>s5F%;rnr:`hVI#CgtUQ:g"=p.f%&:"e'cXkd*L"^bfe2PaiMNB`Poa3_SO"%^:h1k]",>[ +[^EKKZa$a=YH=q.WiE%sVl$;dUnXQVTV%gHS=?":R$a5+Q'IStP*(ieO,f3YN/NRMM26qAL4t;5 +K7\Z)J:E#rI=-EhH?sj]G^"?:G'.qLFE;MDrc&!YDf>Vm!c;airbMOK!,;CF!bZ+WrFH%@@q5IH +!b#JErEfV4?![D6s'#J,rE9/&s&]/"s&K(urDW\ns&&\jr_NJfq+^`[q+Kd@nO_k6pdt0OrCd)_ +q+^i`r_NAer_`YmqG[Amr`/hrrE&u#qcWl$r`f8)ra#M0qHs81raG\5raYqrb).Brb;@H +qJ6(HrGD@Jr,;LPnT"5BolKMBol]MBq/uCQr,_gWp2TnIpM]nIqJlLTs)\-\s)n?brc\ouH$O^^ +H[C-gI=?WpJ:N3&rdu8FKnb>;Ll$tGMieG^]2(L +_>_:P_o2Pn!QN1Za8sE*rlZ)$c-FV\d*^7hdaQ^qe^i@(f\,!4gYDea(uF0.i8N\Uj5f=`k2tjj +l07Kulg4!*mI'uB!V#XYo)J=]o`"O`pAamcq#:*gqYU0gr;6HZrdk*2s*t~> +JcC<$JcG!7n,E7`r;?BfrVHNhqY:*brq?6^s7H<^r:9mXs7#sTs6fpSrTsRMs6BRIs6'IGrT4@H +jQ,@]io8qrhuV`lrnVYNgY1B7f[na+e^W*tda?Ihcd'eZbKJ&LaN)<>`5BI/^q[Xu]Y(kf\[],W +[C!9GZ*:I8Xf\\)Wi;qpVPU)aU7n9RT:VUDS"#k6R$X,(Q'@JqOcYWbNfB!VMi*@JLkg_>KnP)2 +Jq8H&IsuipI=-D@H3SY>GB\4RFoHIfF)l;@EH#l8rbhaQs(q[M!buF`rb2=Es(;7As().>raPn9 +s'Yh5s'>\2rETA,s'#D)s&f;&rDrqus&Aqqr_ibnqb[8frD*,^qb6cXj@\r6lq$kBoh,0UrCm&^ +rD*>fqG@/gr_iVlrD`brqc<\trE/r"rEB2)qcs)*ra,J/ra>_6r*oY8rabn;s(;7Cqe5tCrbD=G +rG;IMphp"Jqf(tColB_Hm<%uCo60hMolU.Rr,VLNp2L"LpMftKrc8$[rH/'^s*"Bcs*+Nhrd"Tl +I/\NpIXh?I'nLshK7nr5L51SAM2I4MN/`jYO-#M'OqNtCQ'IZ%R$a;1S"#q!5&3B!kl=^rkANM_86,f +!Q2kT`<"!!rl>,^b5TQobg"GYcd:%ddF-LneCE.Lf-]/'g=k<:h;-rFi8ESQioB([jlY^gkNM0p +lKdd&m-X6/n*fc8nc&+Zo)SF]p&Facp\jmdq>^ +JcC<$JcG!7n,E7`r;?BfrVHNhqY:*brq?6^s7H<^r:9mXs7#sTs6fpSrTsRMs6BRIs6'IGrT4@H +jQ,@]io8qrhuV`lrnVYNgY1B7f[na+e^W*tda?Ihcd'eZbKJ&LaN)<>`5BI/^q[Xu]Y(kf\[],W +[C!9GZ*:I8Xf\\)Wi;qpVPU)aU7n9RT:VUDS"#k6R$X,(Q'@JqOcYWbNfB!VMi*@JLkg_>KnP)2 +Jq8H&IsuipI=-D@H3SY>GB\4RFoHIfF)l;@EH#l8rbhaQs(q[M!buF`rb2=Es(;7As().>raPn9 +s'Yh5s'>\2rETA,s'#D)s&f;&rDrqus&Aqqr_ibnqb[8frD*,^qb6cXj@\r6lq$kBoh,0UrCm&^ +rD*>fqG@/gr_iVlrD`brqc<\trE/r"rEB2)qcs)*ra,J/ra>_6r*oY8rabn;s(;7Cqe5tCrbD=G +rG;IMphp"Jqf(tColB_Hm<%uCo60hMolU.Rr,VLNp2L"LpMftKrc8$[rH/'^s*"Bcs*+Nhrd"Tl +I/\NpIXh?I'nLshK7nr5L51SAM2I4MN/`jYO-#M'OqNtCQ'IZ%R$a;1S"#q!5&3B!kl=^rkANM_86,f +!Q2kT`<"!!rl>,^b5TQobg"GYcd:%ddF-LneCE.Lf-]/'g=k<:h;-rFi8ESQioB([jlY^gkNM0p +lKdd&m-X6/n*fc8nc&+Zo)SF]p&Facp\jmdq>^ +JcC<$JcG!7n,E7`r;?BfrVHNhqY:*brq?6^s7H<^r:9mXs7#sTs6fpSrTsRMs6BRIs6'IGrT4@H +jQ,@]io8qrhuV`lrnVYNgY1B7f[na+e^W*tda?Ihcd'eZbKJ&LaN)<>`5BI/^q[Xu]Y(kf\[],W +[C!9GZ*:I8Xf\\)Wi;qpVPU)aU7n9RT:VUDS"#k6R$X,(Q'@JqOcYWbNfB!VMi*@JLkg_>KnP)2 +Jq8H&IsuipI=-D@H3SY>GB\4RFoHIfF)l;@EH#l8rbhaQs(q[M!buF`rb2=Es(;7As().>raPn9 +s'Yh5s'>\2rETA,s'#D)s&f;&rDrqus&Aqqr_ibnqb[8frD*,^qb6cXj@\r6lq$kBoh,0UrCm&^ +rD*>fqG@/gr_iVlrD`brqc<\trE/r"rEB2)qcs)*ra,J/ra>_6r*oY8rabn;s(;7Cqe5tCrbD=G +rG;IMphp"Jqf(tColB_Hm<%uCo60hMolU.Rr,VLNp2L"LpMftKrc8$[rH/'^s*"Bcs*+Nhrd"Tl +I/\NpIXh?I'nLshK7nr5L51SAM2I4MN/`jYO-#M'OqNtCQ'IZ%R$a;1S"#q!5&3B!kl=^rkANM_86,f +!Q2kT`<"!!rl>,^b5TQobg"GYcd:%ddF-LneCE.Lf-]/'g=k<:h;-rFi8ESQioB([jlY^gkNM0p +lKdd&m-X6/n*fc8nc&+Zo)SF]p&Facp\jmdq>^ +JcC<$JcG!7n,E4_r;?BfrVHNhqtU0brq?6^s7H<^r:9mXrp]mTrpKgRrTsRMs6BUJs60LGroO:D +jQ-=#!TN);huV`lrnW%YgY1B7f[na+e^W*tda?IhcHa\YbKJ&LaN)<>`5BI/^q[Xu]Y(ke\[],W +[C!9GZ*:F7Xf\Y(Wi;qpVPU)`U7n9RT:VUDS"#k7R$X,(Q'@JqP*(ieNfB!VMi*@JLkg_>KnP)2 +JqAQ(J:E#rI=-BgH?sj]G^"@TF`m_+s)S0\rc.sW!,qjSs(qaPrG)ILBkdQ[s(D@Dral+?!+Yt: +!b#JEra5\3s'>V/s',M,rE9/&!*B,"s&K%trDW\ns&&Yir_NJfpJ(HWoh4C=mRd=Ink&LHrCd)_ +q+^i`rD3;er_`YmqG[Amr`/eqr`B&#qcWl$r`f5(ra#M0qd9>1raG\5raYt=qdob=s(D4Brb;@H +qJ6(HrGD=Ir,;IOluDZj +W2ZcqWWK6&XSo:$Y5b^(YlD!.ZMh-0[/[Q4[f +JcC<$JcG!7n,E4_r;?BfrVHNhqtU0brq?6^s7H<^r:9mXrp]mTrpKgRrTsRMs6BUJs60LGroO:D +jQ-=#!TN);huV`lrnW%YgY1B7f[na+e^W*tda?IhcHa\YbKJ&LaN)<>`5BI/^q[Xu]Y(ke\[],W +[C!9GZ*:F7Xf\Y(Wi;qpVPU)`U7n9RT:VUDS"#k7R$X,(Q'@JqP*(ieNfB!VMi*@JLkg_>KnP)2 +JqAQ(J:E#rI=-BgH?sj]G^"@TF`m_+s)S0\rc.sW!,qjSs(qaPrG)ILBkdQ[s(D@Dral+?!+Yt: +!b#JEra5\3s'>V/s',M,rE9/&!*B,"s&K%trDW\ns&&Yir_NJfpJ(HWoh4C=mRd=Ink&LHrCd)_ +q+^i`rD3;er_`YmqG[Amr`/eqr`B&#qcWl$r`f5(ra#M0qd9>1raG\5raYt=qdob=s(D4Brb;@H +qJ6(HrGD=Ir,;IOluDZj +W2ZcqWWK6&XSo:$Y5b^(YlD!.ZMh-0[/[Q4[f +JcC<$JcG!7n,E4_r;?BfrVHNhqtU0brq?6^s7H<^r:9mXrp]mTrpKgRrTsRMs6BUJs60LGroO:D +jQ-=#!TN);huV`lrnW%YgY1B7f[na+e^W*tda?IhcHa\YbKJ&LaN)<>`5BI/^q[Xu]Y(ke\[],W +[C!9GZ*:F7Xf\Y(Wi;qpVPU)`U7n9RT:VUDS"#k7R$X,(Q'@JqP*(ieNfB!VMi*@JLkg_>KnP)2 +JqAQ(J:E#rI=-BgH?sj]G^"@TF`m_+s)S0\rc.sW!,qjSs(qaPrG)ILBkdQ[s(D@Dral+?!+Yt: +!b#JEra5\3s'>V/s',M,rE9/&!*B,"s&K%trDW\ns&&Yir_NJfpJ(HWoh4C=mRd=Ink&LHrCd)_ +q+^i`rD3;er_`YmqG[Amr`/eqr`B&#qcWl$r`f5(ra#M0qd9>1raG\5raYt=qdob=s(D4Brb;@H +qJ6(HrGD=Ir,;IOluDZj +W2ZcqWWK6&XSo:$Y5b^(YlD!.ZMh-0[/[Q4[f +JcC<$JcG!7mf*+^r;?BfrVHNhqY:'as7Z?_rq-6^r:9jWs7#sTs6fpSrTsRMs6BRI!pJh1roX7B +!9F.>!TN);huV`lrnVMJgY1B7f[na+e^W*tda?IgcHa\YbKJ#KaN)<>`5BI.^q[Xt]Y(ke\[])V +[C!9GZ*:F7Xf\Y(Wi;qpVPU)aU7n9RT:VUDS"#k7R$X,(Q'@JqP*(ieO,f3YN/NRMM26qAL4t;5 +K7\Z)J:E%II0"_Brd"TjGlDmfG'3e+s)S0\rc&!YDf>Vm!c;airbMOKs(VIG!bZ+Wral+?s'u%; +s'bq8ra5\3!+#P.s'#J,rE9/&s&]/"s&K(ur)1raG\5raYqrb).Brb;@HqJ6%G +rb_CIr,;CMl#H?9p2fVCkB6BI0G(LJ:N3& +rduAIKnb>;Ll$tGMis1A9Cs1SHHrkJKK!5\ZOs2+iTrl"oXa8X-a +ai_cLbKS61c2l8aMrpg-^o^r+T!quB_r:p +JcC<$JcG!7mf*+^r;?BfrVHNhqY:'as7Z?_rq-6^r:9jWs7#sTs6fpSrTsRMs6BRI!pJh1roX7B +!9F.>!TN);huV`lrnVMJgY1B7f[na+e^W*tda?IgcHa\YbKJ#KaN)<>`5BI.^q[Xt]Y(ke\[])V +[C!9GZ*:F7Xf\Y(Wi;qpVPU)aU7n9RT:VUDS"#k7R$X,(Q'@JqP*(ieO,f3YN/NRMM26qAL4t;5 +K7\Z)J:E%II0"_Brd"TjGlDmfG'3e+s)S0\rc&!YDf>Vm!c;airbMOKs(VIG!bZ+Wral+?s'u%; +s'bq8ra5\3!+#P.s'#J,rE9/&s&]/"s&K(ur)1raG\5raYqrb).Brb;@HqJ6%G +rb_CIr,;CMl#H?9p2fVCkB6BI0G(LJ:N3& +rduAIKnb>;Ll$tGMis1A9Cs1SHHrkJKK!5\ZOs2+iTrl"oXa8X-a +ai_cLbKS61c2l8aMrpg-^o^r+T!quB_r:p +JcC<$JcG!7mf*+^r;?BfrVHNhqY:'as7Z?_rq-6^r:9jWs7#sTs6fpSrTsRMs6BRI!pJh1roX7B +!9F.>!TN);huV`lrnVMJgY1B7f[na+e^W*tda?IgcHa\YbKJ#KaN)<>`5BI.^q[Xt]Y(ke\[])V +[C!9GZ*:F7Xf\Y(Wi;qpVPU)aU7n9RT:VUDS"#k7R$X,(Q'@JqP*(ieO,f3YN/NRMM26qAL4t;5 +K7\Z)J:E%II0"_Brd"TjGlDmfG'3e+s)S0\rc&!YDf>Vm!c;airbMOKs(VIG!bZ+Wral+?s'u%; +s'bq8ra5\3!+#P.s'#J,rE9/&s&]/"s&K(ur)1raG\5raYqrb).Brb;@HqJ6%G +rb_CIr,;CMl#H?9p2fVCkB6BI0G(LJ:N3& +rduAIKnb>;Ll$tGMis1A9Cs1SHHrkJKK!5\ZOs2+iTrl"oXa8X-a +ai_cLbKS61c2l8aMrpg-^o^r+T!quB_r:p +JcC<$JcFs6mf*+^r;?BfrVHNhqY:'arq?9_rq-3]r:9mXrp]mTrpKgRrTsRM!:'OIs6'IGroX7B +!9F.>#3+V#i8EMLrnVAFgY1B7f[na+e^W*tda?IgcHa\YbK@rJaN)9=`5BI.^q[Us]Y(hd\[])V +[C!9GZ*:F7Xf\Y(Wi;qpVPU)aU7n9RT:VUDS"#k7R$a5*Q'@JqP*(ieO,f3YN/NRMM26qAL4t;5 +K7\[RJ.R3ZI=6KjH[:!`G^+FVG'8$-F96N(ErL%[E,T[oD?=ZkD#S5MC&huHBEDgYB)ZBAA,p-< +@KKtG@/aO5?N4=1>lS%.>5h\)=T;J$j;YsDl<;fho5hb&>lJ%-?Me+/@/aU4@fBm:AG]s/8LPUeDMMmFPNK0'\OHG]hPE_>tQC!u+R@9V7S=Q7CT:_dMTq\=]U]Ih;7&Ii8NYSj5]4^roOUOkiq?slKdg'mHs?@ +mfN"Knc&(\oCV\Sp&Facp\agdq>U6fqu-HjrU0Z9s,?u.~> +JcC<$JcFs6mf*+^r;?BfrVHNhqY:'arq?9_rq-3]r:9mXrp]mTrpKgRrTsRM!:'OIs6'IGroX7B +!9F.>#3+V#i8EMLrnVAFgY1B7f[na+e^W*tda?IgcHa\YbK@rJaN)9=`5BI.^q[Us]Y(hd\[])V +[C!9GZ*:F7Xf\Y(Wi;qpVPU)aU7n9RT:VUDS"#k7R$a5*Q'@JqP*(ieO,f3YN/NRMM26qAL4t;5 +K7\[RJ.R3ZI=6KjH[:!`G^+FVG'8$-F96N(ErL%[E,T[oD?=ZkD#S5MC&huHBEDgYB)ZBAA,p-< +@KKtG@/aO5?N4=1>lS%.>5h\)=T;J$j;YsDl<;fho5hb&>lJ%-?Me+/@/aU4@fBm:AG]s/8LPUeDMMmFPNK0'\OHG]hPE_>tQC!u+R@9V7S=Q7CT:_dMTq\=]U]Ih;7&Ii8NYSj5]4^roOUOkiq?slKdg'mHs?@ +mfN"Knc&(\oCV\Sp&Facp\agdq>U6fqu-HjrU0Z9s,?u.~> +JcC<$JcFs6mf*+^r;?BfrVHNhqY:'arq?9_rq-3]r:9mXrp]mTrpKgRrTsRM!:'OIs6'IGroX7B +!9F.>#3+V#i8EMLrnVAFgY1B7f[na+e^W*tda?IgcHa\YbK@rJaN)9=`5BI.^q[Us]Y(hd\[])V +[C!9GZ*:F7Xf\Y(Wi;qpVPU)aU7n9RT:VUDS"#k7R$a5*Q'@JqP*(ieO,f3YN/NRMM26qAL4t;5 +K7\[RJ.R3ZI=6KjH[:!`G^+FVG'8$-F96N(ErL%[E,T[oD?=ZkD#S5MC&huHBEDgYB)ZBAA,p-< +@KKtG@/aO5?N4=1>lS%.>5h\)=T;J$j;YsDl<;fho5hb&>lJ%-?Me+/@/aU4@fBm:AG]s/8LPUeDMMmFPNK0'\OHG]hPE_>tQC!u+R@9V7S=Q7CT:_dMTq\=]U]Ih;7&Ii8NYSj5]4^roOUOkiq?slKdg'mHs?@ +mfN"Knc&(\oCV\Sp&Facp\agdq>U6fqu-HjrU0Z9s,?u.~> +JcC<$JcFp5n,E4_r;??erVHNhqY:'arq?6^s7H<^r:9jWs7#sTs6fpSrTsRMs6BUJs60LGroO7C +jSn0Dio/kSi8KnTGX +"bM;UJ:E%II0"_Brd"TjGlDmgG'.s,F9-H'rc.sW!,qjSs)%dPrbDRMBkdQ[s(;=DrFH%@@q5LI +s'Yn8rEfV4?![D6!aAi3rE9/&s&]/"s&K(ur)dnkJdNoh4L@mn*%Ar(Hu^q+^i` +rD38dr_`YmqG[Amr`/eqrE&u#qH1raG\5raYqrb)+Arb;@HqeQ.H +rGD:HqJZ+Ij)Od5piF`&qfDXTno=ABp2U(PrcA$[s)n?brceBe!."Qis*G3&I=6QnIt3'#JqJ]/ +L&QfVLPUeDMN!LRNfT6_OcklkPa.N"Q^F/.R[]e:SXuFFTV/!PU8+N[V5:'gVZE`qri6"!!3H1% +s/uC*rilF-s0DU0s0Vg6r3lX7s1&$Ymb0%oN +bfn>WcHjh`dF$CkrmVV3f%8O+f\,!4gYCW@hVR/Ji8N\pit1;5k2tjjkiq?slg*p(mI'EAmfDqJ +rpp*\s7H<`s7ZKerV6Bfs8)ThrVZTln,@n +JcC<$JcFp5n,E4_r;??erVHNhqY:'arq?6^s7H<^r:9jWs7#sTs6fpSrTsRMs6BUJs60LGroO7C +jSn0Dio/kSi8KnTGX +"bM;UJ:E%II0"_Brd"TjGlDmgG'.s,F9-H'rc.sW!,qjSs)%dPrbDRMBkdQ[s(;=DrFH%@@q5LI +s'Yn8rEfV4?![D6!aAi3rE9/&s&]/"s&K(ur)dnkJdNoh4L@mn*%Ar(Hu^q+^i` +rD38dr_`YmqG[Amr`/eqrE&u#qH1raG\5raYqrb)+Arb;@HqeQ.H +rGD:HqJZ+Ij)Od5piF`&qfDXTno=ABp2U(PrcA$[s)n?brceBe!."Qis*G3&I=6QnIt3'#JqJ]/ +L&QfVLPUeDMN!LRNfT6_OcklkPa.N"Q^F/.R[]e:SXuFFTV/!PU8+N[V5:'gVZE`qri6"!!3H1% +s/uC*rilF-s0DU0s0Vg6r3lX7s1&$Ymb0%oN +bfn>WcHjh`dF$CkrmVV3f%8O+f\,!4gYCW@hVR/Ji8N\pit1;5k2tjjkiq?slg*p(mI'EAmfDqJ +rpp*\s7H<`s7ZKerV6Bfs8)ThrVZTln,@n +JcC<$JcFp5n,E4_r;??erVHNhqY:'arq?6^s7H<^r:9jWs7#sTs6fpSrTsRMs6BUJs60LGroO7C +jSn0Dio/kSi8KnTGX +"bM;UJ:E%II0"_Brd"TjGlDmgG'.s,F9-H'rc.sW!,qjSs)%dPrbDRMBkdQ[s(;=DrFH%@@q5LI +s'Yn8rEfV4?![D6!aAi3rE9/&s&]/"s&K(ur)dnkJdNoh4L@mn*%Ar(Hu^q+^i` +rD38dr_`YmqG[Amr`/eqrE&u#qH1raG\5raYqrb)+Arb;@HqeQ.H +rGD:HqJZ+Ij)Od5piF`&qfDXTno=ABp2U(PrcA$[s)n?brceBe!."Qis*G3&I=6QnIt3'#JqJ]/ +L&QfVLPUeDMN!LRNfT6_OcklkPa.N"Q^F/.R[]e:SXuFFTV/!PU8+N[V5:'gVZE`qri6"!!3H1% +s/uC*rilF-s0DU0s0Vg6r3lX7s1&$Ymb0%oN +bfn>WcHjh`dF$CkrmVV3f%8O+f\,!4gYCW@hVR/Ji8N\pit1;5k2tjjkiq?slg*p(mI'EAmfDqJ +rpp*\s7H<`s7ZKerV6Bfs8)ThrVZTln,@n +JcC<$JcFp5mf*+^r;??erVHNhqY:'arq?6^rq-3]r:9mXrp]mTrpKgRrTjUOlK\?4!pJh1roOUM +jQ,@]io8qTi8lS%.>5h\)=T;J$5hb&>l@t-?Me+.@/aU4@fBm:AG]s/8LPUeD +MMmFPNK0'\OHG]iPa.N"Q^F/.R[]e:SXuFFTV/!PU8+N[V5C,fVl6Sori-""XT#@%Y5b^)YlD!. +ZMh-0[/[Q4[f +JcC<$JcFp5mf*+^r;??erVHNhqY:'arq?6^rq-3]r:9mXrp]mTrpKgRrTjUOlK\?4!pJh1roOUM +jQ,@]io8qTi8lS%.>5h\)=T;J$5hb&>l@t-?Me+.@/aU4@fBm:AG]s/8LPUeD +MMmFPNK0'\OHG]iPa.N"Q^F/.R[]e:SXuFFTV/!PU8+N[V5C,fVl6Sori-""XT#@%Y5b^)YlD!. +ZMh-0[/[Q4[f +JcC<$JcFp5mf*+^r;??erVHNhqY:'arq?6^rq-3]r:9mXrp]mTrpKgRrTjUOlK\?4!pJh1roOUM +jQ,@]io8qTi8lS%.>5h\)=T;J$5hb&>l@t-?Me+.@/aU4@fBm:AG]s/8LPUeD +MMmFPNK0'\OHG]iPa.N"Q^F/.R[]e:SXuFFTV/!PU8+N[V5C,fVl6Sori-""XT#@%Y5b^)YlD!. +ZMh-0[/[Q4[f +JcC<$JcFm4mf*+^r;??erVHNhqY:'arq?6^rq-3]r:9jWs7#sTs6fpSrTsRMs6BUJs6'IGroOUM +jQ,@]io8qTi8eN +raPn9!+>b4!a]/f +qG@/grDNMkrD`brqH!SsrE/o!rEB/(qHX#*rEfA.ra>_6qdTP7rabq>db0%oNbfn?2c2l8< +rm:bpe,Ii(e^i@(f\+s3g=tE^h$W#ri8ESRioB([jo4BHkNM0plK[^7liHMArpKpXnaZVL!qZ'V +rUg6cp\4U\s7uZjqtp?irVc9cJcCN*J,~> +JcC<$JcFm4mf*+^r;??erVHNhqY:'arq?6^rq-3]r:9jWs7#sTs6fpSrTsRMs6BUJs6'IGroOUM +jQ,@]io8qTi8eN +raPn9!+>b4!a]/f +qG@/grDNMkrD`brqH!SsrE/o!rEB/(qHX#*rEfA.ra>_6qdTP7rabq>db0%oNbfn?2c2l8< +rm:bpe,Ii(e^i@(f\+s3g=tE^h$W#ri8ESRioB([jo4BHkNM0plK[^7liHMArpKpXnaZVL!qZ'V +rUg6cp\4U\s7uZjqtp?irVc9cJcCN*J,~> +JcC<$JcFm4mf*+^r;??erVHNhqY:'arq?6^rq-3]r:9jWs7#sTs6fpSrTsRMs6BUJs6'IGroOUM +jQ,@]io8qTi8eN +raPn9!+>b4!a]/f +qG@/grDNMkrD`brqH!SsrE/o!rEB/(qHX#*rEfA.ra>_6qdTP7rabq>db0%oNbfn?2c2l8< +rm:bpe,Ii(e^i@(f\+s3g=tE^h$W#ri8ESRioB([jo4BHkNM0plK[^7liHMArpKpXnaZVL!qZ'V +rUg6cp\4U\s7uZjqtp?irVc9cJcCN*J,~> +JcC<$JcFj3mf*+^r;??erVHKgqY:'arq?6^rq-3]r:9mXrp]mTs6fmRrp9[Ns6BUJs6'IGroX7B +$0:.,io8qTi86%k*=oVV(=8c2!sJi;uTbqP_V(?2\+,?iFI4@JaO5A,^$9AcHBABDZBAC&MfCC]/)J +D=h`>Ds_N.EVXYMF4k[3F89k;EW'qWF8U.ZFT?U`GQ2mfH2`+FH[L3hI=?WpJ:N3&K7ei1Knb>; +Ll$tGMiaMrpg-^ +o^r.Us7ZKerV6Bfs8)WirVZWmo)=4?L&ZZ~> +JcC<$JcFj3mf*+^r;??erVHKgqY:'arq?6^rq-3]r:9mXrp]mTs6fmRrp9[Ns6BUJs6'IGroX7B +$0:.,io8qTi86%k*=oVV(=8c2!sJi;uTbqP_V(?2\+,?iFI4@JaO5A,^$9AcHBABDZBAC&MfCC]/)J +D=h`>Ds_N.EVXYMF4k[3F89k;EW'qWF8U.ZFT?U`GQ2mfH2`+FH[L3hI=?WpJ:N3&K7ei1Knb>; +Ll$tGMiaMrpg-^ +o^r.Us7ZKerV6Bfs8)WirVZWmo)=4?L&ZZ~> +JcC<$JcFj3mf*+^r;??erVHKgqY:'arq?6^rq-3]r:9mXrp]mTs6fmRrp9[Ns6BUJs6'IGroX7B +$0:.,io8qTi86%k*=oVV(=8c2!sJi;uTbqP_V(?2\+,?iFI4@JaO5A,^$9AcHBABDZBAC&MfCC]/)J +D=h`>Ds_N.EVXYMF4k[3F89k;EW'qWF8U.ZFT?U`GQ2mfH2`+FH[L3hI=?WpJ:N3&K7ei1Knb>; +Ll$tGMiaMrpg-^ +o^r.Us7ZKerV6Bfs8)WirVZWmo)=4?L&ZZ~> +JcC<$JcFj3mJd"]r;??erVHKgqY:'arq?6^rq-3]r:9jWs7#sTs6fpSrTjUOlK\B5s6'IGroX7B +$0:.,io8qTi8Q7n*=oVV(=8c2"sJi;uTbpP_V'?2e1,?iFI4@JaO5A,g*:Ac?<@BDZBAC&VlCC]/)I +D=_Z9DsVH1EVXYMF5:s6F89k>EVskVF8U.ZFoQXaGQ2mfH2`-iHN8HmI7/O6J:N3%JqJ]/Knb>; +Ll$tGMiStD[LTq\9VUnjiaVl-JmWN)u!XK8P+Y-+u-YlCs. +ZMh-0ZiIN4[f +JcC<$JcFj3mJd"]r;??erVHKgqY:'arq?6^rq-3]r:9jWs7#sTs6fpSrTjUOlK\B5s6'IGroX7B +$0:.,io8qTi8Q7n*=oVV(=8c2"sJi;uTbpP_V'?2e1,?iFI4@JaO5A,g*:Ac?<@BDZBAC&VlCC]/)I +D=_Z9DsVH1EVXYMF5:s6F89k>EVskVF8U.ZFoQXaGQ2mfH2`-iHN8HmI7/O6J:N3%JqJ]/Knb>; +Ll$tGMiStD[LTq\9VUnjiaVl-JmWN)u!XK8P+Y-+u-YlCs. +ZMh-0ZiIN4[f +JcC<$JcFj3mJd"]r;??erVHKgqY:'arq?6^rq-3]r:9jWs7#sTs6fpSrTjUOlK\B5s6'IGroX7B +$0:.,io8qTi8Q7n*=oVV(=8c2"sJi;uTbpP_V'?2e1,?iFI4@JaO5A,g*:Ac?<@BDZBAC&VlCC]/)I +D=_Z9DsVH1EVXYMF5:s6F89k>EVskVF8U.ZFoQXaGQ2mfH2`-iHN8HmI7/O6J:N3%JqJ]/Knb>; +Ll$tGMiStD[LTq\9VUnjiaVl-JmWN)u!XK8P+Y-+u-YlCs. +ZMh-0ZiIN4[f +JcC<$JcFg2mf*(]r;??erVHKgqY:'arV$-]rq-6^qssdWrp]mTs6fpSrTsRM!:'OIH0FGSk2tde +jQ#:[io/hRhqm2FgtUT;g=Y$/f%&:"e'cXkcd'h\bfe/NaN2E@`Pf[2_8*h"]tD"i\[f5Z[^EKK +Za$a=YHG"/X/`2!W2HMhUnjc[TqS*MSt2C@S!ob4R$X,(Q'@JqP*(ieO,f3YN/NRMM26rdL'iWf +K7ec,JUi9#If=`rI!bj=#C1Q=GB\4RFoHL_Er^7[E<:)tDuOVUD/=%fCBA6bC&VcIB4bcTAcH9@ +A,]s;@K0a7?NOP>?2\"0>?Y5/=oVV(=8Z,!*i^:\RWP:&.KW9B8_A9DhKY:&[od +:\moe;>jDh;uTbpP_V'?2e1,?iFI4@JaO5A,^$:Ac?<@BDZB@C&VlDC]&#H +D=DH/Dt.f8EVa_NF5V08F89kAEVskUF8U.[FoHR`GQ2pfH2`*jH[Pg@!IfOtJ2Dh/K7ei2L5(J> +M2@+JN/WaVO,oBbP*2&pQ'Rc(R$jD4S"-%@StD[LTq\A^&GbE^]2+L_>V7N_uI[R`W*pXa8O'\ai_d*b6#o4c2Puhcd;[= +("1R[eC<%!f%8O+f\,!4gYCT?h;7&ghuVfrro4%?jo4BCkNMp0!UB"MliHMArpTmV!:g'Zs766_ +rUp3as7cKes7uZjqtpBjr;H6dJcCE'J,~> +JcC<$JcFg2mf*(]r;??erVHKgqY:'arV$-]rq-6^qssdWrp]mTs6fpSrTsRM!:'OIH0FGSk2tde +jQ#:[io/hRhqm2FgtUT;g=Y$/f%&:"e'cXkcd'h\bfe/NaN2E@`Pf[2_8*h"]tD"i\[f5Z[^EKK +Za$a=YHG"/X/`2!W2HMhUnjc[TqS*MSt2C@S!ob4R$X,(Q'@JqP*(ieO,f3YN/NRMM26rdL'iWf +K7ec,JUi9#If=`rI!bj=#C1Q=GB\4RFoHL_Er^7[E<:)tDuOVUD/=%fCBA6bC&VcIB4bcTAcH9@ +A,]s;@K0a7?NOP>?2\"0>?Y5/=oVV(=8Z,!*i^:\RWP:&.KW9B8_A9DhKY:&[od +:\moe;>jDh;uTbpP_V'?2e1,?iFI4@JaO5A,^$:Ac?<@BDZB@C&VlDC]&#H +D=DH/Dt.f8EVa_NF5V08F89kAEVskUF8U.[FoHR`GQ2pfH2`*jH[Pg@!IfOtJ2Dh/K7ei2L5(J> +M2@+JN/WaVO,oBbP*2&pQ'Rc(R$jD4S"-%@StD[LTq\A^&GbE^]2+L_>V7N_uI[R`W*pXa8O'\ai_d*b6#o4c2Puhcd;[= +("1R[eC<%!f%8O+f\,!4gYCT?h;7&ghuVfrro4%?jo4BCkNMp0!UB"MliHMArpTmV!:g'Zs766_ +rUp3as7cKes7uZjqtpBjr;H6dJcCE'J,~> +JcC<$JcFg2mf*(]r;??erVHKgqY:'arV$-]rq-6^qssdWrp]mTs6fpSrTsRM!:'OIH0FGSk2tde +jQ#:[io/hRhqm2FgtUT;g=Y$/f%&:"e'cXkcd'h\bfe/NaN2E@`Pf[2_8*h"]tD"i\[f5Z[^EKK +Za$a=YHG"/X/`2!W2HMhUnjc[TqS*MSt2C@S!ob4R$X,(Q'@JqP*(ieO,f3YN/NRMM26rdL'iWf +K7ec,JUi9#If=`rI!bj=#C1Q=GB\4RFoHL_Er^7[E<:)tDuOVUD/=%fCBA6bC&VcIB4bcTAcH9@ +A,]s;@K0a7?NOP>?2\"0>?Y5/=oVV(=8Z,!*i^:\RWP:&.KW9B8_A9DhKY:&[od +:\moe;>jDh;uTbpP_V'?2e1,?iFI4@JaO5A,^$:Ac?<@BDZB@C&VlDC]&#H +D=DH/Dt.f8EVa_NF5V08F89kAEVskUF8U.[FoHR`GQ2pfH2`*jH[Pg@!IfOtJ2Dh/K7ei2L5(J> +M2@+JN/WaVO,oBbP*2&pQ'Rc(R$jD4S"-%@StD[LTq\A^&GbE^]2+L_>V7N_uI[R`W*pXa8O'\ai_d*b6#o4c2Puhcd;[= +("1R[eC<%!f%8O+f\,!4gYCT?h;7&ghuVfrro4%?jo4BCkNMp0!UB"MliHMArpTmV!:g'Zs766_ +rUp3as7cKes7uZjqtpBjr;H6dJcCE'J,~> +JcC<$JcFd1mJd"]r;??erVHKgqY:$`rq?6^rq-3]r:9jWs7#sTs6fpSrp9[Ns6BUJId#tXk2tde +jQ#:[io/hRhqm2FgtUQ:g"=p.f%&:"e'cXjcd'h\bfe/NaN2B?`PfX1_8*h"]tD"h\[f5Z[^EKK +Za$a=YHG"/X/`2!W2HMhUnjc[TqS-OSt2C@S!ob4R$X,(Q'@JqP*(ieO,f3YN/NRNM2@%DL5(D8 +rdt6'Jc:0#It%BF!IT7nH3&;9rceBc!-S9_!crC&rc&!YDf>Vm!GuZPC]A,LC&M]HB4bcTAHHCP +A,]p=@:3LB?iOI4?2e+/>Q7n*=oVV(=8Z,!!c\:\[]R:&.KW9Bo.F9DhKY:&Rid +:\did;>sJi;uK\pPVP'?2\++?iFI4@JaO5A,g*:Ac?<@BDZBAC&MfCC]&#H +D=)6(DtJ#=EVa_NF5qB:F8'_FEVa_SF8L(ZFoQX`GQ2pfH2`*jH[Pg@6[jN7J:N3&K7ei2Knb>; +Ll$tGN/WaVO,oBbP*2#nQ'Rc(R$jD4S"-%@StD[LTq\V7N_uI[R`W*sXa8X0[aT0K^b6Q89c-FV\cd;[= +0@J=ueC<%!f%8O+f\,!4gY:N>h;7#Gi8ESRioB([jlPXekNM-ol0@U#m-O-,mf)YVnF?&JncJFT +o_nFap@n=Zq#C0iqYU0gr;HTbrdk*&s*t~> +JcC<$JcFd1mJd"]r;??erVHKgqY:$`rq?6^rq-3]r:9jWs7#sTs6fpSrp9[Ns6BUJId#tXk2tde +jQ#:[io/hRhqm2FgtUQ:g"=p.f%&:"e'cXjcd'h\bfe/NaN2B?`PfX1_8*h"]tD"h\[f5Z[^EKK +Za$a=YHG"/X/`2!W2HMhUnjc[TqS-OSt2C@S!ob4R$X,(Q'@JqP*(ieO,f3YN/NRNM2@%DL5(D8 +rdt6'Jc:0#It%BF!IT7nH3&;9rceBc!-S9_!crC&rc&!YDf>Vm!GuZPC]A,LC&M]HB4bcTAHHCP +A,]p=@:3LB?iOI4?2e+/>Q7n*=oVV(=8Z,!!c\:\[]R:&.KW9Bo.F9DhKY:&Rid +:\did;>sJi;uK\pPVP'?2\++?iFI4@JaO5A,g*:Ac?<@BDZBAC&MfCC]&#H +D=)6(DtJ#=EVa_NF5qB:F8'_FEVa_SF8L(ZFoQX`GQ2pfH2`*jH[Pg@6[jN7J:N3&K7ei2Knb>; +Ll$tGN/WaVO,oBbP*2#nQ'Rc(R$jD4S"-%@StD[LTq\V7N_uI[R`W*sXa8X0[aT0K^b6Q89c-FV\cd;[= +0@J=ueC<%!f%8O+f\,!4gY:N>h;7#Gi8ESRioB([jlPXekNM-ol0@U#m-O-,mf)YVnF?&JncJFT +o_nFap@n=Zq#C0iqYU0gr;HTbrdk*&s*t~> +JcC<$JcFd1mJd"]r;??erVHKgqY:$`rq?6^rq-3]r:9jWs7#sTs6fpSrp9[Ns6BUJId#tXk2tde +jQ#:[io/hRhqm2FgtUQ:g"=p.f%&:"e'cXjcd'h\bfe/NaN2B?`PfX1_8*h"]tD"h\[f5Z[^EKK +Za$a=YHG"/X/`2!W2HMhUnjc[TqS-OSt2C@S!ob4R$X,(Q'@JqP*(ieO,f3YN/NRNM2@%DL5(D8 +rdt6'Jc:0#It%BF!IT7nH3&;9rceBc!-S9_!crC&rc&!YDf>Vm!GuZPC]A,LC&M]HB4bcTAHHCP +A,]p=@:3LB?iOI4?2e+/>Q7n*=oVV(=8Z,!!c\:\[]R:&.KW9Bo.F9DhKY:&Rid +:\did;>sJi;uK\pPVP'?2\++?iFI4@JaO5A,g*:Ac?<@BDZBAC&MfCC]&#H +D=)6(DtJ#=EVa_NF5qB:F8'_FEVa_SF8L(ZFoQX`GQ2pfH2`*jH[Pg@6[jN7J:N3&K7ei2Knb>; +Ll$tGN/WaVO,oBbP*2#nQ'Rc(R$jD4S"-%@StD[LTq\V7N_uI[R`W*sXa8X0[aT0K^b6Q89c-FV\cd;[= +0@J=ueC<%!f%8O+f\,!4gY:N>h;7#Gi8ESRioB([jlPXekNM-ol0@U#m-O-,mf)YVnF?&JncJFT +o_nFap@n=Zq#C0iqYU0gr;HTbrdk*&s*t~> +JcC<$JcFa0mf*(]r;?`P]R0_8*h"]tCtg\[f5Y[^EKK +Za$a=YHG"/X/`2!W2HPiUnjc[TqS-OSt;LCS"#k7R$X,(Q'@JqP*(lgO,o<\N/W[PM2@%Dre;/A +KS+o/JUr?%IsuipI=-BgH?sj^GlDmlG'.qLFE;MDrc.sW!,qjS!c;airbDRMBkdQ[!bZ+Wrac.A +@q5LIs'Yn8rEfV4?![G7s',M,rE9/&s&],!r`/qsqG[>jr)*&^pJ:QZnP/gQoh4pLpIkBWpeC]^ +rD38dr_`VlqG[AmrDi\prE&r"q-!Z"rEK)&rE]D/qHs50raG\5raYqp2f87rH%gWs)n?brHJ9ds*=Ti7sfW2I=6QnIt3'#JV&N,KS>/8LPUeD +MMmFPNK0'\OcklkPa.N"Q^F20S"#q=St;RITqS3UUnjiaVl-JmWiE,$XKAV-YPtd+YlM*/ZN@MA +[JmW7\,Wu:\c98@]DT>A^&PhE^]2+L_>M1M_uI[R`W*sXa8O'\ai_d*bQ#cdc2Q#gcN)>kdJqVp +e,Ihte^j`O!SH*)g&]s`rnRV3hu;O7iSsjs!T`AAjoOZ/rojIKli-5PmI'EAmfN"Knc&(\oCV\S +p&Facp\jmdq>^ +JcC<$JcFa0mf*(]r;?`P]R0_8*h"]tCtg\[f5Y[^EKK +Za$a=YHG"/X/`2!W2HPiUnjc[TqS-OSt;LCS"#k7R$X,(Q'@JqP*(lgO,o<\N/W[PM2@%Dre;/A +KS+o/JUr?%IsuipI=-BgH?sj^GlDmlG'.qLFE;MDrc.sW!,qjS!c;airbDRMBkdQ[!bZ+Wrac.A +@q5LIs'Yn8rEfV4?![G7s',M,rE9/&s&],!r`/qsqG[>jr)*&^pJ:QZnP/gQoh4pLpIkBWpeC]^ +rD38dr_`VlqG[AmrDi\prE&r"q-!Z"rEK)&rE]D/qHs50raG\5raYqp2f87rH%gWs)n?brHJ9ds*=Ti7sfW2I=6QnIt3'#JV&N,KS>/8LPUeD +MMmFPNK0'\OcklkPa.N"Q^F20S"#q=St;RITqS3UUnjiaVl-JmWiE,$XKAV-YPtd+YlM*/ZN@MA +[JmW7\,Wu:\c98@]DT>A^&PhE^]2+L_>M1M_uI[R`W*sXa8O'\ai_d*bQ#cdc2Q#gcN)>kdJqVp +e,Ihte^j`O!SH*)g&]s`rnRV3hu;O7iSsjs!T`AAjoOZ/rojIKli-5PmI'EAmfN"Knc&(\oCV\S +p&Facp\jmdq>^ +JcC<$JcFa0mf*(]r;?`P]R0_8*h"]tCtg\[f5Y[^EKK +Za$a=YHG"/X/`2!W2HPiUnjc[TqS-OSt;LCS"#k7R$X,(Q'@JqP*(lgO,o<\N/W[PM2@%Dre;/A +KS+o/JUr?%IsuipI=-BgH?sj^GlDmlG'.qLFE;MDrc.sW!,qjS!c;airbDRMBkdQ[!bZ+Wrac.A +@q5LIs'Yn8rEfV4?![G7s',M,rE9/&s&],!r`/qsqG[>jr)*&^pJ:QZnP/gQoh4pLpIkBWpeC]^ +rD38dr_`VlqG[AmrDi\prE&r"q-!Z"rEK)&rE]D/qHs50raG\5raYqp2f87rH%gWs)n?brHJ9ds*=Ti7sfW2I=6QnIt3'#JV&N,KS>/8LPUeD +MMmFPNK0'\OcklkPa.N"Q^F20S"#q=St;RITqS3UUnjiaVl-JmWiE,$XKAV-YPtd+YlM*/ZN@MA +[JmW7\,Wu:\c98@]DT>A^&PhE^]2+L_>M1M_uI[R`W*sXa8O'\ai_d*bQ#cdc2Q#gcN)>kdJqVp +e,Ihte^j`O!SH*)g&]s`rnRV3hu;O7iSsjs!T`AAjoOZ/rojIKli-5PmI'EAmfN"Knc&(\oCV\S +p&Facp\jmdq>^ +JcC<$JcFa0mJct\r;?`P]R0_8!b!]tCtg\[f5Y[^EKK +Za$a=YHG"0X/`2!W2HPjV50l\TqS-OSt;LCS"#k7R$a5+Q'IStP*1rhO,o<\N/W[PMM[1GLPCP; +KS4u1Jqlr`/bprE&r"q-!Z"rEK)&rE]A.qd9;0raG\5raYqrb)+ArFu7GphTeDqJFo' +oPaPEo5XSHpiGV?olKD=qfDUUrcS6arHJ9ds*=Ti!df/8LPUeDMMmFP +NK0'\OHG]iPa.N"Q^F/.R[]h +JcC<$JcFa0mJct\r;?`P]R0_8!b!]tCtg\[f5Y[^EKK +Za$a=YHG"0X/`2!W2HPjV50l\TqS-OSt;LCS"#k7R$a5+Q'IStP*1rhO,o<\N/W[PMM[1GLPCP; +KS4u1Jqlr`/bprE&r"q-!Z"rEK)&rE]A.qd9;0raG\5raYqrb)+ArFu7GphTeDqJFo' +oPaPEo5XSHpiGV?olKD=qfDUUrcS6arHJ9ds*=Ti!df/8LPUeDMMmFP +NK0'\OHG]iPa.N"Q^F/.R[]h +JcC<$JcFa0mJct\r;?`P]R0_8!b!]tCtg\[f5Y[^EKK +Za$a=YHG"0X/`2!W2HPjV50l\TqS-OSt;LCS"#k7R$a5+Q'IStP*1rhO,o<\N/W[PMM[1GLPCP; +KS4u1Jqlr`/bprE&r"q-!Z"rEK)&rE]A.qd9;0raG\5raYqrb)+ArFu7GphTeDqJFo' +oPaPEo5XSHpiGV?olKD=qfDUUrcS6arHJ9ds*=Ti!df/8LPUeDMMmFP +NK0'\OHG]iPa.N"Q^F/.R[]h +JcC<$JcF[.mf*(]r;?`5BI/^q[Xu]tCtg\[f5Y[^EKK +Za$a=YHG"0X/`2!W2HPjV50o^TqS-OSt;LCS"#k7R$a5+Q'IStP*1rhrf7PLNJrgSMM[1GLPLV= +KnTGX$\Eq[J:E&tI=6KjHiAlS%.>5_V'=T;J#j;Yj>k<;fhn5VV#>lJ%-?M\%.@/aU3@fBm:AG]s;B)ZH?B`;`ECA;TBD#%qu +DYA#FE:\)GEqaY=FRjMEEqsePFT6L_G5ZXbGlN'gHN/
  • M2@+J +N/`jYO-#KeP*;,qQC!u+R@9V7SXuFFTV8'RUSO]^VPg>jWN)u!XKAV-YHP17Z*L[AZa@*IrjMj9 +s1&'=s186BrOi0Ds1\EGs1nWMr5/KOs2=iSs2P)ZrQ,#\s2t>as31MfrltSkd*Vd>!n,QHrmV2' +f%/I)f\"mVg&]s`rnRV3hu;O7iSsjs!T`AAjoOZ/roj[Qlg*p(mHs?@n,MkWnc&+Zo)SF]p&Fac +p\jmeq>U6fqu-HkrUTr=s+LE&~> +JcC<$JcF[.mf*(]r;?`5BI/^q[Xu]tCtg\[f5Y[^EKK +Za$a=YHG"0X/`2!W2HPjV50o^TqS-OSt;LCS"#k7R$a5+Q'IStP*1rhrf7PLNJrgSMM[1GLPLV= +KnTGX$\Eq[J:E&tI=6KjHiAlS%.>5_V'=T;J#j;Yj>k<;fhn5VV#>lJ%-?M\%.@/aU3@fBm:AG]s;B)ZH?B`;`ECA;TBD#%qu +DYA#FE:\)GEqaY=FRjMEEqsePFT6L_G5ZXbGlN'gHN/
  • M2@+J +N/`jYO-#KeP*;,qQC!u+R@9V7SXuFFTV8'RUSO]^VPg>jWN)u!XKAV-YHP17Z*L[AZa@*IrjMj9 +s1&'=s186BrOi0Ds1\EGs1nWMr5/KOs2=iSs2P)ZrQ,#\s2t>as31MfrltSkd*Vd>!n,QHrmV2' +f%/I)f\"mVg&]s`rnRV3hu;O7iSsjs!T`AAjoOZ/roj[Qlg*p(mHs?@n,MkWnc&+Zo)SF]p&Fac +p\jmeq>U6fqu-HkrUTr=s+LE&~> +JcC<$JcF[.mf*(]r;?`5BI/^q[Xu]tCtg\[f5Y[^EKK +Za$a=YHG"0X/`2!W2HPjV50o^TqS-OSt;LCS"#k7R$a5+Q'IStP*1rhrf7PLNJrgSMM[1GLPLV= +KnTGX$\Eq[J:E&tI=6KjHiAlS%.>5_V'=T;J#j;Yj>k<;fhn5VV#>lJ%-?M\%.@/aU3@fBm:AG]s;B)ZH?B`;`ECA;TBD#%qu +DYA#FE:\)GEqaY=FRjMEEqsePFT6L_G5ZXbGlN'gHN/
  • M2@+J +N/`jYO-#KeP*;,qQC!u+R@9V7SXuFFTV8'RUSO]^VPg>jWN)u!XKAV-YHP17Z*L[AZa@*IrjMj9 +s1&'=s186BrOi0Ds1\EGs1nWMr5/KOs2=iSs2P)ZrQ,#\s2t>as31MfrltSkd*Vd>!n,QHrmV2' +f%/I)f\"mVg&]s`rnRV3hu;O7iSsjs!T`AAjoOZ/roj[Qlg*p(mHs?@n,MkWnc&+Zo)SF]p&Fac +p\jmeq>U6fqu-HkrUTr=s+LE&~> +JcC<$JcFX-mf*(]qu$6dr;-Bfq=ss`rV$-]rq-6^r:9jWs7$!Us6fpSrp9[N!:'RJs6'dPk2tde +jQ#:[iVqbbhqm2FgtUQ:g"=p-e^W*tda?IgcHa\YbK@rJaN)9=`5BI.^q[Xu]Y(kf\[f2X[^EKK +ZE^X +KnY24K7\Z*J:N,uIXQWls*Ocls*4Thrc\TjF`heJF)uC$E<:)tDuOVTD/B2es(VOJrb2=E!+u4A +s'u+>raPn9s'Yh5s'>\2rETA,s'#A(s&f8%r)Wbrr`&Ykqbm5enPK$WqG-WVp.Y'Npe:BUrD*;e +q,%&frDNJjrD`brq,[GqrE/htrEB,'q-\5qdTP7s()";Ll$tGMiM1M_u@UQ`W!mWa8O*ZaoBN^b6#o4c2Q#gci;Akd/qbFe,Ii%e^i=' +f@\a/rn7D-h#?+AhV[5Ki8N\Tj5]4]jlY^gkNMp0!UB"MliQSBmf)YVnF?&JncJFTo_nI_pAamc +q#C0hqYU0hr;?Nbrdk*%s*t~> +JcC<$JcFX-mf*(]qu$6dr;-Bfq=ss`rV$-]rq-6^r:9jWs7$!Us6fpSrp9[N!:'RJs6'dPk2tde +jQ#:[iVqbbhqm2FgtUQ:g"=p-e^W*tda?IgcHa\YbK@rJaN)9=`5BI.^q[Xu]Y(kf\[f2X[^EKK +ZE^X +KnY24K7\Z*J:N,uIXQWls*Ocls*4Thrc\TjF`heJF)uC$E<:)tDuOVTD/B2es(VOJrb2=E!+u4A +s'u+>raPn9s'Yh5s'>\2rETA,s'#A(s&f8%r)Wbrr`&Ykqbm5enPK$WqG-WVp.Y'Npe:BUrD*;e +q,%&frDNJjrD`brq,[GqrE/htrEB,'q-\5qdTP7s()";Ll$tGMiM1M_u@UQ`W!mWa8O*ZaoBN^b6#o4c2Q#gci;Akd/qbFe,Ii%e^i=' +f@\a/rn7D-h#?+AhV[5Ki8N\Tj5]4]jlY^gkNMp0!UB"MliQSBmf)YVnF?&JncJFTo_nI_pAamc +q#C0hqYU0hr;?Nbrdk*%s*t~> +JcC<$JcFX-mf*(]qu$6dr;-Bfq=ss`rV$-]rq-6^r:9jWs7$!Us6fpSrp9[N!:'RJs6'dPk2tde +jQ#:[iVqbbhqm2FgtUQ:g"=p-e^W*tda?IgcHa\YbK@rJaN)9=`5BI.^q[Xu]Y(kf\[f2X[^EKK +ZE^X +KnY24K7\Z*J:N,uIXQWls*Ocls*4Thrc\TjF`heJF)uC$E<:)tDuOVTD/B2es(VOJrb2=E!+u4A +s'u+>raPn9s'Yh5s'>\2rETA,s'#A(s&f8%r)Wbrr`&Ykqbm5enPK$WqG-WVp.Y'Npe:BUrD*;e +q,%&frDNJjrD`brq,[GqrE/htrEB,'q-\5qdTP7s()";Ll$tGMiM1M_u@UQ`W!mWa8O*ZaoBN^b6#o4c2Q#gci;Akd/qbFe,Ii%e^i=' +f@\a/rn7D-h#?+AhV[5Ki8N\Tj5]4]jlY^gkNMp0!UB"MliQSBmf)YVnF?&JncJFTo_nI_pAamc +q#C0hqYU0hr;?Nbrdk*%s*t~> +JcC<$JcFU,mJd"]qu$3crVHKgq=sp_rq?6^rq-3]r:9mXs7$!Us6fpSrp9[N!:'RJs6'dPk2tde +jQ#:[iVqbChqm2FgtUQ:g"4j,e^W*tda?FfcHa\YbK@rJaMu3<`5BI.^q[Xu]Y(kf\[f2X[^EKK +Za$a=YHG"0XK/A#W2HPjV50o^U7n9RT:VXFS=?":R@'A.QBd`"PEM)kOT(:NNfB!VMi*@JLkph@ +L4t<[K)pRTrdY$!If=`rI!bj=!dT$8rc\BdFoHIaF)l=#E<1#srbhaQ!,VXM!buF`rb)@GAnM$R +!b>eNraGq;?srt@s'G_2rETA,s'#A(s&f8%qc<\rrD`JhqGR,dnkf0YqbH]Vj@o8Ar(d2dqG@,f +r_iSkrD`_qq,[GqrE/htrEB,'q--ra>_6qdTP7rabn;rau.Bqe5qBrG)+CqJ>kBdr+u" +qf)1IqJu@Pj)j[0olU.Trc\6arcnHgrd+Tk!.=co5^n34J:N3&JqJ]/Knb>;Ll$tGMi3S"-%@StD^MU8+N[V5C/gW2ZesX/rG*Y-7i/#-kJ?Za@*IrjDm;\@DOKs186B +rk/9Es1\EGs1nWMrPJQOs2=iSs2P&YrQ,#\s2t;`s31Mfrm(Pi!7:\l!n,QHrmV2'f%/I)f\"mV +g'?BfgtgfChV\=j!TE&;irS6&roOIKkih9qlK[^7liHMArpTmV!:g$Y!qZ'Vrq6 +JcC<$JcFU,mJd"]qu$3crVHKgq=sp_rq?6^rq-3]r:9mXs7$!Us6fpSrp9[N!:'RJs6'dPk2tde +jQ#:[iVqbChqm2FgtUQ:g"4j,e^W*tda?FfcHa\YbK@rJaMu3<`5BI.^q[Xu]Y(kf\[f2X[^EKK +Za$a=YHG"0XK/A#W2HPjV50o^U7n9RT:VXFS=?":R@'A.QBd`"PEM)kOT(:NNfB!VMi*@JLkph@ +L4t<[K)pRTrdY$!If=`rI!bj=!dT$8rc\BdFoHIaF)l=#E<1#srbhaQ!,VXM!buF`rb)@GAnM$R +!b>eNraGq;?srt@s'G_2rETA,s'#A(s&f8%qc<\rrD`JhqGR,dnkf0YqbH]Vj@o8Ar(d2dqG@,f +r_iSkrD`_qq,[GqrE/htrEB,'q--ra>_6qdTP7rabn;rau.Bqe5qBrG)+CqJ>kBdr+u" +qf)1IqJu@Pj)j[0olU.Trc\6arcnHgrd+Tk!.=co5^n34J:N3&JqJ]/Knb>;Ll$tGMi3S"-%@StD^MU8+N[V5C/gW2ZesX/rG*Y-7i/#-kJ?Za@*IrjDm;\@DOKs186B +rk/9Es1\EGs1nWMrPJQOs2=iSs2P&YrQ,#\s2t;`s31Mfrm(Pi!7:\l!n,QHrmV2'f%/I)f\"mV +g'?BfgtgfChV\=j!TE&;irS6&roOIKkih9qlK[^7liHMArpTmV!:g$Y!qZ'Vrq6 +JcC<$JcFU,mJd"]qu$3crVHKgq=sp_rq?6^rq-3]r:9mXs7$!Us6fpSrp9[N!:'RJs6'dPk2tde +jQ#:[iVqbChqm2FgtUQ:g"4j,e^W*tda?FfcHa\YbK@rJaMu3<`5BI.^q[Xu]Y(kf\[f2X[^EKK +Za$a=YHG"0XK/A#W2HPjV50o^U7n9RT:VXFS=?":R@'A.QBd`"PEM)kOT(:NNfB!VMi*@JLkph@ +L4t<[K)pRTrdY$!If=`rI!bj=!dT$8rc\BdFoHIaF)l=#E<1#srbhaQ!,VXM!buF`rb)@GAnM$R +!b>eNraGq;?srt@s'G_2rETA,s'#A(s&f8%qc<\rrD`JhqGR,dnkf0YqbH]Vj@o8Ar(d2dqG@,f +r_iSkrD`_qq,[GqrE/htrEB,'q--ra>_6qdTP7rabn;rau.Bqe5qBrG)+CqJ>kBdr+u" +qf)1IqJu@Pj)j[0olU.Trc\6arcnHgrd+Tk!.=co5^n34J:N3&JqJ]/Knb>;Ll$tGMi3S"-%@StD^MU8+N[V5C/gW2ZesX/rG*Y-7i/#-kJ?Za@*IrjDm;\@DOKs186B +rk/9Es1\EGs1nWMrPJQOs2=iSs2P&YrQ,#\s2t;`s31Mfrm(Pi!7:\l!n,QHrmV2'f%/I)f\"mV +g'?BfgtgfChV\=j!TE&;irS6&roOIKkih9qlK[^7liHMArpTmV!:g$Y!qZ'Vrq6 +JcC<$JcFR+mJct\r;?raPn9!+>b4s'>\2rETA,s'#>'s&f8%qc-ra>_6qdTP7rabn;rau.Bqe5qBrG)(BqJ>P9g2?b* +qf)4Jqf;FPa)q9&rc\3`s*4QhrHeKj!.=cos*b9(J:N3%JqJ]/L&QflLPUeDMMmFQNfT6_Ocklk +Pa.Q$R$a;1S"-%@StD[LTqeEZV5C/gW2ZesX/rG*Y-5(6Z*CU@Za@-J[^NZS\Gj&=])TDA]`5\F +^AYhH_#M7K_Z%IQ`;IUS`r=$WaSs<]b5KN`bl>recMu5jd/MGmdK%bpe-FOTf%8O+f\-8X!o)Mc +rnRV3hu;OBiSrkWj5f=`k2tjikl0fOlKdd&m-X3.rpTmV!:g'Zs7?9_rq6 +JcC<$JcFR+mJct\r;?raPn9!+>b4s'>\2rETA,s'#>'s&f8%qc-ra>_6qdTP7rabn;rau.Bqe5qBrG)(BqJ>P9g2?b* +qf)4Jqf;FPa)q9&rc\3`s*4QhrHeKj!.=cos*b9(J:N3%JqJ]/L&QflLPUeDMMmFQNfT6_Ocklk +Pa.Q$R$a;1S"-%@StD[LTqeEZV5C/gW2ZesX/rG*Y-5(6Z*CU@Za@-J[^NZS\Gj&=])TDA]`5\F +^AYhH_#M7K_Z%IQ`;IUS`r=$WaSs<]b5KN`bl>recMu5jd/MGmdK%bpe-FOTf%8O+f\-8X!o)Mc +rnRV3hu;OBiSrkWj5f=`k2tjikl0fOlKdd&m-X3.rpTmV!:g'Zs7?9_rq6 +JcC<$JcFR+mJct\r;?raPn9!+>b4s'>\2rETA,s'#>'s&f8%qc-ra>_6qdTP7rabn;rau.Bqe5qBrG)(BqJ>P9g2?b* +qf)4Jqf;FPa)q9&rc\3`s*4QhrHeKj!.=cos*b9(J:N3%JqJ]/L&QflLPUeDMMmFQNfT6_Ocklk +Pa.Q$R$a;1S"-%@StD[LTqeEZV5C/gW2ZesX/rG*Y-5(6Z*CU@Za@-J[^NZS\Gj&=])TDA]`5\F +^AYhH_#M7K_Z%IQ`;IUS`r=$WaSs<]b5KN`bl>recMu5jd/MGmdK%bpe-FOTf%8O+f\-8X!o)Mc +rnRV3hu;OBiSrkWj5f=`k2tjikl0fOlKdd&m-X3.rpTmV!:g'Zs7?9_rq6 +JcC<$JcFR+m/Hn\qu$3cr;-Bfq=sp_rq?6^rq-3]r:9mXs7$!U!q,ICrp9[N!:'RJE9QKJk2tdd +jQ#:[iS`YOhVI#CgY1B7f[na+e^W*sdF$=ecHXSVbK@rJa2Z*;`59C-^q[Us]Y(kf\[],W[^EKK +Za$a=YHG"0XK/A$WMl_mVPU)aUS=HUTV%gISXc1=R[KP1Q^3o%P`q8nOc]R'"ceS$N/NSmM&M2* +L5(D8KS+o/JUr?%IsuipI=-BgH?sj^GlDmfG'3e+!crC&rc%sXDuOVUD/=%fCBnTgBkV0mB4h-S +s'u+>rF,h:?srt@s'G_2rETA,s'#>'r`K2%qH!Ppr)E;eq,7&doMGE\qG-NSo1\^LrD*8dqG@,f +rDNJjr`&hrq,[Gqr)i_sr*'#&pg!c'rEf>-ra>_6qdTP7rabn;rau.BqIohArG)(Bph\]%m;Dc= +r,D=Kqf;LRa`RH'rc\0_s*4QhrHeKj!.=cos*artrd[1`JqJ]/KnY89LPUeDMMmFPNK0']Ocklk +Pa.N"R$a;1S"#q>StD[LTq\?YV5C/gW2ZesX/rG*Y-5(6Z*OA8!OT96[Ks@P\@K/]]">TR]`5\F +^AbnH_#M7L_Z%IQ`;IUR`rF*WaT'B]b5KN`bl>rdcMu2jd/DAldK%bqeGn&!f)F;$fDsV(gAfn- +h#?+7hV[5Ki8NYSro4%?jo4BIkNM-ol0@R"rp0^RmdC)C!q>aMrpp*\!;-6_s7ZKerV6Bfs8)Wi +rVZWmo)=4?KE$H~> +JcC<$JcFR+m/Hn\qu$3cr;-Bfq=sp_rq?6^rq-3]r:9mXs7$!U!q,ICrp9[N!:'RJE9QKJk2tdd +jQ#:[iS`YOhVI#CgY1B7f[na+e^W*sdF$=ecHXSVbK@rJa2Z*;`59C-^q[Us]Y(kf\[],W[^EKK +Za$a=YHG"0XK/A$WMl_mVPU)aUS=HUTV%gISXc1=R[KP1Q^3o%P`q8nOc]R'"ceS$N/NSmM&M2* +L5(D8KS+o/JUr?%IsuipI=-BgH?sj^GlDmfG'3e+!crC&rc%sXDuOVUD/=%fCBnTgBkV0mB4h-S +s'u+>rF,h:?srt@s'G_2rETA,s'#>'r`K2%qH!Ppr)E;eq,7&doMGE\qG-NSo1\^LrD*8dqG@,f +rDNJjr`&hrq,[Gqr)i_sr*'#&pg!c'rEf>-ra>_6qdTP7rabn;rau.BqIohArG)(Bph\]%m;Dc= +r,D=Kqf;LRa`RH'rc\0_s*4QhrHeKj!.=cos*artrd[1`JqJ]/KnY89LPUeDMMmFPNK0']Ocklk +Pa.N"R$a;1S"#q>StD[LTq\?YV5C/gW2ZesX/rG*Y-5(6Z*OA8!OT96[Ks@P\@K/]]">TR]`5\F +^AbnH_#M7L_Z%IQ`;IUR`rF*WaT'B]b5KN`bl>rdcMu2jd/DAldK%bqeGn&!f)F;$fDsV(gAfn- +h#?+7hV[5Ki8NYSro4%?jo4BIkNM-ol0@R"rp0^RmdC)C!q>aMrpp*\!;-6_s7ZKerV6Bfs8)Wi +rVZWmo)=4?KE$H~> +JcC<$JcFR+m/Hn\qu$3cr;-Bfq=sp_rq?6^rq-3]r:9mXs7$!U!q,ICrp9[N!:'RJE9QKJk2tdd +jQ#:[iS`YOhVI#CgY1B7f[na+e^W*sdF$=ecHXSVbK@rJa2Z*;`59C-^q[Us]Y(kf\[],W[^EKK +Za$a=YHG"0XK/A$WMl_mVPU)aUS=HUTV%gISXc1=R[KP1Q^3o%P`q8nOc]R'"ceS$N/NSmM&M2* +L5(D8KS+o/JUr?%IsuipI=-BgH?sj^GlDmfG'3e+!crC&rc%sXDuOVUD/=%fCBnTgBkV0mB4h-S +s'u+>rF,h:?srt@s'G_2rETA,s'#>'r`K2%qH!Ppr)E;eq,7&doMGE\qG-NSo1\^LrD*8dqG@,f +rDNJjr`&hrq,[Gqr)i_sr*'#&pg!c'rEf>-ra>_6qdTP7rabn;rau.BqIohArG)(Bph\]%m;Dc= +r,D=Kqf;LRa`RH'rc\0_s*4QhrHeKj!.=cos*artrd[1`JqJ]/KnY89LPUeDMMmFPNK0']Ocklk +Pa.N"R$a;1S"#q>StD[LTq\?YV5C/gW2ZesX/rG*Y-5(6Z*OA8!OT96[Ks@P\@K/]]">TR]`5\F +^AbnH_#M7L_Z%IQ`;IUR`rF*WaT'B]b5KN`bl>rdcMu2jd/DAldK%bqeGn&!f)F;$fDsV(gAfn- +h#?+7hV[5Ki8NYSro4%?jo4BIkNM-ol0@R"rp0^RmdC)C!q>aMrpp*\!;-6_s7ZKerV6Bfs8)Wi +rVZWmo)=4?KE$H~> +JcC<$JcFO*m/Hn\qu$0br;-Bfq=sp_rq?6^rq-6^r:9mXs7$!Us6]mSrp9[N!:'RJ#3b75k2tdd +ro7eRiS`YOhVI#CgY1B7f[na+eC;sqdF$=dcHXSVbK7iHa2Z*:_ns:,^q[Us]Y(kf\[],W[^EKK +Za-g>YHG"0XK/A$WMl_mVPU)aUS=HUTV%gISXc1=R[KP1Q^3o%P`q;oP*(ieO,f5!N!5,sM2@%D +re:H-K`6T)JqVm!GuZPC]A,LC&VcIB4bcT +AHHCPA,]s;@/s^6?iOI4?2\%.>Q7n)=oMP&=8>nq!c_:]!o>:&Ica:\did;>jDh +;uK\oPMJ%?2\++?i=C3@JaO5A,^$9Ac?<@BDQTR]`5YF^AYhH +_#M7K_Z.OR`;IUR`rF*WaSs<]b5BH_bl>rdcMu5jd/MGmdf7eqeGn&!f)F;$fDsV(gAfn-h#?+2 +hV[5ihuVfrro47EjlPXekND(.klU/9li-5OmI'uBs6p$YrUL$]o^r+Ts7ZKerV6EgrqcNhrVZWm +o)=4?KE$H~> +JcC<$JcFO*m/Hn\qu$0br;-Bfq=sp_rq?6^rq-6^r:9mXs7$!Us6]mSrp9[N!:'RJ#3b75k2tdd +ro7eRiS`YOhVI#CgY1B7f[na+eC;sqdF$=dcHXSVbK7iHa2Z*:_ns:,^q[Us]Y(kf\[],W[^EKK +Za-g>YHG"0XK/A$WMl_mVPU)aUS=HUTV%gISXc1=R[KP1Q^3o%P`q;oP*(ieO,f5!N!5,sM2@%D +re:H-K`6T)JqVm!GuZPC]A,LC&VcIB4bcT +AHHCPA,]s;@/s^6?iOI4?2\%.>Q7n)=oMP&=8>nq!c_:]!o>:&Ica:\did;>jDh +;uK\oPMJ%?2\++?i=C3@JaO5A,^$9Ac?<@BDQTR]`5YF^AYhH +_#M7K_Z.OR`;IUR`rF*WaSs<]b5BH_bl>rdcMu5jd/MGmdf7eqeGn&!f)F;$fDsV(gAfn-h#?+2 +hV[5ihuVfrro47EjlPXekND(.klU/9li-5OmI'uBs6p$YrUL$]o^r+Ts7ZKerV6EgrqcNhrVZWm +o)=4?KE$H~> +JcC<$JcFO*m/Hn\qu$0br;-Bfq=sp_rq?6^rq-6^r:9mXs7$!Us6]mSrp9[N!:'RJ#3b75k2tdd +ro7eRiS`YOhVI#CgY1B7f[na+eC;sqdF$=dcHXSVbK7iHa2Z*:_ns:,^q[Us]Y(kf\[],W[^EKK +Za-g>YHG"0XK/A$WMl_mVPU)aUS=HUTV%gISXc1=R[KP1Q^3o%P`q;oP*(ieO,f5!N!5,sM2@%D +re:H-K`6T)JqVm!GuZPC]A,LC&VcIB4bcT +AHHCPA,]s;@/s^6?iOI4?2\%.>Q7n)=oMP&=8>nq!c_:]!o>:&Ica:\did;>jDh +;uK\oPMJ%?2\++?i=C3@JaO5A,^$9Ac?<@BDQTR]`5YF^AYhH +_#M7K_Z.OR`;IUR`rF*WaSs<]b5BH_bl>rdcMu5jd/MGmdf7eqeGn&!f)F;$fDsV(gAfn-h#?+2 +hV[5ihuVfrro47EjlPXekND(.klU/9li-5OmI'uBs6p$YrUL$]o^r+Ts7ZKerV6EgrqcNhrVZWm +o)=4?KE$H~> +JcC<$JcFL)m/Hk[qu$0brVHHfq=ss`rV$-]s7H<^rUU!Ys7$!Us6]mSrTjRNlMg#Pki_-kk2k\' +j&Y0ui8EMLh;-l@g=k64f@JL%eC2jndEg+`c-4ARaiMQD`l5m6_SX.)^V7Co]Xtbc\@8oT[C!9H +ZE^XrF,h:?srq?!a]/'r`K,#q,[Dnqc*,bqbm;gohbN]qbGp@r(d/cq,%#er_iPj +r`&hrq,[DprE/esr*'#&pK[Z&rEf>-ra>_6qdTP7rabn;rau+AqIohArG(t?g2-=soPXPEr,DCM +qf;LRe9(M/rHA$]rcnHgrHeKjs*Xfos*artrdY$#K)UBnKS>/8LPUeDMMmFPNK0'\OHG]hPE_>u +Q^F/.R[]heF^]2+L +_>V7N_u@UQ`W!mWa8c=3 +hu;O=iSrkWj5f:_roOIKkih9qlK[^7m/QGQmf)\Tn,W"Xo)J=]o`"O`pAambq#C0hqYU0gr;HTb +rdk*%s*t~> +JcC<$JcFL)m/Hk[qu$0brVHHfq=ss`rV$-]s7H<^rUU!Ys7$!Us6]mSrTjRNlMg#Pki_-kk2k\' +j&Y0ui8EMLh;-l@g=k64f@JL%eC2jndEg+`c-4ARaiMQD`l5m6_SX.)^V7Co]Xtbc\@8oT[C!9H +ZE^XrF,h:?srq?!a]/'r`K,#q,[Dnqc*,bqbm;gohbN]qbGp@r(d/cq,%#er_iPj +r`&hrq,[DprE/esr*'#&pK[Z&rEf>-ra>_6qdTP7rabn;rau+AqIohArG(t?g2-=soPXPEr,DCM +qf;LRe9(M/rHA$]rcnHgrHeKjs*Xfos*artrdY$#K)UBnKS>/8LPUeDMMmFPNK0'\OHG]hPE_>u +Q^F/.R[]heF^]2+L +_>V7N_u@UQ`W!mWa8c=3 +hu;O=iSrkWj5f:_roOIKkih9qlK[^7m/QGQmf)\Tn,W"Xo)J=]o`"O`pAambq#C0hqYU0gr;HTb +rdk*%s*t~> +JcC<$JcFL)m/Hk[qu$0brVHHfq=ss`rV$-]s7H<^rUU!Ys7$!Us6]mSrTjRNlMg#Pki_-kk2k\' +j&Y0ui8EMLh;-l@g=k64f@JL%eC2jndEg+`c-4ARaiMQD`l5m6_SX.)^V7Co]Xtbc\@8oT[C!9H +ZE^XrF,h:?srq?!a]/'r`K,#q,[Dnqc*,bqbm;gohbN]qbGp@r(d/cq,%#er_iPj +r`&hrq,[DprE/esr*'#&pK[Z&rEf>-ra>_6qdTP7rabn;rau+AqIohArG(t?g2-=soPXPEr,DCM +qf;LRe9(M/rHA$]rcnHgrHeKjs*Xfos*artrdY$#K)UBnKS>/8LPUeDMMmFPNK0'\OHG]hPE_>u +Q^F/.R[]heF^]2+L +_>V7N_u@UQ`W!mWa8c=3 +hu;O=iSrkWj5f:_roOIKkih9qlK[^7m/QGQmf)\Tn,W"Xo)J=]o`"O`pAambq#C0hqYU0gr;HTb +rdk*%s*t~> +JcC<$JcFI(m/Hk[qu$0br;-Bfq=sp_rq?6^s7H<^rUU!Ys7$!Us6]mSrp9[N!:'RJ!U/_Gk'lFQ +j5].XiS`YOhVI#CgY1?5f@SU(eC;sqdEp4bcHXSVb/q`Ga2Z*:_ns:,^q[Us]Y(kf\[],W[^EKK +Za-j?Yck43XfSS'Wi;qpVl$;dUnaZXTqJ$LSt2C@S!ob4R$X,(Q'@MsP*1rhO,o<\NJrgSMM[1G +Lkg_>L&Zi+K)pRTrdY$!If=a(I!^3dH?ja[GB\4RFoHI`F)q8"#B4U"DJj<.D#S2OC2%D]BEDgY +B)Z?CA7K-K@fKm:@/aO5?N4=0>lIt->5MJ%=T)=rb;#=&b:?,(G:Ado_;#X>j +;Ya8j<;fhl5MP!>l@t,?M\%-@/aU3@fBm:AG]s;B)ZH>B`2ZCC@c5jD"hf>DZ"GN +E;+AMEr'k6FRsYPG56@]GlN'eHN/?lI/\QoIK4lsJ,t4Qrdt6)L&QfiLPUeDMMmFPNK0'\Ocklk +Pa.N"Q^F20S"#q>StD[LTqeEZV5C/gW2ckuXKAV-YHY79ZEpmE[C*HO\%)FJ#J.OZ]Y(qk^AYhH +^];4L_Z%IQ`;R[S`rF*VaT'B]b5BH_bl5lccMu5jd/DAldf7epe,n1Of)F;$fDsV(gAfn-h#?.0 +h>lI4i;_a9ir7sCjQ5Lck3(pkrojLLlg+Q:!q#FDrpKpXnaZVLs766_rUp3as7cHds7uZjqtpBj +r;H3cJcCB&J,~> +JcC<$JcFI(m/Hk[qu$0br;-Bfq=sp_rq?6^s7H<^rUU!Ys7$!Us6]mSrp9[N!:'RJ!U/_Gk'lFQ +j5].XiS`YOhVI#CgY1?5f@SU(eC;sqdEp4bcHXSVb/q`Ga2Z*:_ns:,^q[Us]Y(kf\[],W[^EKK +Za-j?Yck43XfSS'Wi;qpVl$;dUnaZXTqJ$LSt2C@S!ob4R$X,(Q'@MsP*1rhO,o<\NJrgSMM[1G +Lkg_>L&Zi+K)pRTrdY$!If=a(I!^3dH?ja[GB\4RFoHI`F)q8"#B4U"DJj<.D#S2OC2%D]BEDgY +B)Z?CA7K-K@fKm:@/aO5?N4=0>lIt->5MJ%=T)=rb;#=&b:?,(G:Ado_;#X>j +;Ya8j<;fhl5MP!>l@t,?M\%-@/aU3@fBm:AG]s;B)ZH>B`2ZCC@c5jD"hf>DZ"GN +E;+AMEr'k6FRsYPG56@]GlN'eHN/?lI/\QoIK4lsJ,t4Qrdt6)L&QfiLPUeDMMmFPNK0'\Ocklk +Pa.N"Q^F20S"#q>StD[LTqeEZV5C/gW2ckuXKAV-YHY79ZEpmE[C*HO\%)FJ#J.OZ]Y(qk^AYhH +^];4L_Z%IQ`;R[S`rF*VaT'B]b5BH_bl5lccMu5jd/DAldf7epe,n1Of)F;$fDsV(gAfn-h#?.0 +h>lI4i;_a9ir7sCjQ5Lck3(pkrojLLlg+Q:!q#FDrpKpXnaZVLs766_rUp3as7cHds7uZjqtpBj +r;H3cJcCB&J,~> +JcC<$JcFI(m/Hk[qu$0br;-Bfq=sp_rq?6^s7H<^rUU!Ys7$!Us6]mSrp9[N!:'RJ!U/_Gk'lFQ +j5].XiS`YOhVI#CgY1?5f@SU(eC;sqdEp4bcHXSVb/q`Ga2Z*:_ns:,^q[Us]Y(kf\[],W[^EKK +Za-j?Yck43XfSS'Wi;qpVl$;dUnaZXTqJ$LSt2C@S!ob4R$X,(Q'@MsP*1rhO,o<\NJrgSMM[1G +Lkg_>L&Zi+K)pRTrdY$!If=a(I!^3dH?ja[GB\4RFoHI`F)q8"#B4U"DJj<.D#S2OC2%D]BEDgY +B)Z?CA7K-K@fKm:@/aO5?N4=0>lIt->5MJ%=T)=rb;#=&b:?,(G:Ado_;#X>j +;Ya8j<;fhl5MP!>l@t,?M\%-@/aU3@fBm:AG]s;B)ZH>B`2ZCC@c5jD"hf>DZ"GN +E;+AMEr'k6FRsYPG56@]GlN'eHN/?lI/\QoIK4lsJ,t4Qrdt6)L&QfiLPUeDMMmFPNK0'\Ocklk +Pa.N"Q^F20S"#q>StD[LTqeEZV5C/gW2ckuXKAV-YHY79ZEpmE[C*HO\%)FJ#J.OZ]Y(qk^AYhH +^];4L_Z%IQ`;R[S`rF*VaT'B]b5BH_bl5lccMu5jd/DAldf7epe,n1Of)F;$fDsV(gAfn-h#?.0 +h>lI4i;_a9ir7sCjQ5Lck3(pkrojLLlg+Q:!q#FDrpKpXnaZVLs766_rUp3as7cHds7uZjqtpBj +r;H3cJcCB&J,~> +JcC<$JcFF'm/Hk[qY^'arVHHfq=ss`rV$0^rq-6^r:9mXs7$$Vs6]mSrp9[N!:'RJ!U/_Gk'Q4N +j5].Xi8EMLh;-l@g=k64f@SU(eC;spdEp4bcHXPUb/q`Ga2Q$9_ns:,^V@Lr]Y(kf\[f2X[^EKK +Za-j?Yck43XfSS'Wi;qpVl$;dUnaZXTqJ$LSt2C@S!ob5R$a5+Q'IStP*1rhOH5H_NJrgSMi*@J +Lkkta!JQ4+K)pRTrdY$!If=`rI!bj=!I8qhG78Y;F`__HF)l8?E,]apD?k#pChmg$C2*Z\s(;=D +ral+?!+Yt:!b#JErEoS2s'>S.r`fD+qcWl"rE&_oqGmAkoi(`cr)*/aqbR&`kY:nKr(m)ar_`Vl +q,@5kr`/_orE&o!p0%;sqcii#r*B8-qHs50rF,S4raYq3S"-%@T:hmOU8+N\VPg>jWN*##Xf\b0YctC^ +JcC<$JcFF'm/Hk[qY^'arVHHfq=ss`rV$0^rq-6^r:9mXs7$$Vs6]mSrp9[N!:'RJ!U/_Gk'Q4N +j5].Xi8EMLh;-l@g=k64f@SU(eC;spdEp4bcHXPUb/q`Ga2Q$9_ns:,^V@Lr]Y(kf\[f2X[^EKK +Za-j?Yck43XfSS'Wi;qpVl$;dUnaZXTqJ$LSt2C@S!ob5R$a5+Q'IStP*1rhOH5H_NJrgSMi*@J +Lkkta!JQ4+K)pRTrdY$!If=`rI!bj=!I8qhG78Y;F`__HF)l8?E,]apD?k#pChmg$C2*Z\s(;=D +ral+?!+Yt:!b#JErEoS2s'>S.r`fD+qcWl"rE&_oqGmAkoi(`cr)*/aqbR&`kY:nKr(m)ar_`Vl +q,@5kr`/_orE&o!p0%;sqcii#r*B8-qHs50rF,S4raYq3S"-%@T:hmOU8+N\VPg>jWN*##Xf\b0YctC^ +JcC<$JcFF'm/Hk[qY^'arVHHfq=ss`rV$0^rq-6^r:9mXs7$$Vs6]mSrp9[N!:'RJ!U/_Gk'Q4N +j5].Xi8EMLh;-l@g=k64f@SU(eC;spdEp4bcHXPUb/q`Ga2Q$9_ns:,^V@Lr]Y(kf\[f2X[^EKK +Za-j?Yck43XfSS'Wi;qpVl$;dUnaZXTqJ$LSt2C@S!ob5R$a5+Q'IStP*1rhOH5H_NJrgSMi*@J +Lkkta!JQ4+K)pRTrdY$!If=`rI!bj=!I8qhG78Y;F`__HF)l8?E,]apD?k#pChmg$C2*Z\s(;=D +ral+?!+Yt:!b#JErEoS2s'>S.r`fD+qcWl"rE&_oqGmAkoi(`cr)*/aqbR&`kY:nKr(m)ar_`Vl +q,@5kr`/_orE&o!p0%;sqcii#r*B8-qHs50rF,S4raYq3S"-%@T:hmOU8+N\VPg>jWN*##Xf\b0YctC^ +JcC<$JcFC&m/HhZqu$0br;-?eq=ss`rq?6^s7H<^rUU!Ys7$$Vs6]mSrp9[N!:'RJ!U/_Gk#CI' +j5].Xi8EMLh;-l@g=k64f@SU(eC2jndEp4bcHOJTb/q`G`l5p8_ns:,^V@Lr]Y(kf\[f5Y[^EKK +Za-j?Yck43XfSS'Wi;qpVl$;dUna[`TadZeSt;LCS"#k7R$a5+rfmtXPEM)kOH5H_NfB!VMi.Lj ++,G],L4t>7K7ec,JUi9#IXZ]nI!^3dH?jd\GB\4RFoHI`F)q8"#B4U"DJj<.D#S2OC2%D]BEDgY +B)Z?CA7K-K@fKm:@/XI4?N4=/>lS%->5MJ$=Su7onq>5MOu>l@t,?MRt-@/aU3@fBm:AG]s;B)QB=B`2ZCC?o[1D!Ys1D#/#B +DZ+MOE;4GNEr0qJFRF;EG4p.YGlE!dHN/?lI/SHpIXckHJ3ng=JqJ]/KnY89LPUeDMMmFPNK0'\ +OHG]hPE_>tQ^F/.R[]hSe]Y2"m +rkJKK!5\WNs24lTrPefVrl=rXs2k8_r6,)`rltDerm1Vkr6bPms3pqr!nGlQrRV,'g"HAYs4[P/ +rS7P3hr"Fk!TE&;j8\0?jo4EBk5a`FklU/9li-5PmI'EAmfN"Knc&+ZoDeI]o`4^bp\jmeq>U6f +qu-HjrU^#>s+:9$~> +JcC<$JcFC&m/HhZqu$0br;-?eq=ss`rq?6^s7H<^rUU!Ys7$$Vs6]mSrp9[N!:'RJ!U/_Gk#CI' +j5].Xi8EMLh;-l@g=k64f@SU(eC2jndEp4bcHOJTb/q`G`l5p8_ns:,^V@Lr]Y(kf\[f5Y[^EKK +Za-j?Yck43XfSS'Wi;qpVl$;dUna[`TadZeSt;LCS"#k7R$a5+rfmtXPEM)kOH5H_NfB!VMi.Lj ++,G],L4t>7K7ec,JUi9#IXZ]nI!^3dH?jd\GB\4RFoHI`F)q8"#B4U"DJj<.D#S2OC2%D]BEDgY +B)Z?CA7K-K@fKm:@/XI4?N4=/>lS%->5MJ$=Su7onq>5MOu>l@t,?MRt-@/aU3@fBm:AG]s;B)QB=B`2ZCC?o[1D!Ys1D#/#B +DZ+MOE;4GNEr0qJFRF;EG4p.YGlE!dHN/?lI/SHpIXckHJ3ng=JqJ]/KnY89LPUeDMMmFPNK0'\ +OHG]hPE_>tQ^F/.R[]hSe]Y2"m +rkJKK!5\WNs24lTrPefVrl=rXs2k8_r6,)`rltDerm1Vkr6bPms3pqr!nGlQrRV,'g"HAYs4[P/ +rS7P3hr"Fk!TE&;j8\0?jo4EBk5a`FklU/9li-5PmI'EAmfN"Knc&+ZoDeI]o`4^bp\jmeq>U6f +qu-HjrU^#>s+:9$~> +JcC<$JcFC&m/HhZqu$0br;-?eq=ss`rq?6^s7H<^rUU!Ys7$$Vs6]mSrp9[N!:'RJ!U/_Gk#CI' +j5].Xi8EMLh;-l@g=k64f@SU(eC2jndEp4bcHOJTb/q`G`l5p8_ns:,^V@Lr]Y(kf\[f5Y[^EKK +Za-j?Yck43XfSS'Wi;qpVl$;dUna[`TadZeSt;LCS"#k7R$a5+rfmtXPEM)kOH5H_NfB!VMi.Lj ++,G],L4t>7K7ec,JUi9#IXZ]nI!^3dH?jd\GB\4RFoHI`F)q8"#B4U"DJj<.D#S2OC2%D]BEDgY +B)Z?CA7K-K@fKm:@/XI4?N4=/>lS%->5MJ$=Su7onq>5MOu>l@t,?MRt-@/aU3@fBm:AG]s;B)QB=B`2ZCC?o[1D!Ys1D#/#B +DZ+MOE;4GNEr0qJFRF;EG4p.YGlE!dHN/?lI/SHpIXckHJ3ng=JqJ]/KnY89LPUeDMMmFPNK0'\ +OHG]hPE_>tQ^F/.R[]hSe]Y2"m +rkJKK!5\WNs24lTrPefVrl=rXs2k8_r6,)`rltDerm1Vkr6bPms3pqr!nGlQrRV,'g"HAYs4[P/ +rS7P3hr"Fk!TE&;j8\0?jo4EBk5a`FklU/9li-5PmI'EAmfN"Knc&+ZoDeI]o`4^bp\jmeq>U6f +qu-HjrU^#>s+:9$~> +JcC<$JcF@%li-bZqY^'ar;-Bfq=sp_rq?9_rq-6^rUU!Ys7$$Vs6]mSrp9[NlIt,>5DD#=Su7nh;Z'Dc;#3uL:A[i^;#O8i;Ya8i +<;fhmnp>5MOu>l7n+?M\%.@/XO2@fBm:AG]s;B)QB=B`2ZBC<:8dD#8)DDZ+MOE;=MO +Er:"MFS0eHG4TqVGlE!cHN/?lI/SKnIfFosJ4kHFJqJ]/KnY89LPUeDMMd=NN/`jYOHG]hPE_>t +QC!u,R[]e:St;RITqS6WUnsrdW2ZesX/rG*YHY79ZEpmE[C3NQ\%&uZ]"@sS#edsd^V@S"_86,f +s24lTrPefVs2Y&Ys2k8_r6,)`rltAds3L\krR(Vms3pqrs4./#rn%2&s4RD*s4[P/rn[V2s53h6 +!o`.uro4%?jo4EBk5a`Fl2U#Kli-8Nm/ZSRn,MnWnc&+Zo)SF]p&Facp\agdq>U6fqu-HkrUTr= +s+:9$~> +JcC<$JcF@%li-bZqY^'ar;-Bfq=sp_rq?9_rq-6^rUU!Ys7$$Vs6]mSrp9[NlIt,>5DD#=Su7nh;Z'Dc;#3uL:A[i^;#O8i;Ya8i +<;fhmnp>5MOu>l7n+?M\%.@/XO2@fBm:AG]s;B)QB=B`2ZBC<:8dD#8)DDZ+MOE;=MO +Er:"MFS0eHG4TqVGlE!cHN/?lI/SKnIfFosJ4kHFJqJ]/KnY89LPUeDMMd=NN/`jYOHG]hPE_>t +QC!u,R[]e:St;RITqS6WUnsrdW2ZesX/rG*YHY79ZEpmE[C3NQ\%&uZ]"@sS#edsd^V@S"_86,f +s24lTrPefVs2Y&Ys2k8_r6,)`rltAds3L\krR(Vms3pqrs4./#rn%2&s4RD*s4[P/rn[V2s53h6 +!o`.uro4%?jo4EBk5a`Fl2U#Kli-8Nm/ZSRn,MnWnc&+Zo)SF]p&Facp\agdq>U6fqu-HkrUTr= +s+:9$~> +JcC<$JcF@%li-bZqY^'ar;-Bfq=sp_rq?9_rq-6^rUU!Ys7$$Vs6]mSrp9[NlIt,>5DD#=Su7nh;Z'Dc;#3uL:A[i^;#O8i;Ya8i +<;fhmnp>5MOu>l7n+?M\%.@/XO2@fBm:AG]s;B)QB=B`2ZBC<:8dD#8)DDZ+MOE;=MO +Er:"MFS0eHG4TqVGlE!cHN/?lI/SKnIfFosJ4kHFJqJ]/KnY89LPUeDMMd=NN/`jYOHG]hPE_>t +QC!u,R[]e:St;RITqS6WUnsrdW2ZesX/rG*YHY79ZEpmE[C3NQ\%&uZ]"@sS#edsd^V@S"_86,f +s24lTrPefVs2Y&Ys2k8_r6,)`rltAds3L\krR(Vms3pqrs4./#rn%2&s4RD*s4[P/rn[V2s53h6 +!o`.uro4%?jo4EBk5a`Fl2U#Kli-8Nm/ZSRn,MnWnc&+Zo)SF]p&Facp\agdq>U6fqu-HkrUTr= +s+:9$~> +JcC<$JcF=$li-_Yqu$0br;-?eq=ss`rq?9_rq-6^rUU!Ys7$$Vs6]mSrp1$YlK[Wukih3lk2k\' +j'q$,i8EMLh;-l@g=k63f@JL%eC2jndEg+`c-4ASb/hZE`l5p8_ns7*^V@Lr]Y(kf\[f5Z[^NTN +Za6sBYct=6Xf\\*WiE%sVl-DgUnjc[TqS-OT:VXFS=?":R@'A.QN!-QP`q8nOc]R'$BC+)N/NRN +M2@%Dre;>FKS+o/Jq8H&It)oqI=-EhH?sj^G^"@TG'3e+!HW;\E<1#srbhaQ!,VXM!buF`rb)@G +AnM$R!b>eNrF,h:?srq?ra,V1r*95*r`],#r)ihtoiCriqc*;gr)3GipJCZ]lq[CQpJCfcrDNGi +rD`_qq,[Dpr)iVpqc`l$p0@Q%rEf;,ra>_6qdTP7rabk:rau.Bq.T\?r+a5eq/#tGpMTqJrG_RP +rGqgWolTtOoQK\Ir-80cqg/9hrd=Zms*artrI=p"K)UE&KLCNKL51S@M2@+JN/WaVO,oBbP*2&p +Q'Rc(R$jG5S=Q7DTV8'RUSO``Vl-JnWiN5'Xfek3Z*L^B['d?N\%&rY\[oEP]E,^[rkANM_86,f +s2+iTrPefVs2Y&Ys2k8_r6,)`rltAdrm1Vkr6bPmrmUhqs4./#rR_)%!87>)s4[P/rS7P3hr"Fk +!o`.uro4(@jlQL(!pAe2rojLLlg+Q:!q#FDrpTmV!:g$Y!qZ'VrUp3as7cKerqZQiqtp?irVc +JcC<$JcF=$li-_Yqu$0br;-?eq=ss`rq?9_rq-6^rUU!Ys7$$Vs6]mSrp1$YlK[Wukih3lk2k\' +j'q$,i8EMLh;-l@g=k63f@JL%eC2jndEg+`c-4ASb/hZE`l5p8_ns7*^V@Lr]Y(kf\[f5Z[^NTN +Za6sBYct=6Xf\\*WiE%sVl-DgUnjc[TqS-OT:VXFS=?":R@'A.QN!-QP`q8nOc]R'$BC+)N/NRN +M2@%Dre;>FKS+o/Jq8H&It)oqI=-EhH?sj^G^"@TG'3e+!HW;\E<1#srbhaQ!,VXM!buF`rb)@G +AnM$R!b>eNrF,h:?srq?ra,V1r*95*r`],#r)ihtoiCriqc*;gr)3GipJCZ]lq[CQpJCfcrDNGi +rD`_qq,[Dpr)iVpqc`l$p0@Q%rEf;,ra>_6qdTP7rabk:rau.Bq.T\?r+a5eq/#tGpMTqJrG_RP +rGqgWolTtOoQK\Ir-80cqg/9hrd=Zms*artrI=p"K)UE&KLCNKL51S@M2@+JN/WaVO,oBbP*2&p +Q'Rc(R$jG5S=Q7DTV8'RUSO``Vl-JnWiN5'Xfek3Z*L^B['d?N\%&rY\[oEP]E,^[rkANM_86,f +s2+iTrPefVs2Y&Ys2k8_r6,)`rltAdrm1Vkr6bPmrmUhqs4./#rR_)%!87>)s4[P/rS7P3hr"Fk +!o`.uro4(@jlQL(!pAe2rojLLlg+Q:!q#FDrpTmV!:g$Y!qZ'VrUp3as7cKerqZQiqtp?irVc +JcC<$JcF=$li-_Yqu$0br;-?eq=ss`rq?9_rq-6^rUU!Ys7$$Vs6]mSrp1$YlK[Wukih3lk2k\' +j'q$,i8EMLh;-l@g=k63f@JL%eC2jndEg+`c-4ASb/hZE`l5p8_ns7*^V@Lr]Y(kf\[f5Z[^NTN +Za6sBYct=6Xf\\*WiE%sVl-DgUnjc[TqS-OT:VXFS=?":R@'A.QN!-QP`q8nOc]R'$BC+)N/NRN +M2@%Dre;>FKS+o/Jq8H&It)oqI=-EhH?sj^G^"@TG'3e+!HW;\E<1#srbhaQ!,VXM!buF`rb)@G +AnM$R!b>eNrF,h:?srq?ra,V1r*95*r`],#r)ihtoiCriqc*;gr)3GipJCZ]lq[CQpJCfcrDNGi +rD`_qq,[Dpr)iVpqc`l$p0@Q%rEf;,ra>_6qdTP7rabk:rau.Bq.T\?r+a5eq/#tGpMTqJrG_RP +rGqgWolTtOoQK\Ir-80cqg/9hrd=Zms*artrI=p"K)UE&KLCNKL51S@M2@+JN/WaVO,oBbP*2&p +Q'Rc(R$jG5S=Q7DTV8'RUSO``Vl-JnWiN5'Xfek3Z*L^B['d?N\%&rY\[oEP]E,^[rkANM_86,f +s2+iTrPefVs2Y&Ys2k8_r6,)`rltAdrm1Vkr6bPmrmUhqs4./#rR_)%!87>)s4[P/rS7P3hr"Fk +!o`.uro4(@jlQL(!pAe2rojLLlg+Q:!q#FDrpTmV!:g$Y!qZ'VrUp3as7cKerqZQiqtp?irVc +JcC<$JcF:#li-_YqY^'ar;-?eqY:'arq?6^s7H?_rUU!Ys7$$Vs6]mSrp10]lK[Wuki_-kk2k[a +j5T%si(;h_h;$c=g=b-1f@JL%eC2jnd*L"_c-4ASaiMQD`l5p8_ns7*^V@Lr]Y(kf\[f5Z[^NTN +Za6sBYct=6Xf\\*WiE%sVl-DgrhL=)U7n9RT:VXFS=?":R[KP1Q^3o%P`u*0"d+n-O,f5!N":i( +M2@%ELPCP;KS4u1JqraPn9s'Yb3s'G_2qcs,)rEB#"qcN_soiCujr)EDhrDNPjp/(KZp.k?Xp/(]brDNGi +rD`_qq,[Dpr)iVpqHEc#p0@N$rEf>-rF#V5qdTP7rabn;rFZ%Aq.T\?qeF)cqeZ1Iphp%KrG_RP +rGqgWp2p.RpNGtKqfr$aqKi0grd=Zms*jutrdb$"!.t3&s+F.$L5(J>Ll$tGMijWN*##Xf\b0YctC!9O4Bs5sCGrosIJ!:0XNs6TgSrpTmVs7-*Zs7?9_rq6 +JcC<$JcF:#li-_YqY^'ar;-?eqY:'arq?6^s7H?_rUU!Ys7$$Vs6]mSrp10]lK[Wuki_-kk2k[a +j5T%si(;h_h;$c=g=b-1f@JL%eC2jnd*L"_c-4ASaiMQD`l5p8_ns7*^V@Lr]Y(kf\[f5Z[^NTN +Za6sBYct=6Xf\\*WiE%sVl-DgrhL=)U7n9RT:VXFS=?":R[KP1Q^3o%P`u*0"d+n-O,f5!N":i( +M2@%ELPCP;KS4u1JqraPn9s'Yb3s'G_2qcs,)rEB#"qcN_soiCujr)EDhrDNPjp/(KZp.k?Xp/(]brDNGi +rD`_qq,[Dpr)iVpqHEc#p0@N$rEf>-rF#V5qdTP7rabn;rFZ%Aq.T\?qeF)cqeZ1Iphp%KrG_RP +rGqgWp2p.RpNGtKqfr$aqKi0grd=Zms*jutrdb$"!.t3&s+F.$L5(J>Ll$tGMijWN*##Xf\b0YctC!9O4Bs5sCGrosIJ!:0XNs6TgSrpTmVs7-*Zs7?9_rq6 +JcC<$JcF:#li-_YqY^'ar;-?eqY:'arq?6^s7H?_rUU!Ys7$$Vs6]mSrp10]lK[Wuki_-kk2k[a +j5T%si(;h_h;$c=g=b-1f@JL%eC2jnd*L"_c-4ASaiMQD`l5p8_ns7*^V@Lr]Y(kf\[f5Z[^NTN +Za6sBYct=6Xf\\*WiE%sVl-DgrhL=)U7n9RT:VXFS=?":R[KP1Q^3o%P`u*0"d+n-O,f5!N":i( +M2@%ELPCP;KS4u1JqraPn9s'Yb3s'G_2qcs,)rEB#"qcN_soiCujr)EDhrDNPjp/(KZp.k?Xp/(]brDNGi +rD`_qq,[Dpr)iVpqHEc#p0@N$rEf>-rF#V5qdTP7rabn;rFZ%Aq.T\?qeF)cqeZ1Iphp%KrG_RP +rGqgWp2p.RpNGtKqfr$aqKi0grd=Zms*jutrdb$"!.t3&s+F.$L5(J>Ll$tGMijWN*##Xf\b0YctC!9O4Bs5sCGrosIJ!:0XNs6TgSrpTmVs7-*Zs7?9_rq6 +JcC<$JcF7"lMgYYqY^$`r;-Bfq=ss`rq?9_s7H?_rUU!Ys7$$V!q,ICrp0[OlMg#Kki_s-J*#bO +j5T%Ui8Q%b"=o;D!=7oVl!cM:\@Q^;>jDg;uK\o +P;>"?2\+*?iFI4@JaO4A,^$9Ac?8#JDuFYNEW'qV +F80kSFnp4KGPQL]H22dcHiAEkIK"ZqJ,OotJH1<$K2@5TKnb>;LPUeDMMmFPNK0'\OHG]hPE_>t +QC!u,R[]e:SXuIHTqS6WUnsrdW2ZesX0&M,YHY79ZEpmE[^NZT\@K/]]=bei^:q@s^qmkd_?.Wn +`;[aU`rF*XaT'B^b5BH^bl5lbcMl/hd/;;jdf7eoeGn)!f)4/"f`0Y(gAfq-h#?.0hZ)L4i;_a9 +ir8! +JcC<$JcF7"lMgYYqY^$`r;-Bfq=ss`rq?9_s7H?_rUU!Ys7$$V!q,ICrp0[OlMg#Kki_s-J*#bO +j5T%Ui8Q%b"=o;D!=7oVl!cM:\@Q^;>jDg;uK\o +P;>"?2\+*?iFI4@JaO4A,^$9Ac?8#JDuFYNEW'qV +F80kSFnp4KGPQL]H22dcHiAEkIK"ZqJ,OotJH1<$K2@5TKnb>;LPUeDMMmFPNK0'\OHG]hPE_>t +QC!u,R[]e:SXuIHTqS6WUnsrdW2ZesX0&M,YHY79ZEpmE[^NZT\@K/]]=bei^:q@s^qmkd_?.Wn +`;[aU`rF*XaT'B^b5BH^bl5lbcMl/hd/;;jdf7eoeGn)!f)4/"f`0Y(gAfq-h#?.0hZ)L4i;_a9 +ir8! +JcC<$JcF7"lMgYYqY^$`r;-Bfq=ss`rq?9_s7H?_rUU!Ys7$$V!q,ICrp0[OlMg#Kki_s-J*#bO +j5T%Ui8Q%b"=o;D!=7oVl!cM:\@Q^;>jDg;uK\o +P;>"?2\+*?iFI4@JaO4A,^$9Ac?8#JDuFYNEW'qV +F80kSFnp4KGPQL]H22dcHiAEkIK"ZqJ,OotJH1<$K2@5TKnb>;LPUeDMMmFPNK0'\OHG]hPE_>t +QC!u,R[]e:SXuIHTqS6WUnsrdW2ZesX0&M,YHY79ZEpmE[^NZT\@K/]]=bei^:q@s^qmkd_?.Wn +`;[aU`rF*XaT'B^b5BH^bl5lbcMl/hd/;;jdf7eoeGn)!f)4/"f`0Y(gAfq-h#?.0hZ)L4i;_a9 +ir8! +JcC<$JcF4!lMgVXqY^$`r;-BfqY:'arq?9_s7H?_rUU!Ys7$$V!q,ICrp0[OlMg$KnY24K7\Z*J:N,urd=fpHiAVm!GuZPC]A,LC&VfG +B)lQBAcH9@A,Tm:@K0a5?iFC3?2@h)>Q%b!=o2>!=8#\na>f;uK\o +P;>"?2\+*?iFI3@JaO5A,^$9Ac66?BD?0A)JDuFYOEW1"W +F80kTFo-@OGPQL[H2)^aHiAEjIK+crJ,Om!JV&LQK+!?dKnb>;LPUeDMMqIm16%t +QC!u+R@B\9SXuFGTqS3UUnsrdVl?\rX/rG+YHY79ZEpmE[C3QSrj`3D]=bei^AbkJ^qp#e!lMsp +rl+oWs2Y,[s2k8_rQG2as3:Gdrm1Sjr6bMlrmUeps4./#r7Cu$s4RA)s4[P/rS@M1!8mb5!o`.u +ro=%>!9O1A!pAe2rojLLlg+Q:s6TgSrpTmVs7-*Zs7?9_rUp3as7cKerqZQiqtp?irVc +JcC<$JcF4!lMgVXqY^$`r;-BfqY:'arq?9_s7H?_rUU!Ys7$$V!q,ICrp0[OlMg$KnY24K7\Z*J:N,urd=fpHiAVm!GuZPC]A,LC&VfG +B)lQBAcH9@A,Tm:@K0a5?iFC3?2@h)>Q%b!=o2>!=8#\na>f;uK\o +P;>"?2\+*?iFI3@JaO5A,^$9Ac66?BD?0A)JDuFYOEW1"W +F80kTFo-@OGPQL[H2)^aHiAEjIK+crJ,Om!JV&LQK+!?dKnb>;LPUeDMMqIm16%t +QC!u+R@B\9SXuFGTqS3UUnsrdVl?\rX/rG+YHY79ZEpmE[C3QSrj`3D]=bei^AbkJ^qp#e!lMsp +rl+oWs2Y,[s2k8_rQG2as3:Gdrm1Sjr6bMlrmUeps4./#r7Cu$s4RA)s4[P/rS@M1!8mb5!o`.u +ro=%>!9O1A!pAe2rojLLlg+Q:s6TgSrpTmVs7-*Zs7?9_rUp3as7cKerqZQiqtp?irVc +JcC<$JcF4!lMgVXqY^$`r;-BfqY:'arq?9_s7H?_rUU!Ys7$$V!q,ICrp0[OlMg$KnY24K7\Z*J:N,urd=fpHiAVm!GuZPC]A,LC&VfG +B)lQBAcH9@A,Tm:@K0a5?iFC3?2@h)>Q%b!=o2>!=8#\na>f;uK\o +P;>"?2\+*?iFI3@JaO5A,^$9Ac66?BD?0A)JDuFYOEW1"W +F80kTFo-@OGPQL[H2)^aHiAEjIK+crJ,Om!JV&LQK+!?dKnb>;LPUeDMMqIm16%t +QC!u+R@B\9SXuFGTqS3UUnsrdVl?\rX/rG+YHY79ZEpmE[C3QSrj`3D]=bei^AbkJ^qp#e!lMsp +rl+oWs2Y,[s2k8_rQG2as3:Gdrm1Sjr6bMlrmUeps4./#r7Cu$s4RA)s4[P/rS@M1!8mb5!o`.u +ro=%>!9O1A!pAe2rojLLlg+Q:s6TgSrpTmVs7-*Zs7?9_rUp3as7cKerqZQiqtp?irVc +JcC<$JcF-tlMgVXqY^'ar;-BfqY:'arq?9_s7H?_rUU!Ys7$$V&FSrQm-O'(lKRQski_*jjlHF$ +@H-8(i8mJ:N-!IXQWlH[C'bH$FRXGBS+OFEDSFErL%ZE,Y_n!c;airbDRMBkdQ[ +!bZ+Wral+?s'u":s'bq8r*TG0ra#A*r*0,'p0%8pr)`VnrDieqpf%)gr))0Er)*Djq,@2jrDiYo +r)`btoi_)oqHNVtr*B8-qHs2/raG\5raYn;qdob=rFbq>qe>h?j(nF)m;)W9rGD@JrbqaSqJlLT +rH%dVr,qp\o6:"TqK_d\rHnNkr-eQns*suts+(0%rI[^qKnY89LPL\BM2I4LN/WaVO,oBbP*2#n +Q'I]'R$jD4S"6.BT:hmPUSO]^Vl-JmWiN5'Xfek3Z*L^B['d?N\%&uZ]">Vf]tXK\!PlPN_?%Qm +rl+oWs2Y,[s2k;`r6,,arltAdrm1Sjr6bMlrmUeprmh&"r7Cu$s4RA)s4dS/rS@M1!8mb5s5s5j7B!pAe2rosIJ!:0XNs6]jSrpTmV!:g$Ys766_rUp3as7cHdrqZTjqYU6hrVc +JcC<$JcF-tlMgVXqY^'ar;-BfqY:'arq?9_s7H?_rUU!Ys7$$V&FSrQm-O'(lKRQski_*jjlHF$ +@H-8(i8mJ:N-!IXQWlH[C'bH$FRXGBS+OFEDSFErL%ZE,Y_n!c;airbDRMBkdQ[ +!bZ+Wral+?s'u":s'bq8r*TG0ra#A*r*0,'p0%8pr)`VnrDieqpf%)gr))0Er)*Djq,@2jrDiYo +r)`btoi_)oqHNVtr*B8-qHs2/raG\5raYn;qdob=rFbq>qe>h?j(nF)m;)W9rGD@JrbqaSqJlLT +rH%dVr,qp\o6:"TqK_d\rHnNkr-eQns*suts+(0%rI[^qKnY89LPL\BM2I4LN/WaVO,oBbP*2#n +Q'I]'R$jD4S"6.BT:hmPUSO]^Vl-JmWiN5'Xfek3Z*L^B['d?N\%&uZ]">Vf]tXK\!PlPN_?%Qm +rl+oWs2Y,[s2k;`r6,,arltAdrm1Sjr6bMlrmUeprmh&"r7Cu$s4RA)s4dS/rS@M1!8mb5s5s5j7B!pAe2rosIJ!:0XNs6]jSrpTmV!:g$Ys766_rUp3as7cHdrqZTjqYU6hrVc +JcC<$JcF-tlMgVXqY^'ar;-BfqY:'arq?9_s7H?_rUU!Ys7$$V&FSrQm-O'(lKRQski_*jjlHF$ +@H-8(i8mJ:N-!IXQWlH[C'bH$FRXGBS+OFEDSFErL%ZE,Y_n!c;airbDRMBkdQ[ +!bZ+Wral+?s'u":s'bq8r*TG0ra#A*r*0,'p0%8pr)`VnrDieqpf%)gr))0Er)*Djq,@2jrDiYo +r)`btoi_)oqHNVtr*B8-qHs2/raG\5raYn;qdob=rFbq>qe>h?j(nF)m;)W9rGD@JrbqaSqJlLT +rH%dVr,qp\o6:"TqK_d\rHnNkr-eQns*suts+(0%rI[^qKnY89LPL\BM2I4LN/WaVO,oBbP*2#n +Q'I]'R$jD4S"6.BT:hmPUSO]^Vl-JmWiN5'Xfek3Z*L^B['d?N\%&uZ]">Vf]tXK\!PlPN_?%Qm +rl+oWs2Y,[s2k;`r6,,arltAdrm1Sjr6bMlrmUeprmh&"r7Cu$s4RA)s4dS/rS@M1!8mb5s5s5j7B!pAe2rosIJ!:0XNs6]jSrpTmV!:g$Ys766_rUp3as7cHdrqZTjqYU6hrVc +JcC<$JcF*slMgVXq>Bs`r;-BfqY:'as7ZB`s7H?_rUU!Y!:]sU!Uf@Slr*07lKRQskND!ijlGI^ +io/hRhqm2FgtUQ:g"=p.f%&:"e'cXkcd'h\bfe2PaiMQD`l5p8_ns7*^V@Lr]Y(kg]",A]\$i`Q +['R*EZ*:I9Y5YOFXK/A$WMl_mVPU,bUnaZXTqJ$LSt2FBS"#k7R$a5+rfmYOPEM)kOT(:JNfB!V +Mi*CKM26rdL'iWfK7ec,JUi9#If=`rI!bj=!I8qhG6)l0rcA0^ErL%`E,TZ4DJa6,rbMOK!,;FG +s(D@Dral+?s'u":s'bn7r*TG0ra#>)r*0)&p0%;qr)`YorDieqpf%)gr))BKqbd8hq,@5krDiVn +r)`euoNCunq-3Msr*B8-q-X,/rF,S4raYqe>mq_0&nn\/>rGDCKrGV[Sqf2RT +rc@mWrH8'^olp7WqK_a[r-SBiqgJHms*suts+13%re(6(!/:E,:PXa^M2@+JMiZa@-K[^WcW\[oDc]Y2%o^VI\%_SX4. +`;[^W`lH.!aT'B^b5KN`bl5lbcMu5id/25idf._meGn(uf)4/"f`0Y&gAfq-h#6%1hV[5hhu_ls +ir.m=jQ5M&k5XTEkl0iHlMp2Lm/QGQmf)\TnGi%Xo)J=]o_nI_pAambq#C0hqYL*gr;?Nardk*# +s*t~> +JcC<$JcF*slMgVXq>Bs`r;-BfqY:'as7ZB`s7H?_rUU!Y!:]sU!Uf@Slr*07lKRQskND!ijlGI^ +io/hRhqm2FgtUQ:g"=p.f%&:"e'cXkcd'h\bfe2PaiMQD`l5p8_ns7*^V@Lr]Y(kg]",A]\$i`Q +['R*EZ*:I9Y5YOFXK/A$WMl_mVPU,bUnaZXTqJ$LSt2FBS"#k7R$a5+rfmYOPEM)kOT(:JNfB!V +Mi*CKM26rdL'iWfK7ec,JUi9#If=`rI!bj=!I8qhG6)l0rcA0^ErL%`E,TZ4DJa6,rbMOK!,;FG +s(D@Dral+?s'u":s'bn7r*TG0ra#>)r*0)&p0%;qr)`YorDieqpf%)gr))BKqbd8hq,@5krDiVn +r)`euoNCunq-3Msr*B8-q-X,/rF,S4raYqe>mq_0&nn\/>rGDCKrGV[Sqf2RT +rc@mWrH8'^olp7WqK_a[r-SBiqgJHms*suts+13%re(6(!/:E,:PXa^M2@+JMiZa@-K[^WcW\[oDc]Y2%o^VI\%_SX4. +`;[^W`lH.!aT'B^b5KN`bl5lbcMu5id/25idf._meGn(uf)4/"f`0Y&gAfq-h#6%1hV[5hhu_ls +ir.m=jQ5M&k5XTEkl0iHlMp2Lm/QGQmf)\TnGi%Xo)J=]o_nI_pAambq#C0hqYL*gr;?Nardk*# +s*t~> +JcC<$JcF*slMgVXq>Bs`r;-BfqY:'as7ZB`s7H?_rUU!Y!:]sU!Uf@Slr*07lKRQskND!ijlGI^ +io/hRhqm2FgtUQ:g"=p.f%&:"e'cXkcd'h\bfe2PaiMQD`l5p8_ns7*^V@Lr]Y(kg]",A]\$i`Q +['R*EZ*:I9Y5YOFXK/A$WMl_mVPU,bUnaZXTqJ$LSt2FBS"#k7R$a5+rfmYOPEM)kOT(:JNfB!V +Mi*CKM26rdL'iWfK7ec,JUi9#If=`rI!bj=!I8qhG6)l0rcA0^ErL%`E,TZ4DJa6,rbMOK!,;FG +s(D@Dral+?s'u":s'bn7r*TG0ra#>)r*0)&p0%;qr)`YorDieqpf%)gr))BKqbd8hq,@5krDiVn +r)`euoNCunq-3Msr*B8-q-X,/rF,S4raYqe>mq_0&nn\/>rGDCKrGV[Sqf2RT +rc@mWrH8'^olp7WqK_a[r-SBiqgJHms*suts+13%re(6(!/:E,:PXa^M2@+JMiZa@-K[^WcW\[oDc]Y2%o^VI\%_SX4. +`;[^W`lH.!aT'B^b5KN`bl5lbcMu5id/25idf._meGn(uf)4/"f`0Y&gAfq-h#6%1hV[5hhu_ls +ir.m=jQ5M&k5XTEkl0iHlMp2Lm/QGQmf)\TnGi%Xo)J=]o_nI_pAambq#C0hqYL*gr;?Nardk*# +s*t~> +JcC<$JcF'rl2LMWqY^$`rVHKgqY:'arq?<`s7H?_rUU!Y!:^!Vs6]mSrp0jTlK[Wuki_s-:$(Hr +j5T%Ui8rF5b7s'Y_2ra,P/q-nrD`Pjr)3Dhk"tqPr)3;grD`_q +pf@;or)iSoq-*PtoN_<"rEf;,ra>_6qI9G6rabn;rFZ"@ph9P=bA-ZbrG;FLqJQ7Mrc%aSrc7sY +qK2[YrH@pZqfr!`oQpF^r-\?hs*jrsr.+fu!.t0%s+CB+re=C-LkpnEMMd=NN/`jYO-#KeP*;,q +Q'Rc(R$jD4S=Q7CT:qsQUSO``Vl-JnWiN5'Y-5(6Z*L^C[C3NQ\@K/]]=bei^;%Fu_84"*_o0L4 +`Q#pgrm:PirmLepqpbVqs47)!s4IA)r7_2*s4mS/s5*e5rSRb9io9ps +!p&J)roX7D!9jCG!p]+;rp9[Ps6fmTs6p$YrUU![s7H9_s7ZKerV6BfrqcNhrVZTlo)=4?JcC6~> +JcC<$JcF'rl2LMWqY^$`rVHKgqY:'arq?<`s7H?_rUU!Y!:^!Vs6]mSrp0jTlK[Wuki_s-:$(Hr +j5T%Ui8rF5b7s'Y_2ra,P/q-nrD`Pjr)3Dhk"tqPr)3;grD`_q +pf@;or)iSoq-*PtoN_<"rEf;,ra>_6qI9G6rabn;rFZ"@ph9P=bA-ZbrG;FLqJQ7Mrc%aSrc7sY +qK2[YrH@pZqfr!`oQpF^r-\?hs*jrsr.+fu!.t0%s+CB+re=C-LkpnEMMd=NN/`jYO-#KeP*;,q +Q'Rc(R$jD4S=Q7CT:qsQUSO``Vl-JnWiN5'Y-5(6Z*L^C[C3NQ\@K/]]=bei^;%Fu_84"*_o0L4 +`Q#pgrm:PirmLepqpbVqs47)!s4IA)r7_2*s4mS/s5*e5rSRb9io9ps +!p&J)roX7D!9jCG!p]+;rp9[Ps6fmTs6p$YrUU![s7H9_s7ZKerV6BfrqcNhrVZTlo)=4?JcC6~> +JcC<$JcF'rl2LMWqY^$`rVHKgqY:'arq?<`s7H?_rUU!Y!:^!Vs6]mSrp0jTlK[Wuki_s-:$(Hr +j5T%Ui8rF5b7s'Y_2ra,P/q-nrD`Pjr)3Dhk"tqPr)3;grD`_q +pf@;or)iSoq-*PtoN_<"rEf;,ra>_6qI9G6rabn;rFZ"@ph9P=bA-ZbrG;FLqJQ7Mrc%aSrc7sY +qK2[YrH@pZqfr!`oQpF^r-\?hs*jrsr.+fu!.t0%s+CB+re=C-LkpnEMMd=NN/`jYO-#KeP*;,q +Q'Rc(R$jD4S=Q7CT:qsQUSO``Vl-JnWiN5'Y-5(6Z*L^C[C3NQ\@K/]]=bei^;%Fu_84"*_o0L4 +`Q#pgrm:PirmLepqpbVqs47)!s4IA)r7_2*s4mS/s5*e5rSRb9io9ps +!p&J)roX7D!9jCG!p]+;rp9[Ps6fmTs6p$YrUU![s7H9_s7ZKerV6BfrqcNhrVZTlo)=4?JcC6~> +JcC<$JcF$ql2LJVqY^'ar;-BfqtU0brq?<`s7H?_rUL$[nF6GGs6]mSrp0[OlMg#Oki_*jjlHF$ +7H3:ai8r*o\7ra>V1rEfG.pg!`$r*&htr)io!q,[GorD`Pjr)3>fmnigWr)3;gr)EVp +pf@>pqcNJnpfdJto3D3!rEf;,ra>\5qdTP7rabk:rFZ%ApLsD;bA-]crG;FLqJQ:Nrc%aSrc8!Z +qK2^ZrH@s[r-8*aom6L^r-\_:P_o2Pn +!li:$rl>/_b0'\+s31MfrQbDgs3UYjrmLepqpbVqrmq#!rn.8(r7_2*rnRJ.s5*e5ro!h8s5O%< +s5a4AroX7Ds60IHs69UMrTjUQmdC)Cs7$'Yrpp*\s7H9_s7ZKer:p9es8)ThrVZWmnc"+>JcC6~> +JcC<$JcF$ql2LJVqY^'ar;-BfqtU0brq?<`s7H?_rUL$[nF6GGs6]mSrp0[OlMg#Oki_*jjlHF$ +7H3:ai8r*o\7ra>V1rEfG.pg!`$r*&htr)io!q,[GorD`Pjr)3>fmnigWr)3;gr)EVp +pf@>pqcNJnpfdJto3D3!rEf;,ra>\5qdTP7rabk:rFZ%ApLsD;bA-]crG;FLqJQ:Nrc%aSrc8!Z +qK2^ZrH@s[r-8*aom6L^r-\_:P_o2Pn +!li:$rl>/_b0'\+s31MfrQbDgs3UYjrmLepqpbVqrmq#!rn.8(r7_2*rnRJ.s5*e5ro!h8s5O%< +s5a4AroX7Ds60IHs69UMrTjUQmdC)Cs7$'Yrpp*\s7H9_s7ZKer:p9es8)ThrVZWmnc"+>JcC6~> +JcC<$JcF$ql2LJVqY^'ar;-BfqtU0brq?<`s7H?_rUL$[nF6GGs6]mSrp0[OlMg#Oki_*jjlHF$ +7H3:ai8r*o\7ra>V1rEfG.pg!`$r*&htr)io!q,[GorD`Pjr)3>fmnigWr)3;gr)EVp +pf@>pqcNJnpfdJto3D3!rEf;,ra>\5qdTP7rabk:rFZ%ApLsD;bA-]crG;FLqJQ:Nrc%aSrc8!Z +qK2^ZrH@s[r-8*aom6L^r-\_:P_o2Pn +!li:$rl>/_b0'\+s31MfrQbDgs3UYjrmLepqpbVqrmq#!rn.8(r7_2*rnRJ.s5*e5ro!h8s5O%< +s5a4AroX7Ds60IHs69UMrTjUQmdC)Cs7$'Yrpp*\s7H9_s7ZKer:p9es8)ThrVZWmnc"+>JcC6~> +JcC<$JcEsol2LJVqY^'arVHKgqtU0brq?<`s7H?_rUL$[nF6GG8FGm4m-O'(lKRQski_*jjlGI^ +io/kSi8KnTGX++f&oJ:E&tI=6KiH[:!`G^+FVG'.qLFE;JCEH,r:DuOYSD#eDOC]A,L +C&M]HB4bcSAcH<@A,Kg8@K'[2?iFC0?2%V%>Pq\"=oDJ$=8>nrj>a;>X8c;uK\o +Ou+t?2S%*?i=C3@JaO4A,^$9Ac66>BD?09C!(2bC]&#JD>J/LDuO_QEW1"X +F8L(YFo?L[GPl^`H1lR]Hi&3dIJnWoJ,FirJcC?#KE$T)L&Qi,LB*/0M$AiqMitQC+&-R[]e:SXuIHTqS3VUnsrdW2ZesX0&M,YHY:;Za7$H[^WcW\[oDc]Y2%o^VI\b_?%Qm +rl"oXa8X0[aT0K^b6#o4c2>leci;AhdJqYoe,%Snec+.sfDjM&g&0S(g]$",h>c@3hu2L5iW%p: +j8\3?jo4EBkPscFl2U#Kli$2Mm/ZSQmfN"Knbr%YoDeI]p&Facp\agdq>U6equ6NkrUTr=s+11M +s*t~> +JcC<$JcEsol2LJVqY^'arVHKgqtU0brq?<`s7H?_rUL$[nF6GG8FGm4m-O'(lKRQski_*jjlGI^ +io/kSi8KnTGX++f&oJ:E&tI=6KiH[:!`G^+FVG'.qLFE;JCEH,r:DuOYSD#eDOC]A,L +C&M]HB4bcSAcH<@A,Kg8@K'[2?iFC0?2%V%>Pq\"=oDJ$=8>nrj>a;>X8c;uK\o +Ou+t?2S%*?i=C3@JaO4A,^$9Ac66>BD?09C!(2bC]&#JD>J/LDuO_QEW1"X +F8L(YFo?L[GPl^`H1lR]Hi&3dIJnWoJ,FirJcC?#KE$T)L&Qi,LB*/0M$AiqMitQC+&-R[]e:SXuIHTqS3VUnsrdW2ZesX0&M,YHY:;Za7$H[^WcW\[oDc]Y2%o^VI\b_?%Qm +rl"oXa8X0[aT0K^b6#o4c2>leci;AhdJqYoe,%Snec+.sfDjM&g&0S(g]$",h>c@3hu2L5iW%p: +j8\3?jo4EBkPscFl2U#Kli$2Mm/ZSQmfN"Knbr%YoDeI]p&Facp\agdq>U6equ6NkrUTr=s+11M +s*t~> +JcC<$JcEsol2LJVqY^'arVHKgqtU0brq?<`s7H?_rUL$[nF6GG8FGm4m-O'(lKRQski_*jjlGI^ +io/kSi8KnTGX++f&oJ:E&tI=6KiH[:!`G^+FVG'.qLFE;JCEH,r:DuOYSD#eDOC]A,L +C&M]HB4bcSAcH<@A,Kg8@K'[2?iFC0?2%V%>Pq\"=oDJ$=8>nrj>a;>X8c;uK\o +Ou+t?2S%*?i=C3@JaO4A,^$9Ac66>BD?09C!(2bC]&#JD>J/LDuO_QEW1"X +F8L(YFo?L[GPl^`H1lR]Hi&3dIJnWoJ,FirJcC?#KE$T)L&Qi,LB*/0M$AiqMitQC+&-R[]e:SXuIHTqS3VUnsrdW2ZesX0&M,YHY:;Za7$H[^WcW\[oDc]Y2%o^VI\b_?%Qm +rl"oXa8X0[aT0K^b6#o4c2>leci;AhdJqYoe,%Snec+.sfDjM&g&0S(g]$",h>c@3hu2L5iW%p: +j8\3?jo4EBkPscFl2U#Kli$2Mm/ZSQmfN"Knbr%YoDeI]p&Facp\agdq>U6equ6NkrUTr=s+11M +s*t~> +JcC<$JcEpnkl1AUqY^*br;-EgqtU0brq?<`s7H?_rpp*Zs7$$V!Uf@Sliue@lKRQskPjU1jlGI^ +io/hRhqm2FgtUQ:g"=p.f%&:"e'cXkd*L"_c-4ASb/q`Ga2Z*;`5BI/_8*h#^:h1l]=YYb\[],W +[^ELAZN[Y>Yct=6riH@*X/`2!W;`\-VPU)aUS=HUTV.pKSt2C@S!ocEQj&hBQ'IStrfRbROH5H_ +NJrgSMi*@JLkkta$AF.cK7\Z*J:N,urd=fpHiAVm!c;airbDRM +BkdNZ!bZ+WrFQ">raYk8raGe6qHs2-r*B&%r*0,'pf[PtrE&hrrDieqpJ^lcmnrpZp/Cohr)NMm +rE&kuoNColpKR5oqd'/,q-X,/rF,S4raYqc!6tJfs3L\kr6bPmrmUbormgtuqq(i"s4R;'s4dP.rS@M1rnm\4s5F"; +ro=%>s5j7Bs6'FGrosIJs6K[Ns6]jSrpTmVs7-*Zs7?9_rUp3as7cHdrqZQiqtp?ir;H3cJcC<$ +!<7Q~> +JcC<$JcEpnkl1AUqY^*br;-EgqtU0brq?<`s7H?_rpp*Zs7$$V!Uf@Sliue@lKRQskPjU1jlGI^ +io/hRhqm2FgtUQ:g"=p.f%&:"e'cXkd*L"_c-4ASb/q`Ga2Z*;`5BI/_8*h#^:h1l]=YYb\[],W +[^ELAZN[Y>Yct=6riH@*X/`2!W;`\-VPU)aUS=HUTV.pKSt2C@S!ocEQj&hBQ'IStrfRbROH5H_ +NJrgSMi*@JLkkta$AF.cK7\Z*J:N,urd=fpHiAVm!c;airbDRM +BkdNZ!bZ+WrFQ">raYk8raGe6qHs2-r*B&%r*0,'pf[PtrE&hrrDieqpJ^lcmnrpZp/Cohr)NMm +rE&kuoNColpKR5oqd'/,q-X,/rF,S4raYqc!6tJfs3L\kr6bPmrmUbormgtuqq(i"s4R;'s4dP.rS@M1rnm\4s5F"; +ro=%>s5j7Bs6'FGrosIJs6K[Ns6]jSrpTmVs7-*Zs7?9_rUp3as7cHdrqZQiqtp?ir;H3cJcC<$ +!<7Q~> +JcC<$JcEpnkl1AUqY^*br;-EgqtU0brq?<`s7H?_rpp*Zs7$$V!Uf@Sliue@lKRQskPjU1jlGI^ +io/hRhqm2FgtUQ:g"=p.f%&:"e'cXkd*L"_c-4ASb/q`Ga2Z*;`5BI/_8*h#^:h1l]=YYb\[],W +[^ELAZN[Y>Yct=6riH@*X/`2!W;`\-VPU)aUS=HUTV.pKSt2C@S!ocEQj&hBQ'IStrfRbROH5H_ +NJrgSMi*@JLkkta$AF.cK7\Z*J:N,urd=fpHiAVm!c;airbDRM +BkdNZ!bZ+WrFQ">raYk8raGe6qHs2-r*B&%r*0,'pf[PtrE&hrrDieqpJ^lcmnrpZp/Cohr)NMm +rE&kuoNColpKR5oqd'/,q-X,/rF,S4raYqc!6tJfs3L\kr6bPmrmUbormgtuqq(i"s4R;'s4dP.rS@M1rnm\4s5F"; +ro=%>s5j7Bs6'FGrosIJs6K[Ns6]jSrpTmVs7-*Zs7?9_rUp3as7cHdrqZQiqtp?ir;H3cJcC<$ +!<7Q~> +JcC<$JcEjlkl1AUqu$0brVHKgqtU3crq?<`s7H?_rpp*Z!:^!Vs6]mSrp0[OlMg$8ki_*jjlGL_ +j5T%Ui8`Pf[2_SO%&^V7Cp]Y(kf\[f5Z +rjEWN['R*EZ*CO;YHG"0XK/D%Wi;qpVl$l@n)>5;>#=T)=s`;ZBVd;YF&e<;fhl +4u1k>l.h*?MRt,@/aU3@f9g9AGTm:B)QB9B_Z<.C?fO.CA;TCD#J5JDZ4SSE;OYS +ErU4XFT-F^G5?F^Gl;p_HMi-fI.r'eIf4cnJGt-"K)C9$K`?c*LB!&/M#N53MMqIm!KE-=O#iAb +P*2#nQ'IZ%R$a;1S"#t?StD[LU8+N[V5C/hWN*##Xf\b1Yd(L?ZaI6M\%&uZ]"G\h^;%Fu_>_:Z +_o0O5`lH-@aN;QHrlb>cs3:Pgs3L_lr6bMls3pkprmh#!qUb`!rn75'rnIG-rS@J0s53e5s5F"; +rT!q=s5j7Bs6'FGrosIJs6K[Ns6]jSrpTmVs7-'Ys7?9_rUp3as7cHds7uZjqYU6hrVc9cJcC<$ +!<7Q~> +JcC<$JcEjlkl1AUqu$0brVHKgqtU3crq?<`s7H?_rpp*Z!:^!Vs6]mSrp0[OlMg$8ki_*jjlGL_ +j5T%Ui8`Pf[2_SO%&^V7Cp]Y(kf\[f5Z +rjEWN['R*EZ*CO;YHG"0XK/D%Wi;qpVl$l@n)>5;>#=T)=s`;ZBVd;YF&e<;fhl +4u1k>l.h*?MRt,@/aU3@f9g9AGTm:B)QB9B_Z<.C?fO.CA;TCD#J5JDZ4SSE;OYS +ErU4XFT-F^G5?F^Gl;p_HMi-fI.r'eIf4cnJGt-"K)C9$K`?c*LB!&/M#N53MMqIm!KE-=O#iAb +P*2#nQ'IZ%R$a;1S"#t?StD[LU8+N[V5C/hWN*##Xf\b1Yd(L?ZaI6M\%&uZ]"G\h^;%Fu_>_:Z +_o0O5`lH-@aN;QHrlb>cs3:Pgs3L_lr6bMls3pkprmh#!qUb`!rn75'rnIG-rS@J0s53e5s5F"; +rT!q=s5j7Bs6'FGrosIJs6K[Ns6]jSrpTmVs7-'Ys7?9_rUp3as7cHds7uZjqYU6hrVc9cJcC<$ +!<7Q~> +JcC<$JcEjlkl1AUqu$0brVHKgqtU3crq?<`s7H?_rpp*Z!:^!Vs6]mSrp0[OlMg$8ki_*jjlGL_ +j5T%Ui8`Pf[2_SO%&^V7Cp]Y(kf\[f5Z +rjEWN['R*EZ*CO;YHG"0XK/D%Wi;qpVl$l@n)>5;>#=T)=s`;ZBVd;YF&e<;fhl +4u1k>l.h*?MRt,@/aU3@f9g9AGTm:B)QB9B_Z<.C?fO.CA;TCD#J5JDZ4SSE;OYS +ErU4XFT-F^G5?F^Gl;p_HMi-fI.r'eIf4cnJGt-"K)C9$K`?c*LB!&/M#N53MMqIm!KE-=O#iAb +P*2#nQ'IZ%R$a;1S"#t?StD[LU8+N[V5C/hWN*##Xf\b1Yd(L?ZaI6M\%&uZ]"G\h^;%Fu_>_:Z +_o0O5`lH-@aN;QHrlb>cs3:Pgs3L_lr6bMls3pkprmh#!qUb`!rn75'rnIG-rS@J0s53e5s5F"; +rT!q=s5j7Bs6'FGrosIJs6K[Ns6]jSrpTmVs7-'Ys7?9_rUp3as7cHds7uZjqYU6hrVc9cJcC<$ +!<7Q~> +JcC<$JcEjlkPk8TqY^*brVHKgqtU3cs7ZB`s7H?_rpp*Z!:^!Vs6]mSrp0[OlMg#Oki_*jjlHF$ +2WE]Ri8`Pf[2_SO%'^V@Lr]Y(kfrj`3B +\$i`Q[/RBJZE^XfmS`[Ur)ESopf@;o +r)iSopKI8pnQbrsr*K5,rF#V5qI9G6rabk:rau(@pLs;8n7q*"q.fY>rbVOMqelFPrc%dTrc8!Z +r,hp\rc\0_rcnBeq0N!dr-\6erI4ZoqLJQrrdt'#s+LE+rItB/Lku%es,$f7repl;NrG)#OHG]h +PE_>tQC!u+R@9V7S=Q7DTV8'RUnjiaVl-MoWiN8(Y-5(7ZEpmE[C3QS\[f;`]Y(tn^VI\b_?Iiq +`Poj;rl>/_b0'_,!mJp6rm(Pis3U_lrmLhqqpbVqrmpturRh,&qqD&(s4mM-s5*e5r8@V6s5O"; +s5a4AroX7Ds60FG!p]+;rTjUQmdC&Bs6p$YrUU![s7H9_s7ZHdrV6BfrqcNhrVZTlo)=4?JcGcM +J,~> +JcC<$JcEjlkPk8TqY^*brVHKgqtU3cs7ZB`s7H?_rpp*Z!:^!Vs6]mSrp0[OlMg#Oki_*jjlHF$ +2WE]Ri8`Pf[2_SO%'^V@Lr]Y(kfrj`3B +\$i`Q[/RBJZE^XfmS`[Ur)ESopf@;o +r)iSopKI8pnQbrsr*K5,rF#V5qI9G6rabk:rau(@pLs;8n7q*"q.fY>rbVOMqelFPrc%dTrc8!Z +r,hp\rc\0_rcnBeq0N!dr-\6erI4ZoqLJQrrdt'#s+LE+rItB/Lku%es,$f7repl;NrG)#OHG]h +PE_>tQC!u+R@9V7S=Q7DTV8'RUnjiaVl-MoWiN8(Y-5(7ZEpmE[C3QS\[f;`]Y(tn^VI\b_?Iiq +`Poj;rl>/_b0'_,!mJp6rm(Pis3U_lrmLhqqpbVqrmpturRh,&qqD&(s4mM-s5*e5r8@V6s5O"; +s5a4AroX7Ds60FG!p]+;rTjUQmdC&Bs6p$YrUU![s7H9_s7ZHdrV6BfrqcNhrVZTlo)=4?JcGcM +J,~> +JcC<$JcEjlkPk8TqY^*brVHKgqtU3cs7ZB`s7H?_rpp*Z!:^!Vs6]mSrp0[OlMg#Oki_*jjlHF$ +2WE]Ri8`Pf[2_SO%'^V@Lr]Y(kfrj`3B +\$i`Q[/RBJZE^XfmS`[Ur)ESopf@;o +r)iSopKI8pnQbrsr*K5,rF#V5qI9G6rabk:rau(@pLs;8n7q*"q.fY>rbVOMqelFPrc%dTrc8!Z +r,hp\rc\0_rcnBeq0N!dr-\6erI4ZoqLJQrrdt'#s+LE+rItB/Lku%es,$f7repl;NrG)#OHG]h +PE_>tQC!u+R@9V7S=Q7DTV8'RUnjiaVl-MoWiN8(Y-5(7ZEpmE[C3QS\[f;`]Y(tn^VI\b_?Iiq +`Poj;rl>/_b0'_,!mJp6rm(Pis3U_lrmLhqqpbVqrmpturRh,&qqD&(s4mM-s5*e5r8@V6s5O"; +s5a4AroX7Ds60FG!p]+;rTjUQmdC&Bs6p$YrUU![s7H9_s7ZHdrV6BfrqcNhrVZTlo)=4?JcGcM +J,~> +JcC<$JcEdjkPk8Tqu$3crVHKgqtU3cs7ZB`!qc*UrUL$[nF6GG$h!ELm-O''lKRQskPjTQjlGI^ +io/hRhqm2FgtVh^*SK)sf@JL%eC2jndEp4bcHXSVbK@rJaN)<>`Pf[n_@FDt^V@Lr]Y(kg]",A] +\,NfY[C!9HZE^[=Yck43XfSS(WiE%sVl-DgV50o^U7n9RTDkDpSXc1=R[KP1Q^3r&Q'@JqP*(k* +Nt.20N/W[PM2@%ELPCP;K`6T2Jq8H&IsuipI=-D@H3&;9rc\BdFoHL_Er^7[E<:)tDuOVUD/=%f +C]A/LC&M`FBE)TAAcHQ.h%=oMP%=8GtqOYnp?2S%)?iFI4@JXI4A,^$8Ac66>BD-$2C&)N$C&2T>C]8/KD>S5NDuO_REW1"YF8U.Z +FoHR^GQ)jcH2;jcHi8?eIJeQlJ,+WoJc:8uKE$W)L&Hc+L]<20M#rQmMuJY9NK4"!6]dFnP*;,q +Q'Rc(R$jD4S"-%@StD^MU8+N[VPg>jWN*##Xf\e2Yd(L?['d?N\@K/]]=bei^;%Fu_8=(,`5T^8 +a8X-\aiaV+s3(Jfrm(Pis3U_ls3gnqr7(_rrmpturn.2&qqD&(rnRG-rnd\4r8@V6s5O";s5a4A +rT=.Cs60FG!p]+;rTsRO!:KgSs7$'YrUL$]o^r(Ss7ZKer:p9es8)ThrVZTlo)=4?JcGcMJ,~> +JcC<$JcEdjkPk8Tqu$3crVHKgqtU3cs7ZB`!qc*UrUL$[nF6GG$h!ELm-O''lKRQskPjTQjlGI^ +io/hRhqm2FgtVh^*SK)sf@JL%eC2jndEp4bcHXSVbK@rJaN)<>`Pf[n_@FDt^V@Lr]Y(kg]",A] +\,NfY[C!9HZE^[=Yck43XfSS(WiE%sVl-DgV50o^U7n9RTDkDpSXc1=R[KP1Q^3r&Q'@JqP*(k* +Nt.20N/W[PM2@%ELPCP;K`6T2Jq8H&IsuipI=-D@H3&;9rc\BdFoHL_Er^7[E<:)tDuOVUD/=%f +C]A/LC&M`FBE)TAAcHQ.h%=oMP%=8GtqOYnp?2S%)?iFI4@JXI4A,^$8Ac66>BD-$2C&)N$C&2T>C]8/KD>S5NDuO_REW1"YF8U.Z +FoHR^GQ)jcH2;jcHi8?eIJeQlJ,+WoJc:8uKE$W)L&Hc+L]<20M#rQmMuJY9NK4"!6]dFnP*;,q +Q'Rc(R$jD4S"-%@StD^MU8+N[VPg>jWN*##Xf\e2Yd(L?['d?N\@K/]]=bei^;%Fu_8=(,`5T^8 +a8X-\aiaV+s3(Jfrm(Pis3U_ls3gnqr7(_rrmpturn.2&qqD&(rnRG-rnd\4r8@V6s5O";s5a4A +rT=.Cs60FG!p]+;rTsRO!:KgSs7$'YrUL$]o^r(Ss7ZKer:p9es8)ThrVZTlo)=4?JcGcMJ,~> +JcC<$JcEdjkPk8Tqu$3crVHKgqtU3cs7ZB`!qc*UrUL$[nF6GG$h!ELm-O''lKRQskPjTQjlGI^ +io/hRhqm2FgtVh^*SK)sf@JL%eC2jndEp4bcHXSVbK@rJaN)<>`Pf[n_@FDt^V@Lr]Y(kg]",A] +\,NfY[C!9HZE^[=Yck43XfSS(WiE%sVl-DgV50o^U7n9RTDkDpSXc1=R[KP1Q^3r&Q'@JqP*(k* +Nt.20N/W[PM2@%ELPCP;K`6T2Jq8H&IsuipI=-D@H3&;9rc\BdFoHL_Er^7[E<:)tDuOVUD/=%f +C]A/LC&M`FBE)TAAcHQ.h%=oMP%=8GtqOYnp?2S%)?iFI4@JXI4A,^$8Ac66>BD-$2C&)N$C&2T>C]8/KD>S5NDuO_REW1"YF8U.Z +FoHR^GQ)jcH2;jcHi8?eIJeQlJ,+WoJc:8uKE$W)L&Hc+L]<20M#rQmMuJY9NK4"!6]dFnP*;,q +Q'Rc(R$jD4S"-%@StD^MU8+N[VPg>jWN*##Xf\e2Yd(L?['d?N\@K/]]=bei^;%Fu_8=(,`5T^8 +a8X-\aiaV+s3(Jfrm(Pis3U_ls3gnqr7(_rrmpturn.2&qqD&(rnRG-rnd\4r8@V6s5O";s5a4A +rT=.Cs60FG!p]+;rTsRO!:KgSs7$'YrUL$]o^r(Ss7ZKer:p9es8)ThrVZTlo)=4?JcGcMJ,~> +JcC<$JcE^hkPk8Tqu$3crVHNhqtU3cs7ZB`!qc*UrUL$[nF6GG!Uf@SliHG;rol`4kN:pgjlGI^ +io/hRhqm2FgtUQ:g"=p.f%&:"e'cXkd*U+acHXSVbK@rJaN)<>`Pf[3_SX.)^V@Lr]tD"i])K5R +\@8oT[C!FMM[1GLPCP;KnP)2JqA,9[5@JsU/?i47/?27b(>Q.h&=oDJ%=8>nqOGbn?2S%)?i=C3@JaO4A,^$8Ac?<>BD-#^C&2T>C]8/LD>S5MDuXeSEW1"YF8U.ZFoQX^ +GQ2peH2;jdHi8?eIJnWmJ,"QnJc12tKE$W(L&Hc+L]<20M>rG5MuJ\8N<#"Vf]tV7r^qmn)_o0O5`lJ)" +!QiL`b6#o4c2Puicd:&;dJqYpe,7_pec+.sfDaG%g%sG%g]$"*h>Z:2hu)F3iW%p9j8\3?jo+?A +kPscEklU/9li$2MmJlVRn,MnWnbr%YoDeI]p&Fabp\jmdq>U6equ-HkrUKl +JcC<$JcE^hkPk8Tqu$3crVHNhqtU3cs7ZB`!qc*UrUL$[nF6GG!Uf@SliHG;rol`4kN:pgjlGI^ +io/hRhqm2FgtUQ:g"=p.f%&:"e'cXkd*U+acHXSVbK@rJaN)<>`Pf[3_SX.)^V@Lr]tD"i])K5R +\@8oT[C!FMM[1GLPCP;KnP)2JqA,9[5@JsU/?i47/?27b(>Q.h&=oDJ%=8>nqOGbn?2S%)?i=C3@JaO4A,^$8Ac?<>BD-#^C&2T>C]8/LD>S5MDuXeSEW1"YF8U.ZFoQX^ +GQ2peH2;jdHi8?eIJnWmJ,"QnJc12tKE$W(L&Hc+L]<20M>rG5MuJ\8N<#"Vf]tV7r^qmn)_o0O5`lJ)" +!QiL`b6#o4c2Puicd:&;dJqYpe,7_pec+.sfDaG%g%sG%g]$"*h>Z:2hu)F3iW%p9j8\3?jo+?A +kPscEklU/9li$2MmJlVRn,MnWnbr%YoDeI]p&Fabp\jmdq>U6equ-HkrUKl +JcC<$JcE^hkPk8Tqu$3crVHNhqtU3cs7ZB`!qc*UrUL$[nF6GG!Uf@SliHG;rol`4kN:pgjlGI^ +io/hRhqm2FgtUQ:g"=p.f%&:"e'cXkd*U+acHXSVbK@rJaN)<>`Pf[3_SX.)^V@Lr]tD"i])K5R +\@8oT[C!FMM[1GLPCP;KnP)2JqA,9[5@JsU/?i47/?27b(>Q.h&=oDJ%=8>nqOGbn?2S%)?i=C3@JaO4A,^$8Ac?<>BD-#^C&2T>C]8/LD>S5MDuXeSEW1"YF8U.ZFoQX^ +GQ2peH2;jdHi8?eIJnWmJ,"QnJc12tKE$W(L&Hc+L]<20M>rG5MuJ\8N<#"Vf]tV7r^qmn)_o0O5`lJ)" +!QiL`b6#o4c2Puicd:&;dJqYpe,7_pec+.sfDaG%g%sG%g]$"*h>Z:2hu)F3iW%p9j8\3?jo+?A +kPscEklU/9li$2MmJlVRn,MnWnbr%YoDeI]p&Fabp\jmdq>U6equ-HkrUKl +JcC<$JcE[gk5P2Tqu$3crqcThr:p9cs7ZEas7H?_rpp*Z!:^!V&FSrQm-O'(lKRQski_*jjlHF$ +)<0W5i8bKJ&MaN2EArl#&Z_ns:,_#D(U^:h1l]=YYb +\[]-J[L0FLZa6sCZ*:I9Y5YO,XK/A$WMofo&uMM$UnaZXTqJ'NSt;LCS"#k7rg4"YQBd`"PEM)k +OT(:NNfB!VMi*@JLkph@L4t<[K*m3]J:N,uIXQWlHiAAGp$7@f9a6@/++-?N"1*>lIt+>5DD$=T)=ttp<9R9W<;]bj4Ytb>l.h)?MRt,@/aU2@fBm:AGTm9B)QB9BZb&dCA;TDD#S;KDZ=YSE;X_UErL.YFT-F_ +G5QR`GlE!cHN&9jI//3hIf+]jJGk&uK)1-!K`?c(LB!&/M#E/3MMmDlN!kW*NfT6_OHG]hPEc'3 +7$a1,R$jD4S"-(AT:hmOU8+N\VPg>kWiE,$Xfek3Yd1UA['d?O\@K/]]Y(ql^V@S#_SX4/`Poj; +aN2KFb0.uPbg$.4s3C\lrR(Yns3pqrrmh&"qq(f!rn7/%rnIG-qVD2.rnmY3ro*n:r8[h +JcC<$JcE[gk5P2Tqu$3crqcThr:p9cs7ZEas7H?_rpp*Z!:^!V&FSrQm-O'(lKRQski_*jjlHF$ +)<0W5i8bKJ&MaN2EArl#&Z_ns:,_#D(U^:h1l]=YYb +\[]-J[L0FLZa6sCZ*:I9Y5YO,XK/A$WMofo&uMM$UnaZXTqJ'NSt;LCS"#k7rg4"YQBd`"PEM)k +OT(:NNfB!VMi*@JLkph@L4t<[K*m3]J:N,uIXQWlHiAAGp$7@f9a6@/++-?N"1*>lIt+>5DD$=T)=ttp<9R9W<;]bj4Ytb>l.h)?MRt,@/aU2@fBm:AGTm9B)QB9BZb&dCA;TDD#S;KDZ=YSE;X_UErL.YFT-F_ +G5QR`GlE!cHN&9jI//3hIf+]jJGk&uK)1-!K`?c(LB!&/M#E/3MMmDlN!kW*NfT6_OHG]hPEc'3 +7$a1,R$jD4S"-(AT:hmOU8+N\VPg>kWiE,$Xfek3Yd1UA['d?O\@K/]]Y(ql^V@S#_SX4/`Poj; +aN2KFb0.uPbg$.4s3C\lrR(Yns3pqrrmh&"qq(f!rn7/%rnIG-qVD2.rnmY3ro*n:r8[h +JcC<$JcE[gk5P2Tqu$3crqcThr:p9cs7ZEas7H?_rpp*Z!:^!V&FSrQm-O'(lKRQski_*jjlHF$ +)<0W5i8bKJ&MaN2EArl#&Z_ns:,_#D(U^:h1l]=YYb +\[]-J[L0FLZa6sCZ*:I9Y5YO,XK/A$WMofo&uMM$UnaZXTqJ'NSt;LCS"#k7rg4"YQBd`"PEM)k +OT(:NNfB!VMi*@JLkph@L4t<[K*m3]J:N,uIXQWlHiAAGp$7@f9a6@/++-?N"1*>lIt+>5DD$=T)=ttp<9R9W<;]bj4Ytb>l.h)?MRt,@/aU2@fBm:AGTm9B)QB9BZb&dCA;TDD#S;KDZ=YSE;X_UErL.YFT-F_ +G5QR`GlE!cHN&9jI//3hIf+]jJGk&uK)1-!K`?c(LB!&/M#E/3MMmDlN!kW*NfT6_OHG]hPEc'3 +7$a1,R$jD4S"-(AT:hmOU8+N\VPg>kWiE,$Xfek3Yd1UA['d?O\@K/]]Y(ql^V@S#_SX4/`Poj; +aN2KFb0.uPbg$.4s3C\lrR(Yns3pqrrmh&"qq(f!rn7/%rnIG-qVD2.rnmY3ro*n:r8[h +JcC<$JcEXfk5P2TqY^-crVHNhr:p9cs7ZEas7H?_rpg-\nF6GG'^kAUm-O'(lKRQskND!ijlGI^ +io0mp(#Rm(h;$c=g=b-1f@JL%eC2jndEp5=c5b*QbKJ&MaN2EA`l5p8_ns:,_8*h#^:h4m]XtcS +\I,jU[^NTO['R*EZ2Us;YHG"0XK/D%Wi;qpVl$7K7ec,rdYQ0IXQWlI!^0cH$OXYGBS.PrcA3_EcV/!!cW'rrbhaQ +s(q[Ms(_RJr+Q+Crau(>rFGn;q-s;2r*]>-rEfG.qHX#(rEB)$rE0&#pf@;mqGcu`pf./kpK%2n +r)iVpq-*Aol!4*kr*K2+rF#V5qI9G6rabk:rFZ"@ok;N_qeGnArbVRNr,2LPs)@mUrc8$[r,hs] +s*"OA(e"P*;,p +Q'IZ%R$a;1S"#q=St;UKTq\Vf^;%Fu_8=(,`5T^8 +a2l?Dai_fMbfn?2c2u>=d/MGmdf7epeGn(uf)4/!f`'S#gATe*h"ok+hYuF1i;V^8ir%j:jT"?> +k5XWEkl'cGl2^/Km/QJQmeuVSnGi%Wo)J=]o_nI_pAXgaq#C0hqYL*fr;?Nardk*#s8N%K~> +JcC<$JcEXfk5P2TqY^-crVHNhr:p9cs7ZEas7H?_rpg-\nF6GG'^kAUm-O'(lKRQskND!ijlGI^ +io0mp(#Rm(h;$c=g=b-1f@JL%eC2jndEp5=c5b*QbKJ&MaN2EA`l5p8_ns:,_8*h#^:h4m]XtcS +\I,jU[^NTO['R*EZ2Us;YHG"0XK/D%Wi;qpVl$7K7ec,rdYQ0IXQWlI!^0cH$OXYGBS.PrcA3_EcV/!!cW'rrbhaQ +s(q[Ms(_RJr+Q+Crau(>rFGn;q-s;2r*]>-rEfG.qHX#(rEB)$rE0&#pf@;mqGcu`pf./kpK%2n +r)iVpq-*Aol!4*kr*K2+rF#V5qI9G6rabk:rFZ"@ok;N_qeGnArbVRNr,2LPs)@mUrc8$[r,hs] +s*"OA(e"P*;,p +Q'IZ%R$a;1S"#q=St;UKTq\Vf^;%Fu_8=(,`5T^8 +a2l?Dai_fMbfn?2c2u>=d/MGmdf7epeGn(uf)4/!f`'S#gATe*h"ok+hYuF1i;V^8ir%j:jT"?> +k5XWEkl'cGl2^/Km/QJQmeuVSnGi%Wo)J=]o_nI_pAXgaq#C0hqYL*fr;?Nardk*#s8N%K~> +JcC<$JcEXfk5P2TqY^-crVHNhr:p9cs7ZEas7H?_rpg-\nF6GG'^kAUm-O'(lKRQskND!ijlGI^ +io0mp(#Rm(h;$c=g=b-1f@JL%eC2jndEp5=c5b*QbKJ&MaN2EA`l5p8_ns:,_8*h#^:h4m]XtcS +\I,jU[^NTO['R*EZ2Us;YHG"0XK/D%Wi;qpVl$7K7ec,rdYQ0IXQWlI!^0cH$OXYGBS.PrcA3_EcV/!!cW'rrbhaQ +s(q[Ms(_RJr+Q+Crau(>rFGn;q-s;2r*]>-rEfG.qHX#(rEB)$rE0&#pf@;mqGcu`pf./kpK%2n +r)iVpq-*Aol!4*kr*K2+rF#V5qI9G6rabk:rFZ"@ok;N_qeGnArbVRNr,2LPs)@mUrc8$[r,hs] +s*"OA(e"P*;,p +Q'IZ%R$a;1S"#q=St;UKTq\Vf^;%Fu_8=(,`5T^8 +a2l?Dai_fMbfn?2c2u>=d/MGmdf7epeGn(uf)4/!f`'S#gATe*h"ok+hYuF1i;V^8ir%j:jT"?> +k5XWEkl'cGl2^/Km/QJQmeuVSnGi%Wo)J=]o_nI_pAXgaq#C0hqYL*fr;?Nardk*#s8N%K~> +JcC<$JcERdk5P2Tqu$6drVHNhr:p9cs7ZEas7?<_rUL$[nF6GG!Uf@SliHG;rojIIkPjTMjlGI^ +io/hRhqn@g)Vj*$g=b-1f@JL%eC2jndEp4ccHa\YbKJ&Mrl>8``l5p8_u@LR_8-&b&&,`i]Xtee +\[f5Z\$i`Q[/RBJZE^X#*=t0P*2#nrfp'@ +Q^F/.R[]e:SXuFFTV8*TUnjiaVl6SpWiN8(Y-5(7ZEpmF[^NZT\[oDc]Y2%o^qmn)_o0O5`lH0A +aiV]KbKS5UcHab^d/MGmdf7epeGn)!f)4/!f`'S#gA]k*h"ok+hYuF0i;V^7ir.p:jT"??k5XWD +kl'cGlMp2Lm/QJQmeuVSnGi%Wo)J=]o_nI^pAambq#:*gqYL*fr;?Nardk*#s8N%K~> +JcC<$JcERdk5P2Tqu$6drVHNhr:p9cs7ZEas7?<_rUL$[nF6GG!Uf@SliHG;rojIIkPjTMjlGI^ +io/hRhqn@g)Vj*$g=b-1f@JL%eC2jndEp4ccHa\YbKJ&Mrl>8``l5p8_u@LR_8-&b&&,`i]Xtee +\[f5Z\$i`Q[/RBJZE^X#*=t0P*2#nrfp'@ +Q^F/.R[]e:SXuFFTV8*TUnjiaVl6SpWiN8(Y-5(7ZEpmF[^NZT\[oDc]Y2%o^qmn)_o0O5`lH0A +aiV]KbKS5UcHab^d/MGmdf7epeGn)!f)4/!f`'S#gA]k*h"ok+hYuF0i;V^7ir.p:jT"??k5XWD +kl'cGlMp2Lm/QJQmeuVSnGi%Wo)J=]o_nI^pAambq#:*gqYL*fr;?Nardk*#s8N%K~> +JcC<$JcERdk5P2Tqu$6drVHNhr:p9cs7ZEas7?<_rUL$[nF6GG!Uf@SliHG;rojIIkPjTMjlGI^ +io/hRhqn@g)Vj*$g=b-1f@JL%eC2jndEp4ccHa\YbKJ&Mrl>8``l5p8_u@LR_8-&b&&,`i]Xtee +\[f5Z\$i`Q[/RBJZE^X#*=t0P*2#nrfp'@ +Q^F/.R[]e:SXuFFTV8*TUnjiaVl6SpWiN8(Y-5(7ZEpmF[^NZT\[oDc]Y2%o^qmn)_o0O5`lH0A +aiV]KbKS5UcHab^d/MGmdf7epeGn)!f)4/!f`'S#gA]k*h"ok+hYuF0i;V^7ir.p:jT"??k5XWD +kl'cGlMp2Lm/QJQmeuVSnGi%Wo)J=]o_nI^pAambq#:*gqYL*fr;?Nardk*#s8N%K~> +JcC<$JcELbk5P2Tr;??erVHNhr:p)qcWl"rE&bppf6udpf6ufr)`eu +p0%2poipE\qd',+pg=#.rF,S4rF>h;qITV;rFbe:b\?rhq.otGrb_OMs)7mUrGhjXrcA$[s)n?b +r-/0cs*=Ngrd4Wlr-eNmrdXcprIOp!q1JX!re:6(reLN0r/(H2s,6l8s,I&=rf7)AOoCLEPEc'3 +3gQ,"R$jD4S"-%@StD[LTq\?YV5C/gW2ckuXKAY/YctC=Za@-K\%&uZ]"G\h^;%Fu_8=+.`Poj; +rl>Jhb0.uPc-=PZcd:&Z:0htu@2iW%p7j8\3?jo"9@ +kPscEl2U&Kli$2MmJlVQn,MnWnbr%YoDeI\p&Fabp\agdq>U6equ-HjrUKl +JcC<$JcELbk5P2Tr;??erVHNhr:p)qcWl"rE&bppf6udpf6ufr)`eu +p0%2poipE\qd',+pg=#.rF,S4rF>h;qITV;rFbe:b\?rhq.otGrb_OMs)7mUrGhjXrcA$[s)n?b +r-/0cs*=Ngrd4Wlr-eNmrdXcprIOp!q1JX!re:6(reLN0r/(H2s,6l8s,I&=rf7)AOoCLEPEc'3 +3gQ,"R$jD4S"-%@StD[LTq\?YV5C/gW2ckuXKAY/YctC=Za@-K\%&uZ]"G\h^;%Fu_8=+.`Poj; +rl>Jhb0.uPc-=PZcd:&Z:0htu@2iW%p7j8\3?jo"9@ +kPscEl2U&Kli$2MmJlVQn,MnWnbr%YoDeI\p&Fabp\agdq>U6equ-HjrUKl +JcC<$JcELbk5P2Tr;??erVHNhr:p)qcWl"rE&bppf6udpf6ufr)`eu +p0%2poipE\qd',+pg=#.rF,S4rF>h;qITV;rFbe:b\?rhq.otGrb_OMs)7mUrGhjXrcA$[s)n?b +r-/0cs*=Ngrd4Wlr-eNmrdXcprIOp!q1JX!re:6(reLN0r/(H2s,6l8s,I&=rf7)AOoCLEPEc'3 +3gQ,"R$jD4S"-%@StD[LTq\?YV5C/gW2ckuXKAY/YctC=Za@-K\%&uZ]"G\h^;%Fu_8=+.`Poj; +rl>Jhb0.uPc-=PZcd:&Z:0htu@2iW%p7j8\3?jo"9@ +kPscEl2U&Kli$2MmJlVQn,MnWnbr%YoDeI\p&Fabp\agdq>U6equ-HjrUKl +JcC<$JcEIak5P2Tqu$9erVHNhr:plIt+>5MJ$=T)=ono +>4u1X>l%b(?MIn,@/XO2@f9g9AGTm9B)QB8B[(8gCA;TDD#S;LDZ=YSE;aeVErL.YFT6L`G5ZXa +GlN'fHN&9kI/A?kIf=ioJGk&tK)(&uK`-W$LAlu-M#E20MZ8V5Muo!!NrG+>O8tFBOo^c2rfoj: +Q^F/.R[]e:SXuFFTV8'RUSO]_Vl-JmWiN5'Xfen4Z*L^C[C3NQ\[f;`]Y(tn^VI\&_Sa=2`Q#s> +aN;TJbKS61c2u>=d/MDodaQ\EeGn)!f)=5"f`0Y%gATe*h"ok*hYl@/i;V^7iqqd9jSn9=k5XWE +kl'cGlMp2Km/QJQmeuVSnGi%Vo)J=]o_nI^pAambq#:*gqYL*fr;?N`rdk*#s8N%K~> +JcC<$JcEIak5P2Tqu$9erVHNhr:plIt+>5MJ$=T)=ono +>4u1X>l%b(?MIn,@/XO2@f9g9AGTm9B)QB8B[(8gCA;TDD#S;LDZ=YSE;aeVErL.YFT6L`G5ZXa +GlN'fHN&9kI/A?kIf=ioJGk&tK)(&uK`-W$LAlu-M#E20MZ8V5Muo!!NrG+>O8tFBOo^c2rfoj: +Q^F/.R[]e:SXuFFTV8'RUSO]_Vl-JmWiN5'Xfen4Z*L^C[C3NQ\[f;`]Y(tn^VI\&_Sa=2`Q#s> +aN;TJbKS61c2u>=d/MDodaQ\EeGn)!f)=5"f`0Y%gATe*h"ok*hYl@/i;V^7iqqd9jSn9=k5XWE +kl'cGlMp2Km/QJQmeuVSnGi%Vo)J=]o_nI^pAambq#:*gqYL*fr;?N`rdk*#s8N%K~> +JcC<$JcEIak5P2Tqu$9erVHNhr:plIt+>5MJ$=T)=ono +>4u1X>l%b(?MIn,@/XO2@f9g9AGTm9B)QB8B[(8gCA;TDD#S;LDZ=YSE;aeVErL.YFT6L`G5ZXa +GlN'fHN&9kI/A?kIf=ioJGk&tK)(&uK`-W$LAlu-M#E20MZ8V5Muo!!NrG+>O8tFBOo^c2rfoj: +Q^F/.R[]e:SXuFFTV8'RUSO]_Vl-JmWiN5'Xfen4Z*L^C[C3NQ\[f;`]Y(tn^VI\&_Sa=2`Q#s> +aN;TJbKS61c2u>=d/MDodaQ\EeGn)!f)=5"f`0Y%gATe*h"ok*hYl@/i;V^7iqqd9jSn9=k5XWE +kl'cGlMp2Km/QJQmeuVSnGi%Vo)J=]o_nI^pAambq#:*gqYL*fr;?N`rdk*#s8N%K~> +JcC<$JcEC_k5P5Uqu$9erqcWir:p9cs7ZEas7?<_rUL3`nF5o8mdBKAliHG;rojIIkPjTIjlGI^ +io0mp$/aUqh;$c=g=b-Xf+-B^eC;sqdF$=fcd'h\bl5d,b/q`Ga2c3=`Pf[3_SX.)^q[Xu]tM(k +]=PSa\[]-J[K3eCrj+VjZ*:I9Y-+n/XK/A$WMlbnVl$;dUnaZXTqJ$MSt;LCS"#k7R$a5+Q'ISt +PEM)kOH5H_NJrgSMZ/G9Lkg_>KnTGX!J5n%J-LLPI=6KjHiAS0ra,S0qHX#(r`]/$rE0#"g/e)Pr)iYqqHEYu +gKaP[r*K/*ra>\5qdTM6rabk:rFZ"@ok;TaqeGqBrbVRNqelFPs)@mUs)S-\rH/'^s*"?bs*4Ng +rHeKjrd=Wls*jrsqgeZsrIXlurIk-'qM,!)rJ:B.s,-i7r/:]:NfO(!#EY(1P*2#mPl?q8QC!u+ +R@9V7S=Q7CT:hmOU8+N[V5C/hWN)u!Xf\b0Yd(L?Za@0L\%&u[]=bei^;%J"_SX4/`Poj;aN2KG +bKJ,SrltPjd/MGmdK%bqeGn)!f)=5#f`'S%gA]k*h"ok+hYl@.i;MX6iqqd9jSn9=k5XWDkl'cG +lMp2Km/QJQmelPRnGi%Wo)J=]o_eC^pAambq#:*gqYL*fr;?N`rdk*#s8DtJ~> +JcC<$JcEC_k5P5Uqu$9erqcWir:p9cs7ZEas7?<_rUL3`nF5o8mdBKAliHG;rojIIkPjTIjlGI^ +io0mp$/aUqh;$c=g=b-Xf+-B^eC;sqdF$=fcd'h\bl5d,b/q`Ga2c3=`Pf[3_SX.)^q[Xu]tM(k +]=PSa\[]-J[K3eCrj+VjZ*:I9Y-+n/XK/A$WMlbnVl$;dUnaZXTqJ$MSt;LCS"#k7R$a5+Q'ISt +PEM)kOH5H_NJrgSMZ/G9Lkg_>KnTGX!J5n%J-LLPI=6KjHiAS0ra,S0qHX#(r`]/$rE0#"g/e)Pr)iYqqHEYu +gKaP[r*K/*ra>\5qdTM6rabk:rFZ"@ok;TaqeGqBrbVRNqelFPs)@mUs)S-\rH/'^s*"?bs*4Ng +rHeKjrd=Wls*jrsqgeZsrIXlurIk-'qM,!)rJ:B.s,-i7r/:]:NfO(!#EY(1P*2#mPl?q8QC!u+ +R@9V7S=Q7CT:hmOU8+N[V5C/hWN)u!Xf\b0Yd(L?Za@0L\%&u[]=bei^;%J"_SX4/`Poj;aN2KG +bKJ,SrltPjd/MGmdK%bqeGn)!f)=5#f`'S%gA]k*h"ok+hYl@.i;MX6iqqd9jSn9=k5XWDkl'cG +lMp2Km/QJQmelPRnGi%Wo)J=]o_eC^pAambq#:*gqYL*fr;?N`rdk*#s8DtJ~> +JcC<$JcEC_k5P5Uqu$9erqcWir:p9cs7ZEas7?<_rUL3`nF5o8mdBKAliHG;rojIIkPjTIjlGI^ +io0mp$/aUqh;$c=g=b-Xf+-B^eC;sqdF$=fcd'h\bl5d,b/q`Ga2c3=`Pf[3_SX.)^q[Xu]tM(k +]=PSa\[]-J[K3eCrj+VjZ*:I9Y-+n/XK/A$WMlbnVl$;dUnaZXTqJ$MSt;LCS"#k7R$a5+Q'ISt +PEM)kOH5H_NJrgSMZ/G9Lkg_>KnTGX!J5n%J-LLPI=6KjHiAS0ra,S0qHX#(r`]/$rE0#"g/e)Pr)iYqqHEYu +gKaP[r*K/*ra>\5qdTM6rabk:rFZ"@ok;TaqeGqBrbVRNqelFPs)@mUs)S-\rH/'^s*"?bs*4Ng +rHeKjrd=Wls*jrsqgeZsrIXlurIk-'qM,!)rJ:B.s,-i7r/:]:NfO(!#EY(1P*2#mPl?q8QC!u+ +R@9V7S=Q7CT:hmOU8+N[V5C/hWN)u!Xf\b0Yd(L?Za@0L\%&u[]=bei^;%J"_SX4/`Poj;aN2KG +bKJ,SrltPjd/MGmdK%bqeGn)!f)=5#f`'S%gA]k*h"ok+hYl@.i;MX6iqqd9jSn9=k5XWDkl'cG +lMp2Km/QJQmelPRnGi%Wo)J=]o_eC^pAambq#:*gqYL*fr;?N`rdk*#s8DtJ~> +JcC<$JcE=]k5P5Ur;?BfrqcWir:p)e^W*tdf.W$d*L"_c-4DTbK@s+a8s?$rl"oV_u@LR_8-&b!PZ8H +]E,XUrj`'>\,NfC[C!9HZE^[=Yck5/XVS"=WiE%sVl-DgV50o^U7n9RT:VXFSGnurR[KP1Q^3o% +P`q8nOcYWbNfK*XN/NRMM26rdL'iWfK7ec,JUi9#If=a#I!^3dH?jd\rc\EeF`m\*!crC&rc.sW +s)7jRs)%dPr+l=Irb;7CrFc+Aq.9M8raYb5raGe6qHs5.ra#D+r`fA*q-!Yur)_iXqcEYsp0%8r +q-2KVq-El(pg=#.rF,S4rF>h;qITV;rFbh;c>!,iphTkFrb_RNs)7mUrGhjXs)\-\s)n?brHJ9d +s*=Qhrd4Zmr-eTordXirrdk'#qLea"rIt*&rJ1B.qhb?1rep`6s,I&=rJq#AOcfX+$^6g>Q'IZ$ +Q^F/.Rf8d;S=Q7CT:hmPUSO]^VPg>jWiE,$Xf\e2Yd(L?['d?O\@K/]]=bhk^V@S$_Sa=2`Q#s> +aN;TJbKS61c2l8(rnIG-qVD,,rnmP0rSdb8qr@\:roO(?roa=F +r9=7Hs6KXMs6]jSr9s[Ts7-'Ys7?9_r:U*`rqH?crqZQiqYU6hr;H0bJcC<$rVqB~> +JcC<$JcE=]k5P5Ur;?BfrqcWir:p)e^W*tdf.W$d*L"_c-4DTbK@s+a8s?$rl"oV_u@LR_8-&b!PZ8H +]E,XUrj`'>\,NfC[C!9HZE^[=Yck5/XVS"=WiE%sVl-DgV50o^U7n9RT:VXFSGnurR[KP1Q^3o% +P`q8nOcYWbNfK*XN/NRMM26rdL'iWfK7ec,JUi9#If=a#I!^3dH?jd\rc\EeF`m\*!crC&rc.sW +s)7jRs)%dPr+l=Irb;7CrFc+Aq.9M8raYb5raGe6qHs5.ra#D+r`fA*q-!Yur)_iXqcEYsp0%8r +q-2KVq-El(pg=#.rF,S4rF>h;qITV;rFbh;c>!,iphTkFrb_RNs)7mUrGhjXs)\-\s)n?brHJ9d +s*=Qhrd4Zmr-eTordXirrdk'#qLea"rIt*&rJ1B.qhb?1rep`6s,I&=rJq#AOcfX+$^6g>Q'IZ$ +Q^F/.Rf8d;S=Q7CT:hmPUSO]^VPg>jWiE,$Xf\e2Yd(L?['d?O\@K/]]=bhk^V@S$_Sa=2`Q#s> +aN;TJbKS61c2l8(rnIG-qVD,,rnmP0rSdb8qr@\:roO(?roa=F +r9=7Hs6KXMs6]jSr9s[Ts7-'Ys7?9_r:U*`rqH?crqZQiqYU6hr;H0bJcC<$rVqB~> +JcC<$JcE=]k5P5Ur;?BfrqcWir:p)e^W*tdf.W$d*L"_c-4DTbK@s+a8s?$rl"oV_u@LR_8-&b!PZ8H +]E,XUrj`'>\,NfC[C!9HZE^[=Yck5/XVS"=WiE%sVl-DgV50o^U7n9RT:VXFSGnurR[KP1Q^3o% +P`q8nOcYWbNfK*XN/NRMM26rdL'iWfK7ec,JUi9#If=a#I!^3dH?jd\rc\EeF`m\*!crC&rc.sW +s)7jRs)%dPr+l=Irb;7CrFc+Aq.9M8raYb5raGe6qHs5.ra#D+r`fA*q-!Yur)_iXqcEYsp0%8r +q-2KVq-El(pg=#.rF,S4rF>h;qITV;rFbh;c>!,iphTkFrb_RNs)7mUrGhjXs)\-\s)n?brHJ9d +s*=Qhrd4Zmr-eTordXirrdk'#qLea"rIt*&rJ1B.qhb?1rep`6s,I&=rJq#AOcfX+$^6g>Q'IZ$ +Q^F/.Rf8d;S=Q7CT:hmPUSO]^VPg>jWiE,$Xf\e2Yd(L?['d?O\@K/]]=bhk^V@S$_Sa=2`Q#s> +aN;TJbKS61c2l8(rnIG-qVD,,rnmP0rSdb8qr@\:roO(?roa=F +r9=7Hs6KXMs6]jSr9s[Ts7-'Ys7?9_r:U*`rqH?crqZQiqYU6hr;H0bJcC<$rVqB~> +JcC<$JcE7[kPk>Vr;?BfrqcWir:plIt,>5;>"=Sl1bno +>5DIT>k_P$?MIn+@/XO2@f9g9AGTm9B)QB9B[:DhCA;TDD#S;LDZ4SSE;aeVErU4ZFT6L`G5ZXb +GlN'fHN/?lI/JEmIfFopJH(3"K)1-!K`-W$LAco,M#)u-MZ8V4N;nn;Nr>%=O8tFAOo^c2rfm\R +Q^=),R@=,E5Fe:9StD[LTq\Vf^;%Fu_8=(,`Poj; +aN2KGbKJ,Sc-FV\d/MDndaS3Fs4./#rn%2&s4R>(s4dP.qVD/-rSRG/ro*h8qW%S9roO(?roa=F +r9=7Hrp0OLs6]jSr9s[Ts7-'Ys7?6^rUp0`s7cHdrqZQiqYU6hr;H0bJcC<$r;V9~> +JcC<$JcE7[kPk>Vr;?BfrqcWir:plIt,>5;>"=Sl1bno +>5DIT>k_P$?MIn+@/XO2@f9g9AGTm9B)QB9B[:DhCA;TDD#S;LDZ4SSE;aeVErU4ZFT6L`G5ZXb +GlN'fHN/?lI/JEmIfFopJH(3"K)1-!K`-W$LAco,M#)u-MZ8V4N;nn;Nr>%=O8tFAOo^c2rfm\R +Q^=),R@=,E5Fe:9StD[LTq\Vf^;%Fu_8=(,`Poj; +aN2KGbKJ,Sc-FV\d/MDndaS3Fs4./#rn%2&s4R>(s4dP.qVD/-rSRG/ro*h8qW%S9roO(?roa=F +r9=7Hrp0OLs6]jSr9s[Ts7-'Ys7?6^rUp0`s7cHdrqZQiqYU6hr;H0bJcC<$r;V9~> +JcC<$JcE7[kPk>Vr;?BfrqcWir:plIt,>5;>"=Sl1bno +>5DIT>k_P$?MIn+@/XO2@f9g9AGTm9B)QB9B[:DhCA;TDD#S;LDZ4SSE;aeVErU4ZFT6L`G5ZXb +GlN'fHN/?lI/JEmIfFopJH(3"K)1-!K`-W$LAco,M#)u-MZ8V4N;nn;Nr>%=O8tFAOo^c2rfm\R +Q^=),R@=,E5Fe:9StD[LTq\Vf^;%Fu_8=(,`Poj; +aN2KGbKJ,Sc-FV\d/MDndaS3Fs4./#rn%2&s4R>(s4dP.qVD/-rSRG/ro*h8qW%S9roO(?roa=F +r9=7Hrp0OLs6]jSr9s[Ts7-'Ys7?6^rUp0`s7cHdrqZQiqYU6hr;H0bJcC<$r;V9~> +JcC<$JcE1Ykl1GWr;?BfrqcWir:pbao9?^a2\+t!Q;nT_?%KgrkB#Y +]tM(k]=PSa\[],X[^NTNrj**?Z*:I9Y-+n/XK/A$WMofo,,V34UnaZXTqJ$LSt2C@S!ob5R$a5+ +Q'IStP*1rhO,o<\req#=MM[1GL]3#>KnP)2Jq8K'J:E#sI=6KjHiAV1ra,S0qcs,)rEB#"r)i_qpK%#iqH3Go +qc`i#f3IuSqHir(rF#V5qI9G6rFGb9rau+Ap1X)4phJo)qJ,e@rbVRNqelFPs)@pVrc8$[rcJ0_ +s*"?bs*4QhrHeKjs*Xcns*jutr.+cts+:-#re16(qM,!)rJ:<,reg]5r/CW7s,R&=s,d8CrfR>H +Pa)04!LB)OQiWVDrgQ-BSXuFFTV8'RUSO]^Vl-JmWiE,$Xfek3Yd1UA['d?O\@K/^]Y(ql^VI\& +_Sa=2`Q-'@ai_fMbg"DXcHjl:d/h\Erm^tu!7q/$s4IA)rS%8*s4mM-rSIP2q;D51rSm\6roF(? +qr[n@roj:Es6BXMr9XINs6fgRs7$'YrUTsZs7H6^s7ZKeqtU0drqcKgrVZTlnc"+>JcGZJJ,~> +JcC<$JcE1Ykl1GWr;?BfrqcWir:pbao9?^a2\+t!Q;nT_?%KgrkB#Y +]tM(k]=PSa\[],X[^NTNrj**?Z*:I9Y-+n/XK/A$WMofo,,V34UnaZXTqJ$LSt2C@S!ob5R$a5+ +Q'IStP*1rhO,o<\req#=MM[1GL]3#>KnP)2Jq8K'J:E#sI=6KjHiAV1ra,S0qcs,)rEB#"r)i_qpK%#iqH3Go +qc`i#f3IuSqHir(rF#V5qI9G6rFGb9rau+Ap1X)4phJo)qJ,e@rbVRNqelFPs)@pVrc8$[rcJ0_ +s*"?bs*4QhrHeKjs*Xcns*jutr.+cts+:-#re16(qM,!)rJ:<,reg]5r/CW7s,R&=s,d8CrfR>H +Pa)04!LB)OQiWVDrgQ-BSXuFFTV8'RUSO]^Vl-JmWiE,$Xfek3Yd1UA['d?O\@K/^]Y(ql^VI\& +_Sa=2`Q-'@ai_fMbg"DXcHjl:d/h\Erm^tu!7q/$s4IA)rS%8*s4mM-rSIP2q;D51rSm\6roF(? +qr[n@roj:Es6BXMr9XINs6fgRs7$'YrUTsZs7H6^s7ZKeqtU0drqcKgrVZTlnc"+>JcGZJJ,~> +JcC<$JcE1Ykl1GWr;?BfrqcWir:pbao9?^a2\+t!Q;nT_?%KgrkB#Y +]tM(k]=PSa\[],X[^NTNrj**?Z*:I9Y-+n/XK/A$WMofo,,V34UnaZXTqJ$LSt2C@S!ob5R$a5+ +Q'IStP*1rhO,o<\req#=MM[1GL]3#>KnP)2Jq8K'J:E#sI=6KjHiAV1ra,S0qcs,)rEB#"r)i_qpK%#iqH3Go +qc`i#f3IuSqHir(rF#V5qI9G6rFGb9rau+Ap1X)4phJo)qJ,e@rbVRNqelFPs)@pVrc8$[rcJ0_ +s*"?bs*4QhrHeKjs*Xcns*jutr.+cts+:-#re16(qM,!)rJ:<,reg]5r/CW7s,R&=s,d8CrfR>H +Pa)04!LB)OQiWVDrgQ-BSXuFFTV8'RUSO]^Vl-JmWiE,$Xfek3Yd1UA['d?O\@K/^]Y(ql^VI\& +_Sa=2`Q-'@ai_fMbg"DXcHjl:d/h\Erm^tu!7q/$s4IA)rS%8*s4mM-rSIP2q;D51rSm\6roF(? +qr[n@roj:Es6BXMr9XINs6fgRs7$'YrUTsZs7H6^s7ZKeqtU0drqcKgrVZTlnc"+>JcGZJJ,~> +JcC<$JcE.Xkl1GWr;?BfrqcZjr:pbao9?ia2Z-<`Pf^4_SX.*_#D(L +^:jNY!P>rB\H04LrjEcR['R*EZ*CO;YHG"0XK/D%Wi;qpVl$;dUna[`Tb3riSt;LCS"#k7R$a5+ +Q'IStrfRSMOH5H_NJrgSMZ/G9Lkg_>KnTGX!J5n%J,t.Krd=iqH[GanAKC]8)JC&2NABDuN>Ac60=A,Ba7@K'[3?iFC2?2In+>Q%b#=o)7h=8>tk=o2D" +>MEEN?2@n%?i=C3@JXI4A,Ts8Ac66>BD-$6C$]U)C%lB;C]8/LD>S5NDuXeTEW0tYF8^4\FoQX` +GQ2pfH2`-iHiJKlIK+crJ,FisJc:9!KDpQ'L&-Q'L]*&*M>iD2Mu8P5NW5%:O8k=AOoCODP5pjH +Q2d-MQi.rnmS1rSd_7q;_J8rT3q= +roa:Er9=7Hrp0LKs6]jSr9s[Ts7-'Yrq$0^r:U*`rqH?crqZQiqYU6hr;H-aJcC<$r;V9~> +JcC<$JcE.Xkl1GWr;?BfrqcZjr:pbao9?ia2Z-<`Pf^4_SX.*_#D(L +^:jNY!P>rB\H04LrjEcR['R*EZ*CO;YHG"0XK/D%Wi;qpVl$;dUna[`Tb3riSt;LCS"#k7R$a5+ +Q'IStrfRSMOH5H_NJrgSMZ/G9Lkg_>KnTGX!J5n%J,t.Krd=iqH[GanAKC]8)JC&2NABDuN>Ac60=A,Ba7@K'[3?iFC2?2In+>Q%b#=o)7h=8>tk=o2D" +>MEEN?2@n%?i=C3@JXI4A,Ts8Ac66>BD-$6C$]U)C%lB;C]8/LD>S5NDuXeTEW0tYF8^4\FoQX` +GQ2pfH2`-iHiJKlIK+crJ,FisJc:9!KDpQ'L&-Q'L]*&*M>iD2Mu8P5NW5%:O8k=AOoCODP5pjH +Q2d-MQi.rnmS1rSd_7q;_J8rT3q= +roa:Er9=7Hrp0LKs6]jSr9s[Ts7-'Yrq$0^r:U*`rqH?crqZQiqYU6hr;H-aJcC<$r;V9~> +JcC<$JcE.Xkl1GWr;?BfrqcZjr:pbao9?ia2Z-<`Pf^4_SX.*_#D(L +^:jNY!P>rB\H04LrjEcR['R*EZ*CO;YHG"0XK/D%Wi;qpVl$;dUna[`Tb3riSt;LCS"#k7R$a5+ +Q'IStrfRSMOH5H_NJrgSMZ/G9Lkg_>KnTGX!J5n%J,t.Krd=iqH[GanAKC]8)JC&2NABDuN>Ac60=A,Ba7@K'[3?iFC2?2In+>Q%b#=o)7h=8>tk=o2D" +>MEEN?2@n%?i=C3@JXI4A,Ts8Ac66>BD-$6C$]U)C%lB;C]8/LD>S5NDuXeTEW0tYF8^4\FoQX` +GQ2pfH2`-iHiJKlIK+crJ,FisJc:9!KDpQ'L&-Q'L]*&*M>iD2Mu8P5NW5%:O8k=AOoCODP5pjH +Q2d-MQi.rnmS1rSd_7q;_J8rT3q= +roa:Er9=7Hrp0LKs6]jSr9s[Ts7-'Yrq$0^r:U*`rqH?crqZQiqYU6hr;H-aJcC<$r;V9~> +JcC<$JcE%Ul2LSYr;?EgrqcWir:pKnY24K7\Z*J:N-!If=`rI!bj=s*4ThrceBc!-S6^s)\3\ +rGhjVs)7gQs)%aOqeQ.Frb;4BrFc+AqITY:raYh7raGe6r*TG0ra#A*r`f>)p0$Z_o3(roqciGm +gKjV]pL!l,rF,P3raYqSt;RITqS3UUnjiaVl-JmWiN5'Xfek3Z*L^B['mEP\@K2_]Y(qm^VI\&_Sa@3 +`lH0Aai_fMbg"GYcd;[=!RfHre,e+NrRV,'g"H>Xs4dS/r8%A/rnmS1rSd_7q;_G7roO"=roa:E +r9=4Gs6KULrpBaRr9s[Ts7-$Xs7?9_r:U*`rqH?crqZQiq>:-gr;H0bJcC<$qu;0~> +JcC<$JcE%Ul2LSYr;?EgrqcWir:pKnY24K7\Z*J:N-!If=`rI!bj=s*4ThrceBc!-S6^s)\3\ +rGhjVs)7gQs)%aOqeQ.Frb;4BrFc+AqITY:raYh7raGe6r*TG0ra#A*r`f>)p0$Z_o3(roqciGm +gKjV]pL!l,rF,P3raYqSt;RITqS3UUnjiaVl-JmWiN5'Xfek3Z*L^B['mEP\@K2_]Y(qm^VI\&_Sa@3 +`lH0Aai_fMbg"GYcd;[=!RfHre,e+NrRV,'g"H>Xs4dS/r8%A/rnmS1rSd_7q;_G7roO"=roa:E +r9=4Gs6KULrpBaRr9s[Ts7-$Xs7?9_r:U*`rqH?crqZQiq>:-gr;H0bJcC<$qu;0~> +JcC<$JcE%Ul2LSYr;?EgrqcWir:pKnY24K7\Z*J:N-!If=`rI!bj=s*4ThrceBc!-S6^s)\3\ +rGhjVs)7gQs)%aOqeQ.Frb;4BrFc+AqITY:raYh7raGe6r*TG0ra#A*r`f>)p0$Z_o3(roqciGm +gKjV]pL!l,rF,P3raYqSt;RITqS3UUnjiaVl-JmWiN5'Xfek3Z*L^B['mEP\@K2_]Y(qm^VI\&_Sa@3 +`lH0Aai_fMbg"GYcd;[=!RfHre,e+NrRV,'g"H>Xs4dS/r8%A/rnmS1rSd_7q;_G7roO"=roa:E +r9=4Gs6KULrpBaRr9s[Ts7-$Xs7?9_r:U*`rqH?crqZQiq>:-gr;H0bJcC<$qu;0~> +JcC<$JcE"Tl2LSYr;?EgrqcWir:pSeC2mprm:bnci22jc-611#Kk01aN2EB`rYct=6riINKX/`2!W2HPjV50o^U8"?TTV%gISXc1=R[KP1 +Q^3o%P`q8nOc]R''98'2N/NRMM26tCL5(D8KS+o/Jc:0)IsuipI=-Ehrd+Ti!-nKes*"EbrcJ0] +s)S'Xrc%mUr,2LNrbVIIrbDCGqIok@rFYqV1ra,S0qcs)(rEAbppfR#gqc`l$ +nQaUMpg3Z$rF#S4qI9G6rabk:rau+ApLsA:dVAMlrG;IMr,2OQrc%gUs)S-\rH/'^!-\Z:1htu@1iVhd3j8J';jn\'U6equ-HirUKl +JcC<$JcE"Tl2LSYr;?EgrqcWir:pSeC2mprm:bnci22jc-611#Kk01aN2EB`rYct=6riINKX/`2!W2HPjV50o^U8"?TTV%gISXc1=R[KP1 +Q^3o%P`q8nOc]R''98'2N/NRMM26tCL5(D8KS+o/Jc:0)IsuipI=-Ehrd+Ti!-nKes*"EbrcJ0] +s)S'Xrc%mUr,2LNrbVIIrbDCGqIok@rFYqV1ra,S0qcs)(rEAbppfR#gqc`l$ +nQaUMpg3Z$rF#S4qI9G6rabk:rau+ApLsA:dVAMlrG;IMr,2OQrc%gUs)S-\rH/'^!-\Z:1htu@1iVhd3j8J';jn\'U6equ-HirUKl +JcC<$JcE"Tl2LSYr;?EgrqcWir:pSeC2mprm:bnci22jc-611#Kk01aN2EB`rYct=6riINKX/`2!W2HPjV50o^U8"?TTV%gISXc1=R[KP1 +Q^3o%P`q8nOc]R''98'2N/NRMM26tCL5(D8KS+o/Jc:0)IsuipI=-Ehrd+Ti!-nKes*"EbrcJ0] +s)S'Xrc%mUr,2LNrbVIIrbDCGqIok@rFYqV1ra,S0qcs)(rEAbppfR#gqc`l$ +nQaUMpg3Z$rF#S4qI9G6rabk:rau+ApLsA:dVAMlrG;IMr,2OQrc%gUs)S-\rH/'^!-\Z:1htu@1iVhd3j8J';jn\'U6equ-HirUKl +JcC<$JcDqRlMg\Zr;?EgrqcWirV6Eerq??as7H?_rpp*Z!:^!V#O_!Hm-O'(lMg#Kki_s-&*;m4 +j5T(Wi8EMLhVI#Cg]#n-g"?;U!S5g#e,e%Hrm:bnci22pc-4DTbK@uLrl>,\`re;JC]8)IC&2NBBDuN?Ac?6>A,Kg8@K'[4?iFC2?2@h)>Pq[_=o)>!>Ol%J +?2%\!?i4=2@JXI4A,Ts8Ac66>BD?0:C"$hiC]/)KD>\;NDuXeTEW:(ZF8^4\FT?U`GQ2mfH2W'h +HN8HlIK+crJ,XuuJc:9"KE$W)L&6W)L]3,+M>iD2Mu/J3NW+t8O8k=@Oo:ICPQ-mHQ2d0MQi +aND]Lbg"GYcd:%ddF-LneCE+#rmq5(g"HAYs4dS/rS@M1rnmV2ro*h8q;_D6rT3n:-gr;H0bJcC<$qYu'~> +JcC<$JcDqRlMg\Zr;?EgrqcWirV6Eerq??as7H?_rpp*Z!:^!V#O_!Hm-O'(lMg#Kki_s-&*;m4 +j5T(Wi8EMLhVI#Cg]#n-g"?;U!S5g#e,e%Hrm:bnci22pc-4DTbK@uLrl>,\`re;JC]8)IC&2NBBDuN?Ac?6>A,Kg8@K'[4?iFC2?2@h)>Pq[_=o)>!>Ol%J +?2%\!?i4=2@JXI4A,Ts8Ac66>BD?0:C"$hiC]/)KD>\;NDuXeTEW:(ZF8^4\FT?U`GQ2mfH2W'h +HN8HlIK+crJ,XuuJc:9"KE$W)L&6W)L]3,+M>iD2Mu/J3NW+t8O8k=@Oo:ICPQ-mHQ2d0MQi +aND]Lbg"GYcd:%ddF-LneCE+#rmq5(g"HAYs4dS/rS@M1rnmV2ro*h8q;_D6rT3n:-gr;H0bJcC<$qYu'~> +JcC<$JcDqRlMg\Zr;?EgrqcWirV6Eerq??as7H?_rpp*Z!:^!V#O_!Hm-O'(lMg#Kki_s-&*;m4 +j5T(Wi8EMLhVI#Cg]#n-g"?;U!S5g#e,e%Hrm:bnci22pc-4DTbK@uLrl>,\`re;JC]8)IC&2NBBDuN?Ac?6>A,Kg8@K'[4?iFC2?2@h)>Pq[_=o)>!>Ol%J +?2%\!?i4=2@JXI4A,Ts8Ac66>BD?0:C"$hiC]/)KD>\;NDuXeTEW:(ZF8^4\FT?U`GQ2mfH2W'h +HN8HlIK+crJ,XuuJc:9"KE$W)L&6W)L]3,+M>iD2Mu/J3NW+t8O8k=@Oo:ICPQ-mHQ2d0MQi +aND]Lbg"GYcd:%ddF-LneCE+#rmq5(g"HAYs4dS/rS@M1rnmV2ro*h8q;_D6rT3n:-gr;H0bJcC<$qYu'~> +JcC<$JcDkPli-e[rVZNhrqcWir:pKnP,3K7\Z*J:N-!If=`sI!^5>HN/6jGl;gfG'.s+ +FT6F^Er9qVE;skRDZ4MPD#.rHCAhlDB`;ZDB)?0=AH-0:@fKm9@/F=1?N+7,>l7h'>3]8d>5MOq +>k_OM?M7b(@/XO1@fBm:AGTm:B)QB;B_uN;C@c60C@Z0=D#J5KDZ4SSE;aeVErU4ZFT6I`G5ZUd +G^4T5H3/G@I/\QoIfForJH(3#K)L?%K`?c(LB!&.M#3&.MZ/P1N;\b8Nr+n:OT(C@P5^[FPl?sJ +QN*c@2hu)F3iVhd4j8A!:jn\'; +kPaWAl2KuIlhg&KmJcPOn,MnVnbhtXoDeI\p&=[ap\agcq>L0dqu-HjrUBf;s+14Hs*t~> +JcC<$JcDkPli-e[rVZNhrqcWir:pKnP,3K7\Z*J:N-!If=`sI!^5>HN/6jGl;gfG'.s+ +FT6F^Er9qVE;skRDZ4MPD#.rHCAhlDB`;ZDB)?0=AH-0:@fKm9@/F=1?N+7,>l7h'>3]8d>5MOq +>k_OM?M7b(@/XO1@fBm:AGTm:B)QB;B_uN;C@c60C@Z0=D#J5KDZ4SSE;aeVErU4ZFT6I`G5ZUd +G^4T5H3/G@I/\QoIfForJH(3#K)L?%K`?c(LB!&.M#3&.MZ/P1N;\b8Nr+n:OT(C@P5^[FPl?sJ +QN*c@2hu)F3iVhd4j8A!:jn\'; +kPaWAl2KuIlhg&KmJcPOn,MnVnbhtXoDeI\p&=[ap\agcq>L0dqu-HjrUBf;s+14Hs*t~> +JcC<$JcDkPli-e[rVZNhrqcWir:pKnP,3K7\Z*J:N-!If=`sI!^5>HN/6jGl;gfG'.s+ +FT6F^Er9qVE;skRDZ4MPD#.rHCAhlDB`;ZDB)?0=AH-0:@fKm9@/F=1?N+7,>l7h'>3]8d>5MOq +>k_OM?M7b(@/XO1@fBm:AGTm:B)QB;B_uN;C@c60C@Z0=D#J5KDZ4SSE;aeVErU4ZFT6I`G5ZUd +G^4T5H3/G@I/\QoIfForJH(3#K)L?%K`?c(LB!&.M#3&.MZ/P1N;\b8Nr+n:OT(C@P5^[FPl?sJ +QN*c@2hu)F3iVhd4j8A!:jn\'; +kPaWAl2KuIlhg&KmJcPOn,MnVnbhtXoDeI\p&=[ap\agcq>L0dqu-HjrUBf;s+14Hs*t~> +JcC<$JcDeNm/Hn\rVZNhrqcWir:p$*ph?Yck43XfST&W\:?MVl-DgUnjc[TqS-OSt;LCS"#k7 +R$a5+Q'IStPEM)kOH5H_NJrgSMi*@JLkkta!JQ4+K*R!ZJUi9#It%BF!do?Ard+Tis*4Nes*"Eb +rH/'\s)S$Wrc%jTqelCMrbVFHrbDFHqe5tArau%=s()+=r*oY6ra>V1ra,S0q- +JcC<$JcDeNm/Hn\rVZNhrqcWir:p$*ph?Yck43XfST&W\:?MVl-DgUnjc[TqS-OSt;LCS"#k7 +R$a5+Q'IStPEM)kOH5H_NJrgSMi*@JLkkta!JQ4+K*R!ZJUi9#It%BF!do?Ard+Tis*4Nes*"Eb +rH/'\s)S$Wrc%jTqelCMrbVFHrbDFHqe5tArau%=s()+=r*oY6ra>V1ra,S0q- +JcC<$JcDeNm/Hn\rVZNhrqcWir:p$*ph?Yck43XfST&W\:?MVl-DgUnjc[TqS-OSt;LCS"#k7 +R$a5+Q'IStPEM)kOH5H_NJrgSMi*@JLkkta!JQ4+K*R!ZJUi9#It%BF!do?Ard+Tis*4Nes*"Eb +rH/'\s)S$Wrc%jTqelCMrbVFHrbDFHqe5tArau%=s()+=r*oY6ra>V1ra,S0q- +JcC<$JcD_LmJd%^r;?EgrqcZjr:prltPhbl5fcaoKQ_a9Tc*`l5p8`5DSk +&Ac/t^V@Lr]tD"i]"5G_\@;IG"gt_DZa-k8YVWJcXf\\*WiE%sVl-DgUnjc[TqS-OSt;LCS=?": +R@'A.QBd`"PEM)kOH5H_NfB!VMi.Lj#)J%hL4t>7rdt6'Jc:0$IsukGI0+eCHiA?kH2i-fG5ugc +Fo?F^F8g4XEW:"WDu+AND>nAKC]8)JC&;TCBDuN@Ac?6?A,Ba8@K'[3?iFC1?2.\#>Ou%m>P)1r +?1qUi?gV1i?i4=1@JXI3A,^$8Ac?S5NDuO_SEW:(ZF8^4\FT?U`G63#7 +H2`-iHiJKmIK+`rJ,Om!JV&LPKE$W)L&Hc+L]<2.M>iD3Mu/J4NW"n7O8Y1>Oo1CAPQ$gFQ2d0M +Qi39QR@9TDRgYaWSXuFFT:hmOU8.^`2l3CLVl6SpWiN5'Y-5(6Z*L^C[C3NQ\@K2_]Y(qm^VI\& +_SjF4`lH0Ab0.uPc-FV\d*^7he,Ihte^j`O!SH*)gAfn-h#6(/hZ)L3i;V^7iqqd7jSe38k5=E@ +kkXKBlMg,Hm/HDOmelPQnGi%Uo)J=\o_eC^pAXg`q#:*gqYC$er;?N_rdk*#s7u\F~> +JcC<$JcD_LmJd%^r;?EgrqcZjr:prltPhbl5fcaoKQ_a9Tc*`l5p8`5DSk +&Ac/t^V@Lr]tD"i]"5G_\@;IG"gt_DZa-k8YVWJcXf\\*WiE%sVl-DgUnjc[TqS-OSt;LCS=?": +R@'A.QBd`"PEM)kOH5H_NfB!VMi.Lj#)J%hL4t>7rdt6'Jc:0$IsukGI0+eCHiA?kH2i-fG5ugc +Fo?F^F8g4XEW:"WDu+AND>nAKC]8)JC&;TCBDuN@Ac?6?A,Ba8@K'[3?iFC1?2.\#>Ou%m>P)1r +?1qUi?gV1i?i4=1@JXI3A,^$8Ac?S5NDuO_SEW:(ZF8^4\FT?U`G63#7 +H2`-iHiJKmIK+`rJ,Om!JV&LPKE$W)L&Hc+L]<2.M>iD3Mu/J4NW"n7O8Y1>Oo1CAPQ$gFQ2d0M +Qi39QR@9TDRgYaWSXuFFT:hmOU8.^`2l3CLVl6SpWiN5'Y-5(6Z*L^C[C3NQ\@K2_]Y(qm^VI\& +_SjF4`lH0Ab0.uPc-FV\d*^7he,Ihte^j`O!SH*)gAfn-h#6(/hZ)L3i;V^7iqqd7jSe38k5=E@ +kkXKBlMg,Hm/HDOmelPQnGi%Uo)J=\o_eC^pAXg`q#:*gqYC$er;?N_rdk*#s7u\F~> +JcC<$JcD_LmJd%^r;?EgrqcZjr:prltPhbl5fcaoKQ_a9Tc*`l5p8`5DSk +&Ac/t^V@Lr]tD"i]"5G_\@;IG"gt_DZa-k8YVWJcXf\\*WiE%sVl-DgUnjc[TqS-OSt;LCS=?": +R@'A.QBd`"PEM)kOH5H_NfB!VMi.Lj#)J%hL4t>7rdt6'Jc:0$IsukGI0+eCHiA?kH2i-fG5ugc +Fo?F^F8g4XEW:"WDu+AND>nAKC]8)JC&;TCBDuN@Ac?6?A,Ba8@K'[3?iFC1?2.\#>Ou%m>P)1r +?1qUi?gV1i?i4=1@JXI3A,^$8Ac?S5NDuO_SEW:(ZF8^4\FT?U`G63#7 +H2`-iHiJKmIK+`rJ,Om!JV&LPKE$W)L&Hc+L]<2.M>iD3Mu/J4NW"n7O8Y1>Oo1CAPQ$gFQ2d0M +Qi39QR@9TDRgYaWSXuFFT:hmOU8.^`2l3CLVl6SpWiN5'Y-5(6Z*L^C[C3NQ\@K2_]Y(qm^VI\& +_SjF4`lH0Ab0.uPc-FV\d*^7he,Ihte^j`O!SH*)gAfn-h#6(/hZ)L3i;V^7iqqd7jSe38k5=E@ +kkXKBlMg,Hm/HDOmelPQnGi%Uo)J=\o_eC^pAXg`q#:*gqYC$er;?N_rdk*#s7u\F~> +JcC<$JcDYJmf*._r;?HhrqcWir:p>b`l?!:`5KRm +_?%KgrkAKJ^&GYF]=S!P1Usp&[^ENMZa6sBYct=6Xf\\+X/`2!W2HPjV50o^U7n9RT:VXFS=?": +R@'A.QBd`"PQ$^_OcYWbNfB!VMi3ILM26qBL5(D8KS+o/Jq/rE])$mT]3dqH`o' +^L-nHrF,M2raYqrFu+CcYNGprGDCKs)7mUrGhjXs)\-\!d/[0rHAjWN)u!XKAV-YctCc@3hu2L4iW%p7j8J';jnS!:kPXQ>l2BoH +lh]uImJlVOn,DhVnbhtWoD\C[p&Fabp\Xabq>U6dqu-HirUKl +JcC<$JcDYJmf*._r;?HhrqcWir:p>b`l?!:`5KRm +_?%KgrkAKJ^&GYF]=S!P1Usp&[^ENMZa6sBYct=6Xf\\+X/`2!W2HPjV50o^U7n9RT:VXFS=?": +R@'A.QBd`"PQ$^_OcYWbNfB!VMi3ILM26qBL5(D8KS+o/Jq/rE])$mT]3dqH`o' +^L-nHrF,M2raYqrFu+CcYNGprGDCKs)7mUrGhjXs)\-\!d/[0rHAjWN)u!XKAV-YctCc@3hu2L4iW%p7j8J';jnS!:kPXQ>l2BoH +lh]uImJlVOn,DhVnbhtWoD\C[p&Fabp\Xabq>U6dqu-HirUKl +JcC<$JcDYJmf*._r;?HhrqcWir:p>b`l?!:`5KRm +_?%KgrkAKJ^&GYF]=S!P1Usp&[^ENMZa6sBYct=6Xf\\+X/`2!W2HPjV50o^U7n9RT:VXFS=?": +R@'A.QBd`"PQ$^_OcYWbNfB!VMi3ILM26qBL5(D8KS+o/Jq/rE])$mT]3dqH`o' +^L-nHrF,M2raYqrFu+CcYNGprGDCKs)7mUrGhjXs)\-\!d/[0rHAjWN)u!XKAV-YctCc@3hu2L4iW%p7j8J';jnS!:kPXQ>l2BoH +lh]uImJlVOn,DhVnbhtWoD\C[p&Fabp\Xabq>U6dqu-HirUKl +JcC<$JcDYJmJd%^rVZNhrqcWirV6Ees7ZEas7H?_rpp*Z!:^!Vs6]mSrp1'ZlK[Wukih3lk2k^c +ro4%=iVqa9hqn@g#Me(gg=k65f`'J'f%'cLs3gtrrm:eocd2U9!mSs5rlYPhaiVWFa2c4!`rac%=qdTS6ra>S0rEfG.gKaS\q-L[? +r*]J3q-s>5rFGe:rau+AqIoe@qeFJnqeZ1IqelCOrc%gUs)S-\rH/'^!-\Za@-K[^WfX]">Vg^;%Fu_8=+.`Poj; +aN;TJbKS5VcHjkbdF-LneCE.Lf)aOWrn7G.gt_nbs5!b5rS[\6s5Nt:rT*t>q<%V +JcC<$JcDYJmJd%^rVZNhrqcWirV6Ees7ZEas7H?_rpp*Z!:^!Vs6]mSrp1'ZlK[Wukih3lk2k^c +ro4%=iVqa9hqn@g#Me(gg=k65f`'J'f%'cLs3gtrrm:eocd2U9!mSs5rlYPhaiVWFa2c4!`rac%=qdTS6ra>S0rEfG.gKaS\q-L[? +r*]J3q-s>5rFGe:rau+AqIoe@qeFJnqeZ1IqelCOrc%gUs)S-\rH/'^!-\Za@-K[^WfX]">Vg^;%Fu_8=+.`Poj; +aN;TJbKS5VcHjkbdF-LneCE.Lf)aOWrn7G.gt_nbs5!b5rS[\6s5Nt:rT*t>q<%V +JcC<$JcDYJmJd%^rVZNhrqcWirV6Ees7ZEas7H?_rpp*Z!:^!Vs6]mSrp1'ZlK[Wukih3lk2k^c +ro4%=iVqa9hqn@g#Me(gg=k65f`'J'f%'cLs3gtrrm:eocd2U9!mSs5rlYPhaiVWFa2c4!`rac%=qdTS6ra>S0rEfG.gKaS\q-L[? +r*]J3q-s>5rFGe:rau+AqIoe@qeFJnqeZ1IqelCOrc%gUs)S-\rH/'^!-\Za@-K[^WfX]">Vg^;%Fu_8=+.`Poj; +aN;TJbKS5VcHjkbdF-LneCE.Lf)aOWrn7G.gt_nbs5!b5rS[\6s5Nt:rT*t>q<%V +JcC<$JcDVImf*+^rVZNhrqcZjr:pMM[1GLkkta!JQ4+K*$XUJc:0$IsukGIK+]pHiA?kH2i-e +GQ2jdFo6@\F8g4XEW0qVDu4GOD>nAKC]8)KC&DZDBE)T@AcHf?27g: +?i4=0@JOC3A,Ts8Ac66?BDQ<>C&D_oC\_fED>J/MDuO_REW:(ZF8g:]FoQXaGQ2pfH2`*kH[L5? +IK+`rJ,XuuJH1<#K*$^[L&Hc+LB*//M>iD4Mu8P6NW+t8O8b7?Ont7?PQ$gDQ2[*LQi*6NRK&`S +Rf]+NSc53NT:hjNTq\9VUnji`VPg>jWN)u!XKAV-YHY79ZEppG[^NZT\[oDc]Y2%o^qmn)_o9U7 +a2l?DbKJ,ScHab_dF$CkeC<%"rmq2'g&B\,gYCT`h#cHjhu2L5iW%p8j8S-=jn\';kPXQ=l29iF +lh]uHmJcPNn,DhVnb_nVoDeI[p&=[bp\Xabq>L0cqu-HjrUBf;s+14Es*t~> +JcC<$JcDVImf*+^rVZNhrqcZjr:pMM[1GLkkta!JQ4+K*$XUJc:0$IsukGIK+]pHiA?kH2i-e +GQ2jdFo6@\F8g4XEW0qVDu4GOD>nAKC]8)KC&DZDBE)T@AcHf?27g: +?i4=0@JOC3A,Ts8Ac66?BDQ<>C&D_oC\_fED>J/MDuO_REW:(ZF8g:]FoQXaGQ2pfH2`*kH[L5? +IK+`rJ,XuuJH1<#K*$^[L&Hc+LB*//M>iD4Mu8P6NW+t8O8b7?Ont7?PQ$gDQ2[*LQi*6NRK&`S +Rf]+NSc53NT:hjNTq\9VUnji`VPg>jWN)u!XKAV-YHY79ZEppG[^NZT\[oDc]Y2%o^qmn)_o9U7 +a2l?DbKJ,ScHab_dF$CkeC<%"rmq2'g&B\,gYCT`h#cHjhu2L5iW%p8j8S-=jn\';kPXQ=l29iF +lh]uHmJcPNn,DhVnb_nVoDeI[p&=[bp\Xabq>L0cqu-HjrUBf;s+14Es*t~> +JcC<$JcDVImf*+^rVZNhrqcZjr:pMM[1GLkkta!JQ4+K*$XUJc:0$IsukGIK+]pHiA?kH2i-e +GQ2jdFo6@\F8g4XEW0qVDu4GOD>nAKC]8)KC&DZDBE)T@AcHf?27g: +?i4=0@JOC3A,Ts8Ac66?BDQ<>C&D_oC\_fED>J/MDuO_REW:(ZF8g:]FoQXaGQ2pfH2`*kH[L5? +IK+`rJ,XuuJH1<#K*$^[L&Hc+LB*//M>iD4Mu8P6NW+t8O8b7?Ont7?PQ$gDQ2[*LQi*6NRK&`S +Rf]+NSc53NT:hjNTq\9VUnji`VPg>jWN)u!XKAV-YHY79ZEppG[^NZT\[oDc]Y2%o^qmn)_o9U7 +a2l?DbKJ,ScHab_dF$CkeC<%"rmq2'g&B\,gYCT`h#cHjhu2L5iW%p8j8S-=jn\';kPXQ=l29iF +lh]uHmJcPNn,DhVnb_nVoDeI[p&=[bp\Xabq>L0cqu-HjrUBf;s+14Es*t~> +JcC<$JcDPGn,E7`rVZNhrqcWirV6Bds7ZHbs7H?_rpp*Z!:^!Vs6]mSrp9[N!:'RJ!U/_Gk5XNH +jQ#:[io0mp#N+Cph;-lAg]#n3g"=s/f@JO'rm^ts!7Lkos3Lblrm(Pg!6kGcs2k>`rlG,[!65#W +!Q;nT_@+2q^q[Xu]tM(k]=S!P"h;%M[^ELAZR)o^Yct=6Xf\\*WiE%sVl-DgUnjc[TqS-OSt;LC +S"#k7R$a5+rfmYOPEM)kOT(:PNfB!VMi*CKM26qBL5(D9K`6W(JcLB$JH(*!If4]pHiSNlHN/9j +Gl2dcG5cX^FT-@]Er0kUE;jeQDZ4MPD#A)JCB&#GB`;ZEB)H6>AH-0:@fBg8@/41-?M@b">kVJ! +?LM7e@,52e@/OI/@f9g9AG]s:B)ZH>B`2ZCC@>rpD#8)FDZ4SRE;aeUErU4[FT6L`G5c^cGlN'g +H3/G@I/\NqIXckHJH(0#K)UE&K`?c*LB!&/M#N82MZ8V4N;nn:Nr4t;OT(C=P5^[EPkp[EQN* +JcC<$JcDPGn,E7`rVZNhrqcWirV6Bds7ZHbs7H?_rpp*Z!:^!Vs6]mSrp9[N!:'RJ!U/_Gk5XNH +jQ#:[io0mp#N+Cph;-lAg]#n3g"=s/f@JO'rm^ts!7Lkos3Lblrm(Pg!6kGcs2k>`rlG,[!65#W +!Q;nT_@+2q^q[Xu]tM(k]=S!P"h;%M[^ELAZR)o^Yct=6Xf\\*WiE%sVl-DgUnjc[TqS-OSt;LC +S"#k7R$a5+rfmYOPEM)kOT(:PNfB!VMi*CKM26qBL5(D9K`6W(JcLB$JH(*!If4]pHiSNlHN/9j +Gl2dcG5cX^FT-@]Er0kUE;jeQDZ4MPD#A)JCB&#GB`;ZEB)H6>AH-0:@fBg8@/41-?M@b">kVJ! +?LM7e@,52e@/OI/@f9g9AG]s:B)ZH>B`2ZCC@>rpD#8)FDZ4SRE;aeUErU4[FT6L`G5c^cGlN'g +H3/G@I/\NqIXckHJH(0#K)UE&K`?c*LB!&/M#N82MZ8V4N;nn:Nr4t;OT(C=P5^[EPkp[EQN* +JcC<$JcDPGn,E7`rVZNhrqcWirV6Bds7ZHbs7H?_rpp*Z!:^!Vs6]mSrp9[N!:'RJ!U/_Gk5XNH +jQ#:[io0mp#N+Cph;-lAg]#n3g"=s/f@JO'rm^ts!7Lkos3Lblrm(Pg!6kGcs2k>`rlG,[!65#W +!Q;nT_@+2q^q[Xu]tM(k]=S!P"h;%M[^ELAZR)o^Yct=6Xf\\*WiE%sVl-DgUnjc[TqS-OSt;LC +S"#k7R$a5+rfmYOPEM)kOT(:PNfB!VMi*CKM26qBL5(D9K`6W(JcLB$JH(*!If4]pHiSNlHN/9j +Gl2dcG5cX^FT-@]Er0kUE;jeQDZ4MPD#A)JCB&#GB`;ZEB)H6>AH-0:@fBg8@/41-?M@b">kVJ! +?LM7e@,52e@/OI/@f9g9AG]s:B)ZH>B`2ZCC@>rpD#8)FDZ4SRE;aeUErU4[FT6L`G5c^cGlN'g +H3/G@I/\NqIXckHJH(0#K)UE&K`?c*LB!&/M#N82MZ8V4N;nn:Nr4t;OT(C=P5^[EPkp[EQN* +JcC<$JcDJEnG`@arVZNhrqcZjr:ps()+=qdTP5ra>M.q-NSspKmAs +g0j2Qq-a).q-s>5rFGe:rau+AqIokBr+bk>ghce'php(Lrc%dTs)S-\rH/'^s*"Bcs*+Nhrd+Tk +s*Xfo!e,WKrdY'$JqEuS!ec8]reCH.!/UT1s,-i7rJ^c9s,R# +JcC<$JcDJEnG`@arVZNhrqcZjr:ps()+=qdTP5ra>M.q-NSspKmAs +g0j2Qq-a).q-s>5rFGe:rau+AqIokBr+bk>ghce'php(Lrc%dTs)S-\rH/'^s*"Bcs*+Nhrd+Tk +s*Xfo!e,WKrdY'$JqEuS!ec8]reCH.!/UT1s,-i7rJ^c9s,R# +JcC<$JcDJEnG`@arVZNhrqcZjr:ps()+=qdTP5ra>M.q-NSspKmAs +g0j2Qq-a).q-s>5rFGe:rau+AqIokBr+bk>ghce'php(Lrc%dTs)S-\rH/'^s*"Bcs*+Nhrd+Tk +s*Xfo!e,WKrdY'$JqEuS!ec8]reCH.!/UT1s,-i7rJ^c9s,R# +JcC<$JcDJEnG`@arVZNhrqcWirV6Bds7ZHbs7H?_rpp*Zs7$$V!q,ICrp0mUlK[Wukih4/jp1#/ +jQ#:[io0mp!oMkkrnRV1g]#q,f`9\(fDjD%ec+(ue,Rkqd/q\@ci22kc-4E2b6#i.ao9?da2Z-< +`Pf^4rk\]P_#D(Y^:h1l]=PSa\[],W[^ELAZR)o^Yct=6Xf\\*WiE%sVl-DgUnjc[TqS-OSt;LC +S"#k7R$a5+rfmYOPEM)kOT(:ANfF$s!K2j7M#iEfreCH,!/1?(s+16%rI=s!IX_6Ds*XinrHeKh +s*4Hcrc\aN;TJbg"GYcd:(edaQ^qe^i@(f\+s3g=tE^h>c=3hu;R6iW%p9j8\3?jnn3>kPaW>l29iE +lhBcEmJZJLn,;bTnb_nVoD\CZp&Fabp\O[aq>L0dqu$BirU9`:s+14Ds*t~> +JcC<$JcDJEnG`@arVZNhrqcWirV6Bds7ZHbs7H?_rpp*Zs7$$V!q,ICrp0mUlK[Wukih4/jp1#/ +jQ#:[io0mp!oMkkrnRV1g]#q,f`9\(fDjD%ec+(ue,Rkqd/q\@ci22kc-4E2b6#i.ao9?da2Z-< +`Pf^4rk\]P_#D(Y^:h1l]=PSa\[],W[^ELAZR)o^Yct=6Xf\\*WiE%sVl-DgUnjc[TqS-OSt;LC +S"#k7R$a5+rfmYOPEM)kOT(:ANfF$s!K2j7M#iEfreCH,!/1?(s+16%rI=s!IX_6Ds*XinrHeKh +s*4Hcrc\aN;TJbg"GYcd:(edaQ^qe^i@(f\+s3g=tE^h>c=3hu;R6iW%p9j8\3?jnn3>kPaW>l29iE +lhBcEmJZJLn,;bTnb_nVoD\CZp&Fabp\O[aq>L0dqu$BirU9`:s+14Ds*t~> +JcC<$JcDJEnG`@arVZNhrqcWirV6Bds7ZHbs7H?_rpp*Zs7$$V!q,ICrp0mUlK[Wukih4/jp1#/ +jQ#:[io0mp!oMkkrnRV1g]#q,f`9\(fDjD%ec+(ue,Rkqd/q\@ci22kc-4E2b6#i.ao9?da2Z-< +`Pf^4rk\]P_#D(Y^:h1l]=PSa\[],W[^ELAZR)o^Yct=6Xf\\*WiE%sVl-DgUnjc[TqS-OSt;LC +S"#k7R$a5+rfmYOPEM)kOT(:ANfF$s!K2j7M#iEfreCH,!/1?(s+16%rI=s!IX_6Ds*XinrHeKh +s*4Hcrc\aN;TJbg"GYcd:(edaQ^qe^i@(f\+s3g=tE^h>c=3hu;R6iW%p9j8\3?jnn3>kPaW>l29iE +lhBcEmJZJLn,;bTnb_nVoD\CZp&Fabp\O[aq>L0dqu$BirU9`:s+14Ds*t~> +JcC<$JcDABnc&Lcr;?HhrqcWirV6Ees7ZEas7H?_rpp*Zs7$$V!q,ICrp0[OlMg&JkQ'fFjoXZ* +jSn0?io0mps5*h5rnRY2gY;_]!nl5Yrn%2$!7h(us3gtrrQt\ncd2U9!mSs5rlYAcaiXP'(!">6 +`Pod6_ns:,_8*h#^:q:n]XtcS\L"bp[^NTNZa6sBYct=6Xf\\*WiE%sVl-DgUnjc[TqS-OSt;LC +rgO4_R@'A.QBd`"PQ$^QOcYWbNfK*XN/NUOreUZ3L]3&.K`Hf*KE$Q'Jc:3"J,ausIK+]oHi89j +H2`'dGQ2jcFo-:\F8g4WEW:"WDu=MPD?"GMC]8)KC&DZEBDuN@Ac?6>A,Ba6@JjNf?hn+%@Imsu +@H_+p@JF=1A,^$8Ac?<@BDQrJ5MuJ\8NW5%:O8k=AOo1CAPQ$gCQ2[*KQhm*KRJrZQ +S,]#YSc,/[TDtS`U&UheU].(hV*1]RVl6PnWiE,$Xf\b0YHY79ZEppG[^NZT\[f;`]Y2%o^VI\& +_o0O5`lH0Bb0.uPc-FV]dF$CkeC<%"rmqP1g"P07gt^`AhVR/hi;_d9ir8! +JcC<$JcDABnc&Lcr;?HhrqcWirV6Ees7ZEas7H?_rpp*Zs7$$V!q,ICrp0[OlMg&JkQ'fFjoXZ* +jSn0?io0mps5*h5rnRY2gY;_]!nl5Yrn%2$!7h(us3gtrrQt\ncd2U9!mSs5rlYAcaiXP'(!">6 +`Pod6_ns:,_8*h#^:q:n]XtcS\L"bp[^NTNZa6sBYct=6Xf\\*WiE%sVl-DgUnjc[TqS-OSt;LC +rgO4_R@'A.QBd`"PQ$^QOcYWbNfK*XN/NUOreUZ3L]3&.K`Hf*KE$Q'Jc:3"J,ausIK+]oHi89j +H2`'dGQ2jcFo-:\F8g4WEW:"WDu=MPD?"GMC]8)KC&DZEBDuN@Ac?6>A,Ba6@JjNf?hn+%@Imsu +@H_+p@JF=1A,^$8Ac?<@BDQrJ5MuJ\8NW5%:O8k=AOo1CAPQ$gCQ2[*KQhm*KRJrZQ +S,]#YSc,/[TDtS`U&UheU].(hV*1]RVl6PnWiE,$Xf\b0YHY79ZEppG[^NZT\[f;`]Y2%o^VI\& +_o0O5`lH0Bb0.uPc-FV]dF$CkeC<%"rmqP1g"P07gt^`AhVR/hi;_d9ir8! +JcC<$JcDABnc&Lcr;?HhrqcWirV6Ees7ZEas7H?_rpp*Zs7$$V!q,ICrp0[OlMg&JkQ'fFjoXZ* +jSn0?io0mps5*h5rnRY2gY;_]!nl5Yrn%2$!7h(us3gtrrQt\ncd2U9!mSs5rlYAcaiXP'(!">6 +`Pod6_ns:,_8*h#^:q:n]XtcS\L"bp[^NTNZa6sBYct=6Xf\\*WiE%sVl-DgUnjc[TqS-OSt;LC +rgO4_R@'A.QBd`"PQ$^QOcYWbNfK*XN/NUOreUZ3L]3&.K`Hf*KE$Q'Jc:3"J,ausIK+]oHi89j +H2`'dGQ2jcFo-:\F8g4WEW:"WDu=MPD?"GMC]8)KC&DZEBDuN@Ac?6>A,Ba6@JjNf?hn+%@Imsu +@H_+p@JF=1A,^$8Ac?<@BDQrJ5MuJ\8NW5%:O8k=AOo1CAPQ$gCQ2[*KQhm*KRJrZQ +S,]#YSc,/[TDtS`U&UheU].(hV*1]RVl6PnWiE,$Xf\b0YHY79ZEppG[^NZT\[f;`]Y2%o^VI\& +_o0O5`lH0Bb0.uPc-FV]dF$CkeC<%"rmqP1g"P07gt^`AhVR/hi;_d9ir8! +JcC<$JcD>Ao)ARcrVZNhrqcZjr:ph;qITYk5XWDkkXK@ +lMTuBm/68KmeQ>MnG_tSo)A7[o_\=\pAXg_q#:*fqYC$dr;?N_rdk*#s7H>A~> +JcC<$JcD>Ao)ARcrVZNhrqcZjr:ph;qITYk5XWDkkXK@ +lMTuBm/68KmeQ>MnG_tSo)A7[o_\=\pAXg_q#:*fqYC$dr;?N_rdk*#s7H>A~> +JcC<$JcD>Ao)ARcrVZNhrqcZjr:ph;qITYk5XWDkkXK@ +lMTuBm/68KmeQ>MnG_tSo)A7[o_\=\pAXg_q#:*fqYC$dr;?N_rdk*#s7H>A~> +JcC<$JcD>Anc&IbrVZQirqcWirV6Bds7ZEa!qc*UrUL$[nF6GGs6]mSrp9[N!:'RJ!pJh1roO:D +jQ-=##NF_$i8EMMhYl73gtUT_g&fs[f`'M&ec=8!e,n+Idf.YociDDjc2u87bl5cjb/qcHaN)?@ +rl"oV_u@LR_8-&b"hq[_]XtcS\Mq%-[^NTNZa6sBYct=6Xf\\*WiE%sVl-DgUnjc[TqS-OSt;LC +S"#k8R@'A.QBd`"PEV/mOc]R'!KN0=MunopMZ/G5Lkktas+UK+re(6&!.k*!s*t&trI+]nrd4Ti +rd"Ngqfi'`rcS*[s)\0[r,M^Ts)7gQs)%aOrG2CIs(VCEs(D=Cr+5kY4r*eYopgMQZk@+$m +rF>e:qITYrG5MuJ\8NW5%;O8k=AOo:IBPQ-mEQ2[*KQhm*KRJrZPS,SrWSc,/Z +TDtS`U&UkeU].(hV#[ClVZE`qri/#[XKAV-Y-5(6Z*L^B['d?N\%&u[]=bei^;%G!_SX4/`Pom= +aN;TJbKS5Vcd:(edaQ^qe^i@(f\-8X#2@qhh;7#Grnmk:io9sts5a4Ar9"%Broj4CrTa=Hp[%eE +r9jCLrUBdUqXXXWrUg![rq??cqY:'crVH?er;?HjnG\"=JcGBBJ,~> +JcC<$JcD>Anc&IbrVZQirqcWirV6Bds7ZEa!qc*UrUL$[nF6GGs6]mSrp9[N!:'RJ!pJh1roO:D +jQ-=##NF_$i8EMMhYl73gtUT_g&fs[f`'M&ec=8!e,n+Idf.YociDDjc2u87bl5cjb/qcHaN)?@ +rl"oV_u@LR_8-&b"hq[_]XtcS\Mq%-[^NTNZa6sBYct=6Xf\\*WiE%sVl-DgUnjc[TqS-OSt;LC +S"#k8R@'A.QBd`"PEV/mOc]R'!KN0=MunopMZ/G5Lkktas+UK+re(6&!.k*!s*t&trI+]nrd4Ti +rd"Ngqfi'`rcS*[s)\0[r,M^Ts)7gQs)%aOrG2CIs(VCEs(D=Cr+5kY4r*eYopgMQZk@+$m +rF>e:qITYrG5MuJ\8NW5%;O8k=AOo:IBPQ-mEQ2[*KQhm*KRJrZPS,SrWSc,/Z +TDtS`U&UkeU].(hV#[ClVZE`qri/#[XKAV-Y-5(6Z*L^B['d?N\%&u[]=bei^;%G!_SX4/`Pom= +aN;TJbKS5Vcd:(edaQ^qe^i@(f\-8X#2@qhh;7#Grnmk:io9sts5a4Ar9"%Broj4CrTa=Hp[%eE +r9jCLrUBdUqXXXWrUg![rq??cqY:'crVH?er;?HjnG\"=JcGBBJ,~> +JcC<$JcD>Anc&IbrVZQirqcWirV6Bds7ZEa!qc*UrUL$[nF6GGs6]mSrp9[N!:'RJ!pJh1roO:D +jQ-=##NF_$i8EMMhYl73gtUT_g&fs[f`'M&ec=8!e,n+Idf.YociDDjc2u87bl5cjb/qcHaN)?@ +rl"oV_u@LR_8-&b"hq[_]XtcS\Mq%-[^NTNZa6sBYct=6Xf\\*WiE%sVl-DgUnjc[TqS-OSt;LC +S"#k8R@'A.QBd`"PEV/mOc]R'!KN0=MunopMZ/G5Lkktas+UK+re(6&!.k*!s*t&trI+]nrd4Ti +rd"Ngqfi'`rcS*[s)\0[r,M^Ts)7gQs)%aOrG2CIs(VCEs(D=Cr+5kY4r*eYopgMQZk@+$m +rF>e:qITYrG5MuJ\8NW5%;O8k=AOo:IBPQ-mEQ2[*KQhm*KRJrZPS,SrWSc,/Z +TDtS`U&UkeU].(hV#[ClVZE`qri/#[XKAV-Y-5(6Z*L^B['d?N\%&u[]=bei^;%G!_SX4/`Pom= +aN;TJbKS5Vcd:(edaQ^qe^i@(f\-8X#2@qhh;7#Grnmk:io9sts5a4Ar9"%Broj4CrTa=Hp[%eE +r9jCLrUBdUqXXXWrUg![rq??cqY:'crVH?er;?HjnG\"=JcGBBJ,~> +JcC<$JcD;@nc&IbrVZQirqcZjr:p&s4.2#rR:ntdaJ-Bs3Lblrm(Pgs31Mds2k>`rl>Yk +`l?!:`5KR1_SO((^V@Lrrk("u]",A]\$i`Q['R*EZ*:I9Y-"h-X/`2!W2HPjV50o^U7n9RTV%gI +SXc1=R[KP1Q^7W9!L/fIOo^],rf7)?NW+kOT1IAP5gaFPl-gGQN*ai_fMbg"GYcd:(fe'umtf%8O+g"G*5gYDea!T)`5hu_lsir8! +JcC<$JcD;@nc&IbrVZQirqcZjr:p&s4.2#rR:ntdaJ-Bs3Lblrm(Pgs31Mds2k>`rl>Yk +`l?!:`5KR1_SO((^V@Lrrk("u]",A]\$i`Q['R*EZ*:I9Y-"h-X/`2!W2HPjV50o^U7n9RTV%gI +SXc1=R[KP1Q^7W9!L/fIOo^],rf7)?NW+kOT1IAP5gaFPl-gGQN*ai_fMbg"GYcd:(fe'umtf%8O+g"G*5gYDea!T)`5hu_lsir8! +JcC<$JcD;@nc&IbrVZQirqcZjr:p&s4.2#rR:ntdaJ-Bs3Lblrm(Pgs31Mds2k>`rl>Yk +`l?!:`5KR1_SO((^V@Lrrk("u]",A]\$i`Q['R*EZ*:I9Y-"h-X/`2!W2HPjV50o^U7n9RTV%gI +SXc1=R[KP1Q^7W9!L/fIOo^],rf7)?NW+kOT1IAP5gaFPl-gGQN*ai_fMbg"GYcd:(fe'umtf%8O+g"G*5gYDea!T)`5hu_lsir8! +JcC<$JcD8?o)ARcrVZNhs8)`jr:pOT1IAP5gaGPl-gHQN!6JR/WNQReiNQSGo)VT)PA^ +T_tM`UAq"fV#R:kVZ*J$W2ZbrWiN5&Xf\b0rie;cZEpmE[C3NQ\@K/]]=bei^V@S#_SX4/`Q#s> +aN;TJbK\>Xcd:(edaQ^qe^i@(f\,!4gYDea!T)`5hu_lsir8! +JcC<$JcD8?o)ARcrVZNhs8)`jr:pOT1IAP5gaGPl-gHQN!6JR/WNQReiNQSGo)VT)PA^ +T_tM`UAq"fV#R:kVZ*J$W2ZbrWiN5&Xf\b0rie;cZEpmE[C3NQ\@K/]]=bei^V@S#_SX4/`Q#s> +aN;TJbK\>Xcd:(edaQ^qe^i@(f\,!4gYDea!T)`5hu_lsir8! +JcC<$JcD8?o)ARcrVZNhs8)`jr:pOT1IAP5gaGPl-gHQN!6JR/WNQReiNQSGo)VT)PA^ +T_tM`UAq"fV#R:kVZ*J$W2ZbrWiN5&Xf\b0rie;cZEpmE[C3NQ\@K/]]=bei^V@S#_SX4/`Q#s> +aN;TJbK\>Xcd:(edaQ^qe^i@(f\,!4gYDea!T)`5hu_lsir8! +JcC<$JcD8?nc&LcrVZNhrqcZjr:p+f\$/S!nPoPrm^tss3gnos3Lblrm(Pg!6kGcs2k>`rl>,\ +`rSEY^V7Fq]Y(kf\[f5Z[^NTNZa6sBYct=6Xf\\*WiE%sVl-DgUnjc[TqS-OT:VXF +S=?":R@'A.Q^3o%P`q;oP*(ifO,o<]NW+kAc60;A)CbhA)q1oA)Uno +A,Ts6Ac?OT1IBP5gaGPl6mHQN*Vf]tV7r_8=(,`5T^8 +a2lBFbKJ,ScHaeadF-LneCE.%f@\d1g=tE +JcC<$JcD8?nc&LcrVZNhrqcZjr:p+f\$/S!nPoPrm^tss3gnos3Lblrm(Pg!6kGcs2k>`rl>,\ +`rSEY^V7Fq]Y(kf\[f5Z[^NTNZa6sBYct=6Xf\\*WiE%sVl-DgUnjc[TqS-OT:VXF +S=?":R@'A.Q^3o%P`q;oP*(ifO,o<]NW+kAc60;A)CbhA)q1oA)Uno +A,Ts6Ac?OT1IBP5gaGPl6mHQN*Vf]tV7r_8=(,`5T^8 +a2lBFbKJ,ScHaeadF-LneCE.%f@\d1g=tE +JcC<$JcD8?nc&LcrVZNhrqcZjr:p+f\$/S!nPoPrm^tss3gnos3Lblrm(Pg!6kGcs2k>`rl>,\ +`rSEY^V7Fq]Y(kf\[f5Z[^NTNZa6sBYct=6Xf\\*WiE%sVl-DgUnjc[TqS-OT:VXF +S=?":R@'A.Q^3o%P`q;oP*(ifO,o<]NW+kAc60;A)CbhA)q1oA)Uno +A,Ts6Ac?OT1IBP5gaGPl6mHQN*Vf]tV7r_8=(,`5T^8 +a2lBFbKJ,ScHaeadF-LneCE.%f@\d1g=tE +JcC<$JcD8?nc&IbrVZQirqcWir:ps5O(;rnmk8hVS7fs4mY/rn@D*s4I>&s475#rm^tss3gnos3Lblrm(Pg!6kGcs2k>`rl>,\ +`rrA3L])u-L&Zi*KE$Q'Jc(&uJ,auqIK"Wo +Hi/3hH2i-eGQ)dcFo6@]F8g4YEW:"WDuFSRD>nAMC]8)KC&DZDBDuN=Ac-*7A+3t$A+jI!AbK[. +A*[V#A,Km5Ac66?BDZBAC&VlDC]/)JD>.rCDrbm0EW'qWF8L(ZFoQX`GQ2pfH2`*kH[L5?I0+kI +J,Xs!JV*lR#D@ebL5(J=M#N54MMmDlMueourJq#AOcfX+s-*JIrK[DKs-NYNrgEbSqj[STrLNhW +rh'1_qk=%arhKFfs/#amrhodp!3,sts/Q.$riH4(YPtaYZ*L^B['d?N\%&uZ]">Vf]tV7r^qmn) +`5T^8a2l?Db0/#RcHab_dF$CkeC<%Jf+6Neg=k<:h;-rFhr*GOiSsjs!p&J)rT=.Cs60FGrp'LK +q<\(IqsO.Gr:'XSq""CTrUfsZrV$6bqY:$brVH +JcC<$JcD8?nc&IbrVZQirqcWir:ps5O(;rnmk8hVS7fs4mY/rn@D*s4I>&s475#rm^tss3gnos3Lblrm(Pg!6kGcs2k>`rl>,\ +`rrA3L])u-L&Zi*KE$Q'Jc(&uJ,auqIK"Wo +Hi/3hH2i-eGQ)dcFo6@]F8g4YEW:"WDuFSRD>nAMC]8)KC&DZDBDuN=Ac-*7A+3t$A+jI!AbK[. +A*[V#A,Km5Ac66?BDZBAC&VlDC]/)JD>.rCDrbm0EW'qWF8L(ZFoQX`GQ2pfH2`*kH[L5?I0+kI +J,Xs!JV*lR#D@ebL5(J=M#N54MMmDlMueourJq#AOcfX+s-*JIrK[DKs-NYNrgEbSqj[STrLNhW +rh'1_qk=%arhKFfs/#amrhodp!3,sts/Q.$riH4(YPtaYZ*L^B['d?N\%&uZ]">Vf]tV7r^qmn) +`5T^8a2l?Db0/#RcHab_dF$CkeC<%Jf+6Neg=k<:h;-rFhr*GOiSsjs!p&J)rT=.Cs60FGrp'LK +q<\(IqsO.Gr:'XSq""CTrUfsZrV$6bqY:$brVH +JcC<$JcD8?nc&IbrVZQirqcWir:ps5O(;rnmk8hVS7fs4mY/rn@D*s4I>&s475#rm^tss3gnos3Lblrm(Pg!6kGcs2k>`rl>,\ +`rrA3L])u-L&Zi*KE$Q'Jc(&uJ,auqIK"Wo +Hi/3hH2i-eGQ)dcFo6@]F8g4YEW:"WDuFSRD>nAMC]8)KC&DZDBDuN=Ac-*7A+3t$A+jI!AbK[. +A*[V#A,Km5Ac66?BDZBAC&VlDC]/)JD>.rCDrbm0EW'qWF8L(ZFoQX`GQ2pfH2`*kH[L5?I0+kI +J,Xs!JV*lR#D@ebL5(J=M#N54MMmDlMueourJq#AOcfX+s-*JIrK[DKs-NYNrgEbSqj[STrLNhW +rh'1_qk=%arhKFfs/#amrhodp!3,sts/Q.$riH4(YPtaYZ*L^B['d?N\%&uZ]">Vf]tV7r^qmn) +`5T^8a2l?Db0/#RcHab_dF$CkeC<%Jf+6Neg=k<:h;-rFhr*GOiSsjs!p&J)rT=.Cs60FGrp'LK +q<\(IqsO.Gr:'XSq""CTrUfsZrV$6bqY:$brVH +JcC<$JcD5>nc&LcrVZNhrqcWirV6Bds7ZEas7H?_rpp*Zs7$$Vs6]mSrp9[Ns6BUJ!pJh1roX7B +!9F+=!oi1tro!h6s5*b2s4mY/rn@D*s4I>&s475#rm^tss3gnos3Lblrm(Pg!6kGc4j(mgaN2EB +`l5p8_o'@._8*h#^:q:n]Xtbc\[],W[^EKKZa-j?Yck43XfSS'Wi;qpVl$;dUnaZXTqJ%WSct[T +S"#k7rg3_QQN!-MP`u*0!KiKCO8k4?NW+n:MZAY5M#rKgL])r/KnP-XKE$Q&Jc1-!J,XopIK+]o +Hi/3iH2`'eGQ)dcFo6@]F8p:YEW:"XDuFSQD?"GMC]A/KC&DZDBDlH;Abos*A+aBdAbT`qA,Bg4 +Ac66?BDQ<@C&VlEC]8/KD>8#GDtS)-EVskUF8L(ZFoQX`GQ2pfH2`-iHiJKmI0Y4NIt3'#JV*lR +!JH1+L'NKiLl$tGMMqIm!f`5#rf7,BOcfX+s-*JIrg!MLs-NYNs-`kTr1!YTrginWrh'1_qk="` +rhKFfs/#amrMT[os/H!t6E@2hXf\b/YHY79Z*L^B['d?N\%&rY\[oDc]tV7r^qmn)_o0O5a2l?D +b0.uPc-FY^dF$CkeC<%"f@S[.g=k<:rnRe8hr*GOiSsjs!p&J)roX7Ds60CFs6BULqX"1Jr9j7H +qsaORp[\:SrUfpYrV$6bq=ssbrVH +JcC<$JcD5>nc&LcrVZNhrqcWirV6Bds7ZEas7H?_rpp*Zs7$$Vs6]mSrp9[Ns6BUJ!pJh1roX7B +!9F+=!oi1tro!h6s5*b2s4mY/rn@D*s4I>&s475#rm^tss3gnos3Lblrm(Pg!6kGc4j(mgaN2EB +`l5p8_o'@._8*h#^:q:n]Xtbc\[],W[^EKKZa-j?Yck43XfSS'Wi;qpVl$;dUnaZXTqJ%WSct[T +S"#k7rg3_QQN!-MP`u*0!KiKCO8k4?NW+n:MZAY5M#rKgL])r/KnP-XKE$Q&Jc1-!J,XopIK+]o +Hi/3iH2`'eGQ)dcFo6@]F8p:YEW:"XDuFSQD?"GMC]A/KC&DZDBDlH;Abos*A+aBdAbT`qA,Bg4 +Ac66?BDQ<@C&VlEC]8/KD>8#GDtS)-EVskUF8L(ZFoQX`GQ2pfH2`-iHiJKmI0Y4NIt3'#JV*lR +!JH1+L'NKiLl$tGMMqIm!f`5#rf7,BOcfX+s-*JIrg!MLs-NYNs-`kTr1!YTrginWrh'1_qk="` +rhKFfs/#amrMT[os/H!t6E@2hXf\b/YHY79Z*L^B['d?N\%&rY\[oDc]tV7r^qmn)_o0O5a2l?D +b0.uPc-FY^dF$CkeC<%"f@S[.g=k<:rnRe8hr*GOiSsjs!p&J)roX7Ds60CFs6BULqX"1Jr9j7H +qsaORp[\:SrUfpYrV$6bq=ssbrVH +JcC<$JcD5>nc&LcrVZNhrqcWirV6Bds7ZEas7H?_rpp*Zs7$$Vs6]mSrp9[Ns6BUJ!pJh1roX7B +!9F+=!oi1tro!h6s5*b2s4mY/rn@D*s4I>&s475#rm^tss3gnos3Lblrm(Pg!6kGc4j(mgaN2EB +`l5p8_o'@._8*h#^:q:n]Xtbc\[],W[^EKKZa-j?Yck43XfSS'Wi;qpVl$;dUnaZXTqJ%WSct[T +S"#k7rg3_QQN!-MP`u*0!KiKCO8k4?NW+n:MZAY5M#rKgL])r/KnP-XKE$Q&Jc1-!J,XopIK+]o +Hi/3iH2`'eGQ)dcFo6@]F8p:YEW:"XDuFSQD?"GMC]A/KC&DZDBDlH;Abos*A+aBdAbT`qA,Bg4 +Ac66?BDQ<@C&VlEC]8/KD>8#GDtS)-EVskUF8L(ZFoQX`GQ2pfH2`-iHiJKmI0Y4NIt3'#JV*lR +!JH1+L'NKiLl$tGMMqIm!f`5#rf7,BOcfX+s-*JIrg!MLs-NYNs-`kTr1!YTrginWrh'1_qk="` +rhKFfs/#amrMT[os/H!t6E@2hXf\b/YHY79Z*L^B['d?N\%&rY\[oDc]tV7r^qmn)_o0O5a2l?D +b0.uPc-FY^dF$CkeC<%"f@S[.g=k<:rnRe8hr*GOiSsjs!p&J)roX7Ds60CFs6BULqX"1Jr9j7H +qsaORp[\:SrUfpYrV$6bq=ssbrVH +JcC<$JcD5>nc&IbrVZNhrqcZjr:ps5F%;rS[_5!8d\1s4dV/rS%;)s4I>&s475#rm^tss3gnos3Lblrm(Pg!6kGc!QrO`a8s?$ +rl"oV_u@M!_8*h#^:h1l]=PP`\@8oT[C*BJZa$a=YHG"0XK/A$WMl_mVPX9f$)=5gTqJ$LSt2DN +RgY[QR$a5,QBd`"P`u*0!KiKCO8k4?NW+n:MuS\6M>rD3L]3&.L&Zi)KE$Q&Jc1,uJ,auqIK+]o +Hi/3iH2`'eGQ)dcFo?F]F8p:ZEW:"WDuFSRD>nAMC]8)JC&;TCBDlH7Aaa0iAcHB*AbK[)A,'U0 +Ac66?BDQ<@C&VlEC]8/KD>A)IDu+G.EVjeSF8L(YFoQX_GQ2mfH2W'hHN8HmIK+`rJ,Xs'JV&K+ +K7no3re:H/M#N59MMmCON/`gWrf@)@!0R8Ds-!GIrK[DKs-N\Os-`nUqj[VUrginWrh'.^qk="` +rhKCerh]XlrMT[os/H!ts/Q.$riJ>dYHP17Z*L[AZa@-K[^W`U\[f;`]Y(ql^VI\&_Sa=2`Q#s> +aND]Lbg"GYcd:(fe'umtf%8O+g"P07h#?+6hV[8LiSieqir\<'jo4EBkPscEl2U&Jlhg&ImJZJH +n,)VOnb2POoDS=Wp&4U_p\O[`q>L0bqu$BhrU9`:s+14>s*t~> +JcC<$JcD5>nc&IbrVZNhrqcZjr:ps5F%;rS[_5!8d\1s4dV/rS%;)s4I>&s475#rm^tss3gnos3Lblrm(Pg!6kGc!QrO`a8s?$ +rl"oV_u@M!_8*h#^:h1l]=PP`\@8oT[C*BJZa$a=YHG"0XK/A$WMl_mVPX9f$)=5gTqJ$LSt2DN +RgY[QR$a5,QBd`"P`u*0!KiKCO8k4?NW+n:MuS\6M>rD3L]3&.L&Zi)KE$Q&Jc1,uJ,auqIK+]o +Hi/3iH2`'eGQ)dcFo?F]F8p:ZEW:"WDuFSRD>nAMC]8)JC&;TCBDlH7Aaa0iAcHB*AbK[)A,'U0 +Ac66?BDQ<@C&VlEC]8/KD>A)IDu+G.EVjeSF8L(YFoQX_GQ2mfH2W'hHN8HmIK+`rJ,Xs'JV&K+ +K7no3re:H/M#N59MMmCON/`gWrf@)@!0R8Ds-!GIrK[DKs-N\Os-`nUqj[VUrginWrh'.^qk="` +rhKCerh]XlrMT[os/H!ts/Q.$riJ>dYHP17Z*L[AZa@-K[^W`U\[f;`]Y(ql^VI\&_Sa=2`Q#s> +aND]Lbg"GYcd:(fe'umtf%8O+g"P07h#?+6hV[8LiSieqir\<'jo4EBkPscEl2U&Jlhg&ImJZJH +n,)VOnb2POoDS=Wp&4U_p\O[`q>L0bqu$BhrU9`:s+14>s*t~> +JcC<$JcD5>nc&IbrVZNhrqcZjr:ps5F%;rS[_5!8d\1s4dV/rS%;)s4I>&s475#rm^tss3gnos3Lblrm(Pg!6kGc!QrO`a8s?$ +rl"oV_u@M!_8*h#^:h1l]=PP`\@8oT[C*BJZa$a=YHG"0XK/A$WMl_mVPX9f$)=5gTqJ$LSt2DN +RgY[QR$a5,QBd`"P`u*0!KiKCO8k4?NW+n:MuS\6M>rD3L]3&.L&Zi)KE$Q&Jc1,uJ,auqIK+]o +Hi/3iH2`'eGQ)dcFo?F]F8p:ZEW:"WDuFSRD>nAMC]8)JC&;TCBDlH7Aaa0iAcHB*AbK[)A,'U0 +Ac66?BDQ<@C&VlEC]8/KD>A)IDu+G.EVjeSF8L(YFoQX_GQ2mfH2W'hHN8HmIK+`rJ,Xs'JV&K+ +K7no3re:H/M#N59MMmCON/`gWrf@)@!0R8Ds-!GIrK[DKs-N\Os-`nUqj[VUrginWrh'.^qk="` +rhKCerh]XlrMT[os/H!ts/Q.$riJ>dYHP17Z*L[AZa@-K[^W`U\[f;`]Y(ql^VI\&_Sa=2`Q#s> +aND]Lbg"GYcd:(fe'umtf%8O+g"P07h#?+6hV[8LiSieqir\<'jo4EBkPscEl2U&Jlhg&ImJZJH +n,)VOnb2POoDS=Wp&4U_p\O[`q>L0bqu$BhrU9`:s+14>s*t~> +JcC<$JcD2=o)ARcrVZNhrqcWir:p&s475#rm^tss3gnos3LblrltSibfp(0!QrO`a8s?$ +rl#&Z_ns:,_#D(t^:h1l]=PP`\@8oT[C!9HZE^X\ +S!ob5R$a5+QBd`"P`u*0#a(41O,o<]NK*pr!fMqnrJCQ1!/LN-s+UK+r.G$$s+1)us*t#srI+Zm +s*OZis*=TgrHJ9brcS0]s)\3\r,MaUs)7jRrb_[Or+l:Hrb;7CrFc%?g1B/Rmq(`ook")6rb)(@ +rb;@HqeQ1IrGDCKrGVRPic4X3qfDRTrcS6ar-/0cs*=Qh!df"[^NZS\@K/]]=bei^;%Fu_8=+.`Poj;aN2KGbKJ/U +cHjkbdF-LneCE.%f@\d1g=tE=h;7&ghuVfrro4(@jlQL(s6'FGrTX@Is6KRKrpB[Pp[A"Kqsj@M +r:BjYq=X^[rV--_rV?Egq"t!equ,s^JcC<$nGe"~> +JcC<$JcD2=o)ARcrVZNhrqcWir:p&s475#rm^tss3gnos3LblrltSibfp(0!QrO`a8s?$ +rl#&Z_ns:,_#D(t^:h1l]=PP`\@8oT[C!9HZE^X\ +S!ob5R$a5+QBd`"P`u*0#a(41O,o<]NK*pr!fMqnrJCQ1!/LN-s+UK+r.G$$s+1)us*t#srI+Zm +s*OZis*=TgrHJ9brcS0]s)\3\r,MaUs)7jRrb_[Or+l:Hrb;7CrFc%?g1B/Rmq(`ook")6rb)(@ +rb;@HqeQ1IrGDCKrGVRPic4X3qfDRTrcS6ar-/0cs*=Qh!df"[^NZS\@K/]]=bei^;%Fu_8=+.`Poj;aN2KGbKJ/U +cHjkbdF-LneCE.%f@\d1g=tE=h;7&ghuVfrro4(@jlQL(s6'FGrTX@Is6KRKrpB[Pp[A"Kqsj@M +r:BjYq=X^[rV--_rV?Egq"t!equ,s^JcC<$nGe"~> +JcC<$JcD2=o)ARcrVZNhrqcWir:p&s475#rm^tss3gnos3LblrltSibfp(0!QrO`a8s?$ +rl#&Z_ns:,_#D(t^:h1l]=PP`\@8oT[C!9HZE^X\ +S!ob5R$a5+QBd`"P`u*0#a(41O,o<]NK*pr!fMqnrJCQ1!/LN-s+UK+r.G$$s+1)us*t#srI+Zm +s*OZis*=TgrHJ9brcS0]s)\3\r,MaUs)7jRrb_[Or+l:Hrb;7CrFc%?g1B/Rmq(`ook")6rb)(@ +rb;@HqeQ1IrGDCKrGVRPic4X3qfDRTrcS6ar-/0cs*=Qh!df"[^NZS\@K/]]=bei^;%Fu_8=+.`Poj;aN2KGbKJ/U +cHjkbdF-LneCE.%f@\d1g=tE=h;7&ghuVfrro4(@jlQL(s6'FGrTX@Is6KRKrpB[Pp[A"Kqsj@M +r:BjYq=X^[rV--_rV?Egq"t!equ,s^JcC<$nGe"~> +JcC<$JcD2=nc&IbrVZNhrqcZjr:p9cs7ZEas7H?_rUL$[nF6DF!q,ICrp9[Ns6BUJs60LGroX7B +!9F+=s5F%;rS[_5s5*_1!o2PbrS%;)s4I>&s475#rm^tss3gno!mo9>rlu)"bfn8Rb/qcHaN) +S!ocEQiWP>rfmPLPEZ!/!g/S+rf7,@NK*prs,6o7re^Z2s+gQ-s+UK+r.G$$s+1)us*t#sr-eTm +s*OZis*=TgrHJ9bs)n6]s)\3\rGhjVrbqaQs)%aOr+l:Hrb;4Br+Gh;m:Gs&j(J*ueRe\krFbt? +rb;@HqeQ1Irb_LLrGVUQo5X#8pN-(NrcS3`r-/0cs*=Qhs*F`nrI"p"It*!!JUrFPK+*EeKnb>; +LkpnEMMd>kMueourf7;GOcbfiPEV70Pld8d@i +VuN^qWVrjsWrT7"XTu#4YHY79Z*OA86aX80[^WcV\[f;`]Y(ql^V@S#_SX4/`Pom=aN;TJbKS5V +cHjncdaQ^qe^i@(f\,!4gYCW@hV[5Ki8N\Tj5]4]jo4EBk5a`El2U&Klhg&JmJcPKn,)VOnauDM +oDJ7Up&4U^p\FU_q>L0bqu$BhrU0Z9s+14=s*t~> +JcC<$JcD2=nc&IbrVZNhrqcZjr:p9cs7ZEas7H?_rUL$[nF6DF!q,ICrp9[Ns6BUJs60LGroX7B +!9F+=s5F%;rS[_5s5*_1!o2PbrS%;)s4I>&s475#rm^tss3gno!mo9>rlu)"bfn8Rb/qcHaN) +S!ocEQiWP>rfmPLPEZ!/!g/S+rf7,@NK*prs,6o7re^Z2s+gQ-s+UK+r.G$$s+1)us*t#sr-eTm +s*OZis*=TgrHJ9bs)n6]s)\3\rGhjVrbqaQs)%aOr+l:Hrb;4Br+Gh;m:Gs&j(J*ueRe\krFbt? +rb;@HqeQ1Irb_LLrGVUQo5X#8pN-(NrcS3`r-/0cs*=Qhs*F`nrI"p"It*!!JUrFPK+*EeKnb>; +LkpnEMMd>kMueourf7;GOcbfiPEV70Pld8d@i +VuN^qWVrjsWrT7"XTu#4YHY79Z*OA86aX80[^WcV\[f;`]Y(ql^V@S#_SX4/`Pom=aN;TJbKS5V +cHjncdaQ^qe^i@(f\,!4gYCW@hV[5Ki8N\Tj5]4]jo4EBk5a`El2U&Klhg&JmJcPKn,)VOnauDM +oDJ7Up&4U^p\FU_q>L0bqu$BhrU0Z9s+14=s*t~> +JcC<$JcD2=nc&IbrVZNhrqcZjr:p9cs7ZEas7H?_rUL$[nF6DF!q,ICrp9[Ns6BUJs60LGroX7B +!9F+=s5F%;rS[_5s5*_1!o2PbrS%;)s4I>&s475#rm^tss3gno!mo9>rlu)"bfn8Rb/qcHaN) +S!ocEQiWP>rfmPLPEZ!/!g/S+rf7,@NK*prs,6o7re^Z2s+gQ-s+UK+r.G$$s+1)us*t#sr-eTm +s*OZis*=TgrHJ9bs)n6]s)\3\rGhjVrbqaQs)%aOr+l:Hrb;4Br+Gh;m:Gs&j(J*ueRe\krFbt? +rb;@HqeQ1Irb_LLrGVUQo5X#8pN-(NrcS3`r-/0cs*=Qhs*F`nrI"p"It*!!JUrFPK+*EeKnb>; +LkpnEMMd>kMueourf7;GOcbfiPEV70Pld8d@i +VuN^qWVrjsWrT7"XTu#4YHY79Z*OA86aX80[^WcV\[f;`]Y(ql^V@S#_SX4/`Pom=aN;TJbKS5V +cHjncdaQ^qe^i@(f\,!4gYCW@hV[5Ki8N\Tj5]4]jo4EBk5a`El2U&Klhg&JmJcPKn,)VOnauDM +oDJ7Up&4U^p\FU_q>L0bqu$BhrU0Z9s+14=s*t~> +JcC<$JcD2=nc&IbrVZNhrqcWir:ps5O(;rS[_5s5*_1!o2PbrS%;)s4I;%!nPoPrm^tss3gno!mo9>rltPhbl5cib/qcHaN)=" +`Ab`Q_SX.)^V@Lr]tD"i]",A]\$i`Q['R*EZ*:I9Y-"h-X/`2!W2HPjV50o^U7n9RT:_^HSXf\K +!LfGUQiWP>rg!MJ!0dDF!g/S+rf@)>!0-r9s,-l7rJCQ1s+gQ-s+UH*rIb-%rdjuts*t&tr-eTm +rd4Tis*=TgrHJ9bs)n9^s)\3\r,MaUs)7gQs)%aOr+l:HrFu%?q.K,-oOm<"ph0A6hdu[srFbt? +rb;@HqeQ1Irb_LLrbqaSp2ThIl>uQ=rH8'^r-/0crd"Khs*OcnrdFfq!.Xuus+(0%rdt6)L&Qf= +LPUbCM2I4LN/WaVNfT6_OHKO*!gAk5rfmPNQ^@]=s-`nUrLVf]tV7r^qmn)_o0O5`lH0AaihlO +c-FV\d*^7he'umtf@S[.rn7n;gtgfChr*GOiSrnXjQ,G%k5XTEkl'cGlMp2Jm/HDOmeQ>LnGDbJ +o)&%Vo_8%VpAOa]q#1$dqY9scr;6H\rdk*#s6fo;~> +JcC<$JcD2=nc&IbrVZNhrqcWir:ps5O(;rS[_5s5*_1!o2PbrS%;)s4I;%!nPoPrm^tss3gno!mo9>rltPhbl5cib/qcHaN)=" +`Ab`Q_SX.)^V@Lr]tD"i]",A]\$i`Q['R*EZ*:I9Y-"h-X/`2!W2HPjV50o^U7n9RT:_^HSXf\K +!LfGUQiWP>rg!MJ!0dDF!g/S+rf@)>!0-r9s,-l7rJCQ1s+gQ-s+UH*rIb-%rdjuts*t&tr-eTm +rd4Tis*=TgrHJ9bs)n9^s)\3\r,MaUs)7gQs)%aOr+l:HrFu%?q.K,-oOm<"ph0A6hdu[srFbt? +rb;@HqeQ1Irb_LLrbqaSp2ThIl>uQ=rH8'^r-/0crd"Khs*OcnrdFfq!.Xuus+(0%rdt6)L&Qf= +LPUbCM2I4LN/WaVNfT6_OHKO*!gAk5rfmPNQ^@]=s-`nUrLVf]tV7r^qmn)_o0O5`lH0AaihlO +c-FV\d*^7he'umtf@S[.rn7n;gtgfChr*GOiSrnXjQ,G%k5XTEkl'cGlMp2Jm/HDOmeQ>LnGDbJ +o)&%Vo_8%VpAOa]q#1$dqY9scr;6H\rdk*#s6fo;~> +JcC<$JcD2=nc&IbrVZNhrqcWir:ps5O(;rS[_5s5*_1!o2PbrS%;)s4I;%!nPoPrm^tss3gno!mo9>rltPhbl5cib/qcHaN)=" +`Ab`Q_SX.)^V@Lr]tD"i]",A]\$i`Q['R*EZ*:I9Y-"h-X/`2!W2HPjV50o^U7n9RT:_^HSXf\K +!LfGUQiWP>rg!MJ!0dDF!g/S+rf@)>!0-r9s,-l7rJCQ1s+gQ-s+UH*rIb-%rdjuts*t&tr-eTm +rd4Tis*=TgrHJ9bs)n9^s)\3\r,MaUs)7gQs)%aOr+l:HrFu%?q.K,-oOm<"ph0A6hdu[srFbt? +rb;@HqeQ1Irb_LLrbqaSp2ThIl>uQ=rH8'^r-/0crd"Khs*OcnrdFfq!.Xuus+(0%rdt6)L&Qf= +LPUbCM2I4LN/WaVNfT6_OHKO*!gAk5rfmPNQ^@]=s-`nUrLVf]tV7r^qmn)_o0O5`lH0AaihlO +c-FV\d*^7he'umtf@S[.rn7n;gtgfChr*GOiSrnXjQ,G%k5XTEkl'cGlMp2Jm/HDOmeQ>LnGDbJ +o)&%Vo_8%VpAOa]q#1$dqY9scr;6H\rdk*#s6fo;~> +JcC<$JcD/rg!MJ!0dDFs,d;CrJq#?NK*prs,6o7rJCQ1s+gN,s+UK+r.G$$s+1)us*t#srI+]n +rd4Tis*=WhrHJ6as)n9^s)\3\rGhgUs)7gQs)%aOqeQ1GrFtn;mUsp\q.KJ7l=Kj)r+Gh=rb;@H +qeQ1Irb_OMrGV[Spi61OpN,;8r,qs]qfi'brd"Hgs*F`nrI"`rIt.HJ#D%JYK7ei1L&Qf-LPYqd +!K)g7Mueourf7;GOcbfiPEV71Q2d-MQid@hVuEXo +WVrjsX8f:"XoGO(YPtd+YlM*/ZNdeE[C3NQ\Gj#m]">Vf]tV7r^qmn)_o0O5`lH0Aai_fMbg+M[ +d*^7he'umtf%8O+g"P07gtgfChu;O +JcC<$JcD/rg!MJ!0dDFs,d;CrJq#?NK*prs,6o7rJCQ1s+gN,s+UK+r.G$$s+1)us*t#srI+]n +rd4Tis*=WhrHJ6as)n9^s)\3\rGhgUs)7gQs)%aOqeQ1GrFtn;mUsp\q.KJ7l=Kj)r+Gh=rb;@H +qeQ1Irb_OMrGV[Spi61OpN,;8r,qs]qfi'brd"Hgs*F`nrI"`rIt.HJ#D%JYK7ei1L&Qf-LPYqd +!K)g7Mueourf7;GOcbfiPEV71Q2d-MQid@hVuEXo +WVrjsX8f:"XoGO(YPtd+YlM*/ZNdeE[C3NQ\Gj#m]">Vf]tV7r^qmn)_o0O5`lH0Aai_fMbg+M[ +d*^7he'umtf%8O+g"P07gtgfChu;O +JcC<$JcD/rg!MJ!0dDFs,d;CrJq#?NK*prs,6o7rJCQ1s+gN,s+UK+r.G$$s+1)us*t#srI+]n +rd4Tis*=WhrHJ6as)n9^s)\3\rGhgUs)7gQs)%aOqeQ1GrFtn;mUsp\q.KJ7l=Kj)r+Gh=rb;@H +qeQ1Irb_OMrGV[Spi61OpN,;8r,qs]qfi'brd"Hgs*F`nrI"`rIt.HJ#D%JYK7ei1L&Qf-LPYqd +!K)g7Mueourf7;GOcbfiPEV71Q2d-MQid@hVuEXo +WVrjsX8f:"XoGO(YPtd+YlM*/ZNdeE[C3NQ\Gj#m]">Vf]tV7r^qmn)_o0O5`lH0Aai_fMbg+M[ +d*^7he'umtf%8O+g"P07gtgfChu;O +JcC<$JcD/rg!MJ!0dDFs,m>Crf@)>s,I#:s,6o7rJCQ1s+gN,s+UK+r.G$$s+1)us*t#srI+]n +s*OZis*=WhrHJ9bs)n9^s)\3\r,MaUs)7gQrb_XNqeQ.Fqe=_sl=oa$ph/`$qe,_[:gVuEXoWVidq +X8f:"XoGO(YPk[,Z*L\7ZN7G@rjDj:\Gj#i]">Vf]tV7r^qmk(_Sa@3`lH0Aai_fMbg"GYcd:(e +daZdsf%8O+g"P07h#?+5hV[8LiSsjs!T`AAk5XTEkl'`IlKdd6m/QJPmecJOnGMhKo(qtTo_.tU +pAF[[q#1$dqY0mbr;6H\rdk*#s6Tc9~> +JcC<$JcD/rg!MJ!0dDFs,m>Crf@)>s,I#:s,6o7rJCQ1s+gN,s+UK+r.G$$s+1)us*t#srI+]n +s*OZis*=WhrHJ9bs)n9^s)\3\r,MaUs)7gQrb_XNqeQ.Fqe=_sl=oa$ph/`$qe,_[:gVuEXoWVidq +X8f:"XoGO(YPk[,Z*L\7ZN7G@rjDj:\Gj#i]">Vf]tV7r^qmk(_Sa@3`lH0Aai_fMbg"GYcd:(e +daZdsf%8O+g"P07h#?+5hV[8LiSsjs!T`AAk5XTEkl'`IlKdd6m/QJPmecJOnGMhKo(qtTo_.tU +pAF[[q#1$dqY0mbr;6H\rdk*#s6Tc9~> +JcC<$JcD/rg!MJ!0dDFs,m>Crf@)>s,I#:s,6o7rJCQ1s+gN,s+UK+r.G$$s+1)us*t#srI+]n +s*OZis*=WhrHJ9bs)n9^s)\3\r,MaUs)7gQrb_XNqeQ.Fqe=_sl=oa$ph/`$qe,_[:gVuEXoWVidq +X8f:"XoGO(YPk[,Z*L\7ZN7G@rjDj:\Gj#i]">Vf]tV7r^qmk(_Sa@3`lH0Aai_fMbg"GYcd:(e +daZdsf%8O+g"P07h#?+5hV[8LiSsjs!T`AAk5XTEkl'`IlKdd6m/QJPmecJOnGMhKo(qtTo_.tU +pAF[[q#1$dqY0mbr;6H\rdk*#s6Tc9~> +JcC<$JcD,;nc&IbrVZNhrqcWir:p +S!ob5rg3_QQN!0LPlHsHOogc-OSt7?NW>(;N;nh9MZ&D2M#W8/LAuu,K`-Q&K)^E#JH(,uIf4]p +I/eQlHN/9jGl;jdG5l^_FT6F^ErC"WE;skSDZ4MPD#%lECADT5B_#m(CA2H4B_H*5B(os4B`;`E +CAVfGD#S;KDZ4SRE;FSQEr:"HFR=5IG5-:\GlE!dHN/?lI/SHpIXckHJ-(:RK)UB'KSBD[(5I^% +M2@+JMid@gVuEXn +WVidqX8f:"XoGR(YPk[,Z*L\7Zi@B4[JmT8\%)FJ"hM=Y]Y2&Y^GisE_SX4/`Poj;aN2KHbKS5V +cHjkbdF-LneCE.%f@\d1g=tE=h;7&Ii8N\Tj5]4^jlY^gkNMm/!p]+;rTsONs6fdQrUBdUp@A(O +qXjFQr:^'_q"Xd_r;-3cqu$?imf%e;JcG'9J,~> +JcC<$JcD,;nc&IbrVZNhrqcWir:p +S!ob5rg3_QQN!0LPlHsHOogc-OSt7?NW>(;N;nh9MZ&D2M#W8/LAuu,K`-Q&K)^E#JH(,uIf4]p +I/eQlHN/9jGl;jdG5l^_FT6F^ErC"WE;skSDZ4MPD#%lECADT5B_#m(CA2H4B_H*5B(os4B`;`E +CAVfGD#S;KDZ4SRE;FSQEr:"HFR=5IG5-:\GlE!dHN/?lI/SHpIXckHJ-(:RK)UB'KSBD[(5I^% +M2@+JMid@gVuEXn +WVidqX8f:"XoGR(YPk[,Z*L\7Zi@B4[JmT8\%)FJ"hM=Y]Y2&Y^GisE_SX4/`Poj;aN2KHbKS5V +cHjkbdF-LneCE.%f@\d1g=tE=h;7&Ii8N\Tj5]4^jlY^gkNMm/!p]+;rTsONs6fdQrUBdUp@A(O +qXjFQr:^'_q"Xd_r;-3cqu$?imf%e;JcG'9J,~> +JcC<$JcD,;nc&IbrVZNhrqcWir:p +S!ob5rg3_QQN!0LPlHsHOogc-OSt7?NW>(;N;nh9MZ&D2M#W8/LAuu,K`-Q&K)^E#JH(,uIf4]p +I/eQlHN/9jGl;jdG5l^_FT6F^ErC"WE;skSDZ4MPD#%lECADT5B_#m(CA2H4B_H*5B(os4B`;`E +CAVfGD#S;KDZ4SRE;FSQEr:"HFR=5IG5-:\GlE!dHN/?lI/SHpIXckHJ-(:RK)UB'KSBD[(5I^% +M2@+JMid@gVuEXn +WVidqX8f:"XoGR(YPk[,Z*L\7Zi@B4[JmT8\%)FJ"hM=Y]Y2&Y^GisE_SX4/`Poj;aN2KHbKS5V +cHjkbdF-LneCE.%f@\d1g=tE=h;7&Ii8N\Tj5]4^jlY^gkNMm/!p]+;rTsONs6fdQrUBdUp@A(O +qXjFQr:^'_q"Xd_r;-3cqu$?imf%e;JcG'9J,~> +JcC<$JcD,;nc&Ibr;?EgrqcWir:p+f\$/S!nPoPrm^ts!7Lko&CAbLcHa\Zbfe2Pb/q`Ga2\+t +-,d^<_SO%&^V7Co]Xtbc\[],W[^EKKZa-j?Yck43XfSS'Wi;rrVZiroUnjc[rh0@cTDkD_SXf\K +!h,OFrg3bRQBqN8!gJn4rf[;Ds,d5@s,R,=rJ^c7s,-c3reUT0rJ(<*s+L?'rdt0$rIFots*jlo +s*XinrHeKhs*4Kds*"EbrH/'\s)S$Wrc%mUqelCMrbV=EpM0D9n7q<*pM0M-(JqAW-KS5'YL&m'creUZ5 +MuJY9NK4"!!K`HCOo^c2rfmPNQ^@]=!L]DTRf]+NSc55\TDtS^U&UkdU\pqdV>d@gVuioB([jQ6C'!pAe2rojLLlg+N9s6]jSqsXORrUKXQqXaRU +oC`"Sr:fs\rV?Bfp\Xjcqu,s^JcC<$lMlA~> +JcC<$JcD,;nc&Ibr;?EgrqcWir:p+f\$/S!nPoPrm^ts!7Lko&CAbLcHa\Zbfe2Pb/q`Ga2\+t +-,d^<_SO%&^V7Co]Xtbc\[],W[^EKKZa-j?Yck43XfSS'Wi;rrVZiroUnjc[rh0@cTDkD_SXf\K +!h,OFrg3bRQBqN8!gJn4rf[;Ds,d5@s,R,=rJ^c7s,-c3reUT0rJ(<*s+L?'rdt0$rIFots*jlo +s*XinrHeKhs*4Kds*"EbrH/'\s)S$Wrc%mUqelCMrbV=EpM0D9n7q<*pM0M-(JqAW-KS5'YL&m'creUZ5 +MuJY9NK4"!!K`HCOo^c2rfmPNQ^@]=!L]DTRf]+NSc55\TDtS^U&UkdU\pqdV>d@gVuioB([jQ6C'!pAe2rojLLlg+N9s6]jSqsXORrUKXQqXaRU +oC`"Sr:fs\rV?Bfp\Xjcqu,s^JcC<$lMlA~> +JcC<$JcD,;nc&Ibr;?EgrqcWir:p+f\$/S!nPoPrm^ts!7Lko&CAbLcHa\Zbfe2Pb/q`Ga2\+t +-,d^<_SO%&^V7Co]Xtbc\[],W[^EKKZa-j?Yck43XfSS'Wi;rrVZiroUnjc[rh0@cTDkD_SXf\K +!h,OFrg3bRQBqN8!gJn4rf[;Ds,d5@s,R,=rJ^c7s,-c3reUT0rJ(<*s+L?'rdt0$rIFots*jlo +s*XinrHeKhs*4Kds*"EbrH/'\s)S$Wrc%mUqelCMrbV=EpM0D9n7q<*pM0M-(JqAW-KS5'YL&m'creUZ5 +MuJY9NK4"!!K`HCOo^c2rfmPNQ^@]=!L]DTRf]+NSc55\TDtS^U&UkdU\pqdV>d@gVuioB([jQ6C'!pAe2rojLLlg+N9s6]jSqsXORrUKXQqXaRU +oC`"Sr:fs\rV?Bfp\Xjcqu,s^JcC<$lMlA~> +JcC<$JcD,;nG`@arVZNhrqcWir:p9cs7ZEarq-6^rUU!Ys7$$Vs6fpSrTsRMs6BRIs60LGrT=.A +s5a.=s5O(;r8@V4s5*_1s4mY/rS%;)!8.8%s4.2#rm^ts!7Lko$dd5GcHa\Ybfe2Pao9@)a2Z*; +`5BI/_8*h#^:h1l]=PP`\@8oT[C!9HZE^XAr-83dqg/6gs*Xcns*jutrdb$"!.t3&#D@ebL5(J=M#N53MMqIm&<2^2 +O-#HcP*2#mPa.N"QC%T +JcC<$JcD,;nG`@arVZNhrqcWir:p9cs7ZEarq-6^rUU!Ys7$$Vs6fpSrTsRMs6BRIs60LGrT=.A +s5a.=s5O(;r8@V4s5*_1s4mY/rS%;)!8.8%s4.2#rm^ts!7Lko$dd5GcHa\Ybfe2Pao9@)a2Z*; +`5BI/_8*h#^:h1l]=PP`\@8oT[C!9HZE^XAr-83dqg/6gs*Xcns*jutrdb$"!.t3&#D@ebL5(J=M#N53MMqIm&<2^2 +O-#HcP*2#mPa.N"QC%T +JcC<$JcD,;nG`@arVZNhrqcWir:p9cs7ZEarq-6^rUU!Ys7$$Vs6fpSrTsRMs6BRIs60LGrT=.A +s5a.=s5O(;r8@V4s5*_1s4mY/rS%;)!8.8%s4.2#rm^ts!7Lko$dd5GcHa\Ybfe2Pao9@)a2Z*; +`5BI/_8*h#^:h1l]=PP`\@8oT[C!9HZE^XAr-83dqg/6gs*Xcns*jutrdb$"!.t3&#D@ebL5(J=M#N53MMqIm&<2^2 +O-#HcP*2#mPa.N"QC%T +JcC<$JcD):nc&Ibr;?EgrqcWir:p9cs7ZEas7H<^rUU!Ys7$!Us6fpSrp9[Ns6BRIs60LGr9"%@ +s5a.=s5O%:rS[_5s5*_1s4mY/rS%;)!8.8%!nPoPrmV"udaJ-B!RT0lc2l26rl[IIaiMQD`l5p8 +_o'@._8*h#^:h1l]=PP`\@8oT[C!9HZE^Xd@hVuL& +YPk^*Z2_-.ZN@MA[JmW7[fEr;\H]XW]=bei^Abl,^qmn)_o0O5`lH0Aai_fMbg"GYcd:(edaQ^q +e^i@(f\,!4gYCW@hV[8LiSieVj5f=`k2tjikl0fJlKdd7m/QJQmelPRnGVnQo)/+Uo^_\OpA=UX +q#'scqY'g`r;6H[rdk*#s69Q6~> +JcC<$JcD):nc&Ibr;?EgrqcWir:p9cs7ZEas7H<^rUU!Ys7$!Us6fpSrp9[Ns6BRIs60LGr9"%@ +s5a.=s5O%:rS[_5s5*_1s4mY/rS%;)!8.8%!nPoPrmV"udaJ-B!RT0lc2l26rl[IIaiMQD`l5p8 +_o'@._8*h#^:h1l]=PP`\@8oT[C!9HZE^Xd@hVuL& +YPk^*Z2_-.ZN@MA[JmW7[fEr;\H]XW]=bei^Abl,^qmn)_o0O5`lH0Aai_fMbg"GYcd:(edaQ^q +e^i@(f\,!4gYCW@hV[8LiSieVj5f=`k2tjikl0fJlKdd7m/QJQmelPRnGVnQo)/+Uo^_\OpA=UX +q#'scqY'g`r;6H[rdk*#s69Q6~> +JcC<$JcD):nc&Ibr;?EgrqcWir:p9cs7ZEas7H<^rUU!Ys7$!Us6fpSrp9[Ns6BRIs60LGr9"%@ +s5a.=s5O%:rS[_5s5*_1s4mY/rS%;)!8.8%!nPoPrmV"udaJ-B!RT0lc2l26rl[IIaiMQD`l5p8 +_o'@._8*h#^:h1l]=PP`\@8oT[C!9HZE^Xd@hVuL& +YPk^*Z2_-.ZN@MA[JmW7[fEr;\H]XW]=bei^Abl,^qmn)_o0O5`lH0Aai_fMbg"GYcd:(edaQ^q +e^i@(f\,!4gYCW@hV[8LiSieVj5f=`k2tjikl0fJlKdd7m/QJQmelPRnGVnQo)/+Uo^_\OpA=UX +q#'scqY'g`r;6H[rdk*#s69Q6~> +JcC<$JcD):nG`@arVZNhrVHNhr:p&!nPoPrmVM.daHOjd*U+acHXVXbKJ&Mrl@:D`l5p8 +_ns:,^q[Xu]tD"i]",A]\$i`Q['R*EZ*:I9Y-"h-XK/A$WMl_mVPU,bUnaZYTqS-OT:VXFSXf\K +s-`qUrg<_Ps-EYLs-3PIrf[;Ds,d2?s,R,=r/CZ6s,-c3reUT0rJ(?+s+L<&s+:9%rIFots*jop +s*Xinrd+Tis*4Hcs*"EbrH/$[s)S$Wrc%gSq/6(Hhe_[spMBG:qJ,)*r+c%CrG;IMqelFPrc%aS +rc8!ZqK2[Yr-%LPms+\Spj2pdrd=Wls*jutrI=s#JqEuSs+CB+re:H/M#N53MMqIm!KE-=Nrb?) +rfR;GPl?pKQC%Td@iVuEXnWVWXoX8T-rXo>L'YPbX( +Z2_-.Zi@B4[JdN8\%&sI\H0:Rrk&9F^AbkN^qmn)_o2Pn*6-%?aN;TJbKS5VcHjkbdF-Lne^i@( +f\,!4gYDea&)Q4%i8N\Uj5f:_k2tjikl0iHl2^/Km/QJQmeuVRnG_tSo)/+Vo^_\OpA4OVq#'sb +qY'g`r;6H[rdk*#s60K5~> +JcC<$JcD):nG`@arVZNhrVHNhr:p&!nPoPrmVM.daHOjd*U+acHXVXbKJ&Mrl@:D`l5p8 +_ns:,^q[Xu]tD"i]",A]\$i`Q['R*EZ*:I9Y-"h-XK/A$WMl_mVPU,bUnaZYTqS-OT:VXFSXf\K +s-`qUrg<_Ps-EYLs-3PIrf[;Ds,d2?s,R,=r/CZ6s,-c3reUT0rJ(?+s+L<&s+:9%rIFots*jop +s*Xinrd+Tis*4Hcs*"EbrH/$[s)S$Wrc%gSq/6(Hhe_[spMBG:qJ,)*r+c%CrG;IMqelFPrc%aS +rc8!ZqK2[Yr-%LPms+\Spj2pdrd=Wls*jutrI=s#JqEuSs+CB+re:H/M#N53MMqIm!KE-=Nrb?) +rfR;GPl?pKQC%Td@iVuEXnWVWXoX8T-rXo>L'YPbX( +Z2_-.Zi@B4[JdN8\%&sI\H0:Rrk&9F^AbkN^qmn)_o2Pn*6-%?aN;TJbKS5VcHjkbdF-Lne^i@( +f\,!4gYDea&)Q4%i8N\Uj5f:_k2tjikl0iHl2^/Km/QJQmeuVRnG_tSo)/+Vo^_\OpA4OVq#'sb +qY'g`r;6H[rdk*#s60K5~> +JcC<$JcD):nG`@arVZNhrVHNhr:p&!nPoPrmVM.daHOjd*U+acHXVXbKJ&Mrl@:D`l5p8 +_ns:,^q[Xu]tD"i]",A]\$i`Q['R*EZ*:I9Y-"h-XK/A$WMl_mVPU,bUnaZYTqS-OT:VXFSXf\K +s-`qUrg<_Ps-EYLs-3PIrf[;Ds,d2?s,R,=r/CZ6s,-c3reUT0rJ(?+s+L<&s+:9%rIFots*jop +s*Xinrd+Tis*4Hcs*"EbrH/$[s)S$Wrc%gSq/6(Hhe_[spMBG:qJ,)*r+c%CrG;IMqelFPrc%aS +rc8!ZqK2[Yr-%LPms+\Spj2pdrd=Wls*jutrI=s#JqEuSs+CB+re:H/M#N53MMqIm!KE-=Nrb?) +rfR;GPl?pKQC%Td@iVuEXnWVWXoX8T-rXo>L'YPbX( +Z2_-.Zi@B4[JdN8\%&sI\H0:Rrk&9F^AbkN^qmn)_o2Pn*6-%?aN;TJbKS5VcHjkbdF-Lne^i@( +f\,!4gYDea&)Q4%i8N\Uj5f:_k2tjikl0iHl2^/Km/QJQmeuVRnG_tSo)/+Vo^_\OpA4OVq#'sb +qY'g`r;6H[rdk*#s60K5~> +JcC<$JcD&9nc&FarVZNhrqcWiqtU3crq?<`s7H<^rUU!Ys7$!Us6fpSrTsRMs6BOHs60LGrT=+@ +s5a.=ro3t:rS[_5rndV0s4dV/rS%;)!8.8%!nPoPrmUttdf.Vpd*M^:!R8jfb;7;_aN2EA`Pod5 +_SX.)^V@Lr]Y(kf\[f5Z[^NTN['R*EZ*:I9Y-"h-X/`2!WMl_mVPX9f#G\#fTqS-PTDkD`SXc5L +Rf]%HRJrTRQN3?MQ2d*KPPp[EOT:L@O8k7?NW"h9MuS\4M>rD3L])u-L&Zi(KE$Q'Jc:3"J,aur +IK+]pHi89jH2i-fGQ2jdFo6@]F8g4WEW0qUDt\)-DJ)?C\DNS5MDuO_R +EW1"XF8L(XFo?LVGP6:MH1ZF]HiAEiIK+crJ,OotJH1<#K)pXZreCH.!/UW2!K)g7N#I\9O,oBa +OcklkPa%GuQC!r*R$jD3S"#qmFjVuEXoWV`^oX8T-rXo>L%YPbX( +Z2_-.Zi@E4[JdN8\%&sI\H9@S]DfGD]tXK\1VgiD_Sa=1`Poj;aN2KGbKJ,ScHab_dF$CkeC<%" +f@S[.g=k<:h;-rFi8ESRioB([jo4BCkNMp0s69UMrTsROs6fjSs7$$XqXXUVr:KRQq=a[Zo_A@[ +qtg$`qu$ +JcC<$JcD&9nc&FarVZNhrqcWiqtU3crq?<`s7H<^rUU!Ys7$!Us6fpSrTsRMs6BOHs60LGrT=+@ +s5a.=ro3t:rS[_5rndV0s4dV/rS%;)!8.8%!nPoPrmUttdf.Vpd*M^:!R8jfb;7;_aN2EA`Pod5 +_SX.)^V@Lr]Y(kf\[f5Z[^NTN['R*EZ*:I9Y-"h-X/`2!WMl_mVPX9f#G\#fTqS-PTDkD`SXc5L +Rf]%HRJrTRQN3?MQ2d*KPPp[EOT:L@O8k7?NW"h9MuS\4M>rD3L])u-L&Zi(KE$Q'Jc:3"J,aur +IK+]pHi89jH2i-fGQ2jdFo6@]F8g4WEW0qUDt\)-DJ)?C\DNS5MDuO_R +EW1"XF8L(XFo?LVGP6:MH1ZF]HiAEiIK+crJ,OotJH1<#K)pXZreCH.!/UW2!K)g7N#I\9O,oBa +OcklkPa%GuQC!r*R$jD3S"#qmFjVuEXoWV`^oX8T-rXo>L%YPbX( +Z2_-.Zi@E4[JdN8\%&sI\H9@S]DfGD]tXK\1VgiD_Sa=1`Poj;aN2KGbKJ,ScHab_dF$CkeC<%" +f@S[.g=k<:h;-rFi8ESRioB([jo4BCkNMp0s69UMrTsROs6fjSs7$$XqXXUVr:KRQq=a[Zo_A@[ +qtg$`qu$ +JcC<$JcD&9nc&FarVZNhrqcWiqtU3crq?<`s7H<^rUU!Ys7$!Us6fpSrTsRMs6BOHs60LGrT=+@ +s5a.=ro3t:rS[_5rndV0s4dV/rS%;)!8.8%!nPoPrmUttdf.Vpd*M^:!R8jfb;7;_aN2EA`Pod5 +_SX.)^V@Lr]Y(kf\[f5Z[^NTN['R*EZ*:I9Y-"h-X/`2!WMl_mVPX9f#G\#fTqS-PTDkD`SXc5L +Rf]%HRJrTRQN3?MQ2d*KPPp[EOT:L@O8k7?NW"h9MuS\4M>rD3L])u-L&Zi(KE$Q'Jc:3"J,aur +IK+]pHi89jH2i-fGQ2jdFo6@]F8g4WEW0qUDt\)-DJ)?C\DNS5MDuO_R +EW1"XF8L(XFo?LVGP6:MH1ZF]HiAEiIK+crJ,OotJH1<#K)pXZreCH.!/UW2!K)g7N#I\9O,oBa +OcklkPa%GuQC!r*R$jD3S"#qmFjVuEXoWV`^oX8T-rXo>L%YPbX( +Z2_-.Zi@E4[JdN8\%&sI\H9@S]DfGD]tXK\1VgiD_Sa=1`Poj;aN2KGbKJ,ScHab_dF$CkeC<%" +f@S[.g=k<:h;-rFi8ESRioB([jo4BCkNMp0s69UMrTsROs6fjSs7$$XqXXUVr:KRQq=a[Zo_A@[ +qtg$`qu$ +JcC<$JcD&9nG`@arVZKgrqcWir:p9cs7ZB`s7H?_r:9mXs7$!Us6fpSr9XILs6BRIs60IFrT=+@ +s5a+CrK$u=s,Hu9s,6l6rJCQ1s+gQ-s+UK+rIb-%s+1-!s*t&t +rI+]n!.4Zjs*=Whr-/0as)n6]s)\0[qJlIQr,98dqJH+Gn8%]3o5";@rGDFLrbqdTqf2UUs)\'Z +rH8*_pilU[om,_Hr-SBiqgJHms*suts+13%rdt9*Kn]M\'o.U$M2@+IMi +JcC<$JcD&9nG`@arVZKgrqcWir:p9cs7ZB`s7H?_r:9mXs7$!Us6fpSr9XILs6BRIs60IFrT=+@ +s5a+CrK$u=s,Hu9s,6l6rJCQ1s+gQ-s+UK+rIb-%s+1-!s*t&t +rI+]n!.4Zjs*=Whr-/0as)n6]s)\0[qJlIQr,98dqJH+Gn8%]3o5";@rGDFLrbqdTqf2UUs)\'Z +rH8*_pilU[om,_Hr-SBiqgJHms*suts+13%rdt9*Kn]M\'o.U$M2@+IMi +JcC<$JcD&9nG`@arVZKgrqcWir:p9cs7ZB`s7H?_r:9mXs7$!Us6fpSr9XILs6BRIs60IFrT=+@ +s5a+CrK$u=s,Hu9s,6l6rJCQ1s+gQ-s+UK+rIb-%s+1-!s*t&t +rI+]n!.4Zjs*=Whr-/0as)n6]s)\0[qJlIQr,98dqJH+Gn8%]3o5";@rGDFLrbqdTqf2UUs)\'Z +rH8*_pilU[om,_Hr-SBiqgJHms*suts+13%rdt9*Kn]M\'o.U$M2@+IMi +JcC<$JcD#8nc&FarVZKgrqcWir:p9cs7ZB`s7H?_r:9mXs7$!UrpKgRrTsRMrp'IHs60IFrT=+@ +s5a+CrK$u=s,Hu9repf6rJCQ1s+gQ-s+UK+rIb-%s+1-!!e5ZJ +rI+]ns*O]js*=WhrHJ6as)n6]rcA'Zq/Q=Oq/>S:j_s[,qec1GiG8@-rGDCKrbqdTr,M^Vrc@sY +rcS3`qKMj^qg%7Kq0W!dqL/?ls*srss+13%re(6(!/:E,s+^T1reUZ5MuJY9NK4"!!K`HCOqj1F +Q'IZ$Q^F/.R[T_8S=Q4BStDXJrh9@d!2KLgs.o^mr29Rns/Gmqri?%"qQ9_!rNH(%riuI.r3QF1 +rjD^5s0i! +JcC<$JcD#8nc&FarVZKgrqcWir:p9cs7ZB`s7H?_r:9mXs7$!UrpKgRrTsRMrp'IHs60IFrT=+@ +s5a+CrK$u=s,Hu9repf6rJCQ1s+gQ-s+UK+rIb-%s+1-!!e5ZJ +rI+]ns*O]js*=WhrHJ6as)n6]rcA'Zq/Q=Oq/>S:j_s[,qec1GiG8@-rGDCKrbqdTr,M^Vrc@sY +rcS3`qKMj^qg%7Kq0W!dqL/?ls*srss+13%re(6(!/:E,s+^T1reUZ5MuJY9NK4"!!K`HCOqj1F +Q'IZ$Q^F/.R[T_8S=Q4BStDXJrh9@d!2KLgs.o^mr29Rns/Gmqri?%"qQ9_!rNH(%riuI.r3QF1 +rjD^5s0i! +JcC<$JcD#8nc&FarVZKgrqcWir:p9cs7ZB`s7H?_r:9mXs7$!UrpKgRrTsRMrp'IHs60IFrT=+@ +s5a+CrK$u=s,Hu9repf6rJCQ1s+gQ-s+UK+rIb-%s+1-!!e5ZJ +rI+]ns*O]js*=WhrHJ6as)n6]rcA'Zq/Q=Oq/>S:j_s[,qec1GiG8@-rGDCKrbqdTr,M^Vrc@sY +rcS3`qKMj^qg%7Kq0W!dqL/?ls*srss+13%re(6(!/:E,s+^T1reUZ5MuJY9NK4"!!K`HCOqj1F +Q'IZ$Q^F/.R[T_8S=Q4BStDXJrh9@d!2KLgs.o^mr29Rns/Gmqri?%"qQ9_!rNH(%riuI.r3QF1 +rjD^5s0i! +JcC<$JcD#8nG`@ar;?EgrVHNhr:p9cs7ZB`s7H<^rUU!Yrp]mTs6fpSr9XILs6BOHs60IFr9"%@ +roF%`Pf[2 +_SO%&^V7Co]Xtbc\[]-J[L'@KZa6sBYct=6riHR0X/`2!W2QVlVP^3hU]I6brh9@b!2'7^s.01[ +rgWqVs-`kRs-NbOrK[DIs-*DEs,m>CrK$u=rf-l8s,6o7rJCQ1s+gQ-s+UK+rIY0'JV!cMs*t&t +rI+]n!.4Zjrd"NgrHJ6as)n3\rcA'ZpMotIn8I9)q/>nCqJH%En8%l:r,)7IrbqdTqf2UUs)\'Z +rcS3`qfi!`r-@jZmsFhWpO3!hrdXlsrdk*$re(6(s+UH,#D\+kM2@+IMuJY9NK4"!$BUC5P*;,p +Q'IZ%rg3_SRf8cWS=TYN#G7Z^TqS3TU]$tiV5C-gVuN^qWVidqX8f9tXo5F%YPGF%Z2M!*Zi@E3 +[JdQ6\,Wu:\c95@]DfJC]`>eG^F[1:_8=(,`5KX6`lH0Aai_cLbKS5VcHjkbdF-LneCE.%f@\d1 +g=tE=h;7&gi!&*!j5]4^roO7Ekl0iHl2^/Lm/QJQmf)\SnGi%Vo)A7Zo_8%SpA+IPq"jg`qXj[^ +r;-BYrdk*#s5a31~> +JcC<$JcD#8nG`@ar;?EgrVHNhr:p9cs7ZB`s7H<^rUU!Yrp]mTs6fpSr9XILs6BOHs60IFr9"%@ +roF%`Pf[2 +_SO%&^V7Co]Xtbc\[]-J[L'@KZa6sBYct=6riHR0X/`2!W2QVlVP^3hU]I6brh9@b!2'7^s.01[ +rgWqVs-`kRs-NbOrK[DIs-*DEs,m>CrK$u=rf-l8s,6o7rJCQ1s+gQ-s+UK+rIY0'JV!cMs*t&t +rI+]n!.4Zjrd"NgrHJ6as)n3\rcA'ZpMotIn8I9)q/>nCqJH%En8%l:r,)7IrbqdTqf2UUs)\'Z +rcS3`qfi!`r-@jZmsFhWpO3!hrdXlsrdk*$re(6(s+UH,#D\+kM2@+IMuJY9NK4"!$BUC5P*;,p +Q'IZ%rg3_SRf8cWS=TYN#G7Z^TqS3TU]$tiV5C-gVuN^qWVidqX8f9tXo5F%YPGF%Z2M!*Zi@E3 +[JdQ6\,Wu:\c95@]DfJC]`>eG^F[1:_8=(,`5KX6`lH0Aai_cLbKS5VcHjkbdF-LneCE.%f@\d1 +g=tE=h;7&gi!&*!j5]4^roO7Ekl0iHl2^/Lm/QJQmf)\SnGi%Vo)A7Zo_8%SpA+IPq"jg`qXj[^ +r;-BYrdk*#s5a31~> +JcC<$JcD#8nG`@ar;?EgrVHNhr:p9cs7ZB`s7H<^rUU!Yrp]mTs6fpSr9XILs6BOHs60IFr9"%@ +roF%`Pf[2 +_SO%&^V7Co]Xtbc\[]-J[L'@KZa6sBYct=6riHR0X/`2!W2QVlVP^3hU]I6brh9@b!2'7^s.01[ +rgWqVs-`kRs-NbOrK[DIs-*DEs,m>CrK$u=rf-l8s,6o7rJCQ1s+gQ-s+UK+rIY0'JV!cMs*t&t +rI+]n!.4Zjrd"NgrHJ6as)n3\rcA'ZpMotIn8I9)q/>nCqJH%En8%l:r,)7IrbqdTqf2UUs)\'Z +rcS3`qfi!`r-@jZmsFhWpO3!hrdXlsrdk*$re(6(s+UH,#D\+kM2@+IMuJY9NK4"!$BUC5P*;,p +Q'IZ%rg3_SRf8cWS=TYN#G7Z^TqS3TU]$tiV5C-gVuN^qWVidqX8f9tXo5F%YPGF%Z2M!*Zi@E3 +[JdQ6\,Wu:\c95@]DfJC]`>eG^F[1:_8=(,`5KX6`lH0Aai_cLbKS5VcHjkbdF-LneCE.%f@\d1 +g=tE=h;7&gi!&*!j5]4^roO7Ekl0iHl2^/Lm/QJQmf)\SnGi%Vo)A7Zo_8%SpA+IPq"jg`qXj[^ +r;-BYrdk*#s5a31~> +JcC<$JcCu7nG`@ar;?EgrqcWiqtU0bs7ZB`s7H<^rUU!Yrp]mTs6fmRrTsOLs6BOHs60IFr9"%@ +roF%+f\$2T!S5g#e-=CMda?Ihci23:c-4ASb/q`Ga2Z*;`5KR1 +_SO%&^V7Co]Xtbc\[],W[^EKKZa-k8YR7S:Xf\\*X/`2!W;`[rVPU-gU]I6brh9@bs.B:^!hGjO +rL3kWR@4#@s-NbOrK[DIs-*DEs,m>Cr/^l +JcC<$JcCu7nG`@ar;?EgrqcWiqtU0bs7ZB`s7H<^rUU!Yrp]mTs6fmRrTsOLs6BOHs60IFr9"%@ +roF%+f\$2T!S5g#e-=CMda?Ihci23:c-4ASb/q`Ga2Z*;`5KR1 +_SO%&^V7Co]Xtbc\[],W[^EKKZa-k8YR7S:Xf\\*X/`2!W;`[rVPU-gU]I6brh9@bs.B:^!hGjO +rL3kWR@4#@s-NbOrK[DIs-*DEs,m>Cr/^l +JcC<$JcCu7nG`@ar;?EgrqcWiqtU0bs7ZB`s7H<^rUU!Yrp]mTs6fmRrTsOLs6BOHs60IFr9"%@ +roF%+f\$2T!S5g#e-=CMda?Ihci23:c-4ASb/q`Ga2Z*;`5KR1 +_SO%&^V7Co]Xtbc\[],W[^EKKZa-k8YR7S:Xf\\*X/`2!W;`[rVPU-gU]I6brh9@bs.B:^!hGjO +rL3kWR@4#@s-NbOrK[DIs-*DEs,m>Cr/^l +JcC<$JcCu7nG`=`rVZKgrqcWiqtU3crq?9_s7H<^rUTsXs7#sTs6fpSr9XILrp'FGs60IFr9""? +s5a+cd'h\bfe2Pb/q`Ga2Z*;`5BI/ +_8*h#^:h1l]=PP`\@8oT[C#q>"gYD;Yck5/XT>N(ri-!uW;`[rVPU-gU]RNrP+;N;nh9MZ&D3L]E5/LAuu-K`-N)Jq8LOJH(-! +If4]pI/eQlHN/9jGl)^bG5cX[FT$:WEl)hnE;OSEDXVH8DZ+MQE;OYSErL.XFT-F^G5HL_GlE!a +HM`'bI-#eRIf4cmJGt-"K)L?%K`?c*LB!&/M#W>3M?&S6Mueourf7)AOoCLNPE_>tQBml)R$jEB +RfT%Mrgj._T`1VdU8+L_U]RBiVZ*LnW;ijrWrB(!XSf4"Y5YX$Yl1j*ZMCj+[/RK1[f +JcC<$JcCu7nG`=`rVZKgrqcWiqtU3crq?9_s7H<^rUTsXs7#sTs6fpSr9XILrp'FGs60IFr9""? +s5a+cd'h\bfe2Pb/q`Ga2Z*;`5BI/ +_8*h#^:h1l]=PP`\@8oT[C#q>"gYD;Yck5/XT>N(ri-!uW;`[rVPU-gU]RNrP+;N;nh9MZ&D3L]E5/LAuu-K`-N)Jq8LOJH(-! +If4]pI/eQlHN/9jGl)^bG5cX[FT$:WEl)hnE;OSEDXVH8DZ+MQE;OYSErL.XFT-F^G5HL_GlE!a +HM`'bI-#eRIf4cmJGt-"K)L?%K`?c*LB!&/M#W>3M?&S6Mueourf7)AOoCLNPE_>tQBml)R$jEB +RfT%Mrgj._T`1VdU8+L_U]RBiVZ*LnW;ijrWrB(!XSf4"Y5YX$Yl1j*ZMCj+[/RK1[f +JcC<$JcCu7nG`=`rVZKgrqcWiqtU3crq?9_s7H<^rUTsXs7#sTs6fpSr9XILrp'FGs60IFr9""? +s5a+cd'h\bfe2Pb/q`Ga2Z*;`5BI/ +_8*h#^:h1l]=PP`\@8oT[C#q>"gYD;Yck5/XT>N(ri-!uW;`[rVPU-gU]RNrP+;N;nh9MZ&D3L]E5/LAuu-K`-N)Jq8LOJH(-! +If4]pI/eQlHN/9jGl)^bG5cX[FT$:WEl)hnE;OSEDXVH8DZ+MQE;OYSErL.XFT-F^G5HL_GlE!a +HM`'bI-#eRIf4cmJGt-"K)L?%K`?c*LB!&/M#W>3M?&S6Mueourf7)AOoCLNPE_>tQBml)R$jEB +RfT%Mrgj._T`1VdU8+L_U]RBiVZ*LnW;ijrWrB(!XSf4"Y5YX$Yl1j*ZMCj+[/RK1[f +JcC<$JcCr6nG`@ar;?EgrVHNhqtU3crq?9_rq-6^r:9mXs7#sTrpKgRr9XILrp'FGrojCFr9""? +s5a+ +JcC<$JcCr6nG`@ar;?EgrVHNhqtU3crq?9_rq-6^r:9mXs7#sTrpKgRr9XILrp'FGrojCFr9""? +s5a+ +JcC<$JcCr6nG`@ar;?EgrVHNhqtU3crq?9_rq-6^r:9mXs7#sTrpKgRr9XILrp'FGrojCFr9""? +s5a+ +JcC<$JcCr6nG`=`rVZKgrqcThr:p9crq?9_rq-6^r:9mXrp]jSs6fmRr9XILrp'FGroj@Er9"%@ +roF%&@/RFYck44Xf\\*X/`2!WMofo!iDfjrhTRh!2BFc!hc0XrLX%[ +!1a"Ws-itUrL!VOs-ESJs-3PIrK@2Cs,d2?s,R,=rJ^c7!/g`3s+p]1reCH,s+L?'!ePuSrIFot +s*jops*Xinr-JBgrcnmWA/DqJu:LqJc:Lm;Dc=rG_RPrc8!Zr,hp\s*"9`s*4Ng +qKi-frI"9domZF\omm!lrdt$"s+LE+rItB/Lku%es,$f7req5ENfK0]OHGZgP*;.0PmWhDR$a;0 +R[]e:Sc52]T:l1W!MZ@gU]RBiVZ*IpW2ZcqWrK."XSo:$Y5YX%Yl:p,ZMCj*[/IE/[f3c8\GWo: +])TD@]`5\F^AbnI^];4M_?.Wn`;[^V`lJ)"'$8;>bKS5UcHab_dF$CkeC<%"rmqV3g"P07gtgfC +hr*GOir7sBjQ5OdkND(.klL)8rp9[P!:KgSs7$'YrUTsZs7H0\r:^$^nG)eSq"jRYq>C'eli)J8 +JcF[.J,~> +JcC<$JcCr6nG`=`rVZKgrqcThr:p9crq?9_rq-6^r:9mXrp]jSs6fmRr9XILrp'FGroj@Er9"%@ +roF%&@/RFYck44Xf\\*X/`2!WMofo!iDfjrhTRh!2BFc!hc0XrLX%[ +!1a"Ws-itUrL!VOs-ESJs-3PIrK@2Cs,d2?s,R,=rJ^c7!/g`3s+p]1reCH,s+L?'!ePuSrIFot +s*jops*Xinr-JBgrcnmWA/DqJu:LqJc:Lm;Dc=rG_RPrc8!Zr,hp\s*"9`s*4Ng +qKi-frI"9domZF\omm!lrdt$"s+LE+rItB/Lku%es,$f7req5ENfK0]OHGZgP*;.0PmWhDR$a;0 +R[]e:Sc52]T:l1W!MZ@gU]RBiVZ*IpW2ZcqWrK."XSo:$Y5YX%Yl:p,ZMCj*[/IE/[f3c8\GWo: +])TD@]`5\F^AbnI^];4M_?.Wn`;[^V`lJ)"'$8;>bKS5UcHab_dF$CkeC<%"rmqV3g"P07gtgfC +hr*GOir7sBjQ5OdkND(.klL)8rp9[P!:KgSs7$'YrUTsZs7H0\r:^$^nG)eSq"jRYq>C'eli)J8 +JcF[.J,~> +JcC<$JcCr6nG`=`rVZKgrqcThr:p9crq?9_rq-6^r:9mXrp]jSs6fmRr9XILrp'FGroj@Er9"%@ +roF%&@/RFYck44Xf\\*X/`2!WMofo!iDfjrhTRh!2BFc!hc0XrLX%[ +!1a"Ws-itUrL!VOs-ESJs-3PIrK@2Cs,d2?s,R,=rJ^c7!/g`3s+p]1reCH,s+L?'!ePuSrIFot +s*jops*Xinr-JBgrcnmWA/DqJu:LqJc:Lm;Dc=rG_RPrc8!Zr,hp\s*"9`s*4Ng +qKi-frI"9domZF\omm!lrdt$"s+LE+rItB/Lku%es,$f7req5ENfK0]OHGZgP*;.0PmWhDR$a;0 +R[]e:Sc52]T:l1W!MZ@gU]RBiVZ*IpW2ZcqWrK."XSo:$Y5YX%Yl:p,ZMCj*[/IE/[f3c8\GWo: +])TD@]`5\F^AbnI^];4M_?.Wn`;[^V`lJ)"'$8;>bKS5UcHab_dF$CkeC<%"rmqV3g"P07gtgfC +hr*GOir7sBjQ5OdkND(.klL)8rp9[P!:KgSs7$'YrUTsZs7H0\r:^$^nG)eSq"jRYq>C'eli)J8 +JcF[.J,~> +JcC<$JcCo5nG`=`rVZKgrVHNhqtU3crq?9_rq-6^r:9jWs7#sTrpKdQr9XFKs6BLGs60IFr9""? +s5a+hp`l5p8_ns:, +^q[Xu]tD"i]",A]\,NfC[C!9HZE^[=Yck5/XTtr.X/`2!WMofos/#dmrM0LiU8%X\s.KCarLX%[ +s.'%Ws-itUrL!VOs-EVKs-3PIrK@2Cs,d2?s,R,=rf$l8s,-c3s+gZ1rJ(?+!/1<'s+:9%rIFot +s*jops*Xinr-J?frcn9`rHA'\`H:rtqf;CMq/Gb?qJc7MrGqmYr,hp\rc\3`rcnHgqg/6grI"Eh +qL80gk^`S^rIXlus+LE+r.Y9.Lku"d#E"FtN/WaUNrG(?OHKO*$Bp^>Q'R`&R$a;1rgOIhSXuFF +T:hmOU8+KZUnsobrhfgrWN#lss/Q.$rN6+&ric7(riuI.qQp1.r3cC0rO;d9qml^;s1A3As1SHH +rkJKK!5\WN#K+Ku`Poj:a8X.3ai_fMbfn>WcHjkbdF-LmeC<%"f@S[.g=k<:h;-rFhr*GOioB([ +jlPXekNMp0!p]+;rp0^RmdC)Cs7$'YrUU![rq-'[rV$0`nbDkSp\OFWq>C'eli)J8JcFX-J,~> +JcC<$JcCo5nG`=`rVZKgrVHNhqtU3crq?9_rq-6^r:9jWs7#sTrpKdQr9XFKs6BLGs60IFr9""? +s5a+hp`l5p8_ns:, +^q[Xu]tD"i]",A]\,NfC[C!9HZE^[=Yck5/XTtr.X/`2!WMofos/#dmrM0LiU8%X\s.KCarLX%[ +s.'%Ws-itUrL!VOs-EVKs-3PIrK@2Cs,d2?s,R,=rf$l8s,-c3s+gZ1rJ(?+!/1<'s+:9%rIFot +s*jops*Xinr-J?frcn9`rHA'\`H:rtqf;CMq/Gb?qJc7MrGqmYr,hp\rc\3`rcnHgqg/6grI"Eh +qL80gk^`S^rIXlus+LE+r.Y9.Lku"d#E"FtN/WaUNrG(?OHKO*$Bp^>Q'R`&R$a;1rgOIhSXuFF +T:hmOU8+KZUnsobrhfgrWN#lss/Q.$rN6+&ric7(riuI.qQp1.r3cC0rO;d9qml^;s1A3As1SHH +rkJKK!5\WN#K+Ku`Poj:a8X.3ai_fMbfn>WcHjkbdF-LmeC<%"f@S[.g=k<:h;-rFhr*GOioB([ +jlPXekNMp0!p]+;rp0^RmdC)Cs7$'YrUU![rq-'[rV$0`nbDkSp\OFWq>C'eli)J8JcFX-J,~> +JcC<$JcCo5nG`=`rVZKgrVHNhqtU3crq?9_rq-6^r:9jWs7#sTrpKdQr9XFKs6BLGs60IFr9""? +s5a+hp`l5p8_ns:, +^q[Xu]tD"i]",A]\,NfC[C!9HZE^[=Yck5/XTtr.X/`2!WMofos/#dmrM0LiU8%X\s.KCarLX%[ +s.'%Ws-itUrL!VOs-EVKs-3PIrK@2Cs,d2?s,R,=rf$l8s,-c3s+gZ1rJ(?+!/1<'s+:9%rIFot +s*jops*Xinr-J?frcn9`rHA'\`H:rtqf;CMq/Gb?qJc7MrGqmYr,hp\rc\3`rcnHgqg/6grI"Eh +qL80gk^`S^rIXlus+LE+r.Y9.Lku"d#E"FtN/WaUNrG(?OHKO*$Bp^>Q'R`&R$a;1rgOIhSXuFF +T:hmOU8+KZUnsobrhfgrWN#lss/Q.$rN6+&ric7(riuI.qQp1.r3cC0rO;d9qml^;s1A3As1SHH +rkJKK!5\WN#K+Ku`Poj:a8X.3ai_fMbfn>WcHjkbdF-LmeC<%"f@S[.g=k<:h;-rFhr*GOioB([ +jlPXekNMp0!p]+;rp0^RmdC)Cs7$'YrUU![rq-'[rV$0`nbDkSp\OFWq>C'eli)J8JcFX-J,~> +JcC<$JcCo5n,E4_rVZKgrVHNhqtU0bs7Z?_s7H<^r:9mXrp]jSrpKdQr9XFKrp'FGroj@Er9"%@ +roF%!OB!0YQ:r1riHF,X/i8#WMuiqVuNXoV>d:jUB%%eU&UecTDbA] +Sc>5YS,\rWRJiNQQiEBMQ2d*KPPp[EOoLOAO8k4?NW"h9MuS\6M>rD3L]3&.L&Zi*KE$Q'Jc1-! +J,aurIK"WoHi&-gH2`'`GPZL/Fn9_PF8L"MEUIf>EW'qVF8L(ZFoHR^GQ)jdH2N!fHiAEhIJeQk +J*2@WJbt&qKDpQ'L&Hc+L]<2/M#rQmMuJYHNK0$[O-#HcP*2#mPa.N"Qi>]`5\F^AYhH +_#M7M_Z.LR`;[^e`lH-@aN;QHbKJ,Rc-FV\d/ME!daQ^qe^i@(f\-8X$/=7kh;7&Ii8N\pisXr0 +k2tjikiq?slKeH9!q#FDrpTmVs7-'Ys7?6^qt9p]rV,pYpA+IZn,)qYq>KUXJcC<$hZ&*~> +JcC<$JcCo5n,E4_rVZKgrVHNhqtU0bs7Z?_s7H<^r:9mXrp]jSrpKdQr9XFKrp'FGroj@Er9"%@ +roF%!OB!0YQ:r1riHF,X/i8#WMuiqVuNXoV>d:jUB%%eU&UecTDbA] +Sc>5YS,\rWRJiNQQiEBMQ2d*KPPp[EOoLOAO8k4?NW"h9MuS\6M>rD3L]3&.L&Zi*KE$Q'Jc1-! +J,aurIK"WoHi&-gH2`'`GPZL/Fn9_PF8L"MEUIf>EW'qVF8L(ZFoHR^GQ)jdH2N!fHiAEhIJeQk +J*2@WJbt&qKDpQ'L&Hc+L]<2/M#rQmMuJYHNK0$[O-#HcP*2#mPa.N"Qi>]`5\F^AYhH +_#M7M_Z.LR`;[^e`lH-@aN;QHbKJ,Rc-FV\d/ME!daQ^qe^i@(f\-8X$/=7kh;7&Ii8N\pisXr0 +k2tjikiq?slKeH9!q#FDrpTmVs7-'Ys7?6^qt9p]rV,pYpA+IZn,)qYq>KUXJcC<$hZ&*~> +JcC<$JcCo5n,E4_rVZKgrVHNhqtU0bs7Z?_s7H<^r:9mXrp]jSrpKdQr9XFKrp'FGroj@Er9"%@ +roF%!OB!0YQ:r1riHF,X/i8#WMuiqVuNXoV>d:jUB%%eU&UecTDbA] +Sc>5YS,\rWRJiNQQiEBMQ2d*KPPp[EOoLOAO8k4?NW"h9MuS\6M>rD3L]3&.L&Zi*KE$Q'Jc1-! +J,aurIK"WoHi&-gH2`'`GPZL/Fn9_PF8L"MEUIf>EW'qVF8L(ZFoHR^GQ)jdH2N!fHiAEhIJeQk +J*2@WJbt&qKDpQ'L&Hc+L]<2/M#rQmMuJYHNK0$[O-#HcP*2#mPa.N"Qi>]`5\F^AYhH +_#M7M_Z.LR`;[^e`lH-@aN;QHbKJ,Rc-FV\d/ME!daQ^qe^i@(f\-8X$/=7kh;7&Ii8N\pisXr0 +k2tjikiq?slKeH9!q#FDrpTmVs7-'Ys7?6^qt9p]rV,pYpA+IZn,)qYq>KUXJcC<$hZ&*~> +JcC<$JcCl4n,E7`r;?BfrqcThqtU0bs7Z?_s7H<^r:9jWrp]jSrpKdQr9XFKrp'CFrojCFr9""? +s5a.=s5O(;rSRb7hVS7f!o2Pbrn7D+f`'J'f%'cL"k1oIdEp5=c5t6SbKJ&MaN2EA`Pod5_SX.) +^V@Ls]tD"i]",A]\,NfD[C!9HZEga>Yck75riH7'X/l6"!i`,srhfgpV5=-d!i)KarLs7as.B7] +s.01[rLCrf@)>s,Hu9!fMqnrJCQ1!/LN-s+LH+rIb-%s+1-! +s*t&tr-eTmrd4Ngrd"EdoQS]+q/uCQqfDXTiGnd9rH%jXrcS3`r-/-bs*=Kfrd4ZmqL/?lr."?h +nq$Icp4N +JcC<$JcCl4n,E7`r;?BfrqcThqtU0bs7Z?_s7H<^r:9jWrp]jSrpKdQr9XFKrp'CFrojCFr9""? +s5a.=s5O(;rSRb7hVS7f!o2Pbrn7D+f`'J'f%'cL"k1oIdEp5=c5t6SbKJ&MaN2EA`Pod5_SX.) +^V@Ls]tD"i]",A]\,NfD[C!9HZEga>Yck75riH7'X/l6"!i`,srhfgpV5=-d!i)KarLs7as.B7] +s.01[rLCrf@)>s,Hu9!fMqnrJCQ1!/LN-s+LH+rIb-%s+1-! +s*t&tr-eTmrd4Ngrd"EdoQS]+q/uCQqfDXTiGnd9rH%jXrcS3`r-/-bs*=Kfrd4ZmqL/?lr."?h +nq$Icp4N +JcC<$JcCl4n,E7`r;?BfrqcThqtU0bs7Z?_s7H<^r:9jWrp]jSrpKdQr9XFKrp'CFrojCFr9""? +s5a.=s5O(;rSRb7hVS7f!o2Pbrn7D+f`'J'f%'cL"k1oIdEp5=c5t6SbKJ&MaN2EA`Pod5_SX.) +^V@Ls]tD"i]",A]\,NfD[C!9HZEga>Yck75riH7'X/l6"!i`,srhfgpV5=-d!i)KarLs7as.B7] +s.01[rLCrf@)>s,Hu9!fMqnrJCQ1!/LN-s+LH+rIb-%s+1-! +s*t&tr-eTmrd4Ngrd"EdoQS]+q/uCQqfDXTiGnd9rH%jXrcS3`r-/-bs*=Kfrd4ZmqL/?lr."?h +nq$Icp4N +JcC<$JcCl4n,E4_r;?BfrqcThqtU0bs7Z?_rq-6^qssaVs7#pSrpKdQqs==Js6BLGroj@ErT=+@ +s5a.=s5O(;ro!h6s5*b2&DZ$pg=k65f[na+f%&:"e'e6C%FEGHcHXSVbK@rJaN)="`=9c'_SX.) +^V@Lr]Y(kfrj`TM\$i`Q['[0GZE^[=Yck75riH7'X/l6"!i`,srhodns/#^js.fUgrLs7as.B7] +s.01[rLCrf@)>s,I#:s,6o7re^Z2s+gT.s+UK+rIY0'JV!`L +s*t&tr-eTmrd4Kfr-A0aa`mT)qfVUSqfDRRno=JGr,_^VrcS3`r-/-brd"Efs*O`mqgJHmrI=Tm +qLS9jl\#.hrIt-'s+gT0rJCQ3!/pf7#E=b(O,oBaOoCLNPE_>tQBml)R$jEBRgP[VSt;RITV8'R +U].%iV5F6i!NaMrUU![rq--]rq? +JcC<$JcCl4n,E4_r;?BfrqcThqtU0bs7Z?_rq-6^qssaVs7#pSrpKdQqs==Js6BLGroj@ErT=+@ +s5a.=s5O(;ro!h6s5*b2&DZ$pg=k65f[na+f%&:"e'e6C%FEGHcHXSVbK@rJaN)="`=9c'_SX.) +^V@Lr]Y(kfrj`TM\$i`Q['[0GZE^[=Yck75riH7'X/l6"!i`,srhodns/#^js.fUgrLs7as.B7] +s.01[rLCrf@)>s,I#:s,6o7re^Z2s+gT.s+UK+rIY0'JV!`L +s*t&tr-eTmrd4Kfr-A0aa`mT)qfVUSqfDRRno=JGr,_^VrcS3`r-/-brd"Efs*O`mqgJHmrI=Tm +qLS9jl\#.hrIt-'s+gT0rJCQ3!/pf7#E=b(O,oBaOoCLNPE_>tQBml)R$jEBRgP[VSt;RITV8'R +U].%iV5F6i!NaMrUU![rq--]rq? +JcC<$JcCl4n,E4_r;?BfrqcThqtU0bs7Z?_rq-6^qssaVs7#pSrpKdQqs==Js6BLGroj@ErT=+@ +s5a.=s5O(;ro!h6s5*b2&DZ$pg=k65f[na+f%&:"e'e6C%FEGHcHXSVbK@rJaN)="`=9c'_SX.) +^V@Lr]Y(kfrj`TM\$i`Q['[0GZE^[=Yck75riH7'X/l6"!i`,srhodns/#^js.fUgrLs7as.B7] +s.01[rLCrf@)>s,I#:s,6o7re^Z2s+gT.s+UK+rIY0'JV!`L +s*t&tr-eTmrd4Kfr-A0aa`mT)qfVUSqfDRRno=JGr,_^VrcS3`r-/-brd"Efs*O`mqgJHmrI=Tm +qLS9jl\#.hrIt-'s+gT0rJCQ3!/pf7#E=b(O,oBaOoCLNPE_>tQBml)R$jEBRgP[VSt;RITV8'R +U].%iV5F6i!NaMrUU![rq--]rq? +JcC<$JcCi3n,E4_rVZHfrqcWiqY:'arq?9_rq-3]r:9jWrp]gRrpKdQqs==Jrp'CFs60IFr9"%@ +s5a.=s5O(;ro!h6!8d_2s4dV/rn7D+f`'JIf%&:"e'lamdEp4bcHXSVbK@rKaN2EA`Pod5_SX.) +^V@Lrrk&EH]",A]\,Nf:[C#q>!OB!0YlCm,Y5YO)XK/E$WrK$uW;WXoVZ3LlV#R4iUA^ecT`:Y_ +T)YA]SGerVRfAfSR/`KQQMm*KPlHsGP5gXEOSt7?NW>(;MunopMZ&A5LkgcaLAur-K`-Q'K)^E# +JGt&uIf+WnI/SEeHM`!9Gk-(UG5QLVFSKqKEqsePFT$@]G5QR`GlE!dHN/?kI/JElIf=imJGauq +K'%^]K`$Q"LB!&.M#E21MZ8V5Muo!!NrG(?OHKO*#*Y:9Q'IZ%rg4apR[]e:S=Q7CT:hmOU8"EY +UnsrcVl-JmWN)u!X/u<&s/l@*rNQ=,s0DU0s0Vd5qmQL5rOD[6r4;j=qRlg@rkA,^b5TQlbg"DXcHjh`dF$CkrmV,%f%8O+g&B\8gYCW@hV[8LiSrkWj5f>$joOZ/ +rojIKli-5PmI'EAn,MkWnbr%YoD\C[p&=[`p\=OZq=a[NqtU*`rTX<4s+14(s*t~> +JcC<$JcCi3n,E4_rVZHfrqcWiqY:'arq?9_rq-3]r:9jWrp]gRrpKdQqs==Jrp'CFs60IFr9"%@ +s5a.=s5O(;ro!h6!8d_2s4dV/rn7D+f`'JIf%&:"e'lamdEp4bcHXSVbK@rKaN2EA`Pod5_SX.) +^V@Lrrk&EH]",A]\,Nf:[C#q>!OB!0YlCm,Y5YO)XK/E$WrK$uW;WXoVZ3LlV#R4iUA^ecT`:Y_ +T)YA]SGerVRfAfSR/`KQQMm*KPlHsGP5gXEOSt7?NW>(;MunopMZ&A5LkgcaLAur-K`-Q'K)^E# +JGt&uIf+WnI/SEeHM`!9Gk-(UG5QLVFSKqKEqsePFT$@]G5QR`GlE!dHN/?kI/JElIf=imJGauq +K'%^]K`$Q"LB!&.M#E21MZ8V5Muo!!NrG(?OHKO*#*Y:9Q'IZ%rg4apR[]e:S=Q7CT:hmOU8"EY +UnsrcVl-JmWN)u!X/u<&s/l@*rNQ=,s0DU0s0Vd5qmQL5rOD[6r4;j=qRlg@rkA,^b5TQlbg"DXcHjh`dF$CkrmV,%f%8O+g&B\8gYCW@hV[8LiSrkWj5f>$joOZ/ +rojIKli-5PmI'EAn,MkWnbr%YoD\C[p&=[`p\=OZq=a[NqtU*`rTX<4s+14(s*t~> +JcC<$JcCi3n,E4_rVZHfrqcWiqY:'arq?9_rq-3]r:9jWrp]gRrpKdQqs==Jrp'CFs60IFr9"%@ +s5a.=s5O(;ro!h6!8d_2s4dV/rn7D+f`'JIf%&:"e'lamdEp4bcHXSVbK@rKaN2EA`Pod5_SX.) +^V@Lrrk&EH]",A]\,Nf:[C#q>!OB!0YlCm,Y5YO)XK/E$WrK$uW;WXoVZ3LlV#R4iUA^ecT`:Y_ +T)YA]SGerVRfAfSR/`KQQMm*KPlHsGP5gXEOSt7?NW>(;MunopMZ&A5LkgcaLAur-K`-Q'K)^E# +JGt&uIf+WnI/SEeHM`!9Gk-(UG5QLVFSKqKEqsePFT$@]G5QR`GlE!dHN/?kI/JElIf=imJGauq +K'%^]K`$Q"LB!&.M#E21MZ8V5Muo!!NrG(?OHKO*#*Y:9Q'IZ%rg4apR[]e:S=Q7CT:hmOU8"EY +UnsrcVl-JmWN)u!X/u<&s/l@*rNQ=,s0DU0s0Vd5qmQL5rOD[6r4;j=qRlg@rkA,^b5TQlbg"DXcHjh`dF$CkrmV,%f%8O+g&B\8gYCW@hV[8LiSrkWj5f>$joOZ/ +rojIKli-5PmI'EAn,MkWnbr%YoD\C[p&=[`p\=OZq=a[NqtU*`rTX<4s+14(s*t~> +JcC<$JcCf2n,E7`r;?BfrVHNhqY:'arq?6^s7H<^qssaVrp]gRrpKdQqX"4Irp'FGrojCFr9"%@ +s5a.=s5O(;rnmk8hVS7f!SlH/g'66_f[na+ec+&:e'cXkd*L"_c-=JUbK@rJaN)<>`Pf[2_SO%e +^BM?b]Y(kfrj`6C\$i`Q[C#q>!OB!0YlCm,Y5YR'X8o="WWK/uW;WUqVPU-fV#R4iUA^ecT`:Y_ +T)P;\SGerWRfAfSR/`KQQMm*KPlHsHP5g[EOT(=@NrP+ +JcC<$JcCf2n,E7`r;?BfrVHNhqY:'arq?6^s7H<^qssaVrp]gRrpKdQqX"4Irp'FGrojCFr9"%@ +s5a.=s5O(;rnmk8hVS7f!SlH/g'66_f[na+ec+&:e'cXkd*L"_c-=JUbK@rJaN)<>`Pf[2_SO%e +^BM?b]Y(kfrj`6C\$i`Q[C#q>!OB!0YlCm,Y5YR'X8o="WWK/uW;WUqVPU-fV#R4iUA^ecT`:Y_ +T)P;\SGerWRfAfSR/`KQQMm*KPlHsHP5g[EOT(=@NrP+ +JcC<$JcCf2n,E7`r;?BfrVHNhqY:'arq?6^s7H<^qssaVrp]gRrpKdQqX"4Irp'FGrojCFr9"%@ +s5a.=s5O(;rnmk8hVS7f!SlH/g'66_f[na+ec+&:e'cXkd*L"_c-=JUbK@rJaN)<>`Pf[2_SO%e +^BM?b]Y(kfrj`6C\$i`Q[C#q>!OB!0YlCm,Y5YR'X8o="WWK/uW;WUqVPU-fV#R4iUA^ecT`:Y_ +T)P;\SGerWRfAfSR/`KQQMm*KPlHsHP5g[EOT(=@NrP+ +JcC<$JcCc1n,E4_rVZHfrqcThqtU0brq?6^rq-3]qssaVrp]dQrpKdQqs==Jrp'CFs60IFrT=.A +s5a.=s5F%;rSRq(;MunopMZ&A5LkgcaLAuu-K`-Q'K)^E" +JGt&tIenKkI/A96HMVpbGkQ@ZG5?@EFSp:[G5?F^GlE!dHN&9kI/JElIfFopJGk&uK(jonK^sic +LAZi+M#3&/MZ/P4Muo!!NrG+>O8tFBOtDl^Pa.N"QC!u+R@9S6S"-%@StD[KTqS3UUnji`VPg>j +WMuntX/rD)Xfeh1rilF-s0DX1s0Vg6r3lU6rj_j9rOVs>pq6R=rP&-CrkSQMr5/KOs2=lTs2P)Z +rl>/_b0'_,&BrDDcHab^d*^7hdaQ^qe^j`O"k_M^g=tE^h$)Zmi8ESRro4CIjlY^gkNM0plK[^7 +liQSBmf)YVnF?&Io)J=]o_eC]pAXg^q"sm_qW[nMr:g0Qrdk*#s4I@%~> +JcC<$JcCc1n,E4_rVZHfrqcThqtU0brq?6^rq-3]qssaVrp]dQrpKdQqs==Jrp'CFs60IFrT=.A +s5a.=s5F%;rSRq(;MunopMZ&A5LkgcaLAuu-K`-Q'K)^E" +JGt&tIenKkI/A96HMVpbGkQ@ZG5?@EFSp:[G5?F^GlE!dHN&9kI/JElIfFopJGk&uK(jonK^sic +LAZi+M#3&/MZ/P4Muo!!NrG+>O8tFBOtDl^Pa.N"QC!u+R@9S6S"-%@StD[KTqS3UUnji`VPg>j +WMuntX/rD)Xfeh1rilF-s0DX1s0Vg6r3lU6rj_j9rOVs>pq6R=rP&-CrkSQMr5/KOs2=lTs2P)Z +rl>/_b0'_,&BrDDcHab^d*^7hdaQ^qe^j`O"k_M^g=tE^h$)Zmi8ESRro4CIjlY^gkNM0plK[^7 +liQSBmf)YVnF?&Io)J=]o_eC]pAXg^q"sm_qW[nMr:g0Qrdk*#s4I@%~> +JcC<$JcCc1n,E4_rVZHfrqcThqtU0brq?6^rq-3]qssaVrp]dQrpKdQqs==Jrp'CFs60IFrT=.A +s5a.=s5F%;rSRq(;MunopMZ&A5LkgcaLAuu-K`-Q'K)^E" +JGt&tIenKkI/A96HMVpbGkQ@ZG5?@EFSp:[G5?F^GlE!dHN&9kI/JElIfFopJGk&uK(jonK^sic +LAZi+M#3&/MZ/P4Muo!!NrG+>O8tFBOtDl^Pa.N"QC!u+R@9S6S"-%@StD[KTqS3UUnji`VPg>j +WMuntX/rD)Xfeh1rilF-s0DX1s0Vg6r3lU6rj_j9rOVs>pq6R=rP&-CrkSQMr5/KOs2=lTs2P)Z +rl>/_b0'_,&BrDDcHab^d*^7hdaQ^qe^j`O"k_M^g=tE^h$)Zmi8ESRro4CIjlY^gkNM0plK[^7 +liQSBmf)YVnF?&Io)J=]o_eC]pAXg^q"sm_qW[nMr:g0Qrdk*#s4I@%~> +JcC<$JcCc1n,E4_r;??erqcThqtU0brV$-]rq-3]qssaVrp]dQrpKdQqX"4Irp'FGs60IFrT=.A +s5a.=!oi1tro!h6!8d_2!SlH/g&]mZrmq>)e^W*tdf.W9d*L"_c-4ASb/q`Ga2Z-<`Pf[2_SO%& +^V7Fq]Y(kfrj`'>\,Nf@[C!mos/,gmrM9Igs.]Ics.KCa +rLX%[s.'%Ws-itUrL!VO!1*SKs-*MIrK75EOHBI&s,R,=rf$l8s,-f4s+p]1reCH,s+L<&s+:9% +qgeZqrdOWjqL$nAn9Y"XqfqjZqKD+Gqf_g[rHSs,d8Cs-!DG!0mJJ!LB)OQjT7MS"#q\@^])%J_>M1L_uI[R`W*sXa8X0[ +aT0K_bQ#cdc2Q!"cd:%ddF-IleC<%"f%8O+g&B\/gYCW@hV\=j$K:")j5f=`k2tjjroj[Qlg*p( +mHs?@n,MkWnbr%YoDeI\p&=[ap\FU^q>'mOqt9m\rTF02s+14%s*t~> +JcC<$JcCc1n,E4_r;??erqcThqtU0brV$-]rq-3]qssaVrp]dQrpKdQqX"4Irp'FGs60IFrT=.A +s5a.=!oi1tro!h6!8d_2!SlH/g&]mZrmq>)e^W*tdf.W9d*L"_c-4ASb/q`Ga2Z-<`Pf[2_SO%& +^V7Fq]Y(kfrj`'>\,Nf@[C!mos/,gmrM9Igs.]Ics.KCa +rLX%[s.'%Ws-itUrL!VO!1*SKs-*MIrK75EOHBI&s,R,=rf$l8s,-f4s+p]1reCH,s+L<&s+:9% +qgeZqrdOWjqL$nAn9Y"XqfqjZqKD+Gqf_g[rHSs,d8Cs-!DG!0mJJ!LB)OQjT7MS"#q\@^])%J_>M1L_uI[R`W*sXa8X0[ +aT0K_bQ#cdc2Q!"cd:%ddF-IleC<%"f%8O+g&B\/gYCW@hV\=j$K:")j5f=`k2tjjroj[Qlg*p( +mHs?@n,MkWnbr%YoDeI\p&=[ap\FU^q>'mOqt9m\rTF02s+14%s*t~> +JcC<$JcCc1n,E4_r;??erqcThqtU0brV$-]rq-3]qssaVrp]dQrpKdQqX"4Irp'FGs60IFrT=.A +s5a.=!oi1tro!h6!8d_2!SlH/g&]mZrmq>)e^W*tdf.W9d*L"_c-4ASb/q`Ga2Z-<`Pf[2_SO%& +^V7Fq]Y(kfrj`'>\,Nf@[C!mos/,gmrM9Igs.]Ics.KCa +rLX%[s.'%Ws-itUrL!VO!1*SKs-*MIrK75EOHBI&s,R,=rf$l8s,-f4s+p]1reCH,s+L<&s+:9% +qgeZqrdOWjqL$nAn9Y"XqfqjZqKD+Gqf_g[rHSs,d8Cs-!DG!0mJJ!LB)OQjT7MS"#q\@^])%J_>M1L_uI[R`W*sXa8X0[ +aT0K_bQ#cdc2Q!"cd:%ddF-IleC<%"f%8O+g&B\/gYCW@hV\=j$K:")j5f=`k2tjjroj[Qlg*p( +mHs?@n,MkWnbr%YoDeI\p&=[ap\FU^q>'mOqt9m\rTF02s+14%s*t~> +JcC<$JcC`0n,E4_r;??erqcThqY:'arq?6^rq-0\qssaVrUB^QrU0[Pqs==Jrp'FGrojCFrT=.A +s5a1>s5O(;rnmh7hYu=NgtUT;g=b-2f@SU(eC;srda?Ihcd'h\bfe2Pao9?fa2Z*;`5BI/_8-&b +$bjs0;X0rilF+s/u@'s/c7$rMfpuW2TZms/,dlrM9Igs.]Ics.KCa +rLX%[s.'%Ws-itUrg<_Ps-EYLs-3PIrf[;Ds,d5@s,I)=rJUf9MMh@hs+gZ1rJ(?+re16&rdt0$ +qgeWprI49bfR3LAp3QX^r-7jXlur,IrHSs,d8CrfRhVPa%GuQBml)R$jA2S"#q=rgj:cTV8'RU].%rV5C/gW2ZbrWiN6# +XTGZ/YPta,Z*O>7!joACrO2a8s1&!;rjr'?qRla>rP&'ArP8EKqni?Ms2=iSs2P)ZrlG,]s2t>a +s3(Jfrlu)$d*U1fdaHUoeCE+#f@S[.rn7_6gtgfChV[8LiSsjs$fpF3k3(pkl07Kuli-5OmI'rA +!q>aMrpp*\s7H6^s7ZHdq=sm`qtfUToDJ:[k5Kr3JcF=$J,~> +JcC<$JcC`0n,E4_r;??erqcThqY:'arq?6^rq-0\qssaVrUB^QrU0[Pqs==Jrp'FGrojCFrT=.A +s5a1>s5O(;rnmh7hYu=NgtUT;g=b-2f@SU(eC;srda?Ihcd'h\bfe2Pao9?fa2Z*;`5BI/_8-&b +$bjs0;X0rilF+s/u@'s/c7$rMfpuW2TZms/,dlrM9Igs.]Ics.KCa +rLX%[s.'%Ws-itUrg<_Ps-EYLs-3PIrf[;Ds,d5@s,I)=rJUf9MMh@hs+gZ1rJ(?+re16&rdt0$ +qgeWprI49bfR3LAp3QX^r-7jXlur,IrHSs,d8CrfRhVPa%GuQBml)R$jA2S"#q=rgj:cTV8'RU].%rV5C/gW2ZbrWiN6# +XTGZ/YPta,Z*O>7!joACrO2a8s1&!;rjr'?qRla>rP&'ArP8EKqni?Ms2=iSs2P)ZrlG,]s2t>a +s3(Jfrlu)$d*U1fdaHUoeCE+#f@S[.rn7_6gtgfChV[8LiSsjs$fpF3k3(pkl07Kuli-5OmI'rA +!q>aMrpp*\s7H6^s7ZHdq=sm`qtfUToDJ:[k5Kr3JcF=$J,~> +JcC<$JcC`0n,E4_r;??erqcThqY:'arq?6^rq-0\qssaVrUB^QrU0[Pqs==Jrp'FGrojCFrT=.A +s5a1>s5O(;rnmh7hYu=NgtUT;g=b-2f@SU(eC;srda?Ihcd'h\bfe2Pao9?fa2Z*;`5BI/_8-&b +$bjs0;X0rilF+s/u@'s/c7$rMfpuW2TZms/,dlrM9Igs.]Ics.KCa +rLX%[s.'%Ws-itUrg<_Ps-EYLs-3PIrf[;Ds,d5@s,I)=rJUf9MMh@hs+gZ1rJ(?+re16&rdt0$ +qgeWprI49bfR3LAp3QX^r-7jXlur,IrHSs,d8CrfRhVPa%GuQBml)R$jA2S"#q=rgj:cTV8'RU].%rV5C/gW2ZbrWiN6# +XTGZ/YPta,Z*O>7!joACrO2a8s1&!;rjr'?qRla>rP&'ArP8EKqni?Ms2=iSs2P)ZrlG,]s2t>a +s3(Jfrlu)$d*U1fdaHUoeCE+#f@S[.rn7_6gtgfChV[8LiSsjs$fpF3k3(pkl07Kuli-5OmI'rA +!q>aMrpp*\s7H6^s7ZHdq=sm`qtfUToDJ:[k5Kr3JcF=$J,~> +JcC<$JcC`0mf*+^r;?BfrVHKgqY:'arq?3]rq-3]qXXUTrp]dQrpKaPqs==Jrp'FGs60LGrT=.A +s5a1>s5F%;rnn@FhVR)Egt^Z[4iU]7(eU&Uec +TDbA]Sc>5YS,\rWRJrTRQiEBNQ2d'KPPpXGOcY\(O8k7?NW+n:MuS\6M>rD3L])u-L&Zi(KDpK% +JbjopJ,=]?IJS?gHhVjaH2DjFGPudbH2DpeHiAEjIK+cqJ,FirJcC?!KDpQ&L%pDuL[g2hM>W81 +Mu/J5NW5%;O8k=AOoCODP5pjHPl[2;rg3_SRf8ciS=Q7CT:_dMTq\8d +c-?75!RK-ldJqW)e'umte^i@(f\+s3g=tE^h$W#ri8ESRioB([jo4BCkNMp0!UB"MliQSBmf)YV +nF?&IncJFTo_eC^pAXg_q#'sbqX"+Nr:KsLrdk*#s4%(!~> +JcC<$JcC`0mf*+^r;?BfrVHKgqY:'arq?3]rq-3]qXXUTrp]dQrpKaPqs==Jrp'FGs60LGrT=.A +s5a1>s5F%;rnn@FhVR)Egt^Z[4iU]7(eU&Uec +TDbA]Sc>5YS,\rWRJrTRQiEBNQ2d'KPPpXGOcY\(O8k7?NW+n:MuS\6M>rD3L])u-L&Zi(KDpK% +JbjopJ,=]?IJS?gHhVjaH2DjFGPudbH2DpeHiAEjIK+cqJ,FirJcC?!KDpQ&L%pDuL[g2hM>W81 +Mu/J5NW5%;O8k=AOoCODP5pjHPl[2;rg3_SRf8ciS=Q7CT:_dMTq\8d +c-?75!RK-ldJqW)e'umte^i@(f\+s3g=tE^h$W#ri8ESRioB([jo4BCkNMp0!UB"MliQSBmf)YV +nF?&IncJFTo_eC^pAXg_q#'sbqX"+Nr:KsLrdk*#s4%(!~> +JcC<$JcC`0mf*+^r;?BfrVHKgqY:'arq?3]rq-3]qXXUTrp]dQrpKaPqs==Jrp'FGs60LGrT=.A +s5a1>s5F%;rnn@FhVR)Egt^Z[4iU]7(eU&Uec +TDbA]Sc>5YS,\rWRJrTRQiEBNQ2d'KPPpXGOcY\(O8k7?NW+n:MuS\6M>rD3L])u-L&Zi(KDpK% +JbjopJ,=]?IJS?gHhVjaH2DjFGPudbH2DpeHiAEjIK+cqJ,FirJcC?!KDpQ&L%pDuL[g2hM>W81 +Mu/J5NW5%;O8k=AOoCODP5pjHPl[2;rg3_SRf8ciS=Q7CT:_dMTq\8d +c-?75!RK-ldJqW)e'umte^i@(f\+s3g=tE^h$W#ri8ESRioB([jo4BCkNMp0!UB"MliQSBmf)YV +nF?&IncJFTo_eC^pAXg_q#'sbqX"+Nr:KsLrdk*#s4%(!~> +JcC<$JcC]/mf*+^r;??erqcThqY:$`rq?3]rq-3]qXXUTrp]aPrpKdQqs==Jrp'FGs60LGrT41C +jQ-=#s5O(;s5%=OT1IBP5g^GPl?sJQ2m9NQjT7MS"#qa +s3(Jfrm(Pi!7:_ms3_S0eC<%!f%8O+f\,!4gY:N>h;7&gi"4l,j5]4]jlY^gkih9qlK[^7liHMA +rpTmVs7-*Zs7?9_rUp0`rqH +JcC<$JcC]/mf*+^r;??erqcThqY:$`rq?3]rq-3]qXXUTrp]aPrpKdQqs==Jrp'FGs60LGrT41C +jQ-=#s5O(;s5%=OT1IBP5g^GPl?sJQ2m9NQjT7MS"#qa +s3(Jfrm(Pi!7:_ms3_S0eC<%!f%8O+f\,!4gY:N>h;7&gi"4l,j5]4]jlY^gkih9qlK[^7liHMA +rpTmVs7-*Zs7?9_rUp0`rqH +JcC<$JcC]/mf*+^r;??erqcThqY:$`rq?3]rq-3]qXXUTrp]aPrpKdQqs==Jrp'FGs60LGrT41C +jQ-=#s5O(;s5%=OT1IBP5g^GPl?sJQ2m9NQjT7MS"#qa +s3(Jfrm(Pi!7:_ms3_S0eC<%!f%8O+f\,!4gY:N>h;7&gi"4l,j5]4]jlY^gkih9qlK[^7liHMA +rpTmVs7-*Zs7?9_rUp0`rqH +JcC<$JcCZ.mf*+^r;??erVHNhq=ss`rV$-]rUg*\q==OTrUB[PrU0[Pqs=@Krp'FGs60LGroX7B +s5a1>s5F%;rnmh7hYu=8gtUT;g=b-Xf.,A%eC;sqdF$=fcd'h\bfe2PaiMQDa2Z*;`5BI/_83q% +^V7Cp]Y(kg])K5A\@8sH[KYMIeJ3gI/J?bHMDdZGklX[HN&9iI/JElIfFoqJGt-"K)C9#K`6]&LAco+M"->lMYN,( +N;eh9Nr4tas31Mf +rm(Pi!7:_m#L_)MeC<%!f)F83f\,!4gY:N>h;7&Hi8ESRro4%?jo4BCkNMp0!UB"MliQSBmf)YV +nF?&Jo)J=]o_nI^pAam`q#1$dqXFCQr:9gHrdk*#s3^js~> +JcC<$JcCZ.mf*+^r;??erVHNhq=ss`rV$-]rUg*\q==OTrUB[PrU0[Pqs=@Krp'FGs60LGroX7B +s5a1>s5F%;rnmh7hYu=8gtUT;g=b-Xf.,A%eC;sqdF$=fcd'h\bfe2PaiMQDa2Z*;`5BI/_83q% +^V7Cp]Y(kg])K5A\@8sH[KYMIeJ3gI/J?bHMDdZGklX[HN&9iI/JElIfFoqJGt-"K)C9#K`6]&LAco+M"->lMYN,( +N;eh9Nr4tas31Mf +rm(Pi!7:_m#L_)MeC<%!f)F83f\,!4gY:N>h;7&Hi8ESRro4%?jo4BCkNMp0!UB"MliQSBmf)YV +nF?&Jo)J=]o_nI^pAam`q#1$dqXFCQr:9gHrdk*#s3^js~> +JcC<$JcCZ.mf*+^r;??erVHNhq=ss`rV$-]rUg*\q==OTrUB[PrU0[Pqs=@Krp'FGs60LGroX7B +s5a1>s5F%;rnmh7hYu=8gtUT;g=b-Xf.,A%eC;sqdF$=fcd'h\bfe2PaiMQDa2Z*;`5BI/_83q% +^V7Cp]Y(kg])K5A\@8sH[KYMIeJ3gI/J?bHMDdZGklX[HN&9iI/JElIfFoqJGt-"K)C9#K`6]&LAco+M"->lMYN,( +N;eh9Nr4tas31Mf +rm(Pi!7:_m#L_)MeC<%!f)F83f\,!4gY:N>h;7&Hi8ESRro4%?jo4BCkNMp0!UB"MliQSBmf)YV +nF?&Jo)J=]o_nI^pAam`q#1$dqXFCQr:9gHrdk*#s3^js~> +JcC<$JcCW-mf*+^r;??erVHKgqY:$`rq?3]rUg'[qXXUTrUB[PrpKdQqs==Js6BRIroa@FrT=.A +!9F.>s5F%;ro!h6'&MI#gt^Z_KrjDm9[']h=s0D[0rNQ=*s/u=&s/c7$rMomss/>jns/,gmrM9Igs.]Ic +s.KCargs.\s.'(Xs-itUrg<_P!1*VLs-3PIrf[;D!0I/?!fi8"rJ^c7!/g]2s+p]1r.b3)re1-# +r.=`qd=D(Cr-nBgr-\Ehh0T$HrI"Kjs*jrsr.+furdt'#s+LB*qhG**reU?+q24g&m#:k%rf6l: +rfI/BrK@2E!0mGI#F:^CR$a;0Rf8c`S=Q7CT:_dMTq\=]U^j5uVl-JmWiE,#XKAV-YPta,Z*OA8 +s0Md6rjDm;\@DLJ!kQ"Ur4N'CrkA6DrP8BJpqlsHr5AHNrl4rXr5eo[s2t8_!mJp6rQYJjd*Vd> +#L_)MeC<%!f)F8%f\-8X!ScE/h&>/-i8ESQioB([jlPXekNM-ol0@U#m-O-,mf)\Tn,W"WncJFT +o_eC^pAam`q#:*eqXXOTr:0aFrdk*#s3CXp~> +JcC<$JcCW-mf*+^r;??erVHKgqY:$`rq?3]rUg'[qXXUTrUB[PrpKdQqs==Js6BRIroa@FrT=.A +!9F.>s5F%;ro!h6'&MI#gt^Z_KrjDm9[']h=s0D[0rNQ=*s/u=&s/c7$rMomss/>jns/,gmrM9Igs.]Ic +s.KCargs.\s.'(Xs-itUrg<_P!1*VLs-3PIrf[;D!0I/?!fi8"rJ^c7!/g]2s+p]1r.b3)re1-# +r.=`qd=D(Cr-nBgr-\Ehh0T$HrI"Kjs*jrsr.+furdt'#s+LB*qhG**reU?+q24g&m#:k%rf6l: +rfI/BrK@2E!0mGI#F:^CR$a;0Rf8c`S=Q7CT:_dMTq\=]U^j5uVl-JmWiE,#XKAV-YPta,Z*OA8 +s0Md6rjDm;\@DLJ!kQ"Ur4N'CrkA6DrP8BJpqlsHr5AHNrl4rXr5eo[s2t8_!mJp6rQYJjd*Vd> +#L_)MeC<%!f)F8%f\-8X!ScE/h&>/-i8ESQioB([jlPXekNM-ol0@U#m-O-,mf)\Tn,W"WncJFT +o_eC^pAam`q#:*eqXXOTr:0aFrdk*#s3CXp~> +JcC<$JcCW-mf*+^r;??erVHKgqY:$`rq?3]rUg'[qXXUTrUB[PrpKdQqs==Js6BRIroa@FrT=.A +!9F.>s5F%;ro!h6'&MI#gt^Z_KrjDm9[']h=s0D[0rNQ=*s/u=&s/c7$rMomss/>jns/,gmrM9Igs.]Ic +s.KCargs.\s.'(Xs-itUrg<_P!1*VLs-3PIrf[;D!0I/?!fi8"rJ^c7!/g]2s+p]1r.b3)re1-# +r.=`qd=D(Cr-nBgr-\Ehh0T$HrI"Kjs*jrsr.+furdt'#s+LB*qhG**reU?+q24g&m#:k%rf6l: +rfI/BrK@2E!0mGI#F:^CR$a;0Rf8c`S=Q7CT:_dMTq\=]U^j5uVl-JmWiE,#XKAV-YPta,Z*OA8 +s0Md6rjDm;\@DLJ!kQ"Ur4N'CrkA6DrP8BJpqlsHr5AHNrl4rXr5eo[s2t8_!mJp6rQYJjd*Vd> +#L_)MeC<%!f)F8%f\-8X!ScE/h&>/-i8ESQioB([jlPXekNM-ol0@U#m-O-,mf)\Tn,W"WncJFT +o_eC^pAam`q#:*eqXXOTr:0aFrdk*#s3CXp~> +JcC<$JcCW-mf*+^qu$6drVHKgqY:$`rV$*\rUg'[q==LSrp]aPrpKdQr9XFKs6BRIs60LGrT41C +jQ-=#!oi1trnmh7hYu=_KrjMj7!4;^2s0D[0rNQ=*s/u=&s/c7$r2Tdrs/>mos/,gmrM9Igs.]Ic +s.B@arLX%[!1a"W!h,OFrg<_Ps-EYL!gJn4rf[;Ds,d5@s,R,=rf$l8s,-`2s+p]1qhG*(rIjot +pO_1OnppXfr-nEhr-\?fm!APUrI"HirdOirr.+furdt*$re1<*qhG**reUE-r/1B0k)B+qqi:N6 +rfI/BrK@2Es-3JI!g]1>rg3_SRf8c\S=Q4BStD\TT`q0cUnjiarhfpuWN)u!XT#=0Y-5(6Z*CU@ +Za@*IrjDm;\@DOKs186BrOi0DrkAC*\qt0gVrS[[+s+13ps*t~> +JcC<$JcCW-mf*+^qu$6drVHKgqY:$`rV$*\rUg'[q==LSrp]aPrpKdQr9XFKs6BRIs60LGrT41C +jQ-=#!oi1trnmh7hYu=_KrjMj7!4;^2s0D[0rNQ=*s/u=&s/c7$r2Tdrs/>mos/,gmrM9Igs.]Ic +s.B@arLX%[!1a"W!h,OFrg<_Ps-EYL!gJn4rf[;Ds,d5@s,R,=rf$l8s,-`2s+p]1qhG*(rIjot +pO_1OnppXfr-nEhr-\?fm!APUrI"HirdOirr.+furdt*$re1<*qhG**reUE-r/1B0k)B+qqi:N6 +rfI/BrK@2Es-3JI!g]1>rg3_SRf8c\S=Q4BStD\TT`q0cUnjiarhfpuWN)u!XT#=0Y-5(6Z*CU@ +Za@*IrjDm;\@DOKs186BrOi0DrkAC*\qt0gVrS[[+s+13ps*t~> +JcC<$JcCW-mf*+^qu$6drVHKgqY:$`rV$*\rUg'[q==LSrp]aPrpKdQr9XFKs6BRIs60LGrT41C +jQ-=#!oi1trnmh7hYu=_KrjMj7!4;^2s0D[0rNQ=*s/u=&s/c7$r2Tdrs/>mos/,gmrM9Igs.]Ic +s.B@arLX%[!1a"W!h,OFrg<_Ps-EYL!gJn4rf[;Ds,d5@s,R,=rf$l8s,-`2s+p]1qhG*(rIjot +pO_1OnppXfr-nEhr-\?fm!APUrI"HirdOirr.+furdt*$re1<*qhG**reUE-r/1B0k)B+qqi:N6 +rfI/BrK@2Es-3JI!g]1>rg3_SRf8c\S=Q4BStD\TT`q0cUnjiarhfpuWN)u!XT#=0Y-5(6Z*CU@ +Za@*IrjDm;\@DOKs186BrOi0DrkAC*\qt0gVrS[[+s+13ps*t~> +JcC<$JcCT,mf*+^qu$6drVHKgq=sp_rV$*\rUg'[q""FSrUB[PrpKdQr9XFKs6BRIs60LGroX7B +!9F.>s5F%;rnmh7hYu=3gtVh^"khP[f@JLOe0[4iU]7(e +T`UmZTDb>_SXc5LS,\rWRJrQTQ^3s:Q2d'KPPpXGOcY\'Nrk?$NW"h9MuS\4M>i>2L\cc(L&?VX +KCXWjJbO]mJ,FciIJJ9\Hhr-cIK"]pJ,=crJc:9"KDpQ(L&?])L]3,,M>`>1MtDtuNV8D+O8Y1> +Oo1CBPQ-mGPld81tG_u.IJ`VdaSa8 +JcC<$JcCT,mf*+^qu$6drVHKgq=sp_rV$*\rUg'[q""FSrUB[PrpKdQr9XFKs6BRIs60LGroX7B +!9F.>s5F%;rnmh7hYu=3gtVh^"khP[f@JLOe0[4iU]7(e +T`UmZTDb>_SXc5LS,\rWRJrQTQ^3s:Q2d'KPPpXGOcY\'Nrk?$NW"h9MuS\4M>i>2L\cc(L&?VX +KCXWjJbO]mJ,FciIJJ9\Hhr-cIK"]pJ,=crJc:9"KDpQ(L&?])L]3,,M>`>1MtDtuNV8D+O8Y1> +Oo1CBPQ-mGPld81tG_u.IJ`VdaSa8 +JcC<$JcCT,mf*+^qu$6drVHKgq=sp_rV$*\rUg'[q""FSrUB[PrpKdQr9XFKs6BRIs60LGroX7B +!9F.>s5F%;rnmh7hYu=3gtVh^"khP[f@JLOe0[4iU]7(e +T`UmZTDb>_SXc5LS,\rWRJrQTQ^3s:Q2d'KPPpXGOcY\'Nrk?$NW"h9MuS\4M>i>2L\cc(L&?VX +KCXWjJbO]mJ,FciIJJ9\Hhr-cIK"]pJ,=crJc:9"KDpQ(L&?])L]3,,M>`>1MtDtuNV8D+O8Y1> +Oo1CBPQ-mGPld81tG_u.IJ`VdaSa8 +JcC<$JcCQ+mJd"]r;?,\`r\,Ec8[K!W4Zi@?2Z2Lp,YQ(d'XoGL&X8K!tWW/pqVuNXoV>d:jU]7(e +T`UmZTDkG^Sc>5ZS,\oWRJrTRQiEBNPld26PQ$aFOoLOBO8k7?NW"h9MuJV3M>i>1L\Z]&L%g8M +KDU8uJbXcnJ,FcdIJ8-]IJnWoJ,=cqJcC?"KDpQ(L&?]*L]3,,M>iD3Mti8-NV&7sO8P+D+J_u.II`VdaSa8*gTao9H\bQ#fdc2Grfci;Ajd/qbFe,Ihu +e^i=Nf)aOWrn8=Ggt^`AhV[5Ki8N\Tj5]4^jlY^gkih9qlK[^7liHMArpTmV!:g$Ys766_rUp0` +s7cEcrqZNhp&"L]nGV,@JcC<$bQ!(~> +JcC<$JcCQ+mJd"]r;?,\`r\,Ec8[K!W4Zi@?2Z2Lp,YQ(d'XoGL&X8K!tWW/pqVuNXoV>d:jU]7(e +T`UmZTDkG^Sc>5ZS,\oWRJrTRQiEBNPld26PQ$aFOoLOBO8k7?NW"h9MuJV3M>i>1L\Z]&L%g8M +KDU8uJbXcnJ,FcdIJ8-]IJnWoJ,=cqJcC?"KDpQ(L&?]*L]3,,M>iD3Mti8-NV&7sO8P+D+J_u.II`VdaSa8*gTao9H\bQ#fdc2Grfci;Ajd/qbFe,Ihu +e^i=Nf)aOWrn8=Ggt^`AhV[5Ki8N\Tj5]4^jlY^gkih9qlK[^7liHMArpTmV!:g$Ys766_rUp0` +s7cEcrqZNhp&"L]nGV,@JcC<$bQ!(~> +JcC<$JcCQ+mJd"]r;?,\`r\,Ec8[K!W4Zi@?2Z2Lp,YQ(d'XoGL&X8K!tWW/pqVuNXoV>d:jU]7(e +T`UmZTDkG^Sc>5ZS,\oWRJrTRQiEBNPld26PQ$aFOoLOBO8k7?NW"h9MuJV3M>i>1L\Z]&L%g8M +KDU8uJbXcnJ,FcdIJ8-]IJnWoJ,=cqJcC?"KDpQ(L&?]*L]3,,M>iD3Mti8-NV&7sO8P+D+J_u.II`VdaSa8*gTao9H\bQ#fdc2Grfci;Ajd/qbFe,Ihu +e^i=Nf)aOWrn8=Ggt^`AhV[5Ki8N\Tj5]4^jlY^gkih9qlK[^7liHMArpTmV!:g$Ys766_rUp0` +s7cEcrqZNhp&"L]nGV,@JcC<$bQ!(~> +JcC<$JcCN*mf*(]r;?&E;[-i8EMMhVI#CgY:H9g"?;U"kM5ReC2kFd07nCcHa\YrlYkqaiMQD`l?!:`5BL0_SO(( +rkANK]tOEX!kZ%Trji'=s0qs8s0_m6rNlO0s0;O,ric@)rN6+$s/Z'ts/H$srMT[ms/#^js.fUg +rh9@bs.B:^!hGjOrgWqV!1EeQ!gf4=rg!MJ!0dAEs,d;CrK$u=s,Hu9repf6qhb<.rJ1'#kCr;V +oRm'nrIO]nr."Tml$`JYrI=Zos+10$r.G!%s+UB*s+gT0r/(E1repW3rJg]7kE#A!r/pfG +rK[DKs-N_Ps-WkUrgWqX!1j+\!M?%aTamflUnjiaVPg>jWN)u!XT#=/Y-5(6Z*L[AZa@.>[Kj:O +\@K/]]"@pR!kl=^rP/BJrk\NLrkn]Qpr30NqoAKQrQ5&]qoeu_s3:Jes3C\lrR(Yn!7Unr!nGlQ +rmq2'g&B\;gYCT?h;7#Gi8ESQioB([jQ6C'!U&\GklL)8rp0^RmdC)C!q>aMrpp*\s7H9_s7ZKe +qtU0drVH6bq#'[\gAZ['JcEgkJ,~> +JcC<$JcCN*mf*(]r;?&E;[-i8EMMhVI#CgY:H9g"?;U"kM5ReC2kFd07nCcHa\YrlYkqaiMQD`l?!:`5BL0_SO(( +rkANK]tOEX!kZ%Trji'=s0qs8s0_m6rNlO0s0;O,ric@)rN6+$s/Z'ts/H$srMT[ms/#^js.fUg +rh9@bs.B:^!hGjOrgWqV!1EeQ!gf4=rg!MJ!0dAEs,d;CrK$u=s,Hu9repf6qhb<.rJ1'#kCr;V +oRm'nrIO]nr."Tml$`JYrI=Zos+10$r.G!%s+UB*s+gT0r/(E1repW3rJg]7kE#A!r/pfG +rK[DKs-N_Ps-WkUrgWqX!1j+\!M?%aTamflUnjiaVPg>jWN)u!XT#=/Y-5(6Z*L[AZa@.>[Kj:O +\@K/]]"@pR!kl=^rP/BJrk\NLrkn]Qpr30NqoAKQrQ5&]qoeu_s3:Jes3C\lrR(Yn!7Unr!nGlQ +rmq2'g&B\;gYCT?h;7#Gi8ESQioB([jQ6C'!U&\GklL)8rp0^RmdC)C!q>aMrpp*\s7H9_s7ZKe +qtU0drVH6bq#'[\gAZ['JcEgkJ,~> +JcC<$JcCN*mf*(]r;?&E;[-i8EMMhVI#CgY:H9g"?;U"kM5ReC2kFd07nCcHa\YrlYkqaiMQD`l?!:`5BL0_SO(( +rkANK]tOEX!kZ%Trji'=s0qs8s0_m6rNlO0s0;O,ric@)rN6+$s/Z'ts/H$srMT[ms/#^js.fUg +rh9@bs.B:^!hGjOrgWqV!1EeQ!gf4=rg!MJ!0dAEs,d;CrK$u=s,Hu9repf6qhb<.rJ1'#kCr;V +oRm'nrIO]nr."Tml$`JYrI=Zos+10$r.G!%s+UB*s+gT0r/(E1repW3rJg]7kE#A!r/pfG +rK[DKs-N_Ps-WkUrgWqX!1j+\!M?%aTamflUnjiaVPg>jWN)u!XT#=/Y-5(6Z*L[AZa@.>[Kj:O +\@K/]]"@pR!kl=^rP/BJrk\NLrkn]Qpr30NqoAKQrQ5&]qoeu_s3:Jes3C\lrR(Yn!7Unr!nGlQ +rmq2'g&B\;gYCT?h;7#Gi8ESQioB([jQ6C'!U&\GklL)8rp0^RmdC)C!q>aMrpp*\s7H9_s7ZKe +qtU0drVH6bq#'[\gAZ['JcEgkJ,~> +JcC<$JcCN*mJd"]qu$3crVHHfq=sm^rV$$ZrUg$Zq==LSrp]gRrpKdQrTsRMs6BRIs6'IGroX7B +!9F.>s5F%;rnn.@hVI#CgtUQ:g"?;U"kM5ReC2kFd0e7HcHa\Ybfe2Pao9?^a2\+t!Q;nT_?.Qh +_#D(M^:h5Z]E5^V])B2>\,a#:[fTR]E5d\^AYhH_#M7K_Z.OQ`;.CM`r*mOaSa0Yb50<\bl>rccMu5id/MGmdf7eqeGn&!f)F;$ +fDsV(gAfn-h#?+1hV\=j!TE&;irS6&roO7Ekl0fOlKdd&m-X3.rpTmV!:g$Y!qZ'VrUp3arqH?c +rqZNhp\Xdao)72>JcC<$a8^Y~> +JcC<$JcCN*mJd"]qu$3crVHHfq=sm^rV$$ZrUg$Zq==LSrp]gRrpKdQrTsRMs6BRIs6'IGroX7B +!9F.>s5F%;rnn.@hVI#CgtUQ:g"?;U"kM5ReC2kFd0e7HcHa\Ybfe2Pao9?^a2\+t!Q;nT_?.Qh +_#D(M^:h5Z]E5^V])B2>\,a#:[fTR]E5d\^AYhH_#M7K_Z.OQ`;.CM`r*mOaSa0Yb50<\bl>rccMu5id/MGmdf7eqeGn&!f)F;$ +fDsV(gAfn-h#?+1hV\=j!TE&;irS6&roO7Ekl0fOlKdd&m-X3.rpTmV!:g$Y!qZ'VrUp3arqH?c +rqZNhp\Xdao)72>JcC<$a8^Y~> +JcC<$JcCN*mJd"]qu$3crVHHfq=sm^rV$$ZrUg$Zq==LSrp]gRrpKdQrTsRMs6BRIs6'IGroX7B +!9F.>s5F%;rnn.@hVI#CgtUQ:g"?;U"kM5ReC2kFd0e7HcHa\Ybfe2Pao9?^a2\+t!Q;nT_?.Qh +_#D(M^:h5Z]E5^V])B2>\,a#:[fTR]E5d\^AYhH_#M7K_Z.OQ`;.CM`r*mOaSa0Yb50<\bl>rccMu5id/MGmdf7eqeGn&!f)F;$ +fDsV(gAfn-h#?+1hV\=j!TE&;irS6&roO7Ekl0fOlKdd&m-X3.rpTmV!:g$Y!qZ'VrUp3arqH?c +rqZNhp\Xdao)72>JcC<$a8^Y~> +JcC<$JcCK)mJct\r;?TR +]E5d\^AbnI_#M7L_Z%IQ`;7IO`r3sOaSa0Xb5'6[bl5lacMu5jd/;8mdaQ\DeGn&!f)F;$fDsV( +gAfn-h#?+1hV\=j!TE&;isb#1jlY^gkNM0plK[^7liQSBmf)YVnF?&Jo)J=]o_nI_pAambq#:*f +qY0m`r:Ks=rdk*#s2=qf~> +JcC<$JcCK)mJct\r;?TR +]E5d\^AbnI_#M7L_Z%IQ`;7IO`r3sOaSa0Xb5'6[bl5lacMu5jd/;8mdaQ\DeGn&!f)F;$fDsV( +gAfn-h#?+1hV\=j!TE&;isb#1jlY^gkNM0plK[^7liQSBmf)YVnF?&Jo)J=]o_nI_pAambq#:*f +qY0m`r:Ks=rdk*#s2=qf~> +JcC<$JcCK)mJct\r;?TR +]E5d\^AbnI_#M7L_Z%IQ`;7IO`r3sOaSa0Xb5'6[bl5lacMu5jd/;8mdaQ\DeGn&!f)F;$fDsV( +gAfn-h#?+1hV\=j!TE&;isb#1jlY^gkNM0plK[^7liQSBmf)YVnF?&Jo)J=]o_nI_pAambq#:*f +qY0m`r:Ks=rdk*#s2=qf~> +JcC<$JcCH(mJct\qu$3cr;-Bfq"Xd]r:]pYr:KsZq==LSrp]gRs6fpSr9XIL!:'OI!pJh1roX7B +!9F.>!TN);huV`lrnRq:gY1B7g"=p.f%'cL"k1oIdEp5=c2l26rlY>bao9?^a2\+t!lW!ork\`Q +^qfra!ku@]rO`3D]"7jNs1&*mo!iDfjrhTRh +s.]Lds.B@args.\!1a"W!h,OFrg<_P!1*SK!gJn4rK@2Cs,d2?rf7#gPrgk.&TV/!PU8+KZUnsrcVl-JmWiE,$XKAV-YHY79ZMq0<['d?N\$rlX\[oAark&)rn7G. +gt_nb!T)`5i!86#ioB([jQ6C'!U&\Gkm-M>lg4!*mI'uBs6p$YrUL$]o^r+Ts7ZKeqtU0drqcEe +qY^$beGb%!JcEXfJ,~> +JcC<$JcCH(mJct\qu$3cr;-Bfq"Xd]r:]pYr:KsZq==LSrp]gRs6fpSr9XIL!:'OI!pJh1roX7B +!9F.>!TN);huV`lrnRq:gY1B7g"=p.f%'cL"k1oIdEp5=c2l26rlY>bao9?^a2\+t!lW!ork\`Q +^qfra!ku@]rO`3D]"7jNs1&*mo!iDfjrhTRh +s.]Lds.B@args.\!1a"W!h,OFrg<_P!1*SK!gJn4rK@2Cs,d2?rf7#gPrgk.&TV/!PU8+KZUnsrcVl-JmWiE,$XKAV-YHY79ZMq0<['d?N\$rlX\[oAark&)rn7G. +gt_nb!T)`5i!86#ioB([jQ6C'!U&\Gkm-M>lg4!*mI'uBs6p$YrUL$]o^r+Ts7ZKeqtU0drqcEe +qY^$beGb%!JcEXfJ,~> +JcC<$JcCH(mJct\qu$3cr;-Bfq"Xd]r:]pYr:KsZq==LSrp]gRs6fpSr9XIL!:'OI!pJh1roX7B +!9F.>!TN);huV`lrnRq:gY1B7g"=p.f%'cL"k1oIdEp5=c2l26rlY>bao9?^a2\+t!lW!ork\`Q +^qfra!ku@]rO`3D]"7jNs1&*mo!iDfjrhTRh +s.]Lds.B@args.\!1a"W!h,OFrg<_P!1*SK!gJn4rK@2Cs,d2?rf7#gPrgk.&TV/!PU8+KZUnsrcVl-JmWiE,$XKAV-YHY79ZMq0<['d?N\$rlX\[oAark&)rn7G. +gt_nb!T)`5i!86#ioB([jQ6C'!U&\Gkm-M>lg4!*mI'uBs6p$YrUL$]o^r+Ts7ZKeqtU0drqcEe +qY^$beGb%!JcEXfJ,~> +JcC<$JcCE'm/Hn\qu$3cr;-?ep\=^]r:]mXr:KsZq==OTrp]jSrpKgRrTsRMs6BUJs6'IGroX7B +!9F.>!TN);huV`lrnRV1g]#n1g"=p.f%'cL$IdGNdEp7dcHa\YrlY>bao9?da2Z-<`Pf^4rke]O +s1nWKs1SKHrOi0Bs180>s1&*pps/,gmrhTRh +!2BIds.B@arLO(]S=KSJ!h,OFrg<_Ps-EYLs-3PIrK@2Cs,d/>rf6u;qMb?1qMNj\q2"p'pkJa$ +r.OitqL\*cqh"Wrre19)r.b6,reUN0reg`6r/CZ8rf6l:rfI)@p6,-5n!*I0rKdGLr0[JOs-inU +!h>gPrgj1`TV2:X!MZ@gU^ErqVl-JlWN)u!XT#=3Y-5(6Z*L^B['[6L[^WdG\Hf^X]=bei]tXK\ +s1eWNrPJTPs2=iSrl4rXqT/TVr6"]Ur65,aqTf)ds3U\krmLhqrR:o!f%0fO!nc2Zrn7G.gt_nb +!T)`5i;_a9ir7s=jQ6C'#Nt=7l07Kuli-5PmI'EAmfN"Knc&+Zo)SF]p&Fabp\agcq>U6cqtp +JcC<$JcCE'm/Hn\qu$3cr;-?ep\=^]r:]mXr:KsZq==OTrp]jSrpKgRrTsRMs6BUJs6'IGroX7B +!9F.>!TN);huV`lrnRV1g]#n1g"=p.f%'cL$IdGNdEp7dcHa\YrlY>bao9?da2Z-<`Pf^4rke]O +s1nWKs1SKHrOi0Bs180>s1&*pps/,gmrhTRh +!2BIds.B@arLO(]S=KSJ!h,OFrg<_Ps-EYLs-3PIrK@2Cs,d/>rf6u;qMb?1qMNj\q2"p'pkJa$ +r.OitqL\*cqh"Wrre19)r.b6,reUN0reg`6r/CZ8rf6l:rfI)@p6,-5n!*I0rKdGLr0[JOs-inU +!h>gPrgj1`TV2:X!MZ@gU^ErqVl-JlWN)u!XT#=3Y-5(6Z*L^B['[6L[^WdG\Hf^X]=bei]tXK\ +s1eWNrPJTPs2=iSrl4rXqT/TVr6"]Ur65,aqTf)ds3U\krmLhqrR:o!f%0fO!nc2Zrn7G.gt_nb +!T)`5i;_a9ir7s=jQ6C'#Nt=7l07Kuli-5PmI'EAmfN"Knc&+Zo)SF]p&Fabp\agcq>U6cqtp +JcC<$JcCE'm/Hn\qu$3cr;-?ep\=^]r:]mXr:KsZq==OTrp]jSrpKgRrTsRMs6BUJs6'IGroX7B +!9F.>!TN);huV`lrnRV1g]#n1g"=p.f%'cL$IdGNdEp7dcHa\YrlY>bao9?da2Z-<`Pf^4rke]O +s1nWKs1SKHrOi0Bs180>s1&*pps/,gmrhTRh +!2BIds.B@arLO(]S=KSJ!h,OFrg<_Ps-EYLs-3PIrK@2Cs,d/>rf6u;qMb?1qMNj\q2"p'pkJa$ +r.OitqL\*cqh"Wrre19)r.b6,reUN0reg`6r/CZ8rf6l:rfI)@p6,-5n!*I0rKdGLr0[JOs-inU +!h>gPrgj1`TV2:X!MZ@gU^ErqVl-JlWN)u!XT#=3Y-5(6Z*L^B['[6L[^WdG\Hf^X]=bei]tXK\ +s1eWNrPJTPs2=iSrl4rXqT/TVr6"]Ur65,aqTf)ds3U\krmLhqrR:o!f%0fO!nc2Zrn7G.gt_nb +!T)`5i;_a9ir7s=jQ6C'#Nt=7l07Kuli-5PmI'EAmfN"Knc&+Zo)SF]p&Fabp\agcq>U6cqtp +JcC<$JcCB&m/Hn\qu$0br;-?ep\=[\r:]mXr:KsZqXXXUrp]jSrpKgRrTjUOlK\?4!pJh1roO7C +jSn0Iio/kSi8rj`!;r3lX5s0V^1s0D[0r364)s/u=&s/c7$ri6!ts/>pps/#dmrM0Li +U8%X\!hc0Xrgs.\!1a%Xs-itUrg<_P!1*SKs-3PIrK@2CrfI&=rf6r:pPem*iem5^r.t9+pkJa$ +r.O]pnq-RfrIk0(qhG-+reUN0reg`6r/CZ8rf6o;rfI,Aq3(W=q39s*qj.2Iqj@ANs-inUs.'+[ +rgs.^!20=b$_jDkUnjiaVPg>jWW&n$X/rG*Y-7i/"gPA>Za@.>[Ka4N\[f;_]DfGD]tXK\s1eWN +rPAWR`5MSms2P&YqoJ`Xr6"`Vqonu_q9Jrbrm:Sjs3gnqrRCkts472$s4IA)rn7G.gt_nb#N"@q +i8ESQir7sCjQ5Lck3(pkrojIKli-8Nm/ZSRn,MkWnc&+ZoDeI]p&Facp\agcq>U6cqtp +JcC<$JcCB&m/Hn\qu$0br;-?ep\=[\r:]mXr:KsZqXXXUrp]jSrpKgRrTjUOlK\?4!pJh1roO7C +jSn0Iio/kSi8rj`!;r3lX5s0V^1s0D[0r364)s/u=&s/c7$ri6!ts/>pps/#dmrM0Li +U8%X\!hc0Xrgs.\!1a%Xs-itUrg<_P!1*SKs-3PIrK@2CrfI&=rf6r:pPem*iem5^r.t9+pkJa$ +r.O]pnq-RfrIk0(qhG-+reUN0reg`6r/CZ8rf6o;rfI,Aq3(W=q39s*qj.2Iqj@ANs-inUs.'+[ +rgs.^!20=b$_jDkUnjiaVPg>jWW&n$X/rG*Y-7i/"gPA>Za@.>[Ka4N\[f;_]DfGD]tXK\s1eWN +rPAWR`5MSms2P&YqoJ`Xr6"`Vqonu_q9Jrbrm:Sjs3gnqrRCkts472$s4IA)rn7G.gt_nb#N"@q +i8ESQir7sCjQ5Lck3(pkrojIKli-8Nm/ZSRn,MkWnc&+ZoDeI]p&Facp\agcq>U6cqtp +JcC<$JcCB&m/Hn\qu$0br;-?ep\=[\r:]mXr:KsZqXXXUrp]jSrpKgRrTjUOlK\?4!pJh1roO7C +jSn0Iio/kSi8rj`!;r3lX5s0V^1s0D[0r364)s/u=&s/c7$ri6!ts/>pps/#dmrM0Li +U8%X\!hc0Xrgs.\!1a%Xs-itUrg<_P!1*SKs-3PIrK@2CrfI&=rf6r:pPem*iem5^r.t9+pkJa$ +r.O]pnq-RfrIk0(qhG-+reUN0reg`6r/CZ8rf6o;rfI,Aq3(W=q39s*qj.2Iqj@ANs-inUs.'+[ +rgs.^!20=b$_jDkUnjiaVPg>jWW&n$X/rG*Y-7i/"gPA>Za@.>[Ka4N\[f;_]DfGD]tXK\s1eWN +rPAWR`5MSms2P&YqoJ`Xr6"`Vqonu_q9Jrbrm:Sjs3gnqrRCkts472$s4IA)rn7G.gt_nb#N"@q +i8ESQir7sCjQ5Lck3(pkrojIKli-8Nm/ZSRn,MkWnc&+ZoDeI]p&Facp\agcq>U6cqtp +JcC<$JcC?%m/Hk[qu$0br;-?epA"R[r:]mXr:KsZqssaVrp]jSs6fpSrTsRMs6BUJ!pJh1roOdR +jQ,@]io/kSi8VD]DoJ?\c92>\,<]7[JmQ3Zi791Z2Lp,YQ(d(XoGI&X8T'uW;rmqVZN`lV>d7l +US=L^U&UbcTDkG^SH,2YRf]%HRJrTRQiEBMQ2d*KPPp[DOoCI>O8Y+:NT5ubMu&>)M>`8.L\Z]& +L&6PeKD^E$L&6W(L]<2.M>iD4MuAV6NW5%:O8b7?Oo(=?PPg[5Q11+9QhZsIRJrZQS,]#YSc55\ +T)bP`U&UheU].%iV5F6i-`F#EWiN2%Xf\b0YctC;ZEpmE[C3NQ\%&uZ]">Se]Y2%n^V@S"_>V4P +_o0Ll`W*sXa8 +JcC<$JcC?%m/Hk[qu$0br;-?epA"R[r:]mXr:KsZqssaVrp]jSs6fpSrTsRMs6BUJ!pJh1roOdR +jQ,@]io/kSi8VD]DoJ?\c92>\,<]7[JmQ3Zi791Z2Lp,YQ(d(XoGI&X8T'uW;rmqVZN`lV>d7l +US=L^U&UbcTDkG^SH,2YRf]%HRJrTRQiEBMQ2d*KPPp[DOoCI>O8Y+:NT5ubMu&>)M>`8.L\Z]& +L&6PeKD^E$L&6W(L]<2.M>iD4MuAV6NW5%:O8b7?Oo(=?PPg[5Q11+9QhZsIRJrZQS,]#YSc55\ +T)bP`U&UheU].%iV5F6i-`F#EWiN2%Xf\b0YctC;ZEpmE[C3NQ\%&uZ]">Se]Y2%n^V@S"_>V4P +_o0Ll`W*sXa8 +JcC<$JcC?%m/Hk[qu$0br;-?epA"R[r:]mXr:KsZqssaVrp]jSs6fpSrTsRMs6BUJ!pJh1roOdR +jQ,@]io/kSi8VD]DoJ?\c92>\,<]7[JmQ3Zi791Z2Lp,YQ(d(XoGI&X8T'uW;rmqVZN`lV>d7l +US=L^U&UbcTDkG^SH,2YRf]%HRJrTRQiEBMQ2d*KPPp[DOoCI>O8Y+:NT5ubMu&>)M>`8.L\Z]& +L&6PeKD^E$L&6W(L]<2.M>iD4MuAV6NW5%:O8b7?Oo(=?PPg[5Q11+9QhZsIRJrZQS,]#YSc55\ +T)bP`U&UheU].%iV5F6i-`F#EWiN2%Xf\b0YctC;ZEpmE[C3NQ\%&uZ]">Se]Y2%n^V@S"_>V4P +_o0Ll`W*sXa8 +JcC<$JcC<$m/Hk[qu$0bqtg6dpA"R[qtBdWrUg'[qssaVrp]jSs6fpSrp9[Ns6BUJs6'IGroOsW +jQ,@]io8qTi8rfR,Arfd;FpQbN>n!EO2rL*YRqj[VUs.0+[s.9:a +rh9@d!2KOh$`0_tVl-JmWN)u!XT#=*Y-5(6Z*OA8"gk\G[^WdG\H0:Rrk&9F^AbkK^qmkd_?.Wn +`;[aU`rF*WaSs<\b5'6Ybl#`XcMZ#ed/)/hdf._neGn)!f)=5#f`0Y(gAfn-h#6%6hV[5Ki8NYS +ro=%>!9O4B!U&\Gl2U#Kli-5PmI'EAmfN"Knc&+ZoDeI]p&Facp\agcq>U6dqu$BfrRUt!s+13Z +s*t~> +JcC<$JcC<$m/Hk[qu$0bqtg6dpA"R[qtBdWrUg'[qssaVrp]jSs6fpSrp9[Ns6BUJs6'IGroOsW +jQ,@]io8qTi8rfR,Arfd;FpQbN>n!EO2rL*YRqj[VUs.0+[s.9:a +rh9@d!2KOh$`0_tVl-JmWN)u!XT#=*Y-5(6Z*OA8"gk\G[^WdG\H0:Rrk&9F^AbkK^qmkd_?.Wn +`;[aU`rF*WaSs<\b5'6Ybl#`XcMZ#ed/)/hdf._neGn)!f)=5#f`0Y(gAfn-h#6%6hV[5Ki8NYS +ro=%>!9O4B!U&\Gl2U#Kli-5PmI'EAmfN"Knc&+ZoDeI]p&Facp\agcq>U6dqu$BfrRUt!s+13Z +s*t~> +JcC<$JcC<$m/Hk[qu$0bqtg6dpA"R[qtBdWrUg'[qssaVrp]jSs6fpSrp9[Ns6BUJs6'IGroOsW +jQ,@]io8qTi8rfR,Arfd;FpQbN>n!EO2rL*YRqj[VUs.0+[s.9:a +rh9@d!2KOh$`0_tVl-JmWN)u!XT#=*Y-5(6Z*OA8"gk\G[^WdG\H0:Rrk&9F^AbkK^qmkd_?.Wn +`;[aU`rF*WaSs<\b5'6Ybl#`XcMZ#ed/)/hdf._neGn)!f)=5#f`0Y(gAfn-h#6%6hV[5Ki8NYS +ro=%>!9O4B!U&\Gl2U#Kli-5PmI'EAmfN"Knc&+ZoDeI]p&Facp\agcq>U6dqu$BfrRUt!s+13Z +s*t~> +JcC<$JcC<$!<;EbqYgh=L^]2%J^&5PC]DfD>\c92=\,Ec7[K!W4Zi@?2Z2Lp,YQ(d)XoGL&X8].!W;rmqVZN`l +V>d7lUS=L^T`UmZTDkG^SH,2YRf]%HRJiNQQiEBMQ2d*JPPgUBOo:C6O6DVnNV&2.Mu8J.M>`8. +L\$8nL%U3!L]3,-M>iD4Mu8P6NW+t:O8b7@Oo1CAPQ$gBQ2R$FQf=D/RJiTNS,SrXSc,/[TDtS_ +Ta.Se]Y2%n^V@S"_>_:Q_o0Lm +`W*sXa8O*YaoBN[bPo``c1TBZchl)adJhSne,.Ypec45!fDjM'g&9Y)gAp%-h#cHjhu;O=iSrkW +j5f:_roO:Fkii$1!UB"Mm/QGQmf)\Tn,W"Wo)J:]o_nI_pAambq#:*gqYC$dr;$ +JcC<$JcC<$!<;EbqYgh=L^]2%J^&5PC]DfD>\c92=\,Ec7[K!W4Zi@?2Z2Lp,YQ(d)XoGL&X8].!W;rmqVZN`l +V>d7lUS=L^T`UmZTDkG^SH,2YRf]%HRJiNQQiEBMQ2d*JPPgUBOo:C6O6DVnNV&2.Mu8J.M>`8. +L\$8nL%U3!L]3,-M>iD4Mu8P6NW+t:O8b7@Oo1CAPQ$gBQ2R$FQf=D/RJiTNS,SrXSc,/[TDtS_ +Ta.Se]Y2%n^V@S"_>_:Q_o0Lm +`W*sXa8O*YaoBN[bPo``c1TBZchl)adJhSne,.Ypec45!fDjM'g&9Y)gAp%-h#cHjhu;O=iSrkW +j5f:_roO:Fkii$1!UB"Mm/QGQmf)\Tn,W"Wo)J:]o_nI_pAambq#:*gqYC$dr;$ +JcC<$JcC<$!<;EbqYgh=L^]2%J^&5PC]DfD>\c92=\,Ec7[K!W4Zi@?2Z2Lp,YQ(d)XoGL&X8].!W;rmqVZN`l +V>d7lUS=L^T`UmZTDkG^SH,2YRf]%HRJiNQQiEBMQ2d*JPPgUBOo:C6O6DVnNV&2.Mu8J.M>`8. +L\$8nL%U3!L]3,-M>iD4Mu8P6NW+t:O8b7@Oo1CAPQ$gBQ2R$FQf=D/RJiTNS,SrXSc,/[TDtS_ +Ta.Se]Y2%n^V@S"_>_:Q_o0Lm +`W*sXa8O*YaoBN[bPo``c1TBZchl)adJhSne,.Ypec45!fDjM'g&9Y)gAp%-h#cHjhu;O=iSrkW +j5f:_roO:Fkii$1!UB"Mm/QGQmf)\Tn,W"Wo)J:]o_nI_pAambq#:*gqYC$dr;$ +JcC<$JcC<$s8VHbqYg9gp&"X_qt]p[r:g*^q"=UXrq$$Xrpg$Xr9s[Rs6]gPs6B[MrosIH!9a@D +s5aFFj5].YiVqaGhqm2Fgt^ZGqj%,GrKm,Cm@!^;pRD/PrgitYs.B=arLj:e +USIga&>c8$Vl-JlWN)u!X/rG*Y-7i/"gPA>Za@.>[KX.M\[f;`rk&9F^AbkJ^qp#es2+iTrl+oW +s2Y)Zs2k;`r6,&_rQY)^qp5/dp +!9O4B!pAe2roj[Qlg*p(mHs?@n,MnWnc&+ZoDeI^p&Fabp\jmdq>U6dqu$BgrRq1$s+13Ts*t~> +JcC<$JcC<$s8VHbqYg9gp&"X_qt]p[r:g*^q"=UXrq$$Xrpg$Xr9s[Rs6]gPs6B[MrosIH!9a@D +s5aFFj5].YiVqaGhqm2Fgt^ZGqj%,GrKm,Cm@!^;pRD/PrgitYs.B=arLj:e +USIga&>c8$Vl-JlWN)u!X/rG*Y-7i/"gPA>Za@.>[KX.M\[f;`rk&9F^AbkJ^qp#es2+iTrl+oW +s2Y)Zs2k;`r6,&_rQY)^qp5/dp +!9O4B!pAe2roj[Qlg*p(mHs?@n,MnWnc&+ZoDeI^p&Fabp\jmdq>U6dqu$BgrRq1$s+13Ts*t~> +JcC<$JcC<$s8VHbqYg9gp&"X_qt]p[r:g*^q"=UXrq$$Xrpg$Xr9s[Rs6]gPs6B[MrosIH!9a@D +s5aFFj5].YiVqaGhqm2Fgt^ZGqj%,GrKm,Cm@!^;pRD/PrgitYs.B=arLj:e +USIga&>c8$Vl-JlWN)u!X/rG*Y-7i/"gPA>Za@.>[KX.M\[f;`rk&9F^AbkJ^qp#es2+iTrl+oW +s2Y)Zs2k;`r6,&_rQY)^qp5/dp +!9O4B!pAe2roj[Qlg*p(mHs?@n,MnWnc&+ZoDeI^p&Fabp\jmdq>U6dqu$BgrRq1$s+13Ts*t~> +JcC<$JcC<$rr;?aq>L3go_\O^qt]p[qtL!]q=X^Yrq$$Xs7-*XrU9dSs6]gPs6K^Mroj[OkND!i +jlPS&irS/urnmh7hYu=GgtUQ:g"G$0f@JL&eC;sqda?Ihd*M^:!R8jfbQ#]bao09^a2Z-t`<*uq +_u7IO_>h=K^]2%J^&,JB]DfD?\c0,=\,<]7[K!W4Zi@?2Z2V!-YQ(d)XTGT)X8].!W;rmrVuNUo +V>d:jUB%%eT`UmZTDkG^SH,2YS,\rWRJiNQQiEBKQ2[$IPPC=:OlqhkO8P%9NVSP3MuAP-M>E%s +L\lo(M>`>3Mu8P5NW5%:O8k=AOo1CBPQ$gEQ2R$JQhZsERIQa3S,AfUSbo#YTDtS_U&UkeU].%j +V5C-hVZE`qri-""XT#=BY-5(6Z*L[AZa@-K[^WcV\[f;`]Y(qk^;%Fu^qp#e!Q2kT`W*sXa8X0[ +aoBN]bPo`bc2#Z_chl)]dJMAje,%Snec+.tfDjM'g&9Y)g]-(.h>c=3hu;R6iW%p;j8\0?jo4EB +k5a`Fl2U#Kli-5PmI'EAn,MkWnc&+ZoDeI]p&Facp\agcq>U6equ$BhrS@I(s+13Ns*t~> +JcC<$JcC<$rr;?aq>L3go_\O^qt]p[qtL!]q=X^Yrq$$Xs7-*XrU9dSs6]gPs6K^Mroj[OkND!i +jlPS&irS/urnmh7hYu=GgtUQ:g"G$0f@JL&eC;sqda?Ihd*M^:!R8jfbQ#]bao09^a2Z-t`<*uq +_u7IO_>h=K^]2%J^&,JB]DfD?\c0,=\,<]7[K!W4Zi@?2Z2V!-YQ(d)XTGT)X8].!W;rmrVuNUo +V>d:jUB%%eT`UmZTDkG^SH,2YS,\rWRJiNQQiEBKQ2[$IPPC=:OlqhkO8P%9NVSP3MuAP-M>E%s +L\lo(M>`>3Mu8P5NW5%:O8k=AOo1CBPQ$gEQ2R$JQhZsERIQa3S,AfUSbo#YTDtS_U&UkeU].%j +V5C-hVZE`qri-""XT#=BY-5(6Z*L[AZa@-K[^WcV\[f;`]Y(qk^;%Fu^qp#e!Q2kT`W*sXa8X0[ +aoBN]bPo`bc2#Z_chl)]dJMAje,%Snec+.tfDjM'g&9Y)g]-(.h>c=3hu;R6iW%p;j8\0?jo4EB +k5a`Fl2U#Kli-5PmI'EAn,MkWnc&+ZoDeI]p&Facp\agcq>U6equ$BhrS@I(s+13Ns*t~> +JcC<$JcC<$rr;?aq>L3go_\O^qt]p[qtL!]q=X^Yrq$$Xs7-*XrU9dSs6]gPs6K^Mroj[OkND!i +jlPS&irS/urnmh7hYu=GgtUQ:g"G$0f@JL&eC;sqda?Ihd*M^:!R8jfbQ#]bao09^a2Z-t`<*uq +_u7IO_>h=K^]2%J^&,JB]DfD?\c0,=\,<]7[K!W4Zi@?2Z2V!-YQ(d)XTGT)X8].!W;rmrVuNUo +V>d:jUB%%eT`UmZTDkG^SH,2YS,\rWRJiNQQiEBKQ2[$IPPC=:OlqhkO8P%9NVSP3MuAP-M>E%s +L\lo(M>`>3Mu8P5NW5%:O8k=AOo1CBPQ$gEQ2R$JQhZsERIQa3S,AfUSbo#YTDtS_U&UkeU].%j +V5C-hVZE`qri-""XT#=BY-5(6Z*L[AZa@-K[^WcV\[f;`]Y(qk^;%Fu^qp#e!Q2kT`W*sXa8X0[ +aoBN]bPo`bc2#Z_chl)]dJMAje,%Snec+.tfDjM'g&9Y)g]-(.h>c=3hu;R6iW%p;j8\0?jo4EB +k5a`Fl2U#Kli-5PmI'EAn,MkWnc&+ZoDeI]p&Facp\agcq>U6equ$BhrS@I(s+13Ns*t~> +JcC<$JcC<$rVu3_q>L3go_\L]qt]mZr:g*^q=XaZrq$$Xs7--Yr9j^TmHsl=!pf.:roj[OkND!i +jlPS&irS/urnmh7hYu=3gtVh^#2.Y\f@JO'rmUttdf.Vpd*M^:s31Pfrlb>a!6P2\!lr=#rPefT +s24fPrk\WMr4i9Grk86Brk&3Ar42j;s0qp7s0_m6rNcR2Z*F83!jAc0riQ4%s/Z.!!i`,srhfgp +V5=0e!i)Karh9@b!2'4]!hGjOrLs,m5Bs-*JIr0@8Irg3JKrL*POjI>n6r13YTrh'4`r1X.b!2KLgs.o^m +rhgs=WMuntX/i>(Xfek2YctCVf]tXK\!PlPN_?e&t`5T^8`lH.!aT'B^ +b5KN`bl5lacMc)dd.G`_dehMheG[qsf)4/!f`0Y'gAfq-h#6%1hV[5ii;_a9ir.m=jQ5M&joOZ/ +rosIJ!:0XNs6TgSrpTmVs7-*Zs766_rUp3as7cHdrqZQiqYU3gqu,IPJcC<$VuM8~> +JcC<$JcC<$rVu3_q>L3go_\L]qt]mZr:g*^q=XaZrq$$Xs7--Yr9j^TmHsl=!pf.:roj[OkND!i +jlPS&irS/urnmh7hYu=3gtVh^#2.Y\f@JO'rmUttdf.Vpd*M^:s31Pfrlb>a!6P2\!lr=#rPefT +s24fPrk\WMr4i9Grk86Brk&3Ar42j;s0qp7s0_m6rNcR2Z*F83!jAc0riQ4%s/Z.!!i`,srhfgp +V5=0e!i)Karh9@b!2'4]!hGjOrLs,m5Bs-*JIr0@8Irg3JKrL*POjI>n6r13YTrh'4`r1X.b!2KLgs.o^m +rhgs=WMuntX/i>(Xfek2YctCVf]tXK\!PlPN_?e&t`5T^8`lH.!aT'B^ +b5KN`bl5lacMc)dd.G`_dehMheG[qsf)4/!f`0Y'gAfq-h#6%1hV[5ii;_a9ir.m=jQ5M&joOZ/ +rosIJ!:0XNs6TgSrpTmVs7-*Zs766_rUp3as7cHdrqZQiqYU3gqu,IPJcC<$VuM8~> +JcC<$JcC<$rVu3_q>L3go_\L]qt]mZr:g*^q=XaZrq$$Xs7--Yr9j^TmHsl=!pf.:roj[OkND!i +jlPS&irS/urnmh7hYu=3gtVh^#2.Y\f@JO'rmUttdf.Vpd*M^:s31Pfrlb>a!6P2\!lr=#rPefT +s24fPrk\WMr4i9Grk86Brk&3Ar42j;s0qp7s0_m6rNcR2Z*F83!jAc0riQ4%s/Z.!!i`,srhfgp +V5=0e!i)Karh9@b!2'4]!hGjOrLs,m5Bs-*JIr0@8Irg3JKrL*POjI>n6r13YTrh'4`r1X.b!2KLgs.o^m +rhgs=WMuntX/i>(Xfek2YctCVf]tXK\!PlPN_?e&t`5T^8`lH.!aT'B^ +b5KN`bl5lacMc)dd.G`_dehMheG[qsf)4/!f`0Y'gAfq-h#6%1hV[5ii;_a9ir.m=jQ5M&joOZ/ +rosIJ!:0XNs6TgSrpTmVs7-*Zs766_rUp3as7cHdrqZQiqYU3gqu,IPJcC<$VuM8~> +JcC<$JcC<$rVu0^q>L0fo_\L]qYBdYr:g-_q=XaZrq$'Yrpg$XrU9dS!:BaO!pf.:roj[OkND!i +jlPS&irS/urnmh7hYu=3gtVh^!SQ-)f)aIQrmUttdf.YociDDkc2u87bl5fcaoKQ^aT'<\`r3mV +`;daQ_Z.IO_#1tI^AbhD]`5VC])9,=\Gs&:[f%(rS%;+s4mS/s5*e5ro!h8!94" +JcC<$JcC<$rVu0^q>L0fo_\L]qYBdYr:g-_q=XaZrq$'Yrpg$XrU9dS!:BaO!pf.:roj[OkND!i +jlPS&irS/urnmh7hYu=3gtVh^!SQ-)f)aIQrmUttdf.YociDDkc2u87bl5fcaoKQ^aT'<\`r3mV +`;daQ_Z.IO_#1tI^AbhD]`5VC])9,=\Gs&:[f%(rS%;+s4mS/s5*e5ro!h8!94" +JcC<$JcC<$rVu0^q>L0fo_\L]qYBdYr:g-_q=XaZrq$'Yrpg$XrU9dS!:BaO!pf.:roj[OkND!i +jlPS&irS/urnmh7hYu=3gtVh^!SQ-)f)aIQrmUttdf.YociDDkc2u87bl5fcaoKQ^aT'<\`r3mV +`;daQ_Z.IO_#1tI^AbhD]`5VC])9,=\Gs&:[f%(rS%;+s4mS/s5*e5ro!h8!94" +JcC<$JcC<$qu>s\qYg6foDAC\qYBdYr:g0`q=XaZrq$'Ys7--YrU9dSs6]gP!pf.:rojLJkNDj, +!TiDAirS/urnmh7hYu=3gtVh^!SQ-)f*BmWe^W*te'e6C!mo9>rltSibfp(0s2k>`rQ,#Zs2OuU +s2=rTr5/HLs1nNHs1\KGr4N'Arjr'=s1&*ldci2;edJMAge+;)eec"(qfDaG%g&9Y(g]-(-h>c=3hu2L5i;hm9ir\<'jo4BDkNM./klU/9 +li-5PmI'EAn,MkWnbr"[oCV\Rp&Facp\agcq>U6equ-HirT4$0s+13Cs*t~> +JcC<$JcC<$qu>s\qYg6foDAC\qYBdYr:g0`q=XaZrq$'Ys7--YrU9dSs6]gP!pf.:rojLJkNDj, +!TiDAirS/urnmh7hYu=3gtVh^!SQ-)f*BmWe^W*te'e6C!mo9>rltSibfp(0s2k>`rQ,#Zs2OuU +s2=rTr5/HLs1nNHs1\KGr4N'Arjr'=s1&*ldci2;edJMAge+;)eec"(qfDaG%g&9Y(g]-(-h>c=3hu2L5i;hm9ir\<'jo4BDkNM./klU/9 +li-5PmI'EAn,MkWnbr"[oCV\Rp&Facp\agcq>U6equ-HirT4$0s+13Cs*t~> +JcC<$JcC<$qu>s\qYg6foDAC\qYBdYr:g0`q=XaZrq$'Ys7--YrU9dSs6]gP!pf.:rojLJkNDj, +!TiDAirS/urnmh7hYu=3gtVh^!SQ-)f*BmWe^W*te'e6C!mo9>rltSibfp(0s2k>`rQ,#Zs2OuU +s2=rTr5/HLs1nNHs1\KGr4N'Arjr'=s1&*ldci2;edJMAge+;)eec"(qfDaG%g&9Y(g]-(-h>c=3hu2L5i;hm9ir\<'jo4BDkNM./klU/9 +li-5PmI'EAn,MkWnbr"[oCV\Rp&Facp\agcq>U6equ-HirT4$0s+13Cs*t~> +JcC<$JcC<$q>]d[q>L-eo)&:[qYBdYr:g0`qXsj[rq$*Zs7-*XrpTmTs6]gPs6B[MrosIH!9a@D +!TiDAirS/urnnCGhVR)EgtUT;g=b-2f@SU)ec+&!e'e6Cs3Lblrm(Pgs31Jcs2tA`rQ,#Zs2P#V +rl"iSr5/HLrkSHHrkAEGr4N$@s180>s1&*Hsss/Q+"!3H1% +!NrX*YQ;#7rj)d8[C3NQ\Gj#B]">Vf]tXK\!PlPN_?%Qmrl"oXa8X0[aT0K^bQ#cdc2>leci2;f +dJ_Mke+2#bebn"nfDaG%g&0S'g]-(-h>c@3hu2I7iSrkrj8\3?jo4BDkNM./klU/9li-8Nm/ZSR +n,MnWnc&+ZoDeI]p&Facp\agdq>U6equ$BirT4$0s+13Bs*t~> +JcC<$JcC<$q>]d[q>L-eo)&:[qYBdYr:g0`qXsj[rq$*Zs7-*XrpTmTs6]gPs6B[MrosIH!9a@D +!TiDAirS/urnnCGhVR)EgtUT;g=b-2f@SU)ec+&!e'e6Cs3Lblrm(Pgs31Jcs2tA`rQ,#Zs2P#V +rl"iSr5/HLrkSHHrkAEGr4N$@s180>s1&*Hsss/Q+"!3H1% +!NrX*YQ;#7rj)d8[C3NQ\Gj#B]">Vf]tXK\!PlPN_?%Qmrl"oXa8X0[aT0K^bQ#cdc2>leci2;f +dJ_Mke+2#bebn"nfDaG%g&0S'g]-(-h>c@3hu2I7iSrkrj8\3?jo4BDkNM./klU/9li-8Nm/ZSR +n,MnWnc&+ZoDeI]p&Facp\agdq>U6equ$BirT4$0s+13Bs*t~> +JcC<$JcC<$q>]d[q>L-eo)&:[qYBdYr:g0`qXsj[rq$*Zs7-*XrpTmTs6]gPs6B[MrosIH!9a@D +!TiDAirS/urnnCGhVR)EgtUT;g=b-2f@SU)ec+&!e'e6Cs3Lblrm(Pgs31Jcs2tA`rQ,#Zs2P#V +rl"iSr5/HLrkSHHrkAEGr4N$@s180>s1&*Hsss/Q+"!3H1% +!NrX*YQ;#7rj)d8[C3NQ\Gj#B]">Vf]tXK\!PlPN_?%Qmrl"oXa8X0[aT0K^bQ#cdc2>leci2;f +dJ_Mke+2#bebn"nfDaG%g&0S'g]-(-h>c@3hu2I7iSrkrj8\3?jo4BDkNM./klU/9li-8Nm/ZSR +n,MnWnc&+ZoDeI]p&Facp\agdq>U6equ$BirT4$0s+13Bs*t~> +JcC<$JcC<$q#BXYq>L-eo)&7ZqYBgZr:g0`qt9s\rq$'Ys7--YrpTmTs6]gPs6B[MrosIH!9a@D +!TiDAit:;0iS`YOhVR)EgtUT;g=b03rmq2%ec+&"e'c\Dd/q\@ci25ic2Z#ebQ#`bao0<[a8a0W +`W*mU_u%=N_>_7J^](tI^&5PC]DoJ@\c92>\,E`:[C!=?Zi@?2Z2Us/YHG&-XTGT)X8]+#WMlcp +VZN`lV>d:jUB%%eU&UecTDbA]Sc>5XS,SlTRJE6GQg9t#Q2?gEPPC=>Oo:C;O8P%7NUVo(NW"n6 +O8k=@Oo1CBPQ-mFQ2d0MQi*6NRJrZQS,JlVSbJ`MTB`*@U&C_bU\pqfV>mFkVuN^qWW&nLX/rD) +Xfeh1YctC;ZEpmE[C*HO\%&uZ]"5Md]Y2%o^VIY$_SX4/`5T^8a2e2#!m/U-rlYAec-?44s3L\k +r6bJkrR:Jiq:5;lpXfArrRq)%s4dP.rS@M1s53e5s5F";ro=%>s5j7B!pAe2rosIJ!:0XNs6]jS +rpKpXnaZSK!qZ'VrUp3as7cHdrqZQiqYU6hqu,[VJcC<$T)X<~> +JcC<$JcC<$q#BXYq>L-eo)&7ZqYBgZr:g0`qt9s\rq$'Ys7--YrpTmTs6]gPs6B[MrosIH!9a@D +!TiDAit:;0iS`YOhVR)EgtUT;g=b03rmq2%ec+&"e'c\Dd/q\@ci25ic2Z#ebQ#`bao0<[a8a0W +`W*mU_u%=N_>_7J^](tI^&5PC]DoJ@\c92>\,E`:[C!=?Zi@?2Z2Us/YHG&-XTGT)X8]+#WMlcp +VZN`lV>d:jUB%%eU&UecTDbA]Sc>5XS,SlTRJE6GQg9t#Q2?gEPPC=>Oo:C;O8P%7NUVo(NW"n6 +O8k=@Oo1CBPQ-mFQ2d0MQi*6NRJrZQS,JlVSbJ`MTB`*@U&C_bU\pqfV>mFkVuN^qWW&nLX/rD) +Xfeh1YctC;ZEpmE[C*HO\%&uZ]"5Md]Y2%o^VIY$_SX4/`5T^8a2e2#!m/U-rlYAec-?44s3L\k +r6bJkrR:Jiq:5;lpXfArrRq)%s4dP.rS@M1s53e5s5F";ro=%>s5j7B!pAe2rosIJ!:0XNs6]jS +rpKpXnaZSK!qZ'VrUp3as7cHdrqZQiqYU6hqu,[VJcC<$T)X<~> +JcC<$JcC<$q#BXYq>L-eo)&7ZqYBgZr:g0`qt9s\rq$'Ys7--YrpTmTs6]gPs6B[MrosIH!9a@D +!TiDAit:;0iS`YOhVR)EgtUT;g=b03rmq2%ec+&"e'c\Dd/q\@ci25ic2Z#ebQ#`bao0<[a8a0W +`W*mU_u%=N_>_7J^](tI^&5PC]DoJ@\c92>\,E`:[C!=?Zi@?2Z2Us/YHG&-XTGT)X8]+#WMlcp +VZN`lV>d:jUB%%eU&UecTDbA]Sc>5XS,SlTRJE6GQg9t#Q2?gEPPC=>Oo:C;O8P%7NUVo(NW"n6 +O8k=@Oo1CBPQ-mFQ2d0MQi*6NRJrZQS,JlVSbJ`MTB`*@U&C_bU\pqfV>mFkVuN^qWW&nLX/rD) +Xfeh1YctC;ZEpmE[C*HO\%&uZ]"5Md]Y2%o^VIY$_SX4/`5T^8a2e2#!m/U-rlYAec-?44s3L\k +r6bJkrR:Jiq:5;lpXfArrRq)%s4dP.rS@M1s53e5s5F";ro=%>s5j7B!pAe2rosIJ!:0XNs6]jS +rpKpXnaZSK!qZ'VrUp3as7cHdrqZQiqYU6hqu,[VJcC<$T)X<~> +JcC<$JcC<$pAaFWq>L-enb`.YqYBgZrV-9aqt9s\s7?0Zs7--YrU0gUmHso>s6B[MrosIH!9a@D +!TiDAisar+iS`YOhqm2Fgt^Z`g&]mZrmq5&e^aZK!n5TGrm:eocd2U9s3:SfrQG5`s2k5\rl>&Y +qo/TRrknWMs2"]Mr4i6Fs1SBDrk&3Arji'=s0r!9s0_m6rj2X1!3uO-s/uF*riQ4%!3?+!s/?!s +rhodn!2]Xi!i)KarLs7as.B7]s.0.Zqj[PQrL*/BjHoY-p6GQ?rKI&?rfR,?pQ,*0qMk91q2bN: +rfR,ArfdAHr0@;Js-NYNs-`nUr1!\UrginWr1EhYhkBn@rM04bs/#^lrMT[o!3,ps!irE(riH4( +YPta1Z*L[AZa@.>[KX.M\[f;`rk&TO^;%Fu_84"*_o2Pn!QN1ZaT'?^b5TTabQ,odcMu5jd/;;j +df._jeG@_kf(7Mlf_jG"gA]k+h#-".hZ)L3i;_d9ir8! +JcC<$JcC<$pAaFWq>L-enb`.YqYBgZrV-9aqt9s\s7?0Zs7--YrU0gUmHso>s6B[MrosIH!9a@D +!TiDAisar+iS`YOhqm2Fgt^Z`g&]mZrmq5&e^aZK!n5TGrm:eocd2U9s3:SfrQG5`s2k5\rl>&Y +qo/TRrknWMs2"]Mr4i6Fs1SBDrk&3Arji'=s0r!9s0_m6rj2X1!3uO-s/uF*riQ4%!3?+!s/?!s +rhodn!2]Xi!i)KarLs7as.B7]s.0.Zqj[PQrL*/BjHoY-p6GQ?rKI&?rfR,?pQ,*0qMk91q2bN: +rfR,ArfdAHr0@;Js-NYNs-`nUr1!\UrginWr1EhYhkBn@rM04bs/#^lrMT[o!3,ps!irE(riH4( +YPta1Z*L[AZa@.>[KX.M\[f;`rk&TO^;%Fu_84"*_o2Pn!QN1ZaT'?^b5TTabQ,odcMu5jd/;;j +df._jeG@_kf(7Mlf_jG"gA]k+h#-".hZ)L3i;_d9ir8! +JcC<$JcC<$pAaFWq>L-enb`.YqYBgZrV-9aqt9s\s7?0Zs7--YrU0gUmHso>s6B[MrosIH!9a@D +!TiDAisar+iS`YOhqm2Fgt^Z`g&]mZrmq5&e^aZK!n5TGrm:eocd2U9s3:SfrQG5`s2k5\rl>&Y +qo/TRrknWMs2"]Mr4i6Fs1SBDrk&3Arji'=s0r!9s0_m6rj2X1!3uO-s/uF*riQ4%!3?+!s/?!s +rhodn!2]Xi!i)KarLs7as.B7]s.0.Zqj[PQrL*/BjHoY-p6GQ?rKI&?rfR,?pQ,*0qMk91q2bN: +rfR,ArfdAHr0@;Js-NYNs-`nUr1!\UrginWr1EhYhkBn@rM04bs/#^lrMT[o!3,ps!irE(riH4( +YPta1Z*L[AZa@.>[KX.M\[f;`rk&TO^;%Fu_84"*_o2Pn!QN1ZaT'?^b5TTabQ,odcMu5jd/;;j +df._jeG@_kf(7Mlf_jG"gA]k+h#-".hZ)L3i;_d9ir8! +JcC<$JcC<$pAaCVq#1$dnGE%XqYBj[rV-s6B[MrosIH!9a@D +!TiDAis4T&iS`YOhqn@g!SlH/g'?<`f[na+f%'cLs3gtrrmCbms3L\is3:SfrQG5`rlP)Zs2Y,Y +r5JZRrknWMs2"]Mr4i9Gs1S?Cs189BrOMsd:jU]7(eU&UecTDY;[Sc5/US,A`MRG!u(Qi*0EQ2QsGPPLC?Oo1=$O8Y1=Oo(=APQ$gF +Q2d0LQi3mFjVuN^qWVrguX/rE%XTu#4YHY79Z*OA8 +'=>0U[^WcV\[f;`]Y(qk^;%Fu_>_:U_o0O5`l?'ua8sE*rlb>c!6tJf!mf6?r6bPmrmU_nr71\q +n^mWir7Uo"rnIG-qq_;/s53e5s5F";rT!q=!9O1A!pAe2rosIJs6K[N!q#FDrpTmVs7-*Zs7?9_ +rUp3as7cHds7uZjqYU6hqu,j[JcC<$QiDR~> +JcC<$JcC<$pAaCVq#1$dnGE%XqYBj[rV-s6B[MrosIH!9a@D +!TiDAis4T&iS`YOhqn@g!SlH/g'?<`f[na+f%'cLs3gtrrmCbms3L\is3:SfrQG5`rlP)Zs2Y,Y +r5JZRrknWMs2"]Mr4i9Gs1S?Cs189BrOMsd:jU]7(eU&UecTDY;[Sc5/US,A`MRG!u(Qi*0EQ2QsGPPLC?Oo1=$O8Y1=Oo(=APQ$gF +Q2d0LQi3mFjVuN^qWVrguX/rE%XTu#4YHY79Z*OA8 +'=>0U[^WcV\[f;`]Y(qk^;%Fu_>_:U_o0O5`l?'ua8sE*rlb>c!6tJf!mf6?r6bPmrmU_nr71\q +n^mWir7Uo"rnIG-qq_;/s53e5s5F";rT!q=!9O1A!pAe2rosIJs6K[N!q#FDrpTmVs7-*Zs7?9_ +rUp3as7cHds7uZjqYU6hqu,j[JcC<$QiDR~> +JcC<$JcC<$pAaCVq#1$dnGE%XqYBj[rV-s6B[MrosIH!9a@D +!TiDAis4T&iS`YOhqn@g!SlH/g'?<`f[na+f%'cLs3gtrrmCbms3L\is3:SfrQG5`rlP)Zs2Y,Y +r5JZRrknWMs2"]Mr4i9Gs1S?Cs189BrOMsd:jU]7(eU&UecTDY;[Sc5/US,A`MRG!u(Qi*0EQ2QsGPPLC?Oo1=$O8Y1=Oo(=APQ$gF +Q2d0LQi3mFjVuN^qWVrguX/rE%XTu#4YHY79Z*OA8 +'=>0U[^WcV\[f;`]Y(qk^;%Fu_>_:U_o0O5`l?'ua8sE*rlb>c!6tJf!mf6?r6bPmrmU_nr71\q +n^mWir7Uo"rnIG-qq_;/s53e5s5F";rT!q=!9O1A!pAe2rosIJs6K[N!q#FDrpTmVs7-*Zs7?9_ +rUp3as7cHds7uZjqYU6hqu,j[JcC<$QiDR~> +JcC<$JcC<$p&F:Uq#1!cn,)qWqt]s\rV-\,a#:[KaMrpp*\ +s7H9_s7ZKer:p9erqcNhr;?KkmJ_\:JcCu7J,~> +JcC<$JcC<$p&F:Uq#1!cn,)qWqt]s\rV-\,a#:[KaMrpp*\ +s7H9_s7ZKer:p9erqcNhr;?KkmJ_\:JcCu7J,~> +JcC<$JcC<$p&F:Uq#1!cn,)qWqt]s\rV-\,a#:[KaMrpp*\ +s7H9_s7ZKer:p9erqcNhr;?KkmJ_\:JcCu7J,~> +JcC<$JcC<$oDe(Sp\jmbn,)qWqt^!]rV-+P5^[EPl-gGQN*jdJqYpe,7_pec"(nfD=.p +g%3qrg\oq(h>Z:2hu)F4iW%p9j8\3?jo+U6fqu$BirUBf;s+133s*t~> +JcC<$JcC<$oDe(Sp\jmbn,)qWqt^!]rV-+P5^[EPl-gGQN*jdJqYpe,7_pec"(nfD=.p +g%3qrg\oq(h>Z:2hu)F4iW%p9j8\3?jo+U6fqu$BirUBf;s+133s*t~> +JcC<$JcC<$oDe(Sp\jmbn,)qWqt^!]rV-+P5^[EPl-gGQN*jdJqYpe,7_pec"(nfD=.p +g%3qrg\oq(h>Z:2hu)F4iW%p9j8\3?jo+U6fqu$BirUBf;s+133s*t~> +JcC<$JcC<$oDe"Qp\jjan,)tXqt^!]rqHEcqt:!]rq$*Zs7$*YrU9dS!:BdPs6B[MrosIH!9a@D +#Nb%-j5].YiVqa?hqm5Gh;$f?rn7G,f\$2Ts4.2#rm^tss3gkns3UelrQbGfs31A`s2t>_qoJcW +rl4iSrl"iSr5/KMrkSKIs1\NHrk/9Cs183?s0r'Ql^[+,r0mPOq3_,IrKd;Fr07,Ck*#Y+rfm;Frg*SNr0[MP +s-inUrga"ZrLX"\rh01_rM':doq_&Qn##fVri#gqr2Tass/c4%s/uC*ricF.ZMq0<['ddc2Q#gcN)>jdJqYpe,@eqec+.rfDF4sg$dYl +g\oq'h>Z:1hu)F4iW%p8j8\3?jo4EBkPscFl2U&Kli-8NmJlVRn,MkWnbr%YoDeI]p&Facp\agd +q>U6equ-HkrUBf;s+131s*t~> +JcC<$JcC<$oDe"Qp\jjan,)tXqt^!]rqHEcqt:!]rq$*Zs7$*YrU9dS!:BdPs6B[MrosIH!9a@D +#Nb%-j5].YiVqa?hqm5Gh;$f?rn7G,f\$2Ts4.2#rm^tss3gkns3UelrQbGfs31A`s2t>_qoJcW +rl4iSrl"iSr5/KMrkSKIs1\NHrk/9Cs183?s0r'Ql^[+,r0mPOq3_,IrKd;Fr07,Ck*#Y+rfm;Frg*SNr0[MP +s-inUrga"ZrLX"\rh01_rM':doq_&Qn##fVri#gqr2Tass/c4%s/uC*ricF.ZMq0<['ddc2Q#gcN)>jdJqYpe,@eqec+.rfDF4sg$dYl +g\oq'h>Z:1hu)F4iW%p8j8\3?jo4EBkPscFl2U&Kli-8NmJlVRn,MkWnbr%YoDeI]p&Facp\agd +q>U6equ-HkrUBf;s+131s*t~> +JcC<$JcC<$oDe"Qp\jjan,)tXqt^!]rqHEcqt:!]rq$*Zs7$*YrU9dS!:BdPs6B[MrosIH!9a@D +#Nb%-j5].YiVqa?hqm5Gh;$f?rn7G,f\$2Ts4.2#rm^tss3gkns3UelrQbGfs31A`s2t>_qoJcW +rl4iSrl"iSr5/KMrkSKIs1\NHrk/9Cs183?s0r'Ql^[+,r0mPOq3_,IrKd;Fr07,Ck*#Y+rfm;Frg*SNr0[MP +s-inUrga"ZrLX"\rh01_rM':doq_&Qn##fVri#gqr2Tass/c4%s/uC*ricF.ZMq0<['ddc2Q#gcN)>jdJqYpe,@eqec+.rfDF4sg$dYl +g\oq'h>Z:1hu)F4iW%p8j8\3?jo4EBkPscFl2U&Kli-8NmJlVRn,MkWnbr%YoDeI]p&Facp\agd +q>U6equ-HkrUBf;s+131s*t~> +JcC<$JcC<$nc.bNp\jg`n,)tXr;$-_rqHEcr:U']s7?3[s7--YrpTmT!:BdPs6B[MrosIH!9a@D +!p/M(ro4%=iVqa:hqm5hh#Zerlk;`rlY5^qoJcW +rl4iSs2=oSr5/KMs1nTJs1SKHrOi0B!4r->!k>_KrjDm9[']h=!j])9ricI-Y-.c+!j&H'ri6!t +!3#jos/,gmrM9IgrhB:`rh01]n=J[2pmh)Jr0mSPqO%5JrKd8EqipH2r07#Brg*SNr0[MPrgNeT +s.'(ZrLX%]rh01_rhBCeqP="bq52uGr2BRnql9Xrs/c1$s/uC*ricI/ZEjJ9!OT96[K3kIrj`'@ +]DfGH]tV7r^qp#e&AuH*`Q#p +JcC<$JcC<$nc.bNp\jg`n,)tXr;$-_rqHEcr:U']s7?3[s7--YrpTmT!:BdPs6B[MrosIH!9a@D +!p/M(ro4%=iVqa:hqm5hh#Zerlk;`rlY5^qoJcW +rl4iSs2=oSr5/KMs1nTJs1SKHrOi0B!4r->!k>_KrjDm9[']h=!j])9ricI-Y-.c+!j&H'ri6!t +!3#jos/,gmrM9IgrhB:`rh01]n=J[2pmh)Jr0mSPqO%5JrKd8EqipH2r07#Brg*SNr0[MPrgNeT +s.'(ZrLX%]rh01_rhBCeqP="bq52uGr2BRnql9Xrs/c1$s/uC*ricI/ZEjJ9!OT96[K3kIrj`'@ +]DfGH]tV7r^qp#e&AuH*`Q#p +JcC<$JcC<$nc.bNp\jg`n,)tXr;$-_rqHEcr:U']s7?3[s7--YrpTmT!:BdPs6B[MrosIH!9a@D +!p/M(ro4%=iVqa:hqm5hh#Zerlk;`rlY5^qoJcW +rl4iSs2=oSr5/KMs1nTJs1SKHrOi0B!4r->!k>_KrjDm9[']h=!j])9ricI-Y-.c+!j&H'ri6!t +!3#jos/,gmrM9IgrhB:`rh01]n=J[2pmh)Jr0mSPqO%5JrKd8EqipH2r07#Brg*SNr0[MPrgNeT +s.'(ZrLX%]rh01_rhBCeqP="bq52uGr2BRnql9Xrs/c1$s/uC*ricI/ZEjJ9!OT96[K3kIrj`'@ +]DfGH]tV7r^qp#e&AuH*`Q#p +JcC<$JcC<$nGhYMpAO^_n,)tXr;$0`rqHEcr:U']s7?3[s7--YrpTmT!:BdPs6B[MrosIH!9a@D +!p/M(ro4%=iVqd8hZ2O4h#cBdg]#n.g"=sVfDjG%ec+(ue,RkpdJqSmci)/gc2PrabPoZ`ans0Y +a8X*U`W*mU_u7IP_>h=L^]2"J^&>SF]=PTQ\c9/>\,Ni9[/dT5ZN@G;Z2Us/YHG&-XoGI&X8T%" +WMlcoVuNXoV>R.hU]."aU&:SZT@]\2Sc##QS,SlTRJE6LQi*0BQ1L76Q2[*KQi!0MRK&`RS,]#Y +Sc#)ZTDtS^U&UkdU\gkcV>R4UVsLAYWVWXoX8]3uXoGO(YPk[,Z*L\7ZQ?K][C3NQ\%&uZ]"5Md +]Y2%n^V@S#_SX4.`5T^8a8X-\aiaV+!R/gfcMu2jd/MGmdf7eqeGn(uf)4/!f_sLrgA'Fsh"BM% +hYuF/i;_d8ir%j:jT"??k5XWEkl0iHlMp2Lm/QJQmf)\TnGi%Wo)J=]o_nI_pAambq#C0hqYU0g +r;?N`rdk*#s,?u.~> +JcC<$JcC<$nGhYMpAO^_n,)tXr;$0`rqHEcr:U']s7?3[s7--YrpTmT!:BdPs6B[MrosIH!9a@D +!p/M(ro4%=iVqd8hZ2O4h#cBdg]#n.g"=sVfDjG%ec+(ue,RkpdJqSmci)/gc2PrabPoZ`ans0Y +a8X*U`W*mU_u7IP_>h=L^]2"J^&>SF]=PTQ\c9/>\,Ni9[/dT5ZN@G;Z2Us/YHG&-XoGI&X8T%" +WMlcoVuNXoV>R.hU]."aU&:SZT@]\2Sc##QS,SlTRJE6LQi*0BQ1L76Q2[*KQi!0MRK&`RS,]#Y +Sc#)ZTDtS^U&UkdU\gkcV>R4UVsLAYWVWXoX8]3uXoGO(YPk[,Z*L\7ZQ?K][C3NQ\%&uZ]"5Md +]Y2%n^V@S#_SX4.`5T^8a8X-\aiaV+!R/gfcMu2jd/MGmdf7eqeGn(uf)4/!f_sLrgA'Fsh"BM% +hYuF/i;_d8ir%j:jT"??k5XWEkl0iHlMp2Lm/QJQmf)\TnGi%Wo)J=]o_nI_pAambq#C0hqYU0g +r;?N`rdk*#s,?u.~> +JcC<$JcC<$nGhYMpAO^_n,)tXr;$0`rqHEcr:U']s7?3[s7--YrpTmT!:BdPs6B[MrosIH!9a@D +!p/M(ro4%=iVqd8hZ2O4h#cBdg]#n.g"=sVfDjG%ec+(ue,RkpdJqSmci)/gc2PrabPoZ`ans0Y +a8X*U`W*mU_u7IP_>h=L^]2"J^&>SF]=PTQ\c9/>\,Ni9[/dT5ZN@G;Z2Us/YHG&-XoGI&X8T%" +WMlcoVuNXoV>R.hU]."aU&:SZT@]\2Sc##QS,SlTRJE6LQi*0BQ1L76Q2[*KQi!0MRK&`RS,]#Y +Sc#)ZTDtS^U&UkdU\gkcV>R4UVsLAYWVWXoX8]3uXoGO(YPk[,Z*L\7ZQ?K][C3NQ\%&uZ]"5Md +]Y2%n^V@S#_SX4.`5T^8a8X-\aiaV+!R/gfcMu2jd/MGmdf7eqeGn(uf)4/!f_sLrgA'Fsh"BM% +hYuF/i;_d8ir%j:jT"??k5XWEkl0iHlMp2Lm/QJQmf)\TnGi%Wo)J=]o_nI_pAambq#C0hqYU0g +r;?N`rdk*#s,?u.~> +JcC<$JcC<$nGhSKpAO[^n,*"Yr;$0`rqHEcr:U*^s7?3[s7--YrpTmT!:BdPs6B[MrosIH!9a@D +s5a7Aro47CiSi_Qhr!;ih>c71g]#q,g&K_(fDjG%ec+(ue,RkodJqSmchu)fc2PrabPfT_ans0Y +a8a0W`W!gU_u7IP_>h=M^]2%J^&G\E])]GA\c9/>\,Ni9[/dT5Zi@<2Z2V!-Y5ka)XoGL&X8].! +WW/pqVuNXoV>I(fU]."]U%+fd@eVtd4PWUm.gX8]3tXoGR(YPk[,Z*L\7Zi@B4[JmTB\%&rY\[oDb]Y(ql +rkAfU_8=(,`5KX6`lJ)"#0G$2bKS2TrltPjd/MGmdf7eqeGn)!f)4/!f`'S"gA9Ruh!j.thYl@. +i;V^7ir%j:jT"??k5XWEkl'cGlMp2Lm/QJQmf)\TnGi%Wo)J=]o_nI_pAambq#C0hqYL*fr;?Na +rdk*#s,6o-~> +JcC<$JcC<$nGhSKpAO[^n,*"Yr;$0`rqHEcr:U*^s7?3[s7--YrpTmT!:BdPs6B[MrosIH!9a@D +s5a7Aro47CiSi_Qhr!;ih>c71g]#q,g&K_(fDjG%ec+(ue,RkodJqSmchu)fc2PrabPfT_ans0Y +a8a0W`W!gU_u7IP_>h=M^]2%J^&G\E])]GA\c9/>\,Ni9[/dT5Zi@<2Z2V!-Y5ka)XoGL&X8].! +WW/pqVuNXoV>I(fU]."]U%+fd@eVtd4PWUm.gX8]3tXoGR(YPk[,Z*L\7Zi@B4[JmTB\%&rY\[oDb]Y(ql +rkAfU_8=(,`5KX6`lJ)"#0G$2bKS2TrltPjd/MGmdf7eqeGn)!f)4/!f`'S"gA9Ruh!j.thYl@. +i;V^7ir%j:jT"??k5XWEkl'cGlMp2Lm/QJQmf)\TnGi%Wo)J=]o_nI_pAambq#C0hqYL*fr;?Na +rdk*#s,6o-~> +JcC<$JcC<$nGhSKpAO[^n,*"Yr;$0`rqHEcr:U*^s7?3[s7--YrpTmT!:BdPs6B[MrosIH!9a@D +s5a7Aro47CiSi_Qhr!;ih>c71g]#q,g&K_(fDjG%ec+(ue,RkodJqSmchu)fc2PrabPfT_ans0Y +a8a0W`W!gU_u7IP_>h=M^]2%J^&G\E])]GA\c9/>\,Ni9[/dT5Zi@<2Z2V!-Y5ka)XoGL&X8].! +WW/pqVuNXoV>I(fU]."]U%+fd@eVtd4PWUm.gX8]3tXoGR(YPk[,Z*L\7Zi@B4[JmTB\%&rY\[oDb]Y(ql +rkAfU_8=(,`5KX6`lJ)"#0G$2bKS2TrltPjd/MGmdf7eqeGn)!f)4/!f`'S"gA9Ruh!j.thYl@. +i;V^7ir%j:jT"??k5XWEkl'cGlMp2Lm/QJQmf)\TnGi%Wo)J=]o_nI_pAambq#C0hqYL*fr;?Na +rdk*#s,6o-~> +JcC<$JcC<$mJl8Hp&4R]nb`4[r;$3arqHEcr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rojIIkPjWD +jT+B@ir\6!iVqa:hqm5hh#cBdg]#q,f`9\'fDjG%ec""te,RkodJqSmchl#ec2Pr`bPoZ`ans0Y +a8a0W`W*mV_u7IP_>h=M^]2"J^&G\E]DoJA\HfXR\$i`Q[C#q>s0;X0rilF+s/u@'!j&H'rMoms +s/>morhf^lqP=(br1_i;pRqDUpn%GTrLE_RrL3\QpmCoEns90>q3_/Ls-ikTrga"ZrLX"\s.K=a +s.]Lfr1s@hrhfOir2BLlfrFqMrN,muriZ:)rNQ=,s0DX1s0Md6rjMj9!4`$=!P5oB]F)?d^V@S" +_8=(,`;[^e`lH0Aai_cLbKS5UcHab^d/MDodaQ\EeGn)!f)=5#f`'S#gATe&h!NqohYZ4+i;V^7 +iqqd9jT"?>k5XWEkl'cGlMp2Lm/QJQmeuSUnF?&Io)J=]o_nI_pAambq#:*gqYU0gr;?N`rdk*# +s,6o-~> +JcC<$JcC<$mJl8Hp&4R]nb`4[r;$3arqHEcr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rojIIkPjWD +jT+B@ir\6!iVqa:hqm5hh#cBdg]#q,f`9\'fDjG%ec""te,RkodJqSmchl#ec2Pr`bPoZ`ans0Y +a8a0W`W*mV_u7IP_>h=M^]2"J^&G\E]DoJA\HfXR\$i`Q[C#q>s0;X0rilF+s/u@'!j&H'rMoms +s/>morhf^lqP=(br1_i;pRqDUpn%GTrLE_RrL3\QpmCoEns90>q3_/Ls-ikTrga"ZrLX"\s.K=a +s.]Lfr1s@hrhfOir2BLlfrFqMrN,muriZ:)rNQ=,s0DX1s0Md6rjMj9!4`$=!P5oB]F)?d^V@S" +_8=(,`;[^e`lH0Aai_cLbKS5UcHab^d/MDodaQ\EeGn)!f)=5#f`'S#gATe&h!NqohYZ4+i;V^7 +iqqd9jT"?>k5XWEkl'cGlMp2Lm/QJQmeuSUnF?&Io)J=]o_nI_pAambq#:*gqYU0gr;?N`rdk*# +s,6o-~> +JcC<$JcC<$mJl8Hp&4R]nb`4[r;$3arqHEcr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rojIIkPjWD +jT+B@ir\6!iVqa:hqm5hh#cBdg]#q,f`9\'fDjG%ec""te,RkodJqSmchl#ec2Pr`bPoZ`ans0Y +a8a0W`W*mV_u7IP_>h=M^]2"J^&G\E]DoJA\HfXR\$i`Q[C#q>s0;X0rilF+s/u@'!j&H'rMoms +s/>morhf^lqP=(br1_i;pRqDUpn%GTrLE_RrL3\QpmCoEns90>q3_/Ls-ikTrga"ZrLX"\s.K=a +s.]Lfr1s@hrhfOir2BLlfrFqMrN,muriZ:)rNQ=,s0DX1s0Md6rjMj9!4`$=!P5oB]F)?d^V@S" +_8=(,`;[^e`lH0Aai_cLbKS5UcHab^d/MDodaQ\EeGn)!f)=5#f`'S#gATe&h!NqohYZ4+i;V^7 +iqqd9jT"?>k5XWEkl'cGlMp2Lm/QJQmeuSUnF?&Io)J=]o_nI_pAambq#:*gqYU0gr;?N`rdk*# +s,6o-~> +JcC<$JcC<$m/Q,Fo_nL]nb`4[rV?dc2Puncd:%ddF-Ilrm^tus47/#s4IA)qqD&(r7pl!p>5W&pYc#/rSmb8roF(? +rT=.Cs60CFs69UMrTsROs6fjSs6p$YrUU![s7H9_rq?Bdr:p +JcC<$JcC<$m/Q,Fo_nL]nb`4[rV?dc2Puncd:%ddF-Ilrm^tus47/#s4IA)qqD&(r7pl!p>5W&pYc#/rSmb8roF(? +rT=.Cs60CFs69UMrTsROs6fjSs6p$YrUU![s7H9_rq?Bdr:p +JcC<$JcC<$m/Q,Fo_nL]nb`4[rV?dc2Puncd:%ddF-Ilrm^tus47/#s4IA)qqD&(r7pl!p>5W&pYc#/rSmb8roF(? +rT=.Cs60CFs69UMrTsROs6fjSs6p$YrUU![s7H9_rq?Bdr:p +JcC<$JcC<$lMolCo_nI\o)&@]rV?h=M^B2-_^&G\E])]GA\H9:M\,Nf;[C!=?ZN@G;Z2V!-Y5ka(XoGL&X8T'u +WW&joVuU\UYXU&CY_TDG/YSc,)SS,A`PRIHU@RJiTOS,SrXSc#)ZTDtS^U&UkeU]%"f +V>mFjVuEXoWVNRkX7NFNXo,@$YPYR(Z2_-.Zi@E4[JmT9\%&sI\H0:Rrk&9F^AbkJ^qp#e"iJ9t +`Q#sta8sE*rlY>dc2Puhcd;[=!n,QHrmV#"f%0fOs4IA)r7_/)rnR8(ptk]$oAKQ*rSm_7roF(? +r9"%Bs60FGs6BXMrTsROs6fjSs7$'YrUU![s7H9_s7ZKer:p9erqcNhrVZTlnc"+>JcCW-J,~> +JcC<$JcC<$lMolCo_nI\o)&@]rV?h=M^B2-_^&G\E])]GA\H9:M\,Nf;[C!=?ZN@G;Z2V!-Y5ka(XoGL&X8T'u +WW&joVuU\UYXU&CY_TDG/YSc,)SS,A`PRIHU@RJiTOS,SrXSc#)ZTDtS^U&UkeU]%"f +V>mFjVuEXoWVNRkX7NFNXo,@$YPYR(Z2_-.Zi@E4[JmT9\%&sI\H0:Rrk&9F^AbkJ^qp#e"iJ9t +`Q#sta8sE*rlY>dc2Puhcd;[=!n,QHrmV#"f%0fOs4IA)r7_/)rnR8(ptk]$oAKQ*rSm_7roF(? +r9"%Bs60FGs6BXMrTsROs6fjSs7$'YrUU![s7H9_s7ZKer:p9erqcNhrVZTlnc"+>JcCW-J,~> +JcC<$JcC<$lMolCo_nI\o)&@]rV?h=M^B2-_^&G\E])]GA\H9:M\,Nf;[C!=?ZN@G;Z2V!-Y5ka(XoGL&X8T'u +WW&joVuU\UYXU&CY_TDG/YSc,)SS,A`PRIHU@RJiTOS,SrXSc#)ZTDtS^U&UkeU]%"f +V>mFjVuEXoWVNRkX7NFNXo,@$YPYR(Z2_-.Zi@E4[JmT9\%&sI\H0:Rrk&9F^AbkJ^qp#e"iJ9t +`Q#sta8sE*rlY>dc2Puhcd;[=!n,QHrmV#"f%0fOs4IA)r7_/)rnR8(ptk]$oAKQ*rSm_7roF(? +r9"%Bs60FGs6BXMrTsROs6fjSs7$'YrUU![s7H9_s7ZKer:p9erqcNhrVZTlnc"+>JcCW-J,~> +JcC<$JcC<$kl9W@oDSC\o_\R_rV?iSjdo!oMkkrn[V0s4dP,s4RG)rR_)#rmgqrs3ptqqU,;hrm1GdrQY>cqoeu]s2k2[ +s2Y/ZrPefT!5ncP!l;[frkJKI!58BEs189Brji'=!4Vs9s0Vj6rj2X1!3uL,!jAc0rN6+$s/Z't +s/H!rqPX7gq5)W;qkO(`q4[b[rh'%YrLNnWpRCoGrgEMLpm_8QrgitYs.B=ar1X.bs.fOgs/#^l +rMTXnri,dprN#jtfrb(Qr3,t$riuI.rNlO2s0_j7s0i!WcHjkadF$Cje,IkseH"2!fDjJ'g&0S'g]-()h>?((hsB:uiVhd3j8S-=jo"9@ +kPj]Dl2U&Kli$2MmJlVQn,MnWnbr%YoDeI]p&Fabp\jmdq>U6equ-HjrUTr=s+13,s*t~> +JcC<$JcC<$kl9W@oDSC\o_\R_rV?iSjdo!oMkkrn[V0s4dP,s4RG)rR_)#rmgqrs3ptqqU,;hrm1GdrQY>cqoeu]s2k2[ +s2Y/ZrPefT!5ncP!l;[frkJKI!58BEs189Brji'=!4Vs9s0Vj6rj2X1!3uL,!jAc0rN6+$s/Z't +s/H!rqPX7gq5)W;qkO(`q4[b[rh'%YrLNnWpRCoGrgEMLpm_8QrgitYs.B=ar1X.bs.fOgs/#^l +rMTXnri,dprN#jtfrb(Qr3,t$riuI.rNlO2s0_j7s0i!WcHjkadF$Cje,IkseH"2!fDjJ'g&0S'g]-()h>?((hsB:uiVhd3j8S-=jo"9@ +kPj]Dl2U&Kli$2MmJlVQn,MnWnbr%YoDeI]p&Fabp\jmdq>U6equ-HjrUTr=s+13,s*t~> +JcC<$JcC<$kl9W@oDSC\o_\R_rV?iSjdo!oMkkrn[V0s4dP,s4RG)rR_)#rmgqrs3ptqqU,;hrm1GdrQY>cqoeu]s2k2[ +s2Y/ZrPefT!5ncP!l;[frkJKI!58BEs189Brji'=!4Vs9s0Vj6rj2X1!3uL,!jAc0rN6+$s/Z't +s/H!rqPX7gq5)W;qkO(`q4[b[rh'%YrLNnWpRCoGrgEMLpm_8QrgitYs.B=ar1X.bs.fOgs/#^l +rMTXnri,dprN#jtfrb(Qr3,t$riuI.rNlO2s0_j7s0i!WcHjkadF$Cje,IkseH"2!fDjJ'g&0S'g]-()h>?((hsB:uiVhd3j8S-=jo"9@ +kPj]Dl2U&Kli$2MmJlVQn,MnWnbr%YoDeI]p&Fabp\jmdq>U6equ-HjrUTr=s+13,s*t~> +JcC<$JcC<$kPsH=oDSF]o_\R_rV??crqHHdr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rojLJkNDj, +!p/M(ro4(>iSjdos5*h5rS@M/!8IJ+s4RG)r7Cu"s4."rrmUkpqU,;hrQk>crltGdr6,)^s2k2[ +s2Y/Zrl+oUs24iQs1n]NrkJKI!58BEs189Brji'=!4Vs9s0Vj6rj2X1s0;R-s0)I*rN6+$s/Z't +ri,jppS[Y\iMH1Br1j4bqP!n]rL`qXrLNkVjI?+)rnIJ.qq_2,r86l!pYl#/puDA7roO%>s6'CFrTX=H +s6KXMs6]jSrU9dUs7-'Ys7?9_rUp3arqH?cs7uZjqYU6hr;H0bJcC<$M>r)~> +JcC<$JcC<$kPsH=oDSF]o_\R_rV??crqHHdr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rojLJkNDj, +!p/M(ro4(>iSjdos5*h5rS@M/!8IJ+s4RG)r7Cu"s4."rrmUkpqU,;hrQk>crltGdr6,)^s2k2[ +s2Y/Zrl+oUs24iQs1n]NrkJKI!58BEs189Brji'=!4Vs9s0Vj6rj2X1s0;R-s0)I*rN6+$s/Z't +ri,jppS[Y\iMH1Br1j4bqP!n]rL`qXrLNkVjI?+)rnIJ.qq_2,r86l!pYl#/puDA7roO%>s6'CFrTX=H +s6KXMs6]jSrU9dUs7-'Ys7?9_rUp3arqH?cs7uZjqYU6hr;H0bJcC<$M>r)~> +JcC<$JcC<$kPsH=oDSF]o_\R_rV??crqHHdr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rojLJkNDj, +!p/M(ro4(>iSjdos5*h5rS@M/!8IJ+s4RG)r7Cu"s4."rrmUkpqU,;hrQk>crltGdr6,)^s2k2[ +s2Y/Zrl+oUs24iQs1n]NrkJKI!58BEs189Brji'=!4Vs9s0Vj6rj2X1s0;R-s0)I*rN6+$s/Z't +ri,jppS[Y\iMH1Br1j4bqP!n]rL`qXrLNkVjI?+)rnIJ.qq_2,r86l!pYl#/puDA7roO%>s6'CFrTX=H +s6KXMs6]jSrU9dUs7-'Ys7?9_rUp3arqH?cs7uZjqYU6hr;H0bJcC<$M>r)~> +JcC<$JcC<$jo=3:oDSF]p&"^arV??crqHHdr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rojLJkNDj, +!p/M(ro=%\,E`:[C!=?Zi@<2Z2Lp,YQ(d(XoGL%X8Apq +WVi^FVtd.dV>-kbU]."aU&CY`TD5#USbJZQS+iHOSberWTDtS^U&UkdU]%"gV>mFkVuEXpWVidq +X8]3sXo,?uYL]rVZ2M!*Zi7?3[JdQ6[fEr:\Hf^X]=bei]tXK\!PlPN_@OQ&`Poj:a2l?Db0%oN +bg$.4!RK-ld/h\Erm^tu!7q/$s4IA)rn@D,rnRG-rndV2oAK9"pYto,rT*q=qr[n@s60CFs6BXM +r9XINs6fjSs7$'YrUU![s7H9_rq?Bdr:p9erqcNhrVZTlnc"+>JcCQ+J,~> +JcC<$JcC<$jo=3:oDSF]p&"^arV??crqHHdr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rojLJkNDj, +!p/M(ro=%\,E`:[C!=?Zi@<2Z2Lp,YQ(d(XoGL%X8Apq +WVi^FVtd.dV>-kbU]."aU&CY`TD5#USbJZQS+iHOSberWTDtS^U&UkdU]%"gV>mFkVuEXpWVidq +X8]3sXo,?uYL]rVZ2M!*Zi7?3[JdQ6[fEr:\Hf^X]=bei]tXK\!PlPN_@OQ&`Poj:a2l?Db0%oN +bg$.4!RK-ld/h\Erm^tu!7q/$s4IA)rn@D,rnRG-rndV2oAK9"pYto,rT*q=qr[n@s60CFs6BXM +r9XINs6fjSs7$'YrUU![s7H9_rq?Bdr:p9erqcNhrVZTlnc"+>JcCQ+J,~> +JcC<$JcC<$jo=3:oDSF]p&"^arV??crqHHdr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rojLJkNDj, +!p/M(ro=%\,E`:[C!=?Zi@<2Z2Lp,YQ(d(XoGL%X8Apq +WVi^FVtd.dV>-kbU]."aU&CY`TD5#USbJZQS+iHOSberWTDtS^U&UkdU]%"gV>mFkVuEXpWVidq +X8]3sXo,?uYL]rVZ2M!*Zi7?3[JdQ6[fEr:\Hf^X]=bei]tXK\!PlPN_@OQ&`Poj:a2l?Db0%oN +bg$.4!RK-ld/h\Erm^tu!7q/$s4IA)rn@D,rnRG-rndV2oAK9"pYto,rT*q=qr[n@s60CFs6BXM +r9XINs6fjSs7$'YrUU![s7H9_rq?Bdr:p9erqcNhrVZTlnc"+>JcCQ+J,~> +JcC<$JcC<$jT"$7oDSI^pA=gbrV??crqHHdr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rojLJkNDj, +s5a7Aro=%(r7Cr!rmgkprmUhoq9f2grm1JerltGdrQG2_s2k8] +s2Y/Zrl+oUs24iQ!l;[frkANK]tOEX!kZ%Trj`*?\$u@F!k#DBrj2X1s0;O,s0)I*r2p"#ri>jp +qPiGPm&0cYrMB=crhKFdqP!n]rL`eTn"'3Erh'1_r1X.brhKFfs/#amrMTXns/Gssri?(#qlTh" +rNG^pi3E0bqQp1.rjD^5s0r$q^V@S"_8=(,_o0O5`l?'?aN;U(b5oi3rltPj +d/MDndaS3F!nGlQrmq5(g"HAYs4dS/r8%A/rnmM/q;Lr)nDjH-rT3n +JcC<$JcC<$jT"$7oDSI^pA=gbrV??crqHHdr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rojLJkNDj, +s5a7Aro=%(r7Cr!rmgkprmUhoq9f2grm1JerltGdrQG2_s2k8] +s2Y/Zrl+oUs24iQ!l;[frkANK]tOEX!kZ%Trj`*?\$u@F!k#DBrj2X1s0;O,s0)I*r2p"#ri>jp +qPiGPm&0cYrMB=crhKFdqP!n]rL`eTn"'3Erh'1_r1X.brhKFfs/#amrMTXns/Gssri?(#qlTh" +rNG^pi3E0bqQp1.rjD^5s0r$q^V@S"_8=(,_o0O5`l?'?aN;U(b5oi3rltPj +d/MDndaS3F!nGlQrmq5(g"HAYs4dS/r8%A/rnmM/q;Lr)nDjH-rT3n +JcC<$JcC<$jT"$7oDSI^pA=gbrV??crqHHdr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rojLJkNDj, +s5a7Aro=%(r7Cr!rmgkprmUhoq9f2grm1JerltGdrQG2_s2k8] +s2Y/Zrl+oUs24iQ!l;[frkANK]tOEX!kZ%Trj`*?\$u@F!k#DBrj2X1s0;O,s0)I*r2p"#ri>jp +qPiGPm&0cYrMB=crhKFdqP!n]rL`eTn"'3Erh'1_r1X.brhKFfs/#amrMTXns/Gssri?(#qlTh" +rNG^pi3E0bqQp1.rjD^5s0r$q^V@S"_8=(,_o0O5`l?'?aN;U(b5oi3rltPj +d/MDndaS3F!nGlQrmq5(g"HAYs4dS/r8%A/rnmM/q;Lr)nDjH-rT3n +JcC<$JcC<$i;_U3o_nU`pA=gbrqZHdrqHHdr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rosIH!9a@D +s5j:Aro=%)!o)Mcr8%D0rnmS1r8IJ2l/VX$r8mb:roa:Er9=4Gs6KULs6]jSr9s[T +s7-'Ys7?9_r:U*`s7cEcs7uZjqYU6hr;H0bJcC<$L];l~> +JcC<$JcC<$i;_U3o_nU`pA=gbrqZHdrqHHdr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rosIH!9a@D +s5j:Aro=%)!o)Mcr8%D0rnmS1r8IJ2l/VX$r8mb:roa:Er9=4Gs6KULs6]jSr9s[T +s7-'Ys7?9_r:U*`s7cEcs7uZjqYU6hr;H0bJcC<$L];l~> +JcC<$JcC<$i;_U3o_nU`pA=gbrqZHdrqHHdr:U*^s7?3[s7--YrpTmT!:BaO!pf.:rosIH!9a@D +s5j:Aro=%)!o)Mcr8%D0rnmS1r8IJ2l/VX$r8mb:roa:Er9=4Gs6KULs6]jSr9s[T +s7-'Ys7?9_r:U*`s7cEcs7uZjqYU6hr;H0bJcC<$L];l~> +JcC<$JcC<$hZ)=/pAOgbp\XpcrV??cs7cNdrUp3_s7?3[s7--YrpTmT!:BaO!pf.:rosIH!9a=C +!p/M(ro=%hrb0.uPbg"GYcd:%ddF-Lm +eC<%!f)F8&f\+sWgAfn-h#6(.hZ)L1i;MX4ip,RujSJ!5k5FKBkkjWElMg,Im/QJQmelPRnGi%W +o)J=\o_nI_pAXgaq#:*gqYL*fr;?N`rdk*#s+gW)~> +JcC<$JcC<$hZ)=/pAOgbp\XpcrV??cs7cNdrUp3_s7?3[s7--YrpTmT!:BaO!pf.:rosIH!9a=C +!p/M(ro=%hrb0.uPbg"GYcd:%ddF-Lm +eC<%!f)F8&f\+sWgAfn-h#6(.hZ)L1i;MX4ip,RujSJ!5k5FKBkkjWElMg,Im/QJQmelPRnGi%W +o)J=\o_nI_pAXgaq#:*gqYL*fr;?N`rdk*#s+gW)~> +JcC<$JcC<$hZ)=/pAOgbp\XpcrV??cs7cNdrUp3_s7?3[s7--YrpTmT!:BaO!pf.:rosIH!9a=C +!p/M(ro=%hrb0.uPbg"GYcd:%ddF-Lm +eC<%!f)F8&f\+sWgAfn-h#6(.hZ)L1i;MX4ip,RujSJ!5k5FKBkkjWElMg,Im/QJQmelPRnGi%W +o)J=\o_nI_pAXgaq#:*gqYL*fr;?N`rdk*#s+gW)~> +JcC<$JcC<$h#H+-pAOgbp\XsdrV??cs7cNdrUp3_s7?3[s7--YrpTmT!:BaO!pf.:rosIHs6'CD +s5a7ArT!q;!9*n7s53k5rS@J.s4dJ*rn7;'qUb\srRL_nrR:_nqpGDis3LVgs3:SfrQG5`s2k8] +s2P,Zrl+oU!5nfQs1n]NrkJKI!58BEs189Brji'=!4Vp8s0Vj6rNlO0riuC*ric=(poX7kg8jnH +rMfaoqPX=irh]IerM0=co:c#RoV)8YrM0:ds/#^lrMT[os/Gprs/Z1$rN6(%s0)=(riuF-p9WM\ +q6g%,rO;g:r42j=s1A9Cs1SHHrkBAe_84"*_o'F3`Q#ptu0rTF1DqW\%Frp0LKs6]gRrU9aTs7-'Ys7?6^ +rUp0`s7cHdrqZQiqYU6hr;H0bJcC<$LAuc~> +JcC<$JcC<$h#H+-pAOgbp\XsdrV??cs7cNdrUp3_s7?3[s7--YrpTmT!:BaO!pf.:rosIHs6'CD +s5a7ArT!q;!9*n7s53k5rS@J.s4dJ*rn7;'qUb\srRL_nrR:_nqpGDis3LVgs3:SfrQG5`s2k8] +s2P,Zrl+oU!5nfQs1n]NrkJKI!58BEs189Brji'=!4Vp8s0Vj6rNlO0riuC*ric=(poX7kg8jnH +rMfaoqPX=irh]IerM0=co:c#RoV)8YrM0:ds/#^lrMT[os/Gprs/Z1$rN6(%s0)=(riuF-p9WM\ +q6g%,rO;g:r42j=s1A9Cs1SHHrkBAe_84"*_o'F3`Q#ptu0rTF1DqW\%Frp0LKs6]gRrU9aTs7-'Ys7?6^ +rUp0`s7cHdrqZQiqYU6hr;H0bJcC<$LAuc~> +JcC<$JcC<$h#H+-pAOgbp\XsdrV??cs7cNdrUp3_s7?3[s7--YrpTmT!:BaO!pf.:rosIHs6'CD +s5a7ArT!q;!9*n7s53k5rS@J.s4dJ*rn7;'qUb\srRL_nrR:_nqpGDis3LVgs3:SfrQG5`s2k8] +s2P,Zrl+oU!5nfQs1n]NrkJKI!58BEs189Brji'=!4Vp8s0Vj6rNlO0riuC*ric=(poX7kg8jnH +rMfaoqPX=irh]IerM0=co:c#RoV)8YrM0:ds/#^lrMT[os/Gprs/Z1$rN6(%s0)=(riuF-p9WM\ +q6g%,rO;g:r42j=s1A9Cs1SHHrkBAe_84"*_o'F3`Q#ptu0rTF1DqW\%Frp0LKs6]gRrU9aTs7-'Ys7?6^ +rUp0`s7cHdrqZQiqYU6hr;H0bJcC<$LAuc~> +JcC<$JcC<$gAfk*p\jsdp\XsdrV?BdrqHHdr:U*^s7?3[s7$*YrU9dS!:BaOs6B[MrTOCIkNDj, +s5j:Aro=%(rn7;'q:GSrr71YnrR:boqpGGjrm1Pgs3:SfrQ>8baiXP' +s2P,Zrl+oU!5nfQs1n]NrkJKI!58BEs189BrOE!>\$u@Fs0_m6r3QF/s0;I*rNH.%d]N;Gr2]Um +rMfdpqPX=irMB@drM07am\0QQrM07crh]Xlr29Rns/Gssri?(#rN6+&ric7(s0;R/q6U"+pU/P[ +rO;d9r42j=rk&0Bs1SHHrkJKK!5\ZO&AuH)`Poj;a2l?Db0%oNbg$.4!RK-ld/h\ErmUu!f)F8& +f\+sWg&g$ah#?.0hZ)L2i;V^7iqVR0jRM@$k5=E?kkaQClMp2Im/QJPmeuVSnG_tVo)J=\o_nI^ +pAamaq#C0hqYC$er;?N`rdk*#s+^Q(~> +JcC<$JcC<$gAfk*p\jsdp\XsdrV?BdrqHHdr:U*^s7?3[s7$*YrU9dS!:BaOs6B[MrTOCIkNDj, +s5j:Aro=%(rn7;'q:GSrr71YnrR:boqpGGjrm1Pgs3:SfrQ>8baiXP' +s2P,Zrl+oU!5nfQs1n]NrkJKI!58BEs189BrOE!>\$u@Fs0_m6r3QF/s0;I*rNH.%d]N;Gr2]Um +rMfdpqPX=irMB@drM07am\0QQrM07crh]Xlr29Rns/Gssri?(#rN6+&ric7(s0;R/q6U"+pU/P[ +rO;d9r42j=rk&0Bs1SHHrkJKK!5\ZO&AuH)`Poj;a2l?Db0%oNbg$.4!RK-ld/h\ErmUu!f)F8& +f\+sWg&g$ah#?.0hZ)L2i;V^7iqVR0jRM@$k5=E?kkaQClMp2Im/QJPmeuVSnG_tVo)J=\o_nI^ +pAamaq#C0hqYC$er;?N`rdk*#s+^Q(~> +JcC<$JcC<$gAfk*p\jsdp\XsdrV?BdrqHHdr:U*^s7?3[s7$*YrU9dS!:BaOs6B[MrTOCIkNDj, +s5j:Aro=%(rn7;'q:GSrr71YnrR:boqpGGjrm1Pgs3:SfrQ>8baiXP' +s2P,Zrl+oU!5nfQs1n]NrkJKI!58BEs189BrOE!>\$u@Fs0_m6r3QF/s0;I*rNH.%d]N;Gr2]Um +rMfdpqPX=irMB@drM07am\0QQrM07crh]Xlr29Rns/Gssri?(#rN6+&ric7(s0;R/q6U"+pU/P[ +rO;d9r42j=rk&0Bs1SHHrkJKK!5\ZO&AuH)`Poj;a2l?Db0%oNbg$.4!RK-ld/h\ErmUu!f)F8& +f\+sWg&g$ah#?.0hZ)L2i;V^7iqVR0jRM@$k5=E?kkaQClMp2Im/QJPmeuVSnG_tVo)J=\o_nI^ +pAamaq#C0hqYC$er;?N`rdk*#s+^Q(~> +JcC<$JcC<$f`0V'q#1'eq"t$drqZHds7cNdrUp3_s7?3[s7--YrpTmTs6]gPs6K^MrosIH!9a=C +s5a7ArT!q;s5Eq7s53h4r8%D.rnI>(rRq/%q:GPqrRLbormUkpr6bPks3LVg!mSs5rQG5`!6P5] +s2P,Zrl+oU!5nfQs1n]NrkJKI!58BEs1Ag +r2][ori,mqqPX=irMB:bqP3bYqP3k^rh]Ukr29Rns/Gsss/Z.#rN6+&s0)@)s0;R/qm6:/r3aq\ +qR?F5qRQU:s1A6Bs1SHHrkJKK!5\ZOs2+iTrl"oXa8X-\aiaV+!R/gfc3qtFdF$Cje'umte^j`O +!SH*)gAfn-h#6%1hV[5gi;_d8iqh^5jS@p!k54?>kkXKBlMg,Hm/QJPmelPRnGi%Vo)J=\o_nI^ +pAamaq#:*gqYL*fr;?N`rdk*#s+UK'~> +JcC<$JcC<$f`0V'q#1'eq"t$drqZHds7cNdrUp3_s7?3[s7--YrpTmTs6]gPs6K^MrosIH!9a=C +s5a7ArT!q;s5Eq7s53h4r8%D.rnI>(rRq/%q:GPqrRLbormUkpr6bPks3LVg!mSs5rQG5`!6P5] +s2P,Zrl+oU!5nfQs1n]NrkJKI!58BEs1Ag +r2][ori,mqqPX=irMB:bqP3bYqP3k^rh]Ukr29Rns/Gsss/Z.#rN6+&s0)@)s0;R/qm6:/r3aq\ +qR?F5qRQU:s1A6Bs1SHHrkJKK!5\ZOs2+iTrl"oXa8X-\aiaV+!R/gfc3qtFdF$Cje'umte^j`O +!SH*)gAfn-h#6%1hV[5gi;_d8iqh^5jS@p!k54?>kkXKBlMg,Hm/QJPmelPRnGi%Vo)J=\o_nI^ +pAamaq#:*gqYL*fr;?N`rdk*#s+UK'~> +JcC<$JcC<$f`0V'q#1'eq"t$drqZHds7cNdrUp3_s7?3[s7--YrpTmTs6]gPs6K^MrosIH!9a=C +s5a7ArT!q;s5Eq7s53h4r8%D.rnI>(rRq/%q:GPqrRLbormUkpr6bPks3LVg!mSs5rQG5`!6P5] +s2P,Zrl+oU!5nfQs1n]NrkJKI!58BEs1Ag +r2][ori,mqqPX=irMB:bqP3bYqP3k^rh]Ukr29Rns/Gsss/Z.#rN6+&s0)@)s0;R/qm6:/r3aq\ +qR?F5qRQU:s1A6Bs1SHHrkJKK!5\ZOs2+iTrl"oXa8X-\aiaV+!R/gfc3qtFdF$Cje'umte^j`O +!SH*)gAfn-h#6%1hV[5gi;_d8iqh^5jS@p!k54?>kkXKBlMg,Hm/QJPmelPRnGi%Vo)J=\o_nI^ +pAamaq#:*gqYL*fr;?N`rdk*#s+UK'~> +JcC<$JcC<$ec4;$q>L3gq"t$drqZHds7cQer:U*^s7?3[s7--YrpTmTs6]gPs6K^MrosIHs6'CD +s5j:ArT!q;s5Eq7rnmb4r8%A-rS.2&rRq/%pt,JqrRLeprmUkprR(Yls3LYhs3:Sfrlb>as2k8] +!lr=#rl"rW_o)Jj!l;[frkANK]tOEX!kZ%Trji'=s0qs8s0_m6qm6:-riu.#f!"nPpT=Cqri>mq +ri,mqqPX:hr2&JMrMBIir29Rnri,jrs/Z1$r2p"%s0)C*riuL/r3QC0rO)F/pp]Y#pp]q+pppC8 +rk&*@s1SHHrkJKKs2"]O#K+Ku`Poj:a8X-\aiaV+(!OqJcHjh`dF$Cke'umtf%/I)f\"mVg&g$a +h#?.0hZ)L3i;_d9iqqd7jS\-&k4e'8kkOE@lMg,Hm/HDPmelPQnGi%Vo)J=\o_eC^pAXgaq#:*g +qYL*fr;6H_rdk*#s+UK'~> +JcC<$JcC<$ec4;$q>L3gq"t$drqZHds7cQer:U*^s7?3[s7--YrpTmTs6]gPs6K^MrosIHs6'CD +s5j:ArT!q;s5Eq7rnmb4r8%A-rS.2&rRq/%pt,JqrRLeprmUkprR(Yls3LYhs3:Sfrlb>as2k8] +!lr=#rl"rW_o)Jj!l;[frkANK]tOEX!kZ%Trji'=s0qs8s0_m6qm6:-riu.#f!"nPpT=Cqri>mq +ri,mqqPX:hr2&JMrMBIir29Rnri,jrs/Z1$r2p"%s0)C*riuL/r3QC0rO)F/pp]Y#pp]q+pppC8 +rk&*@s1SHHrkJKKs2"]O#K+Ku`Poj:a8X-\aiaV+(!OqJcHjh`dF$Cke'umtf%/I)f\"mVg&g$a +h#?.0hZ)L3i;_d9iqqd7jS\-&k4e'8kkOE@lMg,Hm/HDPmelPQnGi%Vo)J=\o_eC^pAXgaq#:*g +qYL*fr;6H_rdk*#s+UK'~> +JcC<$JcC<$ec4;$q>L3gq"t$drqZHds7cQer:U*^s7?3[s7--YrpTmTs6]gPs6K^MrosIHs6'CD +s5j:ArT!q;s5Eq7rnmb4r8%A-rS.2&rRq/%pt,JqrRLeprmUkprR(Yls3LYhs3:Sfrlb>as2k8] +!lr=#rl"rW_o)Jj!l;[frkANK]tOEX!kZ%Trji'=s0qs8s0_m6qm6:-riu.#f!"nPpT=Cqri>mq +ri,mqqPX:hr2&JMrMBIir29Rnri,jrs/Z1$r2p"%s0)C*riuL/r3QC0rO)F/pp]Y#pp]q+pppC8 +rk&*@s1SHHrkJKKs2"]O#K+Ku`Poj:a8X-\aiaV+(!OqJcHjh`dF$Cke'umtf%/I)f\"mVg&g$a +h#?.0hZ)L3i;_d9iqqd7jS\-&k4e'8kkOE@lMg,Hm/HDPmelPQnGi%Vo)J=\o_eC^pAXgaq#:*g +qYL*fr;6H_rdk*#s+UK'~> +JcC<$JcC<$df8#"q>L3gq"t'erqZHds7cNdrUp3_s7?3[s7--YrpTmTs6]gPs6K^MrosIHs6'@C +s5j:ArT!q;s5Eq7rnm_3r8%>,rnI8&r7V&$pt,Jqrmgnqs3ptqrR(Yls3LYhs31PfrQ>8baiXP' +!lr=#rl"rW_o)Jj!l;[frkANK]tOEXs189BrOMs +JcC<$JcC<$df8#"q>L3gq"t'erqZHds7cNdrUp3_s7?3[s7--YrpTmTs6]gPs6K^MrosIHs6'@C +s5j:ArT!q;s5Eq7rnm_3r8%>,rnI8&r7V&$pt,Jqrmgnqs3ptqrR(Yls3LYhs31PfrQ>8baiXP' +!lr=#rl"rW_o)Jj!l;[frkANK]tOEXs189BrOMs +JcC<$JcC<$df8#"q>L3gq"t'erqZHds7cNdrUp3_s7?3[s7--YrpTmTs6]gPs6K^MrosIHs6'@C +s5j:ArT!q;s5Eq7rnm_3r8%>,rnI8&r7V&$pt,Jqrmgnqs3ptqrR(Yls3LYhs31PfrQ>8baiXP' +!lr=#rl"rW_o)Jj!l;[frkANK]tOEXs189BrOMs +JcC<$JcC<$d/Vi!q>L6hq"t$drqZKerqHHdr:U*^s7?3[s7$*YrU9dSs6]gPs6K^MrTX@G!9a=C +s5j:ArT!n:s5En6rnm_3qq_5+rS.,$r7V&$q:GVsrmgqrs3ptqrR(Yls3L\is31PfrQ>8baiXP' +!lr=#rl"rW_o)Jj!l;[frkANK]tOEXs1Apr +rMfaopS[GVpo"+iri,gqs/Z1$r2p"%s0)C*s0;U0r3QF1rjD[4rO;a8o==;#o==V,r4Dj=rk8)[&BW);bKJ,Sc-FV\d*U1fdaS3F!S,d#f*Bs]g"P07gYDeas5*e5 +ro!h8s5Nt:roF(?pZD86n*'<+r9F7HqX"4KrpK^Qrp]pWr:9mZrq--]s7ZHdr:p9erqcHfrVZTl +nG\"=JcCE'J,~> +JcC<$JcC<$d/Vi!q>L6hq"t$drqZKerqHHdr:U*^s7?3[s7$*YrU9dSs6]gPs6K^MrTX@G!9a=C +s5j:ArT!n:s5En6rnm_3qq_5+rS.,$r7V&$q:GVsrmgqrs3ptqrR(Yls3L\is31PfrQ>8baiXP' +!lr=#rl"rW_o)Jj!l;[frkANK]tOEXs1Apr +rMfaopS[GVpo"+iri,gqs/Z1$r2p"%s0)C*s0;U0r3QF1rjD[4rO;a8o==;#o==V,r4Dj=rk8)[&BW);bKJ,Sc-FV\d*U1fdaS3F!S,d#f*Bs]g"P07gYDeas5*e5 +ro!h8s5Nt:roF(?pZD86n*'<+r9F7HqX"4KrpK^Qrp]pWr:9mZrq--]s7ZHdr:p9erqcHfrVZTl +nG\"=JcCE'J,~> +JcC<$JcC<$d/Vi!q>L6hq"t$drqZKerqHHdr:U*^s7?3[s7$*YrU9dSs6]gPs6K^MrTX@G!9a=C +s5j:ArT!n:s5En6rnm_3qq_5+rS.,$r7V&$q:GVsrmgqrs3ptqrR(Yls3L\is31PfrQ>8baiXP' +!lr=#rl"rW_o)Jj!l;[frkANK]tOEXs1Apr +rMfaopS[GVpo"+iri,gqs/Z1$r2p"%s0)C*s0;U0r3QF1rjD[4rO;a8o==;#o==V,r4Dj=rk8)[&BW);bKJ,Sc-FV\d*U1fdaS3F!S,d#f*Bs]g"P07gYDeas5*e5 +ro!h8s5Nt:roF(?pZD86n*'<+r9F7HqX"4KrpK^Qrp]pWr:9mZrq--]s7ZHdr:p9erqcHfrVZTl +nG\"=JcCE'J,~> +JcC<$JcC<$c2ZSuq>L6hq"t'erV?BdrqHHdr:U*^s7?3[s7--YrpTmTs6]dOs6B[MrTX@Gs6'@C +s5j:Ar8[h:s5Ek5rnm_3q;)#)r7h##rRq/%qUb_trmgtsrmUnqrQt\ncd2R8!mSs5rlYAcaiXP' +!lr=#rl"rW_o)Jj!l;[frkJKI!58?Ds1APqm#t$rNH4'qlTk!rN#dp +rMfaokGS9WrMf^pri?(#r2p"%s0)C*s0;U0r3QF1s0_d5rjVm:q76@5e@YIfrOr3ErP/?Is2"]O +s24lTrl#,^a2c9BaiV^)b5oi3rltPjd/MDndaS3F!S,d#f)aOWrn@D,!8RS0!oDhlro!h8s5Nt: +s5a1@qW@\ +JcC<$JcC<$c2ZSuq>L6hq"t'erV?BdrqHHdr:U*^s7?3[s7--YrpTmTs6]dOs6B[MrTX@Gs6'@C +s5j:Ar8[h:s5Ek5rnm_3q;)#)r7h##rRq/%qUb_trmgtsrmUnqrQt\ncd2R8!mSs5rlYAcaiXP' +!lr=#rl"rW_o)Jj!l;[frkJKI!58?Ds1APqm#t$rNH4'qlTk!rN#dp +rMfaokGS9WrMf^pri?(#r2p"%s0)C*s0;U0r3QF1s0_d5rjVm:q76@5e@YIfrOr3ErP/?Is2"]O +s24lTrl#,^a2c9BaiV^)b5oi3rltPjd/MDndaS3F!S,d#f)aOWrn@D,!8RS0!oDhlro!h8s5Nt: +s5a1@qW@\ +JcC<$JcC<$c2ZSuq>L6hq"t'erV?BdrqHHdr:U*^s7?3[s7--YrpTmTs6]dOs6B[MrTX@Gs6'@C +s5j:Ar8[h:s5Ek5rnm_3q;)#)r7h##rRq/%qUb_trmgtsrmUnqrQt\ncd2R8!mSs5rlYAcaiXP' +!lr=#rl"rW_o)Jj!l;[frkJKI!58?Ds1APqm#t$rNH4'qlTk!rN#dp +rMfaokGS9WrMf^pri?(#r2p"%s0)C*s0;U0r3QF1s0_d5rjVm:q76@5e@YIfrOr3ErP/?Is2"]O +s24lTrl#,^a2c9BaiV^)b5oi3rltPjd/MDndaS3F!S,d#f)aOWrn@D,!8RS0!oDhlro!h8s5Nt: +s5a1@qW@\ +JcC<$JcC<$aoC2rqYg?iq>:-erqZKerqHHdr:U*^s7?3[s7--YrU0gUmHsl=s6K^MrTX@Gs6'@C +s5j:Ar8[h:ro*b4rnm\2q;(u(r7h##rRq/%qq(l!rmgtss3q"rrR(Yl!71Vh!mSs5rlYAcaiXP' +!lr=#rl"rW_o)Jj!l;[frkJKIs1SEEs1A)[#Kb-2bKJ,Rc2Puhcd;[=!RfHre,e+Nrmq2'g&B\,gYCT`h#cHjhu;R6i;hm8j8\3? +jne-U6equ$BirUBf;s+13&s*t~> +JcC<$JcC<$aoC2rqYg?iq>:-erqZKerqHHdr:U*^s7?3[s7--YrU0gUmHsl=s6K^MrTX@Gs6'@C +s5j:Ar8[h:ro*b4rnm\2q;(u(r7h##rRq/%qq(l!rmgtss3q"rrR(Yl!71Vh!mSs5rlYAcaiXP' +!lr=#rl"rW_o)Jj!l;[frkJKIs1SEEs1A)[#Kb-2bKJ,Rc2Puhcd;[=!RfHre,e+Nrmq2'g&B\,gYCT`h#cHjhu;R6i;hm8j8\3? +jne-U6equ$BirUBf;s+13&s*t~> +JcC<$JcC<$aoC2rqYg?iq>:-erqZKerqHHdr:U*^s7?3[s7--YrU0gUmHsl=s6K^MrTX@Gs6'@C +s5j:Ar8[h:ro*b4rnm\2q;(u(r7h##rRq/%qq(l!rmgtss3q"rrR(Yl!71Vh!mSs5rlYAcaiXP' +!lr=#rl"rW_o)Jj!l;[frkJKIs1SEEs1A)[#Kb-2bKJ,Rc2Puhcd;[=!RfHre,e+Nrmq2'g&B\,gYCT`h#cHjhu;R6i;hm8j8\3? +jne-U6equ$BirUBf;s+13&s*t~> +JcC<$JcC<$`W+lqqYg?iq>:-erqZKerqHHdr:U*^s7?3[s7--YrU9dS!:BaOs6K^MrTX@Gs6'@C +roO1@r8[e9ro*b4rSRS1pYGc&r7h&$rn78&r7Cu"rmgtss3q"rrmCbms3L\i!mSs5rlb>a!6P5] +!lr=#rl"rW_o)Jjs1n]NrP/BH!58?Ds1A9Ar42j;rO;O0dC&eWpp9q)riu=(ric=(qlTgurN#Xl +oVqPari?%"r2ot$s0)C*s0;U0r3QF1s0_g6s0r!;r42g +JcC<$JcC<$`W+lqqYg?iq>:-erqZKerqHHdr:U*^s7?3[s7--YrU9dS!:BaOs6K^MrTX@Gs6'@C +roO1@r8[e9ro*b4rSRS1pYGc&r7h&$rn78&r7Cu"rmgtss3q"rrmCbms3L\i!mSs5rlb>a!6P5] +!lr=#rl"rW_o)Jjs1n]NrP/BH!58?Ds1A9Ar42j;rO;O0dC&eWpp9q)riu=(ric=(qlTgurN#Xl +oVqPari?%"r2ot$s0)C*s0;U0r3QF1s0_g6s0r!;r42g +JcC<$JcC<$`W+lqqYg?iq>:-erqZKerqHHdr:U*^s7?3[s7--YrU9dS!:BaOs6K^MrTX@Gs6'@C +roO1@r8[e9ro*b4rSRS1pYGc&r7h&$rn78&r7Cu"rmgtss3q"rrmCbms3L\i!mSs5rlb>a!6P5] +!lr=#rl"rW_o)Jjs1n]NrP/BH!58?Ds1A9Ar42j;rO;O0dC&eWpp9q)riu=(ric=(qlTgurN#Xl +oVqPari?%"r2ot$s0)C*s0;U0r3QF1s0_g6s0r!;r42g +JcC<$JcC<$^Am,Z%rS.2&rn7;'r7Cu"s4.(ts3q"rrmCbms3L\i!mSs5rlYAcaiXP' +!lr=#rl"rW_o)Jjs2"`NrkJKIs1SBDs1A9Aqml^9r3sbUqmHC0q6U(+riu@)ric:'qlTdtr2].` +rN#muqlTn$ric:)s0;U0rNlL1s0_g6s0r$r4Vm>o"XD&p:pRArk\NLs24lTrl+oW +s2Y,[s2b8`rlZ)$c-=PZcd0tcdF-IleC<%!f%8O+f\-8X!ScE/h#cHjhu;R6i;hm9j8\3?jo"9? +kPj]=l1=30lgsK@mJZJLn,DhUnb_nVoD\C[p&=[ap\agbq>U6equ$BirUBf;s+13$s*t~> +JcC<$JcC<$^Am,Z%rS.2&rn7;'r7Cu"s4.(ts3q"rrmCbms3L\i!mSs5rlYAcaiXP' +!lr=#rl"rW_o)Jjs2"`NrkJKIs1SBDs1A9Aqml^9r3sbUqmHC0q6U(+riu@)ric:'qlTdtr2].` +rN#muqlTn$ric:)s0;U0rNlL1s0_g6s0r$r4Vm>o"XD&p:pRArk\NLs24lTrl+oW +s2Y,[s2b8`rlZ)$c-=PZcd0tcdF-IleC<%!f%8O+f\-8X!ScE/h#cHjhu;R6i;hm9j8\3?jo"9? +kPj]=l1=30lgsK@mJZJLn,DhUnb_nVoD\C[p&=[ap\agbq>U6equ$BirUBf;s+13$s*t~> +JcC<$JcC<$^Am,Z%rS.2&rn7;'r7Cu"s4.(ts3q"rrmCbms3L\i!mSs5rlYAcaiXP' +!lr=#rl"rW_o)Jjs2"`NrkJKIs1SBDs1A9Aqml^9r3sbUqmHC0q6U(+riu@)ric:'qlTdtr2].` +rN#muqlTn$ric:)s0;U0rNlL1s0_g6s0r$r4Vm>o"XD&p:pRArk\NLs24lTrl+oW +s2Y,[s2b8`rlZ)$c-=PZcd0tcdF-IleC<%!f%8O+f\-8X!ScE/h#cHjhu;R6i;hm9j8\3?jo"9? +kPj]=l1=30lgsK@mJZJLn,DhUnb_nVoD\C[p&=[ap\agbq>U6equ$BirUBf;s+13$s*t~> +JcC<$JcC<$]`7-nqu-Hjq>:-erqZKerqHHdrUp0^s7?3[s7--YrU9dSs6]dOs6K^MrTX=Fs6'=B +s5j7@qr@\8rSdS1r87D.pYGf'rS.5'rn7;'rR_)#s4.(ts3gtrrQt\ncd2U9!mSs5rlYAcaiXP' +!lr=#rl+oU!5nfQs2"`NrP/BHs1SBDrk&0@qRQL5caWSUr3cO2qQp1,riu@)rNH4'q5sLpo;hbi +qQ9b"ric7(s0;U0r3QF1s0_g6s0r$c!6tMg(=1@SdF$Cke'umtf%/I)f\"m2g=tB;rnRY4hr"Fk!o`.uro=%>s5j1@s6'CFq<@b@ +na#H+qsF@Mq="=PrUKdUs7?6^qt9s^rqH:-gqu-'aJcC<$Jc>`MJ,~> +JcC<$JcC<$]`7-nqu-Hjq>:-erqZKerqHHdrUp0^s7?3[s7--YrU9dSs6]dOs6K^MrTX=Fs6'=B +s5j7@qr@\8rSdS1r87D.pYGf'rS.5'rn7;'rR_)#s4.(ts3gtrrQt\ncd2U9!mSs5rlYAcaiXP' +!lr=#rl+oU!5nfQs2"`NrP/BHs1SBDrk&0@qRQL5caWSUr3cO2qQp1,riu@)rNH4'q5sLpo;hbi +qQ9b"ric7(s0;U0r3QF1s0_g6s0r$c!6tMg(=1@SdF$Cke'umtf%/I)f\"m2g=tB;rnRY4hr"Fk!o`.uro=%>s5j1@s6'CFq<@b@ +na#H+qsF@Mq="=PrUKdUs7?6^qt9s^rqH:-gqu-'aJcC<$Jc>`MJ,~> +JcC<$JcC<$]`7-nqu-Hjq>:-erqZKerqHHdrUp0^s7?3[s7--YrU9dSs6]dOs6K^MrTX=Fs6'=B +s5j7@qr@\8rSdS1r87D.pYGf'rS.5'rn7;'rR_)#s4.(ts3gtrrQt\ncd2U9!mSs5rlYAcaiXP' +!lr=#rl+oU!5nfQs2"`NrP/BHs1SBDrk&0@qRQL5caWSUr3cO2qQp1,riu@)rNH4'q5sLpo;hbi +qQ9b"ric7(s0;U0r3QF1s0_g6s0r$c!6tMg(=1@SdF$Cke'umtf%/I)f\"m2g=tB;rnRY4hr"Fk!o`.uro=%>s5j1@s6'CFq<@b@ +na#H+qsF@Mq="=PrUKdUs7?6^qt9s^rqH:-gqu-'aJcC<$Jc>`MJ,~> +JcC<$JcC<$]Dq$mqu-Hjq>:-erqZKerqHHdr:U*^s7?3[s7--YrU9dSs6]dOrp0ULrTX@Groa4A +roO1@qW%P6rSdM/r87D.ptbo(rnI>(s4RG)r7Cu"s4.+us3q"rrm:eocd2U9s31Pfrlb>a!6P5] +s2P,Zrl+oU!5ncPs2"`NrkJHHs1S?Crk&-?ossCumCE#%r3uI0rjDa4qQp1,riu@)rNH1&o<%ql +oWA(pric7(s0;U0r3QF1s0_g6s0r$otf\(qn`-Grkn`RrPefVs2Y,[ +s2k;`rlYPjc-=PZcd0u;d/h\ErmUu!f)F8+f\+s3g=tEU6dqu$BirUBf;s+13$rrE(L~> +JcC<$JcC<$]Dq$mqu-Hjq>:-erqZKerqHHdr:U*^s7?3[s7--YrU9dSs6]dOrp0ULrTX@Groa4A +roO1@qW%P6rSdM/r87D.ptbo(rnI>(s4RG)r7Cu"s4.+us3q"rrm:eocd2U9s31Pfrlb>a!6P5] +s2P,Zrl+oU!5ncPs2"`NrkJHHs1S?Crk&-?ossCumCE#%r3uI0rjDa4qQp1,riu@)rNH1&o<%ql +oWA(pric7(s0;U0r3QF1s0_g6s0r$otf\(qn`-Grkn`RrPefVs2Y,[ +s2k;`rlYPjc-=PZcd0u;d/h\ErmUu!f)F8+f\+s3g=tEU6dqu$BirUBf;s+13$rrE(L~> +JcC<$JcC<$]Dq$mqu-Hjq>:-erqZKerqHHdr:U*^s7?3[s7--YrU9dSs6]dOrp0ULrTX@Groa4A +roO1@qW%P6rSdM/r87D.ptbo(rnI>(s4RG)r7Cu"s4.+us3q"rrm:eocd2U9s31Pfrlb>a!6P5] +s2P,Zrl+oU!5ncPs2"`NrkJHHs1S?Crk&-?ossCumCE#%r3uI0rjDa4qQp1,riu@)rNH1&o<%ql +oWA(pric7(s0;U0r3QF1s0_g6s0r$otf\(qn`-Grkn`RrPefVs2Y,[ +s2k;`rlYPjc-=PZcd0u;d/h\ErmUu!f)F8+f\+s3g=tEU6dqu$BirUBf;s+13$rrE(L~> +JcC<$JcC<$])UsmqYg?iq>:0frqZHds7cNdrUp0^s7?3[s7--Yr9s[Rs6]dOs6K^Mr9=7Froa4A +roO+>qW%P6r8IA-qqq>.q;)&*rnIA)s4RG)rR_)#s4.+us3q"rrm:eocd2U9!mSs5rlYAcaiXP' +s2P,Zrl+oUs24iQs2"`NrP/?Gs1Srk&-Ark8c +!6tMg!mf6?rm:bpe,Ihte^j`O!SH*)g'?BfgtgfChV\=j!o`.uro=%>s5j4As6'FGqs"(Er9NJ2 +o^2MCp[A(MrUKdUrq$-]qt9s^rqH9arqZQiq>:*fr;H-aJcC<$JcGcMJ,~> +JcC<$JcC<$])UsmqYg?iq>:0frqZHds7cNdrUp0^s7?3[s7--Yr9s[Rs6]dOs6K^Mr9=7Froa4A +roO+>qW%P6r8IA-qqq>.q;)&*rnIA)s4RG)rR_)#s4.+us3q"rrm:eocd2U9!mSs5rlYAcaiXP' +s2P,Zrl+oUs24iQs2"`NrP/?Gs1Srk&-Ark8c +!6tMg!mf6?rm:bpe,Ihte^j`O!SH*)g'?BfgtgfChV\=j!o`.uro=%>s5j4As6'FGqs"(Er9NJ2 +o^2MCp[A(MrUKdUrq$-]qt9s^rqH9arqZQiq>:*fr;H-aJcC<$JcGcMJ,~> +JcC<$JcC<$])UsmqYg?iq>:0frqZHds7cNdrUp0^s7?3[s7--Yr9s[Rs6]dOs6K^Mr9=7Froa4A +roO+>qW%P6r8IA-qqq>.q;)&*rnIA)s4RG)rR_)#s4.+us3q"rrm:eocd2U9!mSs5rlYAcaiXP' +s2P,Zrl+oUs24iQs2"`NrP/?Gs1Srk&-Ark8c +!6tMg!mf6?rm:bpe,Ihte^j`O!SH*)g'?BfgtgfChV\=j!o`.uro=%>s5j4As6'FGqs"(Er9NJ2 +o^2MCp[A(MrUKdUrq$-]qt9s^rqH9arqZQiq>:*fr;H-aJcC<$JcGcMJ,~> +JcC<$JcC<$\Gtakqu-Hjq>:0frqZHds7cNdr:U*^s7?3[rpg$XrU9dSs6]aNs6K^Mr9=4Es6':A +roO+>q;_D4qr.8,r87J0qVD/+rnID*rn7>(rn%2$s4.+us3q"rrm:eocd2U9!mSs5rlYAcaiXP' +s2P,ZrP\iV_o)Gis2"`Nr4i9Grk8*>qRc%(lauu(ppp@5rO;[4rjDa4qm6:-rNZ.%pojUupojLt +riuI.rNlL1s0_g6s0r$rk&-As1SEGr4i3GrPA'ApVYq+qnrBNqo/TTs2Y)Zs2k;`rQ>8d +c-?75#LCcDdF$Cje,Ihte^j`O!SH*)g'?BfgtgfChV\=j!o`.uro=%>!9O1As6'CFr9=4GrTj%@ +m-XN7p$_kKrUKaTrU^$\qt9s^rqH9arqZNhqYU3gr;H*`JcC<$JcGcMJ,~> +JcC<$JcC<$\Gtakqu-Hjq>:0frqZHds7cNdr:U*^s7?3[rpg$XrU9dSs6]aNs6K^Mr9=4Es6':A +roO+>q;_D4qr.8,r87J0qVD/+rnID*rn7>(rn%2$s4.+us3q"rrm:eocd2U9!mSs5rlYAcaiXP' +s2P,ZrP\iV_o)Gis2"`Nr4i9Grk8*>qRc%(lauu(ppp@5rO;[4rjDa4qm6:-rNZ.%pojUupojLt +riuI.rNlL1s0_g6s0r$rk&-As1SEGr4i3GrPA'ApVYq+qnrBNqo/TTs2Y)Zs2k;`rQ>8d +c-?75#LCcDdF$Cje,Ihte^j`O!SH*)g'?BfgtgfChV\=j!o`.uro=%>!9O1As6'CFr9=4GrTj%@ +m-XN7p$_kKrUKaTrU^$\qt9s^rqH9arqZNhqYU3gr;H*`JcC<$JcGcMJ,~> +JcC<$JcC<$\Gtakqu-Hjq>:0frqZHds7cNdr:U*^s7?3[rpg$XrU9dSs6]aNs6K^Mr9=4Es6':A +roO+>q;_D4qr.8,r87J0qVD/+rnID*rn7>(rn%2$s4.+us3q"rrm:eocd2U9!mSs5rlYAcaiXP' +s2P,ZrP\iV_o)Gis2"`Nr4i9Grk8*>qRc%(lauu(ppp@5rO;[4rjDa4qm6:-rNZ.%pojUupojLt +riuI.rNlL1s0_g6s0r$rk&-As1SEGr4i3GrPA'ApVYq+qnrBNqo/TTs2Y)Zs2k;`rQ>8d +c-?75#LCcDdF$Cje,Ihte^j`O!SH*)g'?BfgtgfChV\=j!o`.uro=%>!9O1As6'CFr9=4GrTj%@ +m-XN7p$_kKrUKaTrU^$\qt9s^rqH9arqZNhqYU3gr;H*`JcC<$JcGcMJ,~> +JcC<$JcC<$[K#Ljqu-Hjq>:0frqZHds7cNdr:U*^s7?0Zs7--YrU9dSrpB[Nrp0ULr9=4Eroa1@ +rT4"=pZ)22qVh2,rSRS1qq_;-rnID*s4RG)rR_)#!7h(us3q"rrm:eocd2U9!mSs5rlYAcaiXP' +s2P,ZrPefT!5n`Os2"`Nr4i3Erk67_qn)d;qRQR7rjVd5rjDa4qm67,rNYFfriuF-r3QF1rjD^5 +s0r$rk&-As1SHHr4i6Hrk\EIqSVU:l,3A9qSiHRrl=uYs2k;`rQG5b!6tMgs3C\lrm:u! +e'lgre^`7Mf)aOWrn7D-h#?+2hV[5ihu_lsir7s>jQ5M%joFTDkl'cFlMg,Dm.]o4md]cDnGMhQ +o)81Zo_S7[pAXg`q#1$fqYC$dr;?N^rdk*#s+14Ls*t~> +JcC<$JcC<$[K#Ljqu-Hjq>:0frqZHds7cNdr:U*^s7?0Zs7--YrU9dSrpB[Nrp0ULr9=4Eroa1@ +rT4"=pZ)22qVh2,rSRS1qq_;-rnID*s4RG)rR_)#!7h(us3q"rrm:eocd2U9!mSs5rlYAcaiXP' +s2P,ZrPefT!5n`Os2"`Nr4i3Erk67_qn)d;qRQR7rjVd5rjDa4qm67,rNYFfriuF-r3QF1rjD^5 +s0r$rk&-As1SHHr4i6Hrk\EIqSVU:l,3A9qSiHRrl=uYs2k;`rQG5b!6tMgs3C\lrm:u! +e'lgre^`7Mf)aOWrn7D-h#?+2hV[5ihu_lsir7s>jQ5M%joFTDkl'cFlMg,Dm.]o4md]cDnGMhQ +o)81Zo_S7[pAXg`q#1$fqYC$dr;?N^rdk*#s+14Ls*t~> +JcC<$JcC<$[K#Ljqu-Hjq>:0frqZHds7cNdr:U*^s7?0Zs7--YrU9dSrpB[Nrp0ULr9=4Eroa1@ +rT4"=pZ)22qVh2,rSRS1qq_;-rnID*s4RG)rR_)#!7h(us3q"rrm:eocd2U9!mSs5rlYAcaiXP' +s2P,ZrPefT!5n`Os2"`Nr4i3Erk67_qn)d;qRQR7rjVd5rjDa4qm67,rNYFfriuF-r3QF1rjD^5 +s0r$rk&-As1SHHr4i6Hrk\EIqSVU:l,3A9qSiHRrl=uYs2k;`rQG5b!6tMgs3C\lrm:u! +e'lgre^`7Mf)aOWrn7D-h#?+2hV[5ihu_lsir7s>jQ5M%joFTDkl'cFlMg,Dm.]o4md]cDnGMhQ +o)81Zo_S7[pAXg`q#1$fqYC$dr;?N^rdk*#s+14Ls*t~> +JcC<$JcC<$ZN'7iqu-Hjq>:0frqZHds7cNdr:U*^s7?0Zs7--Yr9s[Rs6]aNs6K[Lr9=4ErTF%> +rT3tqml^9rjVd5rjD^3qQp+*q6Bb"q6Bn(qm6:/ +rjD^5s0r$s5j7Bs6'FGrTX=Hrp0CHqsF(EipZd6 +r:0URrU^$\qXsj]rV-3arV?Hhq"t$fqu-$`JcC<$JcG]KJ,~> +JcC<$JcC<$ZN'7iqu-Hjq>:0frqZHds7cNdr:U*^s7?0Zs7--Yr9s[Rs6]aNs6K[Lr9=4ErTF%> +rT3tqml^9rjVd5rjD^3qQp+*q6Bb"q6Bn(qm6:/ +rjD^5s0r$s5j7Bs6'FGrTX=Hrp0CHqsF(EipZd6 +r:0URrU^$\qXsj]rV-3arV?Hhq"t$fqu-$`JcC<$JcG]KJ,~> +JcC<$JcC<$ZN'7iqu-Hjq>:0frqZHds7cNdr:U*^s7?0Zs7--Yr9s[Rs6]aNs6K[Lr9=4ErTF%> +rT3tqml^9rjVd5rjD^3qQp+*q6Bb"q6Bn(qm6:/ +rjD^5s0r$s5j7Bs6'FGrTX=Hrp0CHqsF(EipZd6 +r:0URrU^$\qXsj]rV-3arV?Hhq"t$fqu-$`JcC<$JcG]KJ,~> +JcC<$JcC<$Y5dngr;HQkq>:0frqZHds7cNdr:U*^s7?0Zs7-*XrU9aRs6]aNs6K[Lqs"+DrTF"= +r8mh:p#Gr/r8IM1rnm_3r8%D.s4dM+s4RG)rn%2$!7h%t!n5TGrm:eocd2U9!mSs5rlb>a!6P2\ +!lr=#rPefTs24cOrk\TLpqPUupqQO:qn;g +JcC<$JcC<$Y5dngr;HQkq>:0frqZHds7cNdr:U*^s7?0Zs7-*XrU9aRs6]aNs6K[Lqs"+DrTF"= +r8mh:p#Gr/r8IM1rnm_3r8%D.s4dM+s4RG)rn%2$!7h%t!n5TGrm:eocd2U9!mSs5rlb>a!6P2\ +!lr=#rPefTs24cOrk\TLpqPUupqQO:qn;g +JcC<$JcC<$Y5dngr;HQkq>:0frqZHds7cNdr:U*^s7?0Zs7-*XrU9aRs6]aNs6K[Lqs"+DrTF"= +r8mh:p#Gr/r8IM1rnm_3r8%D.s4dM+s4RG)rn%2$!7h%t!n5TGrm:eocd2U9!mSs5rlb>a!6P2\ +!lr=#rPefTs24cOrk\TLpqPUupqQO:qn;g +JcC<$JcC<$WrMPer;HTlq>:0frqZHdrqHHdr:U*^rq$*Zrpg$Xr9s[RrpBXMrp0ULqW\"CrTEq; +qrR_9p#Gu0rSdY3rnm_3rS@M/s4dM+s4RG)rn%2$!7h(us3gtrrmCbm!71Vh!mSs5rlYAcaiXM& +!lr=#rPecSs24`Nrk\QK_8#o^rOr'?rk&0@qml^9rjVa4rO)U2kHk,orjDX3s0r!;rOMs>s1A6B +s1SHHr4i9Is2"WMrkn`RqSi?OjN$T+qoANRrlP2_r6,,as3:Pgs3L_lrm:eqe'n +JcC<$JcC<$WrMPer;HTlq>:0frqZHdrqHHdr:U*^rq$*Zrpg$Xr9s[RrpBXMrp0ULqW\"CrTEq; +qrR_9p#Gu0rSdY3rnm_3rS@M/s4dM+s4RG)rn%2$!7h(us3gtrrmCbm!71Vh!mSs5rlYAcaiXM& +!lr=#rPecSs24`Nrk\QK_8#o^rOr'?rk&0@qml^9rjVa4rO)U2kHk,orjDX3s0r!;rOMs>s1A6B +s1SHHr4i9Is2"WMrkn`RqSi?OjN$T+qoANRrlP2_r6,,as3:Pgs3L_lrm:eqe'n +JcC<$JcC<$WrMPer;HTlq>:0frqZHdrqHHdr:U*^rq$*Zrpg$Xr9s[RrpBXMrp0ULqW\"CrTEq; +qrR_9p#Gu0rSdY3rnm_3rS@M/s4dM+s4RG)rn%2$!7h(us3gtrrmCbm!71Vh!mSs5rlYAcaiXM& +!lr=#rPecSs24`Nrk\QK_8#o^rOr'?rk&0@qml^9rjVa4rO)U2kHk,orjDX3s0r!;rOMs>s1A6B +s1SHHr4i9Is2"WMrkn`RqSi?OjN$T+qoANRrlP2_r6,,as3:Pgs3L_lrm:eqe'n +JcC<$JcC<$W;lAdr;HTlq>:0frqZHdrqHHdr:U']s7?0Zs7--Yr9sXQs6]^Mrp0RKqs"(Cr9*e9 +qW7S7pZ)53rSdY3s53k5r8%D.s4dP,s4RG)rmq5&e^aZKs3gtrrmCbm!71Yis3:Sfrlb>a!6P2\ +s2Y/ZrPecSrknWMr5&0DotTt2pVHR=pV6[@rk83Ark&0@qml^9rjV^3r3bmurO)L1rjVp;r42j= +s1A6Bs1SHHr4i9Is2"ZNrkncSqo/NRr5[O4p;cgHrQ5&]r6,)`s3:Pgs3L_lrmCbo!7Uqss4%,# +rmqD-g"G*5gY:N_h#ZBirnmk:io9st!p&J)roX7D!9jCGs6BULr9XFMrU07Fl1"E:o^_tPr:KjY +rV$3aqY:$brqcEer;?Kkn,@n +JcC<$JcC<$W;lAdr;HTlq>:0frqZHdrqHHdr:U']s7?0Zs7--Yr9sXQs6]^Mrp0RKqs"(Cr9*e9 +qW7S7pZ)53rSdY3s53k5r8%D.s4dP,s4RG)rmq5&e^aZKs3gtrrmCbm!71Yis3:Sfrlb>a!6P2\ +s2Y/ZrPecSrknWMr5&0DotTt2pVHR=pV6[@rk83Ark&0@qml^9rjV^3r3bmurO)L1rjVp;r42j= +s1A6Bs1SHHr4i9Is2"ZNrkncSqo/NRr5[O4p;cgHrQ5&]r6,)`s3:Pgs3L_lrmCbo!7Uqss4%,# +rmqD-g"G*5gY:N_h#ZBirnmk:io9st!p&J)roX7D!9jCGs6BULr9XFMrU07Fl1"E:o^_tPr:KjY +rV$3aqY:$brqcEer;?Kkn,@n +JcC<$JcC<$W;lAdr;HTlq>:0frqZHdrqHHdr:U']s7?0Zs7--Yr9sXQs6]^Mrp0RKqs"(Cr9*e9 +qW7S7pZ)53rSdY3s53k5r8%D.s4dP,s4RG)rmq5&e^aZKs3gtrrmCbm!71Yis3:Sfrlb>a!6P2\ +s2Y/ZrPecSrknWMr5&0DotTt2pVHR=pV6[@rk83Ark&0@qml^9rjV^3r3bmurO)L1rjVp;r42j= +s1A6Bs1SHHr4i9Is2"ZNrkncSqo/NRr5[O4p;cgHrQ5&]r6,)`s3:Pgs3L_lrmCbo!7Uqss4%,# +rmqD-g"G*5gY:N_h#ZBirnmk:io9st!p&J)roX7D!9jCGs6BULr9XFMrU07Fl1"E:o^_tPr:KjY +rV$3aqY:$brqcEer;?Kkn,@n +JcC<$JcC<$W;lAdqu-Kkq>:0frqZHdrqHHdr:U']s7?0Zrpg$Xr9sXQs6]^Mrp0OJqW[qAr9*\6 +qW7Y9puDA5ro*b4s53k5rS@M/s4dP,s4RG)rn%2$!7h(us3gtrrmCbm!71Vh!mSs5rlb>as2k5\ +s2Y/Zr5JZRrknKIjMC)tqSE*FqS3$DrOr-Ark&0@qml[8rjVU0o!S5#rjVm:r42j=s1A3As1SHH +rP/BJs2"ZNs24iSr5JZTrQ"ZRkfMo,r5no[qof#`s3:Je!mf6?rQt\pe'n +JcC<$JcC<$W;lAdqu-Kkq>:0frqZHdrqHHdr:U']s7?0Zrpg$Xr9sXQs6]^Mrp0OJqW[qAr9*\6 +qW7Y9puDA5ro*b4s53k5rS@M/s4dP,s4RG)rn%2$!7h(us3gtrrmCbm!71Vh!mSs5rlb>as2k5\ +s2Y/Zr5JZRrknKIjMC)tqSE*FqS3$DrOr-Ark&0@qml[8rjVU0o!S5#rjVm:r42j=s1A3As1SHH +rP/BJs2"ZNs24iSr5JZTrQ"ZRkfMo,r5no[qof#`s3:Je!mf6?rQt\pe'n +JcC<$JcC<$W;lAdqu-Kkq>:0frqZHdrqHHdr:U']s7?0Zrpg$Xr9sXQs6]^Mrp0OJqW[qAr9*\6 +qW7Y9puDA5ro*b4s53k5rS@M/s4dP,s4RG)rn%2$!7h(us3gtrrmCbm!71Vh!mSs5rlb>as2k5\ +s2Y/Zr5JZRrknKIjMC)tqSE*FqS3$DrOr-Ark&0@qml[8rjVU0o!S5#rjVm:r42j=s1A3As1SHH +rP/BJs2"ZNs24iSr5JZTrQ"ZRkfMo,r5no[qof#`s3:Je!mf6?rQt\pe'n +JcC<$JcC<$VuQ8cr;HQkq>:0frqZHdrqHHdr:U']s7?0Zrpg!Wr9sXQs6][Lrp0OJq<@e?qrdP4 +qrRe;q;_J6s5En6s53k5rS@M/s4dP,s4RG)rmq5&e^aZKs3gtrrmCbm!71Vh!mSs5rlb>as2k5\ +rl>&Yqo/QQr571(pVZOYs~> +JcC<$JcC<$VuQ8cr;HQkq>:0frqZHdrqHHdr:U']s7?0Zrpg!Wr9sXQs6][Lrp0OJq<@e?qrdP4 +qrRe;q;_J6s5En6s53k5rS@M/s4dP,s4RG)rmq5&e^aZKs3gtrrmCbm!71Vh!mSs5rlb>as2k5\ +rl>&Yqo/QQr571(pVZOYs~> +JcC<$JcC<$VuQ8cr;HQkq>:0frqZHdrqHHdr:U']s7?0Zrpg!Wr9sXQs6][Lrp0OJq<@e?qrdP4 +qrRe;q;_J6s5En6s53k5rS@M/s4dP,s4RG)rmq5&e^aZKs3gtrrmCbm!71Vh!mSs5rlb>as2k5\ +rl>&Yqo/QQr571(pVZOYs~> +JcC<$JcC<$VuQ5br;HQkqYU6frqZHdrqHHdqt:!]rq$'Yrpg$XqsXOPrpBULrTjFIpZ_P#XqSiBNikt$!qSW*Frk\QKqnN0Frk83Ark&0@q76F5m^N,(qRQU:s1A3As1SHHrP/BJs2"ZN +s24iSrPefVrl=oWrlP)\fus!0oZR6XrltAds3L_lrR(Yns3ptss4%,#rn%2&!87A*#M\%hh;-rE +hu;O=iSrkWj5f:_roX7Ds60IHs6BXMrTsONrpKXOr:'OPg[b44qt0[Vr:^*`q=ssbr;-6dr;?Hj +n,@nj~> +JcC<$JcC<$VuQ5br;HQkqYU6frqZHdrqHHdqt:!]rq$'Yrpg$XqsXOPrpBULrTjFIpZ_P#XqSiBNikt$!qSW*Frk\QKqnN0Frk83Ark&0@q76F5m^N,(qRQU:s1A3As1SHHrP/BJs2"ZN +s24iSrPefVrl=oWrlP)\fus!0oZR6XrltAds3L_lrR(Yns3ptss4%,#rn%2&!87A*#M\%hh;-rE +hu;O=iSrkWj5f:_roX7Ds60IHs6BXMrTsONrpKXOr:'OPg[b44qt0[Vr:^*`q=ssbr;-6dr;?Hj +n,@nj~> +JcC<$JcC<$VuQ5br;HQkqYU6frqZHdrqHHdqt:!]rq$'Yrpg$XqsXOPrpBULrTjFIpZ_P#XqSiBNikt$!qSW*Frk\QKqnN0Frk83Ark&0@q76F5m^N,(qRQU:s1A3As1SHHrP/BJs2"ZN +s24iSrPefVrl=oWrlP)\fus!0oZR6XrltAds3L_lrR(Yns3ptss4%,#rn%2&!87A*#M\%hh;-rE +hu;O=iSrkWj5f:_roX7Ds60IHs6BXMrTsONrpKXOr:'OPg[b44qt0[Vr:^*`q=ssbr;-6dr;?Hj +n,@nj~> +JcC<$JcC<$VZ6/bqu-Kkq>:-erqZHdrqHHdqt:!]rq$'Yrpg!WqsXOPrpBRKrTjCHo]c28qWIS7 +rT4%>qr@_9ro*h6s53k5rn[V0s4dP,s4ID)rn%2$s4.+u!n5TGrmCbm!71Vh!mSs5rQG5`rlP)Z +s2Y)XpVlF9hSoE2rPSKKrk\TLqnN-Erk83Ark&-?ossh,p::.5rk&*@s1SHHr4i9Is2"ZNs24lT +rPefVrl=rXrlP/^pWM^Cj3.AErQY5bs3L_lrR(Yns3ptss4./#rmq5(g"HAY!ScE/h>c=3hu;O7 +iSsjss5X1AroX7Ds60IHs6BXMrTsROrpK[PrUB^Sh=C:2qXjOTr:^*`q=sparVHj~> +JcC<$JcC<$VZ6/bqu-Kkq>:-erqZHdrqHHdqt:!]rq$'Yrpg!WqsXOPrpBRKrTjCHo]c28qWIS7 +rT4%>qr@_9ro*h6s53k5rn[V0s4dP,s4ID)rn%2$s4.+u!n5TGrmCbm!71Vh!mSs5rQG5`rlP)Z +s2Y)XpVlF9hSoE2rPSKKrk\TLqnN-Erk83Ark&-?ossh,p::.5rk&*@s1SHHr4i9Is2"ZNs24lT +rPefVrl=rXrlP/^pWM^Cj3.AErQY5bs3L_lrR(Yns3ptss4./#rmq5(g"HAY!ScE/h>c=3hu;O7 +iSsjss5X1AroX7Ds60IHs6BXMrTsROrpK[PrUB^Sh=C:2qXjOTr:^*`q=sparVHj~> +JcC<$JcC<$VZ6/bqu-Kkq>:-erqZHdrqHHdqt:!]rq$'Yrpg!WqsXOPrpBRKrTjCHo]c28qWIS7 +rT4%>qr@_9ro*h6s53k5rn[V0s4dP,s4ID)rn%2$s4.+u!n5TGrmCbm!71Vh!mSs5rQG5`rlP)Z +s2Y)XpVlF9hSoE2rPSKKrk\TLqnN-Erk83Ark&-?ossh,p::.5rk&*@s1SHHr4i9Is2"ZNs24lT +rPefVrl=rXrlP/^pWM^Cj3.AErQY5bs3L_lrR(Yns3ptss4./#rmq5(g"HAY!ScE/h>c=3hu;O7 +iSsjss5X1AroX7Ds60IHs6BXMrTsROrpK[PrUB^Sh=C:2qXjOTr:^*`q=sparVHj~> +JcC<$JcC<$V>p&aqu-Kkq>:-erqZHdrqHEcr:U']rq$'Yrpg!WqsXOPrU'FIr9O:Gn`fo6qrdb: +roO.?qr@_9s5Eq7s53k5rn[V0s4dP,s4ID)rn%2$!7h%t!n5TGrmCbm!71Vhs3:SfrQG5`rlP)Z +rQ"iUhSng#ou6mJrknTLrk\WMqnN-Erk80@rO`!=mCE/+rO`!?rk8?Gr4i9Is2"ZNs24lTrPefV +rl=uYrlP/^qoeo]qT\QUp!)dGqp"u_rm1SjrR(Yns3pqr!nGlQrn%2&!87A*s4[P/rnRY4hr"Fk +!TE&;j8\0?jo4EBk5a`EklU/9li$2LmJlVOn,DhSn`o]2oD%tNp&+O^p\=O^q>L0aqu$BhrU9`: +s+13$s7cPD~> +JcC<$JcC<$V>p&aqu-Kkq>:-erqZHdrqHEcr:U']rq$'Yrpg!WqsXOPrU'FIr9O:Gn`fo6qrdb: +roO.?qr@_9s5Eq7s53k5rn[V0s4dP,s4ID)rn%2$!7h%t!n5TGrmCbm!71Vhs3:SfrQG5`rlP)Z +rQ"iUhSng#ou6mJrknTLrk\WMqnN-Erk80@rO`!=mCE/+rO`!?rk8?Gr4i9Is2"ZNs24lTrPefV +rl=uYrlP/^qoeo]qT\QUp!)dGqp"u_rm1SjrR(Yns3pqr!nGlQrn%2&!87A*s4[P/rnRY4hr"Fk +!TE&;j8\0?jo4EBk5a`EklU/9li$2LmJlVOn,DhSn`o]2oD%tNp&+O^p\=O^q>L0aqu$BhrU9`: +s+13$s7cPD~> +JcC<$JcC<$V>p&aqu-Kkq>:-erqZHdrqHEcr:U']rq$'Yrpg!WqsXOPrU'FIr9O:Gn`fo6qrdb: +roO.?qr@_9s5Eq7s53k5rn[V0s4dP,s4ID)rn%2$!7h%t!n5TGrmCbm!71Vhs3:SfrQG5`rlP)Z +rQ"iUhSng#ou6mJrknTLrk\WMqnN-Erk80@rO`!=mCE/+rO`!?rk8?Gr4i9Is2"ZNs24lTrPefV +rl=uYrlP/^qoeo]qT\QUp!)dGqp"u_rm1SjrR(Yns3pqr!nGlQrn%2&!87A*s4[P/rnRY4hr"Fk +!TE&;j8\0?jo4EBk5a`EklU/9li$2LmJlVOn,DhSn`o]2oD%tNp&+O^p\=O^q>L0aqu$BhrU9`: +s+13$s7cPD~> +JcC<$JcC<$V#Tr`qu-Kkq>:-erqZHdrqHEcqt9s\s7?-Yrpg!WqsXLOrU'CHqs4+Dn`fr7r9*n< +roO1@r8[h:s5Eq7s53k5rn[V0s4dP,!nl5Yrn%2$!7h(us3q"rrmCbms3L\is3:Sfr6,,_rlOuW +r5[s>o#LUJp;d*Nq8N?OrknWMrk\TLqnN-Erk8-?qn)F1r4Dd;rk8?Gr4i9Is2"ZNs24lTr5J]U +s2Y)Zs2k8_qoeu_rQX$@n'1ROrQkJir6bPms3pqrs4%,#rRV,'g"HAY!o)McrnRV3hu;R6i;hm: +ir\<'jo4BDkNM./l2U&Kli$2MmJlVPn,;bSnauD8oCV\Hp&+O]p\=O^q>C*aqtp +JcC<$JcC<$V#Tr`qu-Kkq>:-erqZHdrqHEcqt9s\s7?-Yrpg!WqsXLOrU'CHqs4+Dn`fr7r9*n< +roO1@r8[h:s5Eq7s53k5rn[V0s4dP,!nl5Yrn%2$!7h(us3q"rrmCbms3L\is3:Sfr6,,_rlOuW +r5[s>o#LUJp;d*Nq8N?OrknWMrk\TLqnN-Erk8-?qn)F1r4Dd;rk8?Gr4i9Is2"ZNs24lTr5J]U +s2Y)Zs2k8_qoeu_rQX$@n'1ROrQkJir6bPms3pqrs4%,#rRV,'g"HAY!o)McrnRV3hu;R6i;hm: +ir\<'jo4BDkNM./l2U&Kli$2MmJlVPn,;bSnauD8oCV\Hp&+O]p\=O^q>C*aqtp +JcC<$JcC<$V#Tr`qu-Kkq>:-erqZHdrqHEcqt9s\s7?-Yrpg!WqsXLOrU'CHqs4+Dn`fr7r9*n< +roO1@r8[h:s5Eq7s53k5rn[V0s4dP,!nl5Yrn%2$!7h(us3q"rrmCbms3L\is3:Sfr6,,_rlOuW +r5[s>o#LUJp;d*Nq8N?OrknWMrk\TLqnN-Erk8-?qn)F1r4Dd;rk8?Gr4i9Is2"ZNs24lTr5J]U +s2Y)Zs2k8_qoeu_rQX$@n'1ROrQkJir6bPms3pqrs4%,#rRV,'g"HAY!o)McrnRV3hu;R6i;hm: +ir\<'jo4BDkNM./l2U&Kli$2MmJlVPn,;bSnauD8oCV\Hp&+O]p\=O^q>C*aqtp +JcC<$JcC<$V#To_r;HQkq>:-erqZHdrqHEcqt9s\rq$$Xrpg!WqX=CNrU'=FqWmqAoBH2:rTF%> +s5j7@rT!q;s5Eq7s53k5rn[V0!8IJ+!nl5Yrmq5&e^aZKs3q"rrmCbms3LYhs3:Sfr6,)^rlOlT +m)Ri$r5\cUqSiHPrknZNrk\TLqnN-ErOqj9qRcF5rOr3Er4i9Is2"WMs24lTrPefVs2Y)Zs2k8_ +r6,)`rlt5`jNli2r6PAhqpGDks3pqrs4./#rn%2&!87>)#M\%hh;-rEhu;R6i;hm:ir\<'jo4BD +kNM./l2U&Kli$2MmJlVPn,DhUnb;VJoB,]6p&+O\p\=O]q>L0aqtp +JcC<$JcC<$V#To_r;HQkq>:-erqZHdrqHEcqt9s\rq$$Xrpg!WqX=CNrU'=FqWmqAoBH2:rTF%> +s5j7@rT!q;s5Eq7s53k5rn[V0!8IJ+!nl5Yrmq5&e^aZKs3q"rrmCbms3LYhs3:Sfr6,)^rlOlT +m)Ri$r5\cUqSiHPrknZNrk\TLqnN-ErOqj9qRcF5rOr3Er4i9Is2"WMs24lTrPefVs2Y)Zs2k8_ +r6,)`rlt5`jNli2r6PAhqpGDks3pqrs4./#rn%2&!87>)#M\%hh;-rEhu;R6i;hm:ir\<'jo4BD +kNM./l2U&Kli$2MmJlVPn,DhUnb;VJoB,]6p&+O\p\=O]q>L0aqtp +JcC<$JcC<$V#To_r;HQkq>:-erqZHdrqHEcqt9s\rq$$Xrpg!WqX=CNrU'=FqWmqAoBH2:rTF%> +s5j7@rT!q;s5Eq7s53k5rn[V0!8IJ+!nl5Yrmq5&e^aZKs3q"rrmCbms3LYhs3:Sfr6,)^rlOlT +m)Ri$r5\cUqSiHPrknZNrk\TLqnN-ErOqj9qRcF5rOr3Er4i9Is2"WMs24lTrPefVs2Y)Zs2k8_ +r6,)`rlt5`jNli2r6PAhqpGDks3pqrs4./#rn%2&!87>)#M\%hh;-rEhu;R6i;hm:ir\<'jo4BD +kNM./l2U&Kli$2MmJlVPn,DhUnb;VJoB,]6p&+O\p\=O]q>L0aqtp +JcC<$JcC<$U]9i_qu-Hjq>:-erqZHdrqHEcqt9s\rq$!Wrpg!Wq=":Mr9a+Bq!7b@p?DP>rTF+@ +roO1@rT!q;s5Eq7s5*h5rS7P1gY;_]s4ID)rRV,%e^aZKs3q"rrmCbms3LYhrltJeqoeu]r5mp= +j2q&:rQ"oWqo/QQrknZNrk\TLqS3!Cr4VO2r4W*DqnN-Gs2"WMs24lTrPefVs2Y)Zs2k8_rQG2a +rlt>cr6P5do$R0Xjj3kOqU,;jrmUhqs4./#rRV,'g"HAYs4[P/rn[V2!8me6s5 +JcC<$JcC<$U]9i_qu-Hjq>:-erqZHdrqHEcqt9s\rq$!Wrpg!Wq=":Mr9a+Bq!7b@p?DP>rTF+@ +roO1@rT!q;s5Eq7s5*h5rS7P1gY;_]s4ID)rRV,%e^aZKs3q"rrmCbms3LYhrltJeqoeu]r5mp= +j2q&:rQ"oWqo/QQrknZNrk\TLqS3!Cr4VO2r4W*DqnN-Gs2"WMs24lTrPefVs2Y)Zs2k8_rQG2a +rlt>cr6P5do$R0Xjj3kOqU,;jrmUhqs4./#rRV,'g"HAYs4[P/rn[V2!8me6s5 +JcC<$JcC<$U]9i_qu-Hjq>:-erqZHdrqHEcqt9s\rq$!Wrpg!Wq=":Mr9a+Bq!7b@p?DP>rTF+@ +roO1@rT!q;s5Eq7s5*h5rS7P1gY;_]s4ID)rRV,%e^aZKs3q"rrmCbms3LYhrltJeqoeu]r5mp= +j2q&:rQ"oWqo/QQrknZNrk\TLqS3!Cr4VO2r4W*DqnN-Gs2"WMs24lTrPefVs2Y)Zs2k8_rQG2a +rlt>cr6P5do$R0Xjj3kOqU,;jrmUhqs4./#rRV,'g"HAYs4[P/rn[V2!8me6s5 +JcC<$JcC<$U]9f^qu-Hjq>:-erqZEcrqHEcqt9s\rq$!WrpfsVq="7LqsEn>q!7hBq!%b@roa4A +s5j:Ar8Rk +nB:XMr5nfVrl>#Xqo/QQrknZNrk\QKq7lg@oY(.9q7lpEs2"WMs24lTr5J]Us2Y)Zs2k;`rQG2a +s3:Gdrm1PigX594pX/ugrmUeps4./#rR_)%!87>)!o)Mcrn[V2!8me6!o`.uro4(@jlQL(!pAe2 +rosIJ!:0UMs6]jSr9s[TrpfjUqt'UTg%G48qY0aZr;$9ep\Xjcqu,s^JcC<$JcG?AJ,~> +JcC<$JcC<$U]9f^qu-Hjq>:-erqZEcrqHEcqt9s\rq$!WrpfsVq="7LqsEn>q!7hBq!%b@roa4A +s5j:Ar8Rk +nB:XMr5nfVrl>#Xqo/QQrknZNrk\QKq7lg@oY(.9q7lpEs2"WMs24lTr5J]Us2Y)Zs2k;`rQG2a +s3:Gdrm1PigX594pX/ugrmUeps4./#rR_)%!87>)!o)Mcrn[V2!8me6!o`.uro4(@jlQL(!pAe2 +rosIJ!:0UMs6]jSr9s[TrpfjUqt'UTg%G48qY0aZr;$9ep\Xjcqu,s^JcC<$JcG?AJ,~> +JcC<$JcC<$U]9f^qu-Hjq>:-erqZEcrqHEcqt9s\rq$!WrpfsVq="7LqsEn>q!7hBq!%b@roa4A +s5j:Ar8Rk +nB:XMr5nfVrl>#Xqo/QQrknZNrk\QKq7lg@oY(.9q7lpEs2"WMs24lTr5J]Us2Y)Zs2k;`rQG2a +s3:Gdrm1PigX594pX/ugrmUeps4./#rR_)%!87>)!o)Mcrn[V2!8me6!o`.uro4(@jlQL(!pAe2 +rosIJ!:0UMs6]jSr9s[TrpfjUqt'UTg%G48qY0aZr;$9ep\Xjcqu,s^JcC<$JcG?AJ,~> +JcC<$JcC<$UAs]]qu-Hjq>:-erqZEcrqHEcqXsj[rq$!WrUKjUq!\+Jq#Xr5JZRrknWMrk\QKikPH-rk\NLs24iSrPefVs2Y)Zs2k;`rQG2as3:Jerm1SjpsJ6P +h9l2LrR:\ormh&"rR_)%s4RD*s4dS/rnRY4hr"Fk!o`.uro4(@jlQL(!pAe2rojLLlg+N9s6]jS +rU9dUrpfjUrU]pYg%G+5qY0[Xr;$9epA=dcqYfj]JcC<$JcG<@J,~> +JcC<$JcC<$UAs]]qu-Hjq>:-erqZEcrqHEcqXsj[rq$!WrUKjUq!\+Jq#Xr5JZRrknWMrk\QKikPH-rk\NLs24iSrPefVs2Y)Zs2k;`rQG2as3:Jerm1SjpsJ6P +h9l2LrR:\ormh&"rR_)%s4RD*s4dS/rnRY4hr"Fk!o`.uro4(@jlQL(!pAe2rojLLlg+N9s6]jS +rU9dUrpfjUrU]pYg%G+5qY0[Xr;$9epA=dcqYfj]JcC<$JcG<@J,~> +JcC<$JcC<$UAs]]qu-Hjq>:-erqZEcrqHEcqXsj[rq$!WrUKjUq!\+Jq#Xr5JZRrknWMrk\QKikPH-rk\NLs24iSrPefVs2Y)Zs2k;`rQG2as3:Jerm1SjpsJ6P +h9l2LrR:\ormh&"rR_)%s4RD*s4dS/rnRY4hr"Fk!o`.uro4(@jlQL(!pAe2rojLLlg+N9s6]jS +rU9dUrpfjUrU]pYg%G+5qY0[Xr;$9epA=dcqYfj]JcC<$JcG<@J,~> +JcC<$JcC<$U&XT\qu-Hjq>:-erqZEcrqHBbqt9p[rq$!WrUKgTp@%kGq!IS;qs44Gqs"+Droa7B +roO1@ro=%&Yqo/QQrknWMrPABHn%\e9rPABJs24iSrPefVs2Y)Zs2k;`r6,,as3:Jes3L\k +qpG>iqU>#bp=&cao?mE_r6tMls4.,"rR_)%s4RA)!o)Mcrn[V2!8me6s5!9O4Bs6'FG +rojLLlg+N9!q#FDr9s[Ts7,sVrq$'[i:ZU5q=jOVqt^0dpA=dcqYfj]JcC<$JcG9?J,~> +JcC<$JcC<$U&XT\qu-Hjq>:-erqZEcrqHBbqt9p[rq$!WrUKgTp@%kGq!IS;qs44Gqs"+Droa7B +roO1@ro=%&Yqo/QQrknWMrPABHn%\e9rPABJs24iSrPefVs2Y)Zs2k;`r6,,as3:Jes3L\k +qpG>iqU>#bp=&cao?mE_r6tMls4.,"rR_)%s4RA)!o)Mcrn[V2!8me6s5!9O4Bs6'FG +rojLLlg+N9!q#FDr9s[Ts7,sVrq$'[i:ZU5q=jOVqt^0dpA=dcqYfj]JcC<$JcG9?J,~> +JcC<$JcC<$U&XT\qu-Hjq>:-erqZEcrqHBbqt9p[rq$!WrUKgTp@%kGq!IS;qs44Gqs"+Droa7B +roO1@ro=%&Yqo/QQrknWMrPABHn%\e9rPABJs24iSrPefVs2Y)Zs2k;`r6,,as3:Jes3L\k +qpG>iqU>#bp=&cao?mE_r6tMls4.,"rR_)%s4RA)!o)Mcrn[V2!8me6s5!9O4Bs6'FG +rojLLlg+N9!q#FDr9s[Ts7,sVrq$'[i:ZU5q=jOVqt^0dpA=dcqYfj]JcC<$JcG9?J,~> +JcC<$JcC<$U&XQ[qu-Hjq>:-erV?r9O@Iqs"+Ds6'=B +s5j:Aro=%#Xr5JZRrPSHJqSDm@qn`*FrkncSr5J]Url=uYs2k;`rQG5bs3:Mfrm1VkqpGDk +rR9QOo[E]cpXArfrRLr!r7Cu$s4RA)s4dS/rn[V2!8me6s5!9O4Bs5sCGrTOCKlg+Q: +s6]jSrU9dUrpfpWrU^![nFbl9p%S(Qqt^0dpA=abqYfg\JcC<$JcG9?J,~> +JcC<$JcC<$U&XQ[qu-Hjq>:-erV?r9O@Iqs"+Ds6'=B +s5j:Aro=%#Xr5JZRrPSHJqSDm@qn`*FrkncSr5J]Url=uYs2k;`rQG5bs3:Mfrm1VkqpGDk +rR9QOo[E]cpXArfrRLr!r7Cu$s4RA)s4dS/rn[V2!8me6s5!9O4Bs5sCGrTOCKlg+Q: +s6]jSrU9dUrpfpWrU^![nFbl9p%S(Qqt^0dpA=abqYfg\JcC<$JcG9?J,~> +JcC<$JcC<$U&XQ[qu-Hjq>:-erV?r9O@Iqs"+Ds6'=B +s5j:Aro=%#Xr5JZRrPSHJqSDm@qn`*FrkncSr5J]Url=uYs2k;`rQG5bs3:Mfrm1VkqpGDk +rR9QOo[E]cpXArfrRLr!r7Cu$s4RA)s4dS/rn[V2!8me6s5!9O4Bs5sCGrTOCKlg+Q: +s6]jSrU9dUrpfpWrU^![nFbl9p%S(Qqt^0dpA=abqYfg\JcC<$JcG9?J,~> +JcC<$JcC<$T`=HZqu-Hjq>:-erV?c +qTJl\s2k/Zrl>&Yqo/NPrPRX3rkn`Rr5JZTs2Y)Zs2k;`rQG2as3:Mfs3L_lr6bMlrmUYlkLJ88 +rRLnuqq(l#s4RA)s4dS/rS7P3hr"Fks5!9O4Bs5sCGrTOCKlg+Q:s6]jSrU9dUrpfpW +rq$*\p%@YEmJ$,Fqt^-cp&"XaqYfg\JcC<$JcG6>J,~> +JcC<$JcC<$T`=HZqu-Hjq>:-erV?c +qTJl\s2k/Zrl>&Yqo/NPrPRX3rkn`Rr5JZTs2Y)Zs2k;`rQG2as3:Mfs3L_lr6bMlrmUYlkLJ88 +rRLnuqq(l#s4RA)s4dS/rS7P3hr"Fks5!9O4Bs5sCGrTOCKlg+Q:s6]jSrU9dUrpfpW +rq$*\p%@YEmJ$,Fqt^-cp&"XaqYfg\JcC<$JcG6>J,~> +JcC<$JcC<$T`=HZqu-Hjq>:-erV?c +qTJl\s2k/Zrl>&Yqo/NPrPRX3rkn`Rr5JZTs2Y)Zs2k;`rQG2as3:Mfs3L_lr6bMlrmUYlkLJ88 +rRLnuqq(l#s4RA)s4dS/rS7P3hr"Fks5!9O4Bs5sCGrTOCKlg+Q:s6]jSrU9dUrpfpW +rq$*\p%@YEmJ$,Fqt^-cp&"XaqYfg\JcC<$JcG6>J,~> +JcC<$JcC<$TE"BZqu-Eiq>:-erV?#Xqo/NPqnqp?r58KOqo/QSs2Y&Ys2k;`rQG5bs3:Mfs3L_lr6bMls3phor71Vo +pXf,ipXSTZqpkYrqq(i"s4RA)s4dS/rS@M1!8mb5!o`.uro=%>!9O4Bs5sCGrosIJs6K[Ns6]jS +rU9dUs7-$Xrq$*\q"=CTj7hp8qYC$bp&"U`qYfg\JcC<$JcG3=J,~> +JcC<$JcC<$TE"BZqu-Eiq>:-erV?#Xqo/NPqnqp?r58KOqo/QSs2Y&Ys2k;`rQG5bs3:Mfs3L_lr6bMls3phor71Vo +pXf,ipXSTZqpkYrqq(i"s4RA)s4dS/rS@M1!8mb5!o`.uro=%>!9O4Bs5sCGrosIJs6K[Ns6]jS +rU9dUs7-$Xrq$*\q"=CTj7hp8qYC$bp&"U`qYfg\JcC<$JcG3=J,~> +JcC<$JcC<$TE"BZqu-Eiq>:-erV?#Xqo/NPqnqp?r58KOqo/QSs2Y&Ys2k;`rQG5bs3:Mfs3L_lr6bMls3phor71Vo +pXf,ipXSTZqpkYrqq(i"s4RA)s4dS/rS@M1!8mb5!o`.uro=%>!9O4Bs5sCGrosIJs6K[Ns6]jS +rU9dUs7-$Xrq$*\q"=CTj7hp8qYC$bp&"U`qYfg\JcC<$JcG3=J,~> +JcC<$JcC<$T)\9Yqu-Eiq>:*drqZBbrV-crltGd +qof#^rlP&Yrl>#Xq8N3Kp;?aFqSiHRrl=rXs2k;`rQG5bs3:Jes3L_lrR(YnrmUbormgtuhq.YS +ma_3cq:GVurn78(rnIJ.rn[V2s53h6s5F";ro4(@jlQL(s5sCGrosIJs6K[Ns6]jSrU9dUs7-$X +rq$-]q"=LWmJ#T7q>'m`p&"U`qYfd[JcC<$JcG0 +JcC<$JcC<$T)\9Yqu-Eiq>:*drqZBbrV-crltGd +qof#^rlP&Yrl>#Xq8N3Kp;?aFqSiHRrl=rXs2k;`rQG5bs3:Jes3L_lrR(YnrmUbormgtuhq.YS +ma_3cq:GVurn78(rnIJ.rn[V2s53h6s5F";ro4(@jlQL(s5sCGrosIJs6K[Ns6]jSrU9dUs7-$X +rq$-]q"=LWmJ#T7q>'m`p&"U`qYfd[JcC<$JcG0 +JcC<$JcC<$T)\9Yqu-Eiq>:*drqZBbrV-crltGd +qof#^rlP&Yrl>#Xq8N3Kp;?aFqSiHRrl=rXs2k;`rQG5bs3:Jes3L_lrR(YnrmUbormgtuhq.YS +ma_3cq:GVurn78(rnIJ.rn[V2s53h6s5F";ro4(@jlQL(s5sCGrosIJs6K[Ns6]jSrU9dUs7-$X +rq$-]q"=LWmJ#T7q>'m`p&"U`qYfd[JcC<$JcG0 +JcC<$JcC<$ScA-Wqu-Hjq"t$drV?9arqHBbq=X[Xr:BUPq!n%HnF-;CrU'LKrp0ULr9=7Fs6'@C +s5j:Aro=%'j_o_\L_qYfd[JcC<$JcG-;J,~> +JcC<$JcC<$ScA-Wqu-Hjq"t$drV?9arqHBbq=X[Xr:BUPq!n%HnF-;CrU'LKrp0ULr9=7Fs6'@C +s5j:Aro=%'j_o_\L_qYfd[JcC<$JcG-;J,~> +JcC<$JcC<$ScA-Wqu-Hjq"t$drV?9arqHBbq=X[Xr:BUPq!n%HnF-;CrU'LKrp0ULr9=7Fs6'@C +s5j:Aro=%'j_o_\L_qYfd[JcC<$JcG-;J,~> +JcC<$JcC<$SH&$Vqu-Hjq"t$drV?9arV-9aq"=RWr:BLMp$qbFo^DbHrU'LKs6K[LrTX@Gs6'@C +s5a7ArT!q;!9*n7!oMkkrS7P1gY;\\s4RG)rR_)#rmgqrrR:_nhpM5Im*kgZq9f2grQkDerltGd +r6,)^rlP&YrQ"fTn&>4ErQ"fVs2k8_rQG5bs3:Jes3L_lrR(Yns3pnqs4.,"qUbYtkLoX_jOa=^ +rRq)%s4dP.rS@M1s53h6s5F";ro=%>s5j7B!pAe2rosIJ!:0UMs6TgSrU9dUs7-$Xs7?6^qXsd[ +qY/M7p\FX]oDAC^q>K[ZJcC<$JcG*:J,~> +JcC<$JcC<$SH&$Vqu-Hjq"t$drV?9arV-9aq"=RWr:BLMp$qbFo^DbHrU'LKs6K[LrTX@Gs6'@C +s5a7ArT!q;!9*n7!oMkkrS7P1gY;\\s4RG)rR_)#rmgqrrR:_nhpM5Im*kgZq9f2grQkDerltGd +r6,)^rlP&YrQ"fTn&>4ErQ"fVs2k8_rQG5bs3:Jes3L_lrR(Yns3pnqs4.,"qUbYtkLoX_jOa=^ +rRq)%s4dP.rS@M1s53h6s5F";ro=%>s5j7B!pAe2rosIJ!:0UMs6TgSrU9dUs7-$Xs7?6^qXsd[ +qY/M7p\FX]oDAC^q>K[ZJcC<$JcG*:J,~> +JcC<$JcC<$SH&$Vqu-Hjq"t$drV?9arV-9aq"=RWr:BLMp$qbFo^DbHrU'LKs6K[LrTX@Gs6'@C +s5a7ArT!q;!9*n7!oMkkrS7P1gY;\\s4RG)rR_)#rmgqrrR:_nhpM5Im*kgZq9f2grQkDerltGd +r6,)^rlP&YrQ"fTn&>4ErQ"fVs2k8_rQG5bs3:Jes3L_lrR(Yns3pnqs4.,"qUbYtkLoX_jOa=^ +rRq)%s4dP.rS@M1s53h6s5F";ro=%>s5j7B!pAe2rosIJ!:0UMs6TgSrU9dUs7-$Xs7?6^qXsd[ +qY/M7p\FX]oDAC^q>K[ZJcC<$JcG*:J,~> +JcC<$JcC<$S,_pUqu-Hjq"t!crV?9arV-6`q"=OVqt'4Gp$qkIp[A+LrU'OLs6K[LrTX@Gs6'@C +!p/M(rSmt=iSjan!oMkkrS7P1gY;\\s4RG)r7Cu"rmgkprR:Sjo[3E]q:"KUqpYMlqU,;hs3LSf +rltJeqoeu]rlOuWqoAK[ZJcC<$JcG$8J,~> +JcC<$JcC<$S,_pUqu-Hjq"t!crV?9arV-6`q"=OVqt'4Gp$qkIp[A+LrU'OLs6K[LrTX@Gs6'@C +!p/M(rSmt=iSjan!oMkkrS7P1gY;\\s4RG)r7Cu"rmgkprR:Sjo[3E]q:"KUqpYMlqU,;hs3LSf +rltJeqoeu]rlOuWqoAK[ZJcC<$JcG$8J,~> +JcC<$JcC<$S,_pUqu-Hjq"t!crV?9arV-6`q"=OVqt'4Gp$qkIp[A+LrU'OLs6K[LrTX@Gs6'@C +!p/M(rSmt=iSjan!oMkkrS7P1gY;\\s4RG)r7Cu"rmgkprR:Sjo[3E]q:"KUqpYMlqU,;hs3LSf +rltJeqoeu]rlOuWqoAK[ZJcC<$JcG$8J,~> +JcC<$JcC<$S,_pUqYg?ip\XpcrV?6`rV-6`p\"FUqX`qAq!n7Nq!\4MrpBXMs6K[LrTX@Gs6'CD +s5j:Aro=%K[ZJcC<$JcG!7J,~> +JcC<$JcC<$S,_pUqYg?ip\XpcrV?6`rV-6`p\"FUqX`qAq!n7Nq!\4MrpBXMs6K[LrTX@Gs6'CD +s5j:Aro=%K[ZJcC<$JcG!7J,~> +JcC<$JcC<$S,_pUqYg?ip\XpcrV?6`rV-6`p\"FUqX`qAq!n7Nq!\4MrpBXMs6K[LrTX@Gs6'CD +s5j:Aro=%K[ZJcC<$JcG!7J,~> +JcC<$JcC<$RK)^Squ-Eiq"t!crV?6`rV-6`p%A1Rp[dV>qsjURq="=Ns6]aNs6K[LrTOCIkNDg+ +s5j:Aro=%,qq_;/ +rnm\4s5F";ro=%>s5j7Bs6'FGrosIJ!:0UM!q#FDrU9dUs7-'Ys7?6^qt9p]rV,jWiVE*An,)qY +q>KXYJcC<$JcFs6J,~> +JcC<$JcC<$RK)^Squ-Eiq"t!crV?6`rV-6`p%A1Rp[dV>qsjURq="=Ns6]aNs6K[LrTOCIkNDg+ +s5j:Aro=%,qq_;/ +rnm\4s5F";ro=%>s5j7Bs6'FGrosIJ!:0UM!q#FDrU9dUs7-'Ys7?6^qt9p]rV,jWiVE*An,)qY +q>KXYJcC<$JcFs6J,~> +JcC<$JcC<$RK)^Squ-Eiq"t!crV?6`rV-6`p%A1Rp[dV>qsjURq="=Ns6]aNs6K[LrTOCIkNDg+ +s5j:Aro=%,qq_;/ +rnm\4s5F";ro=%>s5j7Bs6'FGrosIJ!:0UM!q#FDrU9dUs7-'Ys7?6^qt9p]rV,jWiVE*An,)qY +q>KXYJcC<$JcFs6J,~> +JcC<$JcC<$RK)[Rqu-Eip\Xpcr;$-_r:g-_o_%tNo^hJ@r:0aTqX=FOs6]aNs6K^MrTX@Gs6'@C +!p/M(rSmt=iSjans5*h5rS@M/rnID*rn7>(qUb\sqpk)`q:5;lkL]U^rRLbormUkpr6bMjs3LSf +rltGdq9/ZXo#^dOqTJl^rltDerm1VkrR(Yns3pqrs4./#r7Cu$rn72&rS.8*lJ;9kptP,gqqM)) +qq_8.s53b4s5F";rT!q=!9O1As5sCGrTOCKlg+Q:s6]jSrU9dUs7-'Ys7?6^r:U$^rV,sZkkXQ@ +mJH_Wq#0OXJcC<$JcFp5J,~> +JcC<$JcC<$RK)[Rqu-Eip\Xpcr;$-_r:g-_o_%tNo^hJ@r:0aTqX=FOs6]aNs6K^MrTX@Gs6'@C +!p/M(rSmt=iSjans5*h5rS@M/rnID*rn7>(qUb\sqpk)`q:5;lkL]U^rRLbormUkpr6bMjs3LSf +rltGdq9/ZXo#^dOqTJl^rltDerm1VkrR(Yns3pqrs4./#r7Cu$rn72&rS.8*lJ;9kptP,gqqM)) +qq_8.s53b4s5F";rT!q=!9O1As5sCGrTOCKlg+Q:s6]jSrU9dUs7-'Ys7?6^r:U$^rV,sZkkXQ@ +mJH_Wq#0OXJcC<$JcFp5J,~> +JcC<$JcC<$RK)[Rqu-Eip\Xpcr;$-_r:g-_o_%tNo^hJ@r:0aTqX=FOs6]aNs6K^MrTX@Gs6'@C +!p/M(rSmt=iSjans5*h5rS@M/rnID*rn7>(qUb\sqpk)`q:5;lkL]U^rRLbormUkpr6bMjs3LSf +rltGdq9/ZXo#^dOqTJl^rltDerm1VkrR(Yns3pqrs4./#r7Cu$rn72&rS.8*lJ;9kptP,gqqM)) +qq_8.s53b4s5F";rT!q=!9O1As5sCGrTOCKlg+Q:s6]jSrU9dUs7-'Ys7?6^r:U$^rV,sZkkXQ@ +mJH_Wq#0OXJcC<$JcFp5J,~> +JcC<$JcC<$R/cRQqu-Eip\Xmbr;$-_qtL$^nb)SIoCMPDrUKjUqsXOPs6]aNs6K^MrTX@Gs6'CD +s5j:Aro=%cs3L_lrR(Vms3pqrs4./#rR_)%rn75'rnID,g>2PZmb@Woq;)&,rnmY3 +s5F";rT!q=s5j7Bs6'FGrosIJs6K[Ns6]jSrU0gWnaZPJs7?9_qt9s^rV-$\p%dPBl21;Sq#0LW +JcC<$JcFm4J,~> +JcC<$JcC<$R/cRQqu-Eip\Xmbr;$-_qtL$^nb)SIoCMPDrUKjUqsXOPs6]aNs6K^MrTX@Gs6'CD +s5j:Aro=%cs3L_lrR(Vms3pqrs4./#rR_)%rn75'rnID,g>2PZmb@Woq;)&,rnmY3 +s5F";rT!q=s5j7Bs6'FGrosIJs6K[Ns6]jSrU0gWnaZPJs7?9_qt9s^rV-$\p%dPBl21;Sq#0LW +JcC<$JcFm4J,~> +JcC<$JcC<$R/cRQqu-Eip\Xmbr;$-_qtL$^nb)SIoCMPDrUKjUqsXOPs6]aNs6K^MrTX@Gs6'CD +s5j:Aro=%cs3L_lrR(Vms3pqrs4./#rR_)%rn75'rnID,g>2PZmb@Woq;)&,rnmY3 +s5F";rT!q=s5j7Bs6'FGrosIJs6K[Ns6]jSrU0gWnaZPJs7?9_qt9s^rV-$\p%dPBl21;Sq#0LW +JcC<$JcFm4J,~> +JcC<$JcC<$R/cRQqYg(rnIG-q;(i&q;:o&nD3Thp"fW(rnmV2 +s5F";rT!q=s5j4As6'FGrosIJs6K[Ns6]jSrpTmVs7-$Xs7?9_r:U$^rqH0^q>'(Ij88TKq#0IV +JcC<$JcFj3J,~> +JcC<$JcC<$R/cRQqYg(rnIG-q;(i&q;:o&nD3Thp"fW(rnmV2 +s5F";rT!q=s5j4As6'FGrosIJs6K[Ns6]jSrpTmVs7-$Xs7?9_r:U$^rqH0^q>'(Ij88TKq#0IV +JcC<$JcFj3J,~> +JcC<$JcC<$R/cRQqYg(rnIG-q;(i&q;:o&nD3Thp"fW(rnmV2 +s5F";rT!q=s5j4As6'FGrosIJs6K[Ns6]jSrpTmVs7-$Xs7?9_r:U$^rqH0^q>'(Ij88TKq#0IV +JcC<$JcFj3J,~> +JcC<$JcC<$QN-@Oqu-EipA=dar;$']qY0j[kk4T?q=FCPrUKmVr9sXQs6]dOs6K^MrTX@Gs6'CD +s5j:ArT!q;s5Et8s53h4rS@J.s4dG)rRq,$kL]O^q:Y&eqq:r#qUb_trmgnqs3ptqqpGGjrQk>c +r6=ZRr6>)`rm1SjrR(Vms3pqrs4./#rR_)%rn78(rnIG-qq_2,q;:o(pYYi(i8+=frnmV2ro*n: +r8[h +JcC<$JcC<$QN-@Oqu-EipA=dar;$']qY0j[kk4T?q=FCPrUKmVr9sXQs6]dOs6K^MrTX@Gs6'CD +s5j:ArT!q;s5Et8s53h4rS@J.s4dG)rRq,$kL]O^q:Y&eqq:r#qUb_trmgnqs3ptqqpGGjrQk>c +r6=ZRr6>)`rm1SjrR(Vms3pqrs4./#rR_)%rn78(rnIG-qq_2,q;:o(pYYi(i8+=frnmV2ro*n: +r8[h +JcC<$JcC<$QN-@Oqu-EipA=dar;$']qY0j[kk4T?q=FCPrUKmVr9sXQs6]dOs6K^MrTX@Gs6'CD +s5j:ArT!q;s5Et8s53h4rS@J.s4dG)rRq,$kL]O^q:Y&eqq:r#qUb_trmgnqs3ptqqpGGjrQk>c +r6=ZRr6>)`rm1SjrR(Vms3pqrs4./#rR_)%rn78(rnIG-qq_2,q;:o(pYYi(i8+=frnmV2ro*n: +r8[h +JcC<$JcC<$Q2g7NqYgr:B^Srpg!Wr9s[RrpB[Ns6K^MrTOCIkNDg+ +s5j:ArSmt=iSj^ms53k5r8%D.rnI8&r7U>eq:XHTrRq2&qq(hurmgqrrmUkpr6bJirm1>ao$-pS +rm1SjqpGGls3pqrrmh&"rR_)%s4R>(s4dS/qq_5-rSQVmqVV))n_O&ur87A/ro*n:r8[h +JcC<$JcC<$Q2g7NqYgr:B^Srpg!Wr9s[RrpB[Ns6K^MrTOCIkNDg+ +s5j:ArSmt=iSj^ms53k5r8%D.rnI8&r7U>eq:XHTrRq2&qq(hurmgqrrmUkpr6bJirm1>ao$-pS +rm1SjqpGGls3pqrrmh&"rR_)%s4R>(s4dS/qq_5-rSQVmqVV))n_O&ur87A/ro*n:r8[h +JcC<$JcC<$Q2g7NqYgr:B^Srpg!Wr9s[RrpB[Ns6K^MrTOCIkNDg+ +s5j:ArSmt=iSj^ms53k5r8%D.rnI8&r7U>eq:XHTrRq2&qq(hurmgqrrmUkpr6bJirm1>ao$-pS +rm1SjqpGGls3pqrrmh&"rR_)%s4R>(s4dS/qq_5-rSQVmqVV))n_O&ur87A/ro*n:r8[h +JcC<$JcC<$Q2g4MqYg +JcC<$JcC<$Q2g4MqYg +JcC<$JcC<$Q2g4MqYg +JcC<$JcC<$PlL+LqYg9gpA=a`qt]gXp\44OlLk)IrU]mVrpg!Wr9s[Rs6]dOs6K^MrTX@Gs6'@C +!p/M(rT!q;ro*h6s53h4qq_8,r7g/`qV1i$n(miqr7h)%rn7;'r7Cr!rmgqrrmUkpqU,5fps8l` +ps8ocqU,>krmUeps4./#rR_)%s4R>(s4dS/r8%A/rnmS1qr-u&q;Lf#o\]?"rSdb8qr@_;roO+@ +s6'FGrTX@Is6KXM!q#FDrU9dUs7-'Ys7?6^r:U*`rqH6`r;$3cd/3D3pAO.QJcC<$JcF[.J,~> +JcC<$JcC<$PlL+LqYg9gpA=a`qt]gXp\44OlLk)IrU]mVrpg!Wr9s[Rs6]dOs6K^MrTX@Gs6'@C +!p/M(rT!q;ro*h6s53h4qq_8,r7g/`qV1i$n(miqr7h)%rn7;'r7Cr!rmgqrrmUkpqU,5fps8l` +ps8ocqU,>krmUeps4./#rR_)%s4R>(s4dS/r8%A/rnmS1qr-u&q;Lf#o\]?"rSdb8qr@_;roO+@ +s6'FGrTX@Is6KXM!q#FDrU9dUs7-'Ys7?6^r:U*`rqH6`r;$3cd/3D3pAO.QJcC<$JcF[.J,~> +JcC<$JcC<$PlL+LqYg9gpA=a`qt]gXp\44OlLk)IrU]mVrpg!Wr9s[Rs6]dOs6K^MrTX@Gs6'@C +!p/M(rT!q;ro*h6s53h4qq_8,r7g/`qV1i$n(miqr7h)%rn7;'r7Cr!rmgqrrmUkpqU,5fps8l` +ps8ocqU,>krmUeps4./#rR_)%s4R>(s4dS/r8%A/rnmS1qr-u&q;Lf#o\]?"rSdb8qr@_;roO+@ +s6'FGrTX@Is6KXM!q#FDrU9dUs7-'Ys7?6^r:U*`rqH6`r;$3cd/3D3pAO.QJcC<$JcF[.J,~> +JcC<$JcC<$P5jnJqYg +JcC<$JcC<$P5jnJqYg +JcC<$JcC<$P5jnJqYg +JcC<$JcC<$OoOeIqYg9go_\O^qYBLQn+ZJJp%A:UrU]pWrpg$Xr9s[Rs6]dOs6K^MrTX@Gs6'@C +s5j:ArT!q;ro*e5rnm_3ptbc$p=o>so%iNdptbo(rnI>(rn7>(qq(hus4."rrR:_njjF%TrR:\o +rmh&"rR_&$s4RA)s4dS/r8%D0s53_3ro*h8h;e@kp>Pc(pu2/1qW%S9roO+@roa=FrTX@Is6KXM +s6]jSrU9dUs7-'Ys7?9_r:U'_rqH9arV?BfiVV[5oDRbLJcC<$JcFR+J,~> +JcC<$JcC<$OoOeIqYg9go_\O^qYBLQn+ZJJp%A:UrU]pWrpg$Xr9s[Rs6]dOs6K^MrTX@Gs6'@C +s5j:ArT!q;ro*e5rnm_3ptbc$p=o>so%iNdptbo(rnI>(rn7>(qq(hus4."rrR:_njjF%TrR:\o +rmh&"rR_&$s4RA)s4dS/r8%D0s53_3ro*h8h;e@kp>Pc(pu2/1qW%S9roO+@roa=FrTX@Is6KXM +s6]jSrU9dUs7-'Ys7?9_r:U'_rqH9arV?BfiVV[5oDRbLJcC<$JcFR+J,~> +JcC<$JcC<$OoOeIqYg9go_\O^qYBLQn+ZJJp%A:UrU]pWrpg$Xr9s[Rs6]dOs6K^MrTX@Gs6'@C +s5j:ArT!q;ro*e5rnm_3ptbc$p=o>so%iNdptbo(rnI>(rn7>(qq(hus4."rrR:_njjF%TrR:\o +rmh&"rR_&$s4RA)s4dS/r8%D0s53_3ro*h8h;e@kp>Pc(pu2/1qW%S9roO+@roa=FrTX@Is6KXM +s6]jSrU9dUs7-'Ys7?9_r:U'_rqH9arV?BfiVV[5oDRbLJcC<$JcFR+J,~> +JcC<$JcC<$OT4\Hq>L0fo_\L]q>'4Kn+ZVNp\"LWrq$$Xs7-*XrU9aRs6]dOs6K^MrTX@Gs6'@C +s5j:ArT!n:s5Ek5rnm\2oA05tn(misp##Z)pYYo*q;)&*rnIA)rn7;'r7Cr!rmgkprR:Ylo$R?_ +rR:Ynrmh&"r7Cu$s4R>(s4dS/rS@J0s53b4ro*k9puCZ#o&KH'pYko,puDA7roO%>s6'FGr9=7H +s6KXMs6]jSrU9dUs7-'Ys7?9_r:U'_s7cBbrV?BflhfH7nbqPJJcC<$JcFL)J,~> +JcC<$JcC<$OT4\Hq>L0fo_\L]q>'4Kn+ZVNp\"LWrq$$Xs7-*XrU9aRs6]dOs6K^MrTX@Gs6'@C +s5j:ArT!n:s5Ek5rnm\2oA05tn(misp##Z)pYYo*q;)&*rnIA)rn7;'r7Cr!rmgkprR:Ylo$R?_ +rR:Ynrmh&"r7Cu$s4R>(s4dS/rS@J0s53b4ro*k9puCZ#o&KH'pYko,puDA7roO%>s6'FGr9=7H +s6KXMs6]jSrU9dUs7-'Ys7?9_r:U'_s7cBbrV?BflhfH7nbqPJJcC<$JcFL)J,~> +JcC<$JcC<$OT4\Hq>L0fo_\L]q>'4Kn+ZVNp\"LWrq$$Xs7-*XrU9aRs6]dOs6K^MrTX@Gs6'@C +s5j:ArT!n:s5Ek5rnm\2oA05tn(misp##Z)pYYo*q;)&*rnIA)rn7;'r7Cr!rmgkprR:Ylo$R?_ +rR:Ynrmh&"r7Cu$s4R>(s4dS/rS@J0s53b4ro*k9puCZ#o&KH'pYko,puDA7roO%>s6'FGr9=7H +s6KXMs6]jSrU9dUs7-'Ys7?9_r:U'_s7cBbrV?BflhfH7nbqPJJcC<$JcFL)J,~> +JcC<$JcC<$O8nSGq>L0foDA@[q"`nDo_84Uq"=UXrq$'Yrpg$Xr9s[Rs6]dOs6K^MrTX@Gs6'=B +s5j:Ar8[h:ro*b4rSRP0k2#mjqVU>kr87J0qq_8,rnIA)rn7;'r7Cr!rRL_nqU>,cqpYAjrmh#! +r7Cu$s4RA)rnIJ.rS@M1s53b4ro*k9qW%M7lK.j&n)O-$o],o2rT3q=s6'CFrTX@Is6KXMs6]gR +rU9dUs7-'Ys7?9_r:U'_rqH +JcC<$JcC<$O8nSGq>L0foDA@[q"`nDo_84Uq"=UXrq$'Yrpg$Xr9s[Rs6]dOs6K^MrTX@Gs6'=B +s5j:Ar8[h:ro*b4rSRP0k2#mjqVU>kr87J0qq_8,rnIA)rn7;'r7Cr!rRL_nqU>,cqpYAjrmh#! +r7Cu$s4RA)rnIJ.rS@M1s53b4ro*k9qW%M7lK.j&n)O-$o],o2rT3q=s6'CFrTX@Is6KXMs6]gR +rU9dUs7-'Ys7?9_r:U'_rqH +JcC<$JcC<$O8nSGq>L0foDA@[q"`nDo_84Uq"=UXrq$'Yrpg$Xr9s[Rs6]dOs6K^MrTX@Gs6'=B +s5j:Ar8[h:ro*b4rSRP0k2#mjqVU>kr87J0qq_8,rnIA)rn7;'r7Cr!rRL_nqU>,cqpYAjrmh#! +r7Cu$s4RA)rnIJ.rS@M1s53b4ro*k9qW%M7lK.j&n)O-$o],o2rT3q=s6'CFrTX@Is6KXMs6]gR +rU9dUs7-'Ys7?9_r:U'_rqH +JcC<$JcC<$O8nMEq>L0fo)&4YpA*S?q"O^[q"=XYrq$'Yrpg$Xr9s[Rs6]dOs6K^MrTX@Gs6'=B +s5j:Ar8[e9ro*\2r86bqq;:`#n_s0!rSRV2qq_8,s4dG)rn7>(qq(etrmgViqpY2erRLnur7Cu$ +rn78(s4dS/r8%D0s53b4s5Et:qr@Y9r8m2*qW7P6jQ$-urT3q=roa=Fr9=7Hrp0OLs6]jSrU9dU +s7-$Xs7?9_r:U*`rqH9arqZKgo)%GEkPa<;JcC<$JcFF'J,~> +JcC<$JcC<$O8nMEq>L0fo)&4YpA*S?q"O^[q"=XYrq$'Yrpg$Xr9s[Rs6]dOs6K^MrTX@Gs6'=B +s5j:Ar8[e9ro*\2r86bqq;:`#n_s0!rSRV2qq_8,s4dG)rn7>(qq(etrmgViqpY2erRLnur7Cu$ +rn78(s4dS/r8%D0s53b4s5Et:qr@Y9r8m2*qW7P6jQ$-urT3q=roa=Fr9=7Hrp0OLs6]jSrU9dU +s7-$Xs7?9_r:U*`rqH9arqZKgo)%GEkPa<;JcC<$JcFF'J,~> +JcC<$JcC<$O8nMEq>L0fo)&4YpA*S?q"O^[q"=XYrq$'Yrpg$Xr9s[Rs6]dOs6K^MrTX@Gs6'=B +s5j:Ar8[e9ro*\2r86bqq;:`#n_s0!rSRV2qq_8,s4dG)rn7>(qq(etrmgViqpY2erRLnur7Cu$ +rn78(s4dS/r8%D0s53b4s5Et:qr@Y9r8m2*qW7P6jQ$-urT3q=roa=Fr9=7Hrp0OLs6]jSrU9dU +s7-$Xs7?9_r:U*`rqH9arqZKgo)%GEkPa<;JcC<$JcFF'J,~> +JcC<$JcC<$NW8>Dq>L-enb`+XoD.;=qY0p]qXsgZs7?-Ys7--Yr9s[Rs6]dOs6K^Mr9=7Fs6'@C +roO1@qr@\8ro*V0l/2*jq;Lc$qVh8.rnm_3qq_8,rnIA)rn7;'qq(etqpk)`r71bsqq(i"s4R>( +s4dS/rS@J0s53e5ro*n:qr@\:rT2ktq;qA3p#Gl/r8mb:roa:Er9=7Hs6KULs6]jSrU9dUs7-'Y +rq$0^r:U*`rqH +JcC<$JcC<$NW8>Dq>L-enb`+XoD.;=qY0p]qXsgZs7?-Ys7--Yr9s[Rs6]dOs6K^Mr9=7Fs6'@C +roO1@qr@\8ro*V0l/2*jq;Lc$qVh8.rnm_3qq_8,rnIA)rn7;'qq(etqpk)`r71bsqq(i"s4R>( +s4dS/rS@J0s53e5ro*n:qr@\:rT2ktq;qA3p#Gl/r8mb:roa:Er9=7Hs6KULs6]jSrU9dUs7-'Y +rq$0^r:U*`rqH +JcC<$JcC<$NW8>Dq>L-enb`+XoD.;=qY0p]qXsgZs7?-Ys7--Yr9s[Rs6]dOs6K^Mr9=7Fs6'@C +roO1@qr@\8ro*V0l/2*jq;Lc$qVh8.rnm_3qq_8,rnIA)rn7;'qq(etqpk)`r71bsqq(i"s4R>( +s4dS/rS@J0s53e5ro*n:qr@\:rT2ktq;qA3p#Gl/r8mb:roa:Er9=7Hs6KULs6]jSrU9dUs7-'Y +rq$0^r:U*`rqH +JcC<$JcC<$N;r2Bq>L-en,)hTmeQ#?qtL'_qXsj[rq$'Yrpg$XrU9aRs6]dOs6K^MrTX=Fs6'=B +s5j7@qr@\8r8HJiqr.A1m,S!&r8IM1rnm_3r8%A-s4dG)rn7;'q:GPqmFD-cqUb`!s4R>(rnIJ. +rS@M1rnm\4s5Et:r8[e;roNq;lK@^"pZ;)/puV;5roa:Eqs".Grp0OLs6]jSr9s[Ts7-'Yrq$0^ +r:U*`rqH +JcC<$JcC<$N;r2Bq>L-en,)hTmeQ#?qtL'_qXsj[rq$'Yrpg$XrU9aRs6]dOs6K^MrTX=Fs6'=B +s5j7@qr@\8r8HJiqr.A1m,S!&r8IM1rnm_3r8%A-s4dG)rn7;'q:GPqmFD-cqUb`!s4R>(rnIJ. +rS@M1rnm\4s5Et:r8[e;roNq;lK@^"pZ;)/puV;5roa:Eqs".Grp0OLs6]jSr9s[Ts7-'Yrq$0^ +r:U*`rqH +JcC<$JcC<$N;r2Bq>L-en,)hTmeQ#?qtL'_qXsj[rq$'Yrpg$XrU9aRs6]dOs6K^MrTX=Fs6'=B +s5j7@qr@\8r8HJiqr.A1m,S!&r8IM1rnm_3r8%A-s4dG)rn7;'q:GPqmFD-cqUb`!s4R>(rnIJ. +rS@M1rnm\4s5Et:r8[e;roNq;lK@^"pZ;)/puV;5roa:Eqs".Grp0OLs6]jSr9s[Ts7-'Yrq$0^ +r:U*`rqH +JcC<$JcC<$MuW)Aq#1!cn,)_QlM9iBr:g0`qXsj[rq$'Ys7-*XrU9dSs6]aNs6K^MrTX=Fs6'=B +roO.?qr@V6qr-o"q;M20h;eInrSdY3rnm_3r8%A-rnIA)rRq2&pXelbpt,Jsrn75's4dS/r8%D0 +s53b4s5F";r8[e;roO"=r9*A/q<.5/o]>`-rTF.Cqs".Grp0LKs6]jSrU9aTs7-'Ys7?6^r:U*` +rqH +JcC<$JcC<$MuW)Aq#1!cn,)_QlM9iBr:g0`qXsj[rq$'Ys7-*XrU9dSs6]aNs6K^MrTX=Fs6'=B +roO.?qr@V6qr-o"q;M20h;eInrSdY3rnm_3r8%A-rnIA)rRq2&pXelbpt,Jsrn75's4dS/r8%D0 +s53b4s5F";r8[e;roO"=r9*A/q<.5/o]>`-rTF.Cqs".Grp0LKs6]jSrU9aTs7-'Ys7?6^r:U*` +rqH +JcC<$JcC<$MuW)Aq#1!cn,)_QlM9iBr:g0`qXsj[rq$'Ys7-*XrU9dSs6]aNs6K^MrTX=Fs6'=B +roO.?qr@V6qr-o"q;M20h;eInrSdY3rnm_3r8%A-rnIA)rRq2&pXelbpt,Jsrn75's4dS/r8%D0 +s53b4s5F";r8[e;roO"=r9*A/q<.5/o]>`-rTF.Cqs".Grp0LKs6]jSrU9aTs7-'Ys7?6^r:U*` +rqH +JcC<$JcC<$M>ul?q#1!cm/-2HmJ6>Jr:g0`qt9s\rq$'Ys7--Yr9s[Rs6]dOrp0ULrTX=Fs6'=B +roO+>q;_A3m,@d"o&K&spZ)53ro*b4rnm_3r8%A-rnI>(rRq/%jk'I`rn72&s4dP.r8%D0s53e5 +ro*n:r8[hrTF+BlKS-.q<-`!r9+%Bqs"+Frp0LKs6]gRrU9dUrpfsXs7?6^r:U*`rqH +JcC<$JcC<$M>ul?q#1!cm/-2HmJ6>Jr:g0`qt9s\rq$'Ys7--Yr9s[Rs6]dOrp0ULrTX=Fs6'=B +roO+>q;_A3m,@d"o&K&spZ)53ro*b4rnm_3r8%A-rnI>(rRq/%jk'I`rn72&s4dP.r8%D0s53e5 +ro*n:r8[hrTF+BlKS-.q<-`!r9+%Bqs"+Frp0LKs6]gRrU9dUrpfsXs7?6^r:U*`rqH +JcC<$JcC<$M>ul?q#1!cm/-2HmJ6>Jr:g0`qt9s\rq$'Ys7--Yr9s[Rs6]dOrp0ULrTX=Fs6'=B +roO+>q;_A3m,@d"o&K&spZ)53ro*b4rnm_3r8%A-rnI>(rRq/%jk'I`rn72&s4dP.r8%D0s53e5 +ro*n:r8[hrTF+BlKS-.q<-`!r9+%Bqs"+Frp0LKs6]gRrU9dUrpfsXs7?6^r:U*`rqH +JcC<$JcC<$M#Z`=q#0sbl20`AoD/%Rr:g3aqXsm\rq$'Ys7-*XrU9dSrpB[Ns6K^Mr9=4Es6':A +roO+>p>bQ"o&KQ,l/hg'q;_J6ro*e5rnm_3qq_;-rS.2&rRq&"p"0&mrRq&$rnIJ.r8%D0rnm\4 +s5Et:rT!n +JcC<$JcC<$M#Z`=q#0sbl20`AoD/%Rr:g3aqXsm\rq$'Ys7-*XrU9dSrpB[Ns6K^Mr9=4Es6':A +roO+>p>bQ"o&KQ,l/hg'q;_J6ro*e5rnm_3qq_;-rS.2&rRq&"p"0&mrRq&$rnIJ.r8%D0rnm\4 +s5Et:rT!n +JcC<$JcC<$M#Z`=q#0sbl20`AoD/%Rr:g3aqXsm\rq$'Ys7-*XrU9dSrpB[Ns6K^Mr9=4Es6':A +roO+>p>bQ"o&KQ,l/hg'q;_J6ro*e5rnm_3qq_;-rS.2&rRq&"p"0&mrRq&$rnIJ.r8%D0rnm\4 +s5Et:rT!n +JcC<$JcC<$L]?T;p\jjaj88*;q"aXYrV-9aqt9s\s7?0Zrpg$Xr9s[Rs6]aNs6K^Mr9=4Eroa1@ +rT4"=hW+InqW6r'qrRe;qW%S7ro*b4s53h4qq_8,rnI5%q:YPqq:YStrnIG-r8%D0s53b4s5F"; +r8[h +JcC<$JcC<$L]?T;p\jjaj88*;q"aXYrV-9aqt9s\s7?0Zrpg$Xr9s[Rs6]aNs6K^Mr9=4Eroa1@ +rT4"=hW+InqW6r'qrRe;qW%S7ro*b4s53h4qq_8,rnI5%q:YPqq:YStrnIG-r8%D0s53b4s5F"; +r8[h +JcC<$JcC<$L]?T;p\jjaj88*;q"aXYrV-9aqt9s\s7?0Zrpg$Xr9s[Rs6]aNs6K^Mr9=4Eroa1@ +rT4"=hW+InqW6r'qrRe;qW%S7ro*b4s53h4qq_8,rnI5%q:YPqq:YStrnIG-r8%D0s53b4s5F"; +r8[h +JcC<$JcC<$LB$K:p\jg`gACC9q>'d[rV-9aqt:!]rq$'Ys7-*XrU9aRs6]aNs6K^Mqs"+Droa.? +rT3n:mc4-(qW6GnrT4"=qr@\8ro*b4s53h4qq_5+rS-tuqq:SprnID,r8%A/s53b4s5F";r8[h< +s5j1@roa:Eq<@eAmHaT5nEKB)p$)G?rp0IJrpB^Qr9s[Ts7-$Xrq$0^r:U'_s7cEcrV?Hhp\Xgb +p&2H#JcC<$JcEmmJ,~> +JcC<$JcC<$LB$K:p\jg`gACC9q>'d[rV-9aqt:!]rq$'Ys7-*XrU9aRs6]aNs6K^Mqs"+Droa.? +rT3n:mc4-(qW6GnrT4"=qr@\8ro*b4s53h4qq_5+rS-tuqq:SprnID,r8%A/s53b4s5F";r8[h< +s5j1@roa:Eq<@eAmHaT5nEKB)p$)G?rp0IJrpB^Qr9s[Ts7-$Xrq$0^r:U'_s7cEcrV?Hhp\Xgb +p&2H#JcC<$JcEmmJ,~> +JcC<$JcC<$LB$K:p\jg`gACC9q>'d[rV-9aqt:!]rq$'Ys7-*XrU9aRs6]aNs6K^Mqs"+Droa.? +rT3n:mc4-(qW6GnrT4"=qr@\8ro*b4s53h4qq_5+rS-tuqq:SprnID,r8%A/s53b4s5F";r8[h< +s5j1@roa:Eq<@eAmHaT5nEKB)p$)G?rp0IJrpB^Qr9s[Ts7-$Xrq$0^r:U'_s7cEcrV?Hhp\Xgb +p&2H#JcC<$JcEmmJ,~> +JcC<$JcC<$K`C67pAO[^ebf%9qt^$^rV- +JcC<$JcC<$K`C67pAO[^ebf%9qt^$^rV- +JcC<$JcC<$K`C67pAO[^ebf%9qt^$^rV- +JcC<$JcC<$KE(*5p&4L[eGK(r8[e9ro*b4rnm_3qVD&(m+_HnqVD/-rnmY3ro*n:rT!n +JcC<$JcC<$KE(*5p&4L[eGK(r8[e9ro*b4rnm_3qVD&(m+_HnqVD/-rnmY3ro*n:rT!n +JcC<$JcC<$KE(*5p&4L[eGK(r8[e9ro*b4rnm_3qVD&(m+_HnqVD/-rnmY3ro*n:rT!n +JcC<$JcC<$KE('4o_n:Webf4>r;$-_rqHEcqt9s\s7?0Zrpg$Xr9sXQs6]aNrp0RKqs"(Cr9)r! +qWI\8q:'eq#.c&JcC<$JcERd +J,~> +JcC<$JcC<$KE('4o_n:Webf4>r;$-_rqHEcqt9s\s7?0Zrpg$Xr9sXQs6]aNrp0RKqs"(Cr9)r! +qWI\8q:'eq#.c&JcC<$JcERd +J,~> +JcC<$JcC<$KE('4o_n:Webf4>r;$-_rqHEcqt9s\s7?0Zrpg$Xr9sXQs6]aNrp0RKqs"(Cr9)r! +qWI\8q:'eq#.c&JcC<$JcERd +J,~> +JcC<$JcC<$JcFj2oDS(Sf_bOAr;$0`rqHEcqt9s\s7?0Zrpg$Xr9sXQs6]^Mrp0RKqW[qAqWI8. +q<.V +JcC<$JcC<$JcFj2oDS(Sf_bOAr;$0`rqHEcqt9s\s7?0Zrpg$Xr9sXQs6]^Mrp0RKqW[qAqWI8. +q<.V +JcC<$JcC<$JcFj2oDS(Sf_bOAr;$0`rqHEcqt9s\s7?0Zrpg$Xr9sXQs6]^Mrp0RKqW[qAqWI8. +q<.V +JcC<$JcC<$JcGcMir8NIjo"3:qYL0dq=ss`rq?6^rq-6^qssdWrp]jSs6fmRqs==JrTa4CqWR8. +q<7G7kN_j,rTO7DqW@h>roEt:ro3q9qV_>0qqgbsqqh;/qr%J4ro3k9s5a4Ar9"%Broj:Erp'LK +qX".IkO/05mHjW6na-5ArU0ONrp]pWr:9jYrq--]rq??cqtU0drVH?equ$ +JcC<$JcC<$JcGcMir8NIjo"3:qYL0dq=ss`rq?6^rq-6^qssdWrp]jSs6fmRqs==JrTa4CqWR8. +q<7G7kN_j,rTO7DqW@h>roEt:ro3q9qV_>0qqgbsqqh;/qr%J4ro3k9s5a4Ar9"%Broj:Erp'LK +qX".IkO/05mHjW6na-5ArU0ONrp]pWr:9jYrq--]rq??cqtU0drVH?equ$ +JcC<$JcC<$JcGcMir8NIjo"3:qYL0dq=ss`rq?6^rq-6^qssdWrp]jSs6fmRqs==JrTa4CqWR8. +q<7G7kN_j,rTO7DqW@h>roEt:ro3q9qV_>0qqgbsqqh;/qr%J4ro3k9s5a4Ar9"%Broj:Erp'LK +qX".IkO/05mHjW6na-5ArU0ONrp]pWr:9jYrq--]rq??cqtU0drVH?equ$ +JcC<$JcC<$JcG]KiVr +JcC<$JcC<$JcG]KiVr +JcC<$JcC<$JcG]KiVr +JcC<$JcC<$JcGZJi;W*Ai;E'@r;-?eqY:'arq?6^rq-6^qssdWrp]jSrpKdQqX"1Hr9E&$qWdnB +l0S<5rTa7Droj@Eqr[n>roEt:rSme7pYbPup>Gr/ro3h8s5a1@r9"%Broj:Es6BULqs=:KrU/S3 +qfJcC<$YQ'+~> +JcC<$JcC<$JcGZJi;W*Ai;E'@r;-?eqY:'arq?6^rq-6^qssdWrp]jSrpKdQqX"1Hr9E&$qWdnB +l0S<5rTa7Droj@Eqr[n>roEt:rSme7pYbPup>Gr/ro3h8s5a1@r9"%Broj:Es6BULqs=:KrU/S3 +qfJcC<$YQ'+~> +JcC<$JcC<$JcGZJi;W*Ai;E'@r;-?eqY:'arq?6^rq-6^qssdWrp]jSrpKdQqX"1Hr9E&$qWdnB +l0S<5rTa7Droj@Eqr[n>roEt:rSme7pYbPup>Gr/ro3h8s5a1@r9"%Broj:Es6BULqs=:KrU/S3 +qfJcC<$YQ'+~> +JcC<$JcC<$JcGWIh>ZL6kPXoJr;-Bfq=ss`rq?9_rq-3]r:9jWrp]gRrpKdQqX".Gqs*A/qroEq9rSme7jP]spro3h8roF(?r9"%Broj=Frp'LKr9XCLrU0@Io^M>< +q!RA5qX4.IrUBgVqXXXWrq--]rq??cqY:'crVH?er;?EibPm(mJcC<$VuM8~> +JcC<$JcC<$JcGWIh>ZL6kPXoJr;-Bfq=ss`rq?9_rq-3]r:9jWrp]gRrpKdQqX".Gqs*A/qroEq9rSme7jP]spro3h8roF(?r9"%Broj=Frp'LKr9XCLrU0@Io^M>< +q!RA5qX4.IrUBgVqXXXWrq--]rq??cqY:'crVH?er;?EibPm(mJcC<$VuM8~> +JcC<$JcC<$JcGWIh>ZL6kPXoJr;-Bfq=ss`rq?9_rq-3]r:9jWrp]gRrpKdQqX".Gqs*A/qroEq9rSme7jP]spro3h8roF(?r9"%Broj=Frp'LKr9XCLrU0@Io^M>< +q!RA5qX4.IrUBgVqXXXWrq--]rq??cqY:'crVH?er;?EibPm(mJcC<$VuM8~> +JcC<$JcC<$JcGQGgA]q,nGMnTr;-BfqY:'arq?6^rq-3]r:9jWrp]gRrpKaPq<\"Ejm)^.na,Z1 +p?_bDrTa:Eroj@Eqr[n>roEn8rSm\4n_j<'r8RV6roF(?r9""As60CFrp'OLqs==LrpKOLk4%m/ +jmMg1rUBdUqssaXrUg![rq??cqtU-crqcEer;?EifD^@$JcC<$Rf@m~> +JcC<$JcC<$JcGQGgA]q,nGMnTr;-BfqY:'arq?6^rq-3]r:9jWrp]gRrpKaPq<\"Ejm)^.na,Z1 +p?_bDrTa:Eroj@Eqr[n>roEn8rSm\4n_j<'r8RV6roF(?r9""As60CFrp'OLqs==LrpKOLk4%m/ +jmMg1rUBdUqssaXrUg![rq??cqtU-crqcEer;?EifD^@$JcC<$Rf@m~> +JcC<$JcC<$JcGQGgA]q,nGMnTr;-BfqY:'arq?6^rq-3]r:9jWrp]gRrpKaPq<\"Ejm)^.na,Z1 +p?_bDrTa:Eroj@Eqr[n>roEn8rSm\4n_j<'r8RV6roF(?r9""As60CFrp'OLqs==LrpKOLk4%m/ +jmMg1rUBdUqssaXrUg![rq??cqtU-crqcEer;?EifD^@$JcC<$Rf@m~> +JcC<$JcC<$JcGKEfDaP'o_e@YrVHKgqY:$`rq?9_rq-3]qssaVrp]gRrU0XOp[%Pq!@tFrp'CFroj@Eqr[n>rT*e7qVq&(qr7G3rT*t>r9""As60CFrp'OLqs=@MrU0LMr:&t@ +q!dY=q!RY?rUBdUq==OVrq-*\rq??cqY:'crVH?er;?Eih>W!*JcC<$P5g%~> +JcC<$JcC<$JcGKEfDaP'o_e@YrVHKgqY:$`rq?9_rq-3]qssaVrp]gRrU0XOp[%Pq!@tFrp'CFroj@Eqr[n>rT*e7qVq&(qr7G3rT*t>r9""As60CFrp'OLqs=@MrU0LMr:&t@ +q!dY=q!RY?rUBdUq==OVrq-*\rq??cqY:'crVH?er;?Eih>W!*JcC<$P5g%~> +JcC<$JcC<$JcGKEfDaP'o_e@YrVHKgqY:$`rq?9_rq-3]qssaVrp]gRrU0XOp[%Pq!@tFrp'CFroj@Eqr[n>rT*e7qVq&(qr7G3rT*t>r9""As60CFrp'OLqs=@MrU0LMr:&t@ +q!dY=q!RY?rUBdUq==OVrq-*\rq??cqY:'crVH?er;?Eih>W!*JcC<$P5g%~> +JcC<$JcC<$JcGHDd/Mo#p\a[\rVHKgqY:'arq?6^rq-3]qssaVrp]dQrU0XOna-#9md0f;p[7YA +qqr[qAroj:Es6BULr9XFMrpKXOr:'URmIL&B +q=*5/qsaORqXXUVrq-'[rq??cqtU-crqcEer;?Hjhu83,JcC<$NrOV~> +JcC<$JcC<$JcGHDd/Mo#p\a[\rVHKgqY:'arq?6^rq-3]qssaVrp]dQrU0XOna-#9md0f;p[7YA +qqr[qAroj:Es6BULr9XFMrpKXOr:'URmIL&B +q=*5/qsaORqXXUVrq-'[rq??cqtU-crqcEer;?Hjhu83,JcC<$NrOV~> +JcC<$JcC<$JcGHDd/Mo#p\a[\rVHKgqY:'arq?6^rq-3]qssaVrp]dQrU0XOna-#9md0f;p[7YA +qqr[qAroj:Es6BULr9XFMrpKXOr:'URmIL&B +q=*5/qsaORqXXUVrq-'[rq??cqtU-crqcEer;?Hjhu83,JcC<$NrOV~> +JcC<$JcC<$JcG?A`r>3#q#'g^rVHKgqY:'arV$-]rq-3]qssaVrp]aPrU0RMi9^:,qX3A3r9jON +qX"4IrTa:Eroj@EqW@b +JcC<$JcC<$JcG?A`r>3#q#'g^rVHKgqY:'arV$-]rq-3]qssaVrp]aPrU0RMi9^:,qX3A3r9jON +qX"4IrTa:Eroj@EqW@b +JcC<$JcC<$JcG?A`r>3#q#'g^rVHKgqY:'arV$-]rq-3]qssaVrp]aPrU0RMi9^:,qX3A3r9jON +qX"4IrTa:Eroj@EqW@b +JcC<$JcC<$JcG<@^AdR!q>Bp_rVHKgqY:'arq?6^rq-3]qXXXUrUBXOqsO:In*Ki:q +JcC<$JcC<$JcG<@^AdR!q>Bp_rVHKgqY:'arq?6^rq-3]qXXXUrUBXOqsO:In*Ki:q +JcC<$JcC<$JcG<@^AdR!q>Bp_rVHKgqY:'arq?6^rq-3]qXXXUrUBXOqsO:In*Ki:q +JcC<$JcC<$JcG6>\c24!q>Bs`rVHKgqY:'arV$-]rq-3]qXXXUrUBRMqX3\:q!R\@l1"E8rU0XO +qX"4Irp'CFrTO7Dpu_G7n`9Q.q<%Y=roj:Erp'LKr9XFMrpK[Prp]mVp@@SAn+-#=rUBILp%&(Q +rUfpYrq? +JcC<$JcC<$JcG6>\c24!q>Bs`rVHKgqY:'arV$-]rq-3]qXXXUrUBRMqX3\:q!R\@l1"E8rU0XO +qX"4Irp'CFrTO7Dpu_G7n`9Q.q<%Y=roj:Erp'LKr9XFMrpK[Prp]mVp@@SAn+-#=rUBILp%&(Q +rUfpYrq? +JcC<$JcC<$JcG6>\c24!q>Bs`rVHKgqY:'arV$-]rq-3]qXXXUrUBRMqX3\:q!R\@l1"E8rU0XO +qX"4Irp'CFrTO7Dpu_G7n`9Q.q<%Y=roj:Erp'LKr9XFMrpK[Prp]mVp@@SAn+-#=rUBILp%&(Q +rUfpYrq? +JcC<$JcC<$JcG-;\Gl.!qY^'arVHKgqY:'arq?3]rq-3]qXXUTr:'CJkjJ!0q!dY?qXF:KrU0[P +qs==JrTa:ErTO4Cp?(i*p?)>:roj7Drp'LKr9XFMs6fdQrp]mVq""7PoCVbJmIK`9o()_MrUfpY +rV$6bqY:$brVH?er;?Hjm/DS9JcC<$JcGZJJ,~> +JcC<$JcC<$JcG-;\Gl.!qY^'arVHKgqY:'arq?3]rq-3]qXXUTr:'CJkjJ!0q!dY?qXF:KrU0[P +qs==JrTa:ErTO4Cp?(i*p?)>:roj7Drp'LKr9XFMs6fdQrp]mVq""7PoCVbJmIK`9o()_MrUfpY +rV$6bqY:$brVH?er;?Hjm/DS9JcC<$JcGZJJ,~> +JcC<$JcC<$JcG-;\Gl.!qY^'arVHKgqY:'arq?3]rq-3]qXXUTr:'CJkjJ!0q!dY?qXF:KrU0[P +qs==JrTa:ErTO4Cp?(i*p?)>:roj7Drp'LKr9XFMs6fdQrp]mVq""7PoCVbJmIK`9o()_MrUfpY +rV$6bqY:$brVH?er;?Hjm/DS9JcC<$JcGZJJ,~> +JcC<$JcC<$JcG!7\Gl4#qY^*brVHKgqY:'arV$-]rUg*\q==LSr:&8*q=+.KnacMGr:'ONrpKaP +qs==JrTa7DrTO4CiTC+%rTO.Crp'LKqs=@MrpK[Prp]pWq==FSk4JH?eaiV/rUfmXrq? +JcC<$JcC<$JcG!7\Gl4#qY^*brVHKgqY:'arV$-]rUg*\q==LSr:&8*q=+.KnacMGr:'ONrpKaP +qs==JrTa7DrTO4CiTC+%rTO.Crp'LKqs=@MrpK[Prp]pWq==FSk4JH?eaiV/rUfmXrq? +JcC<$JcC<$JcG!7\Gl4#qY^*brVHKgqY:'arV$-]rUg*\q==LSr:&8*q=+.KnacMGr:'ONrpKaP +qs==JrTa7DrTO4CiTC+%rTO.Crp'LKqs=@MrpK[Prp]pWq==FSk4JH?eaiV/rUfmXrq? +JcC<$JcC<$JcFm4\,Q1$qY^-cr;-Egq=ss`rV$-]rUg'[q==IRqs`M3q=+4MjRW6=r:'ONrpKdQ +qX"4Irp'=Dr94%@mH4 +JcC<$JcC<$JcFm4\,Q1$qY^-cr;-Egq=ss`rV$-]rUg'[q==IRqs`M3q=+4MjRW6=r:'ONrpKdQ +qX"4Irp'=Dr94%@mH4 +JcC<$JcC<$JcFm4\,Q1$qY^-cr;-Egq=ss`rV$-]rUg'[q==IRqs`M3q=+4MjRW6=r:'ONrpKdQ +qX"4Irp'=Dr94%@mH4 +JcC<$JcC<$JcFd1\Gl=&qY^*brVHKgqY:$`rq?3]rUg'[q""=Pq!db@p[J"Kg%,(2rUB[PrU0[P +qX"4IrTa4CqrmA/qrmk?rp'LKqs==LrpK[Prp]pWqXXUVr:Jq?q"44MoCDVHqt0XUr:^*`q=spa +rVH +JcC<$JcC<$JcFd1\Gl=&qY^*brVHKgqY:$`rq?3]rUg'[q""=Pq!db@p[J"Kg%,(2rUB[PrU0[P +qX"4IrTa4CqrmA/qrmk?rp'LKqs==LrpK[Prp]pWqXXUVr:Jq?q"44MoCDVHqt0XUr:^*`q=spa +rVH +JcC<$JcC<$JcFd1\Gl=&qY^*brVHKgqY:$`rq?3]rUg'[q""=Pq!db@p[J"Kg%,(2rUB[PrU0[P +qX"4IrTa4CqrmA/qrmk?rp'LKqs==LrpK[Prp]pWqXXUVr:Jq?q"44MoCDVHqt0XUr:^*`q=spa +rVH +JcC<$JcC<$JcF^/\Gl=&qu$3crVHKgq=ss`rV$*\rUg$Zp[\.Ml1"Kq=OCRr:^*`q=spar;-3cr;?Hj +n,@n +JcC<$JcC<$JcF^/\Gl=&qu$3crVHKgq=ss`rV$*\rUg$Zp[\.Ml1"Kq=OCRr:^*`q=spar;-3cr;?Hj +n,@n +JcC<$JcC<$JcF^/\Gl=&qu$3crVHKgq=ss`rV$*\rUg$Zp[\.Ml1"Kq=OCRr:^*`q=spar;-3cr;?Hj +n,@n +JcC<$JcC<$JcFL)^&Ij+qu$3crVHKgq=sp_rV$*\r:KsZo^_)5n+-/Cp[n4Op[\:QrUB[PrpKaP +qX"1HrT`5'rTa@IqX"4KrpK^Qrp]pWqXXUVrUfaTnFl5Ai:Q[7r:^'_q=sm`rVH +JcC<$JcC<$JcFL)^&Ij+qu$3crVHKgq=sp_rV$*\r:KsZo^_)5n+-/Cp[n4Op[\:QrUB[PrpKaP +qX"1HrT`5'rTa@IqX"4KrpK^Qrp]pWqXXUVrUfaTnFl5Ai:Q[7r:^'_q=sm`rVH +JcC<$JcC<$JcFL)^&Ij+qu$3crVHKgq=sp_rV$*\r:KsZo^_)5n+-/Cp[n4Op[\:QrUB[PrpKaP +qX"1HrT`5'rTa@IqX"4KrpK^Qrp]pWqXXUVrUfaTnFl5Ai:Q[7r:^'_q=sm`rVH +JcC<$JcC<$JcF=$_#F0.qu$3crVHKgq=sp_rV$'[r:KpYlLFrFkjnN?jn/HAq""CRrp]dQrU0[P +q<\%Fqs*D0r9F4GqX"4KrpK[Prp]pWqXXXWrUfgVjn@s3nFZ2Br:^'_q"Xg`r;-3cr;?Ein,@n< +JcC<$JcG?AJ,~> +JcC<$JcC<$JcF=$_#F0.qu$3crVHKgq=sp_rV$'[r:KpYlLFrFkjnN?jn/HAq""CRrp]dQrU0[P +q<\%Fqs*D0r9F4GqX"4KrpK[Prp]pWqXXXWrUfgVjn@s3nFZ2Br:^'_q"Xg`r;-3cr;?Ein,@n< +JcC<$JcG?AJ,~> +JcC<$JcC<$JcF=$_#F0.qu$3crVHKgq=sp_rV$'[r:KpYlLFrFkjnN?jn/HAq""CRrp]dQrU0[P +q<\%Fqs*D0r9F4GqX"4KrpK[Prp]pWqXXXWrUfgVjn@s3nFZ2Br:^'_q"Xg`r;-3cr;?Ein,@n< +JcC<$JcG?AJ,~> +JcC<$JcC<$JcEmmb5V89qu$3crVHKgq=sp_r:]sZqt0dWg@G%1q"3nFqXj^Wq""FSrUB[PrpKaP +q!@qEpZhS=pZh\Bq<\(IrpK[Prp]pWqXXXWrUfmXq=a7Np%Hi,qY'j]p\=^_r;-3cqu$?in,@n< +JcC<$JcG9?J,~> +JcC<$JcC<$JcEmmb5V89qu$3crVHKgq=sp_r:]sZqt0dWg@G%1q"3nFqXj^Wq""FSrUB[PrpKaP +q!@qEpZhS=pZh\Bq<\(IrpK[Prp]pWqXXXWrUfmXq=a7Np%Hi,qY'j]p\=^_r;-3cqu$?in,@n< +JcC<$JcG9?J,~> +JcC<$JcC<$JcEmmb5V89qu$3crVHKgq=sp_r:]sZqt0dWg@G%1q"3nFqXj^Wq""FSrUB[PrpKaP +q!@qEpZhS=pZh\Bq<\(IrpK[Prp]pWqXXXWrUfmXq=a7Np%Hi,qY'j]p\=^_r;-3cqu$?in,@n< +JcC<$JcG9?J,~> +JcC<$JcC<$JcELbe,K1Ar;? +JcC<$JcC<$JcELbe,K1Ar;? +JcC<$JcC<$JcELbe,K1Ar;? +JcC<$JcC<$JcE.Xh#@-Jr;? +J,~> +JcC<$JcC<$JcE.Xh#@-Jr;? +J,~> +JcC<$JcC<$JcE.Xh#@-Jr;? +J,~> +JcC<$JcC<$JcDtShu +JcC<$JcC<$JcDtShu +JcC<$JcC<$JcDtShu +JcC<$JcC<$JcDeNj8SoRqu$3cr;-Bfp\=[\r:]^Sk4J'6j7`0=rUg'[q==LSrUBXOr9jFKlg4K8 +r9jCLrp]mVqss^Wrq-$ZrV$-_f_G+5m.U/IoD&7Zr;--aqu$ +JcC<$JcC<$JcDeNj8SoRqu$3cr;-Bfp\=[\r:]^Sk4J'6j7`0=rUg'[q==LSrUBXOr9jFKlg4K8 +r9jCLrp]mVqss^Wrq-$ZrV$-_f_G+5m.U/IoD&7Zr;--aqu$ +JcC<$JcC<$JcDeNj8SoRqu$3cr;-Bfp\=[\r:]^Sk4J'6j7`0=rUg'[q==LSrUBXOr9jFKlg4K8 +r9jCLrp]mVqss^Wrq-$ZrV$-_f_G+5m.U/IoD&7Zr;--aqu$ +JcC<$JcC<$JcDYJjo5,Tqu$3cr;-Bfp\=[\qtA8,p@dhHq=aRUrUg'[q==LSrUBUNqsNY7qsO7J +rUBgVqXXXWrUfsZr:^*`cM6;ko(`(Wr;-*`qu$?imJ_\:JcC<$JcG-;J,~> +JcC<$JcC<$JcDYJjo5,Tqu$3cr;-Bfp\=[\qtA8,p@dhHq=aRUrUg'[q==LSrUBUNqsNY7qsO7J +rUBgVqXXXWrUfsZr:^*`cM6;ko(`(Wr;-*`qu$?imJ_\:JcC<$JcG-;J,~> +JcC<$JcC<$JcDYJjo5,Tqu$3cr;-Bfp\=[\qtA8,p@dhHq=aRUrUg'[q==LSrUBUNqsNY7qsO7J +rUBgVqXXXWrUfsZr:^*`cM6;ko(`(Wr;-*`qu$?imJ_\:JcC<$JcG-;J,~> +JcC<$JcC<$JcDPGkPk>Vqu$0brVHHfpA"R[qY&J4q"EY?qY'^WrUg'[q==LSr:'FKp?qeEp?q\D +rUBdUqXXXWrUfsZrV$0`oD%bLjS83 +JcC<$JcC<$JcDPGkPk>Vqu$0brVHHfpA"R[qY&J4q"EY?qY'^WrUg'[q==LSr:'FKp?qeEp?q\D +rUBdUqXXXWrUfsZrV$0`oD%bLjS83 +JcC<$JcC<$JcDPGkPk>Vqu$0brVHHfpA"R[qY&J4q"EY?qY'^WrUg'[q==LSr:'FKp?qeEp?q\D +rUBdUqXXXWrUfsZrV$0`oD%bLjS83 +JcC<$JcC<$JcDDCl2LPXr;?9cr;-?epA"LYq"Eb@p@e4Sl1k)KqtBgXrUg'[q==IRr:':Go^;>> +r:'[Tq==OVrUfsZrV$3ao_@JBanY]-qtfs^qu$ +JcC<$JcC<$JcDDCl2LPXr;?9cr;-?epA"LYq"Eb@p@e4Sl1k)KqtBgXrUg'[q==IRr:':Go^;>> +r:'[Tq==OVrUfsZrV$3ao_@JBanY]-qtfs^qu$ +JcC<$JcC<$JcDDCl2LPXr;?9cr;-?epA"LYq"Eb@p@e4Sl1k)KqtBgXrUg'[q==IRr:':Go^;>> +r:'[Tq==OVrUfsZrV$3ao_@JBanY]-qtfs^qu$ +JcC<$JcC<$JcD;@li-bZqu$0br;-?ep%\@Wo_.tNo(MhPh>$mAqtBjYr:KsZq==IRqs`M3r:'XS +q==LUrq-$ZrV$3apA"@Wo_S+RdeNY6qYKj]qu$ +JcC<$JcC<$JcD;@li-bZqu$0br;-?ep%\@Wo_.tNo(MhPh>$mAqtBjYr:KsZq==IRqs`M3r:'XS +q==LUrq-$ZrV$3apA"@Wo_S+RdeNY6qYKj]qu$ +JcC<$JcC<$JcD;@li-bZqu$0br;-?ep%\@Wo_.tNo(MhPh>$mAqtBjYr:KsZq==IRqs`M3r:'XS +q==LUrq-$ZrV$3apA"@Wo_S+RdeNY6qYKj]qu$ +JcC<$JcC<$JcD5>m/Hk[qu$0bqtg3co_A4UjS&9@f(f.:r:]pYrUg'[p[\7Pq=*_=q=+=Pq""CT +rq-$ZrV$3ap\=R[jneTEhtZp@qYKg\qu$9gmJ_\:JcC<$JcFs6J,~> +JcC<$JcC<$JcD5>m/Hk[qu$0bqtg3co_A4UjS&9@f(f.:r:]pYrUg'[p[\7Pq=*_=q=+=Pq""CT +rq-$ZrV$3ap\=R[jneTEhtZp@qYKg\qu$9gmJ_\:JcC<$JcFs6J,~> +JcC<$JcC<$JcD5>m/Hk[qu$0bqtg3co_A4UjS&9@f(f.:r:]pYrUg'[p[\7Pq=*_=q=+=Pq""CT +rq-$ZrV$3ap\=R[jneTEhtZp@qYKg\qu$9gmJ_\:JcC<$JcFs6J,~> +JcC<$JcC<$JcD/ +JcC<$JcC<$JcD/ +JcC<$JcC<$JcD/ +JcC<$JcC<$JcD):m/Hk[qu$-aqtg0bn+c/AkkOB;o(`.WrV$$Zr:KsZp%%kIp$h_Gp@A1Rr:KjY +rV$0`q"Xa^q"j:Qo(q)9p\OIXq>C*fli)J8JcC<$JcFp5J,~> +JcC<$JcC<$JcD):m/Hk[qu$-aqtg0bn+c/AkkOB;o(`.WrV$$Zr:KsZp%%kIp$h_Gp@A1Rr:KjY +rV$0`q"Xa^q"j:Qo(q)9p\OIXq>C*fli)J8JcC<$JcFp5J,~> +JcC<$JcC<$JcD):m/Hk[qu$-aqtg0bn+c/AkkOB;o(`.WrV$$Zr:KsZp%%kIp$h_Gp@A1Rr:KjY +rV$0`q"Xa^q"j:Qo(q)9p\OIXq>C*fli)J8JcC<$JcFp5J,~> +JcC<$JcC<$JcD&9mJct\qY^$`qYL'a`q\Edo_A@Yr:]pYrUg!YoCD;=oCDhNrUfpYrV$0`q"Xd_ +q>0%HnbVJFo_S(SqY^0fli)J8JcC<$JcFj3J,~> +JcC<$JcC<$JcD&9mJct\qY^$`qYL'a`q\Edo_A@Yr:]pYrUg!YoCD;=oCDhNrUfpYrV$0`q"Xd_ +q>0%HnbVJFo_S(SqY^0fli)J8JcC<$JcFj3J,~> +JcC<$JcC<$JcD&9mJct\qY^$`qYL'a`q\Edo_A@Yr:]pYrUg!YoCD;=oCDhNrUfpYrV$0`q"Xd_ +q>0%HnbVJFo_S(SqY^0fli)J8JcC<$JcFj3J,~> +JcC<$JcC<$JcD#8m/Hk[qY^!_qYL$`chR/.m/$JPp%\IZrV$!Yr:KpYf^eq2rUfmXrV$3ap\=[^ +qYJh@eb\_2q>C'eli)J8JcC<$JcFg2J,~> +JcC<$JcC<$JcD#8m/Hk[qY^!_qYL$`chR/.m/$JPp%\IZrV$!Yr:KpYf^eq2rUfmXrV$3ap\=[^ +qYJh@eb\_2q>C'eli)J8JcC<$JcFg2J,~> +JcC<$JcC<$JcD#8m/Hk[qY^!_qYL$`chR/.m/$JPp%\IZrV$!Yr:KpYf^eq2rUfmXrV$3ap\=[^ +qYJh@eb\_2q>C'eli)J8JcC<$JcFg2J,~> +JcC<$JcC<$JcCu7m/HhZqY^!_q>0m^gA(=9htm3FpA"R[r:]mXqt0aViq!! +JcC<$JcC<$JcCu7m/HhZqY^!_q>0m^gA(=9htm3FpA"R[r:]mXqt0aViq!! +JcC<$JcC<$JcCu7m/HhZqY^!_q>0m^gA(=9htm3FpA"R[r:]mXqt0aViq!! +JcC<$JcC<$JcCr6m/HhZqY]p]q>0d[k4nQDo(qnRpA4X]pA"R[rV#sXqt0XSn+-8Fqt0XUr:^*` +q"Xd_qte,*p%mbHq#'pclMcA7JcC<$JcFa0J,~> +JcC<$JcC<$JcCr6m/HhZqY]p]q>0d[k4nQDo(qnRpA4X]pA"R[rV#sXqt0XSn+-8Fqt0XUr:^*` +q"Xd_qte,*p%mbHq#'pclMcA7JcC<$JcFa0J,~> +JcC<$JcC<$JcCr6m/HhZqY]p]q>0d[k4nQDo(qnRpA4X]pA"R[rV#sXqt0XSn+-8Fqt0XUr:^*` +q"Xd_qte,*p%mbHq#'pclMcA7JcC<$JcFa0J,~> +JcC<$JcC<$JcCo5li-_YqY]m\p\NP +JcC<$JcC<$JcCo5li-_YqY]m\p\NP +JcC<$JcC<$JcCo5li-_YqY]m\p\NP +JcC<$JcC<$JcCl4li-\XqY]j[p%m_Eo(q,1!apA"R[r:]aTiUld8r:^*`p\=[^qtfgZl28Hr +pAF[`l2H86JcC<$JcFX-J,~> +JcC<$JcC<$JcCl4li-\XqY]j[p%m_Eo(q,1!apA"R[r:]aTiUld8r:^*`p\=[^qtfgZl28Hr +pAF[`l2H86JcC<$JcFX-J,~> +JcC<$JcC<$JcCl4li-\XqY]j[p%m_Eo(q,1!apA"R[r:]aTiUld8r:^*`p\=[^qtfgZl28Hr +pAF[`l2H86JcC<$JcFX-J,~> +JcC<$JcC<$JcCi3lMgSWq>B[XeG@SiqYL*bpA"R[qtBOPme$&BqtBs^p\=[^qtfm\i;CdqpAFX_ +kl-/5JcC<$JcFU,J,~> +JcC<$JcC<$JcCi3lMgSWq>B[XeG@SiqYL*bpA"R[qtBOPme$&BqtBs^p\=[^qtfm\i;CdqpAFX_ +kl-/5JcC<$JcFU,J,~> +JcC<$JcC<$JcCi3lMgSWq>B[XeG@SiqYL*bpA"R[qtBOPme$&BqtBs^p\=[^qtfm\i;CdqpAFX_ +kl-/5JcC<$JcFU,J,~> +JcC<$JcC<$JcCc1lMgVXq#'LUh>57jqYL*bpA"R[qY&G3qtBp]p\=[^r;-!]ebn%ro_eF]kPg&4 +JcC<$JcFR+J,~> +JcC<$JcC<$JcCc1lMgVXq#'LUh>57jqYL*bpA"R[qY&G3qtBp]p\=[^r;-!]ebn%ro_eF]kPg&4 +JcC<$JcFR+J,~> +JcC<$JcC<$JcCc1lMgVXq#'LUh>57jqYL*bpA"R[qY&G3qtBp]p\=[^r;-!]ebn%ro_eF]kPg&4 +JcC<$JcFR+J,~> +JcC<$JcC<$JcC`0l2LJVq#'=Pn+s]oqtg3cp%\FYq=`Y;qY'g\pA"R]qtfs^oDJ.Wk5=NAn,2hV +kPg&4JcC<$JcFL)J,~> +JcC<$JcC<$JcC`0l2LJVq#'=Pn+s]oqtg3cp%\FYq=`Y;qY'g\pA"R]qtfs^oDJ.Wk5=NAn,2hV +kPg&4JcC<$JcFL)J,~> +JcC<$JcC<$JcC`0l2LJVq#'=Pn+s]oqtg3cp%\FYq=`Y;qY'g\pA"R]qtfs^oDJ.Wk5=NAn,2hV +kPg&4JcC<$JcFL)J,~> +JcC<$JcC<$JcCZ.lMgPVq#%Z!m/6;KqYL*bp%\CXq"EqEq"FRYpA"R]qtfs^p\a%LaSbZ.jo0i2 +JcC<$JcFL)J,~> +JcC<$JcC<$JcCZ.lMgPVq#%Z!m/6;KqYL*bp%\CXq"EqEq"FRYpA"R]qtfs^p\a%LaSbZ.jo0i2 +JcC<$JcFL)J,~> +JcC<$JcC<$JcCZ.lMgPVq#%Z!m/6;KqYL*bp%\CXq"EqEq"FRYpA"R]qtfs^p\a%LaSbZ.jo0i2 +JcC<$JcFL)J,~> +JcC<$JcC<$JcCZ.kl1AUpADf)i;E*Aqtg3co_A4Ui:d!@p%\F[qtfs^q#&hDe,8e8jo0i2JcC<$ +JcF@%J,~> +JcC<$JcC<$JcCZ.kl1AUpADf)i;E*Aqtg3co_A4Ui:d!@p%\F[qtfs^q#&hDe,8e8jo0i2JcC<$ +JcF@%J,~> +JcC<$JcC<$JcCZ.kl1AUpADf)i;E*Aqtg3co_A4Ui:d!@p%\F[qtfs^q#&hDe,8e8jo0i2JcC<$ +JcF@%J,~> +JcC<$JcC<$JcCT,kl1;Sp&*)3fDP19qtg0bo_A.SlLsuHo_A=Zqtfs^q#&J:i;E'Bj8OW0JcC<$ +JcF@%J,~> +JcC<$JcC<$JcCT,kl1;Sp&*)3fDP19qtg0bo_A.SlLsuHo_A=Zqtfs^q#&J:i;E'Bj8OW0JcC<$ +JcF@%J,~> +JcC<$JcC<$JcCT,kl1;Sp&*)3fDP19qtg0bo_A.SlLsuHo_A=Zqtfs^q#&J:i;E'Bj8OW0JcC<$ +JcF@%J,~> +JcC<$JcC<$JcCQ+kPk2RoDI2:m/6GQoDJ.Uqtg0bnbD&:o(`+Xqtfp]q>Ba\pAX"KnGMVNiVnE. +JcC<$JcF:#J,~> +JcC<$JcC<$JcCQ+kPk2RoDI2:m/6GQoDJ.Uqtg0bnbD&:o(`+Xqtfp]q>Ba\pAX"KnGMVNiVnE. +JcC<$JcF:#J,~> +JcC<$JcC<$JcCQ+kPk2RoDI2:m/6GQoDJ.Uqtg0bnbD&:o(`+Xqtfp]q>Ba\pAX"KnGMVNiVnE. +JcC<$JcF:#J,~> +JcC<$JcC<$JcCK)kPk/QnbhACm/6&Fp&+CXqYL'amJ-,DmeHYSqtfp]q>Bm`kl/O!i;S<-JcC<$ +JcF4!J,~> +JcC<$JcC<$JcCK)kPk/QnbhACm/6&Fp&+CXqYL'amJ-,DmeHYSqtfp]q>Bm`kl/O!i;S<-JcC<$ +JcF4!J,~> +JcC<$JcC<$JcCK)kPk/QnbhACm/6&Fp&+CXqYL'amJ-,DmeHYSqtfp]q>Bm`kl/O!i;S<-JcC<$ +JcF4!J,~> +JcC<$JcC<$JcCH(k5OuNl2:DTjo!s5p\aRYqYL'ac1q/2qYKj]q#'jag]#Y"h#;m)JcC<$JcF0u +J,~> +JcC<$JcC<$JcCH(k5OuNl2:DTjo!s5p\aRYqYL'ac1q/2qYKj]q#'jag]#Y"h#;m)JcC<$JcF0u +J,~> +JcC<$JcC<$JcCH(k5OuNl2:DTjo!s5p\aRYqYL'ac1q/2qYKj]q#'jag]#Y"h#;m)JcC<$JcF0u +J,~> +JcC<$JcC<$JcCE'jSn`KdJVJlp\aUZq>0m^f(f(:qYKg\q>Bsbdf/,%f`$I%JcC<$JcF*sJ,~> +JcC<$JcC<$JcCE'jSn`KdJVJlp\aUZq>0m^f(f(:qYKg\q>Bsbdf/,%f`$I%JcC<$JcF*sJ,~> +JcC<$JcC<$JcCE'jSn`KdJVJlp\aUZq>0m^f(f(:qYKg\q>Bsbdf/,%f`$I%JcC<$JcF*sJ,~> +JcC<$JcC<$JcCB&j8SQHg\g=7nc&(Wq#'^[q>0j]hY?mAq>0^[q>C!c`W#B*e,FpuJcC<$JcF!p +J,~> +JcC<$JcC<$JcCB&j8SQHg\g=7nc&(Wq#'^[q>0j]hY?mAq>0^[q>C!c`W#B*e,FpuJcC<$JcF!p +J,~> +JcC<$JcC<$JcCB&j8SQHg\g=7nc&(Wq#'^[q>0j]hY?mAq>0^[q>C!c`W#B*e,FpuJcC<$JcF!p +J,~> +JcC<$JcC<$JcC?%i;Vs=o_dhLiVrNKq#'^[q"jUXmeHGMq>0[Zq>C!cL&QZ'JcC<$JcEpnJ,~> +JcC<$JcC<$JcC?%i;Vs=o_dhLiVrNKq#'^[q"jUXmeHGMq>0[Zq>C!cL&QZ'JcC<$JcEpnJ,~> +JcC<$JcC<$JcC?%i;Vs=o_dhLiVrNKq#'^[q"jUXmeHGMq>0[Zq>C!cL&QZ'JcC<$JcEpnJ,~> +JcC<$JcC<$JcC<$!<:sU`r4Zkp&4[`nb`(Wg\LU?o)&7\p\fgFJcC<$JcC<$ao?k~> +JcC<$JcC<$JcC<$!<:sU`r4Zkp&4[`nb`(Wg\LU?o)&7\p\fgFJcC<$JcC<$ao?k~> +JcC<$JcC<$JcC<$!<:sU`r4Zkp&4[`nb`(Wg\LU?o)&7\p\fgFJcC<$JcC<$ao?k~> +JcC<$JcC<$JcC<$rr:gRci)Amp&4[`n,)bRl1suJnGE%Zq#,mFJcC<$JcC<$a8^Y~> +JcC<$JcC<$JcC<$rr:gRci)Amp&4[`n,)bRl1suJnGE%Zq#,mFJcC<$JcC<$a8^Y~> +JcC<$JcC<$JcC<$rr:gRci)Amp&4[`n,)bRl1suJnGE%Zq#,mFJcC<$JcC<$a8^Y~> +JcC<$JcC<$JcC<$r;YCJi;LarpAOdamebT3n,)nXq#,mFJcC<$JcC<$`W(G~> +JcC<$JcC<$JcC<$r;YCJi;LarpAOdamebT3n,)nXq#,mFJcC<$JcC<$`W(G~> +JcC<$JcC<$JcC<$r;YCJi;LarpAOdamebT3n,)nXq#,mFJcC<$JcC<$`W(G~> +JcC<$JcC<$JcC<$qu=t@p&2N%pAOa`lMKW +JcC<$JcC<$JcC<$qu=t@p&2N%pAOa`lMKW +JcC<$JcC<$JcC<$qu=t@p&2N%pAOa`lMKW +JcC<$JcC<$JcC<$q#>pEr;QEgp\a.Mp%meIp\agbLAlc(JcC<$JcEIaJ,~> +JcC<$JcC<$JcC<$q#>pEr;QEgp\a.Mp%meIp\agbLAlc(JcC<$JcEIaJ,~> +JcC<$JcC<$JcC<$q#>pEr;QEgp\a.Mp%meIp\agbLAlc(JcC<$JcEIaJ,~> +JcC<$JcC<$JcC<$p]#gDqu6 +JcC<$JcC<$JcC<$p]#gDqu6 +JcC<$JcC<$JcC<$p]#gDqu6 +%%EndData +showpage +%%Trailer +end +%%EOF diff --git a/ecore/doc/img/ecore_big.png b/ecore/doc/img/ecore_big.png new file mode 100644 index 0000000..cd818f7 Binary files /dev/null and b/ecore/doc/img/ecore_big.png differ diff --git a/ecore/doc/img/ecore_mini.png b/ecore/doc/img/ecore_mini.png new file mode 100644 index 0000000..f4f99f0 Binary files /dev/null and b/ecore/doc/img/ecore_mini.png differ diff --git a/ecore/doc/img/ecore_small.png b/ecore/doc/img/ecore_small.png new file mode 100644 index 0000000..8bea367 Binary files /dev/null and b/ecore/doc/img/ecore_small.png differ diff --git a/ecore/doc/img/hilite.png b/ecore/doc/img/hilite.png new file mode 100644 index 0000000..88a4381 Binary files /dev/null and b/ecore/doc/img/hilite.png differ diff --git a/ecore/doc/img/prog_flow.png b/ecore/doc/img/prog_flow.png new file mode 100644 index 0000000..06c89c1 Binary files /dev/null and b/ecore/doc/img/prog_flow.png differ diff --git a/ecore/ecore-config.in b/ecore/ecore-config.in new file mode 100644 index 0000000..f47a0aa --- /dev/null +++ b/ecore/ecore-config.in @@ -0,0 +1,59 @@ +#!/bin/sh + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +exec_prefix_set=no + +usage="\ +Usage: ecore-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--libs] [--cflags]" + +if test $# -eq 0; then + echo "${usage}" 1>&2 + exit 1 +fi + +while test $# -gt 0; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case $1 in + --prefix=*) + prefix=$optarg + if test $exec_prefix_set = no ; then + exec_prefix=$optarg + fi + ;; + --prefix) + echo $prefix + ;; + --exec-prefix=*) + exec_prefix=$optarg + exec_prefix_set=yes + ;; + --exec-prefix) + echo $exec_prefix + ;; + --version) + echo @VERSION@ + ;; + --cflags) + if test @includedir@ != /usr/include ; then + includes=-I@includedir@ + fi + echo $includes + ;; + --libs) + libdirs=-L@libdir@ + echo $libdirs -lecore @ecore_job_libs@ @ecore_x_libs@ @ecore_evas_libs@ @ecore_con_libs@ @ecore_ipc_libs@ @ecore_txt_libs@ @ecore_fb_libs@ @ecore_config_libs@ @ecore_file_libs@ @eet_libs@ -lm + ;; + *) + echo "${usage}" 1>&2 + exit 1 + ;; + esac + shift +done + +exit 0 diff --git a/ecore/ecore-native.oe.in b/ecore/ecore-native.oe.in new file mode 100644 index 0000000..eb245fb --- /dev/null +++ b/ecore/ecore-native.oe.in @@ -0,0 +1,24 @@ +DESCRIPTION = "Ecore is the core event abstraction layer for the \ +enlightenment foundation libraries. It makes makes doing selections, drag \ +and drop, event loops, timeouts and idle handlers fast, optimized, and \ +convenient." +HOMEPAGE = "http://www.enlightenment.org" +MAINTAINER = "Carsten Haitzler (Rasterman) " +SECTION = "e/libs" +PRIORITY = "optional" +include ecore.oe +inherit native +DEPENDS = "eet-native evas-native" + +export EET_CONFIG = "${STAGING_BINDIR}/eet-config-native" +export EVAS_CONFIG = "${STAGING_BINDIR}/evas-config-native" + +do_stage () { + for p in ${parts}; do + dir=`echo $p|tr A-Z a-z` + install -m 0644 ${S}/src/lib/$dir/$p.h ${STAGING_INCDIR}/ + oe_libinstall -C src/lib/$dir lib$dir ${STAGING_LIBDIR}/ + done + install -m 0644 ${S}/src/lib/ecore/Ecore_Data.h ${STAGING_INCDIR}/ + install -m 0644 ${S}/ecore.m4 ${STAGING_DATADIR}/aclocal/ +} diff --git a/ecore/ecore.bb.in b/ecore/ecore.bb.in new file mode 100644 index 0000000..6df234c --- /dev/null +++ b/ecore/ecore.bb.in @@ -0,0 +1,58 @@ +DESCRIPTION = "Ecore is the core event abstraction layer for the \ +enlightenment foundation libraries. It makes makes doing selections, drag \ +and drop, event loops, timeouts and idle handlers fast, optimized, and \ +convenient." +HOMEPAGE = "http://www.enlightenment.org" +MAINTAINER = "Carsten Haitzler (Rasterman) " +SECTION = "e/libs" +PRIORITY = "optional" +DEPENDS = "eet evas diet-x11 xserver-kdrive" +PR = "@VERSION@" +PR = "1" + +do_prepsources () { + make clean distclean || true +} +addtask prepsources after do_fetch before do_unpack + +SRC_URI = "file://./" +S = "${WORKDIR}/ecore" + +inherit autotools binconfig + +export EET_CONFIG = "${STAGING_BINDIR}/eet-config" +export EVAS_CONFIG = "${STAGING_BINDIR}/evas-config" + +EXTRA_OECONF = "--enable-ecore-fb \ + --enable-ecore-job \ + --enable-ecore-evas \ + --enable-ecore-evas-fb \ + --enable-ecore-evas-x \ + --disable-ecore-evas-gl \ + --enable-ecore-con \ + --enable-ecore-ipc \ + --enable-ecore-txt \ + --enable-ecore-x \ + --enable-ecore-config \ + --disable-openssl" + +parts = "Ecore Ecore_Job \ + Ecore_Txt Ecore_Fb Ecore_Con \ + Ecore_Ipc Ecore_Evas Ecore_Config \ + Ecore_X" + +do_stage () { + for p in ${parts}; do + dir=`echo $p|tr A-Z a-z` + install -m 0644 ${S}/src/lib/$dir/$p.h ${STAGING_INCDIR}/ + oe_libinstall -C src/lib/$dir lib$dir ${STAGING_LIBDIR}/ + done + install -m 0644 ${S}/src/lib/ecore/Ecore_Data.h ${STAGING_INCDIR}/ + install -m 0644 ${S}/ecore.m4 ${STAGING_DATADIR}/aclocal/ +} + +PACKAGES += "ecore-examples" + +FILES_${PN} = "${libdir}/libecore*.so* ${libdir}/ecore_config_ipc_ecore.so" +FILES_${PN}-dev += "${bindir}/ecore-config ${libdir}/pkgconfig" +FILES_${PN}-examples = "${bindir}/ecore_test ${bindir}/ecore_evas_test ${datadir}" diff --git a/ecore/ecore.c.in b/ecore/ecore.c.in new file mode 100644 index 0000000..3780e28 --- /dev/null +++ b/ecore/ecore.c.in @@ -0,0 +1,378 @@ +/** +@brief Ecore Library Public API Calls + +These routines are used for Ecore Library interaction +*/ + +/** + +@mainpage Ecore + +@image latex ecore_big.eps width=5cm +@image html ecore.png + +@version 1.0.0 +@author Carsten Haitzler +@author Tom Gilbert +@author Burra +@author Chris Ross +@author Term +@author Tilman Sauerbeck +@author Nathan Ingersoll +@date 2000-2004 + +@section intro Introduction + +Ecore is a library of convenience functions. + +The Ecore library provides the following modules: +@li @link Ecore.h Ecore - Main Loop Functions. @endlink +@li @link Ecore_Con.h Ecore_Con - Connection functions. @endlink +@li @link Ecore_Config.h Ecore_Config - Configuration functions. @endlink +@li @link Ecore_Evas.h Ecore_Evas - Evas convenience functions. @endlink +@li @link Ecore_Fb.h Ecore_FB - Frame buffer convenience functions. @endlink +@li @link Ecore_Ipc.h Ecore_IPC - Inter Process Communication functions. @endlink +@li @link Ecore_Job.h Ecore_Job - Job functions, to be used in the Ecore main loop. @endlink +@li @link Ecore_Txt.h Ecore_Txt - Text encoding conversion. @endlink +@li @link Ecore_X.h Ecore_X - X Windows System wrapper. @endlink + +@section compiling How to compile using Ecore? + +This section has to be documented. Below is just a quick line to handle all +Ecore modules at once. + +@verbatim +gcc *.c \ +-I/usr/local/include -I/usr/X11R6/include \ +-L/usr/local/lib -L/usr/X11R6/lib \ +-lecore -lecore_evas -lecore_x -lecore_fb -lecore_job \ +`evas-config --cflags --libs` +@endverbatim + +@section install How is it installed? + +Suggested configure options for evas for a Linux desktop X display: + +@verbatim +./configure \ +--enable-ecore-x \ +--enable-ecore-fb \ +--enable-ecore-evas \ +--enable-ecore-evas-gl \ +--enable-ecore-job \ +--enable-ecore-con \ +--enable-ecore-ipc \ +--enable-ecore-txt +make CFLAGS="-O9 -mpentiumpro -march=pentiumpro -mcpu=pentiumpro" +@endverbatim + +@todo (1.0) Document API + +*/ + +/* +@page Ecore_Main_Loop_Page The Ecore Main Loop + +@section intro What is Ecore? + +Ecore is a clean and tiny event loop library with many modules to do lots of +convenient things for a programmer, to save time and effort. + +It's small and lean, designed to work on embedded systems all the way to +large and powerful multi-cpu workstations. It serialises all system signals, +events etc. into a single event queue, that is easily processed without +needing to worry about concurrency. A properly written, event-driven program +using this kind of programming doesn't need threads, nor has to worry about +concurrency. It turns a program into a state machine, and makes it very +robust and easy to follow. + +Ecore gives you other handy primitives, such as timers to tick over for you +and call specified functions at particular times so the programmer can use +this to do things, like animate, or time out on connections or tasks that take +too long etc. + +Idle handlers are provided too, as well as calls on entering an idle state +(often a very good time to update the state of the program). All events that +enter the system are passed to specific callback functions that the program +sets up to handle those events. Handling them is simple and other Ecore +modules produce more events on the queue, coming from other sources such as +file descriptors etc. + +Ecore also lets you have functions called when file descriptors become active +for reading or writing, allowing for streamlined, non-blocking IO. + +Here is an exmaple of a simple program and its basic event loop flow: + +@image html prog_flow.png + + + +@section work How does Ecore work? + +Ecore is very easy to learn and use. All the function calls are designed to +be easy to remember, explicit in describing what they do, and heavily +name-spaced. Ecore programs can start and be very simple. + +For example: + +@code +#include + +int main(int argc, const char **argv) +{ + ecore_init(); + ecore_app_args_set(argc, argv); + ecore_main_loop_begin(); + ecore_shutdown(); + return 0; +} +@endcode + +This program is very simple and does't check for errors, but it does start up +and begin a main loop waiting for events or timers to tick off. This program +doesn't set up any, but now we can expand on this simple program a little +more by adding some event handlers and timers. + +@code +#include + +Ecore_Timer *timer1 = NULL; +Ecore_Event_Handler *handler1 = NULL; +double start_time = 0.0; + +int timer_func(void *data) +{ + printf("Tick timer. Sec: %3.2f\n", ecore_time_get() - start_time); + return 1; +} + +int exit_func(void *data, int ev_type, void *ev) +{ + Ecore_Event_Signal_Exit *e; + + e = (Ecore_Event_Signal_Exit *)ev; + if (e->interrupt) printf("Exit: interrupt\n"); + else if (e->quit) printf("Exit: quit\n"); + else if (e->terminate) printf("Exit: terminate\n"); + ecore_main_loop_quit(); + return 1; +} + +int main(int argc, const char **argv) +{ + ecore_init(); + ecore_app_args_set(argc, argv); + start_time = ecore_time_get(); + handler1 = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, exit_func, NULL); + timer1 = ecore_timer_add(0.5, timer_func, NULL); + ecore_main_loop_begin(); + ecore_shutdown(); + return 0; +} +@endcode + +In the previous example, we initialize our application and get the time at +which our program has started so we can calculate an offset. We set +up a timer to tick off in 0.5 seconds, and since it returns 1, will +keep ticking off every 0.5 seconds until it returns 0, or is deleted +by hand. An event handler is set up to call a function - exit_func(), +whenever an event of type ECORE_EVENT_SIGNAL_EXIT is received (CTRL-C +on the command line will cause such an event to happen). If this event +occurs it tells you what kind of exit signal was received, and asks +the main loop to quit when it is finished by calling +ecore_main_loop_quit(). + +The handles returned by ecore_timer_add() and ecore_event_handler_add() are +only stored here as an example. If you don't need to address the timer or +event handler again you don't need to store the result, so just call the +function, and don't assign the result to any variable. + +This program looks slightly more complex than needed to do these simple +things, but in principle, programs don't get any more complex. You add more +event handlers, for more events, will have more timers and such, BUT it all +follows the same principles as shown in this example. + +*/ + +/** +@page Ecore_Config_Page The Enlightened Property Library + +The Enlightened Property Library (Ecore_Config) is an adbstraction +from the complexities of writing your own configuration. It provides +many features using the Enlightenment 17 development libraries. + +To use the library, you: +@li Set the default values of your properties. +@li Load the configuration from a file. You must set the default values + first, so that the library knows the correct type of each argument. + +The following examples show how to use the Enlightened Property Library: +@li @link config_basic_example.c config_basic_example.c @endlink +@li @link config_listener_example.c config_listener_example.c @endlink + +*/ + +/** +@page Ecore_ADT_Page Ecore Abstract Data Types + +This page briefly describes the different abstract data types +that are provided by the Ecore library for general usage. You need to +include the @link Ecore_Data.h Ecore_Data.h @endlink to use them. + +@section Ecore_ADT_List List + +A list is a simple data type where one each piece of data points to +another piece of data. + +Associated modules that describe the List ADT include: +@li @ref Ecore_Data_List_Creation_Group +@li @ref Ecore_Data_List_Add_Item_Group +@li @ref Ecore_Data_List_Remove_Item_Group +@li @ref Ecore_Data_List_Traverse_Group +@li @ref Ecore_Data_List_Node_Group + +Examples involving lists include: +@li @link list_example.c list_example.c @endlink + +@section Ecore_ADT_DList Doubly Linked List + +A doubly linked list is like a linked list, only each piece of data +can also point to the piece before it. In other words, you can traverse +a doubly linked list in both directions. + +Associated modules that describe the DList ADT include: +@li @ref Ecore_Data_DList_Creation_Group +@li @ref Ecore_Data_DList_Add_Item_Group +@li @ref Ecore_Data_DList_Remove_Item_Group + +@section Ecore_ADT_Hash Hash + +A hash is an abstract data type where one value is associated with another +value. Instead of each element of the group being accessible using a +number, each element is accessed using another object. + +Associated modules that describe the Hash ADT include: +@li @ref Ecore_Data_Hash_ADT_Creation_Group +@li @ref Ecore_Data_Hash_ADT_Destruction_Group +@li @ref Ecore_Data_Hash_ADT_Data_Group + +@todo Finish this. +*/ + +/** +@page X_Window_System_Page X Window System + +The Ecore library includes a wrapper for handling the X window system. +This page briefly explains what the X window system is and various terms +that are used. +*/ + +// GROUP DEFINITIONS + +/** +@defgroup Ecore_Timer_Group Ecore Timer + +The timer allows callbacks to be called at specific intervals. + */ + +/** +@defgroup Ecore_Job_Group Ecore Jobs + +You can queue jobs that are to be done by the main loop when the current +event is dealt with. +*/ + +/** +@defgroup Idle_Group Idle Handlers + +Callbacks that are called when the program enters or exits an idle state. + +The ecore main loop enters an idle state when it is waiting for timers +to time out, data to come in on a file descriptor or any other event +to occur. You can set callbacks to be called when the main loop +enters an idle state, during an idle state or just after the program +wakes up. + +Enterer callbacks are good for updating your program's state, if it +has a state engine. Once all of the enterer handlers are called, the +program will enter a "sleeping" state. + +Idler callbacks are called when the main loop has called all enterer +handlers. They are useful for interfaces that require polling and +timers would be too slow to use. + +If no idler callbacks are specified, then the process literally goes +to sleep. Otherwise, the idler callbacks are called continuously +while the loop is "idle", using as much CPU as is available to the +process. + +Exiter callbacks are called when the main loop wakes up from an idle +state. + +*/ + +/** +@defgroup Ecore_Config_Create_Group Ecore Config Create Functions + +Convenience functions that set default values, bounds, option values and +descriptions in one call. +*/ + +/** +@defgroup Ecore_Config_File_Group Ecore Config File Functions + +Functions that are used to load and save properties from and to files. +*/ + +// EXAMPLES + +/** +@example args_example.c +Shows how to set and retrieve the program arguments. +*/ + +/** +@example con_server_example.c +Shows how to write a simple server using the Ecore_Con library. +*/ + +/** +@example con_client_example.c +Shows how to write a simple client, that connects to the example server. +*/ + +/** +@example event_handler_example.c +Shows how to use event handlers. +*/ + +/** +@example timer_example.c +Demonstrates use of the ecore_timer. +*/ + +/** +@example config_basic_example.c +Provides an example of how to use the basic configuration functions. +See the file Ecore_Config.h for the full list of available functions. +*/ + +/** +@example config_listener_example.c +Shows how to set up a listener to listen for configuration changes. +*/ + +/** +@example list_example.c +Provides a basic example of how to append to and traverse a list. +*/ + +/** +@example list_destroy_example.c +Shows how to set and use a destructor for an Ecore_List. +*/ + +/** +@example x_window_example.c +Shows the basics of using the X Windows system through Ecore functions. +*/ diff --git a/ecore/ecore.m4 b/ecore/ecore.m4 new file mode 100644 index 0000000..cd69edf --- /dev/null +++ b/ecore/ecore.m4 @@ -0,0 +1,198 @@ +# Configure paths for Ecore +# Conrad Parker 2001-01-24 +# blatantly ripped from gtk.m4, Owen Taylor 97-11-3 + +dnl AM_PATH_ECORE([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]]) +dnl Test for Ecore, and define ECORE_CFLAGS and ECORE_LIBS +dnl +AC_DEFUN([AM_PATH_ECORE], +[dnl +dnl Get the cflags and libraries from the ecore-config script +dnl +AC_ARG_WITH(ecore-prefix,[ --with-ecore-prefix=PFX Prefix where Ecore is installed (optional)], + ecore_config_prefix="$withval", ecore_config_prefix="") +AC_ARG_WITH(ecore-exec-prefix,[ --with-ecore-exec-prefix=PFX Exec prefix where Ecore is installed (optional)], + ecore_config_exec_prefix="$withval", ecore_config_exec_prefix="") +AC_ARG_ENABLE(ecoretest, [ --disable-ecoretest Do not try to compile and run a test Ecore program], + , enable_ecoretest=yes) + + if test x$ecore_config_exec_prefix != x ; then + ecore_config_args="$ecore_config_args --exec-prefix=$ecore_config_exec_prefix" + if test x${ECORE_CONFIG+set} != xset ; then + ECORE_CONFIG=$ecore_config_exec_prefix/bin/ecore-config + fi + fi + if test x$ecore_config_prefix != x ; then + ecore_config_args="$ecore_config_args --prefix=$ecore_config_prefix" + if test x${ECORE_CONFIG+set} != xset ; then + ECORE_CONFIG=$ecore_config_prefix/bin/ecore-config + fi + fi + + AC_PATH_PROG(ECORE_CONFIG, ecore-config, no) + min_ecore_version=ifelse([$1], ,0.0.0,$1) + AC_MSG_CHECKING(for Ecore - version >= $min_ecore_version) + no_ecore="" + if test "$ECORE_CONFIG" = "no" ; then + no_ecore=yes + else + ECORE_CFLAGS=`$ECORE_CONFIG $ecore_config_args --cflags` + ECORE_LIBS=`$ECORE_CONFIG $ecore_config_args --libs` + ecore_config_major_version=`$ECORE_CONFIG $ecore_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + ecore_config_minor_version=`$ECORE_CONFIG $ecore_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + ecore_config_micro_version=`$ECORE_CONFIG $ecore_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + +dnl ********************************************************************** +dnl Ecore cannot currently report its own version ; version info is not +dnl given in Ecore.h +dnl Thus, the "enable_ecoretest" stuff is currently disabled, enable once +dnl you can determine the currently installed version by querying Ecore[.h] +dnl +dnl K. 2001-01-24 +dnl ********************************************************************** + +dnl if test "x$enable_ecoretest" = "xyes" ; then +dnl ac_save_CFLAGS="$CFLAGS" +dnl ac_save_LIBS="$LIBS" +dnl CFLAGS="$CFLAGS $ECORE_CFLAGS" +dnl LIBS="$ECORE_LIBS $LIBS" +dnl dnl +dnl dnl Now check if the installed Ecore is sufficiently new. (Also sanity +dnl dnl checks the results of ecore-config to some extent +dnl dnl +dnl rm -f conf.ecoretest +dnl AC_TRY_RUN([ +dnl #include +dnl #include +dnl #include +dnl +dnl int +dnl main () +dnl { +dnl int major, minor, micro; +dnl char *tmp_version; +dnl +dnl system ("touch conf.ecoretest"); +dnl +dnl /* HP/UX 9 (%@#!) writes to sscanf strings */ +dnl tmp_version = g_strdup("$min_ecore_version"); +dnl if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { +dnl printf("%s, bad version string\n", "$min_ecore_version"); +dnl exit(1); +dnl } +dnl +dnl if ((ecore_major_version != $ecore_config_major_version) || +dnl (ecore_minor_version != $ecore_config_minor_version) || +dnl (ecore_micro_version != $ecore_config_micro_version)) +dnl { +dnl printf("\n*** 'ecore-config --version' returned %d.%d.%d, but Ecore (%d.%d.%d)\n", +dnl $ecore_config_major_version, $ecore_config_minor_version, $ecore_config_micro_version, +dnl ecore_major_version, ecore_minor_version, ecore_micro_version); +dnl printf ("*** was found! If ecore-config was correct, then it is best\n"); +dnl printf ("*** to remove the old version of Ecore. You may also be able to fix the error\n"); +dnl printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"); +dnl printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); +dnl printf("*** required on your system.\n"); +dnl printf("*** If ecore-config was wrong, set the environment variable ECORE_CONFIG\n"); +dnl printf("*** to point to the correct copy of ecore-config, and remove the file config.cache\n"); +dnl printf("*** before re-running configure\n"); +dnl } +dnl #if defined (ECORE_MAJOR_VERSION) && defined (ECORE_MINOR_VERSION) && defined (ECORE_MICRO_VERSION) +dnl else if ((ecore_major_version != ECORE_MAJOR_VERSION) || +dnl (ecore_minor_version != ECORE_MINOR_VERSION) || +dnl (ecore_micro_version != ECORE_MICRO_VERSION)) +dnl { +dnl printf("*** Ecore header files (version %d.%d.%d) do not match\n", +dnl ECORE_MAJOR_VERSION, ECORE_MINOR_VERSION, ECORE_MICRO_VERSION); +dnl printf("*** library (version %d.%d.%d)\n", +dnl ecore_major_version, ecore_minor_version, ecore_micro_version); +dnl } +dnl #endif /* defined (ECORE_MAJOR_VERSION) ... */ +dnl else +dnl { +dnl if ((ecore_major_version > major) || +dnl ((ecore_major_version == major) && (ecore_minor_version > minor)) || +dnl ((ecore_major_version == major) && (ecore_minor_version == minor) && (ecore_micro_version >= micro))) +dnl { +dnl return 0; +dnl } +dnl else +dnl { +dnl printf("\n*** An old version of Ecore (%d.%d.%d) was found.\n", +dnl ecore_major_version, ecore_minor_version, ecore_micro_version); +dnl printf("*** You need a version of Ecore newer than %d.%d.%d. The latest version of\n", +dnl major, minor, micro); +dnl printf("*** Ecore is always available from ftp://ftp.enlightenment.org.\n"); +dnl printf("***\n"); +dnl printf("*** If you have already installed a sufficiently new version, this error\n"); +dnl printf("*** probably means that the wrong copy of the ecore-config shell script is\n"); +dnl printf("*** being found. The easiest way to fix this is to remove the old version\n"); +dnl printf("*** of Ecore, but you can also set the ECORE_CONFIG environment to point to the\n"); +dnl printf("*** correct copy of ecore-config. (In this case, you will have to\n"); +dnl printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); +dnl printf("*** so that the correct libraries are found at run-time))\n"); +dnl } +dnl } +dnl return 1; +dnl } +dnl ],, no_ecore=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) +dnl CFLAGS="$ac_save_CFLAGS" +dnl LIBS="$ac_save_LIBS" +dnl fi +dnl ********************************************************************** + + fi + if test "x$no_ecore" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$ECORE_CONFIG" = "no" ; then + echo "*** The ecore-config script installed by Ecore could not be found" + echo "*** If Ecore was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the ECORE_CONFIG environment variable to the" + echo "*** full path to ecore-config." + else + if test -f conf.ecoretest ; then + : + else + echo "*** Could not run Ecore test program, checking why..." + CFLAGS="$CFLAGS $ECORE_CFLAGS" + LIBS="$LIBS $ECORE_LIBS" + AC_TRY_LINK([ +#include +#include +], [ return ((ecore_major_version) || (ecore_minor_version) || (ecore_micro_version)); ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding Ecore or finding the wrong" + echo "*** version of Ecore. If it is not finding Ecore, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" + echo "***" + echo "*** If you have a RedHat 5.0 system, you should remove the Ecore package that" + echo "*** came with the system with the command" + echo "***" + echo "*** rpm --erase --nodeps ecore ecore-devel" ], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means Ecore was incorrectly installed" + echo "*** or that you have moved Ecore since it was installed. In the latter case, you" + echo "*** may want to edit the ecore-config script: $ECORE_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + ECORE_CFLAGS="" + ECORE_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(ECORE_CFLAGS) + AC_SUBST(ECORE_LIBS) + rm -f conf.ecoretest +]) diff --git a/ecore/ecore.oe.in b/ecore/ecore.oe.in new file mode 100644 index 0000000..f6c9571 --- /dev/null +++ b/ecore/ecore.oe.in @@ -0,0 +1,58 @@ +DESCRIPTION = "Ecore is the core event abstraction layer for the \ +enlightenment foundation libraries. It makes makes doing selections, drag \ +and drop, event loops, timeouts and idle handlers fast, optimized, and \ +convenient." +HOMEPAGE = "http://www.enlightenment.org" +MAINTAINER = "Carsten Haitzler (Rasterman) " +SECTION = "e/libs" +PRIORITY = "optional" +DEPENDS = "eet evas" +PR = "@VERSION@" +PR = "1" + +do_prepsources () { + make clean distclean || true +} +addtask prepsources after do_fetch before do_unpack + +SRC_URI = "file://./" +S = "${WORKDIR}/ecore" + +inherit autotools binconfig + +export EET_CONFIG = "${STAGING_BINDIR}/eet-config" +export EVAS_CONFIG = "${STAGING_BINDIR}/evas-config" + +EXTRA_OECONF = "--enable-ecore-fb \ + --enable-ecore-job \ + --enable-ecore-evas \ + --enable-ecore-evas-fb \ + --enable-ecore-evas-x \ + --disable-ecore-evas-gl \ + --enable-ecore-con \ + --enable-ecore-ipc \ + --enable-ecore-txt \ + --enable-ecore-x \ + --enable-ecore-config \ + --disable-openssl" + +parts = "Ecore Ecore_Job \ + Ecore_Txt Ecore_Fb Ecore_Con \ + Ecore_Ipc Ecore_Evas Ecore_Config \ + Ecore_X" + +do_stage () { + for p in ${parts}; do + dir=`echo $p|tr A-Z a-z` + install -m 0644 ${S}/src/lib/$dir/$p.h ${STAGING_INCDIR}/ + oe_libinstall -C src/lib/$dir lib$dir ${STAGING_LIBDIR}/ + done + install -m 0644 ${S}/src/lib/ecore/Ecore_Data.h ${STAGING_INCDIR}/ + install -m 0644 ${S}/ecore.m4 ${STAGING_DATADIR}/aclocal/ +} + +PACKAGES += "ecore-examples" + +FILES_${PN} = "${libdir}/libecore*.so* ${libdir}/ecore_config_ipc_ecore.so" +FILES_${PN}-dev += "${bindir}/ecore-config ${libdir}/pkgconfig" +FILES_${PN}-examples = "${bindir}/ecore_test ${bindir}/ecore_evas_test ${datadir}" diff --git a/ecore/ecore.pc.in b/ecore/ecore.pc.in new file mode 100644 index 0000000..39c2c36 --- /dev/null +++ b/ecore/ecore.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ecore +Description: Ecore event abstraction library (FIXME) +Requires: @requirements@ +Version: @VERSION@ +Libs: -L${libdir} -lecore @ecore_txt_libs@ @ecore_x_libs@ @ecore_job_libs@ @ecore_fb_libs@ @ecore_evas_libs@ @ecore_con_libs@ @ecore_ipc_libs@ @ecore_config_libs@ @ecore_file_libs@ +Cflags: -I${includedir} diff --git a/ecore/ecore.spec.in b/ecore/ecore.spec.in new file mode 100644 index 0000000..f9bf80b --- /dev/null +++ b/ecore/ecore.spec.in @@ -0,0 +1,73 @@ +%define _missing_doc_files_terminate_build 0 + +Summary: Enlightened Core X interface library +Name: @PACKAGE@ +Version: @VERSION@ +Release: 1 +License: BSD +Group: User Interface/X +Source: %{name}-%{version}.tar.gz +URL: http://www.enlightenment.org +Packager: %{?_packager:%{_packager}}%{!?_packager:Michael Jennings } +Vendor: %{?_vendorinfo:%{_vendorinfo}}%{!?_vendorinfo:The Enlightenment Project (http://www.enlightenment.org/)} +Distribution: %{?_distribution:%{_distribution}}%{!?_distribution:%{_vendor}} +#BuildSuggests: xorg-x11-devel +BuildRequires: libjpeg-devel XFree86-devel openssl-devel +BuildRequires: evas-devel eet-devel +BuildRoot: %{_tmppath}/%{name}-%{version}-root + +%description +Ecore is the event/X abstraction layer that makes doing selections, +Xdnd, general X stuff, event loops, timeouts and idle handlers fast, +optimized, and convenient. It's a separate library so anyone can make +use of the work put into Ecore to make this job easy for applications. + +%package devel +Summary: Ecore headers and development libraries. +Group: Development/Libraries +Requires: %{name} = %{version} +Requires: libjpeg-devel XFree86-devel openssl-devel +Requires: evas-devel eet-devel + +%description devel +Ecore development files + +%prep +%setup -q -n %{name}-%{version} + +%build +CFLAGS="-I/usr/kerberos/include -I/usr/X11R6/include/X11/extensions" +LDFLAGS="-L/usr/kerberos/lib -L/usr/X11R6/%{_lib}" +export CFLAGS LDFLAGS +%{configure} --prefix=%{_prefix} +%{__make} %{?_smp_mflags} %{?mflags} + +%install +%{__make} %{?mflags_install} DESTDIR=$RPM_BUILD_ROOT install + +%post +/sbin/ldconfig || : + +%postun +/sbin/ldconfig || : + +%clean +test "x$RPM_BUILD_ROOT" != "x/" && rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-, root, root) +%doc AUTHORS COPYING* README* +%{_libdir}/*.so.* +%{_libdir}/*.la +%{_bindir}/ecore_* +%{_datadir}/ecore + +%files devel +%defattr(-, root, root) +%doc doc/html +%{_libdir}/*.so +%{_libdir}/*.a +%{_bindir}/ecore-config +%{_libdir}/pkgconfig/* +%{_datadir}/aclocal/* +%{_includedir}/*.h diff --git a/ecore/ecore.supp b/ecore/ecore.supp new file mode 100644 index 0000000..0d71252 --- /dev/null +++ b/ecore/ecore.supp @@ -0,0 +1,46 @@ +# $Id: ecore.supp,v 1.2 2004/10/19 16:40:25 tsauerbeck Exp $ +# valgrind suppression file for Ecore +# +{ + BogusLeakError + Memcheck:Leak + fun:malloc + obj:/usr/X11R6/lib/libX11.so.6.2 + fun:_XmbTextPropertyToTextList + fun:XmbTextPropertyToTextList +} +{ + bogus2 + Memcheck:Param + write(buf) + obj:/lib/ld-2.3.3.so + fun:_X11TransWrite + obj:/usr/X11R6/lib/libX11.so.6.2 + fun:_XReply +} +{ + bogus3 + Memcheck:Cond + obj:/usr/X11R6/lib/libX11.so.6.2 + obj:/usr/X11R6/lib/libX11.so.6.2 + obj:/usr/X11R6/lib/libX11.so.6.2 + fun:_XlcCreateLocaleDataBase +} +{ + bogus4 + Memcheck:Param + write(buf) + obj:/lib/ld-2.3.3.so + fun:_X11TransWrite + obj:/usr/X11R6/lib/libX11.so.6.2 + fun:_XFlush +} +{ + blah, blah, xlib sucks + Memcheck:Param + writev(vector[...]) + obj:/lib/ld-2.3.3.so + obj:/usr/X11R6/lib/libX11.so.6.2 + fun:_X11TransWritev + fun:_XSend +} diff --git a/ecore/ecoreXnative.bb.in b/ecore/ecoreXnative.bb.in new file mode 100644 index 0000000..eb245fb --- /dev/null +++ b/ecore/ecoreXnative.bb.in @@ -0,0 +1,24 @@ +DESCRIPTION = "Ecore is the core event abstraction layer for the \ +enlightenment foundation libraries. It makes makes doing selections, drag \ +and drop, event loops, timeouts and idle handlers fast, optimized, and \ +convenient." +HOMEPAGE = "http://www.enlightenment.org" +MAINTAINER = "Carsten Haitzler (Rasterman) " +SECTION = "e/libs" +PRIORITY = "optional" +include ecore.oe +inherit native +DEPENDS = "eet-native evas-native" + +export EET_CONFIG = "${STAGING_BINDIR}/eet-config-native" +export EVAS_CONFIG = "${STAGING_BINDIR}/evas-config-native" + +do_stage () { + for p in ${parts}; do + dir=`echo $p|tr A-Z a-z` + install -m 0644 ${S}/src/lib/$dir/$p.h ${STAGING_INCDIR}/ + oe_libinstall -C src/lib/$dir lib$dir ${STAGING_LIBDIR}/ + done + install -m 0644 ${S}/src/lib/ecore/Ecore_Data.h ${STAGING_INCDIR}/ + install -m 0644 ${S}/ecore.m4 ${STAGING_DATADIR}/aclocal/ +} diff --git a/ecore/examples/.cvsignore b/ecore/examples/.cvsignore new file mode 100644 index 0000000..f456a0f --- /dev/null +++ b/ecore/examples/.cvsignore @@ -0,0 +1,13 @@ +.deps +.libs +Makefile +Makefile.in +args_example +con_client_example +con_server_example +config_basic_example +event_handler_example +list_destroy_example +list_example +timer_example +x_window_example diff --git a/ecore/examples/CVS/Entries b/ecore/examples/CVS/Entries new file mode 100644 index 0000000..17a55d9 --- /dev/null +++ b/ecore/examples/CVS/Entries @@ -0,0 +1,13 @@ +/.cvsignore/1.2/Sat Oct 23 14:27:09 2004//THEAD +/Makefile.am/1.11/Mon Jun 13 10:52:22 2005//THEAD +/args_example.c/1.3/Sat Jun 25 09:46:59 2005//THEAD +/con_client_example.c/1.2/Tue Mar 22 10:54:16 2005//THEAD +/con_server_example.c/1.1/Wed Jul 14 14:15:50 2004//THEAD +/config_basic_example.c/1.2/Sat May 8 14:51:05 2004//THEAD +/config_listener_example.c/1.1/Wed Jul 14 14:15:50 2004//THEAD +/event_handler_example.c/1.4/Sat Jun 25 09:46:59 2005//THEAD +/list_destroy_example.c/1.1/Wed Jul 14 14:15:50 2004//THEAD +/list_example.c/1.1/Wed Jul 14 14:15:50 2004//THEAD +/timer_example.c/1.2/Wed May 12 14:40:06 2004//THEAD +/x_window_example.c/1.1/Wed Jul 14 14:15:50 2004//THEAD +D diff --git a/ecore/examples/CVS/Repository b/ecore/examples/CVS/Repository new file mode 100644 index 0000000..14dc21d --- /dev/null +++ b/ecore/examples/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/examples diff --git a/ecore/examples/CVS/Root b/ecore/examples/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/examples/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/examples/CVS/Tag b/ecore/examples/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/examples/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/examples/Makefile.am b/ecore/examples/Makefile.am new file mode 100644 index 0000000..ffa4971 --- /dev/null +++ b/ecore/examples/Makefile.am @@ -0,0 +1,69 @@ +MAINTAINERCLEANFILES = Makefile.in +EXAMPLES = \ +timer_example \ +event_handler_example \ +args_example \ +list_example \ +list_destroy_example + +if BUILD_ECORE_CON +CON_EXAMPLES = con_server_example con_client_example +endif + +if BUILD_ECORE_CONFIG +CONFIG_EXAMPLES = config_basic_example +endif + +if BUILD_ECORE_X +X_EXAMPLES = x_window_example +endif + +noinst_PROGRAMS = $(EXAMPLES) $(CON_EXAMPLES) $(CONFIG_EXAMPLES) $(X_EXAMPLES) + +INCLUDES = \ +-I$(includedir) \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_config \ +-I$(top_srcdir)/src/lib/ecore_x \ +-I$(top_srcdir)/src/lib/ecore_con \ +@evas_cflags@ + +LDADD = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +-lm @iconv_libs@ + +DEPENDENCIES = \ +$(top_builddir)/src/lib/ecore/libecore.la + +timer_example_SOURCES = timer_example.c +list_example_SOURCES = list_example.c +list_destroy_example_SOURCES = list_destroy_example.c +event_handler_example_SOURCES = event_handler_example.c +args_example_SOURCES = args_example.c + +if BUILD_ECORE_CON +con_server_example_SOURCES = con_server_example.c +con_server_example_LDADD = $(top_builddir)/src/lib/ecore/libecore.la \ + $(top_builddir)/src/lib/ecore_con/libecore_con.la + +con_client_example_SOURCES = con_client_example.c +con_client_example_LDADD = $(top_builddir)/src/lib/ecore/libecore.la \ + $(top_builddir)/src/lib/ecore_con/libecore_con.la +endif + +if BUILD_ECORE_CONFIG +config_basic_example_SOURCES = config_basic_example.c +config_basic_example_LDADD = $(top_builddir)/src/lib/ecore/libecore.la \ + $(top_builddir)/src/lib/ecore_config/libecore_config.la \ + $(top_builddir)/src/lib/ecore_ipc/libecore_ipc.la \ + $(top_builddir)/src/lib/ecore_con/libecore_con.la +endif + +if BUILD_ECORE_X +x_window_example_SOURCES = x_window_example.c +x_window_example_LDADD = $(top_builddir)/src/lib/ecore/libecore.la \ + $(top_builddir)/src/lib/ecore_txt/libecore_txt.la \ + $(top_builddir)/src/lib/ecore_job/libecore_job.la \ + $(top_builddir)/src/lib/ecore_x/libecore_x.la + +endif diff --git a/ecore/examples/args_example.c b/ecore/examples/args_example.c new file mode 100644 index 0000000..439b09c --- /dev/null +++ b/ecore/examples/args_example.c @@ -0,0 +1,25 @@ +/* Example of how to set and retrieve program arguments. + */ +#include + +int timer_once(void *data) +{ + int argc; + char **argv; + int i; + + ecore_app_args_get(&argc, &argv); + for (i = 0; i < argc; i++) printf("ARG %i: %s\n", i, argv[i]); + ecore_main_loop_quit(); + return 1; +} + +int main(int argc, char **argv) +{ + ecore_init(); + ecore_app_args_set(argc, (const char **) argv); + ecore_timer_add(0.1, timer_once, NULL); + ecore_main_loop_begin(); + ecore_shutdown(); + return 0; +} diff --git a/ecore/examples/con_client_example.c b/ecore/examples/con_client_example.c new file mode 100644 index 0000000..1a172c7 --- /dev/null +++ b/ecore/examples/con_client_example.c @@ -0,0 +1,53 @@ +/* Ecore_Con Usage Example + */ + +#include +#include + +#include +#include +#include + +Ecore_Con_Server *svr; + +#define SOCKET_NAME "con_example" +#define SOCKET_PORT 0 + +char *msg = "Hello server!"; + +typedef int (*Handler_Func) (void *data, int type, void *event); + +int +server_data (void *data, + int ev_type, + Ecore_Con_Event_Server_Data *ev) { + printf("Data received from the server! Data was:\n"); + printf(" %*s\n", ev->size, (char *)ev->data); + ecore_main_loop_quit(); + return 0; +} + +int +main (int argc, + char *argv[]) { + ecore_con_init(); + + // Try to conect to server. + svr = ecore_con_server_connect(ECORE_CON_REMOTE_SYSTEM, "mail.valinux.co.jp", + 110, NULL); + if (NULL == svr) { + printf("*** ERROR: Unable to connect to server.\n"); + printf("*** Start con_server_example before running this program.\n"); + return 0; + } + ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, + (Handler_Func)server_data, NULL); + ecore_con_server_send(svr, msg, strlen(msg)); + + ecore_main_loop_begin(); + + ecore_con_server_del(svr); + + ecore_con_shutdown(); + return 0; +} diff --git a/ecore/examples/con_server_example.c b/ecore/examples/con_server_example.c new file mode 100644 index 0000000..6b710ad --- /dev/null +++ b/ecore/examples/con_server_example.c @@ -0,0 +1,59 @@ +/* Ecore_Con Usage Example + */ + +#include +#include + +//#include +#include +#include +#include + +Ecore_Con_Server *svr; +char *msg = "Hello client! Received your message"; + +typedef int (*Handler_Func) (void *data, int type, void *event); + +int +client_connect (Ecore_Con_Client *client, + int ev_type, + Ecore_Con_Event_Client_Add *ev) { + printf("Client connected.\n"); + return 0; +} + +int +client_disconnect (Ecore_Con_Client *client, + int ev_type, + Ecore_Con_Event_Client_Del *ev){ + printf("Client disconnected.\n"); + return 0; +} + +int +client_data (void *data, + int ev_type, + Ecore_Con_Event_Client_Data *ev) { + printf("Client sent data! Replying..."); + ecore_con_client_send(ev->client, msg, strlen(msg)); + printf("done! Data was:\n"); + printf(" %*s\n", ev->size, (char *)ev->data); + return 0; +} + +int main (int argc, char *argv[]) { + ecore_con_init(); + + printf("Server is running: waiting for connections\n"); + svr = ecore_con_server_add(ECORE_CON_LOCAL_USER, "con_example", 0, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, + (Handler_Func)client_connect, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, + (Handler_Func)client_disconnect, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, + (Handler_Func)client_data, NULL); + ecore_main_loop_begin(); + + ecore_con_shutdown(); + return 0; +} diff --git a/ecore/examples/config_basic_example.c b/ecore/examples/config_basic_example.c new file mode 100644 index 0000000..256be85 --- /dev/null +++ b/ecore/examples/config_basic_example.c @@ -0,0 +1,93 @@ +/* Shows how to handle the Enlightened Properties Library. + */ + +#include +#include +#include + +#define INT_VAL_KEY "int_val" +#define FLT_VAL_KEY "flt_val" +#define STR_VAL_KEY "str_val" +#define RGB_VAL_KEY "rgb_val" +#define THM_VAL_KEY "thm_val" + +long int_val; +float flt_val; +char *str_val; +char *rgb_val; +char *thm_val; + +void set_defaults (void) { + ecore_config_int_default(INT_VAL_KEY, 0); + ecore_config_float_default(FLT_VAL_KEY, 0.0); + ecore_config_string_default(STR_VAL_KEY, "test1"); + ecore_config_rgb_default(RGB_VAL_KEY, "#000000"); + ecore_config_theme_default(THM_VAL_KEY, "default"); +} + +void get_settings (void) { + /* Note the order here. Defaults are to be set before load, so that the + * types are definitely right. + */ + set_defaults(); + ecore_config_load(); + int_val = ecore_config_int_get(INT_VAL_KEY); + flt_val = ecore_config_float_get(FLT_VAL_KEY); + str_val = ecore_config_string_get(STR_VAL_KEY); + rgb_val = ecore_config_rgbstr_get(RGB_VAL_KEY); + thm_val = ecore_config_theme_get(THM_VAL_KEY); +} + +void change_settings(void) { + int_val += 1; + flt_val += 0.1; + if('9' == str_val[4]) { + str_val[4] = '0'; + } else { + str_val[4] += 1; + } + if('9' == rgb_val[1]) { + rgb_val[1] = '\0'; + rgb_val[3] = '\0'; + rgb_val[5] = '\0'; + } else { + rgb_val[1] += 1; + rgb_val[3] += 1; + rgb_val[5] += 1; + } + if(!strcmp(thm_val, "default")) { + thm_val = strdup("winter"); + } else { + thm_val = strdup("default"); + } +} + +void save_settings (void) { + ecore_config_int_set(INT_VAL_KEY, int_val); + ecore_config_float_set(FLT_VAL_KEY, flt_val); + ecore_config_string_set(STR_VAL_KEY, str_val); + ecore_config_rgb_set(RGB_VAL_KEY, rgb_val); + ecore_config_theme_set(THM_VAL_KEY, thm_val); + ecore_config_save(); +} + +void dump_settings (void) { + printf(" Int Value: %li\n", int_val); + printf(" Float Value: %f\n", flt_val); + printf(" String Value: %s\n", str_val); + printf(" RGB Value: %s\n", rgb_val); + printf(" Theme Value: %s\n", thm_val); +} + +int main (int argc, char **argv) { + ecore_config_init("config_basic_example"); + get_settings(); + printf("--- Original Values ---\n"); + dump_settings(); + change_settings(); + printf("--- Values to be Saved ---\n"); + dump_settings(); + save_settings(); + ecore_config_shutdown(); + return 0; +} diff --git a/ecore/examples/config_listener_example.c b/ecore/examples/config_listener_example.c new file mode 100644 index 0000000..dac95bd --- /dev/null +++ b/ecore/examples/config_listener_example.c @@ -0,0 +1,26 @@ +/* Demonstrates how to use listeners. + */ + +#include +#include +#include + +#define INT_PROPERTY_KEY "int_val" +#define CALLBACK_NAME "change listener" + +int change_listener (const char *key, const Ecore_Config_Type type, + const int tag, void *data) { + printf("Callback called when property '%s' is %li\n", key, ecore_config_int_get(key)); + return 0; +} + +int main (int argc, char *argv[]) { + /* We'll use the same config as config_basic_example.c */ + ecore_config_init("config_basic_example"); + ecore_config_int_default (INT_PROPERTY_KEY, -1); + ecore_config_listen(CALLBACK_NAME, INT_PROPERTY_KEY, change_listener, 1, NULL); + ecore_config_load(); + ecore_config_int_set(INT_PROPERTY_KEY, ecore_config_int_get(INT_PROPERTY_KEY) + 1); + ecore_config_shutdown(); + return 0; +} diff --git a/ecore/examples/event_handler_example.c b/ecore/examples/event_handler_example.c new file mode 100644 index 0000000..6e0f1f7 --- /dev/null +++ b/ecore/examples/event_handler_example.c @@ -0,0 +1,42 @@ +/* Ecore Event Handler Example. */ +#include + +Ecore_Event_Handler *handler1 = NULL, *handler2 = NULL; + +int event_hup(void *data, int ev_type, void *ev) +{ + printf("Hup signal! Remove the exit handler.\n"); + if (handler1) + { + ecore_event_handler_del(handler1); + handler1 = NULL; + } + return 0; +} + +int event_exit(void *data, int ev_type, void *ev) +{ + Ecore_Event_Signal_Exit *e; + + e = (Ecore_Event_Signal_Exit *)ev; + printf("This callback handles event type: %i\n", ECORE_EVENT_SIGNAL_EXIT); + printf("Event type recieved: %i\n", ev_type); + if (e->interrupt) printf("Exit: interrupt\n"); + if (e->quit) printf("Exit: quit\n"); + if (e->terminate) printf("Exit: terminate\n"); + ecore_main_loop_quit(); + return 1; +} + +int main(int argc, char **argv) +{ + ecore_init(); + ecore_app_args_set(argc, (const char **) argv); + handler1 = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, + event_exit, NULL); + handler2 = ecore_event_handler_add(ECORE_EVENT_SIGNAL_HUP, + event_hup, NULL); + ecore_main_loop_begin(); + ecore_shutdown(); + return 0; +} diff --git a/ecore/examples/list_destroy_example.c b/ecore/examples/list_destroy_example.c new file mode 100644 index 0000000..ccf00ff --- /dev/null +++ b/ecore/examples/list_destroy_example.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +void alloc_data (Ecore_List *list) { + ecore_list_append(list, strdup("first")); + ecore_list_append(list, strdup("second")); + ecore_list_append(list, strdup("third")); +} + +void destroy_cb (void *data) { + printf("Destroying \"%s\".\n", (char *)data); + free(data); +} + +int main (int argc, char *argv[]) { + Ecore_List *list; + + list = ecore_list_new(); + alloc_data(list); + ecore_list_set_free_cb(list, destroy_cb); + ecore_list_destroy(list); + + return 0; +} diff --git a/ecore/examples/list_example.c b/ecore/examples/list_example.c new file mode 100644 index 0000000..877c292 --- /dev/null +++ b/ecore/examples/list_example.c @@ -0,0 +1,28 @@ +#include +#include + +void print_list (Ecore_List *list) { + char *list_item; + + printf("--- Current List ---\n"); + ecore_list_goto_first(list); + while((list_item = (char*)ecore_list_next(list)) != NULL) { + printf("\t%s\n", list_item); + } +} + +int main (int argc, char *argv[]) { + Ecore_List *list; + char *first = "first"; + char *second = "second"; + char *last = "last"; + + list = ecore_list_new(); + ecore_list_append(list, last); // Insert + ecore_list_prepend(list, first); // Add to front + ecore_list_goto_index(list, 2); + ecore_list_insert(list, second); // Insert before item at index 2 + print_list(list); + + return 0; +} diff --git a/ecore/examples/timer_example.c b/ecore/examples/timer_example.c new file mode 100644 index 0000000..d04dba2 --- /dev/null +++ b/ecore/examples/timer_example.c @@ -0,0 +1,40 @@ +/* Timer example. + */ + +#include + +Ecore_Timer *timer1 = NULL; +Ecore_Timer *timer2 = NULL; +Ecore_Timer *timer3 = NULL; + +char *data1 = "data1"; +char *data2 = "data2"; +char *data3 = "data3"; + +int timer3_tick(void *data) { + printf("Tick timer %3.2f\n", ecore_time_get()); + return 1; +} + +int timer2_tick(void *data) { + printf("Repeat timer called at %3.2f seconds, data %p\n", + ecore_time_get(), data); + return 1; +} + +int timer1_tick(void *data) { + printf("Once only timer called at %3.2f seconds, data %p\n", + ecore_time_get(), data); + ecore_timer_del(timer2); + return 0; +} + +int main(int argc, char **argv) { + ecore_init(); + timer1 = ecore_timer_add(5.0, timer1_tick, data1); + timer2 = ecore_timer_add(0.5, timer2_tick, data2); + timer3 = ecore_timer_add(1.0, timer3_tick, data3); + ecore_main_loop_begin(); + ecore_shutdown(); + return 0; +} diff --git a/ecore/examples/x_window_example.c b/ecore/examples/x_window_example.c new file mode 100644 index 0000000..33ef63a --- /dev/null +++ b/ecore/examples/x_window_example.c @@ -0,0 +1,20 @@ +/* X Windows Example + */ + +#include +#include +#include + +int main (int argc, char *argv[]) { + Ecore_X_Window win; + + ecore_x_init(NULL); + + win = ecore_x_window_new(0, 20, 20, 200, 200); + ecore_x_window_show(win); + ecore_x_flush(); // Ensure requests are sent to the server. + usleep(3000000); // Sleep for 3 seconds. + + ecore_x_shutdown(); + return 0; +} diff --git a/ecore/gendoc b/ecore/gendoc new file mode 100644 index 0000000..86a8f5b --- /dev/null +++ b/ecore/gendoc @@ -0,0 +1,9 @@ +#!/bin/sh +rm -rf ./doc/html ./doc/latex ./doc/man +mkdir -p ./doc/html ./doc/latex ./doc/man 2>/dev/null +doxygen +cp doc/img/*.png doc/html/ +rm -f ecore_docs.tar ecore_docs.tar.gz +tar -cvf ecore_docs.tar doc/html doc/man doc/latex +gzip -9 ecore_docs.tar +exit 0 diff --git a/ecore/m4/CVS/Entries b/ecore/m4/CVS/Entries new file mode 100644 index 0000000..7adec05 --- /dev/null +++ b/ecore/m4/CVS/Entries @@ -0,0 +1,5 @@ +/ac_attribute.m4/1.1/Wed Mar 2 08:31:02 2005//THEAD +/ac_expand_dir.m4/1.1/Thu Jun 24 06:11:31 2004//THEAD +/ac_path_generic.m4/1.1/Thu Jun 24 06:11:31 2004//THEAD +/pkg.m4/1.2/Sat Jun 11 02:32:23 2005//THEAD +D diff --git a/ecore/m4/CVS/Repository b/ecore/m4/CVS/Repository new file mode 100644 index 0000000..443301a --- /dev/null +++ b/ecore/m4/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/m4 diff --git a/ecore/m4/CVS/Root b/ecore/m4/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/m4/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/m4/CVS/Tag b/ecore/m4/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/m4/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/m4/ac_attribute.m4 b/ecore/m4/ac_attribute.m4 new file mode 100644 index 0000000..46c1a42 --- /dev/null +++ b/ecore/m4/ac_attribute.m4 @@ -0,0 +1,14 @@ + +AC_DEFUN([AC_C___ATTRIBUTE__], +[ + AC_MSG_CHECKING(for __attribute__) + AC_CACHE_VAL(ac_cv___attribute__, [ + AC_TRY_COMPILE([#include ], + [int func(int x); int foo(int x __attribute__ ((unused))) { exit(1); }], + ac_cv___attribute__=yes, ac_cv___attribute__=no)]) + if test "$ac_cv___attribute__" = "yes"; then + AC_DEFINE(HAVE___ATTRIBUTE__, 1, [Define to 1 if your compiler has __attribute__]) + fi + AC_MSG_RESULT($ac_cv___attribute__) +]) + diff --git a/ecore/m4/ac_expand_dir.m4 b/ecore/m4/ac_expand_dir.m4 new file mode 100644 index 0000000..b5599a0 --- /dev/null +++ b/ecore/m4/ac_expand_dir.m4 @@ -0,0 +1,14 @@ +dnl AC_EXPAND_DIR(VARNAME, DIR) +dnl expands occurrences of ${prefix} and ${exec_prefix} in the given DIR, +dnl and assigns the resulting string to VARNAME +dnl example: AC_DEFINE_DIR(DATADIR, "$datadir") +dnl by Alexandre Oliva +AC_DEFUN([AC_EXPAND_DIR], [ + $1=$2 + $1=`( + test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" + eval echo \""[$]$1"\" + )` +]) + diff --git a/ecore/m4/ac_path_generic.m4 b/ecore/m4/ac_path_generic.m4 new file mode 100644 index 0000000..27b55b3 --- /dev/null +++ b/ecore/m4/ac_path_generic.m4 @@ -0,0 +1,136 @@ +dnl @synopsis AC_PATH_GENERIC(LIBRARY [, MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl +dnl Runs a LIBRARY-config script and defines LIBRARY_CFLAGS and LIBRARY_LIBS +dnl +dnl The script must support `--cflags' and `--libs' args. +dnl If MINIMUM-VERSION is specified, the script must also support the +dnl `--version' arg. +dnl If the `--with-library-[exec-]prefix' arguments to ./configure are given, +dnl it must also support `--prefix' and `--exec-prefix'. +dnl (In other words, it must be like gtk-config.) +dnl +dnl For example: +dnl +dnl AC_PATH_GENERIC(Foo, 1.0.0) +dnl +dnl would run `foo-config --version' and check that it is at least 1.0.0 +dnl +dnl If so, the following would then be defined: +dnl +dnl FOO_CFLAGS to `foo-config --cflags` +dnl FOO_LIBS to `foo-config --libs` +dnl +dnl At present there is no support for additional "MODULES" (see AM_PATH_GTK) +dnl (shamelessly stolen from gtk.m4 and then hacked around a fair amount) +dnl +dnl @author Angus Lees + +AC_DEFUN([AC_PATH_GENERIC], +[dnl +dnl we're going to need uppercase, lowercase and user-friendly versions of the +dnl string `LIBRARY' +pushdef([UP], translit([$1], [a-z], [A-Z]))dnl +pushdef([DOWN], translit([$1], [A-Z], [a-z]))dnl + +dnl +dnl Get the cflags and libraries from the LIBRARY-config script +dnl +AC_ARG_WITH(DOWN-prefix,[ --with-]DOWN[-prefix=PFX Prefix where $1 is installed (optional)], + DOWN[]_config_prefix="$withval", DOWN[]_config_prefix="") +AC_ARG_WITH(DOWN-exec-prefix,[ --with-]DOWN[-exec-prefix=PFX Exec prefix where $1 is installed (optional)], + DOWN[]_config_exec_prefix="$withval", DOWN[]_config_exec_prefix="") + + if test x$DOWN[]_config_exec_prefix != x ; then + DOWN[]_config_args="$DOWN[]_config_args --exec-prefix=$DOWN[]_config_exec_prefix" + if test x${UP[]_CONFIG+set} != xset ; then + UP[]_CONFIG=$DOWN[]_config_exec_prefix/bin/DOWN-config + fi + fi + if test x$DOWN[]_config_prefix != x ; then + DOWN[]_config_args="$DOWN[]_config_args --prefix=$DOWN[]_config_prefix" + if test x${UP[]_CONFIG+set} != xset ; then + UP[]_CONFIG=$DOWN[]_config_prefix/bin/DOWN-config + fi + fi + + AC_PATH_PROG(UP[]_CONFIG, DOWN-config, no) + ifelse([$2], , + AC_MSG_CHECKING(for $1), + AC_MSG_CHECKING(for $1 - version >= $2) + ) + no_[]DOWN="" + if test "$UP[]_CONFIG" = "no" ; then + no_[]DOWN=yes + else + UP[]_CFLAGS="`$UP[]_CONFIG $DOWN[]_config_args --cflags`" + UP[]_LIBS="`$UP[]_CONFIG $DOWN[]_config_args --libs`" + ifelse([$2], , ,[ + DOWN[]_config_major_version=`$UP[]_CONFIG $DOWN[]_config_args \ + --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + DOWN[]_config_minor_version=`$UP[]_CONFIG $DOWN[]_config_args \ + --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + DOWN[]_config_micro_version=`$UP[]_CONFIG $DOWN[]_config_args \ + --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + DOWN[]_wanted_major_version="regexp($2, [\<\([0-9]*\)], [\1])" + DOWN[]_wanted_minor_version="regexp($2, [\<\([0-9]*\)\.\([0-9]*\)], [\2])" + DOWN[]_wanted_micro_version="regexp($2, [\<\([0-9]*\).\([0-9]*\).\([0-9]*\)], [\3])" + + # Compare wanted version to what config script returned. + # If I knew what library was being run, i'd probably also compile + # a test program at this point (which also extracted and tested + # the version in some library-specific way) + if test "$DOWN[]_config_major_version" -lt \ + "$DOWN[]_wanted_major_version" \ + -o \( "$DOWN[]_config_major_version" -eq \ + "$DOWN[]_wanted_major_version" \ + -a "$DOWN[]_config_minor_version" -lt \ + "$DOWN[]_wanted_minor_version" \) \ + -o \( "$DOWN[]_config_major_version" -eq \ + "$DOWN[]_wanted_major_version" \ + -a "$DOWN[]_config_minor_version" -eq \ + "$DOWN[]_wanted_minor_version" \ + -a "$DOWN[]_config_micro_version" -lt \ + "$DOWN[]_wanted_micro_version" \) ; then + # older version found + no_[]DOWN=yes + echo -n "*** An old version of $1 " + echo -n "($DOWN[]_config_major_version" + echo -n ".$DOWN[]_config_minor_version" + echo ".$DOWN[]_config_micro_version) was found." + echo -n "*** You need a version of $1 newer than " + echo -n "$DOWN[]_wanted_major_version" + echo -n ".$DOWN[]_wanted_minor_version" + echo ".$DOWN[]_wanted_micro_version." + echo "***" + echo "*** If you have already installed a sufficiently new version, this error" + echo "*** probably means that the wrong copy of the DOWN-config shell script is" + echo "*** being found. The easiest way to fix this is to remove the old version" + echo "*** of $1, but you can also set the UP[]_CONFIG environment to point to the" + echo "*** correct copy of DOWN-config. (In this case, you will have to" + echo "*** modify your LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf" + echo "*** so that the correct libraries are found at run-time)" + fi + ]) + fi + if test "x$no_[]DOWN" = x ; then + AC_MSG_RESULT(yes) + ifelse([$3], , :, [$3]) + else + AC_MSG_RESULT(no) + if test "$UP[]_CONFIG" = "no" ; then + echo "*** The DOWN-config script installed by $1 could not be found" + echo "*** If $1 was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the UP[]_CONFIG environment variable to the" + echo "*** full path to DOWN-config." + fi + UP[]_CFLAGS="" + UP[]_LIBS="" + ifelse([$4], , :, [$4]) + fi + AC_SUBST(UP[]_CFLAGS) + AC_SUBST(UP[]_LIBS) + + popdef([UP]) + popdef([DOWN]) +]) + diff --git a/ecore/m4/pkg.m4 b/ecore/m4/pkg.m4 new file mode 100644 index 0000000..f2bfc2d --- /dev/null +++ b/ecore/m4/pkg.m4 @@ -0,0 +1,57 @@ + +dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not) +dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page +dnl also defines GSTUFF_PKG_ERRORS on error +AC_DEFUN([PKG_CHECK_MODULES], [ + succeeded=no + + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + AC_MSG_CHECKING(for $2) + + if $PKG_CONFIG --exists "$2" ; then + AC_MSG_RESULT(yes) + succeeded=yes + + AC_MSG_CHECKING($1_CFLAGS) + $1_CFLAGS=`$PKG_CONFIG --cflags "$2"` + AC_MSG_RESULT($$1_CFLAGS) + + AC_MSG_CHECKING($1_LIBS) + $1_LIBS=`$PKG_CONFIG --libs "$2"` + AC_MSG_RESULT($$1_LIBS) + else + $1_CFLAGS="" + $1_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + ifelse([$4], ,echo $$1_PKG_ERRORS,) + fi + + AC_SUBST($1_CFLAGS) + AC_SUBST($1_LIBS) + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + ifelse([$3], , :, [$3]) + else + ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4]) + fi +]) + + diff --git a/ecore/src/.cvsignore b/ecore/src/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/ecore/src/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/ecore/src/CVS/Entries b/ecore/src/CVS/Entries new file mode 100644 index 0000000..8b75dcf --- /dev/null +++ b/ecore/src/CVS/Entries @@ -0,0 +1,12 @@ +/.cvsignore/1.3/Thu Nov 13 12:30:47 2003//THEAD +/Ecore.h/1.49/Tue Sep 23 08:09:28 2003//THEAD +/Makefile.am/1.10/Thu Mar 10 15:19:35 2005//THEAD +/e_ev_filter.c/1.8/Tue Sep 23 08:09:28 2003//THEAD +/e_ev_signal.c/1.7/Tue Sep 23 08:09:28 2003//THEAD +/e_ev_x.c/1.30/Tue Sep 23 08:09:28 2003//THEAD +/e_events.c/1.16/Tue Sep 23 08:09:28 2003//THEAD +/e_ipc.c/1.5/Tue Sep 23 08:09:28 2003//THEAD +/e_util.c/1.7/Tue Sep 23 08:09:28 2003//THEAD +/e_x.c/1.56/Tue Sep 23 08:09:28 2003//THEAD +D/bin//// +D/lib//// diff --git a/ecore/src/CVS/Repository b/ecore/src/CVS/Repository new file mode 100644 index 0000000..0014dc3 --- /dev/null +++ b/ecore/src/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/src diff --git a/ecore/src/CVS/Root b/ecore/src/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/src/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/src/CVS/Tag b/ecore/src/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/src/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/src/Ecore.h b/ecore/src/Ecore.h new file mode 100644 index 0000000..9bdd679 --- /dev/null +++ b/ecore/src/Ecore.h @@ -0,0 +1,916 @@ +#ifndef E_CORE_H +#define E_CORE_H 1 + +#include +#include +#include +#include +#include + +#define XK_MISCELLANY 1 + +#include +#include +#include +#include +#include +#include +#include +#ifdef WITH_DMALLOC +#include +#endif + +#define XEV_NONE NoEventMask +#define XEV_KEY KeyPressMask | KeyReleaseMask +#define XEV_BUTTON ButtonPressMask | ButtonReleaseMask +#define XEV_KEY_PRESS KeyPressMask +#define XEV_KEY_RELEASE KeyReleaseMask +#define XEV_BUTTON_PRESS ButtonPressMask +#define XEV_BUTTON_RELEASE ButtonReleaseMask +#define XEV_IN_OUT EnterWindowMask | LeaveWindowMask +#define XEV_MOUSE_MOVE PointerMotionMask | ButtonMotionMask +#define XEV_EXPOSE ExposureMask +#define XEV_VISIBILITY VisibilityChangeMask +#define XEV_CONFIGURE StructureNotifyMask +#define XEV_CHILD_CHANGE SubstructureNotifyMask +#define XEV_CHILD_REDIRECT SubstructureRedirectMask | ResizeRedirectMask +#define XEV_FOCUS FocusChangeMask +#define XEV_PROPERTY PropertyChangeMask +#define XEV_COLORMAP ColormapChangeMask + + +#define ECORE_ATOM(atom, name) \ + if (!atom) (atom) = ecore_atom_get(name); +#define MEMCPY(src, dst, type, num) \ + memcpy(dst, src, sizeof(type) * (num)) +#define NEW(type, num) \ + malloc(sizeof(type) * (num)) +#define ZERO(ptr, type, num) \ + memset((ptr), 0, sizeof(type) * (num)) +#define NEW_PTR(num) \ + malloc(sizeof(void *) * (num)) +#define FREE(ptr) \ + { \ + free(ptr); \ + (ptr) = NULL; \ + } +#define IF_FREE(ptr) \ + {if (ptr) FREE(ptr);} +#define REALLOC(ptr, type, num) \ + { \ + if ((ptr) && (num == 0)) {free(ptr); ptr = NULL;} \ + else if (ptr) ptr = realloc((ptr), sizeof(type) * (num)); \ + else ptr = malloc(sizeof(type) * (num)); \ + } +#define REALLOC_PTR(ptr, num) \ + { \ + if ((ptr) && (num == 0)) {free(ptr); ptr = NULL;} \ + else if (ptr) ptr = realloc(ptr, sizeof(void *) * (num)); \ + else ptr = malloc(sizeof(void *) * (num)); \ + } + +#define START_LIST_DEL(type, base, cmp) \ + type *_p, *_pp; _pp = NULL; \ + _p = (base); \ + while(_p) \ + { \ + if (cmp) \ + { \ + if (_pp) _pp->next = _p->next; \ + else (base) = _p->next; +#define END_LIST_DEL \ + return; \ + } \ + _pp = _p; \ + _p = _p->next; \ + } + +#define DND_TYPE_URI_LIST 0 +#define DND_TYPE_PLAIN_TEXT 1 +#define DND_TYPE_MOZ_URL 2 +#define DND_TYPE_NETSCAPE_URL 3 + +#ifdef __cplusplus +extern "C" +{ +#endif + + extern XContext xid_context; + + typedef void (*Ecore_Error_Function) (Display * d, XErrorEvent * ev); + + typedef struct _ecore_keygrab Ecore_KeyGrab; + + typedef enum _ecore_ev_modifiers + { + ECORE_EVENT_KEY_MODIFIER_NONE = 0, + ECORE_EVENT_KEY_MODIFIER_SHIFT = (1 << 0), + ECORE_EVENT_KEY_MODIFIER_CTRL = (1 << 1), + ECORE_EVENT_KEY_MODIFIER_ALT = (1 << 2), + ECORE_EVENT_KEY_MODIFIER_WIN = (1 << 3) + } Ecore_Event_Key_Modifiers; + + typedef enum _ecore_event_stack_detail + { + ECORE_EVENT_STACK_ABOVE = Above, + ECORE_EVENT_STACK_BELOW = Below, + ECORE_EVENT_STACK_TOP_IF = TopIf, + ECORE_EVENT_STACK_BOTTOM_IF = BottomIf, + ECORE_EVENT_STACK_OPPOSITE = Opposite + } Ecore_Event_Stack_Detail; + + typedef enum _ecore_event_value_mask + { + ECORE_EVENT_VALUE_X = CWX, + ECORE_EVENT_VALUE_Y = CWY, + ECORE_EVENT_VALUE_W = CWWidth, + ECORE_EVENT_VALUE_H = CWHeight, + ECORE_EVENT_VALUE_BORDER = CWBorderWidth, + ECORE_EVENT_VALUE_SIBLING = CWSibling, + ECORE_EVENT_VALUE_STACKING = CWStackMode + } Ecore_Event_Value_Mask; + + typedef enum _ecore_event_type + { + ECORE_EVENT_MOUSE_MOVE, + ECORE_EVENT_MOUSE_DOWN, + ECORE_EVENT_MOUSE_UP, + ECORE_EVENT_MOUSE_IN, + ECORE_EVENT_MOUSE_OUT, + ECORE_EVENT_MOUSE_WHEEL, + ECORE_EVENT_KEY_DOWN, + ECORE_EVENT_KEY_UP, + ECORE_EVENT_WINDOW_MAP, + ECORE_EVENT_WINDOW_UNMAP, + ECORE_EVENT_WINDOW_CREATE, + ECORE_EVENT_WINDOW_DESTROY, + ECORE_EVENT_WINDOW_CONFIGURE, + ECORE_EVENT_WINDOW_CONFIGURE_REQUEST, + ECORE_EVENT_WINDOW_MAP_REQUEST, + ECORE_EVENT_WINDOW_PROPERTY, + ECORE_EVENT_WINDOW_CIRCULATE, + ECORE_EVENT_WINDOW_CIRCULATE_REQUEST, + ECORE_EVENT_WINDOW_REPARENT, + ECORE_EVENT_WINDOW_EXPOSE, + ECORE_EVENT_WINDOW_VISIBILITY, + ECORE_EVENT_WINDOW_SHAPE, + ECORE_EVENT_WINDOW_FOCUS_IN, + ECORE_EVENT_WINDOW_FOCUS_OUT, + ECORE_EVENT_MESSAGE, + ECORE_EVENT_WINDOW_DELETE, + ECORE_EVENT_COLORMAP, + + ECORE_EVENT_DND_DROP_REQUEST, + ECORE_EVENT_DND_DROP_END, + ECORE_EVENT_DND_DROP_POSITION, + ECORE_EVENT_DND_DROP, + ECORE_EVENT_DND_DROP_STATUS, + ECORE_EVENT_DND_DATA_REQUEST, + ECORE_EVENT_PASTE_REQUEST, + ECORE_EVENT_CLEAR_SELECTION, + + ECORE_EVENT_CHILD, + ECORE_EVENT_USER, + + ECORE_EVENT_MAX + } Ecore_Event_Type; + + typedef struct _ecore_event + { + Ecore_Event_Type type; + char ignore; + void *event; + void (*ev_free) (void *evnt); + struct _ecore_event *next; + } Ecore_Event; + + typedef struct _ecore_event_fd_handler + { + int fd; + void (*func) (int fd); + struct _ecore_event_fd_handler *next; + } Ecore_Event_Fd_Handler; + + typedef struct _ecore_event_pid_handler + { + pid_t pid; + void (*func) (pid_t pid); + struct _ecore_event_pid_handler *next; + } Ecore_Event_Pid_Handler; + + typedef struct _ecore_event_ipc_handler + { + int ipc; + void (*func) (int ipc); + struct _ecore_event_ipc_handler *next; + } Ecore_Event_Ipc_Handler; + + typedef struct _ecore_event_timer + { + char *name; + void (*func) (int val, void *data); + int val; + void *data; + double in; + char just_added; + struct _ecore_event_timer *next; + } Ecore_Event_Timer; + + typedef struct _ecore_event_key_down + { + Window win, root; + Ecore_Event_Key_Modifiers mods; + char *key; + char *compose; + Time time; + } Ecore_Event_Key_Down; + + typedef struct _ecore_event_key_up + { + Window win, root; + Ecore_Event_Key_Modifiers mods; + char *key; + char *compose; + Time time; + } Ecore_Event_Key_Up; + + typedef struct _ecore_event_mouse_down + { + Window win, root; + Ecore_Event_Key_Modifiers mods; + int button; + int x, y; + int rx, ry; + int double_click, triple_click; + Time time; + } Ecore_Event_Mouse_Down; + + typedef struct _ecore_event_mouse_up + { + Window win, root; + Ecore_Event_Key_Modifiers mods; + int button; + int x, y; + int rx, ry; + Time time; + } Ecore_Event_Mouse_Up; + + typedef struct _ecore_event_wheel + { + Window win, root; + Ecore_Event_Key_Modifiers mods; + int x, y, z; + int rx, ry; + Time time; + } Ecore_Event_Wheel; + + typedef struct _ecore_event_mouse_move + { + Window win, root; + Ecore_Event_Key_Modifiers mods; + int x, y; + int rx, ry; + Time time; + } Ecore_Event_Mouse_Move; + + typedef struct _ecore_event_window_enter + { + Window win, root; + int x, y; + int rx, ry; + Ecore_Event_Key_Modifiers mods; + Time time; + } Ecore_Event_Window_Enter; + + typedef struct _ecore_event_window_leave + { + Window win, root; + int x, y; + int rx, ry; + Ecore_Event_Key_Modifiers mods; + Time time; + } Ecore_Event_Window_Leave; + + typedef struct _ecore_event_window_focus_in + { + Window win, root; + int key_grab; + Time time; + } Ecore_Event_Window_Focus_In; + + typedef struct _ecore_event_window_focus_out + { + Window win, root; + int key_grab; + Time time; + } Ecore_Event_Window_Focus_Out; + + typedef struct _ecore_event_window_expose + { + Window win, root; + int x, y, w, h; + } Ecore_Event_Window_Expose; + + typedef struct _ecore_event_window_visibility + { + Window win, root; + int fully_obscured; + } Ecore_Event_Window_Visibility; + + typedef struct _ecore_event_window_create + { + Window win, root; + int override; + } Ecore_Event_Window_Create; + + typedef struct _ecore_event_window_destroy + { + Window win, root; + } Ecore_Event_Window_Destroy; + + typedef struct _ecore_event_window_map + { + Window win, root; + } Ecore_Event_Window_Map; + + typedef struct _ecore_event_window_unmap + { + Window win, root; + } Ecore_Event_Window_Unmap; + + typedef struct _ecore_event_window_map_request + { + Window win, root; + } Ecore_Event_Window_Map_Request; + + typedef struct _ecore_event_window_reparent + { + Window win, root; + Window parent_from, parent; + } Ecore_Event_Window_Reparent; + + typedef struct _ecore_event_window_configure + { + Window win, root; + int x, y, w, h; + int wm_generated; + } Ecore_Event_Window_Configure; + + typedef struct _ecore_event_window_configure_request + { + Window win, root; + int x, y, w, h; + int border; + Window stack_win; + Ecore_Event_Stack_Detail detail; + Ecore_Event_Value_Mask mask; + } Ecore_Event_Window_Configure_Request; + + typedef struct _ecore_event_window_circulate + { + Window win, root; + int lower; + } Ecore_Event_Window_Circulate; + + typedef struct _ecore_event_window_circulate_request + { + Window win, root; + int lower; + } Ecore_Event_Window_Circulate_Request; + + typedef struct _ecore_event_window_property + { + Window win, root; + Atom atom; + Time time; + } Ecore_Event_Window_Property; + + typedef struct _ecore_event_window_shape + { + Window win, root; + Time time; + } Ecore_Event_Window_Shape; + + typedef struct _ecore_event_message + { + Window win; + int format; + Atom atom; + union + { + char b[20]; + short s[10]; + long l[5]; + } + data; + } Ecore_Event_Message; + + typedef struct _ecore_event_colormap + { + Window win, root; + Colormap cmap; + int installed; + } Ecore_Event_Colormap; + + typedef struct _ecore_event_window_delete + { + Window win, root; + } Ecore_Event_Window_Delete; + + typedef struct _ecore_event_paste_request + { + Window win, root, source_win; + char *string; + } Ecore_Event_Paste_Request; + + typedef struct _ecore_event_clear_selection + { + Window win, root; + Atom selection; + } Ecore_Event_Clear_Selection; + + typedef struct _ecore_event_dnd_drop_request + { + Window win, root, source_win; + int num_files; + char **files; + int copy, link, move; + } Ecore_Event_Dnd_Drop_Request; + + typedef struct _ecore_event_dnd_drop_end + { + Window win, root, source_win; + } Ecore_Event_Dnd_Drop_End; + + typedef struct _ecore_event_dnd_drop_position + { + Window win, root, source_win; + int x, y; + } Ecore_Event_Dnd_Drop_Position; + + typedef struct _ecore_event_dnd_drop + { + Window win, root, source_win; + } Ecore_Event_Dnd_Drop; + + typedef struct _ecore_event_dnd_drop_status + { + Window win, root, source_win; + int x, y, w, h; + int copy, link, move, e_private; + int all_position_msgs; + int ok; + } Ecore_Event_Dnd_Drop_Status; + + typedef struct _ecore_event_dnd_data_request + { + Window win, root, source_win; + Atom destination_atom; + int plain_text; + int uri_list; + int moz_url; + int netscape_url; + } Ecore_Event_Dnd_Data_Request; + + typedef struct _ecore_event_child + { + pid_t pid; + int exit_code; + } Ecore_Event_Child; + + typedef struct _ecore_event_user + { + int num; + int hup; + } Ecore_Event_User; + + typedef struct _ecore_event_ipc_service + { + int service; + void (*func) (int fd); + struct _ecore_event_ipc_service *next; + } Ecore_Event_Ipc_Service; + + + typedef struct _ecore_xid + { + Window win; + Window parent; + Window root; + int children_num; + Window *children; + int x, y, w, h; + int mapped; + int mouse_in; + int depth; + int gravity; + int coords_invalid; + int bw; + int (*grab_button_auto_replay) (Ecore_Event_Mouse_Down *ev); + } Ecore_XID; + + + /* ---------------- API CALLS BELOW --------------------*/ + + /* ---------------- X WRAPPER CALLS */ + + int ecore_x_get_fd(void); + void ecore_set_error_handler(Ecore_Error_Function func); + void ecore_reset_error_handler(void); + + /** + * ecore_display_init - Establishes a connection to the X server + * @display: The name of the display to connect to + * + * This function creates a connection to the X server. If + * @display is NULL, the name is taken from the $DISPLAY + * environment variable. + */ + int ecore_display_init(char *display); + + int ecore_events_pending(void); + void ecore_get_next_event(XEvent * event); + int ecore_event_shape_get_id(void); + void ecore_sync(void); + void ecore_flush(void); + + /* ---------------- WINDOW CHILD HANDLING */ + + void ecore_del_child(Window win, Window child); + void ecore_add_child(Window win, Window child); + void ecore_raise_child(Window win, Window child); + void ecore_lower_child(Window win, Window child); + Ecore_XID *ecore_add_xid(Window win, int x, int y, int w, int h, + int depth, Window parent); + Ecore_XID *ecore_validate_xid(Window win); + void ecore_unvalidate_xid(Window win); + + /* ---------------- WINDOWS-RELATED CALLS */ + + Window ecore_window_new(Window parent, int x, int y, int w, + int h); + Window ecore_window_override_new(Window parent, int x, int y, + int w, int h); + Window ecore_window_input_new(Window parent, int x, int y, int w, + int h); + void ecore_window_set_events_propagate(Window win, + int propagate); + void ecore_window_show(Window win); + void ecore_window_hide(Window win); + void ecore_window_set_background_pixmap(Window win, + Pixmap pmap); + void ecore_window_set_shape_mask(Window win, Pixmap mask); + void ecore_window_add_shape_mask(Window win, Pixmap mask); + void ecore_window_set_shape_window(Window win, Window src, + int x, int y); + void ecore_window_add_shape_window(Window win, Window src, + int x, int y); + void ecore_window_set_shape_rectangle(Window win, int x, int y, + int w, int h); + void ecore_window_add_shape_rectangle(Window win, int x, int y, + int w, int h); + void ecore_window_set_shape_rectangles(Window win, + XRectangle * rect, + int num); + void ecore_window_add_shape_rectangles(Window win, + XRectangle * rect, + int num); + void ecore_window_clip_shape_by_rectangle(Window win, int x, + int y, int w, int h); + XRectangle *ecore_window_get_shape_rectangles(Window win, int *num); + void ecore_window_select_shape_events(Window win); + void ecore_window_unselect_shape_events(Window win); + void ecore_window_clear(Window win); + void ecore_window_clear_area(Window win, int x, int y, int w, + int h); + void ecore_window_set_events(Window win, long mask); + void ecore_window_remove_events(Window win, long mask); + void ecore_window_add_events(Window win, long mask); + void ecore_window_move(Window win, int x, int y); + void ecore_window_resize(Window win, int w, int h); + void ecore_window_move_resize(Window win, int x, int y, int w, + int h); + void ecore_window_destroy(Window win); + void ecore_window_reparent(Window win, Window parent, int x, + int y); + void ecore_window_raise(Window win); + void ecore_window_lower(Window win); + void ecore_window_get_geometry(Window win, int *x, int *y, + int *w, int *h); + int ecore_window_get_depth(Window win); + int ecore_window_exists(Window win); + Window ecore_window_get_parent(Window win); + Window *ecore_window_get_children(Window win, int *num); + int ecore_window_mouse_in(Window win); + void ecore_window_mouse_set_in(Window win, int in); + Window ecore_window_get_root(Window win); + void ecore_window_set_delete_inform(Window win); + void ecore_window_property_set(Window win, Atom type, + Atom format, int size, + void *data, int number); + void *ecore_window_property_get(Window win, Atom type, + Atom format, int *size); + void ecore_window_dnd_advertise(Window win); + void ecore_window_ignore(Window win); + void ecore_window_no_ignore(Window win); + int ecore_window_is_ignored(Window win); + Window ecore_window_get_at_xy(int x, int y); + + int ecore_window_dnd_capable(Window win); + void ecore_window_dnd_handle_motion(Window source_win, int x, + int y, int dragging); + void ecore_window_dnd_ok(int ok); + void ecore_window_dnd_finished(void); + void ecore_window_dnd_send_status_ok(Window source_win, + Window win, int x, int y, + int w, int h); + void ecore_window_dnd_send_finished(Window source_win, + Window win); + void ecore_window_set_title(Window win, char *title); + void ecore_window_set_name_class(Window win, char *name, + char *); + void ecore_window_get_name_class(Window win, char **name, + char **name_class); + char *ecore_window_get_machine(Window win); + char *ecore_window_get_command(Window win); + char *ecore_window_get_icon_name(Window win); + void ecore_window_get_hints(Window win, int *accepts_focus, + int *initial_state, + Pixmap * icon_pixmap, + Pixmap * icon_mask, + Window * icon_window, + Window * window_group); + void ecore_window_set_min_size(Window win, int w, int h); + void ecore_window_set_max_size(Window win, int w, int h); + void ecore_window_set_xy_hints(Window win, int x, int y); + void ecore_window_get_frame_size(Window win, int *l, int *r, + int *t, int *b); + int ecore_window_save_under(Window win); + void ecore_window_hint_set_layer(Window win, int layer); + void ecore_window_hint_set_sticky(Window win, int sticky); + void ecore_window_hint_set_borderless(Window win); + int ecore_window_get_gravity(Window win); + void ecore_window_gravity_reset(Window win); + void ecore_window_gravity_set(Window win, int gravity); + void ecore_window_bit_gravity_set(Window win, int gravity); + void ecore_window_get_root_relative_location(Window win, + int *x, int *y); + void ecore_window_send_event_move_resize(Window win, int x, + int y, int w, int h); + void ecore_window_send_client_message(Window win, Atom type, + int format, void *data); + void ecore_window_add_to_save_set(Window win); + void ecore_window_del_from_save_set(Window win); + void ecore_window_kill_client(Window win); + void ecore_window_set_border_width(Window win, int bw); + int ecore_window_get_border_width(Window win); + int ecore_window_get_wm_size_hints(Window win, + XSizeHints * hints, + int *mask); + int ecore_window_is_visible(Window win); + int ecore_window_is_normal(Window win); + + /** + * ecore_window_is_manageable - Returns 1 if a window can be managed by the wm. + * @win: the window for which to query. + * + * This function returns 0 if the window is unmapped, should be ignored + * by the window manager or is of the InputOnly class, 1 otherwise. + */ + int ecore_window_is_manageable(Window win); + + void ecore_windows_restack(Window * wins, int num); + void ecore_window_stack_above(Window win, Window above); + void ecore_window_stack_below(Window win, Window below); + char *ecore_window_get_title(Window win); + void ecore_window_button_grab_auto_replay_set(Window win, + int (*func) (Ecore_Event_Mouse_Down *ev)); + void *ecore_window_button_grab_auto_replay_get(Window win); + Window ecore_window_root(void); + void ecore_window_get_virtual_area(Window win, int *area_x, + int *area_y); + + /* ---------------- PIXMAP CALLS */ + + Pixmap ecore_pixmap_new(Window win, int w, int h, int dep); + void ecore_pixmap_free(Pixmap pmap); + + /* ---------------- POINTER CALLS */ + + void ecore_pointer_xy(Window win, int *x, int *y); + void ecore_pointer_xy_set(int x, int y); + void ecore_pointer_xy_get(int *x, int *y); + void ecore_pointer_warp_by(int dx, int dy); + void ecore_pointer_warp_to(int x, int y); + void ecore_pointer_replay(Time t); + void ecore_pointer_grab(Window win, Time t); + void ecore_pointer_ungrab(Time t); + + /* ---------------- KEYBOARD-RELATED CALLS */ + + KeySym ecore_key_get_keysym_from_keycode(KeyCode keycode); + char *ecore_key_get_string_from_keycode(KeyCode keycode); + void ecore_key_grab(char *key, Ecore_Event_Key_Modifiers mods, + int anymod, int sync); + void ecore_key_ungrab(char *key, + Ecore_Event_Key_Modifiers mods, + int anymod); + KeyCode ecore_key_get_keycode(char *key); + char *ecore_keypress_translate_into_typeable(Ecore_Event_Key_Down * e); + + void ecore_event_allow(int mode, Time t); + + /* ---------------- LOCKS AND MODIFIER CALLS */ + + int ecore_lock_mask_scroll_get(void); + int ecore_lock_mask_num_get(void); + int ecore_lock_mask_caps_get(void); + void ecore_lock_scroll_set(int onoff); + int ecore_lock_scroll_get(void); + void ecore_lock_num_set(int onoff); + int ecore_lock_num_get(void); + void ecore_lock_caps_set(int onoff); + int ecore_lock_caps_get(void); + + int ecore_mod_mask_shift_get(void); + int ecore_mod_mask_ctrl_get(void); + int ecore_mod_mask_alt_get(void); + int ecore_mod_mask_win_get(void); + void ecore_mod_shift_set(int onoff); + int ecore_mod_shift_get(void); + void ecore_mod_ctrl_set(int onoff); + int ecore_mod_ctrl_get(void); + void ecore_mod_alt_set(int onoff); + int ecore_mod_alt_get(void); + void ecore_mod_win_set(int onoff); + int ecore_mod_win_get(void); + + int ecore_lock_mask_get(void); + int ecore_modifier_mask_get(void); + Window ecore_get_key_grab_win(void); + Display *ecore_display_get(void); + void ecore_focus_window_set(Window win); + Window ecore_focus_window_get(void); + void ecore_focus_to_window(Window win); + void ecore_focus_mode_reset(void); + Atom ecore_atom_get(char *name); + + + /* ---------------- GRABBING/UNGRABBING CALLS */ + + /** + * ecore_grab - Grabs the X server connection + * + * This function wraps XGrabServer, which prevents all other + * clients from receiving events. Calls are reference-counted. + */ + void ecore_grab(void); + + /** + * ecore_ungrab - Ungrabs the X server connection + * + * This function releases the server, provided that ecore_grab() + * has been called the same number of times as ecore_ungrab(). + */ + void ecore_ungrab(void); + + void ecore_grab_mouse(Window win, int confine, Cursor cursor); + void ecore_ungrab_mouse(void); + Window ecore_grab_window_get(void); + + void ecore_button_grab(Window win, int button, int events, + Ecore_Event_Key_Modifiers mod, + int any_mod); + void ecore_button_ungrab(Window win, int button, + Ecore_Event_Key_Modifiers mod, + int any_mod); + void ecore_keyboard_grab(Window win); + void ecore_keyboard_ungrab(void); + Window ecore_keyboard_grab_window_get(void); + + + /* ----------------- GRAPHICS CONTEXT AND DRAWING CALLS */ + + GC ecore_gc_new(Drawable d); + void ecore_gc_free(GC gc); + void ecore_gc_set_fg(GC gc, int val); + void ecore_gc_set_include_inferiors(GC gc); + void ecore_fill_rectangle(Drawable d, GC gc, int x, int y, + int w, int h); + void ecore_draw_rectangle(Drawable d, GC gc, int x, int y, + int w, int h); + void ecore_draw_line(Drawable d, GC gc, int x1, int y1, int x2, + int y2); + void ecore_draw_point(Drawable d, GC gc, int x, int y); + void ecore_area_copy(Drawable src, Drawable dest, GC gc, + int sx, int sy, int sw, int sh, int dx, + int dy); + + + /* ---------------- DRAG AND DROP CALLS */ + + + int ecore_dnd_selection_convert(Window win, Window req, + Atom type); + void *ecore_dnd_selection_get(Window win, Window req, Atom type, + int *size); + void ecore_dnd_set_data(Window win); + void ecore_dnd_set_action(Window win); + + void ecore_dnd_send_data(Window win, Window source_win, + void *data, int size, Atom dest_atom, + int type); + void ecore_dnd_set_mode_copy(void); + void ecore_dnd_set_mode_link(void); + void ecore_dnd_set_mode_move(void); + void ecore_dnd_set_mode_ask(void); + void ecore_dnd_own_selection(Window win); + void ecore_dnd_send_drop(Window win, Window source_win); + void ecore_get_virtual_area(int *area_x, int *area_y); + void ecore_clear_target_status(void); + + + /* ---------------- IPC CALLS */ + + void ecore_event_ipc_init(char *path); + void ecore_event_ipc_cleanup(void); + void ecore_add_ipc_service(int service, void (*func) (int fd)); + void ecore_del_ipc_service(int service); + + /* ---------------- SELECTION CALLS */ + + char *ecore_selection_get_data(Window win, Atom prop); + Window ecore_selection_request(void); + Window ecore_selection_set(char *string); + + /* ---------------- CURSOR LOOK CALLS */ + + void ecore_set_blank_pointer(Window w); + Cursor ecore_cursor_new(Pixmap pmap, Pixmap mask, int x, int y, + int fr, int fg, int fb, int br, int bg, + int bb); + void ecore_cursor_free(Cursor c); + void ecore_cursor_set(Window win, Cursor c); + + /* ---------------- EVENT-HANDLING CALLS */ + + void ecore_add_event(Ecore_Event_Type type, void *event, + void (*ev_free) (void *event)); + void ecore_del_event(void *event); + void ecore_del_all_events(void); + Ecore_Event *ecore_get_last_event(void); + void ecore_add_event_fd(int fd, void (*func) (int fd)); + void ecore_del_event_fd(int fd); + void ecore_add_event_pid(pid_t pid, void (*func) (pid_t pid)); + void ecore_del_event_pid(pid_t pid); + void ecore_add_event_ipc(int ipc, void (*func) (int ipc)); + void ecore_del_event_ipc(int ipc); + void ecore_event_loop(void); + void ecore_event_loop_quit(void); + void ecore_add_event_timer(char *name, double in, + void (*func) (int val, void *data), + int val, void *data); + void *ecore_del_event_timer(char *name); + void ecore_event_filter(Ecore_Event * ev); + void ecore_event_filter_events_handle(Ecore_Event * ev); + void ecore_event_filter_idle_handle(void); + + /** + * ecore_event_filter_init - Setup event handlers + * + * This function initializes all ECORE_EVENT_MAX + * event handler to be empty. + */ + void ecore_event_filter_init(void); + + void ecore_event_filter_handler_add(Ecore_Event_Type type, + void (*func) (Ecore_Event *ev)); + void ecore_event_filter_idle_handler_add(void (*func) (void *data), void *data); + + /** + * ecore_event_signal_init - Setup for default signal handlers + * + * This function initializes signal handlers for various + * signals via sigaction(). + */ + void ecore_event_signal_init(void); + + int ecore_event_signal_events_pending(void); + + /** + * ecore_event_x_init - Ecore X initialization + * + * This function initializes Ecore's X event handling + * callbacks. + */ + void ecore_event_x_init(void); + + /* ---------------- MISCELLANEOUS CALLS */ + + double ecore_get_time(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ecore/src/Makefile.am b/ecore/src/Makefile.am new file mode 100644 index 0000000..f8d2f8c --- /dev/null +++ b/ecore/src/Makefile.am @@ -0,0 +1,12 @@ +MAINTAINERCLEANFILES = Makefile.in + +SUBDIRS = lib bin + +EXTRA_DIST = \ + e_ev_filter.c \ + e_ev_signal.c \ + e_ev_x.c \ + e_events.c \ + e_ipc.c \ + e_util.c \ + e_x.c diff --git a/ecore/src/bin/.cvsignore b/ecore/src/bin/.cvsignore new file mode 100644 index 0000000..67aa34d --- /dev/null +++ b/ecore/src/bin/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +ecore_evas_test +ecore_test diff --git a/ecore/src/bin/CVS/Entries b/ecore/src/bin/CVS/Entries new file mode 100644 index 0000000..c8c44fb --- /dev/null +++ b/ecore/src/bin/CVS/Entries @@ -0,0 +1,10 @@ +/.cvsignore/1.1/Thu Nov 13 12:30:47 2003//THEAD +/Makefile.am/1.16/Thu Jun 23 03:33:43 2005//THEAD +/ecore_config.c/1.1/Thu Jun 23 03:33:43 2005//THEAD +/ecore_evas_test.c/1.2/Tue Sep 23 08:09:28 2003//THEAD +/ecore_evas_test.h/1.3/Wed Feb 23 20:55:18 2005//THEAD +/ecore_evas_test_app.c/1.7/Sun May 22 03:01:59 2005//THEAD +/ecore_evas_test_bg.c/1.5/Thu Jul 7 03:31:34 2005//THEAD +/ecore_evas_test_calibrate.c/1.5/Sat Jan 8 18:40:31 2005//THEAD +/ecore_test.c/1.18/Mon Jun 20 09:18:01 2005//THEAD +D diff --git a/ecore/src/bin/CVS/Repository b/ecore/src/bin/CVS/Repository new file mode 100644 index 0000000..5c94258 --- /dev/null +++ b/ecore/src/bin/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/src/bin diff --git a/ecore/src/bin/CVS/Root b/ecore/src/bin/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/src/bin/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/src/bin/CVS/Tag b/ecore/src/bin/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/src/bin/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/src/bin/Makefile.am b/ecore/src/bin/Makefile.am new file mode 100644 index 0000000..67e6a17 --- /dev/null +++ b/ecore/src/bin/Makefile.am @@ -0,0 +1,148 @@ +MAINTAINERCLEANFILES = Makefile.in + +if BUILD_ECORE_EVAS +ECORE_EVAS_LIB = $(top_builddir)/src/lib/ecore_evas/libecore_evas.la +else +ECORE_EVAS_LIB = +endif + +if BUILD_ECORE_X +ECORE_X_LIB = $(top_builddir)/src/lib/ecore_x/libecore_x.la +else +ECORE_X_LIB = +endif + +if BUILD_ECORE_FB +ECORE_FB_LIB = $(top_builddir)/src/lib/ecore_fb/libecore_fb.la +else +ECORE_FB_LIB = +endif + +if BUILD_ECORE_JOB +ECORE_JOB_LIB = $(top_builddir)/src/lib/ecore_job/libecore_job.la +else +ECORE_JOB_LIB = +endif + +if BUILD_ECORE_CON +ECORE_CON_LIB = $(top_builddir)/src/lib/ecore_con/libecore_con.la +else +ECORE_CON_LIB = +endif + +if BUILD_ECORE_IPC +ECORE_IPC_LIB = $(top_builddir)/src/lib/ecore_ipc/libecore_ipc.la +else +ECORE_IPC_LIB = +endif + +if BUILD_ECORE_TXT +ECORE_TXT_LIB = $(top_builddir)/src/lib/ecore_txt/libecore_txt.la +else +ECORE_TXT_LIB = +endif + +if BUILD_ECORE_CONFIG +ECORE_CONFIG_LIB = $(top_builddir)/src/lib/ecore_config/libecore_config.la +else +ECORE_CONFIG_LIB = +endif + +INCLUDES = \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_evas \ +-I$(top_srcdir)/src/lib/ecore_x \ +-I$(top_srcdir)/src/lib/ecore_fb \ +-I$(top_srcdir)/src/lib/ecore_job \ +-I$(top_srcdir)/src/lib/ecore_con \ +-I$(top_srcdir)/src/lib/ecore_ipc \ +-I$(top_srcdir)/src/lib/ecore_txt @iconv_cflags@ \ +-I$(top_srcdir)/src/lib/ecore_config \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_evas \ +-I$(top_builddir)/src/lib/ecore_x \ +-I$(top_builddir)/src/lib/ecore_fb \ +-I$(top_builddir)/src/lib/ecore_job \ +-I$(top_builddir)/src/lib/ecore_con \ +-I$(top_builddir)/src/lib/ecore_ipc \ +-I$(top_builddir)/src/lib/ecore_txt @iconv_cflags@ \ +-I$(top_builddir)/src/lib/ecore_config \ +@evas_cflags@ \ +@x_cflags@ \ +@eet_cflags@ + +bin_PROGRAMS = \ +ecore_test \ +ecore_evas_test \ +ecore_config + +ecore_test_SOURCES = \ +ecore_test.c + +ecore_test_LDADD = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(ECORE_X_LIB) \ +$(ECORE_TXT_LIB) \ +$(ECORE_JOB_LIB) \ +$(ECORE_FB_LIB) \ +$(ECORE_EVAS_LIB) \ +$(ECORE_CON_LIB) \ +$(ECORE_IPC_LIB) \ +-lm @iconv_libs@ + +ecore_test_CFLAGS = \ +$(CFLAGS) \ +$(INCLUDES) + +ecore_test_DEPENDENCIES = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(ECORE_X_LIB) \ +$(ECORE_TXT_LIB) \ +$(ECORE_JOB_LIB) \ +$(ECORE_FB_LIB) \ +$(ECORE_EVAS_LIB) \ +$(ECORE_CON_LIB) \ +$(ECORE_IPC_LIB) + +ecore_evas_test_SOURCES = \ +ecore_evas_test.c \ +ecore_evas_test_app.c \ +ecore_evas_test_bg.c \ +ecore_evas_test_calibrate.c \ +ecore_evas_test.h + +ecore_evas_test_LDADD = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(ECORE_X_LIB) \ +$(ECORE_TXT_LIB) \ +$(ECORE_JOB_LIB) \ +$(ECORE_FB_LIB) \ +$(ECORE_EVAS_LIB) \ +$(ECORE_CON_LIB) \ +$(ECORE_IPC_LIB) \ +-lm @iconv_libs@ + +ecore_evas_test_CFLAGS = \ +$(CFLAGS) \ +$(INCLUDES) + +ecore_evas_test_DEPENDENCIES = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(ECORE_JOB_LIB) \ +$(ECORE_FB_LIB) \ +$(ECORE_X_LIB) \ +$(ECORE_EVAS_LIB) \ +$(ECORE_CON_LIB) \ +$(ECORE_IPC_LIB) \ +$(ECORE_TXT_LIB) + +ecore_config_SOURCES = \ +ecore_config.c + +ecore_config_LDADD = \ +$(ECORE_CONFIG_LIB) + +ecore_config_DEPENDENCIES = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(ECORE_CONFIG_LIB) + diff --git a/ecore/src/bin/ecore_config.c b/ecore/src/bin/ecore_config.c new file mode 100644 index 0000000..690d9fd --- /dev/null +++ b/ecore/src/bin/ecore_config.c @@ -0,0 +1,229 @@ +#include "config.h" +#include "Ecore.h" + +#ifdef BUILD_ECORE_CONFIG +#include "Ecore_Config.h" + +int +set(const char *key, int ec_type, const char *value) +{ + int i; + float f; + + switch (ec_type) { + case PT_INT: + case PT_BLN: + i = atoi(value); + if (ecore_config_typed_set(key, &i, ec_type) != ECORE_CONFIG_ERR_SUCC) return -1; + break; + case PT_FLT: + f = atof(value); + if (ecore_config_typed_set(key, &f, ec_type) != ECORE_CONFIG_ERR_SUCC) return -1; + break; + case PT_STR: + case PT_RGB: + case PT_THM: + case PT_NIL: + if (ecore_config_typed_set(key, value, ec_type) != ECORE_CONFIG_ERR_SUCC) return -1; + break; + } + return 0; +} + +int +get(const char *key) +{ + Ecore_Config_Prop *e; + + if (!(e = ecore_config_get(key))) { + fprintf(stderr, "No such property\n"); + return -1; + } + + switch (e->type) { + case PT_NIL: + printf("\n"); + break; + case PT_INT: + printf("%ld\n", ecore_config_int_get(key)); + break; + case PT_BLN: + printf("%d\n", ecore_config_boolean_get(key)); + break; + case PT_FLT: + printf("%lf\n", ecore_config_float_get(key)); + break; + case PT_STR: + printf("%s\n", ecore_config_string_get(key)); + break; + case PT_RGB: + printf("%s\n", ecore_config_argbstr_get(key)); + break; + case PT_THM: + printf("%s\n", ecore_config_theme_get(key)); + break; + default: + fprintf(stderr, "Property has unrecognised type"); + return -1; + } + return 0; +} + +int +list(const char *file) +{ + fprintf(stderr, "Command not yet supported\n"); + return -1; +} + +int +get_type(const char *key) +{ + Ecore_Config_Prop *e; + if (!(e = ecore_config_get(key))) { + fprintf(stderr, "No such property\n"); + return -1; + } + + switch (e->type) { + case PT_NIL: + printf("nil\n"); + break; + case PT_INT: + printf("int\n"); + break; + case PT_BLN: + printf("bool\n"); + break; + case PT_FLT: + printf("float\n"); + break; + case PT_STR: + printf("string\n"); + break; + case PT_RGB: + printf("rgb\n"); + break; + case PT_THM: + printf("theme\n"); + break; + default: + fprintf(stderr, "Property has unrecognised type"); + return -1; + } + return 0; +} + +int +parse_type(const char *type) +{ + if (!strcmp("nil", type)) { + return PT_NIL; + } else if (!strcmp("int", type)) { + return PT_INT; + } else if (!strcmp("float", type)) { + return PT_FLT; + } else if (!strcmp("bool", type)) { + return PT_BLN; + } else if (!strcmp("str", type)) { + return PT_STR; + } else if (!strcmp("rgb", type)) { + return PT_RGB; + } else if (!strcmp("theme", type)) { + return PT_THM; + } + return -1; +} + +void +usage_and_exit(const char *prog, int ret, const char *msg) +{ + if (msg) fprintf(stderr, msg); + fprintf(stderr, "Usage: %s {get|set|type|list} [args...]\n", prog); + fprintf(stderr, "LIST: %s list\n", prog); + fprintf(stderr, "GET: %s get \n", prog); + fprintf(stderr, "GET TYPE: %s type \n", prog); + fprintf(stderr, "SET: %s set {nil|int|float|bool|str|rgb|theme} \n", prog); + exit(ret); +} + +int +main(int argc, const char **argv) +{ + const char *prog, *file, *cmd, *key, *type, *value; + int ec_type = -1; + int ret = 0; + prog = file = cmd = key = type = value = NULL; + + prog = argv[0]; + if (argc < 3) usage_and_exit(prog, 2, "Not enough arguments\n"); + + file = argv[1]; + cmd = argv[2]; + + // Check for valid command + if (strcmp("get", cmd) && + strcmp("type", cmd) && + strcmp("set", cmd) && + strcmp("list", cmd)) + { + usage_and_exit(prog, 2, "Unrecognised command\n"); + } + + // Check for enough arguments + if ((*cmd == 's') || (*cmd == 'g') || (*cmd == 't')) { + if (argc < 3) usage_and_exit(prog, 2, "Not enough arguments\n"); + key = argv[3]; + } + + if (*cmd == 's') { + if (argc < 5) usage_and_exit(prog, 2, "No type and value specified\n"); + type = argv[4]; + + if ((ec_type = parse_type(type)) < 0) + usage_and_exit(prog, 3, "Unsupported type\n"); + + if (strcmp(type, "nil")) { + if (argc < 6) + usage_and_exit(prog, 2, "No value specified\n"); + value = argv[5]; + } + } + + // Load configuration from file + ecore_config_init("econfig"); + ecore_config_file_load(file); + + // Execute command + switch (*cmd) { + case 's': + if (set(key, ec_type, value)) { + fprintf(stderr, "Set failed\n"); + ret = 4; + } else { + ecore_config_file_save(file); + } + break; + case 'g': + if (get(key)) ret = 4; + break; + case 't': + if (get_type(key)) ret = 4; + break; + case 'l': + if (list(file)) ret = 4; + break; + } + + ecore_config_shutdown(); + + return ret; +} +#else +int +main(int argc, const char **argv) +{ + printf("Ecore_config module not compiled. This program is empty.\n"); + return -1; +} +#endif diff --git a/ecore/src/bin/ecore_evas_test.c b/ecore/src/bin/ecore_evas_test.c new file mode 100644 index 0000000..91536e5 --- /dev/null +++ b/ecore/src/bin/ecore_evas_test.c @@ -0,0 +1,27 @@ +#include "ecore_evas_test.h" + +#ifdef BUILD_ECORE_EVAS + +int +main(int argc, const char **argv) +{ + if (app_start(argc, argv) < 1) return -1; + + bg_start(); + + calibrate_start(); + + ecore_main_loop_begin(); + + app_finish(); + + return 0; +} +#else +int +main(int argc, const char **argv) +{ + printf("Ecore_evas module not compiled. This program is empty.\n"); + return -1; +} +#endif diff --git a/ecore/src/bin/ecore_evas_test.h b/ecore/src/bin/ecore_evas_test.h new file mode 100644 index 0000000..f0b9962 --- /dev/null +++ b/ecore/src/bin/ecore_evas_test.h @@ -0,0 +1,36 @@ +#ifndef _ECORE_EVAS_TEST_H +#define _ECORE_EVAS_TEST_H + +#include "config.h" +#include "Ecore.h" +#include + +#ifdef BUILD_ECORE_EVAS +#include "Ecore_Evas.h" +#include "Ecore_Fb.h" + +#define IM PACKAGE_DATA_DIR"/images/" +#define PT PACKAGE_DATA_DIR"/pointers/" +#define FN PACKAGE_DATA_DIR"/fonts/" + +extern double start_time; +extern Ecore_Evas *ee; +extern Evas *evas; + + + +void calibrate_pos_set(int pos); +int calibrate_pos_get(void); +void calibrate_finish(void); +void calibrate_start(void); + +void bg_resize(double w, double h); +void bg_start(void); +void bg_go(void); + +int app_start(int argc, const char **argv); +void app_finish(void); + +#endif + +#endif diff --git a/ecore/src/bin/ecore_evas_test_app.c b/ecore/src/bin/ecore_evas_test_app.c new file mode 100644 index 0000000..e1d58d2 --- /dev/null +++ b/ecore/src/bin/ecore_evas_test_app.c @@ -0,0 +1,174 @@ +#include "ecore_evas_test.h" + +#ifdef BUILD_ECORE_EVAS + +double start_time = 0.0; +Ecore_Evas *ee = NULL; +Evas *evas = NULL; + +Ecore_Idle_Enterer *getpix_handler = NULL; + +static void app_resize(Ecore_Evas *ee); +static int app_signal_exit(void *data, int ev_type, void *ev); +static void app_delete_request(Ecore_Evas *ee); + +static int +getpix_cb(void *data) +{ + const int *pix; + int p; + int w, h; + FILE *f; + int x, y; + static int count = 0; + char buf[256]; + unsigned char *line; + + pix = ecore_evas_buffer_pixels_get(ee); + ecore_evas_geometry_get(ee, NULL, NULL, &w, &h); + snprintf(buf, sizeof(buf), "out%04i.ppm", count); + count++; + f = fopen(buf, "wb"); + if (f) + { + line = malloc(w * 4); + fprintf(f, "P6\n%i %i\n255\n", w, h); + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + p = pix[(y * w) + x]; + line[(x * 3) + 0] = ((p >> 16) & 0xff); + line[(x * 3) + 1] = ((p >> 8 ) & 0xff); + line[(x * 3) + 2] = ((p ) & 0xff); +/* line[(x * 3) + 3] = ((p >> 24) & 0xff);*/ + } + fwrite(line, w * 3, 1, f); + } + free(line); + fclose(f); + } + return 1; +} + +int +app_start(int argc, const char **argv) +{ + /* init the app */ + start_time = ecore_time_get(); + ecore_init(); + ecore_app_args_set(argc, argv); + ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, app_signal_exit, NULL); + + /* create an evas */ + if (!ecore_evas_init()) return -1; + if ((argc > 1) && (!strcmp(argv[1], "-fb"))) + { + ee = ecore_evas_fb_new(NULL, 0, 240, 320); + evas = ecore_evas_get(ee); + } + else if ((argc > 1) && (!strcmp(argv[1], "-x"))) + { + ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 240, 320); + evas = ecore_evas_get(ee); + } +#if HAVE_ECORE_EVAS_GL + else if ((argc > 1) && (!strcmp(argv[1], "-gl"))) + { + ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, 240, 320); + evas = ecore_evas_get(ee); + } +#endif + else if ((argc > 1) && (!strcmp(argv[1], "-buf"))) + { + ee = ecore_evas_buffer_new(240, 320); + evas = ecore_evas_get(ee); + getpix_handler = ecore_idle_enterer_add(getpix_cb, NULL); + } + else if ((argc > 1) && (!strcmp(argv[1], "-buf2"))) + { + Evas_Object *o; + + ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 240, 320); + + o = evas_object_rectangle_add(ecore_evas_get(ee)); + evas_object_move(o, 0, 0); + evas_object_resize(o, 240, 320); + evas_object_color_set(o, 150, 200, 250, 255); + evas_object_show(o); + + o = ecore_evas_object_image_new(ee); + evas = ecore_evas_get(evas_object_data_get(o, "Ecore_Evas")); + evas_object_move(o, 50, 50); + evas_object_resize(o, 120, 160); + evas_object_image_fill_set(o, 0, 0, 120, 160); + evas_object_image_size_set(o, 240, 320); + ecore_evas_resize(evas_object_data_get(o, "Ecore_Evas"), 240, 320); + evas_object_color_set(o, 255, 255, 255, 200); + evas_object_show(o); + } + else if ((argc > 1) && (!strcmp(argv[1], "-h"))) + { + printf("%s -x Test ecore_evas in X (default)\n" + "%s -gl Test ecore_evas in X GL\n" + "%s -fb Test ecore_evas in the Framebuffer\n" + "%s -buf Test ecore_evas in the Buffer\n" + "%s -buf2 Test ecore_evas in the Image Buffer\n" + "%s -h Display this help\n", + argv[0], argv[0], argv[0], argv[0], argv[0], argv[0]); + ecore_evas_shutdown(); + ecore_shutdown(); + return 0; + } + else { +#ifdef BUILD_ECORE_X + ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 240, 320); +#else +#ifdef BUILD_ECORE_FB + ee = ecore_evas_fb_new(NULL, 270, 240, 320); +#endif +#endif + evas = ecore_evas_get(ee); + } + if (!ee) return -1; + ecore_evas_callback_delete_request_set(ee, app_delete_request); + ecore_evas_callback_resize_set(ee, app_resize); + ecore_evas_title_set(ee, "Ecore Evas Test"); + ecore_evas_name_class_set(ee, "ecore_test", "test_evas"); + ecore_evas_show(ee); + evas_image_cache_set(evas, 8192 * 1024); + evas_font_cache_set(evas, 512 * 1024); + evas_font_path_append(evas, FN); + return 1; +} + +void +app_finish(void) +{ + ecore_evas_shutdown(); + ecore_shutdown(); +} + +static void +app_resize(Ecore_Evas *ee) +{ + Evas_Coord w, h; + + evas_output_viewport_get(evas, NULL, NULL, &w, &h); + bg_resize(w, h); +} + +static int +app_signal_exit(void *data, int ev_type, void *ev) +{ + ecore_main_loop_quit(); + return 1; +} + +static void +app_delete_request(Ecore_Evas *ee) +{ + ecore_main_loop_quit(); +} + +#endif diff --git a/ecore/src/bin/ecore_evas_test_bg.c b/ecore/src/bin/ecore_evas_test_bg.c new file mode 100644 index 0000000..397e5f5 --- /dev/null +++ b/ecore/src/bin/ecore_evas_test_bg.c @@ -0,0 +1,412 @@ +#include "ecore_evas_test.h" + +#ifdef BUILD_ECORE_EVAS + +Evas_Object *o_bg_rect = NULL; +Evas_Object *o_logo = NULL; +Ecore_Timer *anim_timer = NULL; + +#define NUM 32 +#define SIZE 32 +#define SLIDE 80 + +Evas_Object *o_ball[NUM]; +Evas_Object *o_shad[NUM]; + +Evas_Object *o_clip = NULL; +Evas_Object *o_bar[2]; +Evas_Object *o_bar_shad_1[3]; +Evas_Object *o_bar_shad_2[2]; +Evas_Object *o_bg = NULL; + +static int bg_animate_obj_timer(void *data); +static void bg_cb_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info); + +void +bg_resize(double w, double h) +{ + evas_object_resize(o_bg_rect, w, h); + evas_object_move(o_logo, (w - 240) / 2, (h - 280) / 2); + bg_animate_obj_timer(NULL); +} + +void +bg_start(void) +{ + Evas_Object *o; + + /* set up a big white rectangle on the bg */ + o = evas_object_rectangle_add(evas); + evas_object_color_set(o, 255, 255, 255, 255); + evas_object_move(o, 0, 0); + evas_object_resize(o, 240, 320); + evas_object_layer_set(o, -1000000); + evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN, bg_cb_key_down, ee); + evas_object_focus_set(o, 1); + evas_object_show(o); + o_bg_rect = o; + + o = evas_object_image_add(evas); + evas_object_image_file_set(o, IM"e_logo.png", NULL); + evas_object_resize(o, 240, 280); + evas_object_image_fill_set(o, 0, 0, 240, 280); + evas_object_move(o, (240 - 240) / 2, (320 - 280) / 2); + evas_object_layer_set(o, -999); + evas_object_pass_events_set(o, 1); + evas_object_show(o); + o_logo = o; + + o = evas_object_rectangle_add(evas); + evas_object_color_set(o, 255, 255, 255, 255); + evas_object_resize(o, 240, 0); + evas_object_pass_events_set(o, 1); + evas_object_show(o); + o_clip = o; + + o = evas_object_image_add(evas); + evas_object_image_file_set(o, IM"bg.png", NULL); + evas_object_resize(o, 240, 320); + evas_object_image_fill_set(o, 0, 0, 240, 320); + evas_object_layer_set(o, -9999); + evas_object_move(o, 0, 0); + evas_object_clip_set(o, o_clip); + evas_object_pass_events_set(o, 1); + evas_object_show(o); + o_bg = o; + + o = evas_object_image_add(evas); + evas_object_image_file_set(o, IM"bar.png", NULL); + evas_object_image_border_set(o, 5, 5, 5, 5); + evas_object_resize(o, 240, 32); + evas_object_image_fill_set(o, 0, 0, 240, 32); + evas_object_layer_set(o, 100); + evas_object_pass_events_set(o, 1); + o_bar[0] = o; + + o = evas_object_image_add(evas); + evas_object_image_file_set(o, IM"bar.png", NULL); + evas_object_image_border_set(o, 5, 5, 5, 5); + evas_object_resize(o, 240, 32); + evas_object_image_fill_set(o, 0, 0, 240, 32); + evas_object_layer_set(o, 100); + evas_object_pass_events_set(o, 1); + o_bar[1] = o; + + o = evas_object_image_add(evas); + evas_object_image_file_set(o, IM"bar_shad_above.png", NULL); + evas_object_resize(o, 240, 8); + evas_object_image_fill_set(o, 0, 0, 240, 8); + evas_object_image_smooth_scale_set(o, 0); + evas_object_layer_set(o, 100); + evas_object_pass_events_set(o, 1); + o_bar_shad_1[0] = o; + + o = evas_object_image_add(evas); + evas_object_image_file_set(o, IM"bar_shad_below.png", NULL); + evas_object_resize(o, 240, 32); + evas_object_image_fill_set(o, 0, 0, 240, 32); + evas_object_image_smooth_scale_set(o, 0); + evas_object_layer_set(o, -100); + evas_object_pass_events_set(o, 1); + evas_object_clip_set(o, o_clip); + o_bar_shad_1[1] = o; + + o = evas_object_image_add(evas); + evas_object_image_file_set(o, IM"bar_shad_below.png", NULL); + evas_object_resize(o, 240, 16); + evas_object_image_fill_set(o, 0, 0, 240, 16); + evas_object_image_smooth_scale_set(o, 0); + evas_object_layer_set(o, 100); + evas_object_pass_events_set(o, 1); + evas_object_clip_set(o, o_clip); + o_bar_shad_1[2] = o; + + o = evas_object_image_add(evas); + evas_object_image_file_set(o, IM"bar_shad_above.png", NULL); + evas_object_resize(o, 240, 8); + evas_object_image_fill_set(o, 0, 0, 240, 8); + evas_object_image_smooth_scale_set(o, 0); + evas_object_layer_set(o, 100); + evas_object_pass_events_set(o, 1); + evas_object_clip_set(o, o_clip); + o_bar_shad_2[0] = o; + + o = evas_object_image_add(evas); + evas_object_image_file_set(o, IM"bar_shad_below.png", NULL); + evas_object_resize(o, 240, 8); + evas_object_image_fill_set(o, 0, 0, 240, 8); + evas_object_image_smooth_scale_set(o, 0); + evas_object_layer_set(o, 100); + evas_object_pass_events_set(o, 1); + o_bar_shad_2[1] = o; + + { + int i; + + for (i = 0; i < NUM; i++) + { + o = evas_object_image_add(evas); + evas_object_image_file_set(o, IM"ball.png", NULL); + evas_object_resize(o, SIZE, SIZE); + evas_object_image_fill_set(o, 0, 0, SIZE, SIZE); + evas_object_move(o, 0, 0); + evas_object_pass_events_set(o, 1); + evas_object_clip_set(o, o_clip); + o_ball[i] = o; + o = evas_object_image_add(evas); + evas_object_image_file_set(o, IM"shadow.png", NULL); + evas_object_resize(o, SIZE, SIZE); + evas_object_image_fill_set(o, 0, 0, SIZE, SIZE); + evas_object_move(o, 0, 0); + evas_object_pass_events_set(o, 1); + evas_object_clip_set(o, o_clip); + evas_object_lower(o); + o_shad[i] = o; + } + } +} + +void +bg_go(void) +{ + /* add a timer to animate them */ + anim_timer = ecore_timer_add(0.01, bg_animate_obj_timer, NULL); +} + +static int +bg_animate_obj_timer(void *data) +{ + Evas_Object *o; + Evas_Coord x, y, sx, sy; + Evas_Coord w, h; + double v; + int ow, oh; + double t; + int l, m, n; + int i; + static double t_first = 0; + static int done = 0; + + t = ecore_time_get() - start_time; + if (t_first == 0) t_first = t; + if (t - t_first > 2.0) done = 1; + evas_output_viewport_get(evas_object_evas_get(o_clip), NULL, NULL, &w, &h); + if (!done) + { + v = ((cos(((t - t_first) / 2) * 3.14159) - 1.0) / -2); + l = (SLIDE) * v; + } + else + { + l = SLIDE; + } + evas_object_move(o_bar[0], 0, (h / 2) - 32 - l); + evas_object_move(o_bar[1], 0, (h / 2) + l); + evas_object_move(o_bar_shad_1[0], 0, (h / 2) - 32 - l - 8); + evas_object_move(o_bar_shad_1[1], 0, (h / 2) - l); + evas_object_move(o_bar_shad_1[2], 0, (h / 2) - l); + evas_object_move(o_bar_shad_2[0], 0, (h / 2) + l - 8); + evas_object_move(o_bar_shad_2[1], 0, (h / 2) + 32 + l); + + evas_object_resize(o_bar[0], w, 32); + evas_object_image_fill_set(o_bar[0], 0, 0, w, 32); + + evas_object_resize(o_bar[1], w, 32); + evas_object_image_fill_set(o_bar[1], 0, 0, w, 32); + + evas_object_resize(o_bar_shad_1[0], w, 8); + evas_object_image_fill_set(o_bar_shad_1[0], 0, 0, w, 8); + + evas_object_resize(o_bar_shad_1[1], w, 32); + evas_object_image_fill_set(o_bar_shad_1[1], 0, 0, w, 32); + + evas_object_resize(o_bar_shad_1[2], w, 16); + evas_object_image_fill_set(o_bar_shad_1[2], 0, 0, w, 16); + + evas_object_resize(o_bar_shad_2[0], w, 8); + evas_object_image_fill_set(o_bar_shad_2[0], 0, 0, w, 8); + + evas_object_resize(o_bar_shad_2[1], w, 8); + evas_object_image_fill_set(o_bar_shad_2[1], 0, 0, w, 8); + + evas_object_move(o_clip, 0, (h / 2) - l); + evas_object_resize(o_clip, w, l * 2); + + evas_object_resize(o_bg, w, h); + evas_object_image_fill_set(o_bg, 0, 0, w, h); + + evas_object_show(o_bar[0]); + evas_object_show(o_bar[1]); + evas_object_show(o_bar_shad_1[0]); + evas_object_show(o_bar_shad_1[1]); + evas_object_show(o_bar_shad_1[2]); + evas_object_show(o_bar_shad_2[0]); + evas_object_show(o_bar_shad_2[1]); + for (i = 0; i < NUM; i++) + { + o = o_ball[i]; + evas_output_viewport_get(evas_object_evas_get(o), NULL, NULL, &w, &h); + l = ((int)o / 179) & 0x0f; + v = (sin(t * (double)l / 12) + 1.0) / 2; + v = 0.25 + (0.75 * v); + m = 1 + (((int)o / 36) & 0x0f); + n = 1 + (((int)o / 763) & 0x0f); + ow = SIZE * v; + oh = SIZE * v; + evas_object_resize(o, ow, oh); + evas_object_image_fill_set(o, 0, 0, ow, oh); + x = sin(t * (double)m / 12) * ((w - ow) / 2); + y = sin(t * (double)n / 12) * ((h - oh) / 2); + evas_object_move(o, (w / 2) - (ow / 2) + x, (h / 2) - (oh / 2) + y); + evas_object_show(o); + o = o_shad[i]; + evas_object_resize(o, ow, oh); + evas_object_image_fill_set(o, 0, 0, ow, oh); + sx = v * (((w - ow) / 2) + x) / 8; + sy = v * (((h - oh) / 2) + y) / 8; + evas_object_move(o, + (w / 2) - (ow / 2) + x + sx, + (h / 2) - (oh / 2) + y + sy); + evas_object_show(o); + } + return 1; +} + +/* NB: on ipaq + * + * "F1" "F2" "F3" "F4" + * "Up" + * "Left" "Return" "Right" + * "Down" + * + */ +static void +bg_cb_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Key_Down *ev; + + ev = event_info; + if (!strcmp(ev->keyname, "Escape")) ecore_main_loop_quit(); + if (!strcmp(ev->keyname, "q")) ecore_main_loop_quit(); + if (!strcmp(ev->keyname, "Q")) ecore_main_loop_quit(); + if ((!strcmp(ev->keyname, "f")) || + (!strcmp(ev->keyname, "F1"))) + { + if (!ecore_evas_fullscreen_get(ee)) + ecore_evas_fullscreen_set(ee, 1); + else + ecore_evas_fullscreen_set(ee, 0); + } + if (!strcmp(ev->keyname, "o")) + { + if (!ecore_evas_override_get(ee)) + ecore_evas_override_set(ee, 1); + else + ecore_evas_override_set(ee, 0); + } + if ((!strcmp(ev->keyname, "r")) || + (!strcmp(ev->keyname, "F4"))) + { + int r; + + r = ecore_evas_rotation_get(ee); + if (r == 0) r = 90; + else if (r == 90) r = 270; + else if (r == 270) r = 0; + ecore_evas_rotation_set(ee, r); + } + if (!strcmp(ev->keyname, "b")) + { + if (!ecore_evas_borderless_get(ee)) + ecore_evas_borderless_set(ee, 1); + else + ecore_evas_borderless_set(ee, 0); + } + if (!strcmp(ev->keyname, "d")) + { + if (!ecore_evas_avoid_damage_get(ee)) + ecore_evas_avoid_damage_set(ee, 1); + else + ecore_evas_avoid_damage_set(ee, 0); + } + if (!strcmp(ev->keyname, "s")) + { + if (!ecore_evas_shaped_get(ee)) + { + evas_object_hide(o_bg_rect); +// evas_object_hide(o_bg); + ecore_evas_shaped_set(ee, 1); + } + else + { + evas_object_show(o_bg_rect); +// evas_object_show(o_bg); + ecore_evas_shaped_set(ee, 0); + } + } + if (!strcmp(ev->keyname, "Up")) + { +#ifdef BUILD_ECORE_FB + double br; + + br = ecore_fb_backlight_brightness_get(); + ecore_fb_backlight_brightness_set(br + 0.1); +#endif + } + if (!strcmp(ev->keyname, "Down")) + { +#ifdef BUILD_ECORE_FB + double br; + + br = ecore_fb_backlight_brightness_get(); + ecore_fb_backlight_brightness_set(br - 0.1); +#endif + } + if (!strcmp(ev->keyname, "F2")) + { +#ifdef BUILD_ECORE_FB + if (ecore_fb_backlight_get()) + ecore_fb_backlight_set(0); + else + ecore_fb_backlight_set(1); +#endif + } + if (!strcmp(ev->keyname, "F3")) + { +#ifdef BUILD_ECORE_FB + static int v = 0; + + if (v) ecore_fb_led_set(0); + else ecore_fb_led_set(1); + if (!v) v = 1; + else v = 0; +#endif + } + if (!strcmp(ev->keyname, "Left")) + { +#ifdef BUILD_ECORE_FB + ecore_fb_led_blink_set(0.1); +#endif + } + if (!strcmp(ev->keyname, "Right")) + { +#ifdef BUILD_ECORE_FB + ecore_fb_led_blink_set(0.5); +#endif + } + if ((!strcmp(ev->keyname, "p")) || + (!strcmp(ev->keyname, "Return"))) + { + char *fl; + + ecore_evas_cursor_get(ee, &fl, NULL, NULL, NULL); + if (!fl) + ecore_evas_cursor_set(ee, PT"mouse_pointer.png", 1000000, 2, 2); + else + ecore_evas_cursor_set(ee, NULL, 0, 0, 0); +#ifdef BUILD_ECORE_FB + printf("%3.3f\n", ecore_fb_light_sensor_get()); +#endif + } +} +#endif diff --git a/ecore/src/bin/ecore_evas_test_calibrate.c b/ecore/src/bin/ecore_evas_test_calibrate.c new file mode 100644 index 0000000..22b2424 --- /dev/null +++ b/ecore/src/bin/ecore_evas_test_calibrate.c @@ -0,0 +1,285 @@ +#include "ecore_evas_test.h" + +#ifdef BUILD_ECORE_EVAS + +static Evas_Object *o_events = NULL; +static Evas_Object *o_crosshair = NULL; +static Evas_Object *o_text = NULL; +static int cal_pos = 0; +static int down = 0; + +static int cal_coords[] = {15, 15, -15, 15, 15, -15, -15, -15}; +static char *cal_lines[] = +{ + "Please click on the crosshair", + "Again please", + "And again", + "Last one, then calibration is complete" +}; +static int cal_input[8]; + +static int tmp_input_count = 0; +static int tmp_input[16]; + +static void calibrate_cb_down(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void calibrate_cb_up(void *data, Evas *e, Evas_Object *obj, void *event_info); +static void calibrate_cb_move(void *data, Evas *e, Evas_Object *obj, void *event_info); + +void +calibrate_pos_set(int pos) +{ + Evas_Coord w, h, ow, oh; + int x, y; + + cal_pos = pos; + evas_object_geometry_get(o_crosshair, NULL, NULL, &w, &h); + x = cal_coords[(cal_pos * 2) + 0]; + y = cal_coords[(cal_pos * 2) + 1]; + evas_output_viewport_get(evas, NULL, NULL, &ow, &oh); + if (x < 0) x = ow + x - 1; + if (y < 0) y = oh + y - 1; + cal_coords[(cal_pos * 2) + 0] = x; + cal_coords[(cal_pos * 2) + 1] = y; + evas_object_move(o_crosshair, x - (((int)w - 1) / 2), y - (((int)h - 1) / 2)); + evas_object_text_text_set(o_text, cal_lines[cal_pos]); + evas_object_geometry_get(o_text, NULL, NULL, &w, &h); + evas_object_move(o_text, (ow - w) / 2, (oh - h) / 2); +} + +int +calibrate_pos_get(void) +{ + return cal_pos; +} + +void +calibrate_finish(void) +{ + int m0, m1; + int y0, y1; + int x[4], y[4], xi[4], yi[4]; + int i, rot; + + int xscale, xtrans, yscale, ytrans, xyswap; + + rot = ecore_evas_rotation_get(ee); + for (i = 0; i < 4; i++) + { + x[i] = cal_coords[(i * 2) + 0]; + y[i] = cal_coords[(i * 2) + 1]; + xi[i] = cal_input[(i * 2) + 0]; + yi[i] = cal_input[(i * 2) + 1]; + } + xyswap = 0; + + m0 = ((x[1] - x[0]) * 256) / (xi[1] - xi[0]); + y0 = ((x[1] - ((xi[1] * m0) / 256)) + (x[0] - ((xi[0] * m0) >> 8)) ) / 2; + + m1 = ((x[3] - x[2]) * 256) / (xi[3] - xi[2]); + y1 = ((x[3] - ((xi[3] * m1) / 256)) + (x[2] - ((xi[2] * m1) >> 8)) ) / 2; + + xscale = (m0 + m1) / 2; + xtrans = (y0 + y1) / 2; + + m0 = ((y[2] - y[0]) * 256) / (yi[2] - yi[0]); + y0 = ((y[2] - ((yi[2] * m0) / 256)) + (y[0] - ((yi[0] * m0) >> 8)) ) / 2; + + m1 = ((y[3] - y[1]) * 256) / (yi[3] - yi[1]); + y1 = ((y[3] - ((yi[3] * m1) / 256)) + (y[1] - ((yi[1] * m1) >> 8)) ) / 2; + + yscale = (m0 + m1) / 2; + ytrans = (y0 + y1) / 2; + + if (rot == 0) + { +#ifdef BUILD_ECORE_FB + ecore_fb_touch_screen_calibrate_set(xscale, xtrans, yscale, ytrans, xyswap); +#endif + } + else if (rot == 270) + { + int ow, oh; + + evas_output_size_get(evas, &ow, &oh); + ytrans = oh - (ytrans + ((oh * yscale) / 256)); +#ifdef BUILD_ECORE_FB + ecore_fb_touch_screen_calibrate_set(yscale, ytrans, xscale, xtrans, xyswap); +#endif + } + + evas_object_del(o_crosshair); + evas_object_del(o_events); + evas_object_del(o_text); + o_crosshair = NULL; + o_events = NULL; + o_text = NULL; + cal_pos = 0; + bg_go(); +} + +void +calibrate_start(void) +{ + Evas_Object *o; + +#ifdef BUILD_ECORE_FB + ecore_fb_touch_screen_calibrate_set(256, 0, 256, 0, 0); +#endif + + o = evas_object_rectangle_add(evas); + evas_object_layer_set(o, 1000000); + evas_object_color_set(o, 255, 255, 255, 120); + evas_object_move(o, -12000, -16000); + evas_object_resize(o, 24000, 32000); + evas_object_show(o); + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, calibrate_cb_down, ee); + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, calibrate_cb_up, ee); + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, calibrate_cb_move, ee); + o_events = o; + + o = evas_object_image_add(evas); + evas_object_layer_set(o, 1000001); + evas_object_image_file_set(o, IM"crosshair.png", NULL); + evas_object_resize(o, 31, 31); + evas_object_image_fill_set(o, 0, 0, 31, 31); + evas_object_pass_events_set(o, 1); + evas_object_show(o); + o_crosshair = o; + + o = evas_object_text_add(evas); + evas_object_layer_set(o, 1000002); + evas_object_color_set(o, 0, 0, 0, 255); + evas_object_text_font_set(o, "Vera", 10); + evas_object_pass_events_set(o, 1); + evas_object_show(o); + o_text = o; + + calibrate_pos_set(0); +} + + +static void +calibrate_cb_down(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Mouse_Down *ev; + + ev = event_info; + + evas_object_move(o_crosshair, ev->output.x - 15, ev->output.y - 15); + tmp_input_count = 0; + tmp_input[((tmp_input_count & 0x7) * 2) + 0] = ev->output.x; + tmp_input[((tmp_input_count & 0x7) * 2) + 1] = ev->output.y; + tmp_input_count++; + down = 1; +} + +static void +calibrate_cb_up(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Mouse_Up *ev; + int n, i, avx, avy, c, mx, my; + int dists[8]; + int indexes[8]; + int sorted; + + ev = event_info; + down = 0; + tmp_input[((tmp_input_count & 0x7) * 2) + 0] = ev->output.x; + tmp_input[((tmp_input_count & 0x7) * 2) + 1] = ev->output.y; + tmp_input_count++; + n = 8; + if (tmp_input_count < 8) n = tmp_input_count; + avx = 0; avy = 0; c = 0; + for (i = 0; i < n; i++) + { + dists[i] = tmp_input[(i * 2) + 0]; + indexes[i] = i; + } + sorted = 0; + while (!sorted) + { + sorted = 1; + for (i = 0; i < n - 1; i++) + { + if (dists[i + 1] < dists[i]) + { + int tmp; + + sorted = 0; + tmp = dists[i]; + dists[i] = dists[i + 1]; + dists[i + 1] = tmp; + tmp = indexes[i]; + indexes[i] = indexes[i + 1]; + indexes[i + 1] = tmp; + } + } + } + mx = dists[(n + 1) / 2]; + for (i = 0; i < n; i++) + { + dists[i] = tmp_input[(i * 2) + 1]; + indexes[i] = i; + } + sorted = 0; + while (!sorted) + { + sorted = 1; + for (i = 0; i < n - 1; i++) + { + if (dists[i + 1] < dists[i]) + { + int tmp; + + sorted = 0; + tmp = dists[i]; + dists[i] = dists[i + 1]; + dists[i + 1] = tmp; + tmp = indexes[i]; + indexes[i] = indexes[i + 1]; + indexes[i + 1] = tmp; + } + } + } + my = dists[(n + 1) / 2]; + + for (i = 0; i < n; i++) + { + int x, y, dx, dy; + + x = tmp_input[(i * 2) + 0]; + y = tmp_input[(i * 2) + 1]; + dx = x - mx; + dy = y - my; + if (dx < 0) dx = -dx; + if (dy < 0) dy = -dy; + if ((dx <= 8) && (dy <= 8)) + { + avx += tmp_input[(i * 2) + 0]; + avy += tmp_input[(i * 2) + 1]; + c++; + } + } + cal_input[(cal_pos * 2) + 0] = avx / c; + cal_input[(cal_pos * 2) + 1] = avy / c; + n = calibrate_pos_get(); + if (n < 3) + { + calibrate_pos_set(n + 1); + return; + } + calibrate_finish(); +} + +static void +calibrate_cb_move(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Mouse_Move *ev; + + ev = event_info; + if (!down) return; + tmp_input[((tmp_input_count & 0x7) * 2) + 0] = ev->cur.output.x; + tmp_input[((tmp_input_count & 0x7) * 2) + 1] = ev->cur.output.y; + tmp_input_count++; +} +#endif diff --git a/ecore/src/bin/ecore_test.c b/ecore/src/bin/ecore_test.c new file mode 100644 index 0000000..c32aef8 --- /dev/null +++ b/ecore/src/bin/ecore_test.c @@ -0,0 +1,899 @@ +#include "config.h" +#include "Ecore.h" +#ifdef BUILD_ECORE_JOB +#include "Ecore_Job.h" +#endif +#ifdef BUILD_ECORE_X +#include "Ecore_X.h" +#endif +#ifdef BUILD_ECORE_FB +#include "Ecore_Fb.h" +#endif +#ifdef BUILD_ECORE_EVAS +#include "Ecore_Evas.h" +#endif +#ifdef BUILD_ECORE_CON +#include "Ecore_Con.h" +#endif +#ifdef BUILD_ECORE_IPC +#include "Ecore_Ipc.h" +#endif + +#include + +/* APP GLOBALS */ +double start_time = 0; + +int +handler_signal_exit(void *data, int ev_type, void *ev) +{ + Ecore_Event_Signal_Exit *e; + + e = ev; + if (e->interrupt) printf("exit: interrupt\n"); + if (e->quit) printf("exit: quit\n"); + if (e->terminate) printf("exit: terminate\n"); + ecore_main_loop_quit(); + return 1; +} + + + + + + +int +handler_ipc_client_add(void *data, int type, void *event) +{ +#ifdef BUILD_ECORE_IPC + Ecore_Ipc_Event_Client_Add *e; + + e = event; + printf("!!! client %p connected to server!\n", e->client); + return 1; +#endif +} + +int +handler_ipc_client_del(void *data, int type, void *event) +{ +#ifdef BUILD_ECORE_IPC + Ecore_Ipc_Event_Client_Del *e; + + e = event; + printf("!!! client %p disconnected from server!\n", e->client); + return 1; +#endif +} + + +int +handler_ipc_client_data(void *data, int type, void *event) +{ +#ifdef BUILD_ECORE_IPC + Ecore_Ipc_Event_Client_Data *e; + + e = event; + printf("!!! client sent: [%i] [%i] (%i) \"%s\"\n", e->major, e->minor, e->size, (char*)e->data); + ecore_ipc_client_send(e->client, 1, 2, 0, 0, 0, "ABC", 4); + /* we can disconnect a client like this: */ + /* ecore_ipc_client_del(e->client); */ + /* or we can end a server by: */ + /* ecore_ipc_server_del(ecore_ipc_client_server_get(e->client)); */ + return 1; +#endif +} + + +int +handler_ipc_server_add(void *data, int type, void *event) +{ +#ifdef BUILD_ECORE_IPC + Ecore_Ipc_Event_Server_Add *e; + + e = event; + printf("!!! client made successful connect to server %p!\n", e->server); + return 1; +#endif +} + +int +handler_ipc_server_del(void *data, int type, void *event) +{ +#ifdef BUILD_ECORE_IPC + Ecore_Ipc_Event_Server_Del *e; + + e = event; + printf("!!! server went away!\n"); + /* clean up our server connection since it went away */ + ecore_ipc_server_del(e->server); + return 1; +#endif +} + +int +handler_ipc_server_data(void *data, int type, void *event) +{ +#ifdef BUILD_ECORE_IPC + Ecore_Ipc_Event_Server_Data *e; + static int count = 0; + + e = event; + printf("!!! server sent: [%i] [%i] (%i) \"%s\"\n", e->major, e->minor, e->size, (char*)e->data); + ecore_ipc_server_send(e->server, 3, 4, 0, 0, 0, "EFG", 4); + count++; + if (count > 4) + { + printf("!!! go & disconnect from server!\n"); + ecore_ipc_server_del(e->server); + } + return 1; +#endif +} + +/**** ECORE_CON TEST CODE */ +int +handler_client_add(void *data, int type, void *event) +{ +#ifdef BUILD_ECORE_CON + Ecore_Con_Event_Client_Add *e; + + e = event; + printf("!!! client %p connected to server!\n", e->client); + return 1; +#endif +} + +int +handler_client_del(void *data, int type, void *event) +{ +#ifdef BUILD_ECORE_CON + Ecore_Con_Event_Client_Del *e; + + e = event; + printf("!!! client %p disconnected from server!\n", e->client); + return 1; +#endif +} + + +int +handler_client_data(void *data, int type, void *event) +{ +#ifdef BUILD_ECORE_CON + Ecore_Con_Event_Client_Data *e; + + e = event; + printf("!!! client sent: \"%s\"\n", (char*)e->data); + ecore_con_client_send(e->client, "ABC", 4); + /* we can disconnect a client like this: */ + /* ecore_con_client_del(e->client); */ + /* or we can end a server by: */ + /* ecore_con_server_del(ecore_con_client_server_get(e->client)); */ + return 1; +#endif +} + + +int +handler_server_add(void *data, int type, void *event) +{ +#ifdef BUILD_ECORE_CON + Ecore_Con_Event_Server_Add *e; + + e = event; + printf("!!! client made successful connect to server %p!\n", e->server); + return 1; +#endif +} + +int +handler_server_del(void *data, int type, void *event) +{ +#ifdef BUILD_ECORE_CON + Ecore_Con_Event_Server_Del *e; + + e = event; + printf("!!! server went away!\n"); + /* clean up our server connection since it went away */ + ecore_con_server_del(e->server); + return 1; +#endif +} + +int +handler_server_data(void *data, int type, void *event) +{ +#ifdef BUILD_ECORE_CON + Ecore_Con_Event_Server_Data *e; + static int count = 0; + + e = event; + printf("!!! server sent: \"%s\"\n", (char*)e->data); + ecore_con_server_send(e->server, "EFG", 4); + count++; + if (count > 4) + { + printf("!!! go & disconnect from server!\n"); + ecore_con_server_del(e->server); + } + return 1; +#endif +} + + +/* NB: also tests ECORE_JOB */ +#ifdef BUILD_ECORE_JOB +void +job_call(void *data) +{ + printf("!! Job done \"%s\"!\n", (char *)data); +} +#endif + +int +idle_enterer(void *data) +{ + printf("-------> Entering idle %3.3f\n", ecore_time_get() - start_time); + return 1; +} + +int +idler(void *data) +{ + printf("oo Idler %3.3f\n", ecore_time_get() - start_time); + return 1; +} + +int +timer(void *data) +{ + printf("Q- Timer tick %3.8f\n", ecore_time_get() - start_time); + /* test ecore_job */ +#ifdef BUILD_ECORE_JOB + ecore_job_add(job_call, "1"); + ecore_job_add(job_call, "2"); + ecore_job_add(job_call, "3"); +#endif + return 1; +} + +void +setup_ecore_test(void) +{ + ecore_idle_enterer_add(idle_enterer, NULL); +/* ecore_idler_add(idler, NULL); */ + ecore_timer_add(2.0, timer, NULL); +} + +#ifdef BUILD_ECORE_X +/**** ECORE_X TEST CODE */ + +Ecore_X_Window win = 0; + +int +handler_x_key_down(void *data, int type, void *event) +{ + Ecore_X_Event_Key_Down *e; + + e = event; + printf("Key down %s\n", e->keyname); + return 1; +} + +int +handler_x_key_up(void *data, int type, void *event) +{ + Ecore_X_Event_Key_Up *e; + + e = event; + printf("Key up %s\n", e->keyname); + return 1; +} + +int +handler_x_mouse_button_down(void *data, int type, void *event) +{ + Ecore_X_Event_Mouse_Button_Down *e; + + e = event; + printf("Mouse down %i [%i][%i]\n", e->button, e->double_click, e->triple_click); + return 1; +} + +int +handler_x_mouse_button_up(void *data, int type, void *event) +{ + Ecore_X_Event_Mouse_Button_Up *e; + + e = event; + printf("Mouse up %i\n", e->button); + return 1; +} + +int +handler_x_mouse_move(void *data, int type, void *event) +{ + Ecore_X_Event_Mouse_Move *e; + + e = event; + printf("Mouse move to %i %i\n", e->x, e->y); + return 1; +} + +int +handler_x_mouse_in(void *data, int type, void *event) +{ + Ecore_X_Event_Mouse_In *e; + + e = event; + printf("Mouse in\n"); + return 1; +} + +int +handler_x_mouse_out(void *data, int type, void *event) +{ + Ecore_X_Event_Mouse_Out *e; + + e = event; + printf("Mouse out\n"); + return 1; +} + +int +handler_x_window_focus_in(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Focus_In *e; + + e = event; + printf("Focus in\n"); + return 1; +} + +int +handler_x_window_focus_out(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Focus_Out *e; + + e = event; + printf("Focus out\n"); + return 1; +} + +int +handler_x_window_damage(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Damage *e; + + e = event; + printf("Damage %i %i, %ix%i\n", e->x, e->y, e->w, e->h); + return 1; +} + +int +handler_x_window_destroy(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Destroy *e; + + e = event; + printf("Destroy\n"); + ecore_main_loop_quit(); + return 1; +} + +int +handler_x_window_configure(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Configure *e; + const int desktop = 0; + + e = event; + printf("Configure %i %i, %ix%i\n", e->x, e->y, e->w, e->h); + printf("Switching desktops to %d\n", desktop); + ecore_x_netwm_desktop_request_send(e->win, 0, desktop); + return 1; +} + +int +handler_x_window_delete_request(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Delete_Request *e; + + e = event; + printf("Delete Request\n"); + ecore_main_loop_quit(); + return 1; +} + +int +handler_x_window_prop_title_change(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Prop_Title_Change *e; + + e = event; + if (e->title) + printf("Title change to \"%s\"\n", e->title); + else + printf("Title deleted\n"); + return 1; +} + +int +handler_x_window_prop_visible_title_change(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Prop_Visible_Title_Change *e; + + e = event; + if (e->title) + printf("Visible title change to \"%s\"\n", e->title); + else + printf("Visible title deleted\n"); + return 1; +} + +int +handler_x_window_prop_icon_name_change(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Prop_Icon_Name_Change *e; + + e = event; + if (e->name) + printf("Icon name change to \"%s\"\n", e->name); + else + printf("Icon name deleted\n"); + return 1; +} + +int +handler_x_window_prop_visible_icon_name_change(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e; + + e = event; + if (e->name) + printf("Visible icon name change to \"%s\"\n", e->name); + else + printf("Visible icon name deleted\n"); + return 1; +} + +int +handler_x_window_prop_client_machine_change(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Prop_Client_Machine_Change *e; + + e = event; + if (e->name) + printf("Client machine change to \"%s\"\n", e->name); + else + printf("Client machine deleted\n"); + return 1; +} + +int +handler_x_window_prop_pid_change(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Prop_Pid_Change *e; + + e = event; + if (e->pid) + { + printf("Pid change to \"%d\" ", e->pid); + if (e->pid == getpid()) + printf("correct.\n"); + else + printf("INCORRECT!\n"); + } + else + printf("Pid deleted\n"); + return 1; +} + +int +handler_x_window_prop_name_class_change(void *data, int type, void *event) +{ + Ecore_X_Event_Window_Prop_Name_Class_Change *e; + + e = event; + if ((e->name) && (e->clas)) + printf("Name & Class change to \"%s\".\"%s\"\n", e->name, e->clas); + else + printf("Name & Class deleted\n"); + return 1; +} + +void +setup_ecore_x_test(void) +{ + char *tmp; + int pid; + unsigned int desktop; + + win = ecore_x_window_new(0, 0, 0, 120, 60); + ecore_x_netwm_name_set(win, "Ecore Test Program"); + ecore_x_icccm_title_set(win, "Ecore Test Program"); + //printf("Title currently: %s\n", tmp); + free(tmp); +#if 0 + /* Visibile title should be set by the wm */ + tmp = ecore_x_netwm_visible_name_get(win); + if (!tmp) + { + printf("No visible title, setting it to Ecore ... Program\n"); + ecore_x_window_prop_visible_title_set(win, "Ecore ... Program"); + tmp = ecore_x_window_prop_visible_title_get(win); + } + printf("Visible title: %s\n", tmp); + free(tmp); +#endif + ecore_x_netwm_icon_name_get(win, &tmp); + if (!tmp) + { + printf("No icon name, setting it to Ecore_Test\n"); + ecore_x_netwm_icon_name_set(win, "Ecore_Test"); + ecore_x_netwm_icon_name_get(win, &tmp); + } + printf("Icon Name: %s\n", tmp); + free(tmp); +#if 0 + /* Visibile icon should be set by the wm */ + tmp = ecore_x_window_prop_visible_icon_name_get(win); + if (!tmp) + { + printf("No visible icon name, setting it to Ecore\n"); + ecore_x_window_prop_visible_icon_name_set(win, "Ecore"); + tmp = ecore_x_window_prop_visible_icon_name_get(win); + } + printf("Visible icon Name: %s\n", tmp); + free(tmp); +#endif + tmp = ecore_x_icccm_client_machine_get(win); + if (tmp) + { + printf("Client machine: %s\n", tmp); + free(tmp); + } + ecore_x_netwm_pid_get(win, &pid); + printf("Pid: %d\n", pid); + ecore_x_icccm_name_class_set(win, "ecore_test", "main"); + ecore_x_netwm_desktop_set(win, 1); + ecore_x_netwm_desktop_get(win, &desktop); + printf("Window on desktop %u\n", desktop); + ecore_x_netwm_window_type_set(win, ECORE_X_WINDOW_TYPE_DIALOG); + ecore_x_icccm_protocol_set(win, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, 1); + ecore_x_window_show(win); + ecore_x_flush(); + + ecore_event_handler_add(ECORE_X_EVENT_KEY_DOWN, handler_x_key_down, NULL); + ecore_event_handler_add(ECORE_X_EVENT_KEY_UP, handler_x_key_up, NULL); + ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_DOWN, handler_x_mouse_button_down, NULL); + ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_UP, handler_x_mouse_button_up, NULL); + ecore_event_handler_add(ECORE_X_EVENT_MOUSE_MOVE, handler_x_mouse_move, NULL); + ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, handler_x_mouse_in, NULL); + ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, handler_x_mouse_out, NULL); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, handler_x_window_focus_in, NULL); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, handler_x_window_focus_out, NULL); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DAMAGE, handler_x_window_damage, NULL); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, handler_x_window_destroy, NULL); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, handler_x_window_configure, NULL); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, handler_x_window_delete_request, NULL); + /* + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE, handler_x_window_prop_title_change, NULL); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE, handler_x_window_prop_visible_title_change, NULL); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE, handler_x_window_prop_icon_name_change, NULL); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE, handler_x_window_prop_visible_icon_name_change, NULL); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE, handler_x_window_prop_name_class_change, NULL); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE, handler_x_window_prop_client_machine_change, NULL); + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, handler_x_window_prop_pid_change, NULL); + */ + +} +#endif + +#ifdef BUILD_ECORE_EVAS +/* choose: TEST_X, TEST_FB */ +#define TEST_X + +/**** ECORE_EVAS TEST CODE */ + +Ecore_Timer *anim_timer = NULL; +Ecore_Evas *ee = NULL; +Evas *evas = NULL; +Evas_Object *objects[64]; + +int +obj_timer(void *data) +{ + Evas_Object *o; + Evas_Coord x, y; + Evas_Coord w, h; + Evas_Coord ow, oh; + double t; + int m, n; + int i; + + t = ecore_time_get() - start_time; + for (i = 0; i < (sizeof(objects) / sizeof(Evas_Object *)); i++) + { + o = objects[i]; + evas_output_viewport_get(evas_object_evas_get(o), NULL, NULL, &w, &h); + evas_object_geometry_get(o, NULL, NULL, &ow, &oh); + m = ((int)o / 36) & 0x3f; + n = ((int)o / 763) & 0x3f; + x = sin(t * (double)m / 12) * ((w - ow) / 2); + y = sin(t * (double)n / 12) * ((h - oh) / 2); + evas_object_move(o, (w / 2) - (ow / 2) + x, (h / 2) - (oh / 2) + y); + } + return 1; +} + +void +del_req(Ecore_Evas *ee) +{ + int i; + + printf("request to go away... nice exit\n"); + for (i = 0; i < (sizeof(objects) / sizeof(Evas_Object *)); i++) + objects[i] = NULL; + ecore_timer_del(anim_timer); + anim_timer = NULL; + ecore_main_loop_quit(); +} + +static void +cb_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Evas_Event_Key_Down *ev; + + ev = event_info; + if (!strcmp(ev->keyname, "Escape")) ecore_main_loop_quit(); + if (!strcmp(ev->keyname, "q")) ecore_main_loop_quit(); + if (!strcmp(ev->keyname, "Q")) ecore_main_loop_quit(); + if (!strcmp(ev->keyname, "f")) + { + if (!ecore_evas_fullscreen_get(ee)) + ecore_evas_fullscreen_set(ee, 1); + else + ecore_evas_fullscreen_set(ee, 0); + } + if (!strcmp(ev->keyname, "o")) + { + if (!ecore_evas_override_get(ee)) + ecore_evas_override_set(ee, 1); + else + ecore_evas_override_set(ee, 0); + } + if (!strcmp(ev->keyname, "r")) + { + int r; + + r = ecore_evas_rotation_get(ee); + if (r == 0) r = 90; + else if (r == 90) r = 270; + else if (r == 270) r = 0; + ecore_evas_rotation_set(ee, r); + } + if (!strcmp(ev->keyname, "b")) + { + if (!ecore_evas_borderless_get(ee)) + ecore_evas_borderless_set(ee, 1); + else + ecore_evas_borderless_set(ee, 0); + } + if (!strcmp(ev->keyname, "d")) + { + if (!ecore_evas_avoid_damage_get(ee)) + ecore_evas_avoid_damage_set(ee, 1); + else + ecore_evas_avoid_damage_set(ee, 0); + } + if (!strcmp(ev->keyname, "s")) + { + if (!ecore_evas_shaped_get(ee)) + ecore_evas_shaped_set(ee, 1); + else + ecore_evas_shaped_set(ee, 0); + } +#if 1 /* no data files shipped yet to test this */ + if (!strcmp(ev->keyname, "p")) + { + char *fl; + + ecore_evas_cursor_get(ee, &fl, NULL, NULL, NULL); + if (!fl) + ecore_evas_cursor_set(ee, "data/pointers/mouse_pointer.png", 1000000, 2, 2); + else + ecore_evas_cursor_set(ee, NULL, 0, 0, 0); + } +#endif +} + +int +setup_ecore_evas_test(void) +{ + Evas_Object *o; + int i; + + /* create a new ecore wrapped evas canvas in X */ +#ifdef TEST_X + ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 240, 320); +#endif +#ifdef TEST_FB + ee = ecore_evas_fb_new(NULL, 270, 240, 320); +#endif + if (!ee) return 0; + ecore_evas_title_set(ee, "Ecore Evas Test"); + ecore_evas_name_class_set(ee, "ecore_test", "test_evas"); + /* callback if clsoe button is pressed and win is asked to be deleted */ + ecore_evas_callback_delete_request_set(ee, del_req); + + /* get the actual evas ecore created for us */ + evas = ecore_evas_get(ee); + + /* image cache set (in bytes) */ + evas_image_cache_set(evas, 0 * 1024); + /* font cache set (in bytes) */ + evas_font_cache_set(evas, 0 * 1024); + /* add a directory to look in for fonts */ + evas_font_path_append(evas, "./"); + + /* set up a big white rectangle on the bg */ + o = evas_object_rectangle_add(evas); + evas_object_color_set(o, 255, 255, 255, 255); + evas_object_move(o, 0, 0); + evas_object_resize(o, 100000, 100000); + evas_object_layer_set(o, -1000000); + evas_object_event_callback_add(o, EVAS_CALLBACK_KEY_DOWN, cb_key_down, ee); + evas_object_focus_set(o, 1); + evas_object_show(o); + + /* make a bunch of rectangles */ + for (i = 0; i < (sizeof(objects) / sizeof(Evas_Object *)); i++) + { + o = evas_object_rectangle_add(evas); + evas_object_move(o, 10, 10); + evas_object_pass_events_set(o, 1); + evas_object_color_set(o, + ((int)o) & 0xff, + ((int)o / 30) & 0xff, + ((int)o / 65) & 0xff, + ((int)o / 156) & 0xff); + evas_object_resize(o, 4 + (((int)o) % 100), 4 + (((int)o / 50) % 100)); + evas_object_show(o); + objects[i] = o; + } + /* add a timer to animate them */ + anim_timer = ecore_timer_add(0.01, obj_timer, NULL); + + ecore_evas_show(ee); + return 1; +} +#endif + +/**** MAIN */ +int +main(int argc, const char **argv) +{ + /* get the time the program started at */ + start_time = ecore_time_get(); + + /* init ecore */ + ecore_init(); + /* tell ecore what our arguments are */ + ecore_app_args_set(argc, argv); + +#if 1 + /* setup to test ecore module basics */ + setup_ecore_test(); +#endif + +#ifdef BUILD_ECORE_CON +#if 0 + /* init ecore_con */ + ecore_con_init(); + { + Ecore_Con_Server *server; + +/* server = ecore_con_server_add(ECORE_CON_LOCAL_USER, "ecore_test", 0, NULL);*/ + server = ecore_con_server_add(ECORE_CON_LOCAL_SYSTEM, "ecore_test", 0, NULL); +/* server = ecore_con_server_add(ECORE_CON_REMOTE_SYSTEM, "localhost", 7654, NULL); */ + ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, handler_client_add, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, handler_client_del, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, handler_client_data, NULL); + printf("create server %p\n", server); + } + { + Ecore_Con_Server *server; + +/* server = ecore_con_server_connect(ECORE_CON_LOCAL_USER, "ecore_test", 0, NULL);*/ + server = ecore_con_server_connect(ECORE_CON_LOCAL_SYSTEM, "ecore_test", 0, NULL); +/* server = ecore_con_server_connect(ECORE_CON_REMOTE_SYSTEM, "localhost", 7654, NULL); */ +/* server = ecore_con_server_connect(ECORE_CON_REMOTE_SYSTEM, "www.rasterman.com", 80, NULL); */ + ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, handler_server_add, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, handler_server_del, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, handler_server_data, NULL); + printf("connect to server: %p\n", server); + if (server) + { + char data[160 * 1024]; + + strcpy(data, "BLAHPANTS!"); + ecore_con_server_send(server, data, 160 * 1024); + } + } +#endif +#endif + +#ifdef BUILD_ECORE_IPC +#if 1 + /* init ecore_ipc */ + ecore_ipc_init(); + { + Ecore_Ipc_Server *server; + + server = ecore_ipc_server_add(ECORE_IPC_LOCAL_SYSTEM, "ecore_ipc_test", 0, NULL); +/* server = ecore_ipc_server_add(ECORE_IPC_REMOTE_SYSTEM, "localhost", 4567, NULL); */ + ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, handler_ipc_client_add, NULL); + ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, handler_ipc_client_del, NULL); + ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, handler_ipc_client_data, NULL); + printf("create ipc server %p\n", server); + } + { + Ecore_Ipc_Server *server; + + server = ecore_ipc_server_connect(ECORE_IPC_LOCAL_SYSTEM, "ecore_ipc_test", 0, NULL); +/* server = ecore_ipc_server_connect(ECORE_IPC_REMOTE_SYSTEM, "localhost", 4567, NULL); */ + ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD, handler_ipc_server_add, NULL); + ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, handler_ipc_server_del, NULL); + ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, handler_ipc_server_data, NULL); + printf("connect to ipc server: %p\n", server); + if (server) + { + char data[160 * 1024]; + + strcpy(data, "BLAHPANTS!"); + ecore_ipc_server_send(server, 5, 6, 0, 0, 0, data, 160 * 1024); + } + } +#endif +#endif + +#ifdef BUILD_ECORE_EVAS + /* init ecore_evas */ +/* if (!ecore_evas_init()) return -1; */ +#endif + + /* setup a callback to handle a systsme signal to quit */ + ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, handler_signal_exit, NULL); + +#ifdef BUILD_ECORE_X + /* setup to test ecore_x module things */ + if (!ecore_x_init(NULL)) return -1; + setup_ecore_x_test(); +#endif + +#ifdef BUILD_ECORE_EVAS + /* setup to test ecore_evas module */ +/* if (!setup_ecore_evas_test()) return -1; */ +#endif + + /* run the main loop */ + ecore_main_loop_begin(); + +#ifdef BUILD_ECORE_EVAS + /* shut down ecore_evas */ + ecore_evas_shutdown(); +#endif +#ifdef BUILD_ECORE_IPC + /* shut down ecore_ipc */ + ecore_ipc_shutdown(); +#endif +#ifdef BUILD_ECORE_CON + /* shut down ecore_con */ + ecore_con_shutdown(); +#endif + /* shut down ecore */ + ecore_shutdown(); + return 0; +} diff --git a/ecore/src/e_ev_filter.c b/ecore/src/e_ev_filter.c new file mode 100644 index 0000000..58c7e0f --- /dev/null +++ b/ecore/src/e_ev_filter.c @@ -0,0 +1,132 @@ +#include "Ecore.h" + +typedef struct _ecore_event_handler Ecore_Event_Handler; +typedef struct _ecore_event_idle_handler Ecore_Event_Idle_Handler; + +struct _ecore_event_handler +{ + void (*func) (Ecore_Event * ev); + Ecore_Event_Handler *next; +}; + +struct _ecore_event_idle_handler +{ + void (*func) (void *data); + void *data; + Ecore_Event_Idle_Handler *next; +}; + +static Ecore_Event_Handler *handler[ECORE_EVENT_MAX]; +static Ecore_Event_Idle_Handler *idle_handlers = NULL; + +void +ecore_event_filter(Ecore_Event * ev) +{ + Ecore_Event *evp; + int motion_events = 0; + int dnd_pos_events = 0; + int dnd_status_events = 0; + + /* count events to only use last events of some types */ + for (evp = ev; evp; evp = evp->next) + { + if (evp->type == ECORE_EVENT_MOUSE_MOVE) + motion_events++; + if (evp->type == ECORE_EVENT_DND_DROP_POSITION) + dnd_pos_events++; + if (evp->type == ECORE_EVENT_DND_DROP_STATUS) + dnd_status_events++; + } + for (evp = ev; evp; evp = evp->next) + { + if (evp->type == ECORE_EVENT_MOUSE_MOVE) + { + if (motion_events > 1) + { + evp->ignore = 1; + motion_events--; + } + } + else if (evp->type == ECORE_EVENT_DND_DROP_POSITION) + { + if (dnd_pos_events > 1) + { + evp->ignore = 1; + dnd_pos_events--; + } + } + else if (evp->type == ECORE_EVENT_DND_DROP_STATUS) + { + if (dnd_status_events > 1) + { + evp->ignore = 1; + dnd_status_events--; + } + } + } +} + +void +ecore_event_filter_events_handle(Ecore_Event * ev) +{ + Ecore_Event *evp; + + for (evp = ev; evp; evp = evp->next) + { + Ecore_Event_Handler *h; + + if (!evp->ignore) + { + for (h = handler[evp->type]; h; h = h->next) + { + if (h->func) + h->func(evp); + } + } + } +} + +void +ecore_event_filter_idle_handle(void) +{ + Ecore_Event_Idle_Handler *h; + + for (h = idle_handlers; h; h = h->next) + h->func(h->data); +} + +extern int __quit_ev_loop; + +void +ecore_event_filter_init(void) +{ + int i; + + __quit_ev_loop = 0; + for (i = 0; i < ECORE_EVENT_MAX; i++) + handler[i] = NULL; +} + +void +ecore_event_filter_handler_add(Ecore_Event_Type type, + void (*func) (Ecore_Event * ev)) +{ + Ecore_Event_Handler *h; + + h = NEW(Ecore_Event_Handler, 1); + h->func = func; + h->next = handler[type]; + handler[type] = h; +} + +void +ecore_event_filter_idle_handler_add(void (*func) (void *data), void *data) +{ + Ecore_Event_Idle_Handler *h; + + h = NEW(Ecore_Event_Idle_Handler, 1); + h->func = func; + h->data = data; + h->next = idle_handlers; + idle_handlers = h; +} diff --git a/ecore/src/e_ev_signal.c b/ecore/src/e_ev_signal.c new file mode 100644 index 0000000..b0e34cb --- /dev/null +++ b/ecore/src/e_ev_signal.c @@ -0,0 +1,320 @@ +#include "Ecore.h" +#include +#include +#include +#include +#include + +static void ecore_event_signal_free(void *event); +static void ecore_event_signal_handle_sigchld(int num); +static void ecore_event_signal_handle_sigusr1(int num); +static void ecore_event_signal_handle_sigusr2(int num); +static void ecore_event_signal_handle_sighup(int num); +static void ecore_event_signal_handle_sigpipe(int num); +static void ecore_event_signal_handle_sigsegv(int num); +static void ecore_event_signal_handle_sigfpe(int num); +static void ecore_event_signal_handle_sigill(int num); +static void ecore_event_signal_handle_sigbus(int num); + +#ifdef HAVE_SIGSTKFLT +static void ecore_event_signal_handle_sigstkflt(int num); +#endif +#ifdef HAVE_SIGPWR +static void ecore_event_signal_handle_sigpwr(int num); +#endif +static void ecore_event_signal_handle_sigchld(int num); +static void ecore_event_signal_handle_all(pid_t pid); + +static int signal_chld_count = 0; +static int signal_usr1_count = 0; +static int signal_usr2_count = 0; +static int signal_hup_count = 0; + +/* freeing stuff */ +static void +ecore_event_signal_free(void *event) +{ + FREE(event); +} + +/* signal handlers we can return from and add to signal recieved counts */ +static void +ecore_event_signal_handle_sigchld(int num) +{ + signal_chld_count++; + return; + num = 0; +} + +static void +ecore_event_signal_handle_sigusr1(int num) +{ + signal_usr1_count++; + return; + num = 0; +} + +static void +ecore_event_signal_handle_sigusr2(int num) +{ + signal_usr2_count++; + return; + num = 0; +} + +static void +ecore_event_signal_handle_sighup(int num) +{ + signal_hup_count++; + return; + num = 0; +} + +/* signals to ignore */ +static void +ecore_event_signal_handle_sigpipe(int num) +{ + return; + num = 0; +} + +/* signal handlers we cant return from - so handle here */ +static void +ecore_event_signal_handle_sigsegv(int num) +{ + for (;;) + { + fprintf(stderr, "EEEEEEEEK SEGV - waiting 10 seconds\n"); + sleep(10); + } + /* EEK - can't return - bad */ + abort(); + num = 0; +} + +static void +ecore_event_signal_handle_sigfpe(int num) +{ + /* EEK - can't return - bad */ + abort(); + num = 0; +} + +static void +ecore_event_signal_handle_sigill(int num) +{ + /* EEK - can't return - bad */ + abort(); + num = 0; +} + +static void +ecore_event_signal_handle_sigbus(int num) +{ + /* EEK - can't return - bad */ + abort(); + num = 0; +} + +#ifdef HAVE_SIGSTKFLT +static void +ecore_event_signal_handle_sigstkflt(int num) +{ + /* EEK - can't return - bad */ + abort(); + return; + num = 0; +} +#endif + +static void +ecore_event_signal_handle_sigint(int num) +{ + exit(0); + return; + num = 0; +} + +static void +ecore_event_signal_handle_sigquit(int num) +{ + exit(0); + return; + num = 0; +} + +static void +ecore_event_signal_handle_sigabrt(int num) +{ + abort(); + return; + num = 0; +} + +static void +ecore_event_signal_handle_sigalrm(int num) +{ + return; + num = 0; +} + +static void +ecore_event_signal_handle_sigterm(int num) +{ + exit(0); + return; + num = 0; +} + +#ifdef HAVE_SIGPWR +static void +ecore_event_signal_handle_sigpwr(int num) +{ + exit(0); + return; + num = 0; +} +#endif + +static void +ecore_event_signal_handle_all(pid_t pid_pass) +{ + int status; + pid_t pid; + + if (signal_chld_count > 0) + { + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) + { + if (WIFEXITED(status)) + { + Ecore_Event_Child *e; + int code; + + code = WEXITSTATUS(status); + e = NEW(Ecore_Event_Child, 1); + e->pid = pid; + e->exit_code = code; + ecore_add_event(ECORE_EVENT_CHILD, e, ecore_event_signal_free); + } + } + signal_chld_count = 0; + } + while (signal_usr1_count > 0) + { + Ecore_Event_User *e; + + e = NEW(Ecore_Event_User, 1); + e->num = 0; + e->hup = 0; + ecore_add_event(ECORE_EVENT_USER, e, ecore_event_signal_free); + signal_usr1_count--; + } + while (signal_hup_count > 0) + { + Ecore_Event_User *e; + + e = NEW(Ecore_Event_User, 1); + e->num = 0; + e->hup = 1; + ecore_add_event(ECORE_EVENT_USER, e, ecore_event_signal_free); + signal_hup_count--; + } + return; + pid_pass = 0; +} + +int +ecore_event_signal_events_pending(void) +{ + return (signal_chld_count + signal_usr1_count + signal_hup_count); +} + +void +ecore_event_signal_init(void) +{ + struct sigaction sa; + + ecore_add_event_pid(0, ecore_event_signal_handle_all); + + sa.sa_handler = ecore_event_signal_handle_sigchld; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGCHLD, &sa, (struct sigaction *)0); + + sa.sa_handler = ecore_event_signal_handle_sigusr1; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGUSR1, &sa, (struct sigaction *)0); + + sa.sa_handler = ecore_event_signal_handle_sigusr2; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGUSR2, &sa, (struct sigaction *)0); + + sa.sa_handler = ecore_event_signal_handle_sighup; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGHUP, &sa, (struct sigaction *)0); + + sa.sa_handler = ecore_event_signal_handle_sigpipe; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGPIPE, &sa, (struct sigaction *)0); +/* + sa.sa_handler = ecore_event_signal_handle_sigsegv; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, (struct sigaction *)0); +*/ + sa.sa_handler = ecore_event_signal_handle_sigfpe; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGFPE, &sa, (struct sigaction *)0); + + sa.sa_handler = ecore_event_signal_handle_sigill; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGILL, &sa, (struct sigaction *)0); + + sa.sa_handler = ecore_event_signal_handle_sigbus; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGBUS, &sa, (struct sigaction *)0); +#ifdef HAVE_SIGSTKFLT + sa.sa_handler = ecore_event_signal_handle_sigstkflt; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGSTKFLT, &sa, (struct sigaction *)0); +#endif + sa.sa_handler = ecore_event_signal_handle_sigint; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGINT, &sa, (struct sigaction *)0); + + sa.sa_handler = ecore_event_signal_handle_sigquit; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGQUIT, &sa, (struct sigaction *)0); + + sa.sa_handler = ecore_event_signal_handle_sigabrt; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGABRT, &sa, (struct sigaction *)0); + + sa.sa_handler = ecore_event_signal_handle_sigalrm; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGALRM, &sa, (struct sigaction *)0); + + sa.sa_handler = ecore_event_signal_handle_sigterm; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGTERM, &sa, (struct sigaction *)0); +#ifdef HAVE_SIGPWR + sa.sa_handler = ecore_event_signal_handle_sigpwr; + sa.sa_flags = SA_RESTART; + sigemptyset(&sa.sa_mask); + sigaction(SIGPWR, &sa, (struct sigaction *)0); +#endif +} diff --git a/ecore/src/e_ev_x.c b/ecore/src/e_ev_x.c new file mode 100644 index 0000000..a3ea7bd --- /dev/null +++ b/ecore/src/e_ev_x.c @@ -0,0 +1,1234 @@ +#include "Ecore.h" +#include +#include +#include + +/* private funtion prototypes */ +static void ecore_event_x_handle_events(int fd); +static void ecore_event_x_translate_events(XEvent * events, + int num_events); + +static void ecore_event_key_down_free(void *event); +static void ecore_event_key_up_free(void *event); +static void ecore_event_generic_free(void *event); +static void ecore_event_dnd_drop_request_free(void *event); +static void ecore_event_paste_request_free(void *event); + +static void ecore_event_x_handle_keypress(XEvent * xevent); +static void ecore_event_x_handle_keyrelease(XEvent * xevent); +static void ecore_event_x_handle_button_press(XEvent * xevent); +static void ecore_event_x_handle_button_release(XEvent * xevent); +static void ecore_event_x_handle_motion_notify(XEvent * xevent); +static void ecore_event_x_handle_enter_notify(XEvent * xevent); +static void ecore_event_x_handle_leave_notify(XEvent * xevent); +static void ecore_event_x_handle_focus_in(XEvent * xevent); +static void ecore_event_x_handle_focus_out(XEvent * xevent); +static void ecore_event_x_handle_expose(XEvent * xevent); +static void ecore_event_x_handle_visibility_notify(XEvent * xevent); +static void ecore_event_x_handle_create_notify(XEvent * xevent); +static void ecore_event_x_handle_destroy_notify(XEvent * xevent); +static void ecore_event_x_handle_unmap_notify(XEvent * xevent); +static void ecore_event_x_handle_map_notify(XEvent * xevent); +static void ecore_event_x_handle_map_request(XEvent * xevent); +static void ecore_event_x_handle_reparent_notify(XEvent * xevent); +static void ecore_event_x_handle_configure_notify(XEvent * xevent); +static void ecore_event_x_handle_configure_request(XEvent * xevent); +static void ecore_event_x_handle_circulate_notify(XEvent * xevent); +static void ecore_event_x_handle_circulate_request(XEvent * xevent); +static void ecore_event_x_handle_property_notify(XEvent * xevent); +static void ecore_event_x_handle_colormap_notify(XEvent * xevent); +static void ecore_event_x_handle_selection_notify(XEvent * xevent); +static void ecore_event_x_handle_selection_clear(XEvent * xevent); +static void ecore_event_x_handle_selection_request(XEvent * xevent); +static void ecore_event_x_handle_client_message(XEvent * xevent); +static void ecore_event_x_handle_shape_change(XEvent * xevent); + +static int max_event_id = 0; +static void (**event_translator) (XEvent * event) = NULL; + +static int lock_mask_scroll = 0, lock_mask_num = 0, lock_mask_caps = 0; +static int mod_mask_shift = 0, mod_mask_ctrl = 0, mod_mask_alt = + 0, mod_mask_win = 0; + +/* convenience macros */ +#define GETSET_MODS(state, mods) \ +(mods) = ECORE_EVENT_KEY_MODIFIER_NONE;\ +if ((state) & mod_mask_shift) { ecore_mod_shift_set(1); (mods) |= ECORE_EVENT_KEY_MODIFIER_SHIFT; }\ +else ecore_mod_shift_set(0);\ +if ((state) & mod_mask_ctrl) { ecore_mod_ctrl_set(1); (mods) |= ECORE_EVENT_KEY_MODIFIER_CTRL; }\ +else ecore_mod_ctrl_set(0);\ +if ((state) & mod_mask_alt) { ecore_mod_alt_set(1); (mods) |= ECORE_EVENT_KEY_MODIFIER_ALT; }\ +else ecore_mod_alt_set(0);\ +if ((state) & mod_mask_win) { ecore_mod_win_set(1); (mods) |= ECORE_EVENT_KEY_MODIFIER_WIN; }\ +else ecore_mod_win_set(0); + +/* public functions */ + +/* initialise event handling for the fd X is on */ +void +ecore_event_x_init(void) +{ + int i, shape_event_id, current_lock; + + shape_event_id = max_event_id = ecore_event_shape_get_id(); + if (shape_event_id < LASTEvent) + { + max_event_id = LASTEvent; + fprintf(stderr, "ERROR: No shape extension! This is BAD!\n"); + } + event_translator = NEW_PTR(max_event_id + 1); + for (i = 0; i < max_event_id + 1; i++) + event_translator[i] = NULL; + event_translator[KeyPress] = ecore_event_x_handle_keypress; + event_translator[KeyRelease] = ecore_event_x_handle_keyrelease; + event_translator[ButtonPress] = ecore_event_x_handle_button_press; + event_translator[ButtonRelease] = ecore_event_x_handle_button_release; + event_translator[MotionNotify] = ecore_event_x_handle_motion_notify; + event_translator[EnterNotify] = ecore_event_x_handle_enter_notify; + event_translator[LeaveNotify] = ecore_event_x_handle_leave_notify; + event_translator[FocusIn] = ecore_event_x_handle_focus_in; + event_translator[FocusOut] = ecore_event_x_handle_focus_out; + event_translator[Expose] = ecore_event_x_handle_expose; + event_translator[VisibilityNotify] = ecore_event_x_handle_visibility_notify; + event_translator[CreateNotify] = ecore_event_x_handle_create_notify; + event_translator[DestroyNotify] = ecore_event_x_handle_destroy_notify; + event_translator[UnmapNotify] = ecore_event_x_handle_unmap_notify; + event_translator[MapNotify] = ecore_event_x_handle_map_notify; + event_translator[MapRequest] = ecore_event_x_handle_map_request; + event_translator[ReparentNotify] = ecore_event_x_handle_reparent_notify; + event_translator[ConfigureNotify] = ecore_event_x_handle_configure_notify; + event_translator[ConfigureRequest] = ecore_event_x_handle_configure_request; + event_translator[CirculateNotify] = ecore_event_x_handle_circulate_notify; + event_translator[CirculateRequest] = ecore_event_x_handle_circulate_request; + event_translator[PropertyNotify] = ecore_event_x_handle_property_notify; + event_translator[ColormapNotify] = ecore_event_x_handle_colormap_notify; + event_translator[ClientMessage] = ecore_event_x_handle_client_message; + event_translator[SelectionNotify] = ecore_event_x_handle_selection_notify; + event_translator[SelectionClear] = ecore_event_x_handle_selection_clear; + event_translator[SelectionRequest] = ecore_event_x_handle_selection_request; + if (shape_event_id > SelectionRequest) + event_translator[shape_event_id] = ecore_event_x_handle_shape_change; + + lock_mask_scroll = ecore_lock_mask_scroll_get(); + lock_mask_num = ecore_lock_mask_num_get(); + lock_mask_caps = ecore_lock_mask_caps_get(); + + mod_mask_shift = ecore_mod_mask_shift_get(); + mod_mask_ctrl = ecore_mod_mask_ctrl_get(); + mod_mask_alt = ecore_mod_mask_alt_get(); + mod_mask_win = ecore_mod_mask_win_get(); + +/* HRRRMMM lets not do this + ecorecore_keygrab("Num_Lock", ECORE_EVENT_KEY_MODIFIER_NONE, 1, 1); + ecorecore_keygrab("Scroll_Lock", ECORE_EVENT_KEY_MODIFIER_NONE, 1, 1); + ecorecore_keygrab("Caps_Lock", ECORE_EVENT_KEY_MODIFIER_NONE, 1, 1); + */ + current_lock = ecore_modifier_mask_get(); + if (current_lock & lock_mask_scroll) + ecore_lock_scroll_set(1); + if (current_lock & lock_mask_num) + ecore_lock_num_set(1); + if (current_lock & lock_mask_caps) + ecore_lock_caps_set(1); + if (current_lock & mod_mask_shift) + ecore_mod_shift_set(1); + if (current_lock & mod_mask_ctrl) + ecore_mod_ctrl_set(1); + if (current_lock & mod_mask_alt) + ecore_mod_alt_set(1); + if (current_lock & mod_mask_win) + ecore_mod_win_set(1); + ecore_add_event_fd(ecore_x_get_fd(), ecore_event_x_handle_events); +} + +/* private functions */ +/* get all events onthe event queue and translate them */ +static void +ecore_event_x_handle_events(int fd) +{ + int num_events = 0, size_events = 0; + XEvent *events = NULL; + + /* while there are events in the queue */ + while (ecore_events_pending()) + { + /* incriment our event count */ + num_events++; + /* if the numebr fo events is > than our buffer size then */ + if (num_events > size_events) + { + /* increase the buffer size by 64 events */ + size_events += 64; + if (events) + { + REALLOC(events, XEvent, size_events)} + else + events = NEW(XEvent, size_events); + } + /* get the next event into the event buffer */ + ecore_get_next_event(&(events[num_events - 1])); + } + /* call the XEvent -> Eevent translator */ + if (events) + { + ecore_event_x_translate_events(events, num_events); + /* if theres an event buffer - free it */ + FREE(events); + } + return; + fd = 0; +} + +/* take an array of events and translate them into E events */ +static void +ecore_event_x_translate_events(XEvent * events, int num_events) +{ + int i; + + for (i = 0; i < num_events; i++) + { + if ((events[i].type <= max_event_id) && + (event_translator[events[i].type])) + (*(event_translator[events[i].type])) (&(events[i])); + } +} + +static void +ecore_event_key_down_free(void *event) +{ + Ecore_Event_Key_Down *e; + + e = (Ecore_Event_Key_Down *) event; + IF_FREE(e->key); + IF_FREE(e->compose); + FREE(e); +} + +static void +ecore_event_key_up_free(void *event) +{ + Ecore_Event_Key_Up *e; + + e = (Ecore_Event_Key_Up *) event; + IF_FREE(e->key); + IF_FREE(e->compose); + FREE(e); +} + +static void +ecore_event_generic_free(void *event) +{ + FREE(event); +} + +static void +ecore_event_dnd_drop_request_free(void *event) +{ + Ecore_Event_Dnd_Drop_Request *e; + + e = (Ecore_Event_Dnd_Drop_Request *) event; + if (e->files) + { + int i; + + for (i = 0; i < e->num_files; i++) + FREE(e->files[i]); + } + FREE(event); +} + +static void +ecore_event_paste_request_free(void *event) +{ + Ecore_Event_Paste_Request *e; + + e = (Ecore_Event_Paste_Request *) event; + IF_FREE(e->string); + FREE(event); +} + +static void +ecore_event_x_handle_keypress(XEvent * xevent) +{ + Ecore_Event_Key_Down *e; + static KeyCode previous_code = 0; + static Time previous_time = 0; + + /* avoid doubling events up from passive grabs */ + if ((xevent->xkey.keycode == previous_code) && + xevent->xkey.time == previous_time) + return; + previous_code = xevent->xkey.keycode; + previous_time = xevent->xkey.time; +/* + if (ecore_keyget_keysym_from_keycode(xevent->xkey.keycode) == XK_Scroll_Lock) + { + if (ecore_lock_scroll_get()) + ecore_lock_scroll_set(0); + else + ecore_lock_scroll_set(1); + e_event_allow(ReplayKeyboard, xevent->xkey.time); + ecore_flush(); + } + else if (ecore_keyget_keysym_from_keycode(xevent->xkey.keycode) == XK_Num_Lock) + { + if (ecore_lock_num_get()) + ecore_lock_num_set(0); + else + ecore_lock_num_set(1); + e_event_allow(ReplayKeyboard, xevent->xkey.time); + ecore_flush(); + } + else if (ecore_keyget_keysym_from_keycode(xevent->xkey.keycode) == XK_Caps_Lock) + { + if (ecore_lock_caps_get()) + ecore_lock_caps_set(0); + else + ecore_lock_caps_set(1); + e_event_allow(ReplayKeyboard, xevent->xkey.time); + ecore_flush(); + } + */ + e = NEW(Ecore_Event_Key_Down, 1); + e->win = xevent->xkey.window; + e->root = xevent->xkey.root; + GETSET_MODS(xevent->xkey.state, e->mods); + e->time = xevent->xkey.time; + e->key = ecore_key_get_string_from_keycode(xevent->xkey.keycode); + { + int val; + char buf[256]; + KeySym sym; + XComposeStatus stat; + + val = XLookupString((XKeyEvent *) xevent, buf, sizeof(buf), &sym, &stat); + if (val > 0) + { + buf[val] = 0; + e->compose = strdup(buf); + } + else + e->compose = NULL; + } + ecore_add_event(ECORE_EVENT_KEY_DOWN, e, ecore_event_key_down_free); +} + +static void +ecore_event_x_handle_keyrelease(XEvent * xevent) +{ + Ecore_Event_Key_Up *e; + static KeyCode previous_code = 0; + static Time previous_time = 0; + + /* avoid doubling events up from passive grabs */ + if ((xevent->xkey.keycode == previous_code) && + xevent->xkey.time == previous_time) + return; + previous_code = xevent->xkey.keycode; + previous_time = xevent->xkey.time; + + e = NEW(Ecore_Event_Key_Up, 1); + e->win = xevent->xkey.window; + e->root = xevent->xkey.root; + GETSET_MODS(xevent->xkey.state, e->mods); + e->time = xevent->xkey.time; + e->key = ecore_key_get_string_from_keycode(xevent->xkey.keycode); + { + int val; + char buf[256]; + KeySym sym; + XComposeStatus stat; + + val = XLookupString((XKeyEvent *) xevent, buf, sizeof(buf), &sym, &stat); + if (val > 0) + { + buf[val] = 0; + e->compose = strdup(buf); + } + else + e->compose = NULL; + } + ecore_add_event(ECORE_EVENT_KEY_UP, e, ecore_event_key_up_free); +} + +static void +ecore_event_x_handle_button_press(XEvent * xevent) +{ + static Time last_time = 0, last_last_time = 0; + static int last_button = 0, last_last_button = 0; + static Window last_window = 0, last_last_window = 0; + + ecore_pointer_xy_set(xevent->xbutton.x_root, xevent->xbutton.y_root); + if ((xevent->xbutton.button == 4) || (xevent->xbutton.button == 5)) + { + Ecore_Event_Wheel *e; + + e = NEW(Ecore_Event_Wheel, 1); + e->win = xevent->xbutton.window; + e->root = xevent->xbutton.root; + e->x = xevent->xbutton.x; + e->y = xevent->xbutton.y; + e->rx = xevent->xbutton.x_root; + e->ry = xevent->xbutton.y_root; + e->time = xevent->xbutton.time; + if (xevent->xbutton.button == 5) + e->z = 1; + else + e->z = -1; + if (xevent->xbutton.time - last_time < 15) + e->z *= 16; + else if (xevent->xbutton.time - last_time < 30) + e->z *= 4; + GETSET_MODS(xevent->xbutton.state, e->mods); + ecore_add_event(ECORE_EVENT_MOUSE_WHEEL, e, ecore_event_generic_free); + } + else + { + Ecore_Event_Mouse_Down *e; + + e = NEW(Ecore_Event_Mouse_Down, 1); + e->win = xevent->xbutton.window; + e->root = xevent->xbutton.root; + e->button = xevent->xbutton.button; + e->x = xevent->xbutton.x; + e->y = xevent->xbutton.y; + e->rx = xevent->xbutton.x_root; + e->ry = xevent->xbutton.y_root; + e->time = xevent->xbutton.time; + e->double_click = 0; + e->triple_click = 0; + GETSET_MODS(xevent->xbutton.state, e->mods); + if (xevent->xbutton.time - last_last_time < 500) + { + if ((xevent->xbutton.window == (unsigned int)last_window) && + (last_window == last_last_window) && + (xevent->xbutton.button == (unsigned int)last_button) && + (last_button == last_button)) + e->triple_click = 1; + } + else if (xevent->xbutton.time - last_time < 250) + { + if ((xevent->xbutton.window == (unsigned int)last_window) && + (xevent->xbutton.button == (unsigned int)last_button)) + e->double_click = 1; + } + ecore_add_event(ECORE_EVENT_MOUSE_DOWN, e, ecore_event_generic_free); + { + Ecore_XID *xid = NULL; + + if (XFindContext(xevent->xbutton.display, e->win, + xid_context, (XPointer *) & xid) != XCNOENT) + { + if ((xid->grab_button_auto_replay) && + (xid->grab_button_auto_replay(e))) + { + ecore_pointer_replay(e->time); + } + } + } + } + last_last_window = last_window; + last_window = xevent->xbutton.window; + last_last_button = last_button; + last_button = xevent->xbutton.button; + last_last_time = last_time; + last_time = xevent->xbutton.time; +} + +static void +ecore_event_x_handle_button_release(XEvent * xevent) +{ + Ecore_Event_Mouse_Up *e; + + if (xevent->xbutton.button > 3) + return; + + e = NEW(Ecore_Event_Mouse_Up, 1); + e->win = xevent->xbutton.window; + e->root = xevent->xbutton.root; + e->button = xevent->xbutton.button; + e->x = xevent->xbutton.x; + e->y = xevent->xbutton.y; + e->rx = xevent->xbutton.x_root; + e->ry = xevent->xbutton.y_root; + e->time = xevent->xbutton.time; + GETSET_MODS(xevent->xbutton.state, e->mods); + ecore_add_event(ECORE_EVENT_MOUSE_UP, e, ecore_event_generic_free); +} + +static void +ecore_event_x_handle_motion_notify(XEvent * xevent) +{ + Ecore_Event_Mouse_Move *e; + + ecore_pointer_xy_set(xevent->xmotion.x_root, xevent->xmotion.y_root); + e = NEW(Ecore_Event_Mouse_Move, 1); + e->win = xevent->xmotion.window; + e->root = xevent->xmotion.root; + e->x = xevent->xmotion.x; + e->y = xevent->xmotion.y; + e->rx = xevent->xmotion.x_root; + e->ry = xevent->xmotion.y_root; + e->time = xevent->xmotion.time; + GETSET_MODS(xevent->xmotion.state, e->mods); + ecore_add_event(ECORE_EVENT_MOUSE_MOVE, e, ecore_event_generic_free); +} + +static void +ecore_event_x_handle_enter_notify(XEvent * xevent) +{ + Ecore_Event_Window_Enter *e; + +/* if ((xevent->xcrossing.mode == NotifyGrab) || (xevent->xcrossing.mode == NotifyUngrab)) return;*/ + ecore_pointer_xy_set(xevent->xcrossing.x_root, xevent->xcrossing.y_root); + e = NEW(Ecore_Event_Window_Enter, 1); + e->win = xevent->xcrossing.window; + e->root = xevent->xcrossing.root; + e->x = xevent->xcrossing.x; + e->y = xevent->xcrossing.y; + e->rx = xevent->xcrossing.x_root; + e->ry = xevent->xcrossing.y_root; + e->time = xevent->xcrossing.time; + GETSET_MODS(xevent->xcrossing.state, e->mods); + ecore_add_event(ECORE_EVENT_MOUSE_IN, e, ecore_event_generic_free); + ecore_window_mouse_set_in(e->win, 1); + { + Ecore_Event_Mouse_Move *e; + + e = NEW(Ecore_Event_Mouse_Move, 1); + e->win = xevent->xcrossing.window; + e->root = xevent->xcrossing.root; + e->x = xevent->xcrossing.x; + e->y = xevent->xcrossing.y; + e->rx = xevent->xcrossing.x_root; + e->ry = xevent->xcrossing.y_root; + e->time = xevent->xcrossing.time; + GETSET_MODS(xevent->xcrossing.state, e->mods); + ecore_add_event(ECORE_EVENT_MOUSE_MOVE, e, ecore_event_generic_free); + } +} + +static void +ecore_event_x_handle_leave_notify(XEvent * xevent) +{ + Ecore_Event_Window_Leave *e; + +/* if ((xevent->xcrossing.mode == NotifyGrab) || (xevent->xcrossing.mode == NotifyUngrab)) return;*/ + ecore_pointer_xy_set(xevent->xcrossing.x_root, xevent->xcrossing.y_root); + { + Ecore_Event_Mouse_Move *e; + + e = NEW(Ecore_Event_Mouse_Move, 1); + e->win = xevent->xcrossing.window; + e->root = xevent->xcrossing.root; + e->x = xevent->xcrossing.x; + e->y = xevent->xcrossing.y; + e->rx = xevent->xcrossing.x_root; + e->ry = xevent->xcrossing.y_root; + e->time = xevent->xcrossing.time; + GETSET_MODS(xevent->xcrossing.state, e->mods); + ecore_add_event(ECORE_EVENT_MOUSE_MOVE, e, ecore_event_generic_free); + } + e = NEW(Ecore_Event_Window_Leave, 1); + e->win = xevent->xcrossing.window; + e->root = xevent->xcrossing.root; + e->x = xevent->xcrossing.x; + e->y = xevent->xcrossing.y; + e->rx = xevent->xcrossing.x_root; + e->ry = xevent->xcrossing.y_root; + e->time = xevent->xcrossing.time; + GETSET_MODS(xevent->xcrossing.state, e->mods); + ecore_add_event(ECORE_EVENT_MOUSE_OUT, e, ecore_event_generic_free); + ecore_window_mouse_set_in(e->win, 0); +} + +static void +ecore_event_x_handle_focus_in(XEvent * xevent) +{ + Ecore_Event_Window_Focus_In *e; + + e = NEW(Ecore_Event_Window_Focus_In, 1); + e->win = xevent->xfocus.window; + e->root = ecore_window_get_root(e->win); + if (xevent->xfocus.mode != NotifyNormal) + e->key_grab = 1; + else + e->key_grab = 0; + ecore_add_event(ECORE_EVENT_WINDOW_FOCUS_IN, e, ecore_event_generic_free); + ecore_focus_window_set(e->win); +} + +static void +ecore_event_x_handle_focus_out(XEvent * xevent) +{ + Ecore_Event_Window_Focus_Out *e; + + e = NEW(Ecore_Event_Window_Focus_Out, 1); + e->win = xevent->xfocus.window; + e->root = ecore_window_get_root(e->win); + if (xevent->xfocus.mode != NotifyNormal) + e->key_grab = 1; + else + e->key_grab = 0; + ecore_add_event(ECORE_EVENT_WINDOW_FOCUS_OUT, e, ecore_event_generic_free); + ecore_focus_window_set(0); +} + +static void +ecore_event_x_handle_expose(XEvent * xevent) +{ + Ecore_Event_Window_Expose *e; + + e = NEW(Ecore_Event_Window_Expose, 1); + e->win = xevent->xexpose.window; + e->root = ecore_window_get_root(e->win); + e->x = xevent->xexpose.x; + e->y = xevent->xexpose.y; + e->w = xevent->xexpose.width; + e->h = xevent->xexpose.height; + ecore_add_event(ECORE_EVENT_WINDOW_EXPOSE, e, ecore_event_generic_free); +} + +static void +ecore_event_x_handle_visibility_notify(XEvent * xevent) +{ + if (xevent->xvisibility.state != VisibilityPartiallyObscured) + { + Ecore_Event_Window_Visibility *e; + + e = NEW(Ecore_Event_Window_Visibility, 1); + e->win = xevent->xvisibility.window; + e->root = ecore_window_get_root(e->win); + if (xevent->xvisibility.state == VisibilityFullyObscured) + e->fully_obscured = 1; + else + e->fully_obscured = 0; + ecore_add_event(ECORE_EVENT_WINDOW_VISIBILITY, e, + ecore_event_generic_free); + } +} + +static void +ecore_event_x_handle_create_notify(XEvent * xevent) +{ + Ecore_Event_Window_Create *e; + + e = NEW(Ecore_Event_Window_Create, 1); + e->win = xevent->xcreatewindow.window; + ecore_validate_xid(e->win); + e->root = ecore_window_get_root(e->win); + if (xevent->xcreatewindow.override_redirect) + e->override = 1; + else + e->override = 0; + ecore_add_event(ECORE_EVENT_WINDOW_CREATE, e, ecore_event_generic_free); +} + +static void +ecore_event_x_handle_destroy_notify(XEvent * xevent) +{ + Ecore_Event_Window_Destroy *e; + + e = NEW(Ecore_Event_Window_Destroy, 1); + e->win = xevent->xdestroywindow.window; + e->root = ecore_window_get_root(e->win); + ecore_add_event(ECORE_EVENT_WINDOW_DESTROY, e, ecore_event_generic_free); + ecore_unvalidate_xid(e->win); +} + +static void +ecore_event_x_handle_unmap_notify(XEvent * xevent) +{ + Ecore_Event_Window_Unmap *e; + Ecore_XID *xid = NULL; + + e = NEW(Ecore_Event_Window_Unmap, 1); + e->win = xevent->xunmap.window; + e->root = ecore_window_get_root(e->win); + ecore_add_event(ECORE_EVENT_WINDOW_UNMAP, e, ecore_event_generic_free); + xid = ecore_validate_xid(e->win); + if (xid) + xid->mapped = 0; +} + +static void +ecore_event_x_handle_map_notify(XEvent * xevent) +{ + Ecore_Event_Window_Map *e; + Ecore_XID *xid = NULL; + + e = NEW(Ecore_Event_Window_Map, 1); + e->win = xevent->xmap.window; + e->root = ecore_window_get_root(e->win); + ecore_add_event(ECORE_EVENT_WINDOW_MAP, e, ecore_event_generic_free); + xid = ecore_validate_xid(e->win); + if (xid) + xid->mapped = 1; +} + +static void +ecore_event_x_handle_map_request(XEvent * xevent) +{ + Ecore_Event_Window_Map_Request *e; + + e = NEW(Ecore_Event_Window_Map_Request, 1); + e->win = xevent->xmaprequest.window; + e->root = ecore_window_get_root(e->win); + ecore_add_event(ECORE_EVENT_WINDOW_MAP_REQUEST, e, ecore_event_generic_free); + ecore_validate_xid(e->win); +} + +static void +ecore_event_x_handle_reparent_notify(XEvent * xevent) +{ + Ecore_Event_Window_Reparent *e; + Window parent; + Ecore_XID *xid = NULL; + + e = NEW(Ecore_Event_Window_Reparent, 1); + e->win = xevent->xreparent.window; + xid = ecore_validate_xid(e->win); + e->root = ecore_window_get_root(e->win); + parent = ecore_window_get_parent(e->win); + e->parent_from = parent; + e->parent = xevent->xreparent.parent; + ecore_validate_xid(e->parent); + ecore_del_child(parent, e->win); + ecore_add_child(xevent->xreparent.parent, xevent->xreparent.window); + if (xid) + xid->parent = e->parent; + ecore_add_event(ECORE_EVENT_WINDOW_REPARENT, e, ecore_event_generic_free); +} + +static void +ecore_event_x_handle_configure_notify(XEvent * xevent) +{ + Ecore_Event_Window_Configure *e; + Ecore_XID *xid; + + e = NEW(Ecore_Event_Window_Configure, 1); + e->win = xevent->xconfigure.window; + e->root = ecore_window_get_root(e->win); + e->x = xevent->xconfigure.x; + e->y = xevent->xconfigure.y; + e->w = xevent->xconfigure.width; + e->h = xevent->xconfigure.height; + if (!xevent->xconfigure.send_event) + { + xid = ecore_validate_xid(e->win); + if (xid) + { + xid->x = e->x; + xid->y = e->y; + xid->w = e->w; + xid->h = e->h; + } + e->wm_generated = 0; + /* FIXME: don't handle redoing stack for xevent->xconfigure.above */ + /* member (the window is stacked immediately in stack above this) */ + } + else + e->wm_generated = 1; + ecore_add_event(ECORE_EVENT_WINDOW_CONFIGURE, e, ecore_event_generic_free); +} + +static void +ecore_event_x_handle_configure_request(XEvent * xevent) +{ + Ecore_Event_Window_Configure_Request *e; + + e = NEW(Ecore_Event_Window_Configure_Request, 1); + e->win = xevent->xconfigurerequest.window; + e->root = ecore_window_get_root(e->win); + e->x = xevent->xconfigurerequest.x; + e->y = xevent->xconfigurerequest.y; + e->w = xevent->xconfigurerequest.width; + e->h = xevent->xconfigurerequest.height; + e->stack_win = xevent->xconfigurerequest.above; + e->detail = xevent->xconfigurerequest.detail; + e->mask = xevent->xconfigurerequest.value_mask; + ecore_add_event(ECORE_EVENT_WINDOW_CONFIGURE_REQUEST, e, + ecore_event_generic_free); +} + +static void +ecore_event_x_handle_circulate_notify(XEvent * xevent) +{ + Ecore_Event_Window_Circulate *e; + + e = NEW(Ecore_Event_Window_Circulate, 1); + e->win = xevent->xcirculate.window; + e->root = ecore_window_get_root(e->win); + if (xevent->xcirculate.place == PlaceOnBottom) + e->lower = 1; + else + e->lower = 0; + ecore_add_event(ECORE_EVENT_WINDOW_CIRCULATE, e, ecore_event_generic_free); +} + +static void +ecore_event_x_handle_circulate_request(XEvent * xevent) +{ + Ecore_Event_Window_Circulate_Request *e; + + e = NEW(Ecore_Event_Window_Circulate_Request, 1); + e->win = xevent->xcirculaterequest.window; + e->root = ecore_window_get_root(e->win); + if (xevent->xcirculaterequest.place == PlaceOnBottom) + e->lower = 1; + else + e->lower = 0; + ecore_add_event(ECORE_EVENT_WINDOW_CIRCULATE_REQUEST, e, + ecore_event_generic_free); +} + +static void +ecore_event_x_handle_property_notify(XEvent * xevent) +{ + Ecore_Event_Window_Property *e; + + e = NEW(Ecore_Event_Window_Property, 1); + e->win = xevent->xproperty.window; + e->root = ecore_window_get_root(e->win); + e->atom = xevent->xproperty.atom; + e->time = xevent->xproperty.time; + ecore_add_event(ECORE_EVENT_WINDOW_PROPERTY, e, ecore_event_generic_free); +} + +static void +ecore_event_x_handle_colormap_notify(XEvent * xevent) +{ + Ecore_Event_Colormap *e; + + e = NEW(Ecore_Event_Colormap, 1); + e->win = xevent->xcolormap.window; + e->root = ecore_window_get_root(e->win); + e->cmap = xevent->xcolormap.colormap; + if (xevent->xcolormap.state == ColormapInstalled) + e->installed = 1; + else + e->installed = 0; + ecore_add_event(ECORE_EVENT_COLORMAP, e, ecore_event_generic_free); +} + +Ecore_Event_Dnd_Drop_Request *ev_drop_request_pending = NULL; + +static void +ecore_event_x_handle_selection_notify(XEvent * xevent) +{ + Ecore_Event_Dnd_Drop_Request *e; + char *data; + int size; + static Atom atom_xdndactioncopy = 0; + static Atom atom_xdndactionmove = 0; + static Atom atom_xdndactionlink = 0; + static Atom atom_xdndactionask = 0; + static Atom atom_xdndactionlist = 0; + + e = ev_drop_request_pending; + if (!e) + { + Ecore_Event_Paste_Request *e2; + + e2 = NEW(Ecore_Event_Paste_Request, 1); + e2->string = ecore_selection_get_data(xevent->xselection.requestor, + xevent->xselection.property); + if (e2->string) + { + e2->win = xevent->xselection.requestor; + e2->root = ecore_window_get_root(e2->win); + e2->source_win = xevent->xselection.requestor; + ecore_add_event(ECORE_EVENT_PASTE_REQUEST, e2, + ecore_event_paste_request_free); + } + else + { + FREE(e2); + } + return; + } + + ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy"); + ECORE_ATOM(atom_xdndactionmove, "XdndActionMove"); + ECORE_ATOM(atom_xdndactionlink, "XdndActionLink"); + ECORE_ATOM(atom_xdndactionask, "XdndActionAsk"); + ECORE_ATOM(atom_xdndactionlist, "XdndActionList"); + data = ecore_dnd_selection_get(xevent->xany.window, e->source_win, + xevent->xselection.property, &size); + if (data) + { + char *s, *buf; + int i, is; + Atom *method = NULL; + + method = ecore_window_property_get(e->source_win, + atom_xdndactionlist, XA_ATOM, &is); + if (method) + { + e->copy = 0; + e->link = 0; + e->move = 0; + if (*method == atom_xdndactioncopy) + e->copy = 1; + else if (*method == atom_xdndactionmove) + e->move = 1; + else if (*method == atom_xdndactionlink) + e->link = 1; + FREE(method); + } + else + { + e->copy = 0; + e->link = 0; + e->move = 0; + } + s = data; + buf = NEW(char, size); + + i = 0; + is = 0; + e->files = NULL; + while ((s[is]) && (is < size)) + { + if ((i == 0) && (s[is] == '#')) + { + for (; ((s[is] != 0) && (s[is] != '\n')); is++); + } + else + { + if (s[is] != '\r') + { + buf[i++] = s[is]; + } + else + { + buf[i] = 0; + e->num_files++; + REALLOC_PTR(e->files, e->num_files); + e->files[e->num_files - 1] = strdup(buf); + buf[0] = 0; + i = 0; + is++; + } + is++; + } + } + if (i > 0) + { + buf[i] = 0; + e->num_files++; + REALLOC_PTR(e->files, e->num_files); + e->files[e->num_files - 1] = strdup(buf); + } + FREE(buf); + FREE(data); + } + ecore_add_event(ECORE_EVENT_DND_DROP_REQUEST, e, + ecore_event_dnd_drop_request_free); + ev_drop_request_pending = NULL; +} + +static void +ecore_event_x_handle_selection_clear(XEvent * xevent) +{ + Ecore_Event_Clear_Selection *e; + + e = NEW(Ecore_Event_Clear_Selection, 1); + e->win = xevent->xselectionclear.window; + e->root = ecore_window_get_root(e->win); + e->selection = xevent->xselectionclear.selection; + ecore_add_event(ECORE_EVENT_CLEAR_SELECTION, e, ecore_event_generic_free); +} + +static void +ecore_event_x_handle_selection_request(XEvent * xevent) +{ + static Atom atom_xdndselection = 0; + static Atom atom_text_plain = 0; + static Atom atom_text_uri_list = 0; + static Atom atom_text_moz_url = 0; + static Atom atom_netscape_url = 0; + static Atom atom_text_selection = 0; + Ecore_Event_Dnd_Data_Request *e; + + ECORE_ATOM(atom_xdndselection, "XdndSelection"); + ECORE_ATOM(atom_text_plain, "text/plain"); + ECORE_ATOM(atom_text_uri_list, "text/uri-list"); + ECORE_ATOM(atom_text_moz_url, "text/x-moz-url"); + ECORE_ATOM(atom_netscape_url, "_NETSCAPE_URL"); + ECORE_ATOM(atom_text_selection, "TEXT_SELECTION"); + if (xevent->xselectionrequest.selection == atom_xdndselection) + { + e = NEW(Ecore_Event_Dnd_Data_Request, 1); + e->win = xevent->xselectionrequest.owner; + e->root = ecore_window_get_root(e->win); + e->source_win = xevent->xselectionrequest.requestor; + e->plain_text =0; + e->uri_list = 0; + e->moz_url = 0; + e->netscape_url = 0; + + if (xevent->xselectionrequest.target == atom_text_plain) e->plain_text = 1; + if (xevent->xselectionrequest.target == atom_text_uri_list) e->uri_list = 1; + if (xevent->xselectionrequest.target == atom_text_moz_url) e->moz_url = 1; + if (xevent->xselectionrequest.target == atom_netscape_url) e->netscape_url = 1; + e->destination_atom = xevent->xselectionrequest.property; + ecore_add_event(ECORE_EVENT_DND_DATA_REQUEST, e, + ecore_event_generic_free); + } + else + { + XEvent ev; + Atom target_list[2]; + static Atom xa_targets = None; + + if (xa_targets == None) + xa_targets = XInternAtom(xevent->xselectionrequest.display, + "TARGETS", False); + ev.xselection.type = SelectionNotify; + ev.xselection.property = None; + ev.xselection.display = xevent->xselectionrequest.display; + ev.xselection.requestor = xevent->xselectionrequest.requestor; + ev.xselection.selection = xevent->xselectionrequest.selection; + ev.xselection.target = xevent->xselectionrequest.target; + ev.xselection.time = xevent->xselectionrequest.time; + if (xevent->xselectionrequest.target == xa_targets) + { + target_list[0] = (Atom) xa_targets; + target_list[1] = (Atom) XA_STRING; + XChangeProperty(xevent->xselectionrequest.display, + xevent->xselectionrequest.requestor, + xevent->xselectionrequest.property, + xevent->xselectionrequest.target, + (8 * sizeof(target_list[0])), + PropModeReplace, + (unsigned char *)target_list, + (sizeof(target_list) / sizeof(target_list[0]))); + ev.xselection.property = xevent->xselectionrequest.property; + } + else if (xevent->xselectionrequest.target == XA_STRING) + { + void *data; + int size; + + data = ecore_window_property_get(xevent->xselectionrequest.owner, + atom_text_selection, XA_STRING, + &size); + if (data) + { + XChangeProperty(xevent->xselectionrequest.display, + xevent->xselectionrequest.requestor, + xevent->xselectionrequest.property, + xevent->xselectionrequest.target, + 8, PropModeReplace, data, size); + FREE(data); + } + ev.xselection.property = xevent->xselectionrequest.property; + } + XSendEvent(xevent->xselectionrequest.display, + xevent->xselectionrequest.requestor, False, 0, &ev); + } +} + +static void +ecore_event_x_handle_client_message(XEvent * xevent) +{ + static Atom atom_wm_delete_window = 0; + static Atom atom_wm_protocols = 0; + static Atom atom_xdndstatus = 0; + static Atom atom_xdndenter = 0; + static Atom atom_xdndleave = 0; + static Atom atom_xdndfinished = 0; + static Atom atom_xdndposition = 0; + static Atom atom_xdnddrop = 0; + static Atom atom_text_uri_list = 0; + static Atom atom_xdndactioncopy = 0; + static Atom atom_xdndactionlink = 0; + static Atom atom_xdndactionmove = 0; + static Atom atom_xdndactionprivate = 0; + + /* setup some known atoms to translate this message into a sensible event */ + ECORE_ATOM(atom_wm_delete_window, "WM_DELETE_WINDOW"); + ECORE_ATOM(atom_wm_protocols, "WM_PROTOCOLS"); + ECORE_ATOM(atom_xdndstatus, "XdndStatus"); + ECORE_ATOM(atom_xdndfinished, "XdndFinished"); + ECORE_ATOM(atom_xdndenter, "XdndEnter"); + ECORE_ATOM(atom_xdndleave, "XdndLeave"); + ECORE_ATOM(atom_xdnddrop, "XdndDrop"); + ECORE_ATOM(atom_xdndposition, "XdndPosition"); + ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy"); + ECORE_ATOM(atom_xdndactionlink, "XdndActionLink"); + ECORE_ATOM(atom_xdndactionmove, "XdndActionMove"); + ECORE_ATOM(atom_xdndactionprivate, "XdndActionPrivate"); + ECORE_ATOM(atom_text_uri_list, "text/uri-list"); + + /* first type = delete event sent to client */ + if ((xevent->xclient.message_type == atom_wm_protocols) && + (xevent->xclient.format == 32) && + (xevent->xclient.data.l[0] == (long)atom_wm_delete_window)) + { + Ecore_Event_Window_Delete *e; + + e = NEW(Ecore_Event_Window_Delete, 1); + e->win = xevent->xclient.window; + e->root = ecore_window_get_root(e->win); + ecore_add_event(ECORE_EVENT_WINDOW_DELETE, e, ecore_event_generic_free); + } + else if ((xevent->xclient.message_type == atom_xdndenter) && + (xevent->xclient.format == 32)) + { +/* if ((xevent->xclient.data.l[2] == (long)atom_text_uri_list) || + * (xevent->xclient.data.l[3] == (long)atom_text_uri_list) || + * (xevent->xclient.data.l[4] == (long)atom_text_uri_list)) + */ { + Ecore_Event_Dnd_Drop_Request *e; + + + if (ev_drop_request_pending) + { + ecore_event_dnd_drop_request_free(ev_drop_request_pending); + ev_drop_request_pending = NULL; + } + e = NEW(Ecore_Event_Dnd_Drop_Request, 1); + e->win = xevent->xclient.window; + e->root = ecore_window_get_root(e->win); + e->source_win = (Window) xevent->xclient.data.l[0]; + if (!ecore_dnd_selection_convert + (e->source_win, e->win, atom_text_uri_list)) + { + FREE(e); + return; + } + e->files = NULL; + e->num_files = 0; + ev_drop_request_pending = e; + } + } + else if ((xevent->xclient.message_type == atom_xdndleave) && + (xevent->xclient.format == 32)) + { + Ecore_Event_Dnd_Drop_End *e; + + e = NEW(Ecore_Event_Dnd_Drop_End, 1); + e->win = xevent->xclient.window; + e->root = ecore_window_get_root(e->win); + e->source_win = (Window) xevent->xclient.data.l[0]; + ecore_add_event(ECORE_EVENT_DND_DROP_END, e, ecore_event_generic_free); + } + else if ((xevent->xclient.message_type == atom_xdndposition) && + (xevent->xclient.format == 32)) + { + Ecore_Event_Dnd_Drop_Position *e; + + e = NEW(Ecore_Event_Dnd_Drop_Position, 1); + e->win = xevent->xclient.window; + e->root = ecore_window_get_root(e->win); + e->source_win = (Window) xevent->xclient.data.l[0]; + e->x = (xevent->xclient.data.l[2] >> 16) & 0xffff; + e->y = xevent->xclient.data.l[2] & 0xffff; + ecore_add_event(ECORE_EVENT_DND_DROP_POSITION, e, + ecore_event_generic_free); + } + else if ((xevent->xclient.message_type == atom_xdndstatus) && + (xevent->xclient.format == 32)) + { + Ecore_Event_Dnd_Drop_Status *e; + + ecore_clear_target_status(); + e = NEW(Ecore_Event_Dnd_Drop_Status, 1); + e->win = xevent->xclient.window; + e->root = ecore_window_get_root(e->win); + e->source_win = (Window) xevent->xclient.data.l[0]; + e->x = (xevent->xclient.data.l[2] >> 16) & 0xffff; + e->y = xevent->xclient.data.l[2] & 0xffff; + e->w = (xevent->xclient.data.l[3] >> 16) & 0xffff; + e->h = xevent->xclient.data.l[3] & 0xffff; + + e->copy = e->link = e->move = e->e_private = 0; + if( xevent->xclient.data.l[4] == atom_xdndactioncopy ) + e->copy = 1; + else if( xevent->xclient.data.l[4] == atom_xdndactionlink ) + e->link = 1; + else if( xevent->xclient.data.l[4] == atom_xdndactionmove ) + e->move = 1; + else if( xevent->xclient.data.l[4] == atom_xdndactionprivate ) + e->e_private = 1; + + if (xevent->xclient.data.l[1] & 0x1) + e->ok = 1; + else + e->ok = 0; + if (xevent->xclient.data.l[1] & 0x2) + e->all_position_msgs = 1; + else + e->all_position_msgs = 0; + ecore_add_event(ECORE_EVENT_DND_DROP_STATUS, e, ecore_event_generic_free); + } + else if ((xevent->xclient.message_type == atom_xdndfinished) && + (xevent->xclient.format == 32)) + { + Ecore_Event_Dnd_Drop_End *e; + + e = NEW(Ecore_Event_Dnd_Drop_End, 1); + e->win = xevent->xclient.window; + e->root = ecore_window_get_root(e->win); + e->source_win = (Window) xevent->xclient.data.l[0]; + ecore_add_event(ECORE_EVENT_DND_DROP_END, e, ecore_event_generic_free); + } + else if ((xevent->xclient.message_type == atom_xdnddrop) && + (xevent->xclient.format == 32)) + { + Ecore_Event_Dnd_Drop *e; + + e = NEW(Ecore_Event_Dnd_Drop, 1); + e->win = xevent->xclient.window; + e->root = ecore_window_get_root(e->win); + e->source_win = (Window) xevent->xclient.data.l[0]; + ecore_add_event(ECORE_EVENT_DND_DROP, e, ecore_event_generic_free); + } + else + { + Ecore_Event_Message *e; + + e = NEW(Ecore_Event_Message, 1); + e->win = xevent->xclient.window; + e->format = xevent->xclient.format; + e->atom = xevent->xclient.message_type; + MEMCPY(xevent->xclient.data.b, e->data.b, char, 20); + + ecore_add_event(ECORE_EVENT_MESSAGE, e, ecore_event_generic_free); + } +} + +static void +ecore_event_x_handle_shape_change(XEvent * xevent) +{ + Ecore_Event_Window_Shape *e; + XShapeEvent *shape_event; + + shape_event = (XShapeEvent *) xevent; + e = NEW(Ecore_Event_Window_Shape, 1); + e->win = shape_event->window; + e->root = ecore_window_get_root(e->win); + e->time = shape_event->time; + ecore_add_event(ECORE_EVENT_WINDOW_SHAPE, e, ecore_event_generic_free); +} + +char * +ecore_keypress_translate_into_typeable(Ecore_Event_Key_Down * e) +{ + /* exceptions */ + if ((!strcmp(e->key, "Delete")) || + (!strcmp(e->key, "BackSpace")) || + (!strcmp(e->key, "Tab")) || + (!strcmp(e->key, "Escape")) || + (!strcmp(e->key, "Return")) || + (!strcmp(e->key, "KP_Enter")) || + (!strcmp(e->key, "Enter")) || + (!strcmp(e->key, "KP_Divide")) || + (!strcmp(e->key, "KP_Multiply")) || + (!strcmp(e->key, "KP_Subtract")) || + (!strcmp(e->key, "KP_Add")) || (!strcmp(e->key, "Enter"))) + return NULL; + return e->compose; +} diff --git a/ecore/src/e_events.c b/ecore/src/e_events.c new file mode 100644 index 0000000..0a8f442 --- /dev/null +++ b/ecore/src/e_events.c @@ -0,0 +1,430 @@ +#include "Ecore.h" +#include +#include +#include +#include +#include + +/* glocal (yes global/local) variabels for events */ +Ecore_Event_Fd_Handler *fd_handlers = NULL; +Ecore_Event_Ipc_Handler *ipc_handlers = NULL; +Ecore_Event_Pid_Handler *pid_handlers = NULL; +Ecore_Event_Timer *timers = NULL; + +Ecore_Event *events = NULL; +Ecore_Event *last_event = NULL; + +int __quit_ev_loop = 0; + +/* local functions for event handling */ +static void ecore_handle_event_timer(void); +static void ecore_handle_zero_event_timer(void); + +/* public functions */ + +/* add an event to the end of the event queue */ +void +ecore_add_event(Ecore_Event_Type type, void *event, + void (*ev_free) (void *event)) +{ + Ecore_Event *ev; + + ev = NEW(Ecore_Event, 1); + ev->type = type; + ev->ignore = 0; + ev->event = event; + ev->next = NULL; + ev->ev_free = ev_free; + if (!events) + events = ev; + else + last_event->next = ev; + last_event = ev; +} + +/* delete an event from the event queue */ +void +ecore_del_event(void *event) +{ + Ecore_Event *ev, *pev; + + pev = NULL; + ev = events; + while (ev) + { + if (ev->event == event) + { + if (pev) + pev->next = ev->next; + else + events = ev->next; + if (!ev->next) + last_event = pev; + if ((ev->event) && (ev->ev_free)) + (*ev->ev_free) (ev->event); + FREE(ev); + return; + } + pev = ev; + ev = ev->next; + } +} + +void +ecore_del_all_events(void) +{ + Ecore_Event *ev, *pev; + + ev = events; + while (ev) + { + pev = ev; + ev = ev->next; + if ((pev->event) && (pev->ev_free)) + pev->ev_free(pev->event); + FREE(pev); + } + events = NULL; + last_event = NULL; +} + +Ecore_Event * +ecore_get_last_event(void) +{ + return last_event; +} + +/* add a callback handler if fd is active for reading */ +void +ecore_add_event_fd(int fd, void (*func) (int fd)) +{ + Ecore_Event_Fd_Handler *fd_h; + + /* new handler struct */ + fd_h = NEW(Ecore_Event_Fd_Handler, 1); + fd_h->next = fd_handlers; + fd_h->fd = fd; + fd_h->func = func; + fd_handlers = fd_h; +} + +/* delete handler for fd */ +void +ecore_del_event_fd(int fd) +{ + START_LIST_DEL(Ecore_Event_Fd_Handler, fd_handlers, (_p->fd == fd)); + FREE(_p); + END_LIST_DEL; +} + +void +ecore_add_event_pid(pid_t pid, void (*func) (pid_t pid)) +{ + Ecore_Event_Pid_Handler *pid_h; + + /* delete the old handler */ + ecore_del_event_pid(pid); + /* new handler struct */ + pid_h = NEW(Ecore_Event_Pid_Handler, 1); + pid_h->next = pid_handlers; + pid_h->pid = pid; + pid_h->func = func; + pid_handlers = pid_h; +} + +void +ecore_del_event_pid(pid_t pid) +{ + START_LIST_DEL(Ecore_Event_Pid_Handler, pid_handlers, (_p->pid == pid)); + FREE(_p); + END_LIST_DEL; +} + +void +ecore_add_event_ipc(int ipc, void (*func) (int ipc)) +{ + Ecore_Event_Ipc_Handler *ipc_h; + + /* delete the old handler */ + ecore_del_event_ipc(ipc); + /* new handler struct */ + ipc_h = NEW(Ecore_Event_Ipc_Handler, 1); + ipc_h->next = ipc_handlers; + ipc_h->ipc = ipc; + ipc_h->func = func; + ipc_handlers = ipc_h; +} + +void +ecore_del_event_ipc(int ipc) +{ + START_LIST_DEL(Ecore_Event_Ipc_Handler, ipc_handlers, (_p->ipc == ipc)); + FREE(_p); + END_LIST_DEL; +} + +/* sit in this loop forever and process events */ +void +ecore_event_loop(void) +{ + int fdcount, fdsize, ipccount, ipcsize; + int timed_out, were_events; + double time1, time2, prev_time = 0.0; + struct timeval tval; + fd_set fdset, ipcset; + Ecore_Event_Fd_Handler *fd_h; + Ecore_Event_Pid_Handler *pid_h; + Ecore_Event_Ipc_Handler *ipc_h; + + /* init some of the time variables */ + time1 = ecore_get_time(); + time2 = time1 - prev_time; + prev_time = time1; + while (__quit_ev_loop == 0) + { + /* state setup */ + timed_out = 0; + were_events = 0; + + /* setup fd array from list of listening fd's */ + fdsize = 0; + FD_ZERO(&fdset); + /* for ever fd handler add the fd to the array and incriment fdsize */ + for (fd_h = fd_handlers; fd_h; fd_h = fd_h->next) + { + FD_SET(fd_h->fd, &fdset); + if (fd_h->fd > fdsize) + fdsize = fd_h->fd; + } + fdcount = 1; + ipcsize = 0; + FD_ZERO(&ipcset); + /* for ever fd handler add the fd to the array and incriment fdsize */ + for (ipc_h = ipc_handlers; ipc_h; ipc_h = ipc_h->next) + { + FD_SET(ipc_h->ipc, &ipcset); + if (ipc_h->ipc > ipcsize) + ipcsize = ipc_h->ipc; + } + ipccount = 1; + /* if there are timers setup adjust timeout value and select */ + if (timers) + { + if (timers->just_added) + { + timers->just_added = 0; + time1 = timers->in; + } + else + { + time1 = timers->in - time2; + if (time1 < 0.0) + time1 = 0.0; + timers->in = time1; + } + tval.tv_sec = (long)time1; + tval.tv_usec = (long)((time1 - ((double)tval.tv_sec)) * 1000000); + if (tval.tv_sec < 0) + tval.tv_sec = 0; + if (tval.tv_usec <= 1000) + tval.tv_usec = 1000; + ecore_handle_zero_event_timer(); + if ((!ecore_events_pending()) && (!ecore_event_signal_events_pending())) + fdcount = select(fdsize + 1, &fdset, NULL, NULL, &tval); + } + /* no timers - just sit and block */ + else + { + if ((!ecore_events_pending()) && (!ecore_event_signal_events_pending())) + fdcount = select(fdsize + 1, &fdset, NULL, NULL, NULL); + } + for (pid_h = pid_handlers; pid_h; pid_h = pid_h->next) + pid_h->func(pid_h->pid); + + /* see if we have any new ipc connections */ + tval.tv_sec = 0; + tval.tv_usec = 0; + ipccount += select(ipcsize + 1, &ipcset, NULL, NULL, &tval); + + /* return < 0 - error or signal interrupt */ + if (fdcount < 0) + { + /* error */ + if ((errno == ENOMEM) || (errno == EINVAL) || (errno == EBADF)) + { + fprintf(stderr, "Lost connection to X display.\n"); + exit(1); + } + } + /* timers are available and its a timeout */ + if ((timers) && (fdcount == 0)) + { + ecore_handle_event_timer(); + timed_out = 1; + } + if (fdcount < 0) + fdcount = 0; + if (ecore_events_pending()) + { + fdcount++; + FD_SET(ecore_x_get_fd(), &fdset); + } + /* fd's are active */ + if (fdcount > 0) + { + /* for every fd handler - if its fd is set - call the func */ + for (fd_h = fd_handlers; fd_h;) + { + Ecore_Event_Fd_Handler *fdh; + + fdh = fd_h; + fd_h = fd_h->next; + if (FD_ISSET(fdh->fd, &fdset)) + fdh->func(fdh->fd); + } + } + + /* ipc clients are active */ + if (ipccount > 0) + { + for (ipc_h = ipc_handlers; ipc_h;) + { + Ecore_Event_Ipc_Handler *ipch; + + ipch = ipc_h; + ipc_h = ipc_h->next; + if (FD_ISSET(ipch->ipc, &ipcset)) + ipch->func(ipch->ipc); + } + } + if (events) + ecore_event_filter(events); + if (events) + { + ecore_event_filter_events_handle(events); + were_events = 1; + } + ecore_del_all_events(); + if ((timed_out) || (were_events)) + ecore_event_filter_idle_handle(); + ecore_flush(); + time1 = ecore_get_time(); + time2 = time1 - prev_time; + prev_time = time1; + } + __quit_ev_loop = 0; +} + +/* set a flag to 0 so that we can quit the event loop and shutdown + * properly */ +void +ecore_event_loop_quit(void) +{ + __quit_ev_loop = 1; +} + +/* add a timeout funcitont o be called in "in" seconds with name name */ +void +ecore_add_event_timer(char *name, double in, void (*func) (int val, void *data), + int val, void *data) +{ + Ecore_Event_Timer *timer, *ptr, *pptr; + double tally; + + if (name) + ecore_del_event_timer(name); + timer = NEW(Ecore_Event_Timer, 1); + timer->next = NULL; + timer->func = func; + timer->data = data; + timer->val = val; + timer->just_added = 1; + timer->in = in; + timer->name = strdup(name); + if (!timers) + timers = timer; + else + { + pptr = NULL; + ptr = timers; + tally = 0.0; + while (ptr) + { + tally += ptr->in; + if (tally > in) + { + tally -= ptr->in; + timer->next = ptr; + if (pptr) + pptr->next = timer; + else + timers = timer; + timer->in -= tally; + if (timer->next) + timer->next->in -= timer->in; + return; + } + pptr = ptr; + ptr = ptr->next; + } + if (pptr) + pptr->next = timer; + else + timers = timer; + timer->in -= tally; + } +} + +/* delete a timer timeout entry named "name" */ +void * +ecore_del_event_timer(char *name) +{ + Ecore_Event_Timer *timer, *ptr, *pptr; + + pptr = NULL; + ptr = timers; + while (ptr) + { + timer = ptr; + if (!strcmp(timer->name, name)) + { + void *data; + + if (pptr) + pptr->next = timer->next; + else + timers = timer->next; + if (timer->next) + timer->next->in += timer->in; + IF_FREE(timer->name); + data = timer->data; + FREE(timer); + return data; + } + pptr = ptr; + ptr = ptr->next; + } + return NULL; +} + +/* private functions */ +static void +ecore_handle_event_timer(void) +{ + Ecore_Event_Timer *timer; + + if (!timers) + return; + timer = timers; + timers = timer->next; + (*(timer->func)) (timer->val, timer->data); + IF_FREE(timer->name); + FREE(timer); +} + +static void +ecore_handle_zero_event_timer(void) +{ + while ((timers) && (timers->in == 0.0)) + ecore_handle_event_timer(); +} diff --git a/ecore/src/e_ipc.c b/ecore/src/e_ipc.c new file mode 100644 index 0000000..2a6de2b --- /dev/null +++ b/ecore/src/e_ipc.c @@ -0,0 +1,187 @@ +#include "Ecore.h" +#include +#include +#include +#include +#include + +void ecore_ipc_init(char *path); +void ecore_ipc_cleanup(void); +static void ecore_ipc_connect_handler(int fd); +static void ecore_ipc_client_handler(int fd); +void ecore_ipc_get_data(int fd, void *buf); +void ecore_ipc_send_data(int fd, void *buf, int size); +void ecore_add_ipc_service(int service, void (*func) (int fd)); +void ecore_del_ipc_service(int service); + +Ecore_Event_Ipc_Service *ipc_services = NULL; + +void +ecore_ev_ipc_init(char *path) +{ + int fd, len; + struct sockaddr_un saun; + + if (path == NULL) + return; + + /* a UNIX domain, stream socket */ + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + { + printf("Cannot create ipc socket... disabling ipc.\n"); + return; + } + + /* create the address we will be binding to */ + saun.sun_family = AF_UNIX; + strcpy(saun.sun_path, path); + + /* unlink the address so the bind won't fail */ + unlink(path); + len = sizeof(saun.sun_family) + strlen(saun.sun_path); + + if (bind(fd, (struct sockaddr *)&saun, len) < 0) + { + printf("Cannot bind ipc socket... disabling ipc.\n"); + return; + } + + /* listen on the socket */ + if (listen(fd, 5) < 0) + { + printf("Cannot listen on ipc socket... disabling ipc.\n"); + return; + } + + /* add ipc listener */ + ecore_add_event_ipc(fd, ecore_ipc_connect_handler); +} + +void +ecore_ev_ipc_cleanup(void) +{ + Ecore_Event_Ipc_Service *ipc_s; + + /* cleanup services list */ + for (ipc_s = ipc_services; ipc_s; ipc_s = ipc_s->next) + { + ecore_del_ipc_service(ipc_s->service); + } +} + +static void +ecore_ipc_connect_handler(int fd) +{ + struct sockaddr_un fsaun; + int fromlen, nfd; + + /* accept ipc connection */ + fromlen = sizeof(fsaun); + + if ((nfd = accept(fd, (struct sockaddr *)&fsaun, &fromlen)) < 0) + { + printf("Cannot accept ipc connection... ignoring connection attempt.\n"); + return; + } + + /* add ipc client */ + ecore_add_event_ipc(nfd, ecore_ipc_client_handler); +} + +static void +ecore_ipc_client_handler(int fd) +{ + int nread, service; + Ecore_Event_Ipc_Service *ipc_s; + + if ((nread = read(fd, &service, sizeof(service))) == 0) + { + close(fd); + ecore_del_event_ipc(fd); + } + else if (nread > 0) + { + /* call the service function */ + for (ipc_s = ipc_services; ipc_s; ipc_s = ipc_s->next) + { + if (ipc_s->service == service) + { + ipc_s->func(fd); + break; + } + } + } + else + { + printf("ipc error in read service.\n"); + fflush(stdout); + } +} + +void +ecore_ipc_get_data(int fd, void *buf) +{ + int readn, nread; + + /* read number of bytes being sent */ + if ((nread = read(fd, &readn, sizeof(readn))) == -1) + { + printf("ipc error in get data.\n"); + fflush(stdout); + return; + } + + /* get data structure */ + if ((nread = read(fd, buf, readn)) == -1) + { + printf("ipc error in get data.\n"); + fflush(stdout); + return; + } +} + +void +ecore_ipc_send_data(int fd, void *buf, int size) +{ + int n; + + /* send length of data being sent */ + if ((n = write(fd, &size, sizeof(size))) == -1) + { + printf("ipc error in send data length.\n"); + fflush(stdout); + return; + } + + /* send data */ + if ((n = write(fd, buf, size)) == -1) + { + printf("ipc error in send data.\n"); + fflush(stdout); + return; + } +} + +void +ecore_add_ipc_service(int service, void (*func) (int fd)) +{ + Ecore_Event_Ipc_Service *ipc_s; + + /* delete the old service */ + ecore_del_ipc_service(service); + /* new service struct */ + ipc_s = NEW(Ecore_Event_Ipc_Service, 1); + ipc_s->next = ipc_services; + ipc_s->service = service; + ipc_s->func = func; + ipc_services = ipc_s; +} + +void +ecore_del_ipc_service(int service) +{ + START_LIST_DEL(Ecore_Event_Ipc_Service, ipc_services, + (_p->service == service)); + FREE(_p); + END_LIST_DEL; +} diff --git a/ecore/src/e_util.c b/ecore/src/e_util.c new file mode 100644 index 0000000..fc4a2ae --- /dev/null +++ b/ecore/src/e_util.c @@ -0,0 +1,10 @@ +#include "Ecore.h" + +double +ecore_get_time(void) +{ + struct timeval timev; + + gettimeofday(&timev, NULL); + return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000); +} diff --git a/ecore/src/e_x.c b/ecore/src/e_x.c new file mode 100644 index 0000000..b3d8069 --- /dev/null +++ b/ecore/src/e_x.c @@ -0,0 +1,3610 @@ +#include "Ecore.h" +#include +#include +#include +#include + +#ifdef XA_CLIPBOARD +#define X_CLIPBOARD_SELECTION XA_CLIPBOARD(disp) +#define X_CLIPBOARD_PROP XA_CLIPBOARD(disp) +#else +#define X_CLIPBOARD_SELECTION XA_PRIMARY +#define X_CLIPBOARD_PROP XA_CUT_BUFFER0 +#endif + +typedef struct _window_list Window_List; + +struct _window_list +{ + Window win; + Window_List *next; +}; + +XContext xid_context = 0; + +static Display *disp; +static Visual *default_vis; +static Colormap default_cm; +static int default_depth; +static Window default_win; +static Window default_root; + +static int lock_scroll = 0; +static int lock_num = 0; +static int lock_caps = 0; + +static Window focused_win = 0; + +static int mod_shift = 0; +static int mod_ctrl = 0; +static int mod_alt = 0; +static int mod_win = 0; + +static Window grabkey_win = 0; + +static int mouse_x = 0, mouse_y = 0; + +static Window current_dnd_win = 0; +static int current_dnd_target_ok = 0; +static int dnd_await_target_status = 0; + +static int x_grabs = 0; + +static Window_List *ignore_wins = NULL; + +static Window grab_pointer_win = 0; + +static Window keyboard_grab_win = 0; + +static int dnd_copy = 0; +static int dnd_link = 0; +static int dnd_move = 1; + +static void ecore_handle_x_error(Display * d, XErrorEvent * ev); +static void ecore_handle_x_io_error(Display * d); +static Window ecore_window_at_xy_0(Window base, int bx, int by, int x, + int y); + +static void +ecore_handle_x_error(Display * d, XErrorEvent * ev) +{ +/* + char err[16384]; + + XGetErrorText(d, ev->error_code, err, 16000); + printf("X Error:\n" + "Error: %s\nrequest: %i\nminor: %i\n", err, ev->request_code, ev->minor_code); + */ + /* ignore all X errors */ + return; + d = NULL; + ev = NULL; +} + +static void +ecore_handle_x_io_error(Display * d) +{ + /* FIXME: call clean exit handler */ + exit(1); + d = NULL; +} + +void +ecore_del_child(Window win, Window child) +{ + Ecore_XID *xid = NULL; + + if (!disp) + return; + if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT) + return; + if (xid) + { + int i; + + for (i = 0; i < xid->children_num; i++) + { + if (xid->children[i] == child) + { + int j; + + for (j = i; j < xid->children_num - 1; j++) + xid->children[j] = xid->children[j + 1]; + xid->children_num--; + REALLOC(xid->children, Window, xid->children_num); + return; + } + } + } +} + +void +ecore_add_child(Window win, Window child) +{ + Ecore_XID *xid = NULL; + + if (!disp) + return; + if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT) + return; + if (xid) + { + int i; + + for (i = 0; i < xid->children_num; i++) + { + if (xid->children[i] == child) + return; + } + xid->children_num++; + REALLOC(xid->children, Window, xid->children_num); + xid->children[xid->children_num - 1] = child; + } + xid = ecore_validate_xid(child); +} + +void +ecore_raise_child(Window win, Window child) +{ + Ecore_XID *xid = NULL; + + if (!disp) + return; + if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT) + return; + if (xid) + { + int i; + + for (i = 0; i < xid->children_num; i++) + { + if (xid->children[i] == child) + { + int j; + + for (j = i; j < xid->children_num - 1; j++) + xid->children[j] = xid->children[j + 1]; + xid->children[xid->children_num - 1] = child; + return; + } + } + } +} + +void +ecore_lower_child(Window win, Window child) +{ + Ecore_XID *xid = NULL; + + if (!disp) + return; + if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT) + return; + if (xid) + { + int i; + + for (i = 0; i < xid->children_num; i++) + { + if (xid->children[i] == child) + { + int j; + + for (j = i; j > 0; j--) + xid->children[j] = xid->children[j - 1]; + xid->children[0] = child; + return; + } + } + } +} + +Ecore_XID * +ecore_add_xid(Window win, int x, int y, int w, int h, int depth, Window parent) +{ + Ecore_XID *xid = NULL; + + ecore_window_add_events(win, XEV_IN_OUT | XEV_CONFIGURE | XEV_VISIBILITY); + xid = NEW(Ecore_XID, 1); + xid->win = win; + xid->x = x; + xid->y = y; + xid->w = w; + xid->h = h; + xid->mapped = 0; + xid->depth = depth; + xid->mouse_in = 0; + xid->parent = parent; + xid->root = ecore_window_get_root(parent); + xid->children_num = 0; + xid->children = NULL; + xid->gravity = ecore_window_get_gravity(win); + xid->coords_invalid = 0; + xid->bw = 0; + xid->grab_button_auto_replay = NULL; + XSaveContext(disp, xid->win, xid_context, (XPointer) xid); + ecore_add_child(parent, win); + return xid; +} + +Ecore_XID * +ecore_validate_xid(Window win) +{ + Ecore_XID *xid = NULL; + + if (!disp) + return NULL; + if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT) + { + XWindowAttributes att; + Window root_ret = 0, parent_ret = 0, *children_ret = NULL; + unsigned int children_ret_num = 0; + + ecore_window_add_events(win, XEV_IN_OUT | XEV_CONFIGURE | + XEV_VISIBILITY | XEV_CHILD_CHANGE); + xid = NEW(Ecore_XID, 1); + xid->win = win; + if (!XGetWindowAttributes(disp, win, &att)) + { + FREE(xid); + return NULL; + } + if (!XQueryTree(disp, win, &root_ret, &parent_ret, &children_ret, + &children_ret_num)) + { + FREE(xid); + return NULL; + } + xid->parent = parent_ret; + if (xid->parent) + ecore_validate_xid(xid->parent); + if (children_ret) + { + xid->children_num = children_ret_num; + xid->children = NEW(Window, children_ret_num); + MEMCPY(children_ret, xid->children, Window, children_ret_num); + XFree(children_ret); + } + else + { + xid->children_num = 0; + xid->children = NULL; + } + xid->root = root_ret; + xid->x = att.x; + xid->y = att.y; + xid->w = att.width; + xid->h = att.height; + if (att.map_state == IsUnmapped) + xid->mapped = 0; + else + xid->mapped = 1; + xid->depth = att.depth; + xid->mouse_in = 0; + xid->gravity = att.win_gravity; + xid->bw = att.border_width; + xid->coords_invalid = 0; + xid->grab_button_auto_replay = NULL; + XSaveContext(disp, xid->win, xid_context, (XPointer) xid); + ecore_add_child(xid->parent, win); + } + return xid; +} + +void +ecore_unvalidate_xid(Window win) +{ + Ecore_XID *xid = NULL; + + if (!disp) + return; + if (XFindContext(disp, win, xid_context, (XPointer *) & xid) == XCNOENT) + return; + if (xid) + { + int i; + + for (i = 0; i < xid->children_num; i++) + ecore_unvalidate_xid(xid->children[i]); + ecore_del_child(xid->parent, win); + IF_FREE(xid->children); + FREE(xid); + XDeleteContext(disp, win, xid_context); + } +} + +void +ecore_sync(void) +{ + if (!disp) + return; + + XSync(disp, False); +} + +void +ecore_flush(void) +{ + if (!disp) + return; + XFlush(disp); +} + +Window +ecore_window_new(Window parent, int x, int y, int w, int h) +{ + Window win; + XSetWindowAttributes attr; + + if (!disp) + return 0; + if (!parent) + parent = default_root; + attr.backing_store = NotUseful; + attr.override_redirect = False; + attr.colormap = default_cm; + attr.border_pixel = 0; + attr.background_pixmap = None; + attr.save_under = False; + attr.do_not_propagate_mask = True; + win = XCreateWindow(disp, parent, + x, y, w, h, 0, + default_depth, InputOutput, default_vis, + CWOverrideRedirect | CWSaveUnder | CWBackingStore | + CWColormap | CWBackPixmap | CWBorderPixel | + CWDontPropagate, &attr); + ecore_add_xid(win, x, y, w, h, default_depth, parent); + ecore_add_child(parent, win); + ecore_validate_xid(parent); + return win; +} + +Window +ecore_window_override_new(Window parent, int x, int y, int w, int h) +{ + Window win; + XSetWindowAttributes attr; + + if (!disp) + return 0; + if (!parent) + parent = default_root; + attr.backing_store = NotUseful; + attr.override_redirect = True; + attr.colormap = default_cm; + attr.border_pixel = 0; + attr.background_pixmap = None; + attr.save_under = False; + attr.do_not_propagate_mask = True; + win = XCreateWindow(disp, parent, + x, y, w, h, 0, + default_depth, InputOutput, default_vis, + CWOverrideRedirect | CWSaveUnder | CWBackingStore | + CWColormap | CWBackPixmap | CWBorderPixel | + CWDontPropagate, &attr); + ecore_add_xid(win, x, y, w, h, default_depth, parent); + ecore_add_child(parent, win); + ecore_validate_xid(parent); + return win; +} + +Window +ecore_window_input_new(Window parent, int x, int y, int w, int h) +{ + Window win; + XSetWindowAttributes attr; + + if (!disp) + return 0; + if (!parent) + parent = default_root; + attr.override_redirect = True; + attr.do_not_propagate_mask = True; + win = XCreateWindow(disp, parent, + x, y, w, h, 0, + 0, InputOnly, default_vis, + CWOverrideRedirect | CWDontPropagate, &attr); + ecore_add_xid(win, x, y, w, h, 0, parent); + ecore_add_child(parent, win); + ecore_validate_xid(parent); + return win; +} + +void +ecore_window_set_events_propagate(Window win, int propagate) +{ + XSetWindowAttributes attr; + + if (!disp) + return; + if (!win) + win = default_root; + if (!propagate) + attr.do_not_propagate_mask = True; + else + attr.do_not_propagate_mask = False; + XChangeWindowAttributes(disp, win, CWDontPropagate, &attr); +} + +void +ecore_window_show(Window win) +{ + Ecore_XID *xid = NULL; + + if (!disp) + return; + xid = ecore_validate_xid(win); + if (xid) + { + if (xid->mapped) + return; + xid->mapped = 1; + XMapWindow(disp, win); + } +} + +void +ecore_window_hide(Window win) +{ + Ecore_XID *xid = NULL; + + if (!disp) + return; + xid = ecore_validate_xid(win); + if (xid) + { + if (!xid->mapped) + return; + xid->mapped = 0; + XUnmapWindow(disp, win); + } +} + +Pixmap +ecore_pixmap_new(Window win, int w, int h, int dep) +{ + if (!disp) + return 0; + if (!win) + win = default_win; + if (dep == 0) + dep = default_depth; + return XCreatePixmap(disp, win, w, h, dep); +} + +void +ecore_pixmap_free(Pixmap pmap) +{ + if (!disp) + return; + if (!pmap) + return; + XFreePixmap(disp, pmap); +} + +void +ecore_window_set_background_pixmap(Window win, Pixmap pmap) +{ + if (!disp) + return; + if (win == 0) + win = default_root; + XSetWindowBackgroundPixmap(disp, win, pmap); +} + +void +ecore_window_set_shape_mask(Window win, Pixmap mask) +{ + if (!disp) + return; + XShapeCombineMask(disp, win, ShapeBounding, 0, 0, mask, ShapeSet); +} + +void +ecore_window_add_shape_mask(Window win, Pixmap mask) +{ + if (!disp) + return; + XShapeCombineMask(disp, win, ShapeBounding, 0, 0, mask, ShapeUnion); +} + +void +ecore_window_set_shape_window(Window win, Window src, int x, int y) +{ + if (!disp) + return; + XShapeCombineShape(disp, win, ShapeBounding, x, y, src, ShapeBounding, + ShapeSet); +} + +void +ecore_window_add_shape_window(Window win, Window src, int x, int y) +{ + if (!disp) + return; + XShapeCombineShape(disp, win, ShapeBounding, x, y, src, ShapeBounding, + ShapeUnion); +} + +void +ecore_window_set_shape_rectangle(Window win, int x, int y, int w, int h) +{ + XRectangle rect; + + if (!disp) + return; + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeSet, + Unsorted); +} + +void +ecore_window_add_shape_rectangle(Window win, int x, int y, int w, int h) +{ + XRectangle rect; + + if (!disp) + return; + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeUnion, + Unsorted); +} + +void +ecore_window_set_shape_rectangles(Window win, XRectangle * rect, int num) +{ + if (!disp) + return; + XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, rect, num, ShapeSet, + Unsorted); +} + +void +ecore_window_add_shape_rectangles(Window win, XRectangle * rect, int num) +{ + if (!disp) + return; + XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, rect, num, ShapeUnion, + Unsorted); +} + +void +ecore_window_clip_shape_by_rectangle(Window win, int x, int y, int w, int h) +{ + XRectangle rect; + + if (!disp) + return; + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, &rect, 1, + ShapeIntersect, Unsorted); +} + +XRectangle * +ecore_window_get_shape_rectangles(Window win, int *num) +{ + int ord; + + if (!disp) + return NULL; + return XShapeGetRectangles(disp, win, ShapeBounding, num, &ord); +} + +void +ecore_window_select_shape_events(Window win) +{ + if (!disp) + return; + + XShapeSelectInput(disp, win, ShapeNotifyMask); +} + +void +ecore_window_unselect_shape_events(Window win) +{ + if (!disp) + return; + + XShapeSelectInput(disp, win, 0); +} + +void +ecore_window_clear(Window win) +{ + if (!disp) + return; + if (win == 0) + win = default_root; + XClearWindow(disp, win); +} + +void +ecore_window_clear_area(Window win, int x, int y, int w, int h) +{ + if (!disp) + return; + if (win == 0) + win = default_root; + XClearArea(disp, win, x, y, w, h, False); +} + +void +ecore_pointer_xy(Window win, int *x, int *y) +{ + Window dw; + unsigned int dm; + int wx, wy; + + if (!disp) + return; + + if (win == 0) + win = default_root; + + XQueryPointer(disp, win, &dw, &dw, &mouse_x, &mouse_y, &wx, &wy, &dm); + + if (x) + *x = wx; + if (y) + *y = wy; +} + +void +ecore_pointer_xy_set(int x, int y) +{ + if (!disp) return; + mouse_x = x; + mouse_y = y; +} + +void +ecore_pointer_xy_get(int *x, int *y) +{ + if (!disp) return; + if (x) + *x = mouse_x; + if (y) + *y = mouse_y; +} + +void +ecore_window_set_events(Window win, long mask) +{ + if (!disp) return; + if (win == 0) + win = default_root; + XSelectInput(disp, win, mask); +} + +void +ecore_window_remove_events(Window win, long mask) +{ + XWindowAttributes att; + + if (!disp) return; + if (win == 0) + win = default_root; + if (XGetWindowAttributes(disp, win, &att) == True) + { + mask = att.your_event_mask & (~mask); + ecore_window_set_events(win, mask); + } +} + +void +ecore_window_add_events(Window win, long mask) +{ + XWindowAttributes att; + + if (!disp) return; + if (win == 0) + win = default_root; + if (XGetWindowAttributes(disp, win, &att) == True) + { + mask = att.your_event_mask | mask; + ecore_window_set_events(win, mask); + } +} + +void +ecore_window_move(Window win, int x, int y) +{ + Ecore_XID *xid = NULL; + + if (!disp) return; + xid = ecore_validate_xid(win); + if (xid) + { + if (!xid->coords_invalid) + { + if ((xid->x == x) && (xid->y == y)) + return; + } + xid->x = x; + xid->y = y; + xid->coords_invalid = 0; + XMoveWindow(disp, win, x, y); + } +} + +#define REGRAVITATE \ +if (xid->children) \ +{ \ + int j; \ +\ + for (j = 0; j < xid->children_num; j++) \ + { \ + Ecore_XID *xid2; \ +\ + xid2 = ecore_validate_xid(xid->children[j]); \ + if (xid2) \ + { \ + xid2->coords_invalid = 1; \ + } \ + } \ +} + +#if 0 +switch (xid2->gravity) + { + case UnmapGravity: + xid2->mapped = 0; + break; + case NorthWestGravity: + break; + case NorthGravity: + xid2->x += (w - xid->w) / 2; + break; + case NorthEastGravity: + xid2->x += (w - xid->w); + break; + case WestGravity: + xid2->h += (h - xid->h) / 2; + break; + case CenterGravity: + xid2->x += (w - xid->w) / 2; + xid2->h += (h - xid->h) / 2; + break; + case EastGravity: + xid2->x += (w - xid->w); + break; + case SouthWestGravity: + xid2->y += (h - xid->h); + break; + case SouthGravity: + xid2->x += (w - xid->w) / 2; + xid2->y += (h - xid->h); + break; + case SouthEastGravity: + xid2->x += (w - xid->w); + xid2->y += (h - xid->h); + break; + case StaticGravity: + xid2->coords_invalid = 1; + break; + default: + break; + } +} +} +} +#endif + +void +ecore_window_resize(Window win, int w, int h) +{ + Ecore_XID *xid = NULL; + + if (!disp) return; + xid = ecore_validate_xid(win); + if (xid) + { + if (!xid->coords_invalid) + { + if ((xid->w == w) && (xid->h == h)) + return; + } + REGRAVITATE; + xid->w = w; + xid->h = h; + xid->coords_invalid = 0; + XResizeWindow(disp, win, w, h); + } +} + +void +ecore_window_move_resize(Window win, int x, int y, int w, int h) +{ + Ecore_XID *xid = NULL; + + if (!disp) return; + xid = ecore_validate_xid(win); + if (xid) + { + if (!xid->coords_invalid) + { + if ((xid->x == x) && (xid->y == y) && (xid->w == w) && (xid->h == h)) + return; + } + REGRAVITATE; + xid->x = x; + xid->y = y; + xid->w = w; + xid->h = h; + xid->coords_invalid = 0; + XMoveResizeWindow(disp, win, x, y, w, h); + } +} + +int +ecore_x_get_fd(void) +{ + if (!disp) return 0; + return ConnectionNumber(disp); +} + +void +ecore_set_error_handler(Ecore_Error_Function func) +{ + if (!disp) return; + XSetErrorHandler((XErrorHandler) func); +} + +void +ecore_reset_error_handler(void) +{ + if (!disp) return; + XSetErrorHandler((XErrorHandler) ecore_handle_x_error); +} + +int +ecore_display_init(char *display) +{ + int revert; + + xid_context = XUniqueContext(); + disp = XOpenDisplay(display); + if (!disp) + { + char *d; + + d = getenv("DISPLAY"); +/* no need for this anymore + if (d) + fprintf(stderr, + "Fatal Error:\n" + "Cannot connect to the display nominated by your DISPLAY variable:\n" + "%s\n" + "Try changing your DISPLAY variable like:\n" + "DISPLAY=host:0 application_name\n", d); + else + fprintf(stderr, + "Fatal Error:\n" + "No DISPLAY variable set so cannot determine display to connect to.\n" + "Try setting your DISPLAY variable like:\n" + "DISPLAY=host:0 appication_name\n"); +*/ + return 0; + } + XSetErrorHandler((XErrorHandler) ecore_handle_x_error); + XSetIOErrorHandler((XIOErrorHandler) ecore_handle_x_io_error); + default_vis = DefaultVisual(disp, DefaultScreen(disp)); + default_depth = DefaultDepth(disp, DefaultScreen(disp)); + default_cm = DefaultColormap(disp, DefaultScreen(disp)); + default_win = DefaultRootWindow(disp); + default_root = DefaultRootWindow(disp); + mod_shift = ecore_mod_mask_shift_get(); + mod_ctrl = ecore_mod_mask_ctrl_get(); + mod_alt = ecore_mod_mask_alt_get(); + mod_win = ecore_mod_mask_win_get(); + XGetInputFocus(disp, &focused_win, &revert); + ecore_window_set_events(default_root, XEV_KEY | XEV_IN_OUT | XEV_MOUSE_MOVE | + XEV_CONFIGURE | XEV_CHILD_CHANGE | XEV_PROPERTY | + XEV_COLORMAP | XEV_VISIBILITY); + ecore_pointer_xy(0, NULL, NULL); + return 1; +} + +int +ecore_events_pending(void) +{ + if (!disp) return 0; + return XPending(disp); +} + +void +ecore_get_next_event(XEvent * event) +{ + if (!disp) return; + XNextEvent(disp, event); +} + +int +ecore_event_shape_get_id(void) +{ + int base = -1, err_base; + + if (!disp) return 0; + XShapeQueryExtension(disp, &base, &err_base); + base += ShapeNotify; + return base; +} + +KeySym +ecore_key_get_keysym_from_keycode(KeyCode keycode) +{ + if (!disp) return 0; + return XKeycodeToKeysym(disp, keycode, 0); +} + +char * +ecore_key_get_string_from_keycode(KeyCode keycode) +{ + char *str; + + if (!disp) return strdup(""); + str = XKeysymToString(ecore_key_get_keysym_from_keycode(keycode)); + if (!str) + return strdup(""); + return strdup(str); +} + +void +ecore_event_allow(int mode, Time t) +{ + if (!disp) return; + XAllowEvents(disp, mode, t); +} + +int +ecore_lock_mask_scroll_get(void) +{ + static int have_mask = 0; + static int mask = 0; + XModifierKeymap *mod; + KeyCode nl; + int i; + int masks[8] = { + ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, + Mod4Mask, Mod5Mask + }; + + if (!disp) return 0; + if (have_mask) + return mask; + mod = XGetModifierMapping(disp); + nl = XKeysymToKeycode(disp, XK_Scroll_Lock); + if ((mod) && (mod->max_keypermod > 0)) + { + for (i = 0; i < (8 * mod->max_keypermod); i++) + { + if ((nl) && (mod->modifiermap[i] == nl)) + { + mask = masks[i / mod->max_keypermod]; + if (mod->modifiermap) + XFree(mod->modifiermap); + XFree(mod); + have_mask = 1; + return mask; + } + } + } + if (mod) + { + if (mod->modifiermap) + XFree(mod->modifiermap); + XFree(mod); + } + return 0; +} + +int +ecore_lock_mask_num_get(void) +{ + static int have_mask = 0; + static int mask = 0; + XModifierKeymap *mod; + KeyCode nl; + int i; + int masks[8] = { + ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, + Mod4Mask, Mod5Mask + }; + + if (!disp) return 0; + if (have_mask) + return mask; + mod = XGetModifierMapping(disp); + nl = XKeysymToKeycode(disp, XK_Num_Lock); + if ((mod) && (mod->max_keypermod > 0)) + { + for (i = 0; i < (8 * mod->max_keypermod); i++) + { + if ((nl) && (mod->modifiermap[i] == nl)) + { + mask = masks[i / mod->max_keypermod]; + if (mod->modifiermap) + XFree(mod->modifiermap); + XFree(mod); + have_mask = 1; + return mask; + } + } + } + if (mod) + { + if (mod->modifiermap) + XFree(mod->modifiermap); + XFree(mod); + } + return 0; +} + +int +ecore_lock_mask_caps_get(void) +{ + static int have_mask = 0; + static int mask = 0; + XModifierKeymap *mod; + KeyCode nl; + int i; + int masks[8] = { + ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, + Mod4Mask, Mod5Mask + }; + + if (!disp) return 0; + if (have_mask) + return mask; + mod = XGetModifierMapping(disp); + nl = XKeysymToKeycode(disp, XK_Caps_Lock); + if ((mod) && (mod->max_keypermod > 0)) + { + for (i = 0; i < (8 * mod->max_keypermod); i++) + { + if ((nl) && (mod->modifiermap[i] == nl)) + { + mask = masks[i / mod->max_keypermod]; + if (mod->modifiermap) + XFree(mod->modifiermap); + XFree(mod); + have_mask = 1; + return mask; + } + } + } + if (mod) + { + if (mod->modifiermap) + XFree(mod->modifiermap); + XFree(mod); + } + return 0; +} + +int +ecore_mod_mask_shift_get(void) +{ + static int have_mask = 0; + static int mask = 0; + XModifierKeymap *mod; + KeyCode nl; + int i; + int masks[8] = { + ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, + Mod4Mask, Mod5Mask + }; + + if (!disp) return 0; + if (have_mask) + return mask; + mod = XGetModifierMapping(disp); + nl = XKeysymToKeycode(disp, XK_Shift_L); + if ((mod) && (mod->max_keypermod > 0)) + { + for (i = 0; i < (8 * mod->max_keypermod); i++) + { + if ((nl) && (mod->modifiermap[i] == nl)) + { + mask = masks[i / mod->max_keypermod]; + if (mod->modifiermap) + XFree(mod->modifiermap); + XFree(mod); + have_mask = 1; + return mask; + } + } + } + if (mod) + { + if (mod->modifiermap) + XFree(mod->modifiermap); + XFree(mod); + } + return 0; +} + +int +ecore_mod_mask_ctrl_get(void) +{ + static int have_mask = 0; + static int mask = 0; + XModifierKeymap *mod; + KeyCode nl; + int i; + int masks[8] = { + ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, + Mod4Mask, Mod5Mask + }; + + if (!disp) return 0; + if (have_mask) + return mask; + mod = XGetModifierMapping(disp); + nl = XKeysymToKeycode(disp, XK_Control_L); + if ((mod) && (mod->max_keypermod > 0)) + { + for (i = 0; i < (8 * mod->max_keypermod); i++) + { + if ((nl) && (mod->modifiermap[i] == nl)) + { + mask = masks[i / mod->max_keypermod]; + if (mod->modifiermap) + XFree(mod->modifiermap); + XFree(mod); + have_mask = 1; + return mask; + } + } + } + if (mod) + { + if (mod->modifiermap) + XFree(mod->modifiermap); + XFree(mod); + } + return 0; +} + +int +ecore_mod_mask_alt_get(void) +{ + static int have_mask = 0; + static int mask = 0; + XModifierKeymap *mod; + KeyCode nl; + int i; + int masks[8] = { + ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, + Mod4Mask, Mod5Mask + }; + + if (!disp) return 0; + if (have_mask) + return mask; + mod = XGetModifierMapping(disp); + nl = XKeysymToKeycode(disp, XK_Alt_L); + if ((mod) && (mod->max_keypermod > 0)) + { + for (i = 0; i < (8 * mod->max_keypermod); i++) + { + if ((nl) && (mod->modifiermap[i] == nl)) + { + mask = masks[i / mod->max_keypermod]; + if (mod->modifiermap) + XFree(mod->modifiermap); + XFree(mod); + have_mask = 1; + return mask; + } + } + } + if (mod) + { + if (mod->modifiermap) + XFree(mod->modifiermap); + XFree(mod); + } + return 0; +} + +int +ecore_mod_mask_win_get(void) +{ + static int have_mask = 0; + static int mask = 0; + XModifierKeymap *mod; + KeyCode nl; + int i; + int masks[8] = { + ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, + Mod4Mask, Mod5Mask + }; + + if (!disp) return 0; + if (have_mask) + return mask; + mod = XGetModifierMapping(disp); + nl = XKeysymToKeycode(disp, XK_Meta_L); + if ((mod) && (mod->max_keypermod > 0)) + { + for (i = 0; i < (8 * mod->max_keypermod); i++) + { + if ((nl) && (mod->modifiermap[i] == nl)) + { + mask = masks[i / mod->max_keypermod]; + if (mod->modifiermap) + XFree(mod->modifiermap); + XFree(mod); + if (mask == ecore_mod_mask_alt_get()) + mask = 0; + if (mask == ecore_mod_mask_ctrl_get()) + mask = 0; + have_mask = 1; + return mask; + } + } + } + if (mod) + { + if (mod->modifiermap) + XFree(mod->modifiermap); + XFree(mod); + } + return 0; +} + +int +ecore_lock_mask_get(void) +{ + static int mask = 0; + Window root_ret, child_ret; + int root_x_ret, root_y_ret, win_x_ret, win_y_ret; + unsigned int mask_ret; + + if (!disp) return 0; + if (!mask) + mask = ecore_lock_mask_scroll_get() | ecore_lock_mask_num_get() | + ecore_lock_mask_caps_get(); + XQueryPointer(disp, default_root, &root_ret, &child_ret, &root_x_ret, + &root_y_ret, &win_x_ret, &win_y_ret, &mask_ret); + return (mask_ret & mask); +} + +int +ecore_modifier_mask_get(void) +{ + Window root_ret, child_ret; + int root_x_ret, root_y_ret, win_x_ret, win_y_ret; + unsigned int mask_ret; + + if (!disp) return 0; + XQueryPointer(disp, default_root, &root_ret, &child_ret, &root_x_ret, + &root_y_ret, &win_x_ret, &win_y_ret, &mask_ret); + return (mask_ret); +} + +Window +ecore_get_key_grab_win(void) +{ + if (!disp) return 0; + return grabkey_win; +} + +void +ecore_key_grab(char *key, Ecore_Event_Key_Modifiers mods, int anymod, int sync) +{ + KeyCode keycode; + int i, mod, mask_scroll, mask_num, mask_caps, masks[8], mode; + + if (!disp) return; + keycode = ecore_key_get_keycode(key); + mod = 0; + mode = GrabModeAsync; + if (sync) + mode = GrabModeSync; + if (!grabkey_win) + grabkey_win = default_root; + if (mods & ECORE_EVENT_KEY_MODIFIER_SHIFT) + mod |= ecore_mod_mask_shift_get(); + if (mods & ECORE_EVENT_KEY_MODIFIER_CTRL) + mod |= ecore_mod_mask_ctrl_get(); + if (mods & ECORE_EVENT_KEY_MODIFIER_ALT) + mod |= ecore_mod_mask_alt_get(); + if (mods & ECORE_EVENT_KEY_MODIFIER_WIN) + mod |= ecore_mod_mask_win_get(); + mask_scroll = ecore_lock_mask_scroll_get(); + mask_num = ecore_lock_mask_num_get(); + mask_caps = ecore_lock_mask_caps_get(); + masks[0] = 0; + masks[1] = mask_scroll; + masks[2] = mask_num; + masks[3] = mask_caps; + masks[4] = mask_scroll | mask_num; + masks[5] = mask_scroll | mask_caps; + masks[6] = mask_num | mask_caps; + masks[7] = mask_scroll | mask_num | mask_caps; + if (anymod) + XGrabKey(disp, keycode, AnyModifier, grabkey_win, False, mode, mode); + else + { + for (i = 0; i < 8; i++) + XGrabKey(disp, keycode, masks[i] | mod, grabkey_win, False, mode, mode); + } +} + +void +ecore_key_ungrab(char *key, Ecore_Event_Key_Modifiers mods, int anymod) +{ + KeyCode keycode; + + if (!disp) return; + keycode = ecore_key_get_keycode(key); + if (anymod) + XUngrabKey(disp, keycode, AnyModifier, default_root); + else + { + int i, mod, mask_scroll, mask_num, mask_caps, masks[8]; + + mod = 0; + if (mods & ECORE_EVENT_KEY_MODIFIER_SHIFT) + mod |= ecore_mod_mask_shift_get(); + if (mods & ECORE_EVENT_KEY_MODIFIER_CTRL) + mod |= ecore_mod_mask_ctrl_get(); + if (mods & ECORE_EVENT_KEY_MODIFIER_ALT) + mod |= ecore_mod_mask_alt_get(); + if (mods & ECORE_EVENT_KEY_MODIFIER_WIN) + mod |= ecore_mod_mask_win_get(); + mask_scroll = ecore_lock_mask_scroll_get(); + mask_num = ecore_lock_mask_num_get(); + mask_caps = ecore_lock_mask_caps_get(); + masks[0] = 0; + masks[1] = mask_scroll; + masks[2] = mask_num; + masks[3] = mask_caps; + masks[4] = mask_scroll | mask_num; + masks[5] = mask_scroll | mask_caps; + masks[6] = mask_num | mask_caps; + masks[7] = mask_scroll | mask_num | mask_caps; + for (i = 0; i < 8; i++) + XUngrabKey(disp, keycode, masks[i] | mod, grabkey_win); + } +} + +KeyCode +ecore_key_get_keycode(char *key) +{ + if (!disp) return 0; + return XKeysymToKeycode(disp, XStringToKeysym(key)); +} + +void +ecore_window_destroy(Window win) +{ + if (!disp) return; + ecore_unvalidate_xid(win); + XDestroyWindow(disp, win); +} + +void +ecore_window_reparent(Window win, Window parent, int x, int y) +{ + Ecore_XID *xid = NULL; + + if (!disp) return; + xid = ecore_validate_xid(win); + if (xid) + { + if (parent == 0) + parent = default_root; + XReparentWindow(disp, win, parent, x, y); + ecore_del_child(xid->parent, win); + ecore_add_child(parent, win); + xid->parent = parent; + xid->x = x; + xid->y = y; + } +} + +void +ecore_window_raise(Window win) +{ + Ecore_XID *xid = NULL; + + if (!disp) return; + xid = ecore_validate_xid(win); + if (xid) + { + XRaiseWindow(disp, win); + ecore_raise_child(xid->parent, win); + } +} + +void +ecore_window_lower(Window win) +{ + Ecore_XID *xid = NULL; + + if (!disp) return; + xid = ecore_validate_xid(win); + if (xid) + { + XLowerWindow(disp, win); + ecore_lower_child(xid->parent, win); + } +} + +void +ecore_window_get_geometry(Window win, int *x, int *y, int *w, int *h) +{ + Ecore_XID *xid = NULL; + + if (!disp) return; + if (win == 0) + win = default_root; + xid = ecore_validate_xid(win); + if ((xid) && (xid->coords_invalid)) + { + Window dw; + int rx, ry; + unsigned int rw, rh, di; + + XGetGeometry(disp, win, &dw, &rx, &ry, &rw, &rh, &di, &di); + xid->x = rx; + xid->y = ry; + xid->w = (int)rw; + xid->h = (int)rh; + xid->coords_invalid = 0; + } + if (xid) + { + if (x) + *x = xid->x; + if (y) + *y = xid->y; + if (w) + *w = xid->w; + if (h) + *h = xid->h; + } + else + { + if (x) + *x = 0; + if (y) + *y = 0; + if (w) + *w = 0; + if (h) + *h = 0; + } +} + +int +ecore_window_get_depth(Window win) +{ + Ecore_XID *xid = NULL; + + if (!disp) return 0; + if (win == 0) + win = default_root; + xid = ecore_validate_xid(win); + if (xid) + return xid->depth; + return -1; +} + +int +ecore_window_exists(Window win) +{ + Ecore_XID *xid = NULL; + + if (!disp) return 0; + xid = ecore_validate_xid(win); + if (xid) + return 1; + return 0; +} + +Window +ecore_window_get_parent(Window win) +{ + Ecore_XID *xid = NULL; + + if (!disp) return 0; + xid = ecore_validate_xid(win); + if (xid) + return xid->parent; + return 0; +} + +Window * +ecore_window_get_children(Window win, int *num) +{ + Ecore_XID *xid = NULL; + + if (!disp) return NULL; + if (win == 0) + win = default_root; + xid = ecore_validate_xid(win); + if (xid) + { + Window *wlist = NULL; + + *num = xid->children_num; + if (xid->children) + { + wlist = NEW(Window, xid->children_num); + MEMCPY(xid->children, wlist, Window, xid->children_num); + } + return wlist; + } + *num = 0; + return NULL; +} + +int +ecore_window_mouse_in(Window win) +{ + Ecore_XID *xid = NULL; + + if (!disp) return 0; + if (win == 0) + win = default_root; + xid = ecore_validate_xid(win); + if (xid) + return xid->mouse_in; + return 0; +} + +void +ecore_window_mouse_set_in(Window win, int in) +{ + Ecore_XID *xid = NULL; + + if (!disp) return; + if (win == 0) + win = default_root; + xid = ecore_validate_xid(win); + if (xid) + xid->mouse_in = in; +} + +Display * +ecore_display_get(void) +{ + return disp; +} + +Window +ecore_window_get_root(Window win) +{ + Ecore_XID *xid = NULL; + + if (!disp) return 0; + xid = ecore_validate_xid(win); + if (xid) + return xid->root; + return 0; +} + +void +ecore_lock_scroll_set(int onoff) +{ + lock_scroll = onoff; +} + +int +ecore_lock_scroll_get(void) +{ + return lock_scroll; +} + +void +ecore_lock_num_set(int onoff) +{ + lock_num = onoff; +} + +int +ecore_lock_num_get(void) +{ + return lock_num; +} + +void +ecore_lock_caps_set(int onoff) +{ + lock_caps = onoff; +} + +int +ecore_lock_caps_get(void) +{ + return lock_caps; +} + +void +ecore_mod_shift_set(int onoff) +{ + mod_shift = onoff; +} + +int +ecore_mod_shift_get(void) +{ + return mod_shift; +} + +void +ecore_mod_ctrl_set(int onoff) +{ + mod_ctrl = onoff; +} + +int +ecore_mod_ctrl_get(void) +{ + return mod_ctrl; +} + +void +ecore_mod_alt_set(int onoff) +{ + mod_alt = onoff; +} + +int +ecore_mod_alt_get(void) +{ + return mod_alt; +} + +void +ecore_mod_win_set(int onoff) +{ + mod_win = onoff; +} + +int +ecore_mod_win_get(void) +{ + return mod_win; +} + +void +ecore_focus_window_set(Window win) +{ + focused_win = win; +} + +Window +ecore_focus_window_get(void) +{ + return focused_win; +} + +void +ecore_focus_to_window(Window win) +{ + if (!disp) return; + if (win == 0) + win = default_root; + XSetInputFocus(disp, win, RevertToNone, CurrentTime); +} + +void +ecore_focus_mode_reset(void) +{ + if (!disp) return; + XSetInputFocus(disp, default_root, RevertToPointerRoot, CurrentTime); +} + +Atom +ecore_atom_get(char *name) +{ + if (!disp) return 0; + return XInternAtom(disp, name, False); +} + +void +ecore_window_set_delete_inform(Window win) +{ + static Atom protocols[1] = { 0 }; + + if (!disp) return; + ECORE_ATOM(protocols[0], "WM_DELETE_WINDOW"); + XSetWMProtocols(disp, win, protocols, 1); +} + +void +ecore_window_property_set(Window win, Atom type, Atom format, int size, + void *data, int number) +{ + if (!disp) return; + if (win == 0) + win = default_root; + if (size != 32) + XChangeProperty(disp, win, type, format, size, PropModeReplace, + (unsigned char *)data, number); + else + { + long *dat; + int i, *ptr; + + dat = NEW(long, number); + + for (ptr = (int *)data, i = 0; i < number; i++) + dat[i] = ptr[i]; + XChangeProperty(disp, win, type, format, size, PropModeReplace, + (unsigned char *)dat, number); + FREE(dat); + } +} + +void * +ecore_window_property_get(Window win, Atom type, Atom format, int *size) +{ + unsigned char *retval; + Atom type_ret; + unsigned long bytes_after, num_ret; + int format_ret; + void *data = NULL; + + if (!disp) + return NULL; + + retval = NULL; + if (win == 0) + win = default_root; + XGetWindowProperty(disp, win, type, 0, 0x7fffffffL, False, format, + &type_ret, &format_ret, &num_ret, &bytes_after, &retval); + if (retval) + { + if (format_ret == 32) + { + int i; + + *size = num_ret * sizeof(unsigned int); + + data = NEW(unsigned int, num_ret); + + for (i = 0; i < (int)num_ret; i++) + ((unsigned int *)data)[i] = ((unsigned long *)retval)[i]; + } + else if (format_ret == 16) + { + int i; + + *size = num_ret * sizeof(unsigned short); + + data = NEW(unsigned short, *size); + + for (i = 0; i < (int)num_ret; i++) + ((unsigned short *)data)[i] = ((unsigned short *)retval)[i]; + } + else if (format_ret == 8) + { + /* format_ret == 8 */ + *size = num_ret; + data = NEW(char, num_ret); + + if (data) + memcpy(data, retval, num_ret); + } + XFree(retval); + return data; + } + *size = 0; + return NULL; +} + +void +ecore_window_dnd_advertise(Window win) +{ + static Atom atom_xdndaware = 0; + int dnd_version = 3; + + if (!disp) return; + ECORE_ATOM(atom_xdndaware, "XdndAware"); + ecore_window_property_set(win, atom_xdndaware, XA_ATOM, 32, &dnd_version, 1); +} + +void +ecore_grab(void) +{ + if (!disp) + return; + + x_grabs++; + + if (x_grabs == 1) + XGrabServer(disp); +} + +void +ecore_ungrab(void) +{ + if (!disp) + return; + + x_grabs--; + + if (x_grabs == 0) + { + XUngrabServer(disp); + ecore_sync(); + } +} + +void +ecore_window_ignore(Window win) +{ + Window_List *w; + + if (!disp) return; + if (win == 0) + win = default_root; + w = NEW(Window_List, 1); + w->win = win; + w->next = ignore_wins; + ignore_wins = w; +} + +void +ecore_window_no_ignore(Window win) +{ + Window_List *w, *pw; + + if (!disp) return; + if (win == 0) + win = default_root; + for (pw = NULL, w = ignore_wins; w; pw = w, w = w->next) + { + if (w->win == win) + { + if (pw) + pw->next = w->next; + else + ignore_wins = w->next; + FREE(w); + return; + } + } +} + +int +ecore_window_is_ignored(Window win) +{ + Window_List *w; + + if (!disp) return 0; + if (win == 0) + win = default_root; + for (w = ignore_wins; w; w = w->next) + { + if (w->win == win) + return 1; + } + return 0; +} + +static Window +ecore_window_at_xy_0(Window base, int bx, int by, int x, int y) +{ + Window *list = NULL; + XWindowAttributes att; + Window child = 0, parent_win = 0, root_win = 0; + int i; + unsigned int ww, wh, num; + int wx, wy; + + if (!disp) return 0; + if ((!XGetWindowAttributes(disp, base, &att)) || + (att.map_state != IsViewable)) + return 0; + + wx = att.x; + wy = att.y; + ww = att.width; + wh = att.height; + + wx += bx; + wy += by; + + if (!((x >= wx) && (y >= wy) && (x < (int)(wx + ww)) && (y < (int)(wy + wh)))) + return 0; + + if (!XQueryTree(disp, base, &root_win, &parent_win, &list, &num)) + return base; + if (list) + { + for (i = num - 1;; i--) + { + if (!ecore_window_is_ignored(list[i])) + { + if ((child = ecore_window_at_xy_0(list[i], wx, wy, x, y)) != 0) + { + XFree(list); + return child; + } + } + if (!i) + break; + } + XFree(list); + } + return base; +} + +Window +ecore_window_get_at_xy(int x, int y) +{ + Window child; + + if (!disp) return 0; + ecore_grab(); + child = ecore_window_at_xy_0(default_root, 0, 0, x, y); + if (child) + { + ecore_ungrab(); + return child; + } + ecore_ungrab(); + return default_root; +} + +int +ecore_window_dnd_capable(Window win) +{ + static Atom atom_xdndaware = 0; + int dnd_version = 3; + int *atom_ret; + int size = 0; + + if (!disp) return 0; + ECORE_ATOM(atom_xdndaware, "XdndAware"); + atom_ret = ecore_window_property_get(win, atom_xdndaware, XA_ATOM, &size); + if ((atom_ret) && (size >= (int)sizeof(int))) + { + if (atom_ret[0] == dnd_version) + { + FREE(atom_ret); + return 1; + } + FREE(atom_ret); + } + return 0; +} + +void +ecore_window_dnd_handle_motion(Window source_win, int x, int y, int dragging) +{ + static Atom atom_xdndenter = 0; + static Atom atom_xdndleave = 0; + static Atom atom_xdnddrop = 0; + static Atom atom_xdndposition = 0; + static Atom atom_xdndactioncopy = 0; + static Atom atom_xdndactionmove = 0; + static Atom atom_xdndactionlink = 0; + static Atom atom_xdndactionask = 0; + static Atom atom_text_uri_list = 0; + static Atom atom_text_plain = 0; + static Atom atom_text_moz_url = 0; + static Atom atom_netscape_url = 0; + Window win; + XEvent xevent; + + if (!disp) return; + win = ecore_window_get_at_xy(x, y); + while ((win) && (!ecore_window_dnd_capable(win))) + win = ecore_window_get_parent(win); + ECORE_ATOM(atom_xdndenter, "XdndEnter"); + ECORE_ATOM(atom_xdndleave, "XdndLeave"); + ECORE_ATOM(atom_xdnddrop, "XdndDrop"); + ECORE_ATOM(atom_xdndposition, "XdndPosition"); + ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy"); + ECORE_ATOM(atom_xdndactionmove, "XdndActionMove"); + ECORE_ATOM(atom_xdndactionlink, "XdndActionLink"); + ECORE_ATOM(atom_xdndactionask, "XdndActionAsk"); + ECORE_ATOM(atom_text_uri_list, "text/uri-list"); + ECORE_ATOM(atom_text_plain, "text/plain"); + ECORE_ATOM(atom_text_moz_url, "text/x-moz-url"); + ECORE_ATOM(atom_netscape_url, "_NETSCAPE_URL"); + if ((win != current_dnd_win) && (current_dnd_win)) + { + /* send leave to old dnd win */ + xevent.xany.type = ClientMessage; + xevent.xany.display = disp; + xevent.xclient.format = 32; + xevent.xclient.window = current_dnd_win; + xevent.xclient.message_type = atom_xdndleave; + xevent.xclient.data.l[0] = source_win; + xevent.xclient.data.l[1] = 0; + xevent.xclient.data.l[2] = 0; + xevent.xclient.data.l[3] = 0; + xevent.xclient.data.l[4] = 0; + XSendEvent(disp, current_dnd_win, False, 0, &xevent); + } + if (win) + { + if (win != current_dnd_win) + { + /* send enter on new win */ + xevent.xany.type = ClientMessage; + xevent.xany.display = disp; + xevent.xclient.window = win; + xevent.xclient.message_type = atom_xdndenter; + xevent.xclient.format = 32; + xevent.xclient.data.l[0] = source_win; + xevent.xclient.data.l[1] = (3 << 24); + xevent.xclient.data.l[2] = atom_text_uri_list; + xevent.xclient.data.l[3] = atom_text_plain; + xevent.xclient.data.l[4] = atom_text_moz_url; + XSendEvent(disp, win, False, 0, &xevent); + ecore_clear_target_status(); + } + /* kjb cep */ + if(!dnd_await_target_status) + { + /* send position information */ + xevent.xany.type = ClientMessage; + xevent.xany.display = disp; + xevent.xclient.window = win; + xevent.xclient.message_type = atom_xdndposition; + xevent.xclient.format = 32; + xevent.xclient.data.l[0] = source_win; + xevent.xclient.data.l[1] = (3 << 24); + xevent.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff); + xevent.xclient.data.l[3] = CurrentTime; + if (dnd_copy) + xevent.xclient.data.l[4] = atom_xdndactioncopy; + else if (dnd_link) + xevent.xclient.data.l[4] = atom_xdndactionlink; + else if (dnd_move) + xevent.xclient.data.l[4] = atom_xdndactionmove; + else + xevent.xclient.data.l[4] = atom_xdndactionask; + XSendEvent(disp, win, False, 0, &xevent); + dnd_await_target_status = 1; + } + } + if (!dragging) + { + if (win) + { + if (current_dnd_target_ok) + { + xevent.xany.type = ClientMessage; + xevent.xany.display = disp; + xevent.xclient.window = win; + xevent.xclient.message_type = atom_xdnddrop; + xevent.xclient.format = 32; + xevent.xclient.data.l[0] = source_win; + xevent.xclient.data.l[1] = 0; + xevent.xclient.data.l[2] = CurrentTime; + xevent.xclient.data.l[3] = 0; + xevent.xclient.data.l[4] = 0; + XSendEvent(disp, win, False, 0, &xevent); + } + else + { + xevent.xany.type = ClientMessage; + xevent.xany.display = disp; + xevent.xclient.window = win; + xevent.xclient.message_type = atom_xdndleave; + xevent.xclient.format = 32; + xevent.xclient.data.l[0] = source_win; + xevent.xclient.data.l[1] = 0; + xevent.xclient.data.l[2] = 0; + xevent.xclient.data.l[3] = 0; + xevent.xclient.data.l[4] = 0; + XSendEvent(disp, win, False, 0, &xevent); + } + } + current_dnd_target_ok = 0; + } + current_dnd_win = win; +} + + +void +ecore_clear_target_status(void) +{ + dnd_await_target_status = 0; +} + + +int +ecore_dnd_selection_convert(Window win, Window req, Atom type) +{ + static Atom atom_xdndselection = 0; + static Atom atom_jxselectionwindowproperty = 0; + + if (!disp) return 0; + ECORE_ATOM(atom_xdndselection, "XdndSelection"); + ECORE_ATOM(atom_jxselectionwindowproperty, "JXSelectionWindowProperty"); + if (win == XGetSelectionOwner(disp, atom_xdndselection)) + { + XConvertSelection(disp, atom_xdndselection, type, + atom_jxselectionwindowproperty, req, CurrentTime); + return 1; + } + return 0; +} + +void * +ecore_dnd_selection_get(Window win, Window req, Atom type, int *size) +{ + unsigned char *data = NULL; + long bytes_read; + unsigned long remaining = 1; + + if (!disp) return NULL; + *size = 0; + bytes_read = 0; + while (remaining) + { + unsigned char *s; + Atom actual; + int format; + unsigned long count; + + s = NULL; + if (XGetWindowProperty(disp, win, type, bytes_read / 4, 0x10000, 1, + AnyPropertyType, &actual, &format, &count, + &remaining, &s) != Success) + { + /* error occured */ + XFree(s); + IF_FREE(data); + *size = 0; + return NULL; + } + if (s) + { + /* got some mroe data - append it */ + bytes_read += count; + if (!data) + data = NEW(char, bytes_read); + + else + REALLOC(data, char, bytes_read); + MEMCPY(s, data + (bytes_read - count), char, count); + + XFree(s); + } + } + *size = bytes_read; + return data; + req = 0; +} + +void +ecore_dnd_set_data(Window win) +{ + static Atom atom_xdndselection = 0; + + if (!disp) return; + ECORE_ATOM(atom_xdndselection, "XdndSelection"); + ecore_dnd_set_action(win); + XSetSelectionOwner(disp, atom_xdndselection, win, CurrentTime); +} + +void +ecore_dnd_set_action(Window win) +{ + static int atom_xdndactioncopy = 0; + static int atom_xdndactionmove = 0; + static int atom_xdndactionlink = 0; + static int atom_xdndactionask = 0; + static Atom atom_xdndactionlist = 0; + + if (!disp) return; + ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy"); + ECORE_ATOM(atom_xdndactionmove, "XdndActionMove"); + ECORE_ATOM(atom_xdndactionlink, "XdndActionLink"); + ECORE_ATOM(atom_xdndactionask, "XdndActionAsk"); + ECORE_ATOM(atom_xdndactionlist, "XdndActionList"); + if (dnd_copy) + ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32, + &atom_xdndactioncopy, 1); + else if (dnd_link) + ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32, + &atom_xdndactionlink, 1); + else if (dnd_move) + ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32, + &atom_xdndactionmove, 1); + else + ecore_window_property_set(win, atom_xdndactionlist, XA_ATOM, 32, + &atom_xdndactionask, 1); +} + +void +ecore_dnd_send_data(Window win, Window source_win, void *data, int size, + Atom dest_atom, int type) +{ + XEvent xevent; + static Atom atom_text_plain = 0; + static Atom atom_text_uri_list = 0; + static Atom atom_text_moz_url = 0; + static Atom atom_netscape_url = 0; + static Atom atom_xdndselection = 0; + Atom target; + + if (!disp) return; + ECORE_ATOM(atom_xdndselection, "XdndSelection"); + ECORE_ATOM(atom_text_uri_list, "text/uri-list"); + ECORE_ATOM(atom_text_plain, "text/plain"); + ECORE_ATOM(atom_text_moz_url, "text/x-moz-url"); + ECORE_ATOM(atom_text_moz_url, "_NETSCAPE_URL"); + ECORE_ATOM(atom_text_plain, "text/plain"); + if (type == DND_TYPE_URI_LIST) target = atom_text_uri_list; + else if (type == DND_TYPE_PLAIN_TEXT) target = atom_text_plain; + else if (type == DND_TYPE_MOZ_URL) target = atom_text_moz_url; + else if (type == DND_TYPE_NETSCAPE_URL) target = atom_netscape_url; + else target = 0; + ecore_window_property_set(win, dest_atom, target, 8, data, size); + xevent.xselection.type = SelectionNotify; + xevent.xselection.property = dest_atom; + xevent.xselection.display = disp; + xevent.xselection.requestor = win; + xevent.xselection.selection = atom_xdndselection; + xevent.xselection.target = target; + xevent.xselection.time = CurrentTime; + XSendEvent(disp, win, False, 0, &xevent); + return; + source_win = 0; +} + +void +ecore_dnd_set_mode_copy(void) +{ + dnd_copy = 1; + dnd_link = 0; + dnd_move = 0; +} + +void +ecore_dnd_set_mode_link(void) +{ + dnd_copy = 0; + dnd_link = 1; + dnd_move = 0; +} + +void +ecore_dnd_set_mode_move(void) +{ + dnd_copy = 0; + dnd_link = 0; + dnd_move = 1; +} + +void +ecore_dnd_set_mode_ask(void) +{ + dnd_copy = 0; + dnd_link = 0; + dnd_move = 0; +} + +void +ecore_dnd_own_selection(Window win) +{ + static Atom atom_xdndselection = 0; + static Atom atom_jxselectionwindowproperty = 0; + + if (!disp) return; + ECORE_ATOM(atom_xdndselection, "XdndSelection"); + ECORE_ATOM(atom_jxselectionwindowproperty, "JXSelectionWindowProperty"); + + if (!XSetSelectionOwner(disp, atom_xdndselection, win, CurrentTime)) + return; +} + +void +ecore_dnd_send_drop(Window win, Window source_win) +{ + static Atom atom_xdnddrop = 0; + XEvent xevent; + + if (!disp) return; + ECORE_ATOM(atom_xdnddrop, "XdndDrop"); + + ecore_dnd_own_selection(source_win); + + memset(&xevent, 0, sizeof(xevent)); + xevent.xany.type = ClientMessage; + xevent.xany.display = disp; + xevent.xclient.window = win; + xevent.xclient.message_type = atom_xdnddrop; + xevent.xclient.format = 32; + + xevent.xclient.data.l[0] = source_win; + xevent.xclient.data.l[1] = CurrentTime; + xevent.xclient.data.l[2] = 0; + xevent.xclient.data.l[3] = 0; + xevent.xclient.data.l[4] = 0; + XSendEvent(disp, win, False, 0, &xevent); +} + +void +ecore_window_dnd_send_status_ok(Window source_win, Window win, int x, int y, + int w, int h) +{ + static Atom atom_xdndstatus = 0; + static Atom atom_xdndactioncopy = 0; + static Atom atom_xdndactionmove = 0; + static Atom atom_xdndactionlink = 0; + static Atom atom_xdndactionask = 0; + XEvent xevent; + + if (!disp) return; + ECORE_ATOM(atom_xdndstatus, "XdndStatus"); + ECORE_ATOM(atom_xdndactioncopy, "XdndActionCopy"); + ECORE_ATOM(atom_xdndactionmove, "XdndActionMove"); + ECORE_ATOM(atom_xdndactionlink, "XdndActionLink"); + ECORE_ATOM(atom_xdndactionask, "XdndActionAsk"); + memset(&xevent, 0, sizeof(xevent)); + + xevent.xany.type = ClientMessage; + xevent.xany.display = disp; + xevent.xclient.window = win; + xevent.xclient.message_type = atom_xdndstatus; + xevent.xclient.format = 32; + + xevent.xclient.data.l[0] = source_win; + xevent.xclient.data.l[1] = 3; + xevent.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff); + xevent.xclient.data.l[3] = ((h << 16) & 0xffff0000) | (w & 0xffff); + if (dnd_copy) + xevent.xclient.data.l[4] = atom_xdndactioncopy; + else if (dnd_link) + xevent.xclient.data.l[4] = atom_xdndactionlink; + else if (dnd_move) + xevent.xclient.data.l[4] = atom_xdndactionmove; + else + xevent.xclient.data.l[4] = atom_xdndactionask; + XSendEvent(disp, win, False, 0, &xevent); +} + +void +ecore_window_dnd_send_finished(Window source_win, Window win) +{ + static Atom atom_xdndfinished = 0; + XEvent xevent; + + if (!disp) return; + ECORE_ATOM(atom_xdndfinished, "XdndFinished"); + memset(&xevent, 0, sizeof(xevent)); + + xevent.xany.type = ClientMessage; + xevent.xany.display = disp; + xevent.xclient.window = win; + xevent.xclient.message_type = atom_xdndfinished; + xevent.xclient.format = 32; + + xevent.xclient.data.l[0] = source_win; + xevent.xclient.data.l[1] = 0; + xevent.xclient.data.l[2] = 0; + xevent.xclient.data.l[3] = 0; + xevent.xclient.data.l[4] = 0; + XSendEvent(disp, win, False, 0, &xevent); +} + +void +ecore_window_dnd_ok(int ok) +{ + current_dnd_target_ok = ok; +} + +void +ecore_window_dnd_finished(void) +{ + current_dnd_win = 0; +} + +void +ecore_window_set_title(Window win, char *title) +{ + if (!disp) return; + XStoreName(disp, win, title); +} + +void +ecore_window_set_name_class(Window win, char *name, char *class) +{ + XClassHint hint; + + if (!disp) return; + hint.res_name = name; + hint.res_class = class; + XSetClassHint(disp, win, &hint); +} + +void +ecore_window_get_name_class(Window win, char **name, char **class) +{ + XClassHint xch; + + if (!disp) return; + if (name) + *name = NULL; + if (class) + *class = NULL; + if (XGetClassHint(disp, win, &xch)) + { + if (name) + { + if (xch.res_name) + *name = strdup(xch.res_name); + } + if (class) + { + if (xch.res_class) + *class = strdup(xch.res_class); + } + XFree(xch.res_name); + XFree(xch.res_class); + } +} + +void +ecore_window_get_hints(Window win, int *accepts_focus, int *initial_state, + Pixmap * icon_pixmap, Pixmap * icon_mask, + Window * icon_window, Window * window_group) +{ + XWMHints *hints; + + if (!disp) return; + hints = XGetWMHints(disp, win); + if (hints) + { + if ((hints->flags & InputHint) && (accepts_focus)) + { + if (hints->input) + *accepts_focus = 1; + else + *accepts_focus = 0; + } + if ((hints->flags & StateHint) && (initial_state)) + { + *initial_state = hints->initial_state; + } + if ((hints->flags & IconPixmapHint) && (icon_pixmap)) + { + *icon_pixmap = hints->icon_pixmap; + } + if ((hints->flags & IconMaskHint) && (icon_mask)) + { + *icon_mask = hints->icon_pixmap; + } + if ((hints->flags & IconWindowHint) && (icon_window)) + { + *icon_window = hints->icon_window; + } + if ((hints->flags & WindowGroupHint) && (window_group)) + { + *window_group = hints->window_group; + } + XFree(hints); + } +} + +char * +ecore_window_get_machine(Window win) +{ + XTextProperty xtp; + + if (!disp) return NULL; + if (XGetWMClientMachine(disp, win, &xtp)) + { + char *s; + + if (!xtp.value) + return NULL; + s = strdup(xtp.value); + XFree(xtp.value); + return s; + } + return NULL; +} + +char * +ecore_window_get_command(Window win) +{ + int cargc; + char **cargv; + + if (!disp) return NULL; + if (XGetCommand(disp, win, &cargv, &cargc)) + { + if (cargc > 0) + { + char *s; + int size, i; + + size = 0; + for (i = 0; i < cargc; i++) + size += strlen(cargv[i]); + size += cargc - 1; + s = NEW(char, size + 1); + s[0] = 0; + + strcpy(s, cargv[0]); + for (i = 1; i < cargc; i++) + { + strcat(s, " "); + strcat(s, cargv[i]); + } + XFreeStringList(cargv); + return s; + } + else + return NULL; + } + return NULL; +} + +char * +ecore_window_get_icon_name(Window win) +{ + XTextProperty xtp; + + if (!disp) return NULL; + if (XGetWMIconName(disp, win, &xtp)) + { + char *s; + + if (!xtp.value) + return NULL; + s = strdup(xtp.value); + XFree(xtp.value); + return s; + } + return NULL; +} + +void +ecore_window_set_min_size(Window win, int w, int h) +{ + XSizeHints hints; + long ret; + + if (!disp) return; + memset(&hints, 0, sizeof(XSizeHints)); + XGetWMNormalHints(disp, win, &hints, &ret); + hints.flags |= PMinSize | PSize | USSize; + hints.min_width = w; + hints.min_height = h; + XSetWMNormalHints(disp, win, &hints); +} + +void +ecore_window_set_max_size(Window win, int w, int h) +{ + XSizeHints hints; + long ret; + + if (!disp) return; + memset(&hints, 0, sizeof(XSizeHints)); + XGetWMNormalHints(disp, win, &hints, &ret); + hints.flags |= PMaxSize | PSize | USSize; + hints.max_width = w; + hints.max_height = h; + XSetWMNormalHints(disp, win, &hints); +} + +void +ecore_window_set_xy_hints(Window win, int x, int y) +{ + XSizeHints hints; + long ret; + + if (!disp) return; + memset(&hints, 0, sizeof(XSizeHints)); + XGetWMNormalHints(disp, win, &hints, &ret); + hints.flags |= PPosition | USPosition | PSize | USSize; + hints.x = x; + hints.y = y; + XSetWMNormalHints(disp, win, &hints); +} + +void +ecore_window_get_frame_size(Window win, int *l, int *r, int *t, int *b) +{ + static Atom atom_e_frame_size = 0; + int *data, size; + + if (!disp) return; + ECORE_ATOM(atom_e_frame_size, "_E_FRAME_SIZE"); + data = ecore_window_property_get(win, atom_e_frame_size, XA_CARDINAL, &size); + if (data) + { + if (size == (4 * sizeof(int))) + { + if (l) + *l = data[0]; + if (r) + *r = data[1]; + if (t) + *t = data[2]; + if (b) + *b = data[3]; + } + else + { + if (l) + *l = 0; + if (r) + *r = 0; + if (t) + *t = 0; + if (b) + *b = 0; + } + FREE(data); + } + else + { + if (l) + *l = 0; + if (r) + *r = 0; + if (t) + *t = 0; + if (b) + *b = 0; + } +} + +int +ecore_window_save_under(Window win) +{ + XSetWindowAttributes att; + XWindowAttributes gatt; + + if (!disp) return 0; + att.save_under = True; + XChangeWindowAttributes(disp, win, CWSaveUnder, &att); + XGetWindowAttributes(disp, win, &gatt); + return (gatt.save_under == True) ? 1 : 0; +} + +GC +ecore_gc_new(Drawable d) +{ + XGCValues gcv; + + if (!disp) return 0; + if (d == 0) + d = default_root; + return XCreateGC(disp, d, 0, &gcv); +} + +void +ecore_gc_free(GC gc) +{ + if (!disp) return; + XFreeGC(disp, gc); +} + +void +ecore_gc_set_fg(GC gc, int val) +{ + if (!disp) return; + XSetForeground(disp, gc, val); +} + +void +ecore_fill_rectangle(Drawable d, GC gc, int x, int y, int w, int h) +{ + if (!disp) return; + XFillRectangle(disp, d, gc, x, y, w, h); +} + +void +ecore_draw_rectangle(Drawable d, GC gc, int x, int y, int w, int h) +{ + if (!disp) return; + XDrawRectangle(disp, d, gc, x, y, w - 1, h - 1); +} + +void +ecore_draw_line(Drawable d, GC gc, int x1, int y1, int x2, int y2) +{ + if (!disp) return; + XDrawLine(disp, d, gc, x1, y1, x2, y2); +} + +void +ecore_draw_point(Drawable d, GC gc, int x, int y) +{ + if (!disp) return; + XDrawPoint(disp, d, gc, x, y); +} + +void +ecore_window_hint_set_layer(Window win, int layer) +{ + static Atom atom_win_layer = 0; + + if (!disp) return; + ECORE_ATOM(atom_win_layer, "_WIN_LAYER"); + ecore_window_property_set(win, atom_win_layer, XA_CARDINAL, 32, &layer, 1); +} + +void +ecore_window_hint_set_sticky(Window win, int sticky) +{ + static Atom atom_win_state = 0; + static Atom atom_win_hints = 0; + int data; + + if (!disp) return; + ECORE_ATOM(atom_win_state, "_WIN_STATE"); + ECORE_ATOM(atom_win_hints, "_WIN_HINTS"); + if (sticky) + { + data = ((1 << 0) | (1 << 8) | (1 << 9)); + ecore_window_property_set(win, atom_win_state, XA_CARDINAL, 32, &data, 1); + data = ((1 << 0) | (1 << 1) | (1 << 2)); + ecore_window_property_set(win, atom_win_hints, XA_CARDINAL, 32, &data, 1); + } + else + { + data = 0; + ecore_window_property_set(win, atom_win_state, XA_CARDINAL, 32, &data, 1); + ecore_window_property_set(win, atom_win_hints, XA_CARDINAL, 32, &data, 1); + } +} + +void +ecore_window_hint_set_borderless(Window win) +{ + static Atom atom_motif_wm_hints = 0; + int data[5]; + + if (!disp) return; + ECORE_ATOM(atom_motif_wm_hints, "_MOTIF_WM_HINTS"); + data[0] = 0x3; + data[1] = 0x0; + data[2] = 0x0; + data[3] = 0x2ada27b0; + data[4] = 0x2aabd6b0; + ecore_window_property_set(win, atom_motif_wm_hints, atom_motif_wm_hints, 32, + data, 5); +} + +void +ecore_grab_mouse(Window win, int confine, Cursor cursor) +{ + int ret; + + if (!disp) + return; + if (confine) + ret = XGrabPointer(disp, win, False, + XEV_BUTTON | XEV_MOUSE_MOVE | XEV_IN_OUT, + GrabModeAsync, GrabModeAsync, win, cursor, CurrentTime); + else + ret = XGrabPointer(disp, win, False, + XEV_BUTTON | XEV_MOUSE_MOVE | XEV_IN_OUT, + GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime); + if (ret == GrabSuccess) + grab_pointer_win = win; +} + +void +ecore_ungrab_mouse(void) +{ + if (!disp) return; + XUngrabPointer(disp, CurrentTime); + grab_pointer_win = 0; +} + +Window +ecore_grab_window_get(void) +{ + return grab_pointer_win; +} + +int +ecore_window_get_gravity(Window win) +{ + XWindowAttributes att; + + if (!disp) + return 0; + + XGetWindowAttributes(disp, win, &att); + return att.win_gravity; +} + +void +ecore_window_gravity_reset(Window win) +{ + Ecore_XID *xid = NULL; + + if (!disp) return; + xid = ecore_validate_xid(win); + if (xid) + { + XSetWindowAttributes att; + +/* if (xid->gravity != NorthWestGravity)*/ + { + att.win_gravity = NorthWestGravity; + XChangeWindowAttributes(disp, win, CWWinGravity, &att); + xid->gravity = NorthWestGravity; + xid->coords_invalid = 1; + } + } +} + +void +ecore_window_gravity_set(Window win, int gravity) +{ + Ecore_XID *xid = NULL; + + if (!disp) return; + xid = ecore_validate_xid(win); + if (xid) + { +/* if (xid->gravity != gravity)*/ + { + XSetWindowAttributes att; + + att.win_gravity = gravity; + XChangeWindowAttributes(disp, win, CWWinGravity, &att); + xid->gravity = gravity; + xid->coords_invalid = 1; + } + } +} + +void +ecore_window_bit_gravity_set(Window win, int gravity) +{ + Ecore_XID *xid = NULL; + + if (!disp) return; + xid = ecore_validate_xid(win); + if (xid) + { + XSetWindowAttributes att; + + att.bit_gravity = gravity; + XChangeWindowAttributes(disp, win, CWBitGravity, &att); + } +} + +void +ecore_pointer_warp_by(int dx, int dy) +{ + if (!disp) return; + XWarpPointer(disp, None, None, 0, 0, 0, 0, dx, dy); +} + +void +ecore_pointer_warp_to(int x, int y) +{ + if (!disp) return; + XWarpPointer(disp, None, default_root, 0, 0, 0, 0, x, y); +} + +void +ecore_gc_set_include_inferiors(GC gc) +{ + XGCValues gcv; + + if (!disp) return; + gcv.subwindow_mode = IncludeInferiors; + XChangeGC(disp, gc, GCSubwindowMode, &gcv); +} + +void +ecore_area_copy(Drawable src, Drawable dest, GC gc, + int sx, int sy, int sw, int sh, int dx, int dy) +{ + if (!disp) return; + if (src == 0) + src = default_root; + if (dest == 0) + dest = default_root; + XCopyArea(disp, src, dest, gc, sx, sy, sw, sh, dx, dy); +} + +Window +ecore_window_root(void) +{ + return default_root; +} + +void +ecore_window_get_virtual_area(Window win, int *area_x, int *area_y) +{ + static Atom atom_win_area = 0; + int *data, size; + + if (!disp) return; + ECORE_ATOM(atom_win_area, "_WIN_AREA"); + data = ecore_window_property_get(win, atom_win_area, XA_CARDINAL, &size); + if (data) + { + if (size == (sizeof(int) * 2)) + { + if (area_x) + *area_x = data[0]; + if (area_y) + *area_y = data[1]; + } + FREE(data); + } +} + +void +ecore_get_virtual_area(int *area_x, int *area_y) +{ + static Atom atom_win_area = 0; + int *data, size; + + if (!disp) return; + ECORE_ATOM(atom_win_area, "_WIN_AREA"); + data = ecore_window_property_get(default_root, atom_win_area, XA_CARDINAL, &size); + if (data) + { + if (size == (sizeof(int) * 2)) + { + if (area_x) + *area_x = data[0]; + if (area_y) + *area_y = data[1]; + } + FREE(data); + } +} + +void +ecore_window_get_root_relative_location(Window win, int *x, int *y) +{ + int dx, dy; + Window parent; + Ecore_XID *xid = NULL; + + if (!disp) return; + if (win == 0) + win = default_root; + if (win == default_root) + { + if (x) + *x = 0; + if (y) + *y = 0; + return; + } + xid = ecore_validate_xid(win); + if (!xid) + { + if (x) + *x = 0; + if (y) + *y = 0; + return; + } + dx = 0; + dy = 0; + do + { + parent = xid->parent; + dx += xid->x; + dy += xid->y; + if (parent != default_root) + { + xid = ecore_validate_xid(parent); + if (!xid) + { + if (x) + *x = dx; + if (y) + *y = dy; + return; + } + } + } + while (parent != default_root); + if (x) + *x = dx; + if (y) + *y = dy; +} + +void +ecore_window_button_grab_auto_replay_set(Window win, int (*func) (Ecore_Event_Mouse_Down *ev)) +{ + Ecore_XID *xid = NULL; + + if (!disp) return; + xid = ecore_validate_xid(win); + if (!xid) return; + xid->grab_button_auto_replay = func; +} + +void * +ecore_window_button_grab_auto_replay_get(Window win) +{ + Ecore_XID *xid = NULL; + + if (!disp) return NULL; + xid = ecore_validate_xid(win); + if (!xid) return NULL; + return xid->grab_button_auto_replay; +} + +void +ecore_button_grab(Window win, int button, int events, + Ecore_Event_Key_Modifiers mod, int any_mod) +{ + unsigned int b; + unsigned int m; + unsigned int locks[8]; + int i; + + if (!disp) return; + b = button; + if (b == 0) + b = AnyButton; + m = 0; + if (any_mod) + m = AnyModifier; + else + { + if (mod & ECORE_EVENT_KEY_MODIFIER_SHIFT) + m |= ecore_mod_mask_shift_get(); + if (mod & ECORE_EVENT_KEY_MODIFIER_CTRL) + m |= ecore_mod_mask_ctrl_get(); + if (mod & ECORE_EVENT_KEY_MODIFIER_ALT) + m |= ecore_mod_mask_alt_get(); + if (mod & ECORE_EVENT_KEY_MODIFIER_WIN) + m |= ecore_mod_mask_win_get(); + } + locks[0] = 0; + locks[1] = ecore_lock_mask_caps_get(); + locks[2] = ecore_lock_mask_num_get(); + locks[3] = ecore_lock_mask_scroll_get(); + locks[4] = ecore_lock_mask_caps_get() | ecore_lock_mask_num_get(); + locks[5] = ecore_lock_mask_caps_get() | ecore_lock_mask_scroll_get(); + locks[6] = ecore_lock_mask_num_get() | ecore_lock_mask_scroll_get(); + locks[7] = + ecore_lock_mask_caps_get() | ecore_lock_mask_num_get() | + ecore_lock_mask_scroll_get(); + for (i = 0; i < 8; i++) + XGrabButton(disp, b, m | locks[i], + win, False, events, GrabModeSync, GrabModeAsync, None, None); +} + +void +ecore_button_ungrab(Window win, int button, Ecore_Event_Key_Modifiers mod, + int any_mod) +{ + unsigned int b; + unsigned int m; + unsigned int locks[8]; + int i; + + if (!disp) return; + b = button; + if (b == 0) + b = AnyButton; + m = 0; + if (any_mod) + m = AnyModifier; + else + { + if (mod & ECORE_EVENT_KEY_MODIFIER_SHIFT) + m |= ecore_mod_mask_shift_get(); + if (mod & ECORE_EVENT_KEY_MODIFIER_CTRL) + m |= ecore_mod_mask_ctrl_get(); + if (mod & ECORE_EVENT_KEY_MODIFIER_ALT) + m |= ecore_mod_mask_alt_get(); + if (mod & ECORE_EVENT_KEY_MODIFIER_WIN) + m |= ecore_mod_mask_win_get(); + } + locks[0] = 0; + locks[1] = ecore_lock_mask_caps_get(); + locks[2] = ecore_lock_mask_num_get(); + locks[3] = ecore_lock_mask_scroll_get(); + locks[4] = ecore_lock_mask_caps_get() | ecore_lock_mask_num_get(); + locks[5] = ecore_lock_mask_caps_get() | ecore_lock_mask_scroll_get(); + locks[6] = ecore_lock_mask_num_get() | ecore_lock_mask_scroll_get(); + locks[7] = + ecore_lock_mask_caps_get() | ecore_lock_mask_num_get() | + ecore_lock_mask_scroll_get(); + for (i = 0; i < 8; i++) + XUngrabButton(disp, b, m | locks[i], win); +} + +void +ecore_pointer_replay(Time t) +{ + if (!disp) return; + XSync(disp, False); + XAllowEvents(disp, ReplayPointer, t); + XSync(disp, False); +} + +void +ecore_pointer_grab(Window win, Time t) +{ + if (!disp) return; + XGrabPointer(disp, win, False, XEV_BUTTON | XEV_MOUSE_MOVE | XEV_IN_OUT, + GrabModeAsync, GrabModeAsync, None, None, t); +} + +void +ecore_pointer_ungrab(Time t) +{ + if (!disp) return; + XUngrabPointer(disp, t); +} + +void +ecore_window_send_event_move_resize(Window win, int x, int y, int w, int h) +{ + XEvent ev; + + if (!disp) return; + ev.type = ConfigureNotify; + ev.xconfigure.display = disp; + ev.xconfigure.event = win; + ev.xconfigure.window = win; + ev.xconfigure.x = x; + ev.xconfigure.y = y; + ev.xconfigure.width = w; + ev.xconfigure.height = h; + ev.xconfigure.border_width = 0; + ev.xconfigure.above = win; + ev.xconfigure.override_redirect = False; + XSendEvent(disp, win, False, StructureNotifyMask, &ev); +} + +void +ecore_window_send_client_message(Window win, Atom type, int format, void *data) +{ + XClientMessageEvent ev; + int i; + + if (!disp) return; + ev.type = ClientMessage; + ev.window = win; + ev.message_type = type; + ev.format = format; + if (format == 32) + { + for (i = 0; i < 5; i++) + ev.data.l[i] = ((unsigned int *)data)[i]; + } + else if (format == 16) + { + for (i = 0; i < 10; i++) + ev.data.s[i] = ((unsigned short *)data)[i]; + } + else if (format == 8) + { + for (i = 0; i < 20; i++) + ev.data.b[i] = ((unsigned char *)data)[i]; + } + XSendEvent(disp, win, False, 0, (XEvent *) & ev); +} + +void +ecore_window_add_to_save_set(Window win) +{ + if (!disp) return; + XAddToSaveSet(disp, win); +} + +void +ecore_window_del_from_save_set(Window win) +{ + if (!disp) return; + XRemoveFromSaveSet(disp, win); +} + +void +ecore_window_kill_client(Window win) +{ + if (!disp) return; + XKillClient(disp, (XID) win); +} + +void +ecore_window_set_border_width(Window win, int bw) +{ + Ecore_XID *xid = NULL; + + if (!disp) return; + xid = ecore_validate_xid(win); + if (xid) + { + xid->bw = bw; + } + XSetWindowBorderWidth(disp, win, bw); +} + +int +ecore_window_get_border_width(Window win) +{ + Ecore_XID *xid = NULL; + + if (!disp) return 0; + + xid = ecore_validate_xid(win); + if (xid) + { + return xid->bw; + } + + return 0; +} + +int +ecore_window_get_wm_size_hints(Window win, XSizeHints * hints, int *mask) +{ + long sup_ret; + Status ok; + + if (!disp) return 0; + + ok = XGetWMNormalHints(disp, win, hints, &sup_ret); + *mask = (int)sup_ret; + return ok; +} + +int +ecore_window_is_visible(Window win) +{ + XWindowAttributes att; + + if (!disp) return 0; + if (win == 0) + win = default_root; + if (XGetWindowAttributes(disp, win, &att) == True) + { + if (att.map_state == IsUnmapped) + return 0; + return 1; + } + return 0; +} + +int +ecore_window_is_normal(Window win) +{ + XWindowAttributes att; + + if (!disp) return 0; + if (win == 0) + win = default_root; + if (XGetWindowAttributes(disp, win, &att) == True) + { + if ((att.override_redirect) || (att.class == InputOnly)) + return 0; + return 1; + } + return 0; +} + +int +ecore_window_is_manageable(Window win) +{ + XWindowAttributes att; + + if (!disp) return 0; + if (win == 0) + win = default_root; + if (XGetWindowAttributes(disp, win, &att) == True) + { + if ((att.map_state == IsUnmapped) || (att.override_redirect) + || (att.class == InputOnly)) + return 0; + return 1; + } + return 0; +} + +void +ecore_windows_restack(Window * wins, int num) +{ + if (!disp) return; + XRestackWindows(disp, wins, num); +} + +void +ecore_window_stack_above(Window win, Window above) +{ + XWindowChanges xwc; + + if (!disp) return; + if (win == 0) + win = default_root; + xwc.sibling = above; + xwc.stack_mode = Above; + XConfigureWindow(disp, win, CWSibling | CWStackMode, &xwc); +} + +void +ecore_window_stack_below(Window win, Window below) +{ + XWindowChanges xwc; + + if (!disp) return; + + if (win == 0) + win = default_root; + xwc.sibling = below; + xwc.stack_mode = Below; + XConfigureWindow(disp, win, CWSibling | CWStackMode, &xwc); +} + +char * +ecore_window_get_title(Window win) +{ + XTextProperty xtp; + + if (!disp) return 0; + + if (win == 0) + win = default_root; + if (XGetWMName(disp, win, &xtp)) + { + int items; + char **list; + Status s; + char *title = NULL; + + if (xtp.format == 8) + { + s = XmbTextPropertyToTextList(disp, &xtp, &list, &items); + if ((s == Success) && (items > 0)) + { + title = strdup(*list); + XFreeStringList(list); + } + else + title = strdup((char *)xtp.value); + } + else + title = strdup((char *)xtp.value); + XFree(xtp.value); + return title; + } + return NULL; +} + +void +ecore_keyboard_grab(Window win) +{ + int status; + + if (!disp) return; + if (keyboard_grab_win) + return; + if (win == 0) + win = default_root; + keyboard_grab_win = win; + status = + XGrabKeyboard(disp, win, False, GrabModeAsync, GrabModeAsync, CurrentTime); + if ((status == AlreadyGrabbed) || (status == GrabNotViewable) + || (status == GrabFrozen) || (status == GrabInvalidTime)) + keyboard_grab_win = 0; +} + +void +ecore_keyboard_ungrab(void) +{ + if (!disp) return; + if (!keyboard_grab_win) + return; + keyboard_grab_win = 0; + XUngrabKeyboard(disp, CurrentTime); +} + +Window +ecore_keyboard_grab_window_get(void) +{ + if (!disp) return 0; + return keyboard_grab_win; +} + +Window +ecore_selection_set(char *string) +{ + Window target = 0; + static Atom dest = 0; + Atom selection; + + if (!disp) return 0; + selection = X_CLIPBOARD_SELECTION; + ECORE_ATOM(dest, "TEXT_SELECTION"); + target = ecore_window_new(0, 0, 0, 77, 7); + ecore_window_add_events(target, XEV_CONFIGURE | XEV_PROPERTY); + XSetSelectionOwner(disp, selection, target, CurrentTime); + if (XGetSelectionOwner(disp, XA_PRIMARY) != target) + { + ecore_window_destroy(target); + return 0; + } + XChangeProperty(disp, target, dest, + XA_STRING, 8, PropModeReplace, string, strlen(string)); + return target; +} + +Window +ecore_selection_request(void) +{ + static Atom dest = 0; + Atom selection; + Window target = 0; + + if (!disp) return 0; + selection = X_CLIPBOARD_SELECTION; + ECORE_ATOM(dest, "TEXT_SELECTION"); + target = ecore_window_new(0, 0, 0, 7, 77); + ecore_window_add_events(target, XEV_CONFIGURE | XEV_PROPERTY); + XConvertSelection(disp, XA_PRIMARY, XA_STRING, dest, target, CurrentTime); + return target; +} + +char * +ecore_selection_get_data(Window win, Atom prop) +{ + char *string = NULL; + long nread; + unsigned long bytes_after, nitems; + unsigned char *data; + Atom actual_type; + int actual_fmt; + + if (!disp) return NULL; + if (prop == None) + return NULL; + for (nread = 0, bytes_after = 1; bytes_after > 0;) + { + if ((XGetWindowProperty(disp, win, prop, nread / 4, + 0x10000, True, AnyPropertyType, + &actual_type, &actual_fmt, &nitems, + &bytes_after, &data) != Success)) + { + IF_FREE(string); + if (data) + { + XFree(data); + } + return NULL; + } + nread += nitems; + + if (actual_type == XA_STRING) + { + if (string) + string = realloc(string, strlen(string) + nitems + 1); + else + { + string = malloc(nitems + 1); + string[0] = 0; + } + string[strlen(string) + nitems] = 0; + strncat(string, data, nitems); + } + else + { + int size, i; + XTextProperty xtextp; + char **cl = NULL; + + xtextp.value = data; + xtextp.encoding = actual_type; + xtextp.format = actual_fmt; + xtextp.nitems = nitems; + XmbTextPropertyToTextList(disp, &xtextp, &cl, &size); + + if (cl) + { + for (i = 0; i < size; i++) + { + if (cl[i]) + { + if (string) + string = + realloc(string, strlen(string) + strlen(cl[i]) + 1); + else + { + string = malloc(strlen(cl[i]) + 1); + string[0] = 0; + } + string[strlen(string) + strlen(cl[i])] = 0; + strcat(string, cl[i]); + } + } + XFreeStringList(cl); + } + } + if (data) + { + XFree(data); + } + } + return string; +} + +void +ecore_set_blank_pointer(Window w) +{ + Cursor c; + XColor cl; + Pixmap p, m; + GC gc; + XGCValues gcv; + + if (!disp) return; + if (w == 0) + w = default_root; + p = XCreatePixmap(disp, w, 1, 1, 1); + m = XCreatePixmap(disp, w, 1, 1, 1); + gc = XCreateGC(disp, m, 0, &gcv); + XSetForeground(disp, gc, 0); + XDrawPoint(disp, m, gc, 0, 0); + XFreeGC(disp, gc); + c = XCreatePixmapCursor(disp, p, m, &cl, &cl, 0, 0); + XDefineCursor(disp, w, c); + XFreeCursor(disp, c); + XFreePixmap(disp, p); + XFreePixmap(disp, m); +} + +Cursor +ecore_cursor_new(Pixmap pmap, Pixmap mask, int x, int y, int fr, int fg, int fb, + int br, int bg, int bb) +{ + XColor cl1, cl2; + + if (!disp) return 0; + cl1.pixel = 0; + cl1.red = fr << 8 | fr; + cl1.green = fg << 8 | fg; + cl1.blue = fb << 8 | fb; + cl1.flags = DoRed | DoGreen | DoBlue; + cl2.pixel = 0; + cl2.red = br << 8 | br; + cl2.green = bg << 8 | bg; + cl2.blue = bb << 8 | bb; + cl2.flags = DoRed | DoGreen | DoBlue; + return XCreatePixmapCursor(disp, pmap, mask, &cl1, &cl2, x, y); +} + +void +ecore_cursor_free(Cursor c) +{ + if (!disp) return; + XFreeCursor(disp, c); +} + +void +ecore_cursor_set(Window win, Cursor c) +{ + if (!disp) return; + if (win == 0) + win = default_root; + XDefineCursor(disp, win, c); +} diff --git a/ecore/src/lib/.cvsignore b/ecore/src/lib/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/ecore/src/lib/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/ecore/src/lib/CVS/Entries b/ecore/src/lib/CVS/Entries new file mode 100644 index 0000000..78afff1 --- /dev/null +++ b/ecore/src/lib/CVS/Entries @@ -0,0 +1,13 @@ +/.cvsignore/1.1/Thu Nov 13 12:30:47 2003//THEAD +/Makefile.am/1.8/Fri Apr 29 05:29:13 2005//THEAD +D/ecore//// +D/ecore_con//// +D/ecore_config//// +D/ecore_dbus//// +D/ecore_evas//// +D/ecore_fb//// +D/ecore_file//// +D/ecore_ipc//// +D/ecore_job//// +D/ecore_txt//// +D/ecore_x//// diff --git a/ecore/src/lib/CVS/Repository b/ecore/src/lib/CVS/Repository new file mode 100644 index 0000000..9ce7be3 --- /dev/null +++ b/ecore/src/lib/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/src/lib diff --git a/ecore/src/lib/CVS/Root b/ecore/src/lib/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/src/lib/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/src/lib/CVS/Tag b/ecore/src/lib/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/src/lib/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/src/lib/Makefile.am b/ecore/src/lib/Makefile.am new file mode 100644 index 0000000..8bfccd9 --- /dev/null +++ b/ecore/src/lib/Makefile.am @@ -0,0 +1,13 @@ +## Process this file with automake to produce Makefile.in +SUBDIRS = \ +ecore \ +ecore_job \ +ecore_txt \ +ecore_fb \ +ecore_con \ +ecore_x \ +ecore_ipc \ +ecore_evas \ +ecore_config \ +ecore_file \ +ecore_dbus diff --git a/ecore/src/lib/ecore/.cvsignore b/ecore/src/lib/ecore/.cvsignore new file mode 100644 index 0000000..78de274 --- /dev/null +++ b/ecore/src/lib/ecore/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +*.lo +libecore.la diff --git a/ecore/src/lib/ecore/CVS/Entries b/ecore/src/lib/ecore/CVS/Entries new file mode 100644 index 0000000..0d13af0 --- /dev/null +++ b/ecore/src/lib/ecore/CVS/Entries @@ -0,0 +1,26 @@ +/.cvsignore/1.2/Mon Mar 29 21:11:30 2004//THEAD +/Ecore.h/1.23/Fri Apr 15 01:22:45 2005//THEAD +/Ecore_Data.h/1.14/Sat Apr 2 15:59:55 2005//THEAD +/Makefile.am/1.9/Thu Mar 10 15:19:36 2005//THEAD +/ecore.c/1.11/Mon Apr 11 15:43:44 2005//THEAD +/ecore_anim.c/1.3/Wed Mar 2 07:06:32 2005//THEAD +/ecore_app.c/1.5/Thu Nov 25 04:07:54 2004//THEAD +/ecore_events.c/1.18/Mon Jun 13 02:30:37 2005//THEAD +/ecore_exe.c/1.8/Thu Jul 7 03:31:34 2005//THEAD +/ecore_hash.c/1.11/Wed Mar 2 07:06:32 2005//THEAD +/ecore_idle_enterer.c/1.5/Sat May 8 04:44:03 2004//THEAD +/ecore_idle_exiter.c/1.3/Sat May 8 04:44:03 2004//THEAD +/ecore_idler.c/1.5/Sat May 8 04:44:03 2004//THEAD +/ecore_main.c/1.18/Mon Mar 28 09:00:08 2005//THEAD +/ecore_path.c/1.6/Tue Jan 4 22:45:05 2005//THEAD +/ecore_plugin.c/1.4/Wed Oct 20 17:51:27 2004//THEAD +/ecore_private.h/1.14/Sat May 28 03:57:17 2005//THEAD +/ecore_sheap.c/1.5/Sat Jan 29 02:13:12 2005//THEAD +/ecore_signal.c/1.16/Wed Mar 2 07:06:33 2005//THEAD +/ecore_time.c/1.5/Wed Oct 20 17:51:28 2004//THEAD +/ecore_timer.c/1.12/Mon Apr 4 16:01:39 2005//THEAD +/ecore_tree.c/1.4/Tue Jan 4 22:45:06 2005//THEAD +/ecore_value.c/1.5/Wed Mar 2 07:06:33 2005//THEAD +/ecore_list.c/1.16/Sat Jul 23 17:35:06 2005//THEAD +/ecore_strings.c/1.7/Sat Jul 23 17:35:06 2005//THEAD +D diff --git a/ecore/src/lib/ecore/CVS/Repository b/ecore/src/lib/ecore/CVS/Repository new file mode 100644 index 0000000..69e64ae --- /dev/null +++ b/ecore/src/lib/ecore/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/src/lib/ecore diff --git a/ecore/src/lib/ecore/CVS/Root b/ecore/src/lib/ecore/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/src/lib/ecore/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/src/lib/ecore/CVS/Tag b/ecore/src/lib/ecore/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/src/lib/ecore/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/src/lib/ecore/Ecore.h b/ecore/src/lib/ecore/Ecore.h new file mode 100644 index 0000000..308262d --- /dev/null +++ b/ecore/src/lib/ecore/Ecore.h @@ -0,0 +1,254 @@ +#ifndef _ECORE_H +#define _ECORE_H + +#ifdef EAPI +#undef EAPI +#endif +#ifdef WIN32 +# ifdef BUILDING_DLL +# define EAPI __declspec(dllexport) +# else +# define EAPI __declspec(dllimport) +# endif +#else +# ifdef GCC_HASCLASSVISIBILITY +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +#endif + +/** + * @file Ecore.h + * @brief The file that provides the program utility, main loop and timer + * functions. + * + * This header provides the Ecore event handling loop. For more + * details, see @ref Ecore_Main_Loop_Group. + * + * For the main loop to be of any use, you need to be able to add events + * and event handlers. Events for file descriptor events are covered in + * @ref Ecore_FD_Handler_Group. + * + * Time functions are covered in @ref Ecore_Time_Group. + * + * There is also provision for callbacks for when the loop enters or + * exits an idle state. See @ref Idle_Group for more information. + * + * Functions are also provided for spawning child processes using fork. + * See @ref Ecore_Exe_Basic_Group and @ref Ecore_Exe_Signal_Group for + * more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +#ifndef MIN +#define MIN(x, y) (((x) > (y)) ? (y) : (x)) +#endif + +#ifndef MAX +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#endif + +#ifndef ABS +#define ABS(x) ((x) < 0 ? -(x) : (x)) +#endif + +#ifndef CLAMP +#define CLAMP(x, min, max) (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x))) +#endif + +#define ECORE_EVENT_NONE 0 +#define ECORE_EVENT_EXE_EXIT 1 /**< Spawned Exe has exit event */ +#define ECORE_EVENT_SIGNAL_USER 2 /**< User signal event */ +#define ECORE_EVENT_SIGNAL_HUP 3 /**< Hup signal event */ +#define ECORE_EVENT_SIGNAL_EXIT 4 /**< Exit signal event */ +#define ECORE_EVENT_SIGNAL_POWER 5 /**< Power signal event */ +#define ECORE_EVENT_SIGNAL_REALTIME 6 /**< Realtime signal event */ +#define ECORE_EVENT_COUNT 7 + +#ifndef _ECORE_PRIVATE_H + enum _Ecore_Fd_Handler_Flags + { + ECORE_FD_READ = 1, /**< Fd Read mask */ + ECORE_FD_WRITE = 2, /**< Fd Write mask */ + ECORE_FD_ERROR = 4 /**< Fd Error mask */ + }; + typedef enum _Ecore_Fd_Handler_Flags Ecore_Fd_Handler_Flags; + +#ifndef WIN32 + typedef void Ecore_Exe; /**< A handle for spawned processes */ +#endif + typedef void Ecore_Timer; /**< A handle for timers */ + typedef void Ecore_Idler; /**< A handle for idlers */ + typedef void Ecore_Idle_Enterer; /**< A handle for idle enterers */ + typedef void Ecore_Idle_Exiter; /**< A handle for idle exiters */ + typedef void Ecore_Fd_Handler; /**< A handle for Fd hanlders */ + typedef void Ecore_Event_Handler; /**< A handle for an event handler */ + typedef void Ecore_Event_Filter; /**< A handle for an event filter */ + typedef void Ecore_Event; /**< A handle for an event */ + typedef void Ecore_Animator; /**< A handle for animators */ +#endif + typedef struct _Ecore_Event_Exe_Exit Ecore_Event_Exe_Exit; /**< Spawned Exe exit event */ + typedef struct _Ecore_Event_Signal_User Ecore_Event_Signal_User; /**< User signal event */ + typedef struct _Ecore_Event_Signal_Hup Ecore_Event_Signal_Hup; /**< Hup signal event */ + typedef struct _Ecore_Event_Signal_Exit Ecore_Event_Signal_Exit; /**< Exit signal event */ + typedef struct _Ecore_Event_Signal_Power Ecore_Event_Signal_Power; /**< Power signal event */ + typedef struct _Ecore_Event_Signal_Realtime Ecore_Event_Signal_Realtime; /**< Realtime signal event */ + +#ifndef WIN32 + struct _Ecore_Event_Exe_Exit /** Process exit event */ + { + pid_t pid; /**< The process ID of the process that exited */ + int exit_code; /**< The exit code of the process */ + Ecore_Exe *exe; /**< The handle to the exited process, or NULL if not found */ + int exit_signal; /** < The signal that caused the process to exit */ + char exited : 1; /** < set to 1 if the process exited of its own accord */ + char signalled : 1; /** < set to 1 id the process exited due to uncaught signal */ + void *ext_data; /**< Extension data - not used */ + siginfo_t data; /**< Signal info */ + }; +#endif + + struct _Ecore_Event_Signal_User /** User signal event */ + { + int number; /**< The signal number. Either 1 or 2 */ + void *ext_data; /**< Extension data - not used */ + +#ifndef WIN32 + siginfo_t data; /**< Signal info */ +#endif + }; + + struct _Ecore_Event_Signal_Hup /** Hup signal event */ + { + void *ext_data; /**< Extension data - not used */ + +#ifndef WIN32 + siginfo_t data; /**< Signal info */ +#endif + }; + + struct _Ecore_Event_Signal_Exit /** Exit request event */ + { + int interrupt : 1; /**< Set if the exit request was an interrupt signal*/ + int quit : 1; /**< set if the exit request was a quit signal */ + int terminate : 1; /**< Set if the exit request was a terminate singal */ + void *ext_data; /**< Extension data - not used */ + +#ifndef WIN32 + siginfo_t data; /**< Signal info */ +#endif + }; + + struct _Ecore_Event_Signal_Power /** Power event */ + { + void *ext_data; /**< Extension data - not used */ + +#ifndef WIN32 + siginfo_t data; /**< Signal info */ +#endif + }; + + struct _Ecore_Event_Signal_Realtime /** Realtime event */ + { + int num; /**< The realtime signal's number */ + +#ifndef WIN32 + siginfo_t data; /**< Signal info */ +#endif + }; + + EAPI int ecore_init(void); + EAPI int ecore_shutdown(void); + + EAPI void ecore_app_args_set(int argc, const char **argv); + EAPI void ecore_app_args_get(int *argc, char ***argv); + EAPI void ecore_app_restart(void); + + EAPI Ecore_Event_Handler *ecore_event_handler_add(int type, int (*func) (void *data, int type, void *event), const void *data); + EAPI void *ecore_event_handler_del(Ecore_Event_Handler *event_handler); + EAPI Ecore_Event *ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data); + EAPI void *ecore_event_del(Ecore_Event *event); + EAPI int ecore_event_type_new(void); + EAPI Ecore_Event_Filter *ecore_event_filter_add(void * (*func_start) (void *data), int (*func_filter) (void *data, void *loop_data, int type, void *event), void (*func_end) (void *data, void *loop_data), const void *data); + EAPI void *ecore_event_filter_del(Ecore_Event_Filter *ef); + EAPI int ecore_event_current_type_get(void); + EAPI void *ecore_event_current_event_get(void); + + +#ifndef WIN32 + EAPI Ecore_Exe *ecore_exe_run(const char *exe_cmd, const void *data); + EAPI void *ecore_exe_free(Ecore_Exe *exe); + EAPI pid_t ecore_exe_pid_get(Ecore_Exe *exe); + EAPI void *ecore_exe_data_get(Ecore_Exe *exe); + EAPI void ecore_exe_pause(Ecore_Exe *exe); + EAPI void ecore_exe_continue(Ecore_Exe *exe); + EAPI void ecore_exe_terminate(Ecore_Exe *exe); + EAPI void ecore_exe_kill(Ecore_Exe *exe); + EAPI void ecore_exe_signal(Ecore_Exe *exe, int num); + EAPI void ecore_exe_hup(Ecore_Exe *exe); +#endif + + EAPI Ecore_Idler *ecore_idler_add(int (*func) (void *data), const void *data); + EAPI void *ecore_idler_del(Ecore_Idler *idler); + + EAPI Ecore_Idle_Enterer *ecore_idle_enterer_add(int (*func) (void *data), const void *data); + EAPI void *ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer); + + EAPI Ecore_Idle_Exiter *ecore_idle_exiter_add(int (*func) (void *data), const void *data); + EAPI void *ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter); + + EAPI void ecore_main_loop_iterate(void); + EAPI void ecore_main_loop_begin(void); + EAPI void ecore_main_loop_quit(void); + EAPI Ecore_Fd_Handler *ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, int (*func) (void *data, Ecore_Fd_Handler *fd_handler), const void *data, int (*buf_func) (void *buf_data, Ecore_Fd_Handler *fd_handler), const void *buf_data); + EAPI void ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, void (*func) (void *data, Ecore_Fd_Handler *fd_handler), const void *data); + EAPI void *ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler); + EAPI int ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler); + EAPI int ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags); + EAPI void ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags); + + EAPI double ecore_time_get(void); + + EAPI Ecore_Timer *ecore_timer_add(double in, int (*func) (void *data), const void *data); + EAPI void *ecore_timer_del(Ecore_Timer *timer); + EAPI void ecore_timer_interval_set(Ecore_Timer *timer, double in); + + EAPI Ecore_Animator *ecore_animator_add(int (*func) (void *data), const void *data); + EAPI void *ecore_animator_del(Ecore_Animator *animator); + EAPI void ecore_animator_frametime_set(double frametime); + EAPI double ecore_animator_frametime_get(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ecore/src/lib/ecore/Ecore_Data.h b/ecore/src/lib/ecore/Ecore_Data.h new file mode 100644 index 0000000..117f96c --- /dev/null +++ b/ecore/src/lib/ecore/Ecore_Data.h @@ -0,0 +1,591 @@ +#ifndef _ECORE_DATA_H +# define _ECORE_DATA_H + +/** + * @file Ecore_Data.h + * @brief Contains threading, list, hash, debugging and tree functions. + */ + +# ifdef __cplusplus +extern "C" { +# endif + +#ifdef __sgi +#define __FUNCTION__ "unknown" +#ifndef __cplusplus +#define inline +#endif +#endif + +# define PRIME_TABLE_MAX 21 +# define PRIME_MIN 17 +# define PRIME_MAX 16777213 + + extern const unsigned int ecore_prime_table[]; + + typedef void (*Ecore_For_Each) (void *value, void *user_data); +# define ECORE_FOR_EACH(function) ((Ecore_For_Each)function) + + typedef void (*Ecore_Free_Cb) (void *data); +# define ECORE_FREE_CB(func) ((Ecore_Free_Cb)func) + + typedef unsigned int (*Ecore_Hash_Cb) (void *key); +# define ECORE_HASH_CB(function) ((Ecore_Hash_Cb)function) + + typedef int (*Ecore_Compare_Cb) (void *data1, void *data2); +# define ECORE_COMPARE_CB(function) ((Ecore_Compare_Cb)function) + + int ecore_direct_compare(void *key1, void *key2); + int ecore_str_compare(void *key1, void *key2); + + unsigned int ecore_direct_hash(void *key); + unsigned int ecore_str_hash(void *key); + + +# ifdef HAVE_PTHREADS /* pthreads are installed */ + +# include + +# define ECORE_DECLARE_LOCKS \ + struct { \ + int readers; \ + pthread_mutex_t readers_mutex; \ + pthread_mutex_t writers_mutex; \ + pthread_cond_t readers_cond; \ + } locks + +# define ECORE_INIT_LOCKS(structure) \ + if (structure) { \ + structure->readers = 0; \ + pthread_mutex_init(&structure->locks.readers_mutex, NULL); \ + pthread_mutex_init(&structure->locks.writers_mutex, NULL); \ + pthread_cond_init(&structure->locks.readers_cond, NULL); \ + } + +# define ECORE_DESTROY_LOCKS(structure) \ + if (structure) { \ + pthread_mutex_destroy(&structure->locks.readers_mutex); \ + pthread_mutex_destroy(&structure->locks.writers_mutex); \ + pthread_cond_destroy(&structure->readers_cond); \ + } + +# define ECORE_READ_LOCK(structure) \ + if (structure) { \ + pthread_mutex_lock(&structure->locks.readers_mutex); \ + structure->locks.readers++; \ + pthread_mutex_unlock(&structure->locks.readers_mutex); \ + } + +# define ECORE_READ_UNLOCK(structure) \ + if (structure) { \ + pthread_mutex_lock(&structure->locks.readers_mutex); \ + if (--structure->locks.readers == 0) \ + pthread_cond_broadcast(&structure->locks.readers_cond); \ + pthread_mutex_unlock(&structure->locks.readers_mutex); \ + } + +# define ECORE_WRITE_LOCK(structure) \ + if (structure) { \ + pthread_mutex_lock(&structure->locks.readers_mutex); \ + pthread_mutex_lock(&structure->locks.writers_mutex); \ + while (structure->locks.readers > 0) \ + pthread_cond_wait(&structure->locks.readers_cond, \ + &structure->locks.readers_mutex); \ + pthread_mutex_unlock(&structure->locks.readers_mutex); \ + } + +# define ECORE_WRITE_UNLOCK(structure) \ + if (structure) \ + pthread_mutex_unlock(&structure->locks.writers_mutex); \ + +# define ECORE_THREAD_CREATE(function, arg) \ + if (function) { \ + pthread_t thread; \ + pthread_create(&thread, NULL, function, arg); \ + pthread_detach(thread); \ + } + +# define ECORE_NO_THREADS(function, arg) + +# else /* No pthreads available */ + +# define ECORE_DECLARE_LOCKS +# define ECORE_INIT_LOCKS(structure) +# define ECORE_READ_LOCK(structure) +# define ECORE_READ_UNLOCK(structure) +# define ECORE_WRITE_LOCK(structure) +# define ECORE_WRITE_UNLOCK(structure) +# define ECORE_THREAD_CREATE(function, args) +# define ECORE_DESTROY_LOCKS(structure) + +# define ECORE_NO_THREADS(function, arg) if (function) function(arg); + +# endif /* HAVE_PTHREADS */ + + typedef struct _ecore_list Ecore_List; +# define ECORE_LIST(list) ((Ecore_List *)list) + + typedef struct _ecore_list_node Ecore_List_Node; +# define ECORE_LIST_NODE(node) ((Ecore_List_Node *)node) + + struct _ecore_list_node { + void *data; + struct _ecore_list_node *next; + + ECORE_DECLARE_LOCKS; + }; + + struct _ecore_list { + Ecore_List_Node *first; /* The first node in the list */ + Ecore_List_Node *last; /* The last node in the list */ + Ecore_List_Node *current; /* The current node in the list */ + + Ecore_Free_Cb free_func; /* The callback to free data in nodes */ + + int nodes; /* The number of nodes in the list */ + int index; /* The position from the front of the + list of current node */ + ECORE_DECLARE_LOCKS; + }; + + + /* Creating and initializing new list structures */ + Ecore_List *ecore_list_new(void); + int ecore_list_init(Ecore_List *list); + + /* Adding items to the list */ + inline int ecore_list_append(Ecore_List * list, void *_data); + inline int ecore_list_prepend(Ecore_List * list, void *_data); + inline int ecore_list_insert(Ecore_List * list, void *_data); + + /* Removing items from the list */ + inline int ecore_list_remove_destroy(Ecore_List *list); + inline void *ecore_list_remove(Ecore_List * list); + inline void *ecore_list_remove_first(Ecore_List * list); + inline void *ecore_list_remove_last(Ecore_List * list); + + /* Retrieve the current position in the list */ + inline void *ecore_list_current(Ecore_List * list); + int ecore_list_index(Ecore_List * list); + int ecore_list_nodes(Ecore_List * list); + + /* Traversing the list */ + int ecore_list_for_each(Ecore_List *list, Ecore_For_Each function, + void *user_data); + inline void *ecore_list_goto_first(Ecore_List * list); + inline void *ecore_list_goto_last(Ecore_List * list); + inline void *ecore_list_goto_index(Ecore_List * list, int index); + inline void *ecore_list_goto(Ecore_List * list, void *_data); + + /* Traversing the list and returning data */ + inline void *ecore_list_next(Ecore_List * list); + + /* Check to see if there is any data in the list */ + int ecore_list_is_empty(Ecore_List * list); + + /* Remove every node in the list without freeing the list itself */ + int ecore_list_clear(Ecore_List * list); + /* Free the list and it's contents */ + void ecore_list_destroy(Ecore_List *list); + + /* Creating and initializing list nodes */ + Ecore_List_Node *ecore_list_node_new(void); + int ecore_list_node_init(Ecore_List_Node *newNode); + + /* Destroying nodes */ + int ecore_list_node_destroy(Ecore_List_Node * _e_node, Ecore_Free_Cb free_func); + + int ecore_list_set_free_cb(Ecore_List * list, Ecore_Free_Cb free_func); + + typedef Ecore_List Ecore_DList; +# define ECORE_DLIST(dlist) ((Ecore_DList *)dlist) + + typedef struct _ecore_dlist_node Ecore_DList_Node; +# define ECORE_DLIST_NODE(dlist) ((Ecore_DList_Node *)dlist) + + struct _ecore_dlist_node { + Ecore_List_Node single; + Ecore_DList_Node *previous; + }; + + /* Creating and initializing new list structures */ + Ecore_DList *ecore_dlist_new(void); + int ecore_dlist_init(Ecore_DList *list); + void ecore_dlist_destroy(Ecore_DList *list); + + /* Adding items to the list */ + int ecore_dlist_append(Ecore_DList * _e_dlist, void *_data); + int ecore_dlist_prepend(Ecore_DList * _e_dlist, void *_data); + int ecore_dlist_insert(Ecore_DList * _e_dlist, void *_data); + + /* Info about list's state */ + void *ecore_dlist_current(Ecore_DList *list); + int ecore_dlist_index(Ecore_DList *list); +# define ecore_dlist_nodes(list) ecore_list_nodes(ECORE_LIST(list)) + + /* Removing items from the list */ + void *ecore_dlist_remove(Ecore_DList * _e_dlist); + void *ecore_dlist_remove_first(Ecore_DList * _e_dlist); + int ecore_dlist_remove_destroy(Ecore_DList *list); + void *ecore_dlist_remove_last(Ecore_DList * _e_dlist); + + /* Traversing the list */ +# define ecore_dlist_for_each(list, function, user_data) \ + ecore_list_for_each(ECORE_LIST(list), function, user_data) + inline void *ecore_dlist_goto_first(Ecore_DList * _e_dlist); + inline void *ecore_dlist_goto_last(Ecore_DList * _e_dlist); + inline void *ecore_dlist_goto_index(Ecore_DList * _e_dlist, int index); + inline void *ecore_dlist_goto(Ecore_DList * _e_dlist, void *_data); + + /* Traversing the list and returning data */ + inline void *ecore_dlist_next(Ecore_DList * list); + inline void *ecore_dlist_previous(Ecore_DList * list); + + /* Check to see if there is any data in the list */ + int ecore_dlist_is_empty(Ecore_DList * _e_dlist); + + /* Remove every node in the list without free'ing it */ + int ecore_dlist_clear(Ecore_DList * _e_dlist); + + /* Creating and initializing list nodes */ + int ecore_dlist_node_init(Ecore_DList_Node * node); + Ecore_DList_Node *ecore_dlist_node_new(void); + + /* Destroying nodes */ + int ecore_dlist_node_destroy(Ecore_DList_Node * node, Ecore_Free_Cb free_func); + + int ecore_dlist_set_free_cb(Ecore_DList * dlist, Ecore_Free_Cb free_func); + + + + /* + * Hash Table Implementation: + * + * Traditional hash table implementation. I had tried a list of tables + * approach to save on the realloc's but it ended up being much slower than + * the traditional approach. + */ + + typedef struct _ecore_hash_node Ecore_Hash_Node; +# define ECORE_HASH_NODE(hash) ((Ecore_Hash_Node *)hash) + + struct _ecore_hash_node { + void *key; /* The key for the data node */ + void *value; /* The value associated with this node */ + + ECORE_DECLARE_LOCKS; + }; + + typedef struct _ecore_hash Ecore_Hash; +# define ECORE_HASH(hash) ((Ecore_Hash *)hash) + + struct _ecore_hash { + Ecore_List **buckets; + int size; /* An index into the table of primes to + determine size */ + int nodes; /* The number of nodes currently in the hash */ + + int index; /* The current index into the bucket table */ + + Ecore_Compare_Cb compare; /* The function used to compare node values */ + Ecore_Hash_Cb hash_func; /* The function used to compare node values */ + + Ecore_Free_Cb free_key; /* The callback function to free key */ + Ecore_Free_Cb free_value; /* The callback function to determine hash */ + + ECORE_DECLARE_LOCKS; + }; + + /* Create and initialize a hash */ + Ecore_Hash *ecore_hash_new(Ecore_Hash_Cb hash_func, Ecore_Compare_Cb compare); + int ecore_hash_init(Ecore_Hash *hash, Ecore_Hash_Cb hash_func, Ecore_Compare_Cb compare); + + /* Functions related to freeing the data in the hash table */ + int ecore_hash_set_free_key(Ecore_Hash *hash, Ecore_Free_Cb function); + int ecore_hash_set_free_value(Ecore_Hash *hash, Ecore_Free_Cb function); + void ecore_hash_destroy(Ecore_Hash *hash); + + int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func, + void *user_data); + Ecore_List *ecore_hash_keys(Ecore_Hash *hash); + + /* Retrieve and store data into the hash */ + void *ecore_hash_get(Ecore_Hash *hash, void *key); + int ecore_hash_set(Ecore_Hash *hash, void *key, void *value); + void *ecore_hash_remove(Ecore_Hash *hash, void *key); + void ecore_hash_dump_graph(Ecore_Hash *hash); + + + inline void ecore_print_warning(const char *function, const char *sparam); + + /* Wrappers around free() that helps debug free() bugs such as freeing NULL + * or accessing a pointer that has already been freed */ +# ifndef IF_FREE +# define IF_FREE(ptr) if (ptr) free(ptr); ptr = NULL; +# endif + +# ifndef FREE +# define FREE(ptr) free(ptr); ptr = NULL; +# endif + + /* Debugging printf, basically a wrapper to fprintf that checks the level + * of the message and checks that it is to be printed at the current debugging + * level */ +# ifndef DPRINTF +# ifdef __sgi +# define DPRINTF(debug, format, args) \ + if (debug >= DEBUG_LEVEL) \ + fprintf(stderr, format, args); +# else +# define DPRINTF(debug, format, args...) \ + if (debug >= DEBUG_LEVEL) \ + fprintf(stderr, format, args); +# endif +# endif + + + /* convenience macros for checking pointer parameters for non-NULL */ +# ifndef CHECK_PARAM_POINTER_RETURN +# define CHECK_PARAM_POINTER_RETURN(sparam, param, ret) \ + if (!(param)) \ + { \ + ecore_print_warning(__FUNCTION__, sparam); \ + return ret; \ + } +# endif + +# ifndef CHECK_PARAM_POINTER +# define CHECK_PARAM_POINTER(sparam, param) \ + if (!(param)) \ + { \ + ecore_print_warning(__FUNCTION__, sparam); \ + return; \ + } +# endif + + /* Use the larger of a and b */ +# ifndef MAX +# define MAX(a, b) (((a) > (b)) ? (a) : (b)) +# endif + + /* Use the smaller of a and b */ +# ifndef MIN +# define MIN(a, b) (((a) < (b)) ? (a) : (b)) +# endif + + + typedef struct _ecore_path_group Ecore_Path_Group; + struct _ecore_path_group + { + int id; + char *name; + Ecore_List *paths; + }; + + /* + * Create a new path group + */ + int ecore_path_group_new(char *group_name); + + /* + * Destroy a previous path group + */ + void ecore_path_group_del(int group_id); + + /* + * Add a directory to be searched for files + */ + void ecore_path_group_add(int group_id, char *path); + + /* + * Remove a directory to be searched for files + */ + void ecore_path_group_remove(int group_id, char *path); + + /* + * Find the absolute path if it exists in the group of paths + */ + char * ecore_path_group_find(int group_id, char *name); + + /* + * Get a list of all the available files in a path set + */ + Ecore_List * ecore_path_group_available(int group_id); + + + typedef struct _ecore_plugin Ecore_Plugin; + struct _ecore_plugin + { + int group; + char *name; + void *handle; + }; + + /* + * Load the specified plugin + */ + Ecore_Plugin *ecore_plugin_load(int group_id, char *plugin); + + /* + * Unload the specified plugin + */ + void ecore_plugin_unload(Ecore_Plugin * plugin); + + /* + * Lookup the specified symbol for the plugin + */ + void *ecore_plugin_call(Ecore_Plugin * plugin, char *symbol_name); + + Ecore_List *ecore_plugin_get_available(int group_id); + + +# define ECORE_SHEAP_MIN 0 +# define ECORE_SHEAP_MAX 1 + +# define HEAP_INCREMENT 4096 + +# define PARENT(i) (i / 2) +# define LEFT(i) (2 * i) +# define RIGHT(i) (2 * i + 1) + + typedef struct _ecore_heap Ecore_Sheap; +# define ECORE_HEAP(heap) ((Ecore_Sheap *)heap) + + struct _ecore_heap { + void **data; + int size; + int space; + + char order, sorted; + + /* Callback for comparing node values, default is direct comparison */ + Ecore_Compare_Cb compare; + + /* Callback for freeing node data, default is NULL */ + Ecore_Free_Cb free_func; + }; + + Ecore_Sheap *ecore_sheap_new(Ecore_Compare_Cb compare, int size); + void ecore_sheap_destroy(Ecore_Sheap *heap); + int ecore_sheap_init(Ecore_Sheap *heap, Ecore_Compare_Cb compare, int size); + int ecore_sheap_set_free_cb(Ecore_Sheap *heap, Ecore_Free_Cb free_func); + int ecore_sheap_insert(Ecore_Sheap *heap, void *data); + void *ecore_sheap_extract(Ecore_Sheap *heap); + void *ecore_sheap_extreme(Ecore_Sheap *heap); + int ecore_sheap_change(Ecore_Sheap *heap, void *item, void *newval); + int ecore_sheap_set_compare(Ecore_Sheap *heap, Ecore_Compare_Cb compare); + void ecore_sheap_set_order(Ecore_Sheap *heap, char order); + void ecore_sheap_sort(Ecore_Sheap *heap); + + inline void *ecore_sheap_item(Ecore_Sheap *heap, int i); + + + typedef struct _ecore_string Ecore_String; + struct _ecore_string { + char *string; + int references; + }; + + char *ecore_string_instance(char *string); + void ecore_string_release(char *string); + + + typedef struct _Ecore_Tree_Node Ecore_Tree_Node; +# define ECORE_TREE_NODE(object) ((Ecore_Tree_Node *)object) + struct _Ecore_Tree_Node { + + /* The actual data for each node */ + void *key; + void *value; + + /* Pointers to surrounding nodes */ + Ecore_Tree_Node *parent; + Ecore_Tree_Node *left_child; + Ecore_Tree_Node *right_child; + + /* Book keeping information for quicker balancing of the tree */ + int max_right; + int max_left; + + ECORE_DECLARE_LOCKS; + }; + + typedef struct _Ecore_Tree Ecore_Tree; +# define ECORE_TREE(object) ((Ecore_Tree *)object) + struct _Ecore_Tree { + /* Nodes of the tree */ + Ecore_Tree_Node *tree; + + /* Callback for comparing node values, default is direct comparison */ + Ecore_Compare_Cb compare_func; + + /* Callback for freeing node data, default is NULL */ + Ecore_Free_Cb free_func; + + ECORE_DECLARE_LOCKS; + }; + + /* Some basic tree functions */ + /* Allocate and initialize a new tree */ + Ecore_Tree *ecore_tree_new(Ecore_Compare_Cb compare_func); + /* Initialize a new tree */ + int ecore_tree_init(Ecore_Tree * tree, Ecore_Compare_Cb compare_func); + + /* Free the tree */ + int ecore_tree_destroy(Ecore_Tree * tree); + /* Check to see if the tree has any nodes in it */ + int ecore_tree_is_empty(Ecore_Tree * tree); + + /* Retrieve the value associated with key */ + void *ecore_tree_get(Ecore_Tree * tree, void *key); + Ecore_Tree_Node *ecore_tree_get_node(Ecore_Tree * tree, void *key); + /* Retrieve the value of node with key greater than or equal to key */ + void *ecore_tree_get_closest_larger(Ecore_Tree * tree, void *key); + /* Retrieve the value of node with key less than or equal to key */ + void *ecore_tree_get_closest_smaller(Ecore_Tree * tree, void *key); + + /* Set the value associated with key to value */ + int ecore_tree_set(Ecore_Tree * tree, void *key, void *value); + /* Remove the key from the tree */ + int ecore_tree_remove(Ecore_Tree * tree, void *key); + + /* Add a node to the tree */ + int ecore_tree_add_node(Ecore_Tree * tree, Ecore_Tree_Node * node); + /* Remove a node from the tree */ + int ecore_tree_remove_node(Ecore_Tree * tree, Ecore_Tree_Node * node); + + /* For each node in the tree perform the for_each_func function */ + /* For this one pass in the node */ + int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func, + void *user_data); + /* And here pass in the node's value */ + int ecore_tree_for_each_node_value(Ecore_Tree * tree, + Ecore_For_Each for_each_func, + void *user_data); + + /* Some basic node functions */ + /* Initialize a node */ + int ecore_tree_node_init(Ecore_Tree_Node * new_node); + /* Allocate and initialize a new node */ + Ecore_Tree_Node *ecore_tree_node_new(void); + /* Free the desired node */ + int ecore_tree_node_destroy(Ecore_Tree_Node * node, Ecore_Free_Cb free_data); + + /* Set the node's key to key */ + int ecore_tree_node_key_set(Ecore_Tree_Node * node, void *key); + /* Retrieve the key in node */ + void *ecore_tree_node_key_get(Ecore_Tree_Node * node); + + /* Set the node's value to value */ + int ecore_tree_node_value_set(Ecore_Tree_Node * node, void *value); + /* Retrieve the value in node */ + void *ecore_tree_node_value_get(Ecore_Tree_Node * node); + + /* Add a function to free the data stored in nodes */ + int ecore_tree_set_free_cb(Ecore_Tree * tree, Ecore_Free_Cb free_func); + +#ifdef __cplusplus +} +#endif +#endif /* _ECORE_DATA_H */ + diff --git a/ecore/src/lib/ecore/Makefile.am b/ecore/src/lib/ecore/Makefile.am new file mode 100644 index 0000000..c0bdd3a --- /dev/null +++ b/ecore/src/lib/ecore/Makefile.am @@ -0,0 +1,34 @@ +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = + +lib_LTLIBRARIES = libecore.la +include_HEADERS = \ +Ecore.h \ +Ecore_Data.h + +libecore_la_SOURCES = \ +ecore.c \ +ecore_app.c \ +ecore_anim.c \ +ecore_events.c \ +ecore_exe.c \ +ecore_hash.c \ +ecore_idle_enterer.c \ +ecore_idle_exiter.c \ +ecore_idler.c \ +ecore_list.c \ +ecore_main.c \ +ecore_path.c \ +ecore_plugin.c \ +ecore_sheap.c \ +ecore_signal.c \ +ecore_strings.c \ +ecore_time.c \ +ecore_timer.c \ +ecore_tree.c \ +ecore_value.c \ +ecore_private.h + +libecore_la_LIBADD = -lm @dlopen_libs@ @winsock_libs@ +libecore_la_LDFLAGS = -version-info 1:0:0 diff --git a/ecore/src/lib/ecore/ecore.c b/ecore/src/lib/ecore/ecore.c new file mode 100644 index 0000000..3e6b2a8 --- /dev/null +++ b/ecore/src/lib/ecore/ecore.c @@ -0,0 +1,236 @@ +#include "ecore_private.h" +#include "Ecore.h" +#include +#include + +static const char *_ecore_magic_string_get(Ecore_Magic m); +static int _ecore_init_count = 0; + +#ifndef WIN32 +int _ecore_fps_debug = 0; +#endif + +/** OpenBSD does not define CODESET + * FIXME ?? + */ + +#ifndef CODESET +#define CODESET "INVALID" +#endif + +/** + * Set up connections, signal handlers, sockets etc. + * @return 1 or greater on success, 0 otherwise + * + * This function sets up all singal handlers and the basic event loop. If it + * succeeds, 1 will be returned, otherwise 0 will be returned. + * + * @code + * #include + * + * int main(int argc, char **argv) + * { + * if (!ecore_init()) + * { + * printf("ERROR: Cannot init Ecore!\n"); + * return -1; + * } + * ecore_main_loop_begin(); + * ecore_shutdown(); + * } + * @endcode + */ +int +ecore_init(void) +{ + if (++_ecore_init_count == 1) + { + setlocale(LC_CTYPE, ""); + if (strcmp(nl_langinfo(CODESET), "UTF-8")) + { +// printf("WARNING: not a utf8 locale!\n"); + } +#ifndef WIN32 + if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1; + if (_ecore_fps_debug) _ecore_fps_debug_init(); + _ecore_signal_init(); +#endif + } + + return _ecore_init_count; +} + +/** + * Shut down connections, signal handlers sockets etc. + * + * This function shuts down all things set up in ecore_init() and cleans up all + * event queues, handlers, filters, timers, idlers, idle enterers/exiters + * etc. set up after ecore_init() was called. + * + * Do not call this function from any callback that may be called from the main + * loop, as the main loop will then fall over and not function properly. + */ +int +ecore_shutdown(void) +{ + if (--_ecore_init_count) + return _ecore_init_count; + +#ifndef WIN32 + if (_ecore_fps_debug) _ecore_fps_debug_shutdown(); +#endif + _ecore_animator_shutdown(); +#ifndef WIN32 + _ecore_exe_shutdown(); +#endif + _ecore_idle_enterer_shutdown(); + _ecore_idle_exiter_shutdown(); + _ecore_idler_shutdown(); + _ecore_timer_shutdown(); + _ecore_event_shutdown(); + _ecore_main_shutdown(); +#ifndef WIN32 + _ecore_signal_shutdown(); +#endif + + return _ecore_init_count; +} + +void +_ecore_magic_fail(void *d, Ecore_Magic m, Ecore_Magic req_m, const char *fname) +{ + fprintf(stderr, + "\n" + "*** ECORE ERROR: Ecore Magic Check Failed!!!\n" + "*** IN FUNCTION: %s()\n", fname); + if (!d) + fprintf(stderr, " Input handle pointer is NULL!\n"); + else if (m == ECORE_MAGIC_NONE) + fprintf(stderr, " Input handle has already been freed!\n"); + else if (m != req_m) + fprintf(stderr, " Input handle is wrong type\n" + " Expected: %08x - %s\n" + " Supplied: %08x - %s\n", + (unsigned int)req_m, _ecore_magic_string_get(req_m), + (unsigned int)m, _ecore_magic_string_get(m)); + fprintf(stderr, + "*** NAUGHTY PROGRAMMER!!!\n" + "*** SPANK SPANK SPANK!!!\n" + "*** Now go fix your code. Tut tut tut!\n" + "\n"); + if (getenv("ECORE_ERROR_ABORT")) abort(); +} + +static const char * +_ecore_magic_string_get(Ecore_Magic m) +{ + switch (m) + { + case ECORE_MAGIC_NONE: + return "None (Freed Object)"; + break; + case ECORE_MAGIC_EXE: + return "Ecore_Exe (Executable)"; + break; + case ECORE_MAGIC_TIMER: + return "Ecore_Timer (Timer)"; + break; + case ECORE_MAGIC_IDLER: + return "Ecore_Idler (Idler)"; + break; + case ECORE_MAGIC_IDLE_ENTERER: + return "Ecore_Idle_Enterer (Idler Enterer)"; + break; + case ECORE_MAGIC_IDLE_EXITER: + return "Ecore_Idle_Exiter (Idler Exiter)"; + break; + case ECORE_MAGIC_FD_HANDLER: + return "Ecore_Fd_Handler (Fd Handler)"; + break; + case ECORE_MAGIC_EVENT_HANDLER: + return "Ecore_Event_Handler (Event Handler)"; + break; + case ECORE_MAGIC_EVENT: + return "Ecore_Event (Event)"; + break; + default: + return ""; + }; + return ""; +} + +#ifndef WIN32 +/* fps debug calls - for debugging how much time your app actually spends */ +/* "running" (and the inverse being time spent running)... this does not */ +/* account for other apps and multitasking... */ + +static int _ecore_fps_debug_init_count = 0; +static int _ecore_fps_debug_fd = -1; +unsigned int *_ecore_fps_runtime_mmap = NULL; + +void +_ecore_fps_debug_init(void) +{ + char buf[4096]; + + _ecore_fps_debug_init_count++; + if (_ecore_fps_debug_init_count > 1) return; + snprintf(buf, sizeof(buf), "/tmp/.ecore_fps_debug-%i", (int)getpid()); + _ecore_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR); + if (_ecore_fps_debug_fd < 0) + { + unlink(buf); + _ecore_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR); + } + if (_ecore_fps_debug_fd >= 0) + { + unsigned int zero = 0; + + write(_ecore_fps_debug_fd, &zero, sizeof(unsigned int)); + _ecore_fps_runtime_mmap = mmap(NULL, sizeof(unsigned int), + PROT_READ | PROT_WRITE, + MAP_SHARED, + _ecore_fps_debug_fd, 0); + } +} + +void +_ecore_fps_debug_shutdown(void) +{ + _ecore_fps_debug_init_count--; + if (_ecore_fps_debug_init_count > 0) return; + if (_ecore_fps_debug_fd >= 0) + { + char buf[4096]; + + snprintf(buf, sizeof(buf), "/tmp/.ecore_fps_debug-%i", (int)getpid()); + unlink(buf); + if (_ecore_fps_runtime_mmap) + { + munmap(_ecore_fps_runtime_mmap, sizeof(int)); + _ecore_fps_runtime_mmap = NULL; + } + close(_ecore_fps_debug_fd); + _ecore_fps_debug_fd = -1; + } +} + +void +_ecore_fps_debug_runtime_add(double t) +{ + if ((_ecore_fps_debug_fd >= 0) && + (_ecore_fps_runtime_mmap)) + { + unsigned int tm; + + tm = (unsigned int)(t * 1000000.0); + /* i know its not 100% theoretically guaranteed, but i'd say a write */ + /* of an int could be considered atomic for all practical purposes */ + /* oh and since this is cumulative, 1 second = 1,000,000 ticks, so */ + /* this can run for about 4294 seconds becore looping. if you are */ + /* doing performance testing in one run for over an hour... well */ + /* time to restart or handle a loop condition :) */ + *(_ecore_fps_runtime_mmap) += tm; + } +} +#endif diff --git a/ecore/src/lib/ecore/ecore_anim.c b/ecore/src/lib/ecore/ecore_anim.c new file mode 100644 index 0000000..476fa20 --- /dev/null +++ b/ecore/src/lib/ecore/ecore_anim.c @@ -0,0 +1,169 @@ +#include "ecore_private.h" +#include "Ecore.h" + +static int _ecore_animator(void *data); + +static Ecore_Timer *timer = NULL; +static int animators_delete_me = 0; +static Ecore_Animator *animators = NULL; +static double animators_frametime = 1.0 / 30.0; + +/** + * Add a animator to tick off at every animaton tick during main loop execution. + * @param func The function to call when it ticks off + * @param data The data to pass to the function + * @return A handle to the new animator + * @ingroup Ecore_Animator_Group + * + * This function adds a animator and returns its handle on success and NULL on + * failure. The function @p func will be called every N seconds where N is the + * frametime interval set by ecore_animator_frametime_set(). The function will + * be passed the @p data pointer as its parameter. + * + * When the animator @p func is called, it must return a value of either 1 or 0. + * If it returns 1, it will be called again at the next tick, or if it returns + * 0 it will be deleted automatically making any references/handles for it + * invalid. + */ +Ecore_Animator * +ecore_animator_add(int (*func) (void *data), const void *data) +{ + Ecore_Animator *animator; + + if (!func) return NULL; + animator = calloc(1, sizeof(Ecore_Animator)); + if (!animator) return NULL; + ECORE_MAGIC_SET(animator, ECORE_MAGIC_ANIMATOR); + animator->func = func; + animator->data = (void *)data; + animators = _ecore_list_append(animators, animator); + if (!timer) + timer = ecore_timer_add(animators_frametime, _ecore_animator, NULL); + return animator; +} + +/** + * Delete the specified animator from the animator list. + * @param animator The animator to delete + * @return The data pointer set for the animator + * @ingroup Ecore_Animator_Group + * + * Delete the specified @p aqnimator from the set of animators that are executed + * during main loop execution. This function returns the data parameter that + * was being passed to the callback on success, or NULL on failure. After this + * call returns the specified animator object @p animator is invalid and should not + * be used again. It will not get called again after deletion. + */ +void * +ecore_animator_del(Ecore_Animator *animator) +{ + if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR)) + { + ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR, + "ecore_animator_del"); + return NULL; + } + if (animator->delete_me) return animator->data; + animator->delete_me = 1; + animators_delete_me++; + return animator->data; +} + +/** + * Set the animator call interval in seconds. + * @param frametime The time in seconds in between animator ticks. + * + * This function sets the time interval (in seconds) inbetween animator ticks. + */ +void +ecore_animator_frametime_set(double frametime) +{ + if (frametime < 0.0) frametime = 0.0; + if (animators_frametime == frametime) return; + animators_frametime = frametime; + if (timer) + { + ecore_timer_del(timer); + timer = NULL; + } + if (animators) + timer = ecore_timer_add(animators_frametime, _ecore_animator, NULL); +} + +/** + * Get the animator call interval in seconds. + * @return The time in second in between animator ticks. + * + * this function retrieves the time inbetween animator ticks, in seconds. + */ +double +ecore_animator_frametime_get(void) +{ + return animators_frametime; +} + +void +_ecore_animator_shutdown(void) +{ + if (timer) + { + ecore_timer_del(timer); + timer = NULL; + } + while (animators) + { + Ecore_Animator *animator; + + animator = animators; + animators = _ecore_list_remove(animators, animator); + ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE); + free(animator); + } +} + +static int +_ecore_animator(void *data __UNUSED__) +{ + Ecore_Oldlist *l; + + for (l = (Ecore_Oldlist *)animators; l;) + { + Ecore_Animator *animator; + + animator = (Ecore_Animator *)l; + l = l->next; + if (!animator->delete_me) + { + if (!animator->func(animator->data)) + { + animator->delete_me = 1; + animators_delete_me = 1; + } + } + } + if (animators_delete_me) + { + + for (l = (Ecore_Oldlist *)animators; l;) + { + Ecore_Animator *animator; + + animator = (Ecore_Animator *)l; + l = l->next; + if (animator->delete_me) + { + animators = _ecore_list_remove(animators, animator); + ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE); + free(animator); + animators_delete_me--; + if (animators_delete_me == 0) break; + } + } + } + if (!animators) + { + timer = NULL; + return 0; + } + return 1; +} diff --git a/ecore/src/lib/ecore/ecore_app.c b/ecore/src/lib/ecore/ecore_app.c new file mode 100644 index 0000000..ecf36bf --- /dev/null +++ b/ecore/src/lib/ecore/ecore_app.c @@ -0,0 +1,64 @@ +#include "ecore_private.h" +#include "Ecore.h" + +static int app_argc = 0; +static char **app_argv = NULL; + +/** + * Set up the programs command-line arguments. + * @param argc The same as passed as argc to the programs main() function + * @param argv The same as passed as argv to the programs main() function + * + * A call to this function will store the programs command-line arguments + * for later use by ecore_app_restart() or ecore_app_args_get(). + */ +void +ecore_app_args_set(int argc, const char **argv) +{ + if ((argc < 1) || + (!argv)) return; + app_argc = argc; + app_argv = (char **)argv; +} + +/** + * Return the programs stored command-line arguments. + * @param argc A pointer to the return value to hold argc + * @param argv A pointer to the return value to hold argv + * + * When called, this funciton returns the arguments for the program stored by + * ecore_app_args_set(). The integer pointed to by @p argc will be filled, if + * the pointer is not NULL, and the string array pointer @p argv will be filled + * also if the pointer is not NULL. The values they are filled with will be the + * same set by ecore_app_args_set(). + */ +void +ecore_app_args_get(int *argc, char ***argv) +{ + if (argc) *argc = app_argc; + if (argv) *argv = app_argv; +} + +/** + * Restart the program executable with the command-line arguments stored. + * + * This function will restart & re-execute this program in place of itself + * using the command-line arguments stored by ecore_app_args_set(). This is + * an easy way for a program to restart itself for cleanup purposes, + * configuration reasons or in the event of a crash. + * + * FIXME: Currently not implimented. + */ +void +ecore_app_restart(void) +{ + char **args; + int i; + + if ((app_argc < 1) || (!app_argv)) return; + args = malloc((app_argc + 1) * sizeof(char *)); + if (!args) return; + for (i = 0; i < app_argc; i++) args[i] = app_argv[i]; + args[i] = NULL; + execvp(app_argv[0], args); +} diff --git a/ecore/src/lib/ecore/ecore_events.c b/ecore/src/lib/ecore/ecore_events.c new file mode 100644 index 0000000..45e2ac9 --- /dev/null +++ b/ecore/src/lib/ecore/ecore_events.c @@ -0,0 +1,519 @@ +#include "ecore_private.h" +#include "Ecore.h" + +static int events_num = 0; +static Ecore_Event *events = NULL; + +static Ecore_Event_Handler **event_handlers = NULL; +static int event_handlers_num = 0; +static int event_handlers_alloc_num = 0; +static Ecore_Oldlist_Data *event_handlers_delete_list = NULL; + +static Ecore_Event_Filter *event_filters = NULL; +static int event_filters_delete_me = 0; + +static int event_id_max = ECORE_EVENT_COUNT; + +static int ecore_raw_event_type = ECORE_EVENT_NONE; +static void *ecore_raw_event_event = NULL; + + +/** + * Add an event handler. + * @param type The type of the event this handler will get called for + * @param func The function to call when the event is found in the queue + * @param data A data pointer to pass to the called function @p func + * @return A new Event handler, or NULL on failure + * + * Add an event handler to the list of handlers. This will, on success, return + * a handle to the event handler object that was created, that can be used + * later to remove the handler using ecore_event_handler_del(). The @p type + * parameter is the iteger of the event type that will trigger this callback + * to be called. The callback @p func is called when this event is processed + * and will be passed the event type, a pointer to the private event + * structure that is specific to that event type, and a data pointer that is + * provided in this call as the @p data parameter. + * + * When the callback @p func is called, it must return 1 or 0. If it returns + * 1, It will keep being called as per normal, for each handler set up for that + * event type. If it returns 0, it will cease processing handlers for that + * particular event, so all handler set to handle that event type that have not + * already been called, will not be. + */ +Ecore_Event_Handler * +ecore_event_handler_add(int type, int (*func) (void *data, int type, void *event), const void *data) +{ + Ecore_Event_Handler *eh; + + if (!func) return NULL; + if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) return NULL; + eh = calloc(1, sizeof(Ecore_Event_Handler)); + if (!eh) return NULL; + ECORE_MAGIC_SET(eh, ECORE_MAGIC_EVENT_HANDLER); + eh->type = type; + eh->func = func; + eh->data = (void *)data; + if (type >= (event_handlers_num - 1)) + { + int p_alloc_num; + + p_alloc_num = event_handlers_alloc_num; + event_handlers_num = type + 1; + if (event_handlers_num > event_handlers_alloc_num) + { + Ecore_Event_Handler **new_handlers; + int i; + + event_handlers_alloc_num = ((event_handlers_num + 16) / 16) * 16; + new_handlers = realloc(event_handlers, event_handlers_alloc_num * sizeof(Ecore_Event_Handler *)); + if (!new_handlers) + { + free(eh); + return NULL; + } + event_handlers = new_handlers; + for (i = p_alloc_num; i < event_handlers_alloc_num; i++) + event_handlers[i] = NULL; + } + } + event_handlers[type] = _ecore_list_append(event_handlers[type], eh); + return eh; +} + +/** + * Delete an event handler. + * @param event_handler Event handler handle to delete + * @return Data passed to handler + * + * Delete a specified event handler from the handler list. On success this will + * delete the event handler and return the pointer passed as @p data when the + * handler was added by ecore_event_handler_add(). On failure NULL will be + * returned. Once a handler is deleted it will no longer be called. + */ +void * +ecore_event_handler_del(Ecore_Event_Handler *event_handler) +{ + Ecore_Oldlist_Data *node; + + if (!ECORE_MAGIC_CHECK(event_handler, ECORE_MAGIC_EVENT_HANDLER)) + { + ECORE_MAGIC_FAIL(event_handler, ECORE_MAGIC_EVENT_HANDLER, + "ecore_event_handler_del"); + return NULL; + } + event_handler->delete_me = 1; + node = calloc(1, sizeof(Ecore_Oldlist_Data)); + node->data = event_handler; + event_handlers_delete_list = _ecore_list_append(event_handlers_delete_list, node); + return event_handler->data; +} + +static void _ecore_event_generic_free (void *data __UNUSED__, void *event) +{ + free (event); +} + +/** + * Add an event to the event queue. + * @param type The event type to add to the end of the event queue + * @param ev The private data structure for this event type + * @param func_free The function to be called to free this private structure + * @param data The data pointer to be passed to the free function + * @return A Handle for that event + * + * On success this function returns a handle to an event on the event queue, or + * NULL if it fails. If it succeeds, an event of type @p type will be added + * to the queue for processing by event handlers added by + * ecore_event_handler_add(). The @p ev parameter will be a pointer to the event + * private data that is specific to that event type. When the event is no + * longer needed, @p func_free will be called and passed the private sructure + * pointer for cleaning up. If @p func_free is NULL, free() will be called + * with the private structure pointer. + * func_free is passed @p data as its data parameter. + */ +Ecore_Event * +ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data) +{ + if (!ev) return NULL; + if (type <= ECORE_EVENT_NONE) return NULL; + if (type >= event_id_max) return NULL; + if (!func_free) func_free = _ecore_event_generic_free; + return _ecore_event_add(type, ev, func_free, data); +} + +/** + * Delete an event from the queue. + * @param event The event handle to delete + * @return The data pointer originally set for the event free function + * + * This deletes the event @p event from the event queue, and returns the + * @p data parameer originally set when adding it with ecore_event_add(). This + * does not immediately call the free function, and it may be called later on + * cleanup, and so if the free function depends on the data pointer to work, + * you should defer cleaning of this till the free function is called later. + */ +void * +ecore_event_del(Ecore_Event *event) +{ + if (!ECORE_MAGIC_CHECK(event, ECORE_MAGIC_EVENT)) + { + ECORE_MAGIC_FAIL(event, ECORE_MAGIC_EVENT, + "ecore_event_del"); + return NULL; + } + event->delete_me = 1; + return event->data; +} + +/** + * Allocate a new event type id sensibly and return the new id. + * @return A new event type id. + * + * This function allocates a new event type id and returns it. Once an event + * type has been allocated it can never be de-allocated during the life of + * the program. There is no guarantee of the contents of this event ID, or how + * it is calculated, except that the ID will be unique to the current instance + * of the process. + */ +int +ecore_event_type_new(void) +{ + event_id_max++; + return event_id_max - 1; +} + +/** + * Add a filter the current event queue. + * @param func_start Function to call just before filtering and return data + * @param func_filter Function to call on each event + * @param func_end Function to call after the queu has been filtered + * @param data Data to pass to the filter functions + * @return A filter handle + * + * This adds a filter to call callbacks to loop through the event queue and + * filter events out of the queue. On failure NULL is returned. On success a + * Filter handle is returned. Filters are called on the queue just before + * Event handler processing to try and remove redundant events. Just as + * processing starts @p func_start is called and passed the @p data pointer. + * This function returns a pointer that is used as loop_data that is now passed to + * @p func_filter as loop_data. @p func_filter is also passed @p data and the + * event type and private event structure. If this callback returns 0, the + * event is removed from the queue. If it returns 1, the event is kept. When + * processing is finished @p func_end is called and is passed the loop_data + * and @p data pointer to clean up. + */ +Ecore_Event_Filter * +ecore_event_filter_add(void * (*func_start) (void *data), int (*func_filter) (void *data, void *loop_data, int type, void *event), void (*func_end) (void *data, void *loop_data), const void *data) +{ + Ecore_Event_Filter *ef; + + if (!func_filter) return NULL; + ef = calloc(1, sizeof(Ecore_Event_Filter)); + if (!ef) return NULL; + ECORE_MAGIC_SET(ef, ECORE_MAGIC_EVENT_FILTER); + ef->func_start = func_start; + ef->func_filter = func_filter; + ef->func_end = func_end; + ef->data = (void *)data; + event_filters = _ecore_list_append(event_filters, ef); + return ef; +} + +/** + * Delete an event filter. + * @param ef The event filter handle + * @return The data set for the filter + * + * Delete a filter that has been added by its @p ef handle. On success this + * will return the data pointer set when this filter was added. On failure + * NULL is returned. + */ +void * +ecore_event_filter_del(Ecore_Event_Filter *ef) +{ + if (!ECORE_MAGIC_CHECK(ef, ECORE_MAGIC_EVENT_FILTER)) + { + ECORE_MAGIC_FAIL(ef, ECORE_MAGIC_EVENT_FILTER, + "ecore_event_filter_del"); + return NULL; + } + ef->delete_me = 1; + event_filters_delete_me = 1; + return ef->data; +} + +/** + * Return the current event type being handled. + * @return The current event type being handled if inside a handler callback + * + * If the program is currently inside an Ecore event handler callback this + * will return the type of the current event being processed. If Ecore is + * not inside an event handler, ECORE_EVENT_NONE is returned. + * + * This is useful when certain Ecore modules such as Ecore_Evas "swallow" + * events and not all the original information is passed on. In special cases + * this extra information may be useful or needed and using this call can let + * the program know if the event type being handled is one it wants to get more + * information about. + */ +int +ecore_event_current_type_get(void) +{ + return ecore_raw_event_type; +} + +/** + * Return the current event type pointer handled. + * @return The current event pointer being handled if inside a handler callback + * + * If the program is currently inside an Ecore event handler callback this + * will return the pointer of the current event being processed. If Ecore is + * not inside an event handler, NULL will be returned. + * + * This is useful when certain Ecore modules such as Ecore_Evas "swallow" + * events and not all the original information is passed on. In special cases + * this extra information may be useful or needed and using this call can let + * the program access the event data if the type of the event is handled by + * the program. + */ +void * +ecore_event_current_event_get(void) +{ + return ecore_raw_event_event; +} + +void +_ecore_event_shutdown(void) +{ + int i; + + while (events) _ecore_event_del(events); + for (i = 0; i < event_handlers_num; i++) + { + while (event_handlers[i]) + { + Ecore_Event_Handler *eh; + + eh = event_handlers[i]; + event_handlers[i] = _ecore_list_remove(event_handlers[i], eh); + ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE); + free(eh); + } + } + while (event_handlers_delete_list) + { + Ecore_Oldlist_Data *ehd; + + ehd = event_handlers_delete_list; + event_handlers_delete_list = _ecore_list_remove(event_handlers_delete_list, ehd); + free(ehd); + } + if (event_handlers) free(event_handlers); + event_handlers = NULL; + event_handlers_num = 0; + event_handlers_alloc_num = 0; + while (event_filters) + { + Ecore_Event_Filter *ef; + + ef = event_filters; + event_filters = _ecore_list_remove(event_filters, ef); + ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE); + free(ef); + } + event_filters_delete_me = 0; +} + +int +_ecore_event_exist(void) +{ + if (events) return 1; + return 0; +} + +Ecore_Event * +_ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data) +{ + Ecore_Event *e; + + e = calloc(1, sizeof(Ecore_Event)); + if (!e) return NULL; + ECORE_MAGIC_SET(e, ECORE_MAGIC_EVENT); + e->type = type; + e->event = ev; + e->func_free = func_free; + e->data = data; + events = _ecore_list_append(events, e); + events_num++; + return e; +} + +void * +_ecore_event_del(Ecore_Event *event) +{ + void *data; + + data = event->data; + event->func_free(event->data, event->event); + events = _ecore_list_remove(events, event); + ECORE_MAGIC_SET(event, ECORE_MAGIC_NONE); + free(event); + events_num--; + return data; +} + +void +_ecore_event_call(void) +{ + Ecore_Oldlist *l, *ll; + Ecore_Event *e; + Ecore_Event_Filter *ef; + Ecore_Event_Handler *eh; + Ecore_Oldlist_Data *ehd; + int handle_count; + + for (l = (Ecore_Oldlist *)event_filters; l; l = l->next) + { + ef = (Ecore_Event_Filter *)l; + if (!ef->delete_me) + { + if (ef->func_start) + ef->loop_data = ef->func_start(ef->data); + for (ll = (Ecore_Oldlist *)events; ll; ll = ll->next) + { + Ecore_Event *e; + + e = (Ecore_Event *)ll; + if (!ef->func_filter(ef->loop_data, ef->data, + e->type, e->event)) + { +// printf("FILTER SAID TO DEL ev %p\n", e->event); + ecore_event_del(e); + } + } + if (ef->func_end) + ef->func_end(ef->data, ef->loop_data); + } + } + if (event_filters_delete_me) + { + for (l = (Ecore_Oldlist *)event_filters; l;) + { + ef = (Ecore_Event_Filter *)l; + l = l->next; + if (ef->delete_me) + { + event_filters = _ecore_list_remove(event_filters, ef); + ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE); + free(ef); + } + } + event_filters_delete_me = 0; + } +// printf("EVENT BATCH...\n"); + for (l = (Ecore_Oldlist *)events; l; l = l->next) + { + e = (Ecore_Event *)l; + if (!e->delete_me) + { + handle_count = 0; + ecore_raw_event_type = e->type; + ecore_raw_event_event = e->event; +// printf("HANDLE ev type %i, %p\n", e->type, e->event); + if ((e->type >= 0) && (e->type < event_handlers_num)) + { + for (ll = (Ecore_Oldlist *)event_handlers[e->type]; ll; ll = ll->next) + { + eh = (Ecore_Event_Handler *)ll; + if (!eh->delete_me) + { + handle_count++; + if (!eh->func(eh->data, e->type, e->event)) + break; /* 0 == "call no further handlers" */ + } + } + } + /* if no handlers were set for EXIT signal - then default is */ + /* to quit the main loop */ + if ((e->type == ECORE_EVENT_SIGNAL_EXIT) && (handle_count == 0)) + ecore_main_loop_quit(); + } + } + ecore_raw_event_type = ECORE_EVENT_NONE; + ecore_raw_event_event = NULL; + + while (events) _ecore_event_del(events); + while (event_handlers_delete_list) + { + ehd = event_handlers_delete_list; + eh = ehd->data; + event_handlers[eh->type] = _ecore_list_remove(event_handlers[eh->type], eh); + event_handlers_delete_list = _ecore_list_remove(event_handlers_delete_list, ehd); + ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE); + free(eh); + free(ehd); + } +} + +#ifndef WIN32 +void * +_ecore_event_exe_exit_new(void) +{ + Ecore_Event_Exe_Exit *e; + + e = calloc(1, sizeof(Ecore_Event_Exe_Exit)); + return e; +} + +void +_ecore_event_exe_exit_free(void *data __UNUSED__, void *ev) +{ + Ecore_Event_Exe_Exit *e; + + e = ev; + if (e->exe) _ecore_exe_free(e->exe); + free(e); +} +#endif + +void * +_ecore_event_signal_user_new(void) +{ + Ecore_Event_Signal_User *e; + + e = calloc(1, sizeof(Ecore_Event_Signal_User)); + return e; +} + +void * +_ecore_event_signal_hup_new(void) +{ + Ecore_Event_Signal_Hup *e; + + e = calloc(1, sizeof(Ecore_Event_Signal_Hup)); + return e; +} + +void * +_ecore_event_signal_exit_new(void) +{ + Ecore_Event_Signal_Exit *e; + + e = calloc(1, sizeof(Ecore_Event_Signal_Exit)); + return e; +} + +void * +_ecore_event_signal_power_new(void) +{ + Ecore_Event_Signal_Power *e; + + e = calloc(1, sizeof(Ecore_Event_Signal_Power)); + return e; +} + +void * +_ecore_event_signal_realtime_new(void) +{ + return calloc(1, sizeof(Ecore_Event_Signal_Realtime)); +} diff --git a/ecore/src/lib/ecore/ecore_exe.c b/ecore/src/lib/ecore/ecore_exe.c new file mode 100644 index 0000000..a91b35b --- /dev/null +++ b/ecore/src/lib/ecore/ecore_exe.c @@ -0,0 +1,263 @@ +#include "ecore_private.h" +#include "Ecore.h" + +#include +#include +#include + +#ifndef WIN32 +static Ecore_Exe *exes = NULL; + +/** + * @defgroup Ecore_Exe_Basic_Group Process Spawning Functions + * + * Functions that deal with spawned processes. + */ + +/** + * Spawns a child process. + * + * This function forks and runs the given command using @c /bin/sh. + * + * Note that the process handle is only valid until a child process + * terminated event is received. After all handlers for the child process + * terminated event have been called, the handle will be freed by Ecore. + * + * @param exe_cmd The command to run with @c /bin/sh. + * @param data Data to attach to the returned process handle. + * @return A process handle to the spawned process. + * @ingroup Ecore_Exe_Basic_Group + */ +Ecore_Exe * +ecore_exe_run(const char *exe_cmd, const void *data) +{ + Ecore_Exe *exe; + pid_t pid; + + if (!exe_cmd) return NULL; + pid = fork(); + if (pid) + { + exe = calloc(1, sizeof(Ecore_Exe)); + if (!exe) + { + kill(pid, SIGKILL); + return NULL; + } + ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE); + exe->pid = pid; + exe->data = (void *)data; + exes = _ecore_list_append(exes, exe); + return exe; + } + setsid(); + execl("/bin/sh", "/bin/sh", "-c", exe_cmd, (char *)NULL); + exit(127); + return NULL; +} + +/** + * Frees the given process handle. + * + * Note that the process that the handle represents is unaffected by this + * function. + * + * @param exe The given process handle. + * @return The data attached to the handle when @ref ecore_exe_run was + * called. + * @ingroup Ecore_Exe_Basic_Group + */ +void * +ecore_exe_free(Ecore_Exe *exe) +{ + if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) + { + ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, + "ecore_exe_free"); + return NULL; + } + return _ecore_exe_free(exe); +} + +/** + * Retrieves the process ID of the given spawned process. + * @param exe Handle to the given spawned process. + * @return The process ID on success. @c -1 otherwise. + * @ingroup Ecore_Exe_Basic_Group + */ +pid_t +ecore_exe_pid_get(Ecore_Exe *exe) +{ + if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) + { + ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, + "ecore_exe_pid_get"); + return -1; + } + return exe->pid; +} + +/** + * Retrieves the data attached to the given process handle. + * @param exe The given process handle. + * @return The data pointer attached to @p exe. + * @ingroup Ecore_Exe_Basic_Group + */ +void * +ecore_exe_data_get(Ecore_Exe *exe) +{ + if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) + { + ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, + "ecore_exe_data_get"); + return NULL; + } + return exe->data; +} + +/** + * @defgroup Ecore_Exe_Signal_Group Spawned Process Signal Functions + * + * Functions that send signals to spawned processes. + */ + +/** + * Pauses the given process by sending it a @c SIGSTOP signal. + * @param exe Process handle to the given process. + * @ingroup Ecore_Exe_Signal_Group + */ +void +ecore_exe_pause(Ecore_Exe *exe) +{ + if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) + { + ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, + "ecore_exe_pause"); + return; + } + kill(exe->pid, SIGSTOP); +} + +/** + * Continues the given paused process by sending it a @c SIGCONT signal. + * @param exe Process handle to the given process. + * @ingroup Ecore_Exe_Signal_Group + */ +void +ecore_exe_continue(Ecore_Exe *exe) +{ + if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) + { + ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, + "ecore_exe_continue"); + return; + } + kill(exe->pid, SIGCONT); +} + +/** + * Sends the given spawned process a terminate (@c SIGTERM) signal. + * @param exe Process handle to the given process. + * @ingroup Ecore_Exe_Signal_Group + */ +void +ecore_exe_terminate(Ecore_Exe *exe) +{ + if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) + { + ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, + "ecore_exe_terminate"); + return; + } + kill(exe->pid, SIGTERM); +} + +/** + * Kills the given spawned process by sending it a @c SIGKILL signal. + * @param exe Process handle to the given process. + * @ingroup Ecore_Exe_Signal_Group + */ +void +ecore_exe_kill(Ecore_Exe *exe) +{ + if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) + { + ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, + "ecore_exe_kill"); + return; + } + kill(exe->pid, SIGKILL); +} + +/** + * Sends a @c SIGUSR signal to the given spawned process. + * @param exe Process handle to the given process. + * @param num The number user signal to send. Must be either 1 or 2, or + * the signal will be ignored. + * @ingroup Ecore_Exe_Signal_Group + */ +void +ecore_exe_signal(Ecore_Exe *exe, int num) +{ + if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) + { + ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, + "ecore_exe_signal"); + return; + } + if (num == 1) + kill(exe->pid, SIGUSR1); + else if (num == 2) + kill(exe->pid, SIGUSR2); +} + +/** + * Sends a @c SIGHUP signal to the given spawned process. + * @param exe Process handle to the given process. + * @ingroup Ecore_Exe_Signal_Group + */ +void +ecore_exe_hup(Ecore_Exe *exe) +{ + if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) + { + ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, + "ecore_exe_hup"); + return; + } + kill(exe->pid, SIGHUP); +} + +void +_ecore_exe_shutdown(void) +{ + while (exes) _ecore_exe_free(exes); +} + +Ecore_Exe * +_ecore_exe_find(pid_t pid) +{ + Ecore_Oldlist *l; + + for (l = (Ecore_Oldlist *)exes; l; l = l->next) + { + Ecore_Exe *exe; + + exe = (Ecore_Exe *)l; + if (exe->pid == pid) return exe; + } + return NULL; +} + +void * +_ecore_exe_free(Ecore_Exe *exe) +{ + void *data; + + data = exe->data; + exes = _ecore_list_remove(exes, exe); + ECORE_MAGIC_SET(exe, ECORE_MAGIC_NONE); + free(exe); + return data; +} +#endif diff --git a/ecore/src/lib/ecore/ecore_hash.c b/ecore/src/lib/ecore/ecore_hash.c new file mode 100644 index 0000000..0fde533 --- /dev/null +++ b/ecore/src/lib/ecore/ecore_hash.c @@ -0,0 +1,713 @@ +#include + +#define ECORE_HASH_CHAIN_MAX 3 + +#define ECORE_COMPUTE_HASH(hash, key) hash->hash_func(key) % \ + ecore_prime_table[hash->size]; + +#define ECORE_HASH_INCREASE(hash) ((hash && hash->size < PRIME_MAX) ? \ + (hash->nodes / ecore_prime_table[hash->size]) > \ + ECORE_HASH_CHAIN_MAX : FALSE) +#define ECORE_HASH_REDUCE(hash) ((hash && hash->size > PRIME_MIN) ? \ + (double)hash->nodes / (double)ecore_prime_table[hash->size-1] \ + < ((double)ECORE_HASH_CHAIN_MAX * 0.375) : FALSE) + + +/* Private hash manipulation functions */ +static int _ecore_hash_add_node(Ecore_Hash *hash, Ecore_Hash_Node *node); +static Ecore_Hash_Node * _ecore_hash_get_node(Ecore_Hash *hash, void *key); +static int _ecore_hash_increase(Ecore_Hash *hash); +static int _ecore_hash_decrease(Ecore_Hash *hash); +inline int _ecore_hash_rehash(Ecore_Hash *hash, Ecore_List **old_table, int old_size); +static int _ecore_hash_bucket_destroy(Ecore_List *list, Ecore_Free_Cb keyd, + Ecore_Free_Cb valued); +inline Ecore_Hash_Node * _ecore_hash_get_bucket(Ecore_Hash *hash, Ecore_List *bucket, + void *key); + +static Ecore_Hash_Node *_ecore_hash_node_new(void *key, void *value); +static int _ecore_hash_node_init(Ecore_Hash_Node *node, void *key, void *value); +static int _ecore_hash_node_destroy(Ecore_Hash_Node *node, Ecore_Free_Cb keyd, + Ecore_Free_Cb valued); + +/** + * @defgroup Ecore_Data_Hash_ADT_Creation_Group Hash Creation Functions + * + * Functions that create hash tables. + */ + +/** + * Creates and initializes a new hash + * @param hash_func The function for determining hash position. + * @param compare The function for comparing node keys. + * @return @c NULL on error, a new hash on success. + * @ingroup Ecore_Data_Hash_ADT_Creation_Group + */ +Ecore_Hash *ecore_hash_new(Ecore_Hash_Cb hash_func, Ecore_Compare_Cb compare) +{ + Ecore_Hash *new_hash = (Ecore_Hash *)malloc(sizeof(Ecore_Hash)); + if (!new_hash) + return NULL; + + if (!ecore_hash_init(new_hash, hash_func, compare)) { + FREE(new_hash); + return NULL; + } + + return new_hash; +} + +/** + * Initializes the given hash. + * @param hash The given hash. + * @param hash_func The function used for hashing node keys. + * @param compare The function used for comparing node keys. + * @return @c TRUE on success, @c FALSE on an error. + * @ingroup Ecore_Data_Hash_ADT_Creation_Group + */ +int ecore_hash_init(Ecore_Hash *hash, Ecore_Hash_Cb hash_func, Ecore_Compare_Cb compare) +{ + CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE); + + memset(hash, 0, sizeof(Ecore_Hash)); + + hash->hash_func = hash_func; + hash->compare = compare; + + hash->buckets = (Ecore_List **)malloc(ecore_prime_table[0] * + sizeof(Ecore_List *)); + memset(hash->buckets, 0, ecore_prime_table[0] * sizeof(Ecore_List *)); + + ECORE_INIT_LOCKS(hash); + + return TRUE; +} + +/** + * @defgroup Ecore_Data_Hash_ADT_Destruction_Group Hash Destruction Functions + * + * Functions that destroy hash tables and their contents. + */ + +/** + * Sets the function to destroy the keys of the given hash. + * @param hash The given hash. + * @param function The function used to free the node keys. + * @return @c TRUE on success, @c FALSE on error. + * @ingroup Ecore_Data_Hash_ADT_Destruction_Group + */ +int ecore_hash_set_free_key(Ecore_Hash *hash, Ecore_Free_Cb function) +{ + CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE); + CHECK_PARAM_POINTER_RETURN("function", function, FALSE); + + ECORE_WRITE_LOCK(hash); + hash->free_key = function; + ECORE_WRITE_UNLOCK(hash); + + return TRUE; +} + +/** + * Sets the function to destroy the values in the given hash. + * @param hash The given hash. + * @param function The function that will free the node values. + * @return @c TRUE on success, @c FALSE on error + * @ingroup Ecore_Data_Hash_ADT_Destruction_Group + */ +int ecore_hash_set_free_value(Ecore_Hash *hash, Ecore_Free_Cb function) +{ + CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE); + CHECK_PARAM_POINTER_RETURN("function", function, FALSE); + + ECORE_WRITE_LOCK(hash); + hash->free_value = function; + ECORE_WRITE_UNLOCK(hash); + + return TRUE; +} + +/** + * @defgroup Ecore_Data_Hash_ADT_Data_Group Hash Data Functions + * + * Functions that set, access and delete values from the hash tables. + */ + +/** + * Sets a key-value pair in the given hash table. + * @param hash The given hash table. + * @param key The key. + * @param value The value. + * @return @c TRUE if successful, @c FALSE if not. + * @ingroup Ecore_Data_Hash_ADT_Data_Group + */ +int ecore_hash_set(Ecore_Hash *hash, void *key, void *value) +{ + int ret = FALSE; + Ecore_Hash_Node *node; + + CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE); + + ECORE_WRITE_LOCK(hash); + node = _ecore_hash_get_node(hash, key); + if (node) + node->value = value; + else { + node = _ecore_hash_node_new(key, value); + if (node) + ret = _ecore_hash_add_node(hash, node); + } + ECORE_WRITE_UNLOCK(hash); + + return ret; +} + +/** + * Frees the hash table and the data contained inside it. + * @param hash The hash table to destroy. + * @return @c TRUE on success, @c FALSE on error. + * @ingroup Ecore_Data_Hash_ADT_Destruction_Group + */ +void ecore_hash_destroy(Ecore_Hash *hash) +{ + unsigned int i = 0; + + CHECK_PARAM_POINTER("hash", hash); + + ECORE_WRITE_LOCK(hash); + + while (i < ecore_prime_table[hash->size]) { + if (hash->buckets[i]) + _ecore_hash_bucket_destroy(hash->buckets[i], + hash->free_key, hash->free_value); + i++; + } + + FREE(hash->buckets); + + ECORE_WRITE_UNLOCK(hash); + ECORE_DESTROY_LOCKS(hash); + + FREE(hash); + + return; +} + +/** + * @defgroup Ecore_Data_Hash_ADT_Traverse_Group Hash Traverse Functions + * + * Functions that iterate through hash tables. + */ + +/** + * Runs the @p for_each_func function on each entry in the given hash. + * @param hash The given hash. + * @param for_each_func The function that each entry is passed to. + * @param user_data a pointer passed to calls of for_each_func + * @return TRUE on success, FALSE otherwise. + * @ingroup Ecore_Data_Hash_ADT_Traverse_Group + */ +int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func, + void *user_data) +{ + unsigned int i = 0; + + CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE); + CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, FALSE); + + ECORE_READ_LOCK(hash); + + while (i < ecore_prime_table[hash->size]) { + if (hash->buckets[i]) { + Ecore_Hash_Node *node; + + ecore_list_goto_first(hash->buckets[i]); + while ((node = ecore_list_next(hash->buckets[i]))) { + for_each_func(node, user_data); + } + } + i++; + } + + ECORE_READ_UNLOCK(hash); + + return TRUE; +} + +/** + * Retrieves an ecore_list of all keys in the given hash. + * @param hash The given hash. + * @return new ecore_list on success, NULL otherwise + * @ingroup Ecore_Data_Hash_ADT_Traverse_Group + */ +Ecore_List *ecore_hash_keys(Ecore_Hash *hash) +{ + unsigned int i = 0; + Ecore_List *keys; + + CHECK_PARAM_POINTER_RETURN("hash", hash, NULL); + + ECORE_READ_LOCK(hash); + + keys = ecore_list_new(); + + while (i < ecore_prime_table[hash->size]) { + if (hash->buckets[i]) { + Ecore_Hash_Node *node; + + ecore_list_goto_first(hash->buckets[i]); + while ((node = ecore_list_next(hash->buckets[i]))) { + ecore_list_append(keys, node->key); + } + } + i++; + } + + ECORE_READ_UNLOCK(hash); + + return keys; +} + +/** + * Prints the distribution of the given hash table for graphing. + * @param hash The given hash table. + */ +void +ecore_hash_dump_graph(Ecore_Hash *hash) +{ + unsigned int i; + + for (i = 0; i < ecore_prime_table[hash->size]; i++) + if (hash->buckets[i]) + printf("%d\t%u\n", i, ecore_list_nodes(hash->buckets[i])); + else + printf("%d\t0\n", i); +} + +static int +_ecore_hash_bucket_destroy(Ecore_List *list, Ecore_Free_Cb keyd, Ecore_Free_Cb valued) +{ + Ecore_Hash_Node *node; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + while ((node = ecore_list_remove_first(list)) != NULL) + _ecore_hash_node_destroy(node, keyd, valued); + + ecore_list_destroy(list); + + return TRUE; +} + +/* + * @brief Add the node to the hash table + * @param hash: the hash table to add the key + * @param node: the node to add to the hash table + * @return Returns FALSE on error, TRUE on success + */ +static int +_ecore_hash_add_node(Ecore_Hash *hash, Ecore_Hash_Node *node) +{ + unsigned int hash_val; + + CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE); + CHECK_PARAM_POINTER_RETURN("node", node, FALSE); + + /* Check to see if the hash needs to be resized */ + if (ECORE_HASH_INCREASE(hash)) + _ecore_hash_increase(hash); + + /* Compute the position in the table */ + if (!hash->hash_func) + hash_val = (unsigned int)node->key % + ecore_prime_table[hash->size]; + else + hash_val = ECORE_COMPUTE_HASH(hash, node->key); + + /* Create the list if it's not already present */ + if (!hash->buckets[hash_val]) + hash->buckets[hash_val] = ecore_list_new(); + + /* Append the node to the list at the index position */ + if (!ecore_list_prepend(hash->buckets[hash_val], node)) + return FALSE; + hash->nodes++; + + return TRUE; +} + +/** + * Retrieves the value associated with the given key from the given hash + * table. + * @param hash The given hash table. + * @param key The key to search for. + * @return The value corresponding to key on success, @c NULL otherwise. + * @ingroup Ecore_Data_Hash_ADT_Data_Group + */ +void *ecore_hash_get(Ecore_Hash *hash, void *key) +{ + void *data; + Ecore_Hash_Node *node; + + CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE); + + node = _ecore_hash_get_node(hash, key); + if (!node) + return NULL; + + ECORE_READ_LOCK(node); + data = node->value; + ECORE_READ_UNLOCK(node); + + return data; +} + + +/** + * Removes the value associated with the given key in the given hash + * table. + * @param hash The given hash table. + * @param key The key to search for. + * @return The value corresponding to the key on success. @c NULL is + * returned if there is an error. + * @ingroup Ecore_Data_Hash_ADT_Data_Group + */ +void *ecore_hash_remove(Ecore_Hash *hash, void *key) +{ + Ecore_Hash_Node *node = NULL; + Ecore_List *list; + unsigned int hash_val; + void *ret = NULL; + + CHECK_PARAM_POINTER_RETURN("hash", hash, NULL); + + ECORE_WRITE_LOCK(hash); + + /* Compute the position in the table */ + if (!hash->hash_func) + hash_val = (unsigned int)key % ecore_prime_table[hash->size]; + else + hash_val = ECORE_COMPUTE_HASH(hash, key); + + /* + * If their is a list that could possibly hold the key/value pair + * traverse it and remove the hash node. + */ + if (hash->buckets[hash_val]) { + list = hash->buckets[hash_val]; + ecore_list_goto_first(list); + + /* + * Traverse the list to find the specified key + */ + if (hash->compare) { + while ((node = ecore_list_current(list)) && + hash->compare(node->key, key) != 0) + ecore_list_next(list); + } + else { + while ((node = ecore_list_current(list)) && + node->key != key) + ecore_list_next(list); + } + + if (node) { + ecore_list_remove(list); + ret = node->value; + node->value = NULL; + _ecore_hash_node_destroy(node, hash->free_key, + hash->free_value); + } + } + + if (ECORE_HASH_REDUCE(hash)) + _ecore_hash_decrease(hash); + + ECORE_WRITE_UNLOCK(hash); + + return ret; +} + +/* + * @brief Retrieve the node associated with key + * @param hash: the hash table to search for the key + * @param key: the key to search for in the hash table + * @return Returns NULL on error, node corresponding to key on success + */ +static Ecore_Hash_Node * +_ecore_hash_get_node(Ecore_Hash *hash, void *key) +{ + unsigned int hash_val; + Ecore_Hash_Node *node = NULL; + + CHECK_PARAM_POINTER_RETURN("hash", hash, NULL); + + ECORE_READ_LOCK(hash); + + /* Compute the position in the table */ + if (!hash->hash_func) + hash_val = (unsigned int)key % ecore_prime_table[hash->size]; + else + hash_val = ECORE_COMPUTE_HASH(hash, key); + + /* Grab the bucket at the specified position */ + if (hash->buckets[hash_val]) + node = _ecore_hash_get_bucket(hash, hash->buckets[hash_val], key); + + ECORE_READ_UNLOCK(hash); + + return node; +} + +/* + * @brief Search the hash bucket for a specified key + * @param hash: the hash table to retrieve the comparison function + * @param bucket: the list to search for the key + * @param key: the key to search for in the list + * @return Returns NULL on error or not found, the found node on success + */ +inline Ecore_Hash_Node * +_ecore_hash_get_bucket(Ecore_Hash *hash, Ecore_List *bucket, void *key) +{ + Ecore_Hash_Node *node = NULL; + + ECORE_READ_LOCK(hash); + ecore_list_goto_first(bucket); + + /* + * Traverse the list to find the desired node, if the node is in the + * list, then return the node. + */ + if (hash->compare) { + while ((node = ecore_list_next(bucket)) != NULL) { + ECORE_READ_LOCK(node); + if (hash->compare(node->key, key) == 0) { + ECORE_READ_UNLOCK(node); + ECORE_READ_UNLOCK(hash); + return node; + } + ECORE_READ_UNLOCK(node); + } + } + else { + while ((node = ecore_list_next(bucket)) != NULL) { + ECORE_READ_LOCK(node); + if (node->key == key) { + ECORE_READ_UNLOCK(node); + ECORE_READ_UNLOCK(hash); + return node; + } + ECORE_READ_UNLOCK(node); + } + } + ECORE_READ_UNLOCK(hash); + + return NULL; +} + +/* + * @brief Increase the size of the hash table by approx. 2 * current size + * @param hash: the hash table to increase the size of + * @return Returns TRUE on success, FALSE on error + */ +static int +_ecore_hash_increase(Ecore_Hash *hash) +{ + void *old; + + CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE); + + /* Max size reached so return FALSE */ + if (hash->size == PRIME_TABLE_MAX) + return FALSE; + + /* + * Increase the size of the hash and save a pointer to the old data + */ + hash->size++; + old = hash->buckets; + + /* + * Allocate a new bucket area, of the new larger size + */ + hash->buckets = (Ecore_List **)calloc(ecore_prime_table[hash->size], + sizeof(Ecore_List *)); + + /* + * Make sure the allocation succeeded, if not replace the old data and + * return a failure. + */ + if (!hash->buckets) { + hash->buckets = old; + hash->size--; + return FALSE; + } + hash->nodes = 0; + + /* + * Now move all of the old data into the new bucket area + */ + if (_ecore_hash_rehash(hash, old, hash->size - 1)) { + FREE(old); + return TRUE; + } + + /* + * Free the old buckets regardless of success. + */ + FREE(old); + + return FALSE; +} + +/* + * @brief Decrease the size of the hash table by < 1/2 * current size + * @param hash: the hash table to decrease the size of + * @return Returns TRUE on success, FALSE on error + */ +static int +_ecore_hash_decrease(Ecore_Hash *hash) +{ + Ecore_List **old; + + CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE); + + if (ecore_prime_table[hash->size] == PRIME_MIN) + return FALSE; + + /* + * Decrease the hash size and store a pointer to the old data + */ + hash->size--; + old = hash->buckets; + + /* + * Allocate a new area to store the data + */ + hash->buckets = (Ecore_List **)malloc(ecore_prime_table[hash->size] * + sizeof(Ecore_List *)); + + /* + * Make sure allocation succeeded otherwise rreturn to the previous + * state + */ + if (!hash->buckets) { + hash->buckets = old; + hash->size++; + return FALSE; + } + + /* + * Zero out the new area + */ + memset(hash->buckets, 0, ecore_prime_table[hash->size] + * sizeof(Ecore_List *)); + hash->nodes = 0; + + if (_ecore_hash_rehash(hash, old, hash->size - 1)) { + FREE(old); + return TRUE; + } + + return FALSE; +} + +/* + * @brief Rehash the nodes of a table into the hash table + * @param hash: the hash to place the nodes of the table + * @param table: the table to remove the nodes from and place in hash + * @return Returns TRUE on success, FALSE on success + */ +inline int +_ecore_hash_rehash(Ecore_Hash *hash, Ecore_List **old_table, int old_size) +{ + unsigned int i; + Ecore_Hash_Node *node; + Ecore_List *old; + + CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE); + CHECK_PARAM_POINTER_RETURN("old_table", old_table, FALSE); + + for (i = 0; i < ecore_prime_table[old_size]; i++) { + /* Hash into a new list to avoid loops of rehashing the same + * nodes */ + old = old_table[i]; + old_table[i] = NULL; + + /* Loop through re-adding each node to the hash table */ + while (old && (node = ecore_list_remove_last(old))) { + _ecore_hash_add_node(hash, node); + } + + /* Now free up the old list space */ + if (old) + ecore_list_destroy(old); + } + + return TRUE; +} + +/* + * @brief Create a new hash node for key and value storage + * @param key: the key for this node + * @param value: the value that the key references + * @return Returns NULL on error, a new hash node on success + */ +static Ecore_Hash_Node * +_ecore_hash_node_new(void *key, void *value) +{ + Ecore_Hash_Node *node; + + node = (Ecore_Hash_Node *)malloc(sizeof(Ecore_Hash_Node)); + if (!node) + return NULL; + + if (!_ecore_hash_node_init(node, key, value)) { + FREE(node); + return NULL; + } + + return node; +} + +/* + * @brief Initialize a hash node to some sane default values + * @param node: the node to set the values + * @param key: the key to reference this node + * @param value: the value that key refers to + * @return Returns TRUE on success, FALSE on error + */ +static int +_ecore_hash_node_init(Ecore_Hash_Node *node, void *key, void *value) +{ + CHECK_PARAM_POINTER_RETURN("node", node, FALSE); + + ECORE_INIT_LOCKS(node); + node->key = key; + node->value = value; + + return TRUE; +} + +/* + * @brief Destroy a node and call the specified callbacks to free data + * @param node: the node to be destroyed + * @param keyd: the function to free the key + * @param valued: the function to free the value + * @return Returns TRUE on success, FALSE on error + */ +static int +_ecore_hash_node_destroy(Ecore_Hash_Node *node, Ecore_Free_Cb keyd, + Ecore_Free_Cb valued) +{ + CHECK_PARAM_POINTER_RETURN("node", node, FALSE); + + if (keyd) + keyd(node->key); + + if (valued) + valued(node->value); + + FREE(node); + + return TRUE; +} diff --git a/ecore/src/lib/ecore/ecore_idle_enterer.c b/ecore/src/lib/ecore/ecore_idle_enterer.c new file mode 100644 index 0000000..7b8c967 --- /dev/null +++ b/ecore/src/lib/ecore/ecore_idle_enterer.c @@ -0,0 +1,105 @@ +#include "ecore_private.h" +#include "Ecore.h" + +static Ecore_Idle_Enterer *idle_enterers = NULL; +static int idle_enterers_delete_me = 0; + +/** + * Add an idle enterer handler. + * @param func The function to call when entering an idle state. + * @param data The data to be passed to the @p func call + * @return A handle to the idle enterer callback if successful. Otherwise, + * NULL is returned. + * @ingroup Idle_Group + */ +Ecore_Idle_Enterer * +ecore_idle_enterer_add(int (*func) (void *data), const void *data) +{ + Ecore_Idle_Enterer *ie; + + if (!func) return NULL; + ie = calloc(1, sizeof(Ecore_Idle_Enterer)); + if (!ie) return NULL; + ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER); + ie->func = func; + ie->data = (void *)data; + idle_enterers = _ecore_list_append(idle_enterers, ie); + return ie; +} + +/** + * Delete an idle enterer callback. + * @param idle_enterer The idle enterer to delete + * @return The data pointer passed to the idler enterer callback on success. + * NULL otherwise. + * @ingroup Idle_Group + */ +void * +ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer) +{ + if (!ECORE_MAGIC_CHECK(idle_enterer, ECORE_MAGIC_IDLE_ENTERER)) + { + ECORE_MAGIC_FAIL(idle_enterer, ECORE_MAGIC_IDLE_ENTERER, + "ecore_idle_enterer_del"); + return NULL; + } + idle_enterer->delete_me = 1; + idle_enterers_delete_me = 1; + return idle_enterer->data; +} + +void +_ecore_idle_enterer_shutdown(void) +{ + while (idle_enterers) + { + Ecore_Idle_Enterer *ie; + + ie = idle_enterers; + idle_enterers = _ecore_list_remove(idle_enterers, ie); + ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); + free(ie); + } + idle_enterers_delete_me = 0; +} + +void +_ecore_idle_enterer_call(void) +{ + Ecore_Oldlist *l; + + for (l = (Ecore_Oldlist *)idle_enterers; l; l = l->next) + { + Ecore_Idle_Enterer *ie; + + ie = (Ecore_Idle_Enterer *)l; + if (!ie->delete_me) + { + if (!ie->func(ie->data)) ecore_idle_enterer_del(ie); + } + } + if (idle_enterers_delete_me) + { + for (l = (Ecore_Oldlist *)idle_enterers; l;) + { + Ecore_Idle_Enterer *ie; + + ie = (Ecore_Idle_Enterer *)l; + l = l->next; + if (ie->delete_me) + { + idle_enterers = _ecore_list_remove(idle_enterers, ie); + ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); + free(ie); + } + } + idle_enterers_delete_me = 0; + } +} + +int +_ecore_idle_enterer_exist(void) +{ + if (idle_enterers) return 1; + return 0; +} diff --git a/ecore/src/lib/ecore/ecore_idle_exiter.c b/ecore/src/lib/ecore/ecore_idle_exiter.c new file mode 100644 index 0000000..1b8a6ae --- /dev/null +++ b/ecore/src/lib/ecore/ecore_idle_exiter.c @@ -0,0 +1,104 @@ +#include "ecore_private.h" +#include "Ecore.h" + +static Ecore_Idle_Exiter *idle_exiters = NULL; +static int idle_exiters_delete_me = 0; + +/** + * Add an idle exiter handler. + * @param func The function to call when exiting an idle state. + * @param data The data to be passed to the @p func call + * @return A handle to the idle exiter callback on success. NULL otherwise. + * @ingroup Idle_Group + */ +Ecore_Idle_Exiter * +ecore_idle_exiter_add(int (*func) (void *data), const void *data) +{ + Ecore_Idle_Exiter *ie; + + if (!func) return NULL; + ie = calloc(1, sizeof(Ecore_Idle_Exiter)); + if (!ie) return NULL; + ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_EXITER); + ie->func = func; + ie->data = (void *)data; + idle_exiters = _ecore_list_append(idle_exiters, ie); + return ie; +} + +/** + * Delete an idle exiter handler from the list to be run on exiting idle state. + * @param idle_exiter The idle exiter to delete + * @return The data pointer that was being being passed to the handler if + * successful. NULL otherwise. + * @ingroup Idle_Group + */ +void * +ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter) +{ + if (!ECORE_MAGIC_CHECK(idle_exiter, ECORE_MAGIC_IDLE_EXITER)) + { + ECORE_MAGIC_FAIL(idle_exiter, ECORE_MAGIC_IDLE_EXITER, + "ecore_idle_exiter_del"); + return NULL; + } + idle_exiter->delete_me = 1; + idle_exiters_delete_me = 1; + return idle_exiter->data; +} + +void +_ecore_idle_exiter_shutdown(void) +{ + while (idle_exiters) + { + Ecore_Idle_Exiter *ie; + + ie = idle_exiters; + idle_exiters = _ecore_list_remove(idle_exiters, ie); + ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); + free(ie); + } + idle_exiters_delete_me = 0; +} + +void +_ecore_idle_exiter_call(void) +{ + Ecore_Oldlist *l; + + for (l = (Ecore_Oldlist *)idle_exiters; l; l = l->next) + { + Ecore_Idle_Exiter *ie; + + ie = (Ecore_Idle_Exiter *)l; + if (!ie->delete_me) + { + if (!ie->func(ie->data)) ecore_idle_exiter_del(ie); + } + } + if (idle_exiters_delete_me) + { + for (l = (Ecore_Oldlist *)idle_exiters; l;) + { + Ecore_Idle_Exiter *ie; + + ie = (Ecore_Idle_Exiter *)l; + l = l->next; + if (ie->delete_me) + { + idle_exiters = _ecore_list_remove(idle_exiters, ie); + ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); + free(ie); + } + } + idle_exiters_delete_me = 0; + } +} + +int +_ecore_idle_exiter_exist(void) +{ + if (idle_exiters) return 1; + return 0; +} diff --git a/ecore/src/lib/ecore/ecore_idler.c b/ecore/src/lib/ecore/ecore_idler.c new file mode 100644 index 0000000..4332439 --- /dev/null +++ b/ecore/src/lib/ecore/ecore_idler.c @@ -0,0 +1,106 @@ +#include "ecore_private.h" +#include "Ecore.h" + +static Ecore_Idler *idlers = NULL; +static int idlers_delete_me = 0; + +/** + * Add an idler handler. + * @param func The function to call when idling. + * @param data The data to be passed to this @p func call. + * @return A idler handle if successfully added. NULL otherwise. + * @ingroup Idle_Group + */ +Ecore_Idler * +ecore_idler_add(int (*func) (void *data), const void *data) +{ + Ecore_Idler *ie; + + if (!func) return NULL; + ie = calloc(1, sizeof(Ecore_Idler)); + if (!ie) return NULL; + ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLER); + ie->func = func; + ie->data = (void *)data; + idlers = _ecore_list_append(idlers, ie); + return ie; +} + +/** + * Delete an idler callback from the list to be executed. + * @param idler The handle of the idler callback to delete + * @return The data pointer passed to the idler callback on success. NULL + * otherwise. + * @ingroup Idle_Group + */ +void * +ecore_idler_del(Ecore_Idler *idler) +{ + if (!ECORE_MAGIC_CHECK(idler, ECORE_MAGIC_IDLER)) + { + ECORE_MAGIC_FAIL(idler, ECORE_MAGIC_IDLER, + "ecore_idler_del"); + return NULL; + } + idler->delete_me = 1; + idlers_delete_me = 1; + return idler->data; +} + +void +_ecore_idler_shutdown(void) +{ + while (idlers) + { + Ecore_Idler *ie; + + ie = idlers; + idlers = _ecore_list_remove(idlers, ie); + ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); + free(ie); + } + idlers_delete_me = 0; +} + +int +_ecore_idler_call(void) +{ + Ecore_Oldlist *l; + + for (l = (Ecore_Oldlist *)idlers; l; l = l->next) + { + Ecore_Idler *ie; + + ie = (Ecore_Idler *)l; + if (!ie->delete_me) + { + if (!ie->func(ie->data)) ecore_idler_del(ie); + } + } + if (idlers_delete_me) + { + for (l = (Ecore_Oldlist *)idlers; l;) + { + Ecore_Idler *ie; + + ie = (Ecore_Idler *)l; + l = l->next; + if (ie->delete_me) + { + idlers = _ecore_list_remove(idlers, ie); + ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); + free(ie); + } + } + idlers_delete_me = 0; + } + if (idlers) return 1; + return 0; +} + +int +_ecore_idler_exist(void) +{ + if (idlers) return 1; + return 0; +} diff --git a/ecore/src/lib/ecore/ecore_list.c b/ecore/src/lib/ecore/ecore_list.c new file mode 100644 index 0000000..82562b9 --- /dev/null +++ b/ecore/src/lib/ecore/ecore_list.c @@ -0,0 +1,1537 @@ +#include "ecore_private.h" +#include "Ecore.h" + +/* Return information about the list */ +static void *_ecore_list_current(Ecore_List * list); + +/* Adding functions */ +static int _ecore_list_insert(Ecore_List * list, Ecore_List_Node *node); +static int _ecore_list_append_0(Ecore_List * list, Ecore_List_Node *node); +static int _ecore_list_prepend_0(Ecore_List * list, Ecore_List_Node *node); + +/* Remove functions */ +static void *_ecore_list_remove_0(Ecore_List * list); +static void *_ecore_list_remove_first(Ecore_List * list); +static void *_ecore_list_remove_last(Ecore_List * list); + +/* Basic traversal functions */ +static void *_ecore_list_next(Ecore_List * list); +static void *_ecore_list_goto_last(Ecore_List * list); +static void *_ecore_list_goto_first(Ecore_List * list); +static void *_ecore_list_goto(Ecore_List * list, void *data); +static void *_ecore_list_goto_index(Ecore_List *list, int index); + +/* Iterative function */ +static int _ecore_list_for_each(Ecore_List *list, Ecore_For_Each function, + void *user_data); + +/* Private double linked list functions */ +static void *_ecore_dlist_previous(Ecore_DList * list); +static void *_ecore_dlist_remove_first(Ecore_DList *list); +static void *_ecore_dlist_goto_index(Ecore_DList *list, int index); + +/* XXX: Begin deprecated code */ +void * +_ecore_list_append(void *in_list, void *in_item) +{ + Ecore_Oldlist *l, *new_l; + Ecore_Oldlist *list, *item; + + list = in_list; + item = in_item; + new_l = item; + new_l->next = NULL; + if (!list) + { + new_l->prev = NULL; + new_l->last = new_l; + return new_l; + } + if (list->last) l = list->last; + else for (l = list; l; l = l->next); + l->next = new_l; + new_l->prev = l; + list->last = new_l; + return list; +} + +void * +_ecore_list_prepend(void *in_list, void *in_item) +{ + Ecore_Oldlist *new_l; + Ecore_Oldlist *list, *item; + + list = in_list; + item = in_item; + new_l = item; + new_l->prev = NULL; + if (!list) + { + new_l->next = NULL; + new_l->last = new_l; + return new_l; + } + new_l->next = list; + list->prev = new_l; + new_l->last = list->last; + list->last = NULL; + return new_l; +} + +void * +_ecore_list_append_relative(void *in_list, void *in_item, void *in_relative) +{ + Ecore_Oldlist *l; + Ecore_Oldlist *list, *item, *relative; + + list = in_list; + item = in_item; + relative = in_relative; + for (l = list; l; l = l->next) + { + if (l == relative) + { + Ecore_Oldlist *new_l; + + new_l = item; + if (l->next) + { + new_l->next = l->next; + l->next->prev = new_l; + } + + else new_l->next = NULL; + l->next = new_l; + new_l->prev = l; + if (!new_l->next) + list->last = new_l; + return list; + } + } + return _ecore_list_append(list, item); +} + +void * +_ecore_list_prepend_relative(void *in_list, void *in_item, void *in_relative) +{ + Ecore_Oldlist *l; + Ecore_Oldlist *list, *item, *relative; + + list = in_list; + item = in_item; + relative = in_relative; + for (l = list; l; l = l->next) + { + if (l == relative) + { + Ecore_Oldlist *new_l; + + new_l = item; + new_l->prev = l->prev; + new_l->next = l; + l->prev = new_l; + if (new_l->prev) + { + new_l->prev->next = new_l; + if (!new_l->next) + list->last = new_l; + return list; + } + else + { + if (!new_l->next) + new_l->last = new_l; + else + { + new_l->last = list->last; + list->last = NULL; + } + return new_l; + } + } + } + return _ecore_list_prepend(list, item); +} + +void * +_ecore_list_remove(void *in_list, void *in_item) +{ + Ecore_Oldlist *return_l; + Ecore_Oldlist *list, *item; + + /* checkme */ + if(!in_list) + return in_list; + + list = in_list; + item = in_item; + if (!item) return list; + if (item->next) + item->next->prev = item->prev; + if (item->prev) + { + item->prev->next = item->next; + return_l = list; + } + else + { + return_l = item->next; + if (return_l) + return_l->last = list->last; + } + if (item == list->last) + list->last = item->prev; + item->next = NULL; + item->prev = NULL; + return return_l; +} + +void * +_ecore_list_find(void *in_list, void *in_item) +{ + Ecore_Oldlist *l; + Ecore_Oldlist *list, *item; + + list = in_list; + item = in_item; + for (l = list; l; l = l->next) + { + if (l == item) return item; + } + return NULL; +} +/* XXX: End deprecated code */ + +/** +@defgroup Ecore_Data_List_Creation_Group List Creation/Destruction Functions + +Functions that create, initialize and destroy Ecore_Lists. +*/ + +/** + * Create and initialize a new list. + * @return A new initialized list on success, @c NULL on failure. + * @ingroup Ecore_Data_List_Creation_Group + */ +Ecore_List *ecore_list_new() +{ + Ecore_List *list; + + list = (Ecore_List *)malloc(sizeof(Ecore_List)); + if (!list) + return NULL; + + if (!ecore_list_init(list)) { + FREE(list); + return NULL; + } + + return list; +} + +/** + * Initialize a list to some sane starting values. + * @param list The list to initialize. + * @return @c TRUE if successful, @c FALSE if an error occurs. + * @ingroup Ecore_Data_List_Creation_Group + */ +int ecore_list_init(Ecore_List *list) +{ + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + memset(list, 0, sizeof(Ecore_List)); + + return TRUE; +} + +/** + * Free a list and all of it's nodes. + * @param list The list to be freed. + * @ingroup Ecore_Data_List_Creation_Group + */ +void ecore_list_destroy(Ecore_List * list) +{ + void *data; + + CHECK_PARAM_POINTER("list", list); + + while (list->first) { + data = _ecore_list_remove_first(list); + if (list->free_func) + list->free_func(data); + } + + FREE(list); +} + +/** + * Set the function for freeing data. + * @param list The list that will use this function when nodes are + * destroyed. + * @param free_func The function that will free the key data. + * @return @c TRUE on successful set, @c FALSE otherwise. + */ +int ecore_list_set_free_cb(Ecore_List * list, Ecore_Free_Cb free_func) +{ + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + list->free_func = free_func; + + return TRUE; +} + +/** + * Checks the list for any nodes. + * @param list The list to check for nodes + * @return @c TRUE if no nodes in list, @c FALSE if the list contains nodes + */ +int ecore_list_is_empty(Ecore_List * list) +{ + int ret = TRUE; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + if (list->nodes) + ret = FALSE; + + return ret; +} + +/** + * Returns the number of the current node. + * @param list The list to return the number of the current node. + * @return The number of the current node in the list. + */ +int ecore_list_index(Ecore_List * list) +{ + int ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = list->index; + + return ret; +} + +/** + * Find the number of nodes in the list. + * @param list The list to find the number of nodes + * @return The number of nodes in the list. + */ +int ecore_list_nodes(Ecore_List * list) +{ + int ret = 0; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = list->nodes; + + return ret; +} + +/** +@defgroup Ecore_Data_List_Add_Item_Group List Item Adding Functions + +Functions that are used to add nodes to an Ecore_List. +*/ + +/** + * Append data to the list. + * @param list The list. + * @param data The data to append. + * @return @c FALSE if an error occurs, @c TRUE if appended successfully + * @ingroup Ecore_Data_List_Add_Item_Group + */ +inline int ecore_list_append(Ecore_List * list, void *data) +{ + int ret; + Ecore_List_Node *node; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + node = ecore_list_node_new(); + node->data = data; + + ret = _ecore_list_append_0(list, node); + + return ret; +} + +/* For adding items to the end of the list */ +static int _ecore_list_append_0(Ecore_List * list, Ecore_List_Node *end) +{ + if (list->last) { + list->last->next = end; + } + + list->last = end; + + if (list->first == NULL) { + list->first = end; + list->index = 0; + list->current = NULL; + } + + if (list->index >= list->nodes) + list->index++; + + list->nodes++; + + return TRUE; +} + +/** + * Prepend data to the beginning of the list. + * @param list The list. + * @param data The data to prepend. + * @return @c FALSE if an error occurs, @c TRUE if prepended successfully. + * @ingroup Ecore_Data_List_Add_Item_Group + */ +inline int ecore_list_prepend(Ecore_List * list, void *data) +{ + int ret; + Ecore_List_Node *node; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + node = ecore_list_node_new(); + node->data = data; + + ret = _ecore_list_prepend_0(list, node); + + return ret; +} + +/* For adding items to the beginning of the list */ +static int _ecore_list_prepend_0(Ecore_List * list, Ecore_List_Node *start) +{ + /* Put it at the beginning of the list */ + start->next = list->first; + + list->first = start; + + /* If no last node, then the first node is the last node */ + if (list->last == NULL) + list->last = list->first; + + list->nodes++; + list->index++; + + return TRUE; +} + +/** + * Insert data in front of the current point in the list. + * @param list The list to hold the inserted @p data. + * @param data The data to insert into @p list. + * @return @c FALSE if there is an error, @c TRUE on success + * @ingroup Ecore_Data_List_Add_Item_Group + */ +inline int ecore_list_insert(Ecore_List * list, void *data) +{ + int ret; + Ecore_List_Node *node; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + node = ecore_list_node_new(); + node->data = data; + + ret = _ecore_list_insert(list, node); + + return ret; +} + +/* For adding items in front of the current position in the list */ +static int _ecore_list_insert(Ecore_List * list, Ecore_List_Node *new_node) +{ + /* + * If the current point is at the beginning of the list, then it's the + * same as prepending it to the list. + */ + if (list->current == list->first) + return _ecore_list_prepend_0(list, new_node); + + if (list->current == NULL) { + int ret_value; + + ret_value = _ecore_list_append_0(list, new_node); + list->current = list->last; + + return ret_value; + } + + /* Setup the fields of the new node */ + new_node->next = list->current; + + /* And hook the node into the list */ + _ecore_list_goto_index(list, ecore_list_index(list) - 1); + + list->current->next = new_node; + + /* Now move the current item to the inserted item */ + list->current = new_node; + list->index++; + list->nodes++; + + return TRUE; +} + +/** +@defgroup Ecore_Data_List_Remove_Item_Group List Item Removing Functions + +Functions that remove nodes from an Ecore_List. +*/ + +/** + * Remove the current item from the list. + * @param list The list to remove the current item + * @return A pointer to the removed data on success, @c NULL on failure. + * @ingroup Ecore_Data_List_Remove_Item_Group + */ +inline void *ecore_list_remove(Ecore_List * list) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = _ecore_list_remove_0(list); + + return ret; +} + +/* Remove the current item from the list */ +static void *_ecore_list_remove_0(Ecore_List * list) +{ + void *ret = NULL; + Ecore_List_Node *old; + + if (!list) + return FALSE; + + if (ecore_list_is_empty(list)) + return FALSE; + + if (!list->current) + return FALSE; + + if (list->current == list->first) + return _ecore_list_remove_first(list); + + if (list->current == list->last) + return _ecore_list_remove_last(list); + + old = list->current; + + _ecore_list_goto_index(list, list->index - 1); + + list->current->next = old->next; + old->next = NULL; + ret = old->data; + old->data = NULL; + + _ecore_list_next(list); + + ecore_list_node_destroy(old, NULL); + list->nodes--; + + return ret; +} + +/** + * Remove and free the data in lists current position. + * @param list The list to remove and free the current item. + * @return @c TRUE on success, @c FALSE on error + * @ingroup Ecore_Data_List_Remove_Item_Group + */ +int ecore_list_remove_destroy(Ecore_List *list) +{ + void *data; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + data = _ecore_list_remove_0(list); + if (list->free_func) + list->free_func(data); + + return TRUE; +} + +/** + * Remove the first item from the list. + * @param list The list to remove the current item + * @return Returns a pointer to the removed data on success, @c NULL on + * failure. + * @ingroup Ecore_Data_List_Remove_Item_Group + */ +inline void *ecore_list_remove_first(Ecore_List * list) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = _ecore_list_remove_first(list); + + return ret; +} + +/* Remove the first item from the list */ +static void *_ecore_list_remove_first(Ecore_List * list) +{ + void *ret = NULL; + Ecore_List_Node *old; + + if (!list) + return FALSE; + + if (ecore_list_is_empty(list)) + return FALSE; + + if (!list->first) + return FALSE; + + old = list->first; + + list->first = list->first->next; + + if (list->current == old) + list->current = list->first; + else + (list->index ? list->index-- : 0); + + if (list->last == old) + list->last = list->first; + + ret = old->data; + old->data = NULL; + + ecore_list_node_destroy(old, NULL); + list->nodes--; + + return ret; +} + +/** + * Remove the last item from the list. + * @param list The list to remove the last node from + * @return A pointer to the removed data on success, @c NULL on failure. + * @ingroup Ecore_Data_List_Remove_Item_Group + */ +inline void *ecore_list_remove_last(Ecore_List * list) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = _ecore_list_remove_last(list); + + return ret; +} + +/* Remove the last item from the list */ +static void *_ecore_list_remove_last(Ecore_List * list) +{ + void *ret = NULL; + Ecore_List_Node *old, *prev; + + if (!list) + return FALSE; + + if (ecore_list_is_empty(list)) + return FALSE; + + if (!list->last) + return FALSE; + + old = list->last; + if (list->current == old) + list->current = NULL; + + if (list->first == old) + list->first = NULL; + for (prev = list->first; prev && prev->next != old; prev = prev->next); + list->last = prev; + if (prev) { + prev->next = NULL; + if (list->current == old) { + list->current = NULL; + } + } + + + if (old) { + old->next = NULL; + ret = old->data; + old->data = NULL; + } + + ecore_list_node_destroy(old, NULL); + list->nodes--; + + return ret; +} + +/** +@defgroup Ecore_Data_List_Traverse_Group List Traversal Functions + +Functions that can be used to traverse an Ecore_List. +*/ + +/** + * Make the current item the item with the given index number. + * @param list The list. + * @param index The position to move the current item. + * @return A pointer to new current item on success, @c NULL on failure. + * @ingroup Ecore_Data_List_Traverse_Group + */ +inline void *ecore_list_goto_index(Ecore_List * list, int index) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = _ecore_list_goto_index(list, index); + + return ret; +} + +/* This is the non-threadsafe version, use this inside internal functions that + * already lock the list */ +static void *_ecore_list_goto_index(Ecore_List *list, int index) +{ + int i; + + if (!list) + return FALSE; + + if (ecore_list_is_empty(list)) + return FALSE; + + if (index > ecore_list_nodes(list) || index < 0) + return FALSE; + + _ecore_list_goto_first(list); + + for (i = 0; i < index && _ecore_list_next(list); i++); + + if (i >= list->nodes) + return FALSE; + + list->index = i; + + return list->current->data; +} + +/** + * Make the current item the node that contains @p data. + * @param list The list. + * @param data The data to find. + * @return A pointer to @p data on success, @c NULL on failure. + * @ingroup Ecore_Data_List_Traverse_Group + */ +inline void *ecore_list_goto(Ecore_List * list, void *data) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = _ecore_list_goto(list, data); + + return ret; +} + +/* Set the current position to the node containing data */ +static void *_ecore_list_goto(Ecore_List * list, void *data) +{ + int index; + Ecore_List_Node *node; + + if (!list) + return NULL; + + index = 0; + + node = list->first; + while (node && node->data) { + Ecore_List_Node *next; + + if (node->data == data) + break; + + next = node->next; + + node = next; + + index++; + } + + if (!node) + return NULL; + + list->current = node; + list->index = index; + + return list->current->data; +} + +/** + * Make the current item the first item in the list + * @param list The list. + * @return A pointer to the first item on success, @c NULL on failure + * @ingroup Ecore_Data_List_Traverse_Group + */ +inline void *ecore_list_goto_first(Ecore_List *list) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = _ecore_list_goto_first(list); + + return ret; +} + +/* Set the current position to the start of the list */ +static void *_ecore_list_goto_first(Ecore_List * list) +{ + if (!list || !list->first) + return NULL; + + list->current = list->first; + list->index = 0; + + return list->current->data; +} + +/** + * Make the current item the last item in the list. + * @param list The list. + * @return A pointer to the last item on success, @c NULL on failure. + * @ingroup Ecore_Data_List_Traverse_Group + */ +inline void *ecore_list_goto_last(Ecore_List * list) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = _ecore_list_goto_last(list); + + return ret; +} + +/* Set the current position to the end of the list */ +static void *_ecore_list_goto_last(Ecore_List * list) +{ + if (!list || !list->last) + return NULL; + + list->current = list->last; + list->index = (list->nodes - 1); + + return list->current->data; +} + +/** + * Retrieve the data pointed to by the current item in @p list. + * @param list The list. + * @return Returns the data at current position, can be @c NULL. + */ +inline void *ecore_list_current(Ecore_List * list) +{ + void *ret; + + ret = _ecore_list_current(list); + + return ret; +} + +/* Return the data of the current node without incrementing */ +static void *_ecore_list_current(Ecore_List * list) +{ + void *ret; + + if (!list->current) + return NULL; + + ret = list->current->data; + + return ret; +} + +/** + * Retrieve the data pointed to by the current item, and make the next item + * the current item. + * @param list The list to retrieve data from. + * @return The current item in the list on success, @c NULL on failure. + */ +inline void *ecore_list_next(Ecore_List * list) +{ + void *data; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + data = _ecore_list_next(list); + + return data; +} + +/* Return the data contained in the current node and go to the next node */ +static void *_ecore_list_next(Ecore_List * list) +{ + void *data; + Ecore_List_Node *ret; + Ecore_List_Node *next; + + if (!list->current) + return NULL; + + ret = list->current; + next = list->current->next; + + list->current = next; + list->index++; + + data = ret->data; + + return data; +} + +/** + * Remove all nodes from @p list. + * @param list The list. + * @return Returns @c TRUE on success, @c FALSE on error. + * @note The data for each item on the list is not freed by + * @c ecore_list_clear(). + */ +int ecore_list_clear(Ecore_List * list) +{ + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + while (!ecore_list_is_empty(list)) + _ecore_list_remove_first(list); + + return TRUE; +} + +/** + * Execute function for each node in @p list. + * @param list The list. + * @param function The function to pass each node from @p list to. + * @return Returns @c TRUE on success, @c FALSE on failure. + * @ingroup Ecore_Data_List_Traverse_Group + */ +int ecore_list_for_each(Ecore_List *list, Ecore_For_Each function, + void *user_data) +{ + int ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = _ecore_list_for_each(list, function, user_data); + + return ret; +} + +/* The real meat of executing the function for each data node */ +static int _ecore_list_for_each(Ecore_List *list, Ecore_For_Each function, + void *user_data) +{ + void *value; + + if (!list || !function) + return FALSE; + + _ecore_list_goto_first(list); + while ((value = _ecore_list_next(list)) != NULL) + function(value, user_data); + + return TRUE; +} + +/* Initialize a node to starting values */ +int ecore_list_node_init(Ecore_List_Node * node) +{ + + CHECK_PARAM_POINTER_RETURN("node", node, FALSE); + + node->next = NULL; + node->data = NULL; + + return TRUE; +} + +/** +@defgroup Ecore_Data_List_Node_Group List Node Functions + +Functions that are used in the creation, maintenance and destruction of +Ecore_List nodes. +*/ + +/** + * Allocates and initializes a new list node. + * @return A new Ecore_List_Node on success, @c NULL otherwise. + * @ingroup Ecore_Data_List_Node_Group + */ +Ecore_List_Node *ecore_list_node_new() +{ + Ecore_List_Node *new_node; + + new_node = malloc(sizeof(Ecore_List_Node)); + + if (!ecore_list_node_init(new_node)) { + FREE(new_node); + return NULL; + } + + return new_node; +} + +/** + * Calls the function to free the data and the node. + * @param node Node to destroy. + * @param free_func Function to call if @p node points to data to free. + * @return @c TRUE. + * @ingroup Ecore_Data_List_Node_Group + */ +int ecore_list_node_destroy(Ecore_List_Node * node, Ecore_Free_Cb free_func) +{ + CHECK_PARAM_POINTER_RETURN("node", node, FALSE); + + if (free_func && node->data) + free_func(node->data); + + FREE(node); + + return TRUE; +} + +/** + * @defgroup Ecore_Data_DList_Creation_Group Doubly Linked List Creation/Destruction Functions + * + * Functions used to create, initialize and destroy @c Ecore_DLists. + */ + +/** + * Creates and initialises a new doubly linked list. + * @return A new initialised doubly linked list on success, @c NULL + * on failure. + * @ingroup Ecore_Data_DList_Creation_Group + */ +Ecore_DList *ecore_dlist_new() +{ + Ecore_DList *list = NULL; + + list = (Ecore_DList *)malloc(sizeof(Ecore_DList)); + if (!list) + return NULL; + + if (!ecore_dlist_init(list)) { + IF_FREE(list); + return NULL; + } + + return list; +} + +/** + * Initialises a list to some sane starting values. + * @param list The doubly linked list to initialise. + * @return @c TRUE if successful, @c FALSE if an error occurs. + * @ingroup Ecore_Data_DList_Creation_Group + */ +int ecore_dlist_init(Ecore_DList *list) +{ + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + memset(list, 0, sizeof(Ecore_DList)); + + return TRUE; +} + +/** + * Frees a doubly linked list and all of its nodes. + * @param list The doubly linked list to be freed. + * @ingroup Ecore_Data_DList_Creation_Group + */ +void ecore_dlist_destroy(Ecore_DList * list) +{ + void *data; + CHECK_PARAM_POINTER("list", list); + + while (list->first) { + data = _ecore_dlist_remove_first(list); + if (list->free_func) + list->free_func(data); + } + + FREE(list); +} + +/** + * Sets the function used for freeing data stored in a doubly linked list. + * @param list The doubly linked list that will use this function when + * nodes are destroyed. + * @param free_func The function that will free the key data + * @return @c TRUE on success, @c FALSE on failure. + * @ingroup Ecore_Data_DList_Creation_Group + */ +int ecore_dlist_set_free_cb(Ecore_DList * list, Ecore_Free_Cb free_func) +{ + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + return ecore_list_set_free_cb(ECORE_LIST(list), free_func); +} + +/** + * Returns whether there is anything in the given doubly linked list. + * @param list The given doubly linked list. + * @return @c TRUE if there are nodes, @c FALSE otherwise. + */ +int ecore_dlist_is_empty(Ecore_DList * list) +{ + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + return ecore_list_is_empty(ECORE_LIST(list)); +} + +/** + * Retrieves the index of the current node of the given doubly linked list. + * @param list The given doubly linked list. + * @return The index of the current node. + */ +inline int ecore_dlist_index(Ecore_DList * list) +{ + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + return ecore_list_index(ECORE_LIST(list)); +} + +/** + * @defgroup Ecore_Data_DList_Add_Item_Group Doubly Linked List Adding Functions + * + * Functions that are used to add nodes to an Ecore_DList. + */ + +/** + * Appends data to the given doubly linked list. + * @param list The given doubly linked list. + * @param data The data to append. + * @return @c TRUE if the data is successfully appended, @c FALSE otherwise. + * @ingroup Ecore_Data_DList_Add_Item_Group + */ +int ecore_dlist_append(Ecore_DList * list, void *data) +{ + int ret; + Ecore_DList_Node *prev; + Ecore_DList_Node *node; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + node = ecore_dlist_node_new(); + ECORE_LIST_NODE(node)->data = data; + + prev = ECORE_DLIST_NODE(ECORE_LIST(list)->last); + ret = _ecore_list_append_0(ECORE_LIST(list), ECORE_LIST_NODE(node)); + if (ret) { + node->previous = prev; + } + + return ret; +} + +/** + * Adds data to the very beginning of the given doubly linked list. + * @param list The given doubly linked list. + * @param data The data to prepend. + * @return @c TRUE if the data is successfully prepended, @c FALSE otherwise. + * @ingroup Ecore_Data_DList_Add_Item_Group + */ +int ecore_dlist_prepend(Ecore_DList * list, void *data) +{ + int ret; + Ecore_DList_Node *prev; + Ecore_DList_Node *node; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + node = ecore_dlist_node_new(); + ECORE_LIST_NODE(node)->data = data; + + prev = ECORE_DLIST_NODE(ECORE_LIST(list)->first); + ret = _ecore_list_prepend_0(ECORE_LIST(list), ECORE_LIST_NODE(node)); + if (ret && prev) + prev->previous = node; + + return ret; +} + +/** + * Inserts data at the current point in the given doubly linked list. + * @param list The given doubly linked list. + * @param data The data to be inserted. + * @return @c TRUE on success, @c FALSE otherwise. + * @ingroup Ecore_Data_DList_Add_Item_Group + */ +int ecore_dlist_insert(Ecore_DList * list, void *data) +{ + int ret; + Ecore_DList_Node *prev; + Ecore_DList_Node *node; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + prev = ECORE_DLIST_NODE(ECORE_LIST(list)->current); + if (!prev) + prev = ECORE_DLIST_NODE(ECORE_LIST(list)->last); + + if (prev) + prev = prev->previous; + + node = ecore_dlist_node_new(); + ECORE_LIST_NODE(node)->data = data; + + ret = _ecore_list_insert(list, ECORE_LIST_NODE(node)); + if (!ret) { + return ret; + } + + if (ECORE_LIST_NODE(node)->next) + ECORE_DLIST_NODE(ECORE_LIST_NODE(node)->next)->previous = node; + + if (prev) + node->previous = prev; + + return ret; +} + +/** + * @defgroup Ecore_Data_DList_Remove_Item_Group Doubly Linked List Removing Functions + * + * Functions that remove nodes from an @c Ecore_DList. + */ + +/** + * Removes the current item from the given doubly linked list. + * @param list The given doubly linked list. + * @return A pointer to the removed data on success, @c NULL otherwise. + * @ingroup Ecore_Data_DList_Remove_Item_Group + */ +void *ecore_dlist_remove(Ecore_DList * list) +{ + void *ret; + Ecore_List *l2 = ECORE_LIST(list); + Ecore_DList_Node *node; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + if (l2->current) { + node = ECORE_DLIST_NODE(list->current->next); + if (node) + node->previous = ECORE_DLIST_NODE(l2->current)->previous; + } + ret = _ecore_list_remove_0(list); + + return ret; +} + +/** + * Removes the first item from the given doubly linked list. + * @param list The given doubly linked list. + * @return A pointer to the removed data on success, @c NULL on failure. + * @ingroup Ecore_Data_DList_Remove_Item_Group + */ +void *ecore_dlist_remove_first(Ecore_DList * list) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = _ecore_dlist_remove_first(list); + + return ret; +} + +/** + * Removes and frees the data at the current position in the given doubly + * linked list. + * @param list The given doubly linked list. + * @return @c TRUE on success, @c FALSE otherwise. + * @ingroup Ecore_Data_DList_Remove_Item_Group + */ +int ecore_dlist_remove_destroy(Ecore_DList *list) +{ + void *data; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + data = ecore_dlist_remove(list); + if (!data) + return FALSE; + + if (list->free_func) + list->free_func(data); + + return TRUE; +} + +static void *_ecore_dlist_remove_first(Ecore_DList *list) +{ + void *ret; + + if (!list) + return FALSE; + + ret = _ecore_list_remove_first(list); + if (ret && ECORE_LIST(list)->first) + ECORE_DLIST_NODE(ECORE_LIST(list)->first)->previous = NULL; + + return ret; +} + +/** + * Removes the last item from the given doubly linked list. + * @param list The given doubly linked list. + * @return A pointer to the removed data on success, @c NULL otherwise. + * @ingroup Ecore_Data_DList_Remove_Item_Group + */ +void *ecore_dlist_remove_last(Ecore_DList * list) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = _ecore_list_remove_last(list); + + return ret; +} + +/** + * Moves the current item to the index number in the given doubly linked list. + * @param list The given doubly linked list. + * @param index The position to move the current item + * @return The node at specified index on success, @c NULL on error. + */ +void *ecore_dlist_goto_index(Ecore_DList * list, int index) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = _ecore_dlist_goto_index(list, index); + + return ret; +} + +/* This is the non-threadsafe version, use this inside internal functions that + * already lock the list */ +static void *_ecore_dlist_goto_index(Ecore_DList *list, int index) +{ + int i, increment; + + if (!list) + return FALSE; + + if (ecore_list_is_empty(ECORE_LIST(list))) + return FALSE; + + if (index > ecore_list_nodes(ECORE_LIST(list)) || index < 0) + return FALSE; + + if (ECORE_LIST(list)->index >= ECORE_LIST(list)->nodes) + _ecore_list_goto_last(ECORE_LIST(list)); + + if (index < ECORE_LIST(list)->index) + increment = -1; + else + increment = 1; + + for (i = ECORE_LIST(list)->index; i != index; i += increment) { + if (increment > 0) + _ecore_list_next(list); + else + _ecore_dlist_previous(list); + } + + return _ecore_list_current(list); +} + +/** + * @brief Move the current item to the node that contains data + * @param list: the list to move the current item in + * @param data: the data to find and set the current item to + * + * @return Returns specified data on success, NULL on error + */ +void *ecore_dlist_goto(Ecore_DList * list, void *data) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = _ecore_list_goto(ECORE_LIST(list), data); + + return ret; +} + +/** + * @brief Move the current pointer to the first item in the list + * @param list: the list to change the current to the first item + * + * @return Returns a pointer to the first item on success, NULL on failure. + */ +void *ecore_dlist_goto_first(Ecore_DList *list) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = _ecore_list_goto_first(list); + + return ret; +} + +/** + * @brief Move the pointer to the current item to the last item + * @param list: the list to move the current item pointer to the last + * @return Returns a pointer to the last item in the list , NULL if empty. + */ +void *ecore_dlist_goto_last(Ecore_DList * list) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ret = _ecore_list_goto_last(ECORE_LIST(list)); + + return ret; +} + +/** + * @brief Return the data in the current list item + * @param list: the list to the return the current data + * @return Returns value of the current data item, NULL if no current item + */ +void *ecore_dlist_current(Ecore_DList * list) +{ + void *ret; + + ret = _ecore_list_current(ECORE_LIST(list)); + + return ret; +} + +/** + * @brief Move to the next item in the list and return current item + * @param list: the list to move to the next item in. + * @return Returns data in the current list node, or NULL on error + */ +void *ecore_dlist_next(Ecore_DList * list) +{ + void *data; + + data = _ecore_list_next(list); + + return data; +} + +/** + * @brief Move to the previous item and return current item + * @param list: the list to move to the previous item in. + * @return Returns data in the current list node, or NULL on error + */ +void *ecore_dlist_previous(Ecore_DList * list) +{ + void *data; + + data = _ecore_dlist_previous(list); + + return data; +} + +static void *_ecore_dlist_previous(Ecore_DList * list) +{ + void *data = NULL; + + if (!list) + return NULL; + + if (ECORE_LIST(list)->current) { + data = ECORE_LIST(list)->current->data; + ECORE_LIST(list)->current = ECORE_LIST_NODE(ECORE_DLIST_NODE( + ECORE_LIST(list)->current)->previous); + ECORE_LIST(list)->index--; + } + else + _ecore_list_goto_last(ECORE_LIST(list)); + + return data; +} + +/** + * @brief Remove all nodes from the list. + * @param list: the list to remove all nodes from + * + * @return Returns TRUE on success, FALSE on errors + */ +int ecore_dlist_clear(Ecore_DList * list) +{ + CHECK_PARAM_POINTER_RETURN("list", list, FALSE); + + ecore_list_clear(ECORE_LIST(list)); + + return TRUE; +} + +/* + * @brief Initialize a node to sane starting values + * @param node: the node to initialize + * @return Returns TRUE on success, FALSE on errors + */ +int ecore_dlist_node_init(Ecore_DList_Node * node) +{ + int ret; + + CHECK_PARAM_POINTER_RETURN("node", node, FALSE); + + ret = ecore_list_node_init(ECORE_LIST_NODE(node)); + if (ret) + node->previous = NULL; + + return ret; +} + +/* + * @brief Allocate and initialize a new list node + * @return Returns NULL on error, new list node on success + */ +Ecore_DList_Node *ecore_dlist_node_new() +{ + Ecore_DList_Node *new_node; + + new_node = malloc(sizeof(Ecore_DList_Node)); + + if (!new_node) + return NULL; + + if (!ecore_dlist_node_init(new_node)) { + FREE(new_node); + return NULL; + } + + return new_node; +} + +/* + * @brief Call the data's free callback function, then free the node + * @param node: the node to be freed + * @param free_func: the callback function to execute on the data + * @return Returns TRUE on success, FALSE on error + */ +int ecore_dlist_node_destroy(Ecore_DList_Node * node, Ecore_Free_Cb free_func) +{ + CHECK_PARAM_POINTER_RETURN("node", node, + FALSE); + + return ecore_list_node_destroy(ECORE_LIST_NODE(node), free_func); +} diff --git a/ecore/src/lib/ecore/ecore_main.c b/ecore/src/lib/ecore/ecore_main.c new file mode 100644 index 0000000..6944db4 --- /dev/null +++ b/ecore/src/lib/ecore/ecore_main.c @@ -0,0 +1,635 @@ +#include "ecore_private.h" +#include "Ecore.h" + +#ifdef WIN32 +#include +#endif + +#define FIX_HZ 1 + +#include +#include +#include +#include + +#ifdef FIX_HZ +#include +#ifndef HZ +#define HZ 100 +#endif +#endif + + +static int _ecore_main_select(double timeout); +static void _ecore_main_fd_handlers_cleanup(void); +static void _ecore_main_fd_handlers_call(void); +static int _ecore_main_fd_handlers_buf_call(void); +static void _ecore_main_loop_iterate_internal(int once_only); + +static int in_main_loop = 0; +static int do_quit = 0; +static Ecore_Fd_Handler *fd_handlers = NULL; +static int fd_handlers_delete_me = 0; + +static double t1 = 0.0; +static double t2 = 0.0; + +/** + * @defgroup Ecore_Main_Loop_Group Main Loop Functions + * + * These functions control the Ecore event handling loop. This loop is + * designed to work on embedded systems all the way to large and + * powerful mutli-cpu workstations. + * + * It serialises all system signals and events into a single event + * queue, that can be easily processed without needing to worry about + * concurrency. A properly written, event-driven program using this + * kind of programming does not need threads. It makes the program very + * robust and easy to follow. + * + * Here is an example of simple program and its basic event loop flow: + * @image html prog_flow.png + * + * For examples of setting up and using a main loop, see + * @ref event_handler_example.c and @ref timer_example.c. + */ + +/** + * Runs a single iteration of the main loop to process everything on the + * queue. + * @ingroup Ecore_Main_Loop_Group + */ +void +ecore_main_loop_iterate(void) +{ + _ecore_main_loop_iterate_internal(1); +} + +/** + * Runs the application main loop. + * + * This function will not return until @ref ecore_main_loop_quit is called. + * + * @ingroup Ecore_Main_Loop_Group + */ +void +ecore_main_loop_begin(void) +{ + in_main_loop++; + for (;do_quit == 0;) _ecore_main_loop_iterate_internal(0); + do_quit = 0; + in_main_loop--; +} + +/** + * Quits the main loop once all the events currently on the queue have + * been processed. + * @ingroup Ecore_Main_Loop_Group + */ +void +ecore_main_loop_quit(void) +{ + do_quit = 1; +} + +/** + * @defgroup Ecore_FD_Handler_Group File Event Handling Functions + * + * Functions that deal with file descriptor handlers. + */ + +/** + * Adds a callback for activity on the given file descriptor. + * + * @p func will be called during the execution of @ref ecore_main_loop_begin + * when the file descriptor is available for reading, or writing, or both. + * @p buf_func is called during event loop handling to check if data that has + * been read from the file descriptor is in a buffer and is available to + * read. + * + * @param fd The file descriptor to watch. + * @param flags To watch it for read (@c ECORE_FD_READ) and/or + * (@c ECORE_FD_WRITE) write ability. @c ECORE_FD_ERROR + * + * @param func The callback function. + * @param data The data to pass to the callback. + * @param buf_func The function to call to check if any data has been + * buffered and already read from the fd. Can be @c NULL. + * @param buf_data The data to pass to the @p buf_func function. + * @return A fd handler handle if successful. @c NULL otherwise. + * @ingroup Ecore_FD_Handler_Group + */ +Ecore_Fd_Handler * +ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, int (*func) (void *data, Ecore_Fd_Handler *fd_handler), const void *data, int (*buf_func) (void *buf_data, Ecore_Fd_Handler *fd_handler), const void *buf_data) +{ + Ecore_Fd_Handler *fdh; + + if ((fd < 0) || + (flags == 0) || + (!func)) return NULL; + fdh = calloc(1, sizeof(Ecore_Fd_Handler)); + if (!fdh) return NULL; + ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER); + fdh->fd = fd; + fdh->flags = flags; + fdh->read_active = 0; + fdh->write_active = 0; + fdh->error_active = 0; + fdh->delete_me = 0; + fdh->func = func; + fdh->data = (void *)data; + fdh->buf_func = buf_func; + fdh->buf_data = (void *)buf_data; + fd_handlers = _ecore_list_append(fd_handlers, fdh); + return fdh; +} + +/** + * Deletes the given FD handler. + * @param fd_handler The given FD handler. + * @return The data pointer set using @ref ecore_main_fd_handler_add, + * for @p fd_handler on success. @c NULL otherwise. + * @ingroup Ecore_FD_Handler_Group + */ +void * +ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler) +{ + if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) + { + ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, + "ecore_main_fd_handler_del"); + return NULL; + } + fd_handler->delete_me = 1; + fd_handlers_delete_me = 1; + return fd_handler->data; +} + +void +ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, void (*func) (void *data, Ecore_Fd_Handler *fd_handler), const void *data) +{ + if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) + { + ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, + "ecore_main_fd_handler_prepare_callback_set"); + return; + } + fd_handler->prep_func = func; + fd_handler->prep_data = (void *) data; +} + +/** + * Retrieves the file descriptor that the given handler is handling. + * @param fd_handler The given FD handler. + * @return The file descriptor the handler is watching. + * @ingroup Ecore_FD_Handler_Group + */ +int +ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler) +{ + if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) + { + ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, + "ecore_main_fd_handler_fd_get"); + return -1; + } + return fd_handler->fd; +} + +/** + * Return if read, write or error, or a combination thereof, is active on the + * file descriptor of the given FD handler. + * @param fd_handler The given FD handler. + * @param flags The flags, @c ECORE_FD_READ, @c ECORE_FD_WRITE or + * @c ECORE_FD_ERROR to query. + * @return @c 1 if any of the given flags are active. @c 0 otherwise. + * @ingroup Ecore_FD_Handler_Group + */ +int +ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags) +{ + int ret; + + if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) + { + ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, + "ecore_main_fd_handler_active_get"); + return 0; + } + ret = 0; + if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = 1; + if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = 1; + if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = 1; + return ret; +} + +/** + * Set what active streams the given FD handler should be monitoring. + * @param fd_handler The given FD handler. + * @param flags The flags to be watching. + * @ingroup Ecore_FD_Handler_Group + */ +void +ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags) +{ + if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) + { + ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, + "ecore_main_fd_handler_active_set"); + return; + } + fd_handler->flags = flags; +} + +void +_ecore_main_shutdown(void) +{ + if (in_main_loop) + { + fprintf(stderr, + "\n" + "*** ECORE WARINING: Calling ecore_shutdown() while still in the main loop.\n" + "*** Program may crash or behave strangely now.\n"); + return; + } + while (fd_handlers) + { + Ecore_Fd_Handler *fdh; + + fdh = fd_handlers; + fd_handlers = _ecore_list_remove(fd_handlers, fdh); + ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE); + free(fdh); + } + fd_handlers_delete_me = 0; +} + +static int +_ecore_main_select(double timeout) +{ + struct timeval tv, *t; + fd_set rfds, wfds, exfds; + int max_fd; + int ret; + Ecore_Oldlist *l; + + t = NULL; + if (timeout > 0.0) + { + int sec, usec; + +#ifdef FIX_HZ + timeout += (0.5 / HZ); + sec = (int)timeout; + usec = (int)((timeout - (double)sec) * 1000000); +#else + sec = (int)timeout; + usec = (int)((timeout - (double)sec) * 1000000); +#endif + tv.tv_sec = sec; + tv.tv_usec = usec; + t = &tv; + } + else if (timeout == 0.0) + { + tv.tv_sec = 0; + tv.tv_usec = 0; + t = &tv; + } + max_fd = 0; + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&exfds); + + /* call the prepare callback for all handlers */ + for (l = (Ecore_Oldlist *)fd_handlers; l; l = l->next) + { + Ecore_Fd_Handler *fdh; + + fdh = (Ecore_Fd_Handler *)l; + + if (fdh->prep_func) + fdh->prep_func (fdh->prep_data, fdh); + } + for (l = (Ecore_Oldlist *)fd_handlers; l; l = l->next) + { + Ecore_Fd_Handler *fdh; + + fdh = (Ecore_Fd_Handler *)l; + if (fdh->flags & ECORE_FD_READ) + { + FD_SET(fdh->fd, &rfds); + if (fdh->fd > max_fd) max_fd = fdh->fd; + } + if (fdh->flags & ECORE_FD_WRITE) + { + FD_SET(fdh->fd, &wfds); + if (fdh->fd > max_fd) max_fd = fdh->fd; + } + if (fdh->flags & ECORE_FD_ERROR) + { + FD_SET(fdh->fd, &exfds); + if (fdh->fd > max_fd) max_fd = fdh->fd; + } + } +#ifndef WIN32 + if (_ecore_signal_count_get()) return -1; +#endif + ret = select(max_fd + 1, &rfds, &wfds, &exfds, t); + if (ret < 0) + { + if (errno == EINTR) return -1; + } + if (ret > 0) + { + for (l = (Ecore_Oldlist *)fd_handlers; l; l = l->next) + { + Ecore_Fd_Handler *fdh; + + fdh = (Ecore_Fd_Handler *)l; + if (!fdh->delete_me) + { + if (FD_ISSET(fdh->fd, &rfds)) + fdh->read_active = 1; + if (FD_ISSET(fdh->fd, &wfds)) + fdh->write_active = 1; + if (FD_ISSET(fdh->fd, &exfds)) + fdh->error_active = 1; + } + } + _ecore_main_fd_handlers_cleanup(); + return 1; + } + return 0; +} + +static void +_ecore_main_fd_handlers_cleanup(void) +{ + Ecore_Oldlist *l; + + if (!fd_handlers_delete_me) return; + for (l = (Ecore_Oldlist *)fd_handlers; l;) + { + Ecore_Fd_Handler *fdh; + + fdh = (Ecore_Fd_Handler *)l; + l = l->next; + if (fdh->delete_me) + { + fd_handlers = _ecore_list_remove(fd_handlers, fdh); + ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE); + free(fdh); + } + } + fd_handlers_delete_me = 0; +} + +static void +_ecore_main_fd_handlers_call(void) +{ + Ecore_Oldlist *l; + + for (l = (Ecore_Oldlist *)fd_handlers; l; l = l->next) + { + Ecore_Fd_Handler *fdh; + + fdh = (Ecore_Fd_Handler *)l; + if (!fdh->delete_me) + { + if ((fdh->read_active) || + (fdh->write_active) || + (fdh->error_active)) + { + if (!fdh->func(fdh->data, fdh)) + { + fdh->delete_me = 1; + fd_handlers_delete_me = 1; + } + fdh->read_active = 0; + fdh->write_active = 0; + fdh->error_active = 0; + } + } + } +} + +static int +_ecore_main_fd_handlers_buf_call(void) +{ + Ecore_Oldlist *l; + int ret; + + ret = 0; + for (l = (Ecore_Oldlist *)fd_handlers; l; l = l->next) + { + Ecore_Fd_Handler *fdh; + + fdh = (Ecore_Fd_Handler *)l; + if (!fdh->delete_me) + { + if (fdh->buf_func) + { + if (fdh->buf_func(fdh->buf_data, fdh)) + { + ret |= fdh->func(fdh->data, fdh); + fdh->read_active = 1; + } + } + } + } + return ret; +} + +static void +_ecore_main_loop_iterate_internal(int once_only) +{ + double next_time; + int have_event = 0; + int have_signal; + + in_main_loop++; + /* expire any timers */ + { + double now; + + now = ecore_time_get(); + while (_ecore_timer_call(now)); + _ecore_timer_cleanup(); + } + /* any timers re-added as a result of these are allowed to go */ + _ecore_timer_enable_new(); +#ifndef WIN32 + /* process signals into events .... */ + while (_ecore_signal_count_get()) _ecore_signal_call(); +#endif + if (_ecore_event_exist()) + { + int ret; + + have_event = 1; + have_signal = 1; + ret = _ecore_main_select(0); + goto process_events; + } + /* call idle enterers ... */ + if (!once_only) + _ecore_idle_enterer_call(); + else + { + int ret; + + have_event = have_signal = 0; + ret = _ecore_main_select(0); + + if (ret > 0) have_event = 1; +#ifndef WIN32 + if (_ecore_signal_count_get() > 0) have_signal = 1; +#endif + + if (have_signal || have_event) + goto process_events; + } + + /* if these calls caused any biuffered events to appear - deal with them */ + while (_ecore_main_fd_handlers_buf_call()); + /* if ther are any - jump to processing them */ + if (_ecore_event_exist()) + { + int ret; + + have_event = 1; + have_signal = 1; + ret = _ecore_main_select(0); + goto process_events; + } + if (once_only) + { + _ecore_idle_enterer_call(); + in_main_loop--; + return; + } + +#ifndef WIN32 + if (_ecore_fps_debug) + { + t2 = ecore_time_get(); + if ((t1 > 0.0) && (t2 > 0.0)) + _ecore_fps_debug_runtime_add(t2 - t1); + } +#endif + start_loop: + if (do_quit) + { + in_main_loop--; + return; + } + if (!_ecore_event_exist()) + { + /* init flags */ + have_event = have_signal = 0; + next_time = _ecore_timer_next_get(); + /* no timers */ + if (next_time < 0) + { + /* no idlers */ + if (!_ecore_idler_exist()) + { + int ret; + + ret = _ecore_main_select(-1); + if (ret > 0) have_event = 1; +#ifndef WIN32 + if (_ecore_signal_count_get() > 0) have_signal = 1; +#endif + } + /* idlers */ + else + { + for (;;) + { + int ret; + + if (!_ecore_idler_call()) goto start_loop; + if (_ecore_event_exist()) break; + ret = _ecore_main_select(0); + if (ret > 0) have_event = 1; +#ifndef WIN32 + if (_ecore_signal_count_get() > 0) have_signal = 1; +#endif + if (have_event || have_signal) break; + next_time = _ecore_timer_next_get(); + if (next_time >= 0) goto start_loop; + if (do_quit) break; + } + } + } + /* timers */ + else + { + /* no idlers */ + if (!_ecore_idler_exist()) + { + int ret; + + ret = _ecore_main_select(next_time); + if (ret > 0) have_event = 1; +#ifndef WIN32 + if (_ecore_signal_count_get() > 0) have_signal = 1; +#endif + } + /* idlers */ + else + { + for (;;) + { + double cur_time, t; + int ret; + + if (!_ecore_idler_call()) goto start_loop; + if (_ecore_event_exist()) break; + ret = _ecore_main_select(0); + if (ret > 0) have_event = 1; +#ifndef WIN32 + if (_ecore_signal_count_get() > 0) have_signal = 1; +#endif + if ((have_event) || (have_signal)) break; + cur_time = ecore_time_get(); + t = ecore_time_get() - cur_time; + if (t >= next_time) break; + next_time = _ecore_timer_next_get(); + if (next_time < 0) goto start_loop; + if (do_quit) break; + } + } + } + } +#ifndef WIN32 + if (_ecore_fps_debug) + { + t1 = ecore_time_get(); + } +#endif + /* we came out of our "wait state" so idle has exited */ + if (!once_only) + _ecore_idle_exiter_call(); + /* call the fd handler per fd that became alive... */ + /* this should read or write any data to the monitored fd and then */ + /* post events onto the ecore event pipe if necessary */ + process_events: + if (have_event) _ecore_main_fd_handlers_call(); + do + { +#ifndef WIN32 + /* process signals into events .... */ + while (_ecore_signal_count_get()) _ecore_signal_call(); +#endif + + /* handle events ... */ + _ecore_event_call(); + _ecore_main_fd_handlers_cleanup(); + } + while (_ecore_main_fd_handlers_buf_call()); + if (once_only) _ecore_idle_enterer_call(); + in_main_loop--; +} diff --git a/ecore/src/lib/ecore/ecore_path.c b/ecore/src/lib/ecore/ecore_path.c new file mode 100644 index 0000000..9202eea --- /dev/null +++ b/ecore/src/lib/ecore/ecore_path.c @@ -0,0 +1,282 @@ +#include + +static Ecore_List *group_list = NULL; + +Ecore_Path_Group *__ecore_path_group_find(char *name); +Ecore_Path_Group *__ecore_path_group_find_id(int id); + +/** + * @defgroup Ecore_Path_Group Path Group Functions + * + * Functions that make it easier to find a file in a set of search paths. + * + * @todo Give this a better description. + */ + +/** + * Creates a new path group. + * @param group_name The name of the new group. + * @return @c 0 on error, the integer id of the new group on success. + * @ingroup Ecore_Path_Group + */ +int +ecore_path_group_new(char *group_name) +{ + Ecore_Path_Group *last; + Ecore_Path_Group *group; + + CHECK_PARAM_POINTER_RETURN("group_name", group_name, -1); + + if (!group_list) { + group_list = ecore_list_new(); + } + else { + group = __ecore_path_group_find(group_name); + if (group) + return -1; + } + + group = (Ecore_Path_Group *)malloc(sizeof(Ecore_Path_Group)); + memset(group, 0, sizeof(Ecore_Path_Group)); + + group->name = strdup(group_name); + ecore_list_append(group_list, group); + + last = ecore_list_goto_last(group_list); + group->id = last->id + 1; + + return group->id; +} + +/** + * Destroys a previously created path group + * @param group_id The unique identifier for the group. + * @ingroup Ecore_Path_Group + */ +void +ecore_path_group_del(int group_id) +{ + Ecore_Path_Group *group; + + group = __ecore_path_group_find_id(group_id); + + if (!group) + return; + + if (group->paths) { + ecore_list_for_each(group->paths, + ECORE_FOR_EACH(free), NULL); + ecore_list_destroy(group->paths); + } + + free(group->name); + free(group); +} + +/** + * Adds a directory to be searched for files. + * @param group_id The unique identifier for the group to add the path. + * @param path The new path to be added to the group. + * @ingroup Ecore_Path_Group + */ +void +ecore_path_group_add(int group_id, char *path) +{ + Ecore_Path_Group *group; + + CHECK_PARAM_POINTER("path", path); + + group = __ecore_path_group_find_id(group_id); + + if (!group) + return; + + if (!group->paths) + group->paths = ecore_list_new(); + + ecore_list_append(group->paths, strdup(path)); +} + +/** + * Removes the given directory from the given group. + * @param group_id The identifier for the given group. + * @param path The path of the directory to be removed. + * @ingroup Ecore_Path_Group + */ +void +ecore_path_group_remove(int group_id, char *path) +{ + char *found; + Ecore_Path_Group *group; + + CHECK_PARAM_POINTER("path", path); + + group = __ecore_path_group_find_id(group_id); + + if (!group || !group->paths) + return; + + /* + * Find the path in the list of available paths + */ + ecore_list_goto_first(group->paths); + + while ((found = ecore_list_current(group->paths)) + && strcmp(found, path)) + ecore_list_next(group->paths); + + /* + * If the path is found, remove and free it + */ + if (found) { + ecore_list_remove(group->paths); + free(found); + } +} + +/** + * Finds a file in a group of paths. + * @param group_id The path group id to search. + * @param name The name of the file to find. + * @return A pointer to a newly allocated path location of the found file + * on success. @c NULL on failure. + * @ingroup Ecore_Path_Group + */ +char * +ecore_path_group_find(int group_id, char *name) +{ + int r; + char *p; + struct stat st; + char path[PATH_MAX]; + Ecore_Path_Group *group; + + CHECK_PARAM_POINTER_RETURN("name", name, NULL); + + group = __ecore_path_group_find_id(group_id); + + /* + * Search the paths of the path group for the specified file name + */ + ecore_list_goto_first(group->paths); + p = ecore_list_next(group->paths); + do { + snprintf(path, PATH_MAX, "%s/%s", p, name); + r = stat(path, &st); + } while (((r < 0) || !S_ISREG(st.st_mode)) && + (p = ecore_list_next(group->paths))); + + if (p) + p = strdup(path); + + return p; +} + +/** + * Retrieves a list of all available files in the given path. + * @param group_id The identifier for the given path. + * @return A pointer to a newly allocated list of all files found in the paths + * identified by @p group_id. @c NULL otherwise. + * @ingroup Ecore_Path_Group + */ +Ecore_List * +ecore_path_group_available(int group_id) +{ + Ecore_List *avail = NULL; + Ecore_Path_Group *group; + char *path; + + group = __ecore_path_group_find_id(group_id); + + if (!group || !group->paths || ecore_list_is_empty(group->paths)) + return NULL; + + ecore_list_goto_first(group->paths); + + while ((path = ecore_list_next(group->paths)) != NULL) + { + DIR *dir; + struct stat st; + struct dirent *d; + + stat(path, &st); + + if (!S_ISDIR(st.st_mode)) + continue; + + dir = opendir(path); + + if (!dir) + continue; + + while ((d = readdir(dir)) != NULL) + { + char ppath[PATH_MAX]; + char *ext; + char n[PATH_MAX]; + int l; + + if (!strncmp(d->d_name, ".", 1)) + continue; + + ext = strrchr(d->d_name, '.'); + + if (!ext || strncmp(ext, ".so", 3)) + continue; + + snprintf(ppath, PATH_MAX, "%s/%s", path, d->d_name); + + stat(ppath, &st); + + if (!S_ISREG(st.st_mode)) + continue; + + l = strlen(d->d_name); + + strncpy(n, d->d_name, l - 2); + + if (!avail) + avail = ecore_list_new(); + + ecore_list_append(avail, strdup(n)); + } + } + + return avail; +} + +/* + * Find the specified group name + */ +Ecore_Path_Group * +__ecore_path_group_find(char *name) +{ + Ecore_Path_Group *group; + + CHECK_PARAM_POINTER_RETURN("name", name, NULL); + + ecore_list_goto_first(group_list); + + while ((group = ecore_list_next(group_list)) != NULL) + if (!strcmp(group->name, name)) + return group; + + return NULL; +} + +/* + * Find the specified group id + */ +Ecore_Path_Group * +__ecore_path_group_find_id(int id) +{ + Ecore_Path_Group *group; + + ecore_list_goto_first(group_list); + + while ((group = ecore_list_next(group_list)) != NULL) + if (group->id == id) + return group; + + return NULL; +} diff --git a/ecore/src/lib/ecore/ecore_plugin.c b/ecore/src/lib/ecore/ecore_plugin.c new file mode 100644 index 0000000..42d6203 --- /dev/null +++ b/ecore/src/lib/ecore/ecore_plugin.c @@ -0,0 +1,109 @@ +#include + +#ifndef WIN32 +#include + +static Ecore_List *loaded_plugins = NULL; + +/** + * @defgroup Ecore_Plugin Plugin Functions + * + * Functions that load modules of compiled code into memory. + */ + +/** + * Loads the specified plugin from the specified path group. + * @param group_id The path group to search for the plugin to load + * @param plugin_name The name of the plugin to load. + * @return A pointer to the newly loaded plugin on success, @c NULL on + * failure. + * @ingroup Ecore_Plugin + */ +Ecore_Plugin * +ecore_plugin_load(int group_id, char *plugin_name) +{ + char *path; + char temp[PATH_MAX]; + + Ecore_Plugin *plugin; + void *handle = NULL; + + CHECK_PARAM_POINTER_RETURN("plugin_name", plugin_name, NULL); + + snprintf(temp, PATH_MAX, "%s.so", plugin_name); + path = ecore_path_group_find(group_id, temp); + if (!path) + return NULL; + + handle = dlopen(path, RTLD_LAZY); + if (!handle) + return NULL; + + /* + * Allocate the new plugin and initialize it's fields + */ + plugin = malloc(sizeof(Ecore_Plugin)); + memset(plugin, 0, sizeof(Ecore_Plugin)); + + plugin->group = group_id; + plugin->name = strdup(plugin_name); + plugin->handle = handle; + + /* + * Now add it to the list of the groups loaded plugins + */ + if (!loaded_plugins) + loaded_plugins = ecore_list_new(); + + ecore_list_append(loaded_plugins, plugin); + + FREE(path); + + return plugin; +} + +/** + * Unloads the given plugin from memory. + * @param plugin The given plugin. + * @ingroup Ecore_Plugin + */ +void +ecore_plugin_unload(Ecore_Plugin * plugin) +{ + CHECK_PARAM_POINTER("plugin", plugin); + + if (!plugin->handle) + return; + + if (ecore_list_goto(loaded_plugins, plugin)) + ecore_list_remove(loaded_plugins); + + dlclose(plugin->handle); + + FREE(plugin->name); + FREE(plugin); +} + +/* + * Searches for the specified symbol in the given plugin. + * @param plugin The given plugin. + * @param symbol_name The symbol to search for. + * @return Address of the given symbol if successful. Otherwise, @c NULL. + * @ingroup Ecore_Plugin + */ +void * +ecore_plugin_call(Ecore_Plugin * plugin, char *symbol_name) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("plugin", plugin, NULL); + CHECK_PARAM_POINTER_RETURN("symbol_name", symbol_name, NULL); + + if (!plugin->handle) + return NULL; + + ret = dlsym(plugin->handle, symbol_name); + + return ret; +} +#endif diff --git a/ecore/src/lib/ecore/ecore_private.h b/ecore/src/lib/ecore/ecore_private.h new file mode 100644 index 0000000..89a7328 --- /dev/null +++ b/ecore/src/lib/ecore/ecore_private.h @@ -0,0 +1,262 @@ +#ifndef _ECORE_PRIVATE_H +#define _ECORE_PRIVATE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if HAVE___ATTRIBUTE__ +#define __UNUSED__ __attribute__((unused)) +#else +#define __UNUSED__ +#endif + +#define ECORE_MAGIC_NONE 0x1234fedc +#define ECORE_MAGIC_EXE 0xf7e812f5 +#define ECORE_MAGIC_TIMER 0xf7d713f4 +#define ECORE_MAGIC_IDLER 0xf7c614f3 +#define ECORE_MAGIC_IDLE_ENTERER 0xf7b515f2 +#define ECORE_MAGIC_IDLE_EXITER 0xf7601afd +#define ECORE_MAGIC_FD_HANDLER 0xf7a416f1 +#define ECORE_MAGIC_EVENT_HANDLER 0xf79317f0 +#define ECORE_MAGIC_EVENT_FILTER 0xf78218ff +#define ECORE_MAGIC_EVENT 0xf77119fe +#define ECORE_MAGIC_ANIMATOR 0xf7643ea5 + +#define ECORE_MAGIC Ecore_Magic __magic + +#define ECORE_MAGIC_SET(d, m) (d)->__magic = (m) +#define ECORE_MAGIC_CHECK(d, m) ((d) && ((d)->__magic == (m))) +#define ECORE_MAGIC_FAIL(d, m, fn) _ecore_magic_fail((d), (d) ? (d)->__magic : 0, (m), (fn)); + +typedef unsigned int Ecore_Magic; + +typedef struct _Ecore_Oldlist Ecore_Oldlist; +typedef struct _Ecore_Oldlist_Data Ecore_Oldlist_Data; + +struct _Ecore_Oldlist +{ + Ecore_Oldlist *next, *prev; + Ecore_Oldlist *last; +}; + +struct _Ecore_Oldlist_Data +{ + Ecore_Oldlist __list_data; + void *data; +}; + +#ifndef _ECORE_H +enum _Ecore_Fd_Handler_Flags +{ + ECORE_FD_READ = 1, + ECORE_FD_WRITE = 2, + ECORE_FD_ERROR = 4 +}; +typedef enum _Ecore_Fd_Handler_Flags Ecore_Fd_Handler_Flags; + +#ifndef WIN32 +typedef struct _Ecore_Exe Ecore_Exe; +#endif +typedef struct _Ecore_Timer Ecore_Timer; +typedef struct _Ecore_Idler Ecore_Idler; +typedef struct _Ecore_Idle_Enterer Ecore_Idle_Enterer; +typedef struct _Ecore_Idle_Exiter Ecore_Idle_Exiter; +typedef struct _Ecore_Fd_Handler Ecore_Fd_Handler; +typedef struct _Ecore_Event_Handler Ecore_Event_Handler; +typedef struct _Ecore_Event_Filter Ecore_Event_Filter; +typedef struct _Ecore_Event Ecore_Event; +typedef struct _Ecore_Animator Ecore_Animator; + +#ifndef WIN32 +struct _Ecore_Exe +{ + Ecore_Oldlist __list_data; + ECORE_MAGIC; + pid_t pid; + void *data; +}; +#endif + +struct _Ecore_Timer +{ + Ecore_Oldlist __list_data; + ECORE_MAGIC; + double in; + double at; + signed char delete_me : 1; + signed char just_added : 1; + int (*func) (void *data); + void *data; +}; + +struct _Ecore_Idler +{ + Ecore_Oldlist __list_data; + ECORE_MAGIC; + int delete_me : 1; + int (*func) (void *data); + void *data; +}; + +struct _Ecore_Idle_Enterer +{ + Ecore_Oldlist __list_data; + ECORE_MAGIC; + int delete_me : 1; + int (*func) (void *data); + void *data; +}; + +struct _Ecore_Idle_Exiter +{ + Ecore_Oldlist __list_data; + ECORE_MAGIC; + int delete_me : 1; + int (*func) (void *data); + void *data; +}; + +struct _Ecore_Fd_Handler +{ + Ecore_Oldlist __list_data; + ECORE_MAGIC; + int fd; + Ecore_Fd_Handler_Flags flags; + int read_active : 1; + int write_active : 1; + int error_active : 1; + int delete_me : 1; + int (*func) (void *data, Ecore_Fd_Handler *fd_handler); + void *data; + int (*buf_func) (void *data, Ecore_Fd_Handler *fd_handler); + void *buf_data; + void (*prep_func) (void *data, Ecore_Fd_Handler *fd_handler); + void *prep_data; +}; + +struct _Ecore_Event_Handler +{ + Ecore_Oldlist __list_data; + ECORE_MAGIC; + int type; + int delete_me : 1; + int (*func) (void *data, int type, void *event); + void *data; +}; + +struct _Ecore_Event_Filter +{ + Ecore_Oldlist __list_data; + ECORE_MAGIC; + int delete_me : 1; + void * (*func_start) (void *data); + int (*func_filter) (void *data, void *loop_data, int type, void *event); + void (*func_end) (void *data, void *loop_data); + void *loop_data; + void *data; +}; + +struct _Ecore_Event +{ + Ecore_Oldlist __list_data; + ECORE_MAGIC; + int type; + void *event; + int delete_me : 1; + void (*func_free) (void *data, void *ev); + void *data; +}; + +struct _Ecore_Animator +{ + Ecore_Oldlist __list_data; + ECORE_MAGIC; + signed char delete_me : 1; + int (*func) (void *data); + void *data; +}; + +#endif + +void _ecore_magic_fail(void *d, Ecore_Magic m, Ecore_Magic req_m, const char *fname); + +void _ecore_timer_shutdown(void); +void _ecore_timer_cleanup(void); +void _ecore_timer_enable_new(void); +double _ecore_timer_next_get(void); +int _ecore_timer_call(double when); + +void _ecore_idler_shutdown(void); +int _ecore_idler_call(void); +int _ecore_idler_exist(void); + +void _ecore_idle_enterer_shutdown(void); +void _ecore_idle_enterer_call(void); +int _ecore_idle_enterer_exist(void); + +void _ecore_idle_exiter_shutdown(void); +void _ecore_idle_exiter_call(void); +int _ecore_idle_exiter_exist(void); + +void _ecore_event_shutdown(void); +int _ecore_event_exist(void); +Ecore_Event *_ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data); +void *_ecore_event_del(Ecore_Event *event); +void _ecore_event_call(void); + +#ifndef WIN32 +void *_ecore_event_exe_exit_new(void); +void _ecore_event_exe_exit_free(void *data, void *ev); +#endif +void *_ecore_event_signal_user_new(void); +void *_ecore_event_signal_hup_new(void); +void *_ecore_event_signal_exit_new(void); +void *_ecore_event_signal_power_new(void); +void *_ecore_event_signal_realtime_new(void); + +void _ecore_main_shutdown(void); + +void _ecore_signal_shutdown(void); +void _ecore_signal_init(void); +int _ecore_signal_count_get(void); +void _ecore_signal_call(void); + +#ifndef WIN32 +void _ecore_exe_shutdown(void); +Ecore_Exe *_ecore_exe_find(pid_t pid); +void *_ecore_exe_free(Ecore_Exe *exe); +#endif + +void _ecore_animator_shutdown(void); + + +void *_ecore_list_append (void *in_list, void *in_item); +void *_ecore_list_prepend (void *in_list, void *in_item); +void *_ecore_list_append_relative (void *in_list, void *in_item, void *in_relative); +void *_ecore_list_prepend_relative (void *in_list, void *in_item, void *in_relative); +void *_ecore_list_remove (void *in_list, void *in_item); +void *_ecore_list_find (void *in_list, void *in_item); + +void _ecore_fps_debug_init(void); +void _ecore_fps_debug_shutdown(void); +void _ecore_fps_debug_runtime_add(double t); + + + +extern int _ecore_fps_debug; + +#endif diff --git a/ecore/src/lib/ecore/ecore_sheap.c b/ecore/src/lib/ecore/ecore_sheap.c new file mode 100644 index 0000000..b630608 --- /dev/null +++ b/ecore/src/lib/ecore/ecore_sheap.c @@ -0,0 +1,419 @@ +#include + +static void _ecore_sheap_heapify(Ecore_Sheap *heap, int i); +static void _ecore_sheap_update_data(Ecore_Sheap *heap); + +/** + * Allocate and initialize a new binary heap + * @param compare The function for comparing keys, NULL for direct comparison + * @param size The number of elements to allow in the heap + * @return A pointer to the newly allocated binary heap on success, NULL on + * failure. + */ +Ecore_Sheap *ecore_sheap_new(Ecore_Compare_Cb compare, int size) +{ + Ecore_Sheap *heap = NULL; + + heap = (Ecore_Sheap *)malloc(sizeof(Ecore_Sheap)); + if (!heap) + return NULL; + memset(heap, 0, sizeof(Ecore_Sheap)); + + if (!ecore_sheap_init(heap, compare, size)) { + FREE(heap); + return NULL; + } + + return heap; +} + +/** + * Initialize a binary heap to default values + * @param heap The heap to initialize + * @param compare The function for comparing keys, NULL for direct comparison + * @param size The number of elements to allow in the heap + * @return TRUE on success, FALSE on failure + */ +int ecore_sheap_init(Ecore_Sheap *heap, Ecore_Compare_Cb compare, int size) +{ + CHECK_PARAM_POINTER_RETURN("heap", heap, FALSE); + + heap->space = size; + if (!compare) + heap->compare = ecore_direct_compare; + else + heap->compare = compare; + heap->order = ECORE_SHEAP_MIN; + + heap->data = (void **)malloc(heap->space * sizeof(void *)); + if (!heap->data) + return FALSE; + memset(heap->data, 0, heap->space * sizeof(void *)); + + return TRUE; +} + +/** + * Free up the memory used by the heap + * + * Frees the memory used by @a heap, calls the destroy function on each data + * item if necessary. + * + * @param heap The heap to be freed + */ +void ecore_sheap_destroy(Ecore_Sheap *heap) +{ + int i; + + CHECK_PARAM_POINTER("heap", heap); + + /* + * Free data in heap + */ + if (heap->free_func) + for (i = 0; i < heap->size; i++) + heap->free_func(heap->data[i]); + + FREE(heap->data); + + FREE(heap); +} + +/** + * Set the function for freeing data. + * @param heap The heap that will use this function when nodes are + * destroyed. + * @param free_func The function that will free the key data. + * @return @c TRUE on successful set, @c FALSE otherwise. + */ +int ecore_sheap_set_free_cb(Ecore_Sheap *heap, Ecore_Free_Cb free_func) +{ + CHECK_PARAM_POINTER_RETURN("heap", heap, FALSE); + + heap->free_func = free_func; + + return TRUE; +} + +/** + * Insert new data into the heap. + * @param heap The heap to insert @a data. + * @param data The data to add to @a heap. + * @return TRUE on success, NULL on failure. Increases the size of the heap if + * it becomes larger than available space. + */ +int ecore_sheap_insert(Ecore_Sheap *heap, void *data) +{ + int i; + void *temp; + int parent; + int position; + + CHECK_PARAM_POINTER_RETURN("heap", heap, FALSE); + + /* + * Increase the size of the allocated data area if there isn't enough + * space available to add this data + */ + if (heap->size >= heap->space) + return FALSE; + + heap->sorted = FALSE; + + /* + * Place the data at the end of the heap initially. Then determine the + * parent and position in the array of it's parent. + */ + heap->data[heap->size] = data; + position = heap->size; + heap->size++; + i = heap->size; + parent = PARENT(i) - 1; + + /* + * Check the order of the heap to decide where to place the inserted + * data. The loop is placed inside the if statement to reduce the + * number of branching decisions that must be predicted. + */ + if (heap->order == ECORE_SHEAP_MIN) { + while ((position > 0) && heap->compare(heap->data[parent], + heap->data[position]) > 0) { + + /* + * Swap the data with it's parents to move it up in + * the heap. + */ + temp = heap->data[position]; + heap->data[position] = heap->data[parent]; + heap->data[parent] = temp; + + /* + * Now determine the new position for the next + * iteration of the loop, as well as it's parents + * position. + */ + i = PARENT(i); + position = i - 1; + parent = PARENT(i) - 1; + } + } + else { + while ((position > 0) && heap->compare(heap->data[parent], + heap->data[position]) < 0) { + + /* + * Swap the data with it's parents to move it up in + * the heap. + */ + temp = heap->data[position]; + heap->data[position] = heap->data[PARENT(i) - 1]; + heap->data[PARENT(i) - 1] = temp; + + /* + * Now determine the new position for the next + * iteration of the loop, as well as it's parents + * position. + */ + i = PARENT(i); + position = i - 1; + parent = PARENT(i) - 1; + } + } + + return TRUE; +} + +/** + * Extract the item at the top of the heap + * @param heap The heap to remove the top item + * @return The top item of the heap on success, NULL on failure. + * @note The extract function maintains the heap properties after the + * extract. + */ +void *ecore_sheap_extract(Ecore_Sheap *heap) +{ + void *extreme; + + if (heap->size < 1) + return NULL; + + heap->sorted = FALSE; + + extreme = heap->data[0]; + heap->size--; + heap->data[0] = heap->data[heap->size]; + + _ecore_sheap_heapify(heap, 1); + + return extreme; +} + +/** + * Examine the item at the top of the heap + * @param heap The heap to examine the top item + * @return The top item of the heap on success, NULL on failure. + * @note The function does not alter the heap. + */ +void *ecore_sheap_extreme(Ecore_Sheap *heap) +{ + if (heap->size < 1) + return NULL; + + return heap->data[0]; +} + +/** + * Change the value of the specified item in the heap + * @param heap The heap to search for the item to change + * @param item The item in the heap to change + * @param newval The new value assigned to the item in the heap + * @return TRUE on success, FALSE on failure. + * @note The heap does not free the old data since it must be passed + * in, so the caller can perform the free if desired. + */ +int ecore_sheap_change(Ecore_Sheap *heap, void *item, void *newval) +{ + int i; + + CHECK_PARAM_POINTER_RETURN("heap", heap, FALSE); + + for (i = 0; i < heap->size && heap->compare(heap->data[i], item); i++); + + if (i < heap->size) + heap->data[i] = newval; + else + return FALSE; + + /* + * FIXME: This is not the correct procedure when a change occurs. + */ + _ecore_sheap_heapify(heap, 1); + + return TRUE; +} + +/** + * Change the comparison function for the heap + * @param heap The heap to change comparison function + * @param compare The new function for comparing nodes + * @return TRUE on success, FALSE on failure. + * + * The comparison function is changed to @compare and the heap is heapified + * by the new comparison. + */ +int ecore_sheap_set_compare(Ecore_Sheap *heap, Ecore_Compare_Cb compare) +{ + CHECK_PARAM_POINTER_RETURN("heap", heap, FALSE); + + if (!compare) + heap->compare = ecore_direct_compare; + else + heap->compare = compare; + + _ecore_sheap_update_data(heap); + + return TRUE; +} + +/** + * Change the order of the heap + * @param heap The heap to change the order + * @param order The new order of the heap + * + * Changes the heap order of @heap and re-heapifies the data to this new + * order. The default order is a min heap. + */ +void ecore_sheap_set_order(Ecore_Sheap *heap, char order) +{ + CHECK_PARAM_POINTER("heap", heap); + + heap->order = order; + + _ecore_sheap_update_data(heap); +} + +/** + * Sort the data in the heap + * @param heap The heap to be sorted + * + * Sorts the data in the heap into the order that is used for the heap's + * data. + */ +void ecore_sheap_sort(Ecore_Sheap *heap) +{ + int i = 0; + void **new_data; + + CHECK_PARAM_POINTER("heap", heap); + + new_data = (void **)malloc(heap->size * sizeof(void *)); + + /* + * Extract the heap and insert into the new data array in order. + */ + while (heap->size > 0) + new_data[i++] = ecore_sheap_extract(heap); + + /* + * Free the old data array and update the heap with the new data, also + * mark as sorted. + */ + FREE(heap->data); + heap->data = new_data; + heap->size = i; + heap->sorted = TRUE; +} + +/* + * Access the item at the ith position in the heap + * @param heap The heap to access the internal data + * @param i The index of the data within the heap + * @return The data located at the ith position within @heap on success, + * NULL on failure. + * @note The data is guaranteed to be in sorted order. + */ +inline void *ecore_sheap_item(Ecore_Sheap *heap, int i) +{ + if (i >= heap->size) + return NULL; + + /* + * Make sure the data is sorted so we return the correct value. + */ + if (!heap->sorted) + ecore_sheap_sort(heap); + + return heap->data[i]; +} + +/* + * Regain the heap properties starting at position i + * @param heap The heap to regain heap properties + * @param i The position to start heapifying + */ +static void _ecore_sheap_heapify(Ecore_Sheap *heap, int i) +{ + int extreme; + int left = LEFT(i); + int right = RIGHT(i); + + if (heap->order == ECORE_SHEAP_MIN) { + if (left <= heap->size && heap->compare(heap->data[left - 1], + heap->data[i - 1]) < 0) + extreme = left; + else + extreme = i; + + if (right <= heap->size && heap->compare(heap->data[right - 1], + heap->data[extreme - 1]) < 0) + extreme = right; + } + else { + if (left <= heap->size && heap->compare(heap->data[left - 1], + heap->data[i - 1]) > 0) + extreme = left; + else + extreme = i; + + if (right <= heap->size && heap->compare(heap->data[right - 1], + heap->data[extreme - 1]) > 0) + extreme = right; + } + + /* + * If the data needs to be swapped down the heap, recurse on + * heapifying it's new placement. + */ + if (extreme != i) { + void *temp; + + temp = heap->data[extreme - 1]; + heap->data[extreme - 1] = heap->data[i - 1]; + heap->data[i - 1] = temp; + + _ecore_sheap_heapify(heap, extreme); + } +} + +static void _ecore_sheap_update_data(Ecore_Sheap *heap) +{ + int i, old_size; + void **data; + + /* + * Track the old values from the heap + */ + old_size = heap->size; + data = heap->data; + + /* + * + */ + heap->size = 0; + heap->data = malloc(heap->space * sizeof(void *)); + + for (i = 0; i < old_size; i++) + ecore_sheap_insert(heap, data[i]); + + FREE(data); +} diff --git a/ecore/src/lib/ecore/ecore_signal.c b/ecore/src/lib/ecore/ecore_signal.c new file mode 100644 index 0000000..fb45b1b --- /dev/null +++ b/ecore/src/lib/ecore/ecore_signal.c @@ -0,0 +1,455 @@ +#include "ecore_private.h" +#include "Ecore.h" + +#ifndef WIN32 + +#include +#include +#include +#include +#include + +/* make mono happy - this is evil though... */ +#undef SIGPWR +/* valgrind in some versions/setups uses SIGRT's... hmmm */ +/* #undef SIGRTMIN */ + +typedef void (*Signal_Handler)(int sig, siginfo_t *si, void *foo); + +static void _ecore_signal_callback_set(int sig, Signal_Handler func); +static void _ecore_signal_callback_ignore(int sig, siginfo_t *si, void *foo); +static void _ecore_signal_callback_sigchld(int sig, siginfo_t *si, void *foo); +static void _ecore_signal_callback_sigusr1(int sig, siginfo_t *si, void *foo); +static void _ecore_signal_callback_sigusr2(int sig, siginfo_t *si, void *foo); +static void _ecore_signal_callback_sighup(int sig, siginfo_t *si, void *foo); +static void _ecore_signal_callback_sigquit(int sig, siginfo_t *si, void *foo); +static void _ecore_signal_callback_sigint(int sig, siginfo_t *si, void *foo); +static void _ecore_signal_callback_sigterm(int sig, siginfo_t *si, void *foo); +#ifdef SIGPWR +static void _ecore_signal_callback_sigpwr(int sig, siginfo_t *si, void *foo); +#endif + +#ifdef SIGRTMIN +static void _ecore_signal_callback_sigrt(int sig, siginfo_t *si, void *foo); +#endif + +static volatile sig_atomic_t sig_count = 0; +static volatile sig_atomic_t sigchld_count = 0; +static volatile sig_atomic_t sigusr1_count = 0; +static volatile sig_atomic_t sigusr2_count = 0; +static volatile sig_atomic_t sighup_count = 0; +static volatile sig_atomic_t sigquit_count = 0; +static volatile sig_atomic_t sigint_count = 0; +static volatile sig_atomic_t sigterm_count = 0; + +static volatile siginfo_t sigchld_info; +static volatile siginfo_t sigusr1_info; +static volatile siginfo_t sigusr2_info; +static volatile siginfo_t sighup_info; +static volatile siginfo_t sigquit_info; +static volatile siginfo_t sigint_info; +static volatile siginfo_t sigterm_info; + +#ifdef SIGPWR +static volatile sig_atomic_t sigpwr_count = 0; +static volatile siginfo_t sigpwr_info = {0}; +#endif + +#ifdef SIGRTMIN +static volatile sig_atomic_t *sigrt_count = NULL; +static volatile siginfo_t *sigrt_info = NULL; +#endif + +void +_ecore_signal_shutdown(void) +{ +#ifdef SIGRTMIN + int i, num = SIGRTMAX - SIGRTMIN; +#endif + + _ecore_signal_callback_set(SIGPIPE, (Signal_Handler) SIG_DFL); + _ecore_signal_callback_set(SIGALRM, (Signal_Handler) SIG_DFL); + _ecore_signal_callback_set(SIGCHLD, (Signal_Handler) SIG_DFL); + _ecore_signal_callback_set(SIGUSR1, (Signal_Handler) SIG_DFL); + _ecore_signal_callback_set(SIGUSR2, (Signal_Handler) SIG_DFL); + _ecore_signal_callback_set(SIGHUP, (Signal_Handler) SIG_DFL); + _ecore_signal_callback_set(SIGQUIT, (Signal_Handler) SIG_DFL); + _ecore_signal_callback_set(SIGINT, (Signal_Handler) SIG_DFL); + _ecore_signal_callback_set(SIGTERM, (Signal_Handler) SIG_DFL); +#ifdef SIGPWR + _ecore_signal_callback_set(SIGPWR, (Signal_Handler) SIG_DFL); + sigpwr_count = 0; +#endif + sigchld_count = 0; + sigusr1_count = 0; + sigusr2_count = 0; + sighup_count = 0; + sigquit_count = 0; + sigint_count = 0; + sigterm_count = 0; + sig_count = 0; + +#ifdef SIGRTMIN + for (i = 0; i < num; i++) { + _ecore_signal_callback_set(SIGRTMIN + i, (Signal_Handler) SIG_DFL); + sigrt_count[i] = 0; + } + + if (sigrt_count) { + free((sig_atomic_t *) sigrt_count); + sigrt_count = NULL; + } + + if (sigrt_info) { + free((siginfo_t *) sigrt_info); + sigrt_info = NULL; + } +#endif +} + +void +_ecore_signal_init(void) +{ +#ifdef SIGRTMIN + int i, num = SIGRTMAX - SIGRTMIN; +#endif + + _ecore_signal_callback_set(SIGPIPE, _ecore_signal_callback_ignore); + _ecore_signal_callback_set(SIGALRM, _ecore_signal_callback_ignore); + _ecore_signal_callback_set(SIGCHLD, _ecore_signal_callback_sigchld); + _ecore_signal_callback_set(SIGUSR1, _ecore_signal_callback_sigusr1); + _ecore_signal_callback_set(SIGUSR2, _ecore_signal_callback_sigusr2); + _ecore_signal_callback_set(SIGHUP, _ecore_signal_callback_sighup); + _ecore_signal_callback_set(SIGQUIT, _ecore_signal_callback_sigquit); + _ecore_signal_callback_set(SIGINT, _ecore_signal_callback_sigint); + _ecore_signal_callback_set(SIGTERM, _ecore_signal_callback_sigterm); +#ifdef SIGPWR + _ecore_signal_callback_set(SIGPWR, _ecore_signal_callback_sigpwr); +#endif + +#ifdef SIGRTMIN + sigrt_count = calloc(1, sizeof(sig_atomic_t) * num); + assert(sigrt_count); + + sigrt_info = calloc(1, sizeof(siginfo_t) * num); + assert(sigrt_info); + + for (i = 0; i < num; i++) + _ecore_signal_callback_set(SIGRTMIN + i, _ecore_signal_callback_sigrt); +#endif +} + +int +_ecore_signal_count_get(void) +{ + return sig_count; +} + +void +_ecore_signal_call(void) +{ +#ifdef SIGRTMIN + int i, num = SIGRTMAX - SIGRTMIN; +#endif + + while (sigchld_count > 0) + { + pid_t pid; + int status; + + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) + { + Ecore_Event_Exe_Exit *e; + + e = _ecore_event_exe_exit_new(); + if (e) + { + if (WIFEXITED(status)) + { + e->exit_code = WEXITSTATUS(status); + e->exited = 1; + } + else if (WIFSIGNALED(status)) + { + e->exit_signal = WTERMSIG(status); + e->signalled = 1; + } + e->pid = pid; + e->exe = _ecore_exe_find(pid); + + if (sigchld_info.si_signo) + e->data = sigchld_info; + + _ecore_event_add(ECORE_EVENT_EXE_EXIT, e, + _ecore_event_exe_exit_free, NULL); + } + } + sigchld_count--; + sig_count--; + } + while (sigusr1_count > 0) + { + Ecore_Event_Signal_User *e; + + e = _ecore_event_signal_user_new(); + if (e) + { + e->number = 1; + + if (sigusr1_info.si_signo) + e->data = sigusr1_info; + + ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, NULL); + } + sigusr1_count--; + sig_count--; + } + while (sigusr2_count > 0) + { + Ecore_Event_Signal_User *e; + + e = _ecore_event_signal_user_new(); + if (e) + { + e->number = 2; + + if (sigusr2_info.si_signo) + e->data = sigusr2_info; + + ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, NULL); + } + sigusr2_count--; + sig_count--; + } + while (sighup_count > 0) + { + Ecore_Event_Signal_Hup *e; + + e = _ecore_event_signal_hup_new(); + if (e) + { + if (sighup_info.si_signo) + e->data = sighup_info; + + ecore_event_add(ECORE_EVENT_SIGNAL_HUP, e, NULL, NULL); + } + sighup_count--; + sig_count--; + } + while (sigquit_count > 0) + { + Ecore_Event_Signal_Exit *e; + + e = _ecore_event_signal_exit_new(); + if (e) + { + e->quit = 1; + + if (sigquit_info.si_signo) + e->data = sigquit_info; + + ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL); + } + sigquit_count--; + sig_count--; + } + while (sigint_count > 0) + { + Ecore_Event_Signal_Exit *e; + + e = _ecore_event_signal_exit_new(); + if (e) + { + e->interrupt = 1; + + if (sigint_info.si_signo) + e->data = sigint_info; + + ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL); + } + sigint_count--; + sig_count--; + } + while (sigterm_count > 0) + { + Ecore_Event_Signal_Exit *e; + + e = _ecore_event_signal_exit_new(); + if (e) + { + e->terminate = 1; + + if (sigterm_info.si_signo) + e->data = sigterm_info; + + ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL); + } + sigterm_count--; + sig_count--; + } +#ifdef SIGPWR + while (sigpwr_count > 0) + { + Ecore_Event_Signal_Power *e; + + e = _ecore_event_signal_power_new(); + if (e) + { + if (sigpwr_info.si_signo) + e->data = sigpwr_info; + + ecore_event_add(ECORE_EVENT_SIGNAL_POWER, e, NULL, NULL); + } + sigpwr_count--; + sig_count--; + } +#endif + +#ifdef SIGRTMIN + for (i = 0; i < num; i++) + while (sigrt_count[i] > 0) { + Ecore_Event_Signal_Realtime *e; + + if ((e = _ecore_event_signal_realtime_new())) { + e->num = i; + + if (sigrt_info[i].si_signo) + e->data = sigrt_info[i]; + + ecore_event_add(ECORE_EVENT_SIGNAL_REALTIME, e, NULL, NULL); + } + + sigrt_count[i]--; + sig_count--; + } +#endif +} + +static void +_ecore_signal_callback_set(int sig, Signal_Handler func) +{ + struct sigaction sa; + + sa.sa_sigaction = func; + sa.sa_flags = SA_RESTART | SA_SIGINFO; + sigemptyset(&sa.sa_mask); + sigaction(sig, &sa, NULL); +} + +static void +_ecore_signal_callback_ignore(int sig __UNUSED__, siginfo_t *si __UNUSED__, void *foo __UNUSED__) +{ +} + +static void +_ecore_signal_callback_sigchld(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__) +{ + if (si) + sigchld_info = *si; + else + sigchld_info.si_signo = 0; + + sigchld_count++; + sig_count++; +} + +static void +_ecore_signal_callback_sigusr1(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__) +{ + if (si) + sigusr1_info = *si; + else + sigusr1_info.si_signo = 0; + + sigusr1_count++; + sig_count++; +} + +static void +_ecore_signal_callback_sigusr2(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__) +{ + if (si) + sigusr2_info = *si; + else + sigusr2_info.si_signo = 0; + + sigusr2_count++; + sig_count++; +} + +static void +_ecore_signal_callback_sighup(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__) +{ + if (si) + sighup_info = *si; + else + sighup_info.si_signo = 0; + + sighup_count++; + sig_count++; +} + +static void +_ecore_signal_callback_sigquit(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__) +{ + if (si) + sigquit_info = *si; + else + sigquit_info.si_signo = 0; + + sigquit_count++; + sig_count++; +} + +static void +_ecore_signal_callback_sigint(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__) +{ + if (si) + sigint_info = *si; + else + sigint_info.si_signo = 0; + + sigint_count++; + sig_count++; +} + +static void +_ecore_signal_callback_sigterm(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__) +{ + if (si) + sigterm_info = *si; + else + sigterm_info.si_signo = 0; + + sigterm_count++; + sig_count++; +} + +#ifdef SIGPWR +static void +_ecore_signal_callback_sigpwr(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__) +{ + if (si) + sigpwr_info = *si; + else + sigpwr_info.si_signo = 0; + + sigpwr_count++; + sig_count++; +} +#endif + +#ifdef SIGRTMIN +static void +_ecore_signal_callback_sigrt(int sig, siginfo_t *si, void *foo __UNUSED__) +{ + if (si) + sigrt_info[sig - SIGRTMIN] = *si; + else + sigrt_info[sig - SIGRTMIN].si_signo = 0; + + sigrt_count[sig - SIGRTMIN]++; + sig_count++; +} +#endif +#endif diff --git a/ecore/src/lib/ecore/ecore_strings.c b/ecore/src/lib/ecore/ecore_strings.c new file mode 100644 index 0000000..032d2a5 --- /dev/null +++ b/ecore/src/lib/ecore/ecore_strings.c @@ -0,0 +1,79 @@ +#include + +static Ecore_Hash *ecore_strings = NULL; + +/** + * @defgroup Ecore_String_Group String Instance Functions + * + * These functions allow you to store one copy of a string, and use it + * throughout your program. + */ + +/** + * Retrieves an instance of a string for use in an ecore program. + * @param string The string to retrieve an instance of. + * @return A pointer to an instance of the string on success. + * @c NULL on failure. + * @ingroup Ecore_String_Group + */ +char *ecore_string_instance(char *string) +{ + Ecore_String *str; + + CHECK_PARAM_POINTER_RETURN("string", string, NULL); + + /* + * No strings have been loaded at this point, so create the hash + * table for storing string info for later. + */ + if (!ecore_strings) + ecore_strings = ecore_hash_new(ecore_str_hash, ecore_str_compare); + + /* + * Check for a previous instance of the string, if not found, create + * it. + */ + str = ecore_hash_get(ecore_strings, string); + if (!str) { + + /* + * Allocate and initialize a new string reference. + */ + str = (Ecore_String *)malloc(sizeof(Ecore_String)); + + str->string = strdup(string); + str->references = 0; + + ecore_hash_set(ecore_strings, str->string, str); + } + + str->references++; + + return str->string; +} + +/** + * Notes that the given string has lost an instance. + * + * It will free the string if no other instances are left. + * + * @param string The given string. + * @ingroup Ecore_String_Group + */ +void ecore_string_release(char *string) +{ + Ecore_String *str; + + CHECK_PARAM_POINTER("string", string); + + str = ecore_hash_get(ecore_strings, string); + if (!str) + return; + + str->references--; + if (str->references < 1) { + ecore_hash_remove(ecore_strings, string); + FREE(str->string); + FREE(str); + } +} diff --git a/ecore/src/lib/ecore/ecore_time.c b/ecore/src/lib/ecore/ecore_time.c new file mode 100644 index 0000000..969f508 --- /dev/null +++ b/ecore/src/lib/ecore/ecore_time.c @@ -0,0 +1,41 @@ +#include "ecore_private.h" +#include "Ecore.h" + +#include + +#ifndef HAVE_GETTIMEOFDAY +#ifdef WIN32 +#include + +static int gettimeofday (struct timeval *tv, void *unused) +{ + struct _timeb t; + + if (!tv) + return -1; + + _ftime (&t); + + tv->tv_sec = t.time; + tv->tv_usec = t.millitm * 1000; + + return 0; +} +#else +#error "Your platform isn't supported yet" +#endif +#endif + +/** + * Retrieves the current system time as a floating point value in seconds. + * @return The number of seconds since 12.00AM 1st January 1970. + * @ingroup Ecore_Time_Group + */ +double +ecore_time_get(void) +{ + struct timeval timev; + + gettimeofday(&timev, NULL); + return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000); +} diff --git a/ecore/src/lib/ecore/ecore_timer.c b/ecore/src/lib/ecore/ecore_timer.c new file mode 100644 index 0000000..3c24291 --- /dev/null +++ b/ecore/src/lib/ecore/ecore_timer.c @@ -0,0 +1,223 @@ +#include "ecore_private.h" +#include "Ecore.h" + +static void _ecore_timer_set(Ecore_Timer *timer, double at, double in, int (*func) (void *data), void *data); + +static int timers_added = 0; +static int timers_delete_me = 0; +static Ecore_Timer *timers = NULL; +static double last_check = 0.0; + +/** + * @defgroup Ecore_Time_Group Ecore Time Functions + * + * Functions that deal with time. These functions include those that simply + * retrieve it in a given format, and those that create events based on it. + */ + +/** + * Creates a timer to call the given function in the given period of time. + * @param in The interval in seconds. + * @param func The given function. If @p func returns 1, the timer is + * rescheduled for the next interval @p in. + * @param data Data to pass to @p func when it is called. + * @return A timer object on success. @c NULL on failure. + * @ingroup Ecore_Time_Group + */ +Ecore_Timer * +ecore_timer_add(double in, int (*func) (void *data), const void *data) +{ + double now; + Ecore_Timer *timer; + + if (!func) return NULL; + if (in < 0.0) in = 0.0; + timer = calloc(1, sizeof(Ecore_Timer)); + if (!timer) return NULL; + ECORE_MAGIC_SET(timer, ECORE_MAGIC_TIMER); + now = ecore_time_get(); + _ecore_timer_set(timer, now + in, in, func, (void *)data); + return timer; +} + +/** + * Delete the specified timer from the timer list. + * @param timer The timer to delete. + * @return The data pointer set for the timer when @ref ecore_timer_add was + * called. @c NULL is returned if the function is unsuccessful. + * @ingroup Ecore_Time_Group + */ +void * +ecore_timer_del(Ecore_Timer *timer) +{ + if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) + { + ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, + "ecore_timer_del"); + return NULL; + } + if (timer->delete_me) return timer->data; + timers_delete_me++; + timer->delete_me = 1; + return timer->data; +} + +/** + * Change the interval the timer ticks of. If set during + * a timer call, this will affect the next interval. + * + * @param timer The timer to change. + * @param in The interval in seconds. + * @ingroup Ecore_Time_Group + */ +void +ecore_timer_interval_set(Ecore_Timer *timer, double in) +{ + if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER)) + { + ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER, + "ecore_timer_interval_set"); + return; + } + timer->in = in; +} + +void +_ecore_timer_shutdown(void) +{ + while (timers) + { + Ecore_Timer *timer; + + timer = timers; + timers = _ecore_list_remove(timers, timer); + ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE); + free(timer); + } +} + +void +_ecore_timer_cleanup(void) +{ + Ecore_Oldlist *l; + + if (!timers_delete_me) return; + for (l = (Ecore_Oldlist *)timers; l;) + { + Ecore_Timer *timer; + + timer = (Ecore_Timer *)l; + l = l->next; + if (timer->delete_me) + { + timers = _ecore_list_remove(timers, timer); + ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE); + free(timer); + timers_delete_me--; + if (timers_delete_me == 0) return; + } + } + timers_delete_me = 0; +} + +void +_ecore_timer_enable_new(void) +{ + Ecore_Oldlist *l; + + if (!timers_added) return; + timers_added = 0; + for (l = (Ecore_Oldlist *)timers; l; l = l->next) + { + Ecore_Timer *timer; + + timer = (Ecore_Timer *)l; + timer->just_added = 0; + } +} + +double +_ecore_timer_next_get(void) +{ + double now; + double in; + + if (!timers) return -1; + now = ecore_time_get(); + in = timers->at - now; + if (in < 0) in = 0; + return in; +} + +int +_ecore_timer_call(double when) +{ + Ecore_Oldlist *l; + Ecore_Timer *timer; + + if (!timers) return 0; + if (last_check > when) + { + /* User set time backwards */ + for (l = (Ecore_Oldlist *)timers; l; l = l->next) + { + timer = (Ecore_Timer *)l; + timer->at -= (last_check - when); + } + } + last_check = when; + for (l = (Ecore_Oldlist *)timers; l; l = l->next) + { + timer = (Ecore_Timer *)l; + if ((timer->at <= when) && + (!timer->just_added) && + (!timer->delete_me)) + { + timers = _ecore_list_remove(timers, timer); + _ecore_timer_call(when); + if ((!timer->delete_me) && (timer->func(timer->data))) + { + /* if the timer would have gone off more than 30 seconds ago, + * assume that the system hung and set the timer to go off + * timer->in from now. + */ + if ((timer->at + timer->in) < (when - 30.0)) + _ecore_timer_set(timer, when + timer->in, timer->in, timer->func, timer->data); + else + _ecore_timer_set(timer, timer->at + timer->in, timer->in, timer->func, timer->data); + } + else + free(timer); + return 1; + } + } + return 0; +} + +static void +_ecore_timer_set(Ecore_Timer *timer, double at, double in, int (*func) (void *data), void *data) +{ + Ecore_Oldlist *l; + + timers_added = 1; + timer->at = at; + timer->in = in; + timer->func = func; + timer->data = data; + timer->just_added = 1; + if (timers) + { + for (l = ((Ecore_Oldlist *)(timers))->last; l; l = l->prev) + { + Ecore_Timer *t2; + + t2 = (Ecore_Timer *)l; + if (timer->at > t2->at) + { + timers = _ecore_list_append_relative(timers, timer, t2); + return; + } + } + } + timers = _ecore_list_prepend(timers, timer); +} diff --git a/ecore/src/lib/ecore/ecore_tree.c b/ecore/src/lib/ecore/ecore_tree.c new file mode 100644 index 0000000..55322dd --- /dev/null +++ b/ecore/src/lib/ecore/ecore_tree.c @@ -0,0 +1,816 @@ +#include + +/* A macro for determining the highest node at given branch */ +#define MAX_HEIGHT(node) (node ? MAX(node->max_left, node->max_right) : 0) + +/* Utility functions for searching the tree and returning a node, or its + * parent */ +Ecore_Tree_Node *tree_node_find(Ecore_Tree * tree, void *key); +Ecore_Tree_Node *tree_node_find_parent(Ecore_Tree * tree, void *key); + +/* Balancing functions, keep the tree balanced within a one node height + * difference */ +int tree_node_balance(Ecore_Tree * Tree, Ecore_Tree_Node * top_node); +int tree_node_rotate_right(Ecore_Tree * tree, Ecore_Tree_Node * top_node); +int tree_node_rotate_left(Ecore_Tree * tree, Ecore_Tree_Node * top_node); + +/* Fucntions for executing a specified function on each node of a tree */ +int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func, + void *user_data); +int tree_for_each_node_value(Ecore_Tree_Node * node, + Ecore_For_Each for_each_func, void *user_data); + +/** + * @brief Allocate a new tree structure. + * @param compare_func: function used to compare the two values + * @return Returns NULL if the operation fails, otherwise the new tree + */ +Ecore_Tree *ecore_tree_new(Ecore_Compare_Cb compare_func) +{ + Ecore_Tree *new_tree; + + new_tree = ECORE_TREE(malloc(sizeof(Ecore_Tree))); + if (!new_tree) + return NULL; + + if (!ecore_tree_init(new_tree, compare_func)) { + IF_FREE(new_tree); + return NULL; + } + + return new_tree; +} + +/** + * @brief Initialize a tree structure to some sane initial values + * @param new_tree: the new tree structure to be initialized + * @param compare_func: the function used to compare node keys + * @return Returns TRUE on successful initialization, FALSE on an error + */ +int ecore_tree_init(Ecore_Tree * new_tree, Ecore_Compare_Cb compare_func) +{ + CHECK_PARAM_POINTER_RETURN("new_tree", new_tree, FALSE); + + memset(new_tree, 0, sizeof(Ecore_Tree)); + + if (!compare_func) + new_tree->compare_func = ecore_direct_compare; + else + new_tree->compare_func = compare_func; + + ECORE_INIT_LOCKS(new_tree); + + return TRUE; +} + +/* + * @brief Add a function to be called at node destroy time + * @param tree: the tree that will use this function when nodes are destroyed + * @param free_func: the function that will be passed the node being freed + * @return Returns TRUE on successful set, FALSE otherwise. + */ +int ecore_tree_set_free_cb(Ecore_Tree * tree, Ecore_Free_Cb free_func) +{ + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + + ECORE_WRITE_LOCK(tree); + tree->free_func = free_func; + ECORE_WRITE_UNLOCK(tree); + + return TRUE; +} + +/* + * @brief Initialize a new tree node + * @return Returns FALSE if the operation fails, otherwise TRUE + */ +int ecore_tree_node_init(Ecore_Tree_Node * new_node) +{ + CHECK_PARAM_POINTER_RETURN("new_node", new_node, FALSE); + + new_node->key = NULL; + new_node->value = NULL; + + new_node->parent = NULL; + new_node->right_child = NULL; + new_node->left_child = NULL; + + new_node->max_left = new_node->max_right = 0; + + ECORE_INIT_LOCKS(new_node); + + return TRUE; +} + +/* + * @brief Allocate a new tree node + * @return Returns NULL if the operation fails, otherwise the new node. + */ +Ecore_Tree_Node *ecore_tree_node_new() +{ + Ecore_Tree_Node *new_node; + + new_node = ECORE_TREE_NODE(malloc(sizeof(Ecore_Tree_Node))); + if (!new_node) + return NULL; + + if (!ecore_tree_node_init(new_node)) { + IF_FREE(new_node); + return NULL; + } + + return new_node; +} + +/* + * @brief Free a tree node and it's children. + * @param node: tree node to be free()'d + * @param data_free: callback for destroying the data held in node + * @return Returns TRUE if the node is destroyed successfully, FALSE if not. + * + * If you don't want the children free'd then you need to remove the node first. + */ +int ecore_tree_node_destroy(Ecore_Tree_Node * node, Ecore_Free_Cb data_free) +{ + CHECK_PARAM_POINTER_RETURN("node", node, FALSE); + + ECORE_WRITE_LOCK(node); + if (data_free) + data_free(node->value); + ECORE_WRITE_UNLOCK(node); + + ECORE_DESTROY_LOCKS(node); + + FREE(node); + + return TRUE; +} + +/* + * @brief Set the value of the node to value + * @param node: the node to be set + * @param value: the value to set the node to. + * @return Returns TRUE if the node is set successfully, FALSE if not. + */ +int ecore_tree_node_value_set(Ecore_Tree_Node * node, void *value) +{ + CHECK_PARAM_POINTER_RETURN("node", node, + FALSE); + + ECORE_WRITE_LOCK(node); + node->value = value; + ECORE_WRITE_UNLOCK(node); + + return TRUE; +} + +/* + * @brief Get the value of the node + * @param node: the node that contains the desired value + * @return Returns NULL if an error, otherwise the value associated with node + */ +void *ecore_tree_node_value_get(Ecore_Tree_Node * node) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("node", node, FALSE); + ECORE_READ_LOCK(node); + ret = node->value; + ECORE_READ_UNLOCK(node); + + return ret; +} + +/* + * @brief Set the value of the node's key to key + * @param node: the node to be set + * @param key: the value to set it's key to. + * @return Returns TRUE if the node is set successfully, FALSE if not. + */ +int ecore_tree_node_key_set(Ecore_Tree_Node * node, void *key) +{ + CHECK_PARAM_POINTER_RETURN("node", node, FALSE); + + ECORE_WRITE_LOCK(node); + node->key = key; + ECORE_WRITE_UNLOCK(node); + + return TRUE; +} + +/* + * @brief Get the value of the node's key + * @param node: the node that contains the desired key + * + * @return Returns NULL if an error occurs, otherwise the key is returned + */ +void *ecore_tree_node_key_get(Ecore_Tree_Node * node) +{ + void *ret; + + CHECK_PARAM_POINTER_RETURN("node", node, FALSE); + ECORE_READ_LOCK(node); + ret = node->key; + ECORE_READ_UNLOCK(node); + + return ret; +} + +/** + * @brief Free the tree and it's stored data + * @param tree: the tree to destroy + * + * @return Returns TRUE if tree destroyed successfully, FALSE if not. + */ +int ecore_tree_destroy(Ecore_Tree * tree) +{ + Ecore_Tree_Node *node; + + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + + ECORE_WRITE_LOCK(tree); + while ((node = tree->tree)) { + ecore_tree_remove_node(tree, node); + ecore_tree_node_destroy(node, tree->free_func); + } + ECORE_WRITE_UNLOCK(tree); + ECORE_DESTROY_LOCKS(tree); + + FREE(tree); + + return TRUE; +} + +/** + * @brief Return the node corresponding to key + * @param tree: the tree to search + * @param key: the key to search for in the tree + * + * @return Returns the node corresponding to the key if found, otherwise NULL. + */ +Ecore_Tree_Node *ecore_tree_get_node(Ecore_Tree * tree, void *key) +{ + Ecore_Tree_Node *ret; + + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + + ECORE_READ_LOCK(tree); + ret = tree_node_find(tree, key); + ECORE_READ_UNLOCK(tree); + + return ret; +} + +/** + * @brief Return the value corresponding to key + * @param tree: the tree to search + * @param key: the key to search for in @a tree + * @return Returns the value corresponding to the key if found, otherwise NULL. + */ +void *ecore_tree_get(Ecore_Tree * tree, void *key) +{ + void *ret; + Ecore_Tree_Node *node; + + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + + ECORE_READ_LOCK(tree); + node = tree_node_find(tree, key); + ECORE_READ_UNLOCK(tree); + + ECORE_READ_LOCK(node); + ret = (node ? node->value : NULL); + ECORE_READ_UNLOCK(node); + + return ret; +} + +/** + * @brief Find the closest value greater than or equal to the key. + * @param tree The tree to search. + * @param key The key to search for in @a tree. + * @return NULL if no valid nodes, otherwise the node greater than or + * equal to the key + */ +void *ecore_tree_get_closest_larger(Ecore_Tree * tree, void *key) +{ + Ecore_Tree_Node *node; + + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + + ECORE_READ_LOCK(tree); + node = tree_node_find(tree, key); + ECORE_READ_UNLOCK(tree); + + if (node) + return node; + + ECORE_READ_LOCK(tree); + node = tree_node_find_parent(tree, key); + + if (!node) { + ECORE_READ_UNLOCK(tree); + return NULL; + } + + ECORE_READ_LOCK(node); + if (tree->compare_func(node->key, key) < 0) + return NULL; + ECORE_READ_UNLOCK(node); + ECORE_READ_UNLOCK(tree); + + return node; +} + +/** + * @brief Find the closest value <= key + * @param tree the tree to search + * @param key the key to search for in tree + * @return Returns NULL if no valid nodes, otherwise the node <= key + */ +void *ecore_tree_get_closest_smaller(Ecore_Tree * tree, void *key) +{ + Ecore_Tree_Node *node; + + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + + ECORE_READ_LOCK(tree); + node = tree_node_find(tree, key); + ECORE_READ_UNLOCK(tree); + + if (node) + return node; + + ECORE_READ_LOCK(tree); + node = tree_node_find_parent(tree, key); + ECORE_READ_LOCK(tree); + + if (node) + node = node->right_child; + + return node; +} + +/** + * Set the value associated with key to @a value. + * @param tree The tree that contains the key/value pair. + * @param key The key to identify which node to set a value. + * @param value Value to set the found node. + * @return TRUE if successful, FALSE if not. + */ +int ecore_tree_set(Ecore_Tree * tree, void *key, void *value) +{ + Ecore_Tree_Node *node = NULL; + + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + + ECORE_READ_LOCK(tree); + node = tree_node_find(tree, key); + ECORE_READ_UNLOCK(tree); + + if (!node) { + node = ecore_tree_node_new(); + ecore_tree_node_key_set(node, key); + if (!ecore_tree_add_node(tree, node)) + return FALSE; + } + ecore_tree_node_value_set(node, value); + + ECORE_WRITE_LOCK(tree); + for (; node; node = node->parent) + tree_node_balance(tree, node); + ECORE_WRITE_UNLOCK(tree); + + return TRUE; +} + +/** + * Place a node in the tree. + * @param tree The tree to add @a node. + * @param node The node to add to @a tree. + * @return TRUE on a successful add, FALSE otherwise. + */ +int ecore_tree_add_node(Ecore_Tree * tree, Ecore_Tree_Node * node) +{ + Ecore_Tree_Node *travel = NULL; + + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + CHECK_PARAM_POINTER_RETURN("node", node, FALSE); + + /* Find where to put this new node. */ + if (!tree->tree) { + tree->tree = node; + } else { + travel = tree_node_find_parent(tree, node->key); + node->parent = travel; + + /* The node is less than travel */ + if (tree->compare_func(node->key, travel->key) < 0) { + travel->right_child = node; + travel->max_left = 1; + /* The node is greater than travel */ + } else { + travel->left_child = node; + travel->max_right = 1; + } + } + + return TRUE; +} + + +/** + * Remove the node from the tree. + * @param tree The tree to remove @a node from. + * @param node The node to remove from @a tree. + * @return TRUE on a successful remove, FALSE otherwise. + */ +int ecore_tree_remove_node(Ecore_Tree * tree, Ecore_Tree_Node * node) +{ + Ecore_Tree_Node *traverse; + + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + CHECK_PARAM_POINTER_RETURN("node", node, FALSE); + + /* + * Find the nearest value to the balanced one. + */ + if (node->left_child) { + traverse = node->left_child; + + /* Now work our way down right side of the traverse node. + * This will give us the node with the next closest value + * to the current node. If traverse had no right node, then + * this will stop at node's left node. */ + while (traverse->right_child) { + traverse = traverse->right_child; + } + + /* + * Hook any dropped leaves into the moved nodes spot + */ + if (traverse->parent) + traverse->parent->left_child = traverse->left_child; + } + else if (node->right_child) { + traverse = node->right_child; + + /* Now work our way down left side of the traverse node. + * This will give us the node with the next closest value + * to the current node. If traverse had no left node, then + * this will stop at node's right node. */ + while (traverse->left_child) { + traverse = traverse->left_child; + } + + /* + * Hook any dropped leaves into the moved nodes spot + */ + if (traverse->right_child) + traverse->right_child->parent = traverse->parent; + + if (traverse->parent) + traverse->parent->right_child = traverse->right_child; + else + tree->tree = traverse->right_child; + } + else + traverse = NULL; + + if (traverse) { + + /* + * Ensure that we don't get a recursive reference. + */ + if (node->right_child && node->right_child != traverse) { + node->right_child->parent = traverse; + traverse->right_child = node->right_child; + } + + if (node->left_child && node->left_child != traverse) { + node->left_child->parent = traverse; + traverse->left_child = node->left_child; + } + + /* + * Unlink the node to be moved from it's parent. + */ + if (traverse->parent) { + if (traverse->parent->left_child == traverse) + traverse->parent->left_child = NULL; + else + traverse->parent->right_child = NULL; + } + traverse->parent = node->parent; + } + + if (node->parent) { + if (node == node->parent->left_child) + node->parent->left_child = traverse; + else + node->parent->right_child = traverse; + } + + if (tree->tree == node) + tree->tree = traverse; + + node->parent = node->left_child = node->right_child = NULL; + + /* + * Rebalance the tree to ensure short search paths. + */ + while (traverse) { + tree_node_balance(tree, traverse); + traverse = traverse->parent; + } + + return TRUE; +} + +/** + * Remove the key from the tree. + * @param tree The tree to remove @a key. + * @param key The key to remove from @a tree. + * @return TRUE on a successful remove, FALSE otherwise. + */ +int ecore_tree_remove(Ecore_Tree * tree, void *key) +{ + Ecore_Tree_Node *node; + + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + if (!tree->tree) + return FALSE; + + /* Find the node we need to remove */ + node = tree_node_find(tree, key); + if (!node) + return FALSE; + + if (!ecore_tree_remove_node(tree, node)) + return FALSE; + + ecore_tree_node_destroy(node, tree->free_func); + + return TRUE; +} + +/** + * @brief Test to see if the tree has any nodes + * @param tree: the tree to check for nodes + * @return Returns TRUE if no nodes exist, FALSE otherwise + */ +int ecore_tree_is_empty(Ecore_Tree * tree) +{ + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + + if (!tree->tree) + return TRUE; + + return FALSE; +} + +/** + * @brief Execute function for each value in the tree + * @param tree: the tree to traverse + * @param for_each_func: the function to execute for each value in the tree + * @param user_data: data passed to each for_each_func call + * @return Returns TRUE on success, FALSE on failure. + */ +int ecore_tree_for_each_node_value(Ecore_Tree * tree, + Ecore_For_Each for_each_func, void *user_data) +{ + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, FALSE); + + if (!tree->tree) + return FALSE; + + return tree_for_each_node_value(tree->tree, for_each_func, user_data); +} + +/** + * @brief Execute the function for each node in the tree + * @param tree: the tree to traverse + * @param for_each_func: the function to execute for each node + * @param user_data: data passed to each for_each_func call + * @return Returns TRUE on success, FALSE on failure. + */ +int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func, + void *user_data) +{ + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, FALSE); + + if (!tree->tree) + return FALSE; + + return tree_for_each_node(tree->tree, for_each_func, user_data); +} + +/* Find the parent for the key */ +Ecore_Tree_Node *tree_node_find_parent(Ecore_Tree * tree, void *key) +{ + Ecore_Tree_Node *parent, *travel; + + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + + parent = tree_node_find(tree, key); + if (parent) + parent = parent->parent; + + travel = tree->tree; + if (!travel) + return NULL; + + while (!parent) { + int compare; + + if ((compare = tree->compare_func(key, travel->key)) < 0) { + if (!travel->right_child) + parent = travel; + travel = travel->right_child; + } else { + if (!travel->left_child) + parent = travel; + travel = travel->left_child; + } + } + + return parent; +} + +/* Search for the node with a specified key */ +Ecore_Tree_Node *tree_node_find(Ecore_Tree * tree, void *key) +{ + int compare; + Ecore_Tree_Node *node; + + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + + node = tree->tree; + while (node && (compare = tree->compare_func(key, node->key)) != 0) { + + if (compare < 0) { + if (!node->right_child) { + return NULL; + } + + node = node->right_child; + } else { + if (!node->left_child) { + return NULL; + } + + node = node->left_child; + } + } + + return node; +} + +/* Balance the tree with respect to node */ +int tree_node_balance(Ecore_Tree * tree, Ecore_Tree_Node * top_node) +{ + int balance; + + CHECK_PARAM_POINTER_RETURN("top_node", top_node, FALSE); + + /* Get the height of the left branch. */ + if (top_node->right_child) { + top_node->max_left = MAX_HEIGHT(top_node->right_child) + 1; + } else + top_node->max_left = 0; + + /* Get the height of the right branch. */ + if (top_node->left_child) { + top_node->max_right = MAX_HEIGHT(top_node->left_child) + 1; + } else + top_node->max_right = 0; + + /* Determine which side has a larger height. */ + balance = top_node->max_right - top_node->max_left; + + /* if the left side has a height advantage >1 rotate right */ + if (balance < -1) + tree_node_rotate_right(tree, top_node); + /* else if the left side has a height advantage >1 rotate left */ + else if (balance > 1) + tree_node_rotate_left(tree, top_node); + + return TRUE; +} + +/* Tree is overbalanced to the left, so rotate nodes to the right. */ +int tree_node_rotate_right(Ecore_Tree * tree, Ecore_Tree_Node * top_node) +{ + Ecore_Tree_Node *temp; + + CHECK_PARAM_POINTER_RETURN("top_node", top_node, FALSE); + + /* The left branch's right branch becomes the nodes left branch, + * the left branch becomes the top node, and the node becomes the + * right branch. */ + temp = top_node->right_child; + top_node->right_child = temp->left_child; + temp->left_child = top_node; + + /* Make sure the nodes know who their new parents are and the tree + * structure knows the start of the tree. */ + temp->parent = top_node->parent; + if (temp->parent == NULL) + tree->tree = temp; + else { + if (temp->parent->left_child == top_node) + temp->parent->left_child = temp; + else + temp->parent->right_child = temp; + } + top_node->parent = temp; + + /* And recalculate node heights */ + tree_node_balance(tree, top_node); + tree_node_balance(tree, temp); + + return TRUE; +} + +/* The tree is overbalanced to the right, so we rotate nodes to the left */ +int tree_node_rotate_left(Ecore_Tree * tree, Ecore_Tree_Node * top_node) +{ + Ecore_Tree_Node *temp; + + CHECK_PARAM_POINTER_RETURN("top_node", top_node, FALSE); + + /* + * The right branch's left branch becomes the nodes right branch, + * the right branch becomes the top node, and the node becomes the + * left branch. + */ + temp = top_node->left_child; + top_node->left_child = temp->right_child; + temp->right_child = top_node; + + /* Make sure the nodes know who their new parents are. */ + temp->parent = top_node->parent; + if (temp->parent == NULL) + tree->tree = temp; + else { + if (temp->parent->left_child == top_node) + temp->parent->left_child = temp; + else + temp->parent->right_child = temp; + } + top_node->parent = temp; + + /* And recalculate node heights */ + tree_node_balance(tree, top_node); + tree_node_balance(tree, temp); + + return TRUE; +} + +/* + * @brief Execute a function for each node below this point in the tree. + * @param node: the highest node in the tree the function will be executed for + * @param for_each_func: the function to pass the nodes as data into + * @param user_data: data passed to each for_each_func call + * @return Returns FALSE if an error condition occurs, otherwise TRUE + */ +int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func, + void *user_data) +{ + CHECK_PARAM_POINTER_RETURN("node", node, FALSE); + + if (node->right_child) + tree_for_each_node(node->right_child, for_each_func, user_data); + + if (node->left_child) + tree_for_each_node(node->left_child, for_each_func, user_data); + + for_each_func(node, user_data); + + return TRUE; +} + + +/* + * @brief Execute a function for each node below this point in the tree. + * @param node: the highest node in the tree the function will be executed for + * @param for_each_func: the function to pass the nodes values as data + * @return Returns FALSE if an error condition occurs, otherwise TRUE + */ +int tree_for_each_node_value(Ecore_Tree_Node * node, + Ecore_For_Each for_each_func, void *user_data) +{ + CHECK_PARAM_POINTER_RETURN("node", node, FALSE); + + if (node->right_child) + tree_for_each_node_value(node->right_child, for_each_func, user_data); + + if (node->left_child) + tree_for_each_node_value(node->left_child, for_each_func, user_data); + + for_each_func(node->value, user_data); + + return TRUE; +} diff --git a/ecore/src/lib/ecore/ecore_value.c b/ecore/src/lib/ecore/ecore_value.c new file mode 100644 index 0000000..d893809 --- /dev/null +++ b/ecore/src/lib/ecore/ecore_value.c @@ -0,0 +1,118 @@ +/* ecore_value.c + +Copyright (C) 2001 Christopher Rosendahl + Nathan Ingersoll + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies of the Software and its documentation and acknowledgment shall be +given in the documentation and software packages that this Software was +used. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#include + +const unsigned int ecore_prime_table[] = { 17, 31, 61, 127, 257, 509, 1021, + 2053, 4093, 8191, 16381, 32771, 65537, 131071, 262147, 524287, 1048573, + 2097143, 4194301, 8388617, 16777213 +}; + +inline void ecore_print_warning(const char *function, const char *sparam) +{ + fprintf(stderr, "***** Developer Warning ***** :\n" + "\tThis program is calling:\n\n" + "\t%s();\n\n" + "\tWith the parameter:\n\n" + "\t%s\n\n" + "\tbeing NULL. Please fix your program.\n", function, sparam); + fflush(stderr); +} + +/** + * Just casts the key to an unsigned int + * @param key The key to return compute a hash value + * @return The key cast to an unsigned int. + */ +unsigned int ecore_direct_hash(void *key) +{ + return ((unsigned int) key); +} + +/** + * Compute the hash value of a string + * @param key A pointer to the string to compute a hash value + * @return A computed hash value for @a key. + */ +unsigned int ecore_str_hash(void *key) +{ + int i; + unsigned int value = 0; + char *k = (char *) key; + + if (!k) + return 0; + + for (i = 0; k[i] != '\0'; i++) { + value ^= ((unsigned int) k[i] << ((i * 5) % + (sizeof(unsigned int) * 8))); + } + + return value; +} + +/** + * Perform a direct comparison of two keys' values + * @param key1 The first key to compare + * @param key2 The second key to compare + * @return A strcmp style value to indicate the larger key + */ +int ecore_direct_compare(void *key1, void *key2) +{ + unsigned int k1, k2; + + k1 = (unsigned int) key1; + k2 = (unsigned int) key2; + + if (k1 > k2) + return 1; + + if (k1 < k2) + return -1; + + return 0; +} + +/** + * Perform a string comparison of two keys values + * @param key1 The first key to compare + * @param key2 The second key to compare + * @return A strcmp style value to indicate the larger key + */ +int ecore_str_compare(void *key1, void *key2) +{ + char *k1, *k2; + + if (!key1 || !key2) + return ecore_direct_compare(key1, key2); + else if (key1 == key2) + return 0; + + k1 = (char *) key1; + k2 = (char *) key2; + + return strcmp(k1, k2); +} diff --git a/ecore/src/lib/ecore_con/.cvsignore b/ecore/src/lib/ecore_con/.cvsignore new file mode 100644 index 0000000..c9eb519 --- /dev/null +++ b/ecore/src/lib/ecore_con/.cvsignore @@ -0,0 +1,7 @@ +.deps +.libs +Ecore_Con.h +Makefile +Makefile.in +ecore_con.lo +libecore_con.la diff --git a/ecore/src/lib/ecore_con/CVS/Entries b/ecore/src/lib/ecore_con/CVS/Entries new file mode 100644 index 0000000..1740d38 --- /dev/null +++ b/ecore/src/lib/ecore_con/CVS/Entries @@ -0,0 +1,7 @@ +/.cvsignore/1.2/Wed Mar 31 16:47:45 2004//THEAD +/Ecore_Con.h/1.9/Fri Jun 24 13:38:27 2005//THEAD +/Makefile.am/1.10/Fri Jun 24 13:38:27 2005//THEAD +/ecore_con.c/1.41/Fri Apr 29 04:51:31 2005//THEAD +/ecore_con_private.h/1.8/Fri Jun 24 13:38:27 2005//THEAD +/ecore_con_url.c/1.6/Fri Jun 24 15:01:59 2005//THEAD +D diff --git a/ecore/src/lib/ecore_con/CVS/Repository b/ecore/src/lib/ecore_con/CVS/Repository new file mode 100644 index 0000000..282cc26 --- /dev/null +++ b/ecore/src/lib/ecore_con/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/src/lib/ecore_con diff --git a/ecore/src/lib/ecore_con/CVS/Root b/ecore/src/lib/ecore_con/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/src/lib/ecore_con/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/src/lib/ecore_con/CVS/Tag b/ecore/src/lib/ecore_con/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/src/lib/ecore_con/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/src/lib/ecore_con/Ecore_Con.h b/ecore/src/lib/ecore_con/Ecore_Con.h new file mode 100644 index 0000000..fd022b3 --- /dev/null +++ b/ecore/src/lib/ecore_con/Ecore_Con.h @@ -0,0 +1,168 @@ +#ifndef _ECORE_CON_H +#define _ECORE_CON_H + +#ifdef EAPI +#undef EAPI +#endif +#ifdef WIN32 +# ifdef BUILDING_DLL +# define EAPI __declspec(dllexport) +# else +# define EAPI __declspec(dllimport) +# endif +#else +# ifdef GCC_HASCLASSVISIBILITY +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +#endif + +/** + * @file Ecore_Con.h + * @brief Sockets functions. + * + * The Ecore Connection Library ( @c Ecore_Con ) provides simple mechanisms + * for communications between programs using reliable sockets. It saves + * the programmer from having to worry about file descripters and waiting + * for incoming connections. + * + * There are two main objects in the @c Ecore_Con library: the @c + * Ecore_Con_Server and the @c Ecore_Con_Client. + * + * The @c Ecore_Con_Server represents a server to connect to. It is + * represents a server that can be connected to. It is used regardless + * of whether the program is acting as a server or client itself. + * + * To create a listening server, call @c ecore_con_server_add(). + * + * To connect to a server, call @c ecore_con_server_connect(). Data can + * then be sent to the server using the @c ecore_con_server_send(). + * + * Whenever a client connection is made to an @c Ecore_Con_Server, a + * @c ECORE_CON_CLIENT_ADD event is emitted. Any event callbacks that are + * called receive a @c Ecore_Con_Client object, which represents a + * connection that that particular client. + * + * Functions are described in the following groupings: + * @li @ref Ecore_Con_Lib_Group + * @li @ref Ecore_Con_Server_Group + * @li @ref Ecore_Con_Client_Group + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ECORE_CON_PRIVATE_H + typedef void Ecore_Con_Server; /**< A connection handle */ + typedef void Ecore_Con_Client; /**< A connection handle */ + typedef void Ecore_Con_Url; + + typedef enum _Ecore_Con_Type + { + ECORE_CON_LOCAL_USER, + ECORE_CON_LOCAL_SYSTEM, + ECORE_CON_REMOTE_SYSTEM, + ECORE_CON_USE_SSL = 16 + } Ecore_Con_Type; + +#endif + + typedef struct _Ecore_Con_Event_Client_Add Ecore_Con_Event_Client_Add; + typedef struct _Ecore_Con_Event_Client_Del Ecore_Con_Event_Client_Del; + typedef struct _Ecore_Con_Event_Server_Add Ecore_Con_Event_Server_Add; + typedef struct _Ecore_Con_Event_Server_Del Ecore_Con_Event_Server_Del; + typedef struct _Ecore_Con_Event_Client_Data Ecore_Con_Event_Client_Data; + typedef struct _Ecore_Con_Event_Server_Data Ecore_Con_Event_Server_Data; + typedef struct _Ecore_Con_Event_Url_Data Ecore_Con_Event_Url_Data; + typedef struct _Ecore_Con_Event_Url_Complete Ecore_Con_Event_Url_Complete; + + struct _Ecore_Con_Event_Client_Add + { + Ecore_Con_Client *client; + }; + + struct _Ecore_Con_Event_Client_Del + { + Ecore_Con_Client *client; + }; + + struct _Ecore_Con_Event_Server_Add + { + Ecore_Con_Server *server; + }; + + struct _Ecore_Con_Event_Server_Del + { + Ecore_Con_Server *server; + }; + + struct _Ecore_Con_Event_Client_Data + { + Ecore_Con_Client *client; + void *data; + int size; + }; + + struct _Ecore_Con_Event_Server_Data + { + Ecore_Con_Server *server; + void *data; + int size; + }; + + struct _Ecore_Con_Event_Url_Data + { + Ecore_Con_Url *url_con; + void *data; + int size; + }; + + struct _Ecore_Con_Event_Url_Complete + { + Ecore_Con_Url *url_con; + int status; + }; + + extern int ECORE_CON_EVENT_CLIENT_ADD; + extern int ECORE_CON_EVENT_CLIENT_DEL; + extern int ECORE_CON_EVENT_SERVER_ADD; + extern int ECORE_CON_EVENT_SERVER_DEL; + extern int ECORE_CON_EVENT_CLIENT_DATA; + extern int ECORE_CON_EVENT_SERVER_DATA; + extern int ECORE_CON_EVENT_URL_DATA; + extern int ECORE_CON_EVENT_URL_COMPLETE; + + EAPI int ecore_con_init(void); + EAPI int ecore_con_shutdown(void); + + EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type, const char *name, int port, const void *data); + + EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type, const char *name, int port, const void *data); + EAPI void *ecore_con_server_del(Ecore_Con_Server *svr); + EAPI void *ecore_con_server_data_get(Ecore_Con_Server *svr); + EAPI int ecore_con_server_connected_get(Ecore_Con_Server *svr); + EAPI int ecore_con_server_send(Ecore_Con_Server *svr, void *data, int size); + EAPI void ecore_con_server_client_limit_set(Ecore_Con_Server *svr, int client_limit, char reject_excess_clients); + + EAPI int ecore_con_client_send(Ecore_Con_Client *cl, void *data, int size); + EAPI Ecore_Con_Server *ecore_con_client_server_get(Ecore_Con_Client *cl); + EAPI void *ecore_con_client_del(Ecore_Con_Client *cl); + EAPI void ecore_con_client_data_set(Ecore_Con_Client *cl, const void *data); + EAPI void *ecore_con_client_data_get(Ecore_Con_Client *cl); + + EAPI int ecore_con_ssl_available_get(void); + + EAPI int ecore_con_url_init(void); + EAPI int ecore_con_url_shutdown(void); + EAPI Ecore_Con_Url *ecore_con_url_new(const char *url); + EAPI void ecore_con_url_destroy(Ecore_Con_Url *url_con); + EAPI int ecore_con_url_url_set(Ecore_Con_Url *url_con, const char *url); + EAPI int ecore_con_url_send(Ecore_Con_Url *url_con, void *data, size_t length, char *content_type); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ecore/src/lib/ecore_con/Makefile.am b/ecore/src/lib/ecore_con/Makefile.am new file mode 100644 index 0000000..e40be6e --- /dev/null +++ b/ecore/src/lib/ecore_con/Makefile.am @@ -0,0 +1,36 @@ +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_con \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_con \ +@SSL_CFLAGS@ @curl_cflags@ + +libecore_con_la_LDFLAGS = -version-info 1:0:0 \ +-L$(top_builddir)/src/lib/ecore/.libs + +if BUILD_ECORE_CON + +lib_LTLIBRARIES = libecore_con.la +include_HEADERS = \ +Ecore_Con.h + +libecore_con_la_SOURCES = \ +ecore_con.c \ +ecore_con_url.c \ +ecore_con_private.h + +libecore_con_la_LIBADD = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +@SSL_LIBS@ @winsock_libs@ @curl_libs@ + +libecore_con_la_DEPENDENCIES = \ +$(top_builddir)/src/lib/ecore/libecore.la + +endif + +EXTRA_DIST = \ +ecore_con.c \ +ecore_con_url.c \ +ecore_con_private.h diff --git a/ecore/src/lib/ecore_con/ecore_con.c b/ecore/src/lib/ecore_con/ecore_con.c new file mode 100644 index 0000000..b394ae2 --- /dev/null +++ b/ecore/src/lib/ecore_con/ecore_con.c @@ -0,0 +1,1270 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +#include "Ecore.h" +#include "config.h" +#include "ecore_private.h" +#include "ecore_con_private.h" +#include "Ecore_Con.h" + +#ifdef HAVE_NETINET_IN_H +#include +#elif WIN32 +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if USE_OPENSSL +#include +#endif + +static void _ecore_con_server_free(Ecore_Con_Server *svr); +static void _ecore_con_client_free(Ecore_Con_Client *cl); +static int _ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler); +static int _ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler); +static int _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler); +static void _ecore_con_server_flush(Ecore_Con_Server *svr); +static void _ecore_con_client_flush(Ecore_Con_Client *cl); +static void _ecore_con_event_client_data_free(void *data, void *ev); +static void _ecore_con_event_server_data_free(void *data, void *ev); + +int ECORE_CON_EVENT_CLIENT_ADD = 0; +int ECORE_CON_EVENT_CLIENT_DEL = 0; +int ECORE_CON_EVENT_SERVER_ADD = 0; +int ECORE_CON_EVENT_SERVER_DEL = 0; +int ECORE_CON_EVENT_CLIENT_DATA = 0; +int ECORE_CON_EVENT_SERVER_DATA = 0; + +static Ecore_List *servers = NULL; +static int init_count = 0; + +#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path)) + +/** + * @defgroup Ecore_Con_Lib_Group Ecore Connection Library Functions + * + * Utility functions that set up and shut down the Ecore Connection + * library. + */ + +/** + * Initialises the Ecore_Con library. + * @return Number of times the library has been initialised without being + * shut down. + * @ingroup Ecore_Con_Lib_Group + */ +int +ecore_con_init(void) +{ + init_count++; + if (!ECORE_CON_EVENT_CLIENT_ADD) + { + ECORE_CON_EVENT_CLIENT_ADD = ecore_event_type_new(); + ECORE_CON_EVENT_CLIENT_DEL = ecore_event_type_new(); + ECORE_CON_EVENT_SERVER_ADD = ecore_event_type_new(); + ECORE_CON_EVENT_SERVER_DEL = ecore_event_type_new(); + ECORE_CON_EVENT_CLIENT_DATA = ecore_event_type_new(); + ECORE_CON_EVENT_SERVER_DATA = ecore_event_type_new(); + +#if USE_OPENSSL + SSL_library_init(); + SSL_load_error_strings(); +#endif + } + if (!servers) + servers = ecore_list_new(); + return init_count; +} + +/** + * Shuts down the Ecore_Con library. + * @return Number of times the library has been initialised without being + * shut down. + * @ingroup Ecore_Con_Lib_Group + */ +int +ecore_con_shutdown(void) +{ + if (init_count > 0) + { + init_count--; + if (init_count > 0) return init_count; + while (!ecore_list_is_empty(servers)) + _ecore_con_server_free(ecore_list_remove_first(servers)); + ecore_list_destroy(servers); + servers = NULL; + } + return 0; +} + +/** + * @defgroup Ecore_Con_Server_Group Ecore Connection Server Functions + * + * Functions that operate on Ecore server objects. + */ + +/** + * Creates a server to listen for connections. + * + * The socket on which the server listens depends on the connection + * type: + * @li If @a compl_type is @c ECORE_CON_LOCAL_USER, the server will listen on + * the Unix socket "~/.ecore/[name]/[port]". + * @li If @a compl_type is @c ECORE_CON_LOCAL_SYSTEM, the server will listen + * on Unix socket "/tmp/.ecore_service|[name]|[port]". + * @li If @a compl_type is @c ECORE_CON_REMOTE_SYSTEM, the server will listen + * on TCP port @c port. + * + * @param compl_type The connection type. + * @param name Name to associate with the socket. It is used when + * generating the socket name of a Unix socket. Though + * it is not used for the TCP socket, it still needs to + * be a valid character array. @c NULL will not be + * accepted. + * @param port Number to identify socket. When a Unix socket is used, + * it becomes part of the socket name. When a TCP socket + * is used, it is used as the TCP port. + * @param data Data to associate with the created Ecore_Con_Server + * object. + * @return A new Ecore_Con_Server. + * @ingroup Ecore_Con_Server_Group + */ +Ecore_Con_Server * +ecore_con_server_add(Ecore_Con_Type compl_type, + const char *name, + int port, + const void *data) +{ + Ecore_Con_Server *svr; + Ecore_Con_Type type; + struct sockaddr_in socket_addr; + struct sockaddr_un socket_unix; + struct linger lin; + char buf[4096]; + + if (port < 0) return NULL; + /* local user socket: FILE: ~/.ecore/[name]/[port] */ + /* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */ + /* remote system socket: TCP/IP: [name]:[port] */ + svr = calloc(1, sizeof(Ecore_Con_Server)); + if (!svr) return NULL; + + type = compl_type; +#if USE_OPENSSL + /* unset the SSL flag for the following checks */ + type &= ~ECORE_CON_USE_SSL; +#endif + + if ((type == ECORE_CON_LOCAL_USER) || + (type == ECORE_CON_LOCAL_SYSTEM)) + { + const char *homedir; + struct stat st; + mode_t pmode, mask; + + if (!name) goto error; + mask = + S_IRGRP | S_IWGRP | S_IXGRP | + S_IROTH | S_IWOTH | S_IXOTH; + if (type == ECORE_CON_LOCAL_USER) + { + homedir = getenv("HOME"); + if (!homedir) homedir = getenv("TMP"); + if (!homedir) homedir = "/tmp"; + mask = S_IRUSR | S_IWUSR | S_IXUSR; + snprintf(buf, sizeof(buf), "%s/.ecore", homedir); + if (stat(buf, &st) < 0) mkdir(buf, mask); + snprintf(buf, sizeof(buf), "%s/.ecore/%s", homedir, name); + if (stat(buf, &st) < 0) mkdir(buf, mask); + snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, name, port); + mask = + S_IRGRP | S_IWGRP | S_IXGRP | + S_IROTH | S_IWOTH | S_IXOTH; + } + else if (type == ECORE_CON_LOCAL_SYSTEM) + { + mask = 0; + if (name[0] == '/') + snprintf(buf, sizeof(buf), "%s|%i", name, port); + else + snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i", name, port); + } + pmode = umask(mask); + start: + svr->fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (svr->fd < 0) + { + umask(pmode); + goto error; + } + if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) + { + umask(pmode); + goto error; + } + if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) + { + umask(pmode); + goto error; + } + lin.l_onoff = 1; + lin.l_linger = 100; + if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0) + { + umask(pmode); + goto error; + } + socket_unix.sun_family = AF_UNIX; + strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path)); + if (bind(svr->fd, (struct sockaddr *)&socket_unix, LENGTH_OF_SOCKADDR_UN(&socket_unix)) < 0) + { + if (connect(svr->fd, (struct sockaddr *)&socket_unix, + LENGTH_OF_SOCKADDR_UN(&socket_unix)) < 0) + { + if ((type == ECORE_CON_LOCAL_USER) || + (type == ECORE_CON_LOCAL_SYSTEM)) + { + if (unlink(buf) < 0) + { + umask(pmode); + goto error; + } + else + goto start; + } + else + { + umask(pmode); + goto error; + } + } + else + { + umask(pmode); + goto error; + } + } + if (listen(svr->fd, 4096) < 0) + { + umask(pmode); + goto error; + } + svr->path = strdup(buf); + if (!svr->path) + { + umask(pmode); + goto error; + } + svr->fd_handler = ecore_main_fd_handler_add(svr->fd, + ECORE_FD_READ, + _ecore_con_svr_handler, svr, + NULL, NULL); + umask(pmode); + if (!svr->fd_handler) goto error; + } + else if (type == ECORE_CON_REMOTE_SYSTEM) + { + svr->fd = socket(AF_INET, SOCK_STREAM, 0); + if (svr->fd < 0) goto error; + if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error; + if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error; + lin.l_onoff = 1; + lin.l_linger = 100; + if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0) goto error; + socket_addr.sin_family = AF_INET; + socket_addr.sin_port = htons(port); + socket_addr.sin_addr.s_addr = htonl(INADDR_ANY); + if (bind(svr->fd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in)) < 0) goto error; + if (listen(svr->fd, 4096) < 0) goto error; + svr->fd_handler = ecore_main_fd_handler_add(svr->fd, + ECORE_FD_READ, + _ecore_con_svr_handler, svr, + NULL, NULL); + if (!svr->fd_handler) goto error; + } + +#if USE_OPENSSL + if (compl_type & ECORE_CON_USE_SSL) + { + /* SSLv3 gives *weird* results on my box, don't use it yet */ + if (!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method()))) + goto error; + + if (!(svr->ssl = SSL_new(svr->ssl_ctx))) + goto error; + + SSL_set_fd(svr->ssl, svr->fd); + } +#endif + + svr->name = strdup(name); + if (!svr->name) goto error; + svr->type = type; + svr->port = port; + svr->data = (void *)data; + svr->created = 1; + svr->reject_excess_clients = 0; + svr->client_limit = -1; + svr->clients = ecore_list_new(); + ecore_list_append(servers, svr); + ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER); + return svr; + + error: + if (svr->name) free(svr->name); + if (svr->path) free(svr->path); + if (svr->fd >= 0) close(svr->fd); + if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler); + if (svr->write_buf) free(svr->write_buf); +#if USE_OPENSSL + if (svr->ssl) SSL_free(svr->ssl); + if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx); +#endif + free(svr); + return NULL; +} + +/** + * Creates a server object to represent the server listening at the + * given port. + * + * The socket to which the server connects depends on the connection type: + * @li If @a compl_type is @c ECORE_CON_LOCAL_USER, the function will + * connect to the server listening on the Unix socket + * "~/.ecore/[name]/[port]". + * @li If @a compl_type is @c ECORE_CON_LOCAL_SYSTEM, the function will + * connect to the server listening on the Unix socket + * "/tmp/.ecore_service|[name]|[port]". + * @li If @a compl_type is @c ECORE_CON_REMOTE_SYSTEM, the function will + * connect to the server listening on the TCP port "[name]:[port]". + * + * @param compl_type The connection type. + * @param name Name used when determining what socket to connect to. + * It is used to generate the socket name when the socket + * is a Unix socket. It is used as the hostname when + * connecting with a TCP socket. + * @param port Number to identify the socket to connect to. Used when + * generating the socket name for a Unix socket, or as the + * TCP port when connecting to a TCP socket. + * @param data Data to associate with the created Ecore_Con_Server + * object. + * @return A new Ecore_Con_Server. + * @ingroup Ecore_Con_Server_Group + */ +Ecore_Con_Server * +ecore_con_server_connect(Ecore_Con_Type compl_type, + const char *name, + int port, + const void *data) +{ + Ecore_Con_Server *svr; + Ecore_Con_Type type; + struct sockaddr_un socket_unix; + struct sockaddr_in socket_addr; + int curstate = 0; + char buf[4096]; + + if (!name) return NULL; + if (port < 0) return NULL; + /* local user socket: FILE: ~/.ecore/[name]/[port] */ + /* local system socket: FILE: /tmp/.ecore_service|[name]|[port] */ + /* remote system socket: TCP/IP: [name]:[port] */ + svr = calloc(1, sizeof(Ecore_Con_Server)); + if (!svr) return NULL; + + type = compl_type; +#if USE_OPENSSL + /* unset the SSL flag for the following checks */ + type &= ~ECORE_CON_USE_SSL; +#endif + + if ((type == ECORE_CON_LOCAL_USER) || + (type == ECORE_CON_LOCAL_SYSTEM)) + { + const char *homedir; + + if (type == ECORE_CON_LOCAL_USER) + { + homedir = getenv("HOME"); + if (!homedir) homedir = getenv("TMP"); + if (!homedir) homedir = "/tmp"; + snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, name, port); + } + else if (type == ECORE_CON_LOCAL_SYSTEM) + { + if (name[0] == '/') + snprintf(buf, sizeof(buf), "%s|%i", name, port); + else + snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i", name, port); + } + svr->fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (svr->fd < 0) goto error; + if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error; + if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error; + if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) goto error; + socket_unix.sun_family = AF_UNIX; + strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path)); + if (connect(svr->fd, (struct sockaddr *)&socket_unix, LENGTH_OF_SOCKADDR_UN(&socket_unix)) < 0) goto error; + svr->path = strdup(buf); + if (!svr->path) goto error; + svr->fd_handler = ecore_main_fd_handler_add(svr->fd, + ECORE_FD_READ, + _ecore_con_cl_handler, svr, + NULL, NULL); + if (!svr->fd_handler) goto error; + { + /* we got our server! */ + Ecore_Con_Event_Server_Add *e; + + e = calloc(1, sizeof(Ecore_Con_Event_Server_Add)); + if (e) + { + e->server = svr; + ecore_event_add(ECORE_CON_EVENT_SERVER_ADD, e, NULL, NULL); + } + } + } + else if (type == ECORE_CON_REMOTE_SYSTEM) + { + struct hostent *he; + + /* FIXME: gethostbyname is blocking... */ + if (!(he = gethostbyname(name))) goto error; + svr->fd = socket(AF_INET, SOCK_STREAM, 0); + if (svr->fd < 0) goto error; + if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error; + if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error; + if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, &curstate, sizeof(curstate)) < 0) goto error; + socket_addr.sin_family = AF_INET; + socket_addr.sin_port = htons(port); + memcpy((struct in_addr *)&socket_addr.sin_addr, + he->h_addr, sizeof(struct in_addr)); + if (connect(svr->fd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in)) < 0) + { + if (errno != EINPROGRESS) + goto error; + svr->connecting = 1; + svr->fd_handler = ecore_main_fd_handler_add(svr->fd, + ECORE_FD_READ | ECORE_FD_WRITE, + _ecore_con_cl_handler, svr, + NULL, NULL); + } + else + svr->fd_handler = ecore_main_fd_handler_add(svr->fd, + ECORE_FD_READ, + _ecore_con_cl_handler, svr, + NULL, NULL); + + if (!svr->fd_handler) goto error; + } + +#if USE_OPENSSL + if (compl_type & ECORE_CON_USE_SSL) + { + /* SSLv3 gives *weird* results on my box, don't use it yet */ + if (!(svr->ssl_ctx = SSL_CTX_new(SSLv2_client_method()))) + goto error; + + if (!(svr->ssl = SSL_new(svr->ssl_ctx))) + goto error; + + SSL_set_fd(svr->ssl, svr->fd); + } +#endif + + svr->name = strdup(name); + if (!svr->name) goto error; + svr->type = type; + svr->port = port; + svr->data = (void *)data; + svr->created = 0; + svr->reject_excess_clients = 0; + svr->client_limit = -1; + svr->clients = ecore_list_new(); + ecore_list_append(servers, svr); + ECORE_MAGIC_SET(svr, ECORE_MAGIC_CON_SERVER); + return svr; + + error: + if (svr->name) free(svr->name); + if (svr->path) free(svr->path); + if (svr->fd >= 0) close(svr->fd); + if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler); +#if USE_OPENSSL + if (svr->ssl) SSL_free(svr->ssl); + if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx); +#endif + free(svr); + return NULL; +} + +/** + * Closes the connection and frees the given server. + * @param svr The given server. + * @return Data associated with the server when it was created. + * @ingroup Ecore_Con_Server_Group + */ +void * +ecore_con_server_del(Ecore_Con_Server *svr) +{ + void *data; + + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, + "ecore_con_server_del"); + return NULL; + } + data = svr->data; + _ecore_con_server_free(svr); + if (ecore_list_goto(servers, svr)) ecore_list_remove(servers); + return data; +} + +/** + * Retrieves the data associated with the given server. + * @param svr The given server. + * @return The associated data. + * @ingroup Ecore_Con_Server_Group + */ +void * +ecore_con_server_data_get(Ecore_Con_Server *svr) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, + "ecore_con_server_data_get"); + return NULL; + } + return svr->data; +} + +/** + * Retrieves whether the given server is currently connected. + * @todo Check that this function does what the documenter believes it does. + * @param svr The given server. + * @return @c 1 if the server is connected. @c 0 otherwise. + * @ingroup Ecore_Con_Server_Group + */ +int +ecore_con_server_connected_get(Ecore_Con_Server *svr) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, + "ecore_con_server_connected_get"); + return 0; + } + if (svr->connecting) return 0; + return 1; +} + +/** + * Sends the given data to the given server. + * @param svr The given server. + * @param data The given data. + * @param size Length of the data, in bytes, to send. + * @return The number of bytes sent. @c 0 will be returned if there is an + * error. + * @ingroup Ecore_Con_Server_Group + */ +int +ecore_con_server_send(Ecore_Con_Server *svr, void *data, int size) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, + "ecore_con_server_send"); + return 0; + } + if (svr->dead) return 0; + if (!data) return 0; + if (size < 1) return 0; + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); + if (svr->write_buf) + { + unsigned char *newbuf; + + newbuf = realloc(svr->write_buf, svr->write_buf_size + size); + if (newbuf) svr->write_buf = newbuf; + else return 0; + memcpy(svr->write_buf + svr->write_buf_size, data, size); + svr->write_buf_size += size; + } + else + { + svr->write_buf = malloc(size); + if (!svr->write_buf) return 0; + svr->write_buf_size = size; + memcpy(svr->write_buf, data, size); + } + return size; +} + +/** + * Sets a limit on the number of clients that can be handled concurrently + * by the given server, and a policy on what to do if excess clients try to + * connect. + * Beware that if you set this once ecore is already running, you may + * already have pending CLIENT_ADD events in your event queue. Those + * clients have already connected and will not be affected by this call. + * Only clients subsequently trying to connect will be affected. + * @param svr The given server. + * @param client_limit The maximum number of clients to handle + * concurrently. -1 means unlimited (default). 0 + * effectively disables the server. + * @param reject_excess_clients Set to 1 to automatically disconnect + * excess clients as soon as they connect if you are + * already handling client_limit clients. Set to 0 + * (default) to just hold off on the "accept()" + * system call until the number of active clients + * drops. This causes the kernel to queue up to 4096 + * connections (or your kernel's limit, whichever is + * lower). + * @ingroup Ecore_Con_Server_Group + */ +void +ecore_con_server_client_limit_set(Ecore_Con_Server *svr, int client_limit, char reject_excess_clients) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, + "ecore_con_server_client_limit_set"); + return; + } + svr->client_limit = client_limit; + svr->reject_excess_clients = reject_excess_clients; +} + +/** + * @defgroup Ecore_Con_Client_Group Ecore Connection Client Functions + * + * Functions that operate on Ecore connection client objects. + */ + +/** + * Sends the given data to the given client. + * @param cl The given client. + * @param data The given data. + * @param size Length of the data, in bytes, to send. + * @return The number of bytes sent. @c 0 will be returned if there is an + * error. + * @ingroup Ecore_Con_Client_Group + */ +int +ecore_con_client_send(Ecore_Con_Client *cl, void *data, int size) +{ + if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) + { + ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, + "ecore_con_client_send"); + return 0; + } + if (cl->dead) return 0; + if (!data) return 0; + if (size < 1) return 0; + ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); + if (cl->buf) + { + unsigned char *newbuf; + + newbuf = realloc(cl->buf, cl->buf_size + size); + if (newbuf) cl->buf = newbuf; + else return 0; + memcpy(cl->buf + cl->buf_size, data, size); + cl->buf_size += size; + } + else + { + cl->buf = malloc(size); + if (!cl->buf) return 0; + cl->buf_size = size; + memcpy(cl->buf, data, size); + } + return size; +} + +/** + * Retrieves the server representing the socket the client has + * connected to. + * @param cl The given client. + * @return The server that the client connected to. + * @ingroup Ecore_Con_Client_Group + */ +Ecore_Con_Server * +ecore_con_client_server_get(Ecore_Con_Client *cl) +{ + if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) + { + ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, + "ecore_con_client_server_get"); + return NULL; + } + return cl->server; +} + +/** + * Closes the connection and frees memory allocated to the given client. + * @param cl The given client. + * @return Data associated with the client. + * @ingroup Ecore_Con_Client_Group + */ +void * +ecore_con_client_del(Ecore_Con_Client *cl) +{ + void *data; + + if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) + { + ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, + "ecore_con_client_del"); + return NULL; + } + data = cl->data; + _ecore_con_client_free(cl); + if (ecore_list_goto(cl->server->clients, cl)) ecore_list_remove(cl->server->clients); + return data; +} + +/** + * Sets the data associated with the given client to @p data. + * @param cl The given client. + * @param data What to set the data to. + * @ingroup Ecore_Con_Client_Group + */ +void +ecore_con_client_data_set(Ecore_Con_Client *cl, const void *data) +{ + if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) + { + ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, + "ecore_con_client_data_set"); + return; + } + cl->data = (void *)data; +} + +/** + * Retrieves the data associated with the given client. + * @param cl The given client. + * @return The data associated with @p cl. + * @ingroup Ecore_Con_Client_Group + */ +void * +ecore_con_client_data_get(Ecore_Con_Client *cl) +{ + if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) + { + ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, + "ecore_con_client_data_get"); + return NULL; + } + return cl->data; +} + +/** + * Returns if SSL support is available + * @return 1 if SSL is available, 0 if it is not. + * @ingroup Ecore_Con_Client_Group + */ +int +ecore_con_ssl_available_get(void) +{ +#if USE_OPENSSL + return 1; +#else + return 0; +#endif +} + +static void +_ecore_con_server_free(Ecore_Con_Server *svr) +{ + ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE); + while ((svr->write_buf) && (!svr->dead)) _ecore_con_server_flush(svr); + if (svr->write_buf) free(svr->write_buf); + while (!ecore_list_is_empty(svr->clients)) + _ecore_con_client_free(ecore_list_remove_first(svr->clients)); + ecore_list_destroy(svr->clients); + if ((svr->created) && (svr->path)) unlink(svr->path); + if (svr->fd >= 0) close(svr->fd); +#if USE_OPENSSL + if (svr->ssl) + { + SSL_shutdown(svr->ssl); + SSL_free(svr->ssl); + } + if (svr->ssl_ctx) SSL_CTX_free(svr->ssl_ctx); +#endif + if (svr->name) free(svr->name); + if (svr->path) free(svr->path); + if (svr->fd_handler) ecore_main_fd_handler_del(svr->fd_handler); + free(svr); +} + +static void +_ecore_con_client_free(Ecore_Con_Client *cl) +{ + ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE); + while ((cl->buf) && (!cl->dead)) _ecore_con_client_flush(cl); + if (cl->buf) free(cl->buf); + if (cl->fd >= 0) close(cl->fd); + if (cl->fd_handler) ecore_main_fd_handler_del(cl->fd_handler); + free(cl); +} + +static int +_ecore_con_svr_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) +{ + Ecore_Con_Server *svr; + int new_fd; + struct sockaddr_in incoming; + size_t size_in; + + svr = data; + if (svr->dead) return 1; + if ((svr->client_limit >= 0) && (!svr->reject_excess_clients)) + { + if (ecore_list_nodes(svr->clients) >= svr->client_limit) return 1; + } + /* a new client */ + size_in = sizeof(struct sockaddr_in); + new_fd = accept(svr->fd, (struct sockaddr *)&incoming, &size_in); + if (new_fd >= 0) + { + Ecore_Con_Client *cl; + + if ((svr->client_limit >= 0) && (svr->reject_excess_clients)) + { + close(new_fd); + return 1; + } + + cl = calloc(1, sizeof(Ecore_Con_Client)); + if (!cl) + { + close(new_fd); + return 1; + } + fcntl(new_fd, F_SETFL, O_NONBLOCK); + fcntl(new_fd, F_SETFD, FD_CLOEXEC); + cl->fd = new_fd; + cl->server = svr; + cl->fd_handler = ecore_main_fd_handler_add(cl->fd, + ECORE_FD_READ, + _ecore_con_svr_cl_handler, + cl, NULL, NULL); + ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); + ecore_list_append(svr->clients, cl); + { + Ecore_Con_Event_Client_Add *e; + + e = calloc(1, sizeof(Ecore_Con_Event_Client_Add)); + if (e) + { + e->client = cl; + ecore_event_add(ECORE_CON_EVENT_CLIENT_ADD, e, NULL, NULL); + } + } + } + return 1; +} + +#if USE_OPENSSL +/* Tries to connect an Ecore_Con_Server to an SSL host. + * Returns 1 on success, -1 on fatal errors and 0 if the caller + * should try again later. + */ +static int +svr_try_connect_ssl(Ecore_Con_Server *svr) +{ + int res, ssl_err, flag = 0; + + res = SSL_connect(svr->ssl); + if (res == 1) return 1; + ssl_err = SSL_get_error(svr->ssl, res); + + if (ssl_err == SSL_ERROR_NONE) return 1; + if (ssl_err == SSL_ERROR_WANT_READ) flag = ECORE_FD_READ; + else if (ssl_err == SSL_ERROR_WANT_WRITE) flag = ECORE_FD_WRITE; + else return -1; + if (flag) ecore_main_fd_handler_active_set(svr->fd_handler, flag); + return 0; +} +#endif + +static void +kill_server(Ecore_Con_Server *svr) +{ + Ecore_Con_Event_Server_Del *e; + + e = calloc(1, sizeof(Ecore_Con_Event_Server_Del)); + if (e) + { + e->server = svr; + ecore_event_add(ECORE_CON_EVENT_SERVER_DEL, e, NULL, NULL); + } + + svr->dead = 1; + ecore_main_fd_handler_del(svr->fd_handler); + svr->fd_handler = NULL; +} + +static int +svr_try_connect_plain(Ecore_Con_Server *svr) +{ + int so_err = 0, size = sizeof(int); + + if (getsockopt(svr->fd, SOL_SOCKET, SO_ERROR, &so_err, &size) < 0) + so_err = -1; + + if (so_err != 0) + { + /* we lost our server! */ + kill_server(svr); + } + else + { + /* we got our server! */ + Ecore_Con_Event_Server_Add *e; + + svr->connecting = 0; + e = calloc(1, sizeof(Ecore_Con_Event_Server_Add)); + if (e) + { + e->server = svr; + ecore_event_add(ECORE_CON_EVENT_SERVER_ADD, e, NULL, NULL); + } + if (!svr->write_buf) + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); + } + return (!svr->dead); +} + +/* returns 1 on success, 0 on failure */ +static int svr_try_connect (Ecore_Con_Server *svr) +{ +#if USE_OPENSSL + if (!svr->ssl) + { +#endif + return svr_try_connect_plain(svr); +#if USE_OPENSSL + } + else + switch (svr_try_connect_ssl(svr)) { + case 1: + return svr_try_connect_plain(svr); + case -1: + kill_server(svr); + return 0; + default: + return 0; + } +#endif +} + + +static int +_ecore_con_cl_handler(void *data, Ecore_Fd_Handler *fd_handler) +{ + Ecore_Con_Server *svr; +#if USE_OPENSSL + int ssl_err = SSL_ERROR_NONE; +#endif + + svr = data; + if (svr->dead) return 1; + if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) + { + unsigned char *inbuf = NULL; + int inbuf_num = 0; + + if (svr->connecting && !svr_try_connect(svr)) + return 1; + + for (;;) + { + int num, lost_server = 0; + char buf[READBUFSIZ]; + +#if USE_OPENSSL + if (!svr->ssl) + { +#endif + if ((num = read(svr->fd, buf, READBUFSIZ)) < 1) + lost_server = (errno == EIO || errno == EBADF || + errno == EPIPE || errno == EINVAL || + errno == ENOSPC || num == 0); /* is num == 0 right? */ +#if USE_OPENSSL + } + else + { + num = SSL_read(svr->ssl, buf, READBUFSIZ); + if (num < 1) + { + ssl_err = SSL_get_error(svr->ssl, num); + lost_server = (ssl_err == SSL_ERROR_ZERO_RETURN); + } + else + ssl_err = SSL_ERROR_NONE; + } +#endif + if (num < 1) + { + if (inbuf) + { + Ecore_Con_Event_Server_Data *e; + + e = calloc(1, sizeof(Ecore_Con_Event_Server_Data)); + if (e) + { + e->server = svr; + e->data = inbuf; + e->size = inbuf_num; + ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e, + _ecore_con_event_server_data_free, NULL); + } + } + if (lost_server) + { + /* we lost our server! */ + kill_server(svr); + return 1; + } + break; + } + else + { + inbuf = realloc(inbuf, inbuf_num + num); + memcpy(inbuf + inbuf_num, buf, num); + inbuf_num += num; + } + } + +#if USE_OPENSSL + if (svr->ssl && ssl_err == SSL_ERROR_WANT_READ) + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); + else if (svr->ssl && ssl_err == SSL_ERROR_WANT_WRITE) + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); +#endif + } + else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) + { + if (svr->connecting && !svr_try_connect (svr)) + return 1; + + _ecore_con_server_flush(svr); + } + + return 1; +} + +static int +_ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler) +{ + Ecore_Con_Client *cl; + + cl = data; + if (cl->dead) return 1; + if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) + { + unsigned char *inbuf = NULL; + int inbuf_num = 0; + + for (;;) + { + char buf[65536]; + int num; + + errno = 0; + num = read(cl->fd, buf, 65536); + if (num < 1) + { + if (inbuf) + { + Ecore_Con_Event_Client_Data *e; + + e = calloc(1, sizeof(Ecore_Con_Event_Client_Data)); + if (e) + { + e->client = cl; + e->data = inbuf; + e->size = inbuf_num; + ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e, + _ecore_con_event_client_data_free, NULL); + } + } + if ((errno == EIO) || (errno == EBADF) || + (errno == EPIPE) || (errno == EINVAL) || + (errno == ENOSPC) || (num == 0)/* is num == 0 right? */) + { + /* we lost our client! */ + Ecore_Con_Event_Client_Del *e; + + e = calloc(1, sizeof(Ecore_Con_Event_Client_Del)); + if (e) + { + e->client = cl; + ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e, NULL, NULL); + } + cl->dead = 1; + ecore_main_fd_handler_del(cl->fd_handler); + cl->fd_handler = NULL; + } + break; + } + else + { + inbuf = realloc(inbuf, inbuf_num + num); + memcpy(inbuf + inbuf_num, buf, num); + inbuf_num += num; + } + } + } + else if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) + _ecore_con_client_flush(cl); + return 1; +} + +static void +_ecore_con_server_flush(Ecore_Con_Server *svr) +{ + int count, num, lost_server = 0; +#if USE_OPENSSL + int ssl_err = SSL_ERROR_NONE; +#endif + + if (!svr->write_buf) return; + + /* check whether we need to write anything at all. + * we must not write zero bytes with SSL_write() since it + * causes undefined behaviour + */ + if (svr->write_buf_size == svr->write_buf_offset) + return; + + num = svr->write_buf_size - svr->write_buf_offset; +#if USE_OPENSSL + if (!svr->ssl) + { +#endif + count = write(svr->fd, svr->write_buf + svr->write_buf_offset, num); + if (count < 1) + lost_server = (errno == EIO || errno == EBADF || + errno == EPIPE || errno == EINVAL || + errno == ENOSPC); +#if USE_OPENSSL + } + else + { + count = SSL_write(svr->ssl, svr->write_buf + svr->write_buf_offset, num); + + if (count < 1) + { + ssl_err = SSL_get_error(svr->ssl, count); + lost_server = (ssl_err == SSL_ERROR_ZERO_RETURN); + } + } +#endif + + if (lost_server) + { + /* we lost our server! */ + kill_server(svr); + return; + } + + if (count < 1) + { +#if USE_OPENSSL + if (svr->ssl && ssl_err == SSL_ERROR_WANT_READ) + ecore_main_fd_handler_active_set(svr->fd_handler, + ECORE_FD_READ); + else if (svr->ssl && ssl_err == SSL_ERROR_WANT_WRITE) + ecore_main_fd_handler_active_set(svr->fd_handler, + ECORE_FD_WRITE); +#endif + return; + } + + svr->write_buf_offset += count; + if (svr->write_buf_offset >= svr->write_buf_size) + { + svr->write_buf_size = 0; + svr->write_buf_offset = 0; + free(svr->write_buf); + svr->write_buf = NULL; + ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); + } +} + +static void +_ecore_con_client_flush(Ecore_Con_Client *cl) +{ + int count, num; + + if (!cl->buf) return; + num = cl->buf_size - cl->buf_offset; + count = write(cl->fd, cl->buf + cl->buf_offset, num); + if (count < 1) + { + if ((errno == EIO) || (errno == EBADF) || (errno == EPIPE) || + (errno == EINVAL) || (errno == ENOSPC)) + { + /* we lost our client! */ + Ecore_Con_Event_Client_Del *e; + + e = calloc(1, sizeof(Ecore_Con_Event_Client_Del)); + if (e) + { + e->client = cl; + ecore_event_add(ECORE_CON_EVENT_CLIENT_DEL, e, NULL, NULL); + } + cl->dead = 1; + ecore_main_fd_handler_del(cl->fd_handler); + cl->fd_handler = NULL; + } + return; + } + cl->buf_offset += count; + if (cl->buf_offset >= cl->buf_size) + { + cl->buf_size = 0; + cl->buf_offset = 0; + free(cl->buf); + cl->buf = NULL; + ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); + } +} + +static void +_ecore_con_event_client_data_free(void *data __UNUSED__, void *ev) +{ + Ecore_Con_Event_Client_Data *e; + + e = ev; + if (e->data) free(e->data); + free(e); +} + +static void +_ecore_con_event_server_data_free(void *data __UNUSED__, void *ev) +{ + Ecore_Con_Event_Server_Data *e; + + e = ev; + if (e->data) free(e->data); + free(e); +} diff --git a/ecore/src/lib/ecore_con/ecore_con_private.h b/ecore/src/lib/ecore_con/ecore_con_private.h new file mode 100644 index 0000000..d94793e --- /dev/null +++ b/ecore/src/lib/ecore_con/ecore_con_private.h @@ -0,0 +1,86 @@ +#ifndef _ECORE_CON_PRIVATE_H +#define _ECORE_CON_PRIVATE_H + +#define ECORE_MAGIC_CON_SERVER 0x77665544 +#define ECORE_MAGIC_CON_CLIENT 0x77556677 + +#if USE_OPENSSL +#include +#endif +#ifdef HAVE_CURL +#include +#endif + +#define READBUFSIZ 65536 + +typedef struct _Ecore_Con_Client Ecore_Con_Client; +typedef struct _Ecore_Con_Server Ecore_Con_Server; +#ifdef HAVE_CURL +typedef struct _Ecore_Con_Url Ecore_Con_Url; +#else +typedef void Ecore_Con_Url; +#endif + +typedef enum _Ecore_Con_Type +{ + ECORE_CON_LOCAL_USER, + ECORE_CON_LOCAL_SYSTEM, + ECORE_CON_REMOTE_SYSTEM +#if USE_OPENSSL + ,ECORE_CON_USE_SSL = 16 +#endif +} Ecore_Con_Type; + +struct _Ecore_Con_Client +{ + Ecore_List __list_data; + ECORE_MAGIC; + int fd; + Ecore_Con_Server *server; + void *data; + Ecore_Fd_Handler *fd_handler; + int buf_size; + int buf_offset; + unsigned char *buf; + char dead : 1; +}; + +struct _Ecore_Con_Server +{ + Ecore_List __list_data; + ECORE_MAGIC; + int fd; + Ecore_Con_Type type; + char *name; + int port; + char *path; + void *data; + Ecore_Fd_Handler *fd_handler; + Ecore_List *clients; + int write_buf_size; + int write_buf_offset; + unsigned char *write_buf; + char dead : 1; + char created : 1; + char connecting : 1; + char reject_excess_clients : 1; + int client_limit; + +#if USE_OPENSSL + SSL_CTX *ssl_ctx; + SSL *ssl; +#endif +}; + +#ifdef HAVE_CURL +struct _Ecore_Con_Url +{ + /* FIXME: ECORE_MAGIC ? */ + CURL *curl_easy; + char *url; + struct curl_slist *headers; + Ecore_Fd_Handler *fd_handler; + char active : 1; +}; +#endif +#endif diff --git a/ecore/src/lib/ecore_con/ecore_con_url.c b/ecore/src/lib/ecore_con/ecore_con_url.c new file mode 100644 index 0000000..2789233 --- /dev/null +++ b/ecore/src/lib/ecore_con/ecore_con_url.c @@ -0,0 +1,408 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +/* + * For info on how to use libcurl, see: + * http://curl.haxx.se/libcurl/c/libcurl-tutorial.html + */ + +/* + * Brief usage: + * 1. Create an Ecore_Con_Url object + * 2. Register to receive the ECORE_CON_EVENT_URL_COMPLETE event + * (and optionally the ECORE_CON_EVENT_URL_DATA event to receive + * the response, e.g. for HTTP/FTP downloads) + * 3. Set the URL with ecore_con_url_url_set(...); + * 4. Perform the operation with ecore_con_url_send(...); + * + * Note that it is good to reuse Ecore_Con_Url objects wherever possible, but + * bear in mind that each one can only perform one operation at a time. + * You need to wait for the ECORE_CON_EVENT_URL_COMPLETE event before re-using + * or destroying the object. + * + * Example Usage 1 (HTTP GET): + * ecore_con_url_url_set(url_con, "http://www.google.com"); + * ecore_con_url_send(url, NULL, 0, NULL); + * + * Example usage 2 (HTTP POST): + * ecore_con_url_url_set(url_con, "http://www.example.com/post_handler.cgi"); + * ecore_con_url_send(url, data, data_length, "multipart/form-data"); + * + * Example Usage 3 (FTP download): + * ecore_con_url_url_set(url_con, "ftp://ftp.example.com/pub/myfile"); + * ecore_con_url_send(url, NULL, 0, NULL); + * + * FIXME: Support more CURL features: Authentication, FTP upload, Progress callbacks and more... + */ +#include "Ecore.h" +#include "config.h" +#include "ecore_private.h" +#include "ecore_con_private.h" +#include "Ecore_Con.h" + +#ifdef HAVE_CURL +static int _ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); +static int _ecore_con_url_perform(Ecore_Con_Url *url_con); +size_t _ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp); +static void _ecore_con_event_url_complete_free(void *data __UNUSED__, void *ev); +static void _ecore_con_event_url_data_free(void *data __UNUSED__, void *ev); +static int _ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match); + +int ECORE_CON_EVENT_URL_DATA = 0; +int ECORE_CON_EVENT_URL_COMPLETE = 0; + +static CURLM *curlm = NULL; +static Ecore_List *_url_con_list = NULL; +static fd_set _current_fd_set; +static int init_count = 0; +#endif + +int +ecore_con_url_init(void) +{ +#ifdef HAVE_CURL + if (!ECORE_CON_EVENT_URL_DATA) + { + ECORE_CON_EVENT_URL_DATA = ecore_event_type_new(); + ECORE_CON_EVENT_URL_COMPLETE = ecore_event_type_new(); + } + + if (!_url_con_list) + { + _url_con_list = ecore_list_new(); + if (!_url_con_list) return 0; + } + + if (!curlm) + { + FD_ZERO(&_current_fd_set); + if (curl_global_init(CURL_GLOBAL_NOTHING)) + { + ecore_list_destroy(_url_con_list); + _url_con_list = NULL; + return 0; + } + + curlm = curl_multi_init(); + if (!curlm) + { + ecore_list_destroy(_url_con_list); + _url_con_list = NULL; + return 0; + } + } + init_count++; + return 1; +#else + return 0; +#endif +} + +int +ecore_con_url_shutdown(void) +{ +#ifdef HAVE_CURL + + if (!init_count) + return 0; + + init_count--; + if (_url_con_list) + { + if (!ecore_list_is_empty(_url_con_list)) + { + Ecore_Con_Url *url_con; + while ((url_con = ecore_list_remove_first(_url_con_list))) + { + ecore_con_url_destroy(url_con); + } + } + ecore_list_destroy(_url_con_list); + _url_con_list = NULL; + } + + if (curlm) + { + curl_multi_cleanup(curlm); + curlm = NULL; + } + + curl_global_cleanup(); +#endif + return 1; +} + +Ecore_Con_Url * +ecore_con_url_new(const char *url) +{ +#ifdef HAVE_CURL + Ecore_Con_Url *url_con; + + if (!init_count) return NULL; + + url_con = calloc(1, sizeof(Ecore_Con_Url)); + if (!url_con) return NULL; + + url_con->curl_easy = curl_easy_init(); + if (!url_con->curl_easy) + { + free(url_con); + return NULL; + } + + ecore_con_url_url_set(url_con, url); + + curl_easy_setopt(url_con->curl_easy, CURLOPT_WRITEFUNCTION, _ecore_con_url_data_cb); + curl_easy_setopt(url_con->curl_easy, CURLOPT_WRITEDATA, url_con); + /* + * FIXME: Check that these timeouts are sensible defaults + * FIXME: Provide a means to change these timeouts + */ + curl_easy_setopt(url_con->curl_easy, CURLOPT_CONNECTTIMEOUT, 30); + curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEOUT, 300); + + return url_con; +#else + return NULL; +#endif +} + +void +ecore_con_url_destroy(Ecore_Con_Url *url_con) +{ +#ifdef HAVE_CURL + if (!url_con) return; + + if (url_con->fd_handler) + ecore_main_fd_handler_del(url_con->fd_handler); + if (url_con->curl_easy) + { + if (url_con->active) + curl_multi_remove_handle(curlm, url_con->curl_easy); + curl_easy_cleanup(url_con->curl_easy); + } + curl_slist_free_all(url_con->headers); + free(url_con->url); + free(url_con); +#endif +} + +int +ecore_con_url_url_set(Ecore_Con_Url *url_con, const char *url) +{ +#ifdef HAVE_CURL + if (url_con->active) return 0; + + free(url_con->url); + url_con->url = NULL; + if (url) + url_con->url = strdup(url); + curl_easy_setopt(url_con->curl_easy, CURLOPT_URL, url_con->url); + +#endif + return 1; +} + +int +ecore_con_url_send(Ecore_Con_Url *url_con, void *data, size_t length, char *content_type) +{ +#ifdef HAVE_CURL + char tmp[256]; + + if (url_con->active) return 0; + if (!url_con->url) return 0; + + curl_slist_free_all(url_con->headers); + url_con->headers = NULL; + + if (data) + { + curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDS, data); + curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, length); + + if (content_type && (strlen(content_type) < 200)) + { + sprintf(tmp, "Content-type: %s", content_type); + url_con->headers = curl_slist_append(url_con->headers, tmp); + } + sprintf(tmp, "Content-length: %d", length); + url_con->headers = curl_slist_append(url_con->headers, tmp); + } + else + { + curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDS, NULL); + } + + curl_easy_setopt(url_con->curl_easy, CURLOPT_HTTPHEADER, url_con->headers); + + return _ecore_con_url_perform(url_con); +#else + return 0; +#endif +} + +#ifdef HAVE_CURL +size_t +_ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp) +{ + Ecore_Con_Url *url_con; + Ecore_Con_Event_Url_Data *e; + size_t real_size = size * nmemb; + + url_con = (Ecore_Con_Url *)userp; + e = calloc(1, sizeof(Ecore_Con_Event_Url_Data)); + if (e) + { + e->url_con = url_con; + e->data = buffer; + e->size = real_size; + ecore_event_add(ECORE_CON_EVENT_URL_DATA, e, + _ecore_con_event_url_data_free, NULL); + } + return real_size; +} + +/* + * FIXME: Use + * CURLOPT_PROGRESSFUNCTION and CURLOPT_PROGRESSDATA to + * get reports on progress. + * And maybe other nifty functions... + */ +static int +_ecore_con_url_perform(Ecore_Con_Url *url_con) +{ + fd_set read_set, write_set, exc_set; + int fd_max; + int fd; + int flags; + int still_running; + int completed_immediately = 0; + + ecore_list_append(_url_con_list, url_con); + + url_con->active = 1; + curl_multi_add_handle(curlm, url_con->curl_easy); + while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM); + + completed_immediately = _ecore_con_url_process_completed_jobs(url_con); + + if (!completed_immediately) + { + /* url_con still active -- set up an fd_handler */ + FD_ZERO(&read_set); + FD_ZERO(&write_set); + FD_ZERO(&exc_set); + + /* Stupid curl, why can't I get the fd to the current added job? */ + curl_multi_fdset(curlm, &read_set, &write_set, &exc_set, &fd_max); + for (fd = 0; fd <= fd_max; fd++) + { + if (!FD_ISSET(fd, &_current_fd_set)) + { + flags = 0; + if (FD_ISSET(fd, &read_set)) flags |= ECORE_FD_READ; + if (FD_ISSET(fd, &write_set)) flags |= ECORE_FD_WRITE; + if (FD_ISSET(fd, &exc_set)) flags |= ECORE_FD_ERROR; + if (flags) + { + FD_SET(fd, &_current_fd_set); + url_con->fd_handler = ecore_main_fd_handler_add(fd, flags, + _ecore_con_url_fd_handler, + NULL, NULL, NULL); + } + } + } + if (!url_con->fd_handler) + { + /* Failed to set up an fd_handler */ + curl_multi_remove_handle(curlm, url_con->curl_easy); + url_con->active = 0; + return 0; + } + } + + return 1; +} + +static int +_ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler) +{ + int still_running; + + /* FIXME: Can this run for a long time? Maybe limit how long it can run */ + while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM); + + _ecore_con_url_process_completed_jobs(NULL); + return 1; +} + +static int +_ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match) +{ + Ecore_Con_Url *url_con; + CURLMsg *curlmsg; + int n_remaining; + int job_matched = 0; + + /* Loop jobs and check if any are done */ + while ((curlmsg = curl_multi_info_read(curlm, &n_remaining)) != NULL) + { + if (curlmsg->msg != CURLMSG_DONE) continue; + + /* find the job which is done */ + ecore_list_goto_first(_url_con_list); + while ((url_con = ecore_list_current(_url_con_list))) + { + if (curlmsg->easy_handle == url_con->curl_easy) + { + /* We have found the completed job in our job list */ + if (url_con_to_match && (url_con == url_con_to_match)) { + job_matched = 1; + } + if (url_con->fd_handler) + { + FD_CLR(ecore_main_fd_handler_fd_get(url_con->fd_handler), + &_current_fd_set); + ecore_main_fd_handler_del(url_con->fd_handler); + url_con->fd_handler = NULL; + } + ecore_list_remove(_url_con_list); + curl_multi_remove_handle(curlm, url_con->curl_easy); + url_con->active = 0; + { + Ecore_Con_Event_Url_Complete *e; + e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete)); + if (e) + { + e->url_con = url_con; + e->status = curlmsg->data.result; + ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, + _ecore_con_event_url_complete_free, NULL); + } + } + break; + } + ecore_list_next(_url_con_list); + } + } + return job_matched; +} +static void +_ecore_con_event_url_data_free(void *data __UNUSED__, void *ev) +{ + Ecore_Con_Event_Url_Data *e; + + e = ev; + free(e); +} + +static void +_ecore_con_event_url_complete_free(void *data __UNUSED__, void *ev) +{ + Ecore_Con_Event_Url_Complete *e; + + e = ev; + free(e); +} +#endif diff --git a/ecore/src/lib/ecore_config/.cvsignore b/ecore/src/lib/ecore_config/.cvsignore new file mode 100644 index 0000000..59bc827 --- /dev/null +++ b/ecore/src/lib/ecore_config/.cvsignore @@ -0,0 +1,8 @@ +.deps +.libs +Makefile +Makefile.in +*.lo +libecore_config.la +ecore_config_ipc_ecore.la +system.db diff --git a/ecore/src/lib/ecore_config/CVS/Entries b/ecore/src/lib/ecore_config/CVS/Entries new file mode 100644 index 0000000..c0a38b1 --- /dev/null +++ b/ecore/src/lib/ecore_config/CVS/Entries @@ -0,0 +1,14 @@ +/.cvsignore/1.7/Sat Oct 23 14:27:10 2004//THEAD +/Ecore_Config.h/1.42/Wed Mar 2 07:06:34 2005//THEAD +/Makefile.am/1.28/Tue Jun 7 21:53:58 2005//THEAD +/ecore_config_db.c/1.6/Sat Jun 25 10:11:25 2005//THEAD +/ecore_config_extra.c/1.6/Tue Mar 22 20:40:19 2005//THEAD +/ecore_config_ipc.h/1.2/Wed Mar 2 07:06:34 2005//THEAD +/ecore_config_ipc_ecore.c/1.8/Sat Jun 25 10:11:25 2005//THEAD +/ecore_config_ipc_main.c/1.3/Tue Jun 7 21:54:07 2005//THEAD +/ecore_config_private.h/1.8/Sat Jun 25 10:11:25 2005//THEAD +/ecore_config_storage.c/1.9/Sat Jun 25 10:11:25 2005//THEAD +/ecore_config_util.c/1.2/Wed Mar 2 07:06:34 2005//THEAD +/ecore_config_util.h/1.2/Wed Mar 2 07:06:34 2005//THEAD +/ecore_config.c/1.60/Sat Jul 23 17:35:06 2005//THEAD +D diff --git a/ecore/src/lib/ecore_config/CVS/Entries.Log b/ecore/src/lib/ecore_config/CVS/Entries.Log new file mode 100644 index 0000000..8e2b110 --- /dev/null +++ b/ecore/src/lib/ecore_config/CVS/Entries.Log @@ -0,0 +1,2 @@ +A D/ipc//// +R D/ipc//// diff --git a/ecore/src/lib/ecore_config/CVS/Repository b/ecore/src/lib/ecore_config/CVS/Repository new file mode 100644 index 0000000..eac9a27 --- /dev/null +++ b/ecore/src/lib/ecore_config/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/src/lib/ecore_config diff --git a/ecore/src/lib/ecore_config/CVS/Root b/ecore/src/lib/ecore_config/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/src/lib/ecore_config/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/src/lib/ecore_config/CVS/Tag b/ecore/src/lib/ecore_config/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/src/lib/ecore_config/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/src/lib/ecore_config/Ecore_Config.h b/ecore/src/lib/ecore_config/Ecore_Config.h new file mode 100644 index 0000000..650feeb --- /dev/null +++ b/ecore/src/lib/ecore_config/Ecore_Config.h @@ -0,0 +1,308 @@ +#ifndef _ECORE_CONFIG_H +# define _ECORE_CONFIG_H + +#ifdef EAPI +#undef EAPI +#endif +#ifdef WIN32 +# ifdef BUILDING_DLL +# define EAPI __declspec(dllexport) +# else +# define EAPI __declspec(dllimport) +# endif +#else +# ifdef GCC_HASCLASSVISIBILITY +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +#endif + +/** + * @file + * @brief Provides the Enlightened Property Library. + * + * This file provies all headers and structs for use with Ecore_Config. + * Using individual header files should not be necessary. + */ + +# define DIR_DELIMITER '/' +# define ECORE_CONFIG_FLOAT_PRECISION 1000 + +# ifndef TRUE +# define FALSE (0) +# define TRUE (!FALSE) +# endif + +/* FIXME: this should only be included if evas is present */ +# include + +# define ECORE_CONFIG_GLOBAL_ID "_system" + +/* structures */ + +/** + * Valid configuration property types. + */ +typedef enum Ecore_Config_Type +{ + PT_NIL = 0, /**< Property with no value. */ + PT_INT = 1, /**< Integer property type. */ + PT_FLT = 2, /**< Float property type. */ + PT_STR = 3, /**< String property type. */ + PT_RGB = 4, /**< Colour property type. */ + PT_THM = 5, /**< Theme property type. */ + PT_BLN = 6, /**< Boolean property type. */ +} Ecore_Config_Type; + +typedef enum Ecore_Config_Flag +{ + PF_NONE = 0, + PF_BOUNDS = 1, + PF_MODIFIED = 2, + PF_SYSTEM = 4, + PF_CMDLN = 8 +} Ecore_Config_Flag; + +/** + * Property change callback function prototype. + */ +typedef int (*Ecore_Config_Listener) (const char *key, + const Ecore_Config_Type type, + const int tag, void *data); + +typedef struct Ecore_Config_Listener_List +{ + Ecore_Config_Listener listener; + const char *name; + void *data; + int tag; + struct Ecore_Config_Listener_List *next; +} Ecore_Config_Listener_List; + +/** + * The actual property for storing a key-value pair. + */ +typedef struct Ecore_Config_Prop +{ + char *key; /* Property key. */ + char *description; /* Description set by ecore_config_descibe. */ + char short_opt; /* short identifier on command line (-f) */ + char *long_opt; /* long identifier on command line (--foo) */ + char *ptr; /* Used as the value when the property is a string or theme. */ + Ecore_Config_Type type; /* Property type. */ + long val; /* Used as the value when the property is an integer, float or colour. */ + long lo; /* Lower bound for the value when the property is an integer or float. */ + long hi; /* Higher bound for the value when the property is an integer or float. */ + long step; /* Increment for the value when the property is an integer or float. */ + Ecore_Config_Flag flags; /// < Configuration flags. + Ecore_Config_Listener_List *listeners; /* List of change listeners. */ + void *data; /// < Stores extra data for the property. + struct Ecore_Config_Prop *next; /* Pointer to the next property in the list. */ +} Ecore_Config_Prop; + +/* + * A container for a list of properties. Provided so that an + * application can use different set of properties at any time. This + * is useful for multiple window support. + */ +typedef struct Ecore_Config_Bundle +{ + char *identifier; /* Identifier for this set of properties (window ID for example) */ + char *owner; /* This is used to store the application name related to the bundle */ + long serial; /* Unique identifier to identify bundle */ + Ecore_Config_Prop *data; /* Pointer to root of property list */ + void *user_data; /* App specific pointer to "other data" */ + struct Ecore_Config_Bundle *next; /* Pointer to next bundle in this application */ +} Ecore_Config_Bundle; + +typedef struct Ecore_Config_Server +{ + void *server; + char *name; + Ecore_Config_Bundle *bundles; /* data anchor */ + struct Ecore_Config_Server *next; +} Ecore_Config_Server; + +# ifdef __cplusplus +extern "C" +{ +# endif + +/* global ptrs to save passing them through the API */ + extern EAPI Ecore_Config_Server *__ecore_config_server_global; + extern EAPI Ecore_Config_Server *__ecore_config_server_local; + extern EAPI Ecore_Config_Bundle *__ecore_config_bundle_local; + extern EAPI char *__ecore_config_app_name; + + EAPI Ecore_Config_Prop *ecore_config_get(const char *key); + EAPI const char *ecore_config_type_get(const Ecore_Config_Prop * e); + EAPI int ecore_config_boolean_get(const char *key); + EAPI void *ecore_config_data_get(const char *key); + EAPI char *ecore_config_string_get(const char *key); + EAPI long ecore_config_int_get(const char *key); + EAPI int ecore_config_rgb_get(const char *key, int *r, int *g, + int *b); + EAPI int ecore_config_argb_get(const char *key, int *a, int *r, + int *g, int *b); + EAPI char *ecore_config_rgbstr_get(const char *key); + EAPI char *ecore_config_argbstr_get(const char *key); + EAPI float ecore_config_float_get(const char *key); + EAPI char *ecore_config_theme_get(const char *key); + EAPI char *ecore_config_as_string_get(const char *key); + EAPI int ecore_config_bound(Ecore_Config_Prop * e); + EAPI int ecore_config_describe(const char *key, char *desc); + EAPI int ecore_config_short_opt_set(const char *key, + char short_opt); + EAPI int ecore_config_long_opt_set(const char *key, + char *long_opt); + EAPI int ecore_config_set(const char *key, char *val); + EAPI int ecore_config_typed_set(const char *key, const void *val, + int type); + EAPI int ecore_config_boolean_set(const char *key, int val); + EAPI int ecore_config_string_set(const char *key, char *val); + EAPI int ecore_config_int_set(const char *key, int val); + EAPI char *ecore_config_rgb_to_argb(char *rgb); + EAPI int ecore_config_rgb_set(const char *key, char *val); + EAPI int ecore_config_argb_set(const char *key, char *val); + EAPI int ecore_config_float_set(const char *key, float val); + EAPI int ecore_config_theme_set(const char *key, char *val); + EAPI int ecore_config_theme_preview_group_set(const char *key, + char *group); + EAPI int ecore_config_as_string_set(const char *key, char *val); + + EAPI int ecore_config_default(const char *key, char *val, + float lo, float hi, float step); + EAPI int ecore_config_typed_default(const char *key, void *val, + int type); + EAPI int ecore_config_boolean_default(const char *key, int val); + EAPI int ecore_config_int_default(const char *key, int val); + EAPI int ecore_config_int_default_bound(const char *key, int val, + int lo, int hi, int step); + EAPI int ecore_config_string_default(const char *key, const char *val); + EAPI int ecore_config_float_default(const char *key, float val); + EAPI int ecore_config_float_default_bound(const char *key, + float val, float lo, + float hi, float step); + EAPI int ecore_config_rgb_default(const char *key, char *val); + EAPI int ecore_config_argb_default(const char *keym, char *val); + EAPI int ecore_config_theme_default(const char *key, char *val); + + EAPI int ecore_config_listen(const char *name, const char *key, + Ecore_Config_Listener listener, + int tag, void *data); + EAPI int ecore_config_deaf(const char *name, const char *key, + Ecore_Config_Listener listener); + EAPI Ecore_Config_Prop *ecore_config_dst(Ecore_Config_Prop * e); + EAPI int ecore_config_type_guess(const char *key, const char *val); + + EAPI Ecore_Config_Bundle *ecore_config_bundle_new(Ecore_Config_Server * srv, + const char *id); + EAPI Ecore_Config_Bundle *ecore_config_bundle_1st_get(Ecore_Config_Server * srv); + EAPI Ecore_Config_Bundle *ecore_config_bundle_next_get(Ecore_Config_Bundle * ns); + EAPI Ecore_Config_Bundle *ecore_config_bundle_by_serial_get(Ecore_Config_Server * + srv, long serial); + EAPI Ecore_Config_Bundle *ecore_config_bundle_by_label_get(Ecore_Config_Server * + srv, + const char *label); + EAPI long ecore_config_bundle_serial_get(Ecore_Config_Bundle * ns); + EAPI char *ecore_config_bundle_label_get(Ecore_Config_Bundle * ns); + + EAPI int ecore_config_init(const char *name); + EAPI int ecore_config_shutdown(void); + + EAPI int ecore_config_system_init(void); + EAPI int ecore_config_system_shutdown(void); + + EAPI int ecore_config_load(void); + EAPI int ecore_config_file_load(const char *file); + EAPI int ecore_config_save(void); + EAPI int ecore_config_file_save(const char *file); + +/* error codes */ +# define ECORE_CONFIG_ERR_NOTSUPP (-16) +# define ECORE_CONFIG_ERR_NOFILE (-15) +# define ECORE_CONFIG_ERR_META_DLFAIL (-14) +# define ECORE_CONFIG_ERR_META_FILE (-13) +# define ECORE_CONFIG_ERR_META_FORMAT (-12) +# define ECORE_CONFIG_ERR_MONMIS (-11) +# define ECORE_CONFIG_ERR_NOEXEC (-10) +# define ECORE_CONFIG_ERR_PARTIAL (-9) +# define ECORE_CONFIG_ERR_PATHEX (-8) +# define ECORE_CONFIG_ERR_TYPEMISMATCH (-7) +# define ECORE_CONFIG_ERR_MUTEX (-6) +# define ECORE_CONFIG_ERR_NOTFOUND (-5) /* Error indicating that the item searched for could not be found. */ +# define ECORE_CONFIG_ERR_OOM (-4) /* Error given when the program runs out of memory. */ +# define ECORE_CONFIG_ERR_IGNORED (-3) /* Error occurred, but was ignored. */ +# define ECORE_CONFIG_ERR_NODATA (-2) /* Error given when necessary data is not provided. */ +# define ECORE_CONFIG_ERR_FAIL (-1) /* Failure result. */ +# define ECORE_CONFIG_ERR_SUCC (0) /* Success result. */ + +# define ECORE_CONFIG_PARSE_HELP (-2) /* Help was displayed */ +# define ECORE_CONFIG_PARSE_EXIT (-1) /* An error occurred */ +# define ECORE_CONFIG_PARSE_CONTINUE (0) /* Arguments parsed successfully */ + +/* convenience mathods in convenience.c */ + /* FIXME: this should only be included if evas is present */ + EAPI int ecore_config_evas_font_path_apply(Evas * evas); + EAPI char *ecore_config_theme_search_path_get(void); + EAPI int ecore_config_theme_search_path_append(char *append); + + EAPI char *ecore_config_theme_default_path_get(void); + EAPI char *ecore_config_theme_with_path_from_name_get(char *name); + EAPI char *ecore_config_theme_with_path_get(const char *key); + EAPI void ecore_config_args_display(void); + EAPI int ecore_config_args_parse(void); + EAPI void ecore_config_args_callback_str_add(char short_opt, + char *long_opt, char *desc, + void (*func)(char *val, void *data), + void *data); + EAPI void ecore_config_args_callback_noarg_add(char short_opt, + char *long_opt, char *desc, + void (*func)(char *val, void *data), + void *data); + EAPI void ecore_config_app_describe(char *description); + + EAPI int ecore_config_create(const char *key, void *val, + char short_opt, char *long_opt, + char *desc); + EAPI int ecore_config_typed_create(const char *key, void *val, + int type, char short_opt, + char *long_opt, char *desc); + EAPI int ecore_config_boolean_create(const char *key, int val, + char short_opt, char *long_opt, + char *desc); + EAPI int ecore_config_int_create(const char *key, int val, + char short_opt, char *long_opt, + char *desc); + EAPI int ecore_config_int_create_bound(const char *key, int val, + int low, int high, + int step, char short_opt, + char *long_opt, + char *desc); + EAPI int ecore_config_string_create(const char *key, char *val, + char short_opt, + char *long_opt, char *desc); + EAPI int ecore_config_float_create(const char *key, float val, + char short_opt, char *long_opt, + char *desc); + EAPI int ecore_config_float_create_bound(const char *key, + float val, float low, + float high, float step, + char short_opt, + char *long_opt, + char *desc); + EAPI int ecore_config_rgb_create(const char *key, char *val, + char short_opt, char *long_opt, + char *desc); + EAPI int ecore_config_argb_create(const char *key, char *val, + char short_opt, char *long_opt, + char *desc); + EAPI int ecore_config_theme_create(const char *key, char *val, + char short_opt, char *long_opt, + char *desc); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/ecore/src/lib/ecore_config/Makefile.am b/ecore/src/lib/ecore_config/Makefile.am new file mode 100644 index 0000000..795eef4 --- /dev/null +++ b/ecore/src/lib/ecore_config/Makefile.am @@ -0,0 +1,65 @@ +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_ipc \ +-I$(top_srcdir)/ \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_ipc \ +-I$(top_builddir)/ \ +@evas_cflags@ @eet_cflags@ + +CLEANFILES = $(DB) + +libecore_config_la_LDFLAGS = -version-info 1:0:0 \ +-L$(top_builddir)/src/lib/ecore/.libs + +if BUILD_ECORE_CONFIG + +#DB = system.db +#$(DB): Makefile +# edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /e/theme/name str "winter" +# edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /e/font/path str "$(pkgdatadir)/data/fonts" +# edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /apps/web/browser str `which firefox 2>/dev/null || which phoenix 2>/dev/null || which mozilla 2>/dev/null || which opera 2>/dev/null || which konqueror 2>/dev/null || which epiphany 2>/dev/null` +# edb_ed $(top_builddir)/src/lib/ecore_config/$(DB) add /apps/web/email str `which thunderbird 2>/dev/null || which mozilla 2>/dev/null || which kmail 2>/dev/null || which sylpheed 2>/dev/null || which evolution 2>/dev/null` + +lib_LTLIBRARIES = libecore_config.la +include_HEADERS = \ +Ecore_Config.h + +#config_DATA = $(DB) +#configdir = $(pkgdatadir) + +libecore_config_la_SOURCES = \ +ecore_config.c \ +ecore_config_ipc_main.c \ +ecore_config_ipc_ecore.c \ +ecore_config_util.c \ +ecore_config_storage.c \ +ecore_config_extra.c \ +ecore_config_db.c \ +ecore_config_private.h + +libecore_config_la_LIBADD = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(top_builddir)/src/lib/ecore_ipc/libecore_ipc.la \ +@eet_libs@ \ +@evas_libs@ + +libecore_config_la_DEPENDENCIES = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(top_builddir)/src/lib/ecore_ipc/libecore_ipc.la + + +endif + +EXTRA_DIST = \ +Ecore_Config.h \ +ecore_config.c \ +ecore_config_ipc_ecore.c \ +ecore_config_ipc_main.c \ +ecore_config_ipc.h \ +ecore_config_util.c \ +ecore_config_util.h \ +ecore_config_storage.c + diff --git a/ecore/src/lib/ecore_config/ecore_config.c b/ecore/src/lib/ecore_config/ecore_config.c new file mode 100644 index 0000000..df6ea43 --- /dev/null +++ b/ecore/src/lib/ecore_config/ecore_config.c @@ -0,0 +1,1623 @@ +#include "Ecore_Config.h" +#include "config.h" +#include "ecore_config_private.h" +#include "ecore_config_ipc.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "ecore_config_util.h" + +int DEBUG = 0; +Ecore_Config_Server *__ecore_config_server_global = NULL; +Ecore_Config_Server *__ecore_config_server_local = NULL; +Ecore_Config_Bundle *__ecore_config_bundle_local = NULL; +char *__ecore_config_app_name = NULL; +int __ecore_config_system_init = 0; + +static int _ecore_config_system_init_no_load(void); +static int _ecore_config_system_load(void); + +static const char *_ecore_config_type[] = + { "undefined", "integer", "float", "string", "colour", "theme", "boolean" }; + +/** + * @defgroup Ecore_Config_Property_Group Ecore Config Property Functions + * + * Functions that retrieve or set the attributes relating to a property. + */ + +/** + * Removes the given property from the local configuration and destroys it. + * @param e Property to destroy. + * @return @c NULL + * @ingroup Ecore_Config_Property_Group + */ +Ecore_Config_Prop * +ecore_config_dst(Ecore_Config_Prop * e) +{ + Ecore_Config_Bundle *t; + Ecore_Config_Prop *p, *c; + Ecore_Config_Listener_List *l; + + p = NULL; + c = e; + t = __ecore_config_bundle_local; + + if (!e || !e->key) + return NULL; + if (t) + { + if (t->data == e) + t->data = e->next; + else + { + do + { + p = c; + c = c->next; + } + while (c && (c != e)); + if (c) /* remove from list if even in there */ + p->next = c->next; + } + } + + while (e->listeners) + { + l = e->listeners; + e->listeners = e->listeners->next; + free(l); + } + + if (e->key) + free(e->key); + if (e->ptr && (e->type == PT_STR)) + free(e->ptr); + + memset(e, 0, sizeof(Ecore_Config_Prop)); + free(e); + + return NULL; +} + +/** + * @defgroup Ecore_Config_Get_Group Configuration Retrieve Functions + * + * Functions that retrieve configuration values, based on type. + */ + +/** + * Returns the property with the given key. + * @param key The unique name of the wanted property. + * @return The property that corresponds to the given key. @c NULL if the + * key could not be found. + * @ingroup Ecore_Config_Get_Group + */ +Ecore_Config_Prop * +ecore_config_get(const char *key) +{ + Ecore_Config_Bundle *t; + Ecore_Config_Prop *e; + + t = __ecore_config_bundle_local; + if (!t || !key) + return NULL; + e = t->data; + while (e) + { + if (!strcmp(key, e->key)) + return e; + e = e->next; + } + return NULL; +} + +/** + * Returns the type of the property. + * @param e Property to get the type of. + * @returns The type of the property. If the property is invalid, then the + * string "not found" is returned. + * @ingroup Ecore_Config_Property_Group + */ +const char * +ecore_config_type_get(const Ecore_Config_Prop * e) +{ + if (e) + { + return _ecore_config_type[e->type]; + } + return "not found"; +} + +/** + * Obtains the data pointed to by the specified property. + * @param key The property key. + * @return Data pointer used by the property. + * @ingroup Ecore_Config_Get_Group + */ +void * +ecore_config_data_get(const char *key) +{ + Ecore_Config_Prop *e; + + e = ecore_config_get(key); + return (e ? ((e->type == PT_STR) ? ((void *)&e->ptr) : ((void *)&e->val)) + : NULL); +} + +/** + * Returns the specified property as a string. + * @param key The property key. + * @return The string value of the property. The function returns @c NULL if + * the property is not a string or is not set. + * @ingroup Ecore_Config_Get_Group + */ +char * +ecore_config_string_get(const char *key) +{ + Ecore_Config_Prop *e; + + e = ecore_config_get(key); + return (e && (e->type == PT_STR)) ? strdup(e->ptr) : NULL; +} + +/** + * Returns the specified property as an integer. + * @param key The property key. + * @return The value of the property. The function returns -1 if the + * property is not an integer or is not set. + * @ingroup Ecore_Config_Get_Group + */ +int +ecore_config_boolean_get(const char *key) +{ + Ecore_Config_Prop *e; + + e = ecore_config_get(key); + return (e && ((e->type == PT_INT) || (e->type == PT_BLN))) ? (e->val != 0) : -1; +} + +/** + * Returns the specified property as a long integer. + * @param key The property key. + * @return The integer value of the property. The function returns 0 if the + * property is not an integer or is not set. + * @ingroup Ecore_Config_Get_Group + */ +long +ecore_config_int_get(const char *key) +{ + Ecore_Config_Prop *e; + + e = ecore_config_get(key); + return (e && ((e->type == PT_INT) || (e->type == PT_RGB))) ? e->val : 0L; +} + +/** + * Returns the specified property as a float. + * @param key The property key. + * @return The float value of the property. The function returns 0.0 if the + * property is not a float or is not set. + * @ingroup Ecore_Config_Get_Group + */ +float +ecore_config_float_get(const char *key) +{ + Ecore_Config_Prop *e; + + e = ecore_config_get(key); + return (e + && (e->type == + PT_FLT)) ? ((float)e->val / ECORE_CONFIG_FLOAT_PRECISION) : 0.0; +} + +/** + * Finds the red, green and blue values of a color property. + * @param key The property key. + * @param r A pointer to an integer to store the red value into. + * @param g A pointer to an integer to store the green value into. + * @param b A pointer to an integer to store the blue value into. + * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_FAIL + * otherwise. + * @ingroup Ecore_Config_Get_Group + * @deprecated + */ +int +ecore_config_rgb_get(const char *key, int *r, int *g, int *b) +{ + int alpha; + return ecore_config_argb_get(key, &alpha, r, g, b); +} + +/** + * Finds the alpha, red, green and blue values of a color property. + * @param key The property key. + * @param a A pointer to an integer to store the alpha value into. + * @param r A pointer to an integer to store the red value into. + * @param g A pointer to an integer to store the green value into. + * @param b A pointer to an integer to store the blue value into. + * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_FAIL + * otherwise. + * @ingroup Ecore_Config_Get_Group + */ +int +ecore_config_argb_get(const char *key, int *a, int *r, int *g, int *b) +{ + Ecore_Config_Prop *e; + + e = ecore_config_get(key); + + if (e && ((e->type == PT_RGB))) + { + *a = (e->val >> 24) & 0xff; + *r = (e->val >> 16) & 0xff; + *g = (e->val >> 8) & 0xff; + *b = e->val & 0xff; + return ECORE_CONFIG_ERR_SUCC; + } + return ECORE_CONFIG_ERR_FAIL; +} + +/** + * Returns a color property as a string of hexadecimal characters. + * @param key The property key. + * @return A string of hexadecimal characters in the format #rrggbb. + * @ingroup Ecore_Config_Get_Group + * @deprecated + */ +char * +ecore_config_rgbstr_get(const char *key) +{ + char *argb, *rgb; + + argb = ecore_config_argbstr_get(key); + rgb = argb + 2; + *rgb = '#'; + return rgb; +} + +/** + * Returns a color property as a string of hexadecimal characters. + * @param key The property key. + * @return A string of hexadecimal characters in the format #aarrggbb. + * @ingroup Ecore_Config_Get_Group + */ +char * +ecore_config_argbstr_get(const char *key) +{ + char *r; + + r = NULL; + esprintf(&r, "#%08x", ecore_config_int_get(key)); + return r; +} + +/** + * Returns a theme property. + * @param key The property key. + * @return The name of the theme the property refers to. The function returns + * @c NULL if the property is not a theme or is not set. + * @ingroup Ecore_Config_Get_Group + */ +char * +ecore_config_theme_get(const char *key) +{ + Ecore_Config_Prop *e; + + e = ecore_config_get(key); + return (e && (e->type == PT_THM)) ? strdup(e->ptr) : NULL; +} + +/** + * Retrieves the key as a string. + * @param key The property key. + * @return Returns a character array in the form of 'key:type=value'. @c NULL + * is returned if the property does not exist. + * @ingroup Ecore_Config_Get_Group + */ +char * +ecore_config_as_string_get(const char *key) +{ + Ecore_Config_Prop *e; + char *r; + + r = NULL; + if (!(e = ecore_config_get(key))) + E(0, "no such property, \"%s\"...\n", key); + else + { + const char *type = ecore_config_type_get(e); + + switch (e->type) + { + case PT_NIL: + esprintf(&r, "%s:%s=", key, type); + break; + case PT_INT: + esprintf(&r, "%s:%s=%ld", key, type, ecore_config_int_get(key)); + break; + case PT_BLN: + esprintf(&r, "%s:%s=%ld", key, type, ecore_config_boolean_get(key)); + break; + case PT_FLT: + esprintf(&r, "%s:%s=%lf", key, type, ecore_config_float_get(key)); + break; + case PT_STR: + esprintf(&r, "%s:%s=\"%s\"", key, type, + ecore_config_string_get(key)); + break; + case PT_RGB: + esprintf(&r, "%s:%s=#%08x", key, type, ecore_config_int_get(key)); + break; + case PT_THM: + esprintf(&r, "%s:%s=\"%s\"", key, type, + ecore_config_theme_get(key)); + break; + default: + esprintf(&r, "%s:unknown_type", key); + break; + } + } + return r; +} + +int +ecore_config_bound(Ecore_Config_Prop * e) +{ + int ret; + long v; + + ret = ECORE_CONFIG_ERR_SUCC; + + if (!e) + return ECORE_CONFIG_ERR_FAIL; + if (e->flags & PF_BOUNDS) + { + if ((e->val < e->lo)) + { + E(0, + "ecore_config_bounds(\"%s\",%ld): value out of range; adjusted to %ld...\n", + e->key, e->val, e->lo); + e->val = e->lo; + } + else if ((e->val > e->hi)) + { + E(0, + "ecore_config_bounds(\"%s\",%ld): value out of range; adjusted to %ld...\n", + e->key, e->val, e->hi); + e->val = e->hi; + } + else + ret = ECORE_CONFIG_ERR_IGNORED; + } + else + ret = ECORE_CONFIG_ERR_IGNORED; + + if (e->step) + { + v = ((int)(e->val / e->step)) * e->step; + if (v != e->val) + { + if (e->type == PT_FLT) + E(0, + "ecore_config_bound(\"%s\"): float value %f not a multiple of %f, adjusted to %f...\n", + e->key, ((double)e->val) / ECORE_CONFIG_FLOAT_PRECISION, + ((double)e->step) / ECORE_CONFIG_FLOAT_PRECISION, + ((double)v) / ECORE_CONFIG_FLOAT_PRECISION); + else + E(0, + "ecore_config_bound(\"%s\"): integer value %ld not a multiple of %ld, adjusted to %ld...\n", + e->key, e->val, e->step, v); + ret = ECORE_CONFIG_ERR_SUCC; + e->val = v; + } + } + + return ret; +} + +/** + * Tries to guess the type of a property. + * + * This function first checks to see if the property exists. If it does, then + * the type of the stored property is returned. Otherwise, the function tries + * to guess the type of the property based on @p val. + * + * @param key The property key. + * @param val The value in string form. + * @return The type of the property determined by the function. Note that if + * val is @c NULL, @c PT_NIL will be returned. + */ +int +ecore_config_type_guess(const char *key, const char *val) +{ + Ecore_Config_Prop *p; + char *l; + long v; + + l = NULL; + + if ((p = ecore_config_get(key)) && p->type != PT_NIL) + return p->type; + + if (!val) + return PT_NIL; + if (val[0] == '#') + return PT_RGB; + v = strtol(val, &l, 10); + if (*l) + { + float f; + + if (sscanf(val, "%f%*s", &f) != 1) + return PT_STR; + return PT_FLT; + } + return PT_INT; +} + +static int +ecore_config_typed_val(Ecore_Config_Prop * e, const void *val, int type) +{ + char *l; + long v; + int *i; + float *f; + + l = NULL; + v = 0; + + if (!(val)) + e->ptr = NULL; + else + { + if (type == PT_INT) + { + i = (int *)val; + e->val = (long)*i; + e->type = PT_INT; + } + else if (type == PT_BLN ) + { + i = (int *)val; + e->val = (long)*i; + e->type = PT_BLN; + } + else if (type == PT_STR || type == PT_THM) + { + if (!(e->ptr = strdup(val))) + return ECORE_CONFIG_ERR_OOM; + if (e->type == PT_NIL) + e->type = type; + } + else if (type == PT_RGB) + { + if (((char *)val)[0] == '#') + { + if ((v = strtol(&((char *)val)[1], &l, 16)) < 0) + { + v = 0; + E(0, + "ecore_config_val: key \"%s\" -- hexadecimal value less than zero, bound to zero...\n", + (char *)val); + l = (char *)val; + } + } + else + { + E(0, + "ecore_config_val: key \"%s\" -- value \"%s\" not a valid hexadecimal RGB value?\n", + e->key, (char *)val); + return ECORE_CONFIG_ERR_FAIL; + } + if (*l) + E(0, + "ecore_config_val: key \"%s\" -- value \"%s\" not a valid hexadecimal RGB value?\n", + e->key, (char *)val); + else + { + e->val = v; + e->type = PT_RGB; + } + } + else if (type == PT_FLT) + { + f = (float *)val; + e->val = (long)((*f) * ECORE_CONFIG_FLOAT_PRECISION); + e->type = PT_FLT; + } + else + e->type = PT_NIL; + + ecore_config_bound(e); + e->flags |= PF_MODIFIED; + e->flags = e->flags & ~PF_CMDLN; + return ECORE_CONFIG_ERR_SUCC; + } + return ECORE_CONFIG_ERR_IGNORED; +} + +static int +ecore_config_typed_add(const char *key, const void *val, int type) +{ + int error = ECORE_CONFIG_ERR_SUCC; + Ecore_Config_Prop *e; + Ecore_Config_Bundle *t; + + t = __ecore_config_bundle_local; + if (!key) + return ECORE_CONFIG_ERR_NODATA; + + if (!(e = malloc(sizeof(Ecore_Config_Prop)))) + goto ret; + memset(e, 0, sizeof(Ecore_Config_Prop)); + + if (!(e->key = strdup(key))) + { + error = ECORE_CONFIG_ERR_OOM; + goto ret_free_nte; + } + + if ((error = ecore_config_typed_val(e, val, type) != ECORE_CONFIG_ERR_SUCC)) + goto ret_free_key; + + e->next = t ? t->data : NULL; + if (t) + { + t->data = e; + return ECORE_CONFIG_ERR_SUCC; + } + + ret_free_key: + free(e->key); + ret_free_nte: + free(e); + ret: + if (error == ECORE_CONFIG_ERR_SUCC) + error = ECORE_CONFIG_ERR_FAIL; + return error; +} + +static int +ecore_config_add(const char *key, const char *val) +{ + int type; + + type = ecore_config_type_guess(key, val); + return ecore_config_typed_add(key, val, type); +} + +/** + * Sets the description field of the indicated property. + * @param key The property key. + * @param desc Description string. + * @note The description string is copied for the property's use. You can + * free @p desc once this function is called. + * @ingroup Ecore_Config_Property_Group + */ +int +ecore_config_describe(const char *key, char *desc) +{ + Ecore_Config_Prop *e; + + if (!(e = ecore_config_get(key))) + return ECORE_CONFIG_ERR_NODATA; + e->description = strdup(desc); + return ECORE_CONFIG_ERR_SUCC; +} + +/** + * Set the short option character of a property. + * @param key The property key. + * @param short_opt Character used to indicate the value of a property + * given on the command line. + * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA + * is returned if the property does not exist. + * @ingroup Ecore_Config_Property_Group + */ +int +ecore_config_short_opt_set(const char *key, char short_opt) +{ + Ecore_Config_Prop *e; + + if (!(e = ecore_config_get(key))) + return ECORE_CONFIG_ERR_NODATA; + e->short_opt = short_opt; + return ECORE_CONFIG_ERR_SUCC; +} + +/** + * Set the long option string of the property. + * @param key The property key. + * @param long_opt String used to indicate the value of a property given + * on the command line. + * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA + * is returned if the property does not exist. + * @ingroup Ecore_Config_Property_Group + */ +int +ecore_config_long_opt_set(const char *key, char *long_opt) +{ + Ecore_Config_Prop *e; + + if (!(e = ecore_config_get(key))) + return ECORE_CONFIG_ERR_NODATA; + if (e->long_opt) + free(e->long_opt); + if (long_opt) + e->long_opt = strdup(long_opt); + return ECORE_CONFIG_ERR_SUCC; +} + +/** + * Sets the indicated property to the given value and type. + * @param key The property key. + * @param val A pointer to the value to set the property to. + * @param type The type of the property. + * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. + * @ingroup Ecore_Config_Property_Group + */ +int +ecore_config_typed_set(const char *key, const void *val, int type) +{ + Ecore_Config_Prop *e; + Ecore_Config_Listener_List *l; + int ret; + + if (!key) + return ECORE_CONFIG_ERR_NODATA; +/* if (!t) { * global prop * + e=ecore_config_get(key); + if (e) + for(l=e->listeners;l;l=l->next) + l->listener(e->key,e->type,l->tag,l->data,t); + return ECORE_CONFIG_ERR_SUCC; + } +*/ + if (!(e = ecore_config_get(key))) + return ecore_config_typed_add(key, val, type); + + if ((ret = ecore_config_typed_val(e, val, type)) == ECORE_CONFIG_ERR_SUCC) + { + for (l = e->listeners; l; l = l->next) + l->listener(e->key, e->type, l->tag, l->data); + } + else + { + E(0, + "ecore_config_typed_set(\"%s\"): ecore_config_typed_val() failed: %d\n", + key, ret); + } + + return ret; +} + +/** + * @defgroup Ecore_Config_Set_Group Ecore Config Setters + * + * Functions that set the value of a property. + */ + +/** + * Sets the indicated property to the value indicated by @a val. + * @param key The property key. + * @param val String representation of value to set. + * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. + * @ingroup Ecore_Config_Set_Group + */ +int +ecore_config_set(const char *key, char *val) +{ + int type; + int tmpi; + float tmpf; + + type = ecore_config_type_guess(key, val); + if (type == PT_INT || type == PT_BLN) + { + tmpi = atoi(val); + return ecore_config_typed_set(key, (void *)&tmpi, type); + } + else if (type == PT_FLT) + { + tmpf = atof(val); + return ecore_config_typed_set(key, (void *)&tmpf, type); + } + else + return ecore_config_typed_set(key, (void *)val, type); +} + +/** + * Sets the indicated property to the value given in the string. + * @param key The property key. + * @param val String representation of the value. + * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. + * @ingroup Ecore_Config_Set_Group + */ +int +ecore_config_as_string_set(const char *key, char *val) +{ + return ecore_config_set(key, val); +} + +/** + * Sets the indicated property to the given boolean. + * @param key The property key. + * @param val Boolean integer to set the property to. + * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. + * @ingroup Ecore_Config_Set_Group + */ +int +ecore_config_boolean_set(const char *key, int val) +{ + val = val ? 1 : 0; + return ecore_config_typed_set(key, (void *)&val, PT_BLN); +} + +/** + * Sets the indicated property to the given integer. + * @param key The property key. + * @param val Integer to set the property to. + * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. + * @ingroup Ecore_Config_Set_Group + */ +int +ecore_config_int_set(const char *key, int val) +{ + return ecore_config_typed_set(key, (void *)&val, PT_INT); +} + +/** + * Sets the indicated property to the given string. + * @param key The property key. + * @param val String to set the property to. + * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. + * @ingroup Ecore_Config_Set_Group + */ +int +ecore_config_string_set(const char *key, char *val) +{ + return ecore_config_typed_set(key, (void *)val, PT_STR); +} + +/** + * Sets the indicated property to the given float value. + * @param key The property key. + * @param val Float to set the property to. + * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. + * @ingroup Ecore_Config_Set_Group + */ +int +ecore_config_float_set(const char *key, float val) +{ + return ecore_config_typed_set(key, (void *)&val, PT_FLT); +} + +char * +ecore_config_rgb_to_argb(char *rgb) +{ + char *argb; + + argb = malloc(strlen(rgb) + 2); + strncpy(argb, "#ff", 3); + strncat(argb, rgb+1, strlen(rgb - 1)); + return argb; +} + +/** + * Sets the indicated property to a color value. + * @param key The property key + * @param val Color value in RGB format. + * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. + * @ingroup Ecore_Config_Set_Group + * @deprecated + */ +int +ecore_config_rgb_set(const char *key, char *val) +{ + char *argb; + int ret; + + argb = ecore_config_rgb_to_argb(val); + ret = ecore_config_argb_set(key, argb); + free(argb); + return ret; +} + +/** + * Sets the indicated property to a color value. + * @param key The property key + * @param val Color value in ARGB format. + * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. + * @ingroup Ecore_Config_Set_Group + */ +int +ecore_config_argb_set(const char *key, char *val) +{ + return ecore_config_typed_set(key, (void *)val, PT_RGB); +} + +/** + * Sets the indicated property to a theme name. + * @param key The property key. + * @param val String giving the name of the theme. + * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. + * @ingroup Ecore_Config_Set_Group + */ +int +ecore_config_theme_set(const char *key, char *val) +{ + return ecore_config_typed_set(key, (void *)val, PT_THM); +} + +/** + * Sets the theme preview group of an indicated property. + * @param key The property key. + * @param group The group name. + * @return @c ECORE_CONFIG_ERR_SUCC on success. + * @ingroup Ecore_Config_Set_Group + */ +int +ecore_config_theme_preview_group_set(const char *key, char *group) +{ + int ret; + Ecore_Config_Prop *e; + + ret = ECORE_CONFIG_ERR_SUCC; + if (!(e = ecore_config_get(key))) + { /* prop doesn't exist yet */ + if ((ret = ecore_config_typed_add(key, "", PT_THM)) != ECORE_CONFIG_ERR_SUCC) /* try to add it */ + return ret; /* ...failed */ + if (!(e = ecore_config_get(key))) /* get handle */ + return ECORE_CONFIG_ERR_FAIL; + } + if (e->data) + free(e->data); + e->data = strdup(group); + + return ret; +} + +int +ecore_config_typed_default(const char *key, void *val, int type) +{ + int ret; + Ecore_Config_Prop *e; + + ret = ECORE_CONFIG_ERR_SUCC; + + if (!(e = ecore_config_get(key))) + { /* prop doesn't exist yet */ + if ((ret = ecore_config_typed_add(key, val, type)) != ECORE_CONFIG_ERR_SUCC) /* try to add it */ + return ret; /* ...failed */ + if (!(e = ecore_config_get(key))) /* get handle */ + return ECORE_CONFIG_ERR_FAIL; + e->flags = e->flags & ~PF_MODIFIED; + } + else if (!(e->flags & PF_MODIFIED) && !(e->flags & PF_SYSTEM)) + { + ecore_config_typed_set(key, val, type); + if (!(e = ecore_config_get(key))) /* get handle */ + return ECORE_CONFIG_ERR_FAIL; + e->flags = e->flags & ~PF_MODIFIED; + } + return ret; +} + +/** + * @defgroup Ecore_Config_Default_Group Ecore Config Defaults + * + * Functions that are used to set the default values of properties. + */ + +/** + * Sets the indicated property if it has not already been set or loaded. + * @param key The property key. + * @param val Default value of the key. + * @param lo Lowest valid value for the key. + * @param hi Highest valid value for the key. + * @param step Used by integer and float values. + * @return @c ECORE_CONFIG_ERR_SUCC if there are no errors. + * @note The @p lo, @p hi and @p step parameters are only used when storing + * integer and float properties. + * @ingroup Ecore_Config_Default_Group + */ +int +ecore_config_default(const char *key, char *val, float lo, float hi, float step) +{ + int ret, type; + Ecore_Config_Prop *e; + + type = ecore_config_type_guess(key, val); + ret = ecore_config_typed_default(key, val, type); + e = ecore_config_get(key); + if (e) + { + if (type == PT_INT) + { + e->step = step; + e->flags |= PF_BOUNDS; + e->lo = lo; + e->hi = hi; + ecore_config_bound(e); + } + else if (type == PT_FLT) + { + e->step = (int)(step * ECORE_CONFIG_FLOAT_PRECISION); + e->flags |= PF_BOUNDS; + e->lo = (int)(lo * ECORE_CONFIG_FLOAT_PRECISION); + e->hi = (int)(hi * ECORE_CONFIG_FLOAT_PRECISION); + ecore_config_bound(e); + } + } + + return ret; +} + +/** + * Sets the indicated property to the given boolean if the property has not yet + * been set. + * @param key The property key. + * @param val Boolean Integer to set the value to. + * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems. + * @ingroup Ecore_Config_Default_Group + */ +int +ecore_config_boolean_default(const char *key, int val) +{ + val = val ? 1 : 0; + return ecore_config_typed_default(key, (void *)&val, PT_BLN); +} + +/** + * Sets the indicated property to the given integer if the property has not yet + * been set. + * @param key The property key. + * @param val Integer to set the value to. + * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems. + * @ingroup Ecore_Config_Default_Group + */ +int +ecore_config_int_default(const char *key, int val) +{ + return ecore_config_typed_default(key, (void *)&val, PT_INT); +} + +/** + * Sets the indicated property to the given integer if the property has not yet + * been set. + * + * The bounds and step values are set regardless. + * + * @param key The property key. + * @param val Integer to set the property to. + * @param low Lowest valid integer value for the property. + * @param high Highest valid integer value for the property. + * @param step Increment value for the property. + * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems. + * @ingroup Ecore_Config_Default_Group + */ +int +ecore_config_int_default_bound(const char *key, int val, int low, int high, + int step) +{ + Ecore_Config_Prop *e; + int ret; + + ret = ecore_config_typed_default(key, (void *)&val, PT_INT); + e = ecore_config_get(key); + if (e) + { + e->step = step; + e->flags |= PF_BOUNDS; + e->lo = low; + e->hi = high; + ecore_config_bound(e); + } + + return ret; +} + +/** + * Sets the indicated property to the given string if the property has not yet + * been set. + * @param key The property key. + * @param val String to set the property to. + * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems. + * @ingroup Ecore_Config_Default_Group + */ +int +ecore_config_string_default(const char *key, const char *val) +{ + return ecore_config_typed_default(key, (void *)val, PT_STR); +} + +/** + * Sets the indicated property to the given float if the property has not yet + * been set. + * @param key The property key. + * @param val Float to set the property to. + * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems. + * @ingroup Ecore_Config_Default_Group + */ +int +ecore_config_float_default(const char *key, float val) +{ + return ecore_config_typed_default(key, (void *)&val, PT_FLT); +} + +/** + * Sets the indicated property to the given float if the property has not yet + * been set. + * + * The bounds and step values are set regardless. + * + * @param key The property key. + * @param val Float to set the property to. + * @param low Lowest valid integer value for the property. + * @param high Highest valid float value for the property. + * @param step Increment value for the property. + * @return @c ECORE_CONFIG_ERR_SUCC if there were no problems. + * @ingroup Ecore_Config_Default_Group + */ +int +ecore_config_float_default_bound(const char *key, float val, float low, + float high, float step) +{ + Ecore_Config_Prop *e; + int ret; + + ret = ecore_config_typed_default(key, (void *)&val, PT_FLT); + e = ecore_config_get(key); + if (e) + { + e->step = (int)(step * ECORE_CONFIG_FLOAT_PRECISION); + e->flags |= PF_BOUNDS; + e->lo = (int)(low * ECORE_CONFIG_FLOAT_PRECISION); + e->hi = (int)(high * ECORE_CONFIG_FLOAT_PRECISION); + ecore_config_bound(e); + } + + return ret; +} + +/** + * Sets the indicated property to a color value if the property has not yet + * been set. + * @param key The property key. + * @param val Color value in RGB format. + * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems. + * @ingroup Ecore_Config_Default_Group + * @deprecated + */ +int +ecore_config_rgb_default(const char *key, char *val) +{ + char *argb; + int ret; + + argb = ecore_config_rgb_to_argb(val); + ret = ecore_config_argb_default(key, argb); + free(argb); + return ret; +} + +/** + * Sets the indicated property to a color value if the property has not yet + * been set. + * @param key The property key. + * @param val Color value in ARGB format. + * @return @c ECORE_CONFIG_ERR_SUCC if there are no problems. + * @ingroup Ecore_Config_Default_Group + */ +int +ecore_config_argb_default(const char *key, char *val) +{ + return ecore_config_typed_default(key, (void *)val, PT_RGB); +} + +/** + * Sets the indicated property to a theme name if the property has not yet + * been set. + * @param key The property key. + * @param val String giving the name of the theme. + * @return @c ECORE_CONFIG_ERR_SUCC if the property is set successfully. + * @ingroup Ecore_Config_Default_Group + */ +int +ecore_config_theme_default(const char *key, char *val) +{ + return ecore_config_typed_default(key, (void *)val, PT_THM); +} + +/** + * @defgroup Ecore_Config_Listeners_Group Ecore Config Listeners + * + * Functions that set and unset property listener callbacks. + */ + +/** + * Adds a callback function to the list of functions called when a property + * changes. + * @param name Name of the callback. + * @param key The key of the property to listen to. + * @param listener Listener callback function. + * @param tag Tag to pass to @p listener when it is called. + * @param data Data to pass to @p listener when it is called. + * @return @c ECORE_CONFIG_ERR_SUCC if successful in setting up the callback. + * @ingroup Ecore_Config_Listeners_Group + */ +int +ecore_config_listen(const char *name, const char *key, + Ecore_Config_Listener listener, int tag, void *data) +{ + Ecore_Config_Prop *e; + Ecore_Config_Listener_List *l; + + if (!key) + return ECORE_CONFIG_ERR_NODATA; + + if (!(e = ecore_config_get(key))) + { + int ret = ecore_config_add(key, ""); + + if (ret != ECORE_CONFIG_ERR_SUCC) + { + E(0, "ecore_config_listen: ecore_config_add(\"%s\") failed: %d\n", + key, ret); + return ret; + } + if (!(e = ecore_config_get(key))) + { + E(0, "ecore_config_listen: list of properties corrupted!?\n"); + return ECORE_CONFIG_ERR_FAIL; + } + } + + for (l = e->listeners; l; l = l->next) + if (!strcmp(l->name, name) || (l->listener == listener)) + { + E(1, + "ecore_config_listen: %s is already listening for changes of %s...\n", + name, key); + return ECORE_CONFIG_ERR_IGNORED; + } + + if (!(l = malloc(sizeof(Ecore_Config_Listener_List)))) + return ECORE_CONFIG_ERR_OOM; + + E(1, "registering listener \"%s\" for \"%s\" (%d)...\n", name, key, e->type); + + memset(l, 0, sizeof(Ecore_Config_Listener_List)); + + l->listener = listener; + l->name = name; + l->data = data; + l->tag = tag; + l->next = e->listeners; + e->listeners = l; + + if (e->type != PT_NIL) /* call right on creation if prop exists and has val */ + listener(key, e->type, tag, data); + + return ECORE_CONFIG_ERR_SUCC; +} + +/** + * Removes a listener callback. + * @param name Name of the callback to remove. + * @param key The property key the callback is listening to. + * @param listener The callback function to remove. + * @return @c ECORE_CONFIG_ERR_SUCC if successful in removing the callback. + * If no callback matches the given parameters, then + * @c ECORE_CONFIG_ERR_NOTFOUND is returned. If @c NULL is passed + * for the key pointer, @c ECORE_CONFIG_ERR_NODATA is returned. + * @ingroup Ecore_Config_Listeners_Group + */ +int +ecore_config_deaf(const char *name, const char *key, + Ecore_Config_Listener listener) +{ + Ecore_Config_Prop *e; + Ecore_Config_Listener_List *l, *p; + int ret; + + ret = ECORE_CONFIG_ERR_NOTFOUND; + + if (!key) + return ECORE_CONFIG_ERR_NODATA; + + if (!(e = ecore_config_get(key))) + return ECORE_CONFIG_ERR_NOTFOUND; + + for (p = NULL, l = e->listeners; l; p = l) + { + Ecore_Config_Listener_List *nl; + + nl = l->next; + if ((name && !strcmp(l->name, name)) || (l->listener == listener)) + { + ret = ECORE_CONFIG_ERR_SUCC; + if (!p) + e->listeners = e->listeners->next; + else + p->next = l->next; + memset(l, 0, sizeof(Ecore_Config_Listener)); + free(l); + } + l = nl; + } + + return ret; +} + +/** + * Locates the first configuration bundle on the given server. + * @param srv The configuration server. + * @return Pointer to the first configuration bundle. + */ +Ecore_Config_Bundle * +ecore_config_bundle_1st_get(Ecore_Config_Server * srv) +{ /* anchor: global, but read-only */ + return srv->bundles; +} + +/** + * Locates the configuration bundle after the given one. + * @param ns The configuration bundle. + * @return The next configuration bundle. + */ +Ecore_Config_Bundle * +ecore_config_bundle_next_get(Ecore_Config_Bundle * ns) +{ + return ns ? ns->next : NULL; +} + +/** + * Locates a configuration bundle on a configuration server based on its serial + * number. + * @param srv The configuration server. + * @param serial Serial number. + * @return The configuration bundle with the given serial number. + */ +Ecore_Config_Bundle * +ecore_config_bundle_by_serial_get(Ecore_Config_Server * srv, long serial) +{ + Ecore_Config_Bundle *eb; + + eb = srv->bundles; + + if (serial < 0) + return NULL; + else if (serial == 0) + { + Ecore_Config_Bundle *r = eb; + + return r; + } + + while (eb) + { + if (eb->serial == serial) + return eb; + eb = eb->next; + } + return NULL; +} + +/** + * Gets the Ecore_Config_Bundle with the given identifier from the given + * server. + * @param srv The configuration server. + * @param label The bundle's identifier string. + * @return The bundle with the given identifier string, or @c NULL if it + * could not be found. + */ +Ecore_Config_Bundle * +ecore_config_bundle_by_label_get(Ecore_Config_Server * srv, const char *label) +{ + Ecore_Config_Bundle *ns; + + ns = srv->bundles; + + while (ns) + { + if (ns->identifier && !strcmp(ns->identifier, label)) + return ns; + ns = ns->next; + } + return NULL; +} + +/** + * Retrieves the bundle's serial number. + * @param ns The configuration bundle. + * @return The bundle's identifier string, or -1 if ns is @c NULL. + */ +long +ecore_config_bundle_serial_get(Ecore_Config_Bundle * ns) +{ + return ns ? ns->serial : -1; +} + +/** + * Retrieves the bundle's identifier. + * @param ns The configuration bundle. + * @return The bundle's identifer string. + */ +char * +ecore_config_bundle_label_get(Ecore_Config_Bundle * ns) +{ + return ns ? ns->identifier : NULL; +} + +/** + * Creates a new Ecore_Config_Bundle. + * @param srv Config server. + * @param identifier Identifier string for the new bundle. + * @return A pointer to a new Ecore_Config_Bundle. @c NULL is returned if the + * structure couldn't be allocated. + */ +Ecore_Config_Bundle * +ecore_config_bundle_new(Ecore_Config_Server * srv, const char *identifier) +{ + Ecore_Config_Bundle *t; + static long ss; + + ss = 0; /* bundle unique serial */ + + if ((t = malloc(sizeof(Ecore_Config_Bundle)))) + { + memset(t, 0, sizeof(Ecore_Config_Bundle)); + + t->identifier = (char *)identifier; + t->serial = ++ss; + t->owner = srv->name; + t->next = srv->bundles; + srv->bundles = t; + } + return t; +} + +static Ecore_Config_Server * +do_init(const char *name) +{ + return _ecore_config_ipc_init(name); +} + +static Ecore_Config_Server * +ecore_config_init_local(const char *name) +{ + char *p; + char *buf; + + if ((p = getenv("HOME"))) + { /* debug-only ### FIXME */ + if (!(buf = malloc(PATH_MAX * sizeof(char)))) + return NULL; + snprintf(buf, PATH_MAX, "%s/.ecore/%s/.global", p, name); + unlink(buf); + + free(buf); + } + + return do_init(name); +} + +static Ecore_Config_Server * +ecore_config_init_global(const char *name) +{ + char *p; + int global; + char *buf; + global = 0; + + if ((p = getenv("HOME"))) + { /* debug-only ### FIXME */ + if (!(buf = malloc(PATH_MAX * sizeof(char)))) + return NULL; + snprintf(buf, PATH_MAX, "%s/.ecore/%s/.global", p, name); + global = creat(buf, S_IRWXU); + + if (global) + close(global); + + free(buf); + } + + return do_init(name); +} + +/** + * @defgroup Ecore_Config_App_Lib_Group Ecore Config App Library Functions + * + * Functions that are used to start up and shutdown the Enlightened + * Property Library when used directly by an application. + */ + +/** + * Initializes the Enlightened Property Library. + * + * Either this function or @ref ecore_config_system_init must be run + * before any other function in the Enlightened Property Library, even + * if you have run @ref ecore_init . The name given is used to + * determine the default configuration to load. + * + * @param name Application name + * @return @c ECORE_CONFIG_ERR_SUCC if the library is successfully set up. + * @c ECORE_CONFIG_ERR_FAIL otherwise. + * @ingroup Ecore_Config_App_Lib_Group + */ +int +ecore_config_init(const char *name) +{ + char *path; + Ecore_Config_Prop *list; + Ecore_Config_Bundle *temp; + _ecore_config_system_init_no_load(); + + __ecore_config_app_name = strdup(name); + __ecore_config_server_local = ecore_config_init_local(name); + if (!__ecore_config_server_local) + return ECORE_CONFIG_ERR_FAIL; + + temp = __ecore_config_bundle_local; + list = __ecore_config_bundle_local->data; + __ecore_config_bundle_local = + ecore_config_bundle_new(__ecore_config_server_local, "config"); + __ecore_config_bundle_local->data = list; + free(temp); + + path = ecore_config_theme_default_path_get(); + ecore_config_string_default("/e/themes/search_path", path); + if (path) + free(path); + + list = ecore_config_get("/e/themes/search_path"); + if (list) + { + list->flags |= PF_SYSTEM; + list->flags &= ~PF_MODIFIED; + } + + return _ecore_config_system_load(); +} + +/** + * Frees memory and shuts down the library for an application. + * @return @c ECORE_CONFIG_ERR_IGNORED . + * @ingroup Ecore_Config_App_Lib_Group + */ +int +ecore_config_shutdown(void) +{ + return ecore_config_system_shutdown(); +} + +/** + * @defgroup Ecore_Config_Lib_Lib_Group Ecore Config Library Functions + * + * Functions that are used to start up and shutdown the Enlightened + * Property Library when used directly by an application. + */ + +/** + * Initializes the Enlightened Property Library. + * + * This function is meant to be run from other programming libraries. + * It should not be called from applications. + * + * This function (or @ref ecore_config_init ) + * must be run before any other function in the + * Enlightened Property Library, even if you have run @ref ecore_init . + * + * @return @c ECORE_CONFIG_ERR_SUCC if the library is successfully set up. + * @c ECORE_CONFIG_ERR_FAIL otherwise. + * @ingroup Ecore_Config_Lib_Lib_Group + */ +int +ecore_config_system_init(void) +{ + _ecore_config_system_init_no_load(); + return _ecore_config_system_load(); +} + +static int +_ecore_config_system_init_no_load(void) +{ + char *p; + + __ecore_config_system_init++; + if (__ecore_config_system_init > 1) + return ECORE_CONFIG_ERR_IGNORED; + + DEBUG = -1; + if ((p = getenv("ECORE_CONFIG_DEBUG")) && strlen(p) > 0) + { + DEBUG = atoi(p); + } + + __ecore_config_server_global = + ecore_config_init_global(ECORE_CONFIG_GLOBAL_ID); + if (!__ecore_config_server_global) + return ECORE_CONFIG_ERR_FAIL; + + __ecore_config_bundle_local = + ecore_config_bundle_new(__ecore_config_server_global, "system"); + + /* set up a simple default path */ + ecore_config_string_default("/e/themes/search_path", PACKAGE_DATA_DIR "../ewl/themes"); + + return ECORE_CONFIG_ERR_SUCC; +} + + +static int +_ecore_config_system_load(void) +{ + char *buf, *p; + Ecore_Config_Prop *sys; + + if (__ecore_config_system_init != 1) + return ECORE_CONFIG_ERR_FAIL; + + if ((p = getenv("HOME"))) + { /* debug-only ### FIXME */ + if ((buf = malloc(PATH_MAX * sizeof(char)))) + { + snprintf(buf, PATH_MAX, "%s/.e/config.eet", p); + if (ecore_config_file_load(buf) != 0) { + /* even if this file (system.eet) dosen't exist we can + * continue without it as it isn't striclty necessary. + */ + ecore_config_file_load(PACKAGE_DATA_DIR "/system.eet"); + } + sys = __ecore_config_bundle_local->data; + while (sys) + { + /* unmark it modified - modification will mean it has been overridden */ + sys->flags &= ~PF_MODIFIED; + /* mark as system so that examine can hide them */ + sys->flags |= PF_SYSTEM; + sys = sys->next; + } + } + free(buf); + } + + return ECORE_CONFIG_ERR_SUCC; +} + + +/** + * Frees memory and shuts down the library for other programming libraries. + * @return @c ECORE_CONFIG_ERR_IGNORED + * @ingroup Ecore_Config_Lib_Lib_Group + */ +int +ecore_config_system_shutdown(void) +{ + int ret; + + __ecore_config_system_init--; + if (__ecore_config_system_init > 0) + return ECORE_CONFIG_ERR_IGNORED; + + ret = _ecore_config_ipc_exit(); + if (__ecore_config_app_name) + free(__ecore_config_app_name); + free(__ecore_config_bundle_local); + free(__ecore_config_server_local); + free(__ecore_config_server_global); + return ret; +} + diff --git a/ecore/src/lib/ecore_config/ecore_config_db.c b/ecore/src/lib/ecore_config/ecore_config_db.c new file mode 100644 index 0000000..59e673b --- /dev/null +++ b/ecore/src/lib/ecore_config/ecore_config_db.c @@ -0,0 +1,286 @@ +#include "Ecore_Config.h" +#include "ecore_config_private.h" +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +struct _Ecore_Config_DB_File +{ + Eet_File *ef; +}; + +Ecore_Config_DB_File * +_ecore_config_db_open_read(const char *file) +{ + Eet_File *ef; + Ecore_Config_DB_File *db; + + eet_init(); + db = malloc(sizeof(Ecore_Config_DB_File)); + if (!db) return NULL; + ef = eet_open((char*)file, EET_FILE_MODE_READ); + if (!ef) + { + free(db); + return NULL; + } + db->ef = ef; + return db; +} + +Ecore_Config_DB_File * +_ecore_config_db_open_write(const char *file) +{ + Eet_File *ef; + Ecore_Config_DB_File *db; + + eet_init(); + db = malloc(sizeof(Ecore_Config_DB_File)); + if (!db) return NULL; + ef = eet_open((char*)file, EET_FILE_MODE_WRITE); + if (!ef) + { + free(db); + return NULL; + } + db->ef = ef; + return db; +} + +void +_ecore_config_db_close(Ecore_Config_DB_File *db) +{ + eet_close(db->ef); + free(db); + eet_shutdown(); +} + +char ** +_ecore_config_db_keys_get(Ecore_Config_DB_File *db, int *num_ret) +{ + char **keys; + int key_count; + int i; + + keys = eet_list(db->ef, (char*)"*", &key_count); + if (!keys) + { + *num_ret = 0; + return NULL; + } + /* make keys freeable - this is safe to do */ + for (i = 0; i < key_count; i++) keys[i] = strdup(keys[i]); + *num_ret = key_count; + return keys; +} + +Ecore_Config_Type +_ecore_config_db_key_type_get(Ecore_Config_DB_File *db, const char *key) +{ + char *data; + int size; + + data = eet_read(db->ef, (char*)key, &size); + if (data) + { + if (size <= 2) + { + free(data); + return PT_NIL; + } + if (data[size - 1] != 0) + { + free(data); + return PT_NIL; + } + return (Ecore_Config_Type) data[0]; + } + return PT_NIL; +} + +int +_ecore_config_db_read(Ecore_Config_DB_File *db, const char *key) +{ + char *data, *value; + int size; + Ecore_Config_Prop *prop; + Ecore_Config_Type type; + + data = eet_read(db->ef, (char*)key, &size); + if (data) + { + int l; + char *prev_locale; + + if (size <= 2) + { + free(data); + return 0; + } + if (data[size - 1] != 0) + { + free(data); + return 0; + } + /* "type" NIL 1242 NIL */ + l = strlen(data); + if (l >= (size - 1)) + { + free(data); + return 0; + } + + type = data[0]; + value = data + l + 1; + prop = ecore_config_get(key); + + switch (type) + { + case PT_INT: + case PT_BLN: + { + int tmp; + prev_locale = setlocale(LC_NUMERIC, "C"); + tmp = atoi(value); + if (prev_locale) setlocale(LC_NUMERIC, prev_locale); + + ecore_config_typed_set(key, (void *)&tmp, type); + break; + } + case PT_FLT: + { + float tmp; + prev_locale = setlocale(LC_NUMERIC, "C"); + tmp = atof(value); + if (prev_locale) setlocale(LC_NUMERIC, prev_locale); + + ecore_config_typed_set(key, (void *)&tmp, type); + break; + } + case PT_STR: + case PT_RGB: + case PT_THM: + ecore_config_typed_set(key, (void *)value, type); + break; + default: + E(0, "Type %d not handled\n", type); + } + free(data); + return 1; + } + return 0; +} + +/* +void * +_ecore_config_db_key_data_get(Ecore_Config_DB_File *db, const char *key, int *size_ret) +{ + char *data; + int size; + + data = eet_read(db->ef, (char*)key, &size); + if (data) + { + int l; + char *dat; + + if (size <= 2) + { + free(data); + return NULL; + } + if (data[size - 1] != 0) + { + free(data); + return NULL; + } + * "type" NIL data_goes_here NIL * + l = strlen(data); + if (l >= (size - 1)) + { + free(data); + return NULL; + } + dat = malloc(size - (l + 2)); + memcpy(dat, data + l + 1, size - (l + 2)); + free(data); + *size_ret = size - (l + 2); + return dat; + } + return NULL; +}*/ + +void +_ecore_config_db_write(Ecore_Config_DB_File *db, const char *key) +{ + char buf[256]; + int num; + char *prev_locale; + // Ecore_Config_Prop *prop; + Ecore_Config_Type type; + + + type = ecore_config_get(key)->type; + prev_locale = setlocale(LC_NUMERIC, "C"); + + switch (type) + { + case PT_INT: + num = snprintf(buf, sizeof(buf), "%c %i ", (char) type, + (int) ecore_config_int_get(key)); + break; + case PT_BLN: + num = snprintf(buf, sizeof(buf), "%c %i ", (char) type, + (int) ecore_config_int_get(key)); + break; + case PT_FLT: + num = snprintf(buf, sizeof(buf), "%c %16.16f ", (char) type, + ecore_config_float_get(key)); + break; + case PT_STR: + num = snprintf(buf, sizeof(buf), "%c %s ", (char) type, + ecore_config_string_get(key)); + break; + case PT_THM: + num = snprintf(buf, sizeof(buf), "%c %s ", (char) type, + ecore_config_theme_get(key)); + break; + case PT_RGB: + num = snprintf(buf, sizeof(buf), "%c %s ", (char) type, + ecore_config_argbstr_get(key)); + break; + default: + E(0, "Type %d not handled\n", type); + } + + if (prev_locale) setlocale(LC_NUMERIC, prev_locale); + buf[1] = 0; + buf[num - 1] = 0; + eet_write(db->ef, (char*)key, buf, num, 1); +} +/* +void +_ecore_config_db_key_data_set(Ecore_Config_DB_File *db, const char *key, void *data, int data_size) +{ + char *buf; + int num; + + num = 1 + 1 + data_size + 1; + buf = malloc(num); + if (!buf) return; + buf[0] = (char) PT_BIN; + buf[1] = 0; + memcpy(buf + 2, data, data_size); + buf[num - 1] = 0; + eet_write(db->ef, (char*)key, buf, num, 1); + free(buf); +}*/ diff --git a/ecore/src/lib/ecore_config/ecore_config_extra.c b/ecore/src/lib/ecore_config/ecore_config_extra.c new file mode 100644 index 0000000..bdc8b8c --- /dev/null +++ b/ecore/src/lib/ecore_config/ecore_config_extra.c @@ -0,0 +1,828 @@ +#include "Ecore_Config.h" +#include "Ecore.h" + +#include "config.h" + +#include +#include +#include + +#include +#include + +typedef struct __Ecore_Config_Arg_Callback _Ecore_Config_Arg_Callback; +struct __Ecore_Config_Arg_Callback +{ + char short_opt; + char *long_opt; + char *description; + void *data; + void (*func)(char *val, void *data); + Ecore_Config_Type type; + _Ecore_Config_Arg_Callback *next; +}; + +char *__ecore_config_app_description; +_Ecore_Config_Arg_Callback *_ecore_config_arg_callbacks; + +/* shorthand prop setup code to make client apps a little smaller ;) */ + +/** + * Creates a new property, if it does not already exist, and sets its + * attributes to those given. + * + * The type of the property is guessed from the key and the value + * given. + * + * @param key The property key. + * @param val Pointer to default value of key. + * @param short_opt Short option used to set the property from command + * line. + * @param long_opt Long option used to set the property from command line. + * @param desc String description of property. + * @return @c ECORE_CONFIG_ERR_SUCC on success. + * @ingroup Ecore_Config_Create_Group + */ +int +ecore_config_create(const char *key, void *val, char short_opt, char *long_opt, + char *desc) +{ + int type = ecore_config_type_guess(key, val); + + return ecore_config_typed_create(key, val, type, short_opt, long_opt, desc); +} + +/** + * Creates a new property, if it does not already exist, and sets its + * attributes to those given. + * @param key The property key. + * @param val Pointer to default value of key. + * @param type Type of the property. + * @param short_opt Short option used to set the property from + * command line. + * @param long_opt Long option used to set the property from command line. + * @param desc String description of property. + * @return @c ECORE_CONFIG_ERR_SUCC on success. + * @ingroup Ecore_Config_Create_Group + */ +int +ecore_config_typed_create(const char *key, void *val, int type, char short_opt, + char *long_opt, char *desc) +{ + int ret; + + if ((ret = + ecore_config_typed_default(key, val, type)) != ECORE_CONFIG_ERR_SUCC) + return ret; + if ((ret = + ecore_config_short_opt_set(key, short_opt)) != ECORE_CONFIG_ERR_SUCC) + return ret; + if ((ret = + ecore_config_long_opt_set(key, long_opt)) != ECORE_CONFIG_ERR_SUCC) + return ret; + ret = ecore_config_describe(key, desc); + return ret; +} + +/** + * Creates a new boolean property, if it does not already exist, and sets its + * attributes to those given. + * @param key The property key. + * @param val Default boolean value of key. + * @param short_opt Short option used to set the property from command + * line. + * @param long_opt Long option used to set the property from command line. + * @param desc String description of property. + * @return @c ECORE_CONFIG_ERR_SUCC on success. + * @ingroup Ecore_Config_Create_Group + */ +int +ecore_config_boolean_create(const char *key, int val, char short_opt, + char *long_opt, char *desc) +{ + return + ecore_config_typed_create(key, (void *)&val, PT_BLN, short_opt, long_opt, + desc); +} + +/** + * Creates a new integer property, if it does not already exist, and sets its + * attributes to those given. + * @param key The property key. + * @param val Default integer value of key. + * @param short_opt Short option used to set the property from command + * line. + * @param long_opt Long option used to set the property from command line. + * @param desc String description of property. + * @return @c ECORE_CONFIG_ERR_SUCC on success. + * @ingroup Ecore_Config_Create_Group + */ +int +ecore_config_int_create(const char *key, int val, char short_opt, + char *long_opt, char *desc) +{ + return + ecore_config_typed_create(key, (void *)&val, PT_INT, short_opt, long_opt, + desc); +} + +/** + * Creates a new integer property, if it does not already exist, and sets its + * attributes to those given. + * @param key The property key. + * @param val Default integer value of key. + * @param low Lowest valid integer value for the property. + * @param high Highest valid integer value for the property. + * @param step Increment value for the property. + * @param short_opt Short option used to set the property from command + * line. + * @param long_opt Long option used to set the property from command line. + * @param desc String description of property. + * @return @c ECORE_CONFIG_ERR_SUCC on success. + * @ingroup Ecore_Config_Create_Group + */ +int +ecore_config_int_create_bound(const char *key, int val, int low, int high, + int step, char short_opt, char *long_opt, + char *desc) +{ + Ecore_Config_Prop *e; + int ret; + + ret = + ecore_config_typed_create(key, (void *)&val, PT_INT, short_opt, long_opt, + desc); + if (ret != ECORE_CONFIG_ERR_SUCC) + return ret; + e = ecore_config_get(key); + if (e) + { + e->step = step; + e->flags |= PF_BOUNDS; + e->lo = low; + e->hi = high; + ecore_config_bound(e); + } + return ret; +} + +/** + * Creates a new string property, if it does not already exist, and sets its + * attributes to those given. + * @param key The property key. + * @param val Default value of key. + * @param short_opt Short option used to set the property from command + * line. + * @param long_opt Long option used to set the property from command line. + * @param desc String description of property. + * @return @c ECORE_CONFIG_ERR_SUCC on success. + * @ingroup Ecore_Config_Create_Group + */ +int +ecore_config_string_create(const char *key, char *val, char short_opt, + char *long_opt, char *desc) +{ + return + ecore_config_typed_create(key, (void *)val, PT_STR, short_opt, long_opt, + desc); +} + +/** + * Creates a new float property, if it does not already exist, and sets its + * attributes to those given. + * @param key The property key. + * @param val Default float value of key. + * @param short_opt Short option used to set the property from command + * line. + * @param long_opt Long option used to set the property from command line. + * @param desc String description of property. + * @return @c ECORE_CONFIG_ERR_SUCC on success. + * @ingroup Ecore_Config_Create_Group + */ +int +ecore_config_float_create(const char *key, float val, char short_opt, + char *long_opt, char *desc) +{ + return + ecore_config_typed_create(key, (void *)&val, PT_FLT, short_opt, long_opt, + desc); +} + +/** + * Creates a new float property, if it does not already exist, and sets its + * attributes to those given. + * @param key The property key. + * @param val Default float value of key. + * @param low Lowest valid float value for the property. + * @param high Highest valid float value for the property. + * @param step Increment value for the property. + * @param short_opt Short option used to set the property from command + * line. + * @param long_opt Long option used to set the property from command line. + * @param desc String description of property. + * @return @c ECORE_CONFIG_ERR_SUCC on success. + * @ingroup Ecore_Config_Create_Group + */ +int +ecore_config_float_create_bound(const char *key, float val, float low, + float high, float step, char short_opt, + char *long_opt, char *desc) +{ + Ecore_Config_Prop *e; + int ret; + + ret = + ecore_config_typed_create(key, (void *)&val, PT_FLT, short_opt, long_opt, + desc); + e = ecore_config_get(key); + if (e) + { + e->step = (int)(step * ECORE_CONFIG_FLOAT_PRECISION); + e->flags |= PF_BOUNDS; + e->lo = (int)(low * ECORE_CONFIG_FLOAT_PRECISION); + e->hi = (int)(high * ECORE_CONFIG_FLOAT_PRECISION); + ecore_config_bound(e); + } + return ret; +} + +/** + * Creates a new color property, if it does not already exist, and sets its + * attributes to those given. + * @param key The property key. + * @param val Default color value of key, as a hexadecimal string. + * @param short_opt Short option used to set the property from command + * line. + * @param long_opt Long option used to set the property from command line. + * @param desc String description of property. + * @return @c ECORE_CONFIG_ERR_SUCC on success. + * @ingroup Ecore_Config_Create_Group + * @deprecated + */ +int +ecore_config_rgb_create(const char *key, char *val, char short_opt, + char *long_opt, char *desc) +{ + char *argb; + int ret; + + argb = ecore_config_rgb_to_argb(val); + ret = ecore_config_argb_create(key, argb, short_opt, long_opt, desc); + free(argb); + return ret; +} + +/** + * Creates a new color property, if it does not already exist, and sets its + * attributes to those given. + * @param key The property key. + * @param val Default color value of key, as a hexadecimal string. + * @param short_opt Short option used to set the property from command + * line. + * @param long_opt Long option used to set the property from command line. + * @param desc String description of property. + * @return @c ECORE_CONFIG_ERR_SUCC on success. + * @ingroup Ecore_Config_Create_Group + */ +int +ecore_config_argb_create(const char *key, char *val, char short_opt, + char *long_opt, char *desc) +{ + return + ecore_config_typed_create(key, (void *)val, PT_RGB, short_opt, long_opt, + desc); +} + +/** + * Creates a new theme property, if it does not already exist, and sets its + * attributes to those given. + * @param key The property key. + * @param val Default theme name for the property. + * @param short_opt Short option used to set the property from command + * line. + * @param long_opt Long option used to set the property from command line. + * @param desc String description of property. + * @return @c ECORE_CONFIG_ERR_SUCC on success. + * @ingroup Ecore_Config_Create_Group + */ +int +ecore_config_theme_create(const char *key, char *val, char short_opt, + char *long_opt, char *desc) +{ + return + ecore_config_typed_create(key, (void *)val, PT_THM, short_opt, long_opt, + desc); +} + +/* this should only be built if evas is present */ + +/** + * Calls evas_font_path_append on @p evas for each of the font names stored + * in the property "/e/font/path". + * @param evas Evas object to append the font names to. + * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA + * is returned if the property has not been set. + */ +int +ecore_config_evas_font_path_apply(Evas * evas) +{ + char *font_path, *font_path_tmp, *ptr, *end; + + font_path = ecore_config_string_get("/e/font/path"); + + if (!font_path) + return ECORE_CONFIG_ERR_NODATA; + ptr = font_path; + end = font_path + strlen(font_path); + font_path_tmp = font_path; + while (ptr && ptr < end) + { + while (*ptr != '|' && ptr < end) + ptr++; + if (ptr < end) + *ptr = '\0'; + + evas_font_path_append(evas, font_path_tmp); + ptr++; + font_path_tmp = ptr; + } + + free(font_path); + + return ECORE_CONFIG_ERR_SUCC; +} + +/** + * Retrieves the default theme search path. + * + * @return The default theme search path. + */ +char * +ecore_config_theme_default_path_get(void) +{ + char *path, *home; + int len; + + home = getenv("HOME"); + len = strlen(PACKAGE_DATA_DIR "/../") + strlen(__ecore_config_app_name) + + strlen("/themes/") + 1; + if (home) + len += strlen(home) + strlen("/.e/apps/") + + strlen(__ecore_config_app_name) + + strlen("/themes/|"); /* no \0, as that is above */ + + if (!(path = malloc(len))) + return NULL; + + *path = '\0'; + if (home) + { + strcat(path, home); + strcat(path, "/.e/apps/"); + strcat(path, __ecore_config_app_name); + strcat(path, "/themes/|"); + } + strcat(path, PACKAGE_DATA_DIR "/../"); + strcat(path, __ecore_config_app_name); + strcat(path, "/themes/"); + + return path; +} + +/** + * Retrieves the search path used to find themes. + * + * The search path is stored in the property "/e/themes/search_path". If + * the property has not been set, the default path used is + * "/usr/local/share//themes|~/.e/apps//themes". + * See @ref ecore_config_theme_default_path_get for more information about + * the default path. + * + * @return The search path. @c NULL is returned if there is no memory left. + */ +char * +ecore_config_theme_search_path_get(void) +{ + char *search_path; + search_path = ecore_config_string_get("/e/themes/search_path"); + + /* this should no longer be the case, as it is defaulted in init */ + if (!search_path) + { + search_path = ecore_config_theme_default_path_get(); + if (search_path) + { + ecore_config_string_default("/e/themes/search_path", search_path); + free(search_path); + } + } + return search_path; +} + +/** + * Adds the given path to the search path used to find themes. + * + * If the search path is successfully, the new search path will be saved + * into the property "/e/themes/search_path". Therefore, this function + * should be called @b after @ref ecore_config_load to allow a user to + * override the default search path. + * + * @param path The given + * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_FAIL + * will be returned if @p path already exists in the search path. + * @c ECORE_CONFIG_ERR_FAIL is returned if @p path is @c NULL. + */ +int +ecore_config_theme_search_path_append(char *path) +{ + char *search_path, *loc, *new_search_path; + int len, search_len; + Ecore_Config_Prop *prop; + + if (!path) + return ECORE_CONFIG_ERR_NODATA; + search_path = ecore_config_theme_search_path_get(); + + loc = strstr(search_path, path); + len = strlen(path); + search_len = strlen(search_path); + + if (loc == NULL || (loc != search_path && *(loc - 1) != '|') || + (loc != (search_path + search_len - len) && *(loc + len - 1) != '|')) + { + new_search_path = malloc(search_len + len + 2); /* 2 = \0 + | */ + strcpy(new_search_path, search_path); + strncat(new_search_path, "|", 1); + strncat(new_search_path, path, len); + + ecore_config_string_set("/e/themes/search_path", new_search_path); + prop = ecore_config_get("/e/themes/search_path"); + if (prop) + prop->flags &= ~PF_MODIFIED; + + free(new_search_path); + + return ECORE_CONFIG_ERR_SUCC; + } + return ECORE_CONFIG_ERR_FAIL; +} + +/** + * Retrieve a theme file's full path. + * + * The search path for theme files is given by @ref + * ecore_config_theme_search_path_get . + * + * @param name The name of the theme. + * @return A full path to the theme on success. @c NULL will be returned + * if @p name is @c NULL or no theme matching the given name could + * be found. + */ +char * +ecore_config_theme_with_path_from_name_get(char *name) +{ + char *search_path, *search_path_tmp, *ptr, *end, *file; + struct stat st; + + if (!name) + return NULL; /* no theme specified (nor a default) */ + + search_path = ecore_config_theme_search_path_get(); + ptr = search_path; + end = search_path + strlen(search_path); + search_path_tmp = search_path; + while (ptr && ptr < end) + { + while (*ptr != '|' && ptr < end) + ptr++; + if (ptr < end) + *ptr = '\0'; + + file = malloc(strlen(search_path_tmp) + strlen(name) + 6); + /* 6 = / + .edj + \0 */ + + snprintf(file, strlen(search_path_tmp) + strlen(name) + 6, + "%s/%s.edj", search_path_tmp, name); + + if (stat(file, &st) == 0) + { + free(search_path); + return file; + } + free(file); + ptr++; + search_path_tmp = ptr; + } + + free(search_path); + + return NULL; /* we could not find the theme with that name in search path */ +} + +/** + * Retrieves the full path to the theme file of the theme stored in the + * given property. + * + * The search path for themes is given by @ref + * ecore_config_theme_search_path_get . + * + * @param key The given property. + * @return A full path to the theme on success, or @c NULL on failure. + * This function will fail if no key is specified or not theme + * matching that given by the property @p key could be found. + */ +char * +ecore_config_theme_with_path_get(const char *key) +{ + return + ecore_config_theme_with_path_from_name_get(ecore_config_theme_get(key)); +} + +static const char *_ecore_config_short_types[] = + { " ", " ", " ", " ", " ", " ", "" }; + +/** + * Prints the property list of the local configuration bundle to output. + */ +void +ecore_config_args_display(void) +{ + Ecore_Config_Prop *props; + _Ecore_Config_Arg_Callback *callbacks; + + if (__ecore_config_app_description) + printf("%s\n\n", __ecore_config_app_description); + printf("Supported Options:\n"); + printf(" -h, --help\t Print this text\n"); + if (!__ecore_config_bundle_local) + return; + props = __ecore_config_bundle_local->data; + while (props) + { + /* if it is a system prop, or cannot be set on command line hide it */ + if (props->flags & PF_SYSTEM || (!props->short_opt && !props->long_opt)) + { + props = props->next; + continue; + } + printf(" %c%c%c --%s\t%s %s\n", props->short_opt ? '-' : ' ', + props->short_opt ? props->short_opt : ' ', + props->short_opt ? ',' : ' ', + props->long_opt ? props->long_opt : props->key, + _ecore_config_short_types[props->type], + props->description ? props->description : + "(no description available)"); + + props = props->next; + } + callbacks = _ecore_config_arg_callbacks; + while (callbacks) + { + printf(" %c%c%c --%s\t%s %s\n", callbacks->short_opt ? '-' : ' ', + callbacks->short_opt ? callbacks->short_opt : ' ', + callbacks->short_opt ? ',' : ' ', + callbacks->long_opt ? callbacks->long_opt : "", + _ecore_config_short_types[callbacks->type], + callbacks->description ? callbacks->description : + "(no description available)"); + + callbacks = callbacks->next; + } +} + +static int +ecore_config_parse_set(Ecore_Config_Prop * prop, char *arg, char *opt, + char opt2) +{ + if (!arg) + { + if (opt) + printf("Missing expected argument for option --%s\n", opt); + else + printf("Missing expected argument for option -%c\n", opt2); + return ECORE_CONFIG_PARSE_EXIT; + } + else + { + ecore_config_set(prop->key, arg); + prop->flags |= PF_CMDLN; + } + return ECORE_CONFIG_PARSE_CONTINUE; +} + +static void +ecore_config_args_callback_add(char short_opt, char *long_opt, char *desc, + void (*func)(char *val, void *data), + void *data, Ecore_Config_Type type) { + _Ecore_Config_Arg_Callback *new_cb; + + new_cb = malloc(sizeof(_Ecore_Config_Arg_Callback)); + new_cb->short_opt = short_opt; + if (long_opt) + new_cb->long_opt = strdup(long_opt); + if (desc) + new_cb->description = strdup(desc); + new_cb->data = data; + new_cb->func = func; + new_cb->type = type; + + new_cb->next = _ecore_config_arg_callbacks; + _ecore_config_arg_callbacks = new_cb; +} + +void +ecore_config_args_callback_str_add(char short_opt, char *long_opt, char *desc, + void (*func)(char *val, void *data), + void *data) { + ecore_config_args_callback_add(short_opt, long_opt, desc, func, data, PT_STR); +} + +void +ecore_config_args_callback_noarg_add(char short_opt, char *long_opt, char *desc, + void (*func)(char *val, void *data), + void *data) { + ecore_config_args_callback_add(short_opt, long_opt, desc, func, data, PT_NIL); +} + +/** + * Parse the arguments set by @ref ecore_app_args_set and set properties + * accordingly. + * + * @return @c ECORE_CONFIG_PARSE_CONTINUE if successful. + * @c ECORE_CONFIG_PARSE_EXIT is returned if an unrecognised option + * is found. @c ECORE_CONFIG_PARSE_HELP is returned if help was + * displayed. + */ +int +ecore_config_args_parse(void) +{ + int argc; + char **argv; + int nextarg, next_short_opt, found, ret; + char *arg; + char *long_opt, short_opt; + Ecore_Config_Prop *prop; + _Ecore_Config_Arg_Callback *callback; + + ecore_app_args_get(&argc, &argv); + nextarg = 1; + while (nextarg < argc) + { + arg = argv[nextarg]; + + if (*arg != '-') + { + printf("Unexpected attribute \"%s\"\n", arg); + nextarg++; + continue; + } + + next_short_opt = 1; + short_opt = *(arg + next_short_opt); + + if (short_opt == '-') + { + long_opt = arg + 2; + + if (!strcmp(long_opt, "help")) + { + ecore_config_args_display(); + return ECORE_CONFIG_PARSE_HELP; + } + + found = 0; + prop = __ecore_config_bundle_local->data; + while (prop) + { + if ((prop->long_opt && !strcmp(long_opt, prop->long_opt)) + || !strcmp(long_opt, prop->key)) + { + found = 1; + if ((ret = + ecore_config_parse_set(prop, argv[++nextarg], + long_opt, + '\0')) != + ECORE_CONFIG_PARSE_CONTINUE) + return ret; + break; + } + prop = prop->next; + } + if (!found) + { + callback = _ecore_config_arg_callbacks; + while (callback) + { + if ((callback->long_opt && + !strcmp(long_opt, callback->long_opt))) + { + found = 1; + if (callback->type == PT_NIL) + { + callback->func(NULL, callback->data); + } + else + { + if (!argv[++nextarg]) + { + printf("Missing expected argument for option --%s\n", long_opt); + return ECORE_CONFIG_PARSE_EXIT; + } + callback->func(argv[nextarg], callback->data); + } + break; + } + callback = callback->next; + } + } + if (!found) + { + printf("Unrecognised option \"%s\"\n", long_opt); + printf("Try using -h or --help for more information.\n\n"); + return ECORE_CONFIG_PARSE_EXIT; + } + } + else + { + while (short_opt) + { + if (short_opt == 'h') + { + ecore_config_args_display(); + return ECORE_CONFIG_PARSE_HELP; + } + else + { + found = 0; + prop = __ecore_config_bundle_local->data; + while (prop) + { + if (short_opt == prop->short_opt) + { + found = 1; + if ((ret = + ecore_config_parse_set(prop, + argv[++nextarg], + NULL, + short_opt)) != + ECORE_CONFIG_PARSE_CONTINUE) + return ret; + break; + } + prop = prop->next; + } + + if (!found) + { + callback = _ecore_config_arg_callbacks; + while (callback) + { + if (short_opt == callback->short_opt) + { + found = 1; + if (callback->type == PT_NIL) + { + callback->func(NULL, callback->data); + } + else + { + if (!argv[++nextarg]) + { + printf("Missing expected argument for option -%c\n", short_opt); + return ECORE_CONFIG_PARSE_EXIT; + } + callback->func(argv[nextarg], callback->data); + } + break; + } + callback = callback->next; + } + } + if (!found) + { + printf("Unrecognised option '%c'\n", short_opt); + printf + ("Try using -h or --help for more information.\n\n"); + return ECORE_CONFIG_PARSE_EXIT; + } + } + short_opt = *(arg + ++next_short_opt); + } + } + nextarg++; + } + + return ECORE_CONFIG_PARSE_CONTINUE; +} + +/** + * Sets the description string used by @ref ecore_config_args_display . + * @param description Description of application. + */ +void +ecore_config_app_describe(char *description) +{ + if (__ecore_config_app_description) + free(__ecore_config_app_description); + __ecore_config_app_description = strdup(description); +} diff --git a/ecore/src/lib/ecore_config/ecore_config_ipc.h b/ecore/src/lib/ecore_config/ecore_config_ipc.h new file mode 100644 index 0000000..7b3dea1 --- /dev/null +++ b/ecore/src/lib/ecore_config/ecore_config_ipc.h @@ -0,0 +1,50 @@ +#include +#include "Ecore_Config.h" + +typedef enum +{ + IPC_NONE, + IPC_PROP_LIST, + IPC_PROP_DESC, + IPC_PROP_GET, + IPC_PROP_SET, /* end of the codes shared by evidence and econf */ + + IPC_GLOBAL_PROP_LIST, + + IPC_BUNDLE_LIST, + IPC_BUNDLE_NEW, + IPC_BUNDLE_LABEL_GET, + IPC_BUNDLE_LABEL_SET, + IPC_BUNDLE_LABEL_FIND, + + IPC_LAST +} Ecore_Config_Ipc_Call; + +Ecore_Config_Server *_ecore_config_ipc_init(const char *pipe_name); +int _ecore_config_ipc_exit(void); + +Ecore_Config_Server *_ecore_config_server_convert(void *srv); + +char *_ecore_config_ipc_prop_list(Ecore_Config_Server * srv, + const long serial); +char *_ecore_config_ipc_prop_desc(Ecore_Config_Server * srv, + const long serial, + const char *key); +char *_ecore_config_ipc_prop_get(Ecore_Config_Server * srv, + const long serial, + const char *key); +int _ecore_config_ipc_prop_set(Ecore_Config_Server * srv, + const long serial, + const char *key, + const char *val); + +char *_ecore_config_ipc_bundle_list(Ecore_Config_Server * srv); +int _ecore_config_ipc_bundle_new(Ecore_Config_Server * srv, + const char *); +char *_ecore_config_ipc_bundle_label_get(Ecore_Config_Server * + srv, const long); +int _ecore_config_ipc_bundle_label_set(Ecore_Config_Server * + srv, const long, + const char *); +long _ecore_config_ipc_bundle_label_find(Ecore_Config_Server * + srv, const char *); diff --git a/ecore/src/lib/ecore_config/ecore_config_ipc_ecore.c b/ecore/src/lib/ecore_config/ecore_config_ipc_ecore.c new file mode 100644 index 0000000..289c690 --- /dev/null +++ b/ecore/src/lib/ecore_config/ecore_config_ipc_ecore.c @@ -0,0 +1,378 @@ +/* by Azundris, with thanks to Corey Donohoe */ +#include "ecore_private.h" +#include "ecore_config_ipc.h" +#include "ecore_config_util.h" +#include "ecore_config_private.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "Ecore_Config.h" +#include "config.h" + + +/*****************************************************************************/ + +static int +_ecore_config_ipc_ecore_string_get(char **m, char **r) +{ + char *q; + int l = 0; + + if (!m || !*m) + return ECORE_CONFIG_ERR_NODATA; + if (!r) + return ECORE_CONFIG_ERR_FAIL; + q = *m; + if (*q != 's') + return ECORE_CONFIG_ERR_TYPEMISMATCH; + q++; + l = (*(q++)) << 8; + l += *(q++); + *r = q; + q += l; + *m = q; + E(1, "IPC/eCore: got string-%d \"%s\"\n", l, *r); + return ECORE_CONFIG_ERR_SUCC; +} + +static char * +_ecore_config_ipc_global_prop_list(Ecore_Config_Server * srv __UNUSED__, long serial __UNUSED__) +{ + Ecore_Config_DB_File *db; + char **keys; + int key_count, x; + estring *s; + int f; + char buf[PATH_MAX], *p; + // char *data; UNUSED + Ecore_Config_Type type; + + db = NULL; + s = estring_new(8192); + f = 0; + if ((p = getenv("HOME"))) + { + snprintf(buf, sizeof(buf), "%s/.e/config.eet", p); + if (!(db = _ecore_config_db_open_read(buf))) + { + strcpy(buf, PACKAGE_DATA_DIR"/system.eet"); + if (!(db = _ecore_config_db_open_read(buf))) + return NULL; + } + } + if (!db) return NULL; + key_count = 0; + keys = _ecore_config_db_keys_get(db, &key_count); + if (keys) + { + for (x = 0; x < key_count; x++) + { + type = _ecore_config_db_key_type_get(db, keys[x]); + switch (type) + { + case PT_INT: + estring_appendf(s, "%s%s: integer", f ? "\n" : "", keys[x]); + break; + case PT_BLN: + estring_appendf(s, "%s%s: boolean", f ? "\n" : "", keys[x]); + break; + case PT_FLT: + estring_appendf(s, "%s%s: float", f ? "\n" : "", keys[x]); + break; + case PT_STR: + estring_appendf(s, "%s%s: string", f ? "\n" : "", keys[x]); + break; + case PT_RGB: + estring_appendf(s, "%s%s: colour", f ? "\n" : "", keys[x]); + break; + case PT_THM: + estring_appendf(s, "%s%s: theme", f ? "\n" : "", keys[x]); + break; + default: + estring_appendf(s, "%s%s: unknown", f ? "\n" : "", keys[x]); + continue; + } + f = 1; + } + } + _ecore_config_db_close(db); + if (keys) + { + for (x = 0; x < key_count; x++) + { + free(keys[x]); + } + free(keys); + } + + return estring_disown(s); +} + +/*****************************************************************************/ + +static int +_ecore_config_ipc_ecore_send(Ecore_Ipc_Event_Client_Data * e, int code, + char *reply) +{ + static int our_ref = 0; + int len = reply ? strlen(reply) + 1 : 0; + + our_ref++; + E(1, "IPC/eCore: replying [0,0] %d IRT %d => %d {\"%s\":%d}\n", our_ref, + e->ref, code, reply ? reply : "", len); + return ecore_ipc_client_send(e->client, 0, 0, our_ref, e->ref, code, reply, + len); +} + +/*****************************************************************************/ + +static int +_ecore_config_ipc_ecore_handle_request(Ecore_Ipc_Server * server, + Ecore_Ipc_Event_Client_Data * e) +{ + Ecore_Config_Server *srv; + long serial; + int ret; + char *r, *k, *v, *m; + + srv = _ecore_config_server_convert(server); + serial = e->minor; + ret = ECORE_CONFIG_ERR_FAIL; + r = NULL; + m = (char *)e->data; + E(1, "IPC/eCore: client sent: [%d,%d] #%d (%d) @ %p\n", e->major, e->minor, + e->ref, e->size, server); + + switch (e->major) + { + case IPC_PROP_LIST: + if (srv == __ecore_config_server_global) + r = _ecore_config_ipc_global_prop_list(srv, serial); + else + r = _ecore_config_ipc_prop_list(srv, serial); + break; + case IPC_PROP_DESC: + if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC) + r = _ecore_config_ipc_prop_desc(srv, serial, k); + break; + case IPC_PROP_GET: + if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC) + r = _ecore_config_ipc_prop_get(srv, serial, k); + break; + case IPC_PROP_SET: + if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC) + { + if (_ecore_config_ipc_ecore_string_get(&m, &v) == + ECORE_CONFIG_ERR_SUCC) + return _ecore_config_ipc_ecore_send(e, + _ecore_config_ipc_prop_set + (srv, serial, k, v), NULL); + } + break; + + case IPC_BUNDLE_LIST: + r = _ecore_config_ipc_bundle_list(srv); + break; + case IPC_BUNDLE_NEW: + if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC) + return _ecore_config_ipc_ecore_send(e, + k ? + _ecore_config_ipc_bundle_new(srv, + k) : + ECORE_CONFIG_ERR_FAIL, NULL); + break; + case IPC_BUNDLE_LABEL_SET: + if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC) + return _ecore_config_ipc_ecore_send(e, + k ? + _ecore_config_ipc_bundle_label_set + (srv, serial, + k) : ECORE_CONFIG_ERR_FAIL, + NULL); + break; + case IPC_BUNDLE_LABEL_FIND: + if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC) + return _ecore_config_ipc_ecore_send(e, + _ecore_config_ipc_bundle_label_find + (srv, k), NULL); + break; + case IPC_BUNDLE_LABEL_GET: + r = _ecore_config_ipc_bundle_label_get(srv, serial); + break; + } + + ret = + _ecore_config_ipc_ecore_send(e, + r ? ECORE_CONFIG_ERR_SUCC : + ECORE_CONFIG_ERR_FAIL, r); + if (r) + { + free(r); + return ret; + } + return ECORE_CONFIG_ERR_NOTFOUND; +} + +/*****************************************************************************/ + +static int +_ecore_config_ipc_client_add(void *data, int type __UNUSED__, void *event) +{ + Ecore_Ipc_Server **server; + Ecore_Ipc_Event_Client_Data *e; + + server = (Ecore_Ipc_Server **) data; + e = (Ecore_Ipc_Event_Client_Data *) event; + + if (*server != ecore_ipc_client_server_get(e->client)) + return 1; + + E(1, "IPC/eCore: Client connected. @ %p\n", server); + return 1; +} + +static int +_ecore_config_ipc_client_del(void *data, int type __UNUSED__, void *event) +{ + Ecore_Ipc_Server **server; + Ecore_Ipc_Event_Client_Data *e; + + server = (Ecore_Ipc_Server **) data; + e = (Ecore_Ipc_Event_Client_Data *) event; + + if (*server != ecore_ipc_client_server_get(e->client)) + return 1; + + E(1, "IPC/eCore: Client disconnected. @ %p\n", server); + return 1; +} + +static int +_ecore_config_ipc_client_sent(void *data, int type __UNUSED__, void *event) +{ + Ecore_Ipc_Server **server; + Ecore_Ipc_Event_Client_Data *e; + + server = (Ecore_Ipc_Server **) data; + e = (Ecore_Ipc_Event_Client_Data *) event; + + if (*server != ecore_ipc_client_server_get(e->client)) + return 1; + + _ecore_config_ipc_ecore_handle_request(*server, e); + return 1; +} + +/*****************************************************************************/ + +int +_ecore_config_ipc_ecore_init(const char *pipe_name, void **data) +{ + Ecore_Ipc_Server **server; + struct stat st; + char *p; + int port; + char socket[PATH_MAX]; + + server = (Ecore_Ipc_Server **) data; + port = 0; + if (!server) + return ECORE_CONFIG_ERR_FAIL; + +/* if(*server) + return ECORE_CONFIG_ERR_IGNORED; */ + + ecore_init(); + if (ecore_ipc_init() < 1) + return ECORE_CONFIG_ERR_FAIL; + + if ((p = getenv("HOME"))) + { /* debug-only ### FIXME */ + int stale; + + stale = 1; + while (stale) + { + snprintf(socket, PATH_MAX, "%s/.ecore/%s/%d", p, pipe_name, port); + + if (!stat(socket, &st)) + { + E(0, "IPC/eCore: pipe \"%s\" already exists!?\n", socket); +/* if(unlink(buf)) + E(0,"IPC/eCore: could not remove pipe \"%s\": %d\n",buf,errno); }}*/ + port++; + } + else + { + stale = 0; + } + } + } + *server = ecore_ipc_server_add(ECORE_IPC_LOCAL_USER, pipe_name, port, NULL); + ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, + _ecore_config_ipc_client_add, server); + ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, + _ecore_config_ipc_client_del, server); + ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, + _ecore_config_ipc_client_sent, server); + + if (server) + { + E(1, "IPC/eCore: Server is listening on %s.\n", pipe_name); + } + + return ECORE_CONFIG_ERR_SUCC; +} + +int +_ecore_config_ipc_ecore_exit(void **data) +{ + int ret; + Ecore_Ipc_Server **server; + + ret = ECORE_CONFIG_ERR_SUCC; + server = (Ecore_Ipc_Server **) data; + + if (!server) + return ECORE_CONFIG_ERR_FAIL; + + if (*server) + { + ecore_ipc_server_del(*server); + *server = NULL; + } + + ecore_ipc_shutdown(); + + return ret; +} + +/*****************************************************************************/ + +int +_ecore_config_ipc_ecore_poll(void **data) +{ + Ecore_Ipc_Server **server; + + server = (Ecore_Ipc_Server **) data; + + if (!server) + return ECORE_CONFIG_ERR_FAIL; + + ecore_main_loop_iterate(); + + return ECORE_CONFIG_ERR_SUCC; +} + +/*****************************************************************************/ diff --git a/ecore/src/lib/ecore_config/ecore_config_ipc_main.c b/ecore/src/lib/ecore_config/ecore_config_ipc_main.c new file mode 100644 index 0000000..b4adf27 --- /dev/null +++ b/ecore/src/lib/ecore_config/ecore_config_ipc_main.c @@ -0,0 +1,284 @@ +/* ############## bad */ +#define HAVE_EVAS2 + +#include "Ecore_Config.h" +#include "ecore_config_util.h" +#include "ecore_config_ipc.h" + +#include "config.h" +#include "ecore_config_private.h" + +#include +#include +#include +#include +#include +#include +#include +#include /* malloc(), free() */ + +#ifndef TRUE +# define FALSE 0 +# define TRUE (!FALSE) +#endif + +static Ecore_Config_Server *__ecore_config_servers; +static unsigned long ipc_timer = 0L; + +extern int _ecore_config_ipc_ecore_init(const char *pipe_name, void **data); +extern int _ecore_config_ipc_ecore_exit(void **data); +extern int _ecore_config_ipc_ecore_poll(void **data); + +Ecore_Config_Server * +_ecore_config_server_convert(void *srv) +{ + Ecore_Config_Server *srv_tmp; + + srv_tmp = __ecore_config_servers; + while (srv_tmp) + { + if (srv_tmp->server == srv) + return srv_tmp; + srv_tmp = srv_tmp->next; + } + + return __ecore_config_server_global; +} + +/*****************************************************************************/ +/* INTERFACE FOR IPC MODULES */ +/*****************************/ + +char * +_ecore_config_ipc_prop_list(Ecore_Config_Server * srv, const long serial) +{ + Ecore_Config_Bundle *theme; + Ecore_Config_Prop *e; + estring *s; + int f; + + theme = ecore_config_bundle_by_serial_get(srv, serial); + e = theme ? theme->data : NULL; + s = estring_new(8192); + f = 0; + while (e) + { + /* ignore system properties in listings, unless they have been overridden */ + if (e->flags & PF_SYSTEM && !(e->flags & PF_MODIFIED)) + { + e = e->next; + continue; + } + estring_appendf(s, "%s%s: %s", f ? "\n" : "", e->key, + ecore_config_type_get(e)); + if (e->flags & PF_BOUNDS) + { + if (e->type == PT_FLT) + estring_appendf(s, ", range %le..%le", + (float)e->lo / ECORE_CONFIG_FLOAT_PRECISION, + (float)e->hi / ECORE_CONFIG_FLOAT_PRECISION); + else + estring_appendf(s, ", range %d..%d", e->lo, e->hi); + } + if (e->type == PT_THM) + estring_appendf(s, ", group %s", e->data ? e->data : "Main"); + f = 1; + e = e->next; + } + + return estring_disown(s); +} + +char * +_ecore_config_ipc_prop_desc(Ecore_Config_Server * srv, const long serial, + const char *key) +{ +#ifdef HAVE_EVAS2 + Ecore_Config_Bundle *theme; + Ecore_Config_Prop *e; + + theme = ecore_config_bundle_by_serial_get(srv, serial); + e = ecore_config_get(key); + + if (e) + { + estring *s = estring_new(512); + + estring_appendf(s, "%s: %s", e->key, ecore_config_type_get(e)); + if (e->flags & PF_BOUNDS) + estring_appendf(s, ", range %d..%d", e->lo, e->hi); + return estring_disown(s); + } +#endif + return strdup(""); +} + +char * +_ecore_config_ipc_prop_get(Ecore_Config_Server * srv, const long serial, + const char *key) +{ +#ifdef HAVE_EVAS2 + char *ret; + Ecore_Config_Bundle *theme; + + ret = NULL; + theme = ecore_config_bundle_by_serial_get(srv, serial); + if ((ret = ecore_config_as_string_get( /*theme, */ key))) + return ret; +#endif + return strdup(""); +} + +int +_ecore_config_ipc_prop_set(Ecore_Config_Server * srv, const long serial, + const char *key, const char *val) +{ +#ifdef HAVE_EVAS2 + int ret; + Ecore_Config_Bundle *theme; + + theme = ecore_config_bundle_by_serial_get(srv, serial); + ret = ecore_config_set(key, (char *)val); + E(1, "ipc.prop.set(%s->%s,\"%s\") => %d\n", theme ? theme->identifier : "", + key, val, ret); + return ret; +#else + return ECORE_CONFIG_ERR_NOTSUPP; +#endif +} + +/*****************************************************************************/ + +char * +_ecore_config_ipc_bundle_list(Ecore_Config_Server * srv) +{ + Ecore_Config_Bundle *ns; + estring *s; + int f; + + ns = ecore_config_bundle_1st_get(srv); + s = estring_new(8192); + f = 0; + if (!ns) + return strdup(""); + + while (ns) + { + estring_appendf(s, "%s%d: %s", f ? "\n" : "", + ecore_config_bundle_serial_get(ns), + ecore_config_bundle_label_get(ns)); + f = 1; + ns = ecore_config_bundle_next_get(ns); + } + + return estring_disown(s); +} + +int +_ecore_config_ipc_bundle_new(Ecore_Config_Server * srv, const char *label) +{ + if (ecore_config_bundle_new(srv, label)) + return ECORE_CONFIG_ERR_SUCC; + return ECORE_CONFIG_ERR_FAIL; +} + +char * +_ecore_config_ipc_bundle_label_get(Ecore_Config_Server * srv, const long serial) +{ + Ecore_Config_Bundle *ns; + char *label; + + ns = ecore_config_bundle_by_serial_get(srv, serial); + label = ecore_config_bundle_label_get(ns); + return strdup(label ? label : ""); +} + +int +_ecore_config_ipc_bundle_label_set(Ecore_Config_Server * srv, const long serial, + const char *label) +{ + Ecore_Config_Bundle *ns; + + ns = ecore_config_bundle_by_serial_get(srv, serial); + if (!(ns->identifier = malloc(sizeof(label)))) + return ECORE_CONFIG_ERR_OOM; + memcpy(ns->identifier, label, sizeof(label)); + return ECORE_CONFIG_ERR_SUCC; +} + +long +_ecore_config_ipc_bundle_label_find(Ecore_Config_Server * srv, + const char *label) +{ + Ecore_Config_Bundle *ns; + + ns = ecore_config_bundle_by_label_get(srv, label); + return ns ? ecore_config_bundle_serial_get(ns) : -1; +} + +static int +_ecore_config_ipc_poll(void *data) +{ + Ecore_Config_Server *s; + + s = __ecore_config_servers; + while (s) + { + _ecore_config_ipc_ecore_poll(&s->server); + s = s->next; + } + + return TRUE; +} + +int +_ecore_config_ipc_exit(void) +{ + Ecore_Config_Server *l; + + if (ipc_timer) + timeout_remove(ipc_timer); + l = __ecore_config_servers; + while (l) + { + _ecore_config_ipc_ecore_exit(&l->server); + l = l->next; + } + + return ECORE_CONFIG_ERR_SUCC; +} + +Ecore_Config_Server * +_ecore_config_ipc_init(const char *pipe_name) +{ + int ret; + Ecore_Config_Server *list; + Ecore_Config_Server *ret_srv; + + list = NULL; + ret_srv = NULL; + list = NULL; + + list = malloc(sizeof(Ecore_Config_Server)); + memset(list, 0, sizeof(Ecore_Config_Server)); + if ((ret = _ecore_config_ipc_ecore_init(pipe_name, &list->server)) != ECORE_CONFIG_ERR_SUCC) + { + E(2, "_ecore_config_ipc_init: failed to register %s, code %d\n", + pipe_name, ret); + } + + E(2, "_ecore_config_ipc_init: registered \"%s\"...\n", pipe_name); + + list->name = strdup(pipe_name); + list->next = __ecore_config_servers; + + __ecore_config_servers = list; + if (!ret_srv) + ret_srv = list; + + if (!ipc_timer) + ipc_timer = timeout_add(100, _ecore_config_ipc_poll, NULL); + + return ret_srv; +} +/*****************************************************************************/ diff --git a/ecore/src/lib/ecore_config/ecore_config_private.h b/ecore/src/lib/ecore_config/ecore_config_private.h new file mode 100644 index 0000000..2b8ed47 --- /dev/null +++ b/ecore/src/lib/ecore_config/ecore_config_private.h @@ -0,0 +1,28 @@ +#ifndef _ECORE_CONFIG_PRIVATE_H +# define _ECORE_CONFIG_PRIVATE_H + +/* debug */ +extern int DEBUG; +#ifdef __sgi +# define D +# define E +#else +# define D(fmt,args...) do { if(DEBUG>=0) fprintf(stderr,fmt,## args); } while(0); +# define E(lvl,args...) do { if(DEBUG>=(lvl)) fprintf(stderr,## args); } while(0) +#endif + +typedef struct _Ecore_Config_DB_File Ecore_Config_DB_File; + +int _ecore_config_mod_init(const char *pipe_name, void **data); +int _ecore_config_mod_exit(void **data); +int _ecore_config_mod_poll(void **data); + +Ecore_Config_DB_File *_ecore_config_db_open_read(const char *file); +Ecore_Config_DB_File *_ecore_config_db_open_write(const char *file); +void _ecore_config_db_close(Ecore_Config_DB_File *db); +char **_ecore_config_db_keys_get(Ecore_Config_DB_File *db, int *num_ret); +Ecore_Config_Type _ecore_config_db_key_type_get(Ecore_Config_DB_File *db, const char *key); +int _ecore_config_db_read(Ecore_Config_DB_File *db, const char *key); +void _ecore_config_db_write(Ecore_Config_DB_File *db, const char *key); + +#endif diff --git a/ecore/src/lib/ecore_config/ecore_config_storage.c b/ecore/src/lib/ecore_config/ecore_config_storage.c new file mode 100644 index 0000000..e3cba38 --- /dev/null +++ b/ecore/src/lib/ecore_config/ecore_config_storage.c @@ -0,0 +1,172 @@ +#include "Ecore_Config.h" +#include "ecore_config_private.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +/** + * Loads the default configuration. + * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA + * is returned if the file cannot be loaded. + * @ingroup Ecore_Config_File_Group + */ +int +ecore_config_load(void) +{ + char file[PATH_MAX]; + + if (!__ecore_config_app_name) + return ECORE_CONFIG_ERR_FAIL; + + snprintf(file, PATH_MAX, "%s/.e/apps/%s/config.eet", getenv("HOME"), + __ecore_config_app_name); + return ecore_config_file_load(file); +} + +/** + * Saves the current configuration to the default file. + * @return @c ECORE_CONFIG_ERR_SUCC is returned on success. + * @c ECORE_CONFIG_ERR_FAIL is returned if the data cannot be + * saved. + * @ingroup Ecore_Config_File_Group + */ +int +ecore_config_save(void) +{ + char file[PATH_MAX]; + + if (!__ecore_config_app_name) + return ECORE_CONFIG_ERR_FAIL; + + snprintf(file, PATH_MAX, "%s/.e/apps/%s/config.eet", getenv("HOME"), + __ecore_config_app_name); + return ecore_config_file_save(file); +} + +/** + * Load the given configuration file to the local configuration. + * @param file Name of the file to load. + * @return @c ECORE_CONFIG_ERR_SUCC on success. @c ECORE_CONFIG_ERR_NODATA + * is returned if the file cannot be loaded. + * @ingroup Ecore_Config_File_Group + */ +int +ecore_config_file_load(const char *file) +{ + Ecore_Config_DB_File *db; + char **keys; + int key_count; + int x; + // double ftmp; UNUSED + // int pt; UNUSED + // int itmp; UNUSED + // Ecore_Config_Type type; UNUSED + char *data; + + db = NULL; + data = NULL; + + db = _ecore_config_db_open_read(file); + if (!db) + { + E(0, "Cannot open database from file %s!\n", file); + return ECORE_CONFIG_ERR_NODATA; + } + key_count = 0; + keys = _ecore_config_db_keys_get(db, &key_count); + if (keys) + { + for (x = 0; x < key_count; x++) + { + _ecore_config_db_read(db, keys[x]); + } + } + _ecore_config_db_close(db); + if (keys) + { + for (x = 0; x < key_count; x++) + { + free(keys[x]); + } + free(keys); + } + return ECORE_CONFIG_ERR_SUCC; +} + +static void +_ecore_config_recurse_mkdir(const char *file) +{ + char *file_ptr; + char *file_tmp; + struct stat status; + + file_tmp = strdup(file); + file_ptr = file_tmp + strlen(file_tmp); + while (*file_ptr != '/' && file_ptr > file_tmp) + file_ptr--; + *file_ptr = '\0'; + + if (stat(file_tmp, &status)) + { + _ecore_config_recurse_mkdir(file_tmp); + mkdir(file_tmp, S_IRUSR | S_IWUSR | S_IXUSR); + } + free(file_tmp); +} + +/** + * Saves the local configuration to the given file. + * @param file Name of the file to save to. + * @return @c ECORE_CONFIG_ERR_SUCC is returned on success. + * @c ECORE_CONFIG_ERR_FAIL is returned if the data cannot be + * saved. + * @ingroup Ecore_Config_File_Group + */ +int +ecore_config_file_save(const char *file) +{ + Ecore_Config_Prop *next; + Ecore_Config_DB_File *db; + struct stat status; + + next = __ecore_config_bundle_local->data; + db = NULL; + + /* if file does not exist check to see if the dirs exist, creating if not */ + if (stat(file, &status)) + _ecore_config_recurse_mkdir(file); + + db = _ecore_config_db_open_write(file); + if (!db) + { + E(0, "Cannot open database from file %s!\n", file); + return ECORE_CONFIG_ERR_FAIL; + } + + while (next) + { + /* let the config_db deal with this + * handyande: hmm, not sure that it ever does - reinstating until + * further discussions satisfy me! + */ + if (!(next->flags & PF_MODIFIED) || next->flags & PF_CMDLN) + { + next = next->next; + continue; + } + + _ecore_config_db_write(db, next->key); + + next = next->next; + } + + _ecore_config_db_close(db); + return ECORE_CONFIG_ERR_SUCC; +} diff --git a/ecore/src/lib/ecore_config/ecore_config_util.c b/ecore/src/lib/ecore_config/ecore_config_util.c new file mode 100644 index 0000000..07f625a --- /dev/null +++ b/ecore/src/lib/ecore_config/ecore_config_util.c @@ -0,0 +1,781 @@ +/* azundris */ + +/*#include */ + +#include +#include /* gimetimeofday() */ +#include /* NULL */ +#include /* malloc(), free() */ +#include /* str...() */ +#include /* isspace() */ + +#include /* varargs in dlmulti() */ +#include /* dlopen() and friends for dlmulti() */ + +/* #ifdef HAVE_GLIB2 */ +/* # include */ +/* #endif */ + +#include "ecore_private.h" + +#include "Ecore_Config.h" +#include "ecore_config_util.h" + +#include "ecore_config_private.h" + +#define CHUNKLEN 4096 + +/*****************************************************************************/ +/* MISC */ +/********/ + +int +dlmulti(const char *name, const char *file, int flag, void **libr, const char *fmt, ...) +{ +#define MAX_SYM_LEN 256 + va_list ap; + void *lib; + int ret = ECORE_CONFIG_ERR_SUCC; + char buf[MAX_SYM_LEN] = "\0"; + + if (!libr) + return ECORE_CONFIG_ERR_FAIL; + + if (!name) + name = file; + + *libr = NULL; + + if ((lib = dlopen(file, flag))) + { + void **funr, *fun; + char *b, *e; + size_t l; + int required = 1; + + va_start(ap, fmt); + while (*fmt) + { + switch (*fmt) + { + case '?': + required = 0; + fmt++; + break; + + case '!': + case '.': + required = 1; + fmt++; + break; + + case '\t': + case '\n': + case '\r': + case ';': + case ',': + case ' ': + fmt++; + break; + + default: + e = b = (char *)fmt; + while (*e && (strchr("?!.,; \t\n\r", *e) == NULL)) + e++; + + fmt = e; + if (e == b) + ret = ECORE_CONFIG_ERR_NODATA; + else if ((l = (e - b)) >= MAX_SYM_LEN) + ret = ECORE_CONFIG_ERR_OOM; + else + { + memcpy(buf, b, l); + buf[l] = '\0'; + funr = va_arg(ap, void **); + + if (!(fun = dlsym(lib, buf))) + { + if ((ret = + required ? ECORE_CONFIG_ERR_NOTFOUND : + ECORE_CONFIG_ERR_PARTIAL) == + ECORE_CONFIG_ERR_NOTFOUND) + E(1, + "DLMulti: library/plugin/engine \"%s\" (\"%s\") did not contain required function \"%s\"...\n", + name, file, buf); + } + E(2, "DLMulti: %p => %p %c\"%s\"\n", fun, funr, + required ? '!' : '?', buf); + if (funr) + *funr = fun; + } + required = 1; + } + } + + va_end(ap); + + if ((ret == ECORE_CONFIG_ERR_SUCC) || (ret == ECORE_CONFIG_ERR_PARTIAL)) + *libr = lib; + else + dlclose(lib); + } + else + ret = ECORE_CONFIG_ERR_NODATA; + + return ret; +} + +#if 0 /* Unused */ +/*****************************************************************************/ + +unsigned long +now(long delay) +{ + static struct timeval tv; + unsigned long r; + + gettimeofday(&tv, NULL); + r = tv.tv_sec * 1000 + (((float)tv.tv_usec) / 1000.0) + delay; + return r; +} +#endif + +/*****************************************************************************/ + +int +parse_line(char *in, char **o1, char **o2, char **o3, char **o4) +{ +#define PLMAX 16 + int c; + char *p = in; + char *r[PLMAX]; + + for (c = 0; c < PLMAX; c++) + r[c] = NULL; + + c = 0; + if (!in || !*in) + goto pl_end; + + do + { + while (isspace(*p)) + *(p++) = '\0'; + + if (!*p || (strchr("#;", *p) && (!p[1] || isspace(p[1])))) + *p = '\0'; /* it ends HERE */ + else + { + if (*p == '\"') + { + r[c++] = ++p; + while (*p && (*p != '\"')) + { + if ((*p == '\\') && p[1]) + p += 2; + else + p++; + } + if (*p) + *(p++) = '\0'; + } + else + { + r[c++] = p; + while (*p && !isspace(*p)) + p++; + } + } + } + while (*p); + + pl_end: + if (o1) + *o1 = r[0]; + if (o2) + *o2 = r[1]; + if (o3) + *o3 = r[2]; + if (o4) + *o4 = r[3]; + + return c; +} + +/*****************************************************************************/ + +/*char *unit_size(char *size) { + gchar *unit="byte"; + long s; + + if((s=atol(size))&&(s>=1024)) { + if((s>(1024*1024*1024))) { + unit="GB"; + s=(long)(s/(1024*1024)); } + else if((s>(1024*1024))) { + unit="MB"; + s=(long)(s/1024); } + else + unit="KB"; + + if((s/1024)>31) + sprintf(size,"%ld %s",(long)(s/1024),unit); + else + sprintf(size,"%.1f %s",((float)s)/1024,unit); } + else + sprintf(size,"%ld %s",s,unit); + + return size; } + +*/ + +/*****************************************************************************/ + +void +qsrt(void *a[], void *data, int lo, int hi, + int (*compare) (const void *, const void *, const void *)) +{ + int h, l; + void *p, *t; + + if (lo < hi) + { + l = lo; + h = hi; + p = a[hi]; + + do + { + while ((l < h) && (compare(data, a[l], p) <= 0)) + l = l + 1; + while ((h > l) && (compare(data, a[h], p) >= 0)) + h = h - 1; + if (l < h) + { + t = a[l]; + a[l] = a[h]; + a[h] = t; + } + } + while (l < h); + + t = a[l]; + a[l] = a[hi]; + a[hi] = t; + + qsrt(a, data, lo, l - 1, compare); + qsrt(a, data, l + 1, hi, compare); + } +} + +/*****************************************************************************/ +/* TIMERS */ +/**********/ + +#ifdef HAVE_GLIB2 + +unsigned long +timeout_add(uint f, int (*fun) (void *), void *data) +{ + return g_timeout_add((guint) f, (GSourceFunc) fun, (gpointer) data); +} + +int +timeout_remove(unsigned long handle) +{ + return g_source_remove(handle) ? ECORE_CONFIG_ERR_SUCC : + ECORE_CONFIG_ERR_FAIL; +} + +#else + +unsigned long +timeout_add(uint f __UNUSED__, int (*fun) (void *) __UNUSED__, void *data __UNUSED__) +{ + return 0; +} + +int +timeout_remove(unsigned long handle __UNUSED__) +{ + return ECORE_CONFIG_ERR_NOTSUPP; +} + +#endif /* HAVE_GLIB2 */ + +/*****************************************************************************/ +/* HASHES */ +/**********/ + +int +eslist_free(eslist ** l) +{ + eslist *e, *f; + + if (!l) + return ECORE_CONFIG_ERR_NODATA; + for (e = *l; e; e = f) + { + f = e->next; + free(e); + } + *l = NULL; + return ECORE_CONFIG_ERR_SUCC; +} + +int +eslist_next(eslist ** e) +{ + if (!e || !*e) + return ECORE_CONFIG_ERR_NODATA; + *e = (*e)->next; + return ECORE_CONFIG_ERR_SUCC; +} + +void * +eslist_payload(eslist ** e) +{ + return (!e || !*e) ? NULL : (*e)->payload; +} + +int +eslist_prepend(eslist ** e, void *p) +{ + eslist *f; + + if (!e) + return ECORE_CONFIG_ERR_NODATA; + + if (!(f = malloc(sizeof(eslist)))) + return ECORE_CONFIG_ERR_OOM; + + f->payload = p; + f->next = *e; + + *e = f; + + return ECORE_CONFIG_ERR_SUCC; +} + +int +eslist_append(eslist ** e, void *p) +{ + eslist *f; + + if (!e) + return ECORE_CONFIG_ERR_NODATA; + + if (!(f = malloc(sizeof(eslist)))) + return ECORE_CONFIG_ERR_OOM; + + f->payload = p; + f->next = NULL; + + if (!*e) + *e = f; + else + { + eslist *g = *e; + + while (g->next) + g = g->next; + g->next = f; + } + + return ECORE_CONFIG_ERR_SUCC; +} + +/*****************************************************************************/ +/* HASHES */ +/**********/ + +#ifdef HAVE_GLIB2 + +void * +hash_table_new(void (*freekey), void (*freeval)) +{ + return g_hash_table_new_full(g_str_hash, g_str_equal, freekey, freeval); +} + +void * +hash_table_fetch(void *hashtable, char *key) +{ + return g_hash_table_lookup(hashtable, key); +} + +int +hash_table_insert(void *hashtable, char *key, void *value) +{ + g_hash_table_insert(hashtable, key, value); + return ECORE_CONFIG_ERR_SUCC; +} + +int +hash_table_replace(void *hashtable, char *key, void *value) +{ + g_hash_table_replace(hashtable, key, value); + return ECORE_CONFIG_ERR_SUCC; +} + +int +hash_table_remove(void *hashtable, char *key) +{ + g_hash_table_remove(hashtable, key); + return ECORE_CONFIG_ERR_SUCC; +} + +int +hash_table_dst(void *hashtable) +{ + g_hash_table_destroy(hashtable); + return ECORE_CONFIG_ERR_SUCC; +} + +int +hash_table_walk(void *hashtable, hash_walker fun, void *data) +{ + g_hash_table_foreach(hashtable, (GHFunc) fun, data); + return ECORE_CONFIG_ERR_SUCC; +} + +#else + +void * +hash_table_new(void (*freekey) __UNUSED__, void (*freeval) __UNUSED__) +{ + return NULL; +} + +void * +hash_table_fetch(void *hashtable __UNUSED__, char *key __UNUSED__) +{ + return NULL; +} + +int +hash_table_insert(void *hashtable __UNUSED__, char *key __UNUSED__, void *value __UNUSED__) +{ + return ECORE_CONFIG_ERR_NOTSUPP; +} + +int +hash_table_replace(void *hashtable __UNUSED__, char *key __UNUSED__, void *value __UNUSED__) +{ + return ECORE_CONFIG_ERR_NOTSUPP; +} + +int +hash_table_remove(void *hashtable __UNUSED__, char *key __UNUSED__) +{ + return ECORE_CONFIG_ERR_NOTSUPP; +} + +int +hash_table_dst(void *hashtable __UNUSED__) +{ + return ECORE_CONFIG_ERR_NOTSUPP; +} + +int +hash_table_walk(void *hashtable __UNUSED__, hash_walker fun __UNUSED__, void *data __UNUSED__) +{ + return ECORE_CONFIG_ERR_NOTSUPP; +} + +#endif /* HAVE_GLIB2 */ + +/*****************************************************************************/ +/* STRINGS */ +/***********/ + +estring * +estring_new(int size) +{ + estring *e = malloc(sizeof(estring)); + + if (e) + { + memset(e, 0, sizeof(estring)); + if ((size > 0) && (e->str = malloc(size))) + e->alloc = size; + } + return e; +} + +estring * +estring_dst(estring * e) +{ + if (e) + { + if (e->str) + free(e->str); + free(e); + } + return NULL; +} + +char * +estring_disown(estring * e) +{ + if (e) + { + char *r = e->str; + + free(e); + return r; + } + return NULL; +} + +char * +estring_free(estring * e, int release_payload) +{ /* glib compat */ + if (release_payload) + { + estring_dst(e); + return NULL; + } + return estring_disown(e); +} + +int +estring_truncate(estring * e, int size) +{ + if (!e || (size < 0)) + return ECORE_CONFIG_ERR_FAIL; + if (e->used <= size) + return e->used; + e->str[size] = '\0'; + e->used = size; + return size; +} + +int +estring_printf(estring * e, const char *fmt, ...) +{ + int need; + va_list ap; + char *p; + + if (!e) + return ECORE_CONFIG_ERR_FAIL; + + if (!(e->str)) + { + if (!(e->str = (char *)malloc(e->alloc = 512))) + return ECORE_CONFIG_ERR_OOM; + } + + retry: + va_start(ap, fmt); + need = vsnprintf(e->str, e->alloc, fmt, ap); + va_end(ap); + + if ((need >= e->alloc) || (need < 0)) + { + if (need < 0) + need = 2 * e->alloc; + else + need++; + if (!(p = (char *)realloc(e->str, need))) + { + free(e->str); + e->alloc = e->used = 0; + return ECORE_CONFIG_ERR_OOM; + } + e->alloc = need; + e->str = p; + goto retry; + } + + return e->used = need; +} + +int +estring_appendf(estring * e, const char *fmt, ...) +{ + int need; + va_list ap; + char *p; + + if (!e) + return ECORE_CONFIG_ERR_FAIL; + + if (!e->str) + { + e->used = e->alloc = 0; + if (!(e->str = (char *)malloc(e->alloc = 512))) + return ECORE_CONFIG_ERR_OOM; + } + + retry: + va_start(ap, fmt); + need = vsnprintf(e->str + e->used, e->alloc - e->used, fmt, ap); + va_end(ap); + + if ((need >= (e->alloc - e->used)) || (need < 0)) + { + if (need < 0) + need = 2 * e->alloc; + else + need++; + need += e->used; + need += (CHUNKLEN - (need % CHUNKLEN)); + + if (!(p = (char *)realloc(e->str, need))) + { + free(e->str); + e->alloc = e->used = 0; + return ECORE_CONFIG_ERR_OOM; + } + e->alloc = need; + e->str = p; + goto retry; + } + + return e->used += need; +} + +int +esprintf(char **result, const char *fmt, ...) +{ + int need, have; + va_list ap; + char *n; + + if (!result) + return ECORE_CONFIG_ERR_FAIL; + + if (!(n = (char *)malloc(have = 512))) + return ECORE_CONFIG_ERR_OOM; + + retry: + va_start(ap, fmt); + need = vsnprintf(n, have, fmt, ap); + va_end(ap); + + if ((need >= have) || (need < 0)) + { + char *p; + + if (need < 0) + need = 2 * have; + else + need++; + if (!(p = (char *)realloc(n, need))) + { + free(n); + return ECORE_CONFIG_ERR_OOM; + } + have = need; + n = p; + goto retry; + } + + if (*result) + free(*result); + *result = n; + + return need; +} + +#if 0 +int +ejoin(char **result, char *delim, ...) +{ + int dl, cl, ret = ECORE_CONFIG_ERR_SUCC; + va_list ap; + char *e, *n; + + if (!result) + return ECORE_CONFIG_ERR_FAIL; + if (!delim) + delim = ""; + dl = strlen(delim); + + va_start(ap, delim); + cl = -dl; + while ((e = va_arg(ap, char *))) + cl += strlen(e) + dl; + + va_end(ap); + + if (cl <= 0) + { + if (!(n = strdup(""))) + ret = ECORE_CONFIG_ERR_OOM; + } + else if (!(n = malloc(cl + 1))) + ret = ECORE_CONFIG_ERR_OOM; + else + { + char *p = n; + + va_start(ap, delim); + while ((e = va_arg(ap, char *))) + { + if (dl && (p != n)) + { + strcpy(p, delim); + p += dl; + } + strcpy(p, e); + p += strlen(p); + } + va_end(ap); + } + + if (*result) + free(*result); + *result = n; + + return ret; +} + +int +ecat(char **result, ...) +{ + int cl, ret = ECORE_CONFIG_ERR_SUCC; + va_list ap; + char *e, *n; + + if (!result) + return ECORE_CONFIG_ERR_FAIL; + + va_start(ap, result); + cl = 0; + while ((e = va_arg(ap, char *))) + cl += strlen(e); + + va_end(ap); + + if (cl <= 0) + { + if (!(n = strdup(""))) + ret = ECORE_CONFIG_ERR_OOM; + } + else if (!(n = malloc(cl + 1))) + ret = ECORE_CONFIG_ERR_OOM; + else + { + char *p = n; + + va_start(ap, result); + while ((e = va_arg(ap, char *))) + { + strcpy(p, e); + p += strlen(p); + } + va_end(ap); + } + + if (*result) + free(*result); + *result = n; + + return ret; +} +#endif + +/*****************************************************************************/ diff --git a/ecore/src/lib/ecore_config/ecore_config_util.h b/ecore/src/lib/ecore_config/ecore_config_util.h new file mode 100644 index 0000000..eff279e --- /dev/null +++ b/ecore/src/lib/ecore_config/ecore_config_util.h @@ -0,0 +1,63 @@ +#define TIMER_STOP 0 +#define TIMER_CONT 1 + +typedef struct _estring +{ + char *str; + int alloc, used; +} estring; + +typedef struct _eslist +{ + void *payload; + struct _eslist *next; +} eslist; + +int parse_line(char *, char **, char **, char **, char **); +char *unit_size(char *size); + +/*unsigned long now(long delay);*/ +void qsrt(void *a[], void *data, int lo, int hi, + int (*compare) (const void *, const void *, + const void *)); +int dlmulti(const char *name, const char *file, int flag, void **libr, + const char *fmt, ...); + +typedef void (*hash_walker) (char *key, void *value, void *data); + +void *hash_table_new(void (*freekey), void (*freeval)); +void *hash_table_fetch(void *hashtable, char *key); +int hash_table_insert(void *hashtable, char *key, void *value); +int hash_table_replace(void *hashtable, char *key, void *value); +int hash_table_remove(void *hashtable, char *key); +int hash_table_dst(void *hashtable); +int hash_table_walk(void *hashtable, hash_walker fun, + void *data); + +int eslist_free(eslist **); +int eslist_next(eslist **); + +#define ESLIST_NEXT(e) (e=e->next) +void *eslist_payload(eslist **); + +#define ESLIST_PAYLOAD(e) ((e)->payload) +int eslist_prepend(eslist **, void *); +int eslist_append(eslist **, void *); + +estring *estring_new(int size); +estring *estring_dst(estring * e); +char *estring_disown(estring * e); +char *estring_free(estring * e, int release_payload); /* glib compat */ +int estring_printf(estring * e, const char *fmt, ...); +int estring_appendf(estring * e, const char *fmt, ...); +int estring_truncate(estring * e, int size); + +#define ESTRING_GET_CSTRING(a) ((a)->str) + +int esprintf(char **result, const char *fmt, ...); +int ejoin(char **result, const char *delim, ...); +int ecat(char **result, ...); + +unsigned long timeout_add(unsigned int f, int (*fun) (void *), + void *data); +int timeout_remove(unsigned long handle); diff --git a/ecore/src/lib/ecore_dbus/.cvsignore b/ecore/src/lib/ecore_dbus/.cvsignore new file mode 100644 index 0000000..33d062e --- /dev/null +++ b/ecore/src/lib/ecore_dbus/.cvsignore @@ -0,0 +1,7 @@ +.deps +.libs +Ecore_Con.h +Makefile +Makefile.in +*.lo +libecore_dbus.la diff --git a/ecore/src/lib/ecore_dbus/CVS/Entries b/ecore/src/lib/ecore_dbus/CVS/Entries new file mode 100644 index 0000000..c6fd67d --- /dev/null +++ b/ecore/src/lib/ecore_dbus/CVS/Entries @@ -0,0 +1,6 @@ +/.cvsignore/1.2/Mon Jun 6 09:41:44 2005//THEAD +/Ecore_DBus.h/1.2/Fri Jun 10 02:41:37 2005//THEAD +/Makefile.am/1.3/Fri Apr 29 09:45:12 2005//THEAD +/ecore_dbus.c/1.3/Fri Jun 10 02:41:37 2005//THEAD +/ecore_dbus_private.h/1.1/Fri Apr 29 05:29:29 2005//THEAD +D diff --git a/ecore/src/lib/ecore_dbus/CVS/Repository b/ecore/src/lib/ecore_dbus/CVS/Repository new file mode 100644 index 0000000..a763d9e --- /dev/null +++ b/ecore/src/lib/ecore_dbus/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/src/lib/ecore_dbus diff --git a/ecore/src/lib/ecore_dbus/CVS/Root b/ecore/src/lib/ecore_dbus/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/src/lib/ecore_dbus/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/src/lib/ecore_dbus/CVS/Tag b/ecore/src/lib/ecore_dbus/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/src/lib/ecore_dbus/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/src/lib/ecore_dbus/Ecore_DBus.h b/ecore/src/lib/ecore_dbus/Ecore_DBus.h new file mode 100644 index 0000000..3087a20 --- /dev/null +++ b/ecore/src/lib/ecore_dbus/Ecore_DBus.h @@ -0,0 +1,209 @@ +#ifndef _ECORE_DBUS_H +#define _ECORE_DBUS_H +#endif + +#ifdef EAPI +#undef EAPI +#endif +#ifdef WIN32 +# ifdef BUILDING_DLL +# define EAPI __declspec(dllexport) +# else +# define EAPI __declspec(dllimport) +# endif +#else +# ifdef GCC_HASCLASSVISIBILITY +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct _Ecore_DBus_Server Ecore_DBus_Server; + typedef struct _Ecore_DBus_Client Ecore_DBus_Client; + typedef struct _Ecore_DBus_Event_Server_Add Ecore_DBus_Event_Server_Add; + typedef struct _Ecore_DBus_Event_Server_Del Ecore_DBus_Event_Server_Del; + typedef struct _Ecore_DBus_Event_Server_Data Ecore_DBus_Event_Server_Data; + typedef struct _Ecore_DBus_Message Ecore_DBus_Message; + typedef struct _Ecore_DBus_Message_Field Ecore_DBus_Message_Field; + typedef struct _Ecore_DBus_Auth Ecore_DBus_Auth; + typedef unsigned char* (*Ecore_DBus_Auth_Transaction)(void*); + + typedef enum _Ecore_DBus_Type + { + ECORE_DBUS_BUS_SESSION, + ECORE_DBUS_BUS_SYSTEM, + ECORE_DBUS_BUS_ACTIVATION + } Ecore_DBus_Type; + + typedef enum _Ecore_DBus_Message_Type + { + ECORE_DBUS_MESSAGE_TYPE_INVALID, + ECORE_DBUS_MESSAGE_TYPE_METHOD_CALL, + ECORE_DBUS_MESSAGE_TYPE_METHOD_RETURN, + ECORE_DBUS_MESSAGE_TYPE_ERROR, + ECORE_DBUS_MESSAGE_TYPE_SIGNAL + } Ecore_DBus_Message_Type; + + /* message data types */ + typedef enum _Ecore_DBus_Data_Type + { + ECORE_DBUS_DATA_TYPE_INVALID = ((int) '\0'), + ECORE_DBUS_DATA_TYPE_NIL = ((int) '\0'), + ECORE_DBUS_DATA_TYPE_BYTE = ((int) 'y'), + ECORE_DBUS_DATA_TYPE_BOOLEAN = ((int) 'b'), /* 0,1 */ + ECORE_DBUS_DATA_TYPE_INT32 = ((int) 'i'), + ECORE_DBUS_DATA_TYPE_UINT32 =((int) 'u'), + ECORE_DBUS_DATA_TYPE_INT64 = ((int) 'x'), + ECORE_DBUS_DATA_TYPE_UINT64 = ((int) 't'), + ECORE_DBUS_DATA_TYPE_DOUBLE = ((int) 'd'), + ECORE_DBUS_DATA_TYPE_STRING = ((int) 's'), + ECORE_DBUS_DATA_TYPE_CUSTOM = ((int) 'c'), + ECORE_DBUS_DATA_TYPE_ARRAY =((int) 'a'), + ECORE_DBUS_DATA_TYPE_DICT = ((int) 'm'), + ECORE_DBUS_DATA_TYPE_OBJECT_PATH = ((int) 'o') + } Ecore_DBus_Data_Type; + + typedef enum _Ecore_DBus_Message_Header_Field + { + ECORE_DBUS_HEADER_FIELD_INVALID, + ECORE_DBUS_HEADER_FIELD_PATH, + ECORE_DBUS_HEADER_FIELD_INTERFACE, + ECORE_DBUS_HEADER_FIELD_MEMBER, + ECORE_DBUS_HEADER_FIELD_ERROR_NAME, + ECORE_DBUS_HEADER_FIELD_REPLY_SERIAL, + ECORE_DBUS_HEADER_FIELD_DESTINATION, + ECORE_DBUS_HEADER_FIELD_SENDER, + ECORE_DBUS_HEADER_FIELD_SIGNATURE + } Ecore_DBus_Message_Header_Field; + + typedef enum _Ecore_DBus_Auth_Type + { + ECORE_DBUS_AUTH_TYPE_EXTERNAL, + ECORE_DBUS_AUTH_MAGIC_COOKIE, + ECORE_DBUS_AUTH_TYPE_DBUS_COOKIE_SHA1, + ECORE_DBUS_AUTH_TYPE_KERBEROS_V4, + ECORE_DBUS_AUTH_TYPE_SKEY + } Ecore_DBus_Auth_Type; + + struct _Ecore_DBus_Auth + { + char *name; + unsigned int num_transactions; + Ecore_DBus_Auth_Transaction transactions[5]; + }; + + struct _Ecore_DBus_Event_Server_Add + { + Ecore_DBus_Server *server; + }; + + struct _Ecore_DBus_Event_Server_Del + { + Ecore_DBus_Server *server; + }; + + struct _Ecore_DBus_Message_Field + { + Ecore_List __list_data; + Ecore_DBus_Data_Type type; + unsigned int offset; + unsigned int count; /* number of elements, usefull for structs, arrays, dicts */ + unsigned int hfield; /* if the field is a header field, we need the type of it */ + }; + + struct _Ecore_DBus_Message + { + /* header fields */ + unsigned char byte_order; + unsigned char type; + unsigned char flags; + unsigned char protocol; + unsigned long hlength; + unsigned long blength; + unsigned long serial; + + Ecore_DBus_Server *ref_server; + + unsigned char *header; + unsigned int hpos; + Ecore_DBus_Message_Field *header_fields; + unsigned char *body; + unsigned int bpos; + Ecore_DBus_Message_Field *body_fields; + unsigned char *signature; + }; + + extern int ECORE_DBUS_EVENT_SERVER_ADD; + extern int ECORE_DBUS_EVENT_SERVER_DATA; + + /* Message byte order */ +#define DBUS_LITTLE_ENDIAN ('l') /* LSB first */ +#define DBUS_BIG_ENDIAN ('B') /* MSB first */ + + /* Protocol version */ +#define DBUS_MAJOR_PROTOCOL_VERSION 0 + + + /* Max length in bytes of a service or interface or member name */ +#define DBUS_MAXIMUM_NAME_LENGTH 256 + + /* Max length of a match rule string */ +#define DBUS_MAXIMUM_MATCH_RULE_LENGTH 1024 + + + /* Header flags */ +#define DBUS_HEADER_FLAG_NO_REPLY_EXPECTED 0x1 +#define DBUS_HEADER_FLAG_AUTO_ACTIVATION 0x2 + + +#define DBUS_HEADER_FIELD_LAST DBUS_HEADER_FIELD_SIGNATURE + + /* Services */ +#define DBUS_SERVICE_ORG_FREEDESKTOP_DBUS "org.freedesktop.DBus" + + /* Paths */ +#define DBUS_PATH_ORG_FREEDESKTOP_DBUS "/org/freedesktop/DBus" +#define DBUS_PATH_ORG_FREEDESKTOP_LOCAL "/org/freedesktop/Local" + + /* Interfaces, these #define don't do much other than + * * catch typos at compile time + * */ +#define DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS "org.freedesktop.DBus" +#define DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE "org.freedesktop.Introspectable" + + /* This is a special interface whose methods can only be invoked + * by the local implementation (messages from remote apps aren't + * allowed to specify this interface). + */ +#define DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL "org.freedesktop.Local" + /* Service owner flags */ +#define DBUS_SERVICE_FLAG_PROHIBIT_REPLACEMENT 0x1 +#define DBUS_SERVICE_FLAG_REPLACE_EXISTING 0x2 + + /* Service replies */ +#define DBUS_SERVICE_REPLY_PRIMARY_OWNER 0x1 +#define DBUS_SERVICE_REPLY_IN_QUEUE 0x2 +#define DBUS_SERVICE_REPLY_SERVICE_EXISTS 0x4 +#define DBUS_SERVICE_REPLY_ALREADY_OWNER 0x8 + + /* Activation replies */ +#define DBUS_ACTIVATION_REPLY_ACTIVATED 0x0 +#define DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE 0x1 + + /* connection */ + EAPI int ecore_dbus_init(void); + EAPI Ecore_DBus_Server* ecore_dbus_server_connect(Ecore_DBus_Type compl_type, char *name, int port, const void *data); + /* message */ + EAPI unsigned int ecore_dbus_message_new_method_call(Ecore_DBus_Server *svr,char *service,char *path,char *interface,char *method,char *fmt, ...); + EAPI void ecore_dbus_message_print(Ecore_DBus_Message *msg); + EAPI void * ecore_dbus_get_header_field(Ecore_DBus_Message *,Ecore_DBus_Message_Field *, Ecore_DBus_Message_Header_Field); + EAPI void * ecore_dbus_get_body_field(Ecore_DBus_Message *,Ecore_DBus_Message_Field *, unsigned int); + +#ifdef __cplusplus +} +#endif diff --git a/ecore/src/lib/ecore_dbus/Makefile.am b/ecore/src/lib/ecore_dbus/Makefile.am new file mode 100644 index 0000000..3758ca7 --- /dev/null +++ b/ecore/src/lib/ecore_dbus/Makefile.am @@ -0,0 +1,39 @@ +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_con \ +-I$(top_builddir)/src/lib/ecore_dbus \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_con \ +-I$(top_srcdir)/src/lib/ecore_dbus \ +@SSL_CFLAGS@ + +libecore_dbus_la_LDFLAGS = -version-info 1:0:0 \ +-L$(top_builddir)/src/lib/ecore/.libs \ +-L$(top_builddir)/src/lib/ecore_con/.libs + +if BUILD_ECORE_DBUS + +lib_LTLIBRARIES = libecore_dbus.la +include_HEADERS = \ +Ecore_DBus.h + +libecore_dbus_la_SOURCES = \ +ecore_dbus.c \ +ecore_dbus_private.h + +libecore_dbus_la_LIBADD = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(top_builddir)/src/lib/ecore_con/libecore_con.la \ +@SSL_LIBS@ + +libecore_dbus_la_DEPENDENCIES = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(top_builddir)/src/lib/ecore_con/libecore_con.la + +endif + +EXTRA_DIST = \ +ecore_dbus.c \ +ecore_dbus_private.h diff --git a/ecore/src/lib/ecore_dbus/ecore_dbus.c b/ecore/src/lib/ecore_dbus/ecore_dbus.c new file mode 100644 index 0000000..6f2e1a6 --- /dev/null +++ b/ecore/src/lib/ecore_dbus/ecore_dbus.c @@ -0,0 +1,1235 @@ +#include +#include +#include +#include +#include +#include + +#include "Ecore.h" +#include "ecore_private.h" +#include "Ecore_Con.h" +#include "Ecore_DBus.h" +#include "ecore_dbus_private.h" + +/********************************************************************************/ +/* About */ +/********************************************************************************/ +/* Author: Jorge Luis Zapata */ +/* Version: 0.2.1 */ +/********************************************************************************/ +/* Todo */ +/********************************************************************************/ +/* free allocated data */ +/* make other authentication mechanisms besides external */ +/********************************************************************************/ +/* Changelog */ +/********************************************************************************/ +/* 0.0 usable interface */ +/* 0.1 change dbus spec version (0.11): */ +/* different header format */ +/* new type signature */ +/* header length = 8 byte multiple */ +/* paddings value must be null */ +/* body need not to end in a 8 byte boundary */ +/* new data type: variant,signature,dict */ +/* ecore_oldlist cant join two lists so is difficult to handle compound */ +/* data types (variant,struct,dict,array) in a stack way */ +/* 0.2 change again the spec version (0.8) */ +/* i realized that the first version was correct, when i read the spec */ +/* for ecore_dbus 0.1 i was reading a previous version :( */ +/* put again the data type byte in each marshaled data */ +/* */ +/* 29-03-05 */ +/* 0.2.1 some segfault fixes, new tests */ + +static int ecore_dbus_server_send(Ecore_DBus_Server * svr, + char *command, int length); +Ecore_Oldlist *_ecore_dbus_message_print_field(Ecore_Oldlist * l, + unsigned char *buf); +void _ecore_dbus_message_print_raw(unsigned char *msg, + unsigned int msg_len); + +/**********************/ +/* ecore dbus message */ +/**********************/ + +#define BODY_LEN 64 +#define HEADER_LEN 16 + +/* length functions */ +/********************/ +/* all of these increase the length */ +void +_ecore_dbus_message_increase_lengthz(unsigned char **buf, + unsigned int old_length, unsigned int size) +{ + *buf = realloc(*buf, old_length + size); + memset(*buf + old_length, 0, size); +} + +void +_ecore_dbus_message_increase_length(unsigned char **buf, + unsigned int new_length) +{ + *buf = realloc(*buf, new_length); +} + +/* padding functions */ +/*********************/ +/* all of these increase the length */ +void +_ecore_dbus_message_4byte_padding(unsigned char **buf, unsigned int *old_length) +{ + unsigned int padding; + + padding = *old_length % 4; + if (padding != 0) + { + padding = 4 - padding; + _ecore_dbus_message_increase_lengthz(buf, *old_length, padding); + } + *old_length += padding; +} +void +_ecore_dbus_message_8byte_padding(unsigned char **buf, unsigned int *old_length) +{ + unsigned int padding; + + padding = *old_length % 8; + if (padding != 0) + { + padding = 8 - padding; + _ecore_dbus_message_increase_lengthz(buf, *old_length, padding); + } + *old_length += padding; +} + +void +_ecore_dbus_message_skip_8byte_padding(unsigned int *old_length) +{ + unsigned int padding; + + padding = *old_length % 8; + if (padding != 0) + *old_length += 8 - padding; + return; +} + +void +_ecore_dbus_message_skip_4byte_padding(unsigned int *old_length) /* DONE */ +{ + unsigned int padding; + + padding = *old_length % 4; + if (padding != 0) + *old_length += 4 - padding; + return; +} + +/* appending/reading functions */ +/*******************************/ +/* non of these increase the length */ +void +_ecore_dbus_message_append_nbytes(unsigned char *buf, unsigned char *data, + unsigned int data_length) +{ + memcpy(buf, data, data_length); +} + +void +_ecore_dbus_message_append_byte(unsigned char *buf, unsigned char c) +{ + *buf = c; +} + +void +_ecore_dbus_message_append_uint32(unsigned char *buf, unsigned long int i) +{ + unsigned char *c; + + c = (unsigned char *)&i; + *(buf + 0) = *(c + 0); + *(buf + 1) = *(c + 1); + *(buf + 2) = *(c + 2); + *(buf + 3) = *(c + 3); +} + +unsigned long +_ecore_dbus_message_read_uint32(unsigned char *buf) +{ + return *(unsigned long *)buf; +} + +unsigned char +_ecore_dbus_message_read_byte(unsigned char *buf) +{ + return *(unsigned char *)buf; +} + +/* field functions */ +/*******************/ + +/* memory allocation */ +/**********************/ +Ecore_DBus_Message * +_ecore_dbus_message_new(Ecore_DBus_Server * svr) +{ + Ecore_DBus_Message *msg = calloc(1, sizeof(Ecore_DBus_Message)); + + msg->ref_server = svr; + msg->body_fields = NULL; + msg->header_fields = NULL; + msg->hpos = 0; + msg->bpos = 0; + msg->header = NULL; + msg->body = NULL; + msg->hlength = 0; + msg->blength = 0; + return msg; +} + +Ecore_DBus_Message_Field * +_ecore_dbus_message_new_field(Ecore_DBus_Data_Type type, unsigned int offset) +{ + Ecore_DBus_Message_Field *f; + + f = malloc(sizeof(Ecore_DBus_Message_Field)); + f->offset = offset; + f->type = type; + f->count = 0; + return f; +} + +void +_ecore_dbus_message_free(void *data, void *ev) +{ + Ecore_DBus_Message *msg = ev; + Ecore_Oldlist *l = (Ecore_Oldlist *) msg->body_fields; + Ecore_Oldlist *next; + + while (l) + { + next = l->next; + free(l); + l = next; + } + l = (Ecore_Oldlist *) msg->header_fields; + while (l) + { + next = l->next; + free(l); + l = next; + } + free(msg->header); + free(msg->body); + free(msg); +} + +/* signature functions */ +/***********************/ + +/* marshal functions */ +/*********************/ + +/* cambiar todos los *msg por char** asi se podra cambiar el puntero sin problemas */ +/* agregarle el parametro de signature por si se quiere q agregue una variable al signature */ +/* y pasarle la lista de campos por si pone el argumento en la lista del header o del body */ + +Ecore_DBus_Message_Field * +_ecore_dbus_message_marshal_byte(unsigned char **buf, unsigned int *old_length, + unsigned char c) +{ + Ecore_DBus_Message_Field *f; + + _ecore_dbus_message_increase_length(buf, *old_length + 1); // increase the length + 1, old_length changed + _ecore_dbus_message_append_byte(*buf + *old_length, ECORE_DBUS_DATA_TYPE_BYTE); // append the data type + *old_length += 1; + _ecore_dbus_message_increase_length(buf, *old_length + 1); // increase the length + 1, old_length changed + _ecore_dbus_message_append_byte(*buf + *old_length, c); // append c at cur_length + f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_BYTE, *old_length); // create field + *old_length += 1; + return f; +} + +Ecore_DBus_Message_Field * +_ecore_dbus_message_marshal_uint32(unsigned char **buf, + unsigned int *old_length, + unsigned long int i) +{ + Ecore_DBus_Message_Field *f; + + _ecore_dbus_message_increase_length(buf, *old_length + 1); // increase the length + 1, old_length changed + _ecore_dbus_message_append_byte(*buf + *old_length, ECORE_DBUS_DATA_TYPE_UINT32); // append the data type + *old_length += 1; + _ecore_dbus_message_4byte_padding(buf, old_length); + _ecore_dbus_message_increase_length(buf, *old_length + 4); + _ecore_dbus_message_append_uint32(*buf + *old_length, i); + f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_UINT32, *old_length); + *old_length += 4; + return f; +} + +Ecore_DBus_Message_Field * +_ecore_dbus_message_marshal_path(unsigned char **buf, unsigned int *old_length, + unsigned char *str) +{ + int str_len; + Ecore_DBus_Message_Field *f; + + _ecore_dbus_message_increase_length(buf, *old_length + 1); // increase the length + 1, old_length changed + _ecore_dbus_message_append_byte(*buf + *old_length, ECORE_DBUS_DATA_TYPE_OBJECT_PATH); // append the data type + *old_length += 1; + + str_len = strlen((char *)str); + _ecore_dbus_message_4byte_padding(buf, old_length); + _ecore_dbus_message_increase_length(buf, *old_length + 4); + f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_OBJECT_PATH, + *old_length); + _ecore_dbus_message_append_uint32(*buf + *old_length, str_len); + *old_length += 4; + _ecore_dbus_message_increase_length(buf, *old_length + str_len + 1); // for the \n + _ecore_dbus_message_append_nbytes(*buf + *old_length, str, str_len + 1); // append all the string including \n + *old_length += str_len + 1; + + return f; +} + +Ecore_DBus_Message_Field * +_ecore_dbus_message_marshal_string(unsigned char **buf, + unsigned int *old_length, unsigned char *str) +{ + int str_len; + Ecore_DBus_Message_Field *f; + + _ecore_dbus_message_increase_length(buf, *old_length + 1); // increase the length + 1, new_length changed + _ecore_dbus_message_append_byte(*buf + *old_length, ECORE_DBUS_DATA_TYPE_STRING); // append the data type + *old_length += 1; // old_length = new_length + + str_len = strlen((char *)str); + _ecore_dbus_message_4byte_padding(buf, old_length); + _ecore_dbus_message_increase_length(buf, *old_length + 4); + f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_STRING, *old_length); + _ecore_dbus_message_append_uint32(*buf + *old_length, str_len); + *old_length += 4; + _ecore_dbus_message_increase_length(buf, *old_length + str_len + 1); // for the \n + _ecore_dbus_message_append_nbytes(*buf + *old_length, str, str_len + 1); // append all the string including \n + *old_length += str_len + 1; + return f; +} + +Ecore_DBus_Message_Field * +_ecore_dbus_message_marshal_array(unsigned char **msg, unsigned int *old_length) +{ + Ecore_DBus_Message_Field *f; + + _ecore_dbus_message_8byte_padding(msg, old_length); + _ecore_dbus_message_increase_length(msg, *old_length + 4); // for the array length value + f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_ARRAY, *old_length); + *old_length += 4; + return f; +} + +Ecore_DBus_Message_Field * +_ecore_dbus_message_marshal_data(unsigned char **buf, unsigned int *old_length, + Ecore_DBus_Data_Type type, void *data) +{ + Ecore_DBus_Message_Field *f = NULL; + + switch (type) + { + case ECORE_DBUS_DATA_TYPE_UINT32: + f = _ecore_dbus_message_marshal_uint32(buf, old_length, + *(unsigned long *)data); + break; + case ECORE_DBUS_DATA_TYPE_STRING: + f = _ecore_dbus_message_marshal_string(buf, old_length, + (unsigned char *)data); + break; + case ECORE_DBUS_DATA_TYPE_OBJECT_PATH: + f = _ecore_dbus_message_marshal_path(buf, old_length, + (unsigned char *)data); + break; + case ECORE_DBUS_DATA_TYPE_INVALID: + case ECORE_DBUS_DATA_TYPE_BYTE: + case ECORE_DBUS_DATA_TYPE_BOOLEAN: + case ECORE_DBUS_DATA_TYPE_INT32: + case ECORE_DBUS_DATA_TYPE_INT64: + case ECORE_DBUS_DATA_TYPE_UINT64: + case ECORE_DBUS_DATA_TYPE_DOUBLE: + case ECORE_DBUS_DATA_TYPE_CUSTOM: + case ECORE_DBUS_DATA_TYPE_ARRAY: + case ECORE_DBUS_DATA_TYPE_DICT: + default: + printf("[ecore_dbus] unknown/unhandled data type %c\n", type); + break; + } + return f; +} + +Ecore_DBus_Message_Field * +_ecore_dbus_message_marshal_custom_header(unsigned char **buf, + unsigned int *old_length, + unsigned int code, + Ecore_DBus_Data_Type type, void *data) +{ + Ecore_DBus_Message_Field *f; + + _ecore_dbus_message_increase_length(buf, *old_length + 1); // increase the length + 1, old_length changed + _ecore_dbus_message_append_byte(*buf + *old_length, code); // append header field name at cur_length + *old_length += 1; + f = _ecore_dbus_message_marshal_data(buf, old_length, type, data); // marshal header field data + f->hfield = code; + return f; +} + +/* unmarshal functions */ +/***********************/ + +Ecore_DBus_Message_Field * +_ecore_dbus_message_unmarshal_int32(unsigned char *buf, + unsigned int *old_length) +{ + Ecore_DBus_Message_Field *f; + + _ecore_dbus_message_skip_4byte_padding(old_length); + f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_INT32, *old_length); + *old_length += 4; + return f; + +} + +Ecore_DBus_Message_Field * +_ecore_dbus_message_unmarshal_uint32(unsigned char *buf, + unsigned int *old_length) +{ + Ecore_DBus_Message_Field *f; + + _ecore_dbus_message_skip_4byte_padding(old_length); + f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_UINT32, *old_length); + *old_length += 4; + return f; + +} + +Ecore_DBus_Message_Field * +_ecore_dbus_message_unmarshal_string(unsigned char *buf, + unsigned int *old_length) +{ + Ecore_DBus_Message_Field *f; + unsigned long str_len; + + _ecore_dbus_message_skip_4byte_padding(old_length); + f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_STRING, *old_length); + str_len = _ecore_dbus_message_read_uint32(buf + *old_length); + *old_length += 4; + *old_length += str_len + 1; + return f; +} + +Ecore_DBus_Message_Field * +_ecore_dbus_message_unmarshal_path(unsigned char *buf, unsigned int *old_length) +{ + Ecore_DBus_Message_Field *f; + unsigned long str_len; + + _ecore_dbus_message_skip_4byte_padding(old_length); + f = _ecore_dbus_message_new_field(ECORE_DBUS_DATA_TYPE_OBJECT_PATH, + *old_length); + str_len = _ecore_dbus_message_read_uint32(buf + *old_length); + *old_length += 4; + *old_length += str_len + 1; + return f; +} + +Ecore_DBus_Message_Field * +_ecore_dbus_message_unmarshal_data(unsigned char *buf, unsigned int *old_length) +{ + Ecore_DBus_Message_Field *f = NULL; + unsigned char type = _ecore_dbus_message_read_byte(buf + *old_length); + + *old_length += 1; + switch (type) + { + case ECORE_DBUS_DATA_TYPE_INT32: + f = _ecore_dbus_message_unmarshal_int32(buf, old_length); + break; + case ECORE_DBUS_DATA_TYPE_UINT32: + f = _ecore_dbus_message_unmarshal_uint32(buf, old_length); + break; + case ECORE_DBUS_DATA_TYPE_STRING: + f = _ecore_dbus_message_unmarshal_string(buf, old_length); + break; + case ECORE_DBUS_DATA_TYPE_OBJECT_PATH: + f = _ecore_dbus_message_unmarshal_path(buf, old_length); + break; + case ECORE_DBUS_DATA_TYPE_BYTE: + case ECORE_DBUS_DATA_TYPE_BOOLEAN: + case ECORE_DBUS_DATA_TYPE_INT64: + case ECORE_DBUS_DATA_TYPE_UINT64: + case ECORE_DBUS_DATA_TYPE_DOUBLE: + case ECORE_DBUS_DATA_TYPE_CUSTOM: + case ECORE_DBUS_DATA_TYPE_ARRAY: + case ECORE_DBUS_DATA_TYPE_DICT: + case ECORE_DBUS_DATA_TYPE_INVALID: + default: + printf("[ecore_dbus] unknown/unhandled data type %c\n", type); + break; + } + return f; +} + +Ecore_DBus_Message_Field * +_ecore_dbus_message_unmarshal_custom_header(unsigned char *buf, + unsigned int *old_length) +{ + Ecore_DBus_Message_Field *f; + unsigned int code; + + code = _ecore_dbus_message_read_byte(buf + *old_length); // get header field name at cur_length + *old_length += 1; + f = _ecore_dbus_message_unmarshal_data(buf, old_length); // unmarshal header field data + f->hfield = code; + return f; +} + +Ecore_DBus_Message * +_ecore_dbus_message_unmarshal(Ecore_DBus_Server * svr, unsigned char *message) +{ + Ecore_DBus_Message_Field *f; + + /* init */ + /********/ + Ecore_DBus_Message *msg = _ecore_dbus_message_new(svr); + + printf("[ecore_dbus] unmarshaling\n"); + /* message header */ + /******************/ + /* common fields */ + msg->byte_order = *(message + 0); + msg->type = *(message + 1); + msg->flags = *(message + 2); + msg->protocol = *(message + 3); + msg->hlength = *(unsigned long *)(message + 4); + msg->blength = *(unsigned long *)(message + 8); + msg->serial = *(unsigned long *)(message + 12); + if (msg->type == ECORE_DBUS_MESSAGE_TYPE_INVALID) + { + printf("[ecore_dbus] message type invalid\n"); + return NULL; + } + /* memcpy the header part */ + _ecore_dbus_message_increase_length(&msg->header, msg->hlength); + _ecore_dbus_message_append_nbytes(msg->header, message, msg->hlength); + msg->hpos += 16; + /* custom fields */ + while ((msg->hpos + 8 - (msg->hpos % 8)) < msg->hlength) + { + f = _ecore_dbus_message_unmarshal_custom_header(message, &msg->hpos); + msg->header_fields = _ecore_list_append(msg->header_fields, f); + } + msg->hpos = msg->hlength; + /* message body */ + /****************/ + message += msg->hlength; + _ecore_dbus_message_increase_length(&msg->body, msg->blength); + _ecore_dbus_message_append_nbytes(msg->body, message, msg->blength); + while (msg->bpos < msg->blength) + { + f = _ecore_dbus_message_unmarshal_data(message, &msg->bpos); + msg->body_fields = _ecore_list_append(msg->body_fields, f); + + } + return msg; +} + +/* header functions */ +/********************/ +void +_ecore_dbus_message_common_header(Ecore_DBus_Message * msg, int type, int flags) +{ + _ecore_dbus_message_increase_lengthz(&msg->header, msg->hpos, 16); // the body,header length arent filled only alloc + msg->header[0] = msg->byte_order = 'l'; // endiannes (1) + msg->header[1] = msg->type = (char)type; // type (1) + msg->header[2] = msg->flags = 0x0; // flags (1) 0x1 = no reply expected, 0x2 auto activiation + msg->header[3] = msg->protocol = 0x0; // protocol (1) + msg->ref_server->cnt_msg++; // autoincrement the client_serial (0 is invalid) + *(msg->header + 12) = msg->serial = msg->ref_server->cnt_msg; + msg->hpos = 16; +} + +void * +_ecore_dbus_get_field(unsigned char *buf, Ecore_DBus_Message_Field * f) +{ + switch (f->type) + { + case ECORE_DBUS_DATA_TYPE_INT32: + case ECORE_DBUS_DATA_TYPE_UINT32: + case ECORE_DBUS_DATA_TYPE_BYTE: + case ECORE_DBUS_DATA_TYPE_BOOLEAN: + case ECORE_DBUS_DATA_TYPE_INT64: + case ECORE_DBUS_DATA_TYPE_UINT64: + case ECORE_DBUS_DATA_TYPE_DOUBLE: + return buf + f->offset; + break; + case ECORE_DBUS_DATA_TYPE_STRING: + case ECORE_DBUS_DATA_TYPE_OBJECT_PATH: + return buf + f->offset + 4; + break; + case ECORE_DBUS_DATA_TYPE_CUSTOM: + case ECORE_DBUS_DATA_TYPE_ARRAY: + case ECORE_DBUS_DATA_TYPE_DICT: + case ECORE_DBUS_DATA_TYPE_INVALID: + default: + printf("[ecore_dbus] unknown/unhandled data type %c\n", f->type); + break; + + } + return NULL; +} + +void * +ecore_dbus_get_body_field(Ecore_DBus_Message * m, Ecore_DBus_Message_Field * mf, + unsigned int pos) +{ + Ecore_Oldlist *l, *list; + + list = (Ecore_Oldlist *) mf; + unsigned int i = 0; + + for (l = list; l; l = l->next) + { + if (i == pos) + return _ecore_dbus_get_field(m->body, + (Ecore_DBus_Message_Field *) l); + i++; + } + return NULL; +} + +void * +ecore_dbus_get_header_field(Ecore_DBus_Message * m, + Ecore_DBus_Message_Field * mf, + Ecore_DBus_Message_Header_Field hft) +{ + Ecore_Oldlist *l, *list; + + list = (Ecore_Oldlist *) mf; + for (l = list; l; l = l->next) + if (((Ecore_DBus_Message_Field *) l)->hfield == hft) + return _ecore_dbus_get_field(m->header, + (Ecore_DBus_Message_Field *) l); + return NULL; +} + +/* printing functions */ +/**********************/ +Ecore_Oldlist * +_ecore_dbus_message_print_field(Ecore_Oldlist * l, unsigned char *buf) +{ + int i; + Ecore_DBus_Message_Field *f; + + f = (Ecore_DBus_Message_Field *) l; + switch (f->type) + { + case ECORE_DBUS_DATA_TYPE_BYTE: + printf + ("[ecore_dbus] field BYTE : value offset = %d value = %d\n", + f->offset, (char)*(buf + f->offset)); + break; + case ECORE_DBUS_DATA_TYPE_OBJECT_PATH: + printf + ("[ecore_dbus] field PATH : value offset = %d length = %d value = %s\n", + f->offset, *(buf + f->offset), (buf + f->offset + 4)); + break; + case ECORE_DBUS_DATA_TYPE_STRING: + printf + ("[ecore_dbus] field STRING : value offset = %d length = %d value = %s\n", + f->offset, *(buf + f->offset), (buf + f->offset + 4)); + break; + case ECORE_DBUS_DATA_TYPE_INT32: + printf + ("[ecore_dbus] field INT32 : value offset = %d value = %ld\n", + f->offset, (long int)*(buf + f->offset)); + break; + case ECORE_DBUS_DATA_TYPE_UINT32: + printf + ("[ecore_dbus] field UINT32 : value offset = %d value = %lu\n", + f->offset, (unsigned long int)*(buf + f->offset)); + break; + case ECORE_DBUS_DATA_TYPE_ARRAY: + printf + ("[ecore_dbus] field ARRAY : value offset = %d length = %lu elements = %u\n", + f->offset, *(unsigned long int *)(buf + f->offset), f->count); + printf("[ecore_dbus] * ARRAY elements begin *\n"); + l = l->next; + for (i = 0; i < f->count; i++) + l = _ecore_dbus_message_print_field(l, buf); + printf("[ecore_dbus] * ARRAY elements end *\n"); + return l; + break; + default: + printf("[ecore_dbus] field !UNKNOWN! : %c\n", f->type); + break; + } + return l->next; +} + +Ecore_Oldlist * +_ecore_dbus_message_print_header_field(Ecore_Oldlist * l, unsigned char *buf) +{ + static const char *header_fields[] = + { "INVALID", "PATH", "INTERFACE", "MEMBER", "ERROR_NAME", "REPLY_SERIAL", +"DESTINATION", "SERIAL", "SIGNATURE" }; + Ecore_DBus_Message_Field *f; + + f = (Ecore_DBus_Message_Field *) l; + printf("[ecore_dbus] header field %s ", header_fields[f->hfield]); + l = _ecore_dbus_message_print_field(l, buf); + return l; +} + +void +_ecore_dbus_message_print_fields(Ecore_DBus_Message_Field * f) +{ + int i = 0; + Ecore_Oldlist *l; + + l = (Ecore_Oldlist *) f; + while (l) + { + printf("%d\n", i); + l = l->next; + i++; + } + +} + +void +_ecore_dbus_message_print_raw(unsigned char *msg, unsigned int msg_len) +{ + int i; + + printf("[ecore_dbus] raw message:\n"); + for (i = 0; i < msg_len; i++) + { + if (msg[i] == 0) + printf(","); + else if (msg[i] < 21) + printf("*"); + else + printf("%c", msg[i]); + } + printf("\n"); + printf("[ecore_dbus] end raw message\n"); +} + +void +ecore_dbus_message_print(Ecore_DBus_Message * msg) +{ + Ecore_Oldlist *list; + static const char *msg_type[] = + { "INVALID", "METHOD_CALL", "METHOD_RETURN", "ERROR", "SIGNAL" }; + printf("[ecore_dbus] per field message:\n"); + printf("[ecore_dbus] header fields:\n"); + /* header common fields */ + printf("[ecore_dbus] header endianess : %c\n", msg->byte_order); + printf("[ecore_dbus] header type : %s\n", msg_type[msg->type]); + printf("[ecore_dbus] header flags : %c\n", msg->flags + 48); + printf("[ecore_dbus] header protocol : %c\n", msg->protocol + 48); + printf("[ecore_dbus] header hlength : %u\n", + *(unsigned int *)(msg->header + 4)); + printf("[ecore_dbus] header blength : %lu\n", msg->blength); + printf("[ecore_dbus] header serial : %lu\n", msg->serial); + + /* header custom fields */ + list = (Ecore_Oldlist *) msg->header_fields; + while (list) + { + list = _ecore_dbus_message_print_header_field(list, msg->header); + } + /* body fields */ + printf("[ecore_dbus] body fields:\n"); + list = (Ecore_Oldlist *) msg->body_fields; + while (list) + { + list = _ecore_dbus_message_print_field(list, msg->body); + } + printf("[ecore_dbus] end per field message\n"); + +} + +/* message type functions */ +/**************************/ +/* podria retornar el id del mensaje, para asi saber las respuestas y poderlas referenciar en el cliente */ +/* la idea aca seria hacer una funcion q llame metodos remotos, or ej: ("org.freedesktop.DBus", "/org/freedesktop/DBus","org.freedesktop.DBus","AddMatch","%s",rule);*/ +/* el parsing de los argumentos a la funcion podrian ser similares al printf s = string, d = int, f = float etc */ + +unsigned int +ecore_dbus_message_new_method_call(Ecore_DBus_Server * svr, char *service, + char *path, char *interface, char *method, + char *fmt, ...) +{ + va_list ap; + + Ecore_DBus_Message_Field *f; + + /* init message */ + Ecore_DBus_Message *msg = _ecore_dbus_message_new(svr); + + /* common header */ + _ecore_dbus_message_common_header(msg, ECORE_DBUS_MESSAGE_TYPE_METHOD_CALL, + 0); + /* custom header */ + if (path) + { + f = _ecore_dbus_message_marshal_custom_header(&msg->header, &msg->hpos, + 1, + ECORE_DBUS_DATA_TYPE_OBJECT_PATH, + path); + msg->header_fields = _ecore_list_append(msg->header_fields, f); + } + + if (interface) + { + f = _ecore_dbus_message_marshal_custom_header(&msg->header, &msg->hpos, + 2, + ECORE_DBUS_DATA_TYPE_STRING, + interface); + msg->header_fields = _ecore_list_append(msg->header_fields, f); + } + if (method) + { + f = _ecore_dbus_message_marshal_custom_header(&msg->header, &msg->hpos, + 3, + ECORE_DBUS_DATA_TYPE_STRING, + method); + msg->header_fields = _ecore_list_append(msg->header_fields, f); + } + if (service) + { + f = _ecore_dbus_message_marshal_custom_header(&msg->header, &msg->hpos, + 6, + ECORE_DBUS_DATA_TYPE_STRING, + service); + msg->header_fields = _ecore_list_append(msg->header_fields, f); + } + if (fmt) + { + f = _ecore_dbus_message_marshal_custom_header(&msg->header, &msg->hpos, + 8, + ECORE_DBUS_DATA_TYPE_STRING, + fmt); + msg->header_fields = _ecore_list_append(msg->header_fields, f); + } + _ecore_dbus_message_8byte_padding(&msg->header, &msg->hpos); + /* header length */ + *(msg->header + 4) = msg->hlength = msg->hpos; + /* message body */ + va_start(ap, fmt); + while (*fmt) + { + switch (*fmt) + { + case ECORE_DBUS_DATA_TYPE_UINT32: + f = _ecore_dbus_message_marshal_uint32(&msg->body, &msg->bpos, + va_arg(ap, unsigned long)); + msg->body_fields = _ecore_list_append(msg->body_fields, f); + break; + case ECORE_DBUS_DATA_TYPE_STRING: + f = _ecore_dbus_message_marshal_string(&msg->body, &msg->bpos, + (unsigned char *)va_arg(ap, char *)); + msg->body_fields = _ecore_list_append(msg->body_fields, f); + break; + case ECORE_DBUS_DATA_TYPE_OBJECT_PATH: + f = _ecore_dbus_message_marshal_path(&msg->body, &msg->bpos, + (unsigned char *)va_arg(ap, char *)); + msg->body_fields = _ecore_list_append(msg->body_fields, f); + break; + case ECORE_DBUS_DATA_TYPE_INVALID: + case ECORE_DBUS_DATA_TYPE_BYTE: + case ECORE_DBUS_DATA_TYPE_BOOLEAN: + case ECORE_DBUS_DATA_TYPE_INT32: + case ECORE_DBUS_DATA_TYPE_INT64: + case ECORE_DBUS_DATA_TYPE_UINT64: + case ECORE_DBUS_DATA_TYPE_DOUBLE: + case ECORE_DBUS_DATA_TYPE_CUSTOM: + case ECORE_DBUS_DATA_TYPE_ARRAY: + case ECORE_DBUS_DATA_TYPE_DICT: + default: + printf("[ecore_dbus] unknown/unhandled data type %c\n", *fmt); + break; + } + *fmt++; + } + va_end(ap); + *(unsigned int *)(msg->header + 8) = msg->blength = msg->bpos; + /* show message */ + /*ecore_dbus_message_print(msg); + * _ecore_dbus_message_print_raw(msg->header,msg->hlength); + * _ecore_dbus_message_print_raw(msg->body,msg->blength); */ + /* send message */ + ecore_dbus_server_send(svr, (char *)msg->header, msg->hlength); + if (msg->body) + ecore_dbus_server_send(svr, (char *)msg->body, msg->blength); + /* free data TODO free the list of fields */ + /*for(i=0; i<8; i++) + * free(msg->header_fields[i]); + * free(msg->buf); + * free(msg); */ + return msg->serial; +} + +/*******************/ +/* ecore_dbus_auth */ +/*******************/ + +static char *_ecore_dbus_getuid(void); +static char *_ecore_dbus_hex_encode(char *src_str); + +/* helper functions */ +static char * +_ecore_dbus_getuid(void) +{ + /* this calculation is from comp.lang.c faq */ +#define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1) /* +1 for '-' */ + int len; + char *uid; + char *tmp; + + tmp = (char *)malloc(MAX_LONG_LEN); + len = snprintf(tmp, MAX_LONG_LEN, "%ld", (long) getuid()); + uid = (char *)malloc(len + 1); + uid = memcpy(uid, tmp, len); + uid[len] = '\0'; + + free(tmp); + return uid; +} + +/* encodes a string into a string of hex values */ +/* each byte is two hex digits */ +static char * +_ecore_dbus_hex_encode(char *src_str) +{ + const char hexdigits[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f' + }; + char *enc_str; + char *p; + char *end; + int len; + int i = 0; + + len = strlen(src_str); + p = src_str; + end = p + len; + + enc_str = malloc(2 * len + 1); + while (p != end) + { + enc_str[i] = hexdigits[(*p >> 4)]; + i++; + enc_str[i] = hexdigits[(*p & 0x0f)]; + i++; + p++; + } + enc_str[i] = '\0'; + return enc_str; +} + +unsigned char * +_ecore_dbus_auth_external(void *data) +{ + char *uid, *enc_uid, *msg; + + uid = _ecore_dbus_getuid(); + enc_uid = _ecore_dbus_hex_encode(uid); + free(uid); + msg = malloc(strlen(enc_uid) + 17); + sprintf(msg, "AUTH EXTERNAL %s\r\n", enc_uid); + free(enc_uid); + return (unsigned char *)msg; +} + +/*****************************/ +/* main ecore_dbus functions */ +/*****************************/ + +int ECORE_DBUS_EVENT_CLIENT_ADD = 0; +int ECORE_DBUS_EVENT_CLIENT_DEL = 0; +int ECORE_DBUS_EVENT_SERVER_ADD = 0; +int ECORE_DBUS_EVENT_SERVER_DEL = 0; +int ECORE_DBUS_EVENT_CLIENT_DATA = 0; +int ECORE_DBUS_EVENT_SERVER_DATA = 0; + +static const Ecore_DBus_Auth auths[] = { + {"EXTERNAL", 1, {_ecore_dbus_auth_external, NULL, NULL, NULL, NULL}}, + {"MAGIC_COOKIE", 0, {NULL, NULL, NULL, NULL, NULL}}, + {"DBUS_COOKIE_SHA1", 0, {NULL, NULL, NULL, NULL, NULL}}, + {"KERBEROS_V4", 0, {NULL, NULL, NULL, NULL, NULL}}, + {"SKEY", 0, {NULL, NULL, NULL, NULL, NULL}}, +}; + +static int init_count = 0; +static Ecore_List *servers = NULL; + +static int _ecore_dbus_event_client_add(void *data, int ev_type, + void *ev); +static int _ecore_dbus_event_client_del(void *data, int ev_type, + void *ev); +static int _ecore_dbus_event_server_add(void *data, int ev_type, + void *ev); +static int _ecore_dbus_event_server_del(void *data, int ev_type, + void *ev); +static int _ecore_dbus_event_client_data(void *data, int ev_type, + void *ev); +static int _ecore_dbus_event_server_data(void *data, int ev_type, + void *ev); +/* helpers */ +void _ecore_dbus_message_free(void *data, void *ev); + +int +ecore_dbus_init(void) +{ + if (!init_count) + ecore_con_init(); + init_count++; + if (!ECORE_DBUS_EVENT_CLIENT_ADD) + { + ECORE_DBUS_EVENT_CLIENT_ADD = ecore_event_type_new(); + ECORE_DBUS_EVENT_CLIENT_DEL = ecore_event_type_new(); + ECORE_DBUS_EVENT_SERVER_ADD = ecore_event_type_new(); + ECORE_DBUS_EVENT_SERVER_DEL = ecore_event_type_new(); + ECORE_DBUS_EVENT_CLIENT_DATA = ecore_event_type_new(); + ECORE_DBUS_EVENT_SERVER_DATA = ecore_event_type_new(); + + ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, + _ecore_dbus_event_client_add, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, + _ecore_dbus_event_client_del, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, + _ecore_dbus_event_server_add, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, + _ecore_dbus_event_server_del, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, + _ecore_dbus_event_client_data, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, + _ecore_dbus_event_server_data, NULL); + } + return init_count; +} + +Ecore_DBus_Server * +ecore_dbus_server_connect(Ecore_DBus_Type compl_type, char *name, int port, + const void *data) +{ + /* TODO */ + /* se tiene q conectar por direccion (unix socket path) */ + /* o por BUS directo */ + + Ecore_DBus_Server *svr; + Ecore_DBus_Type type; + Ecore_Con_Type extra = 0; + + svr = calloc(1, sizeof(Ecore_DBus_Server)); + if (!svr) + return NULL; + type = compl_type; + switch (type) + { + case ECORE_DBUS_BUS_SESSION: + svr->server = + ecore_con_server_connect(ECORE_CON_LOCAL_USER | extra, name, port, + svr); + break; + case ECORE_DBUS_BUS_SYSTEM: + svr->server = + ecore_con_server_connect(ECORE_CON_LOCAL_USER | extra, name, port, + svr); + break; + + default: + free(svr); + return NULL; + } + if (!svr->server) + { + printf("no hay servidor\n"); + free(svr); + return NULL; + } + svr->authenticated = 0; + svr->cnt_msg = 0; + svr->auth_type = -1; + svr->auth_type_transaction = 0; + servers = _ecore_list_append(servers, svr); + + return svr; +} + +int +ecore_dbus_server_send(Ecore_DBus_Server * svr, char *command, int length) +{ + int ret; + + ret = ecore_con_server_send(svr->server, command, length); + printf + ("[ecore_dbus] ecore_dbus_server: %p ecore_con_server: %p sent %d of %d bytes\n", + svr, svr->server, ret, length); + return ret; +} + +/* private functions */ +static int +_ecore_dbus_event_client_add(void *data, int ev_type, void *ev) +{ + printf("CLIENT ADDED \n"); + printf("this line should appear\n"); + return 1; +} + +static int +_ecore_dbus_event_client_del(void *data, int ev_type, void *ev) +{ + return 0; +} + +static int +_ecore_dbus_event_server_add(void *data, int ev_type, void *ev) +{ + + Ecore_DBus_Event_Server_Add *e; + + e = ev; + if (!_ecore_list_find(servers, ecore_con_server_data_get(e->server))) + return 1; + { + Ecore_DBus_Server *svr; + + svr = ecore_con_server_data_get(e->server); + ecore_dbus_server_send(svr, "\0", 1); + ecore_dbus_server_send(svr, "AUTH\r\n", 6); + printf("[ecore_dbus] begining auth process\n"); + } + return 0; +} + +static int +_ecore_dbus_event_server_del(void *udata, int ev_type, void *ev) +{ + Ecore_Con_Event_Server_Del *e; + + e = ev; + if (!_ecore_list_find(servers, ecore_con_server_data_get(e->server))) + return 1; + { + Ecore_DBus_Server *svr; + + svr = ecore_con_server_data_get(e->server); + { + Ecore_DBus_Event_Server_Del *e2; + + e2 = calloc(1, sizeof(Ecore_DBus_Event_Server_Del)); + if (e2) + { + e2->server = svr; + ecore_event_add(ECORE_DBUS_EVENT_SERVER_DEL, e2, NULL, NULL); + } + } + } + return 0; +} + +static int +_ecore_dbus_event_client_data(void *udata, int ev_type, void *ev) +{ + printf("CLIENT DATA"); + return 1; +} + +static int +_ecore_dbus_event_server_data(void *udata, int ev_type, void *ev) +{ + Ecore_Con_Event_Server_Data *e; + + e = ev; + if (!_ecore_list_find(servers, ecore_con_server_data_get(e->server))) + return 1; + + { + Ecore_DBus_Server *svr; + Ecore_DBus_Event_Server_Add *svr_add; + + svr = ecore_con_server_data_get(e->server); + + /* authentication protocol */ + /***************************/ + if (!svr->authenticated) + { + const Ecore_DBus_Auth *auth; + Ecore_DBus_Auth_Transaction trans; + + if (!strncmp(e->data, "OK", 2)) + { + printf("[ecore_dbus] auth type %s successful\n", + auths[svr->auth_type].name); + ecore_dbus_server_send(svr, "BEGIN\r\n", 7); + svr->authenticated = 1; + svr_add = malloc(sizeof(Ecore_DBus_Event_Server_Add)); + svr_add->server = svr; + ecore_event_add(ECORE_DBUS_EVENT_SERVER_ADD, svr_add, NULL, + NULL); + } + if (!strncmp(e->data, "DATA", 4)) + { + printf("[ecore_dbus] requering data (unaivable)\n"); + } + if (!strncmp(e->data, "ERROR", 5)) + { + printf("[ecore_dbus] auth process error\n"); + } + if (!strncmp(e->data, "REJECTED", 8)) + { + unsigned char *msg; + + if (svr->auth_type >= 0) + printf("[ecore_dbus] auth type %s rejected\n", + auths[svr->auth_type].name); + svr->auth_type++; + auth = &auths[svr->auth_type]; + trans = auth->transactions[0]; + printf("[ecore_dbus] auth type %s started\n", auth->name); + msg = trans(NULL); + ecore_dbus_server_send(svr, (char *)msg, strlen((char *)msg)); + free(msg); + + } + } + /* message protocol */ + /********************/ + else + { + Ecore_DBus_Message *msg; + unsigned int offset = 0; + + printf("[ecore_dbus] received server data, %d bytes\n", e->size); + while (e->size) + { + msg = _ecore_dbus_message_unmarshal(svr, e->data + offset); + if (msg == NULL) + break; + offset += msg->hlength + msg->blength; + e->size -= msg->hlength + msg->blength; + printf("[ecore_dbus] dbus message length %lu bytes, still %d\n", + msg->hlength + msg->blength, e->size); + /*ecore_dbus_message_print(msg); */ + ecore_event_add(ECORE_DBUS_EVENT_SERVER_DATA, msg, + _ecore_dbus_message_free, NULL); + + } + } + } + return 1; +} diff --git a/ecore/src/lib/ecore_dbus/ecore_dbus_private.h b/ecore/src/lib/ecore_dbus/ecore_dbus_private.h new file mode 100644 index 0000000..f9e1a8e --- /dev/null +++ b/ecore/src/lib/ecore_dbus/ecore_dbus_private.h @@ -0,0 +1,56 @@ +#ifndef _ECORE_DBUS_PRIVATE_H +#define _ECORE_DBUS_PRIVATE_H + +struct _Ecore_DBus_Client +{ + Ecore_DBus_Client *client; +}; + +struct _Ecore_DBus_Server +{ + Ecore_List __list_data; + Ecore_Con_Server *server; + Ecore_DBus_Client *clients; + /* unsigned char *buf; */ + /* int buf_size; */ + unsigned int cnt_msg; + Ecore_List *msg_queue; + /* void *data;*/ + unsigned int authenticated; + int auth_type; + unsigned int auth_type_transaction; +}; + +/* Errors */ +/* WARNING dont change order or ABI breaks. */ +#define DBUS_ERROR_FAILED "org.freedesktop.DBus.Error.Failed" +#define DBUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory" +#define DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND "org.freedesktop.DBus.Error.ServiceNotFound" +#define DBUS_ERROR_SERVICE_DOES_NOT_EXIST "org.freedesktop.DBus.Error.ServiceDoesNotExist" +#define DBUS_ERROR_SERVICE_HAS_NO_OWNER "org.freedesktop.DBus.Error.ServiceHasNoOwner" +#define DBUS_ERROR_NO_REPLY "org.freedesktop.DBus.Error.NoReply" +#define DBUS_ERROR_IO_ERROR "org.freedesktop.DBus.Error.IOError" +#define DBUS_ERROR_BAD_ADDRESS "org.freedesktop.DBus.Error.BadAddress" +#define DBUS_ERROR_NOT_SUPPORTED "org.freedesktop.DBus.Error.NotSupported" +#define DBUS_ERROR_LIMITS_EXCEEDED "org.freedesktop.DBus.Error.LimitsExceeded" +#define DBUS_ERROR_ACCESS_DENIED "org.freedesktop.DBus.Error.AccessDenied" +#define DBUS_ERROR_AUTH_FAILED "org.freedesktop.DBus.Error.AuthFailed" +#define DBUS_ERROR_NO_SERVER "org.freedesktop.DBus.Error.NoServer" +#define DBUS_ERROR_TIMEOUT "org.freedesktop.DBus.Error.Timeout" +#define DBUS_ERROR_NO_NETWORK "org.freedesktop.DBus.Error.NoNetwork" +#define DBUS_ERROR_ADDRESS_IN_USE "org.freedesktop.DBus.Error.AddressInUse" +#define DBUS_ERROR_DISCONNECTED "org.freedesktop.DBus.Error.Disconnected" +#define DBUS_ERROR_INVALID_ARGS "org.freedesktop.DBus.Error.InvalidArgs" +#define DBUS_ERROR_FILE_NOT_FOUND "org.freedesktop.DBus.Error.FileNotFound" +#define DBUS_ERROR_UNKNOWN_METHOD "org.freedesktop.DBus.Error.UnknownMethod" +#define DBUS_ERROR_TIMED_OUT "org.freedesktop.DBus.Error.TimedOut" +#define DBUS_ERROR_MATCH_RULE_NOT_FOUND "org.freedesktop.DBus.Error.MatchRuleNotFound" +#define DBUS_ERROR_MATCH_RULE_INVALID "org.freedesktop.DBus.Error.MatchRuleInvalid" +#define DBUS_ERROR_SPAWN_EXEC_FAILED "org.freedesktop.DBus.Error.Spawn.ExecFailed" +#define DBUS_ERROR_SPAWN_FORK_FAILED "org.freedesktop.DBus.Error.Spawn.ForkFailed" +#define DBUS_ERROR_SPAWN_CHILD_EXITED "org.freedesktop.DBus.Error.Spawn.ChildExited" +#define DBUS_ERROR_SPAWN_CHILD_SIGNALED "org.freedesktop.DBus.Error.Spawn.ChildSignaled" +#define DBUS_ERROR_SPAWN_FAILED "org.freedesktop.DBus.Error.Spawn.Failed" +#define DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN "org.freedesktop.DBus.Error.UnixProcessIdUnknown" + +#endif diff --git a/ecore/src/lib/ecore_evas/.cvsignore b/ecore/src/lib/ecore_evas/.cvsignore new file mode 100644 index 0000000..0bf42a4 --- /dev/null +++ b/ecore/src/lib/ecore_evas/.cvsignore @@ -0,0 +1,10 @@ +.deps +.libs +Ecore_Evas.h +Makefile +Makefile.in +ecore_evas.lo +ecore_evas_fb.lo +ecore_evas_x.lo +ecore_evas_buffer.lo +libecore_evas.la diff --git a/ecore/src/lib/ecore_evas/CVS/Entries b/ecore/src/lib/ecore_evas/CVS/Entries new file mode 100644 index 0000000..b0e1a5c --- /dev/null +++ b/ecore/src/lib/ecore_evas/CVS/Entries @@ -0,0 +1,9 @@ +/.cvsignore/1.3/Tue Feb 22 12:42:23 2005//THEAD +/Ecore_Evas.h/1.11/Thu Jul 7 03:33:17 2005//THEAD +/Makefile.am/1.11/Thu Mar 10 15:19:38 2005//THEAD +/ecore_evas.c/1.18/Sat Jan 8 18:40:31 2005//THEAD +/ecore_evas_private.h/1.12/Sat Jun 25 07:23:38 2005//THEAD +/ecore_evas_buffer.c/1.5/Mon Jul 25 17:01:56 2005//THEAD +/ecore_evas_fb.c/1.12/Mon Jul 25 17:01:56 2005//THEAD +/ecore_evas_x.c/1.50/Mon Jul 25 17:01:56 2005//THEAD +D diff --git a/ecore/src/lib/ecore_evas/CVS/Repository b/ecore/src/lib/ecore_evas/CVS/Repository new file mode 100644 index 0000000..d85de4a --- /dev/null +++ b/ecore/src/lib/ecore_evas/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/src/lib/ecore_evas diff --git a/ecore/src/lib/ecore_evas/CVS/Root b/ecore/src/lib/ecore_evas/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/src/lib/ecore_evas/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/src/lib/ecore_evas/CVS/Tag b/ecore/src/lib/ecore_evas/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/src/lib/ecore_evas/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/src/lib/ecore_evas/Ecore_Evas.h b/ecore/src/lib/ecore_evas/Ecore_Evas.h new file mode 100644 index 0000000..108de52 --- /dev/null +++ b/ecore/src/lib/ecore_evas/Ecore_Evas.h @@ -0,0 +1,165 @@ +#ifndef _ECORE_EVAS_H +#define _ECORE_EVAS_H + +#ifdef EAPI +#undef EAPI +#endif +#ifdef WIN32 +# ifdef BUILDING_DLL +# define EAPI __declspec(dllexport) +# else +# define EAPI __declspec(dllimport) +# endif +#else +# ifdef GCC_HASCLASSVISIBILITY +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +#endif + +/** + * @file Ecore_Evas.h + * @brief Evas wrapper functions + */ + +/* FIXME: + * to do soon: + * - iconfication api needs to work + * - maximization api nees to work + * - document all calls + * + * later: + * - buffer back-end that renders to an evas_image_object ??? + * - qt back-end ??? + * - dfb back-end ??? (dfb's threads make this REALLY HARD) + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* these are dummy and just tell u what API levels ecore_evas supports - not if + * the actual support is compiled in. you need to query for that separately. + */ +#define HAVE_ECORE_EVAS_X 1 +#define HAVE_ECORE_EVAS_FB 1 +#define HAVE_ECORE_EVAS_GL 1 + +typedef enum +{ + ECORE_EVAS_ENGINE_SOFTWARE_X11, + ECORE_EVAS_ENGINE_SOFTWARE_FB, + ECORE_EVAS_ENGINE_GL_X11, + ECORE_EVAS_ENGINE_SOFTWARE_BUFFER +} Ecore_Evas_Engine_Type; + +#ifndef _ECORE_X_H +#define _ECORE_X_WINDOW_PREDEF +typedef unsigned int Ecore_X_Window; +#endif + +#ifndef _ECORE_EVAS_PRIVATE_H +/* basic data types */ +typedef void Ecore_Evas; +#endif + +/* module setup/shutdown calls */ + +EAPI int ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine); + +EAPI int ecore_evas_init(void); +EAPI int ecore_evas_shutdown(void); + +/* engine/target specific init calls */ +EAPI Ecore_Evas *ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h); +EAPI Ecore_X_Window ecore_evas_software_x11_window_get(Ecore_Evas *ee); +EAPI Ecore_X_Window ecore_evas_software_x11_subwindow_get(Ecore_Evas *ee); +EAPI void ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, int on); +EAPI int ecore_evas_software_x11_direct_resize_get(Ecore_Evas *ee); + +EAPI Ecore_Evas *ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h); +EAPI Ecore_X_Window ecore_evas_gl_x11_window_get(Ecore_Evas *ee); +EAPI Ecore_X_Window ecore_evas_gl_x11_subwindow_get(Ecore_Evas *ee); +EAPI void ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, int on); +EAPI int ecore_evas_gl_x11_direct_resize_get(Ecore_Evas *ee); + +EAPI Ecore_Evas *ecore_evas_fb_new(char *disp_name, int rotation, int w, int h); + +EAPI Ecore_Evas *ecore_evas_buffer_new(int w, int h); +EAPI const int *ecore_evas_buffer_pixels_get(Ecore_Evas *ee); + +EAPI Evas_Object *ecore_evas_object_image_new(Ecore_Evas *ee_target); + +/* generic manipulation calls */ +EAPI void ecore_evas_free(Ecore_Evas *ee); +EAPI void *ecore_evas_data_get(Ecore_Evas *ee, const char *key); +EAPI void ecore_evas_data_set(Ecore_Evas *ee, const char *key, const void *data); +EAPI void ecore_evas_callback_resize_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); +EAPI void ecore_evas_callback_move_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); +EAPI void ecore_evas_callback_show_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); +EAPI void ecore_evas_callback_hide_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); +EAPI void ecore_evas_callback_delete_request_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); +EAPI void ecore_evas_callback_destroy_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); +EAPI void ecore_evas_callback_focus_in_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); +EAPI void ecore_evas_callback_focus_out_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); +EAPI void ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); +EAPI void ecore_evas_callback_mouse_out_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); +EAPI void ecore_evas_callback_pre_render_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); +EAPI void ecore_evas_callback_post_render_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); +EAPI Evas *ecore_evas_get(Ecore_Evas *ee); +EAPI void ecore_evas_move(Ecore_Evas *ee, int x, int y); +EAPI void ecore_evas_resize(Ecore_Evas *ee, int w, int h); +EAPI void ecore_evas_move_resize(Ecore_Evas *ee, int x, int y, int w, int h); +EAPI void ecore_evas_geometry_get(Ecore_Evas *ee, int *x, int *y, int *w, int *h); +EAPI void ecore_evas_rotation_set(Ecore_Evas *ee, int rot); +EAPI int ecore_evas_rotation_get(Ecore_Evas *ee); +EAPI void ecore_evas_shaped_set(Ecore_Evas *ee, int shaped); +EAPI int ecore_evas_shaped_get(Ecore_Evas *ee); +EAPI void ecore_evas_show(Ecore_Evas *ee); +EAPI void ecore_evas_hide(Ecore_Evas *ee); +EAPI int ecore_evas_visibility_get(Ecore_Evas *ee); +EAPI void ecore_evas_raise(Ecore_Evas *ee); +EAPI void ecore_evas_lower(Ecore_Evas *ee); +EAPI void ecore_evas_title_set(Ecore_Evas *ee, const char *t); +EAPI const char *ecore_evas_title_get(Ecore_Evas *ee); +EAPI void ecore_evas_name_class_set(Ecore_Evas *ee, const char *n, const char *c); +EAPI void ecore_evas_name_class_get(Ecore_Evas *ee, const char **n, const char **c); +EAPI void ecore_evas_size_min_set(Ecore_Evas *ee, int w, int h); +EAPI void ecore_evas_size_min_get(Ecore_Evas *ee, int *w, int *h); +EAPI void ecore_evas_size_max_set(Ecore_Evas *ee, int w, int h); +EAPI void ecore_evas_size_max_get(Ecore_Evas *ee, int *w, int *h); +EAPI void ecore_evas_size_base_set(Ecore_Evas *ee, int w, int h); +EAPI void ecore_evas_size_base_get(Ecore_Evas *ee, int *w, int *h); +EAPI void ecore_evas_size_step_set(Ecore_Evas *ee, int w, int h); +EAPI void ecore_evas_size_step_get(Ecore_Evas *ee, int *w, int *h); +EAPI void ecore_evas_cursor_set(Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y); +EAPI void ecore_evas_cursor_get(Ecore_Evas *ee, char **file, int *layer, int *hot_x, int *hot_y); +EAPI void ecore_evas_layer_set(Ecore_Evas *ee, int layer); +EAPI int ecore_evas_layer_get(Ecore_Evas *ee); +EAPI void ecore_evas_focus_set(Ecore_Evas *ee, int on); +EAPI int ecore_evas_focus_get(Ecore_Evas *ee); +EAPI void ecore_evas_iconified_set(Ecore_Evas *ee, int on); +EAPI int ecore_evas_iconified_get(Ecore_Evas *ee); +EAPI void ecore_evas_borderless_set(Ecore_Evas *ee, int on); +EAPI int ecore_evas_borderless_get(Ecore_Evas *ee); +EAPI void ecore_evas_override_set(Ecore_Evas *ee, int on); +EAPI int ecore_evas_override_get(Ecore_Evas *ee); +EAPI void ecore_evas_maximized_set(Ecore_Evas *ee, int on); +EAPI int ecore_evas_maximized_get(Ecore_Evas *ee); +EAPI void ecore_evas_fullscreen_set(Ecore_Evas *ee, int on); +EAPI int ecore_evas_fullscreen_get(Ecore_Evas *ee); +EAPI void ecore_evas_avoid_damage_set(Ecore_Evas *ee, int on); +EAPI int ecore_evas_avoid_damage_get(Ecore_Evas *ee); +EAPI void ecore_evas_withdrawn_set(Ecore_Evas *ee, int withdrawn); +EAPI int ecore_evas_withdrawn_get(Ecore_Evas *ee); +EAPI void ecore_evas_sticky_set(Ecore_Evas *ee, int sticky); +EAPI int ecore_evas_sticky_get(Ecore_Evas *ee); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ecore/src/lib/ecore_evas/Makefile.am b/ecore/src/lib/ecore_evas/Makefile.am new file mode 100644 index 0000000..a79da95 --- /dev/null +++ b/ecore/src/lib/ecore_evas/Makefile.am @@ -0,0 +1,69 @@ +MAINTAINERCLEANFILES = Makefile.in + +if BUILD_ECORE_X +ECORE_X_INC = -I$(top_srcdir)/src/lib/ecore_x +ECORE_X_LIB = $(top_builddir)/src/lib/ecore_x/libecore_x.la +ECORE_X_LDF = -L$(top_builddir)/src/lib/ecore_x/.libs +else +ECORE_X_INC = +ECORE_X_LIB = +ECORE_X_LDF = +endif + +if BUILD_ECORE_FB +ECORE_FB_INC = -I$(top_srcdir)/src/lib/ecore_fb +ECORE_FB_LIB = $(top_builddir)/src/lib/ecore_fb/libecore_fb.la +ECORE_FB_LDF = -L$(top_builddir)/src/lib/ecore_fb/.libs +else +ECORE_FB_INC = +ECORE_FB_LIB = +ECORE_FB_LDF = +endif + +INCLUDES = \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_evas \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_evas \ +$(ECORE_X_INC) \ +$(ECORE_FB_INC) \ +@evas_cflags@ + +libecore_evas_la_LDFLAGS = -version-info 1:0:0 \ +$(ECORE_X_LDF) \ +$(ECORE_FB_LDF) \ +-L$(top_builddir)/src/lib/ecore/.libs + +if BUILD_ECORE_EVAS + +lib_LTLIBRARIES = libecore_evas.la +include_HEADERS = \ +Ecore_Evas.h + +libecore_evas_la_SOURCES = \ +ecore_evas.c \ +ecore_evas_private.h \ +ecore_evas_x.c \ +ecore_evas_fb.c \ +ecore_evas_buffer.c + +libecore_evas_la_LIBADD = \ +$(ECORE_X_LIB) \ +$(ECORE_FB_LIB) \ +$(top_builddir)/src/lib/ecore/libecore.la \ +@evas_libs@ + +libecore_evas_la_DEPENDENCIES = \ +$(ECORE_X_LIB) \ +$(ECORE_FB_LIB) \ +$(top_builddir)/src/lib/ecore/libecore.la + +endif + +EXTRA_DIST = \ +ecore_evas.c \ +ecore_evas_private.h \ +ecore_evas_x.c \ +ecore_evas_fb.c \ +ecore_evas_buffer.c + diff --git a/ecore/src/lib/ecore_evas/ecore_evas.c b/ecore/src/lib/ecore_evas/ecore_evas.c new file mode 100644 index 0000000..b6e57cd --- /dev/null +++ b/ecore/src/lib/ecore_evas/ecore_evas.c @@ -0,0 +1,1605 @@ +#include "config.h" +#include "Ecore.h" +#include "ecore_private.h" +#include "ecore_evas_private.h" +#include "Ecore_Evas.h" + +static int _ecore_evas_init_count = 0; + +/** + * Query if a particular renginering engine target has support + * @param engine The engine to check support for + * @return 1 if the particualr engine is supported, 0 if it is not + * + * Query if engine @param engine is supported by ecore_evas. 1 is returned if + * it is, and 0 is returned if it is not supported. + */ +int +ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine) +{ + switch (engine) + { + case ECORE_EVAS_ENGINE_SOFTWARE_X11: +#ifdef BUILD_ECORE_X + return 1; +#else + return 0; +#endif + break; + case ECORE_EVAS_ENGINE_SOFTWARE_FB: +#ifdef BUILD_ECORE_EVAS_FB + return 1; +#else + return 0; +#endif + break; + case ECORE_EVAS_ENGINE_GL_X11: +#ifdef BUILD_ECORE_EVAS_GL + return 1; +#else + return 0; +#endif + break; + case ECORE_EVAS_ENGINE_SOFTWARE_BUFFER: +#ifdef BUILD_ECORE_EVAS_BUFFER + return 1; +#else + return 0; +#endif + break; + default: + return 0; + break; + }; + return 0; +} + +/** + * Init the Evas system. + * @return greater than 0 on success, 0 on failure + * + * Set up the Evas wrapper system. + */ +int +ecore_evas_init(void) +{ + if (_ecore_evas_init_count == 0) + evas_init (); + return ++_ecore_evas_init_count; +} + +/** + * Shut down the Evas system. + * @return 0 if ecore evas is fully shut down, or > 0 if it still needs to be shut down + * + * This closes the Evas system down. + */ +int +ecore_evas_shutdown(void) +{ + _ecore_evas_init_count--; + if (_ecore_evas_init_count == 0) + { +#ifdef BUILD_ECORE_X + while (_ecore_evas_x_shutdown()); +#endif +#ifdef BUILD_ECORE_EVAS_FB + while (_ecore_evas_fb_shutdown()); +#endif +#ifdef BUILD_ECORE_EVAS_BUFFER + while (_ecore_evas_buffer_shutdown()); +#endif + evas_shutdown(); + } + if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0; + return _ecore_evas_init_count; +} + +/** + * Free an Ecore_Evas + * @param ee The Ecore_Evas to free + * + * This frees up any memory used by the Ecore_Evas. + */ +void +ecore_evas_free(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_free"); + return; + } + ECORE_MAGIC_SET(ee, ECORE_MAGIC_NONE); + while (ee->sub_ecore_evas) + { + ecore_evas_free(ee->sub_ecore_evas->data); + } + if (ee->data) evas_hash_free(ee->data); + if (ee->driver) free(ee->driver); + if (ee->name) free(ee->name); + if (ee->prop.title) free(ee->prop.title); + if (ee->prop.name) free(ee->prop.name); + if (ee->prop.clas) free(ee->prop.clas); + if (ee->prop.cursor.file) free(ee->prop.cursor.file); + if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object); + if (ee->evas) evas_free(ee->evas); + ee->data = NULL; + ee->driver = NULL; + ee->name = NULL; + ee->prop.title = NULL; + ee->prop.name = NULL; + ee->prop.clas = NULL; + ee->prop.cursor.file = NULL; + ee->prop.cursor.object = NULL; + ee->evas = NULL; + if (ee->engine.func->fn_free) ee->engine.func->fn_free(ee); + free(ee); +} + +void * +ecore_evas_data_get(Ecore_Evas *ee, const char *key) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_data_get"); + return NULL; + } + + if (!key) return NULL; + + return evas_hash_find(ee->data, key); +} + +void +ecore_evas_data_set(Ecore_Evas *ee, const char *key, const void *data) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_data_set"); + return; + } + + if (!key) return; + + ee->data = evas_hash_del(ee->data, key, NULL); + ee->data = evas_hash_add(ee->data, key, data); +} + +#define IFC(_ee, _fn) if (_ee->engine.func->_fn) {_ee->engine.func->_fn +#define IFE return;} + +/** + * Set a callback for Ecore_Evas resize events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called whenever @p ee is resized. + */ +void +ecore_evas_callback_resize_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_callback_resize_set"); + return; + } + IFC(ee, fn_callback_resize_set) (ee, func); + IFE; + ee->func.fn_resize = func; +} + +/** + * Set a callback for Ecore_Evas move events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called whenever @p ee is moved. + */ +void +ecore_evas_callback_move_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_callback_move_set"); + return; + } + IFC(ee, fn_callback_move_set) (ee, func); + IFE; + ee->func.fn_move = func; +} + +/** + * Set a callback for Ecore_Evas show events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called whenever @p ee is shown. + */ +void +ecore_evas_callback_show_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_callback_show_set"); + return; + } + IFC(ee, fn_callback_show_set) (ee, func); + IFE; + ee->func.fn_show = func; +} + +/** + * Set a callback for Ecore_Evas hide events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called whenever @p ee is hidden. + */ +void +ecore_evas_callback_hide_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_callback_hide_set"); + return; + } + IFC(ee, fn_callback_hide_set) (ee, func); + IFE; + ee->func.fn_hide = func; +} + +/** + * Set a callback for Ecore_Evas delete request events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called whenever @p ee gets a delete request. + */ +void +ecore_evas_callback_delete_request_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_callback_delete_request_set"); + return; + } + IFC(ee, fn_callback_delete_request_set) (ee, func); + IFE; + ee->func.fn_delete_request = func; +} + +/** + * Set a callback for Ecore_Evas destroy events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called whenever @p ee is destroyed. + */ +void +ecore_evas_callback_destroy_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_callback_destroy_set"); + return; + } + IFC(ee, fn_callback_destroy_set) (ee, func); + IFE; + ee->func.fn_destroy = func; +} + +/** + * Set a callback for Ecore_Evas focus in events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called whenever @p ee gets focus. + */ +void +ecore_evas_callback_focus_in_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_callback_focus_in_set"); + return; + } + IFC(ee, fn_callback_focus_in_set) (ee, func); + IFE; + ee->func.fn_focus_in = func; +} + +/** + * Set a callback for Ecore_Evas focus out events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called whenever @p ee loses focus. + */ +void +ecore_evas_callback_focus_out_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_callback_focus_out_set"); + return; + } + IFC(ee, fn_callback_focus_out_set) (ee, func); + IFE; + ee->func.fn_focus_out = func; +} + +/** + * Set a callback for Ecore_Evas mouse in events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called whenever the mouse enters @p ee. + */ +void +ecore_evas_callback_mouse_in_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_callback_mouse_in_set"); + return; + } + IFC(ee, fn_callback_mouse_in_set) (ee, func); + IFE; + ee->func.fn_mouse_in = func; +} + +/** + * Set a callback for Ecore_Evas mouse out events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called whenever the mouse leaves @p ee. + */ +void +ecore_evas_callback_mouse_out_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_callback_mouse_out_set"); + return; + } + IFC(ee, fn_callback_mouse_out_set) (ee, func); + IFE; + ee->func.fn_mouse_out = func; +} + +/** + * Set a callback for Ecore_Evas mouse pre render events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called just before the evas in @p ee is rendered. + */ +void +ecore_evas_callback_pre_render_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_callback_pre_render_set"); + return; + } + IFC(ee, fn_callback_pre_render_set) (ee, func); + IFE; + ee->func.fn_pre_render = func; +} + +/** + * Set a callback for Ecore_Evas mouse post render events. + * @param ee The Ecore_Evas to set callbacks on + * @param func The function to call + + * A call to this function will set a callback on an Ecore_Evas, causing + * @p func to be called just after the evas in @p ee is rendered. + */ +void +ecore_evas_callback_post_render_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_callback_post_render_set"); + return; + } + IFC(ee, fn_callback_post_render_set) (ee, func); + IFE; + ee->func.fn_post_render = func; +} + +/** + * Get an Ecore_Evas's Evas + * @param ee The Ecore_Evas whose Evas you wish to get + * @return The Evas wrapped by @p ee + * + * This function returns the Evas contained within @p ee. + */ +Evas * +ecore_evas_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_get"); + return NULL; + } + return ee->evas; +} + +/** + * Move an Ecore_Evas + * @param ee The Ecore_Evas to move + * @param x The x coordinate to move to + * @param y The y coordinate to move to + * + * This moves @p ee to the screen coordinates (@p x, @p y) + */ +void +ecore_evas_move(Ecore_Evas *ee, int x, int y) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_move"); + return; + } + IFC(ee, fn_move) (ee, x, y); + IFE; +} + +/** + * Resize an Ecore_Evas + * @param ee The Ecore_Evas to move + * @param w The w coordinate to resize to + * @param h The h coordinate to resize to + * + * This resizes @p ee to @p w x @p h + */ +void +ecore_evas_resize(Ecore_Evas *ee, int w, int h) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_resize"); + return; + } + if (w < 1) w = 1; + if (h < 1) h = 1; + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + IFC(ee, fn_resize) (ee, h, w); + IFE; + } + else + { + IFC(ee, fn_resize) (ee, w, h); + IFE; + } +} + +/** + * Resize an Ecore_Evas + * @param ee The Ecore_Evas to move + * @param x The x coordinate to move to + * @param y The y coordinate to move to + * @param w The w coordinate to resize to + * @param h The h coordinate to resize to + * + * This moves @p ee to the screen coordinates (@p x, @p y) and resizes + * it to @p w x @p h. + * + */ +void +ecore_evas_move_resize(Ecore_Evas *ee, int x, int y, int w, int h) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_move_resize"); + return; + } + if (w < 1) w = 1; + if (h < 1) h = 1; + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + IFC(ee, fn_move_resize) (ee, x, y, h, w); + IFE; + } + else + { + IFC(ee, fn_move_resize) (ee, x, y, w, h); + IFE; + } +} + +/** + * Get the geometry of an Ecore_Evas + * @param ee The Ecore_Evas whose geometry y + * @param x A pointer to an int to place the x coordinate in + * @param y A pointer to an int to place the y coordinate in + * @param w A pointer to an int to place the w size in + * @param h A pointer to an int to place the h size in + * + * This function takes four pointers to (already allocated) ints, and places + * the geometry of @p ee in them. + * + * @code + * int x, y, w, h; + * ecore_evas_geometry_get(ee, &x, &y, &w, &h); + * @endcode + * + */ +void +ecore_evas_geometry_get(Ecore_Evas *ee, int *x, int *y, int *w, int *h) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_geometry_get"); + return; + } + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + if (x) *x = ee->x; + if (y) *y = ee->y; + if (w) *w = ee->h; + if (h) *h = ee->w; + } + else + { + if (x) *x = ee->x; + if (y) *y = ee->y; + if (w) *w = ee->w; + if (h) *h = ee->h; + } +} + +/** + * Set the rotation of an Ecore_Evas' window + * + * @param ee The Ecore_Evas + * @param rot the angle (in degrees) of rotation. + * + * The allowed values of @p rot depend on the engine being used. Most only + * allow multiples of 90. + */ +void +ecore_evas_rotation_set(Ecore_Evas *ee, int rot) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_rotation_set"); + return; + } + rot = rot % 360; + while (rot < 0) rot += 360; + while (rot >= 360) rot -= 360; + IFC(ee, fn_rotation_set) (ee, rot); + IFE; +} + +/** + * Set the rotation of an Ecore_Evas' window + * + * @param ee The Ecore_Evas + * @return the angle (in degrees) of rotation. + * + */ +int +ecore_evas_rotation_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_rotation_get"); + return 0; + } + return ee->rotation; +} + +/** + * Set whether an Ecore_Evas is shaped or not. + * @param ee The Ecore_Evas to shape + * @param shaped 1 to shape, 0 to not + * + * This function allows one to make an Ecore_Evas shaped to the contents of the + * evas. If @p shaped is 1, @p ee will be transparent in parts of the evas that + * contain no objects. If @p shaped is 0, then @p ee will be rectangular, and + * and parts with no data will show random framebuffer artifacting. For + * non-shaped Ecore_Evases, it is recommend to cover the entire evas with a + * background object. + */ +void +ecore_evas_shaped_set(Ecore_Evas *ee, int shaped) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_shaped_set"); + return; + } + IFC(ee, fn_shaped_set) (ee, shaped); + IFE; +} + +/** + * Query whether an Ecore_Evas is shaped or not. + * @param ee The Ecore_Evas to query. + * @return 1 if shaped, 0 if not. + * + * This function returns 1 if @p ee is shaped, and 0 if not. + */ +int +ecore_evas_shaped_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_shaped_get"); + return 0; + } + return ee->shaped ? 1:0; +} + +/** + * Show an Ecore_Evas' window + * @param ee The Ecore_Evas to show. + * + * This function makes @p ee visible. + */ +void +ecore_evas_show(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_show"); + return; + } + IFC(ee, fn_show) (ee); + IFE; +} + +/** + * Hide an Ecore_Evas' window + * @param ee The Ecore_Evas to show. + * + * This function makes @p ee hidden. + */ +void +ecore_evas_hide(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_hide"); + return; + } + IFC(ee, fn_hide) (ee); + IFE; +} + +/** + * Query whether an Ecore_Evas' window is visible or not. + * @param ee The Ecore_Evas to query. + * @return 1 if visible, 0 if not. + * + * This function queries @p ee and returns 1 if it is visible, and 0 if not. + */ +int +ecore_evas_visibility_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_visibility_get"); + return 0; + } + return ee->visible ? 1:0; +} + +/** + * Raise and Ecore_Evas' window. + * @param ee The Ecore_Evas to raise. + * + * This functions raises the Ecore_Evas to the front. + */ +void +ecore_evas_raise(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_raise"); + return; + } + IFC(ee, fn_raise) (ee); + IFE; +} + +/** + * Lower an Ecore_Evas' window. + * @param ee The Ecore_Evas to raise. + * + * This functions lowers the Ecore_Evas to the back. + */ +void +ecore_evas_lower(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_lower"); + return; + } + IFC(ee, fn_lower) (ee); + IFE; +} + +/** + * Set the title of an Ecore_Evas' window + * @param ee The Ecore_Evas whose title you wish to set. + * @param t The title + * + * This function sets the title of @p ee to @p t. + */ +void +ecore_evas_title_set(Ecore_Evas *ee, const char *t) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_title_set"); + return; + } + IFC(ee, fn_title_set) (ee, t); + IFE; +} + +/** + * Get the title of an Ecore_Evas' window + * @param ee The Ecore_Evas whose title you wish to get. + * @return The title of @p ee. + * + * This function returns the title of @p ee. + */ +const char * +ecore_evas_title_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_title_get"); + return NULL; + } + return ee->prop.title; +} + +/** + * Set the name and class of an Ecore_Evas' window + * @param ee the Ecore_Evas + * @param n the name + * @param c the class + * + * This function sets the name of @p ee to @p n, and its class to @p c. + */ +void +ecore_evas_name_class_set(Ecore_Evas *ee, const char *n, const char *c) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_name_class_set"); + return; + } + IFC(ee, fn_name_class_set) (ee, n, c); + IFE; +} + +/** + * Get the name and class of an Ecore_Evas' window + * @p ee The Ecore_Evas to query + * @p n A pointer to a string to place the name in. + * @p c A pointer to a string to place the class in. + * + * This function gets puts the name of @p ee into @p n, and its class into + * @p c. + */ +void +ecore_evas_name_class_get(Ecore_Evas *ee, const char **n, const char **c) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_name_class_get"); + return; + } + if (n) *n = ee->prop.name; + if (c) *c = ee->prop.clas; +} + +/** + * Set the min size of an Ecore_Evas' window + * @param ee The Ecore_Evas to set + * @param w The minimum width + * @param h The minimum height + * + * This function sets the minimum size of @p ee to @p w x @p h. + */ +void +ecore_evas_size_min_set(Ecore_Evas *ee, int w, int h) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_size_min_set"); + return; + } + if (w < 0) w = 0; + if (h < 0) h = 0; + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + IFC(ee, fn_size_min_set) (ee, h, w); + IFE; + } + else + { + IFC(ee, fn_size_min_set) (ee, w, h); + IFE; + } +} + +/** + * Get the min size of an Ecore_Evas' window + * @param ee The Ecore_Evas to set + * @param w A pointer to an int to place the min width in. + * @param h A pointer to an int to place the min height in. + * + * This function puts the minimum size of @p ee into @p w and @p h. + */ +void +ecore_evas_size_min_get(Ecore_Evas *ee, int *w, int *h) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_size_min_get"); + return; + } + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + if (w) *w = ee->prop.min.h; + if (h) *h = ee->prop.min.w; + } + else + { + if (w) *w = ee->prop.min.w; + if (h) *h = ee->prop.min.h; + } +} + +/** + * Set the max size of an Ecore_Evas' window + * @param ee The Ecore_Evas to set + * @param w The maximum width + * @param h The maximum height + * + * This function sets the maximum size of @p ee to @p w x @p h. + */ +void +ecore_evas_size_max_set(Ecore_Evas *ee, int w, int h) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_size_max_set"); + return; + } + if (w < 0) w = 0; + if (h < 0) h = 0; + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + IFC(ee, fn_size_max_set) (ee, h, w); + IFE; + } + else + { + IFC(ee, fn_size_max_set) (ee, w, h); + IFE; + } +} + +/** + * Get the max size of an Ecore_Evas' window + * @param ee The Ecore_Evas to set + * @param w A pointer to an int to place the max width in. + * @param h A pointer to an int to place the max height in. + * + * This function puts the maximum size of @p ee into @p w and @p h. + */ +void +ecore_evas_size_max_get(Ecore_Evas *ee, int *w, int *h) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_size_max_get"); + return; + } + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + if (w) *w = ee->prop.max.h; + if (h) *h = ee->prop.max.w; + } + else + { + if (w) *w = ee->prop.max.w; + if (h) *h = ee->prop.max.h; + } +} + +/** + * Set the base size of an Ecore_Evas' window + * @param ee The Ecore_Evas to set + * @param w The base width + * @param h The base height + * + * This function sets the base size of @p ee to @p w x @p h. + */ +void +ecore_evas_size_base_set(Ecore_Evas *ee, int w, int h) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_size_base_set"); + return; + } + if (w < 0) w = 0; + if (h < 0) h = 0; + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + IFC(ee, fn_size_base_set) (ee, h, w); + IFE; + } + else + { + IFC(ee, fn_size_base_set) (ee, w, h); + IFE; + } +} + +/** + * Get the base size of an Ecore_Evas' window + * @param ee The Ecore_Evas to set + * @param w A pointer to an int to place the base width in. + * @param h A pointer to an int to place the base height in. + * + * This function puts the base size of @p ee into @p w and @p h. + */ +void +ecore_evas_size_base_get(Ecore_Evas *ee, int *w, int *h) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_size_base_get"); + return; + } + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + if (w) *w = ee->prop.base.h; + if (h) *h = ee->prop.base.w; + } + else + { + if (w) *w = ee->prop.base.w; + if (h) *h = ee->prop.base.h; + } +} + +/** + * Set the step size of an Ecore_Evas + * @param ee The Ecore_Evas to set + * @param w The step width + * @param h The step height + * + * This function sets the step size of @p ee to @p w x @p h. This limits the + * size of an Ecore_Evas to always being an integer multiple of the step size. + */ +void +ecore_evas_size_step_set(Ecore_Evas *ee, int w, int h) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_size_step_set"); + return; + } + if (w < 0) w = 0; + if (h < 0) h = 0; + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + IFC(ee, fn_size_step_set) (ee, h, w); + IFE; + } + else + { + IFC(ee, fn_size_step_set) (ee, w, h); + IFE; + } +} + +/** + * Get the step size of an Ecore_Evas' window + * @param ee The Ecore_Evas to set + * @param w A pointer to an int to place the step width in. + * @param h A pointer to an int to place the step height in. + * + * This function puts the step size of @p ee into @p w and @p h. + */ +void +ecore_evas_size_step_get(Ecore_Evas *ee, int *w, int *h) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_size_step_get"); + return; + } + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + if (w) *w = ee->prop.step.h; + if (h) *h = ee->prop.step.w; + } + else + { + if (w) *w = ee->prop.step.w; + if (h) *h = ee->prop.step.h; + } +} + +/** + * Set the cursor of an Ecore_Evas + * @param ee The Ecore_Evas + * @param file The path to an image file for the cursor + * @param layer + * @param hot_x The x coordinate of the cursor's hot spot + * @param hot_y The y coordinate of the cursor's hot spot + * + * This function makes the mouse cursor over @p ee be the image specified by + * @p file. The actual point within the image that the mouse is at is specified + * by @p hot_x and @p hot_y, which are coordinates with respect to the top left + * corner of the cursor image. + */ +void +ecore_evas_cursor_set(Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_cursor_set"); + return; + } + IFC(ee, fn_cursor_set) (ee, file, layer, hot_x, hot_y); + IFE; +} + +/** + * Get information about an Ecore_Evas' cursor + * @param ee The Ecore_Evas to set + * @param file A pointer to a string to place the cursor file name in. + * @param layer A pointer to an int to place the cursor's layer in.. + * @param hot_x A pointer to an int to place the cursor's hot_x coordinate in. + * @param hot_y A pointer to an int to place the cursor's hot_y coordinate in. + * + * This function queries information about an Ecore_Evas' cursor. + */ +void +ecore_evas_cursor_get(Ecore_Evas *ee, char **file, int *layer, int *hot_x, int *hot_y) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_cursor_get"); + return; + } + if (file) *file = ee->prop.cursor.file; + if (layer) *layer = ee->prop.cursor.layer; + if (hot_x) *hot_x = ee->prop.cursor.hot.x; + if (hot_y) *hot_y = ee->prop.cursor.hot.y; +} + +/** + * Set the layer of an Ecore_Evas' window + * @param ee The Ecore_Evas + * @param layer The layer to put @p ee on. + * + * This function moves @p ee to the layer @p layer. + */ +void +ecore_evas_layer_set(Ecore_Evas *ee, int layer) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_layer_set"); + return; + } + IFC(ee, fn_layer_set) (ee, layer); + IFE; +} + +/** + * Get the layer of an Ecore_Evas' window + * @param ee The Ecore_Evas to set + * @return the layer @p ee's window is on. + * + */ +int +ecore_evas_layer_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_layer_get"); + return 0; + } + return ee->prop.layer; +} + +/** + * Set the focus of an Ecore_Evas' window + * @param ee The Ecore_Evas + * @param on 1 for focus, 0 to defocus. + * + * This function focuses @p ee if @p on is 1, or defocuses @p ee if @p on is 0. + */ +void +ecore_evas_focus_set(Ecore_Evas *ee, int on) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_focus_set"); + return; + } + IFC(ee, fn_focus_set) (ee, on); + IFE; +} + +/** + * Query whether an Ecore_Evas' window is focused or not + * @param ee The Ecore_Evas to set + * @return 1 if @p ee if focused, 0 if not. + * + */ +int +ecore_evas_focus_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_focus_get"); + return 0; + } + return ee->prop.focused ? 1:0; +} + +/** + * Iconify or uniconify an Ecore_Evas' window + * @param ee The Ecore_Evas + * @param on 1 to iconify, 0 to uniconify. + * + * This function iconifies @p ee if @p on is 1, or uniconifies @p ee if @p on + * is 0. + */ +void +ecore_evas_iconified_set(Ecore_Evas *ee, int on) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_iconified_set"); + return; + } + IFC(ee, fn_iconified_set) (ee, on); + IFE; +} + +/** + * Query whether an Ecore_Evas' window is iconified or not + * @param ee The Ecore_Evas to set + * @return 1 if @p ee is iconified, 0 if not. + * + */ +int +ecore_evas_iconified_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_iconified_get"); + return 0; + } + return ee->prop.iconified ? 1:0; +} + +/** + * Set whether an Ecore_Evas' window is borderless or not + * @param ee The Ecore_Evas + * @param on 1 for borderless, 0 for bordered. + * + * This function makes @p ee borderless if @p on is 1, or bordered if @p on + * is 0. + */ +void +ecore_evas_borderless_set(Ecore_Evas *ee, int on) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_borderless_set"); + return; + } + IFC(ee, fn_borderless_set) (ee, on); + IFE; +} + +/** + * Query whether an Ecore_Evas' window is borderless or not + * @param ee The Ecore_Evas to set + * @return 1 if @p ee is borderless, 0 if not. + * + */ +int +ecore_evas_borderless_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_borderless_get"); + return 0; + } + return ee->prop.borderless ? 1:0; +} + +/** + * Tell the WM whether or not to ignore an Ecore_Evas' window + * @param ee The Ecore_Evas + * @param on 1 to ignore, 0 to not. + * + * This function causes the window manager to ignore @p ee if @p on is 1, + * or not ignore @p ee if @p on is 0. + */ +void +ecore_evas_override_set(Ecore_Evas *ee, int on) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_override_set"); + return; + } + IFC(ee, fn_override_set) (ee, on); + IFE; +} + +/** + * Query whether an Ecore_Evas' window is overridden or not + * @param ee The Ecore_Evas to set + * @return 1 if @p ee is overridden, 0 if not. + * + */ +int +ecore_evas_override_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_override_get"); + return 0; + } + return ee->prop.override ? 1:0; +} + +/** + * Maximize (or unmaximize) an Ecore_Evas' window + * @param ee The Ecore_Evas + * @param on 1 to maximize, 0 to unmaximize. + * + * This function maximizes @p ee if @p on is 1, or unmaximizes @p ee + * if @p on is 0. + */ +void +ecore_evas_maximized_set(Ecore_Evas *ee, int on) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_maximized_set"); + return; + } + IFC(ee, fn_maximized_set) (ee, on); + IFE; +} + +/** + * Query whether an Ecore_Evas' window is maximized or not + * @param ee The Ecore_Evas to set + * @return 1 if @p ee is maximized, 0 if not. + * + */ +int +ecore_evas_maximized_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_maximized_get"); + return 0; + } + return ee->prop.maximized ? 1:0; +} + +/** + * Set whether or not an Ecore_Evas' window is fullscreen + * @param ee The Ecore_Evas + * @param on 1 fullscreen, 0 not. + * + * This function causes @p ee to be fullscreen if @p on is 1, + * or not if @p on is 0. + */ +void +ecore_evas_fullscreen_set(Ecore_Evas *ee, int on) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_fullscreen_set"); + return; + } + IFC(ee, fn_fullscreen_set) (ee, on); + IFE; +} + +/** + * Query whether an Ecore_Evas' window is fullscreen or not + * @param ee The Ecore_Evas to set + * @return 1 if @p ee is fullscreen, 0 if not. + * + */ +int +ecore_evas_fullscreen_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_fullscreen_get"); + return 0; + } + return ee->prop.fullscreen ? 1:0; +} + +/** + * Set whether or not an Ecore_Evas' window should avoid damage + * + * @param ee The Ecore_Evas + * @param on 1 to avoid damage, 0 to not + * + * This function causes @p ee to be drawn to a pixmap to avoid recalculations. + * On expose events it will copy from the pixmap to the window. + */ +void +ecore_evas_avoid_damage_set(Ecore_Evas *ee, int on) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_avoid_damage_set"); + return; + } + IFC(ee, fn_avoid_damage_set) (ee, on); + IFE; +} + +/** + * Query whether an Ecore_Evas' window avoids damage or not + * @param ee The Ecore_Evas to set + * @return 1 if @p ee avoids damage, 0 if not. + * + */ +int +ecore_evas_avoid_damage_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_avoid_damage_get"); + return 0; + } + return ee->prop.avoid_damage ? 1:0; +} + +/** + * Set the withdrawn state of an Ecore_Evas' window. + * @param ee The Ecore_Evas whose window's withdrawn state is set. + * @param withdrawn The Ecore_Evas window's new withdrawn state. + * + */ +void +ecore_evas_withdrawn_set(Ecore_Evas *ee, int withdrawn) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_withdrawn_set"); + return; + } + + IFC(ee, fn_withdrawn_set) (ee, withdrawn); + IFE; +} + +/** + * Returns the withdrawn state of an Ecore_Evas' window. + * @param ee The Ecore_Evas whose window's withdrawn state is returned. + * @return The Ecore_Evas window's withdrawn state. + * + */ +int +ecore_evas_withdrawn_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_withdrawn_get"); + return 0; + } else + return ee->prop.withdrawn ? 1:0; +} + +/** + * Set the sticky state of an Ecore_Evas window. + * + * @param ee The Ecore_Evas whose window's sticky state is set. + * @param sticky The Ecore_Evas window's new sticky state. + * + */ +void +ecore_evas_sticky_set(Ecore_Evas *ee, int sticky) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_sticky_set"); + return; + } + + IFC(ee, fn_sticky_set) (ee, sticky); + IFE; +} + +/** + * Returns the sticky state of an Ecore_Evas' window. + * + * @param ee The Ecore_Evas whose window's sticky state is returned. + * @return The Ecore_Evas window's sticky state. + * + */ +int +ecore_evas_sticky_get(Ecore_Evas *ee) +{ + if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS)) + { + ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS, + "ecore_evas_sticky_get"); + return 0; + } else + return ee->prop.sticky ? 1:0; +} + +#ifndef WIN32 +/* fps debug calls - for debugging how much time your app actually spends */ +/* rendering graphics... :) */ + +static int _ecore_evas_fps_debug_init_count = 0; +static int _ecore_evas_fps_debug_fd = -1; +unsigned int *_ecore_evas_fps_rendertime_mmap = NULL; + +void +_ecore_evas_fps_debug_init(void) +{ + char buf[4096]; + + _ecore_evas_fps_debug_init_count++; + if (_ecore_evas_fps_debug_init_count > 1) return; + snprintf(buf, sizeof(buf), "/tmp/.ecore_evas_fps_debug-%i", (int)getpid()); + _ecore_evas_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR); + if (_ecore_evas_fps_debug_fd < 0) + { + unlink(buf); + _ecore_evas_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR); + } + if (_ecore_evas_fps_debug_fd >= 0) + { + unsigned int zero = 0; + + write(_ecore_evas_fps_debug_fd, &zero, sizeof(unsigned int)); + _ecore_evas_fps_rendertime_mmap = mmap(NULL, sizeof(unsigned int), + PROT_READ | PROT_WRITE, + MAP_SHARED, + _ecore_evas_fps_debug_fd, 0); + } +} + +void +_ecore_evas_fps_debug_shutdown(void) +{ + _ecore_evas_fps_debug_init_count--; + if (_ecore_evas_fps_debug_init_count > 0) return; + if (_ecore_evas_fps_debug_fd >= 0) + { + char buf[4096]; + + snprintf(buf, sizeof(buf), "/tmp/.ecore_evas_fps_debug-%i", (int)getpid()); + unlink(buf); + if (_ecore_evas_fps_rendertime_mmap) + { + munmap(_ecore_evas_fps_rendertime_mmap, sizeof(int)); + _ecore_evas_fps_rendertime_mmap = NULL; + } + close(_ecore_evas_fps_debug_fd); + _ecore_evas_fps_debug_fd = -1; + } +} + +void +_ecore_evas_fps_debug_rendertime_add(double t) +{ + if ((_ecore_evas_fps_debug_fd >= 0) && + (_ecore_evas_fps_rendertime_mmap)) + { + unsigned int tm; + + tm = (unsigned int)(t * 1000000.0); + /* i know its not 100% theoretically guaranteed, but i'd say a write */ + /* of an int could be considered atomic for all practical purposes */ + /* oh and since this is cumulative, 1 second = 1,000,000 ticks, so */ + /* this can run for about 4294 seconds becore looping. if you are */ + /* doing performance testing in one run for over an hour... well */ + /* time to restart or handle a loop condition :) */ + *(_ecore_evas_fps_rendertime_mmap) += tm; + } +} +#endif diff --git a/ecore/src/lib/ecore_evas/ecore_evas_buffer.c b/ecore/src/lib/ecore_evas/ecore_evas_buffer.c new file mode 100644 index 0000000..84e0078 --- /dev/null +++ b/ecore/src/lib/ecore_evas/ecore_evas_buffer.c @@ -0,0 +1,634 @@ +#include "config.h" +#include "Ecore.h" +#include "ecore_private.h" +#include "ecore_evas_private.h" +#include "Ecore_Evas.h" + +#ifdef BUILD_ECORE_EVAS_BUFFER +static int _ecore_evas_init_count = 0; + +static int _ecore_evas_fps_debug = 0; + +static Ecore_Evas *ecore_evases = NULL; + +static void +_ecore_evas_mouse_move_process(Ecore_Evas *ee, int x, int y, unsigned int timestamp) +{ + ee->mouse.x = x; + ee->mouse.y = y; + evas_event_feed_mouse_move(ee->evas, x, y, timestamp, NULL); +} + +static int +_ecore_evas_buffer_init(void) +{ + _ecore_evas_init_count++; + if (_ecore_evas_init_count > 1) return _ecore_evas_init_count; + if (getenv("ECORE_EVAS_FPS_DEBUG")) _ecore_evas_fps_debug = 1; + if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_init(); + return _ecore_evas_init_count; +} + +static void +_ecore_evas_buffer_free(Ecore_Evas *ee) +{ + ecore_evases = _ecore_list_remove(ecore_evases, ee); + _ecore_evas_buffer_shutdown(); + if (ee->engine.buffer.image) + { + Ecore_Evas *ee2; + + ee2 = evas_object_data_get(ee->engine.buffer.image, "Ecore_Evas_Parent"); + evas_object_del(ee->engine.buffer.image); + ee2->sub_ecore_evas = evas_list_remove(ee2->sub_ecore_evas, ee); + } + else + free(ee->engine.buffer.pixels); +} + +static void +_ecore_evas_resize(Ecore_Evas *ee, int w, int h) +{ + Evas_Engine_Info_Buffer *einfo; + + if (w < 1) w = 1; + if (h < 1) h = 1; + if ((w == ee->w) && (h == ee->h)) return; + ee->w = w; + ee->h = h; + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + + if (ee->engine.buffer.image) + { + ee->engine.buffer.pixels = evas_object_image_data_get(ee->engine.buffer.image, 1); + } + else + { + if (ee->engine.buffer.pixels) free(ee->engine.buffer.pixels); + ee->engine.buffer.pixels = malloc(ee->w * ee->h * sizeof(int)); + } + + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + einfo->info.dest_buffer = ee->engine.buffer.pixels; + einfo->info.dest_buffer_row_bytes = ee->w * sizeof(int); + einfo->info.use_color_key = 0; + einfo->info.alpha_threshold = 0; + einfo->info.func.new_update_region = NULL; + einfo->info.func.free_update_region = NULL; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + } + if (ee->func.fn_resize) ee->func.fn_resize(ee); +} + +int +_ecore_evas_buffer_shutdown(void) +{ + _ecore_evas_init_count--; + if (_ecore_evas_init_count == 0) + { + while (ecore_evases) + ecore_evas_free((Ecore_Evas *)(ecore_evases->data)); + if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_shutdown(); + } + if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0; + return _ecore_evas_init_count; +} + +void +_ecore_evas_buffer_render(Ecore_Evas *ee) +{ + Evas_List *updates, *l, *ll; + + for (ll = ee->sub_ecore_evas; ll; ll = ll->next) + { + Ecore_Evas *ee2; + + ee2 = ll->data; + if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); + _ecore_evas_buffer_render(ee2); + if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); + } + if (ee->engine.buffer.image) + { + int w, h; + + evas_object_image_size_get(ee->engine.buffer.image, &w, &h); + if ((w != ee->w) || (h != ee->h)) + _ecore_evas_resize(ee, w, h); + } + updates = evas_render_updates(ee->evas); + if (ee->engine.buffer.image) + { + for (l = updates; l; l = l->next) + { + Evas_Rectangle *r; + + r = l->data; + if (ee->engine.buffer.image) + evas_object_image_data_update_add(ee->engine.buffer.image, + r->x, r->y, r->w, r->h); + } + } + if (updates) evas_render_updates_free(updates); +} + +static void +_ecore_evas_buffer_coord_translate(Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y) +{ + Evas_Coord xx, yy, fx, fy, fw, fh; + + evas_object_geometry_get(ee->engine.buffer.image, &xx, &yy, NULL, NULL); + evas_object_image_fill_get(ee->engine.buffer.image, &fx, &fy, &fw, &fh); + + if (fw < 1) fw = 1; + xx = (*x - xx) - fx; + while (xx < 0) xx += fw; + while (xx > fw) xx -= fw; + *x = (ee->w * xx) / fw; + + if (fh < 1) fh = 1; + yy = (*y - yy) - fy; + while (yy < 0) yy += fh; + while (yy > fh) yy -= fh; + *y = (ee->h * yy) / fh; +} + +static void +_ecore_evas_buffer_cb_mouse_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Ecore_Evas *ee; + Evas_Event_Mouse_In *ev; + + ee = data; + ev = event_info; + evas_event_feed_mouse_in(ee->evas, ev->timestamp, NULL); +} + +static void +_ecore_evas_buffer_cb_mouse_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Ecore_Evas *ee; + Evas_Event_Mouse_Out *ev; + + ee = data; + ev = event_info; + evas_event_feed_mouse_out(ee->evas, ev->timestamp, NULL); +} + +static void +_ecore_evas_buffer_cb_mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) +{ + Ecore_Evas *ee; + Evas_Event_Mouse_Down *ev; + + ee = data; + ev = event_info; + evas_event_feed_mouse_down(ee->evas, ev->button, ev->flags, ev->timestamp, NULL); +} + +static void +_ecore_evas_buffer_cb_mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) +{ + Ecore_Evas *ee; + Evas_Event_Mouse_Up *ev; + + ee = data; + ev = event_info; + evas_event_feed_mouse_up(ee->evas, ev->button, ev->flags, ev->timestamp, NULL); +} + +static void +_ecore_evas_buffer_cb_mouse_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) +{ + Ecore_Evas *ee; + Evas_Event_Mouse_Move *ev; + Evas_Coord x, y; + + ee = data; + ev = event_info; + x = ev->cur.canvas.x; + y = ev->cur.canvas.y; + _ecore_evas_buffer_coord_translate(ee, &x, &y); + _ecore_evas_mouse_move_process(ee, x, y, ev->timestamp); +} + +static void +_ecore_evas_buffer_cb_mouse_wheel(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) +{ + Ecore_Evas *ee; + Evas_Event_Mouse_Wheel *ev; + + ee = data; + ev = event_info; + evas_event_feed_mouse_wheel(ee->evas, ev->direction, ev->z, ev->timestamp, NULL); +} + +static void +_ecore_evas_buffer_cb_free(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Ecore_Evas *ee; + + ee = data; + if (ee->driver) + ecore_evas_free(ee); +} + +static void +_ecore_evas_buffer_cb_key_down(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info) +{ + Ecore_Evas *ee; + Evas_Event_Key_Down *ev; + + ee = data; + ev = event_info; + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift")) + evas_key_modifier_on(e, "Shift"); + else + evas_key_modifier_off(e, "Shift"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control")) + evas_key_modifier_on(e, "Control"); + else + evas_key_modifier_off(e, "Control"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt")) + evas_key_modifier_on(e, "Alt"); + else + evas_key_modifier_off(e, "Alt"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta")) + evas_key_modifier_on(e, "Meta"); + else + evas_key_modifier_off(e, "Meta"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper")) + evas_key_modifier_on(e, "Hyper"); + else + evas_key_modifier_off(e, "Hyper"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super")) + evas_key_modifier_on(e, "Super"); + else + evas_key_modifier_off(e, "Super"); + if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock")) + evas_key_lock_on(e, "Scroll_Lock"); + else + evas_key_lock_off(e, "Scroll_Lock"); + if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock")) + evas_key_lock_on(e, "Num_Lock"); + else + evas_key_lock_off(e, "Num_Lock"); + if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock")) + evas_key_lock_on(e, "Caps_Lock"); + else + evas_key_lock_off(e, "Caps_Lock"); + evas_event_feed_key_down(ee->evas, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, NULL); +} + +static void +_ecore_evas_buffer_cb_key_up(void *data, Evas *e, Evas_Object *obj __UNUSED__, void *event_info) +{ + Ecore_Evas *ee; + Evas_Event_Key_Up *ev; + + ee = data; + ev = event_info; + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Shift")) + evas_key_modifier_on(e, "Shift"); + else + evas_key_modifier_off(e, "Shift"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Control")) + evas_key_modifier_on(e, "Control"); + else + evas_key_modifier_off(e, "Control"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Alt")) + evas_key_modifier_on(e, "Alt"); + else + evas_key_modifier_off(e, "Alt"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Meta")) + evas_key_modifier_on(e, "Meta"); + else + evas_key_modifier_off(e, "Meta"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Hyper")) + evas_key_modifier_on(e, "Hyper"); + else + evas_key_modifier_off(e, "Hyper"); + if (evas_key_modifier_is_set(evas_key_modifier_get(e), "Super")) + evas_key_modifier_on(e, "Super"); + else + evas_key_modifier_off(e, "Super"); + if (evas_key_lock_is_set(evas_key_lock_get(e), "Scroll_Lock")) + evas_key_lock_on(e, "Scroll_Lock"); + else + evas_key_lock_off(e, "Scroll_Lock"); + if (evas_key_lock_is_set(evas_key_lock_get(e), "Num_Lock")) + evas_key_lock_on(e, "Num_Lock"); + else + evas_key_lock_off(e, "Num_Lock"); + if (evas_key_lock_is_set(evas_key_lock_get(e), "Caps_Lock")) + evas_key_lock_on(e, "Caps_Lock"); + else + evas_key_lock_off(e, "Caps_Lock"); + evas_event_feed_key_up(ee->evas, ev->keyname, ev->key, ev->string, ev->compose, ev->timestamp, NULL); +} + +static void +_ecore_evas_buffer_cb_focus_in(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Ecore_Evas *ee; + + ee = data; + ee->prop.focused = 1; + if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); +} + +static void +_ecore_evas_buffer_cb_focus_out(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Ecore_Evas *ee; + + ee = data; + ee->prop.focused = 0; + if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); +} + +static void +_ecore_evas_buffer_cb_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Ecore_Evas *ee; + + ee = data; + ee->visible = 1; + if (ee->func.fn_show) ee->func.fn_show(ee); +} + +static void +_ecore_evas_buffer_cb_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Ecore_Evas *ee; + + ee = data; + ee->visible = 0; + if (ee->func.fn_hide) ee->func.fn_hide(ee); +} + +static const Ecore_Evas_Engine_Func _ecore_buffer_engine_func = +{ + _ecore_evas_buffer_free, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + _ecore_evas_resize, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; +#endif + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +Ecore_Evas * +ecore_evas_buffer_new(int w, int h) +{ +#ifdef BUILD_ECORE_EVAS_BUFFER + Evas_Engine_Info_Buffer *einfo; + Ecore_Evas *ee; + int rmethod; + + rmethod = evas_render_method_lookup("buffer"); + if (!rmethod) return NULL; + ee = calloc(1, sizeof(Ecore_Evas)); + if (!ee) return NULL; + + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); + + _ecore_evas_buffer_init(); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_buffer_engine_func; + + ee->driver = strdup("buffer"); + + if (w < 1) w = 1; + if (h < 1) h = 1; + ee->rotation = 0; + ee->visible = 1; + ee->w = w; + ee->h = h; + + ee->prop.max.w = 0; + ee->prop.max.h = 0; + ee->prop.layer = 0; + ee->prop.focused = 1; + ee->prop.borderless = 1; + ee->prop.override = 1; + ee->prop.maximized = 1; + ee->prop.fullscreen = 0; + ee->prop.withdrawn = 0; + ee->prop.sticky = 0; + + /* init evas here */ + ee->evas = evas_new(); + evas_output_method_set(ee->evas, rmethod); + evas_output_size_set(ee->evas, w, h); + evas_output_viewport_set(ee->evas, 0, 0, w, h); + + ee->engine.buffer.pixels = malloc(w * h * sizeof(int)); + + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + einfo->info.dest_buffer = ee->engine.buffer.pixels; + einfo->info.dest_buffer_row_bytes = ee->w * sizeof(int); + einfo->info.use_color_key = 0; + einfo->info.alpha_threshold = 0; + einfo->info.func.new_update_region = NULL; + einfo->info.func.free_update_region = NULL; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + } + evas_key_modifier_add(ee->evas, "Shift"); + evas_key_modifier_add(ee->evas, "Control"); + evas_key_modifier_add(ee->evas, "Alt"); + evas_key_modifier_add(ee->evas, "Meta"); + evas_key_modifier_add(ee->evas, "Hyper"); + evas_key_modifier_add(ee->evas, "Super"); + evas_key_lock_add(ee->evas, "Caps_Lock"); + evas_key_lock_add(ee->evas, "Num_Lock"); + evas_key_lock_add(ee->evas, "Scroll_Lock"); + + evas_event_feed_mouse_in(ee->evas, 0, NULL); + + ecore_evases = _ecore_list_prepend(ecore_evases, ee); + return ee; +#else + return NULL; +#endif +} + +const int * +ecore_evas_buffer_pixels_get(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_EVAS_BUFFER + _ecore_evas_buffer_render(ee); + return ee->engine.buffer.pixels; +#else + return NULL; +#endif +} + +Evas_Object * +ecore_evas_object_image_new(Ecore_Evas *ee_target) +{ +#ifdef BUILD_ECORE_EVAS_BUFFER + Evas_Object *o; + Evas_Engine_Info_Buffer *einfo; + Ecore_Evas *ee; + int rmethod; + int w, h; + + rmethod = evas_render_method_lookup("buffer"); + if (!rmethod) return NULL; + ee = calloc(1, sizeof(Ecore_Evas)); + if (!ee) return NULL; + + o = evas_object_image_add(ee_target->evas); + + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); + + _ecore_evas_buffer_init(); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_buffer_engine_func; + + ee->driver = strdup("buffer"); + + w = 1; + h = 1; + ee->rotation = 0; + ee->visible = 0; + ee->w = w; + ee->h = h; + + ee->prop.max.w = 0; + ee->prop.max.h = 0; + ee->prop.layer = 0; + ee->prop.focused = 0; + ee->prop.borderless = 1; + ee->prop.override = 1; + ee->prop.maximized = 0; + ee->prop.fullscreen = 0; + ee->prop.withdrawn = 0; + ee->prop.sticky = 0; + + /* init evas here */ + ee->evas = evas_new(); + evas_output_method_set(ee->evas, rmethod); + evas_output_size_set(ee->evas, w, h); + evas_output_viewport_set(ee->evas, 0, 0, w, h); + + ee->engine.buffer.image = o; + evas_object_data_set(ee->engine.buffer.image, "Ecore_Evas", ee); + evas_object_data_set(ee->engine.buffer.image, "Ecore_Evas_Parent", ee_target); + evas_object_image_size_set(o, ee->w, ee->h); + evas_object_image_alpha_set(o, 1); + ee->engine.buffer.pixels = evas_object_image_data_get(o, 1); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MOUSE_IN, + _ecore_evas_buffer_cb_mouse_in, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MOUSE_OUT, + _ecore_evas_buffer_cb_mouse_out, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MOUSE_DOWN, + _ecore_evas_buffer_cb_mouse_down, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MOUSE_UP, + _ecore_evas_buffer_cb_mouse_up, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MOUSE_MOVE, + _ecore_evas_buffer_cb_mouse_move, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_MOUSE_WHEEL, + _ecore_evas_buffer_cb_mouse_wheel, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_FREE, + _ecore_evas_buffer_cb_free, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_KEY_DOWN, + _ecore_evas_buffer_cb_key_down, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_KEY_UP, + _ecore_evas_buffer_cb_key_up, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_FOCUS_IN, + _ecore_evas_buffer_cb_focus_in, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_FOCUS_OUT, + _ecore_evas_buffer_cb_focus_out, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_SHOW, + _ecore_evas_buffer_cb_show, ee); + evas_object_event_callback_add(ee->engine.buffer.image, + EVAS_CALLBACK_HIDE, + _ecore_evas_buffer_cb_hide, ee); + einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->info.depth_type = EVAS_ENGINE_BUFFER_DEPTH_ARGB32; + einfo->info.dest_buffer = ee->engine.buffer.pixels; + einfo->info.dest_buffer_row_bytes = ee->w * sizeof(int); + einfo->info.use_color_key = 0; + einfo->info.alpha_threshold = 0; + einfo->info.func.new_update_region = NULL; + einfo->info.func.free_update_region = NULL; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + } + evas_key_modifier_add(ee->evas, "Shift"); + evas_key_modifier_add(ee->evas, "Control"); + evas_key_modifier_add(ee->evas, "Alt"); + evas_key_modifier_add(ee->evas, "Meta"); + evas_key_modifier_add(ee->evas, "Hyper"); + evas_key_modifier_add(ee->evas, "Super"); + evas_key_lock_add(ee->evas, "Caps_Lock"); + evas_key_lock_add(ee->evas, "Num_Lock"); + evas_key_lock_add(ee->evas, "Scroll_Lock"); + + ee_target->sub_ecore_evas = evas_list_append(ee_target->sub_ecore_evas, ee); + return o; +#else + return NULL; +#endif +} diff --git a/ecore/src/lib/ecore_evas/ecore_evas_fb.c b/ecore/src/lib/ecore_evas/ecore_evas_fb.c new file mode 100644 index 0000000..b0a6d2a --- /dev/null +++ b/ecore/src/lib/ecore_evas/ecore_evas_fb.c @@ -0,0 +1,542 @@ +#include "config.h" +#include "Ecore.h" +#include "ecore_private.h" +#include "ecore_evas_private.h" +#include "Ecore_Evas.h" +#ifdef BUILD_ECORE_EVAS_FB +#include "Ecore_Fb.h" +#endif + +#ifdef BUILD_ECORE_EVAS_FB +static int _ecore_evas_init_count = 0; + +static int _ecore_evas_fps_debug = 0; + +static Ecore_Evas *ecore_evases = NULL; +static Ecore_Event_Handler *ecore_evas_event_handlers[5]; +static Ecore_Idle_Enterer *ecore_evas_idle_enterer = NULL; + +static void +_ecore_evas_mouse_move_process(Ecore_Evas *ee, int x, int y, unsigned int timestamp) +{ + int fbw, fbh; + + ee->mouse.x = x; + ee->mouse.y = y; + ecore_fb_size_get(&fbw, &fbh); + if (ee->prop.cursor.object) + { + evas_object_show(ee->prop.cursor.object); + if (ee->rotation == 0) + evas_object_move(ee->prop.cursor.object, + x - ee->prop.cursor.hot.x, + y - ee->prop.cursor.hot.y); + else if (ee->rotation == 90) + evas_object_move(ee->prop.cursor.object, + (fbh - ee->h) + ee->h - y - 1 - ee->prop.cursor.hot.x, + x - ee->prop.cursor.hot.y); + else if (ee->rotation == 180) + evas_object_move(ee->prop.cursor.object, + (fbw - ee->w) + ee->w - x - 1 - ee->prop.cursor.hot.x, + (fbh - ee->h) + ee->h - y - 1 - ee->prop.cursor.hot.y); + else if (ee->rotation == 270) + evas_object_move(ee->prop.cursor.object, + y - ee->prop.cursor.hot.x, + (fbw - ee->w) + ee->w - x - 1 - ee->prop.cursor.hot.y); + } + if (ee->rotation == 0) + evas_event_feed_mouse_move(ee->evas, x, y, timestamp, NULL); + else if (ee->rotation == 90) + evas_event_feed_mouse_move(ee->evas, (fbh - ee->h) + ee->h - y - 1, x, timestamp, NULL); + else if (ee->rotation == 180) + evas_event_feed_mouse_move(ee->evas, (fbw - ee->w) + ee->w - x - 1, (fbh - ee->h) + ee->h - y - 1, timestamp, NULL); + else if (ee->rotation == 270) + evas_event_feed_mouse_move(ee->evas, y, (fbw - ee->w) + ee->w - x - 1, timestamp, NULL); +} + +static Ecore_Evas * +_ecore_evas_fb_match(void) +{ + Ecore_Oldlist *l; + + for (l = (Ecore_Oldlist *)ecore_evases; l; l = l->next) + { + Ecore_Evas *ee; + + ee = (Ecore_Evas *)l; + return ee; + } + return NULL; +} + +static void +_ecore_evas_fb_lose(void *data __UNUSED__) +{ + Ecore_Oldlist *l; + + for (l = (Ecore_Oldlist *)ecore_evases; l; l = l->next) + { + Ecore_Evas *ee; + + ee = (Ecore_Evas *)l; + ee->visible = 0; + } +} + +static void +_ecore_evas_fb_gain(void *data __UNUSED__) +{ + Ecore_Oldlist *l; + + for (l = (Ecore_Oldlist *)ecore_evases; l; l = l->next) + { + Ecore_Evas *ee; + + ee = (Ecore_Evas *)l; + ee->visible = 1; + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + } +} + +static int +_ecore_evas_event_key_down(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Fb_Event_Key_Down *e; + + e = event; + ee = _ecore_evas_fb_match(); + if (!ee) return 1; /* pass on event */ + evas_event_feed_key_down(ee->evas, e->keyname, e->keysymbol, e->key_compose, NULL, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); + return 0; /* dont pass it on */ +} + +static int +_ecore_evas_event_key_up(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Fb_Event_Key_Up *e; + + e = event; + ee = _ecore_evas_fb_match(); + if (!ee) return 1; /* pass on event */ + evas_event_feed_key_up(ee->evas, e->keyname, e->keysymbol, e->key_compose, NULL, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); + return 0; /* dont pass it on */ +} + +static int +_ecore_evas_event_mouse_button_down(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Fb_Event_Mouse_Button_Down *e; + Evas_Button_Flags flags = EVAS_BUTTON_NONE; + + e = event; + ee = _ecore_evas_fb_match(); + if (!ee) return 1; /* pass on event */ + _ecore_evas_mouse_move_process(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff)); + if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK; + if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK; + evas_event_feed_mouse_down(ee->evas, e->button, flags, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); + return 0; /* dont pass it on */ +} + +static int +_ecore_evas_event_mouse_button_up(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Fb_Event_Mouse_Button_Up *e; + + e = event; + ee = _ecore_evas_fb_match(); + if (!ee) return 1; /* pass on event */ + _ecore_evas_mouse_move_process(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff)); + evas_event_feed_mouse_up(ee->evas, e->button, EVAS_BUTTON_NONE, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); + return 0; /* dont pass it on */ +} + +static int +_ecore_evas_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_Fb_Event_Mouse_Move *e; + + e = event; + ee = _ecore_evas_fb_match(); + if (!ee) return 1; /* pass on event */ + _ecore_evas_mouse_move_process(ee, e->x, e->y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff)); + return 0; /* dont pass it on */ +} + +static int +_ecore_evas_idle_enter(void *data __UNUSED__) +{ + Ecore_Oldlist *l; + double t1 = 0.; + double t2 = 0.; + + if (_ecore_evas_fps_debug) + { + t1 = ecore_time_get(); + } + for (l = (Ecore_Oldlist *)ecore_evases; l; l = l->next) + { + Ecore_Evas *ee; + + ee = (Ecore_Evas *)l; + if (ee->visible) + { +#ifdef BUILD_ECORE_EVAS_BUFFER + Evas_List *ll; +#endif + + if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); +#ifdef BUILD_ECORE_EVAS_BUFFER + for (ll = ee->sub_ecore_evas; ll; ll = ll->next) + { + Ecore_Evas *ee2; + + ee2 = ll->data; + if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); + _ecore_evas_buffer_render(ee2); + if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); + } +#endif + evas_render(ee->evas); + if (ee->func.fn_post_render) ee->func.fn_post_render(ee); + } + } + if (_ecore_evas_fps_debug) + { + t2 = ecore_time_get(); + _ecore_evas_fps_debug_rendertime_add(t2 - t1); + } + return 1; +} + +static int +_ecore_evas_fb_init(void) +{ + _ecore_evas_init_count++; + if (_ecore_evas_init_count > 1) return _ecore_evas_init_count; + if (getenv("ECORE_EVAS_FPS_DEBUG")) _ecore_evas_fps_debug = 1; + ecore_evas_idle_enterer = ecore_idle_enterer_add(_ecore_evas_idle_enter, NULL); + ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_FB_EVENT_KEY_DOWN, _ecore_evas_event_key_down, NULL); + ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_FB_EVENT_KEY_UP, _ecore_evas_event_key_up, NULL); + ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_event_mouse_button_down, NULL); + ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, _ecore_evas_event_mouse_button_up, NULL); + ecore_evas_event_handlers[4] = ecore_event_handler_add(ECORE_FB_EVENT_MOUSE_MOVE, _ecore_evas_event_mouse_move, NULL); + if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_init(); + return _ecore_evas_init_count; +} + +static void +_ecore_evas_fb_free(Ecore_Evas *ee) +{ + ecore_evases = _ecore_list_remove(ecore_evases, ee); + _ecore_evas_fb_shutdown(); + ecore_fb_shutdown(); +} + +static void +_ecore_evas_resize(Ecore_Evas *ee, int w, int h) +{ + if ((w == ee->w) && (h == ee->h)) return; + ee->w = w; + ee->h = h; + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + if (ee->func.fn_resize) ee->func.fn_resize(ee); +} + +static void +_ecore_evas_move_resize(Ecore_Evas *ee, int x __UNUSED__, int y __UNUSED__, int w, int h) +{ + if ((w == ee->w) && (h == ee->h)) return; + ee->w = w; + ee->h = h; + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + if (ee->func.fn_resize) ee->func.fn_resize(ee); +} + +static void +_ecore_evas_rotation_set(Ecore_Evas *ee, int rotation) +{ + Evas_Engine_Info_FB *einfo; + int rot_dif; + + if (ee->rotation == rotation) return; + einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas); + if (!einfo) return; + rot_dif = ee->rotation - rotation; + if (rot_dif < 0) rot_dif = -rot_dif; + if (rot_dif != 180) + { + + einfo->info.rotation = rotation; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + if (!ee->prop.fullscreen) + { + int tmp; + + tmp = ee->w; + ee->w = ee->h; + ee->h = tmp; + } + else + { + if ((rotation == 0) || (rotation == 180)) + { + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + } + else + { + evas_output_size_set(ee->evas, ee->h, ee->w); + evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w); + } + } + ee->rotation = rotation; + } + else + { + einfo->info.rotation = rotation; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + ee->rotation = rotation; + } + if ((ee->rotation == 90) || (ee->rotation == 270)) + evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w); + else + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff)); + if (ee->func.fn_resize) ee->func.fn_resize(ee); +} + +static void +_ecore_evas_cursor_set(Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y) +{ + int x, y; + + if (!file) + { + if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object); + if (ee->prop.cursor.file) free(ee->prop.cursor.file); + ee->prop.cursor.object = NULL; + ee->prop.cursor.file = NULL; + ee->prop.cursor.layer = 0; + ee->prop.cursor.hot.x = 0; + ee->prop.cursor.hot.y = 0; + return; + } + if (!ee->prop.cursor.object) ee->prop.cursor.object = evas_object_image_add(ee->evas); + if (ee->prop.cursor.file) free(ee->prop.cursor.file); + ee->prop.cursor.file = strdup(file); + ee->prop.cursor.layer = layer; + ee->prop.cursor.hot.x = hot_x; + ee->prop.cursor.hot.y = hot_y; + evas_pointer_output_xy_get(ee->evas, &x, &y); + evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer); + evas_object_color_set(ee->prop.cursor.object, 255, 255, 255, 255); + evas_object_move(ee->prop.cursor.object, + x - ee->prop.cursor.hot.x, + y - ee->prop.cursor.hot.y); + evas_object_image_file_set(ee->prop.cursor.object, ee->prop.cursor.file, NULL); + evas_object_image_size_get(ee->prop.cursor.object, &x, &y); + evas_object_resize(ee->prop.cursor.object, x, y); + evas_object_image_fill_set(ee->prop.cursor.object, 0, 0, x, y); + evas_object_pass_events_set(ee->prop.cursor.object, 1); + if (evas_pointer_inside_get(ee->evas)) + evas_object_show(ee->prop.cursor.object); +} + +static void +_ecore_evas_fullscreen_set(Ecore_Evas *ee, int on) +{ + int resized = 0; + + if (((ee->prop.fullscreen) && (on)) || + ((!ee->prop.fullscreen) && (!on))) return; + if (on) + { + int w, h; + + ee->engine.fb.real_w = ee->w; + ee->engine.fb.real_h = ee->h; + w = ee->w; + h = ee->h; + ecore_fb_size_get(&w, &h); + if ((w == 0) && (h == 0)) + { + w = ee->w; + h = ee->h; + } + if ((w != ee->w) || (h != ee->h)) resized = 1; + ee->w = w; + ee->h = h; + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + } + else + { + if ((ee->engine.fb.real_w != ee->w) || (ee->engine.fb.real_h != ee->h)) resized = 1; + ee->w = ee->engine.fb.real_w; + ee->h = ee->engine.fb.real_h; + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + } + ee->prop.fullscreen = on; + if (resized) + { + if (ee->func.fn_resize) ee->func.fn_resize(ee); + } +} + +int +_ecore_evas_fb_shutdown(void) +{ + _ecore_evas_init_count--; + if (_ecore_evas_init_count == 0) + { + int i; + + while (ecore_evases) ecore_evas_free(ecore_evases); + for (i = 0; i < 5; i++) + ecore_event_handler_del(ecore_evas_event_handlers[i]); + ecore_idle_enterer_del(ecore_evas_idle_enterer); + ecore_evas_idle_enterer = NULL; + if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_shutdown(); + } + if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0; + return _ecore_evas_init_count; +} + +static const Ecore_Evas_Engine_Func _ecore_fb_engine_func = +{ + _ecore_evas_fb_free, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + _ecore_evas_resize, + _ecore_evas_move_resize, + _ecore_evas_rotation_set, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + _ecore_evas_cursor_set, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + _ecore_evas_fullscreen_set, + NULL, + NULL, + NULL +}; +#endif + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +Ecore_Evas * +ecore_evas_fb_new(char *disp_name, int rotation, int w, int h) +{ +#ifdef BUILD_ECORE_EVAS_FB + Evas_Engine_Info_FB *einfo; + Ecore_Evas *ee; + int rmethod; + + rmethod = evas_render_method_lookup("fb"); + if (!rmethod) return NULL; + if (!ecore_fb_init(disp_name)) return NULL; + ecore_fb_callback_gain_set(_ecore_evas_fb_gain, NULL); + ecore_fb_callback_lose_set(_ecore_evas_fb_lose, NULL); + ee = calloc(1, sizeof(Ecore_Evas)); + if (!ee) return NULL; + + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); + + _ecore_evas_fb_init(); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_fb_engine_func; + + ee->driver = strdup("fb"); + if (disp_name) ee->name = strdup(disp_name); + + if (w < 1) w = 1; + if (h < 1) h = 1; + ee->rotation = rotation; + ee->visible = 1; + ee->w = w; + ee->h = h; + + ee->prop.max.w = 0; + ee->prop.max.h = 0; + ee->prop.layer = 0; + ee->prop.focused = 1; + ee->prop.borderless = 1; + ee->prop.override = 1; + ee->prop.maximized = 1; + ee->prop.fullscreen = 0; + ee->prop.withdrawn = 0; + ee->prop.sticky = 0; + + /* init evas here */ + ee->evas = evas_new(); + evas_output_method_set(ee->evas, rmethod); + evas_output_size_set(ee->evas, w, h); + evas_output_viewport_set(ee->evas, 0, 0, w, h); + + einfo = (Evas_Engine_Info_FB *)evas_engine_info_get(ee->evas); + if (einfo) + { + einfo->info.virtual_terminal = 0; + einfo->info.device_number = 0; + einfo->info.refresh = 0; + einfo->info.rotation = ee->rotation; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + } + evas_key_modifier_add(ee->evas, "Shift"); + evas_key_modifier_add(ee->evas, "Control"); + evas_key_modifier_add(ee->evas, "Alt"); + evas_key_modifier_add(ee->evas, "Meta"); + evas_key_modifier_add(ee->evas, "Hyper"); + evas_key_modifier_add(ee->evas, "Super"); + evas_key_lock_add(ee->evas, "Caps_Lock"); + evas_key_lock_add(ee->evas, "Num_Lock"); + evas_key_lock_add(ee->evas, "Scroll_Lock"); + + evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL); + + ecore_evases = _ecore_list_prepend(ecore_evases, ee); + return ee; +#else + return NULL; +#endif +} diff --git a/ecore/src/lib/ecore_evas/ecore_evas_private.h b/ecore/src/lib/ecore_evas/ecore_evas_private.h new file mode 100644 index 0000000..675816d --- /dev/null +++ b/ecore/src/lib/ecore_evas/ecore_evas_private.h @@ -0,0 +1,216 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#ifndef _ECORE_EVAS_PRIVATE_H +#define _ECORE_EVAS_PRIVATE_H + +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +#include + +#define ECORE_MAGIC_EVAS 0x76543211 + +#ifdef BUILD_ECORE_X +#include "Ecore_X.h" +#include +#include +#include +#ifdef BUILD_ECORE_EVAS_GL +#include +#endif +#endif +#ifdef BUILD_ECORE_EVAS_FB +#include +#endif +#ifdef BUILD_ECORE_EVAS_BUFFER +#include +#endif + +typedef struct _Ecore_Evas Ecore_Evas; +typedef struct _Ecore_Evas_Engine Ecore_Evas_Engine; +typedef struct _Ecore_Evas_Engine_Func Ecore_Evas_Engine_Func; + +struct _Ecore_Evas_Engine_Func +{ + void (*fn_free) (Ecore_Evas *ee); + void (*fn_callback_resize_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); + void (*fn_callback_move_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); + void (*fn_callback_show_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); + void (*fn_callback_hide_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); + void (*fn_callback_delete_request_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); + void (*fn_callback_destroy_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); + void (*fn_callback_focus_in_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); + void (*fn_callback_focus_out_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); + void (*fn_callback_mouse_in_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); + void (*fn_callback_mouse_out_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); + void (*fn_callback_pre_render_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); + void (*fn_callback_post_render_set) (Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)); + void (*fn_move) (Ecore_Evas *ee, int x, int y); + void (*fn_resize) (Ecore_Evas *ee, int w, int h); + void (*fn_move_resize) (Ecore_Evas *ee, int x, int y, int w, int h); + void (*fn_rotation_set) (Ecore_Evas *ee, int rot); + void (*fn_shaped_set) (Ecore_Evas *ee, int shaped); + void (*fn_show) (Ecore_Evas *ee); + void (*fn_hide) (Ecore_Evas *ee); + void (*fn_raise) (Ecore_Evas *ee); + void (*fn_lower) (Ecore_Evas *ee); + void (*fn_title_set) (Ecore_Evas *ee, const char *t); + void (*fn_name_class_set) (Ecore_Evas *ee, const char *n, const char *c); + void (*fn_size_min_set) (Ecore_Evas *ee, int w, int h); + void (*fn_size_max_set) (Ecore_Evas *ee, int w, int h); + void (*fn_size_base_set) (Ecore_Evas *ee, int w, int h); + void (*fn_size_step_set) (Ecore_Evas *ee, int w, int h); + void (*fn_cursor_set) (Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y); + void (*fn_layer_set) (Ecore_Evas *ee, int layer); + void (*fn_focus_set) (Ecore_Evas *ee, int on); + void (*fn_iconified_set) (Ecore_Evas *ee, int on); + void (*fn_borderless_set) (Ecore_Evas *ee, int on); + void (*fn_override_set) (Ecore_Evas *ee, int on); + void (*fn_maximized_set) (Ecore_Evas *ee, int on); + void (*fn_fullscreen_set) (Ecore_Evas *ee, int on); + void (*fn_avoid_damage_set) (Ecore_Evas *ee, int on); + void (*fn_withdrawn_set) (Ecore_Evas *ee, int withdrawn); + void (*fn_sticky_set) (Ecore_Evas *ee, int sticky); +}; + +struct _Ecore_Evas_Engine +{ + Ecore_Evas_Engine_Func *func; + +#ifdef BUILD_ECORE_X + struct { + Ecore_X_Window win_root; + Ecore_X_Window win_container; + Ecore_X_Window win; + Ecore_X_Pixmap pmap; + Ecore_X_Pixmap mask; + Ecore_X_GC gc; + Region damages; + unsigned char direct_resize : 1; + unsigned char using_bg_pixmap : 1; + struct { + /* + unsigned char modal : 1; + */ + unsigned char sticky : 1; + /* + unsigned char maximized_v : 1; + unsigned char maximized_h : 1; + unsigned char shaded : 1; + unsigned char skip_taskbar : 1; + unsigned char skip_pager : 1; + unsigned char fullscreen : 1; + */ + unsigned char above : 1; + unsigned char below : 1; + } state; + } x; +#endif +#ifdef BUILD_ECORE_EVAS_FB + struct { + int real_w; + int real_h; + } fb; +#endif +#ifdef BUILD_ECORE_EVAS_BUFFER + struct { + void *pixels; + Evas_Object *image; + } buffer; +#endif +}; + +struct _Ecore_Evas +{ + Ecore_List __list_data; + ECORE_MAGIC; + Evas *evas; + char *driver; + char *name; + int x, y, w, h; + short rotation; + char shaped : 1; + char visible : 1; + char should_be_visible : 1; + + Evas_Hash *data; + + struct { + int x, y; + } mouse; + + struct { + int w, h; + } expecting_resize; + + struct { + char *title; + char *name; + char *clas; + struct { + int w, h; + } min, + max, + base, + step; + struct { + Evas_Object *object; + char *file; + int layer; + struct { + int x, y; + } hot; + } cursor; + int layer; + char focused : 1; + char iconified : 1; + char borderless : 1; + char override : 1; + char maximized : 1; + char fullscreen : 1; + char avoid_damage : 1; + char withdrawn : 1; + char sticky : 1; + } prop; + + struct { + void (*fn_resize) (Ecore_Evas *ee); + void (*fn_move) (Ecore_Evas *ee); + void (*fn_show) (Ecore_Evas *ee); + void (*fn_hide) (Ecore_Evas *ee); + void (*fn_delete_request) (Ecore_Evas *ee); + void (*fn_destroy) (Ecore_Evas *ee); + void (*fn_focus_in) (Ecore_Evas *ee); + void (*fn_focus_out) (Ecore_Evas *ee); + void (*fn_mouse_in) (Ecore_Evas *ee); + void (*fn_mouse_out) (Ecore_Evas *ee); + void (*fn_pre_render) (Ecore_Evas *ee); + void (*fn_post_render) (Ecore_Evas *ee); + } func; + + Ecore_Evas_Engine engine; + Evas_List *sub_ecore_evas; +}; + +#ifdef BUILD_ECORE_X +int _ecore_evas_x_shutdown(void); +#endif +#ifdef BUILD_ECORE_EVAS_FB +int _ecore_evas_fb_shutdown(void); +#endif +#ifdef BUILD_ECORE_EVAS_BUFFER +int _ecore_evas_buffer_shutdown(void); +void _ecore_evas_buffer_render(Ecore_Evas *ee); +#endif + +void _ecore_evas_fps_debug_init(void); +void _ecore_evas_fps_debug_shutdown(void); +void _ecore_evas_fps_debug_rendertime_add(double t); + +#endif diff --git a/ecore/src/lib/ecore_evas/ecore_evas_x.c b/ecore/src/lib/ecore_evas/ecore_evas_x.c new file mode 100644 index 0000000..243ddb6 --- /dev/null +++ b/ecore/src/lib/ecore_evas/ecore_evas_x.c @@ -0,0 +1,1938 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "config.h" +#include "Ecore.h" +#include "ecore_private.h" +#include "ecore_evas_private.h" +#include "Ecore_Evas.h" +#ifdef BUILD_ECORE_X +#include "Ecore_X.h" +#endif + +#ifdef BUILD_ECORE_X +static int _ecore_evas_init_count = 0; + +static int _ecore_evas_fps_debug = 0; + +static Ecore_Evas *ecore_evases = NULL; +static Evas_Hash *ecore_evases_hash = NULL; +static Ecore_Event_Handler *ecore_evas_event_handlers[16]; +static Ecore_Idle_Enterer *ecore_evas_idle_enterer = NULL; + +static void +_ecore_evas_x_render(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_EVAS_BUFFER + Evas_List *ll; +#endif + +#ifdef BUILD_ECORE_EVAS_BUFFER + for (ll = ee->sub_ecore_evas; ll; ll = ll->next) + { + Ecore_Evas *ee2; + + ee2 = ll->data; + if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); + _ecore_evas_buffer_render(ee2); + if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2); + } +#endif + if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); + if (ee->prop.avoid_damage) + { + Evas_List *updates, *l; + + updates = evas_render_updates(ee->evas); +#if 0 + for (l = updates; l; l = l->next) + { + Evas_Rectangle *r; + + r = l->data; + printf("DMG render [%p] %ix%i, [%i %i %ix%i]\n", + ee, ee->w, ee->h, r->x, r->y, r->w, r->h); + } +#endif + if (ee->engine.x.using_bg_pixmap) + { + if (updates) + { + for (l = updates; l; l = l->next) + { + Evas_Rectangle *r; + + r = l->data; + ecore_x_window_area_clear(ee->engine.x.win, r->x, r->y, r->w, r->h); + } + if ((ee->shaped) && (updates)) + { + if (ee->prop.fullscreen) + ecore_x_window_shape_mask_set(ee->engine.x.win, ee->engine.x.mask); + else + ecore_x_window_shape_mask_set(ee->engine.x.win_container, ee->engine.x.mask); + } + } + if (updates) evas_render_updates_free(updates); + } + else + { + for (l = updates; l; l = l->next) + { + Evas_Rectangle *r; + XRectangle xr; + Region tmpr; + + if (!ee->engine.x.damages) + ee->engine.x.damages = XCreateRegion(); + r = l->data; + tmpr = XCreateRegion(); + if (ee->rotation == 0) + { + xr.x = r->x; + xr.y = r->y; + xr.width = r->w; + xr.height = r->h; + } + else if (ee->rotation == 90) + { + xr.x = r->y; + xr.y = ee->h - r->x - r->w; + xr.width = r->h; + xr.height = r->w; + } + else if (ee->rotation == 180) + { + xr.x = ee->w - r->x - r->w; + xr.y = ee->h - r->y - r->h; + xr.width = r->w; + xr.height = r->h; + } + else if (ee->rotation == 270) + { + xr.x = ee->w - r->y - r->h; + xr.y = r->x; + xr.width = r->h; + xr.height = r->w; + } + XUnionRectWithRegion(&xr, ee->engine.x.damages, tmpr); + XDestroyRegion(ee->engine.x.damages); + ee->engine.x.damages = tmpr; + } + if (ee->engine.x.damages) + { + if ((ee->shaped) && (updates)) + { + if (ee->prop.fullscreen) + ecore_x_window_shape_mask_set(ee->engine.x.win, ee->engine.x.mask); + else + ecore_x_window_shape_mask_set(ee->engine.x.win_container, ee->engine.x.mask); + } + XSetRegion(ecore_x_display_get(), ee->engine.x.gc, ee->engine.x.damages); + /* debug rendering */ + /* + XSetForeground(ecore_x_display_get(), ee->engine.x.gc, rand()); + XFillRectangle(ecore_x_display_get(), ee->engine.x.win, ee->engine.x.gc, + 0, 0, ee->w, ee->h); + XSync(ecore_x_display_get(), False); + usleep(20000); + XSync(ecore_x_display_get(), False); + */ + ecore_x_pixmap_paste(ee->engine.x.pmap, ee->engine.x.win, ee->engine.x.gc, + 0, 0, ee->w, ee->h, 0, 0); + XDestroyRegion(ee->engine.x.damages); + ee->engine.x.damages = 0; + } + if (updates) evas_render_updates_free(updates); + } + } + else if ((ee->visible) || + ((ee->should_be_visible) && (ee->prop.fullscreen)) || + ((ee->should_be_visible) && (ee->prop.override))) + { + if (ee->shaped) + { + Evas_List *updates; + + updates = evas_render_updates(ee->evas); + if (updates) + { + if (ee->prop.fullscreen) + ecore_x_window_shape_mask_set(ee->engine.x.win, ee->engine.x.mask); + else + ecore_x_window_shape_mask_set(ee->engine.x.win_container, ee->engine.x.mask); + evas_render_updates_free(updates); + } + } + else + { + Evas_List *updates; + + updates = evas_render_updates(ee->evas); + if (updates) + { +#if 0 + Evas_List *l; + + printf("RENDER [%p] [%i] %ix%i\n", + ee, ee->visible, ee->w, ee->h); + for (l = updates; l; l = l->next) + { + Evas_Rectangle *r; + + r = l->data; + printf(" render [%i %i %ix%i]\n", + r->x, r->y, r->w, r->h); + } +#endif + evas_render_updates_free(updates); + } + } + } + if (ee->func.fn_post_render) ee->func.fn_post_render(ee); +} + +static void +_ecore_evas_x_mouse_move_process(Ecore_Evas *ee, int x, int y, unsigned int timestamp) +{ + ee->mouse.x = x; + ee->mouse.y = y; + if (ee->prop.cursor.object) + { + evas_object_show(ee->prop.cursor.object); + if (ee->rotation == 0) + evas_object_move(ee->prop.cursor.object, + x - ee->prop.cursor.hot.x, + y - ee->prop.cursor.hot.y); + else if (ee->rotation == 90) + evas_object_move(ee->prop.cursor.object, + ee->h - y - 1 - ee->prop.cursor.hot.x, + x - ee->prop.cursor.hot.y); + else if (ee->rotation == 180) + evas_object_move(ee->prop.cursor.object, + ee->w - x - 1 - ee->prop.cursor.hot.x, + ee->h - y - 1 - ee->prop.cursor.hot.y); + else if (ee->rotation == 270) + evas_object_move(ee->prop.cursor.object, + y - ee->prop.cursor.hot.x, + ee->w - x - 1 - ee->prop.cursor.hot.y); + } + if (ee->rotation == 0) + evas_event_feed_mouse_move(ee->evas, x, y, timestamp, NULL); + else if (ee->rotation == 90) + evas_event_feed_mouse_move(ee->evas, ee->h - y - 1, x, timestamp, NULL); + else if (ee->rotation == 180) + evas_event_feed_mouse_move(ee->evas, ee->w - x - 1, ee->h - y - 1, timestamp, NULL); + else if (ee->rotation == 270) + evas_event_feed_mouse_move(ee->evas, y, ee->w - x - 1, timestamp, NULL); +} + +static char * +_ecore_evas_x_winid_str_get(Ecore_X_Window win) +{ + const char *vals = "qWeRtYuIoP5-$&<~"; + static char id[9]; + unsigned int val; + + val = (unsigned int)win; + id[0] = vals[(val >> 28) & 0xf]; + id[1] = vals[(val >> 24) & 0xf]; + id[2] = vals[(val >> 20) & 0xf]; + id[3] = vals[(val >> 16) & 0xf]; + id[4] = vals[(val >> 12) & 0xf]; + id[5] = vals[(val >> 8) & 0xf]; + id[6] = vals[(val >> 4) & 0xf]; + id[7] = vals[(val ) & 0xf]; + id[8] = 0; + return id; +} + +static Ecore_Evas * +_ecore_evas_x_match(Ecore_X_Window win) +{ + return evas_hash_find(ecore_evases_hash, _ecore_evas_x_winid_str_get(win)); +} + +static void +_ecore_evas_x_resize_shape(Ecore_Evas *ee) +{ + Evas_Engine_Info_Software_X11 *einfo; + + einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas); + if (einfo) + { + GC gc; + XGCValues gcv; + + if (ee->engine.x.mask) ecore_x_pixmap_del(ee->engine.x.mask); + ee->engine.x.mask = ecore_x_pixmap_new(ee->engine.x.win, ee->w, ee->h, 1); + gcv.foreground = 0; + gc = XCreateGC(ecore_x_display_get(), ee->engine.x.mask, + GCForeground, + &gcv); + XFillRectangle(ecore_x_display_get(), ee->engine.x.mask, gc, + 0, 0, ee->w, ee->h); + XFreeGC(ecore_x_display_get(), gc); + einfo->info.mask = ee->engine.x.mask; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + + } +} + +static void +_ecore_evas_x_modifier_locks_update(Ecore_Evas *ee, int modifiers) +{ + if (modifiers & ECORE_X_MODIFIER_SHIFT) + evas_key_modifier_on(ee->evas, "Shift"); + else + evas_key_modifier_off(ee->evas, "Shift"); + if (modifiers & ECORE_X_MODIFIER_CTRL) + evas_key_modifier_on(ee->evas, "Control"); + else + evas_key_modifier_off(ee->evas, "Control"); + if (modifiers & ECORE_X_MODIFIER_ALT) + evas_key_modifier_on(ee->evas, "Alt"); + else + evas_key_modifier_off(ee->evas, "Alt"); + if (modifiers & ECORE_X_MODIFIER_WIN) + { + evas_key_modifier_on(ee->evas, "Super"); + evas_key_modifier_on(ee->evas, "Hyper"); + } + else + { + evas_key_modifier_off(ee->evas, "Super"); + evas_key_modifier_off(ee->evas, "Hyper"); + } + if (modifiers & ECORE_X_LOCK_SCROLL) + evas_key_lock_on(ee->evas, "Scroll_Lock"); + else + evas_key_lock_off(ee->evas, "Scroll_Lock"); + if (modifiers & ECORE_X_LOCK_NUM) + evas_key_lock_on(ee->evas, "Num_Lock"); + else + evas_key_lock_off(ee->evas, "Num_Lock"); + if (modifiers & ECORE_X_LOCK_CAPS) + evas_key_lock_on(ee->evas, "Caps_Lock"); + else + evas_key_lock_off(ee->evas, "Caps_Lock"); +} + +static int +_ecore_evas_x_event_key_down(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Key_Down *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + _ecore_evas_x_modifier_locks_update(ee, e->modifiers); + evas_event_feed_key_down(ee->evas, e->keyname, e->keysymbol, e->key_compose, NULL, e->time, NULL); + return 1; +} + +static int +_ecore_evas_x_event_key_up(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Key_Up *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + _ecore_evas_x_modifier_locks_update(ee, e->modifiers); + evas_event_feed_key_up(ee->evas, e->keyname, e->keysymbol, e->key_compose, NULL, e->time, NULL); + return 1; +} + +static int +_ecore_evas_x_event_mouse_button_down(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Mouse_Button_Down *e; + Evas_Button_Flags flags = EVAS_BUTTON_NONE; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + _ecore_evas_x_modifier_locks_update(ee, e->modifiers); + _ecore_evas_x_mouse_move_process(ee, e->x, e->y, e->time); + if (e->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK; + if (e->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK; + evas_event_feed_mouse_down(ee->evas, e->button, flags, e->time, NULL); + return 1; +} + +static int +_ecore_evas_x_event_mouse_button_up(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Mouse_Button_Up *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + _ecore_evas_x_modifier_locks_update(ee, e->modifiers); + _ecore_evas_x_mouse_move_process(ee, e->x, e->y, e->time); + evas_event_feed_mouse_up(ee->evas, e->button, EVAS_BUTTON_NONE, e->time, NULL); + return 1; +} + +static int +_ecore_evas_x_event_mouse_wheel(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Mouse_Wheel *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + + if (!ee) + return 1; /* pass on event */ + + _ecore_evas_x_modifier_locks_update(ee, e->modifiers); + _ecore_evas_x_mouse_move_process(ee, e->x, e->y, e->time); + evas_event_feed_mouse_wheel(ee->evas, e->direction, e->z, e->time, NULL); + + return 1; +} + +static int +_ecore_evas_x_event_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Mouse_Move *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + _ecore_evas_x_modifier_locks_update(ee, e->modifiers); + _ecore_evas_x_mouse_move_process(ee, e->x, e->y, e->time); + return 1; +} + +static int +_ecore_evas_x_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Mouse_In *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + if (e->event_win == ee->engine.x.win_container) return 0; +/* if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0; */ + if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee); + _ecore_evas_x_modifier_locks_update(ee, e->modifiers); + evas_event_feed_mouse_in(ee->evas, e->time, NULL); + _ecore_evas_x_mouse_move_process(ee, e->x, e->y, e->time); + return 1; +} + +static int +_ecore_evas_x_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Mouse_Out *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + if (e->event_win == ee->engine.x.win_container) return 0; +/* if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0; */ + _ecore_evas_x_modifier_locks_update(ee, e->modifiers); + _ecore_evas_x_mouse_move_process(ee, e->x, e->y, e->time); + evas_event_feed_mouse_out(ee->evas, e->time, NULL); + if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee); + if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object); + return 1; +} + +static int +_ecore_evas_x_event_window_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Window_Focus_In *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + ee->prop.focused = 1; + if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee); + return 1; +} + +static int +_ecore_evas_x_event_window_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Window_Focus_Out *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + if (ee->prop.fullscreen) + ecore_x_window_focus(ee->engine.x.win); + ee->prop.focused = 0; + if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee); + return 1; +} + +static int +_ecore_evas_x_event_window_damage(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Window_Damage *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + if (ee->engine.x.using_bg_pixmap) return 1; + if (ee->prop.avoid_damage) + { + XRectangle xr; + Region tmpr; + + if (!ee->engine.x.damages) ee->engine.x.damages = XCreateRegion(); + tmpr = XCreateRegion(); + xr.x = e->x; + xr.y = e->y; + xr.width = e->w; + xr.height = e->h; + XUnionRectWithRegion(&xr, ee->engine.x.damages, tmpr); + XDestroyRegion(ee->engine.x.damages); + ee->engine.x.damages = tmpr; + } + else + { + if (ee->rotation == 0) + evas_damage_rectangle_add(ee->evas, + e->x, + e->y, + e->w, e->h); + else if (ee->rotation == 90) + evas_damage_rectangle_add(ee->evas, + ee->h - e->y - e->h, + e->x, + e->h, e->w); + else if (ee->rotation == 180) + evas_damage_rectangle_add(ee->evas, + ee->w - e->x - e->w, + ee->h - e->y - e->h, + e->w, e->h); + else if (ee->rotation == 270) + evas_damage_rectangle_add(ee->evas, + e->y, + ee->w - e->x - e->w, + e->h, e->w); + } + return 1; +} + +static int +_ecore_evas_x_event_window_destroy(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Window_Destroy *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + if (ee->func.fn_destroy) ee->func.fn_destroy(ee); + ecore_evas_free(ee); + return 1; +} + +static int +_ecore_evas_x_event_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Window_Configure *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + if ((ee->prop.fullscreen) && (e->win == ee->engine.x.win_container)) return 0; + if (ee->engine.x.direct_resize) return 0; + + if ((e->from_wm) || (ee->prop.fullscreen) || (ee->prop.override)) + { + if ((ee->x != e->x) || (ee->y != e->y)) + { + ee->x = e->x; + ee->y = e->y; + if (ee->func.fn_move) ee->func.fn_move(ee); + } + } + if ((ee->w != e->w) || (ee->h != e->h)) + { + ee->w = e->w; + ee->h = e->h; + if (e->win == ee->engine.x.win_container) + ecore_x_window_move_resize(ee->engine.x.win, 0, 0, ee->w, ee->h); + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + evas_output_size_set(ee->evas, ee->h, ee->w); + evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w); + } + else + { + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + } + if (ee->prop.avoid_damage) + { + ecore_evas_avoid_damage_set(ee, 0); + ecore_evas_avoid_damage_set(ee, 1); + } + if (ee->shaped) + { + _ecore_evas_x_resize_shape(ee); + } + if ((ee->expecting_resize.w > 0) && + (ee->expecting_resize.h > 0)) + { + if ((ee->expecting_resize.w == ee->w) && + (ee->expecting_resize.h == ee->h)) + _ecore_evas_x_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, + ecore_x_current_time_get()); + ee->expecting_resize.w = 0; + ee->expecting_resize.h = 0; + } + if (ee->func.fn_resize) ee->func.fn_resize(ee); + } + return 1; +} + +static int +_ecore_evas_x_event_window_delete_request(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Window_Delete_Request *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee); + return 1; +} + +static int +_ecore_evas_x_event_window_show(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Window_Show *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + if (ee->visible) return 0; /* dont pass it on */ + ee->visible = 1; + if (ee->func.fn_show) ee->func.fn_show(ee); + return 1; +} + +static int +_ecore_evas_x_event_window_hide(void *data __UNUSED__, int type __UNUSED__, void *event) +{ + Ecore_Evas *ee; + Ecore_X_Event_Window_Hide *e; + + e = event; + ee = _ecore_evas_x_match(e->win); + if (!ee) return 1; /* pass on event */ + if (!ee->visible) return 0; /* dont pass it on */ + ee->visible = 0; + if (ee->func.fn_hide) ee->func.fn_hide(ee); + return 1; +} + +/* FIXME, should be in idler */ +static void +_ecore_evas_x_size_pos_hints_update(Ecore_Evas *ee) +{ + ecore_x_icccm_size_pos_hints_set(ee->engine.x.win_container, + 1 /*request_pos */, + ECORE_X_GRAVITY_NW /* gravity */, + ee->prop.min.w /* min_w */, + ee->prop.min.h /* min_h */, + ee->prop.max.w /* max_w */, + ee->prop.max.h /* max_h */, + ee->prop.base.w /* base_w */, + ee->prop.base.h /* base_h */, + ee->prop.step.w /* step_x */, + ee->prop.step.h /* step_y */, + 0 /* min_aspect */, + 0 /* max_aspect */); +} + +/* FIXME, should be in idler */ +static void +_ecore_evas_x_state_update(Ecore_Evas *ee) +{ + Ecore_X_Window_State state[10]; + int num; + + num = 0; + + /* + if (bd->client.netwm.state.modal) + state[num++] = ECORE_X_WINDOW_STATE_MODAL; + */ + if (ee->engine.x.state.sticky) + state[num++] = ECORE_X_WINDOW_STATE_STICKY; + /* + if (bd->client.netwm.state.maximized_v) + state[num++] = ECORE_X_WINDOW_STATE_MAXIMIZED_VERT; + if (bd->client.netwm.state.maximized_h) + state[num++] = ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ; + if (bd->client.netwm.state.shaded) + state[num++] = ECORE_X_WINDOW_STATE_SHADED; + if (bd->client.netwm.state.skip_taskbar) + state[num++] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR; + if (bd->client.netwm.state.skip_pager) + state[num++] = ECORE_X_WINDOW_STATE_SKIP_PAGER; + if (bd->client.netwm.state.hidden) + state[num++] = ECORE_X_WINDOW_STATE_HIDDEN; + if (bd->client.netwm.state.fullscreen) + state[num++] = ECORE_X_WINDOW_STATE_FULLSCREEN; + */ + if (ee->engine.x.state.above) + state[num++] = ECORE_X_WINDOW_STATE_ABOVE; + if (ee->engine.x.state.below) + state[num++] = ECORE_X_WINDOW_STATE_BELOW; + + ecore_x_netwm_window_state_set(ee->engine.x.win_container, state, num); +} + +void +_ecore_evas_x_layer_update(Ecore_Evas *ee) +{ + if (ee->should_be_visible) + { + /* We need to send a netwm request to the wm */ + /* FIXME: Do we have to remove old state before adding new? */ + if (ee->prop.layer < 3) + { + if (ee->engine.x.state.above) + { + ee->engine.x.state.above = 0; + ecore_x_netwm_state_request_send(ee->engine.x.win_container, + ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_ABOVE, -1, 0); + } + if (!ee->engine.x.state.below) + { + ee->engine.x.state.below = 1; + ecore_x_netwm_state_request_send(ee->engine.x.win_container, + ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_BELOW, -1, 1); + } + } + else if (ee->prop.layer > 5) + { + if (ee->engine.x.state.below) + { + ee->engine.x.state.below = 0; + ecore_x_netwm_state_request_send(ee->engine.x.win_container, + ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_BELOW, -1, 0); + } + if (!ee->engine.x.state.above) + { + ee->engine.x.state.above = 1; + ecore_x_netwm_state_request_send(ee->engine.x.win_container, + ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_ABOVE, -1, 1); + } + } + else + { + if (ee->engine.x.state.below) + { + ee->engine.x.state.below = 0; + ecore_x_netwm_state_request_send(ee->engine.x.win_container, + ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_BELOW, -1, 0); + } + if (ee->engine.x.state.above) + { + ee->engine.x.state.above = 0; + ecore_x_netwm_state_request_send(ee->engine.x.win_container, + ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_ABOVE, -1, 0); + } + } + } + else + { + /* Just set the state */ + if (ee->prop.layer < 3) + { + if ((ee->engine.x.state.above) || (!ee->engine.x.state.below)) + { + ee->engine.x.state.above = 0; + ee->engine.x.state.below = 1; + _ecore_evas_x_state_update(ee); + } + } + else if (ee->prop.layer > 5) + { + if ((!ee->engine.x.state.above) || (ee->engine.x.state.below)) + { + ee->engine.x.state.above = 1; + ee->engine.x.state.below = 0; + _ecore_evas_x_state_update(ee); + } + } + else + { + if ((ee->engine.x.state.above) || (ee->engine.x.state.below)) + { + ee->engine.x.state.above = 0; + ee->engine.x.state.below = 0; + _ecore_evas_x_state_update(ee); + } + } + } + /* FIXME: Set gnome layer */ +} + +static int +_ecore_evas_x_idle_enter(void *data __UNUSED__) +{ + Ecore_Oldlist *l; + double t1 = 0.0; + double t2 = 0.0; + + if (_ecore_evas_fps_debug) + { + t1 = ecore_time_get(); + } + for (l = (Ecore_Oldlist *)ecore_evases; l; l = l->next) + { + Ecore_Evas *ee; + + ee = (Ecore_Evas *)l; + _ecore_evas_x_render(ee); + } + ecore_x_flush(); + if (_ecore_evas_fps_debug) + { + t2 = ecore_time_get(); + _ecore_evas_fps_debug_rendertime_add(t2 - t1); + } + return 1; +} + +static int +_ecore_evas_x_init(void) +{ + _ecore_evas_init_count++; + if (_ecore_evas_init_count > 1) return _ecore_evas_init_count; + if (getenv("ECORE_EVAS_FPS_DEBUG")) _ecore_evas_fps_debug = 1; + ecore_evas_idle_enterer = ecore_idle_enterer_add(_ecore_evas_x_idle_enter, NULL); + ecore_evas_event_handlers[0] = ecore_event_handler_add(ECORE_X_EVENT_KEY_DOWN, _ecore_evas_x_event_key_down, NULL); + ecore_evas_event_handlers[1] = ecore_event_handler_add(ECORE_X_EVENT_KEY_UP, _ecore_evas_x_event_key_up, NULL); + ecore_evas_event_handlers[2] = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_DOWN, _ecore_evas_x_event_mouse_button_down, NULL); + ecore_evas_event_handlers[3] = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_BUTTON_UP, _ecore_evas_x_event_mouse_button_up, NULL); + ecore_evas_event_handlers[4] = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_MOVE, _ecore_evas_x_event_mouse_move, NULL); + ecore_evas_event_handlers[5] = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _ecore_evas_x_event_mouse_in, NULL); + ecore_evas_event_handlers[6] = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _ecore_evas_x_event_mouse_out, NULL); + ecore_evas_event_handlers[7] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _ecore_evas_x_event_window_focus_in, NULL); + ecore_evas_event_handlers[8] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _ecore_evas_x_event_window_focus_out, NULL); + ecore_evas_event_handlers[9] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DAMAGE, _ecore_evas_x_event_window_damage, NULL); + ecore_evas_event_handlers[10] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _ecore_evas_x_event_window_destroy, NULL); + ecore_evas_event_handlers[11] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _ecore_evas_x_event_window_configure, NULL); + ecore_evas_event_handlers[12] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, _ecore_evas_x_event_window_delete_request, NULL); + ecore_evas_event_handlers[13] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, _ecore_evas_x_event_window_show, NULL); + ecore_evas_event_handlers[14] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _ecore_evas_x_event_window_hide, NULL); + ecore_evas_event_handlers[15] = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_WHEEL, _ecore_evas_x_event_mouse_wheel, NULL); + if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_init(); + return _ecore_evas_init_count; +} + +static void +_ecore_evas_x_free(Ecore_Evas *ee) +{ + ecore_x_window_del(ee->engine.x.win); + ecore_x_window_del(ee->engine.x.win_container); + if (ee->engine.x.pmap) ecore_x_pixmap_del(ee->engine.x.pmap); + if (ee->engine.x.mask) ecore_x_pixmap_del(ee->engine.x.mask); + if (ee->engine.x.gc) ecore_x_gc_del(ee->engine.x.gc); + if (ee->engine.x.damages) XDestroyRegion(ee->engine.x.damages); + ee->engine.x.pmap = 0; + ee->engine.x.mask = 0; + ee->engine.x.gc = 0; + ee->engine.x.damages = 0; + ecore_evases_hash = evas_hash_del(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win), ee); + ecore_evases_hash = evas_hash_del(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win_container), ee); + ecore_evases = _ecore_list_remove(ecore_evases, ee); + _ecore_evas_x_shutdown(); + ecore_x_shutdown(); +} + +static void +_ecore_evas_x_callback_delete_request_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee)) +{ + if (func) + ecore_x_icccm_protocol_set(ee->engine.x.win_container, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, 1); + else + ecore_x_icccm_protocol_set(ee->engine.x.win_container, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, 0); + ee->func.fn_delete_request = func; +} + +static void +_ecore_evas_x_move(Ecore_Evas *ee, int x, int y) +{ + ecore_x_window_move(ee->engine.x.win_container, x, y); + if (!ee->should_be_visible) + { + /* We need to request pos */ + _ecore_evas_x_size_pos_hints_update(ee); + } +} + +static void +_ecore_evas_x_resize(Ecore_Evas *ee, int w, int h) +{ + ecore_x_window_resize(ee->engine.x.win_container, w, h); + if (ee->engine.x.direct_resize) + { + ecore_x_window_move_resize(ee->engine.x.win, 0, 0, w, h); + if ((ee->w != w) || (ee->h != h)) + { + ee->w = w; + ee->h = h; + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + evas_output_size_set(ee->evas, ee->h, ee->w); + evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w); + } + else + { + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + } + if (ee->prop.avoid_damage) + { + ecore_evas_avoid_damage_set(ee, 0); + ecore_evas_avoid_damage_set(ee, 1); + } + if (ee->shaped) + { + _ecore_evas_x_resize_shape(ee); + } + } + } +} + +static void +_ecore_evas_x_move_resize(Ecore_Evas *ee, int x, int y, int w, int h) +{ + ecore_x_window_move_resize(ee->engine.x.win_container, x, y, w, h); + if (ee->engine.x.direct_resize) + { + ecore_x_window_move_resize(ee->engine.x.win, 0, 0, w, h); + if ((ee->w != w) || (ee->h != h)) + { + ee->w = w; + ee->h = h; + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + evas_output_size_set(ee->evas, ee->h, ee->w); + evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w); + } + else + { + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + } + if (ee->prop.avoid_damage) + { + ecore_evas_avoid_damage_set(ee, 0); + ecore_evas_avoid_damage_set(ee, 1); + } + if (ee->shaped) + { + _ecore_evas_x_resize_shape(ee); + } + } + } +} + +static void +_ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation) +{ + Evas_Engine_Info_Software_X11 *einfo; + int rot_dif; + + if (ee->rotation == rotation) return; + if (!strcmp(ee->driver, "gl_x11")) return; + einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas); + if (!einfo) return; + rot_dif = ee->rotation - rotation; + if (rot_dif < 0) rot_dif = -rot_dif; + if (rot_dif != 180) + { + int minw, minh, maxw, maxh, basew, baseh, stepw, steph; + + einfo->info.rotation = rotation; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + if (!ee->prop.fullscreen) + { + ecore_x_window_resize(ee->engine.x.win_container, ee->h, ee->w); + ee->expecting_resize.w = ee->h; + ee->expecting_resize.h = ee->w; + } + else + { + int w, h; + + ecore_x_window_size_get(ee->engine.x.win_container, &w, &h); + ecore_x_window_resize(ee->engine.x.win_container, h, w); + if ((rotation == 0) || (rotation == 180)) + { + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + } + else + { + evas_output_size_set(ee->evas, ee->h, ee->w); + evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w); + } + if (ee->func.fn_resize) ee->func.fn_resize(ee); + } + ecore_evas_size_min_get(ee, &minw, &minh); + ecore_evas_size_max_get(ee, &maxw, &maxh); + ecore_evas_size_base_get(ee, &basew, &baseh); + ecore_evas_size_step_get(ee, &stepw, &steph); + ee->rotation = rotation; + ecore_evas_size_min_set(ee, minh, minw); + ecore_evas_size_max_set(ee, maxh, maxw); + ecore_evas_size_base_set(ee, baseh, basew); + ecore_evas_size_step_set(ee, steph, stepw); + _ecore_evas_x_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, + ecore_x_current_time_get()); + } + else + { + einfo->info.rotation = rotation; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + ee->rotation = rotation; + _ecore_evas_x_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, + ecore_x_current_time_get()); + if (ee->func.fn_resize) ee->func.fn_resize(ee); + } + if ((ee->rotation == 90) || (ee->rotation == 270)) + evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w); + else + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); +} + +static void +_ecore_evas_x_shaped_set(Ecore_Evas *ee, int shaped) +{ + Evas_Engine_Info_Software_X11 *einfo; + + if (((ee->shaped) && (shaped)) || + ((!ee->shaped) && (!shaped))) + return; + if (!strcmp(ee->driver, "gl_x11")) return; + ee->shaped = shaped; + einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas); + if (einfo) + { + if (ee->shaped) + { + GC gc; + XGCValues gcv; + + ee->engine.x.mask = ecore_x_pixmap_new(ee->engine.x.win, ee->w, ee->h, 1); + gcv.foreground = 0; + gc = XCreateGC(ecore_x_display_get(), ee->engine.x.mask, + GCForeground, + &gcv); + XFillRectangle(ecore_x_display_get(), ee->engine.x.mask, gc, + 0, 0, ee->w, ee->h); + XFreeGC(ecore_x_display_get(), gc); + einfo->info.mask = ee->engine.x.mask; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + } + else + { + if (ee->engine.x.mask) ecore_x_pixmap_del(ee->engine.x.mask); + ee->engine.x.mask = 0; + einfo->info.mask = 0; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + ecore_x_window_shape_mask_set(ee->engine.x.win, 0); + ecore_x_window_shape_mask_set(ee->engine.x.win_container, 0); + } + } +} + +static void +_ecore_evas_x_show(Ecore_Evas *ee) +{ + ee->should_be_visible = 1; + if (ee->prop.avoid_damage) + _ecore_evas_x_render(ee); + if (!ee->prop.fullscreen) + ecore_x_window_show(ee->engine.x.win_container); + ecore_x_window_show(ee->engine.x.win); + if (ee->prop.fullscreen) + ecore_x_window_focus(ee->engine.x.win); +} + +static void +_ecore_evas_x_hide(Ecore_Evas *ee) +{ + if (!ee->prop.fullscreen) + ecore_x_window_hide(ee->engine.x.win_container); + ecore_x_window_hide(ee->engine.x.win); + ee->should_be_visible = 0; +} + +static void +_ecore_evas_x_raise(Ecore_Evas *ee) +{ + if (!ee->prop.fullscreen) + ecore_x_window_raise(ee->engine.x.win_container); + else + ecore_x_window_raise(ee->engine.x.win); +} + +static void +_ecore_evas_x_lower(Ecore_Evas *ee) +{ + if (!ee->prop.fullscreen) + ecore_x_window_lower(ee->engine.x.win_container); + else + ecore_x_window_lower(ee->engine.x.win); +} + +static void +_ecore_evas_x_title_set(Ecore_Evas *ee, const char *t) +{ + if (ee->prop.title) free(ee->prop.title); + ee->prop.title = NULL; + if (t) ee->prop.title = strdup(t); + ecore_x_icccm_title_set(ee->engine.x.win_container, ee->prop.title); + ecore_x_netwm_name_set(ee->engine.x.win_container, ee->prop.title); +} + +static void +_ecore_evas_x_name_class_set(Ecore_Evas *ee, const char *n, const char *c) +{ + if (ee->prop.name) free(ee->prop.name); + if (ee->prop.clas) free(ee->prop.clas); + ee->prop.name = NULL; + ee->prop.clas = NULL; + ee->prop.name = strdup(n); + ee->prop.clas = strdup(c); + ecore_x_icccm_name_class_set(ee->engine.x.win_container, ee->prop.name, ee->prop.clas); +} + +static void +_ecore_evas_x_size_min_set(Ecore_Evas *ee, int w, int h) +{ + if (w < 0) w = 0; + if (h < 0) h = 0; + if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return; + ee->prop.min.w = w; + ee->prop.min.h = h; + _ecore_evas_x_size_pos_hints_update(ee); +} + +static void +_ecore_evas_x_size_max_set(Ecore_Evas *ee, int w, int h) +{ + if (w < 0) w = 0; + if (h < 0) h = 0; + if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return; + ee->prop.max.w = w; + ee->prop.max.h = h; + _ecore_evas_x_size_pos_hints_update(ee); +} + +static void +_ecore_evas_x_size_base_set(Ecore_Evas *ee, int w, int h) +{ + if (w < 0) w = 0; + if (h < 0) h = 0; + if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return; + ee->prop.base.w = w; + ee->prop.base.h = h; + _ecore_evas_x_size_pos_hints_update(ee); +} + +static void +_ecore_evas_x_size_step_set(Ecore_Evas *ee, int w, int h) +{ + if (w < 1) w = 1; + if (h < 1) h = 1; + if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return; + ee->prop.step.w = w; + ee->prop.step.h = h; + _ecore_evas_x_size_pos_hints_update(ee); +} + +static void +_ecore_evas_x_cursor_set(Ecore_Evas *ee, const char *file, int layer, int hot_x, int hot_y) +{ + int x, y; + + if (!file) + { + if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object); + if (ee->prop.cursor.file) free(ee->prop.cursor.file); + ee->prop.cursor.object = NULL; + ee->prop.cursor.file = NULL; + ee->prop.cursor.layer = 0; + ee->prop.cursor.hot.x = 0; + ee->prop.cursor.hot.y = 0; + ecore_x_window_cursor_show(ee->engine.x.win, 1); + return; + } + ecore_x_window_cursor_show(ee->engine.x.win, 0); + if (!ee->prop.cursor.object) ee->prop.cursor.object = evas_object_image_add(ee->evas); + if (ee->prop.cursor.file) free(ee->prop.cursor.file); + ee->prop.cursor.file = strdup(file); + ee->prop.cursor.layer = layer; + ee->prop.cursor.hot.x = hot_x; + ee->prop.cursor.hot.y = hot_y; + evas_pointer_output_xy_get(ee->evas, &x, &y); + evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer); + evas_object_color_set(ee->prop.cursor.object, 255, 255, 255, 255); + evas_object_move(ee->prop.cursor.object, + x - ee->prop.cursor.hot.x, + y - ee->prop.cursor.hot.y); + evas_object_image_file_set(ee->prop.cursor.object, ee->prop.cursor.file, NULL); + evas_object_image_size_get(ee->prop.cursor.object, &x, &y); + evas_object_resize(ee->prop.cursor.object, x, y); + evas_object_image_fill_set(ee->prop.cursor.object, 0, 0, x, y); + evas_object_pass_events_set(ee->prop.cursor.object, 1); + if (evas_pointer_inside_get(ee->evas)) + evas_object_show(ee->prop.cursor.object); +} + +/* + * @param ee + * @param layer If < 3, @a ee will be put below all other windows. + * If > 5, @a ee will be "always-on-top" + * If = 4, @a ee will be put in the default layer. + * Acceptable values range from 1 to 255 (0 reserved for + * desktop windows) + */ +static void +_ecore_evas_x_layer_set(Ecore_Evas *ee, int layer) +{ + if (ee->prop.layer == layer) return; + + /* FIXME: Should this logic be here? */ + if (layer < 1) + layer = 1; + else if (layer > 255) + layer = 255; + + ee->prop.layer = layer; + _ecore_evas_x_layer_update(ee); +} + +static void +_ecore_evas_x_focus_set(Ecore_Evas *ee, int on __UNUSED__) +{ + ecore_x_window_focus(ee->engine.x.win_container); +} + +static void +_ecore_evas_x_iconified_set(Ecore_Evas *ee, int on) +{ + if (((ee->prop.iconified) && (on)) || + ((!ee->prop.iconified) && (!on))) return; + ee->prop.iconified = on; + if (on) + { + ecore_x_icccm_hints_set(ee->engine.x.win_container, + 1 /* accepts_focus */, + ECORE_X_WINDOW_STATE_HINT_ICONIC /* initial_state */, + 0 /* icon_pixmap */, + 0 /* icon_mask */, + 0 /* icon_window */, + 0 /* window_group */, + 0 /* is_urgent */); + ecore_x_icccm_iconic_request_send(ee->engine.x.win_container, ee->engine.x.win_root); + } + else + { + ecore_x_icccm_hints_set(ee->engine.x.win_container, + 1 /* accepts_focus */, + ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */, + 0 /* icon_pixmap */, + 0 /* icon_mask */, + 0 /* icon_window */, + 0 /* window_group */, + 0 /* is_urgent */); + ecore_evas_show(ee); + } +} + +static void +_ecore_evas_x_borderless_set(Ecore_Evas *ee, int on) +{ + if (((ee->prop.borderless) && (on)) || + ((!ee->prop.borderless) && (!on))) return; + ee->prop.borderless = on; + ecore_x_mwm_borderless_set(ee->engine.x.win_container, ee->prop.borderless); +} + +/* FIXME: This function changes the initial state of the ee + * whilest the iconic function changes the current state! */ +static void +_ecore_evas_x_withdrawn_set(Ecore_Evas *ee, int withdrawn) +{ + Ecore_X_Window_State_Hint hint; + + if ((ee->prop.withdrawn && withdrawn) || + (!ee->prop.withdrawn && !withdrawn)) return; + + ee->prop.withdrawn = withdrawn; + if (withdrawn) + hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; + else + hint = ECORE_X_WINDOW_STATE_HINT_NORMAL; + + ecore_x_icccm_hints_set(ee->engine.x.win_container, + 1 /* accepts_focus */, + hint /* initial_state */, + 0 /* icon_pixmap */, + 0 /* icon_mask */, + 0 /* icon_window */, + 0 /* window_group */, + 0 /* is_urgent */); +} + +static void +_ecore_evas_x_sticky_set(Ecore_Evas *ee, int sticky) +{ + if ((ee->prop.sticky && sticky) || + (!ee->prop.sticky && !sticky)) return; + + ee->prop.sticky = sticky; + ee->engine.x.state.sticky = sticky; + if (ee->should_be_visible) + ecore_x_netwm_state_request_send(ee->engine.x.win_container, ee->engine.x.win_root, + ECORE_X_WINDOW_STATE_STICKY, -1, sticky); + else + _ecore_evas_x_state_update(ee); +} + +static void +_ecore_evas_x_override_set(Ecore_Evas *ee, int on) +{ + if (((ee->prop.override) && (on)) || + ((!ee->prop.override) && (!on))) return; + ecore_x_window_hide(ee->engine.x.win); + ecore_x_window_reparent(ee->engine.x.win, ee->engine.x.win_root, 0, 0); + ecore_x_window_del(ee->engine.x.win_container); + ecore_evases_hash = evas_hash_del(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win_container), ee); + if (on) + ee->engine.x.win_container = ecore_x_window_override_new(ee->engine.x.win_root, ee->x, ee->y, ee->w, ee->h); + else + { + Ecore_X_Window_State_Hint hint; + if (ee->prop.withdrawn) + hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; + else + hint = ECORE_X_WINDOW_STATE_HINT_NORMAL; + + ee->engine.x.win_container = ecore_x_window_new(ee->engine.x.win_root, ee->x, ee->y, ee->w, ee->h); + ecore_x_icccm_title_set(ee->engine.x.win_container, ee->prop.title); + ecore_x_netwm_name_set(ee->engine.x.win_container, ee->prop.title); + ecore_x_icccm_name_class_set(ee->engine.x.win_container, ee->prop.name, ee->prop.clas); + if (ee->func.fn_delete_request) + ecore_x_icccm_protocol_set(ee->engine.x.win_container, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, 1); + _ecore_evas_x_size_pos_hints_update(ee); + ecore_x_mwm_borderless_set(ee->engine.x.win_container, ee->prop.borderless); + _ecore_evas_x_layer_update(ee); + ecore_x_icccm_hints_set(ee->engine.x.win_container, 1 /* accepts_focus */, + hint /* initial_state */, 0 /* icon_pixmap */, 0 /* icon_mask */, + 0 /* icon_window */, 0 /* window_group */, 0 /* is_urgent */); + _ecore_evas_x_state_update(ee); + } + ecore_evases_hash = evas_hash_add(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win_container), ee); + ecore_x_window_reparent(ee->engine.x.win, ee->engine.x.win_container, 0, 0); + ecore_x_window_show(ee->engine.x.win); + if (ee->visible) ecore_x_window_show(ee->engine.x.win_container); + if (ee->prop.focused) ecore_x_window_focus(ee->engine.x.win_container); + ee->prop.override = on; +} + +static void +_ecore_evas_x_fullscreen_set(Ecore_Evas *ee, int on) +{ + if (((ee->prop.fullscreen) && (on)) || + ((!ee->prop.fullscreen) && (!on))) return; + if (on) + { + int rw, rh; + + ecore_x_window_size_get(0, &rw, &rh); + ecore_x_window_move_resize(ee->engine.x.win, 0, 0, rw, rh); + ecore_x_window_reparent(ee->engine.x.win, ee->engine.x.win_root, 0, 0); + ecore_x_window_raise(ee->engine.x.win); + ecore_x_window_show(ee->engine.x.win); + ecore_x_window_focus(ee->engine.x.win); + ecore_x_window_hide(ee->engine.x.win_container); + ecore_x_window_shape_mask_set(ee->engine.x.win_container, 0); + if (ee->should_be_visible) + { + ecore_x_window_show(ee->engine.x.win); + ecore_x_window_focus(ee->engine.x.win); + } + ee->x = 0; + ee->y = 0; + ee->w = rw; + ee->h = rh; + } + else + { + int pw, ph; + + ecore_x_window_size_get(ee->engine.x.win_container, &pw, &ph); + ecore_x_window_reparent(ee->engine.x.win, ee->engine.x.win_container, 0, 0); + ecore_x_window_move_resize(ee->engine.x.win, 0, 0, pw, ph); + ecore_x_window_shape_mask_set(ee->engine.x.win, 0); + if (ee->should_be_visible) ecore_x_window_show(ee->engine.x.win_container); + ee->w = pw; + ee->h = ph; + } + ecore_x_window_move_resize(ee->engine.x.win, 0, 0, ee->w, ee->h); + if ((ee->rotation == 90) || (ee->rotation == 270)) + { + evas_output_size_set(ee->evas, ee->h, ee->w); + evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w); + } + else + { + evas_output_size_set(ee->evas, ee->w, ee->h); + evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h); + } + if (ee->prop.avoid_damage) + { + ecore_evas_avoid_damage_set(ee, 0); + ecore_evas_avoid_damage_set(ee, 1); + } + if (ee->shaped) + { + _ecore_evas_x_resize_shape(ee); + } + if ((ee->expecting_resize.w > 0) && + (ee->expecting_resize.h > 0)) + { + if ((ee->expecting_resize.w == ee->w) && + (ee->expecting_resize.h == ee->h)) + _ecore_evas_x_mouse_move_process(ee, ee->mouse.x, ee->mouse.y, + ecore_x_current_time_get()); + ee->expecting_resize.w = 0; + ee->expecting_resize.h = 0; + } + ee->prop.fullscreen = on; + if (ee->func.fn_resize) ee->func.fn_resize(ee); +} + +static void +_ecore_evas_x_avoid_damage_set(Ecore_Evas *ee, int on) +{ + Evas_Engine_Info_Software_X11 *einfo; + + if (((ee->prop.avoid_damage) && (on)) || + ((!ee->prop.avoid_damage) && (!on))) + return; + if (!strcmp(ee->driver, "gl_x11")) return; + ee->prop.avoid_damage = on; + einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas); + if (einfo) + { + if (ee->prop.avoid_damage) + { + ee->engine.x.pmap = ecore_x_pixmap_new(ee->engine.x.win, ee->w, ee->h, 0); + ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap); + einfo->info.drawable = ee->engine.x.pmap; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + if ((ee->rotation == 90) || (ee->rotation == 270)) + evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w); + else + evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); + if (ee->engine.x.direct_resize) + { +/* Turn this off for now + ee->engine.x.using_bg_pixmap = 1; + ecore_x_window_pixmap_set(ee->engine.x.win, ee->engine.x.pmap); + */ + } + } + else + { + if (ee->engine.x.pmap) ecore_x_pixmap_del(ee->engine.x.pmap); + if (ee->engine.x.gc) ecore_x_gc_del(ee->engine.x.gc); + if (ee->engine.x.using_bg_pixmap) + { + ecore_x_window_pixmap_set(ee->engine.x.win, 0); + ee->engine.x.using_bg_pixmap = 0; + } + ee->engine.x.pmap = 0; + ee->engine.x.gc = 0; + einfo->info.drawable = ee->engine.x.win; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + } + } +} + +int +_ecore_evas_x_shutdown(void) +{ + _ecore_evas_init_count--; + if (_ecore_evas_init_count == 0) + { + int i; + + while (ecore_evases) ecore_evas_free(ecore_evases); + for (i = 0; i < 16; i++) + ecore_event_handler_del(ecore_evas_event_handlers[i]); + ecore_idle_enterer_del(ecore_evas_idle_enterer); + ecore_evas_idle_enterer = NULL; + if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_shutdown(); + } + if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0; + return _ecore_evas_init_count; +} + +static const Ecore_Evas_Engine_Func _ecore_x_engine_func = +{ + _ecore_evas_x_free, + NULL, + NULL, + NULL, + NULL, + _ecore_evas_x_callback_delete_request_set, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + _ecore_evas_x_move, + _ecore_evas_x_resize, + _ecore_evas_x_move_resize, + _ecore_evas_x_rotation_set, + _ecore_evas_x_shaped_set, + _ecore_evas_x_show, + _ecore_evas_x_hide, + _ecore_evas_x_raise, + _ecore_evas_x_lower, + _ecore_evas_x_title_set, + _ecore_evas_x_name_class_set, + _ecore_evas_x_size_min_set, + _ecore_evas_x_size_max_set, + _ecore_evas_x_size_base_set, + _ecore_evas_x_size_step_set, + _ecore_evas_x_cursor_set, + _ecore_evas_x_layer_set, + _ecore_evas_x_focus_set, + _ecore_evas_x_iconified_set, + _ecore_evas_x_borderless_set, + _ecore_evas_x_override_set, + NULL, + _ecore_evas_x_fullscreen_set, + _ecore_evas_x_avoid_damage_set, + _ecore_evas_x_withdrawn_set, + _ecore_evas_x_sticky_set +}; +#endif + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +Ecore_Evas * +ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent, + int x, int y, int w, int h) +{ +#ifdef BUILD_ECORE_X + Evas_Engine_Info_Software_X11 *einfo; + Ecore_Evas *ee; + int rmethod; + + rmethod = evas_render_method_lookup("software_x11"); + if (!rmethod) return NULL; + if (!ecore_x_init(disp_name)) return NULL; + ee = calloc(1, sizeof(Ecore_Evas)); + if (!ee) return NULL; + + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); + + _ecore_evas_x_init(); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func; + + ee->driver = strdup("software_x11"); + if (disp_name) ee->name = strdup(disp_name); + + if (w < 1) w = 1; + if (h < 1) h = 1; + ee->x = x; + ee->y = y; + ee->w = w; + ee->h = h; + + ee->prop.max.w = 32767; + ee->prop.max.h = 32767; + ee->prop.layer = 4; + + /* init evas here */ + ee->evas = evas_new(); + evas_output_method_set(ee->evas, rmethod); + evas_output_size_set(ee->evas, w, h); + evas_output_viewport_set(ee->evas, 0, 0, w, h); + + ee->engine.x.win_root = parent; + ee->engine.x.win_container = ecore_x_window_new(parent, x, y, w, h); + ee->engine.x.win = ecore_x_window_override_new(ee->engine.x.win_container, 0, 0, w, h); + + einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas); + if (einfo) + { + int screen; + + /* FIXME: this is inefficient as its a round trip */ + screen = DefaultScreen(ecore_x_display_get()); + if (ScreenCount(ecore_x_display_get()) > 1) + { + Ecore_X_Window *roots; + int num, i; + + num = 0; + roots = ecore_x_window_root_list(&num); + if (roots) + { + XWindowAttributes at; + + if (XGetWindowAttributes(ecore_x_display_get(), + parent, &at)) + { + for (i = 0; i < num; i++) + { + if (at.root == roots[i]) + { + screen = i; + break; + } + } + } + free(roots); + } + } + einfo->info.display = ecore_x_display_get(); + einfo->info.visual = DefaultVisual(ecore_x_display_get(), screen); + einfo->info.colormap = DefaultColormap(ecore_x_display_get(), screen); + einfo->info.drawable = ee->engine.x.win; + einfo->info.depth = DefaultDepth(ecore_x_display_get(), screen); + einfo->info.rotation = 0; + einfo->info.debug = 0; + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + } + evas_key_modifier_add(ee->evas, "Shift"); + evas_key_modifier_add(ee->evas, "Control"); + evas_key_modifier_add(ee->evas, "Alt"); + evas_key_modifier_add(ee->evas, "Meta"); + evas_key_modifier_add(ee->evas, "Hyper"); + evas_key_modifier_add(ee->evas, "Super"); + evas_key_lock_add(ee->evas, "Caps_Lock"); + evas_key_lock_add(ee->evas, "Num_Lock"); + evas_key_lock_add(ee->evas, "Scroll_Lock"); + + ecore_evases = _ecore_list_prepend(ecore_evases, ee); + ecore_evases_hash = evas_hash_add(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win), ee); + ecore_evases_hash = evas_hash_add(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win_container), ee); + return ee; +#else + return NULL; +#endif +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +Ecore_X_Window +ecore_evas_software_x11_window_get(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_X + return ee->engine.x.win_container; +#else + return 0; +#endif +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +Ecore_X_Window +ecore_evas_software_x11_subwindow_get(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_X + return ee->engine.x.win; +#else + return 0; +#endif +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +void +ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, int on) +{ +#ifdef BUILD_ECORE_X + ee->engine.x.direct_resize = on; + if (ee->prop.avoid_damage) + { + if (ee->engine.x.direct_resize) + { +/* turn this off for now + ee->engine.x.using_bg_pixmap = 1; + ecore_x_window_pixmap_set(ee->engine.x.win, ee->engine.x.pmap); + */ + } + else + { + ee->engine.x.using_bg_pixmap = 0; + ecore_x_window_pixmap_set(ee->engine.x.win, 0); + ecore_x_window_area_expose(ee->engine.x.win, 0, 0, ee->w, ee->h); + } + } +#else + return; +#endif +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +int +ecore_evas_software_x11_direct_resize_get(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_X + return ee->engine.x.direct_resize; +#else + return 0; +#endif +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +Ecore_Evas * +ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent, + int x, int y, int w, int h) +{ +#ifdef BUILD_ECORE_EVAS_GL + Evas_Engine_Info_GL_X11 *einfo; + Ecore_Evas *ee; + int rmethod; + + rmethod = evas_render_method_lookup("gl_x11"); + if (!rmethod) return NULL; + if (!ecore_x_init(disp_name)) return NULL; + ee = calloc(1, sizeof(Ecore_Evas)); + if (!ee) return NULL; + + ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); + + _ecore_evas_x_init(); + + ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func; + + ee->driver = strdup("gl_x11"); + if (disp_name) ee->name = strdup(disp_name); + + if (w < 1) w = 1; + if (h < 1) h = 1; + ee->x = x; + ee->y = y; + ee->w = w; + ee->h = h; + + ee->prop.max.w = 32767; + ee->prop.max.h = 32767; + ee->prop.layer = 4; + + /* init evas here */ + ee->evas = evas_new(); + evas_output_method_set(ee->evas, rmethod); + evas_output_size_set(ee->evas, w, h); + evas_output_viewport_set(ee->evas, 0, 0, w, h); + + ee->engine.x.win_root = parent; + ee->engine.x.win_container = ecore_x_window_new(parent, x, y, w, h); + einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas); + if (einfo) + { + XSetWindowAttributes attr; + int screen; + + /* FIXME: this is inefficient as its a round trip */ + screen = DefaultScreen(ecore_x_display_get()); + if (ScreenCount(ecore_x_display_get()) > 1) + { + Ecore_X_Window *roots; + int num, i; + + num = 0; + roots = ecore_x_window_root_list(&num); + if (roots) + { + XWindowAttributes at; + + if (XGetWindowAttributes(ecore_x_display_get(), + parent, &at)) + { + for (i = 0; i < num; i++) + { + if (at.root == roots[i]) + { + screen = i; + break; + } + } + } + free(roots); + } + } + attr.backing_store = NotUseful; + attr.override_redirect = True; + attr.colormap = einfo->func.best_colormap_get(ecore_x_display_get(), screen); + attr.border_pixel = 0; + attr.background_pixmap = None; + attr.event_mask = + KeyPressMask | KeyReleaseMask | + ExposureMask | ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask | + PointerMotionMask | StructureNotifyMask | VisibilityChangeMask | + FocusChangeMask | PropertyChangeMask | ColormapChangeMask; + attr.bit_gravity = ForgetGravity; + + ee->engine.x.win = + XCreateWindow(ecore_x_display_get(), + ee->engine.x.win_container, + 0, 0, + w, h, 0, + einfo->func.best_depth_get(ecore_x_display_get(), screen), + InputOutput, + einfo->func.best_visual_get(ecore_x_display_get(), screen), + CWBackingStore | CWColormap | + CWBackPixmap | CWBorderPixel | + CWBitGravity | CWEventMask | + CWOverrideRedirect, + &attr); + einfo->info.display = ecore_x_display_get(); + einfo->info.visual = einfo->func.best_visual_get(ecore_x_display_get(), screen); + einfo->info.colormap = einfo->func.best_colormap_get(ecore_x_display_get(), screen); + einfo->info.drawable = ee->engine.x.win; + einfo->info.depth = einfo->func.best_depth_get(ecore_x_display_get(), screen); + evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo); + } + evas_key_modifier_add(ee->evas, "Shift"); + evas_key_modifier_add(ee->evas, "Control"); + evas_key_modifier_add(ee->evas, "Alt"); + evas_key_modifier_add(ee->evas, "Meta"); + evas_key_modifier_add(ee->evas, "Hyper"); + evas_key_modifier_add(ee->evas, "Super"); + evas_key_lock_add(ee->evas, "Caps_Lock"); + evas_key_lock_add(ee->evas, "Num_Lock"); + evas_key_lock_add(ee->evas, "Scroll_Lock"); + + ecore_evases = _ecore_list_prepend(ecore_evases, ee); + ecore_evases_hash = evas_hash_add(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win), ee); + ecore_evases_hash = evas_hash_add(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win_container), ee); + return ee; +#else + return NULL; +#endif +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +Ecore_X_Window +ecore_evas_gl_x11_window_get(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_EVAS_GL + return ee->engine.x.win_container; +#else + return 0; +#endif +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +Ecore_X_Window +ecore_evas_gl_x11_subwindow_get(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_X + return ee->engine.x.win; +#else + return 0; +#endif +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +void +ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, int on) +{ +#ifdef BUILD_ECORE_X + ee->engine.x.direct_resize = on; +#else + return; +#endif +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +int +ecore_evas_gl_x11_direct_resize_get(Ecore_Evas *ee) +{ +#ifdef BUILD_ECORE_X + return ee->engine.x.direct_resize; +#else + return 0; +#endif +} + diff --git a/ecore/src/lib/ecore_fb/.cvsignore b/ecore/src/lib/ecore_fb/.cvsignore new file mode 100644 index 0000000..8b1bf12 --- /dev/null +++ b/ecore/src/lib/ecore_fb/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +ecore_fb.lo +libecore_fb.la diff --git a/ecore/src/lib/ecore_fb/CVS/Entries b/ecore/src/lib/ecore_fb/CVS/Entries new file mode 100644 index 0000000..2a35cfe --- /dev/null +++ b/ecore/src/lib/ecore_fb/CVS/Entries @@ -0,0 +1,7 @@ +/.cvsignore/1.2/Fri Jan 16 16:59:03 2004//THEAD +/Ecore_Fb.h/1.5/Tue Dec 14 03:21:42 2004//THEAD +/Makefile.am/1.7/Thu Mar 10 15:19:39 2005//THEAD +/ecore_fb.c/1.11/Tue May 31 22:42:24 2005//THEAD +/ecore_fb_keytab.h/1.1/Tue Dec 14 16:12:05 2004//THEAD +/ecore_fb_private.h/1.2/Tue Sep 23 08:09:31 2003//THEAD +D diff --git a/ecore/src/lib/ecore_fb/CVS/Repository b/ecore/src/lib/ecore_fb/CVS/Repository new file mode 100644 index 0000000..ffa9ebb --- /dev/null +++ b/ecore/src/lib/ecore_fb/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/src/lib/ecore_fb diff --git a/ecore/src/lib/ecore_fb/CVS/Root b/ecore/src/lib/ecore_fb/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/src/lib/ecore_fb/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/src/lib/ecore_fb/CVS/Tag b/ecore/src/lib/ecore_fb/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/src/lib/ecore_fb/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/src/lib/ecore_fb/Ecore_Fb.h b/ecore/src/lib/ecore_fb/Ecore_Fb.h new file mode 100644 index 0000000..9ec1596 --- /dev/null +++ b/ecore/src/lib/ecore_fb/Ecore_Fb.h @@ -0,0 +1,116 @@ +#ifndef _ECORE_FB_H +#define _ECORE_FB_H + +#ifdef EAPI +#undef EAPI +#endif +#ifdef WIN32 +# ifdef BUILDING_DLL +# define EAPI __declspec(dllexport) +# else +# define EAPI __declspec(dllimport) +# endif +#else +# ifdef GCC_HASCLASSVISIBILITY +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +#endif + +/** + * @file + * @brief Ecore frame buffer system functions. + */ + +/* FIXME: + * maybe a new module? + * - code to get battery info + * - code to get thermal info + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int ECORE_FB_EVENT_KEY_DOWN; /**< FB Key Down event */ +extern int ECORE_FB_EVENT_KEY_UP; /**< FB Key Up event */ +extern int ECORE_FB_EVENT_MOUSE_BUTTON_DOWN; /**< FB Mouse Down event */ +extern int ECORE_FB_EVENT_MOUSE_BUTTON_UP; /**< FB Mouse Up event */ +extern int ECORE_FB_EVENT_MOUSE_MOVE; /**< FB Mouse Move event */ + +typedef struct _Ecore_Fb_Event_Key_Down Ecore_Fb_Event_Key_Down; /**< FB Key Down event */ +typedef struct _Ecore_Fb_Event_Key_Up Ecore_Fb_Event_Key_Up; /**< FB Key Up event */ +typedef struct _Ecore_Fb_Event_Mouse_Button_Down Ecore_Fb_Event_Mouse_Button_Down; /**< FB Mouse Down event */ +typedef struct _Ecore_Fb_Event_Mouse_Button_Up Ecore_Fb_Event_Mouse_Button_Up; /**< FB Mouse Up event */ +typedef struct _Ecore_Fb_Event_Mouse_Move Ecore_Fb_Event_Mouse_Move; /**< FB Mouse Move event */ + +struct _Ecore_Fb_Event_Key_Down /** FB Key Down event */ +{ + char *keyname; /**< The name of the key that was pressed */ + char *keysymbol; /**< The logical symbol of the key that was pressed */ + char *key_compose; /**< The UTF-8 string conversion if any */ +}; + +struct _Ecore_Fb_Event_Key_Up /** FB Key Up event */ +{ + char *keyname; /**< The name of the key that was released */ + char *keysymbol; /**< The logical symbol of the key that was pressed */ + char *key_compose; /**< The UTF-8 string conversion if any */ +}; + +struct _Ecore_Fb_Event_Mouse_Button_Down /** FB Mouse Down event */ +{ + int button; /**< Mouse button that was pressed (1 - 32) */ + int x; /**< Mouse co-ordinates when mouse button was pressed */ + int y; /**< Mouse co-ordinates when mouse button was pressed */ + int double_click : 1; /**< Set if click was a double click */ + int triple_click : 1; /**< Set if click was a triple click */ +}; + +struct _Ecore_Fb_Event_Mouse_Button_Up /** FB Mouse Up event */ +{ + int button; /**< Mouse button that was released (1 - 32) */ + int x; /**< Mouse co-ordinates when mouse button was raised */ + int y; /**< Mouse co-ordinates when mouse button was raised */ +}; + +struct _Ecore_Fb_Event_Mouse_Move /** FB Mouse Move event */ +{ + int x; /**< Mouse co-ordinates where the mouse cursor moved to */ + int y; /**< Mouse co-ordinates where the mouse cursor moved to */ +}; + +EAPI int ecore_fb_init(const char *name); +EAPI int ecore_fb_shutdown(void); + +EAPI void ecore_fb_double_click_time_set(double t); +EAPI double ecore_fb_double_click_time_get(void); + +EAPI void ecore_fb_size_get(int *w, int *h); + +EAPI void ecore_fb_touch_screen_calibrate_set(int xscale, int xtrans, int yscale, int ytrans, int xyswap); +EAPI void ecore_fb_touch_screen_calibrate_get(int *xscale, int *xtrans, int *yscale, int *ytrans, int *xyswap); + +EAPI void ecore_fb_backlight_set(int on); +EAPI int ecore_fb_backlight_get(void); + +EAPI void ecore_fb_backlight_brightness_set(double br); +EAPI double ecore_fb_backlight_brightness_get(void); + +EAPI void ecore_fb_led_set(int on); +EAPI void ecore_fb_led_blink_set(double speed); + +EAPI void ecore_fb_contrast_set(double cr); +EAPI double ecore_fb_contrast_get(void); + +EAPI double ecore_fb_light_sensor_get(void); + +EAPI void ecore_fb_callback_gain_set(void (*func) (void *data), void *data); +EAPI void ecore_fb_callback_lose_set(void (*func) (void *data), void *data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ecore/src/lib/ecore_fb/Makefile.am b/ecore/src/lib/ecore_fb/Makefile.am new file mode 100644 index 0000000..46f9374 --- /dev/null +++ b/ecore/src/lib/ecore_fb/Makefile.am @@ -0,0 +1,32 @@ +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore + +libecore_fb_la_LDFLAGS = -version-info 1:0:0 \ +-L$(top_builddir)/src/lib/ecore/.libs + +if BUILD_ECORE_FB + +lib_LTLIBRARIES = libecore_fb.la +include_HEADERS = \ +Ecore_Fb.h + +libecore_fb_la_SOURCES = \ +ecore_fb.c \ +ecore_fb_private.h \ +ecore_fb_keytab.h + +libecore_fb_la_LIBADD = \ +$(top_builddir)/src/lib/ecore/libecore.la + +libecore_fb_la_DEPENDENCIES = \ +$(top_builddir)/src/lib/ecore/libecore.la + +endif + +EXTRA_DIST = \ +Ecore_Fb.h \ +ecore_fb.c \ +ecore_fb_private.h diff --git a/ecore/src/lib/ecore_fb/ecore_fb.c b/ecore/src/lib/ecore_fb/ecore_fb.c new file mode 100644 index 0000000..14c18fa --- /dev/null +++ b/ecore/src/lib/ecore_fb/ecore_fb.c @@ -0,0 +1,1273 @@ + +#include "Ecore.h" +#include "ecore_fb_private.h" +#include "Ecore_Fb.h" +#include "ecore_private.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct _Ecore_Fb_Ts_Event Ecore_Fb_Ts_Event; +typedef struct _Ecore_Fb_Ts_Calibrate Ecore_Fb_Ts_Calibrate; +typedef struct _Ecore_Fb_Ts_Backlight Ecore_Fb_Ts_Backlight; +typedef struct _Ecore_Fb_Ts_Contrast Ecore_Fb_Ts_Contrast; +typedef struct _Ecore_Fb_Ts_Led Ecore_Fb_Ts_Led; +typedef struct _Ecore_Fb_Ts_Flite Ecore_Fb_Ts_Flite; +typedef struct _Ecore_Fb_Ps2_Event Ecore_Fb_Ps2_Event; + +struct _Ecore_Fb_Ts_Event +{ + unsigned short pressure; + unsigned short x; + unsigned short y; + unsigned short _unused; +}; + +struct _Ecore_Fb_Ts_Calibrate +{ + int xscale; + int xtrans; + int yscale; + int ytrans; + int xyswap; +}; + +struct _Ecore_Fb_Ts_Backlight +{ + int on; + unsigned char brightness; +}; + +struct _Ecore_Fb_Ts_Contrast +{ + unsigned char contrast; +}; + +struct _Ecore_Fb_Ts_Led +{ + unsigned char on; + unsigned char blink_time; + unsigned char on_time; + unsigned char off_time; +}; + +struct _Ecore_Fb_Ts_Flite +{ + unsigned char mode; + unsigned char pwr; + unsigned char brightness; +}; + +struct _Ecore_Fb_Ps2_Event +{ + unsigned char button; + unsigned char x; + unsigned char y; + unsigned char z; +}; + +static void _ecore_fb_size_get(int *w, int *h); +static int _ecore_fb_ts_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); +static int _ecore_fb_kbd_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); +static int _ecore_fb_ps2_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); +static void _ecore_fb_event_free_key_down(void *data, void *ev); +static void _ecore_fb_event_free_key_up(void *data, void *ev); +static int _ecore_fb_signal_usr_handler(void *data, int type, void *ev); +static void _ecore_fb_vt_switch(int vt); + +int ECORE_FB_EVENT_KEY_DOWN = 0; +int ECORE_FB_EVENT_KEY_UP = 0; +int ECORE_FB_EVENT_MOUSE_BUTTON_DOWN = 0; +int ECORE_FB_EVENT_MOUSE_BUTTON_UP = 0; +int ECORE_FB_EVENT_MOUSE_MOVE = 0; + +static Ecore_Event_Handler *_ecore_fb_user_handler = NULL; +static Ecore_Event_Filter *_ecore_fb_filter_handler = NULL; +static Ecore_Fd_Handler *_ecore_fb_ts_fd_handler_handle = NULL; +static Ecore_Fd_Handler *_ecore_fb_kbd_fd_handler_handle = NULL; +static int _ecore_fb_init_count = 0; +static int _ecore_fb_ts_fd = 0; +static int _ecore_fb_ps2_fd = 0; +static int _ecore_fb_kbd_fd = 0; +static int _ecore_fb_tty_fd = 0; +static int _ecore_fb_console_w = 0; +static int _ecore_fb_console_h = 0; +static int _ecore_fb_ts_event_byte_count = 0; +static int _ecore_fb_ps2_event_byte_count = 0; +static Ecore_Fb_Ts_Event _ecore_fb_ts_event; +static Ecore_Fb_Ps2_Event _ecore_fb_ps2_event; +static int _ecore_fb_tty_prev_mode = 0; +static int _ecore_fb_tty_prev_kd_mode = 0; +static struct termios _ecore_fb_tty_prev_tio_mode; +static struct vt_mode _ecore_fb_vt_prev_mode; +static int _ecore_fb_current_vt = 0; +static int _ecore_fb_ctrl = 0; +static int _ecore_fb_alt = 0; +static int _ecore_fb_shift = 0; +static int _ecore_fb_lock = 0; + +static void (*_ecore_fb_func_fb_lost) (void *data) = NULL; +static void *_ecore_fb_func_fb_lost_data = NULL; +static void (*_ecore_fb_func_fb_gain) (void *data) = NULL; +static void *_ecore_fb_func_fb_gain_data = NULL; + +static void *_ecore_fb_event_filter_start(void *data); +static int _ecore_fb_event_filter_filter(void *data, void *loop_data, int type, void *event); +static void _ecore_fb_event_filter_end(void *data, void *loop_data); + +static double _ecore_fb_double_click_time = 0.25; + +static struct _Ecore_Fb_Ts_Calibrate _ecore_fb_ts_cal = {1,1,0,0,0}; +static int _ecore_fb_ts_apply_cal = 0; + +static const char *_ecore_fb_kbd_syms[128 * 6] = +{ +#include "ecore_fb_keytab.h" +}; + +static const char *_ecore_fb_btn_syms[128] = +{ + "0x00", + "Escape", + "F1", + "F2", + "F3", + "F4", + "Up", + "Right", + "Left", + "Down", + "Return", + "0x1b", + "0x1c", + "0x1d", + "0x1e", + "0x1f", + "0x20", + "0x21", + "0x22", + "0x23", + "0x24", + "0x25", + "0x26", + "0x27", + "0x28", + "0x29", + "0x2a", + "0x2b", + "0x2c", + "0x2d", + "0x2e", + "0x2f", + "0x30", + "0x31", + "0x32", + "0x33", + "0x34", + "0x35", + "0x36", + "0x37", + "0x38", + "0x39", + "0x3a", + "0x3b", + "0x3c", + "0x3d", + "0x3e", + "0x3f", + "0x40", + "0x41", + "0x42", + "0x43", + "0x44", + "0x45", + "0x46", + "0x47", + "0x48", + "0x49", + "0x4a", + "0x4b", + "0x4c", + "0x4d", + "0x4e", + "0x4f", + "0x50", + "0x51", + "0x52", + "0x53", + "0x54", + "0x55", + "0x56", + "0x57", + "0x58", + "0x59", + "0x5a", + "0x5b", + "0x5c", + "0x5d", + "0x5e", + "0x5f", + "0x60", + "0x61", + "0x62", + "0x63", + "0x64", + "0x65", + "0x66", + "0x67", + "0x68", + "0x69", + "0x6a", + "0x6b", + "0x6c", + "0x6d", + "0x6e", + "0x6f", + "0x70", + "0x71", + "0x72", + "0x73", + "0x74", + "0x75", + "0x76", + "0x77", + "0x78", + "0x79", + "0x7a", + "0x7b", + "0x7c", + "0x7d", + "0x7e", + "0x7f" +}; + +/** + * @defgroup Ecore_FB_Library_Group Framebuffer Library Functions + * + * Functions used to set up and shut down the Ecore_Framebuffer functions. + */ + +/** + * Sets up the Ecore_Fb library. + * @param name device target name + * @return @c 0 on failure. Otherwise, the number of times the library has + * been initialised without being shut down. + * @ingroup Ecore_FB_Library_Group + */ +int +ecore_fb_init(const char *name __UNUSED__) +{ + int prev_flags; + + _ecore_fb_init_count++; + if (_ecore_fb_init_count > 1) return _ecore_fb_init_count; + _ecore_fb_ts_fd = open("/dev/touchscreen/0", O_RDONLY); + if (_ecore_fb_ts_fd >= 0) + { + prev_flags = fcntl(_ecore_fb_ts_fd, F_GETFL); + fcntl(_ecore_fb_ts_fd, F_SETFL, prev_flags | O_NONBLOCK); + _ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ts_fd, + ECORE_FD_READ, + _ecore_fb_ts_fd_handler, NULL, + NULL, NULL); + if (!_ecore_fb_ts_fd_handler_handle) + { + close(_ecore_fb_ts_fd); + } + } + if (_ecore_fb_ts_fd < 0) + { + _ecore_fb_ps2_fd = open("/dev/psaux", O_RDWR); + if (_ecore_fb_ps2_fd >= 0) + { + prev_flags = fcntl(_ecore_fb_ps2_fd, F_GETFL); + fcntl(_ecore_fb_ps2_fd, F_SETFL, prev_flags | O_NONBLOCK); + _ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ps2_fd, + ECORE_FD_READ, + _ecore_fb_ps2_fd_handler, NULL, + NULL, NULL); + if (!_ecore_fb_ts_fd_handler_handle) + { + close(_ecore_fb_ps2_fd); + } + } + } + _ecore_fb_kbd_fd = open("/dev/touchscreen/key", O_RDONLY); + _ecore_fb_tty_fd = open("/dev/tty0", O_RDONLY); + if (_ecore_fb_tty_fd >= 0) + { + struct termios tio; + struct vt_mode new_vtmode; + int vtno; + + if ((ioctl(_ecore_fb_tty_fd, VT_OPENQRY, &vtno) != -1)) + { + char buf[64]; + + _ecore_fb_current_vt = vtno; + ioctl(_ecore_fb_tty_fd, VT_ACTIVATE, _ecore_fb_current_vt); + close(_ecore_fb_tty_fd); + snprintf(buf, sizeof(buf), "/dev/tty%i", _ecore_fb_current_vt); +/* FIXME: switch away works.. but switch to the allocated vt doesnt */ +/* printf("%s\n", buf); */ + _ecore_fb_tty_fd = open(buf, O_RDWR); + if (_ecore_fb_current_vt == 1) + { + Ecore_Event_Signal_User *e; + + e = _ecore_event_signal_user_new(); + if (e) + { + e->number = 2; + ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, NULL); + } + } + } + tcgetattr(_ecore_fb_tty_fd, &_ecore_fb_tty_prev_tio_mode); + ioctl(_ecore_fb_tty_fd, KDGETMODE, &_ecore_fb_tty_prev_kd_mode); + ioctl(_ecore_fb_tty_fd, KDGKBMODE, &_ecore_fb_tty_prev_mode); + ioctl(_ecore_fb_tty_fd, VT_GETMODE, &_ecore_fb_vt_prev_mode); + tio.c_iflag = tio.c_oflag = tio.c_cflag = tio.c_lflag = 0; + tio.c_cc[VTIME] = 0; + tio.c_cc[VMIN] = 1; + new_vtmode.mode = VT_PROCESS; + new_vtmode.waitv = 0; + new_vtmode.relsig = SIGUSR1; + new_vtmode.acqsig = SIGUSR2; + tcsetattr(_ecore_fb_tty_fd, TCSAFLUSH, &tio); + ioctl(_ecore_fb_tty_fd, KDSETMODE, KD_GRAPHICS); + ioctl(_ecore_fb_tty_fd, KDSKBMODE, K_MEDIUMRAW); + ioctl(_ecore_fb_tty_fd, VT_SETMODE, &new_vtmode); + } + if (_ecore_fb_kbd_fd <= 0) _ecore_fb_kbd_fd = _ecore_fb_tty_fd; + if (_ecore_fb_kbd_fd >= 0) + { + prev_flags = fcntl(_ecore_fb_kbd_fd, F_GETFL); + fcntl(_ecore_fb_kbd_fd, F_SETFL, prev_flags | O_NONBLOCK); + _ecore_fb_kbd_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_kbd_fd, + ECORE_FD_READ, + _ecore_fb_kbd_fd_handler, NULL, + NULL, NULL); + if (!_ecore_fb_kbd_fd_handler_handle) + { + tcsetattr(_ecore_fb_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode); + ioctl(_ecore_fb_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode); + ioctl(_ecore_fb_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode); + close(_ecore_fb_tty_fd); + close(_ecore_fb_ts_fd); + close(_ecore_fb_kbd_fd); + if (_ecore_fb_ps2_fd > 0) close(_ecore_fb_ps2_fd); + if (_ecore_fb_tty_fd != _ecore_fb_kbd_fd) + close(_ecore_fb_tty_fd); + ecore_main_fd_handler_del(_ecore_fb_ts_fd_handler_handle); + _ecore_fb_ts_fd_handler_handle = NULL; + _ecore_fb_init_count--; + return 0; + } + } + if (!ECORE_FB_EVENT_KEY_DOWN) + { + ECORE_FB_EVENT_KEY_DOWN = ecore_event_type_new(); + ECORE_FB_EVENT_KEY_UP = ecore_event_type_new(); + ECORE_FB_EVENT_MOUSE_BUTTON_DOWN = ecore_event_type_new(); + ECORE_FB_EVENT_MOUSE_BUTTON_UP = ecore_event_type_new(); + ECORE_FB_EVENT_MOUSE_MOVE = ecore_event_type_new(); + + } + _ecore_fb_size_get(&_ecore_fb_console_w, &_ecore_fb_console_h); + _ecore_fb_user_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER, + _ecore_fb_signal_usr_handler, + NULL); + _ecore_fb_filter_handler = ecore_event_filter_add(_ecore_fb_event_filter_start, _ecore_fb_event_filter_filter, _ecore_fb_event_filter_end, NULL); + return _ecore_fb_init_count; +} + +/** + * Shuts down the Ecore_Fb library. + * @return @c The number of times the system has been initialised without + * being shut down. + * @ingroup Ecore_FB_Library_Group + */ +int +ecore_fb_shutdown(void) +{ + _ecore_fb_init_count--; + if (_ecore_fb_init_count > 0) return _ecore_fb_init_count; + if (_ecore_fb_init_count < 0) + { + _ecore_fb_init_count = 0; + return 0; + } + if (_ecore_fb_tty_fd != 0) + { + tcsetattr(_ecore_fb_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode); + ioctl(_ecore_fb_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode); + ioctl(_ecore_fb_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode); + ioctl(_ecore_fb_tty_fd, VT_SETMODE, &_ecore_fb_vt_prev_mode); + close(_ecore_fb_tty_fd); + if (_ecore_fb_tty_fd == _ecore_fb_kbd_fd) _ecore_fb_kbd_fd = 0; + } + if (_ecore_fb_ps2_fd > 0) close(_ecore_fb_ps2_fd); + if (_ecore_fb_ts_fd >= 0) close(_ecore_fb_ts_fd); + if (_ecore_fb_kbd_fd >= 0) close(_ecore_fb_kbd_fd); + if (_ecore_fb_ts_fd_handler_handle) + ecore_main_fd_handler_del(_ecore_fb_ts_fd_handler_handle); + if (_ecore_fb_kbd_fd_handler_handle) + ecore_main_fd_handler_del(_ecore_fb_kbd_fd_handler_handle); + if (_ecore_fb_user_handler) + ecore_event_handler_del(_ecore_fb_user_handler); + ecore_event_filter_del(_ecore_fb_filter_handler); + _ecore_fb_ts_fd = 0; + _ecore_fb_kbd_fd = 0; + _ecore_fb_tty_fd = 0; + _ecore_fb_ps2_fd = 0; + _ecore_fb_ts_fd_handler_handle = NULL; + _ecore_fb_filter_handler = NULL; + _ecore_fb_kbd_fd_handler_handle = NULL; + _ecore_fb_user_handler = NULL; + _ecore_fb_ctrl = 0; + _ecore_fb_alt = 0; + return _ecore_fb_init_count; +} + +/** + * @defgroup Ecore_FB_Click_Group Framebuffer Double Click Functions + * + * Functions that deal with the double click time of the framebuffer. + */ + +/** + * Sets the timeout for a double and triple clicks to be flagged. + * + * This sets the time between clicks before the double_click flag is + * set in a button down event. If 3 clicks occur within double this + * time, the triple_click flag is also set. + * + * @param t The time in seconds + * @ingroup Ecore_FB_Click_Group + */ +void +ecore_fb_double_click_time_set(double t) +{ + if (t < 0.0) t = 0.0; + _ecore_fb_double_click_time = t; +} + +/** + * Retrieves the double and triple click flag timeout. + * + * See @ref ecore_x_double_click_time_set for more information. + * + * @return The timeout for double clicks in seconds. + * @ingroup Ecore_FB_Click_Group + */ +double +ecore_fb_double_click_time_get(void) +{ + return _ecore_fb_double_click_time; +} + +/** + * Retrieves the width and height of the current frame buffer in pixels. + * @param w Pointer to an integer in which to store the width. + * @param h Pointer to an interge in which to store the height. + */ +void +ecore_fb_size_get(int *w, int *h) +{ + if (w) *w = _ecore_fb_console_w; + if (h) *h = _ecore_fb_console_h; +} + +/** + * @defgroup Ecore_FB_Calibrate_Group Framebuffer Calibration Functions + * + * Functions that calibrate the screen. + */ + +/** + * Calibrates the touschreen using the given parameters. + * @param xscale X scaling, where 256 = 1.0 + * @param xtrans X translation. + * @param yscale Y scaling. + * @param ytrans Y translation. + * @param xyswap Swap X & Y flag. + * @ingroup Ecore_FB_Calibrate_Group + */ +void +ecore_fb_touch_screen_calibrate_set(int xscale, int xtrans, int yscale, int ytrans, int xyswap) +{ + Ecore_Fb_Ts_Calibrate cal; + + if (_ecore_fb_ts_fd < 0) return; + cal.xscale = xscale; + cal.xtrans = xtrans; + cal.yscale = yscale; + cal.ytrans = ytrans; + cal.xyswap = xyswap; + if (ioctl(_ecore_fb_ts_fd, TS_SET_CAL, (void *)&cal)) + { + _ecore_fb_ts_cal = cal; + _ecore_fb_ts_apply_cal = 1; + } +} + +/** + * Retrieves the calibration parameters of the touchscreen. + * @param xscale Pointer to an integer in which to store the X scaling. + * Note that 256 = 1.0. + * @param xtrans Pointer to an integer in which to store the X translation. + * @param yscale Pointer to an integer in which to store the Y scaling. + * @param ytrans Pointer to an integer in which to store the Y translation. + * @param xyswap Pointer to an integer in which to store the Swap X & Y flag. + * @ingroup Ecore_FB_Calibrate_Group + */ +void +ecore_fb_touch_screen_calibrate_get(int *xscale, int *xtrans, int *yscale, int *ytrans, int *xyswap) +{ + Ecore_Fb_Ts_Calibrate cal; + + if (_ecore_fb_ts_fd < 0) return; + if (!_ecore_fb_ts_apply_cal) + { + if (ioctl(_ecore_fb_ts_fd, TS_GET_CAL, (void *)&cal)) + _ecore_fb_ts_cal = cal; + } + else + cal = _ecore_fb_ts_cal; + if (xscale) *xscale = cal.xscale; + if (xtrans) *xtrans = cal.xtrans; + if (yscale) *yscale = cal.yscale; + if (ytrans) *ytrans = cal.ytrans; + if (xyswap) *xyswap = cal.xyswap; +} + +/** + * @defgroup Ecore_FB_Backlight_Group Framebuffer Backlight Functions + * + * Functions that deal with the backlight of a framebuffer's screen. + */ + +/** + * Turns on or off the backlight. + * @param on @c 1 to turn the backlight on. @c 0 to turn it off. + * @ingroup Ecore_FB_Backlight_Group + */ +void +ecore_fb_backlight_set(int on) +{ + Ecore_Fb_Ts_Backlight bl; + + if (_ecore_fb_ts_fd < 0) return; + ioctl(_ecore_fb_ts_fd, TS_GET_BACKLIGHT, &bl); + bl.on = on; + ioctl(_ecore_fb_ts_fd, TS_SET_BACKLIGHT, &bl); +} + +/** + * Retrieves the backlight state. + * @return Whether the backlight is on. + * @ingroup Ecore_FB_Backlight_Group + */ +int +ecore_fb_backlight_get(void) +{ + Ecore_Fb_Ts_Backlight bl; + + if (_ecore_fb_ts_fd < 0) return 1; + ioctl(_ecore_fb_ts_fd, TS_GET_BACKLIGHT, &bl); + return bl.on; +} + +/** + * Sets the backlight brightness. + * @param br Brightness between 0.0 to 1.0, where 0.0 is darkest and 1.0 + * is brightest. + * @ingroup Ecore_FB_Backlight_Group + */ +void +ecore_fb_backlight_brightness_set(double br) +{ + Ecore_Fb_Ts_Backlight bl; + int val; + + if (br < 0) br = 0; + if (br > 1) br = 1; + val = (int)(255.0 * br); + ioctl(_ecore_fb_ts_fd, TS_GET_BACKLIGHT, &bl); + bl.brightness = val; + ioctl(_ecore_fb_ts_fd, TS_SET_BACKLIGHT, &bl); +} + +/** + * Retrieves the backlight brightness. + * @return The current backlight brigntess, where 0.0 is the darkest and + * 1.0 is the brightest. + * @ingroup Ecore_FB_Backlight_Group + */ +double +ecore_fb_backlight_brightness_get(void) +{ + Ecore_Fb_Ts_Backlight bl; + + if (_ecore_fb_ts_fd < 0) return 1.0; + ioctl(_ecore_fb_ts_fd, TS_GET_BACKLIGHT, &bl); + return (double)bl.brightness / 255.0; +} + +/** + * @defgroup Ecore_FB_LED_Group Framebuffer LED Functions + * + * Functions that deal with the light emitting diode connected to the + * current framebuffer. + */ + +/** + * Sets whether the current framebuffer's LED to the given state. + * @param on @c 1 to indicate the LED should be on, @c 0 if it should be off. + * @ingroup Ecore_FB_LED_Group + */ +void +ecore_fb_led_set(int on) +{ + Ecore_Fb_Ts_Led led; + + if (_ecore_fb_ts_fd < 0) return; + if (on) led.on = 1; + else led.on = 0; + ioctl(_ecore_fb_ts_fd, LED_ON, &led); +} + +/** + * Makes the LED of the current framebuffer blink. + * @param speed Number to give the speed on the blink. + * @ingroup Ecore_FB_LED_Group + * @todo Documentation: Work out what speed the units are in. + */ +void +ecore_fb_led_blink_set(double speed) +{ + Ecore_Fb_Ts_Led led; + + if (_ecore_fb_ts_fd < 0) return; + led.on = 1; + led.on_time = (unsigned char)(speed * 10); + led.off_time = (unsigned char)(speed * 10); + led.blink_time = 255; + ioctl(_ecore_fb_ts_fd, LED_ON, &led); +} + +/** + * @defgroup Ecore_FB_Contrast_Group Framebuffer Contrast Functions + * + * Values that set and retrieve the contrast of a framebuffer screen. + */ + +/** + * Sets the contrast used by the framebuffer screen. + * @param cr Value between 0 and 1 that gives the new contrast of the screen. + * @ingroup Ecore_FB_Contrast_Group + */ +void +ecore_fb_contrast_set(double cr) +{ + Ecore_Fb_Ts_Contrast ct; + int val; + + if (cr < 0) cr = 0; + if (cr > 1) cr = 1; + val = (int)(255.0 * cr); + ct.contrast = val; + ioctl(_ecore_fb_ts_fd, TS_SET_CONTRAST, &ct); +} + +/** + * Retrieves the contrast currently being used by the framebuffer screen. + * @return A value between 0 and 1 that represents the current contrast of the + * screen. + * @ingroup Ecore_FB_Contrast_Group + */ +double +ecore_fb_contrast_get(void) +{ + Ecore_Fb_Ts_Contrast ct; + + if (_ecore_fb_ts_fd < 0) return 1.0; + ioctl(_ecore_fb_ts_fd, TS_GET_CONTRAST, &ct); + return (double)ct.contrast / 255.0; +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +double +ecore_fb_light_sensor_get(void) +{ + Ecore_Fb_Ts_Flite fl; + + if (_ecore_fb_ts_fd < 0) return 0.0; + fl.mode = 3; + fl.brightness = 0; + ioctl(_ecore_fb_ts_fd, FLITE_ON, &fl); + return (double)fl.brightness / 255.0; +} + +/** + * To be documented. + * + * FIXME: To be fixed. + * @todo Documentation: Find out what this does. + */ +void +ecore_fb_callback_gain_set(void (*func) (void *data), void *data) +{ + _ecore_fb_func_fb_gain = func; + _ecore_fb_func_fb_gain_data = data; +} + +/** + * To be documented. + * + * FIXME: To be fixed. + * @todo Documentation: Find out what this does. + */ +void +ecore_fb_callback_lose_set(void (*func) (void *data), void *data) +{ + _ecore_fb_func_fb_lost = func; + _ecore_fb_func_fb_lost_data = data; +} + +static void +_ecore_fb_size_get(int *w, int *h) +{ + struct fb_var_screeninfo fb_var; + int fb; + + fb = open("/dev/fb0", O_RDWR); + if (fb < 0) + { + if (w) *w = 0; + if (h) *h = 0; + return; + } + if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_var) == -1) + { + if (w) *w = 0; + if (h) *h = 0; + return; + } + close(fb); + if (w) *w = fb_var.xres; + if (h) *h = fb_var.yres; +} + +static int +_ecore_fb_ts_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__) +{ + static int prev_x = 0, prev_y = 0, prev_pressure = 0; + static double last_time = 0; + static double last_last_time = 0; + int v = 0; + + do + { + int x, y, pressure; + int num; + char *ptr; + double t; + int did_triple = 0; + + ptr = (char *)&(_ecore_fb_ts_event); + ptr += _ecore_fb_ts_event_byte_count; + num = sizeof(Ecore_Fb_Ts_Event) - _ecore_fb_ts_event_byte_count; + v = read(_ecore_fb_ts_fd, ptr, num); + if (v < 0) return 1; + _ecore_fb_ts_event_byte_count += v; + if (v < num) return 1; + t = ecore_time_get(); + _ecore_fb_ts_event_byte_count = 0; + if (_ecore_fb_ts_apply_cal) + { + x = ((_ecore_fb_ts_cal.xscale * _ecore_fb_ts_event.x) >> 8) + _ecore_fb_ts_cal.xtrans; + y = ((_ecore_fb_ts_cal.yscale * _ecore_fb_ts_event.y) >> 8) + _ecore_fb_ts_cal.ytrans; + } + else + { + x = _ecore_fb_ts_event.x; + y = _ecore_fb_ts_event.y; + } + pressure = _ecore_fb_ts_event.pressure; + /* add event to queue */ + /* always add a move event */ + if ((pressure) || (prev_pressure)) + { + /* MOVE: mouse is down and was */ + Ecore_Fb_Event_Mouse_Move *e; + + e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Move)); + if (!e) goto retry; + e->x = x; + e->y = y; + ecore_event_add(ECORE_FB_EVENT_MOUSE_MOVE, e, NULL, NULL); + } + if ((pressure) && (!prev_pressure)) + { + /* DOWN: mouse is down, but was not now */ + Ecore_Fb_Event_Mouse_Button_Down *e; + + e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Down)); + if (!e) goto retry; + e->x = x; + e->y = y; + e->button = 1; + if ((t - last_time) <= _ecore_fb_double_click_time) + e->double_click = 1; + if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time)) + { + did_triple = 1; + e->triple_click = 1; + } + ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL); + } + else if ((!pressure) && (prev_pressure)) + { + /* UP: mouse was down, but is not now */ + Ecore_Fb_Event_Mouse_Button_Up *e; + + e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Up)); + if (!e) goto retry; + e->x = prev_x; + e->y = prev_y; + e->button = 1; + ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL); + } + if (did_triple) + { + last_time = 0; + last_last_time = 0; + } + else + { + last_last_time = last_time; + last_time = t; + } + retry: + prev_x = x; + prev_y = y; + prev_pressure = pressure; + } + while (v > 0); + return 1; +} + +static int +_ecore_fb_kbd_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__) +{ + int v = 0; + + do + { + unsigned char buf; + + v = read(_ecore_fb_kbd_fd, &buf, 1); + if (v < 0) return 1; + if (v < 1) return 1; + if (buf & 0x80) + { + /* DOWN */ + int vt_switch = -1; + Ecore_Fb_Event_Key_Down *e; + + e = calloc(1, sizeof(Ecore_Fb_Event_Key_Down)); + if (!e) goto retry; + if (_ecore_fb_kbd_fd == _ecore_fb_tty_fd) + { + int add = 0; + + if (_ecore_fb_shift) add = 1; + else if (_ecore_fb_lock) add = 2; + e->keyname = strdup(_ecore_fb_kbd_syms[(buf & 0x7f) * 6]); + e->keysymbol = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 6) + add]); + e->key_compose = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 6) + 3 + add]); + } + else + e->keyname = strdup(_ecore_fb_btn_syms[buf & 0x7f]); + if (!e->keyname) + { + free(e); + goto retry; + } + ecore_event_add(ECORE_FB_EVENT_KEY_DOWN, e, _ecore_fb_event_free_key_down, NULL); + if (!strcmp(e->keyname, "Control_L")) + _ecore_fb_ctrl++; + else if (!strcmp(e->keyname, "Control_R")) + _ecore_fb_ctrl++; + else if (!strcmp(e->keyname, "Alt_L")) + _ecore_fb_alt++; + else if (!strcmp(e->keyname, "Alt_R")) + _ecore_fb_alt++; + else if (!strcmp(e->keyname, "Shift_L")) + _ecore_fb_shift++; + else if (!strcmp(e->keyname, "Shift_R")) + _ecore_fb_shift++; + else if (!strcmp(e->keyname, "Caps_Lock")) + _ecore_fb_lock++; + else if (!strcmp(e->keyname, "F1")) vt_switch = 0; + else if (!strcmp(e->keyname, "F2")) vt_switch = 1; + else if (!strcmp(e->keyname, "F3")) vt_switch = 2; + else if (!strcmp(e->keyname, "F4")) vt_switch = 3; + else if (!strcmp(e->keyname, "F5")) vt_switch = 4; + else if (!strcmp(e->keyname, "F6")) vt_switch = 5; + else if (!strcmp(e->keyname, "F7")) vt_switch = 6; + else if (!strcmp(e->keyname, "F8")) vt_switch = 7; + else if (!strcmp(e->keyname, "F9")) vt_switch = 8; + else if (!strcmp(e->keyname, "F10")) vt_switch = 9; + else if (!strcmp(e->keyname, "F11")) vt_switch = 10; + else if (!strcmp(e->keyname, "F12")) vt_switch = 11; + if (_ecore_fb_ctrl > 2) _ecore_fb_ctrl = 2; + if (_ecore_fb_alt > 2) _ecore_fb_alt = 2; + if ((vt_switch >= 0) && + (_ecore_fb_ctrl) && + (_ecore_fb_alt)) + _ecore_fb_vt_switch(vt_switch); + } + else + { + /* UP */ + Ecore_Fb_Event_Key_Up *e; + + e = calloc(1, sizeof(Ecore_Fb_Event_Key_Up)); + if (!e) goto retry; + if (_ecore_fb_kbd_fd == _ecore_fb_tty_fd) + { + int add = 0; + + if (_ecore_fb_shift) add = 1; + else if (_ecore_fb_lock) add = 2; + e->keyname = strdup(_ecore_fb_kbd_syms[(buf & 0x7f) * 6]); + e->keysymbol = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 6) + add]); + e->key_compose = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 6) + 3 + add]); + } + else + e->keyname = strdup(_ecore_fb_btn_syms[buf & 0x7f]); + if (!e->keyname) + { + free(e); + goto retry; + } + ecore_event_add(ECORE_FB_EVENT_KEY_UP, e, _ecore_fb_event_free_key_up, NULL); + if (!strcmp(e->keyname, "Control_L")) + _ecore_fb_ctrl--; + else if (!strcmp(e->keyname, "Control_R")) + _ecore_fb_ctrl--; + else if (!strcmp(e->keyname, "Alt_L")) + _ecore_fb_alt--; + else if (!strcmp(e->keyname, "Alt_R")) + _ecore_fb_alt--; + else if (!strcmp(e->keyname, "Shift_L")) + _ecore_fb_shift--; + else if (!strcmp(e->keyname, "Shift_R")) + _ecore_fb_shift--; + else if (!strcmp(e->keyname, "Caps_Lock")) + _ecore_fb_lock--; + if (_ecore_fb_ctrl < 0) _ecore_fb_ctrl = 0; + if (_ecore_fb_alt < 0) _ecore_fb_alt = 0; + if (_ecore_fb_shift < 0) _ecore_fb_shift = 0; + if (_ecore_fb_lock < 0) _ecore_fb_lock = 0; + } + retry: + ; + } + while (v > 0); + return 1; +} + +static int +_ecore_fb_ps2_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__) +{ + static int prev_x = 0, prev_y = 0, prev_button = 0; + static double last_time = 0; + static double last_last_time = 0; + int v = 0; + + do + { + int x, y, button, i; + int num; + char *ptr; + double t; + int did_triple = 0; + + ptr = (char *)&(_ecore_fb_ps2_event); + ptr += _ecore_fb_ps2_event_byte_count; + num = sizeof(Ecore_Fb_Ps2_Event) - _ecore_fb_ps2_event_byte_count; + v = read(_ecore_fb_ps2_fd, ptr, num); + if (v < 0) return 1; + _ecore_fb_ps2_event_byte_count += v; + if (v < num) return 1; + t = ecore_time_get(); + _ecore_fb_ps2_event_byte_count = 0; + if (_ecore_fb_ps2_event.button & 0x10) + x = prev_x + (0xffffff00 | _ecore_fb_ps2_event.x); + else + x = prev_x + _ecore_fb_ps2_event.x; + if (_ecore_fb_ps2_event.button & 0x20) + y = prev_y - (0xffffff00 | _ecore_fb_ps2_event.y); + else + y = prev_y - _ecore_fb_ps2_event.y; + button = _ecore_fb_ps2_event.button & 0x7; + if (x < 0) x = 0; + if (y < 0) y = 0; + if (x >= _ecore_fb_console_w) x = _ecore_fb_console_w - 1; + if (y >= _ecore_fb_console_h) y = _ecore_fb_console_h - 1; + /* add event to queue */ + /* always add a move event */ + if (1) + { + /* MOVE: mouse is down and was */ + Ecore_Fb_Event_Mouse_Move *e; + + e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Move)); + if (!e) goto retry; + e->x = x; + e->y = y; + ecore_event_add(ECORE_FB_EVENT_MOUSE_MOVE, e, NULL, NULL); + } + for (i = 1; i <= 3; i++) + { + int mask; + + mask = 1 << (i - 1); + if (((button & mask)) && (!(prev_button & mask))) + { + /* DOWN: mouse is down, but was not now */ + Ecore_Fb_Event_Mouse_Button_Down *e; + + e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Down)); + if (!e) goto retry; + e->x = x; + e->y = y; + e->button = 1; + if ((t - last_time) <= _ecore_fb_double_click_time) + e->double_click = 1; + if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time)) + { + did_triple = 1; + e->triple_click = 1; + } + ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL); + } + else if ((!(button & mask)) && ((prev_button & mask))) + { + /* UP: mouse was down, but is not now */ + Ecore_Fb_Event_Mouse_Button_Up *e; + + e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Up)); + if (!e) goto retry; + e->x = x; + e->y = y; + e->button = 1; + ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL); + } + } + if (did_triple) + { + last_time = 0; + last_last_time = 0; + } + else + { + last_last_time = last_time; + last_time = t; + } + retry: + prev_x = x; + prev_y = y; + prev_button = button; + } + while (v > 0); + return 1; +} + +static void +_ecore_fb_event_free_key_down(void *data __UNUSED__, void *ev) +{ + Ecore_Fb_Event_Key_Up *e; + + e = ev; + free(e->keyname); + if (e->keysymbol) free(e->keysymbol); + if (e->key_compose) free(e->key_compose); + free(e); +} + +static void +_ecore_fb_event_free_key_up(void *data __UNUSED__, void *ev) +{ + Ecore_Fb_Event_Key_Up *e; + + e = ev; + free(e->keyname); + if (e->keysymbol) free(e->keysymbol); + if (e->key_compose) free(e->key_compose); + free(e); +} + +static int +_ecore_fb_signal_usr_handler(void *data __UNUSED__, int type __UNUSED__, void *ev) +{ + Ecore_Event_Signal_User *e; + + e = (Ecore_Event_Signal_User *)ev; + if (e->number == 1) + { + /* release */ + if (_ecore_fb_func_fb_lost) + _ecore_fb_func_fb_lost(_ecore_fb_func_fb_lost_data); + if (_ecore_fb_ps2_fd > 0) close(_ecore_fb_ps2_fd); + if (_ecore_fb_ts_fd >= 0) close(_ecore_fb_ts_fd); + if (_ecore_fb_ts_fd_handler_handle) + ecore_main_fd_handler_del(_ecore_fb_ts_fd_handler_handle); + _ecore_fb_ps2_fd = 0; + _ecore_fb_ts_fd = 0; + _ecore_fb_ts_fd_handler_handle = NULL; + ioctl(_ecore_fb_tty_fd, VT_RELDISP, 1); + } + else if (e->number == 2) + { + int prev_flags; + + /* gain */ + if (_ecore_fb_func_fb_gain) + _ecore_fb_func_fb_gain(_ecore_fb_func_fb_gain_data); + if (!_ecore_fb_ts_fd) + { + _ecore_fb_ts_fd = open("/dev/touchscreen/0", O_RDONLY); + if (_ecore_fb_ts_fd >= 0) + { + prev_flags = fcntl(_ecore_fb_ts_fd, F_GETFL); + fcntl(_ecore_fb_ts_fd, F_SETFL, prev_flags | O_NONBLOCK); + _ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ts_fd, + ECORE_FD_READ, + _ecore_fb_ts_fd_handler, NULL, + NULL, NULL); + if (!_ecore_fb_ts_fd_handler_handle) + { + close(_ecore_fb_ts_fd); + } + } + } + if (_ecore_fb_ts_fd < 0) + { + if (!_ecore_fb_ps2_fd) + { + _ecore_fb_ps2_fd = open("/dev/psaux", O_RDWR); + if (_ecore_fb_ps2_fd >= 0) + { + prev_flags = fcntl(_ecore_fb_ps2_fd, F_GETFL); + fcntl(_ecore_fb_ps2_fd, F_SETFL, prev_flags | O_NONBLOCK); + _ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ps2_fd, + ECORE_FD_READ, + _ecore_fb_ps2_fd_handler, NULL, + NULL, NULL); + if (!_ecore_fb_ts_fd_handler_handle) + { + close(_ecore_fb_ps2_fd); + } + } + } + } + if (_ecore_fb_tty_fd != 0) + { + struct termios tio; + struct vt_mode new_vtmode; + + tio.c_iflag = tio.c_oflag = tio.c_cflag = tio.c_lflag = 0; + tio.c_cc[VTIME] = 0; + tio.c_cc[VMIN] = 1; + new_vtmode.mode = VT_PROCESS; + new_vtmode.waitv = 0; + new_vtmode.relsig = SIGUSR1; + new_vtmode.acqsig = SIGUSR2; + tcsetattr(_ecore_fb_tty_fd, TCSAFLUSH, &tio); + ioctl(_ecore_fb_tty_fd, KDSETMODE, KD_GRAPHICS); + ioctl(_ecore_fb_tty_fd, KDSKBMODE, K_MEDIUMRAW); + ioctl(_ecore_fb_tty_fd, VT_SETMODE, &new_vtmode); + } + } + return 1; +} + +static void +_ecore_fb_vt_switch(int vt) +{ + vt++; + if (_ecore_fb_tty_fd != 0) + { + if (vt != _ecore_fb_current_vt) + { + tcsetattr(_ecore_fb_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode); + ioctl(_ecore_fb_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode); + ioctl(_ecore_fb_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode); + } + } + ioctl(_ecore_fb_tty_fd, VT_ACTIVATE, vt); +} + +typedef struct _Ecore_Fb_Filter_Data Ecore_Fb_Filter_Data; + +struct _Ecore_Fb_Filter_Data +{ + int last_event_type; +}; + +static void * +_ecore_fb_event_filter_start(void *data __UNUSED__) +{ + Ecore_Fb_Filter_Data *filter_data; + + filter_data = calloc(1, sizeof(Ecore_Fb_Filter_Data)); + return filter_data; +} + +static int +_ecore_fb_event_filter_filter(void *data __UNUSED__, void *loop_data,int type, void *event __UNUSED__) +{ + Ecore_Fb_Filter_Data *filter_data; + + filter_data = loop_data; + if (!filter_data) return 1; + if (type == ECORE_FB_EVENT_MOUSE_MOVE) + { + if ((filter_data->last_event_type) == ECORE_FB_EVENT_MOUSE_MOVE) + { + filter_data->last_event_type = type; + return 0; + } + } + filter_data->last_event_type = type; + return 1; +} + +static void +_ecore_fb_event_filter_end(void *data __UNUSED__, void *loop_data) +{ + Ecore_Fb_Filter_Data *filter_data; + + filter_data = loop_data; + if (filter_data) free(filter_data); +} diff --git a/ecore/src/lib/ecore_fb/ecore_fb_keytab.h b/ecore/src/lib/ecore_fb/ecore_fb_keytab.h new file mode 100644 index 0000000..dfc17b3 --- /dev/null +++ b/ecore/src/lib/ecore_fb/ecore_fb_keytab.h @@ -0,0 +1,128 @@ + "0x00", "0x00", "0x00", /**/"", "", "",/***/ + "Escape", "Escape", "Escape", /**/"", "", "",/***/ + "1", "exclam", "1", /**/"1", "!", "1",/***/ + "2", "at", "2", /**/"2", "@", "2",/***/ + "3", "numbersign", "3", /**/"3", "#", "3",/***/ + "4", "dollar", "4", /**/"4", "$", "4",/***/ + "5", "percent", "5", /**/"5", "%", "5",/***/ + "6", "asciicircumm", "6", /**/"6", "^", "6",/***/ + "7", "ampersand", "7", /**/"7", "&", "7",/***/ + "8", "asterik", "8", /**/"8", "*", "8",/***/ + "9", "parenleft", "9", /**/"9", "(", "9",/***/ + "0", "parenright", "0", /**/"0", ")", "0",/***/ + "minus", "underscore", "minus", /**/"-", "_", "-",/***/ + "equal", "plus", "equal", /**/"=", "+", "=",/***/ + "BackSpace", "BackSpace", "BackSpace", /**/"\010","\010","\010",/***/ + "Tab", "ISO_Left_Tab", "Tab", /**/"\011","", "\011",/***/ + "q", "Q", "Q", /**/"q", "Q", "Q",/***/ + "w", "W", "W", /**/"w", "W", "W",/***/ + "e", "E", "E", /**/"e", "E", "E",/***/ + "r", "R", "R", /**/"r", "R", "R",/***/ + "t", "T", "T", /**/"t", "T", "T",/***/ + "y", "Y", "Y", /**/"y", "Y", "Y",/***/ + "u", "U", "U", /**/"u", "U", "U",/***/ + "i", "I", "I", /**/"i", "I", "I",/***/ + "o", "O", "O", /**/"o", "O", "O",/***/ + "p", "P", "P", /**/"p", "P", "P",/***/ + "bracketleft", "braceleft", "bracketleft", /**/"[", "{", "[",/***/ + "bracketright", "braceright", "bracketright", /**/"]", "}", "]",/***/ + "Return", "Return", "Return", /**/"\015","\015","\015",/***/ + "Control_L", "Control_L", "Control_L", /**/"", "", "",/***/ + "a", "A", "A", /**/"a", "A", "A",/***/ + "s", "S", "S", /**/"s", "S", "S",/***/ + "d", "D", "D", /**/"d", "D", "D",/***/ + "f", "F", "F", /**/"f", "F", "F",/***/ + "g", "G", "G", /**/"g", "G", "G",/***/ + "h", "h", "H", /**/"h", "H", "H",/***/ + "j", "J", "J", /**/"j", "J", "J",/***/ + "k", "K", "K", /**/"k", "K", "K",/***/ + "l", "L", "L", /**/"l", "L", "L",/***/ + "semicolon", "colon", "semicolon", /**/";", ":", ";",/***/ + "apostrophe", "quotedbl", "apostrophe", /**/"'", "\"", "'",/***/ + "grave", "asciitilde", "grave", /**/"`", "~", "`",/***/ + "Shift_L", "Shift_L", "Shift_L", /**/"", "", "",/***/ + "backslash", "bar", "backslash", /**/"\\", "|", "\\",/***/ + "z", "Z", "Z", /**/"z", "Z", "Z",/***/ + "x", "X", "X", /**/"x", "X", "X",/***/ + "c", "C", "C", /**/"c", "C", "C",/***/ + "v", "V", "V", /**/"v", "V", "V",/***/ + "b", "B", "B", /**/"b", "B", "B",/***/ + "n", "N", "N", /**/"n", "N", "N",/***/ + "m", "M", "M", /**/"m", "M", "M",/***/ + "comma", "less", "comma", /**/",", "<", ",",/***/ + "period", "greater", "period", /**/".", ">", ".",/***/ + "slash", "question", "slash", /**/"/", "?", "/",/***/ + "Shift_R", "Shift_R", "Shift_R", /**/"", "", "",/***/ + "KP_Multiply", "KP_Multiply", "KP_Multiply", /**/"", "*", "",/***/ + "Alt_L", "Alt_L", "Alt_L", /**/"", "", "",/***/ + "space", "space", "space", /**/" ", " ", " ",/***/ + "Caps_Lock", "Caps_Lock", "Caps_Lock", /**/"", "", "",/***/ + "F1", "F1", "F1", /**/"", "", "",/***/ + "F2", "F2", "F2", /**/"", "", "",/***/ + "F3", "F3", "F3", /**/"", "", "",/***/ + "F4", "F4", "F4", /**/"", "", "",/***/ + "F5", "F5", "F5", /**/"", "", "",/***/ + "F6", "F6", "F6", /**/"", "", "",/***/ + "F7", "F7", "F7", /**/"", "", "",/***/ + "F8", "F8", "F8", /**/"", "", "",/***/ + "F9", "F9", "F9", /**/"", "", "",/***/ + "F10", "F10", "F10", /**/"", "", "",/***/ + "Num_Lock", "Num_Lock", "Num_Lock", /**/"", "", "",/***/ + "Scroll_Lock", "Scroll_Lock", "Scroll_Lock", /**/"", "", "",/***/ + "KP_Home", "KP_7", "KP_Home", /**/"", "7", "",/***/ + "KP_Up", "KP_8", "KP_Up", /**/"", "8", "",/***/ + "KP_Prior", "KP_9", "KP_Prior", /**/"", "9", "",/***/ + "KP_Subtract", "KP_Subtract", "KP_Subtract", /**/"", "", "",/***/ + "KP_Left", "KP_4", "KP_Left", /**/"", "4", "",/***/ + "KP_Begin", "KP_5", "KP_Begin", /**/"", "5", "",/***/ + "KP_Right", "KP_6", "KP_Right", /**/"", "6", "",/***/ + "KP_Add", "KP_Add", "KP_Add", /**/"", "", "",/***/ + "KP_End", "KP_1", "KP_End", /**/"", "1", "",/***/ + "KP_Down", "KP_2", "KP_Down", /**/"", "2", "",/***/ + "KP_Next", "KP_3", "KP_Next", /**/"", "3", "",/***/ + "KP_Insert", "KP_0", "KP_Insert", /**/"", "0", "",/***/ + "KP_Delete", "KP_Decimal", "KP_Delete", /**/"", ".", "",/***/ + "0x54", "0x54", "0x54", /**/"", "", "",/***/ + "0x55", "0x55", "0x55", /**/"", "", "",/***/ + "0x56", "0x56", "0x56", /**/"", "", "",/***/ + "F11", "F11", "F11", /**/"", "", "",/***/ + "F12", "F12", "F12", /**/"", "", "",/***/ + "0x59", "0x59", "0x59", /**/"", "", "",/***/ + "0x5a", "0x5a", "0x5a", /**/"", "", "",/***/ + "0x5b", "0x5b", "0x5b", /**/"", "", "",/***/ + "0x5c", "0x5c", "0x5c", /**/"", "", "",/***/ + "0x5d", "0x5d", "0x5d", /**/"", "", "",/***/ + "0x5e", "0x5e", "0x5e", /**/"", "", "",/***/ + "0x5f", "0x5f", "0x5f", /**/"", "", "",/***/ + "KP_Enter", "KP_Enter", "KP_Enter", /**/"", "", "",/***/ + "Control_R", "Control_R", "Control_R", /**/"", "", "",/***/ + "KP_Divide", "KP_Divide", "KP_Divide", /**/"", "", "",/***/ + "Print", "Print", "Print", /**/"", "", "",/***/ + "Alt_R", "Alt_R", "Alt_R", /**/"", "", "",/***/ + "0x65", "0x65", "0x65", /**/"", "", "",/***/ + "Home", "Home", "Home", /**/"", "", "",/***/ + "Up", "Up", "Up", /**/"", "", "",/***/ + "Prior", "Prior", "Prior", /**/"", "", "",/***/ + "Left", "Left", "Left", /**/"", "", "",/***/ + "Right", "Right", "Right", /**/"", "", "",/***/ + "End", "End", "End", /**/"", "", "",/***/ + "Down", "Down", "Down", /**/"", "", "",/***/ + "Next", "Next", "Next", /**/"", "", "",/***/ + "Insert", "Insert", "Insert", /**/"", "", "",/***/ + "Delete", "Delete", "Delete", /**/"\177","\177","\177",/***/ + "0x70", "0x70", "0x70", /**/"", "", "",/***/ + "0x71", "0x71", "0x71", /**/"", "", "",/***/ + "0x72", "0x72", "0x72", /**/"", "", "",/***/ + "0x73", "0x73", "0x73", /**/"", "", "",/***/ + "0x74", "0x74", "0x74", /**/"", "", "",/***/ + "0x75", "0x75", "0x75", /**/"", "", "",/***/ + "0x76", "0x76", "0x76", /**/"", "", "",/***/ + "Pause", "Pause", "Pause", /**/"", "", "",/***/ + "0x78", "0x78", "0x78", /**/"", "", "",/***/ + "0x79", "0x79", "0x79", /**/"", "", "",/***/ + "0x7a", "0x7a", "0x7a", /**/"", "", "",/***/ + "0x7b", "0x7b", "0x7b", /**/"", "", "",/***/ + "0x7c", "0x7c", "0x7c", /**/"", "", "",/***/ + "Super_L", "Super_L", "Super_L", /**/"", "", "",/***/ + "Super_R", "Super_R", "Super_R", /**/"", "", "",/***/ + "0x7f", "0x7f", "0x7f", /**/"", "", "" /***/ diff --git a/ecore/src/lib/ecore_fb/ecore_fb_private.h b/ecore/src/lib/ecore_fb/ecore_fb_private.h new file mode 100644 index 0000000..3c27a34 --- /dev/null +++ b/ecore/src/lib/ecore_fb/ecore_fb_private.h @@ -0,0 +1,30 @@ +#ifndef _ECORE_FB_PRIVATE_H +#define _ECORE_FB_PRIVATE_H + +/* hacks to stop people NEEDING #include */ +#ifndef TS_SET_CAL +#define TS_SET_CAL 0x4014660b +#endif +#ifndef TS_GET_CAL +#define TS_GET_CAL 0x8014660a +#endif +#ifndef TS_SET_BACKLIGHT +#define TS_SET_BACKLIGHT 0x40086614 +#endif +#ifndef TS_GET_BACKLIGHT +#define TS_GET_BACKLIGHT 0x80086614 +#endif +#ifndef LED_ON +#define LED_ON 0x40046605 +#endif +#ifndef TS_SET_CONTRAST +#define TS_SET_CONTRAST 0x40046615 +#endif +#ifndef TS_GET_CONTRAST +#define TS_GET_CONTRAST 0x80046615 +#endif +#ifndef FLITE_ON +#define FLITE_ON 0x40046607 +#endif + +#endif diff --git a/ecore/src/lib/ecore_file/.cvsignore b/ecore/src/lib/ecore_file/.cvsignore new file mode 100644 index 0000000..be74149 --- /dev/null +++ b/ecore/src/lib/ecore_file/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +*.lo +libecore_file.la diff --git a/ecore/src/lib/ecore_file/CVS/Entries b/ecore/src/lib/ecore_file/CVS/Entries new file mode 100644 index 0000000..5ad56ea --- /dev/null +++ b/ecore/src/lib/ecore_file/CVS/Entries @@ -0,0 +1,13 @@ +/.cvsignore/1.1/Sun Feb 20 12:17:07 2005//THEAD +/Ecore_File.h/1.13/Wed Jun 22 14:51:36 2005//THEAD +/Makefile.am/1.8/Fri Jun 17 23:52:32 2005//THEAD +/ecore_file.c/1.11/Fri Jun 17 23:52:32 2005//THEAD +/ecore_file_download.c/1.5/Wed Jun 22 14:51:37 2005//THEAD +/ecore_file_monitor.c/1.2/Wed Mar 30 06:35:12 2005//THEAD +/ecore_file_monitor_fam.c/1.4/Wed Apr 20 09:20:33 2005//THEAD +/ecore_file_monitor_inotify.c/1.4/Wed Apr 20 09:20:33 2005//THEAD +/ecore_file_monitor_poll.c/1.8/Wed Apr 20 09:20:33 2005//THEAD +/ecore_file_path.c/1.2/Sun Jun 12 14:08:46 2005//THEAD +/ecore_file_private.h/1.7/Fri Jun 17 23:52:32 2005//THEAD +/ecore_file_utils.c/1.1/Sun Feb 20 12:17:07 2005//THEAD +D diff --git a/ecore/src/lib/ecore_file/CVS/Repository b/ecore/src/lib/ecore_file/CVS/Repository new file mode 100644 index 0000000..bba5b7a --- /dev/null +++ b/ecore/src/lib/ecore_file/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/src/lib/ecore_file diff --git a/ecore/src/lib/ecore_file/CVS/Root b/ecore/src/lib/ecore_file/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/src/lib/ecore_file/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/src/lib/ecore_file/CVS/Tag b/ecore/src/lib/ecore_file/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/src/lib/ecore_file/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/src/lib/ecore_file/Ecore_File.h b/ecore/src/lib/ecore_file/Ecore_File.h new file mode 100644 index 0000000..541d51a --- /dev/null +++ b/ecore/src/lib/ecore_file/Ecore_File.h @@ -0,0 +1,91 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#ifndef ECORE_FILE_H +#define ECORE_FILE_H + +/* + * TODO: + * - More events, move/rename of directory file + */ + +#ifdef EAPI +#undef EAPI +#endif +#ifdef WIN32 +# ifdef BUILDING_DLL +# define EAPI __declspec(dllexport) +# else +# define EAPI __declspec(dllimport) +# endif +#else +# ifdef GCC_HASCLASSVISIBILITY +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct _Ecore_File_Monitor Ecore_File_Monitor; + typedef struct _Ecore_File_Monitor_Event Ecore_File_Monitor_Event; + + typedef enum + { + ECORE_FILE_EVENT_NONE, + ECORE_FILE_EVENT_CREATED_FILE, + ECORE_FILE_EVENT_CREATED_DIRECTORY, + ECORE_FILE_EVENT_DELETED_FILE, + ECORE_FILE_EVENT_DELETED_DIRECTORY, + ECORE_FILE_EVENT_DELETED_SELF, + ECORE_FILE_EVENT_MODIFIED + } Ecore_File_Event; + + + EAPI int ecore_file_init (void); + EAPI int ecore_file_shutdown (void); + EAPI time_t ecore_file_mod_time (const char *file); + EAPI int ecore_file_exists (const char *file); + EAPI int ecore_file_is_dir (const char *file); + EAPI int ecore_file_mkdir (const char *dir); + EAPI int ecore_file_rmdir (const char *dir); + EAPI int ecore_file_mkpath (const char *path); + EAPI int ecore_file_cp (const char *src, const char *dst); + EAPI int ecore_file_mv (const char *src, const char *dst); + EAPI char *ecore_file_realpath (const char *file); + EAPI int ecore_file_unlink (const char *file); + EAPI char *ecore_file_get_file (char *path); + EAPI char *ecore_file_get_dir (char *path); + + EAPI int ecore_file_can_exec (const char *file); + EAPI char *ecore_file_readlink (const char *link); + EAPI Ecore_List *ecore_file_ls (const char *dir); + + EAPI Ecore_File_Monitor *ecore_file_monitor_add(const char *path, + void (*func) (void *data, + Ecore_File_Monitor *ecore_file_monitor, + Ecore_File_Event event, + const char *path), + void *data); + EAPI void ecore_file_monitor_del(Ecore_File_Monitor *ecore_file_monitor); + EAPI const char *ecore_file_monitor_path_get(Ecore_File_Monitor *ecore_file_monitor); + + EAPI int ecore_file_app_installed(const char *app); + + EAPI int ecore_file_download(const char *url, const char *dst, + void (*completion_cb)(void *data, + const char *file, + int status), + void *data); + EAPI int ecore_file_download_protocol_available(const char *protocol); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ecore/src/lib/ecore_file/Makefile.am b/ecore/src/lib/ecore_file/Makefile.am new file mode 100644 index 0000000..6aceac6 --- /dev/null +++ b/ecore/src/lib/ecore_file/Makefile.am @@ -0,0 +1,40 @@ +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore \ +@curl_cflags@ + +libecore_file_la_LDFLAGS = -version-info 1:0:0 \ +-L$(top_builddir)/src/lib/ecore/.libs + +if BUILD_ECORE_FILE + +lib_LTLIBRARIES = libecore_file.la +include_HEADERS = Ecore_File.h + +libecore_file_la_SOURCES = \ +ecore_file.c \ +ecore_file_private.h \ +ecore_file_monitor.c \ +ecore_file_monitor_fam.c \ +ecore_file_monitor_inotify.c \ +ecore_file_monitor_poll.c \ +ecore_file_path.c \ +ecore_file_download.c + +libecore_file_la_LIBADD = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +@fam_libs@ @curl_libs@ + +endif + +EXTRA_DIST = \ +ecore_file.c \ +ecore_file_private.h \ +ecore_file_monitor.c \ +ecore_file_monitor_fam.c \ +ecore_file_monitor_inotify.c \ +ecore_file_monitor_poll.c \ +ecore_file_path.c + diff --git a/ecore/src/lib/ecore_file/ecore_file.c b/ecore/src/lib/ecore_file/ecore_file.c new file mode 100644 index 0000000..e71fc19 --- /dev/null +++ b/ecore/src/lib/ecore_file/ecore_file.c @@ -0,0 +1,257 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "ecore_file_private.h" + +/* externally accessible functions */ +int +ecore_file_init() +{ + if (!ecore_file_monitor_init()) + return 0; + if (!ecore_file_path_init()) + return 0; + if (!ecore_file_download_init()) + return 0; + return 1; +} + +int +ecore_file_shutdown() +{ + if (!ecore_file_monitor_shutdown()) + return 0; + if (!ecore_file_path_shutdown()) + return 0; + if (!ecore_file_download_shutdown()) + return 0; + return 1; +} + +time_t +ecore_file_mod_time(const char *file) +{ + struct stat st; + + if (stat(file, &st) < 0) return 0; + return st.st_mtime; +} + +int +ecore_file_exists(const char *file) +{ + struct stat st; + + if (stat(file, &st) < 0) return 0; + return 1; +} + +int +ecore_file_is_dir(const char *file) +{ + struct stat st; + + if (stat(file, &st) < 0) return 0; + if (S_ISDIR(st.st_mode)) return 1; + return 0; +} + +static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + +int +ecore_file_mkdir(const char *dir) +{ + if (mkdir(dir, default_mode) < 0) return 0; + return 1; +} + +int +ecore_file_rmdir(const char *dir) +{ + if (rmdir(dir) < 0) return 0; + return 1; +} + +int +ecore_file_unlink(const char *file) +{ + if (unlink(file) < 0) return 0; + return 1; +} + +int +ecore_file_mkpath(const char *path) +{ + char ss[PATH_MAX]; + int i; + + ss[0] = 0; + i = 0; + while (path[i]) + { + if (i == sizeof(ss) - 1) return 0; + ss[i] = path[i]; + ss[i + 1] = 0; + if (path[i] == '/') + { + ss[i] = 0; + if ((ecore_file_exists(ss)) && (!ecore_file_is_dir(ss))) return 0; + else if (!ecore_file_exists(ss)) ecore_file_mkdir(ss); + ss[i] = '/'; + } + i++; + } + if ((ecore_file_exists(ss)) && (!ecore_file_is_dir(ss))) return 0; + else if (!ecore_file_exists(ss)) ecore_file_mkdir(ss); + return 1; +} + +int +ecore_file_cp(const char *src, const char *dst) +{ + FILE *f1, *f2; + char buf[16384]; + size_t num; + + f1 = fopen(src, "rb"); + if (!f1) return 0; + f2 = fopen(dst, "wb"); + if (!f2) + { + fclose(f1); + return 0; + } + while ((num = fread(buf, 1, 16384, f1)) > 0) fwrite(buf, 1, num, f2); + fclose(f1); + fclose(f2); + return 1; +} + +int +ecore_file_mv(const char *src, const char *dst) +{ + if (ecore_file_exists(dst)) return 0; + if (rename(src, dst)) return 0; + return 1; +} + +char * +ecore_file_realpath(const char *file) +{ + char buf[PATH_MAX]; + struct stat st; + + if (!realpath(file, buf) || stat(buf, &st)) return strdup(""); + return strdup(buf); +} + +char * +ecore_file_get_file(char *path) +{ + char *result = NULL; + + if (!path) return NULL; + if ((result = strrchr(path, '/'))) result++; + else result = path; + return result; +} + +char * +ecore_file_get_dir(char *file) +{ + char *p; + char buf[PATH_MAX]; + + strncpy(buf, file, PATH_MAX); + p = strrchr(buf, '/'); + if (!p) + { + return strdup(file); + } + *p = 0; + return strdup(buf); +} + +int +ecore_file_can_exec(const char *file) +{ + static int have_uid = 0; + static uid_t uid = -1; + static gid_t gid = -1; + struct stat st; + int ok; + + if (!file) return 0; + if (stat(file, &st) < 0) return 0; + + ok = 0; + if (!have_uid) uid = getuid(); + if (!have_uid) gid = getgid(); + have_uid = 1; + if (st.st_uid == uid) + { + if (st.st_mode & S_IXUSR) ok = 1; + } + else if (st.st_gid == gid) + { + if (st.st_mode & S_IXGRP) ok = 1; + } + else + { + if (st.st_mode & S_IXOTH) ok = 1; + } + return(ok); +} + +char * +ecore_file_readlink(const char *link) +{ + char buf[PATH_MAX]; + int count; + + if ((count = readlink(link, buf, sizeof(buf))) < 0) return NULL; + buf[count] = 0; + return strdup(buf); +} + +Ecore_List * +ecore_file_ls(const char *dir) +{ + DIR *dirp; + struct dirent *dp; + Ecore_List *list; + + dirp = opendir(dir); + if (!dirp) return NULL; + list = ecore_list_new(); + while ((dp = readdir(dirp))) + { + if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, ".."))) + { + char *file, *f; + + /* insertion sort */ + ecore_list_goto_first(list); + while ((file = ecore_list_current(list))) + { + if (strcmp(file, dp->d_name) > 0) + { + f = strdup(dp->d_name); + ecore_list_insert(list, f); + break; + } + ecore_list_next(list); + } + /* nowhwre to go? just append it */ + if (!file) + { + f = strdup(dp->d_name); + ecore_list_append(list, f); + } + } + } + closedir(dirp); + + ecore_list_goto_first(list); + return list; +} diff --git a/ecore/src/lib/ecore_file/ecore_file_download.c b/ecore/src/lib/ecore_file/ecore_file_download.c new file mode 100644 index 0000000..500a051 --- /dev/null +++ b/ecore/src/lib/ecore_file/ecore_file_download.c @@ -0,0 +1,292 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "ecore_file_private.h" + +#ifdef HAVE_CURL +#include + +typedef struct _Ecore_File_Download_Job Ecore_File_Download_Job; + +struct _Ecore_File_Download_Job +{ + Ecore_Fd_Handler *fd_handler; + CURL *curl; + void (*completion_cb)(void *data, const char *file, int status); + void *data; + FILE *file; + char *dst; +}; + +Ecore_File_Download_Job *_ecore_file_download_curl(const char *url, const char *dst, + void (*completion_cb)(void *data, const char *file, int status), + void *data); +static int _ecore_file_download_curl_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); + +static CURLM *curlm; +static Ecore_List *_job_list; +static fd_set _current_fd_set; +#endif + +int +ecore_file_download_init(void) +{ +#ifdef HAVE_CURL + FD_ZERO(&_current_fd_set); + _job_list = ecore_list_new(); + if (!_job_list) return 0; + + if (curl_global_init(CURL_GLOBAL_NOTHING)) return 0; + + curlm = curl_multi_init(); + if (!curlm) + { + ecore_list_destroy(_job_list); + _job_list = NULL; + return 0; + } +#endif + return 1; +} + +int +ecore_file_download_shutdown(void) +{ +#ifdef HAVE_CURL + Ecore_File_Download_Job *job; + + if (!ecore_list_is_empty(_job_list)) + { + ecore_list_goto_first(_job_list); + while ((job = ecore_list_next(_job_list))) + { + ecore_main_fd_handler_del(job->fd_handler); + curl_multi_remove_handle(curlm, job->curl); + curl_easy_cleanup(job->curl); + fclose(job->file); + free(job->dst); + free(job); + } + } + ecore_list_destroy(_job_list); + curl_multi_cleanup(curlm); + curl_global_cleanup(); +#endif + return 1; +} + +int +ecore_file_download(const char *url, const char *dst, + void (*completion_cb)(void *data, const char *file, int status), + void *data) +{ + if (!ecore_file_is_dir(ecore_file_get_dir(dst))) return 0; + if (ecore_file_exists(dst)) return 0; + + /* FIXME: Add handlers for http and ftp! */ + if (!strncmp(url, "file://", 7)) + { + /* FIXME: Maybe fork? Might take a while to copy. + * Check filesize? */ + /* Just copy it */ + + url += 7; + /* skip hostname */ + url = strchr(url, '/'); + return ecore_file_cp(url, dst); + } +#ifdef HAVE_CURL + else if ((!strncmp(url, "http://", 7)) || + (!strncmp(url, "ftp://", 6))) + { + /* download */ + Ecore_File_Download_Job *job; + + job = _ecore_file_download_curl(url, dst, completion_cb, data); + if (job) + return 1; + else + return 0; + } +#endif + else + { + return 0; + } +} + +int +ecore_file_download_protocol_available(const char *protocol) +{ + if (!strncmp(protocol, "file://", 7)) return 1; +#ifdef HAVE_CURL + else if (!strncmp(protocol, "http://", 7)) return 1; + else if (!strncmp(protocol, "ftp://", 6)) return 1; +#endif + + return 0; +} + +#ifdef HAVE_CURL +/* + * FIXME: Use + * CURLOPT_PROGRESSFUNCTION and CURLOPT_PROGRESSDATA to + * get reports on progress. + * And maybe other nifty functions... + */ +Ecore_File_Download_Job * +_ecore_file_download_curl(const char *url, const char *dst, + void (*completion_cb)(void *data, const char *file, + int status), + void *data) +{ + CURLMsg *curlmsg; + fd_set read_set, write_set, exc_set; + int fd_max; + int fd; + int flags; + int n_remaining, still_running; + Ecore_File_Download_Job *job; + + job = calloc(1, sizeof(Ecore_File_Download_Job)); + if (!job) return NULL; + + job->file = fopen(dst, "wb"); + if (!job->file) + { + free(job); + return NULL; + } + job->curl = curl_easy_init(); + if (!job->curl) + { + fclose(job->file); + free(job); + return NULL; + } + curl_easy_setopt(job->curl, CURLOPT_URL, url); + curl_easy_setopt(job->curl, CURLOPT_WRITEDATA, job->file); + + job->data = data; + job->completion_cb = completion_cb; + job->dst = strdup(dst); + ecore_list_append(_job_list, job); + + curl_multi_add_handle(curlm, job->curl); + while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM); + + /* check for completed jobs */ + while ((curlmsg = curl_multi_info_read(curlm, &n_remaining)) != NULL) + { + Ecore_File_Download_Job *current; + + if (curlmsg->msg != CURLMSG_DONE) continue; + + /* find the job which is done */ + ecore_list_goto_first(_job_list); + while ((current = ecore_list_current(_job_list))) + { + if (curlmsg->easy_handle == current->curl) + { + /* We have a match -- delete the job */ + if (current == job) + job = NULL; + if (current->fd_handler) + { + FD_CLR(ecore_main_fd_handler_fd_get(current->fd_handler), + &_current_fd_set); + ecore_main_fd_handler_del(current->fd_handler); + } + ecore_list_remove(_job_list); + curl_multi_remove_handle(curlm, current->curl); + curl_easy_cleanup(current->curl); + fclose(current->file); + if (current->completion_cb) + current->completion_cb(current->data, current->dst, + curlmsg->data.result); + free(current->dst); + free(current); + break; + } + ecore_list_next(_job_list); + } + } + + if (job) + { + FD_ZERO(&read_set); + FD_ZERO(&write_set); + FD_ZERO(&exc_set); + + /* Stupid curl, why can't I get the fd to the current added job? */ + curl_multi_fdset(curlm, &read_set, &write_set, &exc_set, &fd_max); + for (fd = 0; fd <= fd_max; fd++) + { + if (!FD_ISSET(fd, &_current_fd_set)) + { + flags = 0; + if (FD_ISSET(fd, &read_set)) flags |= ECORE_FD_READ; + if (FD_ISSET(fd, &write_set)) flags |= ECORE_FD_WRITE; + if (FD_ISSET(fd, &exc_set)) flags |= ECORE_FD_ERROR; + if (flags) + { + FD_SET(fd, &_current_fd_set); + job->fd_handler = ecore_main_fd_handler_add(fd, flags, + _ecore_file_download_curl_fd_handler, + NULL, NULL, NULL); + } + } + } + if (!job->fd_handler) + { + curl_easy_cleanup(job->curl); + fclose(job->file); + free(job); + job = NULL; + } + } + + return job; +} + +static int +_ecore_file_download_curl_fd_handler(void *data, Ecore_Fd_Handler *fd_handler) +{ + Ecore_File_Download_Job *job; + CURLMsg *curlmsg; + int n_remaining, still_running; + + /* FIXME: Can this run for a long time? Maybe limit how long it can run */ + while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM); + + /* Loop jobs and check if any are done */ + while ((curlmsg = curl_multi_info_read(curlm, &n_remaining)) != NULL) + { + if (curlmsg->msg != CURLMSG_DONE) continue; + + /* find the job which is done */ + ecore_list_goto_first(_job_list); + while ((job = ecore_list_current(_job_list))) + { + if (curlmsg->easy_handle == job->curl) + { + /* We have a match -- delete the job */ + FD_CLR(ecore_main_fd_handler_fd_get(job->fd_handler), + &_current_fd_set); + ecore_list_remove(_job_list); + ecore_main_fd_handler_del(job->fd_handler); + curl_multi_remove_handle(curlm, job->curl); + curl_easy_cleanup(job->curl); + fclose(job->file); + if (job->completion_cb) + job->completion_cb(job->data, job->dst, !curlmsg->data.result); + free(job->dst); + free(job); + break; + } + ecore_list_next(_job_list); + } + } + return 1; +} +#endif diff --git a/ecore/src/lib/ecore_file/ecore_file_monitor.c b/ecore/src/lib/ecore_file/ecore_file_monitor.c new file mode 100644 index 0000000..e270e01 --- /dev/null +++ b/ecore/src/lib/ecore_file/ecore_file_monitor.c @@ -0,0 +1,126 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "ecore_file_private.h" + +typedef enum { + ECORE_FILE_MONITOR_TYPE_NONE, +#ifdef HAVE_INOTIFY + ECORE_FILE_MONITOR_TYPE_INOTIFY, +#endif +#ifdef HAVE_FAM + ECORE_FILE_MONITOR_TYPE_FAM, +#endif +#ifdef HAVE_POLL + ECORE_FILE_MONITOR_TYPE_POLL +#endif +} Ecore_File_Monitor_Type; + +static Ecore_File_Monitor_Type monitor_type = ECORE_FILE_MONITOR_TYPE_NONE; + +int +ecore_file_monitor_init(void) +{ +#ifdef HAVE_INOTIFY +#if 0 + monitor_type = ECORE_FILE_MONITOR_TYPE_INOTIFY; + if (ecore_file_monitor_inotify_init()) + return 1; +#endif +#endif +#ifdef HAVE_FAM +#if 0 + monitor_type = ECORE_FILE_MONITOR_TYPE_FAM; + if (ecore_file_monitor_fam_init()) + return 1; +#endif +#endif +#ifdef HAVE_POLL + monitor_type = ECORE_FILE_MONITOR_TYPE_POLL; + if (ecore_file_monitor_poll_init()) + return 1; +#endif + monitor_type = ECORE_FILE_MONITOR_TYPE_NONE; + return 0; +} + +int +ecore_file_monitor_shutdown(void) +{ + switch (monitor_type) + { + case ECORE_FILE_MONITOR_TYPE_NONE: + return 1; +#ifdef HAVE_INOTIFY + case ECORE_FILE_MONITOR_TYPE_INOTIFY: + return ecore_file_monitor_inotify_shutdown(); +#endif +#ifdef HAVE_FAM + case ECORE_FILE_MONITOR_TYPE_FAM: + return ecore_file_monitor_fam_shutdown(); +#endif +#ifdef HAVE_POLL + case ECORE_FILE_MONITOR_TYPE_POLL: + return ecore_file_monitor_poll_shutdown(); +#endif + } + return 0; +} + +Ecore_File_Monitor * +ecore_file_monitor_add(const char *path, + void (*func) (void *data, Ecore_File_Monitor *em, + Ecore_File_Event event, + const char *path), + void *data) +{ + switch (monitor_type) + { + case ECORE_FILE_MONITOR_TYPE_NONE: + return NULL; +#ifdef HAVE_INOTIFY + case ECORE_FILE_MONITOR_TYPE_INOTIFY: + return ecore_file_monitor_inotify_add(path, func, data); +#endif +#ifdef HAVE_FAM + case ECORE_FILE_MONITOR_TYPE_FAM: + return ecore_file_monitor_fam_add(path, func, data); +#endif +#ifdef HAVE_POLL + case ECORE_FILE_MONITOR_TYPE_POLL: + return ecore_file_monitor_poll_add(path, func, data); +#endif + } + return NULL; +} + +void +ecore_file_monitor_del(Ecore_File_Monitor *em) +{ + switch (monitor_type) + { + case ECORE_FILE_MONITOR_TYPE_NONE: + break; +#ifdef HAVE_INOTIFY + case ECORE_FILE_MONITOR_TYPE_INOTIFY: + ecore_file_monitor_inotify_del(em); + break; +#endif +#ifdef HAVE_FAM + case ECORE_FILE_MONITOR_TYPE_FAM: + ecore_file_monitor_fam_del(em); + break; +#endif +#ifdef HAVE_POLL + case ECORE_FILE_MONITOR_TYPE_POLL: + ecore_file_monitor_poll_del(em); + break; +#endif + } +} + +const char * +ecore_file_monitor_path_get(Ecore_File_Monitor *em) +{ + return em->path; +} diff --git a/ecore/src/lib/ecore_file/ecore_file_monitor_fam.c b/ecore/src/lib/ecore_file/ecore_file_monitor_fam.c new file mode 100644 index 0000000..ffdfe7d --- /dev/null +++ b/ecore/src/lib/ecore_file/ecore_file_monitor_fam.c @@ -0,0 +1,305 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "ecore_file_private.h" + +/* + * TODO: + * - When several subdirectories are created really fast, the code + * doesn't keep up! + * - Same for deletion of files in deleted directories! + */ + +#ifdef HAVE_FAM + +#include + +typedef struct _Ecore_File_Monitor_Fam Ecore_File_Monitor_Fam; +typedef struct _Ecore_File Ecore_File; + +#define ECORE_FILE_MONITOR_FAM(x) ((Ecore_File_Monitor_Fam *)(x)) + +struct _Ecore_File_Monitor_Fam +{ + Ecore_File_Monitor monitor; + FAMRequest *request; +}; + +struct _Ecore_File +{ + Ecore_Oldlist __list_data; + char *name; +}; + +static Ecore_Fd_Handler *_fdh = NULL; +static FAMConnection *_fc = NULL; +static Ecore_Oldlist *_monitors = NULL; + +static int _ecore_file_monitor_fam_handler(void *data, Ecore_Fd_Handler *fdh); +static Ecore_File *_ecore_file_monitor_fam_file_find(Ecore_File_Monitor *em, char *name); +static Ecore_File_Event _ecore_file_monitor_fam_event_get(FAMCodes code, int self, int is_dir); + +int +ecore_file_monitor_fam_init(void) +{ + _fc = calloc(1, sizeof(FAMConnection)); + if (!_fc) return 0; + + FAMOpen(_fc); + _fdh = ecore_main_fd_handler_add(FAMCONNECTION_GETFD(_fc), ECORE_FD_READ, + _ecore_file_monitor_fam_handler, NULL, NULL, NULL); + + return 1; +} + +int +ecore_file_monitor_fam_shutdown(void) +{ + Ecore_Oldlist *l; + + for (l = _monitors; l;) + { + Ecore_File_Monitor *em; + + em = ECORE_FILE_MONITOR(l); + l = l->next; + ecore_file_monitor_fam_del(em); + } + if (_fdh) ecore_main_fd_handler_del(_fdh); + if (_fc) + { + FAMClose(_fc); + free(_fc); + } + return 1; +} + +Ecore_File_Monitor * +ecore_file_monitor_fam_add(const char *path, + void (*func) (void *data, + Ecore_File_Monitor *em, + Ecore_File_Event event, + const char *path), + void *data) +{ + Ecore_File_Monitor *em; + int len; + + em = calloc(1, sizeof(Ecore_File_Monitor_Fam)); + if (!em) return NULL; + + em->func = func; + em->data = data; + + em->path = strdup(path); + len = strlen(em->path); + if (em->path[len - 1] == '/') + em->path[len - 1] = 0; + + if (ecore_file_exists(em->path)) + { + ECORE_FILE_MONITOR_FAM(em)->request = calloc(1, sizeof(FAMRequest)); + if (!ECORE_FILE_MONITOR_FAM(em)->request) + { + ecore_file_monitor_fam_del(em); + return NULL; + } + if (ecore_file_is_dir(em->path)) + { + FAMMonitorDirectory(_fc, em->path, ECORE_FILE_MONITOR_FAM(em)->request, em); + } + else + { + FAMMonitorFile(_fc, em->path, ECORE_FILE_MONITOR_FAM(em)->request, em); + } + } + else + { + ecore_file_monitor_fam_del(em); + return NULL; + } + + _monitors = _ecore_list_append(_monitors, em); + + return em; +} + +void +ecore_file_monitor_fam_del(Ecore_File_Monitor *em) +{ + Ecore_Oldlist *l; + + for (l = em->files; l; l = l->next) + { + Ecore_File *f; + + f = (Ecore_File *)l; + free(f->name); + free(f); + } + + _monitors = _ecore_list_remove(_monitors, em); + + if (ECORE_FILE_MONITOR_FAM(em)->request) + { + FAMCancelMonitor(_fc, ECORE_FILE_MONITOR_FAM(em)->request); + free(ECORE_FILE_MONITOR_FAM(em)->request); + } + free(em->path); + free(em); +} + +static int +_ecore_file_monitor_fam_handler(void *data, Ecore_Fd_Handler *fdh) +{ + int pending, i; + + while ((pending = FAMPending(_fc))) + { + for (i = 0; i < pending; i++) + { + Ecore_File_Monitor *em; + FAMEvent fe; + Ecore_File_Event event; + char buf[PATH_MAX]; + int len, self; + + buf[0] = 0; + + FAMNextEvent(_fc, &fe); + len = strlen(fe.filename); + if (fe.filename[len - 1] == '/') + fe.filename[len - 1] = 0; + self = !strcmp(em->path, fe.filename); + if (!self) + snprintf(buf, sizeof(buf), "%s/%s", em->path, fe.filename); + + event = _ecore_file_monitor_fam_event_get(fe.code, self, ecore_file_is_dir(buf)); + em = fe.userdata; + if (!em) continue; + if (event == ECORE_FILE_EVENT_NONE) continue; +#if 0 + if (!strcmp(em->path, fe.filename)) + { + Evas_List *l; + + if (event == ECORE_FILE_EVENT_DELETED) + { + /* Notify all files deleted */ + for (l = em->files; l;) + { + Ecore_File *f; + char buf[PATH_MAX]; + + f = l->data; + l = l->next; + snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name); + em->func(em->data, em, f->type, ECORE_FILE_EVENT_DELETED, buf); + free(f->name); + free(f); + } + em->files = evas_list_free(em->files); + em->func(em->data, em, em->type, event, em->path); + em->type = ECORE_FILE_TYPE_NONE; + } + else + { + em->func(em->data, em, em->type, event, em->path); + } + } + else + { + Ecore_File *f; + + switch (event) + { + case ECORE_FILE_EVENT_NONE: + break; + case ECORE_FILE_EVENT_EXISTS: + f = _ecore_file_monitor_fam_file_find(em, fe.filename); + if (f) + { + em->func(em->data, em, f->type, event, buf); + break; + } + case ECORE_FILE_EVENT_CREATED: + f = calloc(1, sizeof(Ecore_File)); + if (!f) break; + + f->type = ecore_file_is_dir(buf) ? + ECORE_FILE_TYPE_DIRECTORY : + ECORE_FILE_TYPE_FILE; + f->name = strdup(fe.filename); + em->files = evas_list_append(em->files, f); + em->func(em->data, em, f->type, event, buf); + break; + case ECORE_FILE_EVENT_DELETED: + f = _ecore_file_monitor_fam_file_find(em, fe.filename); + if (f) + { + em->files = evas_list_remove(em->files, f); + em->func(em->data, em, f->type, event, buf); + free(f->name); + free(f); + } + break; + case ECORE_FILE_EVENT_CHANGED: + em->func(em->data, em, f->type, event, buf); + break; + } + } +#endif + } + } + return 1; +} + +static Ecore_File * +_ecore_file_monitor_fam_file_find(Ecore_File_Monitor *em, char *name) +{ + for (l = em->files; l; l = l->next) + { + Ecore_File *f; + f = l->data; + if (!strcmp(f->name, name)) + return f; + } + return NULL; +} + +static Ecore_File_Event +_ecore_file_monitor_fam_event_get(FAMCodes code, int self, int is_dir) +{ + switch (code) + { + case FAMCreated: + if (self) + return ECORE_FILE_EVENT_NONE; + else if (is_dir) + return ECORE_FILE_EVENT_CREATED_DIRECTORY; + else + return ECORE_FILE_EVENT_CREATED_FILE; + break; + case FAMDeleted: + if (self) + return ECORE_FILE_EVENT_DELETED_SELF; + else if (is_dir) + return ECORE_FILE_EVENT_DELETED_DIRECTORY; + else + return ECORE_FILE_EVENT_DELETED_FILE; + break; + case FAMChanged: + if (!is_dir) + return ECORE_FILE_EVENT_MODIFIED; + break; + case FAMExists: + case FAMStartExecuting: + case FAMStopExecuting: + case FAMMoved: + case FAMAcknowledge: + case FAMEndExist: + return ECORE_FILE_EVENT_NONE; + } + return ECORE_FILE_EVENT_NONE; +} +#endif diff --git a/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c b/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c new file mode 100644 index 0000000..1f8c34f --- /dev/null +++ b/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c @@ -0,0 +1,235 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "ecore_file_private.h" + +/* + * TODO: + */ + +#ifdef HAVE_INOTIFY + +#include +#include +#include +#include +#include + +typedef struct _Ecore_File_Monitor_Inotify Ecore_File_Monitor_Inotify; + +#define ECORE_FILE_MONITOR_INOTIFY(x) ((Ecore_File_Monitor_Inotify *)(x)) + +struct _Ecore_File_Monitor_Inotify +{ + Ecore_File_Monitor monitor; + int wd; +}; + +static Ecore_Fd_Handler *_fdh = NULL; +static Ecore_Oldlist *_monitors = NULL; + +static int _ecore_file_monitor_inotify_handler(void *data, Ecore_Fd_Handler *fdh); +static Ecore_File_Monitor *_ecore_file_monitor_inotify_monitor_find(int wd); +static void _ecore_file_monitor_inotify_events(Ecore_File_Monitor *em, + char *file, int mask); + +int +ecore_file_monitor_inotify_init(void) +{ + int fd; + + fd = open("/dev/inotify", O_RDONLY); + if (fd < 0) + return 0; + + _fdh = ecore_main_fd_handler_add(fd, ECORE_FD_READ, _ecore_file_monitor_inotify_handler, + NULL, NULL, NULL); + if (!_fdh) + { + close(fd); + return 0; + } + + return 1; +} + +int +ecore_file_monitor_inotify_shutdown(void) +{ + int fd; + Ecore_Oldlist *l; + + for (l = _monitors; l;) + { + Ecore_File_Monitor *em; + + em = ECORE_FILE_MONITOR(l); + l = l->next; + ecore_file_monitor_inotify_del(em); + } + + if (_fdh) + { + fd = ecore_main_fd_handler_fd_get(_fdh); + ecore_main_fd_handler_del(_fdh); + close(fd); + } + return 1; +} + +Ecore_File_Monitor * +ecore_file_monitor_inotify_add(const char *path, + void (*func) (void *data, Ecore_File_Monitor *em, + Ecore_File_Event event, + const char *path), + void *data) +{ + Ecore_File_Monitor *em; + int len; + + em = calloc(1, sizeof(Ecore_File_Monitor_Inotify)); + if (!em) return NULL; + + em->func = func; + em->data = data; + + em->path = strdup(path); + len = strlen(em->path); + if (em->path[len - 1] == '/') + em->path[len - 1] = 0; + + if (ecore_file_exists(em->path)) + { + struct inotify_watch_request request; + + request.name = em->path; + request.mask = IN_MODIFY| + IN_MOVED_FROM|IN_MOVED_TO| + IN_DELETE_SUBDIR|IN_DELETE_FILE| + IN_CREATE_SUBDIR|IN_CREATE_FILE| + IN_DELETE_SELF|IN_UNMOUNT; + ECORE_FILE_MONITOR_INOTIFY(em)->wd = ioctl(ecore_main_fd_handler_fd_get(_fdh), + INOTIFY_WATCH, &request); + if (ECORE_FILE_MONITOR_INOTIFY(em)->wd < 0) + { + printf("ioctl error\n"); + ecore_file_monitor_inotify_del(em); + return NULL; + } + } + else + { + ecore_file_monitor_inotify_del(em); + return NULL; + } + + _monitors = _ecore_list_append(_monitors, em); + + return em; +} + +void +ecore_file_monitor_inotify_del(Ecore_File_Monitor *em) +{ + int fd; + + _monitors = _ecore_list_remove(_monitors, em); + + fd = ecore_main_fd_handler_fd_get(_fdh); + if (ECORE_FILE_MONITOR_INOTIFY(em)->wd) + ioctl(fd, INOTIFY_IGNORE, ECORE_FILE_MONITOR_INOTIFY(em)->wd); + free(em->path); + free(em); +} + +static int +_ecore_file_monitor_inotify_handler(void *data, Ecore_Fd_Handler *fdh) +{ + Ecore_File_Monitor *em; + char buffer[16384]; + struct inotify_event *event; + int i = 0; + int event_size; + ssize_t size; + + size = read(ecore_main_fd_handler_fd_get(fdh), buffer, sizeof(buffer)); + while (i < size) + { + event = (struct inotify_event *)&buffer[i]; + event_size = sizeof(struct inotify_event) + event->len; + i += event_size; + + em = _ecore_file_monitor_inotify_monitor_find(event->wd); + if (!em) continue; + + _ecore_file_monitor_inotify_events(em, event->name, event->mask); + } + + return 1; +} + +static Ecore_File_Monitor * +_ecore_file_monitor_inotify_monitor_find(int wd) +{ + Ecore_Oldlist *l; + + for (l = _monitors; l; l = l->next) + { + Ecore_File_Monitor *em; + + em = ECORE_FILE_MONITOR(l); + + if (ECORE_FILE_MONITOR_INOTIFY(em)->wd == wd) + return em; + } + return NULL; +} + +static void +_ecore_file_monitor_inotify_events(Ecore_File_Monitor *em, char *file, int mask) +{ + char buf[PATH_MAX]; + if (file) + snprintf(buf, sizeof(buf), "%s/%s", em->path, file); + else + strcpy(buf, em->path); + + if (mask & IN_MODIFY) + { + if (!ecore_file_is_dir(buf)) + em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf); + } + if (mask & IN_MOVED_FROM) + { + printf("MOVE_FROM "); + } + if (mask & IN_MOVED_TO) + { + printf("MOVE_TO "); + } + if (mask & IN_DELETE_SUBDIR) + { + em->func(em->data, em, ECORE_FILE_EVENT_DELETED_DIRECTORY, buf); + } + if (mask & IN_DELETE_FILE) + { + em->func(em->data, em, ECORE_FILE_EVENT_DELETED_FILE, buf); + } + if (mask & IN_CREATE_SUBDIR) + { + em->func(em->data, em, ECORE_FILE_EVENT_CREATED_DIRECTORY, buf); + } + if (mask & IN_CREATE_FILE) + { + em->func(em->data, em, ECORE_FILE_EVENT_CREATED_FILE, buf); + } + if (mask & IN_DELETE_SELF) + { + em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path); + } + if (mask & IN_UNMOUNT) + { + printf("UNMOUNT "); + } +} +#endif diff --git a/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c b/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c new file mode 100644 index 0000000..420084c --- /dev/null +++ b/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c @@ -0,0 +1,357 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "ecore_private.h" +#include "ecore_file_private.h" + +#ifdef HAVE_POLL + +/* + * TODO: + * - Implement recursive as an option! + * - Keep whole path or just name of file? (Memory or CPU...) + * - Remove requests without files? + * - Change poll time + */ + +typedef struct _Ecore_File_Monitor_Poll Ecore_File_Monitor_Poll; +typedef struct _Ecore_File Ecore_File; + +#define ECORE_FILE_MONITOR_POLL(x) ((Ecore_File_Monitor_Poll *)(x)) + +struct _Ecore_File_Monitor_Poll +{ + Ecore_File_Monitor monitor; + int mtime; + unsigned char deleted; +}; + +struct _Ecore_File +{ + Ecore_Oldlist __list_data; + char *name; + int mtime; + unsigned char is_dir; +}; + +#define ECORE_FILE_INTERVAL_MIN 1.0 +#define ECORE_FILE_INTERVAL_STEP 0.5 +#define ECORE_FILE_INTERVAL_MAX 5.0 + +static double _interval = ECORE_FILE_INTERVAL_MIN; +static Ecore_Timer *_timer = NULL; +static Ecore_Oldlist *_monitors = NULL; +static int _lock = 0; + +static int _ecore_file_monitor_poll_handler(void *data); +static void _ecore_file_monitor_poll_check(Ecore_File_Monitor *em); +static int _ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name); + +int +ecore_file_monitor_poll_init(void) +{ + return 1; +} + +int +ecore_file_monitor_poll_shutdown(void) +{ + Ecore_Oldlist *l; + + for (l = _monitors; l;) + { + Ecore_File_Monitor *em; + + em = ECORE_FILE_MONITOR(l); + l = l->next; + ecore_file_monitor_poll_del(em); + } + + if (_timer) + { + ecore_timer_del(_timer); + _timer = NULL; + } + return 1; +} + +Ecore_File_Monitor * +ecore_file_monitor_poll_add(const char *path, + void (*func) (void *data, Ecore_File_Monitor *em, + Ecore_File_Event event, + const char *path), + void *data) +{ + Ecore_File_Monitor *em; + int len; + + if (!path) return NULL; + if (!func) return NULL; + + em = calloc(1, sizeof(Ecore_File_Monitor_Poll)); + if (!em) return NULL; + + if (!_timer) + _timer = ecore_timer_add(_interval, _ecore_file_monitor_poll_handler, NULL); + else + ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN); + + em->path = strdup(path); + len = strlen(em->path); + if (em->path[len - 1] == '/') + em->path[len - 1] = 0; + + em->func = func; + em->data = data; + + ECORE_FILE_MONITOR_POLL(em)->mtime = ecore_file_mod_time(em->path); + if (ecore_file_exists(em->path)) + { + if (ecore_file_is_dir(em->path)) + { + /* Check for subdirs */ + Ecore_List *files; + char *file; + + files = ecore_file_ls(em->path); + if (files) + { + while ((file = ecore_list_next(files))) + { + Ecore_File *f; + char buf[PATH_MAX]; + + f = calloc(1, sizeof(Ecore_File)); + if (!f) + { + free(file); + continue; + } + + snprintf(buf, sizeof(buf), "%s/%s", em->path, file); + f->name = file; + f->mtime = ecore_file_mod_time(buf); + f->is_dir = ecore_file_is_dir(buf); + em->files = _ecore_list_append(em->files, f); + } + ecore_list_destroy(files); + } + } + } + else + { + ecore_file_monitor_poll_del(em); + return NULL; + } + + _monitors = _ecore_list_append(_monitors, em); + + return em; +} + +void +ecore_file_monitor_poll_del(Ecore_File_Monitor *em) +{ + Ecore_Oldlist *l; + + if (_lock) + { + ECORE_FILE_MONITOR_POLL(em)->deleted = 1; + return; + } + + /* Remove files */ + for (l = em->files; l;) + { + Ecore_File *file; + + file = (Ecore_File *)l; + l = l->next; + free(file->name); + free(file); + } + + _monitors = _ecore_list_remove(_monitors, em); + + free(em->path); + free(em); + + if ((!_monitors) && (_timer)) + { + ecore_timer_del(_timer); + _timer = NULL; + } + else + ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN); +} + +static int +_ecore_file_monitor_poll_handler(void *data __UNUSED__) +{ + Ecore_Oldlist *l; + + _interval += ECORE_FILE_INTERVAL_STEP; + + _lock = 1; + for (l = _monitors; l; l = l->next) + { + Ecore_File_Monitor *em; + + em = ECORE_FILE_MONITOR(l); + _ecore_file_monitor_poll_check(em); + } + _lock = 0; + + if (_interval > ECORE_FILE_INTERVAL_MAX) + _interval = ECORE_FILE_INTERVAL_MAX; + ecore_timer_interval_set(_timer, _interval); + + for (l = _monitors; l;) + { + Ecore_File_Monitor *em; + + em = ECORE_FILE_MONITOR(l); + l = l->next; + if (ECORE_FILE_MONITOR_POLL(em)->deleted) + ecore_file_monitor_del(em); + } + return 1; +} + +static void +_ecore_file_monitor_poll_check(Ecore_File_Monitor *em) +{ + int mtime; + int is_dir; + + mtime = ecore_file_mod_time(em->path); + is_dir = ecore_file_is_dir(em->path); + if (mtime < ECORE_FILE_MONITOR_POLL(em)->mtime) + { + Ecore_Oldlist *l; + Ecore_File_Event event; + + /* Notify all files deleted */ + for (l = em->files; l;) + { + Ecore_File *f; + char buf[PATH_MAX]; + + f = (Ecore_File *)l; + l = l->next; + + snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name); + if (f->is_dir) + event = ECORE_FILE_EVENT_DELETED_DIRECTORY; + else + event = ECORE_FILE_EVENT_DELETED_FILE; + em->func(em->data, em, event, buf); + free(f->name); + free(f); + } + em->files = NULL; + em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path); + _interval = ECORE_FILE_INTERVAL_MIN; + } + else + { + Ecore_Oldlist *l; + + /* Check for changed files */ + for (l = em->files; l;) + { + Ecore_File *f; + char buf[PATH_MAX]; + int mtime; + Ecore_File_Event event; + + f = (Ecore_File *)l; + l = l->next; + + snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name); + mtime = ecore_file_mod_time(buf); + if (mtime < f->mtime) + { + if (f->is_dir) + event = ECORE_FILE_EVENT_DELETED_DIRECTORY; + else + event = ECORE_FILE_EVENT_DELETED_FILE; + + em->func(em->data, em, event, buf); + em->files = _ecore_list_remove(em->files, f); + free(f->name); + free(f); + _interval = ECORE_FILE_INTERVAL_MIN; + } + else if ((mtime > f->mtime) && !(f->is_dir)) + { + em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf); + _interval = ECORE_FILE_INTERVAL_MIN; + } + f->mtime = mtime; + } + + /* Check for new files */ + if (ECORE_FILE_MONITOR_POLL(em)->mtime < mtime) + { + Ecore_List *files; + char *file; + + /* Files have been added or removed */ + files = ecore_file_ls(em->path); + while ((file = ecore_list_next(files))) + { + Ecore_File *f; + char buf[PATH_MAX]; + Ecore_File_Event event; + + if (_ecore_file_monitor_poll_checking(em, file)) + { + free(file); + continue; + } + + snprintf(buf, sizeof(buf), "%s/%s", em->path, file); + f = calloc(1, sizeof(Ecore_File)); + if (!f) + { + free(file); + continue; + } + + f->name = file; + f->mtime = ecore_file_mod_time(buf); + f->is_dir = ecore_file_is_dir(buf); + if (f->is_dir) + event = ECORE_FILE_EVENT_CREATED_DIRECTORY; + else + event = ECORE_FILE_EVENT_CREATED_FILE; + em->func(em->data, em, event, buf); + em->files = _ecore_list_append(em->files, f); + } + ecore_list_destroy(files); + if (!ecore_file_is_dir(em->path)) + em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, em->path); + _interval = ECORE_FILE_INTERVAL_MIN; + } + } + ECORE_FILE_MONITOR_POLL(em)->mtime = mtime; +} + +static int +_ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name) +{ + Ecore_Oldlist *l; + + for (l = em->files; l; l = l->next) + { + Ecore_File *f; + + f = (Ecore_File *)l; + if (!strcmp(f->name, name)) + return 1; + } + + return 0; +} +#endif diff --git a/ecore/src/lib/ecore_file/ecore_file_path.c b/ecore/src/lib/ecore_file/ecore_file_path.c new file mode 100644 index 0000000..d1b5d71 --- /dev/null +++ b/ecore/src/lib/ecore_file/ecore_file_path.c @@ -0,0 +1,84 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "ecore_file_private.h" + +Ecore_List *__ecore_file_path_bin; + +static Ecore_List *_ecore_file_path_from_env(const char *env); + +int +ecore_file_path_init(void) +{ + __ecore_file_path_bin = _ecore_file_path_from_env("PATH"); + return 1; +} + +int +ecore_file_path_shutdown(void) +{ + ecore_list_destroy(__ecore_file_path_bin); + return 1; +} + +Ecore_List * +_ecore_file_path_from_env(const char *env) +{ + Ecore_List *path; + char *env_path, *p, *last; + + path = ecore_list_new(); + + env_path = getenv(env); + if (!env_path) + return path; + + env_path = strdup(env_path); + last = env_path; + for (p = env_path; *p; p++) + { + if (*p == ':') + *p = '\0'; + + if (!*p) + { + ecore_list_append(path, strdup(last)); + last = p+1; + } + + } + if (p > last) + ecore_list_append(path, last); + + free(env_path); + return path; +} + +int +ecore_file_app_installed(const char *app) +{ + int found; + char *dir; + char buf[PATH_MAX]; + + if (!app) + return 0; + + found = 0; + + if (ecore_list_is_empty(__ecore_file_path_bin)) + return 0; + ecore_list_goto_first(__ecore_file_path_bin); + + while ((dir = ecore_list_next(__ecore_file_path_bin)) != NULL) + { + snprintf(buf, sizeof(buf), "%s/%s", dir, app); + if (ecore_file_exists(buf) && ecore_file_can_exec(buf)) + { + found = 1; + break; + } + } + + return found; +} diff --git a/ecore/src/lib/ecore_file/ecore_file_private.h b/ecore/src/lib/ecore_file/ecore_file_private.h new file mode 100644 index 0000000..b691655 --- /dev/null +++ b/ecore/src/lib/ecore_file/ecore_file_private.h @@ -0,0 +1,75 @@ +#define _GNU_SOURCE + +#include +#include +#include + +#include "config.h" + +#include "ecore_private.h" +#include "Ecore.h" +#include "Ecore_File.h" + +/* ecore_file_monitor */ +int ecore_file_monitor_init(void); +int ecore_file_monitor_shutdown(void); + +#define ECORE_FILE_MONITOR(x) ((Ecore_File_Monitor *)(x)) + +struct _Ecore_File_Monitor +{ + Ecore_Oldlist __list_data; + void (*func) (void *data, + Ecore_File_Monitor *ecore_file_monitor, + Ecore_File_Event event, + const char *path); + + char *path; + void *data; + Ecore_Oldlist *files; +}; + +#ifdef HAVE_INOTIFY +EAPI int ecore_file_monitor_inotify_init(void); +EAPI int ecore_file_monitor_inotify_shutdown(void); +EAPI Ecore_File_Monitor *ecore_file_monitor_inotify_add(const char *path, + void (*func) (void *data, + Ecore_File_Monitor *ecore_file_monitor, + Ecore_File_Event event, + const char *path), + void *data); +EAPI void ecore_file_monitor_inotify_del(Ecore_File_Monitor *ecore_file_monitor); +#endif + +#ifdef HAVE_FAM +EAPI int ecore_file_monitor_fam_init(void); +EAPI int ecore_file_monitor_fam_shutdown(void); +EAPI Ecore_File_Monitor *ecore_file_monitor_fam_add(const char *path, + void (*func) (void *data, + Ecore_File_Monitor *ecore_file_monitor, + Ecore_File_Event event, + const char *path), + void *data); +EAPI void ecore_file_monitor_fam_del(Ecore_File_Monitor *ecore_file_monitor); +#endif + +#ifdef HAVE_POLL +EAPI int ecore_file_monitor_poll_init(void); +EAPI int ecore_file_monitor_poll_shutdown(void); +EAPI Ecore_File_Monitor *ecore_file_monitor_poll_add(const char *path, + void (*func) (void *data, + Ecore_File_Monitor *ecore_file_monitor, + Ecore_File_Event event, + const char *path), + void *data); +EAPI void ecore_file_monitor_poll_del(Ecore_File_Monitor *ecore_file_monitor); + +/* ecore_file_path */ +int ecore_file_path_init(void); +int ecore_file_path_shutdown(void); + +/* ecore_file_download */ +int ecore_file_download_init(void); +int ecore_file_download_shutdown(void); + +#endif diff --git a/ecore/src/lib/ecore_file/ecore_file_utils.c b/ecore/src/lib/ecore_file/ecore_file_utils.c new file mode 100644 index 0000000..b3217ad --- /dev/null +++ b/ecore/src/lib/ecore_file/ecore_file_utils.c @@ -0,0 +1,4 @@ +void +_ecore_file_add_slash(char *path) +{ +} diff --git a/ecore/src/lib/ecore_ipc/.cvsignore b/ecore/src/lib/ecore_ipc/.cvsignore new file mode 100644 index 0000000..f98e6f6 --- /dev/null +++ b/ecore/src/lib/ecore_ipc/.cvsignore @@ -0,0 +1,7 @@ +.deps +.libs +Ecore_Ipc.h +Makefile +Makefile.in +ecore_ipc.lo +libecore_ipc.la diff --git a/ecore/src/lib/ecore_ipc/CVS/Entries b/ecore/src/lib/ecore_ipc/CVS/Entries new file mode 100644 index 0000000..789fd35 --- /dev/null +++ b/ecore/src/lib/ecore_ipc/CVS/Entries @@ -0,0 +1,6 @@ +/.cvsignore/1.2/Mon Apr 12 19:35:26 2004//THEAD +/Ecore_Ipc.h/1.11/Thu May 12 14:45:15 2005//THEAD +/Makefile.am/1.8/Thu Mar 10 15:19:40 2005//THEAD +/ecore_ipc.c/1.20/Thu May 12 14:45:15 2005//THEAD +/ecore_ipc_private.h/1.5/Sat Apr 2 15:59:55 2005//THEAD +D diff --git a/ecore/src/lib/ecore_ipc/CVS/Repository b/ecore/src/lib/ecore_ipc/CVS/Repository new file mode 100644 index 0000000..328a12d --- /dev/null +++ b/ecore/src/lib/ecore_ipc/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/src/lib/ecore_ipc diff --git a/ecore/src/lib/ecore_ipc/CVS/Root b/ecore/src/lib/ecore_ipc/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/src/lib/ecore_ipc/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/src/lib/ecore_ipc/CVS/Tag b/ecore/src/lib/ecore_ipc/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/src/lib/ecore_ipc/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/src/lib/ecore_ipc/Ecore_Ipc.h b/ecore/src/lib/ecore_ipc/Ecore_Ipc.h new file mode 100644 index 0000000..36b7b70 --- /dev/null +++ b/ecore/src/lib/ecore_ipc/Ecore_Ipc.h @@ -0,0 +1,312 @@ +#ifndef _ECORE_IPC_H +#define _ECORE_IPC_H + +#ifdef EAPI +#undef EAPI +#endif +#ifdef WIN32 +# ifdef BUILDING_DLL +# define EAPI __declspec(dllexport) +# else +# define EAPI __declspec(dllimport) +# endif +#else +# ifdef GCC_HASCLASSVISIBILITY +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +#endif + +/** + * @file Ecore_Ipc.h + * @brief Ecore inter-process communication functions. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ECORE_IPC_PRIVATE_H + typedef void Ecore_Ipc_Server; /**< An IPC connection handle */ + typedef void Ecore_Ipc_Client; /**< An IPC connection handle */ +#endif + +/** + * Macros used for generic data packing + */ +EAPI unsigned short _ecore_ipc_swap_16(unsigned short v); +EAPI unsigned int _ecore_ipc_swap_32(unsigned int v); +EAPI unsigned long long _ecore_ipc_swap_64(unsigned long long v); + +#ifdef WORDS_BIGENDIAN +#define ECORE_IPC_SWAP2NET64(x) _ecore_ipc_swap_64(x) +#define ECORE_IPC_SWAP2CPU64(x) _ecore_ipc_swap_64(x) +#define ECORE_IPC_SWAP2NET32(x) _ecore_ipc_swap_32(x) +#define ECORE_IPC_SWAP2CPU32(x) _ecore_ipc_swap_32(x) +#define ECORE_IPC_SWAP2NET16(x) _ecore_ipc_swap_16(x) +#define ECORE_IPC_SWAP2CPU16(x) _ecore_ipc_swap_16(x) +#define ECORE_IPC_SWAP2NET8(x) (x) +#define ECORE_IPC_SWAP2CPU8(x) (x) +#else +#define ECORE_IPC_SWAP2NET64(x) (x) +#define ECORE_IPC_SWAP2CPU64(x) (x) +#define ECORE_IPC_SWAP2NET32(x) (x) +#define ECORE_IPC_SWAP2CPU32(x) (x) +#define ECORE_IPC_SWAP2NET16(x) (x) +#define ECORE_IPC_SWAP2CPU16(x) (x) +#define ECORE_IPC_SWAP2NET8(x) (x) +#define ECORE_IPC_SWAP2CPU8(x) (x) +#endif + +/* 1, 2, 4 and 8 byte datatypes */ +/* unpacking */ +#define ECORE_IPC_GET64(v)\ + { \ + p->v = ECORE_IPC_SWAP2CPU64(*(long long *)(ptr)); \ + ptr += 8; \ + } +#define ECORE_IPC_GET32(v)\ + { \ + p->v = ECORE_IPC_SWAP2CPU32(*(int *)(ptr)); \ + ptr += 4; \ + } +#define ECORE_IPC_GET16(v)\ + { \ + p->v = ECORE_IPC_SWAP2CPU16(*(short *)(ptr)); \ + ptr += 2; \ + } +#define ECORE_IPC_GET8(v) \ + { \ + p->v = ECORE_IPC_SWAP2CPU8(*(char *)(ptr)); \ + ptr += 1; \ + } +/* packing */ +#define ECORE_IPC_PUT64(v)\ + { \ + *(long long *)(ptr) = ECORE_IPC_SWAP2NET64(p->v); \ + ptr += 8; \ + } +#define ECORE_IPC_PUT32(v)\ + { \ + *(int *)(ptr) = ECORE_IPC_SWAP2NET32(p->v); \ + ptr += 4; \ + } +#define ECORE_IPC_PUT16(v)\ + { \ + *(short *)(ptr) = ECORE_IPC_SWAP2NET16(p->v); \ + ptr += 2; \ + } +#define ECORE_IPC_PUT8(v) \ + { \ + *(char *)(ptr) = ECORE_IPC_SWAP2NET8(p->v); \ + ptr += 1; \ + } +/* padding data */ +#define ECORE_IPC_PAD8() ptr += 1 +#define ECORE_IPC_PAD16() ptr += 2 +#define ECORE_IPC_PAD32() ptr += 4 +#define ECORE_IPC_PAD64() ptr += 8 + +/* counting data when encoding lists */ +#define ECORE_IPC_CNT8() len += 1 +#define ECORE_IPC_CNT16() len += 2 +#define ECORE_IPC_CNT32() len += 4 +#define ECORE_IPC_CNT64() len += 8 + +/* strings */ +#define ECORE_IPC_CHEKS() if (*((unsigned char *)d + s - 1) != 0) return 0; +#define ECORE_IPC_GETS(v) \ + { \ + if (ptr < ((unsigned char *)d + s)) \ + { \ + p->v = (char *)ptr; \ + ptr += strlen(p->v) + 1; \ + } \ + } +#define ECORE_IPC_PUTS(v, l)\ + { \ + strcpy((char *)ptr, p->v); \ + ptr += l + 1; \ + } + +/* handy to calculate what sized block we need to alloc */ +#define ECORE_IPC_SLEN(l, v) ((l = strlen(p->v)) + 1) +#define ECORE_IPC_CNTS(v) len += strlen(p->v) + 1 + +/* saves typing function headers */ +#define ECORE_IPC_DEC_STRUCT_PROTO(x) static int x(void *d, int s, void *pp) +#define ECORE_IPC_ENC_STRUCT_PROTO(x) static void *x(void *pp, int *s) +#define ECORE_IPC_DEC_EVAS_LIST_PROTO(x) static Evas_List *x(void *d, int s) +#define ECORE_IPC_ENC_EVAS_LIST_PROTO(x) static void *x(Evas_List *lp, int *s) + + +/* decoder setup - saves typing. requires data packet of exact size, or fail */ +#define ECORE_IPC_DEC_STRUCT_HEAD_EXACT(typ, x) \ + typ *p; \ + unsigned char *ptr; \ + p = (typ *)pp; \ + if (!d) return 0; if (s != (x)) return 0; \ + ptr = d; +/* decoder setup - saves typing. requires data packet of a minimum size */ +#define ECORE_IPC_DEC_STRUCT_HEAD_MIN(typ, x) \ + typ *p; \ + unsigned char *ptr; \ + p = (typ *)pp; \ + if (!d) return 0; if (s < (x)) return 0; \ + ptr = d; +/* footer for the hell of it */ +#define ECORE_IPC_DEC_STRUCT_FOOT() return 1 +/* header for encoder - gives native strct type and size of flattened packet */ +#define ECORE_IPC_ENC_STRUCT_HEAD(typ, sz) \ + typ *p; \ + unsigned char *d, *ptr; \ + int len; \ + *s = 0; \ + if(!pp) return NULL; \ + p = (typ *)pp; \ + len = sz; \ + d = malloc(len); \ + if (!d) return NULL; \ + *s = len; \ + ptr = d; +/* footer for the hell of it */ +#define ECORE_IPC_ENC_STRUCT_FOOT() return d + +#define ECORE_IPC_DEC_EVAS_LIST_HEAD(typ) \ + unsigned char *ptr; \ + Evas_List *l; \ + typ *p; \ + l = NULL; \ + ptr = d; \ + while(ptr < (unsigned char *)(d + s)) \ + { \ + p = malloc(sizeof(typ)); + +#define ECORE_IPC_DEC_EVAS_LIST_FOOT() \ + l = evas_list_append(l, p); \ + } \ + return l +#define ECORE_IPC_ENC_EVAS_LIST_HEAD_START(typ) \ + Evas_List *l; \ + typ *p; \ + unsigned char *d, *ptr; \ + int len; \ + *s = 0; \ + len = 0; \ + for (l = lp; l; l = l->next) \ + { \ + p = l->data; +#define ECORE_IPC_ENC_EVAS_LIST_HEAD_FINISH() \ + } \ + d = malloc(len); \ + if(!d) return NULL; \ + *s = len; \ + ptr = d; \ + for (l = lp; l; l = l->next) \ + { \ + p = l->data; + +#define ECORE_IPC_ENC_EVAS_LIST_FOOT() \ + } \ + return d + + typedef enum _Ecore_Ipc_Type + { + ECORE_IPC_LOCAL_USER, + ECORE_IPC_LOCAL_SYSTEM, + ECORE_IPC_REMOTE_SYSTEM, + ECORE_IPC_USE_SSL = 16 + } Ecore_Ipc_Type; + + typedef struct _Ecore_Ipc_Event_Client_Add Ecore_Ipc_Event_Client_Add; + typedef struct _Ecore_Ipc_Event_Client_Del Ecore_Ipc_Event_Client_Del; + typedef struct _Ecore_Ipc_Event_Server_Add Ecore_Ipc_Event_Server_Add; + typedef struct _Ecore_Ipc_Event_Server_Del Ecore_Ipc_Event_Server_Del; + typedef struct _Ecore_Ipc_Event_Client_Data Ecore_Ipc_Event_Client_Data; + typedef struct _Ecore_Ipc_Event_Server_Data Ecore_Ipc_Event_Server_Data; + + struct _Ecore_Ipc_Event_Client_Add + { + Ecore_Ipc_Client *client; + }; + + struct _Ecore_Ipc_Event_Client_Del + { + Ecore_Ipc_Client *client; + }; + + struct _Ecore_Ipc_Event_Server_Add + { + Ecore_Ipc_Server *server; + }; + + struct _Ecore_Ipc_Event_Server_Del + { + Ecore_Ipc_Server *server; + }; + + struct _Ecore_Ipc_Event_Client_Data + { + Ecore_Ipc_Client *client; + /* FIXME: this needs to become an ipc message */ + int major; + int minor; + int ref; + int ref_to; + int response; + void *data; + int size; + }; + + struct _Ecore_Ipc_Event_Server_Data + { + Ecore_Ipc_Server *server; + /* FIXME: this needs to become an ipc message */ + int major; + int minor; + int ref; + int ref_to; + int response; + void *data; + int size; + }; + + extern int ECORE_IPC_EVENT_CLIENT_ADD; + extern int ECORE_IPC_EVENT_CLIENT_DEL; + extern int ECORE_IPC_EVENT_SERVER_ADD; + extern int ECORE_IPC_EVENT_SERVER_DEL; + extern int ECORE_IPC_EVENT_CLIENT_DATA; + extern int ECORE_IPC_EVENT_SERVER_DATA; + + EAPI int ecore_ipc_init(void); + EAPI int ecore_ipc_shutdown(void); + + /* FIXME: need to add protocol type parameter */ + EAPI Ecore_Ipc_Server *ecore_ipc_server_add(Ecore_Ipc_Type type, const char *name, int port, const void *data); + + /* FIXME: need to add protocol type parameter */ + EAPI Ecore_Ipc_Server *ecore_ipc_server_connect(Ecore_Ipc_Type type, char *name, int port, const void *data); + EAPI void *ecore_ipc_server_del(Ecore_Ipc_Server *svr); + EAPI void *ecore_ipc_server_data_get(Ecore_Ipc_Server *svr); + EAPI int ecore_ipc_server_connected_get(Ecore_Ipc_Server *svr); + /* FIXME: this needs to become an ipc message */ + EAPI int ecore_ipc_server_send(Ecore_Ipc_Server *svr, int major, int minor, int ref, int ref_to, int response, void *data, int size); + EAPI void ecore_ipc_server_client_limit_set(Ecore_Ipc_Server *svr, int client_limit, char reject_excess_clients); + + /* FIXME: this needs to become an ipc message */ + EAPI int ecore_ipc_client_send(Ecore_Ipc_Client *cl, int major, int minor, int ref, int ref_to, int response, void *data, int size); + EAPI Ecore_Ipc_Server *ecore_ipc_client_server_get(Ecore_Ipc_Client *cl); + EAPI void *ecore_ipc_client_del(Ecore_Ipc_Client *cl); + EAPI void ecore_ipc_client_data_set(Ecore_Ipc_Client *cl, const void *data); + EAPI void *ecore_ipc_client_data_get(Ecore_Ipc_Client *cl); + + EAPI int ecore_ipc_ssl_available_get(void); + /* FIXME: need to add a callback to "ok" large ipc messages greater than */ + /* a certain size (seurity/DOS attack safety) */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ecore/src/lib/ecore_ipc/Makefile.am b/ecore/src/lib/ecore_ipc/Makefile.am new file mode 100644 index 0000000..48d8746 --- /dev/null +++ b/ecore/src/lib/ecore_ipc/Makefile.am @@ -0,0 +1,39 @@ +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_con \ +-I$(top_builddir)/src/lib/ecore_ipc \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_con \ +-I$(top_srcdir)/src/lib/ecore_ipc \ +@SSL_CFLAGS@ + +libecore_ipc_la_LDFLAGS = -version-info 1:0:0 \ +-L$(top_builddir)/src/lib/ecore/.libs \ +-L$(top_builddir)/src/lib/ecore_con/.libs + +if BUILD_ECORE_IPC + +lib_LTLIBRARIES = libecore_ipc.la +include_HEADERS = \ +Ecore_Ipc.h + +libecore_ipc_la_SOURCES = \ +ecore_ipc.c \ +ecore_ipc_private.h + +libecore_ipc_la_LIBADD = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(top_builddir)/src/lib/ecore_con/libecore_con.la \ +@SSL_LIBS@ @winsock_libs@ + +libecore_ipc_la_DEPENDENCIES = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(top_builddir)/src/lib/ecore_con/libecore_con.la + +endif + +EXTRA_DIST = \ +ecore_ipc.c \ +ecore_ipc_private.h diff --git a/ecore/src/lib/ecore_ipc/ecore_ipc.c b/ecore/src/lib/ecore_ipc/ecore_ipc.c new file mode 100644 index 0000000..cbe2c03 --- /dev/null +++ b/ecore/src/lib/ecore_ipc/ecore_ipc.c @@ -0,0 +1,1257 @@ +#include "Ecore.h" +#include "config.h" +#include "Ecore_Con.h" +#include "ecore_private.h" +#include "ecore_ipc_private.h" +#include "Ecore_Ipc.h" + +#ifdef HAVE_NETINET_IN_H +#include +#elif WIN32 +#include +#endif + +#define DLT_ZERO 0 +#define DLT_ONE 1 +#define DLT_SAME 2 +#define DLT_SHL 3 +#define DLT_SHR 4 +#define DLT_ADD8 5 +#define DLT_DEL8 6 +#define DLT_ADDU8 7 +#define DLT_DELU8 8 +#define DLT_ADD16 9 +#define DLT_DEL16 10 +#define DLT_ADDU16 11 +#define DLT_DELU16 12 +#define DLT_SET 13 +#define DLT_R1 14 +#define DLT_R2 15 + +/* byte swappers - for dealing with big vs little endian machines */ +unsigned short +_ecore_ipc_swap_16(unsigned short v) +{ + unsigned char *s, t; + + s = (unsigned char *)(&v); + t = s[0]; s[0] = s[1]; s[1] = t; + return v; +} + +unsigned int +_ecore_ipc_swap_32(unsigned int v) +{ + unsigned char *s, t; + + s = (unsigned char *)(&v); + t = s[0]; s[0] = s[3]; s[3] = t; + t = s[1]; s[1] = s[2]; s[2] = t; + return v; +} + +unsigned long long +_ecore_ipc_swap_64(unsigned long long v) +{ + unsigned char *s, t; + + s = (unsigned char *)(&v); + t = s[0]; s[0] = s[7]; s[7] = t; + t = s[1]; s[1] = s[6]; s[6] = t; + t = s[2]; s[2] = s[5]; s[5] = t; + t = s[3]; s[3] = s[4]; s[4] = t; + return v; +} + +static int _ecore_ipc_dlt_int(int out, int prev, int *mode); +static int _ecore_ipc_ddlt_int(int in, int prev, int mode); + +static int +_ecore_ipc_dlt_int(int out, int prev, int *mode) +{ + int dlt; + + /* 0 byte */ + if (out == 0) + { + *mode = DLT_ZERO; + return 0; + } + if (out == (int)0xffffffff) + { + *mode = DLT_ONE; + return 0; + } + if (out == prev) + { + *mode = DLT_SAME; + return 0; + } + if (out == prev << 1) + { + *mode = DLT_SHL; + return 0; + } + if (out == prev >> 1) + { + *mode = DLT_SHR; + return 0; + } + /* 1 byte */ + dlt = out - prev; + if (!(dlt & 0xffffff00)) + { + *mode = DLT_ADD8; + return dlt & 0xff; + } + dlt = prev - out; + if (!(dlt & 0xffffff00)) + { + *mode = DLT_DEL8; + return dlt & 0xff; + } + dlt = out - prev; + if (!(dlt & 0x00ffffff)) + { + *mode = DLT_ADDU8; + return (dlt >> 24) & 0xff; + } + dlt = prev - out; + if (!(dlt & 0x00ffffff)) + { + *mode = DLT_DELU8; + return (dlt >> 24) & 0xff; + } + /* 2 byte */ + dlt = out - prev; + if (!(dlt & 0xffff0000)) + { + *mode = DLT_ADD16; + return dlt & 0xfffff; + } + dlt = prev - out; + if (!(dlt & 0xffff0000)) + { + *mode = DLT_DEL16; + return dlt & 0xffff; + } + dlt = out - prev; + if (!(dlt & 0x0000ffff)) + { + *mode = DLT_ADDU16; + return (dlt >> 16) & 0xffff; + } + dlt = prev - out; + if (!(dlt & 0x0000ffff)) + { + *mode = DLT_DELU16; + return (dlt >> 16) & 0xffff; + } + /* 4 byte */ + *mode = DLT_SET; + return out; +} + +static int +_ecore_ipc_ddlt_int(int in, int prev, int mode) +{ + switch (mode) + { + case DLT_ZERO: + return 0; + break; + case DLT_ONE: + return 0xffffffff; + break; + case DLT_SAME: + return prev; + break; + case DLT_SHL: + return prev << 1; + break; + case DLT_SHR: + return prev >> 1; + break; + case DLT_ADD8: + return prev + in; + break; + case DLT_DEL8: + return prev - in; + break; + case DLT_ADDU8: + return prev + (in << 24); + break; + case DLT_DELU8: + return prev - (in << 24); + break; + case DLT_ADD16: + return prev + in; + break; + case DLT_DEL16: + return prev - in; + break; + case DLT_ADDU16: + return prev + (in << 16); + break; + case DLT_DELU16: + return prev - (in << 16); + break; + case DLT_SET: + return in; + break; + case DLT_R1: + return 0; + break; + case DLT_R2: + return 0; + break; + default: + break; + } + return 0; +} + +static int _ecore_ipc_event_client_add(void *data, int ev_type, void *ev); +static int _ecore_ipc_event_client_del(void *data, int ev_type, void *ev); +static int _ecore_ipc_event_server_add(void *data, int ev_type, void *ev); +static int _ecore_ipc_event_server_del(void *data, int ev_type, void *ev); +static int _ecore_ipc_event_client_data(void *data, int ev_type, void *ev); +static int _ecore_ipc_event_server_data(void *data, int ev_type, void *ev); +static void _ecore_ipc_event_client_data_free(void *data, void *ev); +static void _ecore_ipc_event_server_data_free(void *data, void *ev); + +int ECORE_IPC_EVENT_CLIENT_ADD = 0; +int ECORE_IPC_EVENT_CLIENT_DEL = 0; +int ECORE_IPC_EVENT_SERVER_ADD = 0; +int ECORE_IPC_EVENT_SERVER_DEL = 0; +int ECORE_IPC_EVENT_CLIENT_DATA = 0; +int ECORE_IPC_EVENT_SERVER_DATA = 0; + +static int init_count = 0; +static Ecore_Ipc_Server *servers = NULL; + +/** + * @defgroup Ecore_IPC_Library_Group IPC Library Functions + * + * Functions that set up and shut down the Ecore IPC Library. + */ + +/** + * Initialises the Ecore IPC library. + * @return Number of times the library has been initialised without + * being shut down. + * @ingroup Ecore_IPC_Library_Group + */ +int +ecore_ipc_init(void) +{ + if (!init_count) ecore_con_init(); + init_count++; + if (!ECORE_IPC_EVENT_CLIENT_ADD) + { + ECORE_IPC_EVENT_CLIENT_ADD = ecore_event_type_new(); + ECORE_IPC_EVENT_CLIENT_DEL = ecore_event_type_new(); + ECORE_IPC_EVENT_SERVER_ADD = ecore_event_type_new(); + ECORE_IPC_EVENT_SERVER_DEL = ecore_event_type_new(); + ECORE_IPC_EVENT_CLIENT_DATA = ecore_event_type_new(); + ECORE_IPC_EVENT_SERVER_DATA = ecore_event_type_new(); + + ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, _ecore_ipc_event_client_add, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, _ecore_ipc_event_client_del, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, _ecore_ipc_event_server_add, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, _ecore_ipc_event_server_del, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, _ecore_ipc_event_client_data, NULL); + ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, _ecore_ipc_event_server_data, NULL); + } + return init_count; +} + +/** + * Shuts down the Ecore IPC library. + * @return Number of times the library has been initialised without being + * shut down. + * @ingroup Ecore_IPC_Library_Group + */ +int +ecore_ipc_shutdown(void) +{ + if (init_count > 0) + { + init_count--; + if (init_count > 0) return init_count; + while (servers) ecore_ipc_server_del(servers); + ecore_con_shutdown(); + } + return 0; +} + +/** + * @defgroup Ecore_IPC_Server_Group IPC Server Functions + * + * Functions the deal with IPC server objects. + */ + +/** + * Creates an IPC server that listens for connections. + * + * For more details about the @p compl_type, @p name and @p port + * parameters, see the @ref ecore_con_server_add documentation. + * + * @param compl_type The connection type. + * @param name Name to associate with the socket used for connection. + * @param port Number to identify with socket used for connection. + * @param data Data to associate with the IPC server. + * @return New IPC server. If there is an error, @c NULL is returned. + * @ingroup Ecore_IPC_Server_Group + * @todo Need to add protocol type parameter to this function. + */ +Ecore_Ipc_Server * +ecore_ipc_server_add(Ecore_Ipc_Type compl_type, const char *name, int port, const void *data) +{ + Ecore_Ipc_Server *svr; + Ecore_Ipc_Type type; + Ecore_Con_Type extra = 0; + + svr = calloc(1, sizeof(Ecore_Ipc_Server)); + if (!svr) return NULL; + type = compl_type; + type &= ~ECORE_IPC_USE_SSL; + if (compl_type & ECORE_IPC_USE_SSL) extra = ECORE_CON_USE_SSL; + switch (type) + { + case ECORE_IPC_LOCAL_USER: + svr->server = ecore_con_server_add(ECORE_CON_LOCAL_USER | extra, name, port, svr); + break; + case ECORE_IPC_LOCAL_SYSTEM: + svr->server = ecore_con_server_add(ECORE_CON_LOCAL_SYSTEM | extra, name, port, svr); + break; + case ECORE_IPC_REMOTE_SYSTEM: + svr->server = ecore_con_server_add(ECORE_CON_REMOTE_SYSTEM | extra, name, port, svr); + break; + default: + free(svr); + return NULL; + } + if (!svr->server) + { + free(svr); + return NULL; + } + svr->data = (void *)data; + servers = _ecore_list_append(servers, svr); + ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER); + return svr; +} + +/** + * Creates an IPC server object to represent the IPC server listening + * on the given port. + * + * For more details about the @p compl_type, @p name and @p port + * parameters, see the @ref ecore_con_server_connect documentation. + * + * @param compl_type The IPC connection type. + * @param name Name used to determine which socket to use for the + * IPC connection. + * @param port Number used to identify the socket to use for the + * IPC connection. + * @param data Data to associate with the server. + * @return A new IPC server. @c NULL is returned on error. + * @ingroup Ecore_IPC_Server_Group + * @todo Need to add protocol type parameter. + */ +Ecore_Ipc_Server * +ecore_ipc_server_connect(Ecore_Ipc_Type compl_type, char *name, int port, const void *data) +{ + Ecore_Ipc_Server *svr; + Ecore_Ipc_Type type; + Ecore_Con_Type extra = 0; + + svr = calloc(1, sizeof(Ecore_Ipc_Server)); + if (!svr) return NULL; + type = compl_type; + type &= ~ECORE_IPC_USE_SSL; + if (compl_type & ECORE_IPC_USE_SSL) extra = ECORE_CON_USE_SSL; + switch (type) + { + case ECORE_IPC_LOCAL_USER: + svr->server = ecore_con_server_connect(ECORE_CON_LOCAL_USER | extra, name, port, svr); + break; + case ECORE_IPC_LOCAL_SYSTEM: + svr->server = ecore_con_server_connect(ECORE_CON_LOCAL_SYSTEM | extra, name, port, svr); + break; + case ECORE_IPC_REMOTE_SYSTEM: + svr->server = ecore_con_server_connect(ECORE_CON_REMOTE_SYSTEM | extra, name, port, svr); + break; + default: + free(svr); + return NULL; + } + if (!svr->server) + { + free(svr); + return NULL; + } + svr->data = (void *)data; + servers = _ecore_list_append(servers, svr); + ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER); + return svr; +} + +/** + * Closes the connection and frees the given IPC server. + * @param svr The given IPC server. + * @return The data associated with the server when it was created. + * @ingroup Ecore_IPC_Server_Group + */ +void * +ecore_ipc_server_del(Ecore_Ipc_Server *svr) +{ + void *data; + + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER, + "ecore_ipc_server_del"); + return NULL; + } + ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE); + data = svr->data; + while (svr->clients) ecore_ipc_client_del((Ecore_Ipc_Client *)svr->clients); + ecore_con_server_del(svr->server); + servers = _ecore_list_remove(servers, svr); + if (svr->buf) free(svr->buf); + free(svr); + return data; +} + +/** + * Retrieves the data associated with the given IPC server. + * @param svr The given IPC server. + * @return The associated data. + * @ingroup Ecore_IPC_Server_Group + */ +void * +ecore_ipc_server_data_get(Ecore_Ipc_Server *svr) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER, + "ecore_ipc_server_data_get"); + return NULL; + } + return svr->data; +} + +/** + * Retrieves whether the given IPC server is currently connected. + * @param svr The given IPC server. + * @return @c 1 if the server is connected. @c 0 otherwise. + * @ingroup Ecore_IPC_Server_Group + */ +int +ecore_ipc_server_connected_get(Ecore_Ipc_Server *svr) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER, + "ecore_ipc_server_connected_get"); + return 0; + } + return ecore_con_server_connected_get(svr->server); +} + +#define SVENC(_member) \ + d = _ecore_ipc_dlt_int(msg._member, svr->prev.o._member, &md); \ + if (md >= DLT_SET) \ + { \ + unsigned int v; \ + unsigned char *dd; \ + dd = (unsigned char *)&v; \ + v = d; \ + v = htonl(v); \ + *(dat + s + 0) = dd[0]; \ + *(dat + s + 1) = dd[1]; \ + *(dat + s + 2) = dd[2]; \ + *(dat + s + 3) = dd[3]; \ + s += 4; \ + } \ + else if (md >= DLT_ADD16) \ + { \ + unsigned short v; \ + unsigned char *dd; \ + dd = (unsigned char *)&v; \ + v = d; \ + v = htons(v); \ + *(dat + s + 0) = dd[0]; \ + *(dat + s + 1) = dd[1]; \ + s += 2; \ + } \ + else if (md >= DLT_ADD8) \ + { \ + *(dat + s + 0) = (unsigned char)d; \ + s += 1; \ + } + +/** + * Sends a message to the given IPC server. + * + * The content of the parameters, excluding the @p svr paramter, is up to + * the client. + * + * @param svr The given IPC server. + * @param major Major opcode of the message. + * @param minor Minor opcode of the message. + * @param ref Message reference number. + * @param ref_to Reference number of the message this message refers to. + * @param response Requires response. + * @param data The data to send as part of the message. + * @param size Length of the data, in bytes, to send. + * @return Number of bytes sent. @c 0 is returned if there is an error. + * @ingroup Ecore_IPC_Server_Group + * @todo This function needs to become an IPC message. + * @todo Fix up the documentation: Make sure what ref_to and response are. + */ +int +ecore_ipc_server_send(Ecore_Ipc_Server *svr, int major, int minor, int ref, int ref_to, int response, void *data, int size) +{ + Ecore_Ipc_Msg_Head msg; + int ret; + int *head, md = 0, d, s; + unsigned char dat[sizeof(Ecore_Ipc_Msg_Head)]; + + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER, + "ecore_ipc_server_send"); + return 0; + } + if (size < 0) size = 0; + msg.major = major; + msg.minor = minor; + msg.ref = ref; + msg.ref_to = ref_to; + msg.response = response; + msg.size = size; + head = (int *)dat; + s = 4; + SVENC(major); + *head = md; + SVENC(minor); + *head |= md << (4 * 1); + SVENC(ref); + *head |= md << (4 * 2); + SVENC(ref_to); + *head |= md << (4 * 3); + SVENC(response); + *head |= md << (4 * 4); + SVENC(size); + *head |= md << (4 * 5); + *head = htonl(*head); + svr->prev.o = msg; + ret = ecore_con_server_send(svr->server, dat, s); + if (size > 0) ret += ecore_con_server_send(svr->server, data, size); + return ret; +} + +/** + * Sets a limit on the number of clients that can be handled concurrently + * by the given server, and a policy on what to do if excess clients try to + * connect. + * Beware that if you set this once ecore is already running, you may + * already have pending CLIENT_ADD events in your event queue. Those + * clients have already connected and will not be affected by this call. + * Only clients subsequently trying to connect will be affected. + * @param svr The given server. + * @param client_limit The maximum number of clients to handle + * concurrently. -1 means unlimited (default). 0 + * effectively disables the server. + * @param reject_excess_clients Set to 1 to automatically disconnect + * excess clients as soon as they connect if you are + * already handling client_limit clients. Set to 0 + * (default) to just hold off on the "accept()" + * system call until the number of active clients + * drops. This causes the kernel to queue up to 4096 + * connections (or your kernel's limit, whichever is + * lower). + * @ingroup Ecore_Ipc_Server_Group + */ +void +ecore_ipc_server_client_limit_set(Ecore_Ipc_Server *svr, int client_limit, char reject_excess_clients) +{ + if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER)) + { + ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_IPC_SERVER, + "ecore_ipc_server_client_limit_set"); + return; + } + ecore_con_server_client_limit_set(svr->server, client_limit, reject_excess_clients); +} + +#define CLENC(_member) \ + d = _ecore_ipc_dlt_int(msg._member, cl->prev.o._member, &md); \ + if (md >= DLT_SET) \ + { \ + unsigned int v; \ + unsigned char *dd; \ + dd = (unsigned char *)&v; \ + v = d; \ + v = htonl(v); \ + *(dat + s + 0) = dd[0]; \ + *(dat + s + 1) = dd[1]; \ + *(dat + s + 2) = dd[2]; \ + *(dat + s + 3) = dd[3]; \ + s += 4; \ + } \ + else if (md >= DLT_ADD16) \ + { \ + unsigned short v; \ + unsigned char *dd; \ + dd = (unsigned char *)&v; \ + v = d; \ + v = htons(v); \ + *(dat + s + 0) = dd[0]; \ + *(dat + s + 1) = dd[1]; \ + s += 2; \ + } \ + else if (md >= DLT_ADD8) \ + { \ + *(dat + s) = (unsigned char)d; \ + s += 1; \ + } + +/** + * @defgroup Ecore_IPC_Client_Group IPC Client Functions + * + * Functions that deal with IPC client objects. + */ + +/** + * Sends a message to the given IPC client. + * @param cl The given IPC client. + * @param major Major opcode of the message. + * @param minor Minor opcode of the message. + * @param ref Reference number of the message. + * @param ref_to Reference number of the message this message refers to. + * @param response Requires response. + * @param data The data to send as part of the message. + * @param size Length of the data, in bytes, to send. + * @return The number of bytes sent. @c 0 will be returned if there is + * an error. + * @ingroup Ecore_IPC_Client_Group + * @todo This function needs to become an IPC message. + * @todo Make sure ref_to and response parameters are described correctly. + */ +int +ecore_ipc_client_send(Ecore_Ipc_Client *cl, int major, int minor, int ref, int ref_to, int response, void *data, int size) +{ + Ecore_Ipc_Msg_Head msg; + int ret; + int *head, md = 0, d, s; + unsigned char dat[sizeof(Ecore_Ipc_Msg_Head)]; + + if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT)) + { + ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT, + "ecore_ipc_client_send"); + return 0; + } + if (size < 0) size = 0; + msg.major = major; + msg.minor = minor; + msg.ref = ref; + msg.ref_to = ref_to; + msg.response = response; + msg.size = size; + head = (int *)dat; + s = 4; + CLENC(major); + *head = md; + CLENC(minor); + *head |= md << (4 * 1); + CLENC(ref); + *head |= md << (4 * 2); + CLENC(ref_to); + *head |= md << (4 * 3); + CLENC(response); + *head |= md << (4 * 4); + CLENC(size); + *head |= md << (4 * 5); + *head = htonl(*head); + cl->prev.o = msg; + ret = ecore_con_client_send(cl->client, dat, s); + if (size > 0) ret += ecore_con_client_send(cl->client, data, size); + return ret; +} + +/** + * Retrieves the IPC server that the given IPC client is connected to. + * @param cl The given IPC client. + * @return The IPC server the IPC client is connected to. + * @ingroup Ecore_IPC_Client_Group + */ +Ecore_Ipc_Server * +ecore_ipc_client_server_get(Ecore_Ipc_Client *cl) +{ + if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT)) + { + ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT, + "ecore_ipc_client_server_get"); + return NULL; + } + return (ecore_con_server_data_get(ecore_con_client_server_get(cl->client))); +} + +/** + * Closes the connection and frees memory allocated to the given IPC + * client. + * @param cl The given client. + * @return Data associated with the client. + * @ingroup Ecore_IPC_Client_Group + */ +void * +ecore_ipc_client_del(Ecore_Ipc_Client *cl) +{ + void *data; + Ecore_Ipc_Server *svr; + + if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT)) + { + ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT, + "ecore_ipc_client_del"); + return NULL; + } + ECORE_MAGIC_SET(cl, ECORE_MAGIC_NONE); + data = cl->data; + svr = ecore_con_server_data_get(ecore_con_client_server_get(cl->client)); + ecore_con_client_del(cl->client); + svr->clients = _ecore_list_remove(svr->clients, cl); + if (cl->buf) free(cl->buf); + free(cl); + return data; +} + +/** + * Sets the IPC data associated with the given IPC client to @p data. + * @param cl The given IPC client. + * @param data The data to associate with the IPC client. + * @ingroup Ecore_IPC_Client_Group + */ +void +ecore_ipc_client_data_set(Ecore_Ipc_Client *cl, const void *data) +{ + if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT)) + { + ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT, + "ecore_ipc_client_data_set"); + return; + } + cl->data = (void *)data; +} + +/** + * Retrieves the data that has been associated with the given IPC client. + * @param cl The given client. + * @return The data associated with the IPC client. + * @ingroup Ecore_IPC_Client_Group + */ +void * +ecore_ipc_client_data_get(Ecore_Ipc_Client *cl) +{ + if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_IPC_CLIENT)) + { + ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_IPC_CLIENT, + "ecore_ipc_client_data_get"); + return NULL; + } + return cl->data; +} + +/** + * Returns if SSL support is available + * @return 1 if SSL is available, 0 if it is not. + * @ingroup Ecore_Con_Client_Group + */ +int +ecore_ipc_ssl_available_get(void) +{ + return ecore_con_ssl_available_get(); +} + + +static int +_ecore_ipc_event_client_add(void *data __UNUSED__, int ev_type __UNUSED__, void *ev) +{ + Ecore_Con_Event_Client_Add *e; + + e = ev; + if (!_ecore_list_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return 1; + /* handling code here */ + { + Ecore_Ipc_Client *cl; + Ecore_Ipc_Server *svr; + + cl = calloc(1, sizeof(Ecore_Ipc_Client)); + if (!cl) return 0; + svr = ecore_con_server_data_get(ecore_con_client_server_get(e->client)); + ECORE_MAGIC_SET(cl, ECORE_MAGIC_IPC_CLIENT); + cl->client = e->client; + ecore_con_client_data_set(cl->client, (void *)cl); + svr->clients = _ecore_list_append(svr->clients, cl); + { + Ecore_Ipc_Event_Client_Add *e2; + + e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Add)); + if (e2) + { + e2->client = cl; + ecore_event_add(ECORE_IPC_EVENT_CLIENT_ADD, e2, NULL, NULL); + } + } + } + return 0; +} + +static int +_ecore_ipc_event_client_del(void *data __UNUSED__, int ev_type __UNUSED__, void *ev) +{ + Ecore_Con_Event_Client_Del *e; + + e = ev; + if (!_ecore_list_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return 1; + /* handling code here */ + { + Ecore_Ipc_Client *cl; + + cl = ecore_con_client_data_get(e->client); + { + Ecore_Ipc_Event_Client_Del *e2; + + e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Del)); + if (e2) + { + e2->client = cl; + ecore_event_add(ECORE_IPC_EVENT_CLIENT_DEL, e2, NULL, NULL); + } + } + } + return 0; +} + +static int +_ecore_ipc_event_server_add(void *data __UNUSED__, int ev_type __UNUSED__, void *ev) +{ + Ecore_Con_Event_Server_Add *e; + + e = ev; + if (!_ecore_list_find(servers, ecore_con_server_data_get(e->server))) return 1; + /* handling code here */ + { + Ecore_Ipc_Server *svr; + + svr = ecore_con_server_data_get(e->server); + { + Ecore_Ipc_Event_Server_Add *e2; + + e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Add)); + if (e2) + { + e2->server = svr; + ecore_event_add(ECORE_IPC_EVENT_SERVER_ADD, e2, NULL, NULL); + } + } + } + return 0; +} + +static int +_ecore_ipc_event_server_del(void *data __UNUSED__, int ev_type __UNUSED__, void *ev) +{ + Ecore_Con_Event_Server_Del *e; + + e = ev; + if (!_ecore_list_find(servers, ecore_con_server_data_get(e->server))) return 1; + /* handling code here */ + { + Ecore_Ipc_Server *svr; + + svr = ecore_con_server_data_get(e->server); + { + Ecore_Ipc_Event_Server_Del *e2; + + e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Del)); + if (e2) + { + e2->server = svr; + ecore_event_add(ECORE_IPC_EVENT_SERVER_DEL, e2, NULL, NULL); + } + } + } + return 0; +} + +#define CLSZ(_n) \ + md = ((head >> (4 * _n)) & 0xf); \ + if (md >= DLT_SET) s += 4; \ + else if (md >= DLT_ADD16) s += 2; \ + else if (md >= DLT_ADD8) s += 1; + +#define CLDEC(_n, _member) \ + md = ((head >> (4 * _n)) & 0xf); \ + if (md >= DLT_SET) \ + { \ + unsigned int v; \ + unsigned char *dv; \ + dv = (unsigned char *)&v; \ + dv[0] = *(cl->buf + offset + s + 0); \ + dv[1] = *(cl->buf + offset + s + 1); \ + dv[2] = *(cl->buf + offset + s + 2); \ + dv[3] = *(cl->buf + offset + s + 3); \ + d = (int)ntohl(d); \ + s += 4; \ + } \ + else if (md >= DLT_ADD16) \ + { \ + unsigned short v; \ + unsigned char *dv; \ + dv = (unsigned char *)&v; \ + dv[0] = *(cl->buf + offset + s + 0); \ + dv[1] = *(cl->buf + offset + s + 1); \ + d = (int)ntohs(v); \ + s += 2; \ + } \ + else if (md >= DLT_ADD8) \ + { \ + unsigned char v; \ + unsigned char *dv; \ + dv = (unsigned char *)&v; \ + dv[0] = *(cl->buf + offset + s + 0); \ + d = (int)v; \ + s += 1; \ + } \ + msg._member = _ecore_ipc_ddlt_int(d, cl->prev.i._member, md); + +static int +_ecore_ipc_event_client_data(void *data __UNUSED__, int ev_type __UNUSED__, void *ev) +{ + Ecore_Con_Event_Client_Data *e; + + e = ev; + if (!_ecore_list_find(servers, ecore_con_server_data_get(ecore_con_client_server_get(e->client)))) return 1; + /* handling code here */ + { + Ecore_Ipc_Client *cl; + Ecore_Ipc_Msg_Head msg; + int offset = 0; + unsigned char *buf; + + cl = ecore_con_client_data_get(e->client); + + if (!cl->buf) + { + cl->buf_size = e->size; + cl->buf = e->data; + e->data = NULL; /* take it out of the old event */ + } + else + { + unsigned char *buf; + + buf = realloc(cl->buf, cl->buf_size + e->size); + if (!buf) + { + free(cl->buf); + cl->buf = 0; + cl->buf_size = 0; + return 0; + } + cl->buf = buf; + memcpy(cl->buf + cl->buf_size, e->data, e->size); + cl->buf_size += e->size; + } + /* examine header */ + redo: + if ((cl->buf_size - offset) >= (int)sizeof(int)) + { + int s, md, d, head; + unsigned char *dd; + + dd = (unsigned char *)&head; + dd[0] = *(cl->buf + offset + 0); + dd[1] = *(cl->buf + offset + 1); + dd[2] = *(cl->buf + offset + 2); + dd[3] = *(cl->buf + offset + 3); + head = ntohl(head); + dd = (unsigned char *)&d; + s = 4; + CLSZ(0); + CLSZ(1); + CLSZ(2); + CLSZ(3); + CLSZ(4); + CLSZ(5); + if ((cl->buf_size - offset) < s) + { + if (offset > 0) goto scroll; + return 0; + } + + s = 4; + CLDEC(0, major); + CLDEC(1, minor); + CLDEC(2, ref); + CLDEC(3, ref_to); + CLDEC(4, response); + CLDEC(5, size); + if (msg.size < 0) msg.size = 0; + /* there is enough data in the buffer for a full message */ + if ((cl->buf_size - offset) >= (s + msg.size)) + { + Ecore_Ipc_Event_Client_Data *e2; + + buf = NULL; + if (msg.size > 0) + { + buf = malloc(msg.size); + if (!buf) return 0; + memcpy(buf, cl->buf + offset + s, msg.size); + } + e2 = calloc(1, sizeof(Ecore_Ipc_Event_Client_Data)); + if (e2) + { + e2->client = cl; + e2->major = msg.major; + e2->minor = msg.minor; + e2->ref = msg.ref; + e2->ref_to = msg.ref_to; + e2->response = msg.response; + e2->size = msg.size; + e2->data = buf; + ecore_event_add(ECORE_IPC_EVENT_CLIENT_DATA, e2, + _ecore_ipc_event_client_data_free, NULL); + } + cl->prev.i = msg; + offset += (s + msg.size); + if (cl->buf_size == offset) + { + free(cl->buf); + cl->buf = NULL; + cl->buf_size = 0; + return 0; + } + goto redo; + } + else goto scroll; + } + else + { + scroll: + buf = malloc(cl->buf_size - offset); + if (!buf) + { + free(cl->buf); + cl->buf = NULL; + cl->buf_size = 0; + return 0; + } + memcpy(buf, cl->buf + offset, cl->buf_size - offset); + free(cl->buf); + cl->buf = buf; + cl->buf_size -= offset; + } + } + return 0; +} + +#define SVSZ(_n) \ + md = ((head >> (4 * _n)) & 0xf); \ + if (md >= DLT_SET) s += 4; \ + else if (md >= DLT_ADD16) s += 2; \ + else if (md >= DLT_ADD8) s += 1; + +#define SVDEC(_n, _member) \ + md = ((head >> (4 * _n)) & 0xf); \ + if (md >= DLT_SET) \ + { \ + unsigned int v; \ + unsigned char *dv; \ + dv = (unsigned char *)&v; \ + dv[0] = *(svr->buf + offset + s + 0); \ + dv[1] = *(svr->buf + offset + s + 1); \ + dv[2] = *(svr->buf + offset + s + 2); \ + dv[3] = *(svr->buf + offset + s + 3); \ + d = (int)ntohl(d); \ + s += 4; \ + } \ + else if (md >= DLT_ADD16) \ + { \ + unsigned short v; \ + unsigned char *dv; \ + dv = (unsigned char *)&v; \ + dv[0] = *(svr->buf + offset + s + 0); \ + dv[1] = *(svr->buf + offset + s + 1); \ + d = (int)ntohs(v); \ + s += 2; \ + } \ + else if (md >= DLT_ADD8) \ + { \ + unsigned char v; \ + unsigned char *dv; \ + dv = (unsigned char *)&v; \ + dv[0] = *(svr->buf + offset + s + 0); \ + d = (int)v; \ + s += 1; \ + } \ + msg._member = _ecore_ipc_ddlt_int(d, svr->prev.i._member, md); + +static int +_ecore_ipc_event_server_data(void *data __UNUSED__, int ev_type __UNUSED__, void *ev) +{ + Ecore_Con_Event_Server_Data *e; + + e = ev; + if (!_ecore_list_find(servers, ecore_con_server_data_get(e->server))) return 1; + /* handling code here */ + { + Ecore_Ipc_Server *svr; + Ecore_Ipc_Msg_Head msg; + int offset = 0; + unsigned char *buf; + + svr = ecore_con_server_data_get(e->server); + + if (!svr->buf) + { + svr->buf_size = e->size; + svr->buf = e->data; + e->data = NULL; /* take it out of the old event */ + } + else + { + unsigned char *buf; + + buf = realloc(svr->buf, svr->buf_size + e->size); + if (!buf) + { + free(svr->buf); + svr->buf = 0; + svr->buf_size = 0; + return 0; + } + svr->buf = buf; + memcpy(svr->buf + svr->buf_size, e->data, e->size); + svr->buf_size += e->size; + } + /* examine header */ + redo: + if ((svr->buf_size - offset) >= (int)sizeof(int)) + { + int s, md, d, head; + unsigned char *dd; + + dd = (unsigned char *)&head; + dd[0] = *(svr->buf + offset + 0); + dd[1] = *(svr->buf + offset + 1); + dd[2] = *(svr->buf + offset + 2); + dd[3] = *(svr->buf + offset + 3); + head = ntohl(head); + dd = (unsigned char *)&d; + s = 4; + SVSZ(0); + SVSZ(1); + SVSZ(2); + SVSZ(3); + SVSZ(4); + SVSZ(5); + if ((svr->buf_size - offset) < s) + { + if (offset > 0) goto scroll; + return 0; + } + + s = 4; + SVDEC(0, major); + SVDEC(1, minor); + SVDEC(2, ref); + SVDEC(3, ref_to); + SVDEC(4, response); + SVDEC(5, size); + if (msg.size < 0) msg.size = 0; + /* there is enough data in the buffer for a full message */ + if ((svr->buf_size - offset) >= (s + msg.size)) + { + Ecore_Ipc_Event_Server_Data *e2; + + buf = NULL; + if (msg.size > 0) + { + buf = malloc(msg.size); + if (!buf) return 0; + memcpy(buf, svr->buf + offset + s, msg.size); + } + e2 = calloc(1, sizeof(Ecore_Ipc_Event_Server_Data)); + if (e2) + { + e2->server = svr; + e2->major = msg.major; + e2->minor = msg.minor; + e2->ref = msg.ref; + e2->ref_to = msg.ref_to; + e2->response = msg.response; + e2->size = msg.size; + e2->data = buf; + ecore_event_add(ECORE_IPC_EVENT_SERVER_DATA, e2, + _ecore_ipc_event_server_data_free, NULL); + } + svr->prev.i = msg; + offset += (s + msg.size); + if (svr->buf_size == offset) + { + free(svr->buf); + svr->buf = NULL; + svr->buf_size = 0; + return 0; + } + goto redo; + } + else goto scroll; + } + else + { + scroll: + buf = malloc(svr->buf_size - offset); + if (!buf) + { + free(svr->buf); + svr->buf = NULL; + svr->buf_size = 0; + return 0; + } + memcpy(buf, svr->buf + offset, svr->buf_size - offset); + free(svr->buf); + svr->buf = buf; + svr->buf_size -= offset; + } + } + return 0; +} + +static void +_ecore_ipc_event_client_data_free(void *data __UNUSED__, void *ev) +{ + Ecore_Ipc_Event_Client_Data *e; + + e = ev; + if (e->data) free(e->data); + free(e); +} + +static void +_ecore_ipc_event_server_data_free(void *data __UNUSED__, void *ev) +{ + Ecore_Ipc_Event_Server_Data *e; + + e = ev; + if (e->data) free(e->data); + free(e); +} diff --git a/ecore/src/lib/ecore_ipc/ecore_ipc_private.h b/ecore/src/lib/ecore_ipc/ecore_ipc_private.h new file mode 100644 index 0000000..0e4d6ea --- /dev/null +++ b/ecore/src/lib/ecore_ipc/ecore_ipc_private.h @@ -0,0 +1,66 @@ +#ifndef _ECORE_IPC_PRIVATE_H +#define _ECORE_IPC_PRIVATE_H + +#if USE_OPENSSL +#include +#endif + +#define ECORE_MAGIC_IPC_SERVER 0x87786556 +#define ECORE_MAGIC_IPC_CLIENT 0x78875665 + +typedef struct _Ecore_Ipc_Client Ecore_Ipc_Client; +typedef struct _Ecore_Ipc_Server Ecore_Ipc_Server; +typedef struct _Ecore_Ipc_Msg_Head Ecore_Ipc_Msg_Head; + + +#ifdef __sgi +#pragma pack 4 +#endif +struct _Ecore_Ipc_Msg_Head +{ + int head; + int major; + int minor; + int ref; + int ref_to; + int response; + int size; +} +#ifdef _GNU_C_ +__attribute__ ((packed)); +#endif +; +#ifdef __sgi +#pragma pack 0 +#endif + +struct _Ecore_Ipc_Client +{ + Ecore_List __list_data; + ECORE_MAGIC; + Ecore_Con_Client *client; + void *data; + unsigned char *buf; + int buf_size; + + struct { + Ecore_Ipc_Msg_Head i, o; + } prev; +}; + +struct _Ecore_Ipc_Server +{ + Ecore_List __list_data; + ECORE_MAGIC; + Ecore_Con_Server *server; + Ecore_Ipc_Client *clients; + void *data; + unsigned char *buf; + int buf_size; + + struct { + Ecore_Ipc_Msg_Head i, o; + } prev; +}; + +#endif diff --git a/ecore/src/lib/ecore_job/.cvsignore b/ecore/src/lib/ecore_job/.cvsignore new file mode 100644 index 0000000..0aac4af --- /dev/null +++ b/ecore/src/lib/ecore_job/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +ecore_job.lo +libecore_job.la diff --git a/ecore/src/lib/ecore_job/CVS/Entries b/ecore/src/lib/ecore_job/CVS/Entries new file mode 100644 index 0000000..93e034b --- /dev/null +++ b/ecore/src/lib/ecore_job/CVS/Entries @@ -0,0 +1,6 @@ +/.cvsignore/1.1/Thu Nov 13 12:30:47 2003//THEAD +/Ecore_Job.h/1.4/Thu Nov 25 05:17:17 2004//THEAD +/Makefile.am/1.6/Thu Mar 10 15:19:41 2005//THEAD +/ecore_job.c/1.7/Wed Mar 2 07:06:42 2005//THEAD +/ecore_job_private.h/1.2/Tue Sep 23 08:09:31 2003//THEAD +D diff --git a/ecore/src/lib/ecore_job/CVS/Repository b/ecore/src/lib/ecore_job/CVS/Repository new file mode 100644 index 0000000..65ef847 --- /dev/null +++ b/ecore/src/lib/ecore_job/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/src/lib/ecore_job diff --git a/ecore/src/lib/ecore_job/CVS/Root b/ecore/src/lib/ecore_job/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/src/lib/ecore_job/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/src/lib/ecore_job/CVS/Tag b/ecore/src/lib/ecore_job/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/src/lib/ecore_job/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/src/lib/ecore_job/Ecore_Job.h b/ecore/src/lib/ecore_job/Ecore_Job.h new file mode 100644 index 0000000..e676ede --- /dev/null +++ b/ecore/src/lib/ecore_job/Ecore_Job.h @@ -0,0 +1,41 @@ +#ifndef _ECORE_JOB_H +#define _ECORE_JOB_H + +#ifdef EAPI +#undef EAPI +#endif +#ifdef WIN32 +# ifdef BUILDING_DLL +# define EAPI __declspec(dllexport) +# else +# define EAPI __declspec(dllimport) +# endif +#else +# ifdef GCC_HASCLASSVISIBILITY +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +#endif + +/** + * @file + * @brief Functions for dealing with Ecore jobs. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ECORE_JOB_PRIVATE_H +typedef void Ecore_Job; /**< A job handle */ +#endif + +EAPI Ecore_Job *ecore_job_add(void (*func) (void *data), const void *data); +EAPI void *ecore_job_del(Ecore_Job *job); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ecore/src/lib/ecore_job/Makefile.am b/ecore/src/lib/ecore_job/Makefile.am new file mode 100644 index 0000000..476b7c0 --- /dev/null +++ b/ecore/src/lib/ecore_job/Makefile.am @@ -0,0 +1,31 @@ +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore + +libecore_job_la_LDFLAGS = -version-info 1:0:0 \ +-L$(top_builddir)/src/lib/ecore/.libs + +if BUILD_ECORE_JOB + +lib_LTLIBRARIES = libecore_job.la +include_HEADERS = \ +Ecore_Job.h + +libecore_job_la_SOURCES = \ +ecore_job.c \ +ecore_job_private.h + +libecore_job_la_LIBADD = \ +$(top_builddir)/src/lib/ecore/libecore.la + +libecore_job_la_DEPENDENCIES = \ +$(top_builddir)/src/lib/ecore/libecore.la + +endif + +EXTRA_DIST = \ +Ecore_Job.h \ +ecore_job.c \ +ecore_job_private.h diff --git a/ecore/src/lib/ecore_job/ecore_job.c b/ecore/src/lib/ecore_job/ecore_job.c new file mode 100644 index 0000000..b4fba2a --- /dev/null +++ b/ecore/src/lib/ecore_job/ecore_job.c @@ -0,0 +1,86 @@ +#include "Ecore.h" +#include "ecore_private.h" +#include "ecore_job_private.h" +#include "Ecore_Job.h" + +static int _ecore_job_event_handler(void *data, int type, void *ev); +static void _ecore_job_event_free(void *data, void *ev); + +static int ecore_event_job_type = 0; + +/** + * Add a job to the event queue. + * @param func The function to call when the job gets handled. + * @param data Data pointer to be passed to the job function when the job is + * handled. + * @return The handle of the job. @c NULL is returned if the job could not be + * added to the queue. + * @ingroup Ecore_Job_Group + * @note Once the job has been executed, the job handle is invalid. + */ +Ecore_Job * +ecore_job_add(void (*func) (void *data), const void *data) +{ + Ecore_Job *job; + + if (!func) return NULL; + if (!ecore_event_job_type) + { + ecore_event_job_type = ecore_event_type_new(); + ecore_event_handler_add(ecore_event_job_type, _ecore_job_event_handler, NULL); + } + job = calloc(1, sizeof(Ecore_Job)); + if (!job) return NULL; + ECORE_MAGIC_SET(job, ECORE_MAGIC_JOB); + job->event = ecore_event_add(ecore_event_job_type, job, _ecore_job_event_free, NULL); + if (!job->event) + { + free(job); + return NULL; + } + job->func = func; + job->data = (void *)data; + return job; +} + +/** + * Delete a queued job that has not yet been executed. + * @param job Handle of the job to delete. + * @return The data pointer that was to be passed to the job. + * @ingroup Ecore_Job_Group + */ +void * +ecore_job_del(Ecore_Job *job) +{ + void *data; + + if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_JOB)) + { + ECORE_MAGIC_FAIL(job, ECORE_MAGIC_JOB, + "ecore_job_del"); + return NULL; + } + data = job->data; + ECORE_MAGIC_SET(job, ECORE_MAGIC_NONE); + ecore_event_del(job->event); + return data; +} + +static int +_ecore_job_event_handler(void *data __UNUSED__, int type __UNUSED__, void *ev) +{ + Ecore_Job *job; + + job = ev; + job->func(job->data); + return 0; +} + +static void +_ecore_job_event_free(void *data __UNUSED__, void *ev) +{ + Ecore_Job *job; + + job = ev; + free(ev); +} diff --git a/ecore/src/lib/ecore_job/ecore_job_private.h b/ecore/src/lib/ecore_job/ecore_job_private.h new file mode 100644 index 0000000..d5795f2 --- /dev/null +++ b/ecore/src/lib/ecore_job/ecore_job_private.h @@ -0,0 +1,16 @@ +#ifndef _ECORE_JOB_PRIVATE_H +#define _ECORE_JOB_PRIVATE_H + +#define ECORE_MAGIC_JOB 0x76543210 + +typedef struct _Ecore_Job Ecore_Job; + +struct _Ecore_Job +{ + ECORE_MAGIC; + Ecore_Event *event; + void (*func) (void *data); + void *data; +}; + +#endif diff --git a/ecore/src/lib/ecore_txt/.cvsignore b/ecore/src/lib/ecore_txt/.cvsignore new file mode 100644 index 0000000..e599172 --- /dev/null +++ b/ecore/src/lib/ecore_txt/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +ecore_txt.lo +libecore_txt.la diff --git a/ecore/src/lib/ecore_txt/CVS/Entries b/ecore/src/lib/ecore_txt/CVS/Entries new file mode 100644 index 0000000..bdeacd8 --- /dev/null +++ b/ecore/src/lib/ecore_txt/CVS/Entries @@ -0,0 +1,6 @@ +/.cvsignore/1.2/Fri Jan 16 16:59:05 2004//THEAD +/Ecore_Txt.h/1.4/Mon Nov 29 22:26:30 2004//THEAD +/Makefile.am/1.5/Thu Mar 10 15:19:42 2005//THEAD +/ecore_txt.c/1.6/Wed Mar 2 07:06:42 2005//THEAD +/ecore_txt_private.h/1.1/Thu Oct 9 07:49:59 2003//THEAD +D diff --git a/ecore/src/lib/ecore_txt/CVS/Repository b/ecore/src/lib/ecore_txt/CVS/Repository new file mode 100644 index 0000000..6d66175 --- /dev/null +++ b/ecore/src/lib/ecore_txt/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/src/lib/ecore_txt diff --git a/ecore/src/lib/ecore_txt/CVS/Root b/ecore/src/lib/ecore_txt/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/src/lib/ecore_txt/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/src/lib/ecore_txt/CVS/Tag b/ecore/src/lib/ecore_txt/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/src/lib/ecore_txt/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/src/lib/ecore_txt/Ecore_Txt.h b/ecore/src/lib/ecore_txt/Ecore_Txt.h new file mode 100644 index 0000000..60dc659 --- /dev/null +++ b/ecore/src/lib/ecore_txt/Ecore_Txt.h @@ -0,0 +1,36 @@ +#ifndef _ECORE_TXT_H +#define _ECORE_TXT_H + +#ifdef EAPI +#undef EAPI +#endif +#ifdef WIN32 +# ifdef BUILDING_DLL +# define EAPI __declspec(dllexport) +# else +# define EAPI __declspec(dllimport) +# endif +#else +# ifdef GCC_HASCLASSVISIBILITY +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +#endif + +/** + * @file Ecore_Txt.h + * @brief Provides a text encoding conversion function. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +EAPI char *ecore_txt_convert(const char *enc_from, const char *enc_to, const char *text); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ecore/src/lib/ecore_txt/Makefile.am b/ecore/src/lib/ecore_txt/Makefile.am new file mode 100644 index 0000000..e3fdd01 --- /dev/null +++ b/ecore/src/lib/ecore_txt/Makefile.am @@ -0,0 +1,34 @@ +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore \ +@iconv_cflags@ + +libecore_txt_la_LDFLAGS = -version-info 1:0:0 \ +-L$(top_builddir)/src/lib/ecore/.libs + +if BUILD_ECORE_TXT + +lib_LTLIBRARIES = libecore_txt.la +include_HEADERS = \ +Ecore_Txt.h + +libecore_txt_la_SOURCES = \ +ecore_txt.c \ +ecore_txt_private.h + +# FIXME: may have to link with -liconv +libecore_txt_la_LIBADD = \ +@iconv_libs@ + + +libecore_txt_la_DEPENDENCIES = + + +endif + +EXTRA_DIST = \ +Ecore_Txt.h \ +ecore_txt.c \ +ecore_txt_private.h diff --git a/ecore/src/lib/ecore_txt/ecore_txt.c b/ecore/src/lib/ecore_txt/ecore_txt.c new file mode 100644 index 0000000..cab8f5d --- /dev/null +++ b/ecore/src/lib/ecore_txt/ecore_txt.c @@ -0,0 +1,78 @@ +#include "ecore_txt_private.h" +#include "Ecore_Txt.h" + +#include +#include +#include +#include +#include +#include + +/** + * To be documented. + * + * FIXME: Finish this. + */ +char * +ecore_txt_convert(const char *enc_from, const char *enc_to, const char *text) +{ + iconv_t ic; + char *new_txt, *inp, *outp; + size_t inb, outb, outlen, tob, outalloc; + + if (!text) return strdup(""); + ic = iconv_open(enc_to, enc_from); + if (!ic) return strdup(""); + new_txt = malloc(64); + inb = strlen(text); + outb = 64; + inp = (char*)text; + outp = new_txt; + outalloc = 64; + outlen = 0; + tob = 0; + + for (;;) + { + size_t count; + + tob = outb; + count = iconv(ic, &inp, &inb, &outp, &outb); + outlen += tob - outb; + if (count == (size_t)(-1)) + { + if (errno == E2BIG) + { + new_txt = realloc(new_txt, outalloc + 64); + outalloc += 64; + outb += 64; + } + else if (errno == EILSEQ) + { + if (new_txt) free(new_txt); + new_txt = NULL; + break; + } + else if (errno == EINVAL) + { + if (new_txt) free(new_txt); + new_txt = NULL; + break; + } + else + { + if (new_txt) free(new_txt); + new_txt = NULL; + break; + } + } + if (inb == 0) + { + if (outalloc == outlen) new_txt = realloc(new_txt, outalloc + 1); + new_txt[outlen] = 0; + break; + } + } + iconv_close(ic); + return new_txt; +} diff --git a/ecore/src/lib/ecore_txt/ecore_txt_private.h b/ecore/src/lib/ecore_txt/ecore_txt_private.h new file mode 100644 index 0000000..b3e975a --- /dev/null +++ b/ecore/src/lib/ecore_txt/ecore_txt_private.h @@ -0,0 +1,4 @@ +#ifndef _ECORE_TXT_PRIVATE_H +#define _ECORE_TXT_PRIVATE_H + +#endif diff --git a/ecore/src/lib/ecore_x/.cvsignore b/ecore/src/lib/ecore_x/.cvsignore new file mode 100644 index 0000000..8728e80 --- /dev/null +++ b/ecore/src/lib/ecore_x/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +*.lo +libecore_x.la diff --git a/ecore/src/lib/ecore_x/CVS/Entries b/ecore/src/lib/ecore_x/CVS/Entries new file mode 100644 index 0000000..907365e --- /dev/null +++ b/ecore/src/lib/ecore_x/CVS/Entries @@ -0,0 +1,23 @@ +/.cvsignore/1.4/Tue Sep 21 19:18:44 2004//THEAD +/Ecore_X.h/1.138/Sat Jun 25 07:23:38 2005//THEAD +/Ecore_X_Atoms.h/1.10/Mon Jun 6 15:04:28 2005//THEAD +/Ecore_X_Cursor.h/1.2/Fri Apr 30 03:10:17 2004//THEAD +/Makefile.am/1.23/Mon Jun 6 09:40:00 2005//THEAD +/ecore_x.c/1.91/Tue Jul 12 15:27:45 2005//THEAD +/ecore_x_dnd.c/1.20/Sun Apr 10 10:20:18 2005//THEAD +/ecore_x_e.c/1.2/Mon May 16 12:59:26 2005//THEAD +/ecore_x_error.c/1.5/Wed Jun 22 06:47:44 2005//THEAD +/ecore_x_events.c/1.68/Tue Jul 12 15:27:46 2005//THEAD +/ecore_x_gc.c/1.4/Thu Jul 15 13:43:15 2004//THEAD +/ecore_x_icccm.c/1.34/Fri Jun 17 09:05:22 2005//THEAD +/ecore_x_mwm.c/1.4/Fri Jun 10 04:18:24 2005//THEAD +/ecore_x_netwm.c/1.36/Fri Jun 10 04:18:24 2005//THEAD +/ecore_x_pixmap.c/1.5/Thu Aug 12 11:29:18 2004//THEAD +/ecore_x_private.h/1.46/Tue Jul 12 15:27:46 2005//THEAD +/ecore_x_selection.c/1.26/Mon May 16 12:59:26 2005//THEAD +/ecore_x_sync.c/1.2/Mon Jun 6 15:04:28 2005//THEAD +/ecore_x_window.c/1.41/Sat Jun 25 07:23:38 2005//THEAD +/ecore_x_window_prop.c/1.72/Sat Jun 25 00:15:19 2005//THEAD +/ecore_x_window_shape.c/1.6/Sat Apr 23 05:06:18 2005//THEAD +/ecore_x_xinerama.c/1.2/Sat Feb 5 12:59:35 2005//THEAD +D diff --git a/ecore/src/lib/ecore_x/CVS/Repository b/ecore/src/lib/ecore_x/CVS/Repository new file mode 100644 index 0000000..df9cfee --- /dev/null +++ b/ecore/src/lib/ecore_x/CVS/Repository @@ -0,0 +1 @@ +e17/libs/ecore/src/lib/ecore_x diff --git a/ecore/src/lib/ecore_x/CVS/Root b/ecore/src/lib/ecore_x/CVS/Root new file mode 100644 index 0000000..0b69fe3 --- /dev/null +++ b/ecore/src/lib/ecore_x/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sourceforge.net:/cvsroot/enlightenment diff --git a/ecore/src/lib/ecore_x/CVS/Tag b/ecore/src/lib/ecore_x/CVS/Tag new file mode 100644 index 0000000..3903919 --- /dev/null +++ b/ecore/src/lib/ecore_x/CVS/Tag @@ -0,0 +1 @@ +NHEAD diff --git a/ecore/src/lib/ecore_x/Ecore_X.h b/ecore/src/lib/ecore_x/Ecore_X.h new file mode 100644 index 0000000..68ff1dd --- /dev/null +++ b/ecore/src/lib/ecore_x/Ecore_X.h @@ -0,0 +1,1320 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ + +#ifndef _ECORE_X_H +#define _ECORE_X_H + +#ifdef EAPI +#undef EAPI +#endif +#ifdef WIN32 +# ifdef BUILDING_DLL +# define EAPI __declspec(dllexport) +# else +# define EAPI __declspec(dllimport) +# endif +#else +# ifdef GCC_HASCLASSVISIBILITY +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +#endif + +/** + * @file + * @brief Ecore functions for dealing with the X Windows System + * + * Ecore_X provides a wrapper and convenience functions for using the + * X Windows System. Function groups for this part of the library + * include the following: + * @li @ref Ecore_X_Init_Group + * @li @ref Ecore_X_Display_Attr_Group + * @li @ref Ecore_X_Flush_Group + */ + +typedef unsigned int Ecore_X_ID; +#ifndef _ECORE_X_WINDOW_PREDEF +typedef Ecore_X_ID Ecore_X_Window; +#endif +typedef Ecore_X_ID Ecore_X_Pixmap; +typedef Ecore_X_ID Ecore_X_Drawable; +typedef void * Ecore_X_GC; +typedef Ecore_X_ID Ecore_X_Atom; +typedef Ecore_X_ID Ecore_X_Colormap; +typedef Ecore_X_ID Ecore_X_Time; +typedef Ecore_X_ID Ecore_X_Cursor; +typedef void Ecore_X_Display; +typedef Ecore_X_ID Ecore_X_Sync_Counter; +typedef Ecore_X_ID Ecore_X_Sync_Alarm; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _Ecore_X_Rectangle { + int x, y; + unsigned int width, height; +} Ecore_X_Rectangle; + +typedef enum _Ecore_X_Window_State { + /** The window is iconified. */ + ECORE_X_WINDOW_STATE_ICONIFIED, + + /** The window is a modal dialog box. */ + ECORE_X_WINDOW_STATE_MODAL, + + /** The window manager should keep the window's position fixed + * even if the virtual desktop scrolls. */ + ECORE_X_WINDOW_STATE_STICKY, + + /** The window has the maximum vertical size. */ + ECORE_X_WINDOW_STATE_MAXIMIZED_VERT, + + /** The window has the maximum horizontal size. */ + ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ, + + /** The window is shaded. */ + ECORE_X_WINDOW_STATE_SHADED, + + /** The window should not be included in the taskbar. */ + ECORE_X_WINDOW_STATE_SKIP_TASKBAR, + + /** The window should not be included in the pager. */ + ECORE_X_WINDOW_STATE_SKIP_PAGER, + + /** The window is invisible (i.e. minimized/iconified) */ + ECORE_X_WINDOW_STATE_HIDDEN, + + /** The window should fill the entire screen and have no + * window border/decorations */ + ECORE_X_WINDOW_STATE_FULLSCREEN, + + /* The following are not documented because they are not + * intended for use in applications. */ + ECORE_X_WINDOW_STATE_ABOVE, + ECORE_X_WINDOW_STATE_BELOW, + + /* FIXME: Documentation */ + ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION, + + /* Unknown state */ + ECORE_X_WINDOW_STATE_UNKNOWN + +} Ecore_X_Window_State; + +typedef enum _Ecore_X_Window_State_Action { + ECORE_X_WINDOW_STATE_ACTION_REMOVE, + ECORE_X_WINDOW_STATE_ACTION_ADD, + ECORE_X_WINDOW_STATE_ACTION_TOGGLE +} Ecore_X_Window_State_Action; + +typedef enum _Ecore_X_Window_Stack_Mode { + ECORE_X_WINDOW_STACK_ABOVE = 0, + ECORE_X_WINDOW_STACK_BELOW = 1, + ECORE_X_WINDOW_STACK_TOP_IF = 2, + ECORE_X_WINDOW_STACK_BOTTOM_IF = 3, + ECORE_X_WINDOW_STACK_OPPOSITE = 4 +} Ecore_X_Window_Stack_Mode; + +#define ECORE_X_SELECTION_TARGET_TARGETS "TARGETS" +#define ECORE_X_SELECTION_TARGET_TEXT "TEXT" +#define ECORE_X_SELECTION_TARGET_COMPOUND_TEXT "COMPOUND_TEXT" +#define ECORE_X_SELECTION_TARGET_STRING "STRING" +#define ECORE_X_SELECTION_TARGET_UTF8_STRING "UTF8_STRING" +#define ECORE_X_SELECTION_TARGET_FILENAME "FILENAME" + +#define ECORE_X_DND_VERSION 5 + +extern EAPI Ecore_X_Atom ECORE_X_DND_ACTION_COPY; +extern EAPI Ecore_X_Atom ECORE_X_DND_ACTION_MOVE; +extern EAPI Ecore_X_Atom ECORE_X_DND_ACTION_LINK; +extern EAPI Ecore_X_Atom ECORE_X_DND_ACTION_ASK; +extern EAPI Ecore_X_Atom ECORE_X_DND_ACTION_PRIVATE; + +typedef enum _Ecore_X_Selection { + ECORE_X_SELECTION_PRIMARY, + ECORE_X_SELECTION_SECONDARY, + ECORE_X_SELECTION_XDND, + ECORE_X_SELECTION_CLIPBOARD +} Ecore_X_Selection; + +typedef enum _Ecore_X_Event_Mode +{ + ECORE_X_EVENT_MODE_NORMAL, + ECORE_X_EVENT_MODE_WHILE_GRABBED, + ECORE_X_EVENT_MODE_GRAB, + ECORE_X_EVENT_MODE_UNGRAB +} Ecore_X_Event_Mode; + +typedef enum _Ecore_X_Event_Detail +{ + ECORE_X_EVENT_DETAIL_ANCESTOR, + ECORE_X_EVENT_DETAIL_VIRTUAL, + ECORE_X_EVENT_DETAIL_INFERIOR, + ECORE_X_EVENT_DETAIL_NON_LINEAR, + ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL, + ECORE_X_EVENT_DETAIL_POINTER, + ECORE_X_EVENT_DETAIL_POINTER_ROOT, + ECORE_X_EVENT_DETAIL_DETAIL_NONE +} Ecore_X_Event_Detail; + +typedef enum _Ecore_X_Event_Mask +{ + ECORE_X_EVENT_MASK_NONE = 0L, + ECORE_X_EVENT_MASK_KEY_DOWN = (1L << 0), + ECORE_X_EVENT_MASK_KEY_UP = (1L << 1), + ECORE_X_EVENT_MASK_MOUSE_DOWN = (1L << 2), + ECORE_X_EVENT_MASK_MOUSE_UP = (1L << 3), + ECORE_X_EVENT_MASK_MOUSE_IN = (1L << 4), + ECORE_X_EVENT_MASK_MOUSE_OUT = (1L << 5), + ECORE_X_EVENT_MASK_MOUSE_MOVE = (1L << 6), + ECORE_X_EVENT_MASK_WINDOW_DAMAGE = (1L << 15), + ECORE_X_EVENT_MASK_WINDOW_VISIBILITY = (1L << 16), + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE = (1L << 17), + ECORE_X_EVENT_MASK_WINDOW_RESIZE_MANAGE = (1L << 18), + ECORE_X_EVENT_MASK_WINDOW_MANAGE = (1L << 19), + ECORE_X_EVENT_MASK_WINDOW_CHILD_CONFIGURE = (1L << 20), + ECORE_X_EVENT_MASK_WINDOW_FOCUS_CHANGE = (1L << 21), + ECORE_X_EVENT_MASK_WINDOW_PROPERTY = (1L << 22), + ECORE_X_EVENT_MASK_WINDOW_COLORMAP = (1L << 23), + ECORE_X_EVENT_MASK_WINDOW_GRAB = (1L << 24), + ECORE_X_EVENT_MASK_MOUSE_WHEEL = (1L << 29), + ECORE_X_EVENT_MASK_WINDOW_FOCUS_IN = (1L << 30), + ECORE_X_EVENT_MASK_WINDOW_FOCUS_OUT = (1L << 31) +} Ecore_X_Event_Mask; + +typedef enum _Ecore_X_Gravity { + ECORE_X_GRAVITY_FORGET = 0, + ECORE_X_GRAVITY_UNMAP = 0, + ECORE_X_GRAVITY_NW = 1, + ECORE_X_GRAVITY_N = 2, + ECORE_X_GRAVITY_NE = 3, + ECORE_X_GRAVITY_W = 4, + ECORE_X_GRAVITY_CENTER = 5, + ECORE_X_GRAVITY_E = 6, + ECORE_X_GRAVITY_SW = 7, + ECORE_X_GRAVITY_S = 8, + ECORE_X_GRAVITY_SE = 9, + ECORE_X_GRAVITY_STATIC = 10 +} Ecore_X_Gravity; + +typedef struct _Ecore_X_Event_Key_Down Ecore_X_Event_Key_Down; +typedef struct _Ecore_X_Event_Key_Up Ecore_X_Event_Key_Up; +typedef struct _Ecore_X_Event_Mouse_Button_Down Ecore_X_Event_Mouse_Button_Down; +typedef struct _Ecore_X_Event_Mouse_Button_Up Ecore_X_Event_Mouse_Button_Up; +typedef struct _Ecore_X_Event_Mouse_Move Ecore_X_Event_Mouse_Move; +typedef struct _Ecore_X_Event_Mouse_In Ecore_X_Event_Mouse_In; +typedef struct _Ecore_X_Event_Mouse_Out Ecore_X_Event_Mouse_Out; +typedef struct _Ecore_X_Event_Mouse_Wheel Ecore_X_Event_Mouse_Wheel; +typedef struct _Ecore_X_Event_Window_Focus_In Ecore_X_Event_Window_Focus_In; +typedef struct _Ecore_X_Event_Window_Focus_Out Ecore_X_Event_Window_Focus_Out; +typedef struct _Ecore_X_Event_Window_Keymap Ecore_X_Event_Window_Keymap; +typedef struct _Ecore_X_Event_Window_Damage Ecore_X_Event_Window_Damage; +typedef struct _Ecore_X_Event_Window_Visibility_Change Ecore_X_Event_Window_Visibility_Change; +typedef struct _Ecore_X_Event_Window_Create Ecore_X_Event_Window_Create; +typedef struct _Ecore_X_Event_Window_Destroy Ecore_X_Event_Window_Destroy; +typedef struct _Ecore_X_Event_Window_Hide Ecore_X_Event_Window_Hide; +typedef struct _Ecore_X_Event_Window_Show Ecore_X_Event_Window_Show; +typedef struct _Ecore_X_Event_Window_Show_Request Ecore_X_Event_Window_Show_Request; +typedef struct _Ecore_X_Event_Window_Reparent Ecore_X_Event_Window_Reparent; +typedef struct _Ecore_X_Event_Window_Configure Ecore_X_Event_Window_Configure; +typedef struct _Ecore_X_Event_Window_Configure_Request Ecore_X_Event_Window_Configure_Request; +typedef struct _Ecore_X_Event_Window_Gravity Ecore_X_Event_Window_Gravity; +typedef struct _Ecore_X_Event_Window_Resize_Request Ecore_X_Event_Window_Resize_Request; +typedef struct _Ecore_X_Event_Window_Stack Ecore_X_Event_Window_Stack; +typedef struct _Ecore_X_Event_Window_Stack_Request Ecore_X_Event_Window_Stack_Request; +typedef struct _Ecore_X_Event_Window_Property Ecore_X_Event_Window_Property; +typedef struct _Ecore_X_Event_Window_Colormap Ecore_X_Event_Window_Colormap; +typedef struct _Ecore_X_Event_Window_Mapping Ecore_X_Event_Window_Mapping; +typedef struct _Ecore_X_Event_Selection_Clear Ecore_X_Event_Selection_Clear; +typedef struct _Ecore_X_Event_Selection_Request Ecore_X_Event_Selection_Request; +typedef struct _Ecore_X_Event_Selection_Notify Ecore_X_Event_Selection_Notify; +typedef struct _Ecore_X_Selection_Data Ecore_X_Selection_Data; +typedef struct _Ecore_X_Selection_Data_Files Ecore_X_Selection_Data_Files; +typedef struct _Ecore_X_Selection_Data_Text Ecore_X_Selection_Data_Text; +typedef struct _Ecore_X_Selection_Data_Targets Ecore_X_Selection_Data_Targets; +typedef struct _Ecore_X_Event_Xdnd_Enter Ecore_X_Event_Xdnd_Enter; +typedef struct _Ecore_X_Event_Xdnd_Position Ecore_X_Event_Xdnd_Position; +typedef struct _Ecore_X_Event_Xdnd_Status Ecore_X_Event_Xdnd_Status; +typedef struct _Ecore_X_Event_Xdnd_Leave Ecore_X_Event_Xdnd_Leave; +typedef struct _Ecore_X_Event_Xdnd_Drop Ecore_X_Event_Xdnd_Drop; +typedef struct _Ecore_X_Event_Xdnd_Finished Ecore_X_Event_Xdnd_Finished; +typedef struct _Ecore_X_Event_Client_Message Ecore_X_Event_Client_Message; +typedef struct _Ecore_X_Event_Window_Shape Ecore_X_Event_Window_Shape; +typedef struct _Ecore_X_Event_Sync_Counter Ecore_X_Event_Sync_Counter; +typedef struct _Ecore_X_Event_Sync_Alarm Ecore_X_Event_Sync_Alarm; + +typedef struct _Ecore_X_Event_Window_Delete_Request Ecore_X_Event_Window_Delete_Request; +typedef struct _Ecore_X_Event_Window_Prop_Title_Change Ecore_X_Event_Window_Prop_Title_Change; +typedef struct _Ecore_X_Event_Window_Prop_Visible_Title_Change Ecore_X_Event_Window_Prop_Visible_Title_Change; +typedef struct _Ecore_X_Event_Window_Prop_Icon_Name_Change Ecore_X_Event_Window_Prop_Icon_Name_Change; +typedef struct _Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change; +typedef struct _Ecore_X_Event_Window_Prop_Client_Machine_Change Ecore_X_Event_Window_Prop_Client_Machine_Change; +typedef struct _Ecore_X_Event_Window_Prop_Name_Class_Change Ecore_X_Event_Window_Prop_Name_Class_Change; +typedef struct _Ecore_X_Event_Window_Prop_Pid_Change Ecore_X_Event_Window_Prop_Pid_Change; +typedef struct _Ecore_X_Event_Window_Prop_Desktop_Change Ecore_X_Event_Window_Prop_Desktop_Change; + +typedef struct _Ecore_X_Event_Window_Move_Resize_Request Ecore_X_Event_Window_Move_Resize_Request; +typedef struct _Ecore_X_Event_Window_State_Request Ecore_X_Event_Window_State_Request; +typedef struct _Ecore_X_Event_Frame_Extents_Request Ecore_X_Event_Frame_Extents_Request; +typedef struct _Ecore_X_Event_Ping Ecore_X_Event_Ping; +typedef struct _Ecore_X_Event_Desktop_Change Ecore_X_Event_Desktop_Change; + +struct _Ecore_X_Event_Key_Down +{ + char *keyname; + char *keysymbol; + char *key_compose; + int modifiers; + Ecore_X_Window win; + Ecore_X_Window event_win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Key_Up +{ + char *keyname; + char *keysymbol; + char *key_compose; + int modifiers; + Ecore_X_Window win; + Ecore_X_Window event_win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Mouse_Button_Down +{ + int button; + int modifiers; + int x, y; + struct { + int x, y; + } root; + Ecore_X_Window win; + Ecore_X_Window event_win; + Ecore_X_Time time; + int double_click : 1; + int triple_click : 1; +}; + +struct _Ecore_X_Event_Mouse_Button_Up +{ + int button; + int modifiers; + int x, y; + struct { + int x, y; + } root; + Ecore_X_Window win; + Ecore_X_Window event_win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Mouse_Move +{ + int modifiers; + int x, y; + struct { + int x, y; + } root; + Ecore_X_Window win; + Ecore_X_Window event_win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Mouse_In +{ + int modifiers; + int x, y; + struct { + int x, y; + } root; + Ecore_X_Window win; + Ecore_X_Window event_win; + Ecore_X_Event_Mode mode; + Ecore_X_Event_Detail detail; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Mouse_Out +{ + int modifiers; + int x, y; + struct { + int x, y; + } root; + Ecore_X_Window win; + Ecore_X_Window event_win; + Ecore_X_Event_Mode mode; + Ecore_X_Event_Detail detail; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Mouse_Wheel +{ + int direction; /* 0 = default up/down wheel FIXME: more wheel types */ + int z; /* ...,-2,-1 = down, 1,2,... = up */ + int modifiers; + int x, y; + + struct { + int x, y; + } root; + + Ecore_X_Window win; + Ecore_X_Window event_win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Focus_In +{ + Ecore_X_Window win; + Ecore_X_Event_Mode mode; + Ecore_X_Event_Detail detail; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Focus_Out +{ + Ecore_X_Window win; + Ecore_X_Event_Mode mode; + Ecore_X_Event_Detail detail; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Keymap +{ + Ecore_X_Window win; +}; + +struct _Ecore_X_Event_Window_Damage +{ + Ecore_X_Window win; + int x, y, w, h; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Visibility_Change +{ + Ecore_X_Window win; + int fully_obscured; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Create +{ + Ecore_X_Window win; + int override; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Destroy +{ + Ecore_X_Window win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Hide +{ + Ecore_X_Window win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Show +{ + Ecore_X_Window win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Show_Request +{ + Ecore_X_Window win; + Ecore_X_Window parent; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Reparent +{ + Ecore_X_Window win; + Ecore_X_Window parent; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Configure +{ + Ecore_X_Window win; + Ecore_X_Window abovewin; + int x, y, w, h; + int border; + int override : 1; + int from_wm : 1; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Configure_Request +{ + Ecore_X_Window win; + Ecore_X_Window abovewin; + int x, y, w, h; + int border; + Ecore_X_Window_Stack_Mode detail; + unsigned long value_mask; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Gravity +{ + Ecore_X_Window win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Resize_Request +{ + Ecore_X_Window win; + int w, h; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Stack +{ + Ecore_X_Window win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Stack_Request +{ + Ecore_X_Window win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Property +{ + Ecore_X_Window win; + Ecore_X_Atom atom; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Colormap +{ + Ecore_X_Window win; + Ecore_X_Colormap cmap; + int installed; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Selection_Clear +{ + Ecore_X_Window win; + Ecore_X_Selection selection; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Selection_Request +{ + Ecore_X_Window win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Selection_Notify +{ + Ecore_X_Window win; + Ecore_X_Time time; + Ecore_X_Selection selection; + char *target; + void *data; + enum { + ECORE_X_SELECTION_CONTENT_NONE, + ECORE_X_SELECTION_CONTENT_TEXT, + ECORE_X_SELECTION_CONTENT_FILES, + ECORE_X_SELECTION_CONTENT_TARGETS, + ECORE_X_SELECTION_CONTENT_CUSTOM + } content; +}; + +struct _Ecore_X_Selection_Data +{ + unsigned char *data; + int length; + + int (*free)(void *data); +}; + +struct _Ecore_X_Selection_Data_Files +{ + Ecore_X_Selection_Data data; + char **files; + int num_files; +}; + +struct _Ecore_X_Selection_Data_Text +{ + Ecore_X_Selection_Data data; + char *text; +}; + +struct _Ecore_X_Selection_Data_Targets +{ + Ecore_X_Selection_Data data; + char **targets; + int num_targets; +}; + +struct _Ecore_X_Event_Xdnd_Enter +{ + Ecore_X_Window win, source; + + char **types; + int num_types; +}; + +struct _Ecore_X_Event_Xdnd_Position +{ + Ecore_X_Window win, source; + struct { + int x, y; + } position; + Ecore_X_Atom action; +}; + +struct _Ecore_X_Event_Xdnd_Status +{ + Ecore_X_Window win, target; + int will_accept; + Ecore_X_Rectangle rectangle; + Ecore_X_Atom action; +}; + +struct _Ecore_X_Event_Xdnd_Leave +{ + Ecore_X_Window win, source; +}; + +struct _Ecore_X_Event_Xdnd_Drop +{ + Ecore_X_Window win, source; + Ecore_X_Atom action; + struct { + int x, y; + } position; +}; + +struct _Ecore_X_Event_Xdnd_Finished +{ + Ecore_X_Window win, target; + int completed; + Ecore_X_Atom action; +}; + +struct _Ecore_X_Event_Client_Message +{ + Ecore_X_Window win; + Ecore_X_Atom message_type; + int format; + union { + char b[20]; + short s[10]; + long l[5]; + } data; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Shape +{ + Ecore_X_Window win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Sync_Counter +{ + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Sync_Alarm +{ + Ecore_X_Time time; + Ecore_X_Sync_Alarm alarm; +}; + +struct _Ecore_X_Event_Window_Delete_Request +{ + Ecore_X_Window win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Prop_Title_Change +{ + Ecore_X_Window win; + char *title; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Prop_Visible_Title_Change +{ + Ecore_X_Window win; + char *title; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Prop_Icon_Name_Change +{ + Ecore_X_Window win; + char *name; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change +{ + Ecore_X_Window win; + char *name; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Prop_Client_Machine_Change +{ + Ecore_X_Window win; + char *name; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Prop_Name_Class_Change +{ + Ecore_X_Window win; + char *name; + char *clas; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Prop_Pid_Change +{ + Ecore_X_Window win; + pid_t pid; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Prop_Desktop_Change +{ + Ecore_X_Window win; + long desktop; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Window_Move_Resize_Request +{ + Ecore_X_Window win; + int x, y; + int direction; + int button; + int source; +}; + +struct _Ecore_X_Event_Window_State_Request +{ + Ecore_X_Window win; + Ecore_X_Window_State_Action action; + Ecore_X_Window_State state[2]; + int source; +}; + +struct _Ecore_X_Event_Frame_Extents_Request +{ + Ecore_X_Window win; +}; + +struct _Ecore_X_Event_Ping +{ + Ecore_X_Window win; + Ecore_X_Window event_win; + Ecore_X_Time time; +}; + +struct _Ecore_X_Event_Desktop_Change +{ + Ecore_X_Window win; + unsigned int desk; + int source; +}; + +extern EAPI int ECORE_X_EVENT_KEY_DOWN; +extern EAPI int ECORE_X_EVENT_KEY_UP; +extern EAPI int ECORE_X_EVENT_MOUSE_BUTTON_DOWN; +extern EAPI int ECORE_X_EVENT_MOUSE_BUTTON_UP; +extern EAPI int ECORE_X_EVENT_MOUSE_MOVE; +extern EAPI int ECORE_X_EVENT_MOUSE_IN; +extern EAPI int ECORE_X_EVENT_MOUSE_OUT; +extern EAPI int ECORE_X_EVENT_MOUSE_WHEEL; +extern EAPI int ECORE_X_EVENT_WINDOW_FOCUS_IN; +extern EAPI int ECORE_X_EVENT_WINDOW_FOCUS_OUT; +extern EAPI int ECORE_X_EVENT_WINDOW_KEYMAP; +extern EAPI int ECORE_X_EVENT_WINDOW_DAMAGE; +extern EAPI int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE; +extern EAPI int ECORE_X_EVENT_WINDOW_CREATE; +extern EAPI int ECORE_X_EVENT_WINDOW_DESTROY; +extern EAPI int ECORE_X_EVENT_WINDOW_HIDE; +extern EAPI int ECORE_X_EVENT_WINDOW_SHOW; +extern EAPI int ECORE_X_EVENT_WINDOW_SHOW_REQUEST; +extern EAPI int ECORE_X_EVENT_WINDOW_REPARENT; +extern EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE; +extern EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST; +extern EAPI int ECORE_X_EVENT_WINDOW_GRAVITY; +extern EAPI int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST; +extern EAPI int ECORE_X_EVENT_WINDOW_STACK; +extern EAPI int ECORE_X_EVENT_WINDOW_STACK_REQUEST; +extern EAPI int ECORE_X_EVENT_WINDOW_PROPERTY; +extern EAPI int ECORE_X_EVENT_WINDOW_COLORMAP; +extern EAPI int ECORE_X_EVENT_WINDOW_MAPPING; +extern EAPI int ECORE_X_EVENT_SELECTION_CLEAR; +extern EAPI int ECORE_X_EVENT_SELECTION_REQUEST; +extern EAPI int ECORE_X_EVENT_SELECTION_NOTIFY; +extern EAPI int ECORE_X_EVENT_CLIENT_MESSAGE; +extern EAPI int ECORE_X_EVENT_WINDOW_SHAPE; +extern EAPI int ECORE_X_EVENT_SYNC_COUNTER; +extern EAPI int ECORE_X_EVENT_SYNC_ALARM; + +extern EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST; +/* +extern EAPI int ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE; +extern EAPI int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE; +extern EAPI int ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE; +extern EAPI int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE; +extern EAPI int ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE; +extern EAPI int ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE; +extern EAPI int ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE; +extern EAPI int ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE; +*/ + +extern EAPI int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST; +extern EAPI int ECORE_X_EVENT_WINDOW_STATE_REQUEST; +extern EAPI int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST; +extern EAPI int ECORE_X_EVENT_PING; +extern EAPI int ECORE_X_EVENT_DESKTOP_CHANGE; + +extern EAPI int ECORE_X_EVENT_XDND_ENTER; +extern EAPI int ECORE_X_EVENT_XDND_POSITION; +extern EAPI int ECORE_X_EVENT_XDND_STATUS; +extern EAPI int ECORE_X_EVENT_XDND_LEAVE; +extern EAPI int ECORE_X_EVENT_XDND_DROP; +extern EAPI int ECORE_X_EVENT_XDND_FINISHED; + +extern EAPI int ECORE_X_MODIFIER_SHIFT; +extern EAPI int ECORE_X_MODIFIER_CTRL; +extern EAPI int ECORE_X_MODIFIER_ALT; +extern EAPI int ECORE_X_MODIFIER_WIN; + +extern EAPI int ECORE_X_LOCK_SCROLL; +extern EAPI int ECORE_X_LOCK_NUM; +extern EAPI int ECORE_X_LOCK_CAPS; + +typedef enum _Ecore_X_WM_Protocol { + /** + * If enabled the window manager will be asked to send a + * delete message instead of just closing (destroying) the window. + */ + ECORE_X_WM_PROTOCOL_DELETE_REQUEST, + + /** + * If enabled the window manager will be told that the window + * explicitly sets input focus. + */ + ECORE_X_WM_PROTOCOL_TAKE_FOCUS, + + /** + * If enabled the window manager can ping the window to check + * if it is alive. + */ + ECORE_X_NET_WM_PROTOCOL_PING, + + /** + * If enabled the window manager can sync updating with the + * window (?) + */ + ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST, + + /* Number of defined items */ + ECORE_X_WM_PROTOCOL_NUM +} Ecore_X_WM_Protocol; + +typedef enum _Ecore_X_Window_Input_Mode { + /** The window can never be focused */ + ECORE_X_WINDOW_INPUT_MODE_NONE, + + /** The window can be focused by the WM but doesn't focus itself */ + ECORE_X_WINDOW_INPUT_MODE_PASSIVE, + + /** The window sets the focus itself if one of its sub-windows + * already is focused + */ + ECORE_X_WINDOW_INPUT_MODE_ACTIVE_LOCAL, + + /** The window sets the focus itself even if another window + * is currently focused + */ + ECORE_X_WINDOW_INPUT_MODE_ACTIVE_GLOBAL +} Ecore_X_Window_Input_Mode; + +typedef enum _Ecore_X_Window_State_Hint { + /** Do not provide any state hint to the window manager */ + ECORE_X_WINDOW_STATE_HINT_NONE = -1, + + /** The window wants to remain hidden and NOT iconified */ + ECORE_X_WINDOW_STATE_HINT_WITHDRAWN, + + /** The window wants to be mapped normally */ + ECORE_X_WINDOW_STATE_HINT_NORMAL, + + /** The window wants to start in an iconified state */ + ECORE_X_WINDOW_STATE_HINT_ICONIC, +} Ecore_X_Window_State_Hint; + +typedef enum _Ecore_X_Window_Type { + ECORE_X_WINDOW_TYPE_DESKTOP, + ECORE_X_WINDOW_TYPE_DOCK, + ECORE_X_WINDOW_TYPE_TOOLBAR, + ECORE_X_WINDOW_TYPE_MENU, + ECORE_X_WINDOW_TYPE_UTILITY, + ECORE_X_WINDOW_TYPE_SPLASH, + ECORE_X_WINDOW_TYPE_DIALOG, + ECORE_X_WINDOW_TYPE_NORMAL, + ECORE_X_WINDOW_TYPE_UNKNOWN +} Ecore_X_Window_Type; + +typedef enum _Ecore_X_Action { + ECORE_X_ACTION_MOVE, + ECORE_X_ACTION_RESIZE, + ECORE_X_ACTION_MINIMIZE, + ECORE_X_ACTION_SHADE, + ECORE_X_ACTION_STICK, + ECORE_X_ACTION_MAXIMIZE_HORZ, + ECORE_X_ACTION_MAXIMIZE_VERT, + ECORE_X_ACTION_FULLSCREEN, + ECORE_X_ACTION_CHANGE_DESKTOP, + ECORE_X_ACTION_CLOSE +} Ecore_X_Action; + +typedef enum _Ecore_X_Window_Configure_Mask { + ECORE_X_WINDOW_CONFIGURE_MASK_X = (1 << 0), + ECORE_X_WINDOW_CONFIGURE_MASK_Y = (1 << 1), + ECORE_X_WINDOW_CONFIGURE_MASK_W = (1 << 2), + ECORE_X_WINDOW_CONFIGURE_MASK_H = (1 << 3), + ECORE_X_WINDOW_CONFIGURE_MASK_BORDER_WIDTH = (1 << 4), + ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING = (1 << 5), + ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE = (1 << 6) +} Ecore_X_Window_Configure_Mask; + +/* Window layer constants */ +#define ECORE_X_WINDOW_LAYER_BELOW 2 +#define ECORE_X_WINDOW_LAYER_NORMAL 4 +#define ECORE_X_WINDOW_LAYER_ABOVE 6 + +EAPI int ecore_x_init(const char *name); +EAPI int ecore_x_shutdown(void); +EAPI int ecore_x_disconnect(void); +EAPI Ecore_X_Display *ecore_x_display_get(void); +EAPI int ecore_x_fd_get(void); +EAPI void ecore_x_double_click_time_set(double t); +EAPI double ecore_x_double_click_time_get(void); +EAPI void ecore_x_flush(void); +EAPI void ecore_x_sync(void); +EAPI void ecore_x_killall(Ecore_X_Window root); +EAPI void ecore_x_kill(Ecore_X_Window win); + +EAPI Ecore_X_Time ecore_x_current_time_get(void); + +EAPI void ecore_x_error_handler_set(void (*func) (void *data), const void *data); +EAPI void ecore_x_io_error_handler_set(void (*func) (void *data), const void *data); +EAPI int ecore_x_error_request_get(void); +EAPI int ecore_x_error_code_get(void); + +EAPI void ecore_x_event_mask_set(Ecore_X_Window w, Ecore_X_Event_Mask mask); +EAPI void ecore_x_event_mask_unset(Ecore_X_Window w, Ecore_X_Event_Mask mask); + +EAPI int ecore_x_selection_primary_set(Ecore_X_Window w, unsigned char *data, int size); +EAPI int ecore_x_selection_primary_clear(void); +EAPI int ecore_x_selection_secondary_set(Ecore_X_Window w, unsigned char *data, int size); +EAPI int ecore_x_selection_secondary_clear(void); +EAPI int ecore_x_selection_xdnd_set(Ecore_X_Window w, unsigned char *data, int size); +EAPI int ecore_x_selection_xdnd_clear(void); +EAPI int ecore_x_selection_clipboard_set(Ecore_X_Window w, unsigned char *data, int size); +EAPI int ecore_x_selection_clipboard_clear(void); +EAPI void ecore_x_selection_primary_request(Ecore_X_Window w, char *target); +EAPI void ecore_x_selection_primary_request_data_get(void **buf, int *len); +EAPI void ecore_x_selection_secondary_request(Ecore_X_Window w, char *target); +EAPI void ecore_x_selection_secondary_request_data_get(void **buf, int *len); +EAPI void ecore_x_selection_xdnd_request(Ecore_X_Window w, char *target); +EAPI void ecore_x_selection_xdnd_request_data_get(void **buf, int *len); +EAPI void ecore_x_selection_clipboard_request(Ecore_X_Window w, char *target); +EAPI void ecore_x_selection_clipboard_request_data_get(void **buf, int *len); +EAPI void ecore_x_selection_converter_add(char *target, int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret)); +EAPI void ecore_x_selection_converter_atom_add(Ecore_X_Atom target, int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret)); +EAPI void ecore_x_selection_converter_del(char *target); +EAPI void ecore_x_selection_converter_atom_del(Ecore_X_Atom target); +EAPI void ecore_x_selection_parser_add(const char *target, void *(*func)(const char *target, unsigned char *data, int size)); +EAPI void ecore_x_selection_parser_del(const char *target); + +EAPI void ecore_x_dnd_aware_set(Ecore_X_Window win, int on); +EAPI int ecore_x_dnd_version_get(Ecore_X_Window win); +EAPI int ecore_x_dnd_type_isset(Ecore_X_Window win, const char *type); +EAPI void ecore_x_dnd_type_set(Ecore_X_Window win, const char *type, int on); +EAPI int ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size); +EAPI void ecore_x_dnd_drop(void); +EAPI void ecore_x_dnd_send_status(int will_accept, int suppress, Ecore_X_Rectangle rectangle, Ecore_X_Atom action); +EAPI void ecore_x_dnd_send_finished(void); + +EAPI Ecore_X_Window ecore_x_window_new(Ecore_X_Window parent, int x, int y, int w, int h); +EAPI Ecore_X_Window ecore_x_window_override_new(Ecore_X_Window parent, int x, int y, int w, int h); +EAPI Ecore_X_Window ecore_x_window_input_new(Ecore_X_Window parent, int x, int y, int w, int h); +EAPI void ecore_x_window_configure(Ecore_X_Window win, + Ecore_X_Window_Configure_Mask mask, + int x, int y, int w, int h, + int border_width, + Ecore_X_Window sibling, + int stack_mode); +EAPI void ecore_x_window_cursor_set(Ecore_X_Window win, + Ecore_X_Cursor c); +EAPI void ecore_x_window_del(Ecore_X_Window win); +EAPI void ecore_x_window_delete_request_send(Ecore_X_Window win); +EAPI void ecore_x_window_show(Ecore_X_Window win); +EAPI void ecore_x_window_hide(Ecore_X_Window win); +EAPI void ecore_x_window_move(Ecore_X_Window win, int x, int y); +EAPI void ecore_x_window_resize(Ecore_X_Window win, int w, int h); +EAPI void ecore_x_window_move_resize(Ecore_X_Window win, int x, int y, int w, int h); +EAPI void ecore_x_window_focus(Ecore_X_Window win); +EAPI void ecore_x_window_focus_at_time(Ecore_X_Window win, Ecore_X_Time t); +EAPI Ecore_X_Window ecore_x_window_focus_get(void); +EAPI void ecore_x_window_raise(Ecore_X_Window win); +EAPI void ecore_x_window_lower(Ecore_X_Window win); +EAPI void ecore_x_window_reparent(Ecore_X_Window win, Ecore_X_Window new_parent, int x, int y); +EAPI void ecore_x_window_size_get(Ecore_X_Window win, int *w, int *h); +EAPI void ecore_x_window_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h); +EAPI int ecore_x_window_border_width_get(Ecore_X_Window win); +EAPI void ecore_x_window_border_width_set(Ecore_X_Window win, int width); +EAPI int ecore_x_window_depth_get(Ecore_X_Window win); +EAPI void ecore_x_window_cursor_show(Ecore_X_Window win, int show); +EAPI void ecore_x_window_defaults_set(Ecore_X_Window win); +EAPI int ecore_x_window_visible_get(Ecore_X_Window win); +EAPI Ecore_X_Window ecore_x_window_at_xy_get(int x, int y); +EAPI Ecore_X_Window ecore_x_window_parent_get(Ecore_X_Window win); + +EAPI void ecore_x_window_background_color_set(Ecore_X_Window win, + unsigned short r, + unsigned short g, + unsigned short b); +EAPI void ecore_x_window_gravity_set(Ecore_X_Window win, + Ecore_X_Gravity grav); +EAPI void ecore_x_window_pixel_gravity_set(Ecore_X_Window win, + Ecore_X_Gravity grav); +EAPI void ecore_x_window_pixmap_set(Ecore_X_Window win, + Ecore_X_Pixmap pmap); +EAPI void ecore_x_window_area_clear(Ecore_X_Window win, + int x, int y, int w, int h); +EAPI void ecore_x_window_area_expose(Ecore_X_Window win, + int x, int y, int w, int h); + +EAPI void ecore_x_window_prop_card32_set(Ecore_X_Window win, Ecore_X_Atom atom, + unsigned int *val, unsigned int num); +EAPI int ecore_x_window_prop_card32_get(Ecore_X_Window win, Ecore_X_Atom atom, + unsigned int *val, unsigned int len); +EAPI Ecore_X_Atom ecore_x_window_prop_any_type(void); +EAPI void ecore_x_window_prop_property_set(Ecore_X_Window win, Ecore_X_Atom type, Ecore_X_Atom format, int size, void *data, int number); +EAPI int ecore_x_window_prop_property_get(Ecore_X_Window win, Ecore_X_Atom property, Ecore_X_Atom type, int size, unsigned char **data, int *num); +EAPI void ecore_x_window_prop_property_del(Ecore_X_Window win, Ecore_X_Atom property); +EAPI Ecore_X_Atom *ecore_x_window_prop_list(Ecore_X_Window win, int *num_ret); +EAPI void ecore_x_window_prop_string_set(Ecore_X_Window win, Ecore_X_Atom type, const char *str); +EAPI char *ecore_x_window_prop_string_get(Ecore_X_Window win, Ecore_X_Atom type); +EAPI int ecore_x_window_prop_protocol_isset(Ecore_X_Window win, Ecore_X_WM_Protocol protocol); +EAPI Ecore_X_WM_Protocol *ecore_x_window_prop_protocol_list_get(Ecore_X_Window win, int *num_ret); + +EAPI void ecore_x_window_shape_mask_set(Ecore_X_Window win, Ecore_X_Pixmap mask); +EAPI void ecore_x_window_shape_window_set(Ecore_X_Window win, Ecore_X_Window shape_win); +EAPI void ecore_x_window_shape_window_set_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y); +EAPI void ecore_x_window_shape_rectangle_set(Ecore_X_Window win, int x, int y, int w, int h); +EAPI void ecore_x_window_shape_rectangles_set(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num); +EAPI void ecore_x_window_shape_window_add(Ecore_X_Window win, Ecore_X_Window shape_win); +EAPI void ecore_x_window_shape_window_add_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y); +EAPI void ecore_x_window_shape_rectangle_add(Ecore_X_Window win, int x, int y, int w, int h); +EAPI void ecore_x_window_shape_rectangle_clip(Ecore_X_Window win, int x, int y, int w, int h); +EAPI void ecore_x_window_shape_rectangles_add(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num); +EAPI Ecore_X_Rectangle *ecore_x_window_shape_rectangles_get(Ecore_X_Window win, int *num_ret); +EAPI void ecore_x_window_shape_events_select(Ecore_X_Window win, int on); + +EAPI Ecore_X_Pixmap ecore_x_pixmap_new(Ecore_X_Window win, int w, int h, int dep); +EAPI void ecore_x_pixmap_del(Ecore_X_Pixmap pmap); +EAPI void ecore_x_pixmap_paste(Ecore_X_Pixmap pmap, Ecore_X_Drawable dest, Ecore_X_GC gc, int sx, int sy, int w, int h, int dx, int dy); +EAPI void ecore_x_pixmap_geometry_get(Ecore_X_Pixmap pmap, int *x, int *y, int *w, int *h); +EAPI int ecore_x_pixmap_depth_get(Ecore_X_Pixmap pmap); + +EAPI Ecore_X_GC ecore_x_gc_new(Ecore_X_Drawable draw); +EAPI void ecore_x_gc_del(Ecore_X_GC gc); + +EAPI int ecore_x_client_message32_send(Ecore_X_Window win, Ecore_X_Atom type, Ecore_X_Event_Mask mask, long d0, long d1, long d2, long d3, long d4); +EAPI int ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type, const void *data, int len); + + +/* FIXME: these funcs need categorising */ +EAPI void ecore_x_drawable_geometry_get(Ecore_X_Drawable d, int *x, int *y, int *w, int *h); +EAPI int ecore_x_drawable_border_width_get(Ecore_X_Drawable d); +EAPI int ecore_x_drawable_depth_get(Ecore_X_Drawable d); +EAPI Ecore_X_Window *ecore_x_window_root_list(int *num_ret); +EAPI Ecore_X_Window ecore_x_window_root_first_get(void); +EAPI int ecore_x_window_manage(Ecore_X_Window win); +EAPI void ecore_x_window_container_manage(Ecore_X_Window win); +EAPI void ecore_x_window_client_manage(Ecore_X_Window win); +EAPI void ecore_x_window_sniff(Ecore_X_Window win); +EAPI void ecore_x_window_client_sniff(Ecore_X_Window win); +EAPI Ecore_X_Atom ecore_x_atom_get(const char *name); + +EAPI void ecore_x_icccm_init(void); +EAPI void ecore_x_icccm_state_set(Ecore_X_Window win, Ecore_X_Window_State_Hint state); +EAPI Ecore_X_Window_State_Hint ecore_x_icccm_state_get(Ecore_X_Window win); +EAPI void ecore_x_icccm_delete_window_send(Ecore_X_Window win, Ecore_X_Time t); +EAPI void ecore_x_icccm_take_focus_send(Ecore_X_Window win, Ecore_X_Time t); +EAPI void ecore_x_icccm_save_yourself_send(Ecore_X_Window win, Ecore_X_Time t); +EAPI void ecore_x_icccm_move_resize_send(Ecore_X_Window win, int x, int y, int w, int h); +EAPI void ecore_x_icccm_hints_set(Ecore_X_Window win, + int accepts_focus, + Ecore_X_Window_State_Hint initial_state, + Ecore_X_Pixmap icon_pixmap, + Ecore_X_Pixmap icon_mask, + Ecore_X_Window icon_window, + Ecore_X_Window window_group, + int is_urgent); +EAPI int ecore_x_icccm_hints_get(Ecore_X_Window win, + int *accepts_focus, + Ecore_X_Window_State_Hint *initial_state, + Ecore_X_Pixmap *icon_pixmap, + Ecore_X_Pixmap *icon_mask, + Ecore_X_Window *icon_window, + Ecore_X_Window *window_group, + int *is_urgent); +EAPI void ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win, + int request_pos, + Ecore_X_Gravity gravity, + int min_w, int min_h, + int max_w, int max_h, + int base_w, int base_h, + int step_x, int step_y, + double min_aspect, + double max_aspect); +EAPI int ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win, + int *request_pos, + Ecore_X_Gravity *gravity, + int *min_w, int *min_h, + int *max_w, int *max_h, + int *base_w, int *base_h, + int *step_x, int *step_y, + double *min_aspect, + double *max_aspect); +EAPI void ecore_x_icccm_title_set(Ecore_X_Window win, const char *t); +EAPI char *ecore_x_icccm_title_get(Ecore_X_Window win); +EAPI void ecore_x_icccm_protocol_set(Ecore_X_Window win, + Ecore_X_WM_Protocol protocol, + int on); +EAPI int ecore_x_icccm_protocol_isset(Ecore_X_Window win, + Ecore_X_WM_Protocol protocol); +EAPI void ecore_x_icccm_name_class_set(Ecore_X_Window win, + const char *n, + const char *c); +EAPI void ecore_x_icccm_name_class_get(Ecore_X_Window win, + char **n, + char **c); +EAPI char *ecore_x_icccm_client_machine_get(Ecore_X_Window win); +EAPI void ecore_x_icccm_command_set(Ecore_X_Window win, int argc, char **argv); +EAPI void ecore_x_icccm_command_get(Ecore_X_Window win, int *argc, char ***argv); +EAPI char *ecore_x_icccm_icon_name_get(Ecore_X_Window win); +EAPI void ecore_x_icccm_icon_name_set(Ecore_X_Window win, const char *t); +EAPI void ecore_x_icccm_colormap_window_set(Ecore_X_Window win, Ecore_X_Window subwin); +EAPI void ecore_x_icccm_colormap_window_unset(Ecore_X_Window win, Ecore_X_Window subwin); +EAPI void ecore_x_icccm_transient_for_set(Ecore_X_Window win, Ecore_X_Window forwin); +EAPI void ecore_x_icccm_transient_for_unset(Ecore_X_Window win); +EAPI Ecore_X_Window ecore_x_icccm_transient_for_get(Ecore_X_Window win); +EAPI void ecore_x_icccm_window_role_set(Ecore_X_Window win, const char *role); +EAPI char *ecore_x_icccm_window_role_get(Ecore_X_Window win); +EAPI void ecore_x_icccm_client_leader_set(Ecore_X_Window win, Ecore_X_Window l); +EAPI Ecore_X_Window ecore_x_icccm_client_leader_get(Ecore_X_Window win); +EAPI void ecore_x_icccm_iconic_request_send(Ecore_X_Window win, Ecore_X_Window root); + + +typedef enum _Ecore_X_MWM_Hint_Func +{ + ECORE_X_MWM_HINT_FUNC_ALL = (1 << 0), + ECORE_X_MWM_HINT_FUNC_RESIZE = (1 << 1), + ECORE_X_MWM_HINT_FUNC_MOVE = (1 << 2), + ECORE_X_MWM_HINT_FUNC_MINIMIZE = (1 << 3), + ECORE_X_MWM_HINT_FUNC_MAXIMIZE = (1 << 4), + ECORE_X_MWM_HINT_FUNC_CLOSE = (1 << 5) +} Ecore_X_MWM_Hint_Func; + +typedef enum _Ecore_X_MWM_Hint_Decor +{ + ECORE_X_MWM_HINT_DECOR_ALL = (1 << 0), + ECORE_X_MWM_HINT_DECOR_BORDER = (1 << 1), + ECORE_X_MWM_HINT_DECOR_RESIZEH = (1 << 2), + ECORE_X_MWM_HINT_DECOR_TITLE = (1 << 3), + ECORE_X_MWM_HINT_DECOR_MENU = (1 << 4), + ECORE_X_MWM_HINT_DECOR_MINIMIZE = (1 << 5), + ECORE_X_MWM_HINT_DECOR_MAXIMIZE = (1 << 6) +} Ecore_X_MWM_Hint_Decor; + +typedef enum _Ecore_X_MWM_Hint_Input +{ + ECORE_X_MWM_HINT_INPUT_MODELESS = 0, + ECORE_X_MWM_HINT_INPUT_PRIMARY_APPLICATION_MODAL = 1, + ECORE_X_MWM_HINT_INPUT_SYSTEM_MODAL = 2, + ECORE_X_MWM_HINT_INPUT_FULL_APPLICATION_MODAL = 3, +} Ecore_X_MWM_Hint_Input; + +EAPI int ecore_x_mwm_hints_get(Ecore_X_Window win, + Ecore_X_MWM_Hint_Func *fhint, + Ecore_X_MWM_Hint_Decor *dhint, + Ecore_X_MWM_Hint_Input *ihint); +EAPI void ecore_x_mwm_borderless_set(Ecore_X_Window win, int borderless); + +/* netwm */ +EAPI void ecore_x_netwm_init(void); +EAPI void ecore_x_netwm_wm_identify(Ecore_X_Window root, Ecore_X_Window check, const char *wm_name); +EAPI void ecore_x_netwm_supported_set(Ecore_X_Window root, Ecore_X_Atom *supported, int num); +EAPI int ecore_x_netwm_supported_get(Ecore_X_Window root, Ecore_X_Atom **supported, int *num); +EAPI void ecore_x_netwm_desk_count_set(Ecore_X_Window root, unsigned int n_desks); +EAPI void ecore_x_netwm_desk_roots_set(Ecore_X_Window root, Ecore_X_Window *vroots, unsigned int n_desks); +EAPI void ecore_x_netwm_desk_names_set(Ecore_X_Window root, const char **names, unsigned int n_desks); +EAPI void ecore_x_netwm_desk_size_set(Ecore_X_Window root, unsigned int width, unsigned int height); +EAPI void ecore_x_netwm_desk_workareas_set(Ecore_X_Window root, unsigned int *areas, unsigned int n_desks); +EAPI void ecore_x_netwm_desk_current_set(Ecore_X_Window root, unsigned int desk); +EAPI void ecore_x_netwm_desk_viewports_set(Ecore_X_Window root, unsigned int *origins, unsigned int n_desks); +EAPI void ecore_x_netwm_desk_layout_set(Ecore_X_Window root, int orientation, int columns, int rows, int starting_corner); +EAPI void ecore_x_netwm_showing_desktop_set(Ecore_X_Window root, int on); +EAPI void ecore_x_netwm_client_list_set(Ecore_X_Window root, Ecore_X_Window *p_clients, unsigned int n_clients); +EAPI void ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root, Ecore_X_Window *p_clients, unsigned int n_clients); +EAPI void ecore_x_netwm_client_active_set(Ecore_X_Window root, Ecore_X_Window win); +EAPI void ecore_x_netwm_name_set(Ecore_X_Window win, const char *name); +EAPI int ecore_x_netwm_name_get(Ecore_X_Window win, char **name); +EAPI void ecore_x_netwm_visible_name_set(Ecore_X_Window win, const char *name); +EAPI int ecore_x_netwm_visible_name_get(Ecore_X_Window win, char **name); +EAPI void ecore_x_netwm_icon_name_set(Ecore_X_Window win, const char *name); +EAPI int ecore_x_netwm_icon_name_get(Ecore_X_Window win, char **name); +EAPI void ecore_x_netwm_visible_icon_name_set(Ecore_X_Window win, const char *name); +EAPI int ecore_x_netwm_visible_icon_name_get(Ecore_X_Window win, char **name); +EAPI void ecore_x_netwm_desktop_set(Ecore_X_Window win, unsigned int desk); +EAPI int ecore_x_netwm_desktop_get(Ecore_X_Window win, unsigned int *desk); +EAPI void ecore_x_netwm_strut_set(Ecore_X_Window win, int left, int right, int top, int bottom); +EAPI int ecore_x_netwm_strut_get(Ecore_X_Window win, int *left, int *right, int *top, int *bottom); +EAPI void ecore_x_netwm_strut_partial_set(Ecore_X_Window win, int left, int right, int top, int bottom, int left_start_y, int left_end_y, int right_start_y, int right_end_y, int top_start_x, int top_end_x, int bottom_start_x, int bottom_end_x); +EAPI int ecore_x_netwm_strut_partial_get(Ecore_X_Window win, int *left, int *right, int *top, int *bottom, int *left_start_y, int *left_end_y, int *right_start_y, int *right_end_y, int *top_start_x, int *top_end_x, int *bottom_start_x, int *bottom_end_x); +EAPI int ecore_x_netwm_icon_get(Ecore_X_Window win, int *width, int *height, unsigned int **data, int *num); +EAPI void ecore_x_netwm_icon_geometry_set(Ecore_X_Window win, int x, int y, int width, int height); +EAPI int ecore_x_netwm_icon_geometry_get(Ecore_X_Window win, int *x, int *y, int *width, int *height); +EAPI void ecore_x_netwm_pid_set(Ecore_X_Window win, int pid); +EAPI int ecore_x_netwm_pid_get(Ecore_X_Window win, int *pid); +EAPI void ecore_x_netwm_handled_icons_set(Ecore_X_Window win); +EAPI int ecore_x_netwm_handled_icons_get(Ecore_X_Window win); +EAPI void ecore_x_netwm_user_time_set(Ecore_X_Window win, unsigned int time); +EAPI int ecore_x_netwm_user_time_get(Ecore_X_Window win, unsigned int *time); +EAPI void ecore_x_netwm_window_state_set(Ecore_X_Window win, Ecore_X_Window_State *state, unsigned int num); +EAPI int ecore_x_netwm_window_state_get(Ecore_X_Window win, Ecore_X_Window_State **state, unsigned int *num); +EAPI void ecore_x_netwm_window_type_set(Ecore_X_Window win, Ecore_X_Window_Type type); +EAPI int ecore_x_netwm_window_type_get(Ecore_X_Window win, Ecore_X_Window_Type *type); +EAPI int ecore_x_netwm_allowed_action_isset(Ecore_X_Window win, Ecore_X_Action action); +EAPI void ecore_x_netwm_allowed_action_set(Ecore_X_Window win, Ecore_X_Action action, int on); +EAPI void ecore_x_netwm_opacity_set(Ecore_X_Window win, unsigned int opacity); +EAPI int ecore_x_netwm_opacity_get(Ecore_X_Window win, unsigned int *opacity); +EAPI void ecore_x_netwm_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb); +EAPI int ecore_x_netwm_frame_size_get(Ecore_X_Window win, int *fl, int *fr, int *ft, int *fb); +EAPI int ecore_x_netwm_sync_counter_get(Ecore_X_Window win, Ecore_X_Sync_Counter *counter); +EAPI void ecore_x_netwm_ping_send(Ecore_X_Window win); +EAPI void ecore_x_netwm_sync_request_send(Ecore_X_Window win, unsigned int serial); +EAPI void ecore_x_netwm_state_request_send(Ecore_X_Window win, Ecore_X_Window root, Ecore_X_Window_State s1, Ecore_X_Window_State s2, int set); +EAPI void ecore_x_netwm_desktop_request_send(Ecore_X_Window win, Ecore_X_Window root, unsigned int desktop); + + + + +EAPI void ecore_x_e_init(void); +EAPI void ecore_x_e_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb); + + +EAPI int ecore_x_xinerama_screen_count_get(void); +EAPI int ecore_x_xinerama_screen_geometry_get(int screen, int *x, int *y, int *w, int *h); + +/* FIXME: these funcs need categorising */ +EAPI void ecore_x_drawable_geometry_get(Ecore_X_Drawable d, int *x, int *y, int *w, int *h); +EAPI int ecore_x_drawable_border_width_get(Ecore_X_Drawable d); +EAPI int ecore_x_drawable_depth_get(Ecore_X_Drawable d); +EAPI Ecore_X_Window *ecore_x_window_root_list(int *num_ret); +EAPI int ecore_x_window_manage(Ecore_X_Window win); +EAPI void ecore_x_window_container_manage(Ecore_X_Window win); +EAPI void ecore_x_window_client_manage(Ecore_X_Window win); +EAPI void ecore_x_window_sniff(Ecore_X_Window win); +EAPI void ecore_x_window_client_sniff(Ecore_X_Window win); +EAPI Ecore_X_Atom ecore_x_atom_get(const char *name); + +typedef struct _Ecore_X_Window_Attributes +{ + Ecore_X_Window root; + int x, y, w, h; + int border; + int depth; + char visible : 1; + char viewable : 1; + char override : 1; + char input_only : 1; + char save_under : 1; + struct { + Ecore_X_Event_Mask mine; + Ecore_X_Event_Mask all; + Ecore_X_Event_Mask no_propagate; + } event_mask; + Ecore_X_Gravity window_gravity; + Ecore_X_Gravity pixel_gravity; + Ecore_X_Colormap colormap; + /* FIXME: missing + * Colormap comormap; + * int map_installed; + * Screen *screen; + * Visual *visual; + */ +} Ecore_X_Window_Attributes; + +EAPI int ecore_x_window_attributes_get(Ecore_X_Window win, Ecore_X_Window_Attributes *att_ret); +EAPI void ecore_x_window_save_set_add(Ecore_X_Window win); +EAPI void ecore_x_window_save_set_del(Ecore_X_Window win); +EAPI Ecore_X_Window *ecore_x_window_children_get(Ecore_X_Window win, int *num); + +EAPI int ecore_x_cursor_color_supported_get(void); +EAPI Ecore_X_Cursor ecore_x_cursor_new(Ecore_X_Window win, int *pixels, int w, int h, int hot_x, int hot_y); +EAPI void ecore_x_cursor_free(Ecore_X_Cursor c); +EAPI Ecore_X_Cursor ecore_x_cursor_shape_get(int shape); + +EAPI int ecore_x_pointer_grab(Ecore_X_Window win); +EAPI int ecore_x_pointer_confine_grab(Ecore_X_Window win); +EAPI void ecore_x_pointer_ungrab(void); +EAPI int ecore_x_pointer_warp(Ecore_X_Window win, int x, int y); +EAPI int ecore_x_keyboard_grab(Ecore_X_Window win); +EAPI void ecore_x_keyboard_ungrab(void); +EAPI void ecore_x_grab(void); +EAPI void ecore_x_ungrab(void); +EAPI void ecore_x_passive_grab_replay_func_set(int (*func) (void *data, int event_type, void *event), void *data); +EAPI void ecore_x_window_button_grab(Ecore_X_Window win, int button, + Ecore_X_Event_Mask event_mask, + int mod, int any_mod); +EAPI void ecore_x_window_button_ungrab(Ecore_X_Window win, int button, + int mod, int any_mod); +EAPI void ecore_x_window_key_grab(Ecore_X_Window win, char *key, + int mod, int any_mod); +EAPI void ecore_x_window_key_ungrab(Ecore_X_Window win, char *key, + int mod, int any_mod); + +EAPI void ecore_x_focus_reset(void); +EAPI void ecore_x_events_allow_all(void); +EAPI void ecore_x_pointer_last_xy_get(int *x, int *y); +EAPI void ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y); + +/* ecore_x_sync.c */ +EAPI Ecore_X_Sync_Alarm ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter); +EAPI int ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ecore/src/lib/ecore_x/Ecore_X_Atoms.h b/ecore/src/lib/ecore_x/Ecore_X_Atoms.h new file mode 100644 index 0000000..759016c --- /dev/null +++ b/ecore/src/lib/ecore_x/Ecore_X_Atoms.h @@ -0,0 +1,152 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#ifndef _ECORE_X_ATOMS_H +#define _ECORE_X_ATOMS_H + +#include "Ecore_X.h" + +/** + * @file + * @brief Ecore X atoms + */ + +/* General */ +extern Ecore_X_Atom ECORE_X_ATOM_UTF8_STRING; +extern Ecore_X_Atom ECORE_X_ATOM_FILE_NAME; +extern Ecore_X_Atom ECORE_X_ATOM_STRING; +extern Ecore_X_Atom ECORE_X_ATOM_TEXT; +extern Ecore_X_Atom ECORE_X_ATOM_COMPOUND_TEXT; + +/* ICCCM */ +extern Ecore_X_Atom ECORE_X_ATOM_WM_STATE; +extern Ecore_X_Atom ECORE_X_ATOM_WM_DELETE_WINDOW; +extern Ecore_X_Atom ECORE_X_ATOM_WM_TAKE_FOCUS; +extern Ecore_X_Atom ECORE_X_ATOM_WM_PROTOCOLS; +extern Ecore_X_Atom ECORE_X_ATOM_WM_CLASS; +extern Ecore_X_Atom ECORE_X_ATOM_WM_NAME; +extern Ecore_X_Atom ECORE_X_ATOM_WM_COMMAND; +extern Ecore_X_Atom ECORE_X_ATOM_WM_ICON_NAME; +extern Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_MACHINE; +extern Ecore_X_Atom ECORE_X_ATOM_WM_CHANGE_STATE; +extern Ecore_X_Atom ECORE_X_ATOM_WM_COLORMAP_WINDOWS; +extern Ecore_X_Atom ECORE_X_ATOM_WM_WINDOW_ROLE; +extern Ecore_X_Atom ECORE_X_ATOM_WM_HINTS; +extern Ecore_X_Atom ECORE_X_ATOM_WM_NORMAL_HINTS; +extern Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_LEADER; +extern Ecore_X_Atom ECORE_X_ATOM_WM_TRANSIENT_FOR; +extern Ecore_X_Atom ECORE_X_ATOM_WM_SAVE_YOURSELF; + +/* MWM */ +extern Ecore_X_Atom ECORE_X_ATOM_MOTIF_WM_HINTS; + +/* GNOME */ +extern Ecore_X_Atom ECORE_X_ATOM_WIN_LAYER; + +/* EWMH */ +extern Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTED; +extern Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK; + +extern Ecore_X_Atom ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS; +extern Ecore_X_Atom ECORE_X_ATOM_NET_VIRTUAL_ROOTS; +extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_NAMES; +extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_GEOMETRY; +extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_VIEWPORT; +extern Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_LAYOUT; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WORKAREA; + +extern Ecore_X_Atom ECORE_X_ATOM_NET_CURRENT_DESKTOP; +extern Ecore_X_Atom ECORE_X_ATOM_NET_SHOWING_DESKTOP; + +extern Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST; +extern Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST_STACKING; +extern Ecore_X_Atom ECORE_X_ATOM_NET_ACTIVE_WINDOW; + +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_NAME; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_NAME; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_NAME; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_DESKTOP; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT_PARTIAL; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_GEOMETRY; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_PID; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_HANDLED_ICONS; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_USER_TIME; + +extern Ecore_X_Atom ECORE_X_ATOM_NET_CLOSE_WINDOW; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_MOVERESIZE; + +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MOVE; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_RESIZE; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_SHADE; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_STICK; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CLOSE; /*x*/ + +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL; + +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MODAL; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_STICKY; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SHADED; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_HIDDEN; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_ABOVE; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_BELOW; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION; + +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_OPACITY; + +extern Ecore_X_Atom ECORE_X_ATOM_NET_FRAME_EXTENTS; +extern Ecore_X_Atom ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS; + +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_PING; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST; +extern Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER; + +/* Selections */ +extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_TARGETS; +extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PRIMARY; +extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_SECONDARY; +extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_CLIPBOARD; +extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_PRIMARY; +extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_SECONDARY; +extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD; + +/* DND */ +extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_XDND; +extern Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_XDND; +extern Ecore_X_Atom ECORE_X_ATOM_XDND_AWARE; +extern Ecore_X_Atom ECORE_X_ATOM_XDND_TYPE_LIST; +extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_COPY; +extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_PRIVATE; +extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_ASK; +extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_LIST; +extern Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_DESCRIPTION; +extern Ecore_X_Atom ECORE_X_ATOM_XDND_ENTER; +extern Ecore_X_Atom ECORE_X_ATOM_XDND_LEAVE; +extern Ecore_X_Atom ECORE_X_ATOM_XDND_STATUS; +extern Ecore_X_Atom ECORE_X_ATOM_XDND_POSITION; +extern Ecore_X_Atom ECORE_X_ATOM_XDND_DROP; +extern Ecore_X_Atom ECORE_X_ATOM_XDND_FINISHED; + +#endif /* _ECORE_X_ATOMS_H */ diff --git a/ecore/src/lib/ecore_x/Ecore_X_Cursor.h b/ecore/src/lib/ecore_x/Ecore_X_Cursor.h new file mode 100644 index 0000000..af2e97a --- /dev/null +++ b/ecore/src/lib/ecore_x/Ecore_X_Cursor.h @@ -0,0 +1,86 @@ +#ifndef _ECORE_X_CURSOR_H +#define _ECORE_X_CURSOR_H + +/** + * @file + * @brief Defines the various cursor types for the X Windows system. + */ + +#define ECORE_X_CURSOR_X 0 +#define ECORE_X_CURSOR_ARROW 2 +#define ECORE_X_CURSOR_BASED_ARROW_DOWN 4 +#define ECORE_X_CURSOR_UP 6 +#define ECORE_X_CURSOR_BOAT 8 +#define ECORE_X_CURSOR_BOTTOM_LEFT_CORNER 12 +#define ECORE_X_CURSOR_BOTTOM_RIGHT_CORNER 14 +#define ECORE_X_CURSOR_BOTTOM_SIDE 16 +#define ECORE_X_CURSOR_BOTTOM_TEE 18 +#define ECORE_X_CURSOR_BOX_SPIRAL 20 +#define ECORE_X_CURSOR_CENTER_PTR 22 +#define ECORE_X_CURSOR_CIRCLE 24 +#define ECORE_X_CURSOR_CLOCK 26 +#define ECORE_X_CURSOR_COFFEE_MUG 28 +#define ECORE_X_CURSOR_CROSS 30 +#define ECORE_X_CURSOR_CROSS_REVERSE 32 +#define ECORE_X_CURSOR_CROSSHAIR 34 +#define ECORE_X_CURSOR_DIAMOND_CROSS 36 +#define ECORE_X_CURSOR_DOT 38 +#define ECORE_X_CURSOR_DOT_BOX_MASK 40 +#define ECORE_X_CURSOR_DOUBLE_ARROW 42 +#define ECORE_X_CURSOR_DRAFT_LARGE 44 +#define ECORE_X_CURSOR_DRAFT_SMALL 46 +#define ECORE_X_CURSOR_DRAPED_BOX 48 +#define ECORE_X_CURSOR_EXCHANGE 50 +#define ECORE_X_CURSOR_FLEUR 52 +#define ECORE_X_CURSOR_GOBBLER 54 +#define ECORE_X_CURSOR_GUMBY 56 +#define ECORE_X_CURSOR_HAND1 58 +#define ECORE_X_CURSOR_HAND2 60 +#define ECORE_X_CURSOR_HEART 62 +#define ECORE_X_CURSOR_ICON 64 +#define ECORE_X_CURSOR_IRON_CROSS 66 +#define ECORE_X_CURSOR_LEFT_PTR 68 +#define ECORE_X_CURSOR_LEFT_SIDE 70 +#define ECORE_X_CURSOR_LEFT_TEE 72 +#define ECORE_X_CURSOR_LEFTBUTTON 74 +#define ECORE_X_CURSOR_LL_ANGLE 76 +#define ECORE_X_CURSOR_LR_ANGLE 78 +#define ECORE_X_CURSOR_MAN 80 +#define ECORE_X_CURSOR_MIDDLEBUTTON 82 +#define ECORE_X_CURSOR_MOUSE 84 +#define ECORE_X_CURSOR_PENCIL 86 +#define ECORE_X_CURSOR_PIRATE 88 +#define ECORE_X_CURSOR_PLUS 90 +#define ECORE_X_CURSOR_QUESTION_ARROW 92 +#define ECORE_X_CURSOR_RIGHT_PTR 94 +#define ECORE_X_CURSOR_RIGHT_SIDE 96 +#define ECORE_X_CURSOR_RIGHT_TEE 98 +#define ECORE_X_CURSOR_RIGHTBUTTON 100 +#define ECORE_X_CURSOR_RTL_LOGO 102 +#define ECORE_X_CURSOR_SAILBOAT 104 +#define ECORE_X_CURSOR_SB_DOWN_ARROW 106 +#define ECORE_X_CURSOR_SB_H_DOUBLE_ARROW 108 +#define ECORE_X_CURSOR_SB_LEFT_ARROW 110 +#define ECORE_X_CURSOR_SB_RIGHT_ARROW 112 +#define ECORE_X_CURSOR_SB_UP_ARROW 114 +#define ECORE_X_CURSOR_SB_V_DOUBLE_ARROW 116 +#define ECORE_X_CURSOR_SHUTTLE 118 +#define ECORE_X_CURSOR_SIZING 120 +#define ECORE_X_CURSOR_SPIDER 122 +#define ECORE_X_CURSOR_SPRAYCAN 124 +#define ECORE_X_CURSOR_STAR 126 +#define ECORE_X_CURSOR_TARGET 128 +#define ECORE_X_CURSOR_TCROSS 130 +#define ECORE_X_CURSOR_TOP_LEFT_ARROW 132 +#define ECORE_X_CURSOR_TOP_LEFT_CORNER 134 +#define ECORE_X_CURSOR_TOP_RIGHT_CORNER 136 +#define ECORE_X_CURSOR_TOP_SIDE 138 +#define ECORE_X_CURSOR_TOP_TEE 140 +#define ECORE_X_CURSOR_TREK 142 +#define ECORE_X_CURSOR_UL_ANGLE 144 +#define ECORE_X_CURSOR_UMBRELLA 146 +#define ECORE_X_CURSOR_UR_ANGLE 148 +#define ECORE_X_CURSOR_WATCH 150 +#define ECORE_X_CURSOR_XTERM 152 + +#endif diff --git a/ecore/src/lib/ecore_x/Makefile.am b/ecore/src/lib/ecore_x/Makefile.am new file mode 100644 index 0000000..6b3bac9 --- /dev/null +++ b/ecore/src/lib/ecore_x/Makefile.am @@ -0,0 +1,81 @@ +MAINTAINERCLEANFILES = Makefile.in + +INCLUDES = \ +@Xcursor_cflags@ \ +@Xprint_cflags@ \ +@Xinerama_cflags@ \ +@x_cflags@ \ +-I$(top_srcdir)/src/lib/ecore \ +-I$(top_srcdir)/src/lib/ecore_txt \ +-I$(top_srcdir)/src/lib/ecore_job \ +-I$(top_builddir)/src/lib/ecore \ +-I$(top_builddir)/src/lib/ecore_txt \ +-I$(top_builddir)/src/lib/ecore_job + +libecore_x_la_LDFLAGS = -version-info 1:0:0 \ +-L$(top_builddir)/src/lib/ecore/.libs \ +-L$(top_builddir)/src/lib/ecore_txt/.libs \ +-L$(top_builddir)/src/lib/ecore_job/.libs + +if BUILD_ECORE_X + +lib_LTLIBRARIES = libecore_x.la +include_HEADERS = \ +Ecore_X.h \ +Ecore_X_Atoms.h \ +Ecore_X_Cursor.h + +libecore_x_la_SOURCES = \ +ecore_x.c \ +ecore_x_dnd.c \ +ecore_x_sync.c \ +ecore_x_error.c \ +ecore_x_events.c \ +ecore_x_icccm.c \ +ecore_x_netwm.c \ +ecore_x_mwm.c \ +ecore_x_e.c \ +ecore_x_selection.c \ +ecore_x_window.c \ +ecore_x_window_prop.c \ +ecore_x_window_shape.c \ +ecore_x_pixmap.c \ +ecore_x_gc.c \ +ecore_x_xinerama.c \ +ecore_x_private.h + +libecore_x_la_LIBADD = \ +@Xcursor_libs@ \ +@Xprint_libs@ \ +@Xinerama_libs@ \ +@x_ldflags@ \ +@x_libs@ \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(top_builddir)/src/lib/ecore_txt/libecore_txt.la \ +$(top_builddir)/src/lib/ecore_job/libecore_job.la + +libecore_x_la_DEPENDENCIES = \ +$(top_builddir)/src/lib/ecore/libecore.la \ +$(top_builddir)/src/lib/ecore_txt/libecore_txt.la \ +$(top_builddir)/src/lib/ecore_job/libecore_job.la + +endif + +EXTRA_DIST = \ +Ecore_X.h \ +Ecore_X_Atoms.h \ +Ecore_X_Cursor.h \ +ecore_x.c \ +ecore_x_dnd.c \ +ecore_x_sync.c \ +ecore_x_error.c \ +ecore_x_events.c \ +ecore_x_icccm.c \ +ecore_x_netwm.c \ +ecore_x_selection.c \ +ecore_x_window.c \ +ecore_x_window_prop.c \ +ecore_x_window_shape.c \ +ecore_x_pixmap.c \ +ecore_x_gc.c \ +ecore_x_private.h diff --git a/ecore/src/lib/ecore_x/ecore_x.c b/ecore/src/lib/ecore_x/ecore_x.c new file mode 100644 index 0000000..2d52bc3 --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x.c @@ -0,0 +1,1685 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "ecore_private.h" +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" + +static int _ecore_x_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); +static int _ecore_x_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler); +static int _ecore_x_key_mask_get(KeySym sym); +static void *_ecore_x_event_filter_start(void *data); +static int _ecore_x_event_filter_filter(void *data, void *loop_data,int type, void *event); +static void _ecore_x_event_filter_end(void *data, void *loop_data); + +static Ecore_Fd_Handler *_ecore_x_fd_handler_handle = NULL; +static Ecore_Event_Filter *_ecore_x_filter_handler = NULL; +static int _ecore_x_event_shape_id = 0; +static int _ecore_x_event_sync_id = 0; +static int _ecore_x_event_handlers_num = 0; +static void (**_ecore_x_event_handlers) (XEvent * event) = NULL; + +static int _ecore_x_init_count = 0; +static int _ecore_x_grab_count = 0; + +Display *_ecore_x_disp = NULL; +double _ecore_x_double_click_time = 0.25; +Time _ecore_x_event_last_time = 0; +Window _ecore_x_event_last_win = 0; +int _ecore_x_event_last_root_x = 0; +int _ecore_x_event_last_root_y = 0; +int _ecore_x_xcursor = 0; + +Ecore_X_Window _ecore_x_private_win = 0; + +/* FIXME - These are duplicates after making ecore atoms public */ +Ecore_X_Atom ECORE_X_ATOM_FILE_NAME = 0; +Ecore_X_Atom ECORE_X_ATOM_STRING = 0; +Ecore_X_Atom ECORE_X_ATOM_TEXT = 0; +Ecore_X_Atom ECORE_X_ATOM_UTF8_STRING = 0; +Ecore_X_Atom ECORE_X_ATOM_COMPOUND_TEXT = 0; + +Ecore_X_Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM]; + +/* + * GNOME hints. + */ +Ecore_X_Atom ECORE_X_ATOM_WIN_LAYER = 0; + +/* + * Other hints. + */ +Ecore_X_Atom ECORE_X_ATOM_SELECTION_TARGETS; +Ecore_X_Atom ECORE_X_ATOM_SELECTION_PRIMARY = 0; +Ecore_X_Atom ECORE_X_ATOM_SELECTION_SECONDARY = 0; +Ecore_X_Atom ECORE_X_ATOM_SELECTION_CLIPBOARD = 0; +Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_PRIMARY = 0; +Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_SECONDARY = 0; +Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD = 0; + +Ecore_X_Atom ECORE_X_ATOM_SELECTION_XDND = 0; +Ecore_X_Atom ECORE_X_ATOM_SELECTION_PROP_XDND = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_AWARE = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_ENTER = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_TYPE_LIST = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_POSITION = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_COPY = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_MOVE = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_LINK = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_PRIVATE = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_ASK = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_LIST = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_ACTION_DESCRIPTION = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_PROXY = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_STATUS = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_DROP = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_FINISHED = 0; +Ecore_X_Atom ECORE_X_ATOM_XDND_LEAVE = 0; + +/* Xdnd atoms that need to be exposed to the application interface */ +Ecore_X_Atom ECORE_X_DND_ACTION_COPY = 0; +Ecore_X_Atom ECORE_X_DND_ACTION_MOVE = 0; +Ecore_X_Atom ECORE_X_DND_ACTION_LINK = 0; +Ecore_X_Atom ECORE_X_DND_ACTION_ASK = 0; +Ecore_X_Atom ECORE_X_DND_ACTION_PRIVATE = 0; + +int ECORE_X_EVENT_KEY_DOWN = 0; +int ECORE_X_EVENT_KEY_UP = 0; +int ECORE_X_EVENT_MOUSE_BUTTON_DOWN = 0; +int ECORE_X_EVENT_MOUSE_BUTTON_UP = 0; +int ECORE_X_EVENT_MOUSE_MOVE = 0; +int ECORE_X_EVENT_MOUSE_IN = 0; +int ECORE_X_EVENT_MOUSE_OUT = 0; +int ECORE_X_EVENT_MOUSE_WHEEL = 0; +int ECORE_X_EVENT_WINDOW_FOCUS_IN = 0; +int ECORE_X_EVENT_WINDOW_FOCUS_OUT = 0; +int ECORE_X_EVENT_WINDOW_KEYMAP = 0; +int ECORE_X_EVENT_WINDOW_DAMAGE = 0; +int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = 0; +int ECORE_X_EVENT_WINDOW_CREATE = 0; +int ECORE_X_EVENT_WINDOW_DESTROY = 0; +int ECORE_X_EVENT_WINDOW_HIDE = 0; +int ECORE_X_EVENT_WINDOW_SHOW = 0; +int ECORE_X_EVENT_WINDOW_SHOW_REQUEST = 0; +int ECORE_X_EVENT_WINDOW_REPARENT = 0; +int ECORE_X_EVENT_WINDOW_CONFIGURE = 0; +int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = 0; +int ECORE_X_EVENT_WINDOW_GRAVITY = 0; +int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = 0; +int ECORE_X_EVENT_WINDOW_STACK = 0; +int ECORE_X_EVENT_WINDOW_STACK_REQUEST = 0; +int ECORE_X_EVENT_WINDOW_PROPERTY = 0; +int ECORE_X_EVENT_WINDOW_COLORMAP = 0; +int ECORE_X_EVENT_WINDOW_MAPPING = 0; +int ECORE_X_EVENT_SELECTION_CLEAR = 0; +int ECORE_X_EVENT_SELECTION_REQUEST = 0; +int ECORE_X_EVENT_SELECTION_NOTIFY = 0; +int ECORE_X_EVENT_CLIENT_MESSAGE = 0; +int ECORE_X_EVENT_WINDOW_SHAPE = 0; +int ECORE_X_EVENT_SYNC_COUNTER = 0; +int ECORE_X_EVENT_SYNC_ALARM = 0; + +int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0; +/* +int ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE = 0; +int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE = 0; +int ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE = 0; +int ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE = 0; +int ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = 0; +int ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = 0; +int ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = 0; +int ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = 0; +*/ + +int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = 0; +int ECORE_X_EVENT_WINDOW_STATE_REQUEST = 0; +int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = 0; +int ECORE_X_EVENT_PING = 0; +int ECORE_X_EVENT_DESKTOP_CHANGE = 0; + +int ECORE_X_EVENT_XDND_ENTER = 0; +int ECORE_X_EVENT_XDND_POSITION = 0; +int ECORE_X_EVENT_XDND_STATUS = 0; +int ECORE_X_EVENT_XDND_LEAVE = 0; +int ECORE_X_EVENT_XDND_DROP = 0; +int ECORE_X_EVENT_XDND_FINISHED = 0; + +int ECORE_X_MODIFIER_SHIFT = 0; +int ECORE_X_MODIFIER_CTRL = 0; +int ECORE_X_MODIFIER_ALT = 0; +int ECORE_X_MODIFIER_WIN = 0; + +int ECORE_X_LOCK_SCROLL = 0; +int ECORE_X_LOCK_NUM = 0; +int ECORE_X_LOCK_CAPS = 0; + +/** + * @defgroup Ecore_X_Init_Group X Library Init and Shutdown Functions + * + * Functions that start and shut down the Ecore X Library. + */ + +/** + * Initialize the X display connection to the given display. + * + * @param name Display target name. If @c NULL, the default display is + * assumed. + * @return The number of times the library has been initialized without + * being shut down. 0 is returned if an error occurs. + * @ingroup Ecore_X_Init_Group + */ +int +ecore_x_init(const char *name) +{ + int shape_base = 0; + int shape_err_base = 0; + int sync_base = 0; + int sync_err_base = 0; + + if (_ecore_x_init_count > 0) + { + _ecore_x_init_count++; + return _ecore_x_init_count; + } + _ecore_x_disp = XOpenDisplay((char *)name); + if (!_ecore_x_disp) return 0; + _ecore_x_error_handler_init(); + _ecore_x_event_handlers_num = LASTEvent; + + if (XShapeQueryExtension(_ecore_x_disp, &shape_base, &shape_err_base)) + _ecore_x_event_shape_id = shape_base + ShapeNotify; + if (_ecore_x_event_shape_id >= LASTEvent) + _ecore_x_event_handlers_num = _ecore_x_event_shape_id + 1; + + if (XSyncQueryExtension(_ecore_x_disp, &sync_base, &sync_err_base)) + { + int major, minor; + + _ecore_x_event_sync_id = sync_base; + if (!XSyncInitialize(_ecore_x_disp, &major, &minor)) + _ecore_x_event_sync_id = 0; + } + if (_ecore_x_event_sync_id + XSyncAlarmNotify >= LASTEvent) + _ecore_x_event_handlers_num = _ecore_x_event_sync_id + XSyncAlarmNotify + 1; + + _ecore_x_event_handlers = calloc(_ecore_x_event_handlers_num, sizeof(void *)); + if (!_ecore_x_event_handlers) + { + XCloseDisplay(_ecore_x_disp); + _ecore_x_fd_handler_handle = NULL; + _ecore_x_disp = NULL; + return 0; + } +#ifdef ECORE_XCURSOR + _ecore_x_xcursor = XcursorSupportsARGB(_ecore_x_disp); +#endif + _ecore_x_event_handlers[KeyPress] = _ecore_x_event_handle_key_press; + _ecore_x_event_handlers[KeyRelease] = _ecore_x_event_handle_key_release; + _ecore_x_event_handlers[ButtonPress] = _ecore_x_event_handle_button_press; + _ecore_x_event_handlers[ButtonRelease] = _ecore_x_event_handle_button_release; + _ecore_x_event_handlers[MotionNotify] = _ecore_x_event_handle_motion_notify; + _ecore_x_event_handlers[EnterNotify] = _ecore_x_event_handle_enter_notify; + _ecore_x_event_handlers[LeaveNotify] = _ecore_x_event_handle_leave_notify; + _ecore_x_event_handlers[FocusIn] = _ecore_x_event_handle_focus_in; + _ecore_x_event_handlers[FocusOut] = _ecore_x_event_handle_focus_out; + _ecore_x_event_handlers[KeymapNotify] = _ecore_x_event_handle_keymap_notify; + _ecore_x_event_handlers[Expose] = _ecore_x_event_handle_expose; + _ecore_x_event_handlers[GraphicsExpose] = _ecore_x_event_handle_graphics_expose; + _ecore_x_event_handlers[VisibilityNotify] = _ecore_x_event_handle_visibility_notify; + _ecore_x_event_handlers[CreateNotify] = _ecore_x_event_handle_create_notify; + _ecore_x_event_handlers[DestroyNotify] = _ecore_x_event_handle_destroy_notify; + _ecore_x_event_handlers[UnmapNotify] = _ecore_x_event_handle_unmap_notify; + _ecore_x_event_handlers[MapNotify] = _ecore_x_event_handle_map_notify; + _ecore_x_event_handlers[MapRequest] = _ecore_x_event_handle_map_request; + _ecore_x_event_handlers[ReparentNotify] = _ecore_x_event_handle_reparent_notify; + _ecore_x_event_handlers[ConfigureNotify] = _ecore_x_event_handle_configure_notify; + _ecore_x_event_handlers[ConfigureRequest] = _ecore_x_event_handle_configure_request; + _ecore_x_event_handlers[GravityNotify] = _ecore_x_event_handle_gravity_notify; + _ecore_x_event_handlers[ResizeRequest] = _ecore_x_event_handle_resize_request; + _ecore_x_event_handlers[CirculateNotify] = _ecore_x_event_handle_circulate_notify; + _ecore_x_event_handlers[CirculateRequest] = _ecore_x_event_handle_circulate_request; + _ecore_x_event_handlers[PropertyNotify] = _ecore_x_event_handle_property_notify; + _ecore_x_event_handlers[SelectionClear] = _ecore_x_event_handle_selection_clear; + _ecore_x_event_handlers[SelectionRequest] = _ecore_x_event_handle_selection_request; + _ecore_x_event_handlers[SelectionNotify] = _ecore_x_event_handle_selection_notify; + _ecore_x_event_handlers[ColormapNotify] = _ecore_x_event_handle_colormap_notify; + _ecore_x_event_handlers[MappingNotify] = _ecore_x_event_handle_mapping_notify; + _ecore_x_event_handlers[ClientMessage] = _ecore_x_event_handle_client_message; + if (_ecore_x_event_shape_id) + _ecore_x_event_handlers[_ecore_x_event_shape_id] = _ecore_x_event_handle_shape_change; + if (_ecore_x_event_sync_id) + { + _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncCounterNotify] = + _ecore_x_event_handle_sync_counter; + _ecore_x_event_handlers[_ecore_x_event_sync_id + XSyncAlarmNotify] = + _ecore_x_event_handle_sync_alarm; + } + if (!ECORE_X_EVENT_KEY_DOWN) + { + ECORE_X_EVENT_KEY_DOWN = ecore_event_type_new(); + ECORE_X_EVENT_KEY_UP = ecore_event_type_new(); + ECORE_X_EVENT_MOUSE_BUTTON_DOWN = ecore_event_type_new(); + ECORE_X_EVENT_MOUSE_BUTTON_UP = ecore_event_type_new(); + ECORE_X_EVENT_MOUSE_MOVE = ecore_event_type_new(); + ECORE_X_EVENT_MOUSE_IN = ecore_event_type_new(); + ECORE_X_EVENT_MOUSE_OUT = ecore_event_type_new(); + ECORE_X_EVENT_MOUSE_WHEEL = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_FOCUS_IN = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_FOCUS_OUT = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_KEYMAP = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_DAMAGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_CREATE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_DESTROY = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_HIDE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_SHOW = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_SHOW_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_REPARENT = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_CONFIGURE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_GRAVITY = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_STACK = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_STACK_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_PROPERTY = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_COLORMAP = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_MAPPING = ecore_event_type_new(); + ECORE_X_EVENT_SELECTION_CLEAR = ecore_event_type_new(); + ECORE_X_EVENT_SELECTION_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_SELECTION_NOTIFY = ecore_event_type_new(); + ECORE_X_EVENT_CLIENT_MESSAGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_SHAPE = ecore_event_type_new(); + ECORE_X_EVENT_SYNC_COUNTER = ecore_event_type_new(); + ECORE_X_EVENT_SYNC_ALARM = ecore_event_type_new(); + + ECORE_X_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new(); + /* + ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = ecore_event_type_new(); + */ + + ECORE_X_EVENT_DESKTOP_CHANGE = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_WINDOW_STATE_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = ecore_event_type_new(); + ECORE_X_EVENT_PING = ecore_event_type_new(); + + ECORE_X_EVENT_XDND_ENTER = ecore_event_type_new(); + ECORE_X_EVENT_XDND_POSITION = ecore_event_type_new(); + ECORE_X_EVENT_XDND_STATUS = ecore_event_type_new(); + ECORE_X_EVENT_XDND_LEAVE = ecore_event_type_new(); + ECORE_X_EVENT_XDND_DROP = ecore_event_type_new(); + ECORE_X_EVENT_XDND_FINISHED = ecore_event_type_new(); + } + + /* everything has these... unless its like a pda... :) */ + ECORE_X_MODIFIER_SHIFT = _ecore_x_key_mask_get(XK_Shift_L); + ECORE_X_MODIFIER_CTRL = _ecore_x_key_mask_get(XK_Control_L); + + /* apple's xdarwin has no alt!!!! */ + ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Alt_L); + if (!ECORE_X_MODIFIER_ALT) + ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Meta_L); + if (!ECORE_X_MODIFIER_ALT) + ECORE_X_MODIFIER_ALT = _ecore_x_key_mask_get(XK_Super_L); + + /* the windows key... a valid modifier :) */ + ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Super_L); + if (!ECORE_X_MODIFIER_WIN) + ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Mode_switch); + if (!ECORE_X_MODIFIER_WIN) + ECORE_X_MODIFIER_WIN = _ecore_x_key_mask_get(XK_Meta_L); + + ECORE_X_LOCK_SCROLL = _ecore_x_key_mask_get(XK_Scroll_Lock); + ECORE_X_LOCK_NUM = _ecore_x_key_mask_get(XK_Num_Lock); + ECORE_X_LOCK_CAPS = _ecore_x_key_mask_get(XK_Caps_Lock); + + _ecore_x_fd_handler_handle = + ecore_main_fd_handler_add(ConnectionNumber(_ecore_x_disp), + ECORE_FD_READ, + _ecore_x_fd_handler, _ecore_x_disp, + _ecore_x_fd_handler_buf, _ecore_x_disp); + if (!_ecore_x_fd_handler_handle) + { + XCloseDisplay(_ecore_x_disp); + free(_ecore_x_event_handlers); + _ecore_x_fd_handler_handle = NULL; + _ecore_x_disp = NULL; + _ecore_x_event_handlers = NULL; + return 0; + } + _ecore_x_filter_handler = ecore_event_filter_add(_ecore_x_event_filter_start, _ecore_x_event_filter_filter, _ecore_x_event_filter_end, NULL); + + ECORE_X_ATOM_COMPOUND_TEXT = XInternAtom(_ecore_x_disp, "COMPOUND_TEXT", False); + ECORE_X_ATOM_UTF8_STRING = XInternAtom(_ecore_x_disp, "UTF8_STRING", False); + ECORE_X_ATOM_FILE_NAME = XInternAtom(_ecore_x_disp, "FILE_NAME", False); + ECORE_X_ATOM_STRING = XInternAtom(_ecore_x_disp, "STRING", False); + ECORE_X_ATOM_TEXT = XInternAtom(_ecore_x_disp, "TEXT", False); + + /* Set up the ICCCM hints */ + ecore_x_icccm_init(); + + ECORE_X_ATOM_MOTIF_WM_HINTS = XInternAtom(_ecore_x_disp, "_MOTIF_WM_HINTS", False); + + ECORE_X_ATOM_WIN_LAYER = XInternAtom(_ecore_x_disp, "_WIN_LAYER", False); + + /* Set up the _NET_... hints */ + ecore_x_netwm_init(); + + /* old e hints init */ + ecore_x_e_init(); + + /* This is just to be anal about naming conventions */ + ECORE_X_ATOM_SELECTION_TARGETS = XInternAtom(_ecore_x_disp, "TARGETS", False); + ECORE_X_ATOM_SELECTION_PRIMARY = XA_PRIMARY; + ECORE_X_ATOM_SELECTION_SECONDARY = XA_SECONDARY; + ECORE_X_ATOM_SELECTION_CLIPBOARD = XInternAtom(_ecore_x_disp, "CLIPBOARD", False); + ECORE_X_ATOM_SELECTION_PROP_PRIMARY = XInternAtom(_ecore_x_disp, "_ECORE_SELECTION_PRIMARY", False); + ECORE_X_ATOM_SELECTION_PROP_SECONDARY = XInternAtom(_ecore_x_disp, "_ECORE_SELECTION_SECONDARY", False); + ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD = XInternAtom(_ecore_x_disp, "_ECORE_SELECTION_CLIPBOARD", False); + ECORE_X_ATOM_SELECTION_PROP_XDND = XInternAtom(_ecore_x_disp, "JXSelectionWindowProperty", False); + ECORE_X_ATOM_SELECTION_XDND = XInternAtom(_ecore_x_disp, "XdndSelection", False); + ECORE_X_ATOM_XDND_AWARE = XInternAtom(_ecore_x_disp, "XdndAware", False); + ECORE_X_ATOM_XDND_TYPE_LIST = XInternAtom(_ecore_x_disp, "XdndTypeList", False); + ECORE_X_ATOM_XDND_ENTER = XInternAtom(_ecore_x_disp, "XdndEnter", False); + ECORE_X_ATOM_XDND_POSITION = XInternAtom(_ecore_x_disp, "XdndPosition", False); + ECORE_X_ATOM_XDND_ACTION_COPY = XInternAtom(_ecore_x_disp, "XdndActionCopy", False); + ECORE_X_ATOM_XDND_ACTION_MOVE = XInternAtom(_ecore_x_disp, "XdndActionMove", False); + ECORE_X_ATOM_XDND_ACTION_PRIVATE = XInternAtom(_ecore_x_disp, "XdndActionPrivate", False); + ECORE_X_ATOM_XDND_ACTION_ASK = XInternAtom(_ecore_x_disp, "XdndActionAsk", False); + ECORE_X_ATOM_XDND_ACTION_LIST = XInternAtom(_ecore_x_disp, "XdndActionList", False); + ECORE_X_ATOM_XDND_ACTION_LINK = XInternAtom(_ecore_x_disp, "XdndActionLink", False); + ECORE_X_ATOM_XDND_ACTION_DESCRIPTION = XInternAtom(_ecore_x_disp, "XdndActionDescription", False); + ECORE_X_ATOM_XDND_PROXY = XInternAtom(_ecore_x_disp, "XdndProxy", False); + ECORE_X_ATOM_XDND_STATUS = XInternAtom(_ecore_x_disp, "XdndStatus", False); + ECORE_X_ATOM_XDND_LEAVE = XInternAtom(_ecore_x_disp, "XdndLeave", False); + ECORE_X_ATOM_XDND_DROP = XInternAtom(_ecore_x_disp, "XdndDrop", False); + ECORE_X_ATOM_XDND_FINISHED = XInternAtom(_ecore_x_disp, "XdndFinished", False); + + /* Initialize the globally defined xdnd atoms */ + ECORE_X_DND_ACTION_COPY = ECORE_X_ATOM_XDND_ACTION_COPY; + ECORE_X_DND_ACTION_MOVE = ECORE_X_ATOM_XDND_ACTION_MOVE; + ECORE_X_DND_ACTION_LINK = ECORE_X_ATOM_XDND_ACTION_LINK; + ECORE_X_DND_ACTION_ASK = ECORE_X_ATOM_XDND_ACTION_ASK; + ECORE_X_DND_ACTION_PRIVATE = ECORE_X_ATOM_XDND_ACTION_PRIVATE; + + _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_DELETE_REQUEST] = ECORE_X_ATOM_WM_DELETE_WINDOW; + _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_TAKE_FOCUS] = ECORE_X_ATOM_WM_TAKE_FOCUS; + _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_PING] = ECORE_X_ATOM_NET_WM_PING; + _ecore_x_atoms_wm_protocols[ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST; + + _ecore_x_selection_data_init(); + _ecore_x_dnd_init(); + + _ecore_x_init_count++; + + _ecore_x_private_win = ecore_x_window_override_new(0, -77, -777, 123, 456); + + return _ecore_x_init_count; +} + +static int +_ecore_x_shutdown(int close_display) +{ + _ecore_x_init_count--; + if (_ecore_x_init_count > 0) return _ecore_x_init_count; + if (!_ecore_x_disp) return _ecore_x_init_count; + if (close_display) + XCloseDisplay(_ecore_x_disp); + else + close(ConnectionNumber(_ecore_x_disp)); + free(_ecore_x_event_handlers); + ecore_main_fd_handler_del(_ecore_x_fd_handler_handle); + ecore_event_filter_del(_ecore_x_filter_handler); + _ecore_x_fd_handler_handle = NULL; + _ecore_x_filter_handler = NULL; + _ecore_x_disp = NULL; + _ecore_x_event_handlers = NULL; + _ecore_x_selection_shutdown(); + _ecore_x_dnd_shutdown(); + if (_ecore_x_init_count < 0) _ecore_x_init_count = 0; + return _ecore_x_init_count; +} + +/** + * Shuts down the Ecore X library. + * + * In shutting down the library, the X display connection is terminated + * and any event handlers for it are removed. + * + * @return The number of times the library has been initialized without + * being shut down. + * @ingroup Ecore_X_Init_Group + */ +int +ecore_x_shutdown(void) +{ + return _ecore_x_shutdown(1); +} + +/** + * Shuts down the Ecore X library. + * + * As ecore_x_shutdown, except do not close Display, only connection. + * + * @ingroup Ecore_X_Init_Group + */ +int +ecore_x_disconnect(void) +{ + return _ecore_x_shutdown(0); +} + +/** + * @defgroup Ecore_X_Display_Attr_Group X Display Attributes + * + * Functions that set and retrieve X display attributes. + */ + +/** + * Retrieves the Ecore_X_Display handle used for the current X connection. + * @return The current X display. + * @ingroup Ecore_X_Display_Attr_Group + */ +Ecore_X_Display * +ecore_x_display_get(void) +{ + return (Ecore_X_Display *)_ecore_x_disp; +} + +/** + * Retrieves the X display file descriptor. + * @return The current X display file descriptor. + * @ingroup Ecore_X_Display_Attr_Group + */ +int +ecore_x_fd_get(void) +{ + return ConnectionNumber(_ecore_x_disp); +} + +/** + * Sets the timeout for a double and triple clicks to be flagged. + * + * This sets the time between clicks before the double_click flag is + * set in a button down event. If 3 clicks occur within double this + * time, the triple_click flag is also set. + * + * @param t The time in seconds + * @ingroup Ecore_X_Display_Attr_Group + */ +void +ecore_x_double_click_time_set(double t) +{ + if (t < 0.0) t = 0.0; + _ecore_x_double_click_time = t; +} + +/** + * Retrieves the double and triple click flag timeout. + * + * See @ref ecore_x_double_click_time_set for more information. + * + * @return The timeout for double clicks in seconds. + * @ingroup Ecore_X_Display_Attr_Group + */ +double +ecore_x_double_click_time_get(void) +{ + return _ecore_x_double_click_time; +} + +/** + * @defgroup Ecore_X_Flush_Group X Synchronization Functions + * + * Functions that ensure that all commands that have been issued by the + * Ecore X library have been sent to the server. + */ + +/** + * Sends all X commands in the X Display buffer. + * @ingroup Ecore_X_Flush_Group + */ +void +ecore_x_flush(void) +{ + XFlush(_ecore_x_disp); +} + +/** + * Flushes the command buffer and waits until all requests have been + * processed by the server. + * @ingroup Ecore_X_Flush_Group + */ +void +ecore_x_sync(void) +{ + XSync(_ecore_x_disp, False); +} + +/** + * Kill all clients with subwindows under a given window. + * + * You can kill all clients connected to the X server by using + * @ref ecore_x_window_root_list to get a list of root windows, and + * then passing each root window to this function. + * + * @param root The window whose children will be killed. + */ +void +ecore_x_killall(Ecore_X_Window root) +{ + int screens; + int i, j; + + XGrabServer(_ecore_x_disp); + screens = ScreenCount(_ecore_x_disp); + + /* Tranverse window tree starting from root, and drag each + * before the firing squad */ + for (i = 0; i < screens; ++i) + { + Window root_r; + Window parent_r; + Window *children_r = NULL; + unsigned int num_children = 0; + + while (XQueryTree(_ecore_x_disp, root, &root_r, &parent_r, + &children_r, &num_children) && (num_children > 0)) + { + for (j = 0; j < num_children; ++j) + { + XKillClient(_ecore_x_disp, children_r[j]); + } + + XFree(children_r); + } + } + + XUngrabServer(_ecore_x_disp); + XSync(_ecore_x_disp, False); +} + +/** + * Kill a specific client + * + * You can kill a specific client woning window @p win + * + * @param win Window of the client to be killed + */ +void +ecore_x_kill(Ecore_X_Window win) +{ + XKillClient(_ecore_x_disp, win); +} + +/** + * Return the last event time + */ +Ecore_X_Time +ecore_x_current_time_get(void) +{ + return _ecore_x_event_last_time; +} + +static int +_ecore_x_fd_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) +{ + Display *d; + + d = data; + while (XPending(d)) + { + XEvent ev; + + XNextEvent(d, &ev); + if ((ev.type >= 0) && (ev.type < _ecore_x_event_handlers_num)) + { + if (_ecore_x_event_handlers[ev.type]) + _ecore_x_event_handlers[ev.type] (&ev); + } + } + return 1; +} + +static int +_ecore_x_fd_handler_buf(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) +{ + Display *d; + + d = data; + if (XPending(d)) return 1; + return 0; +} + +static int +_ecore_x_key_mask_get(KeySym sym) +{ + XModifierKeymap *mod; + KeySym sym2; + int i, j; + const int masks[8] = + { + ShiftMask, LockMask, ControlMask, + Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask + }; + + mod = XGetModifierMapping(_ecore_x_disp); + if ((mod) && (mod->max_keypermod > 0)) + { + for (i = 0; i < (8 * mod->max_keypermod); i++) + { + for (j = 0; j < 8; j++) + { + sym2 = XKeycodeToKeysym(_ecore_x_disp, mod->modifiermap[i], j); + if (sym2 != 0) break; + } + if (sym2 == sym) + { + int mask; + + mask = masks[i / mod->max_keypermod]; + if (mod->modifiermap) XFree(mod->modifiermap); + XFree(mod); + return mask; + } + } + } + if (mod) + { + if (mod->modifiermap) XFree(mod->modifiermap); + XFree(mod); + } + return 0; +} + +typedef struct _Ecore_X_Filter_Data Ecore_X_Filter_Data; + +struct _Ecore_X_Filter_Data +{ + int last_event_type; +}; + +static void * +_ecore_x_event_filter_start(void *data __UNUSED__) +{ + Ecore_X_Filter_Data *filter_data; + + filter_data = calloc(1, sizeof(Ecore_X_Filter_Data)); + return filter_data; +} + +static int +_ecore_x_event_filter_filter(void *data __UNUSED__, void *loop_data,int type, void *event __UNUSED__) +{ + Ecore_X_Filter_Data *filter_data; + + filter_data = loop_data; + if (!filter_data) return 1; + if (type == ECORE_X_EVENT_MOUSE_MOVE) + { + if ((filter_data->last_event_type) == ECORE_X_EVENT_MOUSE_MOVE) + { + filter_data->last_event_type = type; + return 0; + } + } + filter_data->last_event_type = type; + return 1; +} + +static void +_ecore_x_event_filter_end(void *data __UNUSED__, void *loop_data) +{ + Ecore_X_Filter_Data *filter_data; + + filter_data = loop_data; + if (filter_data) free(filter_data); +} + + + + + + + + + + + + + + + + + + + + + + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/* FIXME: these funcs need categorising */ +/*****************************************************************************/ + +/** + * Retrieves the geometry of the given drawable. + * @param d The given drawable. + * @param x Pointer to an integer into which the X position is to be stored. + * @param y Pointer to an integer into which the Y position is to be stored. + * @param w Pointer to an integer into which the width is to be stored. + * @param h Pointer to an integer into which the height is to be stored. + */ +void +ecore_x_drawable_geometry_get(Ecore_X_Drawable d, int *x, int *y, int *w, int *h) +{ + Window dummy_win; + int ret_x, ret_y; + unsigned int ret_w, ret_h, dummy_border, dummy_depth; + + if (!XGetGeometry(_ecore_x_disp, d, &dummy_win, &ret_x, &ret_y, + &ret_w, &ret_h, &dummy_border, &dummy_depth)) + { + ret_x = 0; + ret_y = 0; + ret_w = 0; + ret_h = 0; + } + + if (x) *x = ret_x; + if (y) *y = ret_y; + if (w) *w = (int) ret_w; + if (h) *h = (int) ret_h; +} + +/** + * Retrieves the width of the border of the given drawable. + * @param d The given drawable. + * @return The border width of the given drawable. + */ +int +ecore_x_drawable_border_width_get(Ecore_X_Drawable d) +{ + Window dummy_win; + int dummy_x, dummy_y; + unsigned int dummy_w, dummy_h, border_ret, dummy_depth; + + if (!XGetGeometry(_ecore_x_disp, d, &dummy_win, &dummy_x, &dummy_y, + &dummy_w, &dummy_h, &border_ret, &dummy_depth)) + border_ret = 0; + + return (int) border_ret; +} + +/** + * Retrieves the depth of the given drawable. + * @param d The given drawable. + * @return The depth of the given drawable. + */ +int +ecore_x_drawable_depth_get(Ecore_X_Drawable d) +{ + Window dummy_win; + int dummy_x, dummy_y; + unsigned int dummy_w, dummy_h, dummy_border, depth_ret; + + if (!XGetGeometry(_ecore_x_disp, d, &dummy_win, &dummy_x, &dummy_y, + &dummy_w, &dummy_h, &dummy_border, &depth_ret)) + depth_ret = 0; + + return (int) depth_ret; +} + +/** + * Get a list of all the root windows on the server. + * + * @note The returned array will need to be freed after use. + * @param num_ret Pointer to integer to put number of windows returned in. + * @return An array of all the root windows. @c NULL is returned if memory + * could not be allocated for the list, or if @p num_ret is @c NULL. + */ +Ecore_X_Window * +ecore_x_window_root_list(int *num_ret) +{ + int num, i; + Ecore_X_Window *roots; + + if (!num_ret) return NULL; + *num_ret = 0; +#ifdef ECORE_XPRINT + { + Screen **ps = NULL; + int psnum = 0; + + num = ScreenCount(_ecore_x_disp); + ps = XpQueryScreens(_ecore_x_disp, &psnum); + if (ps) + { + int overlap, j; + + overlap = 0; + for (i = 0; i < num; i++) + { + for (j = 0; j < psnum; j++) + { + if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j]) + overlap++; + } + } + roots = malloc((num - overlap) * sizeof(Window)); + if (roots) + { + int k; + + k = 0; + for (i = 0; i < num; i++) + { + int is_print; + + is_print = 0; + for (j = 0; j < psnum; j++) + { + if (ScreenOfDisplay(_ecore_x_disp, i) == ps[j]) + { + is_print = 1; + break; + } + } + if (!is_print) + { + roots[k] = RootWindow(_ecore_x_disp, i); + k++; + } + } + *num_ret = k; + } + XFree(ps); + } + else + { + roots = malloc(num * sizeof(Window)); + if (!roots) return NULL; + *num_ret = num; + for (i = 0; i < num; i++) + roots[i] = RootWindow(_ecore_x_disp, i); + } + } +#else + num = ScreenCount(_ecore_x_disp); + roots = malloc(num * sizeof(Window)); + if (!roots) return NULL; + *num_ret = num; + for (i = 0; i < num; i++) + roots[i] = RootWindow(_ecore_x_disp, i); +#endif + return roots; +} + +Ecore_X_Window +ecore_x_window_root_first_get(void) +{ + int num; + Ecore_X_Window root, *roots = NULL; + + roots = ecore_x_window_root_list(&num); + if(!(roots)) return 0; + + if (num > 0) + root = roots[0]; + else + root = 0; + + free(roots); + return root; +} + + +static void _ecore_x_window_manage_error(void *data); + +static int _ecore_x_window_manage_failed = 0; +static void +_ecore_x_window_manage_error(void *data __UNUSED__) +{ + if ((ecore_x_error_request_get() == X_ChangeWindowAttributes) && + (ecore_x_error_code_get() == BadAccess)) + _ecore_x_window_manage_failed = 1; +} + +int +ecore_x_window_manage(Ecore_X_Window win) +{ + XWindowAttributes att; + + if (XGetWindowAttributes(_ecore_x_disp, win, &att) != True) return 0; + ecore_x_sync(); + _ecore_x_window_manage_failed = 0; + ecore_x_error_handler_set(_ecore_x_window_manage_error, NULL); + XSelectInput(_ecore_x_disp, win, + EnterWindowMask | + LeaveWindowMask | + PropertyChangeMask | + ResizeRedirectMask | + SubstructureRedirectMask | + SubstructureNotifyMask | + StructureNotifyMask | + KeyPressMask | + KeyReleaseMask | + att.your_event_mask); + ecore_x_sync(); + ecore_x_error_handler_set(NULL, NULL); + if (_ecore_x_window_manage_failed) + { + _ecore_x_window_manage_failed = 0; + return 0; + } + return 1; +} + +void +ecore_x_window_container_manage(Ecore_X_Window win) +{ + XSelectInput(_ecore_x_disp, win, + ResizeRedirectMask | + SubstructureRedirectMask | + SubstructureNotifyMask); +} + +void +ecore_x_window_client_manage(Ecore_X_Window win) +{ + XSelectInput(_ecore_x_disp, win, + PropertyChangeMask | + ResizeRedirectMask | + FocusChangeMask | + ColormapChangeMask | + VisibilityChangeMask | + StructureNotifyMask + ); + XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask); +} + +void +ecore_x_window_sniff(Ecore_X_Window win) +{ + XSelectInput(_ecore_x_disp, win, + PropertyChangeMask | + SubstructureNotifyMask); +} + +void +ecore_x_window_client_sniff(Ecore_X_Window win) +{ + XSelectInput(_ecore_x_disp, win, + PropertyChangeMask | + FocusChangeMask | + ColormapChangeMask | + VisibilityChangeMask | + StructureNotifyMask); + XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask); +} + +/** + * Retrieves the atom value associated with the given name. + * @param name The given name. + * @return Associated atom value. + */ +Ecore_X_Atom +ecore_x_atom_get(const char *name) +{ + if (!_ecore_x_disp) return 0; + return XInternAtom(_ecore_x_disp, name, False); +} + + + + + + +int +ecore_x_window_attributes_get(Ecore_X_Window win, Ecore_X_Window_Attributes *att_ret) +{ + XWindowAttributes att; + + if (!XGetWindowAttributes(_ecore_x_disp, win, &att)) return 0; + memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes)); + att_ret->root = att.root; + att_ret->x = att.x; + att_ret->y = att.y; + att_ret->w = att.width; + att_ret->h = att.height; + att_ret->border = att.border_width; + att_ret->depth = att.depth; + if (att.map_state != IsUnmapped) att_ret->visible = 1; + if (att.map_state == IsViewable) att_ret->viewable = 1; + if (att.override_redirect) att_ret->override = 1; + if (att.class == InputOnly) att_ret->input_only = 1; + if (att.save_under) att_ret->save_under = 1; + att_ret->event_mask.mine = att.your_event_mask; + att_ret->event_mask.all = att.your_event_mask; + att_ret->event_mask.no_propagate = att.do_not_propagate_mask; + att_ret->window_gravity = att.win_gravity; + att_ret->pixel_gravity = att.win_gravity; + att_ret->colormap = att.colormap; + return 1; +} + +void +ecore_x_window_save_set_add(Ecore_X_Window win) +{ + XAddToSaveSet(_ecore_x_disp, win); +} + +void +ecore_x_window_save_set_del(Ecore_X_Window win) +{ + XRemoveFromSaveSet(_ecore_x_disp, win); +} + +Ecore_X_Window * +ecore_x_window_children_get(Ecore_X_Window win, int *num) +{ + Ecore_X_Window *windows = NULL; + Window root_ret = 0, parent_ret = 0, *children_ret = NULL; + unsigned int children_ret_num = 0; + + if (!XQueryTree(_ecore_x_disp, win, &root_ret, &parent_ret, &children_ret, + &children_ret_num)) + { + return NULL; + } + if (children_ret) + { + windows = malloc(children_ret_num * sizeof(Ecore_X_Window)); + if (windows) + { + unsigned int i; + + for (i = 0; i < children_ret_num; i++) + windows[i] = children_ret[i]; + *num = children_ret_num; + } + XFree(children_ret); + } + return windows; +} + + + + + + +int +ecore_x_cursor_color_supported_get(void) +{ + return _ecore_x_xcursor; +} + +Ecore_X_Cursor +ecore_x_cursor_new(Ecore_X_Window win, int *pixels, int w, int h, int hot_x, int hot_y) +{ +#ifdef ECORE_XCURSOR + if (_ecore_x_xcursor) + { + Cursor c; + XcursorImage *xci; + + xci = XcursorImageCreate(w, h); + if (xci) + { + int i; + + xci->xhot = hot_x; + xci->yhot = hot_y; + xci->delay = 0; + for (i = 0; i < (w * h); i++) + { + int r, g, b, a; + + a = (pixels[i] >> 24) & 0xff; + r = (((pixels[i] >> 16) & 0xff) * a) / 0xff; + g = (((pixels[i] >> 8 ) & 0xff) * a) / 0xff; + b = (((pixels[i] ) & 0xff) * a) / 0xff; + xci->pixels[i] = (a << 24) | (r << 16) | (g << 8) | (b); + } + c = XcursorImageLoadCursor(_ecore_x_disp, xci); + XcursorImageDestroy(xci); + return c; + } + } + else +#endif + { + XColor c1, c2; + Cursor c; + Pixmap pmap, mask; + GC gc; + XGCValues gcv; + XImage *xim; + unsigned int *pix; + int fr, fg, fb, br, bg, bb; + int brightest = 0; + int darkest = 255 * 3; + int x, y; + const int dither[2][2] = + { + {0, 2}, + {3, 1} + }; + + + pmap = XCreatePixmap(_ecore_x_disp, win, w, h, 1); + mask = XCreatePixmap(_ecore_x_disp, win, w, h, 1); + xim = XCreateImage(_ecore_x_disp, + DefaultVisual(_ecore_x_disp, 0), + 1, ZPixmap, 0, NULL, w, h, 32, 0); + xim->data = malloc(xim->bytes_per_line * xim->height); + + fr = 0x00; fg = 0x00; fb = 0x00; + br = 0xff; bg = 0xff; bb = 0xff; + pix = pixels; + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + int r, g, b, a; + + a = (pix[0] >> 24) & 0xff; + r = (pix[0] >> 16) & 0xff; + g = (pix[0] >> 8 ) & 0xff; + b = (pix[0] ) & 0xff; + if (a > 0) + { + if ((r + g + b) > brightest) + { + brightest = r + g + b; + br = r; + bg = g; + bb = b; + } + if ((r + g + b) < darkest) + { + darkest = r + g + b; + fr = r; + fg = g; + fb = b; + } + } + pix++; + } + } + + pix = pixels; + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + int v; + int r, g, b; + int d1, d2; + + r = (pix[0] >> 16) & 0xff; + g = (pix[0] >> 8 ) & 0xff; + b = (pix[0] ) & 0xff; + d1 = + ((r - fr) * (r - fr)) + + ((g - fg) * (g - fg)) + + ((b - fb) * (b - fb)); + d2 = + ((r - br) * (r - br)) + + ((g - bg) * (g - bg)) + + ((b - bb) * (b - bb)); + v = (((d2 * 255) / (d1 + d2)) * 5) / 256; + if (v > dither[x & 0x1][y & 0x1]) v = 1; + else v = 0; + XPutPixel(xim, x, y, v); + pix++; + } + } + gc = XCreateGC(_ecore_x_disp, pmap, 0, &gcv); + XPutImage(_ecore_x_disp, pmap, gc, xim, 0, 0, 0, 0, w, h); + XFreeGC(_ecore_x_disp, gc); + + pix = pixels; + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + int v; + + v = (((pix[0] >> 24) & 0xff) * 5) / 256; + if (v > dither[x & 0x1][y & 0x1]) v = 1; + else v = 0; + XPutPixel(xim, x, y, v); + pix++; + } + } + gc = XCreateGC(_ecore_x_disp, mask, 0, &gcv); + XPutImage(_ecore_x_disp, mask, gc, xim, 0, 0, 0, 0, w, h); + XFreeGC(_ecore_x_disp, gc); + + free(xim->data); + xim->data = NULL; + XDestroyImage(xim); + + c1.pixel = 0; + c1.red = fr << 8 | fr; + c1.green = fg << 8 | fg; + c1.blue = fb << 8 | fb; + c1.flags = DoRed | DoGreen | DoBlue; + + c2.pixel = 0; + c2.red = br << 8 | br; + c2.green = bg << 8 | bg; + c2.blue = bb << 8 | bb; + c2.flags = DoRed | DoGreen | DoBlue; + + c = XCreatePixmapCursor(_ecore_x_disp, + pmap, mask, + &c1, &c2, + hot_x, hot_y); + XFreePixmap(_ecore_x_disp, pmap); + XFreePixmap(_ecore_x_disp, mask); + return c; + } + return 0; +} + +void +ecore_x_cursor_free(Ecore_X_Cursor c) +{ + XFreeCursor(_ecore_x_disp, c); +} + +/* + * Returns the cursor for the given shape. + * Note that the return value must not be freed with + * ecore_x_cursor_free()! + */ +Ecore_X_Cursor +ecore_x_cursor_shape_get(int shape) +{ + /* Shapes are defined in Ecore_X_Cursor.h */ + return XCreateFontCursor(_ecore_x_disp, shape); +} + +int +ecore_x_pointer_grab(Ecore_X_Window win) +{ + return XGrabPointer(_ecore_x_disp, win, False, + ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask | PointerMotionMask, + GrabModeAsync, GrabModeAsync, + None, None, CurrentTime); +} + +int +ecore_x_pointer_confine_grab(Ecore_X_Window win) +{ + return XGrabPointer(_ecore_x_disp, win, False, + ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask | PointerMotionMask, + GrabModeAsync, GrabModeAsync, + win, None, CurrentTime); +} + +void +ecore_x_pointer_ungrab(void) +{ + XUngrabPointer(_ecore_x_disp, CurrentTime); +} + +int +ecore_x_pointer_warp(Ecore_X_Window win, int x, int y) +{ + return XWarpPointer(_ecore_x_disp, None, win, 0, 0, 0, 0, x, y); +} + +int +ecore_x_keyboard_grab(Ecore_X_Window win) +{ + return XGrabKeyboard(_ecore_x_disp, win, False, + GrabModeAsync, GrabModeAsync, + CurrentTime); +} + +void ecore_x_keyboard_ungrab(void) +{ + XUngrabKeyboard(_ecore_x_disp, CurrentTime); +} + +void +ecore_x_grab(void) +{ + _ecore_x_grab_count++; + + if (_ecore_x_grab_count == 1) + XGrabServer(_ecore_x_disp); +} + +void +ecore_x_ungrab(void) +{ + _ecore_x_grab_count--; + if (_ecore_x_grab_count < 0) + _ecore_x_grab_count = 0; + + if (_ecore_x_grab_count == 0) + { + XUngrabServer(_ecore_x_disp); + XSync(_ecore_x_disp, False); + } +} + +int _ecore_window_grabs_num = 0; +Window *_ecore_window_grabs = NULL; +int (*_ecore_window_grab_replay_func) (void *data, int event_type, void *event); +void *_ecore_window_grab_replay_data; + +void +ecore_x_passive_grab_replay_func_set(int (*func) (void *data, int event_type, void *event), void *data) +{ + _ecore_window_grab_replay_func = func; + _ecore_window_grab_replay_data = data; +} + +void +ecore_x_window_button_grab(Ecore_X_Window win, int button, + Ecore_X_Event_Mask event_mask, + int mod, int any_mod) +{ + unsigned int b; + unsigned int m; + unsigned int locks[8]; + int i, ev; + + b = button; + if (b == 0) b = AnyButton; + m = mod; + if (any_mod) m = AnyModifier; + locks[0] = 0; + locks[1] = ECORE_X_LOCK_CAPS; + locks[2] = ECORE_X_LOCK_NUM; + locks[3] = ECORE_X_LOCK_SCROLL; + locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM; + locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL; + locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + ev = event_mask; + for (i = 0; i < 8; i++) + XGrabButton(_ecore_x_disp, b, m | locks[i], + win, False, ev, GrabModeSync, GrabModeAsync, None, None); + _ecore_window_grabs_num++; + _ecore_window_grabs = realloc(_ecore_window_grabs, + _ecore_window_grabs_num * sizeof(Window)); + _ecore_window_grabs[_ecore_window_grabs_num - 1] = win; +} + +void +_ecore_x_sync_magic_send(int val, Ecore_X_Window swin) +{ + XEvent xev; + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.display = _ecore_x_disp; + xev.xclient.window = _ecore_x_private_win; + xev.xclient.format = 32; + xev.xclient.message_type = 27777; + xev.xclient.data.l[0] = 0x7162534; + xev.xclient.data.l[1] = 0x10000000 + val; + xev.xclient.data.l[2] = swin; + XSendEvent(_ecore_x_disp, _ecore_x_private_win, False, NoEventMask, &xev); +} + +void +_ecore_x_window_grab_remove(Ecore_X_Window win) +{ + int i, shuffle = 0; + + if (_ecore_window_grabs_num > 0) + { + for (i = 0; i < _ecore_window_grabs_num; i++) + { + if (shuffle) _ecore_window_grabs[i - 1] = _ecore_window_grabs[i]; + if ((!shuffle) && (_ecore_window_grabs[i] == win)) + shuffle = 1; + } + if (shuffle) + { + _ecore_window_grabs_num--; + _ecore_window_grabs = realloc(_ecore_window_grabs, + _ecore_window_grabs_num * sizeof(Window)); + } + } +} + +void +ecore_x_window_button_ungrab(Ecore_X_Window win, int button, + int mod, int any_mod) +{ + unsigned int b; + unsigned int m; + unsigned int locks[8]; + int i; + + b = button; + if (b == 0) b = AnyButton; + m = mod; + if (any_mod) m = AnyModifier; + locks[0] = 0; + locks[1] = ECORE_X_LOCK_CAPS; + locks[2] = ECORE_X_LOCK_NUM; + locks[3] = ECORE_X_LOCK_SCROLL; + locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM; + locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL; + locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + for (i = 0; i < 8; i++) + XUngrabButton(_ecore_x_disp, b, m | locks[i], win); + _ecore_x_sync_magic_send(1, win); +} + +int _ecore_key_grabs_num = 0; +Window *_ecore_key_grabs = NULL; + +void +ecore_x_window_key_grab(Ecore_X_Window win, char *key, + int mod, int any_mod) +{ + KeyCode keycode = 0; + KeySym keysym; + unsigned int m; + unsigned int locks[8]; + int i; + + if (!strncmp(key, "Keycode-", 8)) + keycode = atoi(key + 8); + else + { + keysym = XStringToKeysym(key); + if (keysym == NoSymbol) return; + keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key)); + } + if (keycode == 0) return; + + m = mod; + if (any_mod) m = AnyModifier; + locks[0] = 0; + locks[1] = ECORE_X_LOCK_CAPS; + locks[2] = ECORE_X_LOCK_NUM; + locks[3] = ECORE_X_LOCK_SCROLL; + locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM; + locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL; + locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + for (i = 0; i < 8; i++) + XGrabKey(_ecore_x_disp, keycode, m | locks[i], + win, True, GrabModeSync, GrabModeAsync); + _ecore_key_grabs_num++; + _ecore_key_grabs = realloc(_ecore_key_grabs, + _ecore_key_grabs_num * sizeof(Window)); + _ecore_key_grabs[_ecore_key_grabs_num - 1] = win; +} + +void +_ecore_x_key_grab_remove(Ecore_X_Window win) +{ + int i, shuffle = 0; + + if (_ecore_key_grabs_num > 0) + { + for (i = 0; i < _ecore_key_grabs_num; i++) + { + if (shuffle) _ecore_key_grabs[i - 1] = _ecore_key_grabs[i]; + if ((!shuffle) && (_ecore_key_grabs[i] == win)) + shuffle = 1; + } + if (shuffle) + { + _ecore_key_grabs_num--; + _ecore_key_grabs = realloc(_ecore_key_grabs, + _ecore_key_grabs_num * sizeof(Window)); + } + } +} + +void +ecore_x_window_key_ungrab(Ecore_X_Window win, char *key, + int mod, int any_mod) +{ + KeyCode keycode = 0; + KeySym keysym; + unsigned int m; + unsigned int locks[8]; + int i; + + if (!strncmp(key, "Keycode-", 8)) + keycode = atoi(key + 8); + else + { + keysym = XStringToKeysym(key); + if (keysym == NoSymbol) return; + keycode = XKeysymToKeycode(_ecore_x_disp, XStringToKeysym(key)); + } + if (keycode == 0) return; + + m = mod; + if (any_mod) m = AnyModifier; + locks[0] = 0; + locks[1] = ECORE_X_LOCK_CAPS; + locks[2] = ECORE_X_LOCK_NUM; + locks[3] = ECORE_X_LOCK_SCROLL; + locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM; + locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL; + locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL; + for (i = 0; i < 8; i++) + XUngrabKey(_ecore_x_disp, keycode, m | locks[i], win); + _ecore_x_sync_magic_send(2, win); +} + +/** + * Send client message with given type and format 32. + * + * @param win The window the message is sent to. + * @param type The client message type. + * @param d0 The client message data item 1 + * @param d1 The client message data item 2 + * @param d2 The client message data item 3 + * @param d3 The client message data item 4 + * @param d4 The client message data item 5 + * + * @return !0 on success. + */ +int +ecore_x_client_message32_send(Ecore_X_Window win, Ecore_X_Atom type, + Ecore_X_Event_Mask mask, + long d0, long d1, long d2, long d3, long d4) +{ + XEvent xev; + + xev.xclient.window = win; + xev.xclient.type = ClientMessage; + xev.xclient.message_type = type; + xev.xclient.format = 32; + xev.xclient.data.l[0] = d0; + xev.xclient.data.l[1] = d1; + xev.xclient.data.l[2] = d2; + xev.xclient.data.l[3] = d3; + xev.xclient.data.l[4] = d4; + + return XSendEvent(_ecore_x_disp, win, False, mask, &xev); +} + +/** + * Send client message with given type and format 8. + * + * @param win The window the message is sent to. + * @param type The client message type. + * @param data Data to be sent. + * @param len Number of data bytes, max 20. + * + * @return !0 on success. + */ +int +ecore_x_client_message8_send(Ecore_X_Window win, Ecore_X_Atom type, + const void *data, int len) +{ + XEvent xev; + + xev.xclient.window = win; + xev.xclient.type = ClientMessage; + xev.xclient.message_type = type; + xev.xclient.format = 8; + if (len > 20) + len = 20; + memcpy(xev.xclient.data.b, data, len); + memset(xev.xclient.data.b + len, 0, 20 - len); + + return XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev); +} + +void +ecore_x_focus_reset(void) +{ + XSetInputFocus(_ecore_x_disp, PointerRoot, RevertToPointerRoot, CurrentTime); +} + +void +ecore_x_events_allow_all(void) +{ + XAllowEvents(_ecore_x_disp, AsyncBoth, CurrentTime); +} + +void +ecore_x_pointer_last_xy_get(int *x, int *y) +{ + if (x) *x = _ecore_x_event_last_root_x; + if (y) *y = _ecore_x_event_last_root_y; +} + +void +ecore_x_pointer_xy_get(Ecore_X_Window win, int *x, int *y) +{ + Window rwin, cwin; + int rx, ry, wx, wy; + unsigned int mask; + + XQueryPointer(_ecore_x_disp, win, &rwin, &cwin, &rx, &ry, &wx, &wy, &mask); + if (x) *x = wx; + if (y) *y = wy; +} +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ diff --git a/ecore/src/lib/ecore_x/ecore_x_dnd.c b/ecore/src/lib/ecore_x/ecore_x_dnd.c new file mode 100644 index 0000000..84f3357 --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_dnd.c @@ -0,0 +1,405 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" + +static Ecore_X_DND_Source *_source = NULL; +static Ecore_X_DND_Target *_target = NULL; +static int _ecore_x_dnd_init_count = 0; + +void +_ecore_x_dnd_init(void) +{ + if (!_ecore_x_dnd_init_count) + { + _source = calloc(1, sizeof(Ecore_X_DND_Source)); + _source->version = ECORE_X_DND_VERSION; + _source->win = None; + _source->dest = None; + _source->state = ECORE_X_DND_SOURCE_IDLE; + + _target = calloc(1, sizeof(Ecore_X_DND_Target)); + _target->win = None; + _target->source = None; + _target->state = ECORE_X_DND_TARGET_IDLE; + } + + _ecore_x_dnd_init_count++; +} + +void +_ecore_x_dnd_shutdown(void) +{ + _ecore_x_dnd_init_count--; + if (_ecore_x_dnd_init_count > 0) + return; + + if (_source) + free(_source); + _source = NULL; + + if (_target) + free(_target); + _target = NULL; + + _ecore_x_dnd_init_count = 0; +} + +void +ecore_x_dnd_aware_set(Ecore_X_Window win, int on) +{ + Ecore_X_Atom prop_data = ECORE_X_DND_VERSION; + + if (on) + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_AWARE, + XA_ATOM, 32, &prop_data, 1); + else + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_AWARE); +} + +int +ecore_x_dnd_version_get(Ecore_X_Window win) +{ + unsigned char *prop_data; + int num; + + if (ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_AWARE, + XA_ATOM, 32, &prop_data, &num)) + { + int version = (int) *prop_data; + free(prop_data); + return version; + } + else + return 0; +} + +int +ecore_x_dnd_type_isset(Ecore_X_Window win, const char *type) +{ + int num, i, ret = 0; + unsigned char *data; + Ecore_X_Atom *atoms, atom; + + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST, + XA_ATOM, 32, &data, &num)) + return ret; + + atom = ecore_x_atom_get(type); + atoms = (Ecore_X_Atom *)data; + + for (i = 0; i < num; ++i) + { + if (atom == atoms[i]) + { + ret = 1; + break; + } + } + + XFree(data); + return ret; +} + +void +ecore_x_dnd_type_set(Ecore_X_Window win, const char *type, int on) +{ + Ecore_X_Atom atom; + Ecore_X_Atom *oldset = NULL, *newset = NULL; + int i, j = 0, num = 0; + unsigned char *data = NULL; + unsigned char *old_data = NULL; + + atom = ecore_x_atom_get(type); + ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST, + XA_ATOM, 32, &old_data, &num); + oldset = (Ecore_X_Atom *)old_data; + + if (on) + { + if (ecore_x_dnd_type_isset(win, type)) + { + XFree(old_data); + return; + } + newset = calloc(num + 1, sizeof(Ecore_X_Atom)); + if (!newset) return; + data = (unsigned char *)newset; + + for (i = 0; i < num; i++) + newset[i + 1] = oldset[i]; + /* prepend the new type */ + newset[0] = atom; + + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST, + XA_ATOM, 32, data, num + 1); + } + else + { + if (!ecore_x_dnd_type_isset(win, type)) + { + XFree(old_data); + return; + } + newset = calloc(num - 1, sizeof(Ecore_X_Atom)); + if (!newset) + { + XFree(old_data); + return; + } + data = (unsigned char *)newset; + for (i = 0; i < num; i++) + if (oldset[i] != atom) + newset[j++] = oldset[i]; + + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST, + XA_ATOM, 32, data, num - 1); + } + XFree(oldset); + free(newset); +} + +Ecore_X_DND_Source * +_ecore_x_dnd_source_get(void) +{ + return _source; +} + +Ecore_X_DND_Target * +_ecore_x_dnd_target_get(void) +{ + return _target; +} + +int +ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size) +{ + + if (!ecore_x_dnd_version_get(source)) + return 0; + + /* Take ownership of XdndSelection */ + if (!ecore_x_selection_xdnd_set(source, data, size)) + return 0; + + _source->win = source; + printf("source: 0x%x\n", source); + _source->state = ECORE_X_DND_SOURCE_DRAGGING; + _source->time = _ecore_x_event_last_time; + + /* Default Accepted Action: ask */ + _source->action = ECORE_X_ATOM_XDND_ACTION_ASK; + _source->accepted_action = None; + return 1; +} + +void +ecore_x_dnd_drop(void) +{ + XEvent xev; + + if (_source->dest) + { + xev.xany.type = ClientMessage; + xev.xany.display = _ecore_x_disp; + xev.xclient.format = 32; + xev.xclient.window = _source->dest; + + if (_source->will_accept) + { + xev.xclient.message_type = ECORE_X_ATOM_XDND_DROP; + xev.xclient.data.l[0] = _source->win; + xev.xclient.data.l[1] = 0; + xev.xclient.data.l[2] = _source->time; + XSendEvent(_ecore_x_disp, _source->dest, False, 0, &xev); + _source->state = ECORE_X_DND_SOURCE_DROPPED; + } + else + { + xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE; + xev.xclient.data.l[0] = _source->win; + xev.xclient.data.l[1] = 0; + XSendEvent(_ecore_x_disp, _source->dest, False, 0, &xev); + _source->state = ECORE_X_DND_SOURCE_IDLE; + } + } + else + { + /* Dropping on nothing */ + ecore_x_selection_xdnd_clear(); + _source->state = ECORE_X_DND_SOURCE_IDLE; + } +} + +void +ecore_x_dnd_send_status(int will_accept, int suppress, Ecore_X_Rectangle rectangle, Ecore_X_Atom action) +{ + XEvent xev; + + if (_target->state == ECORE_X_DND_TARGET_IDLE) + return; + + memset(&xev, 0, sizeof(XEvent)); + + _target->will_accept = will_accept; + + xev.xclient.type = ClientMessage; + xev.xclient.display = _ecore_x_disp; + xev.xclient.message_type = ECORE_X_ATOM_XDND_STATUS; + xev.xclient.format = 32; + xev.xclient.window = _target->source; + + xev.xclient.data.l[0] = _target->win; + xev.xclient.data.l[1] = 0; + if (will_accept) + xev.xclient.data.l[1] |= 0x1UL; + if (!suppress) + xev.xclient.data.l[1] |= 0x2UL; + + /* Set rectangle information */ + xev.xclient.data.l[2] = rectangle.x; + xev.xclient.data.l[2] <<= 16; + xev.xclient.data.l[2] |= rectangle.y; + xev.xclient.data.l[3] = rectangle.width; + xev.xclient.data.l[3] <<= 16; + xev.xclient.data.l[3] |= rectangle.height; + + if (will_accept) + { + xev.xclient.data.l[4] = action; + _target->accepted_action = action; + } + else + { + xev.xclient.data.l[4] = None; + _target->accepted_action = action; + } + + XSendEvent(_ecore_x_disp, _target->source, False, 0, &xev); +} + +void +ecore_x_dnd_send_finished(void) +{ + XEvent xev; + + if (_target->state == ECORE_X_DND_TARGET_IDLE) + return; + + xev.xany.type = ClientMessage; + xev.xany.display = _ecore_x_disp; + xev.xclient.message_type = ECORE_X_ATOM_XDND_FINISHED; + xev.xclient.format = 32; + xev.xclient.window = _target->source; + + xev.xclient.data.l[0] = _target->win; + xev.xclient.data.l[1] = 0; + xev.xclient.data.l[2] = 0; + if (_target->will_accept) + { + xev.xclient.data.l[1] |= 0x1UL; + xev.xclient.data.l[2] = _target->accepted_action; + } + XSendEvent(_ecore_x_disp, _target->source, False, 0, &xev); + + _target->state = ECORE_X_DND_TARGET_IDLE; +} + +void +_ecore_x_dnd_drag(int x, int y) +{ + XEvent xev; + Ecore_X_Window win; + + if (_source->state != ECORE_X_DND_SOURCE_DRAGGING) + return; + + /* Preinitialize XEvent struct */ + memset(&xev, 0, sizeof(XEvent)); + xev.xany.type = ClientMessage; + xev.xany.display = _ecore_x_disp; + xev.xclient.format = 32; + + /* Attempt to find a DND-capable window under the cursor */ + win = ecore_x_window_at_xy_get(x, y); + while ((win) && !(ecore_x_dnd_version_get(win))) + win = ecore_x_window_parent_get(win); + + /* Send XdndLeave to current destination window if we have left it */ + if ((_source->dest) && (win != _source->dest)) + { + xev.xclient.window = _source->dest; + xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE; + xev.xclient.data.l[0] = _source->win; + xev.xclient.data.l[1] = 0; + + XSendEvent(_ecore_x_disp, _source->dest, False, 0, &xev); + _source->suppress = 0; + } + + if (win) + { + int x1, x2, y1, y2; + + _source->version = MIN(ECORE_X_DND_VERSION, + ecore_x_dnd_version_get(win)); + if (win != _source->dest) + { + int i, num; + unsigned char *data; + Ecore_X_Atom *types; + + ecore_x_window_prop_property_get(_source->win, ECORE_X_ATOM_XDND_TYPE_LIST, + XA_ATOM, 32, &data, &num); + types = (Ecore_X_Atom *)data; + + /* Entered new window, send XdndEnter */ + xev.xclient.window = win; + xev.xclient.message_type = ECORE_X_ATOM_XDND_ENTER; + xev.xclient.data.l[0] = _source->win; + xev.xclient.data.l[1] = 0; + if (num > 3) + xev.xclient.data.l[1] |= 0x1UL; + else + xev.xclient.data.l[1] &= 0xfffffffeUL; + xev.xclient.data.l[1] |= ((unsigned long) _source->version) << 24; + + for (i = 2; i < 5; i++) + xev.xclient.data.l[i] = 0; + for (i = 0; i < MIN(num, 3); ++i) + xev.xclient.data.l[i + 2] = types[i]; + XFree(data); + XSendEvent(_ecore_x_disp, win, False, 0, &xev); + _source->await_status = 0; + } + + /* Determine if we're still in the rectangle from the last status */ + x1 = _source->rectangle.x; + x2 = _source->rectangle.x + _source->rectangle.width; + y1 = _source->rectangle.y; + y2 = _source->rectangle.y + _source->rectangle.height; + + if (!(_source->await_status) + || !(_source->suppress) + || ((x < x1) || (x > x2) + || (y < y1) || (y > y2))) + { + xev.xclient.window = win; + xev.xclient.message_type = ECORE_X_ATOM_XDND_POSITION; + xev.xclient.data.l[0] = _source->win; + xev.xclient.data.l[1] = 0; /* Reserved */ + xev.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff); + xev.xclient.data.l[3] = _source->time; /* Version 1 */ + xev.xclient.data.l[4] = _source->action; /* Version 2, Needs to be pre-set */ + XSendEvent(_ecore_x_disp, win, False, 0, &xev); + + _source->await_status = 1; + } + } + + _source->dest = win; +} + diff --git a/ecore/src/lib/ecore_x/ecore_x_e.c b/ecore/src/lib/ecore_x/ecore_x_e.c new file mode 100644 index 0000000..398f4cc --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_e.c @@ -0,0 +1,37 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +/* + * OLD E hints + */ +#include "config.h" +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" + +/* + * Convenience macros + */ +#define _ATOM_GET(name) \ + XInternAtom(_ecore_x_disp, name, False) + +Ecore_X_Atom ECORE_X_ATOM_E_FRAME_SIZE = 0; + +void +ecore_x_e_init(void) +{ + ECORE_X_ATOM_E_FRAME_SIZE = _ATOM_GET("_E_FRAME_SIZE"); +} + +void +ecore_x_e_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb) +{ + unsigned int frames[4]; + + frames[0] = fl; + frames[1] = fr; + frames[2] = ft; + frames[3] = fb; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_FRAME_SIZE, frames, 4); +} diff --git a/ecore/src/lib/ecore_x/ecore_x_error.c b/ecore/src/lib/ecore_x/ecore_x_error.c new file mode 100644 index 0000000..4307da0 --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_error.c @@ -0,0 +1,95 @@ +#include "ecore_private.h" +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" + +static void _ecore_x_error_handle(Display * d, XErrorEvent * ev); +static int _ecore_x_io_error_handle(Display *d); + +static void (*_error_func) (void *data) = NULL; +static void *_error_data = NULL; +static void (*_io_error_func) (void *data) = NULL; +static void *_io_error_data = NULL; +static int _error_request_code = 0; +static int _error_code = 0; + +/** + * Set the error handler. + * @param func The error handler function + * @param data The data to be passed to the handler function + * + * Set the X error handler function + */ +void +ecore_x_error_handler_set(void (*func) (void *data), const void *data) +{ + _error_func = func; + _error_data = (void *)data; +} + +/** + * Set the I/O error handler. + * @param func The I/O error handler function + * @param data The data to be passed to the handler function + * + * Set the X I/O error handler function + */ +void +ecore_x_io_error_handler_set(void (*func) (void *data), const void *data) +{ + _io_error_func = func; + _io_error_data = (void *)data; +} + +/** + * Get the request code that caused the error. + * @return The request code causing the X error + * + * Return the X request code that caused the last X error + */ +int +ecore_x_error_request_get(void) +{ + return _error_request_code; +} + +/** + * Get the error code from the error. + * @return The error code from the X error + * + * Return the error code from the last X error + */ +int +ecore_x_error_code_get(void) +{ + return _error_code; +} + +void +_ecore_x_error_handler_init(void) +{ + XSetErrorHandler((XErrorHandler)_ecore_x_error_handle); + XSetIOErrorHandler((XIOErrorHandler)_ecore_x_io_error_handle); +} + +static void +_ecore_x_error_handle(Display *d, XErrorEvent *ev) +{ + if (d == _ecore_x_disp) + { + _error_request_code = ev->request_code; + _error_code = ev->error_code; + if (_error_func) _error_func(_error_data); + } +} + +static int +_ecore_x_io_error_handle(Display *d) +{ + if (d == _ecore_x_disp) + { + if (_io_error_func) _io_error_func(_io_error_data); + else exit(-1); + } + return 0; +} diff --git a/ecore/src/lib/ecore_x/ecore_x_events.c b/ecore/src/lib/ecore_x/ecore_x_events.c new file mode 100644 index 0000000..5668442 --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_events.c @@ -0,0 +1,1565 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "ecore_private.h" +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" + +#if 0 +static void _ecore_x_event_free_window_prop_name_class_change(void *data, void *ev); +static void _ecore_x_event_free_window_prop_title_change(void *data, void *ev); +static void _ecore_x_event_free_window_prop_visible_title_change(void *data, void *ev); +static void _ecore_x_event_free_window_prop_icon_name_change(void *data, void *ev); +static void _ecore_x_event_free_window_prop_visible_icon_name_change(void *data, void *ev); +static void _ecore_x_event_free_window_prop_client_machine_change(void *data, void *ev); +#endif +static void _ecore_x_event_free_key_down(void *data, void *ev); +static void _ecore_x_event_free_key_up(void *data, void *ev); + +void +ecore_x_event_mask_set(Ecore_X_Window w, Ecore_X_Event_Mask mask) +{ + XWindowAttributes attr; + XSetWindowAttributes s_attr; + + if (!w) + w = DefaultRootWindow(_ecore_x_disp); + + memset(&attr, 0, sizeof(XWindowAttributes)); + XGetWindowAttributes(_ecore_x_disp, w, &attr); + s_attr.event_mask = mask | attr.your_event_mask; + XChangeWindowAttributes(_ecore_x_disp, w, CWEventMask, &s_attr); +} + +void +ecore_x_event_mask_unset(Ecore_X_Window w, Ecore_X_Event_Mask mask) +{ + XWindowAttributes attr; + XSetWindowAttributes s_attr; + + if (!w) + w = DefaultRootWindow(_ecore_x_disp); + + memset(&attr, 0, sizeof(XWindowAttributes)); + XGetWindowAttributes(_ecore_x_disp, w, &attr); + s_attr.event_mask = attr.your_event_mask & ~mask; + XChangeWindowAttributes(_ecore_x_disp, w, CWEventMask, &s_attr); +} + +#if 0 +static void +_ecore_x_event_free_window_prop_name_class_change(void *data, void *ev) +{ + Ecore_X_Event_Window_Prop_Name_Class_Change *e; + + e = ev; + if (e->name) free(e->name); + if (e->clas) free(e->clas); + free(e); +} + +static void +_ecore_x_event_free_window_prop_title_change(void *data, void *ev) +{ + Ecore_X_Event_Window_Prop_Title_Change *e; + + e = ev; + if (e->title) free(e->title); + free(e); +} + +static void +_ecore_x_event_free_window_prop_visible_title_change(void *data, void *ev) +{ + Ecore_X_Event_Window_Prop_Visible_Title_Change *e; + + e = ev; + if (e->title) free(e->title); + free(e); +} + +static void +_ecore_x_event_free_window_prop_icon_name_change(void *data, void *ev) +{ + Ecore_X_Event_Window_Prop_Icon_Name_Change *e; + + e = ev; + if (e->name) free(e->name); + free(e); +} + +static void +_ecore_x_event_free_window_prop_visible_icon_name_change(void *data, void *ev) +{ + Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e; + + e = ev; + if (e->name) free(e->name); + free(e); +} + +static void +_ecore_x_event_free_window_prop_client_machine_change(void *data, void *ev) +{ + Ecore_X_Event_Window_Prop_Client_Machine_Change *e; + + e = ev; + if (e->name) free(e->name); + free(e); +} +#endif + +static void +_ecore_x_event_free_key_down(void *data __UNUSED__, void *ev) +{ + Ecore_X_Event_Key_Down *e; + + e = ev; + if (e->keyname) free(e->keyname); + if (e->keysymbol) free(e->keysymbol); + if (e->key_compose) free(e->key_compose); + free(e); +} + +static void +_ecore_x_event_free_key_up(void *data __UNUSED__, void *ev) +{ + Ecore_X_Event_Key_Up *e; + + e = ev; + if (e->keyname) free(e->keyname); + if (e->keysymbol) free(e->keysymbol); + if (e->key_compose) free(e->key_compose); + free(e); +} + +static void +_ecore_x_event_free_xdnd_enter(void *data __UNUSED__, void *ev) +{ + Ecore_X_Event_Xdnd_Enter *e; + int i; + + e = ev; + for (i = 0; i < e->num_types; i++) + XFree(e->types[i]); + free(e->types); + free(e); +} + +static void +_ecore_x_event_free_selection_notify(void *data __UNUSED__, void *ev) +{ + Ecore_X_Event_Selection_Notify *e; + Ecore_X_Selection_Data *sel; + + e = ev; + sel = e->data; + if (sel->free) + sel->free(sel); + free(e->target); + free(e); +} + +void +_ecore_x_event_handle_key_press(XEvent *xevent) +{ + Ecore_X_Event_Key_Down *e; + char *keyname; + int val; + char buf[256]; + KeySym sym; + XComposeStatus stat; + + e = calloc(1, sizeof(Ecore_X_Event_Key_Down)); + if (!e) return; + keyname = XKeysymToString(XKeycodeToKeysym(xevent->xkey.display, + xevent->xkey.keycode, 0)); + if (!keyname) + { + snprintf(buf, sizeof(buf), "Keycode-%i", xevent->xkey.keycode); + keyname = buf; + } + e->keyname = strdup(keyname); + if (!e->keyname) + { + free(e); + return; + } + val = XLookupString((XKeyEvent *)xevent, buf, sizeof(buf), &sym, &stat); + if (val > 0) + { + buf[val] = 0; + e->key_compose = ecore_txt_convert("LATIN1", "UTF-8", buf); + } + else e->key_compose = NULL; + keyname = XKeysymToString(sym); + if (keyname) e->keysymbol = strdup(keyname); + else e->keysymbol = strdup(e->keyname); + if (!e->keysymbol) + { + if (e->keyname) free(e->keyname); + if (e->key_compose) free(e->key_compose); + free(e); + return; + } + if (xevent->xkey.subwindow) e->win = xevent->xkey.subwindow; + else e->win = xevent->xkey.window; + e->event_win = xevent->xkey.window; + e->time = xevent->xkey.time; + e->modifiers = xevent->xkey.state; + _ecore_x_event_last_time = e->time; + ecore_event_add(ECORE_X_EVENT_KEY_DOWN, e, _ecore_x_event_free_key_down, NULL); +} + +void +_ecore_x_event_handle_key_release(XEvent *xevent) +{ + Ecore_X_Event_Key_Up *e; + char *keyname; + int val; + char buf[256]; + KeySym sym; + XComposeStatus stat; + + e = calloc(1, sizeof(Ecore_X_Event_Key_Up)); + if (!e) return; + keyname = XKeysymToString(XKeycodeToKeysym(xevent->xkey.display, + xevent->xkey.keycode, 0)); + if (!keyname) + { + snprintf(buf, sizeof(buf), "Keycode-%i", xevent->xkey.keycode); + keyname = buf; + } + e->keyname = strdup(keyname); + if (!e->keyname) + { + free(e); + return; + } + val = XLookupString((XKeyEvent *)xevent, buf, sizeof(buf), &sym, &stat); + if (val > 0) + { + buf[val] = 0; + e->key_compose = ecore_txt_convert("LATIN1", "UTF-8", buf); + } + else e->key_compose = NULL; + keyname = XKeysymToString(sym); + if (keyname) e->keysymbol = strdup(keyname); + else e->keysymbol = strdup(e->keyname); + if (!e->keysymbol) + { + if (e->keyname) free(e->keyname); + if (e->key_compose) free(e->key_compose); + free(e); + return; + } + if (xevent->xkey.subwindow) e->win = xevent->xkey.subwindow; + else e->win = xevent->xkey.window; + e->event_win = xevent->xkey.window; + e->time = xevent->xkey.time; + e->modifiers = xevent->xkey.state; + _ecore_x_event_last_time = e->time; + ecore_event_add(ECORE_X_EVENT_KEY_UP, e, _ecore_x_event_free_key_up, NULL); +} + +void +_ecore_x_event_handle_button_press(XEvent *xevent) +{ + static Window last_win = 0; + static Window last_last_win = 0; + static Window last_event_win = 0; + static Window last_last_event_win = 0; + static Time last_time = 0; + static Time last_last_time = 0; + int did_triple = 0; + int i; + + if ((xevent->xbutton.button > 3) && (xevent->xbutton.button < 6)) + { + Ecore_X_Event_Mouse_Wheel *e; + + e = malloc(sizeof(Ecore_X_Event_Mouse_Wheel)); + + if (!e) + return; + + e->modifiers = 0; + e->direction = 0; + e->z = 0; + if (xevent->xbutton.button == 4) e->z = -1; + else if (xevent->xbutton.button == 5) e->z = 1; + e->x = xevent->xbutton.x; + e->y = xevent->xbutton.y; + e->root.x = xevent->xbutton.x_root; + e->root.y = xevent->xbutton.y_root; + + if (xevent->xbutton.subwindow) + e->win = xevent->xbutton.subwindow; + else + e->win = xevent->xbutton.window; + + e->event_win = xevent->xbutton.window; + e->time = xevent->xbutton.time; + _ecore_x_event_last_time = e->time; + _ecore_x_event_last_win = e->win; + _ecore_x_event_last_root_x = e->root.x; + _ecore_x_event_last_root_y = e->root.y; + ecore_event_add(ECORE_X_EVENT_MOUSE_WHEEL, e, NULL, NULL); + for (i = 0; i < _ecore_window_grabs_num; i++) + { + if ((_ecore_window_grabs[i] == xevent->xbutton.window) || + (_ecore_window_grabs[i] == xevent->xbutton.subwindow)) + { + int replay = 0; + + if (_ecore_window_grab_replay_func) + replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data, + ECORE_X_EVENT_MOUSE_WHEEL, + e); + if (replay) + XAllowEvents(xevent->xbutton.display, + ReplayPointer, + xevent->xbutton.time); + else + XAllowEvents(xevent->xbutton.display, + AsyncPointer, + xevent->xbutton.time); + break; + } + } + } + else + { + { + Ecore_X_Event_Mouse_Move *e; + + e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move)); + if (!e) return; + e->modifiers = xevent->xbutton.state; + e->x = xevent->xbutton.x; + e->y = xevent->xbutton.y; + e->root.x = xevent->xbutton.x_root; + e->root.y = xevent->xbutton.y_root; + if (xevent->xbutton.subwindow) e->win = xevent->xbutton.subwindow; + else e->win = xevent->xbutton.window; + e->event_win = xevent->xbutton.window; + e->time = xevent->xbutton.time; + _ecore_x_event_last_time = e->time; + _ecore_x_event_last_win = e->win; + _ecore_x_event_last_root_x = e->root.x; + _ecore_x_event_last_root_y = e->root.y; + ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL); + } + { + Ecore_X_Event_Mouse_Button_Down *e; + + e = calloc(1, sizeof(Ecore_X_Event_Mouse_Button_Down)); + if (!e) return; + e->button = xevent->xbutton.button; + e->modifiers = xevent->xbutton.state; + e->x = xevent->xbutton.x; + e->y = xevent->xbutton.y; + e->root.x = xevent->xbutton.x_root; + e->root.y = xevent->xbutton.y_root; + if (xevent->xbutton.subwindow) e->win = xevent->xbutton.subwindow; + else e->win = xevent->xbutton.window; + e->event_win = xevent->xbutton.window; + e->time = xevent->xbutton.time; + if (e->win == e->event_win) + { + if (((int)(e->time - last_time) <= + (int)(1000 * _ecore_x_double_click_time)) && + (e->win == last_win) + && (e->event_win == last_event_win) + ) + e->double_click = 1; + if (((int)(e->time - last_last_time) <= + (int)(2 * 1000 * _ecore_x_double_click_time)) && + (e->win == last_win) && (e->win == last_last_win) + && (e->event_win == last_event_win) && (e->event_win == last_last_event_win) + ) + { + did_triple = 1; + e->triple_click = 1; + } + } + _ecore_x_event_last_time = e->time; + _ecore_x_event_last_win = e->win; + _ecore_x_event_last_root_x = e->root.x; + _ecore_x_event_last_root_y = e->root.y; + ecore_event_add(ECORE_X_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL); + for (i = 0; i < _ecore_window_grabs_num; i++) + { + if ((_ecore_window_grabs[i] == xevent->xbutton.window) || + (_ecore_window_grabs[i] == xevent->xbutton.subwindow)) + { + int replay = 0; + + if (_ecore_window_grab_replay_func) + replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data, + ECORE_X_EVENT_MOUSE_BUTTON_DOWN, + e); + if (replay) + XAllowEvents(xevent->xbutton.display, + ReplayPointer, + xevent->xbutton.time); + else + XAllowEvents(xevent->xbutton.display, + AsyncPointer, + xevent->xbutton.time); + break; + } + } + if (e->win == e->event_win) + { + if (did_triple) + { + last_win = 0; + last_last_win = 0; + last_event_win = 0; + last_last_event_win = 0; + last_time = 0; + last_last_time = 0; + } + else + { + last_last_win = last_win; + if (xevent->xbutton.subwindow) + last_win = xevent->xbutton.subwindow; + else + last_win = xevent->xbutton.window; + last_last_event_win = last_event_win; + last_event_win = xevent->xbutton.window; + last_last_time = last_time; + last_time = xevent->xbutton.time; + } + } + } + } +} + +void +_ecore_x_event_handle_button_release(XEvent *xevent) +{ + /* filter out wheel buttons */ + if (xevent->xbutton.button <= 3) + { + { + Ecore_X_Event_Mouse_Move *e; + + e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move)); + if (!e) return; + e->modifiers = xevent->xbutton.state; + e->x = xevent->xbutton.x; + e->y = xevent->xbutton.y; + e->root.x = xevent->xbutton.x_root; + e->root.y = xevent->xbutton.y_root; + if (xevent->xbutton.subwindow) e->win = xevent->xbutton.subwindow; + else e->win = xevent->xbutton.window; + e->event_win = xevent->xbutton.window; + e->time = xevent->xbutton.time; + _ecore_x_event_last_time = e->time; + _ecore_x_event_last_win = e->win; + _ecore_x_event_last_root_x = e->root.x; + _ecore_x_event_last_root_y = e->root.y; + ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL); + } + { + Ecore_X_Event_Mouse_Button_Up *e; + + e = calloc(1, sizeof(Ecore_X_Event_Mouse_Button_Up)); + if (!e) return; + e->button = xevent->xbutton.button; + e->modifiers = xevent->xbutton.state; + e->x = xevent->xbutton.x; + e->y = xevent->xbutton.y; + e->root.x = xevent->xbutton.x_root; + e->root.y = xevent->xbutton.y_root; + if (xevent->xbutton.subwindow) e->win = xevent->xbutton.subwindow; + else e->win = xevent->xbutton.window; + e->event_win = xevent->xbutton.window; + e->time = xevent->xbutton.time; + _ecore_x_event_last_time = e->time; + _ecore_x_event_last_win = e->win; + _ecore_x_event_last_root_x = e->root.x; + _ecore_x_event_last_root_y = e->root.y; + ecore_event_add(ECORE_X_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL); + } + } +} + +void +_ecore_x_event_handle_motion_notify(XEvent *xevent) +{ + Ecore_X_Event_Mouse_Move *e; + + e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move)); + if (!e) return; + e->modifiers = xevent->xmotion.state; + e->x = xevent->xmotion.x; + e->y = xevent->xmotion.y; + e->root.x = xevent->xmotion.x_root; + e->root.y = xevent->xmotion.y_root; + if (xevent->xmotion.subwindow) e->win = xevent->xmotion.subwindow; + else e->win = xevent->xmotion.window; + e->event_win = xevent->xmotion.window; + e->time = xevent->xmotion.time; + _ecore_x_event_last_time = e->time; + _ecore_x_event_last_win = e->win; + _ecore_x_event_last_root_x = e->root.x; + _ecore_x_event_last_root_y = e->root.y; + + /* Xdnd handling */ + _ecore_x_dnd_drag(e->root.x, e->root.y); + + ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL); +} + +void +_ecore_x_event_handle_enter_notify(XEvent *xevent) +{ + { + Ecore_X_Event_Mouse_Move *e; + + e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move)); + if (!e) return; + e->modifiers = xevent->xcrossing.state; + e->x = xevent->xcrossing.x; + e->y = xevent->xcrossing.y; + e->root.x = xevent->xcrossing.x_root; + e->root.y = xevent->xcrossing.y_root; + if (xevent->xcrossing.subwindow) e->win = xevent->xcrossing.subwindow; + else e->win = xevent->xcrossing.window; + e->event_win = xevent->xcrossing.window; + e->time = xevent->xcrossing.time; + _ecore_x_event_last_time = e->time; + _ecore_x_event_last_win = e->win; + _ecore_x_event_last_root_x = e->root.x; + _ecore_x_event_last_root_y = e->root.y; + ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL); + } + { + Ecore_X_Event_Mouse_In *e; + + e = calloc(1, sizeof(Ecore_X_Event_Mouse_In)); + if (!e) return; + e->modifiers = xevent->xcrossing.state; + e->x = xevent->xcrossing.x; + e->y = xevent->xcrossing.y; + e->root.x = xevent->xcrossing.x_root; + e->root.y = xevent->xcrossing.y_root; + if (xevent->xcrossing.subwindow) e->win = xevent->xcrossing.subwindow; + else e->win = xevent->xcrossing.window; + e->event_win = xevent->xcrossing.window; + if (xevent->xcrossing.mode == NotifyNormal) e->mode = ECORE_X_EVENT_MODE_NORMAL; + else if (xevent->xcrossing.mode == NotifyGrab) e->mode = ECORE_X_EVENT_MODE_GRAB; + else if (xevent->xcrossing.mode == NotifyUngrab) e->mode = ECORE_X_EVENT_MODE_UNGRAB; + if (xevent->xcrossing.detail == NotifyAncestor) e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR; + else if (xevent->xcrossing.detail == NotifyVirtual) e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL; + else if (xevent->xcrossing.detail == NotifyInferior) e->detail = ECORE_X_EVENT_DETAIL_INFERIOR; + else if (xevent->xcrossing.detail == NotifyNonlinear) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR; + else if (xevent->xcrossing.detail == NotifyNonlinearVirtual) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL; + e->time = xevent->xcrossing.time; + _ecore_x_event_last_time = e->time; + ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL); + } +} + +void +_ecore_x_event_handle_leave_notify(XEvent *xevent) +{ + { + Ecore_X_Event_Mouse_Move *e; + + e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move)); + if (!e) return; + e->modifiers = xevent->xcrossing.state; + e->x = xevent->xcrossing.x; + e->y = xevent->xcrossing.y; + e->root.x = xevent->xcrossing.x_root; + e->root.y = xevent->xcrossing.y_root; + if (xevent->xcrossing.subwindow) e->win = xevent->xcrossing.subwindow; + else e->win = xevent->xcrossing.window; + e->event_win = xevent->xcrossing.window; + e->time = xevent->xcrossing.time; + _ecore_x_event_last_time = e->time; + _ecore_x_event_last_win = e->win; + _ecore_x_event_last_root_x = e->root.x; + _ecore_x_event_last_root_y = e->root.y; + ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL); + } + { + Ecore_X_Event_Mouse_Out *e; + + e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out)); + if (!e) return; + e->modifiers = xevent->xcrossing.state; + e->x = xevent->xcrossing.x; + e->y = xevent->xcrossing.y; + e->root.x = xevent->xcrossing.x_root; + e->root.y = xevent->xcrossing.y_root; + if (xevent->xcrossing.subwindow) e->win = xevent->xcrossing.subwindow; + else e->win = xevent->xcrossing.window; + e->event_win = xevent->xcrossing.window; + if (xevent->xcrossing.mode == NotifyNormal) e->mode = ECORE_X_EVENT_MODE_NORMAL; + else if (xevent->xcrossing.mode == NotifyGrab) e->mode = ECORE_X_EVENT_MODE_GRAB; + else if (xevent->xcrossing.mode == NotifyUngrab) e->mode = ECORE_X_EVENT_MODE_UNGRAB; + if (xevent->xcrossing.detail == NotifyAncestor) e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR; + else if (xevent->xcrossing.detail == NotifyVirtual) e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL; + else if (xevent->xcrossing.detail == NotifyInferior) e->detail = ECORE_X_EVENT_DETAIL_INFERIOR; + else if (xevent->xcrossing.detail == NotifyNonlinear) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR; + else if (xevent->xcrossing.detail == NotifyNonlinearVirtual) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL; + e->time = xevent->xcrossing.time; + _ecore_x_event_last_time = e->time; + _ecore_x_event_last_win = e->win; + _ecore_x_event_last_root_x = e->root.x; + _ecore_x_event_last_root_y = e->root.y; + ecore_event_add(ECORE_X_EVENT_MOUSE_OUT, e, NULL, NULL); + } +} + +void +_ecore_x_event_handle_focus_in(XEvent *xevent) +{ + Ecore_X_Event_Window_Focus_In *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In)); + if (!e) return; + e->win = xevent->xfocus.window; + if (xevent->xfocus.mode == NotifyNormal) e->mode = ECORE_X_EVENT_MODE_NORMAL; + else if (xevent->xfocus.mode == NotifyWhileGrabbed) e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED; + else if (xevent->xfocus.mode == NotifyGrab) e->mode = ECORE_X_EVENT_MODE_GRAB; + else if (xevent->xfocus.mode == NotifyUngrab) e->mode = ECORE_X_EVENT_MODE_UNGRAB; + if (xevent->xfocus.detail == NotifyAncestor) e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR; + else if (xevent->xfocus.detail == NotifyVirtual) e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL; + else if (xevent->xfocus.detail == NotifyInferior) e->detail = ECORE_X_EVENT_DETAIL_INFERIOR; + else if (xevent->xfocus.detail == NotifyNonlinear) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR; + else if (xevent->xfocus.detail == NotifyNonlinearVirtual) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL; + else if (xevent->xfocus.detail == NotifyPointer) e->detail = ECORE_X_EVENT_DETAIL_POINTER; + else if (xevent->xfocus.detail == NotifyPointerRoot) e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT; + else if (xevent->xfocus.detail == NotifyDetailNone) e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE; + e->time = _ecore_x_event_last_time; + _ecore_x_event_last_time = e->time; + ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL); +} + +void +_ecore_x_event_handle_focus_out(XEvent *xevent) +{ + Ecore_X_Event_Window_Focus_Out *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out)); + if (!e) return; + e->win = xevent->xfocus.window; + if (xevent->xfocus.mode == NotifyNormal) e->mode = ECORE_X_EVENT_MODE_NORMAL; + else if (xevent->xfocus.mode == NotifyWhileGrabbed) e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED; + else if (xevent->xfocus.mode == NotifyGrab) e->mode = ECORE_X_EVENT_MODE_GRAB; + else if (xevent->xfocus.mode == NotifyUngrab) e->mode = ECORE_X_EVENT_MODE_UNGRAB; + if (xevent->xfocus.detail == NotifyAncestor) e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR; + else if (xevent->xfocus.detail == NotifyVirtual) e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL; + else if (xevent->xfocus.detail == NotifyInferior) e->detail = ECORE_X_EVENT_DETAIL_INFERIOR; + else if (xevent->xfocus.detail == NotifyNonlinear) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR; + else if (xevent->xfocus.detail == NotifyNonlinearVirtual) e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL; + else if (xevent->xfocus.detail == NotifyPointer) e->detail = ECORE_X_EVENT_DETAIL_POINTER; + else if (xevent->xfocus.detail == NotifyPointerRoot) e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT; + else if (xevent->xfocus.detail == NotifyDetailNone) e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE; + e->time = _ecore_x_event_last_time; + _ecore_x_event_last_time = e->time; + ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL); +} + +void +_ecore_x_event_handle_keymap_notify(XEvent *xevent __UNUSED__) +{ + /* FIXME: handle this event type */ +} + +void +_ecore_x_event_handle_expose(XEvent *xevent) +{ + Ecore_X_Event_Window_Damage *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Damage)); + if (!e) return; + e->win = xevent->xexpose.window; + e->time = _ecore_x_event_last_time; + e->x = xevent->xexpose.x; + e->y = xevent->xexpose.y; + e->w = xevent->xexpose.width; + e->h = xevent->xexpose.height; + ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL); +} + +void +_ecore_x_event_handle_graphics_expose(XEvent *xevent) +{ + Ecore_X_Event_Window_Damage *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Damage)); + if (!e) return; + e->win = xevent->xgraphicsexpose.drawable; + e->time = _ecore_x_event_last_time; + e->x = xevent->xgraphicsexpose.x; + e->y = xevent->xgraphicsexpose.y; + e->w = xevent->xgraphicsexpose.width; + e->h = xevent->xgraphicsexpose.height; + ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL); +} + +void +_ecore_x_event_handle_visibility_notify(XEvent *xevent) +{ + if (xevent->xvisibility.state != VisibilityPartiallyObscured) + { + Ecore_X_Event_Window_Visibility_Change *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change)); + if (!e) return; + e->win = xevent->xvisibility.window; + e->time = _ecore_x_event_last_time; + if (xevent->xvisibility.state == VisibilityFullyObscured) + e->fully_obscured = 1; + else + e->fully_obscured = 0; + ecore_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL); + } +} + +void +_ecore_x_event_handle_create_notify(XEvent *xevent) +{ + Ecore_X_Event_Window_Create *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Create)); + e->win = xevent->xcreatewindow.window; + if (xevent->xcreatewindow.override_redirect) + e->override = 1; + else + e->override = 0; + e->time = _ecore_x_event_last_time; + ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL); +} + +void +_ecore_x_event_handle_destroy_notify(XEvent *xevent) +{ + Ecore_X_Event_Window_Destroy *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy)); + if (!e) return; + e->win = xevent->xdestroywindow.window; + e->time = _ecore_x_event_last_time; + if (e->win == _ecore_x_event_last_win) _ecore_x_event_last_win = 0; + ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL); +} + +void +_ecore_x_event_handle_unmap_notify(XEvent *xevent) +{ + Ecore_X_Event_Window_Hide *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Hide)); + if (!e) return; + e->win = xevent->xunmap.window; + e->time = _ecore_x_event_last_time; + ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL); +} + +void +_ecore_x_event_handle_map_notify(XEvent *xevent) +{ + Ecore_X_Event_Window_Show *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Show)); + if (!e) return; + e->win = xevent->xmap.window; + e->time = _ecore_x_event_last_time; + ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL); +} + +void +_ecore_x_event_handle_map_request(XEvent *xevent) +{ + Ecore_X_Event_Window_Show_Request *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request)); + if (!e) return; + e->win = xevent->xmaprequest.window; + e->time = _ecore_x_event_last_time; + e->parent = xevent->xmaprequest.parent; + ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL); +} + +void +_ecore_x_event_handle_reparent_notify(XEvent *xevent) +{ + Ecore_X_Event_Window_Reparent *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent)); + if (!e) return; + e->win = xevent->xreparent.window; + e->parent = xevent->xreparent.parent; + e->time = _ecore_x_event_last_time; + ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL); +} + +void +_ecore_x_event_handle_configure_notify(XEvent *xevent) +{ + Ecore_X_Event_Window_Configure *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Configure)); + if (!e) return; + e->win = xevent->xconfigure.window; + e->abovewin = xevent->xconfigure.above; + e->x = xevent->xconfigure.x; + e->y = xevent->xconfigure.y; + e->w = xevent->xconfigure.width; + e->h = xevent->xconfigure.height; + e->border = xevent->xconfigure.border_width; + e->override = xevent->xconfigure.override_redirect; + e->from_wm = xevent->xconfigure.send_event; + e->time = _ecore_x_event_last_time; + ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL); +} + +void +_ecore_x_event_handle_configure_request(XEvent *xevent) +{ + Ecore_X_Event_Window_Configure_Request *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request)); + if (!e) return; + e->win = xevent->xconfigurerequest.window; + e->abovewin = xevent->xconfigurerequest.above; + e->x = xevent->xconfigurerequest.x; + e->y = xevent->xconfigurerequest.y; + e->w = xevent->xconfigurerequest.width; + e->h = xevent->xconfigurerequest.height; + e->border = xevent->xconfigurerequest.border_width; + e->value_mask = xevent->xconfigurerequest.value_mask; + e->time = _ecore_x_event_last_time; + if (xevent->xconfigurerequest.detail == Above) + e->detail = ECORE_X_WINDOW_STACK_ABOVE; + else if (xevent->xconfigurerequest.detail == Below) + e->detail = ECORE_X_WINDOW_STACK_BELOW; + else if (xevent->xconfigurerequest.detail == TopIf) + e->detail = ECORE_X_WINDOW_STACK_TOP_IF; + else if (xevent->xconfigurerequest.detail == BottomIf) + e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF; + else if (xevent->xconfigurerequest.detail == Opposite) + e->detail = ECORE_X_WINDOW_STACK_OPPOSITE; + ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL); +} + +void +_ecore_x_event_handle_gravity_notify(XEvent *xevent __UNUSED__) +{ + /* FIXME: handle this event type */ +} + +void +_ecore_x_event_handle_resize_request(XEvent *xevent) +{ + Ecore_X_Event_Window_Resize_Request *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request)); + if (!e) return; + e->win = xevent->xresizerequest.window; + e->w = xevent->xresizerequest.width; + e->h = xevent->xresizerequest.height; + e->time = _ecore_x_event_last_time; + ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL); +} + +void +_ecore_x_event_handle_circulate_notify(XEvent *xevent __UNUSED__) +{ + /* FIXME: handle this event type */ +} + +void +_ecore_x_event_handle_circulate_request(XEvent *xevent __UNUSED__) +{ + /* FIXME: handle this event type */ +} + +void +_ecore_x_event_handle_property_notify(XEvent *xevent) +{ +#if 0 /* for now i disabled this. nice idea though this is - it leaves a lot + * to be desired for efficiency that is better left to the app layer + */ + if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLASS) + { + Ecore_X_Event_Window_Prop_Name_Class_Change *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Name_Class_Change)); + if (!e) return; + ecore_x_window_prop_name_class_get(xevent->xproperty.window, + &(e->name), &(e->clas)); + e->time = xevent->xproperty.time; + _ecore_x_event_last_time = e->time; + ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE, e, _ecore_x_event_free_window_prop_name_class_change, NULL); + } + else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_NAME) || (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_NAME)) + { + Ecore_X_Event_Window_Prop_Title_Change *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Title_Change)); + if (!e) return; + e->title = ecore_x_window_prop_title_get(xevent->xproperty.window); + e->time = xevent->xproperty.time; + _ecore_x_event_last_time = e->time; + ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE, e, _ecore_x_event_free_window_prop_title_change, NULL); + } + else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_NAME) + { + Ecore_X_Event_Window_Prop_Visible_Title_Change *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Title_Change)); + if (!e) return; + e->title = ecore_x_window_prop_visible_title_get(xevent->xproperty.window); + e->time = xevent->xproperty.time; + _ecore_x_event_last_time = e->time; + ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE, e, _ecore_x_event_free_window_prop_visible_title_change, NULL); + } + else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_ICON_NAME) || (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_ICON_NAME)) + { + Ecore_X_Event_Window_Prop_Icon_Name_Change *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Icon_Name_Change)); + if (!e) return; + e->name = ecore_x_window_prop_icon_name_get(xevent->xproperty.window); + e->time = xevent->xproperty.time; + _ecore_x_event_last_time = e->time; + ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE, e, _ecore_x_event_free_window_prop_icon_name_change, NULL); + } + else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME) + { + Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change)); + if (!e) return; + e->name = ecore_x_window_prop_visible_icon_name_get(xevent->xproperty.window); + e->time = xevent->xproperty.time; + _ecore_x_event_last_time = e->time; + ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE, e, _ecore_x_event_free_window_prop_visible_icon_name_change, NULL); + } + else if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLIENT_MACHINE) + { + Ecore_X_Event_Window_Prop_Client_Machine_Change *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Client_Machine_Change)); + if (!e) return; + e->name = ecore_x_window_prop_client_machine_get(xevent->xproperty.window); + e->time = xevent->xproperty.time; + _ecore_x_event_last_time = e->time; + ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE, e, _ecore_x_event_free_window_prop_client_machine_change, NULL); + } + else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_PID) + { + Ecore_X_Event_Window_Prop_Pid_Change *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Pid_Change)); + if (!e) return; + e->pid = ecore_x_window_prop_pid_get(xevent->xproperty.window); + e->time = xevent->xproperty.time; + _ecore_x_event_last_time = e->time; + ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL); + } + else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_DESKTOP) + { + Ecore_X_Event_Window_Prop_Desktop_Change *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Desktop_Change)); + if (!e) return; + e->desktop = ecore_x_window_prop_desktop_get(xevent->xproperty.window); + ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL); + } + else +#endif + { + Ecore_X_Event_Window_Property *e; + + e = calloc(1,sizeof(Ecore_X_Event_Window_Property)); + if (!e) return; + e->win = xevent->xproperty.window; + e->atom = xevent->xproperty.atom; + e->time = xevent->xproperty.time; + _ecore_x_event_last_time = e->time; + ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL); + } +} + +void +_ecore_x_event_handle_selection_clear(XEvent *xevent) +{ + Ecore_X_Selection_Intern *d; + Ecore_X_Event_Selection_Clear *e; + Ecore_X_Atom sel; + + if (!(d = _ecore_x_selection_get(xevent->xselectionclear.selection))) + return; + if (xevent->xselectionclear.time > d->time) + { + _ecore_x_selection_set(None, NULL, 0, + xevent->xselectionclear.selection); + } + + /* Generate event for app cleanup */ + e = malloc(sizeof(Ecore_X_Event_Selection_Clear)); + e->win = xevent->xselectionclear.window; + e->time = xevent->xselectionclear.time; + sel = xevent->xselectionclear.selection; + if (sel == ECORE_X_ATOM_SELECTION_PRIMARY) + e->selection = ECORE_X_SELECTION_PRIMARY; + else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY) + e->selection = ECORE_X_SELECTION_SECONDARY; + else + e->selection = ECORE_X_SELECTION_CLIPBOARD; + ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL); + +} + +void +_ecore_x_event_handle_selection_request(XEvent *xevent) +{ + Ecore_X_Selection_Intern *sd; + XSelectionEvent xnotify; + XEvent xev; + void *data; + + xnotify.type = SelectionNotify; + xnotify.display = xevent->xselectionrequest.display; + xnotify.requestor = xevent->xselectionrequest.requestor; + xnotify.selection = xevent->xselectionrequest.selection; + xnotify.target = xevent->xselectionrequest.target; + xnotify.time = CurrentTime; + xnotify.send_event = True; + xnotify.serial = 0; + + if ((sd = _ecore_x_selection_get(xnotify.selection)) + && (sd->win == xevent->xselectionrequest.owner)) + { + if (!_ecore_x_selection_convert(xnotify.selection, xnotify.target, + &data) == -1) + { + /* Refuse selection, conversion to requested target failed */ + xnotify.property = None; + } + else + { + /* FIXME: This does not properly handle large data transfers */ + ecore_x_window_prop_property_set(xevent->xselectionrequest.requestor, + xevent->xselectionrequest.property, + xevent->xselectionrequest.target, + 8, data, sd->length); + xnotify.property = xevent->xselectionrequest.property; + free(data); + } + } + else + { + xnotify.property = None; + return; + } + + xev.xselection = xnotify; + XSendEvent(xevent->xselectionrequest.display, + xevent->xselectionrequest.requestor, False, 0, &xev); +} + +void +_ecore_x_event_handle_selection_notify(XEvent *xevent) +{ + Ecore_X_Event_Selection_Notify *e; + unsigned char *data = NULL; + Ecore_X_Atom selection; + int num_ret; + + selection = xevent->xselection.selection; + + if (xevent->xselection.target == ECORE_X_ATOM_SELECTION_TARGETS) + { + if (!ecore_x_window_prop_property_get(xevent->xselection.requestor, + xevent->xselection.property, + XA_ATOM, 32, &data, &num_ret)) + return; + } + else + { + if (!ecore_x_window_prop_property_get(xevent->xselection.requestor, + xevent->xselection.property, + AnyPropertyType, 8, &data, &num_ret)) + return; + } + + e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify)); + e->win = xevent->xselection.requestor; + e->time = xevent->xselection.time; + e->target = _ecore_x_selection_target_get(xevent->xselection.target); + + if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) + e->selection = ECORE_X_SELECTION_PRIMARY; + else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) + e->selection = ECORE_X_SELECTION_SECONDARY; + else if (selection == ECORE_X_ATOM_SELECTION_XDND) + e->selection = ECORE_X_SELECTION_XDND; + else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) + e->selection = ECORE_X_SELECTION_CLIPBOARD; + else + { + free(e); + return; + } + e->data = _ecore_x_selection_parse(e->target, data, num_ret); + + ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e, _ecore_x_event_free_selection_notify, NULL); +} + +void +_ecore_x_event_handle_colormap_notify(XEvent *xevent) +{ + Ecore_X_Event_Window_Colormap *e; + + e = calloc(1,sizeof(Ecore_X_Event_Window_Colormap)); + e->win = xevent->xcolormap.window; + e->cmap = xevent->xcolormap.colormap; + e->time = _ecore_x_event_last_time; + if (xevent->xcolormap.state == ColormapInstalled) + e->installed = 1; + else + e->installed = 0; + ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL); +} + +void +_ecore_x_event_handle_client_message(XEvent *xevent) +{ + /* Special client message event handling here. need to put LOTS of if */ + /* checks here and generate synthetic events per special message known */ + /* otherwise generate generic client message event. this would handle*/ + /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */ + if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS) && + (xevent->xclient.format == 32) && + (xevent->xclient.data.l[0] == (long)ECORE_X_ATOM_WM_DELETE_WINDOW)) + { + Ecore_X_Event_Window_Delete_Request *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request)); + if (!e) return; + e->win = xevent->xclient.window; + e->time = _ecore_x_event_last_time; + ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL); + } + + else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_MOVERESIZE) && + (xevent->xclient.format == 32) && + /* Ignore move and resize with keyboard */ + (xevent->xclient.data.l[2] < 9)) + { + Ecore_X_Event_Window_Move_Resize_Request *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request)); + if (!e) return; + e->win = xevent->xclient.window; + e->x = xevent->xclient.data.l[0]; + e->y = xevent->xclient.data.l[1]; + e->direction = xevent->xclient.data.l[2]; + e->button = xevent->xclient.data.l[3]; + e->source = xevent->xclient.data.l[4]; + ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL); + } + + /* Xdnd Client Message Handling Begin */ + /* Message Type: XdndEnter target */ + else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_ENTER) + { + Ecore_X_Event_Xdnd_Enter *e; + Ecore_X_DND_Target *target; + unsigned long three; + + e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter)); + if (!e) return; + + target = _ecore_x_dnd_target_get(); + target->state = ECORE_X_DND_TARGET_ENTERED; + + target = _ecore_x_dnd_target_get(); + target->source = xevent->xclient.data.l[0]; + target->win = xevent->xclient.window; + target->version = (int) (xevent->xclient.data.l[1] >> 24); + if (target->version > ECORE_X_DND_VERSION) + { + printf("DND: Requested version %d, we only support up to %d\n", target->version, + ECORE_X_DND_VERSION); + return; + } + + if ((three = xevent->xclient.data.l[1] & 0x1UL)) + { + /* source supports more than 3 types, fetch property */ + unsigned char *data; + Ecore_X_Atom *types; + int i, num_ret; + if (!(ecore_x_window_prop_property_get(target->source, + ECORE_X_ATOM_XDND_TYPE_LIST, + XA_ATOM, + 32, + &data, + &num_ret))) + { + printf("DND: Could not fetch data type list from source window, aborting.\n"); + return; + } + types = (Ecore_X_Atom *)data; + e->types = calloc(num_ret, sizeof(char *)); + for (i = 0; i < num_ret; i++) + e->types[i] = XGetAtomName(_ecore_x_disp, types[i]); + e->num_types = num_ret; + } + else + { + int i = 0; + + e->types = calloc(3, sizeof(char *)); + while ((i < 3) && (xevent->xclient.data.l[i + 2])) + { + e->types[i] = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[i + 2]); + i++; + } + e->num_types = i; + } + + e->win = target->win; + e->source = target->source; + ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e, _ecore_x_event_free_xdnd_enter, NULL); + } + + /* Message Type: XdndPosition target */ + else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_POSITION) + { + Ecore_X_Event_Xdnd_Position *e; + Ecore_X_DND_Target *target; + + target = _ecore_x_dnd_target_get(); + if ((target->source != xevent->xclient.data.l[0]) + || (target->win != xevent->xclient.window)) + return; + + target->pos.x = xevent->xclient.data.l[2] >> 16; + target->pos.y = xevent->xclient.data.l[2] & 0xFFFFUL; + target->action = xevent->xclient.data.l[4]; /* Version 2 */ + + target->time = (target->version >= 1) ? + (Time)xevent->xclient.data.l[3] : CurrentTime; + + e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position)); + if (!e) return; + e->win = target->win; + e->source = target->source; + e->position.x = target->pos.x; + e->position.y = target->pos.y; + e->action = target->action; + ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL); + } + + /* Message Type: XdndStatus source */ + else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_STATUS) + { + Ecore_X_Event_Xdnd_Status *e; + Ecore_X_DND_Source *source; + + source = _ecore_x_dnd_source_get(); + /* Make sure source/target match */ + if ((source->win != xevent->xclient.window ) + || (source->dest != (Window)xevent->xclient.data.l[0])) + return; + + source->await_status = 0; + + source->will_accept = xevent->xclient.data.l[1] & 0x1UL; + source->suppress = (xevent->xclient.data.l[1] & 0x2UL) ? 0 : 1; + + source->rectangle.x = xevent->xclient.data.l[2] >> 16; + source->rectangle.y = xevent->xclient.data.l[2] & 0xFFFFUL; + source->rectangle.width = xevent->xclient.data.l[3] >> 16; + source->rectangle.height = xevent->xclient.data.l[3] & 0xFFFFUL; + + source->accepted_action = xevent->xclient.data.l[4]; + + e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status)); + if (!e) return; + e->win = source->win; + e->target = source->dest; + e->will_accept = source->will_accept; + e->rectangle.x = source->rectangle.x; + e->rectangle.y = source->rectangle.y; + e->rectangle.width = source->rectangle.width; + e->rectangle.height = source->rectangle.height; + e->action = source->accepted_action; + + ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL); + } + + /* Message Type: XdndLeave target */ + /* Pretend the whole thing never happened, sort of */ + else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_LEAVE) + { + Ecore_X_Event_Xdnd_Leave *e; + Ecore_X_DND_Target *target; + + target = _ecore_x_dnd_target_get(); + if ((target->source != xevent->xclient.data.l[0]) + || (target->win != xevent->xclient.window)) + return; + + target->state = ECORE_X_DND_TARGET_IDLE; + + e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave)); + if (!e) return; + e->win = xevent->xclient.window; + e->source = (Window)xevent->xclient.data.l[0]; + ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL); + } + + /* Message Type: XdndDrop target */ + else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_DROP) + { + Ecore_X_Event_Xdnd_Drop *e; + Ecore_X_DND_Target *target; + + target = _ecore_x_dnd_target_get(); + /* Match source/target */ + if ((target->source != (Window)xevent->xclient.data.l[0]) + || (target->win != xevent->xclient.window)) + return; + + target->time = (target->version >= 1) ? + (Time)xevent->xclient.data.l[2] : _ecore_x_event_last_time; + + e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop)); + if (!e) return; + e->win = target->win; + e->source = target->source; + e->action = target->action; + e->position.x = target->pos.x; + e->position.y = target->pos.y; + ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL); + } + + /* Message Type: XdndFinished source */ + else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_FINISHED) + { + Ecore_X_Event_Xdnd_Finished *e; + Ecore_X_DND_Source *source; + int completed = 1; + + source = _ecore_x_dnd_source_get(); + /* Match source/target */ + if ((source->win != xevent->xclient.window) + || (source->dest != (Window)xevent->xclient.data.l[0])) + return; + + if ((source->version >= 5) && (xevent->xclient.data.l[1] & 0x1UL)) + { + /* Target successfully performed drop action */ + ecore_x_selection_xdnd_clear(); + source->state = ECORE_X_DND_SOURCE_IDLE; + } + else + { + completed = 0; + source->state = ECORE_X_DND_SOURCE_CONVERTING; + + /* FIXME: Probably need to add a timer to switch back to idle + * and discard the selection data */ + } + + e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished)); + if (!e) return; + e->win = source->win; + e->target = source->dest; + e->completed = completed; + if (source->version >= 5) + { + source->accepted_action = xevent->xclient.data.l[2]; + e->action = source->accepted_action; + } + else + { + source->accepted_action = 0; + e->action = source->action; + } + + ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL); + } + else if (xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_STATE) + { + Ecore_X_Event_Window_State_Request *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request)); + if (!e) return; + e->win = xevent->xclient.window; + if (xevent->xclient.data.l[0] == 0) + e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE; + else if (xevent->xclient.data.l[0] == 1) + e->action = ECORE_X_WINDOW_STATE_ACTION_ADD; + else if (xevent->xclient.data.l[0] == 2) + e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE; + else + { + free(e); + return; + } + e->state[0] = _ecore_x_netwm_state_get(xevent->xclient.data.l[1]); + if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN) + { + char *name; + name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[1]); + if (name) + printf("Unknown state: %s\n", name); + XFree(name); + } + e->state[1] = _ecore_x_netwm_state_get(xevent->xclient.data.l[2]); + if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN) + { + char *name; + name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[2]); + if (name) + printf("Unknown state: %s\n", name); + XFree(name); + } + e->source = xevent->xclient.data.l[3]; + + ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL); + } + else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_CHANGE_STATE) + && (xevent->xclient.format == 32) + && (xevent->xclient.data.l[0] == IconicState)) + { + Ecore_X_Event_Window_State_Request *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request)); + if (!e) return; + e->win = xevent->xclient.window; + e->action = ECORE_X_WINDOW_STATE_ACTION_ADD; + e->state[0] = ECORE_X_WINDOW_STATE_ICONIFIED; + + ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL); + } + else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_DESKTOP) + && (xevent->xclient.format == 32)) + { + Ecore_X_Event_Desktop_Change *e; + + e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change)); + if (!e) return; + e->win = xevent->xclient.window; + e->desk = xevent->xclient.data.l[0]; + e->source = xevent->xclient.data.l[1]; + + ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL); + } + else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS)) + { + Ecore_X_Event_Frame_Extents_Request *e; + + e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request)); + if (!e) return; + e->win = xevent->xclient.window; + + ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL); + } + else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS) + && (xevent->xclient.data.l[0] == ECORE_X_ATOM_NET_WM_PING) + && (xevent->xclient.format == 32)) + { + Ecore_X_Event_Ping *e; + + e = calloc(1, sizeof(Ecore_X_Event_Ping)); + if (!e) return; + e->win = xevent->xclient.window; + e->time = xevent->xclient.data.l[1]; + e->event_win = xevent->xclient.data.l[2]; + + ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL); + } + else if ((xevent->xclient.message_type == 27777) + && (xevent->xclient.data.l[0] == 0x7162534) + && (xevent->xclient.format == 32) + && (xevent->xclient.window == _ecore_x_private_win)) + { + /* a grab sync marker */ + if (xevent->xclient.data.l[1] == 0x10000001) + _ecore_x_window_grab_remove(xevent->xclient.data.l[2]); + else if (xevent->xclient.data.l[1] == 0x10000002) + _ecore_x_key_grab_remove(xevent->xclient.data.l[2]); + } + else + { + Ecore_X_Event_Client_Message *e; + int i; + + e = calloc(1, sizeof(Ecore_X_Event_Client_Message)); + if (!e) return; + e->win = xevent->xclient.window; + e->message_type = xevent->xclient.message_type; + e->format = xevent->xclient.format; + for (i = 0; i < 5; i++) + e->data.l[i] = xevent->xclient.data.l[i]; + + ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL); + } +} + +void +_ecore_x_event_handle_mapping_notify(XEvent *xevent __UNUSED__) +{ + /* FIXME: handle this event type */ +} + +void +_ecore_x_event_handle_shape_change(XEvent *xevent) +{ + XShapeEvent *shape_event; + Ecore_X_Event_Window_Shape *e; + + shape_event = (XShapeEvent *)xevent; + e = calloc(1, sizeof(Ecore_X_Event_Window_Shape)); + if (!e) return; + e->win = shape_event->window; + e->time = shape_event->time; + ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL); +} + +void +_ecore_x_event_handle_sync_counter(XEvent *xevent) +{ + XSyncCounterNotifyEvent *sync_counter_event; + Ecore_X_Event_Sync_Counter *e; + + sync_counter_event = (XSyncCounterNotifyEvent *)xevent; + e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter)); + if (!e) return; + e->time = sync_counter_event->time; + ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL); +} + +void +_ecore_x_event_handle_sync_alarm(XEvent *xevent) +{ + XSyncAlarmNotifyEvent *sync_alarm_event; + Ecore_X_Event_Sync_Alarm *e; + + sync_alarm_event = (XSyncAlarmNotifyEvent *)xevent; + + e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm)); + if (!e) return; + e->time = sync_alarm_event->time; + e->alarm = sync_alarm_event->alarm; + ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL); +} diff --git a/ecore/src/lib/ecore_x/ecore_x_gc.c b/ecore/src/lib/ecore_x/ecore_x_gc.c new file mode 100644 index 0000000..99ff0e1 --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_gc.c @@ -0,0 +1,29 @@ +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" + +/** + * Creates a new default graphics context associated with the given + * drawable. + * @param draw Drawable to create graphics context with. If @c 0 is + * given instead, the default root window is used. + * @return The new default graphics context. + */ +Ecore_X_GC +ecore_x_gc_new(Ecore_X_Drawable draw) +{ + XGCValues gcv; + + if (!draw) draw = DefaultRootWindow(_ecore_x_disp); + return XCreateGC(_ecore_x_disp, draw, 0, &gcv); +} + +/** + * Deletes and frees the given graphics context. + * @param gc The given graphics context. + */ +void +ecore_x_gc_del(Ecore_X_GC gc) +{ + XFreeGC(_ecore_x_disp, gc); +} diff --git a/ecore/src/lib/ecore_x/ecore_x_icccm.c b/ecore/src/lib/ecore_x/ecore_x_icccm.c new file mode 100644 index 0000000..a29a83a --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_icccm.c @@ -0,0 +1,1082 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +/* + * Various ICCCM related functions. + * + * This is ALL the code involving anything ICCCM related. for both WM and + * client. + */ +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" + +/* Atoms */ +Ecore_X_Atom ECORE_X_ATOM_WM_STATE = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_DELETE_WINDOW = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_TAKE_FOCUS = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_PROTOCOLS = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_CLASS = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_NAME = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_COMMAND = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_ICON_NAME = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_MACHINE = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_CHANGE_STATE = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_COLORMAP_WINDOWS = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_WINDOW_ROLE = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_HINTS = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_NORMAL_HINTS = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_CLIENT_LEADER = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_TRANSIENT_FOR = 0; +Ecore_X_Atom ECORE_X_ATOM_WM_SAVE_YOURSELF = 0; + +void +ecore_x_icccm_init(void) +{ + + ECORE_X_ATOM_WM_STATE = XInternAtom(_ecore_x_disp, "WM_STATE", False); + ECORE_X_ATOM_WM_DELETE_WINDOW = + XInternAtom(_ecore_x_disp, "WM_DELETE_WINDOW", False); + ECORE_X_ATOM_WM_TAKE_FOCUS = + XInternAtom(_ecore_x_disp, "WM_TAKE_FOCUS", False); + ECORE_X_ATOM_WM_PROTOCOLS = + XInternAtom(_ecore_x_disp, "WM_PROTOCOLS", False); + ECORE_X_ATOM_WM_CLASS = XInternAtom(_ecore_x_disp, "WM_CLASS", False); + ECORE_X_ATOM_WM_NAME = XInternAtom(_ecore_x_disp, "WM_NAME", False); + ECORE_X_ATOM_WM_COMMAND = XInternAtom(_ecore_x_disp, "WM_COMMAND", False); + ECORE_X_ATOM_WM_ICON_NAME = + XInternAtom(_ecore_x_disp, "WM_ICON_NAME", False); + ECORE_X_ATOM_WM_CLIENT_MACHINE = + XInternAtom(_ecore_x_disp, "WM_CLIENT_MACHINE", False); + ECORE_X_ATOM_WM_CHANGE_STATE = + XInternAtom(_ecore_x_disp, "WM_CHANGE_STATE", False); + ECORE_X_ATOM_WM_COLORMAP_WINDOWS = + XInternAtom(_ecore_x_disp, "WM_COLORMAP_WINDOWS", False); + ECORE_X_ATOM_WM_WINDOW_ROLE = + XInternAtom(_ecore_x_disp, "WM_WINDOW_ROLE", False); + ECORE_X_ATOM_WM_HINTS = XInternAtom(_ecore_x_disp, "WM_HINTS", False); + ECORE_X_ATOM_WM_NORMAL_HINTS = + XInternAtom(_ecore_x_disp, "WM_NORMAL_HINTS", False); + ECORE_X_ATOM_WM_CLIENT_LEADER = + XInternAtom(_ecore_x_disp, "WM_CLIENT_LEADER", False); + ECORE_X_ATOM_WM_TRANSIENT_FOR = + XInternAtom(_ecore_x_disp, "WM_TRANSIENT_FOR", False); + ECORE_X_ATOM_WM_SAVE_YOURSELF = + XInternAtom(_ecore_x_disp, "WM_SAVE_YOURSELF", False); +} + +void +ecore_x_icccm_state_set(Ecore_X_Window win, Ecore_X_Window_State_Hint state) +{ + unsigned long c[2]; + + if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) + c[0] = WithdrawnState; + else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL) + c[0] = NormalState; + else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC) + c[0] = IconicState; + c[1] = None; + XChangeProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_STATE, + ECORE_X_ATOM_WM_STATE, 32, PropModeReplace, + (unsigned char *)c, 2); +} + +Ecore_X_Window_State_Hint +ecore_x_icccm_state_get(Ecore_X_Window win) +{ + unsigned char *prop_ret = NULL; + Atom type_ret; + unsigned long bytes_after, num_ret; + int format_ret; + Ecore_X_Window_State_Hint hint; + + hint = ECORE_X_WINDOW_STATE_HINT_NONE; + XGetWindowProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_STATE, + 0, 0x7fffffff, False, ECORE_X_ATOM_WM_STATE, + &type_ret, &format_ret, &num_ret, &bytes_after, + &prop_ret); + if ((prop_ret) && (num_ret == 2)) + { + if (prop_ret[0] == WithdrawnState) + hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; + else if (prop_ret[0] == NormalState) + hint = ECORE_X_WINDOW_STATE_HINT_NORMAL; + else if (prop_ret[0] == IconicState) + hint = ECORE_X_WINDOW_STATE_HINT_ICONIC; + } + + if (prop_ret) + XFree(prop_ret); + + return hint; +} + +void +ecore_x_icccm_delete_window_send(Ecore_X_Window win, Ecore_X_Time t) +{ + ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, + ECORE_X_EVENT_MASK_NONE, + ECORE_X_ATOM_WM_DELETE_WINDOW, + t, 0, 0, 0); +} + +void +ecore_x_icccm_take_focus_send(Ecore_X_Window win, Ecore_X_Time t) +{ + ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, + ECORE_X_EVENT_MASK_NONE, + ECORE_X_ATOM_WM_TAKE_FOCUS, + t, 0, 0, 0); +} + +void +ecore_x_icccm_save_yourself_send(Ecore_X_Window win, Ecore_X_Time t) +{ + ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, + ECORE_X_EVENT_MASK_NONE, + ECORE_X_ATOM_WM_SAVE_YOURSELF, + t, 0, 0, 0); +} + +void +ecore_x_icccm_move_resize_send(Ecore_X_Window win, int x, int y, int w, int h) +{ + XEvent ev; + + ev.type = ConfigureNotify; + ev.xconfigure.display = _ecore_x_disp; + ev.xconfigure.event = win; + ev.xconfigure.window = win; + ev.xconfigure.x = x; + ev.xconfigure.y = y; + ev.xconfigure.width = w; + ev.xconfigure.height = h; + ev.xconfigure.border_width = 0; + ev.xconfigure.above = None; + ev.xconfigure.override_redirect = False; + XSendEvent(_ecore_x_disp, win, False, StructureNotifyMask, &ev); +} + +void +ecore_x_icccm_hints_set(Ecore_X_Window win, + int accepts_focus, + Ecore_X_Window_State_Hint initial_state, + Ecore_X_Pixmap icon_pixmap, + Ecore_X_Pixmap icon_mask, + Ecore_X_Window icon_window, + Ecore_X_Window window_group, int is_urgent) +{ + XWMHints *hints; + + hints = XAllocWMHints(); + if (!hints) + return; + + hints->flags = InputHint | StateHint; + hints->input = accepts_focus; + if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN) + hints->initial_state = WithdrawnState; + else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL) + hints->initial_state = NormalState; + else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC) + hints->initial_state = IconicState; + if (icon_pixmap != 0) + { + hints->icon_pixmap = icon_pixmap; + hints->flags |= IconPixmapHint; + } + if (icon_mask != 0) + { + hints->icon_mask = icon_mask; + hints->flags |= IconMaskHint; + } + if (icon_window != 0) + { + hints->icon_window = icon_window; + hints->flags |= IconWindowHint; + } + if (window_group != 0) + { + hints->window_group = window_group; + hints->flags |= WindowGroupHint; + } + if (is_urgent) + hints->flags |= XUrgencyHint; + XSetWMHints(_ecore_x_disp, win, hints); + XFree(hints); +} + +int +ecore_x_icccm_hints_get(Ecore_X_Window win, + int *accepts_focus, + Ecore_X_Window_State_Hint *initial_state, + Ecore_X_Pixmap *icon_pixmap, + Ecore_X_Pixmap *icon_mask, + Ecore_X_Window *icon_window, + Ecore_X_Window *window_group, int *is_urgent) +{ + XWMHints *hints; + + if (accepts_focus) + *accepts_focus = 0; + if (initial_state) + *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL; + if (icon_pixmap) + *icon_pixmap = 0; + if (icon_mask) + *icon_mask = 0; + if (icon_window) + *icon_window = 0; + if (window_group) + *window_group = 0; + if (is_urgent) + *is_urgent = 0; + hints = XGetWMHints(_ecore_x_disp, win); + if (hints) + { + if ((hints->flags & InputHint) && (accepts_focus)) + { + if (hints->input) + *accepts_focus = 1; + else + *accepts_focus = 0; + } + if ((hints->flags & StateHint) && (initial_state)) + { + if (hints->initial_state == WithdrawnState) + *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN; + else if (hints->initial_state == NormalState) + *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL; + else if (hints->initial_state == IconicState) + *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC; + } + if ((hints->flags & IconPixmapHint) && (icon_pixmap)) + { + *icon_pixmap = hints->icon_pixmap; + } + if ((hints->flags & IconMaskHint) && (icon_mask)) + { + *icon_mask = hints->icon_mask; + } + if ((hints->flags & IconWindowHint) && (icon_window)) + { + *icon_window = hints->icon_window; + } + if ((hints->flags & WindowGroupHint) && (window_group)) + { + *window_group = hints->window_group; + } + if ((hints->flags & XUrgencyHint) && (is_urgent)) + { + *is_urgent = 1; + } + XFree(hints); + return 1; + } + return 0; +} + +void +ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win, + int request_pos, + Ecore_X_Gravity gravity, + int min_w, int min_h, + int max_w, int max_h, + int base_w, int base_h, + int step_x, int step_y, + double min_aspect, double max_aspect) +{ + XSizeHints hint; + long mask; + + if (!XGetWMNormalHints(_ecore_x_disp, win, &hint, &mask)) + { + memset(&hint, 0, sizeof(XSizeHints)); + } + + hint.flags = 0; + if (request_pos) + { + hint.flags |= USPosition; + } + if (gravity != ECORE_X_GRAVITY_NW) + { + hint.flags |= PWinGravity; + hint.win_gravity = gravity; + } + if ((min_w > 0) || (min_h > 0)) + { + hint.flags |= PMinSize; + hint.min_width = min_w; + hint.min_height = min_h; + } + if ((max_w > 0) || (max_h > 0)) + { + hint.flags |= PMaxSize; + hint.max_width = max_w; + hint.max_height = max_h; + } + if ((base_w > 0) || (base_h > 0)) + { + hint.flags |= PBaseSize; + hint.base_width = base_w; + hint.base_height = base_h; + } + if ((step_x > 1) || (step_y > 1)) + { + hint.flags |= PResizeInc; + hint.width_inc = step_x; + hint.height_inc = step_y; + } + if ((min_aspect > 0.0) || (max_aspect > 0.0)) + { + hint.flags |= PAspect; + hint.min_aspect.x = min_aspect * 10000; + hint.min_aspect.y = 10000; + hint.max_aspect.x = max_aspect * 10000; + hint.max_aspect.y = 10000; + } + XSetWMNormalHints(_ecore_x_disp, win, &hint); +} + +int +ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win, + int *request_pos, + Ecore_X_Gravity *gravity, + int *min_w, int *min_h, + int *max_w, int *max_h, + int *base_w, int *base_h, + int *step_x, int *step_y, + double *min_aspect, double *max_aspect) +{ + XSizeHints hint; + long mask; + + int minw = 0, minh = 0; + int maxw = 32767, maxh = 32767; + int basew = -1, baseh = -1; + int stepx = 1, stepy = 1; + double mina = 0.0, maxa = 0.0; + + if (!XGetWMNormalHints(_ecore_x_disp, win, &hint, &mask)) + return 0; + + if ((hint.flags & USPosition) || ((hint.flags & PPosition))) + { + if (request_pos) + *request_pos = 1; + } + else + { + if (request_pos) + *request_pos = 0; + } + if (hint.flags & PWinGravity) + { + if (gravity) + *gravity = hint.win_gravity; + } + else + { + if (gravity) + *gravity = ECORE_X_GRAVITY_NW; + } + if (hint.flags & PMinSize) + { + minw = hint.min_width; + minh = hint.min_height; + } + if (hint.flags & PMaxSize) + { + maxw = hint.max_width; + maxh = hint.max_height; + if (maxw < minw) + maxw = minw; + if (maxh < minh) + maxh = minh; + } + if (hint.flags & PBaseSize) + { + basew = hint.base_width; + baseh = hint.base_height; + if (basew > minw) + minw = basew; + if (baseh > minh) + minh = baseh; + } + if (hint.flags & PResizeInc) + { + stepx = hint.width_inc; + stepy = hint.height_inc; + if (stepx < 1) + stepx = 1; + if (stepy < 1) + stepy = 1; + } + if (hint.flags & PAspect) + { + if (hint.min_aspect.y > 0) + mina = ((double)hint.min_aspect.x) / ((double)hint.min_aspect.y); + if (hint.max_aspect.y > 0) + maxa = ((double)hint.max_aspect.x) / ((double)hint.max_aspect.y); + } + if (min_w) + *min_w = minw; + if (min_h) + *min_h = minh; + if (max_w) + *max_w = maxw; + if (max_h) + *max_h = maxh; + if (base_w) + *base_w = basew; + if (base_h) + *base_h = baseh; + if (step_x) + *step_x = stepx; + if (step_y) + *step_y = stepy; + if (min_aspect) + *min_aspect = mina; + if (max_aspect) + *max_aspect = maxa; + return 1; +} + +void +ecore_x_icccm_title_set(Ecore_X_Window win, const char *t) +{ + char *list[1]; + XTextProperty xprop; + int ret; + + xprop.value = NULL; +#ifdef X_HAVE_UTF8_STRING + list[0] = strdup(t); + ret = + Xutf8TextListToTextProperty(_ecore_x_disp, list, 1, XUTF8StringStyle, + &xprop); +#else + list[0] = strdup(t); + ret = + XmbTextListToTextProperty(_ecore_x_disp, list, 1, XStdICCTextStyle, + &xprop); +#endif + if (ret >= Success) + { + XSetWMName(_ecore_x_disp, win, &xprop); + if (xprop.value) XFree(xprop.value); + } + else + { + if (XStringListToTextProperty(list, 1, &xprop) >= Success) + { + XSetWMName(_ecore_x_disp, win, &xprop); + if (xprop.value) XFree(xprop.value); + } + } + free(list[0]); +} + +char * +ecore_x_icccm_title_get(Ecore_X_Window win) +{ + XTextProperty xprop; + + xprop.value = NULL; + if (XGetWMName(_ecore_x_disp, win, &xprop) >= Success) + { + if (xprop.value) + { + char **list = NULL; + char *t = NULL; + int num = 0; + int ret; + + if (xprop.encoding == ECORE_X_ATOM_UTF8_STRING) + { + t = strdup((char *)xprop.value); + } + else + { + + /* convert to utf8 */ +#ifdef X_HAVE_UTF8_STRING + ret = Xutf8TextPropertyToTextList(_ecore_x_disp, &xprop, + &list, &num); +#else + ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop, + &list, &num); +#endif + + if ((ret == XLocaleNotSupported) || + (ret == XNoMemory) || (ret == XConverterNotFound)) + { + t = strdup((char *)xprop.value); + } + else if ((ret >= Success) && (num > 0)) + { + t = strdup(list[0]); + } + if (list) + XFreeStringList(list); + } + + if (xprop.value) XFree(xprop.value); + return t; + } + } + return NULL; +} + +/** + * Set or unset a wm protocol property. + * @param win The Window + * @param protocol The protocol to enable/disable + * @param on On/Off + */ +void +ecore_x_icccm_protocol_set(Ecore_X_Window win, + Ecore_X_WM_Protocol protocol, int on) +{ + Atom *protos = NULL; + Atom proto; + int protos_count = 0; + int already_set = 0; + int i; + + /* Check for invalid values */ + if (protocol >= ECORE_X_WM_PROTOCOL_NUM) + return; + + proto = _ecore_x_atoms_wm_protocols[protocol]; + + if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count)) + { + protos = NULL; + protos_count = 0; + } + + for (i = 0; i < protos_count; i++) + { + if (protos[i] == proto) + { + already_set = 1; + break; + } + } + + if (on) + { + Atom *new_protos = NULL; + + if (already_set) + goto leave; + new_protos = malloc((protos_count + 1) * sizeof(Atom)); + if (!new_protos) + goto leave; + for (i = 0; i < protos_count; i++) + new_protos[i] = protos[i]; + new_protos[protos_count] = proto; + XSetWMProtocols(_ecore_x_disp, win, new_protos, protos_count + 1); + free(new_protos); + } + else + { + if (!already_set) + goto leave; + for (i = 0; i < protos_count; i++) + { + if (protos[i] == proto) + { + int j; + + for (j = i + 1; j < protos_count; j++) + protos[j - 1] = protos[j]; + if (protos_count > 1) + XSetWMProtocols(_ecore_x_disp, win, protos, + protos_count - 1); + else + XDeleteProperty(_ecore_x_disp, win, + ECORE_X_ATOM_WM_PROTOCOLS); + goto leave; + } + } + } + + leave: + if (protos) + XFree(protos); + +} + +/** + * Determines whether a protocol is set for a window. + * @param win The Window + * @param protocol The protocol to query + * @return 1 if the protocol is set, else 0. + */ +int +ecore_x_icccm_protocol_isset(Ecore_X_Window win, Ecore_X_WM_Protocol protocol) +{ + Atom proto, *protos = NULL; + int i, ret = 0, protos_count = 0; + + /* check for invalid values */ + if (protocol >= ECORE_X_WM_PROTOCOL_NUM) + return 0; + + proto = _ecore_x_atoms_wm_protocols[protocol]; + + if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count)) + return 0; + + for (i = 0; i < protos_count; i++) + if (protos[i] == proto) + { + ret = 1; + break; + } + + if (protos) XFree(protos); + return ret; + +} + +/** + * Set a window name & class. + * @param win The window + * @param n The name string + * @param c The class string + * + * Set a window name * class + */ +void +ecore_x_icccm_name_class_set(Ecore_X_Window win, const char *n, const char *c) +{ + XClassHint *xch; + + xch = XAllocClassHint(); + if (!xch) + return; + xch->res_name = (char *)n; + xch->res_class = (char *)c; + XSetClassHint(_ecore_x_disp, win, xch); + XFree(xch); +} + +/** + * Get a window name & class. + * @param win The window + * @param n The name string + * @param c The class string + * + * Get a window name * class + */ +void +ecore_x_icccm_name_class_get(Ecore_X_Window win, char **n, char **c) +{ + XClassHint xch; + + if (n) *n = NULL; + if (c) *c = NULL; + xch.res_name = NULL; + xch.res_class = NULL; + if (XGetClassHint(_ecore_x_disp, win, &xch)) + { + if (n) + { + if (xch.res_name) *n = strdup(xch.res_name); + } + if (c) + { + if (xch.res_class) *c = strdup(xch.res_class); + } + XFree(xch.res_name); + XFree(xch.res_class); + } +} + +/** + * Get a window client machine string. + * @param win The window + * @return The windows client machine string + * + * Return the client machine of a window. String must be free'd when done with. + */ +char * +ecore_x_icccm_client_machine_get(Ecore_X_Window win) +{ + char *name; + + name = ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_CLIENT_MACHINE); + return name; +} + +/** + * Sets the WM_COMMAND property for @a win. + * + * @param win The window. + * @param argc Number of arguments. + * @param argv Arguments. + */ +void +ecore_x_icccm_command_set(Ecore_X_Window win, int argc, char **argv) +{ + XSetCommand(_ecore_x_disp, win, argv, argc); +} + +/** + * Get the WM_COMMAND property for @a win. + * + * Return the command of a window. String must be free'd when done with. + * + * @param win The window. + * @param argc Number of arguments. + * @param argv Arguments. + */ +void +ecore_x_icccm_command_get(Ecore_X_Window win, int *argc, char ***argv) +{ + XGetCommand(_ecore_x_disp, win, argv, argc); +} + +/** + * Set a window icon name. + * @param win The window + * @param t The icon name string + * + * Set a window icon name + */ +void +ecore_x_icccm_icon_name_set(Ecore_X_Window win, const char *t) +{ + char *list[1]; + XTextProperty xprop; + int ret; + + xprop.value = NULL; +#ifdef X_HAVE_UTF8_STRING + list[0] = strdup(t); + ret = Xutf8TextListToTextProperty(_ecore_x_disp, list, 1, + XUTF8StringStyle, &xprop); +#else + list[0] = strdup(t); + ret = XmbTextListToTextProperty(_ecore_x_disp, list, 1, + XStdICCTextStyle, &xprop); +#endif + if (ret >= Success) + { + XSetWMIconName(_ecore_x_disp, win, &xprop); + if (xprop.value) XFree(xprop.value); + } + else + { + if (XStringListToTextProperty(list, 1, &xprop) >= Success) + { + XSetWMIconName(_ecore_x_disp, win, &xprop); + if (xprop.value) XFree(xprop.value); + } + } + free(list[0]); +} + +/** + * Get a window icon name. + * @param win The window + * @return The windows icon name string + * + * Return the icon name of a window. String must be free'd when done with. + */ +char * +ecore_x_icccm_icon_name_get(Ecore_X_Window win) +{ + XTextProperty xprop; + + xprop.value = NULL; + if (XGetWMIconName(_ecore_x_disp, win, &xprop) >= Success) + { + if (xprop.value) + { + char **list = NULL; + char *t = NULL; + int num = 0; + int ret; + + if (xprop.encoding == ECORE_X_ATOM_UTF8_STRING) + { + t = strdup((char *)xprop.value); + } + else + { + + /* convert to utf8 */ +#ifdef X_HAVE_UTF8_STRING + ret = Xutf8TextPropertyToTextList(_ecore_x_disp, &xprop, + &list, &num); +#else + ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop, + &list, &num); +#endif + + if ((ret == XLocaleNotSupported) || + (ret == XNoMemory) || (ret == XConverterNotFound)) + { + t = strdup((char *)xprop.value); + } + else if (ret >= Success) + { + if ((num >= 1) && (list)) + { + t = strdup(list[0]); + } + if (list) + XFreeStringList(list); + } + } + + if (xprop.value) XFree(xprop.value); + return t; + } + } + return NULL; +} + +/** + * Add a subwindow to the list of windows that need a different colormap installed. + * @param win The toplevel window + * @param subwin The subwindow to be added to the colormap windows list + */ +void +ecore_x_icccm_colormap_window_set(Ecore_X_Window win, Ecore_X_Window subwin) +{ + int num = 0, i; + unsigned char *old_data = NULL; + unsigned char *data = NULL; + Window *oldset = NULL; + Window *newset = NULL; + + if (!ecore_x_window_prop_property_get(win, + ECORE_X_ATOM_WM_COLORMAP_WINDOWS, + XA_WINDOW, 32, &old_data, &num)) + { + newset = calloc(1, sizeof(Window)); + if (!newset) + return; + newset[0] = subwin; + num = 1; + data = (unsigned char *)newset; + } + else + { + newset = calloc(num + 1, sizeof(Window)); + oldset = (Window *) old_data; + if (!newset) + return; + for (i = 0; i < num; ++i) + { + if (oldset[i] == subwin) + { + if (old_data) XFree(old_data); + old_data = NULL; + free(newset); + return; + } + + newset[i] = oldset[i]; + } + + newset[num++] = subwin; + if (old_data) XFree(old_data); + data = (unsigned char *)newset; + } + + ecore_x_window_prop_property_set(win, + ECORE_X_ATOM_WM_COLORMAP_WINDOWS, + XA_WINDOW, 32, data, num); + free(newset); +} + +/** + * Remove a window from the list of colormap windows. + * @param win The toplevel window + * @param subwin The window to be removed from the colormap window list. + */ +void +ecore_x_icccm_colormap_window_unset(Ecore_X_Window win, Ecore_X_Window subwin) +{ + int num = 0, i, j, k = 0; + unsigned char *old_data = NULL; + unsigned char *data = NULL; + Window *oldset = NULL; + Window *newset = NULL; + + if (!ecore_x_window_prop_property_get(win, + ECORE_X_ATOM_WM_COLORMAP_WINDOWS, + XA_WINDOW, 32, &old_data, &num)) + return; + + oldset = (Window *) old_data; + for (i = 0; i < num; i++) + { + if (oldset[i] == subwin) + { + if (num == 1) + { + XDeleteProperty(_ecore_x_disp, + win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS); + if (old_data) XFree(old_data); + old_data = NULL; + return; + } + else + { + newset = calloc(num - 1, sizeof(Window)); + data = (unsigned char *)newset; + for (j = 0; j < num; ++j) + if (oldset[j] != subwin) + newset[k++] = oldset[j]; + ecore_x_window_prop_property_set(win, + ECORE_X_ATOM_WM_COLORMAP_WINDOWS, + XA_WINDOW, 32, data, k); + if (old_data) XFree(old_data); + old_data = NULL; + free(newset); + return; + } + } + } + + if (old_data) XFree(old_data); +} + +/** + * Specify that a window is transient for another top-level window and should be handled accordingly. + * @param win the transient window + * @param forwin the toplevel window + */ +void +ecore_x_icccm_transient_for_set(Ecore_X_Window win, Ecore_X_Window forwin) +{ + XSetTransientForHint(_ecore_x_disp, win, forwin); +} + +/** + * Remove the transient_for setting from a window. + * @param The window + */ +void +ecore_x_icccm_transient_for_unset(Ecore_X_Window win) +{ + XDeleteProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_TRANSIENT_FOR); +} + +/** + * Get the window this window is transient for, if any. + * @param win The window to check + * @return The window ID of the top-level window, or 0 if the property does not exist. + */ +Ecore_X_Window +ecore_x_icccm_transient_for_get(Ecore_X_Window win) +{ + Window forwin; + + if (XGetTransientForHint(_ecore_x_disp, win, &forwin)) + return (Ecore_X_Window) forwin; + else + return 0; + +} + +/** + * Set the window role hint. + * @param win The window + * @param role The role string + */ +void +ecore_x_icccm_window_role_set(Ecore_X_Window win, const char *role) +{ + ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_WINDOW_ROLE, + (char *)role); +} + +/** + * Get the window role. + * @param win The window + * @return The window's role string. + */ +char * +ecore_x_icccm_window_role_get(Ecore_X_Window win) +{ + return ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_WINDOW_ROLE); +} + +/** + * Set the window's client leader. + * @param win The window + * @param l The client leader window + * + * All non-transient top-level windows created by an app other than + * the main window must have this property set to the app's main window. + */ +void +ecore_x_icccm_client_leader_set(Ecore_X_Window win, Ecore_X_Window l) +{ + ecore_x_window_prop_property_set(win, + ECORE_X_ATOM_WM_CLIENT_LEADER, + XA_WINDOW, 32, &l, 1); +} + +/** + * Get the window's client leader. + * @param win The window + * @return The window's client leader window, or 0 if unset */ +Ecore_X_Window +ecore_x_icccm_client_leader_get(Ecore_X_Window win) +{ + unsigned char *data; + int num; + + if (ecore_x_window_prop_property_get(win, + ECORE_X_ATOM_WM_CLIENT_LEADER, + XA_WINDOW, 32, &data, &num)) + { + if (data) + { + Ecore_X_Window wlead; + + wlead = *((Ecore_X_Window *)data); + free(data); + return wlead; + } + } + return 0; +} + +void +ecore_x_icccm_iconic_request_send(Ecore_X_Window win, Ecore_X_Window root) +{ + XEvent xev; + + if (!win) return; + if (!root) root = DefaultRootWindow(_ecore_x_disp); + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.display = _ecore_x_disp; + xev.xclient.window = win; + xev.xclient.format = 32; + xev.xclient.message_type = ECORE_X_ATOM_WM_CHANGE_STATE; + xev.xclient.data.l[0] = IconicState; + + XSendEvent(_ecore_x_disp, root, False, + SubstructureNotifyMask | SubstructureRedirectMask, &xev); +} + +/* FIXME: there are older E hints, gnome hints and mwm hints and new netwm */ +/* hints. each should go in their own file/section so we know which */ +/* is which. also older kde hints too. we should try support as much */ +/* as makese sense to support */ diff --git a/ecore/src/lib/ecore_x/ecore_x_mwm.c b/ecore/src/lib/ecore_x/ecore_x_mwm.c new file mode 100644 index 0000000..caf9e49 --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_mwm.c @@ -0,0 +1,93 @@ +/* + * Various MWM related functions. + * + * This is ALL the code involving anything MWM related. for both WM and + * client. + */ +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" + +#define ECORE_X_MWM_HINTS_FUNCTIONS (1 << 0) +#define ECORE_X_MWM_HINTS_DECORATIONS (1 << 1) +#define ECORE_X_MWM_HINTS_INPUT_MODE (1 << 2) +#define ECORE_X_MWM_HINTS_STATUS (1 << 3) + +typedef struct _mwmhints +{ + CARD32 flags; + CARD32 functions; + CARD32 decorations; + INT32 inputmode; + CARD32 status; +} +MWMHints; + +/* Atoms */ +Ecore_X_Atom ECORE_X_ATOM_MOTIF_WM_HINTS = 0; + +int +ecore_x_mwm_hints_get(Ecore_X_Window win, + Ecore_X_MWM_Hint_Func * fhint, + Ecore_X_MWM_Hint_Decor * dhint, + Ecore_X_MWM_Hint_Input * ihint) +{ + unsigned char *p = NULL; + MWMHints *mwmhints = NULL; + int num; + int ret; + + ret = 0; + if (!ecore_x_window_prop_property_get(win, + ECORE_X_ATOM_MOTIF_WM_HINTS, + ECORE_X_ATOM_MOTIF_WM_HINTS, + 32, &p, &num)) + return 0; + mwmhints = (MWMHints *) p; + if (mwmhints) + { + if (num >= 4) + { + if (dhint) + { + if (mwmhints->flags & ECORE_X_MWM_HINTS_DECORATIONS) + *dhint = mwmhints->decorations; + else + *dhint = ECORE_X_MWM_HINT_DECOR_ALL; + } + if (fhint) + { + if (mwmhints->flags & ECORE_X_MWM_HINTS_FUNCTIONS) + *fhint = mwmhints->functions; + else + *fhint = ECORE_X_MWM_HINT_FUNC_ALL; + } + if (ihint) + { + if (mwmhints->flags & ECORE_X_MWM_HINTS_INPUT_MODE) + *ihint = mwmhints->inputmode; + else + *ihint = ECORE_X_MWM_HINT_INPUT_MODELESS; + } + ret = 1; + } + free(mwmhints); + } + return ret; +} + +void +ecore_x_mwm_borderless_set(Ecore_X_Window win, int borderless) +{ + unsigned int data[5] = {0, 0, 0, 0, 0}; + + data[0] = 2; /* just set the decorations hint! */ + data[2] = !borderless; + + ecore_x_window_prop_property_set(win, + ECORE_X_ATOM_MOTIF_WM_HINTS, + ECORE_X_ATOM_MOTIF_WM_HINTS, + 32, (void *)data, 5); +} + diff --git a/ecore/src/lib/ecore_x/ecore_x_netwm.c b/ecore/src/lib/ecore_x/ecore_x_netwm.c new file mode 100644 index 0000000..76d970e --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_netwm.c @@ -0,0 +1,1238 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +/* + * _NET_WM... aka Extended Window Manager Hint (EWMH) functions. + */ +#include "config.h" +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" + +/* + * Convenience macros + */ +#define _ATOM_GET(name) \ + XInternAtom(_ecore_x_disp, name, False) + +#define _ATOM_SET_UTF8_STRING(win, atom, string) \ + XChangeProperty(_ecore_x_disp, win, atom, ECORE_X_ATOM_UTF8_STRING, 8, PropModeReplace, \ + (unsigned char *)string, strlen(string)) +#define _ATOM_SET_UTF8_STRING_LIST(win, atom, string, cnt) \ + XChangeProperty(_ecore_x_disp, win, atom, ECORE_X_ATOM_UTF8_STRING, 8, PropModeReplace, \ + (unsigned char *)string, cnt) +#define _ATOM_SET_WINDOW(win, atom, p_wins, cnt) \ + XChangeProperty(_ecore_x_disp, win, atom, XA_WINDOW, 32, PropModeReplace, \ + (unsigned char *)p_wins, cnt) +#define _ATOM_SET_ATOM(win, atom, p_atom, cnt) \ + XChangeProperty(_ecore_x_disp, win, atom, XA_ATOM, 32, PropModeReplace, \ + (unsigned char *)p_atom, cnt) +#define _ATOM_SET_CARD32(win, atom, p_val, cnt) \ + XChangeProperty(_ecore_x_disp, win, atom, XA_CARDINAL, 32, PropModeReplace, \ + (unsigned char *)p_val, cnt) + +/* + * Set UTF-8 string property + */ +static void +_ecore_x_window_prop_string_utf8_set(Ecore_X_Window win, Ecore_X_Atom atom, + const char *str) +{ + _ATOM_SET_UTF8_STRING(win, atom, str); +} + +/* + * Get UTF-8 string property + */ +static char * +_ecore_x_window_prop_string_utf8_get(Ecore_X_Window win, Ecore_X_Atom atom) +{ + char *str; + unsigned char *prop_ret; + Atom type_ret; + unsigned long bytes_after, num_ret; + int format_ret; + + str = NULL; + prop_ret = NULL; + XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False, + ECORE_X_ATOM_UTF8_STRING, &type_ret, + &format_ret, &num_ret, &bytes_after, &prop_ret); + if (prop_ret && num_ret > 0 && format_ret == 8) + { + str = malloc(num_ret + 1); + if (str) + { + memcpy(str, prop_ret, num_ret); + str[num_ret] = '\0'; + } + } + if (prop_ret) + XFree(prop_ret); + + return str; +} + +/* + * Root window NetWM hints. + */ +Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTED = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK = 0; + +Ecore_X_Atom ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_VIRTUAL_ROOTS = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_NAMES = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_GEOMETRY = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_VIEWPORT = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_DESKTOP_LAYOUT = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WORKAREA = 0; + +Ecore_X_Atom ECORE_X_ATOM_NET_CURRENT_DESKTOP = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_SHOWING_DESKTOP = 0; + +Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_CLIENT_LIST_STACKING = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_ACTIVE_WINDOW = 0; + +/* + * Client message types. + */ +Ecore_X_Atom ECORE_X_ATOM_NET_CLOSE_WINDOW = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_MOVERESIZE = 0; + +/* + * Pagers + */ +Ecore_X_Atom ECORE_X_ATOM_NET_MOVERESIZE_WINDOW = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_RESTACK_WINDOW = 0; + +/* + * Application window specific NetWM hints. + */ +Ecore_X_Atom ECORE_X_ATOM_NET_WM_NAME = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_NAME = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_NAME = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_DESKTOP = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STRUT_PARTIAL = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON_GEOMETRY = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_ICON = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_PID = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_HANDLED_ICONS = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_USER_TIME = 0; + +Ecore_X_Atom ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MOVE = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_RESIZE = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_SHADE = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_STICK = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_ACTION_CLOSE = 0; + +Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL = 0; + +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MODAL = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_STICKY = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SHADED = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_HIDDEN = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_ABOVE = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_BELOW = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION = 0; + +Ecore_X_Atom ECORE_X_ATOM_NET_WM_WINDOW_OPACITY = 0; + +Ecore_X_Atom ECORE_X_ATOM_NET_FRAME_EXTENTS = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS = 0; + +Ecore_X_Atom ECORE_X_ATOM_NET_WM_PING = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST = 0; +Ecore_X_Atom ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER = 0; + +void +ecore_x_netwm_init(void) +{ + ECORE_X_ATOM_NET_SUPPORTED = _ATOM_GET("_NET_SUPPORTED"); + ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK = _ATOM_GET("_NET_SUPPORTING_WM_CHECK"); + + ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS = _ATOM_GET("_NET_NUMBER_OF_DESKTOPS"); + ECORE_X_ATOM_NET_VIRTUAL_ROOTS = _ATOM_GET("_NET_VIRTUAL_ROOTS"); + ECORE_X_ATOM_NET_DESKTOP_NAMES = _ATOM_GET("_NET_DESKTOP_NAMES"); + ECORE_X_ATOM_NET_DESKTOP_GEOMETRY = _ATOM_GET("_NET_DESKTOP_GEOMETRY"); + ECORE_X_ATOM_NET_DESKTOP_VIEWPORT = _ATOM_GET("_NET_DESKTOP_VIEWPORT"); + ECORE_X_ATOM_NET_DESKTOP_LAYOUT = _ATOM_GET("_NET_DESKTOP_LAYOUT"); + ECORE_X_ATOM_NET_WORKAREA = _ATOM_GET("_NET_WORKAREA"); + + ECORE_X_ATOM_NET_CURRENT_DESKTOP = _ATOM_GET("_NET_CURRENT_DESKTOP"); + ECORE_X_ATOM_NET_SHOWING_DESKTOP = _ATOM_GET("_NET_SHOWING_DESKTOP"); + + ECORE_X_ATOM_NET_CLIENT_LIST = _ATOM_GET("_NET_CLIENT_LIST"); + ECORE_X_ATOM_NET_CLIENT_LIST_STACKING = + _ATOM_GET("_NET_CLIENT_LIST_STACKING"); + ECORE_X_ATOM_NET_ACTIVE_WINDOW = _ATOM_GET("_NET_ACTIVE_WINDOW"); + + ECORE_X_ATOM_NET_CLOSE_WINDOW = _ATOM_GET("_NET_CLOSE_WINDOW"); + ECORE_X_ATOM_NET_WM_MOVERESIZE = _ATOM_GET("_NET_WM_MOVERESIZE"); + + ECORE_X_ATOM_NET_MOVERESIZE_WINDOW = _ATOM_GET("_NET_MOVERESIZE_WINDOW"); + ECORE_X_ATOM_NET_RESTACK_WINDOW = _ATOM_GET("_NET_RESTACK_WINDOW"); + + ECORE_X_ATOM_NET_WM_NAME = _ATOM_GET("_NET_WM_NAME"); + ECORE_X_ATOM_NET_WM_VISIBLE_NAME = _ATOM_GET("_NET_WM_VISIBLE_NAME"); + ECORE_X_ATOM_NET_WM_ICON_NAME = _ATOM_GET("_NET_WM_ICON_NAME"); + ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME = + _ATOM_GET("_NET_WM_VISIBLE_ICON_NAME"); + ECORE_X_ATOM_NET_WM_DESKTOP = _ATOM_GET("_NET_WM_DESKTOP"); + ECORE_X_ATOM_NET_WM_STRUT = _ATOM_GET("_NET_WM_STRUT"); + ECORE_X_ATOM_NET_WM_STRUT_PARTIAL = _ATOM_GET("_NET_WM_STRUT_PARTIAL"); + ECORE_X_ATOM_NET_WM_ICON_GEOMETRY = _ATOM_GET("_NET_WM_ICON_GEOMETRY"); + ECORE_X_ATOM_NET_WM_ICON = _ATOM_GET("_NET_WM_ICON"); + ECORE_X_ATOM_NET_WM_PID = _ATOM_GET("_NET_WM_PID"); + ECORE_X_ATOM_NET_WM_HANDLED_ICONS = _ATOM_GET("_NET_WM_HANDLED_ICONS"); + ECORE_X_ATOM_NET_WM_USER_TIME = _ATOM_GET("_NET_WM_USER_TIME"); + + ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS = _ATOM_GET("_NET_WM_ALLOWED_ACTIONS"); + ECORE_X_ATOM_NET_WM_ACTION_MOVE = _ATOM_GET("_NET_WM_ACTION_MOVE"); + ECORE_X_ATOM_NET_WM_ACTION_RESIZE = _ATOM_GET("_NET_WM_ACTION_RESIZE"); + ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE = _ATOM_GET("_NET_WM_ACTION_MINIMIZE"); + ECORE_X_ATOM_NET_WM_ACTION_SHADE = _ATOM_GET("_NET_WM_ACTION_SHADE"); + ECORE_X_ATOM_NET_WM_ACTION_STICK = _ATOM_GET("_NET_WM_ACTION_STICK"); + ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ = _ATOM_GET("_NET_WM_ACTION_MAXIMIZE_HORZ"); + ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT = _ATOM_GET("_NET_WM_ACTION_MAXIMIZE_VERT"); + ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN = _ATOM_GET("_NET_WM_ACTION_FULLSCREEN"); + ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP = _ATOM_GET("_NET_WM_ACTION_CHANGE_DESKTOP"); + ECORE_X_ATOM_NET_WM_ACTION_CLOSE = _ATOM_GET("_NET_WM_ACTION_CLOSE"); + + ECORE_X_ATOM_NET_WM_WINDOW_TYPE = _ATOM_GET("_NET_WM_WINDOW_TYPE"); + ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP = + _ATOM_GET("_NET_WM_WINDOW_TYPE_DESKTOP"); + ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK = _ATOM_GET("_NET_WM_WINDOW_TYPE_DOCK"); + ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR = + _ATOM_GET("_NET_WM_WINDOW_TYPE_TOOLBAR"); + ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU = _ATOM_GET("_NET_WM_WINDOW_TYPE_MENU"); + ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY = + _ATOM_GET("_NET_WM_WINDOW_TYPE_UTILITY"); + ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH = + _ATOM_GET("_NET_WM_WINDOW_TYPE_SPLASH"); + ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG = + _ATOM_GET("_NET_WM_WINDOW_TYPE_DIALOG"); + ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL = + _ATOM_GET("_NET_WM_WINDOW_TYPE_NORMAL"); + + ECORE_X_ATOM_NET_WM_STATE = _ATOM_GET("_NET_WM_STATE"); + ECORE_X_ATOM_NET_WM_STATE_MODAL = _ATOM_GET("_NET_WM_STATE_MODAL"); + ECORE_X_ATOM_NET_WM_STATE_STICKY = _ATOM_GET("_NET_WM_STATE_STICKY"); + ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT = + _ATOM_GET("_NET_WM_STATE_MAXIMIZED_VERT"); + ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ = + _ATOM_GET("_NET_WM_STATE_MAXIMIZED_HORZ"); + ECORE_X_ATOM_NET_WM_STATE_SHADED = _ATOM_GET("_NET_WM_STATE_SHADED"); + ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR = + _ATOM_GET("_NET_WM_STATE_SKIP_TASKBAR"); + ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER = _ATOM_GET("_NET_WM_STATE_SKIP_PAGER"); + ECORE_X_ATOM_NET_WM_STATE_HIDDEN = _ATOM_GET("_NET_WM_STATE_HIDDEN"); + ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN = _ATOM_GET("_NET_WM_STATE_FULLSCREEN"); + ECORE_X_ATOM_NET_WM_STATE_ABOVE = _ATOM_GET("_NET_WM_STATE_ABOVE"); + ECORE_X_ATOM_NET_WM_STATE_BELOW = _ATOM_GET("_NET_WM_STATE_BELOW"); + ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION = _ATOM_GET("_NET_WM_STATE_DEMANDS_ATTENTION"); + + ECORE_X_ATOM_NET_WM_WINDOW_OPACITY = _ATOM_GET("_NET_WM_WINDOW_OPACITY"); + + ECORE_X_ATOM_NET_FRAME_EXTENTS = _ATOM_GET("_NET_FRAME_EXTENTS"); + ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS = _ATOM_GET("_NET_REQUEST_FRAME_EXTENTS"); + + ECORE_X_ATOM_NET_WM_PING = _ATOM_GET("_NET_WM_PING"); + ECORE_X_ATOM_NET_WM_SYNC_REQUEST = _ATOM_GET("_NET_WM_SYNC_REQUEST"); + ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER = _ATOM_GET("_NET_WM_SYNC_REQUEST_COUNTER"); +} + +/* + * WM identification + */ +void +ecore_x_netwm_wm_identify(Ecore_X_Window root, Ecore_X_Window check, + const char *wm_name) +{ + _ATOM_SET_WINDOW(root, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, &check, 1); + _ATOM_SET_WINDOW(check, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, &check, 1); + _ATOM_SET_UTF8_STRING(check, ECORE_X_ATOM_NET_WM_NAME, wm_name); + /* This one isn't mandatory */ + _ATOM_SET_UTF8_STRING(root, ECORE_X_ATOM_NET_WM_NAME, wm_name); +} + +/* + * Set supported atoms + */ +void +ecore_x_netwm_supported_set(Ecore_X_Window root, Ecore_X_Atom *supported, int num) +{ + _ATOM_SET_ATOM(root, ECORE_X_ATOM_NET_SUPPORTED, supported, num); +} + +int +ecore_x_netwm_supported_get(Ecore_X_Window root, Ecore_X_Atom **supported, int *num) +{ + int num_ret; + unsigned char *data; + + if (num) *num = 0; + if (supported) *supported = NULL; + + if (!ecore_x_window_prop_property_get(root, ECORE_X_ATOM_NET_SUPPORTED, + XA_ATOM, 32, &data, &num_ret)) + return 0; + + if ((!data) || (!num_ret)) return 0; + + if (num) *num = num_ret; + if (supported) *supported = (Ecore_X_Atom *)data; + return 1; +} + +/* + * Desktop configuration and status + */ +void +ecore_x_netwm_desk_count_set(Ecore_X_Window root, unsigned int n_desks) +{ + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS, + &n_desks, 1); +} + +void +ecore_x_netwm_desk_roots_set(Ecore_X_Window root, + Ecore_X_Window *vroots, unsigned int n_desks) +{ + _ATOM_SET_WINDOW(root, ECORE_X_ATOM_NET_VIRTUAL_ROOTS, vroots, n_desks); +} + +void +ecore_x_netwm_desk_names_set(Ecore_X_Window root, + const char **names, unsigned int n_desks) +{ + char ss[32], *buf; + const char *s; + unsigned int i; + int l, len; + + buf = NULL; + len = 0; + + for (i = 0; i < n_desks; i++) + { + s = (names) ? names[i] : NULL; + if (!s) + { + /* Default to "Desk-" */ + sprintf(ss, "Desk-%d", i); + s = ss; + } + + l = strlen(s) + 1; + buf = realloc(buf, len + l); + memcpy(buf + len, s, l); + len += l; + } + + _ATOM_SET_UTF8_STRING_LIST(root, ECORE_X_ATOM_NET_DESKTOP_NAMES, buf, len); + + free(buf); +} + +void +ecore_x_netwm_desk_size_set(Ecore_X_Window root, unsigned int width, + unsigned int height) +{ + unsigned int size[2]; + + size[0] = width; + size[1] = height; + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_GEOMETRY, size, + 2); +} + +void +ecore_x_netwm_desk_viewports_set(Ecore_X_Window root, + unsigned int *origins, unsigned int n_desks) +{ + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_VIEWPORT, + origins, 2 * n_desks); +} + +void +ecore_x_netwm_desk_layout_set(Ecore_X_Window root, int orientation, + int columns, int rows, + int starting_corner) +{ + unsigned int layout[4]; + + layout[0] = orientation; + layout[1] = columns; + layout[2] = rows; + layout[3] = starting_corner; + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_LAYOUT, + layout, 4); +} + +void +ecore_x_netwm_desk_workareas_set(Ecore_X_Window root, + unsigned int *areas, unsigned int n_desks) +{ + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_WORKAREA, areas, + 4 * n_desks); +} + +void +ecore_x_netwm_desk_current_set(Ecore_X_Window root, unsigned int desk) +{ + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_CURRENT_DESKTOP, &desk, + 1); +} + +void +ecore_x_netwm_showing_desktop_set(Ecore_X_Window root, int on) +{ + unsigned int val; + + val = (on) ? 1 : 0; + ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_SHOWING_DESKTOP, &val, + 1); +} + +/* + * Client status + */ + +/* Mapping order */ +void +ecore_x_netwm_client_list_set(Ecore_X_Window root, + Ecore_X_Window *p_clients, unsigned int n_clients) +{ + _ATOM_SET_WINDOW(root, ECORE_X_ATOM_NET_CLIENT_LIST, p_clients, n_clients); +} + +/* Stacking order */ +void +ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root, + Ecore_X_Window *p_clients, + unsigned int n_clients) +{ + _ATOM_SET_WINDOW(root, ECORE_X_ATOM_NET_CLIENT_LIST_STACKING, p_clients, + n_clients); +} + +void +ecore_x_netwm_client_active_set(Ecore_X_Window root, Ecore_X_Window win) +{ + _ATOM_SET_WINDOW(root, ECORE_X_ATOM_NET_ACTIVE_WINDOW, &win, 1); +} + +void +ecore_x_netwm_name_set(Ecore_X_Window win, const char *name) +{ + _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_NAME, name); +} + +int +ecore_x_netwm_name_get(Ecore_X_Window win, char **name) +{ + if (name) + *name = _ecore_x_window_prop_string_utf8_get(win, ECORE_X_ATOM_NET_WM_NAME); + return 1; +} + +void +ecore_x_netwm_visible_name_set(Ecore_X_Window win, const char *name) +{ + _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_VISIBLE_NAME, + name); +} + +int +ecore_x_netwm_visible_name_get(Ecore_X_Window win, char **name) +{ + if (name) + *name = _ecore_x_window_prop_string_utf8_get(win, + ECORE_X_ATOM_NET_WM_VISIBLE_NAME); + return 1; +} + +void +ecore_x_netwm_icon_name_set(Ecore_X_Window win, const char *name) +{ + _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_ICON_NAME, + name); +} + +int +ecore_x_netwm_icon_name_get(Ecore_X_Window win, char **name) +{ + if (name) + *name = _ecore_x_window_prop_string_utf8_get(win, + ECORE_X_ATOM_NET_WM_ICON_NAME); + return 1; +} + +void +ecore_x_netwm_visible_icon_name_set(Ecore_X_Window win, const char *name) +{ + _ecore_x_window_prop_string_utf8_set(win, + ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME, + name); +} + +int +ecore_x_netwm_visible_icon_name_get(Ecore_X_Window win, char **name) +{ + if (name) + *name = _ecore_x_window_prop_string_utf8_get(win, + ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME); + return 1; +} + +void +ecore_x_netwm_desktop_set(Ecore_X_Window win, unsigned int desk) +{ + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_DESKTOP, &desk, 1); +} + +int +ecore_x_netwm_desktop_get(Ecore_X_Window win, unsigned int *desk) +{ + int ret; + unsigned int tmp; + + ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_DESKTOP, + &tmp, 1); + + if (desk) *desk = tmp; + return ret == 1 ? 1 : 0; +} + +/* + * _NET_WM_STRUT is deprecated + */ +void +ecore_x_netwm_strut_set(Ecore_X_Window win, int left, int right, + int top, int bottom) +{ + unsigned int strut[4]; + + strut[0] = left; + strut[1] = right; + strut[2] = top; + strut[3] = bottom; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4); +} + +/* + * _NET_WM_STRUT is deprecated + */ +int +ecore_x_netwm_strut_get(Ecore_X_Window win, int *left, int *right, + int *top, int *bottom) +{ + int ret = 0; + unsigned int strut[4]; + + ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4); + if (ret != 4) + return 0; + + if (left) *left = strut[0]; + if (right) *right = strut[1]; + if (top) *top = strut[2]; + if (bottom) *bottom = strut[3]; + return 1; +} + +void +ecore_x_netwm_strut_partial_set(Ecore_X_Window win, int left, int right, + int top, int bottom, int left_start_y, int left_end_y, + int right_start_y, int right_end_y, int top_start_x, + int top_end_x, int bottom_start_x, int bottom_end_x) +{ + unsigned int strut[12]; + + strut[0] = left; + strut[1] = right; + strut[2] = top; + strut[3] = bottom; + strut[4] = left_start_y; + strut[5] = left_end_y; + strut[6] = right_start_y; + strut[7] = right_end_y; + strut[8] = top_start_x; + strut[9] = top_end_x; + strut[10] = bottom_start_x; + strut[11] = bottom_end_x; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, strut, 12); +} + +int +ecore_x_netwm_strut_partial_get(Ecore_X_Window win, int *left, int *right, + int *top, int *bottom, int *left_start_y, int *left_end_y, + int *right_start_y, int *right_end_y, int *top_start_x, + int *top_end_x, int *bottom_start_x, int *bottom_end_x) +{ + int ret = 0; + unsigned int strut[12]; + + ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, strut, 12); + if (ret != 12) + return 0; + + if (left) *left = strut[0]; + if (right) *right = strut[1]; + if (top) *top = strut[2]; + if (bottom) *bottom = strut[3]; + if (left_start_y) *left_start_y = strut[4]; + if (left_end_y) *left_end_y = strut[5]; + if (right_start_y) *right_start_y = strut[6]; + if (right_end_y) *right_end_y = strut[7]; + if (top_start_x) *top_start_x = strut[8]; + if (top_end_x) *top_end_x = strut[9]; + if (bottom_start_x) *bottom_start_x = strut[10]; + if (bottom_end_x) *bottom_end_x = strut[11]; + return 1; +} + +int +ecore_x_netwm_icon_get(Ecore_X_Window win, int *width, int *height, unsigned int **icon, int *num) +{ + unsigned char *data_ret; + unsigned int *data; + unsigned int *src; + int num_ret, len; + + if (width) *width = 0; + if (height) *height = 0; + if (num) *num = 0; + + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_NET_WM_ICON, + XA_CARDINAL, 32, &data_ret, &num_ret)) + return 0; + data = (unsigned int *)data_ret; + + if (icon) + { + *icon = malloc((num_ret - 2) * sizeof(unsigned int)); + if (!(*icon)) return 0; + } + + if (num) *num = (num_ret - 2); + if (width) *width = data[0]; + if (height) *height = data[1]; + + len = data[0] * data[1]; + src = &(data[2]); + if (icon) + memcpy(*icon, &(data[2]), len * sizeof(unsigned int)); + free(data_ret); + + return 1; +} + +void +ecore_x_netwm_icon_geometry_set(Ecore_X_Window win, int x, int y, int width, int height) +{ + unsigned int geometry[4]; + + geometry[0] = x; + geometry[1] = y; + geometry[2] = width; + geometry[3] = height; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, geometry, 4); +} + +int +ecore_x_netwm_icon_geometry_get(Ecore_X_Window win, int *x, int *y, int *width, int *height) +{ + int ret; + unsigned int geometry[4]; + + ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, geometry, 4); + if (ret != 4) + return 0; + + if (x) *x = geometry[0]; + if (y) *y = geometry[1]; + if (width) *width = geometry[2]; + if (height) *height = geometry[3]; + return 1; +} + +void +ecore_x_netwm_pid_set(Ecore_X_Window win, int pid) +{ + unsigned int tmp; + + tmp = pid; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_PID, + &tmp, 1); +} + +int +ecore_x_netwm_pid_get(Ecore_X_Window win, int *pid) +{ + int ret; + unsigned int tmp; + + ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_PID, + &tmp, 1); + if (pid) *pid = tmp; + return ret == 1 ? 1 : 0; +} + +void +ecore_x_netwm_handled_icons_set(Ecore_X_Window win) +{ + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS, + NULL, 0); +} + +int +ecore_x_netwm_handled_icons_get(Ecore_X_Window win) +{ + int ret = 0; + ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS, + NULL, 0); + return ret == 0 ? 1 : 0; +} + +void +ecore_x_netwm_user_time_set(Ecore_X_Window win, unsigned int time) +{ + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_USER_TIME, + &time, 1); +} + +int +ecore_x_netwm_user_time_get(Ecore_X_Window win, unsigned int *time) +{ + int ret; + unsigned int tmp; + + ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_USER_TIME, + &tmp, 1); + if (time) *time = tmp; + return ret == 1 ? 1 : 0; +} + +Ecore_X_Window_State +_ecore_x_netwm_state_get(Ecore_X_Atom a) +{ + if (a == ECORE_X_ATOM_NET_WM_STATE_MODAL) + return ECORE_X_WINDOW_STATE_MODAL; + else if (a == ECORE_X_ATOM_NET_WM_STATE_STICKY) + return ECORE_X_WINDOW_STATE_STICKY; + else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT) + return ECORE_X_WINDOW_STATE_MAXIMIZED_VERT; + else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ) + return ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ; + else if (a == ECORE_X_ATOM_NET_WM_STATE_SHADED) + return ECORE_X_WINDOW_STATE_SHADED; + else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR) + return ECORE_X_WINDOW_STATE_SKIP_TASKBAR; + else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER) + return ECORE_X_WINDOW_STATE_SKIP_PAGER; + else if (a == ECORE_X_ATOM_NET_WM_STATE_HIDDEN) + return ECORE_X_WINDOW_STATE_HIDDEN; + else if (a == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN) + return ECORE_X_WINDOW_STATE_FULLSCREEN; + else if (a == ECORE_X_ATOM_NET_WM_STATE_ABOVE) + return ECORE_X_WINDOW_STATE_ABOVE; + else if (a == ECORE_X_ATOM_NET_WM_STATE_BELOW) + return ECORE_X_WINDOW_STATE_BELOW; + else if (a == ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION) + return ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION; + else + return ECORE_X_WINDOW_STATE_UNKNOWN; +} + +static Ecore_X_Atom +_ecore_x_netwm_state_atom_get(Ecore_X_Window_State s) +{ + switch(s) + { + case ECORE_X_WINDOW_STATE_MODAL: + return ECORE_X_ATOM_NET_WM_STATE_MODAL; + case ECORE_X_WINDOW_STATE_STICKY: + return ECORE_X_ATOM_NET_WM_STATE_STICKY; + case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT: + return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT; + case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ: + return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ; + case ECORE_X_WINDOW_STATE_SHADED: + return ECORE_X_ATOM_NET_WM_STATE_SHADED; + case ECORE_X_WINDOW_STATE_SKIP_TASKBAR: + return ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR; + case ECORE_X_WINDOW_STATE_SKIP_PAGER: + return ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER; + case ECORE_X_WINDOW_STATE_HIDDEN: + return ECORE_X_ATOM_NET_WM_STATE_HIDDEN; + case ECORE_X_WINDOW_STATE_FULLSCREEN: + return ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN; + case ECORE_X_WINDOW_STATE_ABOVE: + return ECORE_X_ATOM_NET_WM_STATE_ABOVE; + case ECORE_X_WINDOW_STATE_BELOW: + return ECORE_X_ATOM_NET_WM_STATE_BELOW; + case ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION: + return ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION; + default: + return 0; + } +} + +void +ecore_x_netwm_window_state_set(Ecore_X_Window win, Ecore_X_Window_State *state, unsigned int num) +{ + unsigned char *data; + Ecore_X_Atom *set; + int i; + + if (!num) + { + ecore_x_window_prop_property_del(win, ECORE_X_ATOM_NET_WM_STATE); + return; + } + + data = malloc(num * sizeof(Ecore_X_Atom)); + if (!data) return; + + set = (Ecore_X_Atom *) data; + for (i = 0; i < num; i++) + set[i] = _ecore_x_netwm_state_atom_get(state[i]); + + _ATOM_SET_ATOM(win, ECORE_X_ATOM_NET_WM_STATE, data, num); + + free(data); + return; +} + +int +ecore_x_netwm_window_state_get(Ecore_X_Window win, Ecore_X_Window_State **state, unsigned int *num) +{ + int num_ret, i; + unsigned char *data; + Ecore_X_Atom *atoms; + + if (num) *num = 0; + if (state) *state = NULL; + + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_NET_WM_STATE, + XA_ATOM, 32, &data, &num_ret)) + return 0; + + if ((!data) || (!num_ret)) return 0; + + atoms = (Ecore_X_Atom *) data; + if (state) + { + *state = malloc(num_ret * sizeof(Ecore_X_Window_State)); + if (*state) + for (i = 0; i < num_ret; ++i) + (*state)[i] = _ecore_x_netwm_state_get(atoms[i]); + + if (num) *num = num_ret; + } + + free(data); + return 1; +} + +static Ecore_X_Window_Type +_ecore_x_netwm_window_type_type_get(Ecore_X_Atom atom) +{ + if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP) + return ECORE_X_WINDOW_TYPE_DESKTOP; + else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK) + return ECORE_X_WINDOW_TYPE_DOCK; + else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR) + return ECORE_X_WINDOW_TYPE_TOOLBAR; + else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU) + return ECORE_X_WINDOW_TYPE_MENU; + else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY) + return ECORE_X_WINDOW_TYPE_UTILITY; + else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH) + return ECORE_X_WINDOW_TYPE_SPLASH; + else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG) + return ECORE_X_WINDOW_TYPE_DIALOG; + else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL) + return ECORE_X_WINDOW_TYPE_NORMAL; + else + return ECORE_X_WINDOW_TYPE_UNKNOWN; +} + +static Ecore_X_Atom +_ecore_x_netwm_window_type_atom_get(Ecore_X_Window_Type type) +{ + switch (type) + { + case ECORE_X_WINDOW_TYPE_DESKTOP: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP; + case ECORE_X_WINDOW_TYPE_DOCK: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK; + case ECORE_X_WINDOW_TYPE_TOOLBAR: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR; + case ECORE_X_WINDOW_TYPE_MENU: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU; + case ECORE_X_WINDOW_TYPE_UTILITY: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY; + case ECORE_X_WINDOW_TYPE_SPLASH: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH; + case ECORE_X_WINDOW_TYPE_DIALOG: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG; + case ECORE_X_WINDOW_TYPE_NORMAL: + return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL; + default: + return 0; + } +} + +/* + * FIXME: We should set WM_TRANSIENT_FOR if type is ECORE_X_WINDOW_TYPE_TOOLBAR + * , ECORE_X_WINDOW_TYPE_MENU or ECORE_X_WINDOW_TYPE_DIALOG + */ +void +ecore_x_netwm_window_type_set(Ecore_X_Window win, Ecore_X_Window_Type type) +{ + Ecore_X_Atom atom; + + atom = _ecore_x_netwm_window_type_atom_get(type); + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE, + XA_ATOM, 32, (unsigned char *)&atom, 1); +} + +/* FIXME: Maybe return 0 on some conditions? */ +int +ecore_x_netwm_window_type_get(Ecore_X_Window win, Ecore_X_Window_Type *type) +{ + int num, i; + unsigned char *data; + Ecore_X_Atom *atoms; + + if (type) *type = ECORE_X_WINDOW_TYPE_NORMAL; + + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE, + XA_ATOM, 32, &data, &num)) + { + /* Check if WM_TRANSIENT_FOR is set */ + if ((type) && (ecore_x_icccm_transient_for_get(win))) + *type = ECORE_X_WINDOW_TYPE_DIALOG; + return 1; + } + + atoms = (Ecore_X_Atom *) data; + + if (type) + { + for (i = 0; i < num; ++i) + { + *type = _ecore_x_netwm_window_type_type_get(atoms[i]); + if (*type != ECORE_X_WINDOW_TYPE_UNKNOWN) + break; + } + } + + free(data); + return 1; +} + +static Ecore_X_Atom +_ecore_x_netwm_action_atom_get(Ecore_X_Action action) +{ + switch (action) + { + case ECORE_X_ACTION_MOVE: + return ECORE_X_ATOM_NET_WM_ACTION_MOVE; + case ECORE_X_ACTION_RESIZE: + return ECORE_X_ATOM_NET_WM_ACTION_RESIZE; + case ECORE_X_ACTION_MINIMIZE: + return ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE; + case ECORE_X_ACTION_SHADE: + return ECORE_X_ATOM_NET_WM_ACTION_SHADE; + case ECORE_X_ACTION_STICK: + return ECORE_X_ATOM_NET_WM_ACTION_STICK; + case ECORE_X_ACTION_MAXIMIZE_HORZ: + return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ; + case ECORE_X_ACTION_MAXIMIZE_VERT: + return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT; + case ECORE_X_ACTION_FULLSCREEN: + return ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN; + case ECORE_X_ACTION_CHANGE_DESKTOP: + return ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP; + case ECORE_X_ACTION_CLOSE: + return ECORE_X_ATOM_NET_WM_ACTION_CLOSE; + default: + return 0; + } +} + +/* FIXME: Get complete list */ +int +ecore_x_netwm_allowed_action_isset(Ecore_X_Window win, Ecore_X_Action action) +{ + int num, i, ret = 0; + unsigned char *data; + Ecore_X_Atom *atoms, atom; + + if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE, + XA_ATOM, 32, &data, &num)) + return ret; + + atom = _ecore_x_netwm_action_atom_get(action); + atoms = (Ecore_X_Atom *) data; + + for (i = 0; i < num; ++i) + { + if (atom == atoms[i]) + { + ret = 1; + break; + } + } + + free(data); + return ret; +} + +/* FIXME: Set complete list */ +void +ecore_x_netwm_allowed_action_set(Ecore_X_Window win, Ecore_X_Action action, int on) +{ + Ecore_X_Atom atom; + Ecore_X_Atom *oldset = NULL, *newset = NULL; + int i, j = 0, num = 0; + unsigned char *data = NULL; + unsigned char *old_data = NULL; + + atom = _ecore_x_netwm_action_atom_get(action); + + ecore_x_window_prop_property_get(win, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, + XA_ATOM, 32, &old_data, &num); + oldset = (Ecore_X_Atom *) old_data; + + if (on) + { + for (i = 0; i < num; ++i) + { + if (oldset[i] == atom) + goto done; + } + + newset = calloc(num + 1, sizeof(Ecore_X_Atom)); + if (!newset) + goto done; + + data = (unsigned char *) newset; + for (i = 0; i < num; i++) + newset[i] = oldset[i]; + newset[num] = atom; + + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, + XA_ATOM, 32, data, num + 1); + } + else + { + int has; + + has = 0; + for (i = 0; i < num; ++i) + { + if (oldset[i] == atom) + has = 1; + } + if (!has) + goto done; + + newset = calloc(num - 1, sizeof(Ecore_X_Atom)); + if (!newset) + goto done; + + data = (unsigned char *) newset; + for (i = 0; i < num; i++) + if (oldset[i] != atom) + newset[j++] = oldset[i]; + + ecore_x_window_prop_property_set(win, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, + XA_ATOM, 32, data, num - 1); + } + free(newset); +done: + free(oldset); +} + +void +ecore_x_netwm_opacity_set(Ecore_X_Window win, unsigned int opacity) +{ + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY, + &opacity, 1); +} + +int +ecore_x_netwm_opacity_get(Ecore_X_Window win, unsigned int *opacity) +{ + int ret; + unsigned int tmp; + + ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY, + &tmp, 1); + if (opacity) *opacity = tmp; + return ret == 1 ? 1 : 0; +} + +void +ecore_x_netwm_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb) +{ + unsigned int frames[4]; + + frames[0] = fl; + frames[1] = fr; + frames[2] = ft; + frames[3] = fb; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_FRAME_EXTENTS, frames, 4); +} + +int +ecore_x_netwm_frame_size_get(Ecore_X_Window win, int *fl, int *fr, int *ft, int *fb) +{ + int ret = 0; + unsigned int frames[4]; + + ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_FRAME_EXTENTS, frames, 4); + if (ret != 4) + return 0; + + if (fl) *fl = frames[0]; + if (fr) *fr = frames[1]; + if (ft) *ft = frames[2]; + if (fb) *fb = frames[3]; + return 1; +} + +int +ecore_x_netwm_sync_counter_get(Ecore_X_Window win, Ecore_X_Sync_Counter *counter) +{ + int ret; + unsigned int tmp; + + ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER, + &tmp, 1); + + if (counter) *counter = tmp; + return ret == 1 ? 1 : 0; +} + +void +ecore_x_netwm_ping_send(Ecore_X_Window win) +{ + XEvent xev; + + if (!win) return; + + xev.xclient.type = ClientMessage; + xev.xclient.display = _ecore_x_disp; + xev.xclient.window = win; + xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS; + xev.xclient.format = 32; + xev.xclient.data.l[0] = ECORE_X_ATOM_NET_WM_PING; + xev.xclient.data.l[1] = CurrentTime; + xev.xclient.data.l[2] = win; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + xev.xclient.data.l[5] = 0; + + XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev); +} + +void +ecore_x_netwm_sync_request_send(Ecore_X_Window win, unsigned int serial) +{ + XSyncValue value; + XEvent xev; + + if (!win) return; + + XSyncIntToValue(&value, serial); + + xev.xclient.type = ClientMessage; + xev.xclient.display = _ecore_x_disp; + xev.xclient.window = win; + xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS; + xev.xclient.format = 32; + xev.xclient.data.l[0] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST; + xev.xclient.data.l[1] = CurrentTime; + xev.xclient.data.l[2] = XSyncValueLow32(value); + xev.xclient.data.l[3] = XSyncValueHigh32(value); + xev.xclient.data.l[4] = 0; + + XSendEvent(_ecore_x_disp, win, False, 0, &xev); +} + +void +ecore_x_netwm_state_request_send(Ecore_X_Window win, Ecore_X_Window root, + Ecore_X_Window_State s1, Ecore_X_Window_State s2, int set) +{ + XEvent xev; + + if (!win) return; + if (!root) root = DefaultRootWindow(_ecore_x_disp); + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.display = _ecore_x_disp; + xev.xclient.window = win; + xev.xclient.format = 32; + xev.xclient.message_type = ECORE_X_ATOM_NET_WM_STATE; + xev.xclient.data.l[0] = !!set; + xev.xclient.data.l[1] = _ecore_x_netwm_state_atom_get(s1); + xev.xclient.data.l[2] = _ecore_x_netwm_state_atom_get(s2); + /* 1 == normal client, if someone wants to use this + * function in a pager, this should be 2 */ + xev.xclient.data.l[3] = 1; + xev.xclient.data.l[4] = 0; + + XSendEvent(_ecore_x_disp, root, False, 0, &xev); +} + +void +ecore_x_netwm_desktop_request_send(Ecore_X_Window win, Ecore_X_Window root, unsigned int desktop) +{ + XEvent xev; + + if (!win) return; + if (!root) root = DefaultRootWindow(_ecore_x_disp); + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.display = _ecore_x_disp; + xev.xclient.window = win; + xev.xclient.format = 32; + xev.xclient.message_type = ECORE_X_ATOM_NET_WM_DESKTOP; + xev.xclient.data.l[0] = desktop; + + XSendEvent(_ecore_x_disp, root, False, + SubstructureNotifyMask | SubstructureRedirectMask, &xev); +} diff --git a/ecore/src/lib/ecore_x/ecore_x_pixmap.c b/ecore/src/lib/ecore_x/ecore_x_pixmap.c new file mode 100644 index 0000000..bfc96a2 --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_pixmap.c @@ -0,0 +1,95 @@ +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" + +/** + * @defgroup Ecore_X_Pixmap_Group X Pixmap Functions + * + * Functions that operate on pixmaps. + */ + +/** + * Creates a new pixmap. + * @param win Window used to determine which screen of the display the + * pixmap should be created on. If 0, the default root window + * is used. + * @param w Width of the new pixmap. + * @param h Height of the new pixmap. + * @param dep Depth of the pixmap. If 0, the default depth of the default + * screen is used. + * @return New pixmap. + * @ingroup Ecore_X_Pixmap_Group + */ +Ecore_X_Pixmap +ecore_x_pixmap_new(Ecore_X_Window win, int w, int h, int dep) +{ + if (win == 0) win = DefaultRootWindow(_ecore_x_disp); + if (dep == 0) dep = DefaultDepth(_ecore_x_disp, DefaultScreen(_ecore_x_disp)); + return XCreatePixmap(_ecore_x_disp, win, w, h, dep); +} + +/** + * Deletes the reference to the given pixmap. + * + * If no other clients have a reference to the given pixmap, the server + * will destroy it. + * + * @param pmap The given pixmap. + * @ingroup Ecore_X_Pixmap_Group + */ +void +ecore_x_pixmap_del(Ecore_X_Pixmap pmap) +{ + XFreePixmap(_ecore_x_disp, pmap); +} + +/** + * Pastes a rectangular area of the given pixmap onto the given drawable. + * @param pmap The given pixmap. + * @param dest The given drawable. + * @param gc The graphics context which governs which operation will + * be used to paste the area onto the drawable. + * @param sx The X position of the area on the pixmap. + * @param sy The Y position of the area on the pixmap. + * @param w The width of the area. + * @param h The height of the area. + * @param dx The X position at which to paste the area on @p dest. + * @param dy The Y position at which to paste the area on @p dest. + * @ingroup Ecore_X_Pixmap_Group + */ +void +ecore_x_pixmap_paste(Ecore_X_Pixmap pmap, Ecore_X_Drawable dest, + Ecore_X_GC gc, int sx, int sy, + int w, int h, int dx, int dy) +{ + XCopyArea(_ecore_x_disp, pmap, dest, gc, sx, sy, w, h, dx, dy); +} + +/** + * Retrieves the size of the given pixmap. + * @param pmap The given pixmap. + * @param x Pointer to an integer in which to store the X position. + * @param y Pointer to an integer in which to store the Y position. + * @param w Pointer to an integer in which to store the width. + * @param h Pointer to an integer in which to store the height. + * @ingroup Ecore_X_Pixmap_Group + */ +void +ecore_x_pixmap_geometry_get(Ecore_X_Pixmap pmap, int *x, int *y, int *w, int *h) +{ + if (pmap) + ecore_x_drawable_geometry_get(pmap, x, y, w, h); +} + +/** + * Retrieves the depth of the given pixmap. + * @param pmap The given pixmap. + * @return The depth of the pixmap. + * @ingroup Ecore_X_Pixmap_Group + */ +int +ecore_x_pixmap_depth_get(Ecore_X_Pixmap pmap) +{ + return ecore_x_drawable_depth_get(pmap); +} + diff --git a/ecore/src/lib/ecore_x/ecore_x_private.h b/ecore/src/lib/ecore_x/ecore_x_private.h new file mode 100644 index 0000000..bc9d87b --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_private.h @@ -0,0 +1,210 @@ +#ifndef _ECORE_X_PRIVATE_H +#define _ECORE_X_PRIVATE_H + +#include "config.h" + +#include +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 256 +#endif + +#define XK_MISCELLANY 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ECORE_XCURSOR +#include +#endif +#ifdef ECORE_XPRINT +#include +#endif +#ifdef ECORE_XINERAMA +#include +#endif + +#include "Ecore_X.h" + +/* FIXME: this is for simulation only */ +#include "Ecore_Job.h" +#include "Ecore_Txt.h" + +typedef struct _Ecore_X_Reply Ecore_X_Reply; + +struct _Ecore_X_Reply +{ +/* FIXME: this is for simulation only */ + Ecore_Job *job; + + void *reply_data; + void (*reply_data_free) (void *reply_data); + + void (*func) (void *data, Ecore_X_Reply *reply, void *reply_data); + void *data; +}; + +typedef struct _Ecore_X_Selection_Intern Ecore_X_Selection_Intern; + +struct _Ecore_X_Selection_Intern +{ + Ecore_X_Window win; + Ecore_X_Atom selection; + unsigned char *data; + int length; + Time time; +}; + +typedef struct _Ecore_X_Selection_Converter Ecore_X_Selection_Converter; + +struct _Ecore_X_Selection_Converter +{ + Ecore_X_Atom target; + int (*convert)(char *target, void *data, int size, + void **data_ret, int *size_ret); + Ecore_X_Selection_Converter *next; +}; + +typedef struct _Ecore_X_Selection_Parser Ecore_X_Selection_Parser; + +struct _Ecore_X_Selection_Parser +{ + char *target; + void *(*parse)(const char *target, unsigned char *data, int size); + Ecore_X_Selection_Parser *next; +}; + +typedef struct _Ecore_X_DND_Source +{ + int version; + Ecore_X_Window win, dest; + + enum { + ECORE_X_DND_SOURCE_IDLE, + ECORE_X_DND_SOURCE_DRAGGING, + ECORE_X_DND_SOURCE_DROPPED, + ECORE_X_DND_SOURCE_CONVERTING + } state; + + struct { + short x, y; + unsigned short width, height; + } rectangle; + + Time time; + + Ecore_X_Atom action, accepted_action; + + int will_accept; + int suppress; + + int await_status; +} Ecore_X_DND_Source; + +typedef struct _Ecore_X_DND_Target +{ + int version; + Ecore_X_Window win, source; + + enum { + ECORE_X_DND_TARGET_IDLE, + ECORE_X_DND_TARGET_ENTERED + } state; + + struct { + int x, y; + } pos; + + Time time; + + Ecore_X_Atom action, accepted_action; + + int will_accept; +} Ecore_X_DND_Target; + +extern Display *_ecore_x_disp; +extern double _ecore_x_double_click_time; +extern Time _ecore_x_event_last_time; +extern Window _ecore_x_event_last_win; +extern int _ecore_x_event_last_root_x; +extern int _ecore_x_event_last_root_y; +extern int _ecore_x_xcursor; + +extern Ecore_X_Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM]; + +extern int _ecore_window_grabs_num; +extern Window *_ecore_window_grabs; +extern int (*_ecore_window_grab_replay_func) (void *data, int event_type, void *event); +extern void *_ecore_window_grab_replay_data; + +extern Ecore_X_Window _ecore_x_private_win; + +void _ecore_x_error_handler_init(void); +void _ecore_x_event_handle_key_press(XEvent *xevent); +void _ecore_x_event_handle_key_release(XEvent *xevent); +void _ecore_x_event_handle_button_press(XEvent *xevent); +void _ecore_x_event_handle_button_release(XEvent *xevent); +void _ecore_x_event_handle_motion_notify(XEvent *xevent); +void _ecore_x_event_handle_enter_notify(XEvent *xevent); +void _ecore_x_event_handle_leave_notify(XEvent *xevent); +void _ecore_x_event_handle_focus_in(XEvent *xevent); +void _ecore_x_event_handle_focus_out(XEvent *xevent); +void _ecore_x_event_handle_keymap_notify(XEvent *xevent); +void _ecore_x_event_handle_expose(XEvent *xevent); +void _ecore_x_event_handle_graphics_expose(XEvent *xevent); +void _ecore_x_event_handle_visibility_notify(XEvent *xevent); +void _ecore_x_event_handle_create_notify(XEvent *xevent); +void _ecore_x_event_handle_destroy_notify(XEvent *xevent); +void _ecore_x_event_handle_unmap_notify(XEvent *xevent); +void _ecore_x_event_handle_map_notify(XEvent *xevent); +void _ecore_x_event_handle_map_request(XEvent *xevent); +void _ecore_x_event_handle_reparent_notify(XEvent *xevent); +void _ecore_x_event_handle_configure_notify(XEvent *xevent); +void _ecore_x_event_handle_configure_request(XEvent *xevent); +void _ecore_x_event_handle_gravity_notify(XEvent *xevent); +void _ecore_x_event_handle_resize_request(XEvent *xevent); +void _ecore_x_event_handle_circulate_notify(XEvent *xevent); +void _ecore_x_event_handle_circulate_request(XEvent *xevent); +void _ecore_x_event_handle_property_notify(XEvent *xevent); +void _ecore_x_event_handle_selection_clear(XEvent *xevent); +void _ecore_x_event_handle_selection_request(XEvent *xevent); +void _ecore_x_event_handle_selection_notify(XEvent *xevent); +void _ecore_x_event_handle_colormap_notify(XEvent *xevent); +void _ecore_x_event_handle_client_message(XEvent *xevent); +void _ecore_x_event_handle_mapping_notify(XEvent *xevent); +void _ecore_x_event_handle_shape_change(XEvent *xevent); +void _ecore_x_event_handle_sync_counter(XEvent *xevent); +void _ecore_x_event_handle_sync_alarm(XEvent *xevent); + +void _ecore_x_selection_data_init(void); +void _ecore_x_selection_shutdown(void); +Ecore_X_Atom + _ecore_x_selection_target_atom_get(const char *target); +char *_ecore_x_selection_target_get(Ecore_X_Atom target); +Ecore_X_Selection_Intern * + _ecore_x_selection_get(Ecore_X_Atom selection); +int _ecore_x_selection_set(Window w, unsigned char *data, int len, Ecore_X_Atom selection); +int _ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret); +void *_ecore_x_selection_parse(const char *target, unsigned char *data, int size); + +void _ecore_x_sync_magic_send(int val, Ecore_X_Window swin); +void _ecore_x_window_grab_remove(Ecore_X_Window win); +void _ecore_x_key_grab_remove(Ecore_X_Window win); + +/* from dnd */ +void _ecore_x_dnd_init(void); +Ecore_X_DND_Source *_ecore_x_dnd_source_get(void); +Ecore_X_DND_Target *_ecore_x_dnd_target_get(void); +void _ecore_x_dnd_drag(int x, int y); +void _ecore_x_dnd_shutdown(void); + +/* from netwm */ +Ecore_X_Window_State _ecore_x_netwm_state_get(Ecore_X_Atom a); + +/* from sync */ + +#endif diff --git a/ecore/src/lib/ecore_x/ecore_x_selection.c b/ecore/src/lib/ecore_x/ecore_x_selection.c new file mode 100644 index 0000000..5306219 --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_selection.c @@ -0,0 +1,773 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "ecore_private.h" +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" + +static Ecore_X_Selection_Intern selections[4]; +static Ecore_X_Selection_Converter *converters = NULL; +static Ecore_X_Selection_Parser *parsers = NULL; + +static int _ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret); +static int _ecore_x_selection_data_default_free(void *data); +static void *_ecore_x_selection_parser_files(const char *target, unsigned char *data, int size); +static int _ecore_x_selection_data_files_free(void *data); +static void *_ecore_x_selection_parser_text(const char *target, unsigned char *data, int size); +static int _ecore_x_selection_data_text_free(void *data); +static void *_ecore_x_selection_parser_targets(const char *target, unsigned char *data, int size); +static int _ecore_x_selection_data_targets_free(void *data); + +#define ECORE_X_SELECTION_DATA(x) ((Ecore_X_Selection_Data *)(x)) + +void +_ecore_x_selection_data_init(void) +{ + /* Initialize global data */ + memset(selections, 0, sizeof(selections)); + + /* Initialize converters */ + ecore_x_selection_converter_atom_add(ECORE_X_ATOM_TEXT, + _ecore_x_selection_converter_text); +#ifdef X_HAVE_UTF8_STRING + ecore_x_selection_converter_atom_add(ECORE_X_ATOM_UTF8_STRING, + _ecore_x_selection_converter_text); +#endif + ecore_x_selection_converter_atom_add(ECORE_X_ATOM_COMPOUND_TEXT, + _ecore_x_selection_converter_text); + ecore_x_selection_converter_atom_add(ECORE_X_ATOM_STRING, + _ecore_x_selection_converter_text); + + /* Initialize parsers */ + ecore_x_selection_parser_add("text/plain", + _ecore_x_selection_parser_text); + ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_UTF8_STRING, + _ecore_x_selection_parser_text); + ecore_x_selection_parser_add("text/uri-list", + _ecore_x_selection_parser_files); + ecore_x_selection_parser_add("_NETSCAPE_URL", + _ecore_x_selection_parser_files); + ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_TARGETS, + _ecore_x_selection_parser_targets); +} + +void +_ecore_x_selection_shutdown(void) +{ + Ecore_X_Selection_Converter *cnv; + Ecore_X_Selection_Parser *prs; + + /* free the selection converters */ + cnv = converters; + while (cnv) + { + Ecore_X_Selection_Converter *tmp; + + tmp = cnv->next; + free(cnv); + cnv = tmp; + } + converters = NULL; + + /* free the selection parsers */ + prs = parsers; + while (prs) + { + Ecore_X_Selection_Parser *tmp; + + tmp = prs; + prs = prs->next; + free(tmp->target); + free(tmp); + } + parsers = NULL; +} + +Ecore_X_Selection_Intern * +_ecore_x_selection_get(Ecore_X_Atom selection) +{ + if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) + return &selections[0]; + else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) + return &selections[1]; + else if (selection == ECORE_X_ATOM_SELECTION_XDND) + return &selections[2]; + else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) + return &selections[3]; + else + return NULL; +} + +int +_ecore_x_selection_set(Window w, unsigned char *data, int size, Ecore_X_Atom selection) +{ + int in; + unsigned char *buf = NULL; + + XSetSelectionOwner(_ecore_x_disp, selection, w, _ecore_x_event_last_time); + if (XGetSelectionOwner(_ecore_x_disp, selection) != w) + return 0; + + if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) + in = 0; + else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) + in = 1; + else if (selection == ECORE_X_ATOM_SELECTION_XDND) + in = 2; + else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) + in = 3; + else + return 0; + + if (data) + { + selections[in].win = w; + selections[in].selection = selection; + selections[in].length = size; + selections[in].time = _ecore_x_event_last_time; + + buf = malloc(size); + memcpy(buf, data, size); + selections[in].data = buf; + } + else + { + if (selections[in].data) + { + free(selections[in].data); + memset(&selections[in], 0, sizeof(Ecore_X_Selection_Data)); + } + } + + return 1; +} + +/** + * Claim ownership of the PRIMARY selection and set its data. + * @param w The window to which this selection belongs + * @param data The data associated with the selection + * @param size The size of the data buffer in bytes + * @return Returns 1 if the ownership of the selection was successfully + * claimed, or 0 if unsuccessful. + */ +int +ecore_x_selection_primary_set(Ecore_X_Window w, unsigned char *data, int size) +{ + return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_PRIMARY); +} + +/** + * Release ownership of the primary selection + * @return Returns 1 if the selection was successfully cleared, + * or 0 if unsuccessful. + * + */ +int +ecore_x_selection_primary_clear(void) +{ + return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_PRIMARY); +} + +/** + * Claim ownership of the SECONDARY selection and set its data. + * @param w The window to which this selection belongs + * @param data The data associated with the selection + * @param size The size of the data buffer in bytes + * @return Returns 1 if the ownership of the selection was successfully + * claimed, or 0 if unsuccessful. + */ +int +ecore_x_selection_secondary_set(Ecore_X_Window w, unsigned char *data, int size) +{ + return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_SECONDARY); +} + +/** + * Release ownership of the secondary selection + * @return Returns 1 if the selection was successfully cleared, + * or 0 if unsuccessful. + * + */ +int +ecore_x_selection_secondary_clear(void) +{ + return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_SECONDARY); +} + +/** + * Claim ownership of the XDND selection and set its data. + * @param w The window to which this selection belongs + * @param data The data associated with the selection + * @param size The size of the data buffer in bytes + * @return Returns 1 if the ownership of the selection was successfully + * claimed, or 0 if unsuccessful. + */ +int +ecore_x_selection_xdnd_set(Ecore_X_Window w, unsigned char *data, int size) +{ + return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_XDND); +} + +/** + * Release ownership of the XDND selection + * @return Returns 1 if the selection was successfully cleared, + * or 0 if unsuccessful. + * + */ +int +ecore_x_selection_xdnd_clear(void) +{ + return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_XDND); +} + +/** + * Claim ownership of the CLIPBOARD selection and set its data. + * @param w The window to which this selection belongs + * @param data The data associated with the selection + * @param size The size of the data buffer in bytes + * @return Returns 1 if the ownership of the selection was successfully + * claimed, or 0 if unsuccessful. + * + * Get the converted data from a previous CLIPBOARD selection + * request. The buffer must be freed when done with. + */ +int +ecore_x_selection_clipboard_set(Ecore_X_Window w, unsigned char *data, int size) +{ + return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_CLIPBOARD); +} + +/** + * Release ownership of the clipboard selection + * @return Returns 1 if the selection was successfully cleared, + * or 0 if unsuccessful. + * + */ +int +ecore_x_selection_clipboard_clear(void) +{ + return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_CLIPBOARD); +} + +Ecore_X_Atom +_ecore_x_selection_target_atom_get(const char *target) +{ + Ecore_X_Atom x_target; + + if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT)) + x_target = ECORE_X_ATOM_TEXT; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT)) + x_target = ECORE_X_ATOM_COMPOUND_TEXT; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING)) + x_target = ECORE_X_ATOM_STRING; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING)) + x_target = ECORE_X_ATOM_UTF8_STRING; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_FILENAME)) + x_target = ECORE_X_ATOM_FILE_NAME; + else + { + x_target = ecore_x_atom_get(target); + } + + return x_target; +} + +char * +_ecore_x_selection_target_get(Ecore_X_Atom target) +{ + if (target == ECORE_X_ATOM_FILE_NAME) + return strdup(ECORE_X_SELECTION_TARGET_FILENAME); + else if (target == ECORE_X_ATOM_STRING) + return strdup(ECORE_X_SELECTION_TARGET_STRING); + else if (target == ECORE_X_ATOM_UTF8_STRING) + return strdup(ECORE_X_SELECTION_TARGET_UTF8_STRING); + else if (target == ECORE_X_ATOM_TEXT) + return strdup(ECORE_X_SELECTION_TARGET_TEXT); + else + return XGetAtomName(_ecore_x_disp, target); +} + +static void +_ecore_x_selection_request(Ecore_X_Window w, Ecore_X_Atom selection, char *target_str) +{ + Ecore_X_Atom target, prop; + + target = _ecore_x_selection_target_atom_get(target_str); + + if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) + prop = ECORE_X_ATOM_SELECTION_PROP_PRIMARY; + else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) + prop = ECORE_X_ATOM_SELECTION_PROP_SECONDARY; + else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) + prop = ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD; + else + return; + + XConvertSelection(_ecore_x_disp, selection, target, prop, + w, CurrentTime); +} + +void +ecore_x_selection_primary_request(Ecore_X_Window w, char *target) +{ + _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_PRIMARY, target); +} + +void +ecore_x_selection_secondary_request(Ecore_X_Window w, char *target) +{ + _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_SECONDARY, target); +} + +void +ecore_x_selection_xdnd_request(Ecore_X_Window w, char *target) +{ + Ecore_X_Atom atom; + Ecore_X_DND_Target *_target; + + _target = _ecore_x_dnd_target_get(); + atom = _ecore_x_selection_target_atom_get(target); + XConvertSelection(_ecore_x_disp, ECORE_X_ATOM_SELECTION_XDND, atom, + ECORE_X_ATOM_SELECTION_PROP_XDND, w, + _target->time); +} + +void +ecore_x_selection_clipboard_request(Ecore_X_Window w, char *target) +{ + _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_CLIPBOARD, target); +} + +void +ecore_x_selection_converter_atom_add(Ecore_X_Atom target, + int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret)) +{ + Ecore_X_Selection_Converter *cnv; + + cnv = converters; + if (converters) + { + while (1) + { + if (cnv->target == target) + { + cnv->convert = func; + return; + } + if (cnv->next) + cnv = cnv->next; + else + break; + } + + cnv->next = calloc(1, sizeof(Ecore_X_Selection_Converter)); + cnv = cnv->next; + } + else + { + converters = calloc(1, sizeof(Ecore_X_Selection_Converter)); + cnv = converters; + } + cnv->target = target; + cnv->convert = func; +} + +void +ecore_x_selection_converter_add(char *target, + int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret)) +{ + Ecore_X_Atom x_target; + + if (!func || !target) + return; + + x_target = _ecore_x_selection_target_atom_get(target); + + ecore_x_selection_converter_atom_add(x_target, func); +} + +void +ecore_x_selection_converter_atom_del(Ecore_X_Atom target) +{ + Ecore_X_Selection_Converter *cnv, *prev_cnv; + + prev_cnv = NULL; + cnv = converters; + + while (cnv) + { + if (cnv->target == target) + { + if (prev_cnv) + prev_cnv->next = cnv->next; + else + converters = cnv->next; /* This was the first converter */ + free(cnv); + + return; + } + prev_cnv = cnv; + cnv = cnv->next; + } +} + +void +ecore_x_selection_converter_del(char *target) +{ + Ecore_X_Atom x_target; + + if (!target) + return; + + x_target = _ecore_x_selection_target_atom_get(target); + ecore_x_selection_converter_atom_del(x_target); +} + +/* Locate and run conversion callback for specified selection target */ +int +_ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret) +{ + Ecore_X_Selection_Intern *sel; + Ecore_X_Selection_Converter *cnv; + void *data; + int size; + char *tgt_str; + + sel = _ecore_x_selection_get(selection); + tgt_str = _ecore_x_selection_target_get(target); + + for (cnv = converters; cnv; cnv = cnv->next) + { + if (cnv->target == target) + { + int r; + r = cnv->convert(tgt_str, sel->data, sel->length, &data, &size); + free(tgt_str); + if (r) + { + *data_ret = data; + return r; + } + else + return 0; + } + } + + /* Default, just return the data */ + *data_ret = malloc(sel->length); + memcpy(*data_ret, sel->data, sel->length); + free(tgt_str); + return 1; +} + +/* TODO: We need to work out a mechanism for automatic conversion to any requested + * locale using Ecore_Txt functions */ +/* Converter for standard non-utf8 text targets */ +static int +_ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret) +{ + XTextProperty text_prop; + char *mystr; + XICCEncodingStyle style; + + if (!data || !size) + return 0; + + if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT)) + style = XTextStyle; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT)) + style = XCompoundTextStyle; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING)) + style = XStringStyle; +#ifdef X_HAVE_UTF8_STRING + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING)) + style = XUTF8StringStyle; +#endif + else + return 0; + + if (!(mystr = strdup(data))) + return 0; + +#ifdef X_HAVE_UTF8_STRING + if (Xutf8TextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success) + { + int bufsize = strlen((char *)text_prop.value) + 1; + *data_ret = malloc(bufsize); + memcpy(*data_ret, text_prop.value, bufsize); + *size_ret = bufsize; + XFree(text_prop.value); + free(mystr); + return 1; + } +#else + if (XmbTextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success) + { + int bufsize = strlen(text_prop.value) + 1; + *data_ret = malloc(bufsize); + memcpy(*data_ret, text_prop.value, bufsize); + *size_ret = bufsize; + XFree(text_prop.value); + free(mystr); + return 1; + } +#endif + else + { + free(mystr); + return 0; + } +} + +void +ecore_x_selection_parser_add(const char *target, + void *(*func)(const char *target, unsigned char *data, int size)) +{ + Ecore_X_Selection_Parser *prs; + + if (!target) + return; + + prs = parsers; + if (parsers) + { + while (prs->next) + { + if (!strcmp(prs->target, target)) + { + prs->parse = func; + return; + } + prs = prs->next; + } + + prs->next = calloc(1, sizeof(Ecore_X_Selection_Parser)); + prs = prs->next; + } + else + { + parsers = calloc(1, sizeof(Ecore_X_Selection_Parser)); + prs = parsers; + } + prs->target = strdup(target); + prs->parse = func; +} + +void +ecore_x_selection_parser_del(const char *target) +{ + Ecore_X_Selection_Parser *prs, *prev_prs; + + if (!target) + return; + + prev_prs = NULL; + prs = parsers; + + while (prs) + { + if (!strcmp(prs->target, target)) + { + if (prev_prs) + prev_prs->next = prs->next; + else + parsers = prs->next; /* This was the first parser */ + free(prs->target); + free(prs); + + return; + } + prev_prs = prs; + prs = prs->next; + } +} + +/* Locate and run conversion callback for specified selection target */ +void * +_ecore_x_selection_parse(const char *target, unsigned char *data, int size) +{ + Ecore_X_Selection_Parser *prs; + Ecore_X_Selection_Data *sel; + + for (prs = parsers; prs; prs = prs->next) + { + if (!strcmp(prs->target, target)) + { + sel = prs->parse(target, data, size); + return sel; + } + } + + /* Default, just return the data */ + sel = calloc(1, sizeof(Ecore_X_Selection_Data)); + sel->free = _ecore_x_selection_data_default_free; + sel->length = size; + sel->data = data; + return sel; +} + +static int +_ecore_x_selection_data_default_free(void *data) +{ + Ecore_X_Selection_Data *sel; + + sel = data; + free(sel->data); + free(sel); + return 1; +} + +static void * +_ecore_x_selection_parser_files(const char *target, unsigned char *data, int size) +{ + Ecore_X_Selection_Data_Files *sel; + int i, is; + char *tmp; + + if (strcmp(target, "text/uri-list") + && strcmp(target, "_NETSCAPE_URL")) + return NULL; + + sel = calloc(1, sizeof(Ecore_X_Selection_Data_Files)); + ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_files_free; + + if (data[size - 1]) + { + /* Isn't nul terminated */ + printf("BUG: isn't nul terminated!\n"); + size++; + data = realloc(data, size); + data[size - 1] = 0; + } + + tmp = malloc(size); + i = 0; + is = 0; + while ((is < size) && (data[is])) + { + if ((i == 0) && (data[is] == '#')) + { + for (; ((data[is]) && (data[is] != '\n')); is++); + } + else + { + if ((data[is] != '\r') + && (data[is] != '\n')) + { + tmp[i++] = data[is++]; + } + else + { + while ((data[is] == '\r') + || (data[is] == '\n')) + is++; + tmp[i] = 0; + sel->num_files++; + sel->files = realloc(sel->files, sel->num_files * sizeof(char *)); + sel->files[sel->num_files - 1] = strdup(tmp); + tmp[0] = 0; + i = 0; + } + } + } + if (i > 0) + { + tmp[i] = 0; + sel->num_files++; + sel->files = realloc(sel->files, sel->num_files * sizeof(char *)); + sel->files[sel->num_files - 1] = strdup(tmp); + } + free(tmp); + free(data); + + return ECORE_X_SELECTION_DATA(sel); +} + +static int +_ecore_x_selection_data_files_free(void *data) +{ + Ecore_X_Selection_Data_Files *sel; + int i; + + sel = data; + if (sel->files) + { + for (i = 0; i < sel->num_files; i++) + free(sel->files[i]); + free(sel->files); + } + free(sel); + return 0; +} + +static void * +_ecore_x_selection_parser_text(const char *target __UNUSED__, unsigned char *data, int size) +{ + Ecore_X_Selection_Data_Text *sel; + + sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text)); + + if (data[size - 1]) + { + /* Isn't nul terminated */ + printf("BUG: isn't nul terminated!\n"); + size++; + data = realloc(data, size); + data[size - 1] = 0; + } + + sel->text = (char *)data; + ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_text_free; + return sel; +} + +static int +_ecore_x_selection_data_text_free(void *data) +{ + Ecore_X_Selection_Data_Text *sel; + + sel = data; + free(sel->text); + free(sel); + return 1; +} + +static void * +_ecore_x_selection_parser_targets(const char *target __UNUSED__, unsigned char *data, int size) +{ + Ecore_X_Selection_Data_Targets *sel; + unsigned long *targets; + int i; + + sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets)); + targets = (unsigned long *)data; + + sel->num_targets = size - 2; + sel->targets = malloc((size - 2) * sizeof(char *)); + for (i = 2; i < size; i++) + sel->targets[i - 2] = XGetAtomName(_ecore_x_disp, targets[i]); + free(data); + + ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_targets_free; + return sel; +} + +static int +_ecore_x_selection_data_targets_free(void *data) +{ + Ecore_X_Selection_Data_Targets *sel; + int i; + + sel = data; + + if (sel->targets) + { + for (i = 0; i < sel->num_targets; i++) + XFree(sel->targets[i]); + free(sel->targets); + } + free(sel); + return 1; +} diff --git a/ecore/src/lib/ecore_x/ecore_x_sync.c b/ecore/src/lib/ecore_x/ecore_x_sync.c new file mode 100644 index 0000000..0b567bf --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_sync.c @@ -0,0 +1,48 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +/* + * XSync code + */ +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" + +Ecore_X_Sync_Alarm +ecore_x_sync_alarm_new(Ecore_X_Sync_Counter counter) +{ + Ecore_X_Sync_Alarm alarm; + XSyncAlarmAttributes values; + XSyncValue init; + + XSyncIntToValue(&init, 0); + XSyncSetCounter(_ecore_x_disp, counter, init); + + values.trigger.counter = counter; + values.trigger.value_type = XSyncAbsolute; + XSyncIntToValue(&values.trigger.wait_value, 1); + values.trigger.test_type = XSyncPositiveComparison; + + XSyncIntToValue(&values.delta, 1); + + values.events = True; + + alarm = XSyncCreateAlarm(_ecore_x_disp, + XSyncCACounter | + XSyncCAValueType | + XSyncCAValue | + XSyncCATestType | + XSyncCADelta | + XSyncCAEvents, + &values); + + ecore_x_sync(); + return alarm; +} + +int +ecore_x_sync_alarm_free(Ecore_X_Sync_Alarm alarm) +{ + return XSyncDestroyAlarm(_ecore_x_disp, alarm); +} diff --git a/ecore/src/lib/ecore_x/ecore_x_window.c b/ecore/src/lib/ecore_x/ecore_x_window.c new file mode 100644 index 0000000..3577b74 --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_window.c @@ -0,0 +1,768 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" + +/** + * @defgroup Ecore_X_Window_Create_Group X Window Creation Functions + * + * Functions that can be used to create an X window. + */ + +/** + * Creates a new window. + * @param parent The parent window to use. If @p parent is @c 0, the root + * window of the default display is used. + * @param x X position. + * @param y Y position. + * @param w Width. + * @param h Height. + * @return The new window handle. + * @ingroup Ecore_X_Window_Create_Group + */ +Ecore_X_Window +ecore_x_window_new(Ecore_X_Window parent, int x, int y, int w, int h) +{ + Window win; + XSetWindowAttributes attr; + + if (parent == 0) parent = DefaultRootWindow(_ecore_x_disp); + attr.backing_store = NotUseful; + attr.override_redirect = False; + attr.colormap = DefaultColormap(_ecore_x_disp, DefaultScreen(_ecore_x_disp)); + attr.border_pixel = 0; + attr.background_pixmap = None; + attr.save_under = False; + attr.do_not_propagate_mask = NoEventMask; + attr.event_mask = KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + EnterWindowMask | + LeaveWindowMask | + PointerMotionMask | + ExposureMask | + VisibilityChangeMask | + StructureNotifyMask | + FocusChangeMask | + PropertyChangeMask | + ColormapChangeMask; + win = XCreateWindow(_ecore_x_disp, parent, + x, y, w, h, 0, + 0, /*DefaultDepth(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/ + InputOutput, + CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/ + CWBackingStore | + CWOverrideRedirect | +/* CWColormap | */ + CWBorderPixel | + CWBackPixmap | + CWSaveUnder | + CWDontPropagate | + CWEventMask, + &attr); + + if (parent == DefaultRootWindow(_ecore_x_disp)) ecore_x_window_defaults_set(win); + return win; +} + +/** + * Creates a window with the override redirect attribute set to @c True. + * @param parent The parent window to use. If @p parent is @c 0, the root + * window of the default display is used. + * @param x X position. + * @param y Y position. + * @param w Width. + * @param h Height. + * @return The new window handle. + * @ingroup Ecore_X_Window_Create_Group + */ +Ecore_X_Window +ecore_x_window_override_new(Ecore_X_Window parent, int x, int y, int w, int h) +{ + Window win; + XSetWindowAttributes attr; + + if (parent == 0) parent = DefaultRootWindow(_ecore_x_disp); + attr.backing_store = NotUseful; + attr.override_redirect = True; + attr.colormap = DefaultColormap(_ecore_x_disp, DefaultScreen(_ecore_x_disp)); + attr.border_pixel = 0; + attr.background_pixmap = None; + attr.save_under = False; + attr.do_not_propagate_mask = NoEventMask; + attr.event_mask = KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + EnterWindowMask | + LeaveWindowMask | + PointerMotionMask | + ExposureMask | + VisibilityChangeMask | + StructureNotifyMask | + FocusChangeMask | + PropertyChangeMask | + ColormapChangeMask; + win = XCreateWindow(_ecore_x_disp, parent, + x, y, w, h, 0, + 0, /*DefaultDepth(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/ + InputOutput, + CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/ + CWBackingStore | + CWOverrideRedirect | +/* CWColormap | */ + CWBorderPixel | + CWBackPixmap | + CWSaveUnder | + CWDontPropagate | + CWEventMask, + &attr); + + if (parent == DefaultRootWindow(_ecore_x_disp)) ecore_x_window_defaults_set(win); + return win; +} + +/** + * Creates a new input window. + * @param parent The parent window to use. If @p parent is @c 0, the root + * window of the default display is used. + * @param x X position. + * @param y Y position. + * @param w Width. + * @param h Height. + * @return The new window. + * @ingroup Ecore_X_Window_Create_Group + */ +Ecore_X_Window +ecore_x_window_input_new(Ecore_X_Window parent, int x, int y, int w, int h) +{ + Window win; + XSetWindowAttributes attr; + + if (parent == 0) parent = DefaultRootWindow(_ecore_x_disp); + attr.override_redirect = True; + attr.do_not_propagate_mask = NoEventMask; + attr.event_mask = KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + EnterWindowMask | + LeaveWindowMask | + PointerMotionMask | + ExposureMask | + VisibilityChangeMask | + StructureNotifyMask | + FocusChangeMask | + PropertyChangeMask | + ColormapChangeMask; + win = XCreateWindow(_ecore_x_disp, parent, + x, y, w, h, 0, + 0, + InputOnly, + CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/ + CWOverrideRedirect | + CWDontPropagate | + CWEventMask, + &attr); + + if (parent == DefaultRootWindow(_ecore_x_disp)) + { + } + return win; +} + +/** + * @defgroup Evas_X_Window_Properties_Group X Window Property Functions + * + * Functions that set window properties. + */ + +/** + * Sets the default properties for the given window. + * + * The default properties set for the window are @c WM_CLIENT_MACHINE and + * @c _NET_WM_PID. + * + * @param win The given window. + * @ingroup Evas_X_Window_Properties_Groups + */ +void +ecore_x_window_defaults_set(Ecore_X_Window win) +{ + long pid; + char buf[MAXHOSTNAMELEN]; + char *hostname[1]; + int argc; + char **argv; + XTextProperty xprop; + + /* + * Set WM_CLIENT_MACHINE. + */ + gethostname(buf, MAXHOSTNAMELEN); + buf[MAXHOSTNAMELEN - 1] = '\0'; + hostname[0] = buf; + /* The ecore function uses UTF8 which Xlib may not like (especially + * with older clients) */ + /* ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_CLIENT_MACHINE, + (char *)buf); */ + if (XStringListToTextProperty(hostname, 1, &xprop)) + { + XSetWMClientMachine(_ecore_x_disp, win, &xprop); + XFree(xprop.value); + } + + /* + * Set _NET_WM_PID + */ + pid = getpid(); + ecore_x_netwm_pid_set(win, pid); + + ecore_x_netwm_window_type_set(win, ECORE_X_WINDOW_TYPE_NORMAL); + + ecore_app_args_get(&argc, &argv); + ecore_x_icccm_command_set(win, argc, argv); +} + +void +ecore_x_window_configure(Ecore_X_Window win, + Ecore_X_Window_Configure_Mask mask, + int x, int y, int w, int h, + int border_width, Ecore_X_Window sibling, + int stack_mode) +{ + XWindowChanges xwc; + + if (!win) + return; + + xwc.x = x; + xwc.y = y; + xwc.width = w; + xwc.height = h; + xwc.border_width = border_width; + xwc.sibling = sibling; + xwc.stack_mode = stack_mode; + + XConfigureWindow(_ecore_x_disp, win, mask, &xwc); +} + +/** + * @defgroup Evas_X_Window_Destroy_Group X Window Destroy Functions + * + * Functions to destroy X windows. + */ + +/** + * Deletes the given window. + * @param win The given window. + * @ingroup Evas_X_Window_Destroy_Group + */ +void +ecore_x_window_del(Ecore_X_Window win) +{ + /* sorry sir, deleting the root window doesn't sound like + * a smart idea. + */ + if (win) + XDestroyWindow(_ecore_x_disp, win); +} + +/** + * Sends a delete request to the given window. + * @param win The given window. + * @ingroup Evas_X_Window_Destroy_Group + */ +void +ecore_x_window_delete_request_send(Ecore_X_Window win) +{ + XEvent xev; + + /* sorry sir, deleting the root window doesn't sound like + * a smart idea. + */ + if (!win) + return; + + xev.xclient.type = ClientMessage; + xev.xclient.display = _ecore_x_disp; + xev.xclient.window = win; + xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS; + xev.xclient.format = 32; + xev.xclient.data.l[0] = ECORE_X_ATOM_WM_DELETE_WINDOW; + xev.xclient.data.l[1] = CurrentTime; + + XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev); +} + +/** + * @defgroup Evas_X_Window_Visibility_Group X Window Visibility Functions + * + * Functions to access and change the visibility of X windows. + */ + +/** + * Shows a window. + * + * Synonymous to "mapping" a window in X Window System terminology. + * + * @param win The window to show. + * @ingroup Evas_X_Window_Visibility + */ +void +ecore_x_window_show(Ecore_X_Window win) +{ + XMapWindow(_ecore_x_disp, win); +} + +/** + * Hides a window. + * + * Synonymous to "unmapping" a window in X Window System terminology. + * + * @param win The window to hide. + * @ingroup Evas_X_Window_Visibility + */ +void +ecore_x_window_hide(Ecore_X_Window win) +{ + XUnmapWindow(_ecore_x_disp, win); +} + +/** + * @defgroup Ecore_X_Window_Geometry_Group X Window Geometry Functions + * + * Functions that change or retrieve the geometry of X windows. + */ + +/** + * Moves a window to the position @p x, @p y. + * + * The position is relative to the upper left hand corner of the + * parent window. + * + * @param win The window to move. + * @param x X position. + * @param y Y position. + * @ingroup Ecore_X_Window_Geometry_Group + */ +void +ecore_x_window_move(Ecore_X_Window win, int x, int y) +{ + XMoveWindow(_ecore_x_disp, win, x, y); +} + +/** + * Resizes a window. + * @param win The window to resize. + * @param w New width of the window. + * @param h New height of the window. + * @ingroup Ecore_X_Window_Geometry_Group + */ +void +ecore_x_window_resize(Ecore_X_Window win, int w, int h) +{ + if (w < 1) w = 1; + if (h < 1) h = 1; + XResizeWindow(_ecore_x_disp, win, w, h); +} + +/** + * Moves and resizes a window. + * @param win The window to move and resize. + * @param x New X position of the window. + * @param y New Y position of the window. + * @param w New width of the window. + * @param h New height of the window. + * @ingroup Ecore_X_Window_Geometry_Group + */ +void +ecore_x_window_move_resize(Ecore_X_Window win, int x, int y, int w, int h) +{ + if (w < 1) w = 1; + if (h < 1) h = 1; + XMoveResizeWindow(_ecore_x_disp, win, x, y, w, h); +} + +/** + * @defgroup Ecore_X_Window_Focus_Functions X Window Focus Functions + * + * Functions that give the focus to an X Window. + */ + +/** + * Sets the focus to the window @p win. + * @param win The window to focus. + * @ingroup Ecore_X_Window_Focus_Functions + */ +void +ecore_x_window_focus(Ecore_X_Window win) +{ + if (win == 0) win = DefaultRootWindow(_ecore_x_disp); +// XSetInputFocus(_ecore_x_disp, win, RevertToNone, CurrentTime); + XSetInputFocus(_ecore_x_disp, win, PointerRoot, CurrentTime); +} + +/** + * Sets the focus to the given window at a specific time. + * @param win The window to focus. + * @param t When to set the focus to the window. + * @ingroup Ecore_X_Window_Focus_Functions + */ +void +ecore_x_window_focus_at_time(Ecore_X_Window win, Ecore_X_Time t) +{ + if (win == 0) win = DefaultRootWindow(_ecore_x_disp); +// XSetInputFocus(_ecore_x_disp, win, RevertToNone, t); + XSetInputFocus(_ecore_x_disp, win, PointerRoot, t); +} + +/** + * gets the focus to the window @p win. + * @return The window that has focus. + * @ingroup Ecore_X_Window_Focus_Functions + */ +Ecore_X_Window +ecore_x_window_focus_get(void) +{ + Window win; + int revert_mode; + + win = 0; + + XGetInputFocus(_ecore_x_disp, &win, &revert_mode); + return win; +} + +/** + * @defgroup Ecore_X_Window_Z_Order_Group X Window Z Order Functions + * + * Functions that change the Z order of X windows. + */ + +/** + * Raises the given window. + * @param win The window to raise. + * @ingroup Ecore_X_Window_Z_Order_Group + */ +void +ecore_x_window_raise(Ecore_X_Window win) +{ + XRaiseWindow(_ecore_x_disp, win); +} + +/** + * Lowers the given window. + * @param win The window to lower. + * @ingroup Ecore_X_Window_Z_Order_Group + */ +void +ecore_x_window_lower(Ecore_X_Window win) +{ + XLowerWindow(_ecore_x_disp, win); +} + +/** + * @defgroup Ecore_X_Window_Parent_Group X Window Parent Functions + * + * Functions that retrieve or changes the parent window of a window. + */ + +/** + * Moves a window to within another window at a given position. + * @param win The window to reparent. + * @param new_parent The new parent window. + * @param x X position within new parent window. + * @param y Y position within new parent window. + * @ingroup Ecore_X_Window_Parent_Group + */ +void +ecore_x_window_reparent(Ecore_X_Window win, Ecore_X_Window new_parent, int x, int y) +{ + if (new_parent == 0) new_parent = DefaultRootWindow(_ecore_x_disp); + XReparentWindow(_ecore_x_disp, win, new_parent, x, y); +} + +/** + * Retrieves the size of the given window. + * @param win The given window. + * @param w Pointer to an integer into which the width is to be stored. + * @param h Pointer to an integer into which the height is to be stored. + * @ingroup Ecore_X_Window_Geometry_Group + */ +void +ecore_x_window_size_get(Ecore_X_Window win, int *w, int *h) +{ + int dummy_x, dummy_y; + + if (win == 0) + win = DefaultRootWindow(_ecore_x_disp); + + ecore_x_drawable_geometry_get(win, &dummy_x, &dummy_y, w, h); +} + +/** + * Retrieves the geometry of the given window. + * @param win The given window. + * @param x Pointer to an integer in which the X position is to be stored. + * @param y Pointer to an integer in which the Y position is to be stored. + * @param w Pointer to an integer in which the width is to be stored. + * @param h Pointer to an integer in which the height is to be stored. + * @ingroup Ecore_X_Window_Geometry_Group + */ +void +ecore_x_window_geometry_get(Ecore_X_Window win, int *x, int *y, int *w, int *h) +{ + if (!win) + win = DefaultRootWindow(_ecore_x_disp); + + ecore_x_drawable_geometry_get(win, x, y, w, h); +} + +/** + * Retrieves the width of the border of the given window. + * @param win The given window. + * @return Width of the border of @p win. + * @ingroup Ecore_X_Window_Geometry_Group + */ +int +ecore_x_window_border_width_get(Ecore_X_Window win) +{ + /* doesn't make sense to call this on a root window */ + if (!win) + return 0; + + return ecore_x_drawable_border_width_get(win); +} + +/** + * Sets the width of the border of the given window. + * @param win The given window. + * @param width The new border width. + * @ingroup Ecore_X_Window_Geometry_Group + */ +void +ecore_x_window_border_width_set(Ecore_X_Window win, int width) +{ + /* doesn't make sense to call this on a root window */ + if (!win) + return; + + XSetWindowBorderWidth (_ecore_x_disp, win, width); +} + +/** + * Retrieves the depth of the given window. + * @param win The given window. + * @return Depth of the window. + */ +int +ecore_x_window_depth_get(Ecore_X_Window win) +{ + return ecore_x_drawable_depth_get(win); +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +void +ecore_x_window_cursor_show(Ecore_X_Window win, int show) +{ + if (win == 0) win = DefaultRootWindow(_ecore_x_disp); + if (!show) + { + Cursor c; + XColor cl; + Pixmap p, m; + GC gc; + XGCValues gcv; + + p = XCreatePixmap(_ecore_x_disp, win, 1, 1, 1); + m = XCreatePixmap(_ecore_x_disp, win, 1, 1, 1); + gc = XCreateGC(_ecore_x_disp, m, 0, &gcv); + XSetForeground(_ecore_x_disp, gc, 0); + XDrawPoint(_ecore_x_disp, m, gc, 0, 0); + XFreeGC(_ecore_x_disp, gc); + c = XCreatePixmapCursor(_ecore_x_disp, p, m, &cl, &cl, 0, 0); + XDefineCursor(_ecore_x_disp, win, c); + XFreeCursor(_ecore_x_disp, c); + XFreePixmap(_ecore_x_disp, p); + XFreePixmap(_ecore_x_disp, m); + } + else + { + XDefineCursor(_ecore_x_disp, win, 0); + } +} + +void +ecore_x_window_cursor_set(Ecore_X_Window win, Ecore_X_Cursor c) +{ + if (c == 0) + XUndefineCursor(_ecore_x_disp, win); + else + XDefineCursor(_ecore_x_disp, win, c); +} + +/** + * Finds out whether the given window is currently visible. + * @param win The given window. + * @return 1 if the window is visible, otherwise 0. + * @ingroup Ecore_X_Window_Visibility_Group + */ +int +ecore_x_window_visible_get(Ecore_X_Window win) +{ + XWindowAttributes attr; + + return (XGetWindowAttributes(_ecore_x_disp, win, &attr) && + (attr.map_state == IsViewable)); +} + +static Window +_ecore_x_window_at_xy_get(Window base, int bx, int by, int x, int y) +{ + Window *list = NULL; + Window parent_win = 0, child = 0, root_win = 0; + int i, wx, wy, ww, wh; + unsigned int num; + + if (!ecore_x_window_visible_get(base)) + return 0; + + ecore_x_window_geometry_get(base, &wx, &wy, &ww, &wh); + wx += bx; + wy += by; + + if (!((x >= wx) && (y >= wy) && (x < (wx + ww)) && (y < (wy + wh)))) + return 0; + + if (!XQueryTree(_ecore_x_disp, base, &root_win, &parent_win, &list, &num)) + return base; + + if (list) + { + for (i = num - 1;; --i) + { + if ((child = _ecore_x_window_at_xy_get(list[i], wx, wy, x, y))) + { + XFree(list); + return child; + } + if (!i) + break; + } + XFree(list); + } + + return base; +} + +/** + * Retrieves the top, visible window at the given location. + * @param x The given X position. + * @param y The given Y position. + * @return The window at that position. + * @ingroup Ecore_X_Window_Geometry_Group + */ +Ecore_X_Window +ecore_x_window_at_xy_get(int x, int y) +{ + Ecore_X_Window win, root; + + /* FIXME: Proper function to determine current root/virtual root + * window missing here */ + root = DefaultRootWindow(_ecore_x_disp); + + ecore_x_grab(); + win = _ecore_x_window_at_xy_get(root, 0, 0, x, y); + ecore_x_ungrab(); + + return win ? win : root; +} + +/** + * Retrieves the parent window of the given window. + * @param win The given window. + * @return The parent window of @p win. + * @ingroup Ecore_X_Window_Parent_Group + */ +Ecore_X_Window +ecore_x_window_parent_get(Ecore_X_Window win) +{ + Window root, parent, *children = NULL; + unsigned int num; + + if (!XQueryTree(_ecore_x_disp, win, &root, &parent, &children, &num)) + return 0; + if (children) + XFree(children); + + return parent; +} + +/** + * Sets the background color of the given window. + * @param win The given window + * @param color The color to set to (i.e. 0xff0000) + */ +void +ecore_x_window_background_color_set(Ecore_X_Window win, unsigned short r, + unsigned short g, unsigned short b) +{ + XSetWindowAttributes attr; + XColor col; + + col.red = r; + col.green = g; + col.blue = b; + + XAllocColor(_ecore_x_disp, DefaultColormap(_ecore_x_disp, + DefaultScreen(_ecore_x_disp)), + &col); + + attr.background_pixel = col.pixel; + XChangeWindowAttributes(_ecore_x_disp, win, CWBackPixel, &attr); +} + +void +ecore_x_window_gravity_set(Ecore_X_Window win, Ecore_X_Gravity grav) +{ + XSetWindowAttributes att; + + att.win_gravity = grav; + XChangeWindowAttributes(_ecore_x_disp, win, CWWinGravity, &att); +} + +void +ecore_x_window_pixel_gravity_set(Ecore_X_Window win, Ecore_X_Gravity grav) +{ + XSetWindowAttributes att; + + att.bit_gravity = grav; + XChangeWindowAttributes(_ecore_x_disp, win, CWBitGravity, &att); +} + +void +ecore_x_window_pixmap_set(Ecore_X_Window win, Ecore_X_Pixmap pmap) +{ + XSetWindowBackgroundPixmap(_ecore_x_disp, win, pmap); +} + +void +ecore_x_window_area_clear(Ecore_X_Window win, int x, int y, int w, int h) +{ + XClearArea(_ecore_x_disp, win, x, y, w, h, False); +} + +void +ecore_x_window_area_expose(Ecore_X_Window win, int x, int y, int w, int h) +{ + XClearArea(_ecore_x_disp, win, x, y, w, h, True); +} diff --git a/ecore/src/lib/ecore_x/ecore_x_window_prop.c b/ecore/src/lib/ecore_x/ecore_x_window_prop.c new file mode 100644 index 0000000..1c45607 --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_window_prop.c @@ -0,0 +1,342 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" +#include +#include + +#define _ATOM_SET_CARD32(win, atom, p_val, cnt) \ + XChangeProperty(_ecore_x_disp, win, atom, XA_CARDINAL, 32, PropModeReplace, \ + (unsigned char *)p_val, cnt) + +/* + * Set CARD32 (array) property + */ +void +ecore_x_window_prop_card32_set(Ecore_X_Window win, Ecore_X_Atom atom, + unsigned int *val, unsigned int num) +{ +#if SIZEOF_INT == 4 + _ATOM_SET_CARD32(win, atom, val, num); +#else + CARD32 *c32; + unsigned int i; + + c32 = malloc(num * sizeof(CARD32)); + if (!c32) + return; + for (i = 0; i < num; i++) + c32[i] = val[i]; + _ATOM_SET_CARD32(win, atom, c32, num); + free(c32); +#endif +} + +/* + * Get CARD32 (array) property + * + * At most len items are returned in val. + * If the property was successfully fetched the number of items stored in + * val is returned, otherwise -1 is returned. + * Note: Return value 0 means that the property exists but has no elements. + */ +int +ecore_x_window_prop_card32_get(Ecore_X_Window win, Ecore_X_Atom atom, + unsigned int *val, unsigned int len) +{ + unsigned char *prop_ret; + Atom type_ret; + unsigned long bytes_after, num_ret; + int format_ret; + unsigned int i; + int num; + + prop_ret = NULL; + XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False, + XA_CARDINAL, &type_ret, &format_ret, &num_ret, + &bytes_after, &prop_ret); + if (prop_ret && type_ret == XA_CARDINAL && format_ret == 32) + { + if (num_ret < len) + len = num_ret; + for (i = 0; i < len; i++) + val[i] = ((unsigned long *)prop_ret)[i]; + num = len; + } + else + { + num = -1; + } + if (prop_ret) + XFree(prop_ret); + + return num; +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +Ecore_X_Atom +ecore_x_window_prop_any_type(void) +{ + return AnyPropertyType; +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +void +ecore_x_window_prop_property_set(Ecore_X_Window win, Ecore_X_Atom property, Ecore_X_Atom type, int size, void *data, int number) +{ + if (win == 0) win = DefaultRootWindow(_ecore_x_disp); + if (size != 32) + XChangeProperty(_ecore_x_disp, win, property, type, size, PropModeReplace, + (unsigned char *)data, number); + else + { + unsigned long *dat; + int i, *ptr; + + dat = malloc(sizeof(unsigned long) * number); + if (dat) + { + for (ptr = (int *)data, i = 0; i < number; i++) dat[i] = ptr[i]; + XChangeProperty(_ecore_x_disp, win, property, type, size, + PropModeReplace, (unsigned char *)dat, number); + free(dat); + } + } +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +int +ecore_x_window_prop_property_get(Ecore_X_Window win, Ecore_X_Atom property, Ecore_X_Atom type, int size, unsigned char **data, int *num) +{ + Atom type_ret = 0; + int ret, size_ret = 0; + unsigned long num_ret = 0, bytes = 0, i; + unsigned char *prop_ret = NULL; + + /* make sure these are initialized */ + if (num) *num = 0; + + if (data) + *data = NULL; + else /* we can't store the retrieved data, so just return */ + return 0; + + if (!win) win = DefaultRootWindow(_ecore_x_disp); + + ret = XGetWindowProperty(_ecore_x_disp, win, property, 0, LONG_MAX, + False, type, &type_ret, &size_ret, + &num_ret, &bytes, &prop_ret); + + if (ret != Success) + return 0; + + if (size != size_ret || !num_ret) { + XFree(prop_ret); + return 0; + } + + if (!(*data = malloc(num_ret * size / 8))) { + XFree(prop_ret); + return 0; + } + + switch (size) { + case 8: + for (i = 0; i < num_ret; i++) + (*data)[i] = prop_ret[i]; + break; + case 16: + for (i = 0; i < num_ret; i++) + ((uint16_t *) *data)[i] = ((uint16_t *) prop_ret)[i]; + break; + case 32: + for (i = 0; i < num_ret; i++) + ((uint32_t *) *data)[i] = ((uint32_t *) prop_ret)[i]; + break; + } + + XFree(prop_ret); + + if (num) *num = num_ret; + return 1; +} + +void +ecore_x_window_prop_property_del(Ecore_X_Window win, Ecore_X_Atom property) +{ + XDeleteProperty(_ecore_x_disp, win, property); +} + +Ecore_X_Atom * +ecore_x_window_prop_list(Ecore_X_Window win, int *num_ret) +{ + Ecore_X_Atom *atoms; + Atom *atom_ret; + int num = 0, i; + + if (num_ret) *num_ret = 0; + + atom_ret = XListProperties(_ecore_x_disp, win, &num); + if (!atom_ret) return NULL; + + atoms = malloc(num * sizeof(Ecore_X_Atom)); + if (atoms) + { + for (i = 0; i < num; i++) atoms[i] = atom_ret[i]; + if (num_ret) *num_ret = num; + } + XFree(atom_ret); + return atoms; +} + +/** + * Set a window string property. + * @param win The window + * @param type The property + * @param str The string + * + * Set a window string property + */ +void +ecore_x_window_prop_string_set(Ecore_X_Window win, Ecore_X_Atom type, const char *str) +{ + XTextProperty xtp; + + if (win == 0) win = DefaultRootWindow(_ecore_x_disp); + xtp.value = (unsigned char *)str; + xtp.format = 8; + xtp.encoding = ECORE_X_ATOM_UTF8_STRING; + xtp.nitems = strlen(str); + XSetTextProperty(_ecore_x_disp, win, &xtp, type); +} + +/** + * Get a window string property. + * @param win The window + * @param type The property + * + * Return window string property of a window. String must be free'd when done. + */ +char * +ecore_x_window_prop_string_get(Ecore_X_Window win, Ecore_X_Atom type) +{ + XTextProperty xtp; + char *str = NULL; + + if (win == 0) win = DefaultRootWindow(_ecore_x_disp); + if (XGetTextProperty(_ecore_x_disp, win, &xtp, type)) + { + int items; + char **list = NULL; + Status s; + + if (xtp.encoding == ECORE_X_ATOM_UTF8_STRING) + { + str = strdup((char *)xtp.value); + } + else + { +#ifdef X_HAVE_UTF8_STRING + s = Xutf8TextPropertyToTextList(_ecore_x_disp, &xtp, + &list, &items); +#else + s = XmbTextPropertyToTextList(_ecore_x_disp, &xtp, + &list, &items); +#endif + if ((s == XLocaleNotSupported) || + (s == XNoMemory) || (s == XConverterNotFound)) + { + str = strdup((char *)xtp.value); + } + else if ((s >= Success) && (items > 0)) + { + str = strdup(list[0]); + } + if (list) + XFreeStringList(list); + } + XFree(xtp.value); + } + return str; +} + +int +ecore_x_window_prop_protocol_isset(Ecore_X_Window win, + Ecore_X_WM_Protocol protocol) +{ + Atom proto, *protos = NULL; + int i, ret = 0, protos_count = 0; + + /* check for invalid values */ + if (protocol >= ECORE_X_WM_PROTOCOL_NUM) + return 0; + + proto = _ecore_x_atoms_wm_protocols[protocol]; + + if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count)) + return ret; + + for (i = 0; i < protos_count; i++) + if (protos[i] == proto) + { + ret = 1; + break; + } + + XFree(protos); + + return ret; +} + +/** + * To be documented. + * + * FIXME: To be fixed. + */ +Ecore_X_WM_Protocol * +ecore_x_window_prop_protocol_list_get(Ecore_X_Window win, int *num_ret) +{ + Atom *protos = NULL; + int i, protos_count = 0; + Ecore_X_WM_Protocol *prot_ret = NULL; + + if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count)) + return NULL; + + if ((!protos) || (protos_count <= 0)) return NULL; + prot_ret = calloc(1, protos_count * sizeof(Ecore_X_WM_Protocol)); + if (!prot_ret) + { + XFree(protos); + return NULL; + } + for (i = 0; i < protos_count; i++) + { + Ecore_X_WM_Protocol j; + + prot_ret[i] = -1; + for (j = 0; j < ECORE_X_WM_PROTOCOL_NUM; j++) + { + if (_ecore_x_atoms_wm_protocols[j] == protos[i]) + prot_ret[i] = j; + } + } + XFree(protos); + *num_ret = protos_count; + return prot_ret; +} diff --git a/ecore/src/lib/ecore_x/ecore_x_window_shape.c b/ecore/src/lib/ecore_x/ecore_x_window_shape.c new file mode 100644 index 0000000..27ea707 --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_window_shape.c @@ -0,0 +1,159 @@ +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" + +/** + * @defgroup Ecore_X_Window_Shape X Window Shape Functions + * + * These functions use the shape extension of the X server to change + * shape of given windows. + */ + +/** + * Sets the shape of the given window to that given by the pixmap @p mask. + * @param win The given window. + * @param mask A 2-bit depth pixmap that provides the new shape of the + * window. + * @ingroup Ecore_X_Window_Shape + */ +void +ecore_x_window_shape_mask_set(Ecore_X_Window win, Ecore_X_Pixmap mask) +{ + XShapeCombineMask(_ecore_x_disp, win, ShapeBounding, 0, 0, mask, ShapeSet); +} + +void +ecore_x_window_shape_window_set(Ecore_X_Window win, Ecore_X_Window shape_win) +{ + XShapeCombineShape(_ecore_x_disp, win, ShapeBounding, 0, 0, shape_win, ShapeBounding, ShapeSet); +} + +void +ecore_x_window_shape_window_set_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y) +{ + XShapeCombineShape(_ecore_x_disp, win, ShapeBounding, x, y, shape_win, ShapeBounding, ShapeSet); +} + +void +ecore_x_window_shape_rectangle_set(Ecore_X_Window win, int x, int y, int w, int h) +{ + XRectangle rect; + + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeSet, Unsorted); +} + +void +ecore_x_window_shape_rectangles_set(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num) +{ + XRectangle *rect = NULL; + int i; + + if (num > 0) + { + rect = alloca(sizeof(XRectangle) * num); + for (i = 0; i < num; i++) + { + rect[i].x = rects[i].x; + rect[i].y = rects[i].y; + rect[i].width = rects[i].width; + rect[i].height = rects[i].height; + } + } + XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, rect, num, ShapeSet, Unsorted); +} + +void +ecore_x_window_shape_window_add(Ecore_X_Window win, Ecore_X_Window shape_win) +{ + XShapeCombineShape(_ecore_x_disp, win, ShapeBounding, 0, 0, shape_win, ShapeBounding, ShapeUnion); +} + +void +ecore_x_window_shape_window_add_xy(Ecore_X_Window win, Ecore_X_Window shape_win, int x, int y) +{ + XShapeCombineShape(_ecore_x_disp, win, ShapeBounding, x, y, shape_win, ShapeBounding, ShapeUnion); +} + +void +ecore_x_window_shape_rectangle_add(Ecore_X_Window win, int x, int y, int w, int h) +{ + XRectangle rect; + + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeUnion, Unsorted); +} + +void +ecore_x_window_shape_rectangle_clip(Ecore_X_Window win, int x, int y, int w, int h) +{ + XRectangle rect; + + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, &rect, 1, ShapeIntersect, Unsorted); +} + +void +ecore_x_window_shape_rectangles_add(Ecore_X_Window win, Ecore_X_Rectangle *rects, int num) +{ + XRectangle *rect = NULL; + int i; + + if (num > 0) + { + rect = alloca(sizeof(XRectangle) * num); + for (i = 0; i < num; i++) + { + rect[i].x = rects[i].x; + rect[i].y = rects[i].y; + rect[i].width = rects[i].width; + rect[i].height = rects[i].height; + } + } + XShapeCombineRectangles(_ecore_x_disp, win, ShapeBounding, 0, 0, rect, num, ShapeUnion, Unsorted); +} + +Ecore_X_Rectangle * +ecore_x_window_shape_rectangles_get(Ecore_X_Window win, int *num_ret) +{ + XRectangle *rect; + Ecore_X_Rectangle *rects = NULL; + int i, num = 0, ord; + + rect = XShapeGetRectangles(_ecore_x_disp, win, ShapeBounding, &num, &ord); + if (rect) + { + rects = malloc(sizeof(Ecore_X_Rectangle) * num); + if (rects) + { + for (i = 0; i < num; i++) + { + rects[i].x = rect[i].x; + rects[i].y = rect[i].y; + rects[i].width = rect[i].width; + rects[i].height = rect[i].height; + } + } + XFree(rect); + } + if (num_ret) *num_ret = num; + return rects; +} + +void +ecore_x_window_shape_events_select(Ecore_X_Window win, int on) +{ + if (on) + XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask); + else + XShapeSelectInput(_ecore_x_disp, win, 0); +} diff --git a/ecore/src/lib/ecore_x/ecore_x_xinerama.c b/ecore/src/lib/ecore_x/ecore_x_xinerama.c new file mode 100644 index 0000000..d26d8aa --- /dev/null +++ b/ecore/src/lib/ecore_x/ecore_x_xinerama.c @@ -0,0 +1,54 @@ +/* + * Xinerama code + */ +#include "Ecore.h" +#include "ecore_x_private.h" +#include "Ecore_X.h" +#include "Ecore_X_Atoms.h" + +#ifdef ECORE_XINERAMA +static XineramaScreenInfo *_xin_info = NULL; +static int _xin_scr_num = 0; +#endif + +int +ecore_x_xinerama_screen_count_get(void) +{ +#ifdef ECORE_XINERAMA + if (_xin_info) XFree(_xin_info); + _xin_info = NULL; + _xin_info = XineramaQueryScreens(_ecore_x_disp, &_xin_scr_num); + if (_xin_info) return _xin_scr_num; + else return 0; +#else + return 0; +#endif +} + +int +ecore_x_xinerama_screen_geometry_get(int screen, int *x, int *y, int *w, int *h) +{ +#ifdef ECORE_XINERAMA + if (_xin_info) + { + int i; + + for (i = 0; i < _xin_scr_num; i++) + { + if (_xin_info[i].screen_number == screen) + { + if (x) *x = _xin_info[i].x_org; + if (y) *y = _xin_info[i].y_org; + if (w) *w = _xin_info[i].width; + if (h) *h = _xin_info[i].height; + return 1; + } + } + } +#endif + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = DisplayWidth(_ecore_x_disp, 0); + if (h) *h = DisplayHeight(_ecore_x_disp, 0); + return 0; +} -- cgit v1.2.3