From c8e8e816d23e4c9f4434d25038c26ff5bb52feb9 Mon Sep 17 00:00:00 2001 From: Jinkun Jang Date: Wed, 13 Mar 2013 01:53:14 +0900 Subject: [PATCH] Tizen 2.1 base --- AUTHORS | 13 +- COPYING | 45 +- ChangeLog | 96 +- Makefile.am | 55 +- NEWS | 26 + README | 23 +- TC/README | 14 + TC/_export_env.sh | 40 + TC/build.sh | 23 + TC/clean.sh | 11 + TC/emotion/common.h | 65 + TC/emotion/emotion_private.h | 130 + TC/emotion/test.avi | Bin 0 -> 474982 bytes TC/emotion/tslist | 56 + TC/emotion/utc_UIFW_emotion_audio_level_change.c | 37 + TC/emotion/utc_UIFW_emotion_channels_change.c | 37 + TC/emotion/utc_UIFW_emotion_decode_stop.c | 37 + TC/emotion/utc_UIFW_emotion_file_ref_set.c | 37 + TC/emotion/utc_UIFW_emotion_frame_new.c | 37 + TC/emotion/utc_UIFW_emotion_frame_refill.c | 51 + TC/emotion/utc_UIFW_emotion_frame_resize.c | 51 + TC/emotion/utc_UIFW_emotion_init.c | 29 + TC/emotion/utc_UIFW_emotion_module_register.c | 54 + TC/emotion/utc_UIFW_emotion_module_unregister.c | 55 + TC/emotion/utc_UIFW_emotion_object_add.c | 45 + .../utc_UIFW_emotion_object_audio_channel_count.c | 41 + .../utc_UIFW_emotion_object_audio_mute_set_get.c | 60 + .../utc_UIFW_emotion_object_audio_volume_set_get.c | 63 + TC/emotion/utc_UIFW_emotion_object_bg_color_set.c | 65 + TC/emotion/utc_UIFW_emotion_object_border_set.c | 63 + .../utc_UIFW_emotion_object_event_simple_send.c | 39 + TC/emotion/utc_UIFW_emotion_object_file_set_get.c | 76 + TC/emotion/utc_UIFW_emotion_object_image_get.c | 41 + TC/emotion/utc_UIFW_emotion_object_init.c | 70 + .../utc_UIFW_emotion_object_keep_aspect_set.c | 59 + ...c_UIFW_emotion_object_last_position_save_load.c | 47 + TC/emotion/utc_UIFW_emotion_object_meta_info_get.c | 52 + .../utc_UIFW_emotion_object_module_option_set.c | 50 + .../utc_UIFW_emotion_object_play_length_get.c | 43 + TC/emotion/utc_UIFW_emotion_object_play_set_get.c | 63 + .../utc_UIFW_emotion_object_play_speed_set_get.c | 45 + .../utc_UIFW_emotion_object_position_set_get.c | 45 + .../utc_UIFW_emotion_object_progress_info_get.c | 42 + .../utc_UIFW_emotion_object_progress_status_get.c | 46 + TC/emotion/utc_UIFW_emotion_object_ratio_get.c | 43 + TC/emotion/utc_UIFW_emotion_object_ref_file_get.c | 42 + TC/emotion/utc_UIFW_emotion_object_ref_num_get.c | 41 + TC/emotion/utc_UIFW_emotion_object_seekable_get.c | 41 + TC/emotion/utc_UIFW_emotion_object_size_get.c | 46 + .../utc_UIFW_emotion_object_smooth_scale_set.c | 42 + .../utc_UIFW_emotion_object_spu_button_count_get.c | 41 + .../utc_UIFW_emotion_object_spu_button_get.c | 42 + .../utc_UIFW_emotion_object_spu_channel_count.c | 41 + TC/emotion/utc_UIFW_emotion_object_title_get.c | 41 + .../utc_UIFW_emotion_object_video_channel_count.c | 41 + .../utc_UIFW_emotion_object_video_mute_set_get.c | 60 + TC/emotion/utc_UIFW_emotion_object_vis_set_get.c | 111 + TC/emotion/utc_UIFW_emotion_object_vis_supported.c | 68 + TC/emotion/utc_UIFW_emotion_open_done.c | 37 + TC/emotion/utc_UIFW_emotion_playback_finished.c | 37 + TC/emotion/utc_UIFW_emotion_playback_started.c | 37 + TC/emotion/utc_UIFW_emotion_progress_set.c | 37 + TC/emotion/utc_UIFW_emotion_seek_done.c | 37 + TC/emotion/utc_UIFW_emotion_shutdown.c | 31 + TC/emotion/utc_UIFW_emotion_spu_button_num_set.c | 37 + TC/emotion/utc_UIFW_emotion_spu_button_set.c | 37 + TC/emotion/utc_UIFW_emotion_title_set.c | 37 + TC/emotion/utc_UIFW_emotion_video_get.c | 42 + TC/emotion/utc_UIFW_emotion_video_pos_update.c | 48 + TC/emotion/utc_UIFW_emotion_webcam_custom_get.c | 47 + TC/execute.sh | 17 + TC/tet_scen | 8 + TC/tetbuild.cfg | 5 + TC/tetclean.cfg | 5 + TC/tetexec.cfg | 5 + autogen.sh | 25 +- configure.ac | 370 ++ data/Makefile.am | 26 +- data/e_logo.png | Bin 46481 -> 7833 bytes data/icon.edc | 14 + data/theme.edc | 497 ++- debian/changelog | 99 + debian/compat | 1 + debian/control | 42 +- debian/libemotion0-dev.install | 4 + debian/libemotion0-gstreamer.install | 1 + debian/libemotion0.install | 2 + debian/rules | 6 +- doc/Doxyfile.in | 138 + doc/Makefile.am | 33 + doc/e.css | 428 +- doc/examples.dox | 104 + doc/foot.html | 20 +- doc/head.html | 105 +- doc/img/e.png | Bin 0 -> 30052 bytes doc/img/edoxy.css | 486 +++ doc/img/emotion_ratio.eps | 4541 ++++++++++++++++++++ doc/img/emotion_ratio.png | Bin 0 -> 12950 bytes doc/img/foot_bg.png | Bin 0 -> 173 bytes doc/img/head_bg.png | Bin 0 -> 214 bytes doc/img/header_menu_background.png | Bin 0 -> 192 bytes doc/img/header_menu_background_last.png | Bin 0 -> 637 bytes doc/img/header_menu_current_background.png | Bin 0 -> 1200 bytes doc/img/header_menu_unselected_background.png | Bin 0 -> 1596 bytes doc/img/logo.png | Bin 0 -> 3825 bytes emotion-gstreamer.manifest | 5 + emotion.manifest | 5 + emotion.pc.in | 5 +- emotion.spec.in | 5 +- m4/ac_attribute.m4 | 46 + m4/efl_binary.m4 | 44 + m4/efl_doxygen.m4 | 94 + m4/efl_edje_external.m4 | 56 + m4/efl_examples.m4 | 63 + m4/efl_shm_open.m4 | 69 + m4/emotion_check.m4 | 216 + packaging/emotion.spec | 107 + src/Makefile.am | 10 +- src/bin/Makefile.am | 24 +- src/bin/emotion_test_main.c | 611 ++- src/edje_external/Makefile.am | 18 + src/edje_external/emotion.c | 516 +++ src/examples/Makefile.am | 39 + src/examples/emotion_basic_example.c | 81 + src/examples/emotion_border_example.c | 238 + src/examples/emotion_generic_example.c | 233 + src/examples/emotion_signals_example.c | 173 + src/generic_players/Makefile.am | 8 + src/generic_players/vlc/Makefile.am | 18 + src/generic_players/vlc/emotion_generic_vlc.c | 873 ++++ src/lib/Emotion.h | 1255 +++++- src/lib/Makefile.am | 58 +- src/lib/emotion_main.c | 484 +++ src/lib/emotion_private.h | 72 +- src/lib/emotion_smart.c | 1579 +++++-- src/modules/Makefile.am | 2 +- src/modules/generic/Emotion_Generic_Plugin.h | 144 + src/modules/generic/Makefile.am | 31 + src/modules/generic/README | 79 + src/modules/generic/emotion_generic.c | 1794 ++++++++ src/modules/generic/emotion_generic.h | 112 + src/modules/gstreamer/Makefile.am | 34 +- src/modules/gstreamer/emotion_alloc.c | 91 + src/modules/gstreamer/emotion_convert.c | 252 ++ src/modules/gstreamer/emotion_fakeeos.c | 71 + src/modules/gstreamer/emotion_gstreamer.c | 2020 ++++++--- src/modules/gstreamer/emotion_gstreamer.h | 313 +- src/modules/gstreamer/emotion_sink.c | 1391 ++++++ src/modules/xine/Makefile.am | 17 +- src/modules/xine/emotion_xine.c | 398 +- src/modules/xine/emotion_xine.h | 20 +- src/modules/xine/emotion_xine_vo_out.c | 145 +- 152 files changed, 21967 insertions(+), 2175 deletions(-) create mode 100644 TC/README create mode 100755 TC/_export_env.sh create mode 100755 TC/build.sh create mode 100755 TC/clean.sh create mode 100644 TC/emotion/common.h create mode 100644 TC/emotion/emotion_private.h create mode 100644 TC/emotion/test.avi create mode 100644 TC/emotion/tslist create mode 100644 TC/emotion/utc_UIFW_emotion_audio_level_change.c create mode 100644 TC/emotion/utc_UIFW_emotion_channels_change.c create mode 100644 TC/emotion/utc_UIFW_emotion_decode_stop.c create mode 100644 TC/emotion/utc_UIFW_emotion_file_ref_set.c create mode 100644 TC/emotion/utc_UIFW_emotion_frame_new.c create mode 100644 TC/emotion/utc_UIFW_emotion_frame_refill.c create mode 100644 TC/emotion/utc_UIFW_emotion_frame_resize.c create mode 100644 TC/emotion/utc_UIFW_emotion_init.c create mode 100644 TC/emotion/utc_UIFW_emotion_module_register.c create mode 100644 TC/emotion/utc_UIFW_emotion_module_unregister.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_add.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_audio_channel_count.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_audio_mute_set_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_audio_volume_set_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_bg_color_set.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_border_set.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_event_simple_send.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_file_set_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_image_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_init.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_keep_aspect_set.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_last_position_save_load.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_meta_info_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_module_option_set.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_play_length_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_play_set_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_play_speed_set_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_position_set_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_progress_info_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_progress_status_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_ratio_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_ref_file_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_ref_num_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_seekable_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_size_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_smooth_scale_set.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_spu_button_count_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_spu_button_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_spu_channel_count.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_title_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_video_channel_count.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_video_mute_set_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_vis_set_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_object_vis_supported.c create mode 100644 TC/emotion/utc_UIFW_emotion_open_done.c create mode 100644 TC/emotion/utc_UIFW_emotion_playback_finished.c create mode 100644 TC/emotion/utc_UIFW_emotion_playback_started.c create mode 100644 TC/emotion/utc_UIFW_emotion_progress_set.c create mode 100644 TC/emotion/utc_UIFW_emotion_seek_done.c create mode 100644 TC/emotion/utc_UIFW_emotion_shutdown.c create mode 100644 TC/emotion/utc_UIFW_emotion_spu_button_num_set.c create mode 100644 TC/emotion/utc_UIFW_emotion_spu_button_set.c create mode 100644 TC/emotion/utc_UIFW_emotion_title_set.c create mode 100644 TC/emotion/utc_UIFW_emotion_video_get.c create mode 100644 TC/emotion/utc_UIFW_emotion_video_pos_update.c create mode 100644 TC/emotion/utc_UIFW_emotion_webcam_custom_get.c create mode 100755 TC/execute.sh create mode 100644 TC/tet_scen create mode 100755 TC/tetbuild.cfg create mode 100755 TC/tetclean.cfg create mode 100755 TC/tetexec.cfg create mode 100644 configure.ac create mode 100644 data/icon.edc create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/libemotion0-dev.install create mode 100644 debian/libemotion0-gstreamer.install mode change 100644 => 100755 debian/rules create mode 100644 doc/Doxyfile.in create mode 100644 doc/Makefile.am create mode 100644 doc/examples.dox create mode 100644 doc/img/e.png create mode 100644 doc/img/edoxy.css create mode 100644 doc/img/emotion_ratio.eps create mode 100644 doc/img/emotion_ratio.png create mode 100644 doc/img/foot_bg.png create mode 100644 doc/img/head_bg.png create mode 100644 doc/img/header_menu_background.png create mode 100644 doc/img/header_menu_background_last.png create mode 100644 doc/img/header_menu_current_background.png create mode 100644 doc/img/header_menu_unselected_background.png create mode 100644 doc/img/logo.png create mode 100644 emotion-gstreamer.manifest create mode 100644 emotion.manifest create mode 100644 m4/ac_attribute.m4 create mode 100644 m4/efl_binary.m4 create mode 100644 m4/efl_doxygen.m4 create mode 100644 m4/efl_edje_external.m4 create mode 100644 m4/efl_examples.m4 create mode 100644 m4/efl_shm_open.m4 create mode 100644 m4/emotion_check.m4 create mode 100644 packaging/emotion.spec create mode 100644 src/edje_external/Makefile.am create mode 100644 src/edje_external/emotion.c create mode 100644 src/examples/Makefile.am create mode 100644 src/examples/emotion_basic_example.c create mode 100644 src/examples/emotion_border_example.c create mode 100644 src/examples/emotion_generic_example.c create mode 100644 src/examples/emotion_signals_example.c create mode 100644 src/generic_players/Makefile.am create mode 100644 src/generic_players/vlc/Makefile.am create mode 100644 src/generic_players/vlc/emotion_generic_vlc.c create mode 100644 src/lib/emotion_main.c create mode 100644 src/modules/generic/Emotion_Generic_Plugin.h create mode 100644 src/modules/generic/Makefile.am create mode 100644 src/modules/generic/README create mode 100644 src/modules/generic/emotion_generic.c create mode 100644 src/modules/generic/emotion_generic.h create mode 100644 src/modules/gstreamer/emotion_alloc.c create mode 100644 src/modules/gstreamer/emotion_convert.c create mode 100644 src/modules/gstreamer/emotion_fakeeos.c create mode 100644 src/modules/gstreamer/emotion_sink.c diff --git a/AUTHORS b/AUTHORS index 9ba33c3..c2579a8 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,3 +1,10 @@ -The Rasterman (Carsten Haitzler) -doursse (Vincent Torri) -captainigloo +Carsten Haitzler +Vincent Torri +Nicolas Aguirre +Sebastian Dransfeld +Cedric Bail +Rafael Antognolli +Jérôme Pinot +Pierre Le Magourou +Hugo Camboulive +Sohyun Kim diff --git a/COPYING b/COPYING index 474fcc5..aab8362 100644 --- a/COPYING +++ b/COPYING @@ -1,28 +1,25 @@ -Copyright (C) 2000 Carsten Haitzler and various contributors (see AUTHORS) +Copyright notice for Emotion: -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: +Copyright (C) 2004-2011 Carsten Haitzler and various contributors (see AUTHORS) -The above copyright notice and this permission notice shall be included in -all copies of the Software and its Copyright notices. In addition publicly -documented acknowledgment must be given that this software has been used if no -source code of this software is made available publicly. This includes -acknowledgments in either Copyright notices, Manuals, Publicity and Marketing -documents or any documentation provided with any product containing this -software. This License does not apply to any software that links to the -libraries provided by this software (statically or dynamically), but only to -the software provided. +All rights reserved. -Please see the COPYING.PLAIN for a plain-english explanation of this notice -and it's intent. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: -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. + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ChangeLog b/ChangeLog index e47b581..af65492 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,36 +1,60 @@ -2007-10-31 Vincent Torri - - * configure.in: - * src/bin/emotion_test_main.c: - * src/lib/Makefile.am: - * src/lib/emotion_private.h: - * src/lib/emotion_smart.c: - * src/modules/Makefile.am: - * src/modules/emotion_gstreamer.c: - Use ecore_plugin instead of dlfcn - The modules names are now "xine" and "gstreamer" (it's useless to add - the extension, as ecore_plugin does not need it). - Look for the modules in path that is pointed by the env variable - EMOTION_MODULES_DIR first. - Fix a leak in the gstreamer module - Remove some trailing spaces - Fix bug #223 - - add the support of URI playback. Minor fixes. - Fix bug #114 - -2007-09-01 Vincent Torri - - * src/modules/emotion_gstreamer.c: (em_file_open): - * src/modules/emotion_gstreamer_pipeline.c: (cb_handoff), - (emotion_pipeline_dvd_build), (emotion_pipeline_uri_build), - (emotion_pipeline_file_build), (_emotion_streams_sinks_get), - (_emotion_video_sink_fill), (_emotion_audio_sink_fill): - * src/modules/emotion_gstreamer_pipeline.h: - add the support of URI playback. Minor fixes. - Fix bug #114 - -Wed Mar 29 20:33:40 2006 Michael Jennings (mej) - -Xine plugins seem to no longer be built. ----------------------------------------------------------------------- +2012-04-26 Carsten Haitzler (The Rasterman) + + * 1.0.0 release + +2012-04-30 Jérôme Pinot + + * Fix build out of tree. + +2012-05-16 Carsten Haitzler (The Rasterman) + + * Fix emotion video overlay support to detect correct engine name. + +2012-06-05 Sohyun Kim + + * Add fimcconvert element to resize and convert color using fimc on device. + +2012-06-07 Cedric Bail + + * Fix stride for all YUV video stream. + +2012-06-08 Pierre Le Magourou + + * Add support for "playback_started" callback to generic player. + +2012-06-08 Hugo Camboulive + + * Implement SPU switch for generic/vlc. + +2012-06-19 Cedric Bail + + * Sync rendering with Ecore_Animator. + +2012-07-03 Cedric Bail + + * Track pending object for proper shutdown. + +2012-08-01 Cedric Bail + + * Fix race condition in gstreamer render function. + +2012-08-10 Sohyun Kim + + * Fix priority set/get for gstreamer. + +2012-08-28 Cedric Bail + + * Reset VLC pipeline on EOS. + * Fix a race condition on shutdown when still saving a file position. + +2012-08-30 Carsten Haitzler (The Rasterman) + + 1.7.0 release + +2012-09-06 Sohyun Kim + + * Add capsfilter to limit format and size for fimc on device. + +2012-10-11 Sohyun Kim + + * Fix to call correct render function based on the format. diff --git a/Makefile.am b/Makefile.am index 6d2fd00..248f9bd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,22 +2,51 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = src data +SUBDIRS = src data doc -MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess emotion.spec \ - config.h.in config.sub configure install-sh \ - ltconfig ltmain.sh missing mkinstalldirs \ - stamp-h.in emotion_docs.tar emotion_docs.tar.gz \ - emotion.c acconfig.h debian/changelog depcomp +MAINTAINERCLEANFILES = \ +Makefile.in \ +aclocal.m4 \ +config.guess \ +config.h.in \ +config.sub \ +configure \ +depcomp \ +install-sh \ +ltconfig \ +ltmain.sh \ +missing \ +mkinstalldirs \ +stamp-h.in \ +$(PACKAGE_TARNAME)-$(PACKAGE_VERSION).tar.gz \ +$(PACKAGE_TARNAME)-$(PACKAGE_VERSION).tar.bz2 \ +$(PACKAGE_TARNAME)-$(PACKAGE_VERSION)-doc.tar.bz2 -bin_SCRIPTS = +EXTRA_DIST = \ +README \ +AUTHORS \ +COPYING \ +autogen.sh \ +emotion.spec \ +emotion.spec.in \ +emotion.pc.in \ +m4/ac_attribute.m4 \ +m4/efl_binary.m4 \ +m4/efl_doxygen.m4 \ +m4/efl_edje_external.m4 \ +m4/efl_examples.m4 \ +m4/efl_shm_open.m4 \ +m4/emotion_check.m4 \ +m4/gst-element-check.m4 -EXTRA_DIST = README AUTHORS COPYING COPYING-PLAIN \ - emotion.spec emotion.spec.in emotion.c.in gendoc Doxyfile \ - emotion.pc.in debian/changelog debian/control \ - debian/copyright debian/rules debian/libemotion0.install \ - debian/libemotion-dev.install debian/libemotion-bin.install \ - debian/libemotion-gstreamer.install debian/libemotion-xine.install pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = emotion.pc + +.PHONY: doc + +# Documentation + +doc: + @echo "entering doc/" + make -C doc doc diff --git a/NEWS b/NEWS index e69de29..7202b33 100644 --- a/NEWS +++ b/NEWS @@ -0,0 +1,26 @@ +Emotion 1.7.0 + +Changes since Emotion 1.0.0: +------------------------- + +Additions: + - Add support for "playback_started" callback to generic player. + - Implement SPU switch for generic/vlc. + - Sync rendering with Ecore_Animator. + - Track pending object for proper shutdown. + - Start handling embedded hardware customization. + - Add fimcconvert and capsfilter element for device + +Fixes: + - build out of tree. + - stride of all YUV video + - fix race condition in gstreamer render function on shutdown and file set. + - fix priority set/get for gstreamer. + - reset VLC pipeline on EOS. + - fix race condition on shutdown when still saving a file position. + - fix to call correct render function. + +Improvements: + +Removal: + diff --git a/README b/README index c64cc15..301dbaa 100644 --- a/README +++ b/README @@ -1 +1,22 @@ -Emotion 0.0.1 +Emotion 1.7.99 + +****************************************************************************** + + FOR ANY ISSUES PLEASE EMAIL: + enlightenment-devel@lists.sourceforge.net + +****************************************************************************** + +Emotion is a video (and audio) codec playback library that acts as a +front-end to libxine or gstreamer (or something else more generic) +that provides and evas object as a control object and video output +point. It makes using video API's much simpler and easier while it's +at it. + +------------------------------------------------------------------------------ +COMPILING AND INSTALLING: + + ./configure + make +(do this as root unless you are installing in your users directories): + make install diff --git a/TC/README b/TC/README new file mode 100644 index 0000000..d466648 --- /dev/null +++ b/TC/README @@ -0,0 +1,14 @@ +Before starting tests please set and export TET_ROOT_DIR variable. + +It's highly recommened to add similar line at the end of your + ~/.bashrc file: +export TET_ROOT_DIR=/full/path/to/tetware/dir + +Example: +If user with login test placed TETware in it's home directory +(/home/test/TETware contains tetware-simulator and tetware-target) +it should add following line to .bashrc file: + +export TET_ROOT_DIR=/home/test/TETware + +and restart terminal. diff --git a/TC/_export_env.sh b/TC/_export_env.sh new file mode 100755 index 0000000..4215842 --- /dev/null +++ b/TC/_export_env.sh @@ -0,0 +1,40 @@ +# Customize below path information +#TET_INSTALL_PATH=/scratchbox/TETware + +CURRENT_USER=`echo $HOME` +TET_INSTALL_PATH=$CURRENT_USER/sbs/TETware +# temporary fix for SPRC +if [ "$TET_ROOT_DIR" != "" ]; then + TET_INSTALL_PATH=$TET_ROOT_DIR +fi + +TET_SIMUL_PATH=$TET_INSTALL_PATH/tetware-simulator +TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target +TET_MOUNTED_PATH=/mnt/nfs/sbs/TETware/tetware-target +#TET_MOUNTED_PATH=/opt/home/root/tmp/sbs/TETware/tetware-target + +#MACHINE=`echo $SBOX_UNAME_MACHINE` + +MACHINE=`echo $DEB_BUILD_ARCH_ABI` + +if [ $MACHINE = "gnu" ] # SBS i386 +then + export ARCH=simulator + export TET_ROOT=$TET_SIMUL_PATH +elif [ $MACHINE = "gnueabi" ] # SBS ARM +then + export ARCH=target + export TET_ROOT=$TET_TARGET_PATH +else + export ARCH=target + export TET_ROOT=$TET_MOUNTED_PATH +fi + +export PATH=$TET_ROOT/bin:$PATH +export LD_LIBRARY_PATH=$TET_ROOT/lib/tet3:$LD_LIBRARY_PATH + +set $(pwd) +export TET_SUITE_ROOT=$1 + +set $(date +%y%m%d_%H%M%S) +FILE_NAME_EXTENSION=$1 diff --git a/TC/build.sh b/TC/build.sh new file mode 100755 index 0000000..28a7d2a --- /dev/null +++ b/TC/build.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +. ./_export_env.sh # setting environment variables + +export TET_SUITE_ROOT=`pwd` +FILE_NAME_EXTENSION=`date +%s` + +RESULT_DIR=results +HTML_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.html +JOURNAL_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.journal + +mkdir -p $RESULT_DIR + +echo -e "#ifndef __CONFIG_H__\n""#define __CONFIG_H__\n""#define TC_PREFIX \"`pwd`/\"\n""#endif\n" > config.h + +edje_cc edje/data/edje_test.edc -id edje/data/images edje/data/edje_test.edj + +tcc -c -p ./ +tcc -b -j $JOURNAL_RESULT -p ./ +grw -c 7 -f chtml -o $HTML_RESULT $JOURNAL_RESULT + +rm config.h + diff --git a/TC/clean.sh b/TC/clean.sh new file mode 100755 index 0000000..e171e93 --- /dev/null +++ b/TC/clean.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. ./_export_env.sh # setting environment variables + +export TET_SUITE_ROOT=`pwd` +RESULT_DIR=results + +tcc -c -p ./ # executing tcc, with clean option (-c) +rm -r $RESULT_DIR +rm -r tet_tmp_dir +rm `find . -name tet_captured` diff --git a/TC/emotion/common.h b/TC/emotion/common.h new file mode 100644 index 0000000..1b4f989 --- /dev/null +++ b/TC/emotion/common.h @@ -0,0 +1,65 @@ +#ifndef _COMMON_H_ +#define _COMMON_H_ + +enum { + POSITIVE_TC_IDX = 0x01, + NEGATIVE_TC_IDX, + NULL_TC_IDX, +}; + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +void sigprocess(int sig) +{ + signal(SIGSEGV, SIG_DFL); + tet_printf("[TET_SEGFAULT]:: segmentation fault in file: %s", __FILE__); + tet_result(TET_FAIL); + raise(sig); +} + +static Ecore_Evas *ecore_evas; + +static void startup(void) +{ + tet_infoline("[[ TET_MSG ]]:: ============ Startup ============ "); + ecore_evas_init(); + ecore_evas = ecore_evas_buffer_new(100, 45); +} + +static void cleanup(void) +{ + tet_infoline("[[ TET_MSG ]]:: ============ Cleanup ============ "); + ecore_evas_shutdown(); +} + +static Eina_Bool +_exit_func(void *data) +{ + printf("\n\nExiting main loop\n"); + ecore_main_loop_quit(); + return EINA_FALSE; +} + +static Evas_Object *init(void) +{ + signal(SIGSEGV, sigprocess); + + ecore_timer_add(1.0, _exit_func, NULL); + + Evas *evas = ecore_evas_get(ecore_evas); + Evas_Object *object = emotion_object_add(evas); + emotion_object_init(object, NULL/*"gstreamer"*/); + emotion_object_file_set(object, "test.avi"); + + evas_object_move(object, 0, 0); + evas_object_resize(object, 100, 100); + evas_object_show(object); + + return object; +} + +#endif diff --git a/TC/emotion/emotion_private.h b/TC/emotion/emotion_private.h new file mode 100644 index 0000000..6595436 --- /dev/null +++ b/TC/emotion/emotion_private.h @@ -0,0 +1,130 @@ +#ifndef EMOTION_PRIVATE_H +#define EMOTION_PRIVATE_H + +#define META_TRACK_TITLE 1 +#define META_TRACK_ARTIST 2 +#define META_TRACK_GENRE 3 +#define META_TRACK_COMMENT 4 +#define META_TRACK_ALBUM 5 +#define META_TRACK_YEAR 6 +#define META_TRACK_DISCID 7 +#define META_TRACK_COUNT 8 + +typedef enum _Emotion_Format Emotion_Format; +typedef struct _Emotion_Video_Module Emotion_Video_Module; +typedef struct _Emotion_Module_Options Emotion_Module_Options; +typedef struct _Eina_Emotion_Plugins Eina_Emotion_Plugins; + +typedef Eina_Bool (*Emotion_Module_Open)(Evas_Object *, const Emotion_Video_Module **, void **, Emotion_Module_Options *); +typedef void (*Emotion_Module_Close)(Emotion_Video_Module *module, void *); + +enum _Emotion_Format +{ + EMOTION_FORMAT_NONE, + EMOTION_FORMAT_I420, + EMOTION_FORMAT_YV12, + EMOTION_FORMAT_YUY2, /* unused for now since evas does not support yuy2 format */ + EMOTION_FORMAT_BGRA +}; + +struct _Emotion_Module_Options +{ + const char *player; + Eina_Bool no_video : 1; + Eina_Bool no_audio : 1; +}; + +struct _Eina_Emotion_Plugins +{ + Emotion_Module_Open open; + Emotion_Module_Close close; +}; + +struct _Emotion_Video_Module +{ + unsigned char (*init) (Evas_Object *obj, void **video, Emotion_Module_Options *opt); + int (*shutdown) (void *video); + unsigned char (*file_open) (const char *file, Evas_Object *obj, void *video); + void (*file_close) (void *ef); + void (*play) (void *ef, double pos); + void (*stop) (void *ef); + void (*size_get) (void *ef, int *w, int *h); + void (*pos_set) (void *ef, double pos); + double (*len_get) (void *ef); + int (*fps_num_get) (void *ef); + int (*fps_den_get) (void *ef); + double (*fps_get) (void *ef); + double (*pos_get) (void *ef); + void (*vis_set) (void *ef, Emotion_Vis vis); + Emotion_Vis (*vis_get) (void *ef); + Eina_Bool (*vis_supported) (void *ef, Emotion_Vis vis); + double (*ratio_get) (void *ef); + int (*video_handled) (void *ef); + int (*audio_handled) (void *ef); + int (*seekable) (void *ef); + void (*frame_done) (void *ef); + Emotion_Format (*format_get) (void *ef); + void (*video_data_size_get) (void *ef, int *w, int *h); + int (*yuv_rows_get) (void *ef, int w, int h, unsigned char **yrows, unsigned char **urows, unsigned char **vrows); + int (*bgra_data_get) (void *ef, unsigned char **bgra_data); + void (*event_feed) (void *ef, int event); + void (*event_mouse_button_feed) (void *ef, int button, int x, int y); + void (*event_mouse_move_feed) (void *ef, int x, int y); + int (*video_channel_count) (void *ef); + void (*video_channel_set) (void *ef, int channel); + int (*video_channel_get) (void *ef); + const char * (*video_channel_name_get) (void *ef, int channel); + void (*video_channel_mute_set) (void *ef, int mute); + int (*video_channel_mute_get) (void *ef); + int (*audio_channel_count) (void *ef); + void (*audio_channel_set) (void *ef, int channel); + int (*audio_channel_get) (void *ef); + const char * (*audio_channel_name_get) (void *ef, int channel); + void (*audio_channel_mute_set) (void *ef, int mute); + int (*audio_channel_mute_get) (void *ef); + void (*audio_channel_volume_set) (void *ef, double vol); + double (*audio_channel_volume_get) (void *ef); + int (*spu_channel_count) (void *ef); + void (*spu_channel_set) (void *ef, int channel); + int (*spu_channel_get) (void *ef); + const char * (*spu_channel_name_get) (void *ef, int channel); + void (*spu_channel_mute_set) (void *ef, int mute); + int (*spu_channel_mute_get) (void *ef); + int (*chapter_count) (void *ef); + void (*chapter_set) (void *ef, int chapter); + int (*chapter_get) (void *ef); + const char * (*chapter_name_get) (void *ef, int chapter); + void (*speed_set) (void *ef, double speed); + double (*speed_get) (void *ef); + int (*eject) (void *ef); + const char * (*meta_get) (void *ef, int meta); + void (*priority_set) (void *ef, Eina_Bool priority); + Eina_Bool (*priority_get) (void *ef); + + Eina_Emotion_Plugins *plugin; +}; + +EAPI void *_emotion_video_get(const Evas_Object *obj); +EAPI void _emotion_frame_new(Evas_Object *obj); +EAPI void _emotion_video_pos_update(Evas_Object *obj, double pos, double len); +EAPI void _emotion_frame_resize(Evas_Object *obj, int w, int h, double ratio); +EAPI void _emotion_frame_refill(Evas_Object *obj, double w, double h); +EAPI void _emotion_decode_stop(Evas_Object *obj); +EAPI void _emotion_open_done(Evas_Object *obj); +EAPI void _emotion_playback_started(Evas_Object *obj); +EAPI void _emotion_playback_finished(Evas_Object *obj); +EAPI void _emotion_audio_level_change(Evas_Object *obj); +EAPI void _emotion_channels_change(Evas_Object *obj); +EAPI void _emotion_title_set(Evas_Object *obj, char *title); +EAPI void _emotion_progress_set(Evas_Object *obj, char *info, double stat); +EAPI void _emotion_file_ref_set(Evas_Object *obj, const char *file, int num); +EAPI void _emotion_spu_button_num_set(Evas_Object *obj, int num); +EAPI void _emotion_spu_button_set(Evas_Object *obj, int button); +EAPI void _emotion_seek_done(Evas_Object *obj); + +EAPI Eina_Bool _emotion_module_register(const char *name, Emotion_Module_Open open, Emotion_Module_Close close); +EAPI Eina_Bool _emotion_module_unregister(const char *name); + +EAPI const char *emotion_webcam_custom_get(const char *device); + +#endif diff --git a/TC/emotion/test.avi b/TC/emotion/test.avi new file mode 100644 index 0000000000000000000000000000000000000000..b60a3d7cbc8aa972e1fdad2b9c5109bce15e2e71 GIT binary patch literal 474982 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�t{jxO9kvMY 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 U^7=>eff8PDQh(`el|KIe00DRq&;S4c literal 0 HcmV?d00001 diff --git a/TC/emotion/tslist b/TC/emotion/tslist new file mode 100644 index 0000000..f2fb627 --- /dev/null +++ b/TC/emotion/tslist @@ -0,0 +1,56 @@ +/emotion/utc_UIFW_emotion_object_add +/emotion/utc_UIFW_emotion_object_init +/emotion/utc_UIFW_emotion_object_file_set_get +/emotion/utc_UIFW_emotion_object_play_set_get +/emotion/utc_UIFW_emotion_object_position_set_get +/emotion/utc_UIFW_emotion_object_play_length_get +/emotion/utc_UIFW_emotion_object_ratio_get +/emotion/utc_UIFW_emotion_object_audio_mute_set_get +/emotion/utc_UIFW_emotion_object_module_option_set +/emotion/utc_UIFW_emotion_object_border_set +/emotion/utc_UIFW_emotion_object_bg_color_set +/emotion/utc_UIFW_emotion_object_keep_aspect_set +/emotion/utc_UIFW_emotion_object_seekable_get +/emotion/utc_UIFW_emotion_object_play_speed_set_get +/emotion/utc_UIFW_emotion_object_progress_status_get +/emotion/utc_UIFW_emotion_object_size_get +/emotion/utc_UIFW_emotion_object_smooth_scale_set +/emotion/utc_UIFW_emotion_object_audio_volume_set_get +/emotion/utc_UIFW_emotion_object_audio_channel_count +/emotion/utc_UIFW_emotion_object_video_mute_set_get +/emotion/utc_UIFW_emotion_object_video_channel_count +/emotion/utc_UIFW_emotion_object_spu_channel_count +/emotion/utc_UIFW_emotion_object_title_get +/emotion/utc_UIFW_emotion_object_ref_file_get +/emotion/utc_UIFW_emotion_object_ref_num_get +/emotion/utc_UIFW_emotion_object_spu_button_count_get +/emotion/utc_UIFW_emotion_object_spu_button_get +/emotion/utc_UIFW_emotion_object_meta_info_get +/emotion/utc_UIFW_emotion_object_vis_supported +/emotion/utc_UIFW_emotion_object_last_position_save_load +/emotion/utc_UIFW_emotion_object_image_get +/emotion/utc_UIFW_emotion_init +/emotion/utc_UIFW_emotion_shutdown +/emotion/utc_UIFW_emotion_video_get +/emotion/utc_UIFW_emotion_frame_new +/emotion/utc_UIFW_emotion_video_pos_update +/emotion/utc_UIFW_emotion_frame_resize +/emotion/utc_UIFW_emotion_frame_refill +/emotion/utc_UIFW_emotion_decode_stop +/emotion/utc_UIFW_emotion_open_done +/emotion/utc_UIFW_emotion_playback_started +/emotion/utc_UIFW_emotion_playback_finished +/emotion/utc_UIFW_emotion_audio_level_change +/emotion/utc_UIFW_emotion_channels_change +/emotion/utc_UIFW_emotion_title_set +/emotion/utc_UIFW_emotion_progress_set +/emotion/utc_UIFW_emotion_file_ref_set +/emotion/utc_UIFW_emotion_spu_button_num_set +/emotion/utc_UIFW_emotion_spu_button_set +/emotion/utc_UIFW_emotion_seek_done +/emotion/utc_UIFW_emotion_module_register +/emotion/utc_UIFW_emotion_module_unregister +/emotion/utc_UIFW_emotion_webcam_custom_get +/emotion/utc_UIFW_emotion_object_progress_info_get +/emotion/utc_UIFW_emotion_object_vis_set_get +/emotion/utc_UIFW_emotion_object_event_simple_send diff --git a/TC/emotion/utc_UIFW_emotion_audio_level_change.c b/TC/emotion/utc_UIFW_emotion_audio_level_change.c new file mode 100644 index 0000000..de4a19a --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_audio_level_change.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_audio_level_change_p(void); +static void utc_emotion_audio_level_change_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_audio_level_change_p, POSITIVE_TC_IDX}, + { utc_emotion_audio_level_change_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_audio_level_change_p(void) +{ + Evas_Object *object = init(); + _emotion_audio_level_change(object); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_audio_level_change_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_audio_level_change(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_channels_change.c b/TC/emotion/utc_UIFW_emotion_channels_change.c new file mode 100644 index 0000000..9956c83 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_channels_change.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_channels_change_p(void); +static void utc_emotion_channels_change_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_channels_change_p, POSITIVE_TC_IDX}, + { utc_emotion_channels_change_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_channels_change_p(void) +{ + Evas_Object *object = init(); + _emotion_channels_change(object); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_channels_change_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_channels_change(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_decode_stop.c b/TC/emotion/utc_UIFW_emotion_decode_stop.c new file mode 100644 index 0000000..01a63a9 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_decode_stop.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_decode_stop_p(void); +static void utc_emotion_decode_stop_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_decode_stop_p, POSITIVE_TC_IDX}, + { utc_emotion_decode_stop_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_decode_stop_p(void) +{ + Evas_Object *object = init(); + _emotion_decode_stop(object); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_decode_stop_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_decode_stop(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_file_ref_set.c b/TC/emotion/utc_UIFW_emotion_file_ref_set.c new file mode 100644 index 0000000..6831a47 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_file_ref_set.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_file_ref_set_p(void); +static void utc_emotion_file_ref_set_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_file_ref_set_p, POSITIVE_TC_IDX}, + { utc_emotion_file_ref_set_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_file_ref_set_p(void) +{ + Evas_Object *object = init(); + _emotion_file_ref_set(object, "test.avi", 3); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_file_ref_set_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_file_ref_set(NULL, NULL, -5); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_frame_new.c b/TC/emotion/utc_UIFW_emotion_frame_new.c new file mode 100644 index 0000000..ab8c131 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_frame_new.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include "emotion_private.h" +#include "common.h" + +static void utc_emotion_frame_new_p(void); +static void utc_emotion_frame_new_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_frame_new_p, POSITIVE_TC_IDX}, + { utc_emotion_frame_new_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_frame_new_p(void) +{ + Evas_Object *object = init(); + _emotion_frame_new(object); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_frame_new_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_frame_new(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_frame_refill.c b/TC/emotion/utc_UIFW_emotion_frame_refill.c new file mode 100644 index 0000000..4225ad3 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_frame_refill.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_frame_refill_p(void); +static void utc_emotion_frame_refill_n(void); +static void utc_emotion_frame_refill_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_frame_refill_p, POSITIVE_TC_IDX}, + { utc_emotion_frame_refill_n, NEGATIVE_TC_IDX}, + { utc_emotion_frame_refill_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_frame_refill_p(void) +{ + Evas_Object *object = init(); + _emotion_frame_refill(object, 5, 5); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_frame_refill_n(void) +{ + signal(SIGSEGV, sigprocess); + + Evas_Object *object = init(); + _emotion_frame_refill(object, -5, -5); + _emotion_frame_refill(object, 0, 0); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_frame_refill_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_frame_refill(NULL, 0, 0); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_frame_resize.c b/TC/emotion/utc_UIFW_emotion_frame_resize.c new file mode 100644 index 0000000..3350fa6 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_frame_resize.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_frame_resize_p(void); +static void utc_emotion_frame_resize_n(void); +static void utc_emotion_frame_resize_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_frame_resize_p, POSITIVE_TC_IDX}, + { utc_emotion_frame_resize_n, NEGATIVE_TC_IDX}, + { utc_emotion_frame_resize_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_frame_resize_p(void) +{ + Evas_Object *object = init(); + _emotion_frame_resize(object, 100, 200, 0.5); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_frame_resize_n(void) +{ + signal(SIGSEGV, sigprocess); + + Evas_Object *object = init(); + _emotion_frame_resize(object, -100, -200, 0.0); + _emotion_frame_resize(object, 0, 0, 0.0); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_frame_resize_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_frame_resize(NULL, 0, 0, 0.0); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_init.c b/TC/emotion/utc_UIFW_emotion_init.c new file mode 100644 index 0000000..1570acc --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_init.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_init_p(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_init_p, POSITIVE_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_init_p(void) +{ + Eina_Bool res = emotion_init(); + + if (EINA_FALSE == res) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_module_register.c b/TC/emotion/utc_UIFW_emotion_module_register.c new file mode 100644 index 0000000..92292ae --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_module_register.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_module_register_p(void); +static void utc_emotion_module_register_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_module_register_p, POSITIVE_TC_IDX}, + { utc_emotion_module_register_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static Eina_Bool +module_open(Evas_Object *obj, + const Emotion_Video_Module **module, + void **video, + Emotion_Module_Options *opt) +{ + tet_printf("module_open"); + return EINA_TRUE; +} + +static void +module_close(Emotion_Video_Module *module, + void *video) +{ + tet_printf("module_close"); +} + +static void utc_emotion_module_register_p(void) +{ + init(); + _emotion_module_register("gstreamer", module_open, module_close); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_module_register_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_module_register(NULL, NULL, NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_module_unregister.c b/TC/emotion/utc_UIFW_emotion_module_unregister.c new file mode 100644 index 0000000..a55f0f5 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_module_unregister.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_module_unregister_p(void); +static void utc_emotion_module_unregister_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_module_unregister_p, POSITIVE_TC_IDX}, + { utc_emotion_module_unregister_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static Eina_Bool +module_open(Evas_Object *obj, + const Emotion_Video_Module **module, + void **video, + Emotion_Module_Options *opt) +{ + tet_printf("module_open"); + return EINA_TRUE; +} + +static void +module_close(Emotion_Video_Module *module, + void *video) +{ + tet_printf("module_close"); +} + +static void utc_emotion_module_unregister_p(void) +{ + init(); + _emotion_module_register("gstreamer", module_open, module_close); + _emotion_module_unregister("gstreamer"); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_module_unregister_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_module_unregister(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_add.c b/TC/emotion/utc_UIFW_emotion_object_add.c new file mode 100644 index 0000000..5b4142a --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_add.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_add_p(void); +static void utc_emotion_object_add_n(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_add_p, POSITIVE_TC_IDX}, + { utc_emotion_object_add_n, NEGATIVE_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_add_p(void) +{ + Evas *evas = ecore_evas_get(ecore_evas); + Evas_Object *object = emotion_object_add(evas); + + if (NULL == object) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_add_n(void) +{ + signal(SIGSEGV, sigprocess); + + Evas_Object *object = emotion_object_add(NULL); + + if (NULL != object) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} diff --git a/TC/emotion/utc_UIFW_emotion_object_audio_channel_count.c b/TC/emotion/utc_UIFW_emotion_object_audio_channel_count.c new file mode 100644 index 0000000..979b2e0 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_audio_channel_count.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_audio_channel_count_p(void); +static void utc_emotion_object_audio_channel_count_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_audio_channel_count_p, POSITIVE_TC_IDX}, + { utc_emotion_object_audio_channel_count_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_audio_channel_count_p(void) +{ + Evas_Object *object = init(); + int count = emotion_object_audio_channel_count(object); + + if (1 != count) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_audio_channel_count_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_audio_channel_count(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_audio_mute_set_get.c b/TC/emotion/utc_UIFW_emotion_object_audio_mute_set_get.c new file mode 100644 index 0000000..63b8f48 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_audio_mute_set_get.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_audio_mute_set_p(void); +static void utc_emotion_object_audio_mute_set_n(void); +static void utc_emotion_object_audio_mute_set_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_audio_mute_set_p, POSITIVE_TC_IDX}, + { utc_emotion_object_audio_mute_set_n, NEGATIVE_TC_IDX}, + { utc_emotion_object_audio_mute_set_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_audio_mute_set_p(void) +{ + Evas_Object *object = init(); + emotion_object_audio_mute_set(object, EINA_TRUE); + Eina_Bool res = emotion_object_audio_mute_get(object); + + if (EINA_TRUE != res) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_audio_mute_set_n(void) +{ + Evas_Object *object = init(); + emotion_object_audio_mute_set(object, EINA_FALSE); + Eina_Bool res = emotion_object_audio_mute_get(object); + + if (EINA_FALSE != res) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_audio_mute_set_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_audio_mute_set(NULL, EINA_FALSE); + emotion_object_audio_mute_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_audio_volume_set_get.c b/TC/emotion/utc_UIFW_emotion_object_audio_volume_set_get.c new file mode 100644 index 0000000..7cc40f4 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_audio_volume_set_get.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_audio_volume_set_get_p(void); +static void utc_emotion_object_audio_volume_set_get_n(void); +static void utc_emotion_object_audio_volume_set_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_audio_volume_set_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_audio_volume_set_get_n, NEGATIVE_TC_IDX}, + { utc_emotion_object_audio_volume_set_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_audio_volume_set_get_p(void) +{ + Evas_Object *object = init(); + emotion_object_audio_volume_set(object, 0.5); + double volume = emotion_object_audio_volume_get(object); + + if (0.5 != volume) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_audio_volume_set_get_n(void) +{ + Evas_Object *object = init(); + emotion_object_audio_volume_set(object, 0.5); + emotion_object_audio_volume_set(object, -0.5); + emotion_object_audio_volume_set(object, 1.5); + double volume = emotion_object_audio_volume_get(object); + + if (0.5 != volume) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_audio_volume_set_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_audio_volume_set(NULL, 5.0); + emotion_object_audio_volume_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_bg_color_set.c b/TC/emotion/utc_UIFW_emotion_object_bg_color_set.c new file mode 100644 index 0000000..9e5e468 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_bg_color_set.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_bg_color_set_p(void); +static void utc_emotion_object_bg_color_set_n(void); +static void utc_emotion_object_bg_color_set_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_bg_color_set_p, POSITIVE_TC_IDX}, + { utc_emotion_object_bg_color_set_n, NEGATIVE_TC_IDX}, + { utc_emotion_object_bg_color_set_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_bg_color_set_p(void) +{ + int r = 0, g = 0, b = 0, a = 0; + + Evas_Object *object = init(); + ecore_main_loop_begin(); + emotion_object_bg_color_set(object, 5, 4, 3, 2); + emotion_object_bg_color_get(object, &r, &g, &b, &a); + + if (5 != r || 4 != g || 3 != b || 2 != a) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_printf("Expected value(rgba): (5,4,3,2), result value(rgba): (%d,%d,%d,%d)", r, g, b, a); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_bg_color_set_n(void) +{ + int r = 0, g = 0, b = 0, a = 0; + + Evas_Object *object = init(); + emotion_object_bg_color_set(object, -5, -4, -3, -2); + emotion_object_bg_color_get(object, &r, &g, &b, &a); + + if (0 != r || 0 != g || 0 != b || 0 != a) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_bg_color_set_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_bg_color_set(NULL, -5, -4, -3, -2); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_border_set.c b/TC/emotion/utc_UIFW_emotion_object_border_set.c new file mode 100644 index 0000000..914fd20 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_border_set.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_border_set_p(void); +static void utc_emotion_object_border_set_n(void); +static void utc_emotion_object_border_set_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_border_set_p, POSITIVE_TC_IDX}, + { utc_emotion_object_border_set_n, NEGATIVE_TC_IDX}, + { utc_emotion_object_border_set_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_border_set_p(void) +{ + int l = 0, r = 0, t = 0, b = 0; + + Evas_Object *object = init(); + emotion_object_border_set(object, 5, 4, 3, 2); + emotion_object_border_get(object, &l, &r, &t, &b); + + if (5 != l || 4 != r || 3 != t || 2 != b) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_border_set_n(void) +{ + int l = 0, r = 0, t = 0, b = 0; + + Evas_Object *object = init(); + emotion_object_border_set(object, -5, -4, -3, -2); + emotion_object_border_get(object, &l, &r, &t, &b); + + if (-5 != l || -4 != r || -3 != t || -2 != b) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_border_set_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_border_set(NULL, -5, -4, -3, -2); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_event_simple_send.c b/TC/emotion/utc_UIFW_emotion_object_event_simple_send.c new file mode 100644 index 0000000..60f073b --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_event_simple_send.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_event_simple_send_p(void); +static void utc_emotion_object_event_simple_send_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_event_simple_send_p, POSITIVE_TC_IDX}, + { utc_emotion_object_event_simple_send_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_event_simple_send_p(void) +{ + Evas_Object *object = init(); + + for (int event = EMOTION_EVENT_MENU1; event <= EMOTION_EVENT_10; ++event) { + emotion_object_event_simple_send(object, event); + } + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_event_simple_send_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_vis_set(NULL, EMOTION_EVENT_10 + 1); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_file_set_get.c b/TC/emotion/utc_UIFW_emotion_object_file_set_get.c new file mode 100644 index 0000000..a299b02 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_file_set_get.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_file_set_get_p(void); +static void utc_emotion_object_file_set_get_n(void); +static void utc_emotion_object_file_set_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_file_set_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_file_set_get_n, NEGATIVE_TC_IDX}, + { utc_emotion_object_file_set_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_file_set_get_p(void) +{ + Evas_Object *object; + Eina_Bool res = EINA_FALSE; + + signal(SIGSEGV, sigprocess); + + Evas *evas = ecore_evas_get(ecore_evas); + object = emotion_object_add(evas); + emotion_object_init(object, NULL); + res = emotion_object_file_set(object, "test.avi"); + const char *file_name = emotion_object_file_get(object); + + if (EINA_FALSE == res || strcmp(file_name, "test.avi")) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_file_set_get_n(void) +{ + Evas *evas; + Evas_Object *object; + Eina_Bool res = EINA_FALSE; + + signal(SIGSEGV, sigprocess); + + evas = ecore_evas_get(ecore_evas); + object = emotion_object_add(evas); + emotion_object_init(object, NULL); + emotion_object_file_set(object, "test.avi"); + res = emotion_object_file_set(object, "fail.png"); + const char *file_name = emotion_object_file_get(object); + tet_printf("file name: %s", file_name); + + if (EINA_FALSE != res || strcmp(file_name, "test.avi")) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_file_set_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_file_set(NULL, NULL); + emotion_object_file_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} diff --git a/TC/emotion/utc_UIFW_emotion_object_image_get.c b/TC/emotion/utc_UIFW_emotion_object_image_get.c new file mode 100644 index 0000000..63894a5 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_image_get.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_image_get_p(void); +static void utc_emotion_object_image_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_image_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_image_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_image_get_p(void) +{ + Evas_Object *object = init(); + Evas_Object *image = emotion_object_image_get(object); + + if (image == NULL) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_image_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_image_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_init.c b/TC/emotion/utc_UIFW_emotion_object_init.c new file mode 100644 index 0000000..6ce39bf --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_init.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_init_p(void); +static void utc_emotion_object_init_n(void); +static void utc_emotion_object_init_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_init_p, POSITIVE_TC_IDX}, + { utc_emotion_object_init_n, NEGATIVE_TC_IDX}, + { utc_emotion_object_init_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_init_p(void) +{ + Evas *evas = NULL; + Evas_Object *object = NULL; + Eina_Bool res_gstreamer = EINA_FALSE; + + signal(SIGSEGV, sigprocess); + + evas = ecore_evas_get(ecore_evas); + object = emotion_object_add(evas); + res_gstreamer = emotion_object_init(object, NULL); + + if (EINA_FALSE == res_gstreamer) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_init_n(void) +{ + Evas *evas = NULL; + Evas_Object *object = NULL; + Eina_Bool res = EINA_FALSE; + + signal(SIGSEGV, sigprocess); + + evas = ecore_evas_get(ecore_evas); + object = emotion_object_add(evas); + res = emotion_object_init(object, "test"); + + if (EINA_FALSE != res) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_init_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_init(NULL, NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} diff --git a/TC/emotion/utc_UIFW_emotion_object_keep_aspect_set.c b/TC/emotion/utc_UIFW_emotion_object_keep_aspect_set.c new file mode 100644 index 0000000..b96dfbf --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_keep_aspect_set.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_keep_aspect_set_p(void); +static void utc_emotion_object_keep_aspect_set_n(void); +static void utc_emotion_object_keep_aspect_set_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_keep_aspect_set_p, POSITIVE_TC_IDX}, + { utc_emotion_object_keep_aspect_set_n, NEGATIVE_TC_IDX}, + { utc_emotion_object_keep_aspect_set_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_keep_aspect_set_p(void) +{ + Evas_Object *object = init(); + emotion_object_keep_aspect_set(object, EMOTION_ASPECT_KEEP_BOTH); + Emotion_Aspect res = emotion_object_keep_aspect_get(object); + + if (EMOTION_ASPECT_KEEP_BOTH != res) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_keep_aspect_set_n(void) +{ + Evas_Object *object = init(); + emotion_object_keep_aspect_set(object, EMOTION_ASPECT_KEEP_BOTH); + emotion_object_border_set(object, 1, 1, 1, 1); + Emotion_Aspect res = emotion_object_keep_aspect_get(object); + + if (EMOTION_ASPECT_CUSTOM != res) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_keep_aspect_set_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_keep_aspect_set(NULL, EMOTION_ASPECT_KEEP_BOTH); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} diff --git a/TC/emotion/utc_UIFW_emotion_object_last_position_save_load.c b/TC/emotion/utc_UIFW_emotion_object_last_position_save_load.c new file mode 100644 index 0000000..53c0cb4 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_last_position_save_load.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_last_position_save_load_p(void); +static void utc_emotion_object_last_position_save_load_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_last_position_save_load_p, POSITIVE_TC_IDX}, + { utc_emotion_object_last_position_save_load_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_last_position_save_load_p(void) +{ + Evas_Object *object = init(); + emotion_object_position_set(object, 5.0); + emotion_object_last_position_save(object); + emotion_object_position_set(object, 7.0); + emotion_object_last_position_load(object); + double last_position = emotion_object_position_get(object); + tet_printf("Last position: %d", last_position); + + if (5.0 != last_position) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_last_position_save_load_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_last_position_save(NULL); + emotion_object_last_position_load(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_meta_info_get.c b/TC/emotion/utc_UIFW_emotion_object_meta_info_get.c new file mode 100644 index 0000000..5ea4854 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_meta_info_get.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_meta_info_get_p(void); +static void utc_emotion_object_meta_info_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_meta_info_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_meta_info_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_meta_info_get_p(void) +{ + Evas_Object *object = init(); + const char *title = emotion_object_meta_info_get(object, EMOTION_META_INFO_TRACK_TITLE); + const char *artist = emotion_object_meta_info_get(object, EMOTION_META_INFO_TRACK_ARTIST); + const char *album = emotion_object_meta_info_get(object, EMOTION_META_INFO_TRACK_ALBUM); + const char *year = emotion_object_meta_info_get(object, EMOTION_META_INFO_TRACK_YEAR); + const char *genre = emotion_object_meta_info_get(object, EMOTION_META_INFO_TRACK_GENRE); + const char *comment = emotion_object_meta_info_get(object, EMOTION_META_INFO_TRACK_COMMENT); + const char *disc_id = emotion_object_meta_info_get(object, EMOTION_META_INFO_TRACK_DISC_ID); + const char *count = emotion_object_meta_info_get(object, EMOTION_META_INFO_TRACK_COUNT); + tet_printf("title: %s, artist: %s, album: %s, year: %s, genre: %s, comment: %s, disc_id: %s, count: %s", + title, artist, album, year, genre, comment, disc_id, count); + + // it was possible to set only these parameters with ffmpeg, so year, disc_id and count are not checked here + if (strcmp(artist, "Test artist") || strcmp(comment, "Test comment") || strcmp(genre, "Test genre") || + strcmp(title, "Test title") || strcmp(album, "Test album")) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_meta_info_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_meta_info_get(NULL, EMOTION_META_INFO_TRACK_TITLE); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_module_option_set.c b/TC/emotion/utc_UIFW_emotion_object_module_option_set.c new file mode 100644 index 0000000..8cd4821 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_module_option_set.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_module_option_set_p(void); +static void utc_emotion_object_module_option_set_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_module_option_set_p, POSITIVE_TC_IDX}, + { utc_emotion_object_module_option_set_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_module_option_set_p(void) +{ + Evas_Object *object = init(); + ecore_main_loop_begin(); + emotion_object_video_mute_set(object, EINA_FALSE); + emotion_object_module_option_set(object, "video", "off"); + Eina_Bool res_video = emotion_object_video_mute_get(object); + + emotion_object_audio_mute_set(object, EINA_FALSE); + emotion_object_module_option_set(object, "audio", "off"); + Eina_Bool res_audio = emotion_object_audio_mute_get(object); + + if (EINA_TRUE != res_video || EINA_TRUE != res_audio) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_module_option_set_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_module_option_set(NULL, "video", "off"); + emotion_object_module_option_set(NULL, "audio", "off"); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_play_length_get.c b/TC/emotion/utc_UIFW_emotion_object_play_length_get.c new file mode 100644 index 0000000..d38ff5e --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_play_length_get.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_play_length_get_p(void); +static void utc_emotion_object_play_length_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_play_length_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_play_length_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_play_length_get_p(void) +{ + Evas_Object *object = init(); + ecore_main_loop_begin(); + double length = emotion_object_play_length_get(object); + + if (10 != length) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_printf("Expected value: 10, return value: %d", length); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_play_length_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_play_length_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_play_set_get.c b/TC/emotion/utc_UIFW_emotion_object_play_set_get.c new file mode 100644 index 0000000..8375783 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_play_set_get.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_play_set_p(void); +static void utc_emotion_object_play_set_n(void); +static void utc_emotion_object_play_set_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_play_set_p, POSITIVE_TC_IDX}, + { utc_emotion_object_play_set_n, NEGATIVE_TC_IDX}, + { utc_emotion_object_play_set_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_play_set_p(void) +{ + Evas_Object *object = init(); + + emotion_object_play_set(object, EINA_TRUE); + + ecore_main_loop_begin(); + + Eina_Bool res = emotion_object_play_get(object); + + if (EINA_FALSE == res) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_play_set_n(void) +{ + Evas_Object *object = init(); + emotion_object_play_set(object, EINA_FALSE); + Eina_Bool res = emotion_object_play_get(object); + + if (EINA_FALSE != res) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_play_set_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_play_set(NULL, EINA_TRUE); + emotion_object_play_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} diff --git a/TC/emotion/utc_UIFW_emotion_object_play_speed_set_get.c b/TC/emotion/utc_UIFW_emotion_object_play_speed_set_get.c new file mode 100644 index 0000000..5dab151 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_play_speed_set_get.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_play_speed_set_p(void); +static void utc_emotion_object_play_speed_set_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_play_speed_set_p, POSITIVE_TC_IDX}, + { utc_emotion_object_play_speed_set_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_play_speed_set_p(void) +{ + Evas_Object *object = init(); + ecore_main_loop_begin(); + emotion_object_play_speed_set(object, 5.0); + double play_speed = emotion_object_play_speed_get(object); + + if (5.0 != play_speed) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_printf("Expected value: 5.0, return value: %f", play_speed); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_play_speed_set_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_play_speed_set(NULL, 5.0); + emotion_object_play_speed_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_position_set_get.c b/TC/emotion/utc_UIFW_emotion_object_position_set_get.c new file mode 100644 index 0000000..fefedce --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_position_set_get.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_position_set_get_p(void); +static void utc_emotion_object_position_set_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_position_set_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_position_set_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_position_set_get_p(void) +{ + Evas_Object *object = init(); + ecore_main_loop_begin(); + emotion_object_position_set(object, 5); + double position = emotion_object_position_get(object); + + if (5 != position) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_printf("Expected value: 5, return value: %d", position); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_position_set_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_position_set(NULL, 5); + emotion_object_position_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_progress_info_get.c b/TC/emotion/utc_UIFW_emotion_object_progress_info_get.c new file mode 100644 index 0000000..795604f --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_progress_info_get.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_progress_info_get_p(void); +static void utc_emotion_object_progress_info_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_progress_info_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_progress_info_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_progress_info_get_p(void) +{ + Evas_Object *object = init(); + const char *progress_info = emotion_object_progress_info_get(object); + tet_printf("progress_info: %s", progress_info); + + if (NULL == progress_info) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_progress_info_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_progress_info_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_progress_status_get.c b/TC/emotion/utc_UIFW_emotion_object_progress_status_get.c new file mode 100644 index 0000000..e94611e --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_progress_status_get.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_progress_status_get_p(void); +static void utc_emotion_object_progress_status_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_progress_status_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_progress_status_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_progress_status_get_p(void) +{ + double position = 3.0; + + Evas_Object *object = init(); + ecore_main_loop_begin(); + emotion_object_position_set(object, position); + double status = emotion_object_progress_status_get(object); + + if (position / emotion_object_play_length_get(object) != status) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_printf("Expected value: %f, return value: %f", position / emotion_object_play_length_get(object), status); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_progress_status_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_progress_status_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_ratio_get.c b/TC/emotion/utc_UIFW_emotion_object_ratio_get.c new file mode 100644 index 0000000..779859f --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_ratio_get.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_ratio_get_p(void); +static void utc_emotion_object_ratio_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_ratio_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_ratio_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_ratio_get_p(void) +{ + Evas_Object *object = init(); + ecore_main_loop_begin(); + double ratio = emotion_object_ratio_get(object); + + if ((double)436 / 344 != ratio) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_printf("Expeced value: %f, result value: %f", (double)436 / 344, ratio); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_ratio_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_ratio_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_ref_file_get.c b/TC/emotion/utc_UIFW_emotion_object_ref_file_get.c new file mode 100644 index 0000000..3103059 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_ref_file_get.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_ref_file_get_p(void); +static void utc_emotion_object_ref_file_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_ref_file_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_ref_file_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_ref_file_get_p(void) +{ + Evas_Object *object = init(); + const char *file = emotion_object_ref_file_get(object); + tet_printf("file: %s", file); + + if (file != NULL) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_ref_file_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_ref_file_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_ref_num_get.c b/TC/emotion/utc_UIFW_emotion_object_ref_num_get.c new file mode 100644 index 0000000..d337125 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_ref_num_get.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_ref_num_get_p(void); +static void utc_emotion_object_ref_num_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_ref_num_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_ref_num_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_ref_num_get_p(void) +{ + Evas_Object *object = init(); + int num = emotion_object_ref_num_get(object); + + if (num != 0) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_ref_num_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_ref_num_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_seekable_get.c b/TC/emotion/utc_UIFW_emotion_object_seekable_get.c new file mode 100644 index 0000000..366b216 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_seekable_get.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_seekable_get_p(void); +static void utc_emotion_object_seekable_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_seekable_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_seekable_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_seekable_get_p(void) +{ + Evas_Object *object = init(); + ecore_main_loop_begin(); + Eina_Bool res = emotion_object_seekable_get(object); + + if (EINA_TRUE != res) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_seekable_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_seekable_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} diff --git a/TC/emotion/utc_UIFW_emotion_object_size_get.c b/TC/emotion/utc_UIFW_emotion_object_size_get.c new file mode 100644 index 0000000..93fceec --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_size_get.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_size_get_p(void); +static void utc_emotion_object_size_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_size_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_size_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_size_get_p(void) +{ + int w = 0, h = 0; + + Evas_Object *object = init(); + ecore_main_loop_begin(); + emotion_object_size_get(object, &w, &h); + + if (436 != w || 344 != h) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_size_get_null(void) +{ + int w = 0, h = 0; + + signal(SIGSEGV, sigprocess); + + emotion_object_size_get(NULL, &w, &h); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_smooth_scale_set.c b/TC/emotion/utc_UIFW_emotion_object_smooth_scale_set.c new file mode 100644 index 0000000..7907cf4 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_smooth_scale_set.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_smooth_scale_set_p(void); +static void utc_emotion_object_smooth_scale_set_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_smooth_scale_set_p, POSITIVE_TC_IDX}, + { utc_emotion_object_smooth_scale_set_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_smooth_scale_set_p(void) +{ + Evas_Object *object = init(); + emotion_object_smooth_scale_set(object, EINA_TRUE); + Eina_Bool smooth = emotion_object_smooth_scale_get(object); + + if (EINA_TRUE != smooth) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_smooth_scale_set_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_smooth_scale_set(NULL, EINA_TRUE); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_spu_button_count_get.c b/TC/emotion/utc_UIFW_emotion_object_spu_button_count_get.c new file mode 100644 index 0000000..9dc0528 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_spu_button_count_get.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_spu_button_count_get_p(void); +static void utc_emotion_object_spu_button_count_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_spu_button_count_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_spu_button_count_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_spu_button_count_get_p(void) +{ + Evas_Object *object = init(); + int button_count = emotion_object_spu_button_count_get(object); + + if (button_count != 0) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_spu_button_count_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_spu_button_count_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_spu_button_get.c b/TC/emotion/utc_UIFW_emotion_object_spu_button_get.c new file mode 100644 index 0000000..097858f --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_spu_button_get.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_spu_button_get_p(void); +static void utc_emotion_object_spu_button_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_spu_button_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_spu_button_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_spu_button_get_p(void) +{ + Evas_Object *object = init(); + int button = emotion_object_spu_button_get(object); + tet_printf("button: %d", button); + + if (button != 0) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_spu_button_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_spu_button_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_spu_channel_count.c b/TC/emotion/utc_UIFW_emotion_object_spu_channel_count.c new file mode 100644 index 0000000..be764db --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_spu_channel_count.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_spu_channel_count_p(void); +static void utc_emotion_object_spu_channel_count_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_spu_channel_count_p, POSITIVE_TC_IDX}, + { utc_emotion_object_spu_channel_count_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_spu_channel_count_p(void) +{ + Evas_Object *object = init(); + int count = emotion_object_spu_channel_count(object); + + if (0 != count) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_spu_channel_count_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_spu_channel_count(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_title_get.c b/TC/emotion/utc_UIFW_emotion_object_title_get.c new file mode 100644 index 0000000..b9772e0 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_title_get.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_title_get_p(void); +static void utc_emotion_object_title_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_title_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_title_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_title_get_p(void) +{ + Evas_Object *object = init(); + const char *title = emotion_object_title_get(object); + + if (title != NULL) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_title_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_title_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_video_channel_count.c b/TC/emotion/utc_UIFW_emotion_object_video_channel_count.c new file mode 100644 index 0000000..7e1a4d1 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_video_channel_count.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_video_channel_count_p(void); +static void utc_emotion_object_video_channel_count_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_video_channel_count_p, POSITIVE_TC_IDX}, + { utc_emotion_object_video_channel_count_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_video_channel_count_p(void) +{ + Evas_Object *object = init(); + int count = emotion_object_video_channel_count(object); + + if (1 != count) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_video_channel_count_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_video_channel_count(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_video_mute_set_get.c b/TC/emotion/utc_UIFW_emotion_object_video_mute_set_get.c new file mode 100644 index 0000000..6666696 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_video_mute_set_get.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_video_mute_set_p(void); +static void utc_emotion_object_video_mute_set_n(void); +static void utc_emotion_object_video_mute_set_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_video_mute_set_p, POSITIVE_TC_IDX}, + { utc_emotion_object_video_mute_set_n, NEGATIVE_TC_IDX}, + { utc_emotion_object_video_mute_set_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_video_mute_set_p(void) +{ + Evas_Object *object = init(); + emotion_object_video_mute_set(object, EINA_TRUE); + Eina_Bool res = emotion_object_video_mute_get(object); + + if (EINA_TRUE != res) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_video_mute_set_n(void) +{ + Evas_Object *object = init(); + emotion_object_video_mute_set(object, EINA_FALSE); + Eina_Bool res = emotion_object_video_mute_get(object); + + if (EINA_FALSE != res) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_video_mute_set_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_video_mute_set(NULL, EINA_FALSE); + emotion_object_video_mute_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_vis_set_get.c b/TC/emotion/utc_UIFW_emotion_object_vis_set_get.c new file mode 100644 index 0000000..40d64c5 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_vis_set_get.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_vis_set_get_p(void); +static void utc_emotion_object_vis_set_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_vis_set_get_p, POSITIVE_TC_IDX}, + { utc_emotion_object_vis_set_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_vis_set_get_p(void) +{ + Evas_Object *object = init(); + + for (int i = EMOTION_VIS_GOOM; i <= EMOTION_VIS_LIBVISUAL_PLASMA; ++i) { + emotion_object_vis_set(object, i); + Emotion_Vis vis = emotion_object_vis_get(object); + + if (vis != i) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + } + +// emotion_object_vis_set(object, EMOTION_VIS_GOOM); +// Emotion_Vis vis = emotion_object_vis_get(object); +// if (vis != EMOTION_VIS_GOOM) { +// +// } +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_BUMPSCOPE); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_CORONA); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_DANCING_PARTICLES); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_GDKPIXBUF); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_G_FORCE); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_GOOM); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_INFINITE); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_JAKDAW); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_JESS ); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_LV_ANALYSER); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_LV_FLOWER); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_LV_GLTEST); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_LV_SCOPE); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_MADSPIN); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_NEBULUS); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_OINKSIE); +// vis = emotion_object_vis_get(object); +// +// emotion_object_vis_set(object, EMOTION_VIS_LIBVISUAL_PLASMA); +// vis = emotion_object_vis_get(object); +// +// if (goom != EINA_FALSE || bumpscope != EINA_FALSE || corona != EINA_FALSE || dancing_particles != EINA_FALSE +// || gdbpixbuf != EINA_FALSE || g_force != EINA_FALSE || goom2 != EINA_FALSE || infinite != EINA_FALSE +// || jakdaw != EINA_FALSE || jess != EINA_FALSE || analyser != EINA_FALSE || flower != EINA_FALSE +// || madspin != EINA_FALSE || nebulus != EINA_FALSE || oinksie != EINA_FALSE || plasma != EINA_FALSE) { +// tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); +// tet_result(TET_FAIL); +// return; +// } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_vis_set_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_vis_set(NULL, EMOTION_META_INFO_TRACK_TITLE); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_object_vis_supported.c b/TC/emotion/utc_UIFW_emotion_object_vis_supported.c new file mode 100644 index 0000000..722ec89 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_object_vis_supported.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_object_vis_supported_p(void); +static void utc_emotion_object_vis_supported_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_object_vis_supported_p, POSITIVE_TC_IDX}, + { utc_emotion_object_vis_supported_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_object_vis_supported_p(void) +{ + Evas_Object *object = init(); + + Eina_Bool goom = emotion_object_vis_supported(object, EMOTION_VIS_GOOM); + Eina_Bool bumpscope = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_BUMPSCOPE); + Eina_Bool corona = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_CORONA); + Eina_Bool dancing_particles = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_DANCING_PARTICLES); + Eina_Bool gdbpixbuf = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_GDKPIXBUF); + Eina_Bool g_force = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_G_FORCE); + Eina_Bool goom2 = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_GOOM); + Eina_Bool infinite = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_INFINITE); + Eina_Bool jakdaw = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_JAKDAW); + Eina_Bool jess = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_JESS ); + Eina_Bool analyser = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_LV_ANALYSER); + Eina_Bool flower = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_LV_FLOWER); + Eina_Bool gltest = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_LV_GLTEST); + Eina_Bool scope = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_LV_SCOPE); + Eina_Bool madspin = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_MADSPIN); + Eina_Bool nebulus = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_NEBULUS); + Eina_Bool oinksie = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_OINKSIE); + Eina_Bool plasma = emotion_object_vis_supported(object, EMOTION_VIS_LIBVISUAL_PLASMA); + + tet_printf("goom: %d, bumpscope: %d, corona: %d, dancing_particles: %d, gdbpixbuf: %d, \ + g_force: %d, goom2: %d, infinite: %d, jakdaw: %d, jess: %d, analyser: %d, flower: %d, \ + gltest: %d, scope: %d, madspin: %d, nebulus: %d, oinksie: %d, plasma: %d", + goom, bumpscope, corona, dancing_particles, gdbpixbuf, g_force, goom2, infinite, + jakdaw, jess, analyser, flower, gltest, scope, madspin, nebulus, oinksie, plasma); + + if (goom != EINA_FALSE || bumpscope != EINA_FALSE || corona != EINA_FALSE || dancing_particles != EINA_FALSE + || gdbpixbuf != EINA_FALSE || g_force != EINA_FALSE || goom2 != EINA_FALSE || infinite != EINA_FALSE + || jakdaw != EINA_FALSE || jess != EINA_FALSE || analyser != EINA_FALSE || flower != EINA_FALSE + || madspin != EINA_FALSE || nebulus != EINA_FALSE || oinksie != EINA_FALSE || plasma != EINA_FALSE) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_object_vis_supported_null(void) +{ + signal(SIGSEGV, sigprocess); + + emotion_object_vis_supported(NULL, EMOTION_META_INFO_TRACK_TITLE); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_open_done.c b/TC/emotion/utc_UIFW_emotion_open_done.c new file mode 100644 index 0000000..a8de5aa --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_open_done.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_open_done_p(void); +static void utc_emotion_open_done_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_open_done_p, POSITIVE_TC_IDX}, + { utc_emotion_open_done_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_open_done_p(void) +{ + Evas_Object *object = init(); + _emotion_open_done(object); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_open_done_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_open_done(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_playback_finished.c b/TC/emotion/utc_UIFW_emotion_playback_finished.c new file mode 100644 index 0000000..b752e3b --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_playback_finished.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_playback_finished_p(void); +static void utc_emotion_playback_finished_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_playback_finished_p, POSITIVE_TC_IDX}, + { utc_emotion_playback_finished_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_playback_finished_p(void) +{ + Evas_Object *object = init(); + _emotion_playback_finished(object); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_playback_finished_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_playback_finished(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_playback_started.c b/TC/emotion/utc_UIFW_emotion_playback_started.c new file mode 100644 index 0000000..2996028 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_playback_started.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_playback_started_p(void); +static void utc_emotion_playback_started_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_playback_started_p, POSITIVE_TC_IDX}, + { utc_emotion_playback_started_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_playback_started_p(void) +{ + Evas_Object *object = init(); + _emotion_playback_started(object); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_playback_started_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_playback_started(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_progress_set.c b/TC/emotion/utc_UIFW_emotion_progress_set.c new file mode 100644 index 0000000..91c58ff --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_progress_set.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_progress_set_p(void); +static void utc_emotion_progress_set_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_progress_set_p, POSITIVE_TC_IDX}, + { utc_emotion_progress_set_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_progress_set_p(void) +{ + Evas_Object *object = init(); + _emotion_progress_set(object, "info", 0.5); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_progress_set_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_progress_set(NULL, NULL, 0.0); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_seek_done.c b/TC/emotion/utc_UIFW_emotion_seek_done.c new file mode 100644 index 0000000..4884033 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_seek_done.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_seek_done_p(void); +static void utc_emotion_seek_done_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_seek_done_p, POSITIVE_TC_IDX}, + { utc_emotion_seek_done_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_seek_done_p(void) +{ + Evas_Object *object = init(); + _emotion_seek_done(object); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_seek_done_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_seek_done(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_shutdown.c b/TC/emotion/utc_UIFW_emotion_shutdown.c new file mode 100644 index 0000000..656db50 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_shutdown.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +static void utc_emotion_shutdown_p(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_shutdown_p, POSITIVE_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_shutdown_p(void) +{ + signal(SIGSEGV, sigprocess); + + Eina_Bool res = emotion_shutdown(); + + if (EINA_FALSE == res) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_spu_button_num_set.c b/TC/emotion/utc_UIFW_emotion_spu_button_num_set.c new file mode 100644 index 0000000..ff296dd --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_spu_button_num_set.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_spu_button_num_set_p(void); +static void utc_emotion_spu_button_num_set_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_spu_button_num_set_p, POSITIVE_TC_IDX}, + { utc_emotion_spu_button_num_set_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_spu_button_num_set_p(void) +{ + Evas_Object *object = init(); + _emotion_spu_button_num_set(object, 2); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_spu_button_num_set_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_spu_button_num_set(NULL, -2); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_spu_button_set.c b/TC/emotion/utc_UIFW_emotion_spu_button_set.c new file mode 100644 index 0000000..34a316b --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_spu_button_set.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_spu_button_set_p(void); +static void utc_emotion_spu_button_set_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_spu_button_set_p, POSITIVE_TC_IDX}, + { utc_emotion_spu_button_set_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_spu_button_set_p(void) +{ + Evas_Object *object = init(); + _emotion_spu_button_set(object, 2); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_spu_button_set_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_spu_button_set(NULL, -2); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_title_set.c b/TC/emotion/utc_UIFW_emotion_title_set.c new file mode 100644 index 0000000..035fed3 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_title_set.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_title_set_p(void); +static void utc_emotion_title_set_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_title_set_p, POSITIVE_TC_IDX}, + { utc_emotion_title_set_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_title_set_p(void) +{ + Evas_Object *object = init(); + _emotion_title_set(object, "title"); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_title_set_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_title_set(NULL, NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_video_get.c b/TC/emotion/utc_UIFW_emotion_video_get.c new file mode 100644 index 0000000..397f906 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_video_get.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_video_get_p(void); +static void utc_emotion_video_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_video_get_p, POSITIVE_TC_IDX}, + { utc_emotion_video_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_video_get_p(void) +{ + Evas_Object *object = init(); + void *video = _emotion_video_get(object); + + if (video == NULL) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_video_get_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_video_get(NULL); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_video_pos_update.c b/TC/emotion/utc_UIFW_emotion_video_pos_update.c new file mode 100644 index 0000000..f75b8f3 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_video_pos_update.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_video_pos_update_p(void); +static void utc_emotion_video_pos_update_n(void); +static void utc_emotion_video_pos_update_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_video_pos_update_p, POSITIVE_TC_IDX}, + { utc_emotion_video_pos_update_n, NEGATIVE_TC_IDX}, + { utc_emotion_video_pos_update_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_video_pos_update_p(void) +{ + Evas_Object *object = init(); + _emotion_video_pos_update(object, 5.0, 5.0); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_video_pos_update_n(void) +{ + Evas_Object *object = init(); + _emotion_video_pos_update(object, -5.0, -5.0); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_video_pos_update_null(void) +{ + signal(SIGSEGV, sigprocess); + + _emotion_video_pos_update(NULL, 0.0, 0.0); + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/emotion/utc_UIFW_emotion_webcam_custom_get.c b/TC/emotion/utc_UIFW_emotion_webcam_custom_get.c new file mode 100644 index 0000000..d5e00c0 --- /dev/null +++ b/TC/emotion/utc_UIFW_emotion_webcam_custom_get.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "emotion_private.h" + +static void utc_emotion_webcam_custom_get_p(void); +static void utc_emotion_webcam_custom_get_null(void); + +struct tet_testlist tet_testlist[] = { + { utc_emotion_webcam_custom_get_p, POSITIVE_TC_IDX}, + { utc_emotion_webcam_custom_get_null, NULL_TC_IDX}, + { NULL, 0 }, +}; + +static void utc_emotion_webcam_custom_get_p(void) +{ + init(); + const char *launch = emotion_webcam_custom_get("/dev/webcam"); + + if (launch == NULL) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + +static void utc_emotion_webcam_custom_get_null(void) +{ + init(); + const char *launch = emotion_webcam_custom_get(NULL); + + if (launch != NULL) { + tet_printf("[TET_FAIL]:: %s[%d] : Test has failed..", __FILE__, __LINE__); + tet_result(TET_FAIL); + return; + } + + tet_printf("[TET_PASS]:: %s[%d] : Test has passed..", __FILE__, __LINE__); + tet_result(TET_PASS); +} + diff --git a/TC/execute.sh b/TC/execute.sh new file mode 100755 index 0000000..ce3421b --- /dev/null +++ b/TC/execute.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. ./_export_env.sh # setting environment variables + +export TET_SUITE_ROOT=`pwd` +FILE_NAME_EXTENSION=`date +%s` + +RESULT_DIR=results +HTML_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.html +JOURNAL_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.journal + +mkdir -p $RESULT_DIR + +tcc -e -j $JOURNAL_RESULT -p ./ +#grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT +grw -c 7 -f chtml -o $HTML_RESULT $JOURNAL_RESULT + diff --git a/TC/tet_scen b/TC/tet_scen new file mode 100644 index 0000000..2309232 --- /dev/null +++ b/TC/tet_scen @@ -0,0 +1,8 @@ +all + ^EMOTION +##### Scenarios for TEST ##### + +# Test scenario + +EMOTION + :include:/emotion/tslist diff --git a/TC/tetbuild.cfg b/TC/tetbuild.cfg new file mode 100755 index 0000000..f7eda55 --- /dev/null +++ b/TC/tetbuild.cfg @@ -0,0 +1,5 @@ +TET_OUTPUT_CAPTURE=True # capture option for build operation checking +TET_BUILD_TOOL=make # build with using make command +TET_BUILD_FILE=-f Makefile # execution file (Makefile) for build +TET_API_COMPLIANT=True # use TET API in Test Case ? +TET_PASS_TC_NAME=True # report passed TC name in Journal file? diff --git a/TC/tetclean.cfg b/TC/tetclean.cfg new file mode 100755 index 0000000..02d7030 --- /dev/null +++ b/TC/tetclean.cfg @@ -0,0 +1,5 @@ +TET_OUTPUT_CAPTURE=True # capture option +TET_CLEAN_TOOL= make clean # clean tool +TET_CLEAN_FILE= Makefile # file for clean +TET_API_COMPLIANT=True # TET API useage +TET_PASS_TC_NAME=True # showing name , passed TC diff --git a/TC/tetexec.cfg b/TC/tetexec.cfg new file mode 100755 index 0000000..ef3e452 --- /dev/null +++ b/TC/tetexec.cfg @@ -0,0 +1,5 @@ +TET_OUTPUT_CAPTURE=True # capturing execution or not +TET_EXEC_TOOL= # ex) exec : execution tool set up/ Optional +TET_EXEC_FILE= # ex) exectool : execution file/ Optional +TET_API_COMPLIANT=True # Test case or Tool usesTET API? +TET_PASS_TC_NAME=True # showing Passed TC name ? diff --git a/autogen.sh b/autogen.sh index 995ff2f..00116ea 100755 --- a/autogen.sh +++ b/autogen.sh @@ -4,6 +4,7 @@ rm -rf autom4te.cache rm -f aclocal.m4 ltmain.sh touch README +touch ABOUT-NLS echo "Running aclocal..." ; aclocal $ACLOCAL_FLAGS -I m4 || exit 1 echo "Running autoheader..." ; autoheader || exit 1 @@ -11,6 +12,28 @@ echo "Running autoconf..." ; autoconf || exit 1 echo "Running libtoolize..." ; (libtoolize --copy --automake || glibtoolize --automake) || exit 1 echo "Running automake..." ; automake --add-missing --copy --gnu || exit 1 +W=0 + +rm -f config.cache-env.tmp +echo "OLD_PARM=\"$@\"" >> config.cache-env.tmp +echo "OLD_CFLAGS=\"$CFLAGS\"" >> config.cache-env.tmp +echo "OLD_PATH=\"$PATH\"" >> config.cache-env.tmp +echo "OLD_PKG_CONFIG_PATH=\"$PKG_CONFIG_PATH\"" >> config.cache-env.tmp +echo "OLD_LDFLAGS=\"$LDFLAGS\"" >> config.cache-env.tmp + +cmp config.cache-env.tmp config.cache-env >> /dev/null +if [ $? -ne 0 ]; then + W=1; +fi + +if [ $W -ne 0 ]; then + echo "Cleaning configure cache..."; + rm -f config.cache config.cache-env + mv config.cache-env.tmp config.cache-env +else + rm -f config.cache-env.tmp +fi + if [ -z "$NOCONFIGURE" ]; then - ./configure "$@" + ./configure -C "$@" fi diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..13b09c2 --- /dev/null +++ b/configure.ac @@ -0,0 +1,370 @@ +##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## +##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## +m4_define([v_maj], [1]) +m4_define([v_min], [7]) +m4_define([v_mic], [99]) +m4_define([v_rev], m4_esyscmd([(svnversion "${SVN_REPO_PATH:-.}" | grep -v '\(export\|Unversioned directory\)' || echo 0) | awk -F : '{printf("%s\n", $1);}' | tr -d ' :MSP\n'])) +m4_if(v_rev, [0], [m4_define([v_rev], m4_esyscmd([git log 2> /dev/null | (grep -m1 git-svn-id || echo 0) | sed -e 's/.*@\([0-9]*\).*/\1/' | tr -d '\n']))]) +##-- When released, remove the dnl on the below line +dnl m4_undefine([v_rev]) +##-- When doing snapshots - change soname. remove dnl on below line +m4_define([relname], [ver-pre-svn-07]) +m4_define([v_rel], [-release relname]) +##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## +m4_ifdef([v_rev], [m4_define([v_ver], [v_maj.v_min.v_mic.v_rev])], +[m4_define([v_ver], [v_maj.v_min.v_mic])]) +m4_define([lt_rev], m4_eval(v_maj + v_min)) +m4_define([lt_cur], v_mic) +m4_define([lt_age], v_min) +##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## +##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## + +AC_INIT([emotion], [v_ver], [enlightenment-devel@lists.sourceforge.net]) +AC_PREREQ([2.60]) +AC_CONFIG_SRCDIR([configure.ac]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CANONICAL_BUILD +AC_CANONICAL_HOST +AC_ISC_POSIX + +AM_INIT_AUTOMAKE([1.6 dist-bzip2]) +AM_CONFIG_HEADER([config.h]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +AC_LIBTOOL_WIN32_DLL +define([AC_LIBTOOL_LANG_CXX_CONFIG], [:])dnl +define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl +AC_PROG_LIBTOOL + +##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## +##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## +m4_ifdef([v_rev], , [m4_define([v_rev], [0])]) +m4_ifdef([v_rel], , [m4_define([v_rel], [])]) +AC_DEFINE_UNQUOTED(VMAJ, [v_maj], [Major version]) +AC_DEFINE_UNQUOTED(VMIN, [v_min], [Minor version]) +AC_DEFINE_UNQUOTED(VMIC, [v_mic], [Micro version]) +AC_DEFINE_UNQUOTED(VREV, [v_rev], [Revison]) +version_info="lt_rev:lt_cur:lt_age" +release_info="v_rel" +AC_SUBST(version_info) +AC_SUBST(release_info) +##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## +##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## +VMAJ=v_maj +AC_SUBST(VMAJ) + +want_generic="yes" +case "$host_os" in + mingw*) + want_xine="no" + want_gstreamer="yes" + want_generic="no" + want_generic_vlc="no" + ;; + *) + want_xine="yes" + want_gstreamer="yes" + want_generic_vlc="yes" + ;; +esac + +requirement_emotion="" + +### Additional options to configure + +EFL_ENABLE_BIN([emotion-test]) + +# edje_cc + +AC_ARG_WITH([edje-cc], + [AC_HELP_STRING([--with-edje-cc=PATH], [specify a specific path to edje_cc])], + [ + v=$withval; + edje_cc=$v + echo " Enlightenment edje_cc explicitly set to "$edje_cc; + ], + [edje_cc=$(pkg-config --variable=prefix edje)/bin/edje_cc]) +AC_SUBST(edje_cc) + + +### Checks for programs +AC_PROG_CC + +# pkg-config +PKG_PROG_PKG_CONFIG + +# Check whether pkg-config supports Requires.private +if $PKG_CONFIG --atleast-pkgconfig-version 0.22; then + pkgconfig_requires_private="Requires.private" +else + pkgconfig_requires_private="Requires" +fi +AC_SUBST(pkgconfig_requires_private) + +# doxygen program for documentation building + +EFL_CHECK_DOXYGEN([build_doc="yes"], [build_doc="no"]) + + +### Checks for libraries + +requirement_emotion="ecore >= 1.6.99 evas >= 1.6.99 eet >= 1.6.99 eina >= 1.6.99" +PKG_CHECK_MODULES(EMOTION, [${requirement_emotion}]) + + +if test "x${have_emotion_test}" = "xyes" ; then + PKG_CHECK_MODULES(EMOTION_BIN, [eina >= 1.6.99 evas >= 1.6.99 ecore >= 1.6.99 ecore-evas >= 1.6.99 edje >= 1.6.99]) +fi + +PKG_CHECK_MODULES(ECORE_X, [ecore-x >= 1.6.99 ecore-evas >= 1.6.99], [have_ecore_x="yes"], [have_ecore_x="no"]) + +PKG_CHECK_MODULES(ECORE_FB, [ecore-fb >= 1.6.99], [have_ecore_fb="yes"], [have_ecore_fb="no"]) + +if test "x${have_ecore_x}" = "xyes" ; then + AC_DEFINE(EMOTION_HAVE_ECORE_X, 1, [Define to 1 if Ecore_X is enabled]) +fi + +if test "x${have_ecore_fb}" = "xyes" ; then + AC_DEFINE(EMOTION_HAVE_ECORE_FB, 1, [Define to 1 if Ecore_Fb is enabled]) +fi + +PKG_CHECK_EXISTS([evas-software-x11 >= 1.6.99], [AC_DEFINE(HAVE_EVAS_SOFWARE_X11, 1, [Evas Software Xlib Engine Support])]) + +PKG_CHECK_EXISTS([evas-xrender-x11 >= 1.6.99], [AC_DEFINE(HAVE_EVAS_XRENDER_X11, 1, [Evas Software Xlib Engine Support])]) + +PKG_CHECK_EXISTS([evas-opengl-x11 >= 1.6.99], [AC_DEFINE(HAVE_EVAS_OPENGL_X11, 1, [Evas OpenGL Xlib Engine Support])]) + +PKG_CHECK_EXISTS([evas-fb >= 1.6.99], [AC_DEFINE(HAVE_EVAS_FB, 1, [Evas Framebuffer Engine Support])]) + +EFL_EDJE_EXTERNAL([have_edje_external="yes"], [have_edje_external="no"]) + +PKG_CHECK_MODULES(EEZE, [eeze >= 1.6.99], [have_eeze="yes"], [have_eeze="no"]) + +if test "x${have_eeze}" = "xyes"; then + AC_DEFINE(EMOTION_HAVE_EEZE, 1, [Define to 1 if Eeze is available]) + requirement_emotion="${requirement_emotion} eeze >= 1.6.99" +fi + +PKG_CHECK_MODULES([EIO], [eio >= 1.6.99], [have_eio="yes"], [have_eio="no"]) +if test "x${have_eio}" = "xyes"; then + AC_DEFINE(HAVE_EIO, 1, [Use EIO for asynchronous file access]) + requirement_emotion="eio >= 1.6.99 ${requirement_emotion}" +fi + +AM_CONDITIONAL([HAVE_EIO], [test "x${have_eio}" = "xyes"]) + +# ecore-x availability, used for XV, VAAPI, VDPAU output. + +have_ecore_x="no" +AC_ARG_ENABLE([ecore-x], + [AC_HELP_STRING([--disable-ecore-x], [disable ecore-x support. @<:@default=detect@:>@])], + [ + if test "x${enableval}" = "xyes" || test "x${enableval}" = "xauto" ; then + want_ecore_x=${enableval} + else + want_ecore_x="no" + fi + ], + [want_ecore_x="auto"]) + +if ! test "x$want_ecore_x" = "xno" ; then + PKG_CHECK_MODULES([ECORE_X], + [ecore-x >= 1.6.99], + [ + AC_DEFINE(HAVE_ECORE_X, 1, [X11 support for Ecore]) + have_ecore_x="yes" + requirement_elm="ecore-x >= 1.6.99 ${requirement_elm}" + ], + [have_ecore_x="no"] + ) +else + have_ecore_x="no" +fi + +if test "x$want_ecore_x" = "xyes" && test "x$have_ecore_x" = "xno" ; then + AC_MSG_ERROR([ecore-x support requested, but not found by pkg-config.]) +fi + +### Checks for header files + +AC_CHECK_HEADERS([unistd.h]) + +# Check for video4linux + +AC_MSG_CHECKING([for V4L2]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include + ]], + [[ +fprintf(stdout, "%i\n", V4L2_CAP_VIDEO_CAPTURE); + ]])], + [ + AC_DEFINE(HAVE_V4L2, 1, [Define to 1 if you have Video4Linux 2 available]) + have_v4l2="yes" + ], + [have_v4l2="no"]) +AC_MSG_RESULT([${have_v4l2}]) + +### Checks for types + + +### Checks for structures + + +### Checks for compiler characteristics +AC_C_BIGENDIAN +AC_C___ATTRIBUTE__ + +EFL_EMOTION_BUILD="" +case "$host_os" in + mingw32ce*) + EMOTION_CPPFLAGS="-D_WIN32_WCE=0x0420" + EFL_EMOTION_BUILD="-DEFL_EMOTION_BUILD" + ;; + mingw*) + EMOTION_CPPFLAGS="-D_WIN32_WINNT=0x0501" + EFL_EMOTION_BUILD="-DEFL_EMOTION_BUILD" + ;; +esac +AC_SUBST(EFL_EMOTION_BUILD) +AC_SUBST(EMOTION_CPPFLAGS) + + +### Checks for linker characteristics + +# use --enable-auto-import on Windows + +lt_enable_auto_import="" +case "$host_os" in + mingw*) + lt_enable_auto_import="-Wl,--enable-auto-import" + ;; +esac +AC_SUBST(lt_enable_auto_import) + + +### Checks for library functions +AC_FUNC_ALLOCA + + +### Modules + +EMOTION_CHECK_MODULE([Xine], [${want_xine}]) +EMOTION_CHECK_MODULE([Gstreamer], [${want_gstreamer}]) +EMOTION_CHECK_MODULE([Generic], [${want_generic}]) + +EMOTION_CHECK_GENERIC_PLAYER([VLC], [${want_generic_vlc}]) + +if test "x${enable_xine}" = "xno" && test "x${enable_gstreamer}" = "xno" && test "x${enable_generic}" = "xno" ; then + AC_MSG_ERROR([Xine, Gstreamer or Generic backends must be selected to build Emotion]) +fi + +# Check if gstreamer X Overlay is available +build_xoverlay="no" +if test "x${enable_gstreamer}" = "xyes" ; then + PKG_CHECK_MODULES([GSTREAMER_INTERFACE], + [gstreamer-interfaces-0.10 >= 0.10.34], + [build_xoverlay="yes"], + [build_xoverlay="no"]) + if test "x${build_xoverlay}" = "xyes" ; then + save_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$CPPFLAGS ${GSTREAMER_CFLAGS} ${GSTREAMER_INTERFACE_CFLAGS}" + AC_CHECK_HEADER([gst/interfaces/xoverlay.h], + [ + AC_DEFINE(HAVE_XOVERLAY_H, 1, [Build with Gstreamer Xoverlay support]) + build_xoverlay="yes" + ], + [build_xoverlay="no"]) + CPPFLAGS=$save_CPPFLAGS + + save_LDFLAGS=${LDFLAGS} + LDFLAGS="${LDFLAGS} ${GSTREAMER_INTERFACES}" + AC_CHECK_LIB([gstinterfaces-0.10], + [gst_x_overlay_set_window_handle], + [AC_DEFINE([HAVE_X_OVERLAY_SET], [1], [Use gst_x_overlay_set_window_handle instead of old deprecated gst_x_overlay_set_xwindow_id])]) + LDFLAGS=$sava_LDFLAGS + fi +fi + +### install and build examples + +EFL_CHECK_BUILD_EXAMPLES([enable_build_examples="yes"], [enable_build_examples="no"]) +EFL_CHECK_INSTALL_EXAMPLES([enable_install_examples="yes"], [enable_install_examples="no"]) + +AC_SUBST(requirement_emotion) + +AC_OUTPUT([ +Makefile +emotion.pc +emotion.spec +src/Makefile +src/lib/Makefile +src/modules/Makefile +src/modules/xine/Makefile +src/modules/gstreamer/Makefile +src/modules/generic/Makefile +src/edje_external/Makefile +src/generic_players/Makefile +src/generic_players/vlc/Makefile +src/bin/Makefile +src/examples/Makefile +doc/Makefile +doc/Doxyfile +data/Makefile +]) + + +##################################################################### +## Info + +echo +echo +echo +echo "------------------------------------------------------------------------" +echo "$PACKAGE $VERSION" +echo "------------------------------------------------------------------------" +echo +echo "Configuration Options Summary:" +echo +echo " Modules:" +echo " Xine...............: ${enable_xine}" +echo " Gstreamer..........: ${enable_gstreamer} (X: ${have_ecore_x}/${build_xoverlay})" +echo " Generic............: ${enable_generic}" + +if test "x${enable_generic}" = "xyes" || test "x${enable_generic}" = "xstatic"; then +echo +echo " Generic Players:" +echo " VLC................: ${enable_generic_vlc}" +fi + +echo +echo " Build emotion_test...: $have_emotion_test" +echo " edje_cc..............: ${edje_cc}" +echo +echo " Edje EXTERNAL support: ${have_edje_external}" +echo +echo " Eio..................: ${have_eio}" +echo " V4L2.................: ${have_v4l2}" +echo +echo "Documentation..........: ${build_doc}" +echo "Examples.............: ${enable_build_examples}" +echo "Examples installed...: ${enable_install_examples}" +echo +echo "Compilation............: make (or gmake)" +echo " CPPFLAGS.............: $CPPFLAGS" +echo " CFLAGS...............: $CFLAGS" +echo " LDFLAGS..............: $LDFLAGS" +echo +echo "Installation...........: make install (as root if needed, with 'su' or 'sudo')" +echo " prefix...............: $prefix" +echo +if test "x${have_static_module}" = "xyes" ; then +echo -e "\0033\01331;31mWarning\0033\01331;0m: You are trying to link statically one or more modules to Emotion." +echo " You must know what you are doing, or else you will have a lot of problems." +echo " And asparagus will disappear from the earth." +echo " Think about that." +echo +fi diff --git a/data/Makefile.am b/data/Makefile.am index 5121518..6e5ce6f 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,11 +1,20 @@ MAINTAINERCLEANFILES = Makefile.in -EDJE_CC = edje_cc +EDJE_CC = @edje_cc@ EDJE_FLAGS = -v -id $(top_srcdir)/data -fd $(top_srcdir)/data -filesdir = $(datadir)/emotion/data -files_DATA = theme.edj +filesdir = $(datadir)/$(PACKAGE)/data + +files_DATA = + +if BUILD_EMOTION_TEST +files_DATA += theme.edj +endif + +if ENABLE_EDJE_EXTERNAL +files_DATA += icon.edj +endif EXTRA_DIST = \ bpause.png \ @@ -31,13 +40,18 @@ video_frame_right.png \ video_frame_top.png \ whb.png \ window_inner_shadow.png \ -Vera.ttf \ -theme.edc +theme.edc \ +icon.edc -theme.edj: Makefile +theme.edj: Makefile theme.edc $(EDJE_CC) $(EDJE_FLAGS) \ $(top_srcdir)/data/theme.edc \ $(top_builddir)/data/theme.edj +icon.edj: Makefile icon.edc + $(EDJE_CC) $(EDJE_FLAGS) \ + $(top_srcdir)/data/icon.edc \ + $(top_builddir)/data/icon.edj + clean-local: rm -f *.edj diff --git a/data/e_logo.png b/data/e_logo.png index 54100d5b65776e3ff1a13de913369caa2480717e..0b79b69ab39d1dec20bcc729bd17dd51bc31ccdb 100644 GIT binary patch literal 7833 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 KMNUMnLSTZ;UlY0j diff --git a/data/icon.edc b/data/icon.edc new file mode 100644 index 0000000..0a3ea3d --- /dev/null +++ b/data/icon.edc @@ -0,0 +1,14 @@ +collections { + images.image: "e_logo.png" COMP; + group { name: "icon"; + min: 20 10; + parts { + part { name: "icon"; type: IMAGE; + mouse_events: 0; + description { state: "default" 0.0; + image.normal: "e_logo.png"; + } + } + } + } +} diff --git a/data/theme.edc b/data/theme.edc index a3c28a0..63e732d 100644 --- a/data/theme.edc +++ b/data/theme.edc @@ -28,10 +28,6 @@ images { image: "pnl.png" COMP; } -fonts { - font: "Vera.ttf" "Vera"; -} - collections { group { name: "background"; @@ -613,7 +609,7 @@ collections { color2: 0 0 0 255; text { text: "Video Progress"; - font: "Vera"; + font: "Sans"; size: 6; align: 0.0 1.0; }; @@ -869,7 +865,494 @@ collections { color: 0 0 0 255; text { text: "Video Speed"; - font: "Vera"; + font: "Sans"; + size: 6; + align: 1.0 0.5; + }; + } + } + part { + name: "video_progress_confine"; + mouse_events: 0; + type: RECT; + description { + state: "default" 0.0; + fixed: 1 1; + min: 1 18; + align: 0.5 0.0; + rel1 { + to: "video_frame_left"; + relative: 1.0 1.0; + offset: 0 -25; + } + rel2 { + to: "video_frame_right"; + relative: 0.0 1.0; + offset: -1 -25; + } + color: 0 0 0 0; + } + } + part { + name: "video_progress"; + type: RECT; + mouse_events: 1; + dragable { + x: 1 1 0; + y: 0 0 0; + confine: "video_progress_confine"; + } + description { + state: "default" 0.0; + fixed: 1 1; + min: 34 18; + rel1 { + to: "video_progress_confine"; + relative: 0.5 0.5; + offset: 0 0; + } + rel2 { + to: "video_progress_confine"; + relative: 0.5 0.5; + offset: 0 0; + } + color: 0 0 0 0; + } + } + part { + name: "video_progress_img"; + mouse_events: 0; + description { + state: "default" 0.0; + fixed: 1 1; + min: 42 26; + rel1 { + to: "video_progress"; + relative: 0.5 0.5; + offset: 0 0; + } + rel2 { + to: "video_progress"; + relative: 0.5 0.5; + offset: 0 0; + } + image { + normal: "h_slider.png"; + } + } + } + part { + name: "video_speed_confine"; + mouse_events: 0; + type: RECT; + description { + state: "default" 0.0; + rel1 { + to: "video_frame_left"; + relative: 1.0 0.0; + offset: 0 24; + } + rel2 { + to: "video_frame_left"; + relative: 1.0 1.0; + offset: 48 -49; + } + color: 0 0 0 0; + } + } + part { + name: "video_speed"; + mouse_events: 1; + dragable { + x: 0 0 0; + y: -1 1 0; + confine: "video_speed_confine"; + } + description { + state: "default" 0.0; + fixed: 1 1; + min: 24 24; + rel1 { + to: "video_speed_confine"; + relative: 0.5 0.5; + offset: 0 0; + } + rel2 { + to: "video_speed_confine"; + relative: 0.5 0.5; + offset: 0 0; + } + image { + normal: "knob.png"; + } + } + } + part { + name: "video_play"; + mouse_events: 1; + description { + state: "default" 0.0; + fixed: 1 1; + min: 24 24; + rel1 { + to: "video_frame_bottom"; + relative: 0.0 0.5; + offset: 0 0; + } + rel2 { + to: "video_frame_bottom"; + relative: 0.0 0.5; + offset: 0 0; + } + image { + normal: "knob.png"; + } + } + } + part { + name: "video_pause"; + mouse_events: 1; + description { + state: "default" 0.0; + fixed: 1 1; + min: 24 24; + rel1 { + to: "video_frame_bottom"; + relative: 0.5 0.5; + offset: 0 0; + } + rel2 { + to: "video_frame_bottom"; + relative: 0.5 0.5; + offset: 0 0; + } + image { + normal: "knob.png"; + } + } + } + part { + name: "video_stop"; + mouse_events: 1; + description { + state: "default" 0.0; + fixed: 1 1; + min: 24 24; + rel1 { + to: "video_frame_bottom"; + relative: 1.0 0.5; + offset: 0 0; + } + rel2 { + to: "video_frame_bottom"; + relative: 1.0 0.5; + offset: 0 0; + } + image { + normal: "knob.png"; + } + } + } + part { + name: "video_mover"; + mouse_events: 1; + type: RECT; + description { + state: "default" 0.0; + rel1 { + to: "video_frame_top"; + relative: 0.0 0.0; + offset: 0 0; + } + rel2 { + to: "video_frame_top"; + relative: 1.0 1.0; + offset: -1 -1; + } + color: 255 20 20 20; + } + } + part { + name: "video_resizer"; + mouse_events: 1; + type: RECT; + description { + state: "default" 0.0; + rel1 { + to: "video_frame_right"; + relative: 0.0 1.0; + offset: 0 -31; + } + rel2 { + to: "video_frame_right"; + relative: 1.0 1.0; + offset: -1 -1; + } + color: 20 20 255 20; + } + } + part { + name: "video_progress_txt"; + type: TEXT; + mouse_events: 0; + effect: OUTLINE; + description { + state: "default" 0.0; + align: 1.0 1.0; + fixed: 1 1; + rel1 { + relative: 1.0 1.0; + offset: -2 -2; + } + rel2 { + relative: 1.0 1.0; + offset: -2 -2; + } + color: 255 255 255 255; + color2: 0 0 0 255; + text { + text: "XX:XX:XX / XX:XX:XX"; + font: "Sans"; + size: 10; + align: 1.0 1.0; + min: 1 1; + }; + } + } + } + programs { + // emit signals: + // "video_control" "play" + // "video_control" "pause" + // "video_control" "stop" + // "drag" "video_progress" + // "drag" "video_speed" + // + // get signals: + // "video_state" "play" + // "video_state" "pause" + // "video_state" "stop" + program { + name: "video_play"; + signal: "mouse,down,1"; + source: "video_play"; + action: SIGNAL_EMIT "video_control" "play"; + } + program { + name: "video_pause"; + signal: "mouse,down,1"; + source: "video_pause"; + action: SIGNAL_EMIT "video_control" "pause"; + } + program { + name: "video_stop"; + signal: "mouse,down,1"; + source: "video_stop"; + action: SIGNAL_EMIT "video_control" "stop"; + } + program { + name: "video_move_start"; + signal: "mouse,down,*"; + source: "video_mover"; + action: SIGNAL_EMIT "frame_move" "start"; + } + program { + name: "video_move_stop"; + signal: "mouse,up,*"; + source: "video_mover"; + action: SIGNAL_EMIT "frame_move" "stop"; + } + program { + name: "video_resize_start"; + signal: "mouse,down,*"; + source: "video_resizer"; + action: SIGNAL_EMIT "frame_resize" "start"; + } + program { + name: "video_resize_stop"; + signal: "mouse,up,*"; + source: "video_resizer"; + action: SIGNAL_EMIT "frame_resize" "stop"; + } + } + } + + group { + name: "video_controller/reflex"; + parts { + // need swallow parts: + // "video_swallow" + // + // need txt parts: + // "video_speed_txt" + // "video_progress_txt" + // + // need dragables: + // "video_progress" horizontal + // "video_speed" vertical + part { + name: "video_swallow"; + mouse_events: 0; + type: SWALLOW; + description { + state: "default" 0.0; + rel1 { + to: "video_frame_left"; + relative: 1.0 0.0; + offset: -8 23; + } + rel2 { + to: "video_frame_right"; + relative: 0.0 1.0; + offset: 7 -25; + } + } + } + + part { + name: "swallow_center"; + type: RECT; + description { + state: "default" 0.0; + visible: 0; + rel1 { + to: "video_swallow"; + relative: 0.5 1.0; + } + rel2 { + to: "video_swallow"; + relative: 0.5 1.0; + } + } + } + part { + name: "swallow_mirror"; + type: PROXY; + mouse_events: 0; + description { + state: "default" 0.0; + source: "video_swallow"; + rel1 { + to: "video_swallow"; + } + rel2 { + to: "video_swallow"; + } + perspective { + zplane: 0; + focal: 1000; + } + color: 255 255 255 96; + map { + on: 1; + smooth: 0; + alpha: 1; + rotation { + center: "swallow_center"; + x: 100; + } + } + } + } + + part { + name: "video_frame_left"; + mouse_events: 0; + description { + state: "default" 0.0; + rel1 { + relative: 0.0 0.0; + offset: 0 0; + } + rel2 { + relative: 0.0 1.0; + offset: 32 -1; + } + image { + border: 0 0 33 33; + normal: "video_frame_left.png"; + } + } + } + part { + name: "video_frame_right"; + mouse_events: 0; + description { + state: "default" 0.0; + rel1 { + relative: 1.0 0.0; + offset: -32 0; + } + rel2 { + relative: 1.0 1.0; + offset: -1 -1; + } + image { + border: 0 0 33 33; + normal: "video_frame_right.png"; + } + } + } + part { + name: "video_frame_top"; + mouse_events: 0; + description { + state: "default" 0.0; + rel1 { + to: "video_frame_left"; + relative: 1.0 0.0; + offset: 0 0; + } + rel2 { + to: "video_frame_right"; + relative: 0.0 0.0; + offset: -1 31; + } + image { + normal: "video_frame_top.png"; + } + } + } + part { + name: "video_frame_bottom"; + mouse_events: 0; + description { + state: "default" 0.0; + rel1 { + to: "video_frame_left"; + relative: 1.0 1.0; + offset: 0 -32; + } + rel2 { + to: "video_frame_right"; + relative: 0.0 1.0; + offset: -1 -1; + } + image { + normal: "video_frame_bottom.png"; + } + } + } + part { + name: "video_speed_txt"; + type: TEXT; + mouse_events: 0; + description { + state: "default" 0.0; + rel1 { + to: "video_frame_bottom"; + relative: 0.0 0.0; + offset: 0 8; + } + rel2 { + to: "video_frame_bottom"; + relative: 1.0 1.0; + offset: -1 -13; + } + color: 0 0 0 255; + text { + text: "Video Speed"; + font: "Sans"; size: 6; align: 1.0 0.5; }; @@ -1116,7 +1599,7 @@ collections { color2: 0 0 0 255; text { text: "XX:XX:XX / XX:XX:XX"; - font: "Vera"; + font: "Sans"; size: 10; align: 1.0 1.0; min: 1 1; diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..80b0bb3 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,99 @@ +emotion (1.0.0+svn.70375slp2+build02) unstable; urgency=low + + * Package Upload + * Git: slp/pkgs/e/emotion + * Tag: emotion_1.0.0+svn.70375slp2+build02 + + -- Myungjae Lee Wed, 25 Apr 2012 17:30:10 +0900 + +emotion (1.0.0+svn.70375slp2+build01) unstable; urgency=low + + * Pakcage Upload + * Git: slp/pkgs/e/emotion + * Tag: emotion_1.0.0+svn.70375slp2+build01 + + -- Myungjae Lee Wed, 25 Apr 2012 15:15:36 +0900 + +emotion (1.0.0+svn.70278slp2+build01) unstable; urgency=low + + * Package Upload + * Git: slp/pkgs/e/emotion + * Tag: emotion_1.0.0+svn.70278slp2+build01 + + -- Jaehwan Kim Mon, 23 Apr 2012 15:30:14 +0900 + +emotion (1.0.0+svn.69824slp2+build01) unstable; urgency=low + + * Package Upload + * Git: slp/pkgs/e/emotion + * Tag: emotion_1.0.0+svn.69824slp2+build01 + + -- Jeonghyun Yun Fri, 06 Apr 2012 18:25:12 +0900 + +emotion (0.1.0+svn.69618slp2+build01) unstable; urgency=low + + * Package Upload + * Git: slp/pkgs/e/emotion + * Tag: emotion_0.1.0+svn.69618slp2+build01 + + -- Jeonghyun Yun Wed, 28 Mar 2012 14:31:28 +0900 + +emotion (0.1.0+svn.69438slp2+build02) unstable; urgency=low + + * Package Upload + * Git: slp/pkgs/e/emotion + * Tag: emotion_0.1.0+svn.69438slp2+build02 + + -- Jeonghyun Yun Sun, 18 Mar 2012 14:23:12 +0900 + +emotion (0.1.0+svn.69438slp2+build01) unstable; urgency=low + + * EFL migration + * Git: slp/pkgs/e/emotion + * Tag: emotion_0.1.0+svn.69438slp2+build01 + + -- Jeonghyun Yun Fri, 16 Mar 2012 21:51:33 +0900 + +emotion (0.1.0+svn.68849slp2+build01) unstable; urgency=low + + * Package Upload + * Git: slp/pkgs/e/emotion + * Tag: emotion_0.1.0+svn.68849slp2+build01 + + -- Jeonghyun Yun Wed, 07 Mar 2012 16:45:45 +0900 + +emotion (0.1.0+svn.68464slp2+build01) unstable; urgency=low + + * Package upload + * Git: slp/pkgs/e/emotion + * Tag: emotion_0.1.0+svn.68464slp2+build01 + + -- Jeonghyun Yun Fri, 02 Mar 2012 06:35:57 -0500 + +emotion (0.1.0+svn.67705slp2+build01) unstable; urgency=low + + * Package Upload + * Git: slp/pkgs/e/emotion + * Tag: emotion_0.1.0+svn.67705slp2+build01 + + -- Jaehwan Kim Wed, 15 Feb 2012 19:03:23 +0900 + +emotion (0.1.0+svn.66791slp2+build01) unstable; urgency=low + + * Package Upload + * Git: slp/pkgs/e/emotion + * Tag: emotion_0.1.0+svn.66791slp2+build01 + + -- Jaehwan Kim Mon, 16 Jan 2012 18:38:15 +0900 + +emotion (0.1.0+svn.65137slp2+build02) unstable; urgency=low + + * Rebuild after adding package to default.xml + + -- Mike McCormack Mon, 14 Nov 2011 19:18:20 +0900 + +emotion (0.1.0+svn.65137slp2+build01) unstable; urgency=low + + * Initial release, based on @65137 + + -- Mike McCormack Mon, 14 Nov 2011 18:54:14 +0900 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..1e8b314 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +6 diff --git a/debian/control b/debian/control index ed7a589..fe0d60e 100644 --- a/debian/control +++ b/debian/control @@ -1,27 +1,30 @@ Source: emotion Priority: optional Section: libs -Maintainer: Falko Schmidt -Build-Depends: cdbs, debhelper (>= 6), pkg-config, libeet-dev, libevas-dev, libedje-dev, libecore-dev, libembryo-dev, libxine-dev (>=1.1.0), libgstreamer0.10-dev, libgstreamer-plugins-base0.10-dev -Standards-Version: 3.7.3 +Maintainer: Jaehwan Kim , Myoungwoon Kim , Jeonghyun Yun +Original-Maintainer: Falko Schmidt +Build-Depends: cdbs, debhelper (>= 6), libeet-dev, libevas-dev, libedje-dev, libecore-dev, libembryo-dev, libgstreamer0.10-dev, libgstreamer-plugins-base0.10-dev +Standards-Version: 3.8.2 Homepage: http://www.enlightenment.org Package: libemotion0 Section: libs Architecture: any -Depends: ${shlibs:Depends} -Provides: libemotion +Depends: ${shlibs:Depends}, libemotion0-gstreamer +Provides: libemotion, libemotion-bin +Replaces: libemotion-bin Description: Video playback library used in Enlightenment DR0.17 This is the emotion library, a wrapper library used in the next-generation Enlightenment suite for video playback. . This package contains the shared libraries. -Package: libemotion-dev +Package: libemotion0-dev Section: libdevel Architecture: any Depends: libemotion0 (= ${Source-Version}), libevas-dev, libecore-dev -Provides: libemotion0-dev +Provides: libemotion-dev +Replaces: libemotion-dev Description: Headers, static libraries and documentation for Emotion This package contains development files for the Emotion library, a wrapper library used in the next-generation Enlightenment suite for video playback. @@ -29,35 +32,14 @@ Description: Headers, static libraries and documentation for Emotion This package contains headers and static libraries for development with libemotion. -Package: libemotion-xine -Section: libs -Architecture: any -Depends: ${shlibs:Depends}, libemotion0, libxine1 (>=1.1.0) -Provides: libemotion-xine -Description: Video playback library used in Enlightenment DR0.17 - This is the emotion library, a wrapper library used in the next-generation - Enlightenment suite for video playback. - . - This package provides the xine module for emotion. - -Package: libemotion-gstreamer +Package: libemotion0-gstreamer Section: libs Architecture: any Depends: ${shlibs:Depends}, libemotion0, gstreamer0.10-plugins-good Provides: libemotion-gstreamer +Replaces: libemotion-gstreamer Description: Video playback library used in Enlightenment DR0.17 This is the emotion library, a wrapper library used in the next-generation Enlightenment suite for video playback. . This package provides the gstreamer module for emotion. - -Package: libemotion-bin -Section: x11 -Architecture: any -Depends: ${shlibs:Depends} -Provides: libemotion0-bin -Description: Test programs for Emotion - This is the emotion library, a wrapper library used in the next-generation - Enlightenment suite for video playback. - . - This package contains test programs for the Emotion library. diff --git a/debian/libemotion0-dev.install b/debian/libemotion0-dev.install new file mode 100644 index 0000000..b8d218e --- /dev/null +++ b/debian/libemotion0-dev.install @@ -0,0 +1,4 @@ +debian/tmp/usr/include/* +debian/tmp/usr/lib/pkgconfig/* +debian/tmp/usr/lib/*.a +debian/tmp/usr/lib/*.so diff --git a/debian/libemotion0-gstreamer.install b/debian/libemotion0-gstreamer.install new file mode 100644 index 0000000..8494825 --- /dev/null +++ b/debian/libemotion0-gstreamer.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/emotion/*gstreamer*.so diff --git a/debian/libemotion0.install b/debian/libemotion0.install index 7945678..c688e77 100644 --- a/debian/libemotion0.install +++ b/debian/libemotion0.install @@ -1 +1,3 @@ debian/tmp/usr/lib/libemotion.so.* +debian/tmp/usr/bin/emotion_* +debian/tmp/usr/share/emotion/data/theme.edj diff --git a/debian/rules b/debian/rules old mode 100644 new mode 100755 index 378c8aa..49e465a --- a/debian/rules +++ b/debian/rules @@ -3,7 +3,9 @@ include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/autotools.mk -DEB_MAKE_CLEAN_TARGET := clean +DEB_CONFIGURE_SCRIPT := ./autogen.sh +DEB_MAKE_CLEAN_TARGET := distclean +DEB_CONFIGURE_EXTRA_FLAGS := --disable-rpath --enable-xine=no --disable-doc clean:: - ./autogen.sh --prefix=/usr $(DEB_CONFIGURE_EXTRA_FLAGS) + [ ! -f Makefile ] || make distclean diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in new file mode 100644 index 0000000..907be04 --- /dev/null +++ b/doc/Doxyfile.in @@ -0,0 +1,138 @@ +PROJECT_NAME = Emotion +PROJECT_NUMBER = @PACKAGE_VERSION@ +OUTPUT_DIRECTORY = . +INPUT = @top_srcdir@/src/lib \ + @srcdir@/examples.dox +IMAGE_PATH = @srcdir@/img +OUTPUT_LANGUAGE = English +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = @srcdir@/head.html +HTML_FOOTER = @srcdir@/foot.html +HTML_STYLESHEET = @srcdir@/e.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 = YES +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 +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 = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +FILE_PATTERNS = +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = @top_srcdir@/src/examples @top_srcdir@/src/bin +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 = emotion_ _emotion_ Emotion_ _Emotion_ EMOTION_ _EMOTION_ +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 = YES +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 = +DOT_GRAPH_MAX_NODES = 50 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +SEARCHENGINE = NO diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..f5cdc41 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,33 @@ +MAINTAINERCLEANFILES = Makefile.in + +.PHONY: doc + +PACKAGE_DOCNAME = $(PACKAGE_TARNAME)-$(PACKAGE_VERSION)-doc + +if EFL_BUILD_DOC + +doc-clean: + rm -rf html/ latex/ man/ xml/ $(top_builddir)/$(PACKAGE_DOCNAME).tar* + +doc: all doc-clean + $(efl_doxygen) + cp $(srcdir)/img/* html/ + cp $(srcdir)/img/* latex/ + rm -rf $(PACKAGE_DOCNAME).tar* + mkdir -p $(PACKAGE_DOCNAME)/doc + cp -R html/ latex/ man/ $(PACKAGE_DOCNAME)/doc + tar cf $(PACKAGE_DOCNAME).tar $(PACKAGE_DOCNAME)/ + bzip2 -9 $(PACKAGE_DOCNAME).tar + rm -rf $(PACKAGE_DOCNAME)/ + mv $(PACKAGE_DOCNAME).tar.bz2 $(top_builddir) + +clean-local: doc-clean + +else + +doc: + @echo "Documentation not built. Run ./configure --help" + +endif + +EXTRA_DIST = Doxyfile.in $(wildcard img/*.*) e.css head.html foot.html examples.dox diff --git a/doc/e.css b/doc/e.css index 604ee7f..2dd6b44 100644 --- a/doc/e.css +++ b/doc/e.css @@ -1,161 +1,273 @@ +/* + Author: + Andres Blanc + DaveMDS Andreoli + + Supported Browsers: + ie7, opera9, konqueror4 and firefox3 + + Please use a different file for ie6, ie5, etc. hacks. +*/ + + +/* Necessary to place the footer at the bottom of the page */ +html, body { + height: 100%; + margin: 0px; + padding: 0px; +} + +#container { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -53px; +} + +#footer, #push { + height: 53px; +} + + +* html #container { + height: 100%; +} + +/* Prevent floating elements overflowing containers */ +.clear { + clear: both; + width: 0px; + height: 0px; +} + +/* Flexible & centered layout from 750 to 960 pixels */ +.layout { + max-width: 960px; + min-width: 760px; + margin-left: auto; + margin-right: auto; +} + body { - background: url("b.png"); - background-repeat: repeat-x; - background-position: top left; - background-color: #f4f4f4; - text-align: center; - font-family: sans-serif; - padding: 0; - margin: 0; -} - -div.main { - margin: 1em auto; - vertical-align: top; - font-family: "Bitstream Vera", "Vera", "Trebuchet MS", Trebuchet, Tahoma, sans-serif; - color: #444444; - font-size: 0.8em; - text-align: justify; - width: 80%; -} - -td.t { background-image:url("t.gif"); } -td.t[class] { background-image:url("t.png"); } -td.tl { background-image:url("tl.gif"); } -td.tl[class] { background-image:url("tl.png"); } - -td.nav, td.lnav, td.rnav { - align: middle; - text-align: center; - vertical-align: middle; - width: 100px; - height: 25px; - font-family: "Bitstream Vera", "Vera", "Trebuchet MS", Trebuchet, Tahoma, sans-serif; - color: #000000; - font-size: 9px; - font-weight: bold; - white-space: no-wrap; -} - -td.lnav[class] { background-image:url("n.png"); } -td.lnav[class] { background-image:url("n.png"); } -td.rnav { background-image:url("n.gif"); } -td.rnav[class] { background-image:url("n.png"); } - -hr { - width: 200px; - height: 1px; - background: #dddddd; - border: 0; -} - -p { color: #444444 ;} -p.tiny, small { - color: #888888; - font-size: 0.5em; -} - -h1 { - text-align: center; - font-size: 1.3em; -} - -h2 { font-size: 1.1em; } -h3 { font-size: 0.9em; } - -span.keyword { color: #008000; } -span.keywordtype { color: #604020; } -span.keywordflow { color: #e08000; } -span.comment { color: #800000; } -span.preprocessor { color: #806020; } -span.stringliteral { color: #002080; } -span.charliteral { color: #008080; } - -a:link { - color: #445566; - text-decoration: underline; -} - -a:visited { - color: #667788; - text-decoration: underline; -} - -a:active { - color: #88cccc; - text-decoration: none; -} - -a:hover { - color: #112266; - text-decoration: underline; -} - -a.nav { - text-decoration: none; - display: block; -} - -a.nav:link, a.nav:visited { color: #888888; } -a.nav:active { color: #000000; } -a.nav:hover { color: #444444; } -a.code:link, a.code:visited { text-decoration: none; } - -div.fragment { - font-size: 1em; - border: 1px dotted #cccccc; - background-color: #ffffff; - text-align: left; - vertical-align: middle; - padding: 2px; - margin-left: 25px; - margin-right: 25px; - overflow: auto; -} - -td.indexkey { - font-weight: bold; - padding-left: 10px; - padding-right: 0; - padding-top: 2px; - padding-bottom: 0px; - margin: 0; - margin-top: 2px; - margin-bottom: 2px; - border: 1px dotted #cccccc; - border-right: 0px dotted #cccccc; -} - -td.indexvalue { - font-style: italic; - padding-right: 10px; - padding-left: 0; - padding-top: 2px; - padding-bottom: 2px; - margin: 0; - margin-top: 2px; - margin-bottom: 2px; - border: 1px dotted #cccccc; - border-left: 0px dotted #cccccc; -} - -.mdescRight { font-style: italic; } -.memitem { - padding-left: 2px; - padding-right: 2px; - border: 1px dotted #cccccc; - background-color: #ffffff; -} -.memname { - white-space: nowrap; - font-weight: bold; -} -.paramname { font-weight: normal; } - -div.ah { - border: thin solid #888888; - font-weight: bold; - margin-bottom: 3px; - margin-top: 3px; + /*font-family: Lucida Grande, Helvetica, sans-serif;*/ + font-family: "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif +} + +/* Prevent design overflowing the viewport in small resolutions */ +#container { + padding-right: 17px; + padding-left: 17px; + background-image: url(head_bg.png); + background-repeat: repeat-x; +} + +/****************************/ +/* Top main menu */ +/****************************/ +#header_logo { + background-image : url(logo.png); + width : 61px; +} + +#header_logo a { + position : absolute; + border : 0px; + background-color : transparent; + top : 0px; + width : 60px; + height : 60px; +} + +#header_menu { + background-image : url(header_menu_background.png); + font : normal 10pt verdana,'Bitstream Vera Sans',helvetica,arial,sans-serif; + text-align : right; +} + +#header_last { + background-image : url(header_menu_background_last.png); + width : 15px; +} + +td.nav_passive { + background : url(header_menu_unselected_background.png) 0 0 no-repeat; + height : 63px; + font-family : "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif; + font-size : 11px; + padding : 20px 10px 20px 10px; + vertical-align : middle; +} + +td.nav_active { + background : url(header_menu_current_background.png) 0 0 no-repeat; + height : 63px; + color : #646464; + font-family : "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif; + font-size : 11px; + font-weight : bold; + padding : 20px 10px 20px 10px; + vertical-align : middle; +} + +#header_menu a { + display : block; + text-decoration : none; + cursor : pointer; + color : #cdcdcd; +} + + + +#header { + width: 100%; + height: 102px; +} + +#header h1 { + width: 63px; + height: 63px; + position: absolute; + margin: 0px; +} + +#header h1 span { + display: none; +} + +#header h2 { + display: none; +} + +/* .menu-container is used to set properties common to .menu and .submenu */ +#header .menu-container { +} + +#header .menu-container ul { + list-style-type: none; + list-style-position: inside; + margin: 0; +} + +#header .menu-container li { + display: block; + float: right; +} + +#header .menu { + height: 63px; + display: block; + background-image: url(menu_bg.png); + background-repeat: repeat-x; +} + +#header .menu ul { + height: 100%; + display: block; + background-image: url(menu_bg_last.png); + background-repeat: no-repeat; + background-position: top right; + padding-right: 17px; +} + +#header .menu li { + height: 100%; + text-align: center; + background-image: url(menu_bg_unsel.png); + background-repeat: no-repeat; +} + +#header .menu a { + height: 100%; + display: block; + color: #cdcdcd; + text-decoration: none; + font-size: 10pt; + line-height: 59px; + text-align: center; + padding: 0px 15px 0px 15px; +} + +#header .menu li:hover { + background-image: url(menu_bg_hover.png); + background-repeat: no-repeat; +} + +#header .menu li:hover a { + color: #FFFFFF; +} + +#header .menu li.current { + background-image: url(menu_bg_current.png); + background-repeat: no-repeat; +} + +#header .menu li.current a { + color: #646464; +} + + +/* Hide all the submenus but the current */ +#header .submenu ul { + display: none; +} + +#header .submenu .current { + display: block; +} + +#header .submenu { + font: bold 10px verdana,'Bitstream Vera Sans',helvetica,arial,sans-serif; + margin-top: 10px; +} + +#header .submenu a { + color: #888888; + text-decoration: none; + font-size: 0.9em; + line-height: 15px; + padding:0px 5px 0px 5px; +} + +#header .submenu a:hover { + color: #444444; +} + +#header .submenu li { + border-left: 1px solid #DDDDDD; +} + +#header .submenu li:last-child { + border-left: 0; +} + +#header .doxytitle { + position: absolute; + font-size: 1.8em; + font-weight: bold; + color: #444444; + line-height: 35px; +} + +#header small { + font-size: 0.4em; +} + +#footer { + background-image: url(foot_bg.png); + width: 100%; +} + +#footer table { + width: 100%; + text-align: center; + white-space: nowrap; + padding: 5px 30px 5px 30px; + font-size: 0.8em; + font-family: "Bitstream Vera","Vera","Trebuchet MS",Trebuchet,Tahoma,sans-serif; + color: #888888; +} + +#footer td.copyright { + width: 100%; } diff --git a/doc/examples.dox b/doc/examples.dox new file mode 100644 index 0000000..5e193f1 --- /dev/null +++ b/doc/examples.dox @@ -0,0 +1,104 @@ +/** + * @page Examples Examples + * + * Here is a page with some Emotion examples explained: + * + * @li @ref emotion_basic_example_c + * @li @ref emotion_signals_example.c "Emotion signals" + * @li @ref emotion_test_main.c "emotion_test - full API usage" + * + */ + +/** + * @page emotion_basic_example_c Emotion - Basic library usage + * + * This example shows how to setup a simple Emotion object, make it start + * playing and register a callback that tells when the playback started. See @ref + * emotion_basic_example.c "the full code here". + * + * @dontinclude emotion_basic_example.c + * + * We start this example by including some header files that will be necessary + * to work with Emotion, and to display some debug messages: + * + * @until stdio.h + * + * Then a callback will be declared, to be called when the object starts its + * playback: + * + * @until } + * + * Some basic setup of our canvas, window and background is necessary before + * displaying our object on it. This setup also includes reading the file to be + * opened from the program's argument list. Since this is not directly related + * to Emotion itself, we are just displaying the code for this without an + * explanation for it: + * + * @until evas_object_show(bg); + * + * Finally, we start the Emotion part. First we have to create the object in + * this canvas, and initialize it: + * + * @until emotion_object_init + * + * Notice that we didn't specify which module will be used, so emotion will use + * the first module found. There's no guarantee of the order that the modules + * will be found, so if you need to use one of them specifically, please be + * explicit in the second argument of the function emotion_object_init(). + * + * Now the callback can be registered to this object. It's a normal Evas smart + * object callback, so we add it with evas_object_smart_callback_add(): + * + * @until NULL + * + * The object itself is ready for use, but we need to load a file to it. This is + * done by the following function: + * + * @until file_set + * + * This object can play audio or video files. For the latter, the image must be + * displayed in our canvas, and that's why we need to add the object to the + * canvas. So, like any other Evas object in the canvas, we have to specify its + * position and size, and explicitly set its visibility. These are the position + * and dimension where the video will be displayed: + * + * @until evas_object_show + * + * Since the basic steps were done, we can now start playing our file. For this, + * we can just call the basic playback control function, and then we can go to + * the main loop and watch the audio/video playing: + * + * @until main_loop_begin + * + * The rest of the code doesn't contain anything special: + * + * @until } + * + * This code just free the canvas, shutdown the library, and has an entry point + * for exiting on error. + */ + + +/** + * @example emotion_basic_example.c + * This example show how to create and play an Emotion object. See @ref + * emotion_basic_example_c "the explanation here". + */ + +/** + * @example emotion_signals_example.c + * + * This example shows that some of the information available from the emotion + * object, like the media file play length, aspect ratio, etc. can be not + * available just after setting the file to the emotion object. + * + * One callback is declared for each of the following signals, and some of the + * info about the file is displayed. Also notice that the order that these + * signals are emitted can change depending on the module being used. Following + * is the full source code of this example: + */ + +/** + * @example emotion_test_main.c + * This example covers the entire emotion API. Use it as a reference. + */ diff --git a/doc/foot.html b/doc/foot.html index 0d3303d..d43cf8f 100644 --- a/doc/foot.html +++ b/doc/foot.html @@ -1,6 +1,18 @@ + +

+ + + + + + + -
-

Copyright © Enlightenment.org

-

$projectname Documentation Generated: $datetime

- + + + diff --git a/doc/head.html b/doc/head.html index c79a91d..16696c4 100644 --- a/doc/head.html +++ b/doc/head.html @@ -1,43 +1,68 @@ - - - - $title - - + + $title + + + + + + + + + + + - - - - - - -
- - - - - -
Download
-
- - - - - - - -
-
-
- - - - - -
Support
-
- -
+ +
+ + + +
+
diff --git a/doc/img/e.png b/doc/img/e.png new file mode 100644 index 0000000000000000000000000000000000000000..d42aeb420098578b19a3eab3d6d1e6e73e3277bc GIT binary patch literal 30052 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 EKVH2_NB{r; literal 0 HcmV?d00001 diff --git a/doc/img/edoxy.css b/doc/img/edoxy.css new file mode 100644 index 0000000..311ca23 --- /dev/null +++ b/doc/img/edoxy.css @@ -0,0 +1,486 @@ +/* + * This file contain a custom doxygen style to match e.org graphics + */ + + + +/* BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { + font-family: Geneva, Arial, Helvetica, sans-serif; +}*/ +BODY, TD { + font-size: 12px; +} +H1 { + text-align: center; + font-size: 160%; +} +H2 { + font-size: 120%; +} +H3 { + font-size: 100%; +} +CAPTION { + font-weight: bold +} +DIV.qindex { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.navpath { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.navtab { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +TD.navtab { + font-size: 70%; +} +A.qindex { + text-decoration: none; + font-weight: bold; + color: #1A419D; +} +A.qindex:visited { + text-decoration: none; + font-weight: bold; + color: #1A419D +} +A.qindex:hover { + text-decoration: none; + background-color: #ddddff; +} +A.qindexHL { + text-decoration: none; + font-weight: bold; + background-color: #6666cc; + color: #ffffff; + border: 1px double #9295C2; +} +A.qindexHL:hover { + text-decoration: none; + background-color: #6666cc; + color: #ffffff; +} +A.qindexHL:visited { + text-decoration: none; + background-color: #6666cc; + color: #ffffff +} +A.el { + text-decoration: none; + font-weight: bold +} +A.elRef { + font-weight: bold +} +A.code:link { + text-decoration: none; + font-weight: normal; + color: #0000FF +} +A.code:visited { + text-decoration: none; + font-weight: normal; + color: #0000FF +} +A.codeRef:link { + font-weight: normal; + color: #0000FF +} +A.codeRef:visited { + font-weight: normal; + color: #0000FF +} +A:hover, A:visited:hover { + text-decoration: none; + /* background-color: #f2f2ff; */ + color: #000055; +} +A.anchor { + color: #000; +} +DL.el { + margin-left: -1cm +} +.fragment { + font-family: monospace, fixed; + font-size: 95%; +} +PRE.fragment { + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 2px; + margin-right: 8px; + padding-left: 6px; + padding-right: 6px; + padding-top: 4px; + padding-bottom: 4px; +} +DIV.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px +} + +DIV.groupHeader { + margin-left: 16px; + margin-top: 12px; + margin-bottom: 6px; + font-weight: bold; +} +DIV.groupText { + margin-left: 16px; + font-style: italic; + font-size: 90% +} +/*BODY { + background: white; + color: black; + margin-right: 20px; + margin-left: 20px; +}*/ +TD.indexkey { + background-color: #e8eef2; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TD.indexvalue { + background-color: #e8eef2; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TR.memlist { + background-color: #f0f0f0; +} +P.formulaDsp { + text-align: center; +} +IMG.formulaDsp { +} +IMG.formulaInl { + vertical-align: middle; +} +SPAN.keyword { color: #008000 } +SPAN.keywordtype { color: #604020 } +SPAN.keywordflow { color: #e08000 } +SPAN.comment { color: #800000 } +SPAN.preprocessor { color: #806020 } +SPAN.stringliteral { color: #002080 } +SPAN.charliteral { color: #008080 } +SPAN.vhdldigit { color: #ff00ff } +SPAN.vhdlchar { color: #000000 } +SPAN.vhdlkeyword { color: #700070 } +SPAN.vhdllogic { color: #ff0000 } + +.mdescLeft { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.mdescRight { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.memItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplParams { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + color: #606060; + background-color: #FAFAFA; + font-size: 80%; +} +.search { + color: #003399; + font-weight: bold; +} +FORM.search { + margin-bottom: 0px; + margin-top: 0px; +} +INPUT.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +TD.tiny { + font-size: 75%; +} +a { + color: #1A41A8; +} +a:visited { + color: #2A3798; +} +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #84b0c7; +} +TH.dirtab { + background: #e8eef2; + font-weight: bold; +} +HR { + height: 1px; + border: none; + border-top: 1px solid black; +} + +/* Style for detailed member documentation */ +.memtemplate { + font-size: 80%; + color: #606060; + font-weight: normal; + margin-left: 3px; +} +.memnav { + background-color: #eeeeee; + border: 1px solid #dddddd; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +.memitem { + padding: 4px; + background-color: #eeeeee; + border-width: 1px; + border-style: solid; + border-color: #dddddd; + -moz-border-radius: 4px 4px 4px 4px; +} +.memname { + white-space: nowrap; + font-weight: bold; + color: #ffffff; +} +.memdoc{ + padding-left: 10px; +} +.memproto { + background-color: #111111; + width: 100%; + border-width: 1px; + border-style: solid; + border-color: #000000; + font-weight: bold; + -moz-border-radius: 4px 4px 4px 4px; +} +.paramkey { + text-align: right; + color: #ffffff; +} +.paramtype { + white-space: nowrap; + color: #aaaaaa; +} +.paramname { + color: #ff0000; + font-style: italic; + white-space: nowrap; +} +/* End Styling for detailed member documentation */ + +/* for the tree view */ +.ftvtree { + font-family: sans-serif; + margin:0.5em; +} +/* these are for tree view when used as main index */ +.directory { + font-size: 9pt; + font-weight: bold; +} +.directory h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} + +/* The following two styles can be used to replace the root node title */ +/* with an image of your choice. Simply uncomment the next two styles, */ +/* specify the name of your image and be sure to set 'height' to the */ +/* proper pixel height of your image. */ + +/* .directory h3.swap { */ +/* height: 61px; */ +/* background-repeat: no-repeat; */ +/* background-image: url("yourimage.gif"); */ +/* } */ +/* .directory h3.swap span { */ +/* display: none; */ +/* } */ + +.directory > h3 { + margin-top: 0; +} +.directory p { + margin: 0px; + white-space: nowrap; +} +.directory div { + display: none; + margin: 0px; +} +.directory img { + vertical-align: -30%; +} +/* these are for tree view when not used as main index */ +.directory-alt { + font-size: 100%; + font-weight: bold; +} +.directory-alt h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} +.directory-alt > h3 { + margin-top: 0; +} +.directory-alt p { + margin: 0px; + white-space: nowrap; +} +.directory-alt div { + display: none; + margin: 0px; +} +.directory-alt img { + vertical-align: -30%; +} + diff --git a/doc/img/emotion_ratio.eps b/doc/img/emotion_ratio.eps new file mode 100644 index 0000000..624196b --- /dev/null +++ b/doc/img/emotion_ratio.eps @@ -0,0 +1,4541 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: (ImageMagick) +%%Title: (bla.eps) +%%CreationDate: (2011-08-04T18:14:47-03:00) +%%BoundingBox: -0 -0 566 174 +%%HiResBoundingBox: 0 0 565.663 174 +%%DocumentData: Clean7Bit +%%LanguageLevel: 1 +%%Pages: 1 +%%EndComments + +%%BeginDefaults +%%EndDefaults + +%%BeginProlog +% +% Display a color image. The image is displayed in color on +% Postscript viewers or printers that support color, otherwise +% it is displayed as grayscale. +% +/DirectClassPacket +{ + % + % Get a DirectClass packet. + % + % Parameters: + % red. + % green. + % blue. + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/DirectClassImage +{ + % + % Display a DirectClass image. + % + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { DirectClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayDirectClassPacket } image + } ifelse +} bind def + +/GrayDirectClassPacket +{ + % + % Get a DirectClass packet; convert to grayscale. + % + % Parameters: + % red + % green + % blue + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/GrayPseudoClassPacket +{ + % + % Get a PseudoClass packet; convert to grayscale. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassPacket +{ + % + % Get a PseudoClass packet. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassImage +{ + % + % Display a PseudoClass image. + % + % Parameters: + % class: 0-PseudoClass or 1-Grayscale. + % + currentfile buffer readline pop + token pop /class exch def pop + class 0 gt + { + currentfile buffer readline pop + token pop /depth exch def pop + /grays columns 8 add depth sub depth mul 8 idiv string def + columns rows depth + [ + columns 0 0 + rows neg 0 rows + ] + { currentfile grays readhexstring pop } image + } + { + % + % Parameters: + % colors: number of colors in the colormap. + % colormap: red, green, blue color packets. + % + currentfile buffer readline pop + token pop /colors exch def pop + /colors colors 3 mul def + /colormap colors string def + currentfile colormap readhexstring pop pop + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { PseudoClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayPseudoClassPacket } image + } ifelse + } ifelse +} bind def + +/DisplayImage +{ + % + % Display a DirectClass or PseudoClass image. + % + % Parameters: + % x & y translation. + % x & y scale. + % label pointsize. + % image label. + % image columns & rows. + % class: 0-DirectClass or 1-PseudoClass. + % compression: 0-none or 1-RunlengthEncoded. + % hex color packets. + % + gsave + /buffer 512 string def + /byte 1 string def + /color_packet 3 string def + /pixels 768 string def + + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + x y translate + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + currentfile buffer readline pop + token pop /pointsize exch def pop + /Times-Roman findfont pointsize scalefont setfont + x y scale + currentfile buffer readline pop + token pop /columns exch def + token pop /rows exch def pop + currentfile buffer readline pop + token pop /class exch def pop + currentfile buffer readline pop + token pop /compression exch def pop + class 0 gt { PseudoClassImage } { DirectClassImage } ifelse +} bind def +%%EndProlog +%%Page: 1 1 +%%PageBoundingBox: 0 0 566 174 +userdict begin +DisplayImage +0 0 +565.663 173.619 +12 +707 217 +1 +1 +1 +8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000FFFFFF +FFFFFF0000000000000000FFFFFFFFFFFF0000000000000000FFFFFFFFFFFF0000000000 +00000000FFFFFFFFFFFF0000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000FFFFFFFFFF +000000000000000000FFFFFFFFFFFF0000000000000000FFFFFFFFFFFF00000000000000 +00FFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF00060B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B +0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B +0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B +0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B +0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B05FFFFFFFFFFFFFFFFFFFF00 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFF0000000000000000FFFF +FFFFFFFF0000000000000000FFFFFFFFFFFF000000000000000000FFFFFFFFFFFF000000 +0000081B607F7F7F7F7F7F471B1B1B1B1B1B4A7F7F7F7F7F7F5D1B1B1B1B1B1B317F7F7F +7F7F7F731B1B1B1B1B1B1B7F7F7F7F7F7F7F251B1B1B1B1B1B6A7F7F7F7F7F7F3E1B1B1B +1B1B1B547F7F7F7F7F7F541B1B1B1B1B1B3E7F7F7F7F7F7F6A1B1B1B1B1B1B257F7F7F7F +7F7F7F1B1B1B1B1B1B1B737F7F7F7F7F7F341B1B1B1B1B1B5D7F7F7F7F7F7F4A1B1B1B1B +1B1B477F7F7F7F7F7F601B1B1B1B1B1B210AFFFFFFFFFF000000000000000000FFFFFFFF +FFFF0000000000000000FFFFFFFFFFFF0000000000000000FFFFFFFFFFFF000000000000 +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0005868686 +868686868686868686868686868686868686868686868686868686868686868686868686 +868686868686868686868686868686868686868686868686868686868686868686868686 +868686868686868686868686868686868686868686868686868686868686868686868686 +868686868686868686868686868686868686868686868686868686868686868686868686 +868686868686868686868600FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003E +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +07CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00 +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +3ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFF +FFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC92 +10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007 +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF0000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00 +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FF +FFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003E +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFF +FFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFF +FFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +07CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF +00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00 +FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +3ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC07 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFF +FFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFF +FFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC3AA988673788B9EB0CACCCCCCCC9210FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBC9EA6C3CCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFF +FF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC763939393939A7CCCC +CCCCCC773939393939CACCCCCCCCCCCCCCCCCCCC57393939393939393939393A424E5964 +6F81A6C9CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC3A39393939393939 +393939393939393939393939393939393939ACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCAE71350400000000000000000E4884BECC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC845F5F86CCCCCCCC +CCCCCCCCCCCCCCCCCCCC825F5F8CCCCCCC675F5FB4CCCCCCCCCC975F5F5F5F5F606A7E92 +B8CCCCCCCCCCCCCCCCCCCCCCCCCCCC6F5F5F5F5F5F5F5F5F5F5F5F5F5F6BCCCCCCCCCCCC +CCCCCCCCCA7E1900000001309DCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCA140000000012C9CCCCCCCCCC560000000000CACCCCCC +CCCCCCCCCCCCCC2A000000000000000000000000000000000000062A5287C7CCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC000000000000000000000000000000000000000000 +00000000009FCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA737000000000000000000000000 +000000055C8A10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC66000027CCCCCCCCCCCCCCCCCCCCCCCCCCCC1F0000 +74CCCCCC0E00009ECCCCCCCCCC6800000000000000000002337AC7CCCCCCCCCCCCCCCCCC +CCCC1E0000000000000000000000000015CCCCCCCCCCCCCCCCCCBD2A0000000000000000 +56CBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +9000000000005ECCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000000000 +0000000000000000000000000000000000105CADCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC00000000000000000000000000000000000000000000000000009FCCCCCCCCCCCCCC +CCCCCCCCCCCCCCB94E020000000000000000000000000000000000000B09FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC92000003C5CCCCCCCCCCCCCCCCCCCCCCCCBF010000A0CCCCCC0E00009ECCCCCCCCCC +6800000000000000000000000026A8CCCCCCCCCCCCCCCCCCCC1E00000000000000000000 +00000015CCCCCCCCCCCCCCCCBC250000000000000000000050CBCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC430000000000ABCCCCCCCCCCCC +560000000000CACCCCCCCCCCCCCCCCCCCC2A000000000000000000000000000000000000 +0000000000000043BBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0000000000000000000000 +0000000000000000000000000000009FCCCCCCCCCCCCCCCCCCCCCCCCCCAA160000000000 +0000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBD0000009ECCCCCCCCCCCC +CCCCCCCCCCCC95000005C6CCCCCC0E00009ECCCCCCCCCC68000000000000000000000000 +00058CCCCCCCCCCCCCCCCCCC1E0000000000000000000000000015CCCCCCCCCCCCCCCC3A +00000000000000000000000073CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCBD05000000002DCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCC +CCCCCCCC2A0000000003121212121212120900000000000000000000000000128CCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCC000000000000000000000000000000000000000000000000 +00009FCCCCCCCCCCCCCCCCCCCCCCCC9D0E000000000000001E628A9EB2AC98824D0E0000 +00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC1D000072CCCCCCCCCCCCCCCCCCCCCCCC6A00002ACCCCCC +CC0E00009ECCCCCCCCCC6800000000000000000000000000000AA8CCCCCCCCCCCCCCCC1E +0000000000000000000000000015CCCCCCCCCCCCCC86000000001061867D4E030000000A +B6CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFF +FFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC75000000 +00007ACCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCC +CCCCCCCCCCCABFB28A5E310400000000000000005ACCCCCCCCCCCCCCCCCCCCCCCCCCCC00 +0000000052CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC9B0700000000000032A5CCCCCCCCCCCCCCCCCCC9861300000000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +49000047CCCCCCCCCCCCCCCCCCCCCCCC3E000056CCCCCCCC0E00009ECCCCCCCCCC680000 +40BFBFBFBDA88F4E09000000001AC5CCCCCCCCCCCCCC1E000074A6A6A6A6A6A6A6A6A6A6 +AACCCCCCCCCCCCC4130000003EBFCCCCCCCCAA1900000046CCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC280000000008C1CCCCCCCCCCCCCC560000 +000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCB866 +13000000000000006FCCCCCCCCCCCCCCCCCCCCCCCCCC000000000052CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBE160000000000067CCBCCCCCC +CCCCCCCCCCCCCCCCCCBF4A000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC7500001CCCCCCCCCCCCCCCCCCC +CCCCCC13000082CCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCCCCCCBD3C000000 +0074CCCCCCCCCCCCCC1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC7D0000002EC6 +CCCCCCCCCCCCAB0E000002B6CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003DCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCA700000000004ACCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCC +CC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC75C0000000000000189CCCCCC +CCCCCCCCCCCCCCCCCC000000000052CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC4100000000000693CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCB5200 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCA1000000BDCCCCCCCCCCCCCCCCCCCCB4000000AECCCCCCCC0E00 +009ECCCCCCCCCC68000044CCCCCCCCCCCCCCCCCB5300000016C7CCCCCCCCCCCC1E00008E +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC29000003ADCCCCCCCCCCCCCCCC7600000067CC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFF +FFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF002ACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC5A000000000098CC +CCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCC8E0B000000000008B8CCCCCCCCCCCCCCCCCCCCCC00000000 +0052CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC7E000000 +00000290CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCB3400FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC70500 +0092CCCCCCCCCCCCCCCCCCCC8900000ECBCCCCCCCC0E00009ECCCCCCCCCC68000044CCCC +CCCCCCCCCCCCCCC72A00000084CCCCCCCCCCCC1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCA200000052CCCCCCCCCCCCCCCCCCC81D000017CBCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC8E595974CCCCCCCCCCCCCCCCCCCC +CCCCCCCC80595985CCCCCC6A5959AACCCCCCCCCC9D5959595959595E687286ADCACCCCCC +CCCCCCCCCCCCCCCCCC72595959595959595959595959595DCCCCCCCCCCCCCCCCCCCCB170 +361B080A1E3D78B9CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0013CCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCC811000000001ACBCCCCCCCCCCCCCCCC560000000000 +CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +8F01000000000059CCCCCCCCCCCCCCCCCCCCCC000000000052CCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1D000000000056CCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC8B02FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC2B000067CCCCCCCCCCCCCCCCCCCC5E +000039CCCCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCCCCCCCCCCCC9E00000048 +CCCCCCCCCCCC1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC66000000ABCCCCCCCCCC +CCCCCCCCCC6F000000A6CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC9A000004BBCCCCCCCCCCCCCCCCCCCCCCCCC60E00008ACCCCCC1D00 +008FCCCCCCCCCC7700000000000000000000000A4899CCCCCCCCCCCCCCCCCCCC2D000000 +0000000000000000000006CCCCCCCCCCCCCCCCB950020000000000000000065FC2CCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0001BACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC8C000000000067CCCCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A00 +00000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC66000000000006B8CCCCCCCC +CCCCCCCCCCCC000000000052CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCC8C000000000016C2CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC920BFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC5700003CCCCCCCCCCCCCCCCCCCCC32000064CCCCCCCCCC0E00009ECC +CCCCCCCC68000044CCCCCCCCCCCCCCCCCCCCCC2A000010CACCCCCCCCCC1E00008ECCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC3300002ACCCCCCCCCCCCCCCCCCCCCCB602000074CCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFF +FFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC1D0000 +72CCCCCCCCCCCCCCCCCCCCCCCC88000010C8CCCCCC1D00008FCCCCCCCCCC770000000000 +00000000000000000030AFCCCCCCCCCCCCCCCC2D0000000000000000000000000006CCCC +CCCCCCCCCCAC17000000093B514E360500000026B9CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF000070CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC3E0000000002B4CCCCCCCCCC +CCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCA1A00000000005BCCCCCCCCCCCCCCCCCCCC000000000052CC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC3200000000007ACC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007 +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC83000011CC +CCCCCCCCCCCCCCCCCA09000090CCCCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCC +CCCCCCCCCCCC78000000A2CCCCCCCCCC1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6 +0600006DCCCCCCCCCCCCCCCCCCCCCCCC2D000042CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6A000026CCCCCCCCCCCCCCCCCCCCCCCC +3B00005ACCCCCCCC1D00008FCCCCCCCCCC77000033C6C6C6C5BBAF8E61170000000897CC +CCCCCCCCCCCC2D000073B9B9B9B9B9B9B9B9B9B9BACCCCCCCCCCCCB21000000B73C4CCCC +CCCCBE620500001EC1CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000023CCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCBA030000000037CCCCCCCCCCCCCCCCCCCC560000000000CACCCC +CCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC75 +00000000001ACCCCCCCCCCCCCCCCCCCC000000000052CCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCB0000000000008C1CCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCAF000000B2CCCCCCCCCCCCCCCCA8000000BB +CCCCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCCCCCCCCCCCCCCAE0000007ACCCC +CCCCCC1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9E0000009ACCCCCCCCCCCCCCCCCC +CCCCCC5A000012CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCB6020000A6CCCCCCCCCCCCCCCCCCCCB7020000A7CCCCCCCC1D00008FCC +CCCCCCCC77000035CCCCCCCCCCCCCCCCCA7C0800000DACCCCCCCCCCCCC2D00007FCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCC82C000011AACCCCCCCCCCCCCCCC9707000048CCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000A3CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC710000 +00000085CCCCCCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A00000000 +29CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC30D0000000000B5CCCCCCCCCCCC +CCCCCC000000000052CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC8000000000004BCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCC0F000087CCCCCCCCCCCCCCCC7D00001ACCCCCCCCCCCC0E00009ECCCCCCCC +CC68000044CCCCCCCCCCCCCCCCCCCCCCCC1600005DCCCCCCCCCC1E00008ECCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC81000002C4CCCCCCCCCCCCCCCCCCCCCCCC86000000C2CCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00 +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC3A000059CC +CCCCCCCCCCCCCCCCCC6D000029CCCCCCCCCC1D00008FCCCCCCCCCC77000035CCCCCCCCCC +CCCCCCCCCCA206000039CCCCCCCCCCCC2D00007FCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +770000019ACCCCCCCCCCCCCCCCCCCC7E0000009ACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00000056CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC23000000000DC6CCCCCCCCCCCCCCCCCC +CC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC3F000000000082CCCCCCCCCCCCCCCCCC000000000052CCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC51000000000089CCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC3A00005CCCCCCC +CCCCCCCCCC52000046CCCCCCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCCCCCCCC +CCCCCCCC3C000041CCCCCCCCCC1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCC66000020 +CCCCCCCCCCCCCCCCCCCCCCCCCCAB000000A6CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC88000010C8CCCCCCCCCCCCCCCCCC20000076 +CCCCCCCCCC1D00008FCCCCCCCCCC77000035CCCCCCCCCCCCCCCCCCCCCC76000000A2CCCC +CCCCCC2D00007FCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCB1E00004ECCCCCCCCCCCCCCCCCC +CCCCCB2C00003FCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000EC7CCCCCCCCCCCCCC +CCCCCCCCCCCCA2000000000055CCCCCCCCCCCCCCCCCCCCCC560000000000CACCCCCCCCCC +CCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6D0000 +0000004FCCCCCCCCCCCCCCCCCC000000000052CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC220000000000B2CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC66000031CCCCCCCCCCCCCCCC26000072CCCCCCCC +CCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCCCCCCCCCCCCCCCC55000024CCCCCCCCCC +1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCC4A000037CCCCCCCCCCCCCCCCCCCCCCCCCC +C30000008BCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FF +FFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCC70F00008BCCCCCCCCCCCCCCCC9F000006BECCCCCCCCCC1D00008FCCCCCCCC +CC77000035CCCCCCCCCCCCCCCCCCCCCCC71400005BCCCCCCCCCC2D00007FCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC9E000000A4CCCCCCCCCCCCCCCCCCCCCCCC81000002BECCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000000089CCCCCCCCCCCCCCCCCCCCCCCCCC550000000000A2 +CCCCCCCCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9B00000000002ECCCCCCCCCCCCCCCCCC +000000000052CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC30100 +0000000ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC92000008CACCCCCCCCCCCCC40300009ECCCCCCCCCCCC0E00009ECCCCCCCCCC6800 +0044CCCCCCCCCCCCCCCCCCCCCCCC6E00000ECCCCCCCCCC1E00008ECCCCCCCCCCCCCCCCCC +CCCCCCCCCCCC3000004ECCCCCCCCCCCCCCCCCCCCCCCCCCCC0E000071CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC5800003ECCCCCC +CCCCCCCCCC52000046CCCCCCCCCCCC1D00008FCCCCCCCCCC77000035CCCCCCCCCCCCCCCC +CCCCCCCC54000028CCCCCCCCCC2D00007FCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6C000018 +CCCCCCCCCCCCCCCCCCCCCCCCCCC10100008FCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +00003CCCCCCCCCCCCCCCCCCCCCCCCCC60E0000000024CCCCCCCCCCCCCCCCCCCCCCCC5600 +00000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCBB000000000021CCCCCCCCCCCCCCCCCC00000000001739393939393939 +39393939393939393939393995CCCCCCCCCCCCCCB200000000002FCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBE000000A7CCCCCCCCCC +CC9C000004C6CCCCCCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCCCCCCCCCCCCCC +CC82000006CCCCCCCCCC1E00004766666666666666666666A4CCCCCCCC26000064CCCCCC +CCCCCCCCCCCCCCCCCCCCCC23000066CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA6000003BACCCCCCCCCCCCC50C000094CCCCCCCC +CCCC1D00008FCCCCCCCCCC77000035CCCCCCCCCCCCCCCCCCCCCCCC80000002CACCCCCCCC +2D00007FCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC40000042CCCCCCCCCCCCCCCCCCCCCCCCCC +CC1F000062CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000002B9CCCCCCCCCCCCCCCCCC +CCCC87000000000072CCCCCCCCCCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCC +CCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC90000000000 +12CCCCCCCCCCCCCCCCCC000000000000000000000000000000000000000000000000007F +CCCCCCCCCCCCCCA300000000003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCC1D00007CCCCCCCCCCCCC71000029CCCCCCCCCCCCCC0E +00009ECCCCCCCCCC68000044CCCCCCCCCCCCCCCCCCCCCCCC8B000000CBCCCCCCCC1E0000 +00000000000000000000007BCCCCCCCC1F00006DCCCCCCCCCCCCCCCCCCCCCCCCCCCC2C00 +005ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFF +FFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCC28000072CCCCCCCCCCCC84000017CACCCCCCCCCCCC1D00008FCCCCCCCCCC7700 +0035CCCCCCCCCCCCCCCCCCCCCCCC9A000000BECCCCCCCC2D000000000000000000000000 +006CCCCCCCCC2F00005DCCCCCCCCCCCCCCCCCCCCCCCCCCCC3A00004FCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF00000000006ECCCCCCCCCCCCCCCCCCCCCC3A0000000004BBCCCCCCCC +CCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0A0000000004CCCCCCCCCCCCCCCCCC000000 +000000000000000000000000000000000000000000007FCCCCCCCCCCCCCC940000000000 +4ACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC49000051CCCCCCCCCCCC46000055CCCCCCCCCCCCCC0E00009ECCCCCCCCCC68000044CC +CCCCCCCCCCCCCCCCCCCCCC94000000C4CCCCCCCC1E000000000000000000000000007BCC +CCCCCC18000074CCCCCCCCCCCCCCCCCCCCCCCCCCCC33000055CCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC76000024CCCCCCCCCC +CC37000063CCCCCCCCCCCCCC1D00008FCCCCCCCCCC77000035CCCCCCCCCCCCCCCCCCCCCC +CCA9000000B0CCCCCCCC2D000000000000000000000000006CCCCCCCCC2200006ACCCCCC +CCCCCCCCCCCCCCCCCCCCCC46000041CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000 +22CCCCCCCCCCCCCCCCCCCCB6020000000042CCCCCCCCCCCCCCCCCCCCCCCCCC5600000000 +00CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCC160000000000C2CCCCCCCCCCCCCCCC00000000000000000000000000000000 +0000000000000000007FCCCCCCCCCCCCCC85000000000056CCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC75000026CCCCCCCCCCCC1A00 +0080CCCCCCCCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCCCCCCCCCCCCCCCC9C00 +0000BDCCCCCCCC1E000000000000000000000000007BCCCCCCCC1200007ACCCCCCCCCCCC +CCCCCCCCCCCCCCCC3A00004DCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCBE060000A4CCCCCCCCB5020001B0CCCCCCCCCCCCCC1D +00008FCCCCCCCCCC77000035CCCCCCCCCCCCCCCCCCCCCCCCAA000000AECCCCCCCC2D0000 +2B464646464646464646468ECCCCCCCC2000006CCCCCCCCCCCCCCCCCCCCCCCCCCCCC4A00 +003DCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000A2CCCCCCCCCCCCCCCCCC6C00 +000000008FCCCCCCCCCCCCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A +0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC160000000000C4CC +CCCCCCCCCCCCCC000000000000000000000000000000000000000000000000007FCCCCCC +CCCCCCCC83000000000056CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCA1000002C4CCCCCCCCBB000000ACCCCCCCCCCCCCCC0E00009E +CCCCCCCCCC68000044CCCCCCCCCCCCCCCCCCCCCCCC9E000000BACCCCCCCC1E0000000000 +00000000000000007BCCCCCCCC0E00007ECCCCCCCCCCCCCCCCCCCCCCCCCCCC3D000049CC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFF +FFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC46000057CCCCCCCC69000032CCCCCCCCCCCCCCCC1D00008FCCCCCCCCCC77000035CC +CCCCCCCCCCCCCCCCCCCCCC9C000000BCCCCCCCCC2D00007FCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC2C000060CCCCCCCCCCCCCCCCCCCCCCCCCCCC3E00004CCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00000000000054CCCCCCCCCCCCCCCCCC1F0000000014CACCCCCCCCCCCCCCCC +CCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC090000000007CCCCCCCCCCCCCCCCCC000000000052 +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9200000000004ACCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +07CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC706 +00009CCCCCCCCC9000000CCBCCCCCCCCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCC +CCCCCCCCCCCCCCCC97000000C2CCCCCCCC1E00006F9F9F9F9F9F9F9F9F9F9FBACCCCCCCC +14000078CCCCCCCCCCCCCCCCCCCCCCCCCCCC36000051CCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9400000FC7CCCCCC1D0000 +80CCCCCCCCCCCCCCCC1D00008FCCCCCCCCCC77000035CCCCCCCCCCCCCCCCCCCCCCCC8500 +0001C9CCCCCCCC2D00007FCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC3A00004ACCCCCCCCCCCC +CCCCCCCCCCCCCCCC2700005CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000E000000000EC6 +CCCCCCCCCCCCCC9E00000000005ECCCCCCCCCCCCCCCCCCCCCCCCCCCC560000000000CACC +CCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCC8000000000016CCCCCCCCCCCCCCCCCC000000000052CCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCA200000000003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC2C000071CCCCCCCC65000036CCCC +CCCCCCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCCCCCCCCCCCCCCCC8E000000C9 +CCCCCCCC1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCC1B000071CCCCCCCCCCCCCCCCCC +CCCCCCCCCC30000059CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCA1700008ACCCC9B00000AC3CCCCCCCCCCCCCCCC1D00008F +CCCCCCCCCC77000035CCCCCCCCCCCCCCCCCCCCCCCC5A000022CCCCCCCCCC2D00007FCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC60000022CCCCCCCCCCCCCCCCCCCCCCCCCCC704000084CC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0026000000000087CCCCCCCCCCCCCC510000000000 +ADCCCCCCCCCCCCCCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A000000 +0029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBB000000000026CCCCCCCCCC +CCCCCCCC000000000052CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCB1000000000032CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC58000046CCCCCCCC3A000062CCCCCCCCCCCCCCCC0E00009ECCCCCC +CCCC68000044CCCCCCCCCCCCCCCCCCCCCCCC86000004CCCCCCCCCC1E00008ECCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC2200006ACCCCCCCCCCCCCCCCCCCCCCCCCCCC29000061CCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF +00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +6300003DCCCC4E00004FCCCCCCCCCCCCCCCCCC1D00008FCCCCCCCCCC77000035CCCCCCCC +CCCCCCCCCCCCCCCA1E000054CCCCCCCCCC2D00007FCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +91000001B3CCCCCCCCCCCCCCCCCCCCCCCC92000000B6CCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF003B09000000003ACCCCCCCCCCCCC50B000000002ECCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC9A000000000035CCCCCCCCCCCCCCCCCC000000000052CCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC1000000000012CCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC8400001A +CCCCCCCC0E00008ECCCCCCCCCCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCCCCCC +CCCCCCCCCC7700000BCCCCCCCCCC1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCC290000 +5ACCCCCCCCCCCCCCCCCCCCCCCCCCCC1A00006ACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCB1010003BAC30A00009DCCCCCC +CCCCCCCCCCCC1D00008FCCCCCCCCCC77000035CCCCCCCCCCCCCCCCCCCCCC8900000093CC +CCCCCCCC2D00007FCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC40E000063CCCCCCCCCCCCCCCC +CCCCCCCC4100002BCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003E4C0000000002B7CCCC +CCCCCC8200000000007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC560000000000CACCCCCCCC +CCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6C00 +0000000057CCCCCCCCCCCCCCCCCC000000000052CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCC1B0000000000B6CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCB0000000BCCCCCAF000000BACCCCCCCCCC +CCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCCCCCCCCCCCCCCCC5F00001ACCCCCCCC +CC1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCC3B000043CCCCCCCCCCCCCCCCCCCCCCCC +CCCA0400007DCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00 +FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC330000708000001ECCCCCCCCCCCCCCCCCCCC1D00008FCCCCCC +CCCC77000035CCCCCCCCCCCCCCCCCCCCB61200002ACCCCCCCCCCCC2D00007FCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC60000008B1CCCCCCCCCCCCCCCCCCCC9A00000086CCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF003E9A00000000006DCCCCCCCCCC360000000008C2CCCCCC +CCCCCCCCCCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC3F00000000008ACCCCCCCCCCCCCCCC +CC000000000052CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC4A +00000000008DCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCC0F000091CCCC84000019CCCCCCCCCCCCCCCCCC0E00009ECCCCCCCCCC68 +000044CCCCCCCCCCCCCCCCCCCCCCCC46000036CCCCCCCCCC1E00008ECCCCCCCCCCCCCCCC +CCCCCCCCCCCCCC5700002CCCCCCCCCCCCCCCCCCCCCCCCCCCB800000098CCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC8200 +00233300006CCCCCCCCCCCCCCCCCCCCC1D00008FCCCCCCCCCC77000035CCCCCCCCCCCCCC +CCCCA1190000049BCCCCCCCCCCCC2D00007FCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBB14 +000026BECCCCCCCCCCCCCCCCB11600002BC9CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +3ECC1D0000000020CCCCCCCCB301000000004CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC56 +0000000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCC40D0000000000BBCCCCCCCCCCCCCCCCCC000000000052CCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC7A000000000053CCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC3A000066CCCC +59000045CCCCCCCCCCCCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCCCCCCCCCCCC +CCCC2A000052CCCCCCCCCC1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCC7200000FCCCC +CCCCCCCCCCCCCCCCCCCCCC9B000000B4CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC40B0000000002B7CCCCCCCCCCCCCC +CCCCCC1D00008FCCCCCCCCCC77000035CCCCCCCCCCCCB4873B0100000081CCCCCCCCCCCC +CC2D00007FCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC970200001F9DCCCCCCCCCCCC8D14 +000009AECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC07 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECC6A00000000009FCCCCCC67 +00000000009ACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCC +CCCCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC760000000000 +22CCCCCCCCCCCCCCCCCCCC000000000052CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCAA00000000000CC5CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6600003ACCCC2D000071CCCCCCCCCCCCCCCCCC +0E00009ECCCCCCCCCC68000044CCCCCCCCCCCCCCCCCCCCCCC20300006ECCCCCCCCCC1E00 +008ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCC8E000000B1CCCCCCCCCCCCCCCCCCCCCCCC7000 +0005CACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFF +FFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC51000000003BCCCCCCCCCCCCCCCCCCCCCC1D00008FCCCCCCCCCC77 +0000081F1F1F1E150900000000001795CCCCCCCCCCCCCCCC2D00000B1212121212121212 +1212129ECCCCCCCCCCCC8A060000002B627B795E220000000F9ECCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF003ECCB6020000000052CCCCCB1B000000001CCBCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1D000000000061CCCCCCCCCCCCCCCCCCCC0000 +00000052CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC260000 +00000082CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCC92000010CCC80600009CCCCCCCCCCCCCCCCCCC0E00009ECCCCCCCCCC68000044 +CCCCCCCCCCCCCCCCCCCCCC900000008ECCCCCCCCCC1E00008ECCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCB200000085CCCCCCCCCCCCCCCCCCCCCCCC44000028CCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9F000000 +008ACCCCCCCCCCCCCCCCCCCCCC1D00008FCCCCCCCCCC7700000000000000000000000027 +76C2CCCCCCCCCCCCCCCCCC2D000000000000000000000000000099CCCCCCCCCCCCCCA128 +0000000000000000000036AECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCC +3A000000000DC6CC9A000000000069CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC56000000 +0000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC6A000000000008BBCCCCCCCCCCCCCCCCCCCC000000000052CCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC8100000000001EC6CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC920CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBE000000B1A3000003 +C5CCCCCCCCCCCCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCCCCCCCCCCCCCC5100 +0003C0CCCCCCCCCC1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC1800004ECCCCCCCC +CCCCCCCCCCCCCCCA1200005ACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC45323239C7CCCCCCCCCCCCCCCCCCCCCC +4932329ECCCCCCCCCC8D323232323232384551668DB5CCCCCCCCCCCCCCCCCCCCCCCC5532 +32323232323232323232323232A6CCCCCCCCCCCCCCCCCB87430A00000000104B94CCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCC88000000000086CC4C00000000 +02B5CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC +2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC940200000000005BCCCCCC +CCCCCCCCCCCCCCCC000000000052CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCC714000000000062CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC8E02 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC1E00008678000027CCCCCCCCCCCCCCCCCCCC0E0000 +9ECCCCCCCCCC68000044CCCCCCCCCCCCCCCCCCCCBE0800002FCCCCCCCCCCCC1E00008ECC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC4B00000CC6CCCCCCCCCCCCCCCCCCCC940000008CCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFF +FFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCBBEAEAFC0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF003ECCCCC70F0000000038C2090000000039CCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC940E000000000008B9CCCCCCCCCCCCCCCCCCCCCC0000000000 +52CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC7000000000 +00049ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC3E00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC4A00005A4D000052CCCCCCCCCCCCCCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCC +CCCCCCCCCCCCCC6600000069CCCCCCCCCCCC1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC7E00000086CCCCCCCCCCCCCCCCCCCC4A000002BECCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCC5800 +0000000267000000000086CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC560000000000CA +CCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9620100 +000000000189CCCCCCCCCCCCCCCCCCCCCCCC000000000052CCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA3100000000000BA1CCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCC630000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC7600002F2100007ECCCCCC +CCCCCCCCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCCCCCCCCCC9C03000002B0CC +CCCCCCCCCC1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC008000022CACCCCCCCCCC +CCCCCCAE0300003BCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCA6000000000002000000000EC6CCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000 +000029CCCCCCCCCCCCCCCCCCCCCCCCCCCCBC6C180000000000000070CCCCCCCCCCCCCCCC +CCCCCCCCCC000000000052CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCB40E00000000000D8FCCCCCCCCCCCCCCCCCCCCCCCCCCC65D000000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCA2000006010000AACCCCCCCCCCCCCCCCCCCC0E00009ECCCC +CCCCCC68000044CCCCCCCCCCCCCCCC98120000004ACCCCCCCCCCCCCC1E00008ECCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC5000000078CCCCCCCCCCCCCCCC3E0000008ECCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFF +FF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF003ECCCCCCCC2800000000000000000056CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000000029CCCCCCCCCCCCCCCCCCC6 +B89164370600000000000000005ACCCCCCCCCCCCCCCCCCCCCCCCCCCC000000000052CCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC8A0200000000 +000044B6CCCCCCCCCCCCCCCCCCCC991F00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC7 +06000000000BCACCCCCCCCCCCCCCCCCCCC0E00009ECCCCCCCCCC68000044CCCCCCCCCCCC +AA580200000002ADCCCCCCCCCCCCCC1E00008ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +A50000000596CCCCCCCCCCCC6100000016CACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCC76000000 +000000000000A4CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC560000000000CACCCCCC +CCCCCCCCCCCCCC2A0000000005191919191919180F040000000000000000000000000F88 +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC000000000002060606060606060606060606060606 +06060606063ECCCCCCCCCCCCCCCCCCCCCCCC89060000000000000232759EB2C5BFAB9660 +1E000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC2C0000000035CCCCCCCCCCCCCC +CCCCCCCC0E00009ECCCCCCCCCC6800001A4C4C4C4A351C0000000000006BCCCCCCCCCCCC +CCCC1E0000283939393939393939393939B2CCCCCCCCCCCC43000000086DC7CCCCB94900 +0000007ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCBE060000000000000026CCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCCCCCCCCCC2A0000000000 +00000000000000000000000000000000000000003BB8CCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC000000000000000000000000000000000000000000000000000039CCCCCCCCCCCCCC +CCCCCCCCCCCC990C00000000000000000000000000000000000000000000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC580000000061CCCCCCCCCCCCCCCCCCCCCC0E00009ECCCCCCCCCC +68000000000000000000000000000048CCCCCCCCCCCCCCCCCC1E00000000000000000000 +00000000A8CCCCCCCCCCCCB70B0000000006261D020000000031CBCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +003ECCCCCCCCCC460000000000000073CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +560000000000CACCCCCCCCCCCCCCCCCCCC2A000000000000000000000000000000000000 +000000000C54A4CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0000000000000000000000 +00000000000000000000000000000039CCCCCCCCCCCCCCCCCCCCCCCCCCCCAA3600000000 +0000000000000000000000000000000407FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC840000 +00008DCCCCCCCCCCCCCCCCCCCCCC0E00009ECCCCCCCCCC68000000000000000000000000 +0055C6CCCCCCCCCCCCCCCCCC1E0000000000000000000000000000A8CCCCCCCCCCCCCC7E +00000000000000000000000CABCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCC940000000000 +0005BDCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC560000000000CACCCCCCCCCCCC +CCCCCCCC2A00000000000000000000000000000000000003254C83C5CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCC000000000000000000000000000000000000000000000000 +000039CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9325000000000000000000000000000000 +01478010FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCB000000000B8CCCCCCCCCCCCCCCCCCCC +CC0E00009ECCCCCCCCCC6800000000000000000000001B90CCCCCCCCCCCCCCCCCCCCCC1E +0000000000000000000000000000A8CCCCCCCCCCCCCCCC750000000000000000000EA2CC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFF +FFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCA3E32323232325ECCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC733232323232CACCCCCCCCCCCCCCCCCCCC523232323232323232 +3232333B47525E6A7BA2C6CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC33 +323232323232323232323232323232323232323232323232325ECCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCA9A5E22000000000000000000043571AECC9210FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC10000017CCCCCCCCCCCCCCCCCCCCCCCC0E00009ECCCCCCCCCC680000 +000000000A1E325AA0CCCCCCCCCCCCCCCCCCCCCCCCCC1E00000000000000000000000000 +00A8CCCCCCCCCCCCCCCCCC871900000000000032A8CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCB497 +85726065788A9DC1CCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC7 +7E53323B5C96CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC92 +10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFF +FFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFF +FFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007 +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00 +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FF +FFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003E +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFF +FFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFF +FFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +07CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF +00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC0700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00 +FFFFFFFFFFFFFFFFFFFF00CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0700FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00C6C6 +C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 +C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 +C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 +C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6C6 +C6C6C6C6C6C6C6C6C6C6C6C60700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +3ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF01030303030303030303030303030303 +030303030303030303030303030303030303030303030303030303030303030303030303 +030303030303030303030303030303030303030303030303030303030303030303030303 +030303030303030303030303030303030303030303030303030303030303030303030303 +030303030303030303030303030303030303030303030303030303030303030303030301 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFF +FFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC92 +10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007 +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003E +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +07CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF003ECCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCC00FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003ECCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCC9210FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0007CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC00 +FFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000 +FFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFF00 +00000000000000FFFFFFFFFF001715151515151533757575757575631515151515151F75 +757575757575191515151515156A7575757575752E151515151515517575757575754315 +15151515153D75757575757557151515151515287575757575756F151515151515157275 +7575757575251515151515155D75757575757539151515151515467575757575754E1515 +1515151530757575757575671515151515151B757575757575751B0F010000000000FFFF +FFFFFFFF0000000000000000FFFFFFFFFFFF0000000000000000FFFFFFFFFFFF00000000 +00000000FFFFFFFFFFFF000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF0006ACACACACACACACACACACACACACACACACACACACACACACACACACACACAC +ACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACAC +ACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACAC +ACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACAC +ACACACACACACACACACACACACACACACACACACACACACAC00FFFFFFFFFFFFFFFFFFFF000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFF00000000000000 +00FFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFF0000000000000000FFFFFFFFFF00 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000FFFFFFFFFFFF0000000000000000FF +FFFFFFFFFF0000000000000000FFFFFFFFFFFF0000000000000000FFFFFFFFFFFF000000 +000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00060B0B0B0B0B +0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B +0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B +0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B +0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B +0B0B0B0B0B0B0B0B0B05FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000000000FF00000000 +000000FFFFFFFF00000000000000000000000000000000000000FFFF00000000000000FF +FF0000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +000000000000000000000000000000000000FF0000000000000000FFFFFF000000000000 +00000000000000000000000000000000000000000000FFFF0000FFFFFFFFFF000000FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFF0000FFFFFFFF0000 +00FFFFFFFFFF0000FFFFFF000000FFFFFF0000FFFFFFFFFFFFFFFFFFFF000000FFFFFFFF +00000000FFFFFF0000FFFF0000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF0000FFFFFF0000 +00FFFFFF0000FFFFFFFFFFFFFFFFFFFF000000FFFFFF00000000FFFFFFFFFFFFFFFF0000 +FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FF +FFFFFFFFFFFFFFFF000000FFFFFFFFFF0000FFFFFF000000FFFFFF0000FFFFFFFFFFFFFF +FFFFFF000000FFFFFF000000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFF000000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFFFF000000FFFF +FFFFFF0000000000000000FFFFFF0000000000000000FFFFFFFF000000FFFFFF000000FF +FFFFFFFFFFFFFFFF00000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00000000000000FFFFFFFF000000FFFFFFFFFF00000000000000FFFFFF +FF0000000000000000FFFFFFFF000000FFFFFF000000FFFFFFFFFFFFFFFFFF0000000000 +0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 +00FFFFFFFF000000FFFFFFFFFF0000000000000000FFFFFF0000FFFFFFFFFFFFFFFFFFFF +000000FFFFFF000000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFF000000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000000000000000FF000000FFFF000000FFFFFFFFFFFF000000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFF000000FFFFFFFFFF +0000FFFFFF000000FFFFFF0000FFFFFFFFFFFFFFFFFFFF000000FFFFFF000000FFFFFFFF +FFFFFFFFFF0000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000 +00FFFF0000FF0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000 +FF000000FFFF000000FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFF000000FFFFFFFF000000FFFFFFFFFF0000FFFFFFFF000000FFFF0000 +FFFFFFFFFFFFFFFFFFFF000000FFFFFFFF000000FFFFFFFFFF00FFFF0000FFFFFFFFFF00 +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000FFFF0000FF00000000000000 +00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFF000000FFFF000000FFFFFFFF +FFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000FFFF +FFFF000000FFFFFFFFFF0000FFFFFFFF000000FFFF0000000000000000FFFFFFFF000000 +FFFFFFFF000000000000000000FFFF0000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF000000FFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF000000FFFFFFFFFFFF000000FFFF000000FFFFFFFFFFFF000000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFF000000FFFFFFFFFF0000FF +FFFFFFFF000000FF0000000000000000FFFFFFFF000000FFFFFFFFFF0000000000000000 +FFFF0000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFF +0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFF0000 +00FFFF000000FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFF000000FFFF000000FFFFFFFFFFFF00 +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000000000000000FFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +000000000000FFFF000000FFFF000000FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000FFFF0000FF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFF000000FFFF +000000FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFF000000FFFF000000FFFFFFFFFFFF000000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 +FFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF +FFFFFFFFFF000000FFFF000000FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFF0000FFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFF000000FFFF000000 +0000000000FF0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF000000FFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF000000FFFFFFFFFFFF000000FFFF0000000000000000FF00000000000000 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFF +FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFF0000FFFFFFFFFF0000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +end +%%PageTrailer +%%Trailer +%%EOF diff --git a/doc/img/emotion_ratio.png b/doc/img/emotion_ratio.png new file mode 100644 index 0000000000000000000000000000000000000000..4ae37fde7647ecd03923e060b2603e1de198b7a0 GIT binary patch literal 12950 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 GLK6Ub>Mc;VkfoEM{Qf z76xHPhFNnYfP(BLp1!W^H+WcuRXD>A=l%i;Wq7(chG?8W+i%Esz<`6f_y7NWHH!5o z63R1{^0cb0vMSkFaE_%x<+7O{*?Xs&Ff%xKT5jO&GtAqcqoa~}b>qg&H07ky z617wnX2HUfTT*8{kPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iOZ8 z6%`IG`XD&~00I3;L_t(o!^Kz8j>8}fODg_+AF{uksuh}hxC0rJP`W$mkkHl^jB%XM z>f`Y+`Dtd>`gxwMmr`2KIk$cshdiH8N#}XW6$o}5WA?p%5)sKc%eHO9fR!#HlFUqU z&XQ6Z1~3DUmCHm#rjx?$lu|lm24QA+Eh4g2CJ}X<;QbGo;J_$CohD|s1Tu}z3KIrH zRtpQ8-Z|UyQP4caCB~&Z3QG0mMzcQLYIcQ!(sFW-xf9knF@|(?iY~XAOhHzd%#8OD2m>x}XSSsVf@;^obfpX48<@ZgFF$M4@xtjbM#B=Ojp!9yfFNKXj22K7STvD?00000NkvXXu0mjfB76)l literal 0 HcmV?d00001 diff --git a/doc/img/header_menu_current_background.png b/doc/img/header_menu_current_background.png new file mode 100644 index 0000000000000000000000000000000000000000..de97c9268e4ac68310c8b92d6ab6bd8a245611da GIT binary patch literal 1200 zcmV;h1W)^kP)002J-1^@s6XaB>y00001b5ch_0Itp) z=>Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RT3Fc5TrKj#zpOzs?z2=A0p@aw&u*pMn|G)ug+?Vh;0+zHe5dVLoF=!DBW&zJ?E zp99|S_j0@4%Io#|xG+sqdB5NP{rn5Cj%O+78UIn|DpKcsK9>`B2V6JsOB3oD&r;4a z{-e%Sw9ela{A&{jdu5*U-Tgr1~ zQc-ZvZCmQQrCnTG+COg8zWQ3Lv1sjNIKQPlR|Xsq_}(oT0MbDS91lPg3>xeBFKokrh3I+f~!N36>5GNtP zFb=56FWNP#oK=?bNEQ~!rtXW9X1GX=k~FL`OjOeF$R)LGB-wAZi(5xddgID^{pUl5 z$!2zVWE!iC5c%CAFL=jfl{TW1M$7Wjcr9z}SyPKmlC20r0B}G6Q80PClsJ^eQ9Rdb zuHflIJ5saoBdvW)J5o7`LrQ$sb0li*FS@pt^@$vLe#kJ^<1ntHwKLacEE8!V_VYY{ z^jk0Fa-9o0ILfhhgnDcg*`~%yk#UNgFLkMLQ1xp&>oHLMt>=krgKLZ9aoj&)eVyWk z+VI9yb#%knV zBgOT1iW^1q->g9a$6utrxv^4Ql-s5#yS%xS5>LwpJyaYZ1w-06F426k%%gi2p;YTL zn*Zi$*TU&q<}Gq{z5F%GPa}Dt9$}k233)sorIb>h&nNZ+VE-)`LNtIN1b_p=0f8Pk zSwvore6GJZg3A%uh&UU`%8A$z3ApNcvGym`^9BW5y;mkO7OVYaI#wj=im2;bzSt*w z8j*3rXhhk-tiA%ik?Y6P7yM_$}>d^Cl%aa8a!%A!J=gv)gqCjA%RAmjShY zk&jin$jBj)wrhPzE#o_v^@kLW;DnK~k;Uxogc+{8mlL+=3tKP%4hR4$2Lynj z95C}RO)LJ$<@I?2i7h|tH#%lcU&}tk-(ol0<1_foFDdWsgqjV%=7cRA;M<%KLNw4f z2!R6vT{&RuTk7799C>JZ4;!>{ThW;;ZOYD_SA%VO2ZR&C3B68;Eg1NXEf@e0gaF^` zfS#=57JO;X{zkCF($|*uL^8|wn48N;fkQ7R9I3CpA0+QRH%LYRy5b)R!`g7p731Il O0000002J-1^@s6XaB>y00001b5ch_0Itp) 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 + + + + diff --git a/emotion.manifest b/emotion.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/emotion.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/emotion.pc.in b/emotion.pc.in index f628489..5126c3b 100644 --- a/emotion.pc.in +++ b/emotion.pc.in @@ -5,8 +5,7 @@ includedir=@includedir@ Name: emotion Description: Emotion evas based multimedia library -Requires: evas +@pkgconfig_requires_private@: @requirement_emotion@ Version: @VERSION@ Libs: -L${libdir} -lemotion -Libs.private: @EDJE_LIBS@ @ECORE_LIBS@ @XINE_LIBS@ @GST_LIBS@ -Cflags: -I${includedir} +Cflags: -I${includedir}/emotion-@VMAJ@ diff --git a/emotion.spec.in b/emotion.spec.in index cc08edf..c6fa495 100644 --- a/emotion.spec.in +++ b/emotion.spec.in @@ -1,3 +1,4 @@ +%{!?_rel:%{expand:%%global _rel 0.enl%{?dist}}} %define _missing_doc_files_terminate_build 0 Summary: emotion @@ -65,10 +66,12 @@ test "x$RPM_BUILD_ROOT" != "x/" && rm -rf $RPM_BUILD_ROOT %files devel %defattr(-, root, root) %doc doc/html -%{_includedir}/*.h +%{_includedir}/emotion-1/*.h %{_libdir}/libemotion.a %{_libdir}/libemotion.la %{_libdir}/libemotion.so +%{_libdir}/edje/modules/emotion/*/module.la +%{_libdir}/edje/modules/emotion/*/module.so #%{_libdir}/xine/plugins/*/xineplug_vo_out_emotion.a #%{_libdir}/xine/plugins/*/xineplug_vo_out_emotion.la %{_libdir}/pkgconfig/%{name}.pc diff --git a/m4/ac_attribute.m4 b/m4/ac_attribute.m4 new file mode 100644 index 0000000..3926d23 --- /dev/null +++ b/m4/ac_attribute.m4 @@ -0,0 +1,46 @@ +dnl Copyright (C) 2004-2008 Kim Woelders +dnl Copyright (C) 2008 Vincent Torri +dnl That code is public domain and can be freely used or copied. +dnl Originally snatched from somewhere... + +dnl Macro for checking if the compiler supports __attribute__ + +dnl Usage: AC_C___ATTRIBUTE__ +dnl call AC_DEFINE for HAVE___ATTRIBUTE__ and __UNUSED__ +dnl if the compiler supports __attribute__, HAVE___ATTRIBUTE__ is +dnl defined to 1 and __UNUSED__ is defined to __attribute__((unused)) +dnl otherwise, HAVE___ATTRIBUTE__ is not defined and __UNUSED__ is +dnl defined to nothing. + +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"] + )] +) + +AC_MSG_RESULT($ac_cv___attribute__) + +if test "x${ac_cv___attribute__}" = "xyes" ; then + AC_DEFINE([HAVE___ATTRIBUTE__], [1], [Define to 1 if your compiler has __attribute__]) + AC_DEFINE([__UNUSED__], [__attribute__((unused))], [Macro declaring a function argument to be unused]) + else + AC_DEFINE([__UNUSED__], [], [Macro declaring a function argument to be unused]) +fi + +]) diff --git a/m4/efl_binary.m4 b/m4/efl_binary.m4 new file mode 100644 index 0000000..b9c9fd1 --- /dev/null +++ b/m4/efl_binary.m4 @@ -0,0 +1,44 @@ +dnl Copyright (C) 2010 Vincent Torri +dnl That code is public domain and can be freely used or copied. + +dnl Macro that check if a binary is built or not + +dnl Usage: EFL_ENABLE_BIN(binary[, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Call AC_SUBST(BINARY_PRG) (BINARY is the uppercase of binary, - being transformed into _) +dnl Define have_binary (- is transformed into _) +dnl Define conditional BUILD_BINARY (BINARY is the uppercase of binary, - being transformed into _) + +AC_DEFUN([EFL_ENABLE_BIN], +[ + +m4_pushdef([UP], m4_translit([[$1]], [-a-z], [_A-Z]))dnl +m4_pushdef([DOWN], m4_translit([[$1]], [-A-Z], [_a-z]))dnl + +have_[]m4_defn([DOWN])="yes" + +dnl configure option + +AC_ARG_ENABLE([$1], + [AC_HELP_STRING([--disable-$1], [disable building of ]DOWN)], + [ + if test "x${enableval}" = "xyes" ; then + have_[]m4_defn([DOWN])="yes" + else + have_[]m4_defn([DOWN])="no" + fi + ]) + +AC_MSG_CHECKING([whether to build ]DOWN[ binary]) +AC_MSG_RESULT([$have_[]m4_defn([DOWN])]) + +if test "x$have_[]m4_defn([DOWN])" = "xyes"; then + UP[]_PRG=DOWN[${EXEEXT}] +fi + +AC_SUBST(UP[]_PRG) + +AM_CONDITIONAL(BUILD_[]UP, test "x$have_[]m4_defn([DOWN])" = "xyes") + +AS_IF([test "x$have_[]m4_defn([DOWN])" = "xyes"], [$2], [$3]) + +]) diff --git a/m4/efl_doxygen.m4 b/m4/efl_doxygen.m4 new file mode 100644 index 0000000..7324af3 --- /dev/null +++ b/m4/efl_doxygen.m4 @@ -0,0 +1,94 @@ +dnl Copyright (C) 2008 Vincent Torri +dnl That code is public domain and can be freely used or copied. + +dnl Macro that check if doxygen is available or not. + +dnl EFL_CHECK_DOXYGEN([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Test for the doxygen program +dnl Defines efl_doxygen +dnl Defines the automake conditionnal EFL_BUILD_DOC +dnl +AC_DEFUN([EFL_CHECK_DOXYGEN], +[ + +dnl +dnl Disable the build of the documentation +dnl +AC_ARG_ENABLE([doc], + [AC_HELP_STRING( + [--disable-doc], + [Disable documentation build @<:@default=enabled@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + efl_enable_doc="yes" + else + efl_enable_doc="no" + fi + ], + [efl_enable_doc="yes"]) + +AC_MSG_CHECKING([whether to build documentation]) +AC_MSG_RESULT([${efl_enable_doc}]) + +if test "x${efl_enable_doc}" = "xyes" ; then + +dnl Specify the file name, without path + + efl_doxygen="doxygen" + + AC_ARG_WITH([doxygen], + [AC_HELP_STRING( + [--with-doxygen=FILE], + [doxygen program to use @<:@default=doxygen@:>@])], + +dnl Check the given doxygen program. + + [efl_doxygen=${withval} + AC_CHECK_PROG([efl_have_doxygen], + [${efl_doxygen}], + [yes], + [no]) + if test "x${efl_have_doxygen}" = "xno" ; then + echo "WARNING:" + echo "The doxygen program you specified:" + echo "${efl_doxygen}" + echo "was not found. Please check the path and make sure " + echo "the program exists and is executable." + AC_MSG_WARN([no doxygen detected. Documentation will not be built]) + fi + ], + [AC_CHECK_PROG([efl_have_doxygen], + [${efl_doxygen}], + [yes], + [no]) + if test "x${efl_have_doxygen}" = "xno" ; then + echo "WARNING:" + echo "The doxygen program was not found in your execute path." + echo "You may have doxygen installed somewhere not covered by your path." + echo "" + echo "If this is the case make sure you have the packages installed, AND" + echo "that the doxygen program is in your execute path (see your" + echo "shell manual page on setting the \$PATH environment variable), OR" + echo "alternatively, specify the program to use with --with-doxygen." + AC_MSG_WARN([no doxygen detected. Documentation will not be built]) + fi + ]) +else + efl_have_doxygen="no" +fi + +dnl +dnl Substitution +dnl +AC_SUBST([efl_doxygen]) + +if ! test "x${efl_have_doxygen}" = "xyes" ; then + efl_enable_doc="no" +fi + +AM_CONDITIONAL(EFL_BUILD_DOC, test "x${efl_have_doxygen}" = "xyes") + +AS_IF([test "x$efl_have_doxygen" = "xyes"], [$1], [$2]) +]) + +dnl End of efl_doxygen.m4 diff --git a/m4/efl_edje_external.m4 b/m4/efl_edje_external.m4 new file mode 100644 index 0000000..703f83e --- /dev/null +++ b/m4/efl_edje_external.m4 @@ -0,0 +1,56 @@ +dnl Copyright (C) 2010-2011 Vincent Torri +dnl That code is public domain and can be freely used or copied. + +dnl Macro that check if edje external should be enabled or not + +dnl Usage: EFL_EDJE_EXTERNAL([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Call AC_SUBST(EDJE_EXTERNAL_CFLAGS) +dnl Call AC_SUBST(EDJE_EXTERNAL_LIBS) +dnl Define conditional ENABLE_EDJE_EXTERNAL + +AC_DEFUN([EFL_EDJE_EXTERNAL], +[ + +AC_ARG_ENABLE([edje-external], + [AC_HELP_STRING([--disable-edje-external], + [disable providing Edje EXTERNAL support. @<:@default=enabled@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + _efl_want_edje_external="yes" + else + _efl_want_edje_external="no" + fi + ], + [_efl_want_edje_external="auto"]) + +AC_MSG_CHECKING([if should provide Edje EXTERNAL support...]) +AC_MSG_RESULT([${_efl_want_edje_external}]) + +_efl_enable_edje_external="no" +if ! test "x${_efl_want_edje_external}" = "xno" ; then + PKG_CHECK_MODULES([EDJE_EXTERNAL], + [edje >= 1.0.0], + [_efl_enable_edje_external="yes"], + [_efl_enable_edje_external="no"]) +fi + +AC_SUBST(EDJE_EXTERNAL_CFLAGS) +AC_SUBST(EDJE_EXTERNAL_LIBS) + +if test "x${_efl_want_edje_external}" = "xyes" && test "x${_efl_enable_edje_external}" = "xno" ; then + AC_MSG_ERROR([Edje EXTERNAL support requested, but Edje not found by pkg-config.]) +fi + +if test "x${_efl_enable_edje_external}" = "xyes" ; then + EDJE_VERSION=`${PKG_CONFIG} edje --modversion | awk -F . '{printf("%s.0.0", $[]1);}'` + MODULE_EDJE="$host_os-$host_cpu-${EDJE_VERSION}" + AC_DEFINE_UNQUOTED(MODULE_EDJE, "$MODULE_EDJE", "Edje module architecture") +fi + +AC_SUBST(MODULE_EDJE) + +AM_CONDITIONAL([ENABLE_EDJE_EXTERNAL], [test "x${_efl_enable_edje_external}" = "xyes"]) + +AS_IF([test "x${_efl_enable_edje_external}" = "xyes"], [$1], [$2]) + +]) diff --git a/m4/efl_examples.m4 b/m4/efl_examples.m4 new file mode 100644 index 0000000..2a809ad --- /dev/null +++ b/m4/efl_examples.m4 @@ -0,0 +1,63 @@ +dnl Copyright (C) 2008 Vincent Torri +dnl That code is public domain and can be freely used or copied. + +dnl Macro that check if building examples is wanted. + +dnl Usage: EFL_CHECK_BUILD_EXAMPLES([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Defines the automake conditionnal EFL_ENABLE_BUILD_EXAMPLES + +AC_DEFUN([EFL_CHECK_BUILD_EXAMPLES], +[ + +dnl configure option + +AC_ARG_ENABLE([build-examples], + [AC_HELP_STRING([--enable-build-examples], [enable building examples @<:@default=disabled@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + _efl_enable_build_examples="yes" + else + _efl_enable_build_examples="no" + fi + ], + [_efl_enable_build_examples="no"]) + +AC_MSG_CHECKING([whether examples are built]) +AC_MSG_RESULT([${_efl_enable_build_examples}]) + +AM_CONDITIONAL(EFL_BUILD_EXAMPLES, test "x${_efl_enable_build_examples}" = "xyes") + +AS_IF([test "x$_efl_enable_build_examples" = "xyes"], [$1], [$2]) +]) + + +dnl Macro that check if installing examples is wanted. + +dnl Usage: EFL_CHECK_INSTALL_EXAMPLES([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Defines the automake conditionnal EFL_ENABLE_INSTALL_EXAMPLES + +AC_DEFUN([EFL_CHECK_INSTALL_EXAMPLES], +[ + +dnl configure option + +AC_ARG_ENABLE([install-examples], + [AC_HELP_STRING([--enable-install-examples], [enable installing example source files @<:@default=disabled@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + _efl_enable_install_examples="yes" + else + _efl_enable_install_examples="no" + fi + ], + [_efl_enable_install_examples="no"]) + +AC_MSG_CHECKING([whether examples are installed]) +AC_MSG_RESULT([${_efl_enable_install_examples}]) + +AM_CONDITIONAL(EFL_INSTALL_EXAMPLES, test "x${_efl_enable_install_examples}" = "xyes") + +AS_IF([test "x$_efl_enable_install_examples" = "xyes"], [$1], [$2]) +]) + +dnl End of efl_examples.m4 diff --git a/m4/efl_shm_open.m4 b/m4/efl_shm_open.m4 new file mode 100644 index 0000000..0bf1b0b --- /dev/null +++ b/m4/efl_shm_open.m4 @@ -0,0 +1,69 @@ +dnl Copyright (C) 2010 Vincent Torri +dnl That code is public domain and can be freely used or copied. + +dnl Macro that check if shm_open function is available or not. + +dnl Usage: EFL_CHECK_SHM_OPEN([, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl Call AC_SUBST(EFL_SHM_OPEN_LIBS) +dnl Define HAVE_SHM_OPEN to 1if shm_open is available + +AC_DEFUN([EFL_CHECK_SHM_OPEN], +[ +_efl_have_shm_open="no" + +dnl Check is shm_open is in libc + +AC_MSG_CHECKING([for shm_open in libc]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include /* For mode constants */ +#include /* For O_* constants */ + ]], + [[ +int fd; + +fd = shm_open("/dev/null", O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO); + ]])], + [_efl_have_shm_open="yes"], + [_efl_have_shm_open="no"]) + +AC_MSG_RESULT([${_efl_have_shm_open}]) + +if test "x$_efl_have_shm_open" = "xno" ; then + AC_MSG_CHECKING([for shm_open in librt]) + + LIBS_save="${LIBS}" + LIBS="${LIBS} -lrt" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include +#include /* For mode constants */ +#include /* For O_* constants */ + ]], + [[ +int fd; + +fd = shm_open("/dev/null", O_RDONLY, S_IRWXU | S_IRWXG | S_IRWXO); + ]])], + [ + EFL_SHM_OPEN_LIBS="-lrt" + _efl_have_shm_open="yes"], + [_efl_have_shm_open="no"]) + + LIBS="${LIBS_save}" + + AC_MSG_RESULT([${_efl_have_shm_open}]) +fi + +AC_SUBST([EFL_SHM_OPEN_LIBS]) + +if test "x$_efl_have_shm_open" = "xyes" ; then + AC_DEFINE([HAVE_SHM_OPEN], [1], [Define to 1 if you have the `shm_open' function.]) +fi + +AS_IF([test "x$_efl_have_shm_open" = "xyes"], [$1], [$2]) + +]) diff --git a/m4/emotion_check.m4 b/m4/emotion_check.m4 new file mode 100644 index 0000000..043ae44 --- /dev/null +++ b/m4/emotion_check.m4 @@ -0,0 +1,216 @@ + +dnl use: EMOTION_CHECK_DEP_XINE(want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) + +AC_DEFUN([EMOTION_CHECK_DEP_XINE], +[ + +requirement="" + +PKG_CHECK_MODULES([XINE], + [libxine >= 1.1.1 evas >= 1.0.0], + [ + have_dep="yes" + requirement="libxine" + ], + [have_dep="no"]) + +if test "x$1" = "xstatic" ; then + requirement_emotion="${requirement} ${requirement_emotion}" +fi + +AS_IF([test "x$have_dep" = "xyes"], [$2], [$3]) + +]) + +dnl use: EMOTION_CHECK_DEP_GSTREAMER(want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) + +AC_DEFUN([EMOTION_CHECK_DEP_GSTREAMER], +[ + +GST_REQS=0.10.2 +GSTPLUG_REQS=0.10.1 +GST_MAJORMINOR=0.10 + +requirement="" +PKG_CHECK_MODULES([GSTREAMER], + [gstreamer-$GST_MAJORMINOR >= $GST_REQS gstreamer-plugins-base-$GST_MAJORMINOR >= $GSTPLUG_REQS gstreamer-video-$GST_MAJORMINOR >= $GSTPLUG_REQS evas >= 1.0.0 eina >= 1.1.99], + [ + have_dep="yes" + requirement="gstreamer-$GST_MAJORMINOR gstreamer-plugins-base-$GST_MAJORMINOR" + ], + [have_dep="no"]) + +if test "x$1" = "xstatic" ; then + requirement_emotion="${requirement} ${requirement_emotion}" +fi + +AS_IF([test "x$have_dep" = "xyes"], [$2], [$3]) + +]) + +dnl use: EMOTION_CHECK_DEP_GENERIC_VLC(want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) + +AC_DEFUN([EMOTION_CHECK_DEP_GENERIC_VLC], +[ + +requirement="" + +PKG_CHECK_MODULES([GENERIC_VLC], + [libvlc >= 0.9 eina >= 1.1.99], + [ + have_dep="yes" + requirement="libvlc" + ], + [have_dep="no"]) + +if test "x$1" = "xstatic" ; then + requirement_emotion="${requirement} ${requirement_emotion}" +fi + +AS_IF([test "x$have_dep" = "xyes"], [$2], [$3]) + +]) + +dnl use: EMOTION_CHECK_DEP_GENERIC(want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) + +AC_DEFUN([EMOTION_CHECK_DEP_GENERIC], +[ + +requirement="" + +PKG_CHECK_MODULES([GENERIC], + [evas >= 1.0.0], + [ + have_dep="yes" + ], + [have_dep="no"]) + +if test "x$1" = "xstatic" ; then + requirement_emotion="${requirement} ${requirement_emotion}" +fi + +AS_IF([test "x$have_dep" = "xyes"], [$2], [$3]) + +]) + +dnl use: EMOTION_CHECK_MODULE(description, want_module[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +AC_DEFUN([EMOTION_CHECK_MODULE], +[ +m4_pushdef([UP], m4_translit([$1], [-a-z], [_A-Z]))dnl +m4_pushdef([DOWN], m4_translit([$1], [-A-Z], [_a-z]))dnl + +want_module="$2" + +AC_ARG_ENABLE([DOWN], + [AC_HELP_STRING([--enable-]DOWN, [enable build of $1 module @<:@default=yes@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + enable_module="yes" + else + if test "x${enableval}" = "xstatic" ; then + enable_module="static" + else + enable_module="no" + fi + fi + ], + [enable_module="yes"]) + +if test "x${enable_module}" = "xyes" || test "x${enable_module}" = "xstatic" ; then + want_module="yes" +fi + +have_module="no" +if test "x${want_module}" = "xyes" && (test "x${enable_module}" = "xyes" || test "x${enable_module}" = "xstatic") ; then + m4_default([EMOTION_CHECK_DEP_]m4_defn([UP]))(${enable_module}, [have_module="yes"], [have_module="no"]) +fi + +AC_MSG_CHECKING([whether to enable $1 module built]) +AC_MSG_RESULT([${have_module}]) + +static_module="no" +if test "x${have_module}" = "xyes" && test "x${enable_module}" = "xstatic" ; then + static_module="yes" +fi + +AM_CONDITIONAL(EMOTION_BUILD_[]UP, [test "x${have_module}" = "xyes"]) +AM_CONDITIONAL(EMOTION_STATIC_BUILD_[]UP, [test "x${static_module}" = "xyes"]) + +if test "x${static_module}" = "xyes" ; then + AC_DEFINE(EMOTION_STATIC_BUILD_[]UP, 1, [Set to 1 if $1 is statically built]) + have_static_module="yes" +fi + +enable_[]DOWN="no" +if test "x${have_module}" = "xyes" ; then + enable_[]DOWN=${enable_module} + AC_DEFINE(EMOTION_BUILD_[]UP, 1, [Set to 1 if $1 is built]) +fi + +AS_IF([test "x$have_module" = "xyes"], [$3], [$4]) + +m4_popdef([UP]) +m4_popdef([DOWN]) +]) + +dnl use: EMOTION_CHECK_GENERIC_PLAYER(description, want_module[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +AC_DEFUN([EMOTION_CHECK_GENERIC_PLAYER], +[ +m4_pushdef([UP], m4_translit([$1], [-a-z], [_A-Z]))dnl +m4_pushdef([DOWN], m4_translit([$1], [-A-Z], [_a-z]))dnl + +want_module="$2" + +AC_ARG_ENABLE(generic-[]DOWN, + [AC_HELP_STRING([--enable-generic-]DOWN, [enable build of Generic Player $1 @<:@default=yes@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + enable_module="yes" + else + enable_module="no" + fi + ], + [enable_module="auto"]) + +# shm_open +EFL_CHECK_SHM_OPEN([have_shm_open="yes"], [have_shm_open="no"]) + +if test "x${have_shm_open}" != "xyes"; then + enable_generic="no" +fi + +if test "x${enable_generic}" != "xyes" && test "x${enable_generic}" != "xstatic"; then + if test "x${enable_module}" = "xyes"; then + AC_MSG_WARN([Generic module is disabled, force disable of Generic Player $1]) + fi + enable_module="no" + want_module="no" +fi + +if test "x${enable_module}" = "xauto"; then + enable_module="${want_module}" +elif test "x${enable_module}" = "xyes"; then + want_module="yes" +fi + +have_module="no" +if test "x${want_module}" = "xyes" && test "x${enable_module}" = "xyes"; then + m4_default([EMOTION_CHECK_DEP_GENERIC_]m4_defn([UP]))(${enable_module}, [have_module="yes"], [have_module="no"]) +fi + +AC_MSG_CHECKING([Whether to enable Generic Player $1]) +AC_MSG_RESULT([${have_module}]) + +AM_CONDITIONAL(EMOTION_BUILD_GENERIC_[]UP, [test "x${have_module}" = "xyes"]) + +enable_generic_[]DOWN="no" +if test "x${have_module}" = "xyes" ; then + enable_generic_[]DOWN=${enable_module} + AC_DEFINE(EMOTION_BUILD_GENERIC_[]UP, 1, [Set to 1 if $1 is built]) +fi + +AS_IF([test "x$have_module" = "xyes"], [$3], [$4]) + +m4_popdef([UP]) +m4_popdef([DOWN]) +]) diff --git a/packaging/emotion.spec b/packaging/emotion.spec new file mode 100644 index 0000000..30b06c7 --- /dev/null +++ b/packaging/emotion.spec @@ -0,0 +1,107 @@ +Name: emotion +Summary: Media Library +Version: 1.7.1+svn.76438+build01r01 +Release: 1 +Group: System Environment/Libraries +License: BSD +URL: http://www.enlightenment.org/ +Source0: %{name}-%{version}.tar.gz +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig +BuildRequires: eina-devel +BuildRequires: eet-devel +BuildRequires: evas-devel +BuildRequires: ecore-devel +BuildRequires: edje-devel +BuildRequires: edje-bin +BuildRequires: gstreamer-devel +BuildRequires: gst-plugins-base-devel + + +%description +Video playback library used in Enlightenment DR0.17 + This is the emotion library, a wrapper library used in the next-generation + Enlightenment suite for video playback. + . + This package contains the shared libraries. + + +%package devel +Summary: Emotion headers, static libraries, documentation and test programs +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version} +Requires: eet-devel evas-devel edje-devel + + +%description devel +Headers, static libraries, test programs and documentation for Emotion + + +%package gstreamer +Summary: Video playback library used in Enlightenment DR0.17 +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version} +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + + +%description gstreamer +Video playback library used in Enlightenment DR0.17 +This is the emotion library, a wrapper library used in the next-generation +Enlightenment suite for video playback. +. +This package provides the gstreamer module for emotion. + +%prep +%setup -q + +%build + +%autogen +%configure --enable-static \ + --disable-rpath --enable-xine=no --disable-doc +make %{?jobs:-j%jobs} + + +%install +rm -rf %{buildroot} +%make_install +mkdir -p %{buildroot}/usr/share/license +cp %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name} + + +%post -p /sbin/ldconfig + + +%postun -p /sbin/ldconfig + + +%post gstreamer -p /sbin/ldconfig + + +%postun gstreamer -p /sbin/ldconfig + + +%files +%defattr(-,root,root,-) +%{_libdir}/libemotion.so.* +%{_bindir}/emotion_* +%{_datadir}/emotion/data/*.edj +%{_libdir}/emotion +%{_libdir}/edje/modules/emotion/*/module.so +%manifest %{name}.manifest +/usr/share/license/%{name} +%manifest %{name}.manifest + + +%files devel +%defattr(-, root, root) +%{_includedir}/* +%{_libdir}/pkgconfig/emotion*.pc +%{_libdir}/libemotion.so + + +%files gstreamer +%defattr(-, root, root) +%{_libdir}/emotion/*gstreamer*.so +%manifest %{name}-gstreamer.manifest diff --git a/src/Makefile.am b/src/Makefile.am index 2ab111e..4082c3a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,12 @@ MAINTAINERCLEANFILES = Makefile.in -SUBDIRS = lib bin modules +SUBDIRS = lib bin modules examples + +if ENABLE_EDJE_EXTERNAL +SUBDIRS += edje_external +endif + +if EMOTION_BUILD_GENERIC +SUBDIRS += generic_players +endif diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index a90d598..79dd4e3 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -7,16 +7,20 @@ AM_CPPFLAGS = \ -DPACKAGE_BIN_DIR=\"$(bindir)\" \ -DPACKAGE_LIB_DIR=\"$(libdir)\" \ -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ -@EVAS_CFLAGS@ \ -@ECORE_CFLAGS@ \ -@EDJE_CFLAGS@ +@EMOTION_CFLAGS@ \ +@EMOTION_CPPFLAGS@ \ +@EMOTION_BIN_CFLAGS@ \ +@ECORE_X_CFLAGS@ \ +@ECORE_FB_CFLAGS@ -bin_PROGRAMS = \ -emotion_test +bin_PROGRAMS = -emotion_test_SOURCES = \ -emotion_test_main.c +if BUILD_EMOTION_TEST -emotion_test_LDADD = \ -@EVAS_LIBS@ @ECORE_LIBS@ @EDJE_LIBS@ \ -$(top_builddir)/src/lib/libemotion.la +bin_PROGRAMS += emotion_test + +endif + +emotion_test_SOURCES = emotion_test_main.c + +emotion_test_LDADD = @ECORE_X_CFLAGS@ @ECORE_FB_CFLAGS@ @EMOTION_BIN_LIBS@ $(top_builddir)/src/lib/libemotion.la diff --git a/src/bin/emotion_test_main.c b/src/bin/emotion_test_main.c index 16bb1a5..13380d6 100644 --- a/src/bin/emotion_test_main.c +++ b/src/bin/emotion_test_main.c @@ -1,22 +1,45 @@ -#include "config.h" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include #include #include -#if defined(HAVE_ECORE_X_H) || defined(HAVE_ECORE_FB_H) - #include #include -#ifndef FB_ONLY -#include -#else -#include -#endif +#include #include #include #include "Emotion.h" +static const Ecore_Getopt options = { + "emotion_test", + "%prog [options] ", + "1.0.0", + "(C) 2011 Enlightenment", + "BSD\nThis is a 3 clause bsd bla bla", + "a simple test program for emotion.", + 1, + { + ECORE_GETOPT_STORE_STR('e', "engine", "ecore-evas engine to use"), + ECORE_GETOPT_CALLBACK_NOARGS('E', "list-engines", "list ecore-evas engines", + ecore_getopt_callback_ecore_evas_list_engines, NULL), + ECORE_GETOPT_CALLBACK_ARGS('g', "geometry", "geometry to use in x:y:w:h form.", "X:Y:W:H", + ecore_getopt_callback_geometry_parse, NULL), + ECORE_GETOPT_STORE_STR('b', "backend", "backend to use"), + ECORE_GETOPT_STORE_INT('v', "vis", "visualization type"), + ECORE_GETOPT_COUNT('v', "verbose", "be more verbose"), + ECORE_GETOPT_STORE_TRUE('R', "reflex", "show video reflex effect"), + ECORE_GETOPT_VERSION('V', "version"), + ECORE_GETOPT_COPYRIGHT('R', "copyright"), + ECORE_GETOPT_LICENSE('L', "license"), + ECORE_GETOPT_HELP('h', "help"), + ECORE_GETOPT_SENTINEL + } +}; + typedef struct _Frame_Data Frame_Data; struct _Frame_Data @@ -27,10 +50,8 @@ struct _Frame_Data Evas_Coord x, y; }; -static int main_start(int argc, char **argv); -static void main_stop(void); static void main_resize(Ecore_Evas *ee); -static int main_signal_exit(void *data, int ev_type, void *ev); +static Eina_Bool main_signal_exit(void *data, int ev_type, void *ev); static void main_delete_request(Ecore_Evas *ee); static void bg_setup(void); @@ -45,125 +66,35 @@ static Evas *evas = NULL; static int startw = 800; static int starth = 600; -static Evas_List *video_objs = NULL; - -static int -main_start(int argc, char **argv) -{ - int mode = 0; - - start_time = ecore_time_get(); - if (!ecore_init()) return -1; - ecore_app_args_set(argc, (const char **)argv); - ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, main_signal_exit, NULL); - if (!ecore_evas_init()) return -1; -#ifndef FB_ONLY - { - int i; - - for (i = 1; i < argc; i++) - { - if (((!strcmp(argv[i], "-g")) || - (!strcmp(argv[i], "-geometry")) || - (!strcmp(argv[i], "--geometry"))) && (i < (argc - 1))) - { - int n, w, h; - char buf[16], buf2[16]; - - n = sscanf(argv[i +1], "%10[^x]x%10s", buf, buf2); - if (n == 2) - { - w = atoi(buf); - h = atoi(buf2); - startw = w; - starth = h; - } - i++; - } - else if (!strcmp(argv[i], "-gl")) - { - mode = 1; - } - else if (!strcmp(argv[i], "-fb")) - { - mode = 2; - } - else if (!strcmp(argv[i], "-xr")) - { - mode = 3; - } - } - } -#if HAVE_ECORE_EVAS_X - if (mode == 0) - ecore_evas = ecore_evas_software_x11_new(NULL, 0, 0, 0, startw, starth); -#endif -#if HAVE_ECORE_EVAS_X11_GL - if (mode == 1) - ecore_evas = ecore_evas_gl_x11_new(NULL, 0, 0, 0, startw, starth); -#endif -#if HAVE_ECORE_EVAS_FB - if (mode == 2) - ecore_evas = ecore_evas_fb_new(NULL, 0, startw, starth); -#endif - if (mode == 3) - ecore_evas = ecore_evas_xrender_x11_new(NULL, 0, 0, 0, startw, starth); - -#else - startw = 240; - starth = 320; - ecore_evas = ecore_evas_fb_new(NULL, 270, startw, starth); -#endif - if (!ecore_evas) return -1; - ecore_evas_callback_delete_request_set(ecore_evas, main_delete_request); - ecore_evas_callback_resize_set(ecore_evas, main_resize); - ecore_evas_title_set(ecore_evas, "Evas Media Test Program"); - ecore_evas_name_class_set(ecore_evas, "evas_media_test", "main"); - ecore_evas_show(ecore_evas); - evas = ecore_evas_get(ecore_evas); - evas_image_cache_set(evas, 8 * 1024 * 1024); - evas_font_cache_set(evas, 1 * 1024 * 1024); - evas_font_path_append(evas, PACKAGE_DATA_DIR"/data/fonts"); - - edje_init(); - edje_frametime_set(1.0 / 30.0); - return 1; -} - -static void -main_stop(void) -{ - main_signal_exit(NULL, 0, NULL); - edje_shutdown(); - ecore_evas_shutdown(); - ecore_shutdown(); -} +static Eina_List *video_objs = NULL; +static Emotion_Vis vis = EMOTION_VIS_NONE; +static unsigned char reflex = 0; static void main_resize(Ecore_Evas *ee) { Evas_Coord w, h; - evas_output_viewport_get(evas, NULL, NULL, &w, &h); + evas_output_viewport_get(ecore_evas_get(ee), NULL, NULL, &w, &h); bg_resize(w, h); } -static int -main_signal_exit(void *data, int ev_type, void *ev) +static Eina_Bool +main_signal_exit(void *data __UNUSED__, int ev_type __UNUSED__, void *ev __UNUSED__) { + Evas_Object *o; + ecore_main_loop_quit(); - while (video_objs) + EINA_LIST_FREE(video_objs, o) { - printf("del obj!\n"); - evas_object_del(video_objs->data); - video_objs = evas_list_remove_list(video_objs, video_objs); - printf("done\n"); + emotion_object_last_position_save(o); + evas_object_del(o); } - return 1; + return EINA_TRUE; } static void -main_delete_request(Ecore_Evas *ee) +main_delete_request(Ecore_Evas *ee __UNUSED__) { ecore_main_loop_quit(); } @@ -193,23 +124,20 @@ bg_resize(Evas_Coord w, Evas_Coord h) static void broadcast_event(Emotion_Event ev) { - Evas_List *l; - - for (l = video_objs; l; l = l->next) - { - Evas_Object *obj; + Eina_List *l; + Evas_Object *obj; - obj = l->data; - emotion_object_event_simple_send(obj, ev); - } + EINA_LIST_FOREACH(video_objs, l, obj) + emotion_object_event_simple_send(obj, ev); } static void -bg_key_down(void *data, Evas * e, Evas_Object * obj, void *event_info) +bg_key_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info) { - Evas_Event_Key_Down *ev; + Evas_Event_Key_Down *ev = event_info; + Eina_List *l; + Evas_Object *o; - ev = (Evas_Event_Key_Down *)event_info; if (!strcmp(ev->keyname, "Escape")) ecore_main_loop_quit(); else if (!strcmp(ev->keyname, "Up")) @@ -252,77 +180,48 @@ bg_key_down(void *data, Evas * e, Evas_Object * obj, void *event_info) broadcast_event(EMOTION_EVENT_10); else if (!strcmp(ev->keyname, "bracketleft")) { - Evas_List *l; - - for (l = video_objs; l; l = l->next) - { - Evas_Object *obj; - - obj = l->data; - emotion_object_audio_volume_set(obj, emotion_object_audio_volume_get(obj) - 0.1); - } + EINA_LIST_FOREACH(video_objs, l, o) + emotion_object_audio_volume_set(o, emotion_object_audio_volume_get(o) - 0.1); } else if (!strcmp(ev->keyname, "bracketright")) { - Evas_List *l; - - for (l = video_objs; l; l = l->next) - { - Evas_Object *obj; - - obj = l->data; - emotion_object_audio_volume_set(obj, emotion_object_audio_volume_get(obj) + 0.1); - } + EINA_LIST_FOREACH(video_objs, l, o) + emotion_object_audio_volume_set(o, emotion_object_audio_volume_get(o) + 0.1); } else if (!strcmp(ev->keyname, "v")) { - Evas_List *l; - - for (l = video_objs; l; l = l->next) + EINA_LIST_FOREACH(video_objs, l, o) { - Evas_Object *obj; - - obj = l->data; - if (emotion_object_video_mute_get(obj)) - emotion_object_video_mute_set(obj, 0); + if (emotion_object_video_mute_get(o)) + emotion_object_video_mute_set(o, 0); else - emotion_object_video_mute_set(obj, 1); + emotion_object_video_mute_set(o, 1); } } else if (!strcmp(ev->keyname, "a")) { - Evas_List *l; - - for (l = video_objs; l; l = l->next) + EINA_LIST_FOREACH(video_objs, l, o) { - Evas_Object *obj; - - obj = l->data; - if (emotion_object_audio_mute_get(obj)) + if (emotion_object_audio_mute_get(o)) { - emotion_object_audio_mute_set(obj, 0); + emotion_object_audio_mute_set(o, 0); printf("unmute\n"); } else { - emotion_object_audio_mute_set(obj, 1); + emotion_object_audio_mute_set(o, 1); printf("mute\n"); } } } else if (!strcmp(ev->keyname, "i")) { - Evas_List *l; - - for (l = video_objs; l; l = l->next) + EINA_LIST_FOREACH(video_objs, l, o) { - Evas_Object *obj; - - obj = l->data; - printf("audio channels: %i\n", emotion_object_audio_channel_count(obj)); - printf("video channels: %i\n", emotion_object_video_channel_count(obj)); - printf("spu channels: %i\n", emotion_object_spu_channel_count(obj)); - printf("seekable: %i\n", emotion_object_seekable_get(obj)); + printf("audio channels: %i\n", emotion_object_audio_channel_count(o)); + printf("video channels: %i\n", emotion_object_video_channel_count(o)); + printf("spu channels: %i\n", emotion_object_spu_channel_count(o)); + printf("seekable: %i\n", emotion_object_seekable_get(o)); } } else if (!strcmp(ev->keyname, "f")) @@ -366,86 +265,49 @@ bg_key_down(void *data, Evas * e, Evas_Object * obj, void *event_info) { printf("del obj!\n"); evas_object_del(video_objs->data); - video_objs = evas_list_remove_list(video_objs, video_objs); + video_objs = eina_list_remove_list(video_objs, video_objs); printf("done\n"); } } - else + else if (!strcmp(ev->keyname, "z")) { - printf("UNHANDLED: %s\n", ev->keyname); - } -} - -static void -video_obj_in_cb(void *data, Evas *ev, Evas_Object *obj, void *event_info) -{ -// evas_object_color_set(obj, 255, 255, 255, 100); -} - -static void -video_obj_out_cb(void *data, Evas *ev, Evas_Object *obj, void *event_info) -{ -// evas_object_color_set(obj, 255, 255, 255, 200); -} - -static void -video_obj_down_cb(void *data, Evas *ev, Evas_Object *obj, void *event_info) -{ - Evas_Event_Mouse_Down *e; - - e = event_info; - evas_object_color_set(obj, 200, 50, 40, 200); - evas_object_raise(obj); -} + vis = (vis + 1) % EMOTION_VIS_LAST; + printf("new visualization: %d\n", vis); -static void -video_obj_up_cb(void *data, Evas *ev, Evas_Object *obj, void *event_info) -{ - Evas_Event_Mouse_Up *e; - - e = event_info; - evas_object_color_set(obj, 100, 100, 100, 100); -} - -static void -video_obj_move_cb(void *data, Evas *ev, Evas_Object *obj, void *event_info) -{ - Evas_Event_Mouse_Move *e; + EINA_LIST_FOREACH(video_objs, l, o) + { + Eina_Bool supported; - e = event_info; - if (e->buttons & 0x1) - { - Evas_Coord x, y; + supported = emotion_object_vis_supported(o, vis); + if (supported) + emotion_object_vis_set(o, vis); + else + { + const char *file; - evas_object_geometry_get(obj, &x, &y, NULL, NULL); - x += e->cur.canvas.x - e->prev.canvas.x; - y += e->cur.canvas.y - e->prev.canvas.y; - evas_object_move(obj, x, y); + file = emotion_object_file_get(o); + printf("object %p (%s) does not support visualization %d\n", + o, file, vis); + } + } } - else if (e->buttons & 0x4) + else { - Evas_Coord w, h; - - evas_object_geometry_get(obj, NULL, NULL, &w, &h); - w += e->cur.canvas.x - e->prev.canvas.x; - h += e->cur.canvas.y - e->prev.canvas.y; - evas_object_resize(obj, w, h); + printf("UNHANDLED: %s\n", ev->keyname); } } static void -video_obj_frame_decode_cb(void *data, Evas_Object *obj, void *event_info) +video_obj_time_changed(Evas_Object *obj, Evas_Object *edje) { - Evas_Object *oe; - double pos, len; + double pos, len, scale; char buf[256]; int ph, pm, ps, pf, lh, lm, ls; - oe = data; pos = emotion_object_position_get(obj); len = emotion_object_play_length_get(obj); -// printf("%3.3f, %3.3f\n", pos, len); - edje_object_part_drag_value_set(oe, "video_progress", pos / len, 0.0); + scale = (len > 0.0) ? pos / len : 0.0; + edje_object_part_drag_value_set(edje, "video_progress", scale, 0.0); lh = len / 3600; lm = len / 60 - (lh * 60); ls = len - (lm * 60); @@ -455,7 +317,13 @@ video_obj_frame_decode_cb(void *data, Evas_Object *obj, void *event_info) pf = pos * 100 - (ps * 100) - (pm * 60 * 100) - (ph * 60 * 60 * 100); snprintf(buf, sizeof(buf), "%i:%02i:%02i.%02i / %i:%02i:%02i", ph, pm, ps, pf, lh, lm, ls); - edje_object_part_text_set(oe, "video_progress_txt", buf); + edje_object_part_text_set(edje, "video_progress_txt", buf); +} + +static void +video_obj_frame_decode_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__) +{ + video_obj_time_changed(obj, data); if (0) { @@ -468,7 +336,7 @@ video_obj_frame_decode_cb(void *data, Evas_Object *obj, void *event_info) } static void -video_obj_frame_resize_cb(void *data, Evas_Object *obj, void *event_info) +video_obj_frame_resize_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__) { Evas_Object *oe; int iw, ih; @@ -489,46 +357,28 @@ video_obj_frame_resize_cb(void *data, Evas_Object *obj, void *event_info) } static void -video_obj_length_change_cb(void *data, Evas_Object *obj, void *event_info) +video_obj_length_change_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__) { - Evas_Object *oe; - double pos, len; - char buf[256]; - int ph, pm, ps, pf, lh, lm, ls; - - oe = data; - pos = emotion_object_position_get(obj); - len = emotion_object_play_length_get(obj); - edje_object_part_drag_value_set(oe, "video_progress", pos / len, 0.0); - lh = len / 3600; - lm = len / 60 - (lh * 60); - ls = len - (lm * 60); - ph = pos / 3600; - pm = pos / 60 - (ph * 60); - ps = pos - (pm * 60); - pf = pos * 100 - (ps * 100) - (pm * 60 * 100) - (ph * 60 * 60 * 100); - snprintf(buf, sizeof(buf), "%i:%02i:%02i.%02i / %i:%02i:%02i", - ph, pm, ps, pf, lh, lm, ls); - edje_object_part_text_set(oe, "video_progress_txt", buf); + video_obj_time_changed(obj, data); } static void -video_obj_stopped_cb(void *data, Evas_Object *obj, void *event_info) +video_obj_position_update_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__) { - Evas_Object *oe; + video_obj_time_changed(obj, data); +} - oe = data; +static void +video_obj_stopped_cb(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) +{ printf("video stopped!\n"); emotion_object_position_set(obj, 0.0); emotion_object_play_set(obj, 1); } static void -video_obj_channels_cb(void *data, Evas_Object *obj, void *event_info) +video_obj_channels_cb(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - Evas_Object *oe; - - oe = data; printf("channels changed: [AUD %i][VID %i][SPU %i]\n", emotion_object_audio_channel_count(obj), emotion_object_video_channel_count(obj), @@ -536,52 +386,37 @@ video_obj_channels_cb(void *data, Evas_Object *obj, void *event_info) } static void -video_obj_title_cb(void *data, Evas_Object *obj, void *event_info) +video_obj_title_cb(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - Evas_Object *oe; - - oe = data; printf("video title to: \"%s\"\n", emotion_object_title_get(obj)); } static void -video_obj_progress_cb(void *data, Evas_Object *obj, void *event_info) +video_obj_progress_cb(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - Evas_Object *oe; - - oe = data; printf("progress: \"%s\" %3.3f\n", emotion_object_progress_info_get(obj), emotion_object_progress_status_get(obj)); } static void -video_obj_ref_cb(void *data, Evas_Object *obj, void *event_info) +video_obj_ref_cb(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - Evas_Object *oe; - - oe = data; printf("video ref to: \"%s\" %i\n", emotion_object_ref_file_get(obj), emotion_object_ref_num_get(obj)); } static void -video_obj_button_num_cb(void *data, Evas_Object *obj, void *event_info) +video_obj_button_num_cb(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - Evas_Object *oe; - - oe = data; printf("video spu buttons to: %i\n", emotion_object_spu_button_count_get(obj)); } static void -video_obj_button_cb(void *data, Evas_Object *obj, void *event_info) +video_obj_button_cb(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) { - Evas_Object *oe; - - oe = data; printf("video selected spu button: %i\n", emotion_object_spu_button_get(obj)); } @@ -589,58 +424,50 @@ video_obj_button_cb(void *data, Evas_Object *obj, void *event_info) static void -video_obj_signal_play_cb(void *data, Evas_Object *o, const char *emission, const char *source) +video_obj_signal_play_cb(void *data, Evas_Object *o, const char *emission __UNUSED__, const char *source __UNUSED__) { - Evas_Object *ov; - - ov = data; + Evas_Object *ov = data; emotion_object_play_set(ov, 1); edje_object_signal_emit(o, "video_state", "play"); } static void -video_obj_signal_pause_cb(void *data, Evas_Object *o, const char *emission, const char *source) +video_obj_signal_pause_cb(void *data, Evas_Object *o, const char *emission __UNUSED__, const char *source __UNUSED__) { - Evas_Object *ov; - - ov = data; + Evas_Object *ov = data; emotion_object_play_set(ov, 0); edje_object_signal_emit(o, "video_state", "pause"); } static void -video_obj_signal_stop_cb(void *data, Evas_Object *o, const char *emission, const char *source) +video_obj_signal_stop_cb(void *data, Evas_Object *o, const char *emission __UNUSED__, const char *source __UNUSED__) { - Evas_Object *ov; - - ov = data; + Evas_Object *ov = data; emotion_object_play_set(ov, 0); emotion_object_position_set(ov, 0); edje_object_signal_emit(o, "video_state", "stop"); } static void -video_obj_signal_jump_cb(void *data, Evas_Object *o, const char *emission, const char *source) +video_obj_signal_jump_cb(void *data, Evas_Object *o, const char *emission __UNUSED__, const char *source __UNUSED__) { - Evas_Object *ov; + Evas_Object *ov = data; double len; double x, y; - ov = data; edje_object_part_drag_value_get(o, source, &x, &y); len = emotion_object_play_length_get(ov); emotion_object_position_set(ov, x * len); } static void -video_obj_signal_speed_cb(void *data, Evas_Object *o, const char *emission, const char *source) +video_obj_signal_speed_cb(void *data, Evas_Object *o, const char *emission __UNUSED__, const char *source __UNUSED__) { - Evas_Object *ov; + Evas_Object *ov = data; double spd; double x, y; char buf[256]; - ov = data; edje_object_part_drag_value_get(o, source, &x, &y); spd = 255 * y; evas_object_color_set(ov, spd, spd, spd, spd); @@ -649,7 +476,7 @@ video_obj_signal_speed_cb(void *data, Evas_Object *o, const char *emission, cons } static void -video_obj_signal_frame_move_start_cb(void *data, Evas_Object *o, const char *emission, const char *source) +video_obj_signal_frame_move_start_cb(void *data __UNUSED__, Evas_Object *o, const char *emission __UNUSED__, const char *source __UNUSED__) { Frame_Data *fd; Evas_Coord x, y; @@ -663,7 +490,7 @@ video_obj_signal_frame_move_start_cb(void *data, Evas_Object *o, const char *emi } static void -video_obj_signal_frame_move_stop_cb(void *data, Evas_Object *o, const char *emission, const char *source) +video_obj_signal_frame_move_stop_cb(void *data __UNUSED__, Evas_Object *o, const char *emission __UNUSED__, const char *source __UNUSED__) { Frame_Data *fd; @@ -672,7 +499,7 @@ video_obj_signal_frame_move_stop_cb(void *data, Evas_Object *o, const char *emis } static void -video_obj_signal_frame_resize_start_cb(void *data, Evas_Object *o, const char *emission, const char *source) +video_obj_signal_frame_resize_start_cb(void *data __UNUSED__, Evas_Object *o, const char *emission __UNUSED__, const char *source __UNUSED__) { Frame_Data *fd; Evas_Coord x, y; @@ -686,7 +513,7 @@ video_obj_signal_frame_resize_start_cb(void *data, Evas_Object *o, const char *e } static void -video_obj_signal_frame_resize_stop_cb(void *data, Evas_Object *o, const char *emission, const char *source) +video_obj_signal_frame_resize_stop_cb(void *data __UNUSED__, Evas_Object *o, const char *emission __UNUSED__, const char *source __UNUSED__) { Frame_Data *fd; @@ -695,7 +522,7 @@ video_obj_signal_frame_resize_stop_cb(void *data, Evas_Object *o, const char *em } static void -video_obj_signal_frame_move_cb(void *data, Evas_Object *o, const char *emission, const char *source) +video_obj_signal_frame_move_cb(void *data __UNUSED__, Evas_Object *o, const char *emission __UNUSED__, const char *source __UNUSED__) { Frame_Data *fd; @@ -724,7 +551,7 @@ video_obj_signal_frame_move_cb(void *data, Evas_Object *o, const char *emission, static void -init_video_object(char *module_filename, char *filename) +init_video_object(const char *module_filename, const char *filename) { Evas_Object *o, *oe; int iw, ih; @@ -736,7 +563,12 @@ init_video_object(char *module_filename, char *filename) o = emotion_object_add(evas); if (!emotion_object_init(o, module_filename)) return; - emotion_object_file_set(o, filename); + emotion_object_vis_set(o, vis); + if (!emotion_object_file_set(o, filename)) + { + return; + } + emotion_object_last_position_load(o); emotion_object_play_set(o, 1); evas_object_move(o, 0, 0); evas_object_resize(o, 320, 240); @@ -745,7 +577,7 @@ init_video_object(char *module_filename, char *filename) /* end basic video setup. all the rest here is just to be fancy */ - video_objs = evas_list_append(video_objs, o); + video_objs = eina_list_append(video_objs, o); emotion_object_size_get(o, &iw, &ih); w = iw; h = ih; @@ -754,7 +586,10 @@ init_video_object(char *module_filename, char *filename) oe = edje_object_add(evas); evas_object_data_set(oe, "frame_data", fd); - edje_object_file_set(oe, PACKAGE_DATA_DIR"/data/theme.edj", "video_controller"); + if (reflex) + edje_object_file_set(oe, PACKAGE_DATA_DIR"/data/theme.edj", "video_controller/reflex"); + else + edje_object_file_set(oe, PACKAGE_DATA_DIR"/data/theme.edj", "video_controller"); edje_extern_object_min_size_set(o, w, h); edje_object_part_swallow(oe, "video_swallow", o); edje_object_size_min_calc(oe, &w, &h); @@ -767,6 +602,7 @@ init_video_object(char *module_filename, char *filename) evas_object_smart_callback_add(o, "frame_decode", video_obj_frame_decode_cb, oe); evas_object_smart_callback_add(o, "frame_resize", video_obj_frame_resize_cb, oe); evas_object_smart_callback_add(o, "length_change", video_obj_length_change_cb, oe); + evas_object_smart_callback_add(o, "position_update", video_obj_position_update_cb, oe); evas_object_smart_callback_add(o, "decode_stop", video_obj_stopped_cb, oe); evas_object_smart_callback_add(o, "channels_change", video_obj_channels_cb, oe); @@ -796,84 +632,117 @@ init_video_object(char *module_filename, char *filename) evas_object_show(oe); } -static int -enter_idle(void *data) +static Eina_Bool +check_positions(void *data __UNUSED__) { - double t; - static double pt = 0.0; - static int frames = 0; + const Eina_List *lst; + Evas_Object *o; - t = ecore_time_get(); - if (frames == 0) pt = t; - frames++; - if (frames == 100) - { -// printf("FPS: %3.3f\n", frames / (t - pt)); - frames = 0; - } - return 1; + EINA_LIST_FOREACH(video_objs, lst, o) + video_obj_time_changed(o, evas_object_smart_parent_get(o)); + + return !!video_objs; } int main(int argc, char **argv) { - char *module_filename; - int i; + int args; + Eina_Rectangle geometry = {0, 0, startw, starth}; + char *engine = NULL; + char *backend = NULL; + int verbose = 0; + int visual = EMOTION_VIS_NONE; + unsigned char help = 0; + unsigned char engines_listed = 0; + Ecore_Getopt_Value values[] = { + ECORE_GETOPT_VALUE_STR(engine), + ECORE_GETOPT_VALUE_BOOL(engines_listed), + ECORE_GETOPT_VALUE_PTR_CAST(geometry), + ECORE_GETOPT_VALUE_STR(backend), + ECORE_GETOPT_VALUE_INT(visual), + ECORE_GETOPT_VALUE_INT(verbose), + ECORE_GETOPT_VALUE_BOOL(reflex), + ECORE_GETOPT_VALUE_NONE, + ECORE_GETOPT_VALUE_NONE, + ECORE_GETOPT_VALUE_NONE, + ECORE_GETOPT_VALUE_BOOL(help), + ECORE_GETOPT_VALUE_NONE + }; + + + if (!ecore_evas_init()) + return -1; + if (!edje_init()) + goto shutdown_ecore_evas; - if (main_start(argc, argv) < 1) return -1; - bg_setup(); + start_time = ecore_time_get(); + ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, main_signal_exit, NULL); + edje_frametime_set(1.0 / 30.0); - module_filename = "xine"; + ecore_app_args_set(argc, (const char **)argv); + args = ecore_getopt_parse(&options, values, argc, argv); + if (args < 0) goto shutdown_edje; + else if (help) goto shutdown_edje; + else if (engines_listed) goto shutdown_edje; + else if (args == argc) + { + printf("must provide at least one file to play!\n"); + goto shutdown_edje; + } - for (i = 1; i < argc; i++) + if ((geometry.w == 0) || (geometry.h == 0)) { - if (((!strcmp(argv[i], "-g")) || - (!strcmp(argv[i], "-geometry")) || - (!strcmp(argv[i], "--geometry"))) && (i < (argc - 1))) - i++; - else if (((!strcmp(argv[i], "-h")) || - (!strcmp(argv[i], "-help")) || - (!strcmp(argv[i], "--help")))) - { - printf("Usage:\n"); - printf(" %s [-gl] [-g WxH] [-xine] [-gstreamer] filename\n", argv[0]); - exit(-1); - } - else if (!strcmp(argv[i], "-gl")) - { - } - else if (!strcmp(argv[i], "-fb")) - { - } - else if (!strcmp(argv[i], "-xr")) - { - } - else if (!strcmp(argv[i], "-xine")) - { - module_filename = "xine"; - } - else if (!strcmp(argv[i], "-gstreamer")) - { - module_filename = "gstreamer"; - } - else - { - printf ("module : %s\n", module_filename); - init_video_object(module_filename, argv[i]); - } + if (geometry.w == 0) geometry.w = 320; + if (geometry.h == 0) geometry.h = 240; } - ecore_idle_enterer_add(enter_idle, NULL); + printf("evas engine: %s\n", engine ? engine : ""); + printf("emotion backend: %s\n", backend ? backend : ""); + printf("vis: %d\n", vis); + printf("geometry: %d %d %dx%d\n", geometry.x, geometry.y, geometry.w, geometry.h); + + ecore_evas = ecore_evas_new + (engine, geometry.x, geometry.y, geometry.w, geometry.h, NULL); + if (!ecore_evas) + goto shutdown_edje; + +// ecore_evas_alpha_set(ecore_evas, EINA_TRUE); + + ecore_evas_callback_delete_request_set(ecore_evas, main_delete_request); + ecore_evas_callback_resize_set(ecore_evas, main_resize); + ecore_evas_title_set(ecore_evas, "Evas Media Test Program"); + ecore_evas_name_class_set(ecore_evas, "evas_media_test", "main"); + ecore_evas_show(ecore_evas); + evas = ecore_evas_get(ecore_evas); + evas_image_cache_set(evas, 8 * 1024 * 1024); + evas_font_cache_set(evas, 1 * 1024 * 1024); + evas_font_path_append(evas, PACKAGE_DATA_DIR"/data/fonts"); + + emotion_init(); + + bg_setup(); + + for (; args < argc; args++) + init_video_object(backend, argv[args]); + + ecore_animator_add(check_positions, NULL); ecore_main_loop_begin(); - main_stop(); + + main_signal_exit(NULL, 0, NULL); + + emotion_shutdown(); + ecore_evas_free(ecore_evas); + ecore_evas_shutdown(); + edje_shutdown(); + return 0; -} -#else -int main() -{ - puts("Could not find Ecore_X.h or Ecore_Fb.h so test is disabled"); - return 0; + shutdown_edje: + edje_shutdown(); + shutdown_ecore_evas: + ecore_evas_shutdown(); + + return -1; } -#endif diff --git a/src/edje_external/Makefile.am b/src/edje_external/Makefile.am new file mode 100644 index 0000000..9b36faf --- /dev/null +++ b/src/edje_external/Makefile.am @@ -0,0 +1,18 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I$(top_srcdir) \ +-I$(top_srcdir)/src/lib \ +-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ +@EMOTION_CPPFLAGS@ \ +@EMOTION_CFLAGS@ \ +@EDJE_EXTERNAL_CFLAGS@ \ +@EFL_EMOTION_BUILD@ + +pkgdir = $(libdir)/edje/modules/emotion/$(MODULE_EDJE) +pkg_LTLIBRARIES = module.la + +module_la_SOURCES = emotion.c +module_la_LIBADD = @EMOTION_LIBS@ $(top_builddir)/src/lib/libemotion.la @EDJE_EXTERNAL_LIBS@ +module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version +module_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/src/edje_external/emotion.c b/src/edje_external/emotion.c new file mode 100644 index 0000000..d7fc012 --- /dev/null +++ b/src/edje_external/emotion.c @@ -0,0 +1,516 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "Emotion.h" + +typedef struct _External_Emotion_Params External_Emotion_Params; +typedef struct _External_Emotion_Signals_Proxy_Context External_Emotion_Signals_Proxy_Context; + +struct _External_Emotion_Params +{ +#define _STR(M) const char *M +#define _BOOL(M) Eina_Bool M:1; Eina_Bool M##_exists:1 +#define _INT(M) int M; Eina_Bool M##_exists:1 +#define _DOUBLE(M) double M; Eina_Bool M##_exists:1 + _STR(file); + _BOOL(play); + _DOUBLE(position); + _BOOL(smooth_scale); + _DOUBLE(audio_volume); + _BOOL(audio_mute); + _INT(audio_channel); + _BOOL(video_mute); + _INT(video_channel); + _BOOL(spu_mute); + _INT(spu_channel); + _INT(chapter); + _DOUBLE(play_speed); + _DOUBLE(play_length); + //_INT(vis); +#undef _STR +#undef _BOOL +#undef _INT +#undef _DOUBLE +}; + +struct _External_Emotion_Signals_Proxy_Context +{ + const char *emission; + const char *source; + Evas_Object *edje; +}; + +static int _log_dom = -1; +#define CRITICAL(...) EINA_LOG_DOM_CRIT(_log_dom, __VA_ARGS__) +#define ERR(...) EINA_LOG_DOM_ERR(_log_dom, __VA_ARGS__) +#define WRN(...) EINA_LOG_DOM_WARN(_log_dom, __VA_ARGS__) +#define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__) +#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__) + +static const char *_external_emotion_engines[] = { +#ifdef EMOTION_BUILD_XINE + "xine", +#endif +#ifdef EMOTION_BUILD_GSTREAMER + "gstreamer", +#endif +#ifdef EMOTION_BUILD_GENERIC + "generic", +#endif + NULL, +}; + +static const char _external_emotion_engine_def[] = +#if defined(EMOTION_BUILD_XINE) + "xine"; +#elif defined(EMOTION_BUILD_GSTREAMER) + "gstreamer"; +#elif defined(EMOTION_BUILD_GENERIC) + "generic"; +#else + "impossible"; +#endif + +static void +_external_emotion_signal_proxy_free_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + External_Emotion_Signals_Proxy_Context *ctxt = data; + free(ctxt); +} + +static void +_external_emotion_signal_proxy_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + External_Emotion_Signals_Proxy_Context *ctxt = data; + // TODO: Is it worth to check Evas_Smart_Cb_Description and do something + // TODO: with event_info given its description? + edje_object_signal_emit(ctxt->edje, ctxt->emission, ctxt->source); +} + +static Evas_Object * +_external_emotion_add(void *data __UNUSED__, Evas *evas, Evas_Object *edje __UNUSED__, const Eina_List *params, const char *part_name) +{ + const Evas_Smart_Cb_Description **cls_descs, **inst_descs; + unsigned int cls_count, inst_count, total; + External_Emotion_Signals_Proxy_Context *ctxt; + Evas_Object *obj; + const char *engine; + + if (!edje_external_param_choice_get(params, "engine", &engine)) + engine = NULL; + if (!engine) engine = _external_emotion_engine_def; + + obj = emotion_object_add(evas); + if (!emotion_object_init(obj, engine)) + { + ERR("failed to initialize emotion with engine '%s'.", engine); + return NULL; + } + + evas_object_smart_callbacks_descriptions_get + (obj, &cls_descs, &cls_count, &inst_descs, &inst_count); + + total = cls_count + inst_count; + if (!total) goto end; + ctxt = malloc(sizeof(External_Emotion_Signals_Proxy_Context) * total); + if (!ctxt) goto end; + evas_object_event_callback_add + (obj, EVAS_CALLBACK_DEL, _external_emotion_signal_proxy_free_cb, ctxt); + + for (; cls_count > 0; cls_count--, cls_descs++, ctxt++) + { + const Evas_Smart_Cb_Description *d = *cls_descs; + ctxt->emission = d->name; + ctxt->source = part_name; + ctxt->edje = edje; + evas_object_smart_callback_add + (obj, d->name, _external_emotion_signal_proxy_cb, ctxt); + } + + for (; inst_count > 0; inst_count--, inst_descs++, ctxt++) + { + const Evas_Smart_Cb_Description *d = *inst_descs; + ctxt->emission = d->name; + ctxt->source = part_name; + ctxt->edje = edje; + evas_object_smart_callback_add + (obj, d->name, _external_emotion_signal_proxy_cb, ctxt); + } + + end: + return obj; +} + +static void +_external_emotion_signal(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const char *signal, const char *source) +{ + DBG("External Signal received: '%s' '%s'", signal, source); +} + +static void +_external_emotion_state_set(void *data __UNUSED__, Evas_Object *obj, const void *from_params, const void *to_params, float pos __UNUSED__) +{ + const External_Emotion_Params *p; + + if (to_params) p = to_params; + else if (from_params) p = from_params; + else return; + +#define _STR(M) if (p->M) emotion_object_##M##_set(obj, p->M) +#define _BOOL(M) if (p->M##_exists) emotion_object_##M##_set(obj, p->M) +#define _INT(M) if (p->M##_exists) emotion_object_##M##_set(obj, p->M) +#define _DOUBLE(M) if (p->M##_exists) emotion_object_##M##_set(obj, p->M) + _STR(file); + _BOOL(play); + //_DOUBLE(position); + if (p->position_exists) + WRN("position should not be set from state description! Ignored."); + _BOOL(smooth_scale); + _DOUBLE(audio_volume); + _BOOL(audio_mute); + _INT(audio_channel); + _BOOL(video_mute); + _INT(video_channel); + _BOOL(spu_mute); + _INT(spu_channel); + _INT(chapter); + _DOUBLE(play_speed); + if (p->play_length_exists) ERR("play_length is read-only"); + //_INT(vis); +#undef _STR +#undef _BOOL +#undef _INT +#undef _DOUBLE +} + +static Eina_Bool +_external_emotion_param_set(void *data __UNUSED__, Evas_Object *obj, const Edje_External_Param *param) +{ + if (!strcmp(param->name, "engine")) + { + // TODO + WRN("engine is a property that can be set only at object creation!"); + return EINA_FALSE; + } + +#define _STR(M) \ + else if (!strcmp(param->name, #M)) \ + { \ + if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING) \ + { \ + emotion_object_##M##_set(obj, param->s); \ + return EINA_TRUE; \ + } \ + } +#define _BOOL(M) \ + else if (!strcmp(param->name, #M)) \ + { \ + if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL) \ + { \ + emotion_object_##M##_set(obj, param->i); \ + return EINA_TRUE; \ + } \ + } +#define _INT(M) \ + else if (!strcmp(param->name, #M)) \ + { \ + if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT) \ + { \ + emotion_object_##M##_set(obj, param->i); \ + return EINA_TRUE; \ + } \ + } +#define _DOUBLE(M) \ + else if (!strcmp(param->name, #M)) \ + { \ + if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE) \ + { \ + emotion_object_##M##_set(obj, param->d); \ + return EINA_TRUE; \ + } \ + } + + if (0) {} // so else if works... + _STR(file) + _BOOL(play) + _DOUBLE(position) + _BOOL(smooth_scale) + _DOUBLE(audio_volume) + _BOOL(audio_mute) + _INT(audio_channel) + _BOOL(video_mute) + _INT(video_channel) + _BOOL(spu_mute) + _INT(spu_channel) + _INT(chapter) + _DOUBLE(play_speed) + else if (!strcmp(param->name, "play_length")) + { + ERR("play_length is read-only"); + return EINA_FALSE; + } + //_INT(vis); +#undef _STR +#undef _BOOL +#undef _INT +#undef _DOUBLE + + ERR("unknown parameter '%s' of type '%s'", + param->name, edje_external_param_type_str(param->type)); + + return EINA_FALSE; +} + +static Eina_Bool +_external_emotion_param_get(void *data __UNUSED__, const Evas_Object *obj, Edje_External_Param *param) +{ +#define _STR(M) \ + else if (!strcmp(param->name, #M)) \ + { \ + if (param->type == EDJE_EXTERNAL_PARAM_TYPE_STRING) \ + { \ + param->s = emotion_object_##M##_get(obj); \ + return EINA_TRUE; \ + } \ + } +#define _BOOL(M) \ + else if (!strcmp(param->name, #M)) \ + { \ + if (param->type == EDJE_EXTERNAL_PARAM_TYPE_BOOL) \ + { \ + param->i = emotion_object_##M##_get(obj); \ + return EINA_TRUE; \ + } \ + } +#define _INT(M) \ + else if (!strcmp(param->name, #M)) \ + { \ + if (param->type == EDJE_EXTERNAL_PARAM_TYPE_INT) \ + { \ + param->i = emotion_object_##M##_get(obj); \ + return EINA_TRUE; \ + } \ + } +#define _DOUBLE(M) \ + else if (!strcmp(param->name, #M)) \ + { \ + if (param->type == EDJE_EXTERNAL_PARAM_TYPE_DOUBLE) \ + { \ + param->d = emotion_object_##M##_get(obj); \ + return EINA_TRUE; \ + } \ + } + + if (0) {} // so else if works... + _STR(file) + _BOOL(play) + _DOUBLE(position) + _BOOL(smooth_scale) + _DOUBLE(audio_volume) + _BOOL(audio_mute) + _INT(audio_channel) + _BOOL(video_mute) + _INT(video_channel) + _BOOL(spu_mute) + _INT(spu_channel) + _INT(chapter) + _DOUBLE(play_speed) + _DOUBLE(play_length) + //_INT(vis) +#undef _STR +#undef _BOOL +#undef _INT +#undef _DOUBLE + + ERR("unknown parameter '%s' of type '%s'", + param->name, edje_external_param_type_str(param->type)); + + return EINA_FALSE; +} + +static void * +_external_emotion_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params) +{ + const Edje_External_Param *param; + const Eina_List *l; + External_Emotion_Params *p = calloc(1, sizeof(External_Emotion_Params)); + if (!p) return NULL; + + EINA_LIST_FOREACH(params, l, param) + { +#define _STR(M) \ + if (!strcmp(param->name, #M)) p->M = eina_stringshare_add(param->s) +#define _BOOL(M) \ + if (!strcmp(param->name, #M)) \ + { \ + p->M = param->i; \ + p->M##_exists = EINA_TRUE; \ + } +#define _INT(M) \ + if (!strcmp(param->name, #M)) \ + { \ + p->M = param->i; \ + p->M##_exists = EINA_TRUE; \ + } +#define _DOUBLE(M) \ + if (!strcmp(param->name, #M)) \ + { \ + p->M = param->d; \ + p->M##_exists = EINA_TRUE; \ + } + + _STR(file); + _BOOL(play); + _DOUBLE(position); + _BOOL(smooth_scale); + _DOUBLE(audio_volume); + _BOOL(audio_mute); + _INT(audio_channel); + _BOOL(video_mute); + _INT(video_channel); + _BOOL(spu_mute); + _INT(spu_channel); + _INT(chapter); + _DOUBLE(play_speed); + _DOUBLE(play_length); + //_INT(vis); +#undef _STR +#undef _BOOL +#undef _INT +#undef _DOUBLE + } + + return p; +} + +static void +_external_emotion_params_free(void *params) +{ + External_Emotion_Params *p = params; + +#define _STR(M) eina_stringshare_del(p->M) +#define _BOOL(M) do {} while (0) +#define _INT(M) do {} while (0) +#define _DOUBLE(M) do {} while (0) + _STR(file); + _BOOL(play); + _DOUBLE(position); + _BOOL(smooth_scale); + _DOUBLE(audio_volume); + _BOOL(audio_mute); + _INT(audio_channel); + _BOOL(video_mute); + _INT(video_channel); + _BOOL(spu_mute); + _INT(spu_channel); + _INT(chapter); + _DOUBLE(play_speed); + _DOUBLE(play_length); + //_INT(vis); +#undef _STR +#undef _BOOL +#undef _INT +#undef _DOUBLE + free(p); +} + +static const char * +_external_emotion_label_get(void *data __UNUSED__) +{ + return "Emotion"; +} + +static Evas_Object * +_external_emotion_icon_add(void *data __UNUSED__, Evas *e) +{ + Evas_Object *ic; + int w = 0, h = 0; + + ic = edje_object_add(e); + edje_object_file_set(ic, PACKAGE_DATA_DIR"/data/icon.edj", "icon"); + edje_object_size_min_get(ic, &w, &h); + if (w < 1) w = 20; + if (h < 1) h = 10; + evas_object_size_hint_min_set(ic, w, h); + evas_object_size_hint_max_set(ic, w, h); + + return ic; +} + +static const char * +_external_emotion_translate(void *data __UNUSED__, const char *orig) +{ + // in future, mark all params as translatable and use dgettext() + // with "emotion" text domain here. + return orig; +} + +static Edje_External_Param_Info _external_emotion_params[] = { + EDJE_EXTERNAL_PARAM_INFO_CHOICE_FULL + ("engine", _external_emotion_engine_def, _external_emotion_engines), + EDJE_EXTERNAL_PARAM_INFO_STRING("file"), + EDJE_EXTERNAL_PARAM_INFO_BOOL_DEFAULT("play", EINA_FALSE), + EDJE_EXTERNAL_PARAM_INFO_DOUBLE("position"), + EDJE_EXTERNAL_PARAM_INFO_BOOL_DEFAULT("smooth_scale", EINA_FALSE), + EDJE_EXTERNAL_PARAM_INFO_DOUBLE_DEFAULT("audio_volume", 0.9), + EDJE_EXTERNAL_PARAM_INFO_BOOL_DEFAULT("audio_mute", EINA_FALSE), + EDJE_EXTERNAL_PARAM_INFO_INT_DEFAULT("audio_channel", 0), + EDJE_EXTERNAL_PARAM_INFO_BOOL_DEFAULT("video_mute", EINA_FALSE), + EDJE_EXTERNAL_PARAM_INFO_INT_DEFAULT("video_channel", 0), + EDJE_EXTERNAL_PARAM_INFO_BOOL_DEFAULT("spu_mute", EINA_FALSE), + EDJE_EXTERNAL_PARAM_INFO_INT_DEFAULT("spu_channel", 0), + EDJE_EXTERNAL_PARAM_INFO_INT("chapter"), + EDJE_EXTERNAL_PARAM_INFO_DOUBLE_DEFAULT("play_speed", 1.0), + EDJE_EXTERNAL_PARAM_INFO_DOUBLE("play_length"), + //EDJE_EXTERNAL_PARAM_INFO_CHOICE_FULL("vis", ...), + EDJE_EXTERNAL_PARAM_INFO_SENTINEL +}; + +static const Edje_External_Type _external_emotion_type = { + .abi_version = EDJE_EXTERNAL_TYPE_ABI_VERSION, + .module = "emotion", + .module_name = "Emotion", + .add = _external_emotion_add, + .state_set = _external_emotion_state_set, + .signal_emit = _external_emotion_signal, + .param_set = _external_emotion_param_set, + .param_get = _external_emotion_param_get, + .params_parse = _external_emotion_params_parse, + .params_free = _external_emotion_params_free, + .label_get = _external_emotion_label_get, + .description_get = NULL, + .icon_add = _external_emotion_icon_add, + .preview_add = NULL, + .translate = _external_emotion_translate, + .parameters_info = _external_emotion_params, + .data = NULL +}; + +static Edje_External_Type_Info _external_emotion_types[] = +{ + {"emotion", &_external_emotion_type}, + {NULL, NULL} +}; + +static Eina_Bool +external_emotion_mod_init(void) +{ + _log_dom = eina_log_domain_register + ("emotion-externals", EINA_COLOR_LIGHTBLUE); + edje_external_type_array_register(_external_emotion_types); + return EINA_TRUE; +} + +static void +external_emotion_mod_shutdown(void) +{ + edje_external_type_array_unregister(_external_emotion_types); + eina_log_domain_unregister(_log_dom); + _log_dom = -1; +} + +EINA_MODULE_INIT(external_emotion_mod_init); +EINA_MODULE_SHUTDOWN(external_emotion_mod_shutdown); diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am new file mode 100644 index 0000000..7476f08 --- /dev/null +++ b/src/examples/Makefile.am @@ -0,0 +1,39 @@ +MAINTAINERCLEANFILES = Makefile.in + +examplesdir = $(datadir)/$(PACKAGE)/examples + +AM_CPPFLAGS = \ +-I. \ +-I$(top_srcdir) \ +-I$(top_srcdir)/src/lib \ +@EMOTION_CFLAGS@ \ +@EMOTION_CPPFLAGS@ \ +@EMOTION_BIN_CFLAGS@ + +LDADD = \ + $(top_builddir)/src/lib/libemotion.la \ + @EMOTION_BIN_LIBS@ + +SRCS = \ + emotion_basic_example.c \ + emotion_generic_example.c \ + emotion_border_example.c \ + emotion_signals_example.c + +EXTRA_DIST = $(SRCS) + +examples_PROGRAMS = + +if EFL_INSTALL_EXAMPLES +filesdir = $(datadir)/$(PACKAGE)/examples +files_DATA = $(SRCS) +endif + +if EFL_BUILD_EXAMPLES +examples_PROGRAMS += \ + emotion_basic_example \ + emotion_generic_example \ + emotion_border_example \ + emotion_signals_example +endif + diff --git a/src/examples/emotion_basic_example.c b/src/examples/emotion_basic_example.c new file mode 100644 index 0000000..7e3e4c2 --- /dev/null +++ b/src/examples/emotion_basic_example.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include + +#define WIDTH (320) +#define HEIGHT (240) + +static void +_playback_started_cb(void *data, Evas_Object *o, void *event_info) +{ + printf("Emotion object started playback.\n"); +} + +int +main(int argc, const char *argv[]) +{ + Ecore_Evas *ee; + Evas *e; + Evas_Object *bg, *em; + const char *filename = NULL; + + if (argc < 2) + { + printf("One argument is necessary. Usage:\n"); + printf("\t%s \n", argv[0]); + } + + filename = argv[1]; + + if (!ecore_evas_init()) + return EXIT_FAILURE; + + /* this will give you a window with an Evas canvas under the first + * engine available */ + ee = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL); + if (!ee) + goto error; + + ecore_evas_show(ee); + + /* the canvas pointer, de facto */ + e = ecore_evas_get(ee); + + /* adding a background to this example */ + bg = evas_object_rectangle_add(e); + evas_object_name_set(bg, "our dear rectangle"); + evas_object_color_set(bg, 255, 255, 255, 255); /* white bg */ + evas_object_move(bg, 0, 0); /* at canvas' origin */ + evas_object_resize(bg, WIDTH, HEIGHT); /* covers full canvas */ + evas_object_show(bg); + + /* Creating the emotion object */ + em = emotion_object_add(e); + emotion_object_init(em, NULL); + + evas_object_smart_callback_add( + em, "playback_started", _playback_started_cb, NULL); + + emotion_object_file_set(em, filename); + + evas_object_move(em, 0, 0); + evas_object_resize(em, WIDTH, HEIGHT); + evas_object_show(em); + + emotion_object_play_set(em, EINA_TRUE); + + ecore_main_loop_begin(); + + ecore_evas_free(ee); + ecore_evas_shutdown(); + return 0; + +error: + fprintf(stderr, "you got to have at least one evas engine built and linked" + " up to ecore-evas for this example to run properly.\n"); + + ecore_evas_shutdown(); + return -1; +} diff --git a/src/examples/emotion_border_example.c b/src/examples/emotion_border_example.c new file mode 100644 index 0000000..9df53f4 --- /dev/null +++ b/src/examples/emotion_border_example.c @@ -0,0 +1,238 @@ +#include +#include +#include +#include +#include +#include + +#define WIDTH (320) +#define HEIGHT (240) + +static Eina_List *filenames = NULL; +static Eina_List *curfile = NULL; + +static void +_playback_started_cb(void *data, Evas_Object *o, void *event_info) +{ + printf("Emotion object started playback.\n"); +} + +static Evas_Object * +_create_emotion_object(Evas *e) +{ + Evas_Object *em = emotion_object_add(e); + + emotion_object_init(em, "gstreamer"); + + evas_object_smart_callback_add( + em, "playback_started", _playback_started_cb, NULL); + + return em; +} + +static void +_on_key_down(void *data, Evas *e, Evas_Object *o, void *event_info) +{ + Evas_Event_Key_Down *ev = event_info; + Evas_Object *em = data; + + if (!strcmp(ev->keyname, "Return")) + { + emotion_object_play_set(em, EINA_TRUE); + } + else if (!strcmp(ev->keyname, "space")) + { + emotion_object_play_set(em, EINA_FALSE); + } + else if (!strcmp(ev->keyname, "Escape")) + { + ecore_main_loop_quit(); + } + else if (!strcmp(ev->keyname, "n")) + { + const char *file; + if (!curfile) + curfile = filenames; + else + curfile = eina_list_next(curfile); + file = eina_list_data_get(curfile); + fprintf(stderr, "playing next file: %s\n", file); + emotion_object_file_set(em, file); + } + else if (!strcmp(ev->keyname, "p")) + { + const char *file; + if (!curfile) + curfile = eina_list_last(filenames); + else + curfile = eina_list_prev(curfile); + file = eina_list_data_get(curfile); + fprintf(stderr, "playing next file: %s\n", file); + emotion_object_file_set(em, file); + } + else if (!strcmp(ev->keyname, "b")) + { + emotion_object_border_set(em, 0, 0, 50, 50); + } + else if (!strcmp(ev->keyname, "0")) + { + emotion_object_keep_aspect_set(em, EMOTION_ASPECT_KEEP_NONE); + } + else if (!strcmp(ev->keyname, "w")) + { + emotion_object_keep_aspect_set(em, EMOTION_ASPECT_KEEP_WIDTH); + } + else if (!strcmp(ev->keyname, "h")) + { + emotion_object_keep_aspect_set(em, EMOTION_ASPECT_KEEP_HEIGHT); + } + else if (!strcmp(ev->keyname, "2")) + { + emotion_object_keep_aspect_set(em, EMOTION_ASPECT_KEEP_BOTH); + } + else if (!strcmp(ev->keyname, "c")) + { + emotion_object_keep_aspect_set(em, EMOTION_ASPECT_CROP); + } + else + { + fprintf(stderr, "unhandled key: %s\n", ev->keyname); + } +} + +static void +_frame_decode_cb(void *data, Evas_Object *o, void *event_info) +{ + // fprintf(stderr, "smartcb: frame_decode\n"); +} + +static void +_length_change_cb(void *data, Evas_Object *o, void *event_info) +{ + fprintf(stderr, "smartcb: length_change: %0.3f\n", emotion_object_play_length_get(o)); +} + +static void +_position_update_cb(void *data, Evas_Object *o, void *event_info) +{ + fprintf(stderr, "smartcb: position_update: %0.3f\n", emotion_object_position_get(o)); +} + +static void +_progress_change_cb(void *data, Evas_Object *o, void *event_info) +{ + fprintf(stderr, "smartcb: progress_change: %0.3f, %s\n", + emotion_object_progress_status_get(o), + emotion_object_progress_info_get(o)); +} + +static void +_frame_resize_cb(void *data, Evas_Object *o, void *event_info) +{ + int w, h; + emotion_object_size_get(o, &w, &h); + fprintf(stderr, "smartcb: frame_resize: %dx%d\n", w, h); +} + +static void /* adjust canvas' contents on resizes */ +_canvas_resize_cb(Ecore_Evas *ee) +{ + int w, h; + Evas_Object *bg, *em; + + ecore_evas_geometry_get(ee, NULL, NULL, &w, &h); + + bg = ecore_evas_data_get(ee, "bg"); + em = ecore_evas_data_get(ee, "emotion"); + + evas_object_resize(bg, w, h); + evas_object_move(em, 10, 10); + evas_object_resize(em, w - 20, h - 20); +} + +int +main(int argc, const char *argv[]) +{ + Ecore_Evas *ee; + Evas *e; + Evas_Object *bg, *em; + int i; + + if (argc < 2) + { + printf("One argument is necessary. Usage:\n"); + printf("\t%s \n", argv[0]); + } + + eina_init(); + for (i = 1; i < argc; i++) + filenames = eina_list_append(filenames, eina_stringshare_add(argv[i])); + + curfile = filenames; + + if (!ecore_evas_init()) + return EXIT_FAILURE; + + /* this will give you a window with an Evas canvas under the first + * engine available */ + ee = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL); + if (!ee) + goto error; + + ecore_evas_callback_resize_set(ee, _canvas_resize_cb); + + ecore_evas_show(ee); + + /* the canvas pointer, de facto */ + e = ecore_evas_get(ee); + + /* adding a background to this example */ + bg = evas_object_rectangle_add(e); + evas_object_name_set(bg, "our dear rectangle"); + evas_object_color_set(bg, 255, 0, 0, 255); /* white bg */ + evas_object_move(bg, 0, 0); /* at canvas' origin */ + evas_object_resize(bg, WIDTH, HEIGHT); /* covers full canvas */ + evas_object_show(bg); + + ecore_evas_data_set(ee, "bg", bg); + + /* Creating the emotion object */ + em = _create_emotion_object(e); + emotion_object_file_set(em, eina_list_data_get(curfile)); + evas_object_move(em, 10, 10); + evas_object_resize(em, WIDTH, HEIGHT); + evas_object_resize(em, WIDTH - 20, HEIGHT - 20); + emotion_object_keep_aspect_set(em, EMOTION_ASPECT_KEEP_BOTH); + emotion_object_bg_color_set(em, 0, 128, 0, 255); + evas_object_show(em); + + ecore_evas_data_set(ee, "emotion", em); + + evas_object_smart_callback_add(em, "frame_decode", _frame_decode_cb, NULL); + evas_object_smart_callback_add(em, "length_change", _length_change_cb, NULL); + evas_object_smart_callback_add(em, "position_update", _position_update_cb, NULL); + evas_object_smart_callback_add(em, "progress_change", _progress_change_cb, NULL); + evas_object_smart_callback_add(em, "frame_resize", _frame_resize_cb, NULL); + + evas_object_event_callback_add(bg, EVAS_CALLBACK_KEY_DOWN, _on_key_down, em); + evas_object_focus_set(bg, EINA_TRUE); + + emotion_object_play_set(em, EINA_TRUE); + + ecore_main_loop_begin(); + + ecore_evas_free(ee); + ecore_evas_shutdown(); + return 0; + +error: + fprintf(stderr, "you got to have at least one evas engine built and linked" + " up to ecore-evas for this example to run properly.\n"); + + EINA_LIST_FREE(filenames, curfile) + eina_stringshare_del(eina_list_data_get(curfile)); + + ecore_evas_shutdown(); + eina_shutdown(); + return -1; +} diff --git a/src/examples/emotion_generic_example.c b/src/examples/emotion_generic_example.c new file mode 100644 index 0000000..b838286 --- /dev/null +++ b/src/examples/emotion_generic_example.c @@ -0,0 +1,233 @@ +#include +#include +#include +#include +#include +#include +#include + +#define WIDTH (320) +#define HEIGHT (240) + +static Eina_List *filenames = NULL; +static Eina_List *curfile = NULL; + +static void +_playback_started_cb(void *data, Evas_Object *o, void *event_info) +{ + printf("Emotion object started playback.\n"); +} + +static void +_playback_stopped_cb(void *data, Evas_Object *o, void *event_info) +{ + printf("Emotion playback stopped.\n"); + emotion_object_play_set(o, EINA_FALSE); + emotion_object_position_set(o, 0); +} + +static Evas_Object * +_create_emotion_object(Evas *e) +{ + Evas_Object *em = emotion_object_add(e); + + emotion_object_init(em, "generic"); + + evas_object_smart_callback_add( + em, "playback_started", _playback_started_cb, NULL); + evas_object_smart_callback_add( + em, "playback_finished", _playback_stopped_cb, NULL); + + return em; +} + +static void +_on_key_down(void *data, Evas *e, Evas_Object *o, void *event_info) +{ + Evas_Event_Key_Down *ev = event_info; + Evas_Object *em = data; + + if (!strcmp(ev->keyname, "Return")) + { + emotion_object_play_set(em, EINA_TRUE); + } + else if (!strcmp(ev->keyname, "space")) + { + emotion_object_play_set(em, EINA_FALSE); + } + else if (!strcmp(ev->keyname, "Escape")) + { + ecore_main_loop_quit(); + } + else if (!strcmp(ev->keyname, "t")) + { + int w, h; + emotion_object_size_get(em, &w, &h); + fprintf(stderr, "example -> size: %dx%d\n", w, h); + } + else if (!strcmp(ev->keyname, "s")) + { + float len, pos; + len = emotion_object_play_length_get(em); + pos = 0.98 * len; + fprintf(stderr, "skipping to position %0.3f\n", pos); + emotion_object_position_set(em, pos); + } + else if (!strcmp(ev->keyname, "1")) + { + fprintf(stderr, "setting speed to 1.0\n"); + emotion_object_play_speed_set(em, 1.0); + } + else if (!strcmp(ev->keyname, "2")) + { + fprintf(stderr, "setting speed to 2.0\n"); + emotion_object_play_speed_set(em, 2.0); + } + else if (!strcmp(ev->keyname, "n")) + { + const char *file; + if (!curfile) + curfile = filenames; + else + curfile = eina_list_next(curfile); + file = eina_list_data_get(curfile); + fprintf(stderr, "playing next file: %s\n", file); + emotion_object_file_set(em, file); + } + else if (!strcmp(ev->keyname, "p")) + { + const char *file; + if (!curfile) + curfile = eina_list_last(filenames); + else + curfile = eina_list_prev(curfile); + file = eina_list_data_get(curfile); + fprintf(stderr, "playing next file: %s\n", file); + emotion_object_file_set(em, file); + } + else if (!strcmp(ev->keyname, "d")) + { + evas_object_del(em); + } + else if (!strcmp(ev->keyname, "l")) + { + // force frame dropping + sleep(5); + } + else + { + fprintf(stderr, "unhandled key: %s\n", ev->keyname); + } +} + +static void +_frame_decode_cb(void *data, Evas_Object *o, void *event_info) +{ + // fprintf(stderr, "smartcb: frame_decode\n"); +} + +static void +_length_change_cb(void *data, Evas_Object *o, void *event_info) +{ + fprintf(stderr, "smartcb: length_change: %0.3f\n", emotion_object_play_length_get(o)); +} + +static void +_position_update_cb(void *data, Evas_Object *o, void *event_info) +{ + fprintf(stderr, "smartcb: position_update: %0.3f\n", emotion_object_position_get(o)); +} + +static void +_progress_change_cb(void *data, Evas_Object *o, void *event_info) +{ + fprintf(stderr, "smartcb: progress_change: %0.3f, %s\n", + emotion_object_progress_status_get(o), + emotion_object_progress_info_get(o)); +} + +static void +_frame_resize_cb(void *data, Evas_Object *o, void *event_info) +{ + int w, h; + emotion_object_size_get(o, &w, &h); + fprintf(stderr, "smartcb: frame_resize: %dx%d\n", w, h); +} + +int +main(int argc, const char *argv[]) +{ + Ecore_Evas *ee; + Evas *e; + Evas_Object *bg, *em; + int i; + + if (argc < 2) + { + printf("One argument is necessary. Usage:\n"); + printf("\t%s \n", argv[0]); + } + + eina_init(); + for (i = 1; i < argc; i++) + filenames = eina_list_append(filenames, eina_stringshare_add(argv[i])); + + curfile = filenames; + + if (!ecore_evas_init()) + return EXIT_FAILURE; + + /* this will give you a window with an Evas canvas under the first + * engine available */ + ee = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL); + if (!ee) + goto error; + + ecore_evas_show(ee); + + /* the canvas pointer, de facto */ + e = ecore_evas_get(ee); + + /* adding a background to this example */ + bg = evas_object_rectangle_add(e); + evas_object_name_set(bg, "our dear rectangle"); + evas_object_color_set(bg, 255, 255, 255, 255); /* white bg */ + evas_object_move(bg, 0, 0); /* at canvas' origin */ + evas_object_resize(bg, WIDTH, HEIGHT); /* covers full canvas */ + evas_object_show(bg); + + /* Creating the emotion object */ + em = _create_emotion_object(e); + emotion_object_file_set(em, eina_list_data_get(curfile)); + evas_object_move(em, 0, 0); + evas_object_resize(em, WIDTH, HEIGHT); + evas_object_show(em); + + evas_object_smart_callback_add(em, "frame_decode", _frame_decode_cb, NULL); + evas_object_smart_callback_add(em, "length_change", _length_change_cb, NULL); + evas_object_smart_callback_add(em, "position_update", _position_update_cb, NULL); + evas_object_smart_callback_add(em, "progress_change", _progress_change_cb, NULL); + evas_object_smart_callback_add(em, "frame_resize", _frame_resize_cb, NULL); + + evas_object_event_callback_add(bg, EVAS_CALLBACK_KEY_DOWN, _on_key_down, em); + evas_object_focus_set(bg, EINA_TRUE); + + emotion_object_play_set(em, EINA_TRUE); + + ecore_main_loop_begin(); + + ecore_evas_free(ee); + ecore_evas_shutdown(); + return 0; + +error: + fprintf(stderr, "you got to have at least one evas engine built and linked" + " up to ecore-evas for this example to run properly.\n"); + + EINA_LIST_FREE(filenames, curfile) + eina_stringshare_del(eina_list_data_get(curfile)); + + ecore_evas_shutdown(); + eina_shutdown(); + return -1; +} diff --git a/src/examples/emotion_signals_example.c b/src/examples/emotion_signals_example.c new file mode 100644 index 0000000..2469c46 --- /dev/null +++ b/src/examples/emotion_signals_example.c @@ -0,0 +1,173 @@ +#include +#include +#include +#include +#include + +#define WIDTH (320) +#define HEIGHT (240) + +static void +_display_info(Evas_Object *o) +{ + int w, h; + printf("playing: %d\n", emotion_object_play_get(o)); + printf("meta title: %s\n", + emotion_object_meta_info_get(o, EMOTION_META_INFO_TRACK_TITLE)); + printf("seek position: %0.3f\n", + emotion_object_position_get(o)); + printf("play length: %0.3f\n", + emotion_object_play_length_get(o)); + printf("is seekable: %d\n", + emotion_object_seekable_get(o)); + emotion_object_size_get(o, &w, &h); + printf("video geometry: %dx%d\n", w, h); + printf("video width / height ratio: %0.3f\n", + emotion_object_ratio_get(o)); + printf("\n"); +} + +static void +_playback_started_cb(void *data, Evas_Object *o, void *event_info) +{ + printf(">>> Emotion object started playback.\n"); + _display_info(o); +} + +static void +_playback_finished_cb(void *data, Evas_Object *o, void *event_info) +{ + printf(">>> Emotion object finished playback.\n"); + _display_info(o); +} + +static void +_open_done_cb(void *data, Evas_Object *o, void *event_info) +{ + printf(">>> Emotion object open done.\n"); + _display_info(o); +} + +static void +_position_update_cb(void *data, Evas_Object *o, void *event_info) +{ + printf(">>> Emotion object first position update.\n"); + evas_object_smart_callback_del(o, "position_update", _position_update_cb); + _display_info(o); +} + +static void +_frame_decode_cb(void *data, Evas_Object *o, void *event_info) +{ + printf(">>> Emotion object first frame decode.\n"); + evas_object_smart_callback_del(o, "frame_decode", _frame_decode_cb); + _display_info(o); +} + +static void +_decode_stop_cb(void *data, Evas_Object *o, void *event_info) +{ + printf(">>> Emotion object decode stop.\n"); + _display_info(o); +} + +static void +_frame_resize_cb(void *data, Evas_Object *o, void *event_info) +{ + printf(">>> Emotion object frame resize.\n"); + _display_info(o); +} + +static void +_setup_emotion_callbacks(Evas_Object *o) +{ + evas_object_smart_callback_add( + o, "playback_started", _playback_started_cb, NULL); + evas_object_smart_callback_add( + o, "playback_finished", _playback_finished_cb, NULL); + evas_object_smart_callback_add( + o, "open_done", _open_done_cb, NULL); + evas_object_smart_callback_add( + o, "position_update", _position_update_cb, NULL); + evas_object_smart_callback_add( + o, "frame_decode", _frame_decode_cb, NULL); + evas_object_smart_callback_add( + o, "decode_stop", _decode_stop_cb, NULL); + evas_object_smart_callback_add( + o, "frame_resize", _frame_resize_cb, NULL); +} + +int +main(int argc, const char *argv[]) +{ + Ecore_Evas *ee; + Evas *e; + Evas_Object *bg, *em; + const char *filename = NULL; + const char *module = NULL; + + if (argc < 2) + { + printf("At least one argument is necessary. Usage:\n"); + printf("\t%s [module_name]\n", argv[0]); + goto error; + } + + filename = argv[1]; + + if (argc >= 3) + module = argv[2]; + + if (!ecore_evas_init()) + return EXIT_FAILURE; + + /* this will give you a window with an Evas canvas under the first + * engine available */ + ee = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL); + if (!ee) + goto error; + + ecore_evas_show(ee); + + /* the canvas pointer, de facto */ + e = ecore_evas_get(ee); + + /* adding a background to this example */ + bg = evas_object_rectangle_add(e); + evas_object_name_set(bg, "our dear rectangle"); + evas_object_color_set(bg, 255, 255, 255, 255); /* white bg */ + evas_object_move(bg, 0, 0); /* at canvas' origin */ + evas_object_resize(bg, WIDTH, HEIGHT); /* covers full canvas */ + evas_object_show(bg); + + /* Creating the emotion object */ + em = emotion_object_add(e); + + /* Try to load the specified module - NULL for auto-discover */ + if (!emotion_object_init(em, module)) + fprintf(stderr, "Emotion: \"%s\" module could not be initialized.\n", module); + + _display_info(em); + _setup_emotion_callbacks(em); + + if (!emotion_object_file_set(em, filename)) + fprintf(stderr, "Emotion: Could not load the file \"%s\"\n", filename); + + evas_object_move(em, 0, 0); + evas_object_resize(em, WIDTH, HEIGHT); + evas_object_show(em); + + emotion_object_play_set(em, EINA_TRUE); + + ecore_main_loop_begin(); + + ecore_evas_free(ee); + ecore_evas_shutdown(); + return 0; + + ecore_evas_free(ee); + +error: + ecore_evas_shutdown(); + return -1; +} diff --git a/src/generic_players/Makefile.am b/src/generic_players/Makefile.am new file mode 100644 index 0000000..bbdd8c3 --- /dev/null +++ b/src/generic_players/Makefile.am @@ -0,0 +1,8 @@ + +MAINTAINERCLEANFILES = Makefile.in + +SUBDIRS = + +if EMOTION_BUILD_GENERIC_VLC +SUBDIRS += vlc +endif diff --git a/src/generic_players/vlc/Makefile.am b/src/generic_players/vlc/Makefile.am new file mode 100644 index 0000000..5cda1b9 --- /dev/null +++ b/src/generic_players/vlc/Makefile.am @@ -0,0 +1,18 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I$(top_srcdir) \ +-I$(top_srcdir)/src/lib \ +-I$(top_srcdir)/src/modules \ +-I$(top_srcdir)/src/modules/generic \ +-DPACKAGE_BIN_DIR=\"$(bindir)\" \ +-DPACKAGE_LIB_DIR=\"$(libdir)\" \ +-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ +@GENERIC_VLC_CFLAGS@ + +internal_bindir = $(libdir)/emotion/utils +internal_bin_PROGRAMS = em_generic_vlc + +em_generic_vlc_SOURCES = emotion_generic_vlc.c +em_generic_vlc_DEPENDENCIES = $(top_srcdir)/src/modules/generic/Emotion_Generic_Plugin.h +em_generic_vlc_LDADD = @GENERIC_VLC_LIBS@ @EFL_SHM_OPEN_LIBS@ -lpthread diff --git a/src/generic_players/vlc/emotion_generic_vlc.c b/src/generic_players/vlc/emotion_generic_vlc.c new file mode 100644 index 0000000..583036d --- /dev/null +++ b/src/generic_players/vlc/emotion_generic_vlc.c @@ -0,0 +1,873 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +enum _Thread_Events { + EM_THREAD_POSITION_CHANGED, + EM_THREAD_PLAYBACK_STARTED, + EM_THREAD_PLAYBACK_STOPPED, + EM_THREAD_LAST +}; + +struct _App { + Emotion_Generic_Video_Shared *vs; + Emotion_Generic_Video_Frame vf; + libvlc_instance_t *libvlc; + libvlc_media_t *m; + libvlc_media_player_t *mp; + libvlc_event_manager_t *event_mgr; + libvlc_event_manager_t *mevent_mgr; + char *filename; + char *shmname; + void *tmpbuffer; + int w, h; + int fd_read; // read commands from theads here + int fd_write; // write commands from threads here + int em_read; // read commands from emotion here + int em_write; // write commands to emotion here + int size_sent; + int opening; + int closing; + int playing; +}; + +static pthread_mutex_t _mutex_fd = PTHREAD_MUTEX_INITIALIZER; + +int +_em_read_safe(int fd, void *buf, ssize_t size) +{ + ssize_t todo; + char *p; + + todo = size; + p = buf; + + while (todo > 0) + { + ssize_t r; + + r = read(fd, p, todo); + if (r > 0) + { + todo -= r; + p += r; + } + else if (r == 0) + return 0; + else + { + if (errno == EINTR || errno == EAGAIN) + continue; + else + { + fprintf(stderr, "could not read from fd %d: %s", + fd, strerror(errno)); + return 0; + } + } + } + + return 1; +} + +int +_em_write_safe(int fd, const void *buf, ssize_t size) +{ + ssize_t todo; + const char *p; + + todo = size; + p = buf; + + while (todo > 0) + { + ssize_t r; + + r = write(fd, p, todo); + if (r > 0) + { + todo -= r; + p += r; + } + else if (r == 0) + return 0; + else + { + if (errno == EINTR || errno == EAGAIN) + continue; + else + { + fprintf(stderr, "could not write to fd %d: %s", + fd, strerror(errno)); + return 0; + } + } + } + + return 1; +} + +static int +_em_str_read(int fd, char **str) +{ + int size; + int r; + char buf[PATH_MAX]; + + r = _em_read_safe(fd, &size, sizeof(size)); + if (!r) + { + *str = NULL; + return 0; + } + + if (!size) + { + *str = NULL; + return 1; + } + + r = _em_read_safe(fd, buf, size); + if (!r) + { + *str = NULL; + return 0; + } + + *str = strdup(buf); + return 1; +} + +static int +_em_cmd_read(struct _App *app) +{ + int cmd; + _em_read_safe(app->em_read, &cmd, sizeof(cmd)); + + return cmd; +} + +static void +_send_cmd_start(struct _App *app, int cmd) +{ + pthread_mutex_lock(&_mutex_fd); + _em_write_safe(app->em_write, &cmd, sizeof(cmd)); +} + +static void +_send_cmd_finish(struct _App *app __UNUSED__) +{ + pthread_mutex_unlock(&_mutex_fd); +} + +static void +_send_cmd(struct _App *app, int cmd) +{ + _send_cmd_start(app, cmd); + _send_cmd_finish(app); +} + +static void +_send_cmd_str(struct _App *app, const char *str) +{ + int len; + if (str) + len = strlen(str) + 1; + else + len = 0; + _em_write_safe(app->em_write, &len, sizeof(len)); + _em_write_safe(app->em_write, str, len); +} + +#define SEND_CMD_PARAM(app, i) \ + _em_write_safe((app)->em_write, &(i), sizeof((i))); + +static void +_send_resize(struct _App *app, int width, int height) +{ + _send_cmd_start(app, EM_RESULT_FRAME_SIZE); + SEND_CMD_PARAM(app, width); + SEND_CMD_PARAM(app, height); + _send_cmd_finish(app); +} + +static void +_send_length_changed(struct _App *app, const struct libvlc_event_t *ev) +{ + float length = ev->u.media_player_length_changed.new_length; + length /= 1000; + + _send_cmd_start(app, EM_RESULT_LENGTH_CHANGED); + SEND_CMD_PARAM(app, length); + _send_cmd_finish(app); +} + +static void +_send_time_changed(struct _App *app, const struct libvlc_event_t *ev) +{ + float new_time = ev->u.media_player_time_changed.new_time; + new_time /= 1000; + if (app->vs->frame_drop > 1) + return; + _send_cmd_start(app, EM_RESULT_POSITION_CHANGED); + SEND_CMD_PARAM(app, new_time); + _send_cmd_finish(app); +} + +static void +_send_seekable_changed(struct _App *app, const struct libvlc_event_t *ev) +{ + int seekable = ev->u.media_player_seekable_changed.new_seekable; + _send_cmd_start(app, EM_RESULT_SEEKABLE_CHANGED); + SEND_CMD_PARAM(app, seekable); + _send_cmd_finish(app); +} + +static void * +_lock(void *data, void **pixels) +{ + struct _App *app = data; + + if (app->playing) + *pixels = app->vf.frames[app->vs->frame.player]; + else + *pixels = NULL; + + return NULL; // picture identifier, not needed here +} + +static void +_unlock(void *data __UNUSED__, void *id __UNUSED__, void *const *pixels __UNUSED__) +{ +} + +static void +_display(void *data, void *id __UNUSED__) +{ + struct _App *app = data; + if (!app->playing) + return; + + sem_wait(&app->vs->lock); + app->vs->frame.last = app->vs->frame.player; + app->vs->frame.player = app->vs->frame.next; + app->vs->frame.next = app->vs->frame.last; + if (!app->vs->frame_drop++) + _send_cmd(app, EM_RESULT_FRAME_NEW); + sem_post(&app->vs->lock); +} + +static void * +_tmp_lock(void *data, void **pixels) +{ + struct _App *app = data; + *pixels = app->tmpbuffer; + return NULL; +} + +static void +_tmp_unlock(void *data __UNUSED__, void *id __UNUSED__, void *const *pixels __UNUSED__) +{ +} + +static void +_tmp_display(void *data __UNUSED__, void *id __UNUSED__) +{ +} + +static void +_play(struct _App *app) +{ + float pos; + + if (!app->mp) + return; + + _em_read_safe(app->em_read, &pos, sizeof(pos)); + + if (app->playing) + { + libvlc_media_player_set_pause(app->mp, 0); + } + else + { + libvlc_time_t new_time = pos * 1000; + libvlc_media_player_set_time(app->mp, new_time); + libvlc_media_player_play(app->mp); + app->playing = 1; + } +} + +static void +_stop(struct _App *app) +{ + if (app->mp) + libvlc_media_player_set_pause(app->mp, 1); +} + +static void +_send_file_closed(struct _App *app) +{ + app->closing = 0; + emotion_generic_shm_free(app->vs); + _send_cmd(app, EM_RESULT_FILE_CLOSE); +} + +static void +_send_file_set(struct _App *app) +{ + if (app->opening) + _send_cmd(app, EM_RESULT_FILE_SET); + + if (app->closing) + _send_file_closed(app); +} + +static void +_event_cb(const struct libvlc_event_t *ev, void *data) +{ + struct _App *app = data; + int thread_event; + + switch (ev->type) { + case libvlc_MediaPlayerTimeChanged: + _send_time_changed(app, ev); + break; + case libvlc_MediaPlayerPositionChanged: + thread_event = EM_THREAD_POSITION_CHANGED; + write(app->fd_write, &thread_event, sizeof(thread_event)); + break; + case libvlc_MediaPlayerLengthChanged: + _send_length_changed(app, ev); + break; + case libvlc_MediaPlayerSeekableChanged: + _send_seekable_changed(app, ev); + break; + case libvlc_MediaPlayerPlaying: + _send_resize(app, app->w, app->h); + thread_event = EM_THREAD_PLAYBACK_STARTED; + write(app->fd_write, &thread_event, sizeof(thread_event)); + break; + case libvlc_MediaPlayerStopped: + _send_file_set(app); + break; + case libvlc_MediaPlayerEndReached: + thread_event = EM_THREAD_PLAYBACK_STOPPED; + write(app->fd_write, &thread_event, sizeof(thread_event)); + break; + } +} + +static void +_file_set(struct _App *app) +{ + if (app->opening) + { + libvlc_media_release(app->m); + libvlc_media_player_release(app->mp); + free(app->filename); + } + + _em_str_read(app->em_read, &app->filename); + + app->m = libvlc_media_new_path(app->libvlc, app->filename); + if (!app->m) + { + fprintf(stderr, "could not open path: \"%s\"\n", app->filename); + return; + } + + app->mp = libvlc_media_player_new_from_media(app->m); + if (!app->mp) + { + fprintf(stderr, "could not create new player from media.\n"); + return; + } + + app->opening = 1; + libvlc_video_set_format(app->mp, "RV32", DEFAULTWIDTH, DEFAULTHEIGHT, DEFAULTWIDTH * 4); + libvlc_video_set_callbacks(app->mp, _tmp_lock, _tmp_unlock, _tmp_display, app); + app->event_mgr = libvlc_media_player_event_manager(app->mp); + libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerPositionChanged, + _event_cb, app); + libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerStopped, + _event_cb, app); + + app->mevent_mgr = libvlc_media_event_manager(app->m); + + app->tmpbuffer = malloc(sizeof(char) * DEFAULTWIDTH * DEFAULTHEIGHT * 4); + libvlc_audio_set_mute(app->mp, 1); + libvlc_media_player_play(app->mp); +} + +static void +_position_set(struct _App *app) +{ + if (!app->mp) + return; + + float position; + _em_read_safe(app->em_read, &position, sizeof(position)); + + libvlc_time_t new_time = position * 1000; + libvlc_media_player_set_time(app->mp, new_time); +} + +static void +_speed_set(struct _App *app) +{ + float rate; + + if (!app->mp) + return; + + _em_read_safe(app->em_read, &rate, sizeof(rate)); + + libvlc_media_player_set_rate(app->mp, rate); +} + +static void +_mute_set(struct _App *app) +{ + int mute; + + if (!app->mp) + return; + + _em_read_safe(app->em_read, &mute, sizeof(mute)); + + libvlc_audio_set_mute(app->mp, mute); +} + +static void +_volume_set(struct _App *app) +{ + float volume; + int vol; + + if (!app->mp) + return; + + _em_read_safe(app->em_read, &volume, sizeof(volume)); + vol = volume * 100; + + libvlc_audio_set_volume(app->mp, vol); +} + +static void +_spu_track_set(struct _App *app) +{ + int track; + + _em_read_safe(app->em_read, &track, sizeof(track)); + + libvlc_video_set_spu(app->mp, track); +} + +static void +_audio_track_set(struct _App *app) +{ + int track; + + _em_read_safe(app->em_read, &track, sizeof(track)); + + libvlc_audio_set_track(app->mp, track); +} + +static void +_video_track_set(struct _App *app) +{ + int track; + + _em_read_safe(app->em_read, &track, sizeof(track)); + + libvlc_video_set_track(app->mp, track); +} + +static void +_file_set_done(struct _App *app) +{ + int r; + + app->opening = 0; + + r = emotion_generic_shm_get(app->shmname, &app->vs, &app->vf); + if (!r) + { + free(app->filename); + libvlc_media_release(app->m); + libvlc_media_player_release(app->mp); + app->filename = NULL; + app->m = NULL; + app->mp = NULL; + _send_cmd_start(app, EM_RESULT_FILE_SET_DONE); + SEND_CMD_PARAM(app, r); + _send_cmd_finish(app); + } + app->w = app->vs->width; + app->h = app->vs->height; + libvlc_video_set_format(app->mp, "RV32", app->w, app->h, app->w * 4); + libvlc_video_set_callbacks(app->mp, _lock, _unlock, _display, app); + + + libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerPlaying, + _event_cb, app); + libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerTimeChanged, + _event_cb, app); + libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerLengthChanged, + _event_cb, app); + libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerSeekableChanged, + _event_cb, app); + libvlc_event_attach(app->event_mgr, libvlc_MediaPlayerEndReached, + _event_cb, app); + + libvlc_audio_set_mute(app->mp, 0); + + _send_cmd_start(app, EM_RESULT_FILE_SET_DONE); + SEND_CMD_PARAM(app, r); + _send_cmd_finish(app); +} + +static void +_file_close(struct _App *app) +{ + app->playing = 0; + if (app->opening) + goto release_resources; + + if (libvlc_media_player_get_state(app->mp) != libvlc_Playing) + { + _send_file_closed(app); + return; + } + + app->closing = 1; + +release_resources: + libvlc_media_player_stop(app->mp); + if (app->filename) + free(app->filename); + if (app->mp) + { + libvlc_media_release(app->m); + libvlc_media_player_release(app->mp); + free(app->tmpbuffer); + } +} + +static void +_process_emotion_commands(struct _App *app) +{ + int cmd = _em_cmd_read(app); + switch (cmd) { + case EM_CMD_FILE_SET: + _file_set(app); + break; + case EM_CMD_FILE_SET_DONE: + _file_set_done(app); + break; + case EM_CMD_FILE_CLOSE: + _file_close(app); + break; + case EM_CMD_PLAY: + _play(app); + break; + case EM_CMD_STOP: + _stop(app); + break; + case EM_CMD_POSITION_SET: + _position_set(app); + break; + case EM_CMD_SPEED_SET: + _speed_set(app); + break; + case EM_CMD_AUDIO_MUTE_SET: + _mute_set(app); + break; + case EM_CMD_VOLUME_SET: + _volume_set(app); + break; + case EM_CMD_SPU_TRACK_SET: + _spu_track_set(app); + break; + case EM_CMD_AUDIO_TRACK_SET: + _audio_track_set(app); + break; + case EM_CMD_VIDEO_TRACK_SET: + _video_track_set(app); + break; + }; +} + +static void +_send_track_info(struct _App *app, int cmd, int current, int count, libvlc_track_description_t *desc) +{ + _send_cmd_start(app, cmd); + SEND_CMD_PARAM(app, current); + SEND_CMD_PARAM(app, count); + while (desc) + { + int tid = desc->i_id; + const char *name = desc->psz_name; + SEND_CMD_PARAM(app, tid); + _send_cmd_str(app, name); + desc = desc->p_next; + } + _send_cmd_finish(app); +} + +static void +_send_all_track_info(struct _App *app) +{ + int track_count, current; + libvlc_track_description_t *desc; + + current = libvlc_audio_get_track(app->mp); + track_count = libvlc_audio_get_track_count(app->mp); + desc = libvlc_audio_get_track_description(app->mp); + + _send_track_info(app, EM_RESULT_AUDIO_TRACK_INFO, + current, track_count, desc); + + current = libvlc_video_get_track(app->mp); + track_count = libvlc_video_get_track_count(app->mp); + desc = libvlc_video_get_track_description(app->mp); + + _send_track_info(app, EM_RESULT_VIDEO_TRACK_INFO, + current, track_count, desc); + + current = libvlc_video_get_spu(app->mp); + track_count = libvlc_video_get_spu_count(app->mp); + desc = libvlc_video_get_spu_description(app->mp); + + _send_track_info(app, EM_RESULT_SPU_TRACK_INFO, + current, track_count, desc); +} + +static void +_send_all_meta_info(struct _App *app) +{ + const char *meta; + + _send_cmd_start(app, EM_RESULT_META_INFO); + + /* + * Will send in this order: title, artist, album, year, + * genre, comments, disc id and track count. + */ + meta = libvlc_media_get_meta(app->m, libvlc_meta_Title); + _send_cmd_str(app, meta); + meta = libvlc_media_get_meta(app->m, libvlc_meta_Artist); + _send_cmd_str(app, meta); + meta = libvlc_media_get_meta(app->m, libvlc_meta_Album); + _send_cmd_str(app, meta); + meta = libvlc_media_get_meta(app->m, libvlc_meta_Date); + _send_cmd_str(app, meta); + meta = libvlc_media_get_meta(app->m, libvlc_meta_Genre); + _send_cmd_str(app, meta); + meta = NULL; // sending empty comments + _send_cmd_str(app, meta); + meta = NULL; // sending empty disc id + _send_cmd_str(app, meta); + meta = libvlc_media_get_meta(app->m, libvlc_meta_TrackNumber); + _send_cmd_str(app, meta); + _send_cmd_finish(app); +} + +static void +_position_changed(struct _App *app) +{ + if (!app->opening) + return; + + /* sending size info only once */ + int r; + unsigned int w, h; + r = libvlc_video_get_size(app->mp, 0, &w, &h); + if (r < 0) + { + w = 1; + h = 1; + } + _send_resize(app, w, h); + + /* sending audio track info */ + _send_all_track_info(app); + + /* sending meta info */ + _send_all_meta_info(app); + + libvlc_media_player_stop(app->mp); +} + +static void +_process_thread_events(struct _App *app) +{ + int event; + size_t size; + + size = read(app->fd_read, &event, sizeof(event)); + if (size != sizeof(event)) + { + fprintf(stderr, "player: problem when reading thread event. size = %zd\n", size); + return; + } + + switch (event) { + case EM_THREAD_POSITION_CHANGED: + _position_changed(app); + break; + case EM_THREAD_PLAYBACK_STARTED: + _send_cmd(app, EM_RESULT_PLAYBACK_STARTED); + break; + case EM_THREAD_PLAYBACK_STOPPED: + app->playing = 0; + _send_cmd(app, EM_RESULT_PLAYBACK_STOPPED); + break; + } +} + +int +main(int argc, const char *argv[]) +{ + struct _App app; + struct pollfd fds[3]; + int tpipe[2]; // pipe for comunicating events from threads + char cwidth[64], cheight[64], cpitch[64], chroma[64]; + char buf[64]; + const char *vlc_argv[] = + { + "--quiet", + "--vout", + "vmem", + "--vmem-width", + cwidth, + "--vmem-height", + cheight, + "--vmem-pitch", + cpitch, + "--vmem-chroma", + chroma + }; + + if (argc < 3) + { + fprintf(stderr, "player: missing paramters.\n"); + fprintf(stderr, "syntax:\n\t%s \n", argv[0]); + return -1; + } + + app.em_read = atoi(argv[1]); + app.em_write = atoi(argv[2]); + + int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); + snprintf(cwidth, sizeof(cwidth), "%d", DEFAULTWIDTH); + snprintf(cheight, sizeof(cheight), "%d", DEFAULTHEIGHT); + snprintf(cpitch, sizeof(cpitch), "%d", DEFAULTWIDTH * 4); + snprintf(chroma, sizeof(chroma), "RV32"); + + /* + * Naughty xattr in emotion uses ecore_thread to run its thing, this + * may leave emotion's reference count high and it won't kill us... + * letting us play the video in the background. not good. + * + * prctl(PR_SET_PDEATHSIG) is a linux only thing. Need to find ways + * to do it on other platforms. Until then leave it breaking on + * such platforms so people port it instead of ignoring. + */ + prctl(PR_SET_PDEATHSIG, SIGHUP); + + app.libvlc = libvlc_new(vlc_argc, vlc_argv); + app.mp = NULL; + app.filename = NULL; + app.w = 0; + app.h = 0; + app.size_sent = 0; + app.opening = 0; + app.playing = 0; + app.closing = 0; + + if (_em_cmd_read(&app) != EM_CMD_INIT) + { + fprintf(stderr, "player: wrong init command!\n"); + return -1; + } + + int size; + _em_read_safe(app.em_read, &size, sizeof(size)); + _em_read_safe(app.em_read, buf, size); + app.shmname = strdup(buf); + + _send_cmd(&app, EM_RESULT_INIT); + + pipe(tpipe); + app.fd_read = tpipe[0]; + app.fd_write = tpipe[1]; + fds[0].fd = app.em_read; + fds[0].events = POLLIN; + fds[1].fd = app.fd_read; + fds[1].events = POLLIN; + fds[2].fd = STDERR_FILENO; + fds[2].events = 0; + + while (1) + { + int r; + + r = poll(fds, 3, -1); + if (r == 0) + continue; + else if (r < 0) + { + fprintf(stderr, + "emotion_generic_vlc: an error ocurred on poll(): %s\n", + strerror(errno)); + break; + } + + if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) + { + fputs("emotion_generic_vlc: error communicating with stdin\n", + stderr); + break; + } + if (fds[1].revents & (POLLERR | POLLHUP | POLLNVAL)) + { + fputs("emotion_generic_vlc: error communicating with thread\n", + stderr); + break; + } + + if (fds[0].revents & POLLIN) + _process_emotion_commands(&app); + if (fds[1].revents & POLLIN) + _process_thread_events(&app); + if (fds[2].revents & (POLLERR | POLLHUP | POLLNVAL)) + break; + } + + libvlc_release(app.libvlc); + + + return 0; +} +#undef SEND_CMD_PARAM diff --git a/src/lib/Emotion.h b/src/lib/Emotion.h index e55757f..361e4e5 100644 --- a/src/lib/Emotion.h +++ b/src/lib/Emotion.h @@ -1,15 +1,97 @@ #ifndef EMOTION_H #define EMOTION_H +/** + * @file + * @brief Emotion Media Library + * + * These routines are used for Emotion. + */ + +/** + * + * @mainpage Emotion Library Documentation + * + * @version 1.7.0 + * @date 2003-2012 + * + * @section intro What is Emotion? + * + * A media object library for Evas and Ecore. + * + * Emotion is a library that allows playing audio and video files, using one of + * its backends (gstreamer or xine). + * + * It is integrated into Ecore through its mainloop, and is transparent to the + * user of the library how the decoding of audio and video is being done. Once + * the objects are created, the user can set callbacks to the specific events + * and set options to this object, all in the main loop (no threads are needed). + * + * Emotion is also integrated with Evas. The emotion object returned by + * emotion_object_add() is an Evas smart object, so it can be manipulated with + * default Evas object functions. Callbacks can be added to the signals emitted + * by this object with evas_object_smart_callback_add(). + * + * @section work How does Emotion work? + * + * The Emotion library uses Evas smart objects to allow you to manipulate the + * created object as any other Evas object, and to connect to its signals, + * handling them when needed. It's also possible to swallow Emotion objects + * inside Edje themes, and expect it to behave as a normal image or rectangle + * when regarding to its dimensions. + * + * To instantiate an Emotion object, the simple code below is enough: + * + * @code + * em = emotion_object_add(e); + * emotion_object_init(em, NULL); + * + * emotion_object_file_set(em, file_path); + * + * evas_object_move(em, 0, 0); + * evas_object_resize(em, WIDTH, HEIGHT); + * evas_object_show(em); + * + * emotion_object_play_set(em, EINA_TRUE); + * @endcode + * + * See the @ref Emotion_API for a better reference. + * + * Please see the @ref authors page for contact details. + * + */ + +/** + * + * @page authors Authors + * + * @author Carsten Haitzler + * @author Vincent Torri + * @author Nicolas Aguirre + * @author Sebastian Dransfeld + * @author Cedric Bail + * + * Please contact to get in + * contact with the developers and maintainers. + * + */ + +#include + #ifdef EAPI -#undef EAPI +# undef EAPI #endif -#ifdef WIN32 -# ifdef BUILDING_DLL -# define EAPI __declspec(dllexport) + +#ifdef _WIN32 +# ifdef EFL_EMOTION_BUILD +# ifdef DLL_EXPORT +# define EAPI __declspec(dllexport) +# else +# define EAPI +# endif /* ! DLL_EXPORT */ # else # define EAPI __declspec(dllimport) -# endif +# endif /* ! EFL_EMOTION_BUILD */ #else # ifdef __GNUC__ # if __GNUC__ >= 4 @@ -20,9 +102,13 @@ # else # define EAPI # endif -#endif +#endif /* ! _WIN32 */ -#include +/** + * @file Emotion.h + * @brief The file that provides Emotion the API, with functions available for + * play, seek, change volume, etc. + */ enum _Emotion_Module { @@ -62,21 +148,97 @@ enum _Emotion_Event EMOTION_EVENT_10 }; +/** + * @enum _Emotion_Meta_Info + * + * Used for retrieving information about the media file being played. + * + * @see emotion_object_meta_info_get() + * + * @ingroup Emotion_Info + */ enum _Emotion_Meta_Info { - EMOTION_META_INFO_TRACK_TITLE, - EMOTION_META_INFO_TRACK_ARTIST, - EMOTION_META_INFO_TRACK_ALBUM, - EMOTION_META_INFO_TRACK_YEAR, - EMOTION_META_INFO_TRACK_GENRE, - EMOTION_META_INFO_TRACK_COMMENT, - EMOTION_META_INFO_TRACK_DISC_ID, - EMOTION_META_INFO_TRACK_COUNT + EMOTION_META_INFO_TRACK_TITLE, /**< track title */ + EMOTION_META_INFO_TRACK_ARTIST, /**< artist name */ + EMOTION_META_INFO_TRACK_ALBUM, /**< album name */ + EMOTION_META_INFO_TRACK_YEAR, /**< track year */ + EMOTION_META_INFO_TRACK_GENRE, /**< track genre */ + EMOTION_META_INFO_TRACK_COMMENT, /**< track comments */ + EMOTION_META_INFO_TRACK_DISC_ID, /**< track disc ID */ + EMOTION_META_INFO_TRACK_COUNT /**< track count - number of the track in the album */ +}; + +/** + * @enum _Emotion_Vis + * + * Used for displaying a visualization on the emotion object. + * + * @see emotion_object_vis_set() + * + * @ingroup Emotion_Visualization + */ +enum _Emotion_Vis +{ + EMOTION_VIS_NONE, /**< no visualization set */ + EMOTION_VIS_GOOM, /**< goom */ + EMOTION_VIS_LIBVISUAL_BUMPSCOPE, /**< bumpscope */ + EMOTION_VIS_LIBVISUAL_CORONA, /**< corona */ + EMOTION_VIS_LIBVISUAL_DANCING_PARTICLES, /**< dancing particles */ + EMOTION_VIS_LIBVISUAL_GDKPIXBUF, /**< gdkpixbuf */ + EMOTION_VIS_LIBVISUAL_G_FORCE, /**< G force */ + EMOTION_VIS_LIBVISUAL_GOOM, /**< goom */ + EMOTION_VIS_LIBVISUAL_INFINITE, /**< infinite */ + EMOTION_VIS_LIBVISUAL_JAKDAW, /**< jakdaw */ + EMOTION_VIS_LIBVISUAL_JESS, /**< jess */ + EMOTION_VIS_LIBVISUAL_LV_ANALYSER, /**< lv analyser */ + EMOTION_VIS_LIBVISUAL_LV_FLOWER, /**< lv flower */ + EMOTION_VIS_LIBVISUAL_LV_GLTEST, /**< lv gltest */ + EMOTION_VIS_LIBVISUAL_LV_SCOPE, /**< lv scope */ + EMOTION_VIS_LIBVISUAL_MADSPIN, /**< madspin */ + EMOTION_VIS_LIBVISUAL_NEBULUS, /**< nebulus */ + EMOTION_VIS_LIBVISUAL_OINKSIE, /**< oinksie */ + EMOTION_VIS_LIBVISUAL_PLASMA, /**< plasma */ + EMOTION_VIS_LAST /* sentinel */ +}; + +/** + * @enum Emotion_Suspend + * + * Used for emotion pipeline ressource management. + * + * @see emotion_object_suspend_set() + * @see emotion_object_suspend_get() + * + * @ingroup Emotion_Ressource + */ +typedef enum +{ + EMOTION_WAKEUP, /**< pipeline is up and running */ + EMOTION_SLEEP, /**< turn off hardware ressource usage like overlay */ + EMOTION_DEEP_SLEEP, /**< destroy the pipeline, but keep full resolution pixels output around */ + EMOTION_HIBERNATE /**< destroy the pipeline, and keep half resolution or object resolution if lower */ +} Emotion_Suspend; + +/** + * @enum _Emotion_Aspect + * Defines the aspect ratio option. + */ +enum _Emotion_Aspect +{ + EMOTION_ASPECT_KEEP_NONE, /**< ignore video aspect ratio */ + EMOTION_ASPECT_KEEP_WIDTH, /**< respect video aspect, fitting its width inside the object width */ + EMOTION_ASPECT_KEEP_HEIGHT, /**< respect video aspect, fitting its height inside the object height */ + EMOTION_ASPECT_KEEP_BOTH, /**< respect video aspect, fitting it inside the object area */ + EMOTION_ASPECT_CROP, /**< respect video aspect, cropping exceding area */ + EMOTION_ASPECT_CUSTOM, /**< use custom borders/crop for the video */ }; typedef enum _Emotion_Module Emotion_Module; typedef enum _Emotion_Event Emotion_Event; -typedef enum _Emotion_Meta_Info Emotion_Meta_Info; +typedef enum _Emotion_Meta_Info Emotion_Meta_Info; /**< Meta info type to be retrieved. */ +typedef enum _Emotion_Vis Emotion_Vis; /**< Type of visualization. */ +typedef enum _Emotion_Aspect Emotion_Aspect; /**< Aspect ratio option. */ #define EMOTION_CHANNEL_AUTO -1 #define EMOTION_CHANNEL_DEFAULT 0 @@ -84,64 +246,1037 @@ typedef enum _Emotion_Meta_Info Emotion_Meta_Info; #ifdef __cplusplus extern "C" { #endif + +#define EMOTION_VERSION_MAJOR 1 +#define EMOTION_VERSION_MINOR 8 + + typedef struct _Emotion_Version + { + int major; + int minor; + int micro; + int revision; + } Emotion_Version; + + EAPI extern Emotion_Version *emotion_version; /* api calls available */ + +/** + * @brief How to create, initialize, manipulate and connect to signals of an + * Emotion object. + * @defgroup Emotion_API API available for manipulating Emotion object. + * + * @{ + * + * Emotion provides an Evas smart object that allows to play, control and + * display a video or audio file. The API is synchronous but not everything + * happens immediately. There are also some signals to report changed states. + * + * Basically, once the object is created and initialized, a file will be set to + * it, and then it can be resized, moved, and controlled by other Evas object + * functions. + * + * However, the decoding of the music and video occurs not in the Ecore main + * loop, but usually in another thread (this depends on the module being used). + * The synchronization between this other thread and the main loop not visible + * to the end user of the library. The user can just register callbacks to the + * available signals to receive information about the changed states, and can + * call other functions from the API to request more changes on the current + * loaded file. + * + * There will be a delay between an API being called and it being really + * executed, since this request will be done in the main thread, and it needs to + * be sent to the decoding thread. For this reason, always call functions like + * emotion_object_size_get() or emotion_object_length_get() after some signal + * being sent, like "playback_started" or "open_done". @ref + * emotion_signals_example.c "This example demonstrates this behavior". + * + * @section signals Available signals + * The Evas_Object returned by emotion_object_add() has a number of signals that + * can be listened to using evas' smart callbacks mechanism. All signals have + * NULL as event info. The following is a list of interesting signals: + * @li "playback_started" - Emitted when the playback starts + * @li "playback_finished" - Emitted when the playback finishes + * @li "frame_decode" - Emitted every time a frame is decoded + * @li "open_done" - Emitted when the media file is opened + * @li "position_update" - Emitted when emotion_object_position_set is called + * @li "decode_stop" - Emitted after the last frame is decoded + * + * @section Examples + * + * The following examples exemplify the emotion usage. There's also the + * emotion_test binary that is distributed with this library and cover the + * entire API, but since it is too long and repetitive to be explained, its code + * is just displayed as another example. + * + * @li @ref emotion_basic_example_c + * @li @ref emotion_signals_example.c "Emotion signals" + * @li @ref emotion_test_main.c "emotion_test - full API usage" + * + */ + +/** + * @defgroup Emotion_Init Creation and initialization functions + */ + +/** + * @defgroup Emotion_Audio Audio control functions + */ + +/** + * @defgroup Emotion_Video Video control functions + */ + +/** + * @defgroup Emotion_Visualization Visualization control functions + */ + +/** + * @defgroup Emotion_Info Miscellaneous information retrieval functions + */ + +/** + * @defgroup Emotion_Ressource Video ressource management + */ + +EAPI Eina_Bool emotion_init(void); +EAPI Eina_Bool emotion_shutdown(void); + +/** + * @brief Add an emotion object to the canvas. + * + * @param evas The canvas where the object will be added to. + * @return The emotion object just created. + * + * This function creates an emotion object and adds it to the specified @p evas. + * The returned object can be manipulated as any other Evas object, using the + * default object manipulation functions - evas_object_*. + * + * After creating the object with this function, it's still necessary to + * initialize it with emotion_object_init(), and if an audio file is going to be + * played with this object instead of a video, use + * emotion_object_video_mute_set(). + * + * The next step is to open the desired file with emotion_object_file_set(), and + * start playing it with emotion_object_play_set(). + * + * @see emotion_object_init() + * @see emotion_object_video_mute_set() + * @see emotion_object_file_set() + * @see emotion_object_play_set() + * + * @ingroup Emotion_Init + */ EAPI Evas_Object *emotion_object_add (Evas *evas); + +/** + * @brief Set the specified option for the current module. + * + * @param obj The emotion object which the option is being set to. + * @param opt The option that is being set. Currently supported optiosn: "video" + * and "audio". + * @param val The value of the option. Currently only supports "off" (?!?!?!) + * + * This function allows one to mute the video or audio of the emotion object. + * + * @note Please don't use this function, consider using + * emotion_object_audio_mute_set() and emotion_object_video_mute_set() instead. + * + * @see emotion_object_audio_mute_set() + * @see emotion_object_video_mute_set() + * + * @ingroup Emotion_Init + */ EAPI void emotion_object_module_option_set (Evas_Object *obj, const char *opt, const char *val); -EAPI Evas_Bool emotion_object_init (Evas_Object *obj, const char *module_filename); -EAPI void emotion_object_file_set (Evas_Object *obj, const char *filename); -EAPI const char *emotion_object_file_get (Evas_Object *obj); -EAPI void emotion_object_play_set (Evas_Object *obj, Evas_Bool play); -EAPI Evas_Bool emotion_object_play_get (Evas_Object *obj); + +/** + * @brief Initializes an emotion object with the specified module. + * + * @param obj The emotion object to be initialized. + * @param module_filename The name of the module to be used (gstreamer or xine). + * @return @c EINA_TRUE if the specified module was successfully initialized for + * this object, @c EINA_FALSE otherwise. + * + * This function is required after creating the emotion object, in order to + * specify which module will be used with this object. Different objects can + * use different modules to play a media file. The current supported modules are + * @b gstreamer and @b xine. + * + * To use any of them, you need to make sure that support for them was compiled + * correctly. + * + * @note It's possible to disable the build of a module with + * --disable-module_name. + * + * @see emotion_object_add() + * @see emotion_object_file_set() + * + * @ingroup Emotion_Init + */ +EAPI Eina_Bool emotion_object_init (Evas_Object *obj, const char *module_filename); + +/** + * @brief Set borders for the emotion object. + * + * @param obj The emotion object where borders are being set. + * @param l The left border. + * @param r The right border. + * @param t The top border. + * @param b The bottom border. + * + * This function sets borders for the emotion video object (just when a video is + * present). When positive values are given to one of the parameters, a border + * will be added to the respective position of the object, representing that + * size on the original video size. However, if the video is scaled up or down + * (i.e. the emotion object size is different from the video size), the borders + * will be scaled respectively too. + * + * If a negative value is given to one of the parameters, instead of a border, + * that respective side of the video will be cropped. + * + * It's possible to set a color for the added borders (default is transparent) + * with emotion_object_bg_color_set(). By default, an Emotion object doesn't + * have any border. + * + * @see emotion_object_border_get() + * @see emotion_object_bg_color_set() + * + * @ingroup Emotion_Video + */ +EAPI void emotion_object_border_set(Evas_Object *obj, int l, int r, int t, int b); + +/** + * @brief Get the borders set for the emotion object. + * + * @param obj The emotion object from which the borders are being retrieved. + * @param l The left border. + * @param r The right border. + * @param t The top border. + * @param b The bottom border. + * + * @see emotion_object_border_set() + * + * @ingroup Emotion_Video + */ +EAPI void emotion_object_border_get(const Evas_Object *obj, int *l, int *r, int *t, int *b); + +/** + * @brief Set a color for the background rectangle of this emotion object. + * + * @param obj The emotion object where the background color is being set. + * @param r Red component of the color. + * @param g Green component of the color. + * @param b Blue component of the color. + * @param a Alpha channel of the color. + * + * This is useful when a border is added to any side of the Emotion object. The + * area between the edge of the video and the edge of the object will be filled + * with the specified color. + * + * The default color is 0, 0, 0, 0 (transparent). + * + * @see emotion_object_bg_color_get() + * + * @ingroup Emotion_Video + */ +EAPI void emotion_object_bg_color_set(Evas_Object *obj, int r, int g, int b, int a); + +/** + * @brief Get the background color set for the emotion object. + * + * @param obj The emotion object from which the background color is being retrieved. + * @param r Red component of the color. + * @param g Green component of the color. + * @param b Blue component of the color. + * @param a AAlpha channel of the color. + * + * @see emotion_object_bg_color_set() + * + * @ingroup Emotion_Video + */ +EAPI void emotion_object_bg_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a); + +/** + * @brief Set whether emotion should keep the aspect ratio of the video. + * + * @param obj The emotion object where to set the aspect. + * @param a The aspect ratio policy. + * + * Instead of manually calculating the required border to set with + * emotion_object_border_set(), and using this to fix the aspect ratio of the + * video when the emotion object has a different aspect, it's possible to just + * set the policy to be used. + * + * The options are: + * + * - @b #EMOTION_ASPECT_KEEP_NONE - ignore the video aspect ratio, and reset any + * border set to 0, stretching the video inside the emotion object area. This + * option is similar to EVAS_ASPECT_CONTROL_NONE size hint. + * - @b #EMOTION_ASPECT_KEEP_WIDTH - respect the video aspect ratio, fitting the + * video width inside the object width. This option is similar to + * EVAS_ASPECT_CONTROL_HORIZONTAL size hint. + * - @b #EMOTION_ASPECT_KEEP_HEIGHT - respect the video aspect ratio, fitting + * the video height inside the object height. This option is similar to + * EVAS_ASPECT_CONTROL_VERTIAL size hint. + * - @b #EMOTION_ASPECT_KEEP_BOTH - respect the video aspect ratio, fitting both + * its width and height inside the object area. This option is similar to + * EVAS_ASPECT_CONTROL_BOTH size hint. It's the effect called letterboxing. + * - @b #EMOTION_ASPECT_CROP - respect the video aspect ratio, fitting the width + * or height inside the object area, and cropping the exceding areas of the + * video in height or width. It's the effect called pan-and-scan. + * - @b #EMOTION_ASPECT_CUSTOM - ignore the video aspect ratio, and use the + * current set from emotion_object_border_set(). + * + * @note Calling this function with any value except #EMOTION_ASPECT_CUSTOM will + * invalidate borders set with emotion_object_border_set(). + * + * @note Calling emotion_object_border_set() will automatically set the aspect + * policy to #EMOTION_ASPECT_CUSTOM. + * + * @see emotion_object_border_set() + * @see emotion_object_keep_aspect_get() + * + * @ingroup Emotion_Video + */ +EAPI void emotion_object_keep_aspect_set(Evas_Object *obj, Emotion_Aspect a); + +/** + * @brief Get the current emotion aspect ratio policy. + * + * @param obj The emotion object from which we are fetching the aspect ratio + * policy. + * @return The current aspect ratio policy. + * + * @see emotion_object_keep_aspect_set() + * + * @ingroup Emotion_Video + */ +EAPI Emotion_Aspect emotion_object_keep_aspect_get(const Evas_Object *obj); + +/** + * @brief Set the file to be played in the Emotion object. + * + * @param obj The emotion object where the file is being loaded. + * @param filename Path to the file to be loaded. It can be absolute or relative + * path. + * @return EINA_TRUE if the new file could be loaded successfully, and + * EINA_FALSE if the file could not be loaded. This happens when the filename is + * could not be found, when the module couldn't open the file, when no module is + * initialized in this object, or when the @p filename is the same as the + * one previously set. + * + * This function sets the file to be used with this emotion object. If the + * object already has another file set, this file will be unset and unloaded, + * and the new file will be loaded to this emotion object. The seek position + * will be set to 0, and the emotion object will be paused, instead of playing. + * + * If there was already a filename set, and it's the same as the one being set + * now, this function does nothing and returns EINA_FALSE. + * + * Use @c NULL as argument to @p filename if you want to unload the current file + * but don't want to load anything else. + * + * @see emotion_object_init() + * @see emotion_object_play_set() + * @see emotion_object_file_get() + * + * @ingroup Emotion_Init + */ +EAPI Eina_Bool emotion_object_file_set (Evas_Object *obj, const char *filename); + +/** + * @brief Get the filename of the file associated with the emotion object. + * + * @param obj The emotion object from which the filename will be retrieved. + * @return The path to the file loaded into this emotion object. + * + * This function returns the path of the file loaded in this emotion object. If + * no object is loaded, it will return @c NULL. + * + * @note Don't free or change the string returned by this function in any way. + * If you want to unset it, use @c emotion_object_file_set(obj, NULL). + * + * @see emotion_object_file_set() + * + * @ingroup Emotion_Init + */ +EAPI const char *emotion_object_file_get (const Evas_Object *obj); +/** + * @defgroup Emotion_Play Play control functions + * + * @{ + */ +/** + * + * @brief Set play/pause state of the media file. + * + * @param obj The emotion object whose state will be changed. + * @param play EINA_TRUE to play, EINA_FALSE to pause. + * + * This functions sets the currently playing status of the video. Using this + * function to play or pause the video doesn't alter it's current position. + */ +EAPI void emotion_object_play_set (Evas_Object *obj, Eina_Bool play); +/** + * @brief Get play/pause state of the media file. + * + * @param obj The emotion object from which the state will be retrieved. + * @return EINA_TRUE if playing. EINA_FALSE if not playing. + */ +EAPI Eina_Bool emotion_object_play_get (const Evas_Object *obj); +/** + * @brief Set the position in the media file. + * + * @param obj The emotion object whose position will be changed. + * @param sec The position(in seconds) to which the media file will be set. + * + * This functions sets the current position of the media file to @p sec, this + * only works on seekable streams. Setting the position doesn't change the + * playing state of the media file. + * + * @see emotion_object_seekable_get + */ EAPI void emotion_object_position_set (Evas_Object *obj, double sec); -EAPI double emotion_object_position_get (Evas_Object *obj); -EAPI Evas_Bool emotion_object_video_handled_get (Evas_Object *obj); -EAPI Evas_Bool emotion_object_audio_handled_get (Evas_Object *obj); -EAPI Evas_Bool emotion_object_seekable_get (Evas_Object *obj); -EAPI double emotion_object_play_length_get (Evas_Object *obj); -EAPI void emotion_object_size_get (Evas_Object *obj, int *iw, int *ih); -EAPI void emotion_object_smooth_scale_set (Evas_Object *obj, Evas_Bool smooth); -EAPI Evas_Bool emotion_object_smooth_scale_get (Evas_Object *obj); -EAPI double emotion_object_ratio_get (Evas_Object *obj); +/** + * @brief Get the position in the media file. + * + * @param obj The emotion object from which the position will be retrieved. + * @return The position of the media file. + * + * The position is returned as the number of seconds since the beginning of the + * media file. + */ +EAPI double emotion_object_position_get (const Evas_Object *obj); + +/** + * @brief Get the percentual size of the buffering cache. + * + * @param obj The emotion object from which the buffer size will be retrieved. + * @return The buffer percent size, ranging from 0.0 to 1.0 + * + * The buffer size is returned as a number between 0.0 and 1.0, 0.0 means + * the buffer if empty, 1.0 means full. + * If no buffering is in progress 1.0 is returned. In all other cases (maybe + * the backend don't support buffering) 1.0 is returned, thus you can always + * check for buffer_size < 1.0 to know if buffering is in progress. + * + * @warning Generic backend don't implement this (will return 1.0). + */ +EAPI double emotion_object_buffer_size_get (const Evas_Object *obj); + +/** + * @brief Get whether the media file is seekable. + * + * @param obj The emotion object from which the seekable status will be + * retrieved. + * @return EINA_TRUE if the media file is seekable, EINA_FALSE otherwise. + */ +EAPI Eina_Bool emotion_object_seekable_get (const Evas_Object *obj); +/** + * @brief Get the length of play for the media file. + * + * @param obj The emotion object from which the length will be retrieved. + * @return The length of the media file in seconds. + * + * This function returns the length of the media file in seconds. + * + * @warning This will return 0 if called before the "length_change" signal has, + * been emitted. + */ +EAPI double emotion_object_play_length_get (const Evas_Object *obj); + +/** + * @brief Set the play speed of the media file. + * + * @param obj The emotion object whose speed will be set. + * @param speed The speed to be set in the range [0,infinity) + * + * This function sets the speed with which the media file will be played. 1.0 + * represents the normal speed, 2 double speed, 0.5 half speed and so on. + * + * @warning The only backend that implements this is the experimental VLC + * backend. + */ +EAPI void emotion_object_play_speed_set (Evas_Object *obj, double speed); +/** + * @brief Get the play speed of the media file. + * + * @param obj The emotion object from which the filename will be retrieved. + * @return The current speed of the media file. + * + * @see emotion_object_play_speed_set + */ +EAPI double emotion_object_play_speed_get (const Evas_Object *obj); +/** + * @brief Get how much of the file has been played. + * + * @param obj The emotion object from which the filename will be retrieved. + * @return The progress of the media file. + * + * @warning Don't change of free the returned string. + * @warning gstreamer xine backends don't implement this(will return NULL). + */ +EAPI const char *emotion_object_progress_info_get (const Evas_Object *obj); +/** + * @brief Get how much of the file has been played. + * + * @param obj The emotion object from which the filename will be retrieved + * @return The progress of the media file. + * + * This function gets the progress in playing the file, the return value is in + * the [0, 1] range. + * + * @warning gstreamer xine backends don't implement this(will return 0). + */ +EAPI double emotion_object_progress_status_get (const Evas_Object *obj); +/** + * @} + */ +EAPI Eina_Bool emotion_object_video_handled_get (const Evas_Object *obj); +EAPI Eina_Bool emotion_object_audio_handled_get (const Evas_Object *obj); + +/** + * @brief Retrieve the video aspect ratio of the media file loaded. + * + * @param obj The emotion object which the video aspect ratio will be retrieved + * from. + * @return The video aspect ratio of the file loaded. + * + * This function returns the video aspect ratio (width / height) of the file + * loaded. It can be used to adapt the size of the emotion object in the canvas, + * so the aspect won't be changed (by wrongly resizing the object). Or to crop + * the video correctly, if necessary. + * + * The described behavior can be applied like following. Consider a given + * emotion object that we want to position inside an area, which we will + * represent by @c w and @c h. Since we want to position this object either + * stretching, or filling the entire area but overflowing the video, or just + * adjust the video to fit inside the area without keeping the aspect ratio, we + * must compare the video aspect ratio with the area aspect ratio: + * @code + * int w = 200, h = 300; // an arbitrary value which represents the area where + * // the video would be placed + * int vw, vh; + * double r, vr = emotion_object_ratio_get(obj); + * r = (double)w / h; + * @endcode + * + * Now, if we want to make the video fit inside the area, the following code + * would do it: + * @code + * if (vr > r) // the video is wider than the area + * { + * vw = w; + * vh = w / vr; + * } + * else // the video is taller than the area + * { + * vh = h; + * vw = h * vr; + * } + * evas_object_resize(obj, vw, vh); + * @endcode + * + * And for keeping the aspect ratio but making the video fill the entire area, + * overflowing the content which can't fit inside it, we would do: + * @code + * if (vr > r) // the video is wider than the area + * { + * vh = h; + * vw = h * vr; + * } + * else // the video is taller than the area + * { + * vw = w; + * vh = w / vr; + * } + * evas_object_resize(obj, vw, vh); + * @endcode + * + * Finally, by just resizing the video to the video area, we would have the + * video stretched: + * @code + * vw = w; + * vh = h; + * evas_object_resize(obj, vw, vh); + * @endcode + * + * The following diagram exemplifies what would happen to the video, + * respectively, in each case: + * + * @image html emotion_ratio.png + * @image latex emotion_ratio.eps width=\textwidth + * + * @note This function returns the aspect ratio that the video @b should be, but + * sometimes the reported size from emotion_object_size_get() represents a + * different aspect ratio. You can safely resize the video to respect the aspect + * ratio returned by @b this function. + * + * @see emotion_object_size_get() + * + * @ingroup Emotion_Video + */ +EAPI double emotion_object_ratio_get (const Evas_Object *obj); + +/** + * @brief Retrieve the video size of the loaded file. + * + * @param obj The object from which we are retrieving the video size. + * @param iw A pointer to a variable where the width will be stored. + * @param ih A pointer to a variable where the height will be stored. + * + * This function returns the reported size of the loaded video file. If a file + * that doesn't contain a video channel is loaded, then this size can be + * ignored. + * + * The value reported by this function should be consistent with the aspect + * ratio returned by emotion_object_ratio_get(), but sometimes the information + * stored in the file is wrong. So use the ratio size reported by + * emotion_object_ratio_get(), since it is more likely going to be accurate. + * + * @note Use @c NULL for @p iw or @p ih if you don't need one of these values. + * + * @see emotion_object_ratio_get() + * + * @ingroup Emotion_Video + */ +EAPI void emotion_object_size_get (const Evas_Object *obj, int *iw, int *ih); + +/** + * @brief Sets whether to use of high-quality image scaling algorithm + * of the given video object. + * + * When enabled, a higher quality video scaling algorithm is used when + * scaling videos to sizes other than the source video. This gives + * better results but is more computationally expensive. + * + * @param obj The given video object. + * @param smooth Whether to use smooth scale or not. + * + * @see emotion_object_smooth_scale_get() + * + * @ingroup Emotion_Video + */ +EAPI void emotion_object_smooth_scale_set (Evas_Object *obj, Eina_Bool smooth); + +/** + * @brief Gets whether the high-quality image scaling algorithm + * of the given video object is used. + * + * @param obj The given video object. + * @return Whether the smooth scale is used or not. + * + * @see emotion_object_smooth_scale_set() + * + * @ingroup Emotion_Video + */ +EAPI Eina_Bool emotion_object_smooth_scale_get (const Evas_Object *obj); EAPI void emotion_object_event_simple_send (Evas_Object *obj, Emotion_Event ev); + +/** + * @brief Set the audio volume. + * + * @param obj The object where the volume is being set. + * @param vol The new volume parameter. Range is from 0.0 to 1.0. + * + * Sets the audio volume of the stream being played. This has nothing to do with + * the system volume. This volume will be multiplied by the system volume. e.g.: + * if the current volume level is 0.5, and the system volume is 50%, it will be + * 0.5 * 0.5 = 0.25. + * + * The default value depends on the module used. This value doesn't get changed + * when another file is loaded. + * + * @see emotion_object_audio_volume_get() + * + * @ingroup Emotion_Audio + */ EAPI void emotion_object_audio_volume_set (Evas_Object *obj, double vol); -EAPI double emotion_object_audio_volume_get (Evas_Object *obj); -EAPI void emotion_object_audio_mute_set (Evas_Object *obj, Evas_Bool mute); -EAPI Evas_Bool emotion_object_audio_mute_get (Evas_Object *obj); -EAPI int emotion_object_audio_channel_count (Evas_Object *obj); -EAPI const char *emotion_object_audio_channel_name_get(Evas_Object *obj, int channel); + +/** + * @brief Get the audio volume. + * + * @param obj The object from which we are retrieving the volume. + * @return The current audio volume level for this object. + * + * Get the current value for the audio volume level. Range is from 0.0 to 1.0. + * This volume is set with emotion_object_audio_volume_set(). + * + * @see emotion_object_audio_volume_set() + * + * @ingroup Emotion_Audio + */ +EAPI double emotion_object_audio_volume_get (const Evas_Object *obj); + +/** + * @brief Set the mute audio option for this object. + * + * @param obj The object which we are setting the mute audio option. + * @param mute Whether the audio should be muted (@c EINA_TRUE) or not (@c + * EINA_FALSE). + * + * This function sets the mute audio option for this emotion object. The current + * module used for this object can use this to avoid decoding the audio portion + * of the loaded media file. + * + * @see emotion_object_audio_mute_get() + * @see emotion_object_video_mute_set() + * + * @ingroup Emotion_Audio + */ +EAPI void emotion_object_audio_mute_set (Evas_Object *obj, Eina_Bool mute); + +/** + * @brief Get the mute audio option of this object. + * + * @param obj The object which we are retrieving the mute audio option from. + * @return Whether the audio is muted (@c EINA_TRUE) or not (@c EINA_FALSE). + * + * This function return the mute audio option from this emotion object. It can + * be set with emotion_object_audio_mute_set(). + * + * @see emotion_object_audio_mute_set() + * + * @ingroup Emotion_Audio + */ +EAPI Eina_Bool emotion_object_audio_mute_get (const Evas_Object *obj); +EAPI int emotion_object_audio_channel_count (const Evas_Object *obj); +EAPI const char *emotion_object_audio_channel_name_get(const Evas_Object *obj, int channel); EAPI void emotion_object_audio_channel_set (Evas_Object *obj, int channel); -EAPI int emotion_object_audio_channel_get (Evas_Object *obj); -EAPI void emotion_object_video_mute_set (Evas_Object *obj, Evas_Bool mute); -EAPI Evas_Bool emotion_object_video_mute_get (Evas_Object *obj); -EAPI int emotion_object_video_channel_count (Evas_Object *obj); -EAPI const char *emotion_object_video_channel_name_get(Evas_Object *obj, int channel); +EAPI int emotion_object_audio_channel_get (const Evas_Object *obj); + +/** + * @brief Set the mute video option for this object. + * + * @param obj The object which we are setting the mute video option. + * @param mute Whether the video should be muted (@c EINA_TRUE) or not (@c + * EINA_FALSE). + * + * This function sets the mute video option for this emotion object. The + * current module used for this object can use this information to avoid + * decoding the video portion of the loaded media file. + * + * @see emotion_object_video_mute_get() + * @see emotion_object_audio_mute_set() + * + * @ingroup Emotion_Video + */ +EAPI void emotion_object_video_mute_set (Evas_Object *obj, Eina_Bool mute); + +/** + * @brief Get the mute video option of this object. + * + * @param obj The object which we are retrieving the mute video option from. + * @return Whether the video is muted (@c EINA_TRUE) or not (@c EINA_FALSE). + * + * This function returns the mute video option from this emotion object. It can + * be set with emotion_object_video_mute_set(). + * + * @see emotion_object_video_mute_set() + * + * @ingroup Emotion_Video + */ +EAPI Eina_Bool emotion_object_video_mute_get (const Evas_Object *obj); + +/** + * @brief Get the number of available video channel + * + * @param obj The object which we are retrieving the channel count from + * @return the number of available channel. + * + * @see emotion_object_video_channel_name_get() + * + * @ingroup Emotion_Video + */ +EAPI int emotion_object_video_channel_count (const Evas_Object *obj); +EAPI const char *emotion_object_video_channel_name_get(const Evas_Object *obj, int channel); EAPI void emotion_object_video_channel_set (Evas_Object *obj, int channel); -EAPI int emotion_object_video_channel_get (Evas_Object *obj); -EAPI void emotion_object_spu_mute_set (Evas_Object *obj, Evas_Bool mute); -EAPI Evas_Bool emotion_object_spu_mute_get (Evas_Object *obj); -EAPI int emotion_object_spu_channel_count (Evas_Object *obj); -EAPI const char *emotion_object_spu_channel_name_get (Evas_Object *obj, int channel); +EAPI int emotion_object_video_channel_get (const Evas_Object *obj); +EAPI void emotion_object_spu_mute_set (Evas_Object *obj, Eina_Bool mute); +EAPI Eina_Bool emotion_object_spu_mute_get (const Evas_Object *obj); +EAPI int emotion_object_spu_channel_count (const Evas_Object *obj); +EAPI const char *emotion_object_spu_channel_name_get (const Evas_Object *obj, int channel); EAPI void emotion_object_spu_channel_set (Evas_Object *obj, int channel); -EAPI int emotion_object_spu_channel_get (Evas_Object *obj); -EAPI int emotion_object_chapter_count (Evas_Object *obj); +EAPI int emotion_object_spu_channel_get (const Evas_Object *obj); +EAPI int emotion_object_chapter_count (const Evas_Object *obj); EAPI void emotion_object_chapter_set (Evas_Object *obj, int chapter); -EAPI int emotion_object_chapter_get (Evas_Object *obj); -EAPI const char *emotion_object_chapter_name_get (Evas_Object *obj, int chapter); -EAPI void emotion_object_play_speed_set (Evas_Object *obj, double speed); -EAPI double emotion_object_play_speed_get (Evas_Object *obj); +EAPI int emotion_object_chapter_get (const Evas_Object *obj); +EAPI const char *emotion_object_chapter_name_get (const Evas_Object *obj, int chapter); EAPI void emotion_object_eject (Evas_Object *obj); -EAPI const char *emotion_object_title_get (Evas_Object *obj); -EAPI const char *emotion_object_progress_info_get (Evas_Object *obj); -EAPI double emotion_object_progress_status_get (Evas_Object *obj); -EAPI const char *emotion_object_ref_file_get (Evas_Object *obj); -EAPI int emotion_object_ref_num_get (Evas_Object *obj); -EAPI int emotion_object_spu_button_count_get (Evas_Object *obj); -EAPI int emotion_object_spu_button_get (Evas_Object *obj); -EAPI const char *emotion_object_meta_info_get (Evas_Object *obj, Emotion_Meta_Info meta); + +/** + * @brief Get the dvd title from this emotion object. + * + * @param obj The object which the title will be retrieved from. + * @return A string containing the title. + * + * This function is only useful when playing a DVD. + * + * @note Don't change or free the string returned by this function. + * + * @ingroup Emotion_Info + */ +EAPI const char *emotion_object_title_get (const Evas_Object *obj); +EAPI const char *emotion_object_ref_file_get (const Evas_Object *obj); +EAPI int emotion_object_ref_num_get (const Evas_Object *obj); +EAPI int emotion_object_spu_button_count_get (const Evas_Object *obj); +EAPI int emotion_object_spu_button_get (const Evas_Object *obj); + +/** + * @brief Retrieve meta information from this file being played. + * + * @param obj The object which the meta info will be extracted from. + * @param meta The type of meta information that will be extracted. + * + * This function retrieves information about the file loaded. It can retrieve + * the track title, artist name, album name, etc. See @ref Emotion_Meta_Info + * for all the possibilities. + * + * The meta info may be not available on all types of files. It will return @c + * NULL if the the file doesn't have meta info, or if this specific field is + * empty. + * + * @note Don't change or free the string returned by this function. + * + * @see Emotion_Meta_Info + * + * @ingroup Emotion_Info + */ +EAPI const char *emotion_object_meta_info_get (const Evas_Object *obj, Emotion_Meta_Info meta); + +/** + * @brief Set the visualization to be used with this object. + * + * @param obj The object where the visualization will be set on. + * @param visualization The type of visualization to be used. + * + * The @p visualization specified will be played instead of a video. This is + * commonly used to display a visualization for audio only files (musics). + * + * The available visualizations are @ref Emotion_Vis. + * + * @see Emotion_Vis + * @see emotion_object_vis_get() + * @see emotion_object_vis_supported() + * + * @ingroup Emotion_Visualization + */ +EAPI void emotion_object_vis_set (Evas_Object *obj, Emotion_Vis visualization); + +/** + * @brief Get the type of visualization in use by this emotion object. + * + * @param obj The emotion object which the visualization is being retrieved + * from. + * @return The type of visualization in use by this object. + * + * The type of visualization can be set by emotion_object_vis_set(). + * + * @see Emotion_Vis + * @see emotion_object_vis_set() + * @see emotion_object_vis_supported() + * + * @ingroup Emotion_Visualization + */ +EAPI Emotion_Vis emotion_object_vis_get (const Evas_Object *obj); + +/** + * @brief Query whether a type of visualization is supported by this object. + * + * @param obj The object which the query is being ran on. + * @param visualization The type of visualization that is being queried. + * @return EINA_TRUE if the visualization is supported, EINA_FALSE otherwise. + * + * This can be used to check if a visualization is supported. e.g.: one wants to + * display a list of available visualizations for a specific object. + * + * @see Emotion_Vis + * @see emotion_object_vis_set() + * @see emotion_object_vis_get() + * + * @ingroup Emotion_Visualization + */ +EAPI Eina_Bool emotion_object_vis_supported (const Evas_Object *obj, Emotion_Vis visualization); + +/** + * @brief Raise priority of an object so it will have a priviledged access to hardware ressource. + * + * @param obj The object which the query is being ran on. + * @param priority EINA_TRUE means give me a priority access to the hardware ressource. + * + * Hardware have a few dedicated hardware pipeline that process the video at no cost for the CPU. + * Especially on SoC, you mostly have one (on mobile phone SoC) or two (on Set Top Box SoC) when + * Picture in Picture is needed. And most application just have a few video stream that really + * deserve high frame rate, hiogh quality output. That's why this call is for. + * + * Please note that if Emotion can't acquire a priviledged hardware ressource, it will fallback + * to the no-priority path. This work on the first asking first get basis system. + * + * @see emotion_object_priority_get() + * + * @ingroup Emotion_Ressource + */ +EAPI void emotion_object_priority_set(Evas_Object *obj, Eina_Bool priority); + +/** + * @brief Get the actual priority of an object. + * + * @param obj The object which the query is being ran on. + * @return EINA_TRUE if the object has a priority access to the hardware. + * + * This actually return the priority status of an object. If it failed to have a priviledged + * access to the hardware, it will return EINA_FALSE. + * + * @see emotion_object_priority_get() + * + * @ingroup Emotion_Ressource + */ +EAPI Eina_Bool emotion_object_priority_get(const Evas_Object *obj); + +/** + * @brief Change the state of an object pipeline. + * + * @param obj The object which the query is being ran on. + * @param state The new state for the object. + * + * Changing the state of a pipeline should help preserve the battery of an embedded device. + * But it will only work sanely if the pipeline is not playing at the time you change its + * state. Depending on the engine all state may be not implemented. + * + * @see Emotion_Suspend + * @see emotion_object_suspend_get() + * + * @ingroup Emotion_Ressource + */ +EAPI void emotion_object_suspend_set(Evas_Object *obj, Emotion_Suspend state); + +/** + * @brief Get the current state of the pipeline + * + * @param obj The object which the query is being ran on. + * @return the current state of the pipeline. + * + * @see Emotion_Suspend + * @see emotion_object_suspend_set() + * + * @ingroup Emotion_Ressource + */ +EAPI Emotion_Suspend emotion_object_suspend_get(Evas_Object *obj); + +/** + * @brief Load the last known position if available + * + * @param obj The object which the query is being ran on. + * + * By using Xattr, Emotion is able, if the system permitt it, to store and retrieve + * the latest position. It should trigger some smart callback to let the application + * know when it succeed or fail. Every operation is fully asynchronous and not + * linked to the actual engine used to play the vide. + * + * @see emotion_object_last_position_save() + * + * @ingroup Emotion_Info + */ +EAPI void emotion_object_last_position_load(Evas_Object *obj); + +/** + * @brief Save the lastest position if possible + * + * @param obj The object which the query is being ran on. + * + * By using Xattr, Emotion is able, if the system permitt it, to store and retrieve + * the latest position. It should trigger some smart callback to let the application + * know when it succeed or fail. Every operation is fully asynchronous and not + * linked to the actual engine used to play the vide. + * + * @see emotion_object_last_position_load() + * + * @ingroup Emotion_Info + */ +EAPI void emotion_object_last_position_save(Evas_Object *obj); + +/** + * @brief Do we have a chance to play that file + * + * @param file A stringshared filename that we want to know if Emotion can play. + * + * This just actually look at the extention of the file, it doesn't check the mime-type + * nor if the file is actually sane. So this is just an hint for your application. + * + * @see emotion_object_extension_may_play_get() + */ +EAPI Eina_Bool emotion_object_extension_may_play_fast_get(const char *file); + +/** + * @brief Do we have a chance to play that file + * + * @param file A filename that we want to know if Emotion can play. + * + * This just actually look at the extention of the file, it doesn't check the mime-type + * nor if the file is actually sane. So this is just an hint for your application. + * + * @see emotion_object_extension_may_play_fast_get() + */ +EAPI Eina_Bool emotion_object_extension_may_play_get(const char *file); + +/** + * @brief Get the actual image object that contains the pixels of the video stream + * + * @param obj The object which the query is being ran on. + * + * This function is usefull when you want to get a direct access to the pixels. + * + * @see emotion_object_image_get() + */ +EAPI Evas_Object *emotion_object_image_get(const Evas_Object *obj); + +/** + * @defgroup Emotion_Webcam API available for accessing webcam + */ + +typedef struct _Emotion_Webcam Emotion_Webcam; /**< Webcam description */ + +EAPI extern int EMOTION_WEBCAM_UPDATE; /**< Ecore_Event triggered when a new webcam is plugged in */ + +/** + * @brief Get a list of active and available webcam + * + * @return the list of available webcam at the time of the call. + * + * It will return the current live list of webcam. It is updated before + * triggering EMOTION_WEBCAM_UPDATE and should never be modified. + * + * @ingroup Emotion_Webcam + */ +EAPI const Eina_List *emotion_webcams_get(void); + +/** + * @brief Get the human understandable name of a Webcam + * + * @param ew The webcam to get the name from. + * @return the actual human readable name. + * + * @ingroup Emotion_Webcam + */ +EAPI const char *emotion_webcam_name_get(const Emotion_Webcam *ew); + +/** + * @brief Get the uri of a Webcam that will be understood by emotion + * + * @param ew The webcam to get the uri from. + * @return the actual uri that emotion will later understood. + * + * @ingroup Emotion_Webcam + */ +EAPI const char *emotion_webcam_device_get(const Emotion_Webcam *ew); + +/** + * @} + */ #ifdef __cplusplus } #endif - + #endif diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 34a4a2e..a2d2198 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -7,15 +7,53 @@ AM_CPPFLAGS = \ -DPACKAGE_BIN_DIR=\"$(bindir)\" \ -DPACKAGE_LIB_DIR=\"$(libdir)\" \ -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ -@EVAS_CFLAGS@ \ -@ECORE_CFLAGS@ +@EMOTION_CPPFLAGS@ \ +@EMOTION_CFLAGS@ \ +@EIO_CFLAGS@ \ +@EFL_EMOTION_BUILD@ \ +@EEZE_CFLAGS@ + +if EMOTION_STATIC_BUILD_XINE +AM_CPPFLAGS += @XINE_CFLAGS@ +endif + +if EMOTION_STATIC_BUILD_GSTREAMER +AM_CPPFLAGS += @GSTREAMER_CFLAGS@ +endif lib_LTLIBRARIES = libemotion.la -include_HEADERS = Emotion.h -libemotion_la_SOURCES = \ -emotion_smart.c \ -emotion_private.h - -libemotion_la_LIBADD = @EVAS_LIBS@ @ECORE_LIBS@ -libemotion_la_DEPENDENCIES = $(top_builddir)/config.h -libemotion_la_LDFLAGS = -version-info @version_info@ +includes_HEADERS = Emotion.h +includesdir = $(includedir)/emotion-@VMAJ@ + +libemotion_la_SOURCES = emotion_smart.c emotion_main.c + +if EMOTION_STATIC_BUILD_XINE +libemotion_la_SOURCES += \ +$(top_srcdir)/src/modules/xine/emotion_xine.c \ +$(top_srcdir)/src/modules/xine/emotion_xine_vo_out.c +endif + +if EMOTION_STATIC_BUILD_GSTREAMER +libemotion_la_SOURCES += \ +$(top_srcdir)/src/modules/gstreamer/emotion_gstreamer.c \ +$(top_srcdir)/src/modules/gstreamer/emotion_sink.c +endif + +if EMOTION_STATIC_BUILD_GENERIC +libemotion_la_SOURCES += \ +$(top_srcdir)/src/modules/generic/emotion_generic.c +endif + +libemotion_la_LIBADD = @EMOTION_LIBS@ @EIO_LIBS@ @EEZE_LIBS@ + +if EMOTION_STATIC_BUILD_XINE +libemotion_la_LIBADD += @XINE_LIBS@ +endif + +if EMOTION_STATIC_BUILD_GSTREAMER +libemotion_la_LIBADD += @GSTREAMER_LIBS@ +endif + +libemotion_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ + +EXTRA_DIST = emotion_private.h diff --git a/src/lib/emotion_main.c b/src/lib/emotion_main.c new file mode 100644 index 0000000..52b1baa --- /dev/null +++ b/src/lib/emotion_main.c @@ -0,0 +1,484 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_ALLOCA_H +# include +#elif !defined alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# elif !defined HAVE_ALLOCA +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#include + +#ifdef EMOTION_HAVE_EEZE +# include +# include +# include +# include +# ifdef HAVE_V4L2 +# include +# endif + +# include +# include +#endif + +#include + +#include "Emotion.h" +#include "emotion_private.h" + +static Emotion_Version _version = { VMAJ, VMIN, VMIC, VREV }; +static int emotion_pending_objects = 0; +EAPI Emotion_Version *emotion_version = &_version; + +EAPI int EMOTION_WEBCAM_UPDATE = 0; + +struct ext_match_s +{ + unsigned int length; + const char *extension; +}; + +#define MATCHING(Ext) \ + { sizeof (Ext), Ext } + +static const struct ext_match_s matchs[] = +{ /* map extensions to know if it's a emotion playable content for good first-guess tries */ + MATCHING(".264"), + MATCHING(".3g2"), + MATCHING(".3gp"), + MATCHING(".3gp2"), + MATCHING(".3gpp"), + MATCHING(".3gpp2"), + MATCHING(".3p2"), + MATCHING(".asf"), + MATCHING(".avi"), + MATCHING(".bdm"), + MATCHING(".bdmv"), + MATCHING(".clpi"), + MATCHING(".clp"), + MATCHING(".fla"), + MATCHING(".flv"), + MATCHING(".m1v"), + MATCHING(".m2v"), + MATCHING(".m2t"), + MATCHING(".m4v"), + MATCHING(".mkv"), + MATCHING(".mov"), + MATCHING(".mp2"), + MATCHING(".mp2ts"), + MATCHING(".mp4"), + MATCHING(".mpe"), + MATCHING(".mpeg"), + MATCHING(".mpg"), + MATCHING(".mpl"), + MATCHING(".mpls"), + MATCHING(".mts"), + MATCHING(".mxf"), + MATCHING(".nut"), + MATCHING(".nuv"), + MATCHING(".ogg"), + MATCHING(".ogm"), + MATCHING(".ogv"), + MATCHING(".rm"), + MATCHING(".rmj"), + MATCHING(".rmm"), + MATCHING(".rms"), + MATCHING(".rmx"), + MATCHING(".rmvb"), + MATCHING(".swf"), + MATCHING(".ts"), + MATCHING(".weba"), + MATCHING(".webm"), + MATCHING(".wmv") +}; + +Eina_Bool +_emotion_object_extension_can_play_generic_get(const void *data __UNUSED__, const char *file) +{ + unsigned int length; + unsigned int i; + + length = eina_stringshare_strlen(file) + 1; + if (length < 5) return EINA_FALSE; + + for (i = 0; i < sizeof (matchs) / sizeof (struct ext_match_s); ++i) + { + if (matchs[i].length > length) continue; + + if (!strcasecmp(matchs[i].extension, + file + length - matchs[i].length)) + return EINA_TRUE; + } + + return EINA_FALSE; +} + +EAPI Eina_Bool +emotion_object_extension_may_play_fast_get(const char *file) +{ + if (!file) return EINA_FALSE; + return _emotion_object_extension_can_play_generic_get(NULL, file); +} + +EAPI Eina_Bool +emotion_object_extension_may_play_get(const char *file) +{ + const char *tmp; + Eina_Bool result; + + if (!file) return EINA_FALSE; + tmp = eina_stringshare_add(file); + result = emotion_object_extension_may_play_fast_get(tmp); + eina_stringshare_del(tmp); + + return result; +} + +typedef struct _Emotion_Webcams Emotion_Webcams; + +struct _Emotion_Webcams +{ + Eina_List *webcams; +}; + +struct _Emotion_Webcam +{ + EINA_REFCOUNT; + + const char *syspath; + const char *device; + const char *name; + + const char *custom; + + const char *filename; +}; + +static int _emotion_webcams_count = 0; +static Eet_Data_Descriptor *_webcam_edd; +static Eet_Data_Descriptor *_webcams_edd; + +static Emotion_Webcams *_emotion_webcams = NULL; +static Eet_File *_emotion_webcams_file = NULL; + +static Eet_Data_Descriptor * +_emotion_webcams_data(void) +{ + Eet_Data_Descriptor_Class eddc; + + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Emotion_Webcam); + _webcam_edd = eet_data_descriptor_file_new(&eddc); + EET_DATA_DESCRIPTOR_ADD_BASIC(_webcam_edd, Emotion_Webcam, "device", device, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(_webcam_edd, Emotion_Webcam, "name", name, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(_webcam_edd, Emotion_Webcam, "custom", custom, EET_T_STRING); + EET_DATA_DESCRIPTOR_ADD_BASIC(_webcam_edd, Emotion_Webcam, "filename", filename, EET_T_STRING); + + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Emotion_Webcams); + _webcams_edd = eet_data_descriptor_file_new(&eddc); + EET_DATA_DESCRIPTOR_ADD_LIST(_webcams_edd, Emotion_Webcams, "webcams", webcams, _webcam_edd); + + return _webcams_edd; +} + +#ifdef EMOTION_HAVE_EEZE +static Eeze_Udev_Watch *eeze_watcher = NULL; + +static void +emotion_webcam_destroy(Emotion_Webcam *ew) +{ + if (!ew->custom) + { + eina_stringshare_del(ew->syspath); + eina_stringshare_del(ew->device); + eina_stringshare_del(ew->name); + } + free(ew); +} + +static void +_emotion_check_device(Emotion_Webcam *ew) +{ +#ifdef HAVE_V4L2 + Emotion_Webcam *check; + Eina_List *l; + struct v4l2_capability caps; + int fd; +#endif + + if (!ew) return ; +#ifdef HAVE_V4L2 + if (!ew->device) goto on_error; + + fd = open(ew->filename, O_RDONLY); + if (fd < 0) goto on_error; + + if (ioctl(fd, VIDIOC_QUERYCAP, &caps) == -1) goto on_error; + + /* Likely not a webcam */ + if (!caps.capabilities & V4L2_CAP_VIDEO_CAPTURE) goto on_error; + if (caps.capabilities & V4L2_CAP_TUNER + || caps.capabilities & V4L2_CAP_RADIO + || caps.capabilities & V4L2_CAP_MODULATOR) + goto on_error; + + EINA_LIST_FOREACH(_emotion_webcams->webcams, l, check) + if (check->device == ew->device) + goto on_error; + + _emotion_webcams->webcams = eina_list_append(_emotion_webcams->webcams, ew); + + EINA_REFCOUNT_INIT(ew); + + return ; + + on_error: +#endif + fprintf(stderr, "'%s' is not a webcam ['%s']\n", ew->name, strerror(errno)); + eina_stringshare_del(ew->syspath); + eina_stringshare_del(ew->device); + eina_stringshare_del(ew->name); + free(ew); +} + +static Emotion_Webcam * +_emotion_webcam_new(const char *syspath) +{ + Emotion_Webcam *test; + const char *device; + char *local; + + test = malloc(sizeof (Emotion_Webcam)); + if (!test) return NULL; + + test->custom = NULL; + test->syspath = eina_stringshare_ref(syspath); + test->name = eeze_udev_syspath_get_sysattr(syspath, "name"); + + device = eeze_udev_syspath_get_property(syspath, "DEVNAME"); + local = alloca(eina_stringshare_strlen(device) + 8); + snprintf(local, eina_stringshare_strlen(device) + 8, "v4l2://%s", device); + test->device = eina_stringshare_add(local); + eina_stringshare_del(device); + test->filename = test->device + 7; + + return test; +} + +static void +_emotion_enumerate_all_webcams(void) +{ + Eina_List *devices; + const char *syspath; + + devices = eeze_udev_find_by_type(EEZE_UDEV_TYPE_V4L, NULL); + + EINA_LIST_FREE(devices, syspath) + { + Emotion_Webcam *test; + + test = _emotion_webcam_new(syspath); + if (test) _emotion_check_device(test); + + eina_stringshare_del(syspath); + } +} + +static void +_emotion_eeze_events(const char *syspath, + Eeze_Udev_Event ev, + void *data __UNUSED__, + Eeze_Udev_Watch *watcher __UNUSED__) +{ + if (ev == EEZE_UDEV_EVENT_REMOVE) + { + Emotion_Webcam *check; + Eina_List *l; + + EINA_LIST_FOREACH(_emotion_webcams->webcams, l, check) + if (check->syspath == syspath) + { + _emotion_webcams->webcams = eina_list_remove_list(_emotion_webcams->webcams, l); + EINA_REFCOUNT_UNREF(check) + emotion_webcam_destroy(check); + break ; + } + } + else if (ev == EEZE_UDEV_EVENT_ADD) + { + Emotion_Webcam *test; + + test = _emotion_webcam_new(syspath); + if (test) _emotion_check_device(test); + } + ecore_event_add(EMOTION_WEBCAM_UPDATE, NULL, NULL, NULL); +} + +#endif + +EAPI Eina_Bool +emotion_init(void) +{ + char buffer[4096]; + + if (_emotion_webcams_count++) return EINA_TRUE; + + ecore_init(); + + snprintf(buffer, 4096, "%s/emotion.cfg", PACKAGE_DATA_DIR); + _emotion_webcams_file = eet_open(buffer, EET_FILE_MODE_READ); + if (_emotion_webcams_file) + { + Eet_Data_Descriptor *edd; + + edd = _emotion_webcams_data(); + + _emotion_webcams = eet_data_read(_emotion_webcams_file, edd, "config"); + + eet_data_descriptor_free(_webcams_edd); _webcams_edd = NULL; + eet_data_descriptor_free(_webcam_edd); _webcam_edd = NULL; + } + + if (!_emotion_webcams) + { + _emotion_webcams = calloc(1, sizeof (Emotion_Webcams)); + if (!_emotion_webcams) return EINA_FALSE; + } + +#ifdef EMOTION_HAVE_EEZE + EMOTION_WEBCAM_UPDATE = ecore_event_type_new(); + + eeze_init(); + + _emotion_enumerate_all_webcams(); + + eeze_watcher = eeze_udev_watch_add(EEZE_UDEV_TYPE_V4L, + (EEZE_UDEV_EVENT_ADD | EEZE_UDEV_EVENT_REMOVE), + _emotion_eeze_events, NULL); +#endif + + return EINA_TRUE; +} + +EAPI Eina_Bool +emotion_shutdown(void) +{ + Emotion_Webcam *ew; + double start; + + if (_emotion_webcams_count <= 0) + { + EINA_LOG_ERR("Init count not greater than 0 in shutdown."); + return EINA_FALSE; + } + if (--_emotion_webcams_count) return EINA_TRUE; + + EINA_LIST_FREE(_emotion_webcams->webcams, ew) + { +#ifdef EMOTION_HAVE_EEZE + /* There is currently no way to refcount from the outside, this help, but could lead to some issue */ + EINA_REFCOUNT_UNREF(ew) + emotion_webcam_destroy(ew); +#endif + } + free(_emotion_webcams); + _emotion_webcams = NULL; + + if (_emotion_webcams_file) + { + /* As long as there is no one reference any pointer, you are safe */ + eet_close(_emotion_webcams_file); + _emotion_webcams_file = NULL; + } + +#ifdef EMOTION_HAVE_EEZE + eeze_udev_watch_del(eeze_watcher); + eeze_watcher = NULL; + + eeze_shutdown(); +#endif + + start = ecore_time_get(); + while (emotion_pending_objects && ecore_time_get() - start < 0.5) + ecore_main_loop_iterate(); + + if (emotion_pending_objects) + { + EINA_LOG_ERR("There is still %i Emotion pipeline running", emotion_pending_objects); + } + + ecore_shutdown(); + + return EINA_TRUE; +} + +EAPI const Eina_List * +emotion_webcams_get(void) +{ + return _emotion_webcams->webcams; +} + +EAPI const char * +emotion_webcam_name_get(const Emotion_Webcam *ew) +{ + if (!ew) return NULL; + + return ew->name; +} + +EAPI const char * +emotion_webcam_device_get(const Emotion_Webcam *ew) +{ + if (!ew) return NULL; + + return ew->device; +} + +EAPI const char * +emotion_webcam_custom_get(const char *device) +{ + const Emotion_Webcam *ew; + const Eina_List *l; + + if (_emotion_webcams) + { + EINA_LIST_FOREACH(_emotion_webcams->webcams, l, ew) + if (ew->device && strcmp(device, ew->device) == 0) + return ew->custom; + } + + return NULL; +} + +EAPI void +_emotion_pending_object_ref(void) +{ + emotion_pending_objects++; +} + +EAPI void +_emotion_pending_object_unref(void) +{ + emotion_pending_objects--; +} diff --git a/src/lib/emotion_private.h b/src/lib/emotion_private.h index 4d92561..cf24c75 100644 --- a/src/lib/emotion_private.h +++ b/src/lib/emotion_private.h @@ -1,18 +1,6 @@ #ifndef EMOTION_PRIVATE_H #define EMOTION_PRIVATE_H -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "config.h" - #define META_TRACK_TITLE 1 #define META_TRACK_ARTIST 2 #define META_TRACK_GENRE 3 @@ -23,9 +11,12 @@ #define META_TRACK_COUNT 8 typedef enum _Emotion_Format Emotion_Format; -typedef enum _Emotion_Vis Emotion_Vis; typedef struct _Emotion_Video_Module Emotion_Video_Module; typedef struct _Emotion_Module_Options Emotion_Module_Options; +typedef struct _Eina_Emotion_Plugins Eina_Emotion_Plugins; + +typedef Eina_Bool (*Emotion_Module_Open)(Evas_Object *, const Emotion_Video_Module **, void **, Emotion_Module_Options *); +typedef void (*Emotion_Module_Close)(Emotion_Video_Module *module, void *); enum _Emotion_Format { @@ -36,32 +27,17 @@ enum _Emotion_Format EMOTION_FORMAT_BGRA }; -enum _Emotion_Vis +struct _Emotion_Module_Options { - EMOTION_VIS_GOOM, - EMOTION_VIS_LIBVISUAL_BUMPSCOPE, - EMOTION_VIS_LIBVISUAL_CORONA, - EMOTION_VIS_LIBVISUAL_DANCING_PARTICLES, - EMOTION_VIS_LIBVISUAL_GDKPIXBUF, - EMOTION_VIS_LIBVISUAL_G_FORCE, - EMOTION_VIS_LIBVISUAL_GOOM, - EMOTION_VIS_LIBVISUAL_INFINITE, - EMOTION_VIS_LIBVISUAL_JAKDAW, - EMOTION_VIS_LIBVISUAL_JESS, - EMOTION_VIS_LIBVISUAL_LV_ANALYSER, - EMOTION_VIS_LIBVISUAL_LV_FLOWER, - EMOTION_VIS_LIBVISUAL_LV_GLTEST, - EMOTION_VIS_LIBVISUAL_LV_SCOPE, - EMOTION_VIS_LIBVISUAL_MADSPIN, - EMOTION_VIS_LIBVISUAL_NEBULUS, - EMOTION_VIS_LIBVISUAL_OINKSIE, - EMOTION_VIS_LIBVISUAL_PLASMA + const char *player; + Eina_Bool no_video : 1; + Eina_Bool no_audio : 1; }; -struct _Emotion_Module_Options +struct _Eina_Emotion_Plugins { - unsigned char no_video : 1; - unsigned char no_audio : 1; + Emotion_Module_Open open; + Emotion_Module_Close close; }; struct _Emotion_Video_Module @@ -74,13 +50,15 @@ struct _Emotion_Video_Module void (*stop) (void *ef); void (*size_get) (void *ef, int *w, int *h); void (*pos_set) (void *ef, double pos); - void (*vis_set) (void *ef, Emotion_Vis vis); double (*len_get) (void *ef); + double (*buffer_size_get) (void *ef); int (*fps_num_get) (void *ef); int (*fps_den_get) (void *ef); double (*fps_get) (void *ef); double (*pos_get) (void *ef); + void (*vis_set) (void *ef, Emotion_Vis vis); Emotion_Vis (*vis_get) (void *ef); + Eina_Bool (*vis_supported) (void *ef, Emotion_Vis vis); double (*ratio_get) (void *ef); int (*video_handled) (void *ef); int (*audio_handled) (void *ef); @@ -121,23 +99,37 @@ struct _Emotion_Video_Module double (*speed_get) (void *ef); int (*eject) (void *ef); const char * (*meta_get) (void *ef, int meta); + void (*priority_set) (void *ef, Eina_Bool priority); + Eina_Bool (*priority_get) (void *ef); - Ecore_Plugin *plugin; - Ecore_Path_Group *path_group; + Eina_Emotion_Plugins *plugin; }; -EAPI void *_emotion_video_get(Evas_Object *obj); +EAPI void *_emotion_video_get(const Evas_Object *obj); EAPI void _emotion_frame_new(Evas_Object *obj); EAPI void _emotion_video_pos_update(Evas_Object *obj, double pos, double len); EAPI void _emotion_frame_resize(Evas_Object *obj, int w, int h, double ratio); +EAPI void _emotion_frame_refill(Evas_Object *obj, double w, double h); EAPI void _emotion_decode_stop(Evas_Object *obj); +EAPI void _emotion_open_done(Evas_Object *obj); +EAPI void _emotion_playback_started(Evas_Object *obj); EAPI void _emotion_playback_finished(Evas_Object *obj); EAPI void _emotion_audio_level_change(Evas_Object *obj); EAPI void _emotion_channels_change(Evas_Object *obj); EAPI void _emotion_title_set(Evas_Object *obj, char *title); EAPI void _emotion_progress_set(Evas_Object *obj, char *info, double stat); -EAPI void _emotion_file_ref_set(Evas_Object *obj, char *file, int num); +EAPI void _emotion_file_ref_set(Evas_Object *obj, const char *file, int num); EAPI void _emotion_spu_button_num_set(Evas_Object *obj, int num); EAPI void _emotion_spu_button_set(Evas_Object *obj, int button); +EAPI void _emotion_seek_done(Evas_Object *obj); +EAPI void _emotion_image_reset(Evas_Object *obj); + +EAPI Eina_Bool _emotion_module_register(const char *name, Emotion_Module_Open open, Emotion_Module_Close close); +EAPI Eina_Bool _emotion_module_unregister(const char *name); + +EAPI const char *emotion_webcam_custom_get(const char *device); + +EAPI void _emotion_pending_object_ref(void); +EAPI void _emotion_pending_object_unref(void); #endif diff --git a/src/lib/emotion_smart.c b/src/lib/emotion_smart.c index 5943820..48eafda 100644 --- a/src/lib/emotion_smart.c +++ b/src/lib/emotion_smart.c @@ -1,6 +1,24 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#ifdef HAVE_EIO +# include +# include +#endif + #include "Emotion.h" #include "emotion_private.h" +#ifdef _WIN32 +# define FMT_UCHAR "%c" +#else +# define FMT_UCHAR "%hhu" +#endif + #define E_SMART_OBJ_GET(smart, o, type) \ { \ char *_e_smart_str; \ @@ -25,30 +43,37 @@ if (strcmp(_e_smart_str, type)) return ret; \ } +#define DBG(...) EINA_LOG_DOM_DBG(_log_domain, __VA_ARGS__) +#define INF(...) EINA_LOG_DOM_INFO(_log_domain, __VA_ARGS__) +#define WRN(...) EINA_LOG_DOM_WARN(_log_domain, __VA_ARGS__) +#define ERR(...) EINA_LOG_DOM_ERR(_log_domain, __VA_ARGS__) +#define CRITICAL(...) EINA_LOG_DOM_CRIT(_log_domain, __VA_ARGS__) + #define E_OBJ_NAME "emotion_object" typedef struct _Smart_Data Smart_Data; struct _Smart_Data { + EINA_REFCOUNT; Emotion_Video_Module *module; - void *video; + void *video_data; char *module_name; - char *file; + const char *file; Evas_Object *obj; - double ratio; - double pos; - double seek_pos; - double len; + Evas_Object *bg; Ecore_Job *job; - unsigned char play : 1; - unsigned char seek : 1; - char *title; + +#ifdef HAVE_EIO + Eio_File *load_xattr; + Eio_File *save_xattr; +#endif + struct { char *info; double stat; @@ -61,8 +86,39 @@ struct _Smart_Data int button_num; int button; } spu; + struct { + int l; /* left */ + int r; /* right */ + int t; /* top */ + int b; /* bottom */ + Evas_Object *clipper; + } crop; + + struct { + int w, h; + } video; + struct { + double w, h; + } fill; + + double ratio; + double pos; + double remember_jump; + double seek_pos; + double len; Emotion_Module_Options module_options; + + Emotion_Suspend state; + Emotion_Aspect aspect; + + Ecore_Animator *anim; + + Eina_Bool open : 1; + Eina_Bool play : 1; + Eina_Bool remember_play : 1; + Eina_Bool seek : 1; + Eina_Bool seeking : 1; }; static void _mouse_move(void *data, Evas *ev, Evas_Object *obj, void *event_info); @@ -85,75 +141,208 @@ static void _smart_clip_unset(Evas_Object * obj); /* Globals for the E Video Object */ /**********************************/ static Evas_Smart *smart = NULL; -static Ecore_Path_Group *path_group = NULL; +static Eina_Hash *_backends = NULL; +static Eina_Array *_modules = NULL; +static int _log_domain = -1; + +static const char *_backend_priority[] = { + "gstreamer", + "xine", + "generic" +}; + +static const char SIG_FRAME_DECODE[] = "frame_decode"; +static const char SIG_POSITION_UPDATE[] = "position_update"; +static const char SIG_LENGTH_CHANGE[] = "length_change"; +static const char SIG_FRAME_RESIZE[] = "frame_resize"; +static const char SIG_DECODE_STOP[] = "decode_stop"; +static const char SIG_PLAYBACK_STARTED[] = "playback_started"; +static const char SIG_PLAYBACK_FINISHED[] = "playback_finished"; +static const char SIG_AUDIO_LEVEL_CHANGE[] = "audio_level_change"; +static const char SIG_CHANNELS_CHANGE[] = "channels_change"; +static const char SIG_TITLE_CHANGE[] = "title_change"; +static const char SIG_PROGRESS_CHANGE[] = "progress_change"; +static const char SIG_REF_CHANGE[] = "ref_change"; +static const char SIG_BUTTON_NUM_CHANGE[] = "button_num_change"; +static const char SIG_BUTTON_CHANGE[] = "button_change"; +static const char SIG_OPEN_DONE[] = "open_done"; +static const char SIG_POSITION_SAVE_SUCCEED[] = "position_save,succeed"; +static const char SIG_POSITION_SAVE_FAILED[] = "position_save,failed"; +static const char SIG_POSITION_LOAD_SUCCEED[] = "position_load,succeed"; +static const char SIG_POSITION_LOAD_FAILED[] = "position_load,failed"; + +static const Evas_Smart_Cb_Description _smart_callbacks[] = { + {SIG_FRAME_DECODE, ""}, + {SIG_POSITION_UPDATE, ""}, + {SIG_LENGTH_CHANGE, ""}, + {SIG_FRAME_RESIZE, ""}, + {SIG_DECODE_STOP, ""}, + {SIG_PLAYBACK_STARTED, ""}, + {SIG_PLAYBACK_FINISHED, ""}, + {SIG_AUDIO_LEVEL_CHANGE, ""}, + {SIG_CHANNELS_CHANGE, ""}, + {SIG_TITLE_CHANGE, ""}, + {SIG_PROGRESS_CHANGE, ""}, + {SIG_REF_CHANGE, ""}, + {SIG_BUTTON_NUM_CHANGE, ""}, + {SIG_BUTTON_CHANGE, ""}, + {SIG_OPEN_DONE, ""}, + {NULL, NULL} +}; + +static void +_emotion_image_data_zero(Evas_Object *img) +{ + void *data; + + data = evas_object_image_data_get(img, 1); + if (data) + { + int w, h, sz = 0; + Evas_Colorspace cs; + + evas_object_image_size_get(img, &w, &h); + cs = evas_object_image_colorspace_get(img); + if (cs == EVAS_COLORSPACE_ARGB8888) + sz = w * h * 4; + if ((cs == EVAS_COLORSPACE_YCBCR422P601_PL) || + (cs == EVAS_COLORSPACE_YCBCR422P709_PL)) + sz = h * 2 * sizeof(unsigned char *); + if (sz != 0) memset(data, 0, sz); + } + evas_object_image_data_set(img, data); +} + +static void +_emotion_module_close(Emotion_Video_Module *mod, void *video) +{ + if (!mod) return; + if (mod->plugin->close && video) + mod->plugin->close(mod, video); + /* FIXME: we can't go dlclosing here as a thread still may be running from + * the module - this in theory will leak- but it shouldn't be too bad and + * mean that once a module is dlopened() it can't be closed - its refcount + * will just keep going up + */ +} + +static void +_smart_data_free(Smart_Data *sd) +{ + if (sd->video_data) sd->module->file_close(sd->video_data); + _emotion_module_close(sd->module, sd->video_data); + evas_object_del(sd->obj); + evas_object_del(sd->crop.clipper); + evas_object_del(sd->bg); + eina_stringshare_del(sd->file); + free(sd->module_name); + if (sd->job) ecore_job_del(sd->job); + if (sd->anim) ecore_animator_del(sd->anim); + free(sd->progress.info); + free(sd->ref.file); + free(sd); + + ecore_shutdown(); +} + +EAPI Eina_Bool +_emotion_module_register(const char *name, Emotion_Module_Open mod_open, Emotion_Module_Close mod_close) +{ + Eina_Emotion_Plugins *plugin; + + plugin = malloc(sizeof (Eina_Emotion_Plugins)); + if (!plugin) return EINA_FALSE; + + plugin->open = mod_open; + plugin->close = mod_close; -static unsigned char + return eina_hash_add(_backends, name, plugin); +} + +EAPI Eina_Bool +_emotion_module_unregister(const char *name) +{ + return eina_hash_del(_backends, name, NULL); +} + +static const char * _emotion_module_open(const char *name, Evas_Object *obj, Emotion_Video_Module **mod, void **video) { - Ecore_Plugin *plugin; - char *tmp = NULL; + Eina_Emotion_Plugins *plugin; Smart_Data *sd; + unsigned int i = 0; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); - if (!path_group) - path_group = ecore_path_group_new(); - tmp = getenv("EMOTION_MODULES_DIR"); - if (tmp) - ecore_path_group_add(path_group, tmp); - ecore_path_group_add(path_group, PACKAGE_LIB_DIR"/emotion/"); - plugin = ecore_plugin_load(path_group, name, NULL); - if (plugin) + if (!_backends) { - unsigned char (*func_module_open)(Evas_Object *, Emotion_Video_Module **, void **, Emotion_Module_Options *); + ERR("No backend loaded"); + return NULL; + } - func_module_open = ecore_plugin_symbol_get(plugin, "module_open"); - if (func_module_open) - { - if (func_module_open(obj, mod, video, &(sd->module_options))) - { - if (*mod) - { - (*mod)->plugin = plugin; - (*mod)->path_group = path_group; - return 1; - } - } - } - ecore_plugin_unload(plugin); + if (!name && getenv("EMOTION_ENGINE")) + name = getenv("EMOTION_ENGINE"); + + /* FIXME: Always look for a working backend. */ + retry: + if (!name || i > 0) + name = _backend_priority[i++]; + + plugin = eina_hash_find(_backends, name); + if (!plugin) + { + if (i != 0 && i < (sizeof (_backend_priority) / sizeof (char*))) + goto retry; + + ERR("No backend loaded"); + return EINA_FALSE; } - else - printf ("Unable to load module %s\n", name); - if (path_group) + if (plugin->open(obj, (const Emotion_Video_Module **) mod, video, &(sd->module_options))) { - ecore_path_group_del(path_group); - path_group = NULL; + if (*mod) + { + (*mod)->plugin = plugin; + return name; + } } - return 0; + if (i != 0 && i < (sizeof (_backend_priority) / sizeof (char*))) + goto retry; + + ERR("Unable to load module: %s", name); + + return NULL; } static void -_emotion_module_close(Emotion_Video_Module *mod, void *video) +_clipper_position_size_update(Evas_Object *obj, int x, int y, int w, int h, int vid_w, int vid_h) { - Ecore_Plugin *plugin; - void (*module_close) (Emotion_Video_Module *module, void *); + Smart_Data *sd; + double scale_w, scale_h; - plugin = mod->plugin; - module_close = ecore_plugin_symbol_get(mod->plugin, "module_close"); - if ((module_close) && (video)) module_close(mod, video); - /* FIXME: we can't go dlclosing here as a thread still may be running from - * the module - this in theory will leak- but it shouldnt be too bad and - * mean that once a module is dlopened() it cant be closed - its refcount - * will just keep going up - */ - /* - ecore_plugin_unload(plugin); - */ - if (path_group) + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + + if (vid_w == 0 || vid_h == 0) { - ecore_path_group_del(path_group); - path_group = NULL; + evas_object_image_fill_set(sd->obj, 0, 0, 0, 0); + evas_object_move(sd->obj, x, y); + evas_object_resize(sd->obj, 0, 0); + evas_object_move(sd->crop.clipper, x, y); + evas_object_resize(sd->crop.clipper, 0, 0); + } + else + { + evas_object_move(sd->crop.clipper, x, y); + scale_w = (double)w / (double)(vid_w - sd->crop.l - sd->crop.r); + scale_h = (double)h / (double)(vid_h - sd->crop.t - sd->crop.b); + + if (sd->fill.w < 0 && sd->fill.h < 0) + evas_object_image_fill_set(sd->obj, 0, 0, vid_w * scale_w, vid_h * scale_h); + else + evas_object_image_fill_set(sd->obj, 0, 0, sd->fill.w * w, sd->fill.h * h); + evas_object_resize(sd->obj, vid_w * scale_w, vid_h * scale_h); + evas_object_move(sd->obj, x - sd->crop.l * scale_w, y - sd->crop.t * scale_h); + evas_object_resize(sd->crop.clipper, w, h); } } @@ -170,6 +359,16 @@ emotion_object_add(Evas *evas) return evas_object_smart_add(evas, smart); } +EAPI Evas_Object * +emotion_object_image_get(const Evas_Object *obj) +{ + Smart_Data *sd; + + sd = evas_object_smart_data_get(obj); + if (!sd) return NULL; + return sd->obj; +} + EAPI void emotion_object_module_option_set(Evas_Object *obj, const char *opt, const char *val) { @@ -177,93 +376,121 @@ emotion_object_module_option_set(Evas_Object *obj, const char *opt, const char * E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); if ((!opt) || (!val)) return; - if (!strcmp(opt, "video")) - { - if (!strcmp(val, "off")) sd->module_options.no_video = 1; - } - else if (!strcmp(opt, "audio")) - { - if (!strcmp(val, "off")) sd->module_options.no_audio = 1; - } + + if (!strcmp(opt, "player")) + eina_stringshare_replace(&sd->module_options.player, val); } -EAPI Evas_Bool +EAPI Eina_Bool emotion_object_init(Evas_Object *obj, const char *module_filename) { Smart_Data *sd; + const char *file; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); - if (sd->file) free(sd->file); + if ((sd->module_name) && module_filename && (!strcmp(sd->module_name, module_filename))) + return EINA_TRUE; + free(sd->module_name); + sd->module_name = NULL; + + file = sd->file; sd->file = NULL; - if (sd->title) free(sd->title); + + free(sd->title); sd->title = NULL; - if (sd->progress.info) free(sd->progress.info); + free(sd->progress.info); sd->progress.info = NULL; sd->progress.stat = 0.0; - if (sd->ref.file) free(sd->ref.file); + free(sd->ref.file); sd->ref.file = NULL; sd->ref.num = 0; sd->spu.button_num = 0; sd->spu.button = -1; sd->ratio = 1.0; sd->pos = 0; + sd->remember_jump = 0; sd->seek_pos = 0; sd->len = 0; + sd->remember_play = 0; + + if (sd->anim) ecore_animator_del(sd->anim); + sd->anim = NULL; - ecore_job_init(); + _emotion_module_close(sd->module, sd->video_data); + sd->module = NULL; + sd->video_data = NULL; - if ((!sd->module) || (!sd->video)) + module_filename = _emotion_module_open(module_filename, obj, &sd->module, &sd->video_data); + if (!module_filename) + return EINA_FALSE; + + sd->module_name = strdup(module_filename); + + if (file) { - if (!_emotion_module_open(module_filename, obj, - &sd->module, &sd->video)) - return 0; + emotion_object_file_set(obj, file); + eina_stringshare_del(file); } - return 1; + return EINA_TRUE; } -EAPI void +EAPI Eina_Bool emotion_object_file_set(Evas_Object *obj, const char *file) { Smart_Data *sd; - E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EINA_FALSE); + + DBG("file=%s", file); + if (!sd->module) return EINA_FALSE; - if ((file) && (sd->file) && (!strcmp(file, sd->file))) return; + sd->video.w = 0; + sd->video.h = 0; + if ((file) && (sd->file) && + ((file == sd->file) || (!strcmp(file, sd->file)))) return EINA_FALSE; if ((file) && (file[0] != 0)) { - int w, h; - - if (sd->file) free(sd->file); - sd->file = strdup(file); - if (sd->module) - { - sd->module->file_close(sd->video); - evas_object_image_size_set(sd->obj, 0, 0); - } - if (!sd->module->file_open(sd->file, obj, sd->video)) - return; - sd->module->size_get(sd->video, &w, &h); - evas_object_image_size_set(sd->obj, w, h); - sd->ratio = sd->module->ratio_get(sd->video); + eina_stringshare_replace(&sd->file, file); + sd->module->file_close(sd->video_data); + evas_object_image_data_set(sd->obj, NULL); + evas_object_image_size_set(sd->obj, 1, 1); + _emotion_image_data_zero(sd->obj); + sd->open = 0; + if (!sd->module->file_open(sd->file, obj, sd->video_data)) + return EINA_FALSE; sd->pos = 0.0; - if (sd->play) sd->module->play(sd->video, 0.0); + if (sd->play) sd->module->play(sd->video_data, 0.0); } else { - if (sd->video && sd->module) + if (sd->video_data && sd->module) { - sd->module->file_close(sd->video); - evas_object_image_size_set(sd->obj, 0, 0); + sd->module->file_close(sd->video_data); + evas_object_image_data_set(sd->obj, NULL); + evas_object_image_size_set(sd->obj, 1, 1); + _emotion_image_data_zero(sd->obj); } - if (sd->file) free(sd->file); - sd->file = NULL; + eina_stringshare_replace(&sd->file, NULL); } + + if (sd->anim) ecore_animator_del(sd->anim); + sd->anim = NULL; + +#ifdef HAVE_EIO + /* Only cancel the load_xattr or we will loose ref to time_seek stringshare */ + if (sd->load_xattr) eio_file_cancel(sd->load_xattr); + sd->load_xattr = NULL; + if (sd->save_xattr) eio_file_cancel(sd->save_xattr); + sd->save_xattr = NULL; +#endif + + return EINA_TRUE; } EAPI const char * -emotion_object_file_get(Evas_Object *obj) +emotion_object_file_get(const Evas_Object *obj) { Smart_Data *sd; @@ -271,27 +498,242 @@ emotion_object_file_get(Evas_Object *obj) return sd->file; } +static void +_emotion_aspect_borders_apply(Evas_Object *obj, Smart_Data *sd, int w, int h, int iw, int ih) +{ + int x, y; + + evas_object_geometry_get(obj, &x, &y, NULL, NULL); + + /* applying calculated borders */ + if (sd->crop.l == 0 && sd->crop.r == 0 && + sd->crop.t == 0 && sd->crop.b == 0) + { + Evas_Object *old_clipper; + if (sd->crop.clipper) + { + old_clipper = evas_object_clip_get(sd->crop.clipper); + evas_object_clip_unset(sd->obj); + evas_object_clip_set(sd->obj, old_clipper); + evas_object_del(sd->crop.clipper); + sd->crop.clipper = NULL; + } + } + else + { + if (!sd->crop.clipper) + { + Evas_Object *old_clipper; + sd->crop.clipper = evas_object_rectangle_add( + evas_object_evas_get(obj)); + evas_object_color_set(sd->crop.clipper, 255, 255, 255, 255); + evas_object_smart_member_add(sd->crop.clipper, obj); + old_clipper = evas_object_clip_get(sd->obj); + evas_object_clip_set(sd->obj, sd->crop.clipper); + evas_object_clip_set(sd->crop.clipper, old_clipper); + if (evas_object_visible_get(sd->obj)) + evas_object_show(sd->crop.clipper); + } + } + _clipper_position_size_update(obj, x, y, w, h, iw, ih); +} + +static void +_emotion_object_aspect_border_apply(Evas_Object *obj, Smart_Data *sd, int w, int h) +{ + int iw, ih; + double ir; + double r; + + int aspect_opt = 0; + + iw = sd->video.w; + ih = sd->video.h; + + ir = (double)iw / ih; + r = (double)w / h; + + /* First check if we should fit the width or height of the video inside the + * width/height of the object. This check takes into account the original + * aspect ratio and the object aspect ratio, if we are keeping both sizes or + * cropping the exceding area. + */ + if (sd->aspect == EMOTION_ASPECT_KEEP_NONE) + { + sd->crop.l = 0; + sd->crop.r = 0; + sd->crop.t = 0; + sd->crop.b = 0; + aspect_opt = 0; // just ignore keep_aspect + } + else if (sd->aspect == EMOTION_ASPECT_KEEP_WIDTH) + { + aspect_opt = 1; + } + else if (sd->aspect == EMOTION_ASPECT_KEEP_HEIGHT) + { + aspect_opt = 2; + } + else if (sd->aspect == EMOTION_ASPECT_KEEP_BOTH) + { + if (ir > r) + aspect_opt = 1; + else + aspect_opt = 2; + } + else if (sd->aspect == EMOTION_ASPECT_CROP) + { + if (ir > r) + aspect_opt = 2; + else + aspect_opt = 1; + } + else if (sd->aspect == EMOTION_ASPECT_CUSTOM) + { + // nothing to do, just respect the border settings + aspect_opt = 0; + } + + /* updating borders based on keep_aspect settings */ + if (aspect_opt == 1) // keep width + { + int th, dh; + double scale; + + sd->crop.l = 0; + sd->crop.r = 0; + scale = (double)iw / w; + th = h * scale; + dh = ih - th; + sd->crop.t = sd->crop.b = dh / 2; + } + else if (aspect_opt == 2) // keep height + { + int tw, dw; + double scale; + + sd->crop.t = 0; + sd->crop.b = 0; + scale = (double)ih / h; + tw = w * scale; + dw = iw - tw; + sd->crop.l = sd->crop.r = dw / 2; + } + + _emotion_aspect_borders_apply(obj, sd, w, h, iw, ih); +} + +EAPI void +emotion_object_border_set(Evas_Object *obj, int l, int r, int t, int b) +{ + Smart_Data *sd; + int w, h; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + + sd->aspect = EMOTION_ASPECT_CUSTOM; + sd->crop.l = -l; + sd->crop.r = -r; + sd->crop.t = -t; + sd->crop.b = -b; + evas_object_geometry_get(obj, NULL, NULL, &w, &h); + _emotion_object_aspect_border_apply(obj, sd, w, h); +} + +EAPI void +emotion_object_border_get(const Evas_Object *obj, int *l, int *r, int *t, int *b) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + *l = -sd->crop.l; + *r = -sd->crop.r; + *t = -sd->crop.t; + *b = -sd->crop.b; +} + +EAPI void +emotion_object_bg_color_set(Evas_Object *obj, int r, int g, int b, int a) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + + evas_object_color_set(sd->bg, r, g, b, a); + + if (!evas_object_visible_get(obj)) + return; + + if (a > 0) + evas_object_show(sd->bg); + else + evas_object_hide(sd->bg); +} + +EAPI void +emotion_object_bg_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + evas_object_color_get(sd->bg, r, g, b, a); +} + +EAPI void +emotion_object_keep_aspect_set(Evas_Object *obj, Emotion_Aspect a) +{ + Smart_Data *sd; + int w, h; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + + if (a == sd->aspect) + return; + + sd->aspect = a; + evas_object_geometry_get(obj, NULL, NULL, &w, &h); + _emotion_object_aspect_border_apply(obj, sd, w, h); +} + +EAPI Emotion_Aspect +emotion_object_keep_aspect_get(const Evas_Object *obj) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EMOTION_ASPECT_KEEP_NONE); + + return sd->aspect; +} + EAPI void -emotion_object_play_set(Evas_Object *obj, Evas_Bool play) +emotion_object_play_set(Evas_Object *obj, Eina_Bool play) { Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); - if (((play) && (sd->play)) || ((!play) && (!sd->play))) return; + DBG("play=" FMT_UCHAR ", was=" FMT_UCHAR, play, sd->play); + if (play == sd->play) return; if (!sd->module) return; - if (!sd->video) return; + if (!sd->video_data) return; + if (!sd->open) + { + sd->remember_play = play; + return; + } sd->play = play; - if (sd->play) sd->module->play(sd->video, sd->pos); - else sd->module->stop(sd->video); + sd->remember_play = play; + if (sd->state != EMOTION_WAKEUP) emotion_object_suspend_set(obj, EMOTION_WAKEUP); + if (sd->play) sd->module->play(sd->video_data, sd->pos); + else sd->module->stop(sd->video_data); } -EAPI Evas_Bool -emotion_object_play_get(Evas_Object *obj) +EAPI Eina_Bool +emotion_object_play_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); - if (!sd->video) return 0; + if (!sd->video_data) return EINA_FALSE; return sd->play; } @@ -302,8 +744,15 @@ emotion_object_position_set(Evas_Object *obj, double sec) Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + DBG("sec=%f", sec); if (!sd->module) return; - if (!sd->video) return; + if (!sd->video_data) return; + if (!sd->open) + { + sd->remember_jump = sec; + return ; + } + sd->remember_jump = 0; sd->seek_pos = sec; sd->seek = 1; sd->pos = sd->seek_pos; @@ -312,74 +761,89 @@ emotion_object_position_set(Evas_Object *obj, double sec) } EAPI double -emotion_object_position_get(Evas_Object *obj) +emotion_object_position_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0); if (!sd->module) return 0.0; - if (!sd->video) return 0.0; + if (!sd->video_data) return 0.0; + if (!sd->module->pos_get) return 0.0; + sd->pos = sd->module->pos_get(sd->video_data); return sd->pos; } -EAPI Evas_Bool -emotion_object_seekable_get(Evas_Object *obj) +EAPI double +emotion_object_buffer_size_get(const Evas_Object *obj) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 1.0); + if (!sd->module) return 1.0; + if (!sd->video_data) return 1.0; + if (!sd->module->buffer_size_get) return 1.0; + return sd->module->buffer_size_get(sd->video_data); +} + +EAPI Eina_Bool +emotion_object_seekable_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); - if (!sd->module) return 0; - if (!sd->video) return 0; - return sd->module->seekable(sd->video); + if (!sd->module) return EINA_FALSE; + if (!sd->video_data) return EINA_FALSE; + return sd->module->seekable(sd->video_data); } -EAPI Evas_Bool -emotion_object_video_handled_get(Evas_Object *obj) +EAPI Eina_Bool +emotion_object_video_handled_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); - if (!sd->module) return 0; - if (!sd->video) return 0; - return sd->module->video_handled(sd->video); + if (!sd->module) return EINA_FALSE; + if (!sd->video_data) return EINA_FALSE; + return sd->module->video_handled(sd->video_data); } -EAPI Evas_Bool -emotion_object_audio_handled_get(Evas_Object *obj) +EAPI Eina_Bool +emotion_object_audio_handled_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); - if (!sd->module) return 0; - if (!sd->video) return 0; - return sd->module->audio_handled(sd->video); + if (!sd->module) return EINA_FALSE; + if (!sd->video_data) return EINA_FALSE; + return sd->module->audio_handled(sd->video_data); } EAPI double -emotion_object_play_length_get(Evas_Object *obj) +emotion_object_play_length_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0); if (!sd->module) return 0.0; - if (!sd->video) return 0.0; - sd->len = sd->module->len_get(sd->video); + if (!sd->video_data) return 0.0; + sd->len = sd->module->len_get(sd->video_data); return sd->len; } EAPI void -emotion_object_size_get(Evas_Object *obj, int *iw, int *ih) +emotion_object_size_get(const Evas_Object *obj, int *iw, int *ih) { Smart_Data *sd; if (iw) *iw = 0; if (ih) *ih = 0; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); - evas_object_image_size_get(sd->obj, iw, ih); + if (iw) *iw = sd->video.w; + if (ih) *ih = sd->video.h; } EAPI void -emotion_object_smooth_scale_set(Evas_Object *obj, Evas_Bool smooth) +emotion_object_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth) { Smart_Data *sd; @@ -387,8 +851,8 @@ emotion_object_smooth_scale_set(Evas_Object *obj, Evas_Bool smooth) evas_object_image_smooth_scale_set(sd->obj, smooth); } -EAPI Evas_Bool -emotion_object_smooth_scale_get(Evas_Object *obj) +EAPI Eina_Bool +emotion_object_smooth_scale_get(const Evas_Object *obj) { Smart_Data *sd; @@ -397,16 +861,19 @@ emotion_object_smooth_scale_get(Evas_Object *obj) } EAPI double -emotion_object_ratio_get(Evas_Object *obj) +emotion_object_ratio_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 1.0); if (!sd->module) return 0.0; - if (!sd->video) return 0.0; + if (!sd->video_data) return 0.0; return sd->ratio; } +/* + * Send a control event to the DVD. + */ EAPI void emotion_object_event_simple_send(Evas_Object *obj, Emotion_Event ev) { @@ -414,8 +881,8 @@ emotion_object_event_simple_send(Evas_Object *obj, Emotion_Event ev) E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); if (!sd->module) return; - if (!sd->video) return; - sd->module->event_feed(sd->video, ev); + if (!sd->video_data) return; + sd->module->event_feed(sd->video_data, ev); } EAPI void @@ -424,64 +891,66 @@ emotion_object_audio_volume_set(Evas_Object *obj, double vol) Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + DBG("vol=%f", vol); if (!sd->module) return; - if (!sd->video) return; - sd->module->audio_channel_volume_set(sd->video, vol); + if (!sd->video_data) return; + sd->module->audio_channel_volume_set(sd->video_data, vol); } EAPI double -emotion_object_audio_volume_get(Evas_Object *obj) +emotion_object_audio_volume_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 1.0); if (!sd->module) return 0.0; - if (!sd->video) return 0.0; - return sd->module->audio_channel_volume_get(sd->video); + if (!sd->video_data) return 0.0; + return sd->module->audio_channel_volume_get(sd->video_data); } EAPI void -emotion_object_audio_mute_set(Evas_Object *obj, Evas_Bool mute) +emotion_object_audio_mute_set(Evas_Object *obj, Eina_Bool mute) { Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + DBG("mute=" FMT_UCHAR, mute); if (!sd->module) return; - if (!sd->video) return; - sd->module->audio_channel_mute_set(sd->video, mute); + if (!sd->video_data) return; + sd->module->audio_channel_mute_set(sd->video_data, mute); } -EAPI Evas_Bool -emotion_object_audio_mute_get(Evas_Object *obj) +EAPI Eina_Bool +emotion_object_audio_mute_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); - if (!sd->module) return 0; - if (!sd->video) return 0; - return sd->module->audio_channel_mute_get(sd->video); + if (!sd->module) return EINA_FALSE; + if (!sd->video_data) return EINA_FALSE; + return sd->module->audio_channel_mute_get(sd->video_data); } EAPI int -emotion_object_audio_channel_count(Evas_Object *obj) +emotion_object_audio_channel_count(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); if (!sd->module) return 0; - if (!sd->video) return 0; - return sd->module->audio_channel_count(sd->video); + if (!sd->video_data) return 0; + return sd->module->audio_channel_count(sd->video_data); } EAPI const char * -emotion_object_audio_channel_name_get(Evas_Object *obj, int channel) +emotion_object_audio_channel_name_get(const Evas_Object *obj, int channel) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL); if (!sd->module) return NULL; - if (!sd->video) return NULL; - return sd->module->audio_channel_name_get(sd->video, channel); + if (!sd->video_data) return NULL; + return sd->module->audio_channel_name_get(sd->video_data, channel); } EAPI void @@ -490,64 +959,66 @@ emotion_object_audio_channel_set(Evas_Object *obj, int channel) Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + DBG("channel=%d", channel); if (!sd->module) return; - if (!sd->video) return; - sd->module->audio_channel_set(sd->video, channel); + if (!sd->video_data) return; + sd->module->audio_channel_set(sd->video_data, channel); } EAPI int -emotion_object_audio_channel_get(Evas_Object *obj) +emotion_object_audio_channel_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); if (!sd->module) return 0; - if (!sd->video) return 0; - return sd->module->audio_channel_get(sd->video); + if (!sd->video_data) return 0; + return sd->module->audio_channel_get(sd->video_data); } EAPI void -emotion_object_video_mute_set(Evas_Object *obj, Evas_Bool mute) +emotion_object_video_mute_set(Evas_Object *obj, Eina_Bool mute) { Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + DBG("mute=" FMT_UCHAR, mute); if (!sd->module) return; - if (!sd->video) return; - sd->module->video_channel_mute_set(sd->video, mute); + if (!sd->video_data) return; + sd->module->video_channel_mute_set(sd->video_data, mute); } -EAPI Evas_Bool -emotion_object_video_mute_get(Evas_Object *obj) +EAPI Eina_Bool +emotion_object_video_mute_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); - if (!sd->module) return 0; - if (!sd->video) return 0; - return sd->module->video_channel_mute_get(sd->video); + if (!sd->module) return EINA_FALSE; + if (!sd->video_data) return EINA_FALSE; + return sd->module->video_channel_mute_get(sd->video_data); } EAPI int -emotion_object_video_channel_count(Evas_Object *obj) +emotion_object_video_channel_count(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); - if (!sd->module) return 0; - if (!sd->video) return 0; - return sd->module->video_channel_count(sd->video); + if (!sd->module) return EINA_FALSE; + if (!sd->video_data) return EINA_FALSE; + return sd->module->video_channel_count(sd->video_data); } EAPI const char * -emotion_object_video_channel_name_get(Evas_Object *obj, int channel) +emotion_object_video_channel_name_get(const Evas_Object *obj, int channel) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL); if (!sd->module) return NULL; - if (!sd->video) return NULL; - return sd->module->video_channel_name_get(sd->video, channel); + if (!sd->video_data) return NULL; + return sd->module->video_channel_name_get(sd->video_data, channel); } EAPI void @@ -556,64 +1027,66 @@ emotion_object_video_channel_set(Evas_Object *obj, int channel) Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + DBG("channel=%d", channel); if (!sd->module) return; - if (!sd->video) return; - sd->module->video_channel_set(sd->video, channel); + if (!sd->video_data) return; + sd->module->video_channel_set(sd->video_data, channel); } EAPI int -emotion_object_video_channel_get(Evas_Object *obj) +emotion_object_video_channel_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); if (!sd->module) return 0; - if (!sd->video) return 0; - return sd->module->video_channel_get(sd->video); + if (!sd->video_data) return 0; + return sd->module->video_channel_get(sd->video_data); } EAPI void -emotion_object_spu_mute_set(Evas_Object *obj, Evas_Bool mute) +emotion_object_spu_mute_set(Evas_Object *obj, Eina_Bool mute) { Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + DBG("mute=" FMT_UCHAR, mute); if (!sd->module) return; - if (!sd->video) return; - sd->module->spu_channel_mute_set(sd->video, mute); + if (!sd->video_data) return; + sd->module->spu_channel_mute_set(sd->video_data, mute); } -EAPI Evas_Bool -emotion_object_spu_mute_get(Evas_Object *obj) +EAPI Eina_Bool +emotion_object_spu_mute_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); - if (!sd->module) return 0; - if (!sd->video) return 0; - return sd->module->spu_channel_mute_get(sd->video); + if (!sd->module) return EINA_FALSE; + if (!sd->video_data) return EINA_FALSE; + return sd->module->spu_channel_mute_get(sd->video_data); } EAPI int -emotion_object_spu_channel_count(Evas_Object *obj) +emotion_object_spu_channel_count(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); if (!sd->module) return 0; - if (!sd->video) return 0; - return sd->module->spu_channel_count(sd->video); + if (!sd->video_data) return 0; + return sd->module->spu_channel_count(sd->video_data); } EAPI const char * -emotion_object_spu_channel_name_get(Evas_Object *obj, int channel) +emotion_object_spu_channel_name_get(const Evas_Object *obj, int channel) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL); if (!sd->module) return NULL; - if (!sd->video) return NULL; - return sd->module->spu_channel_name_get(sd->video, channel); + if (!sd->video_data) return NULL; + return sd->module->spu_channel_name_get(sd->video_data, channel); } EAPI void @@ -622,31 +1095,32 @@ emotion_object_spu_channel_set(Evas_Object *obj, int channel) Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + DBG("channel=%d", channel); if (!sd->module) return; - if (!sd->video) return; - sd->module->spu_channel_set(sd->video, channel); + if (!sd->video_data) return; + sd->module->spu_channel_set(sd->video_data, channel); } EAPI int -emotion_object_spu_channel_get(Evas_Object *obj) +emotion_object_spu_channel_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); if (!sd->module) return 0; - if (!sd->video) return 0; - return sd->module->spu_channel_get(sd->video); + if (!sd->video_data) return 0; + return sd->module->spu_channel_get(sd->video_data); } EAPI int -emotion_object_chapter_count(Evas_Object *obj) +emotion_object_chapter_count(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); if (!sd->module) return 0; - if (!sd->video) return 0; - return sd->module->chapter_count(sd->video); + if (!sd->video_data) return 0; + return sd->module->chapter_count(sd->video_data); } EAPI void @@ -655,31 +1129,32 @@ emotion_object_chapter_set(Evas_Object *obj, int chapter) Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + DBG("chapter=%d", chapter); if (!sd->module) return; - if (!sd->video) return; - sd->module->chapter_set(sd->video, chapter); + if (!sd->video_data) return; + sd->module->chapter_set(sd->video_data, chapter); } EAPI int -emotion_object_chapter_get(Evas_Object *obj) +emotion_object_chapter_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); if (!sd->module) return 0; - if (!sd->video) return 0; - return sd->module->chapter_get(sd->video); + if (!sd->video_data) return 0; + return sd->module->chapter_get(sd->video_data); } EAPI const char * -emotion_object_chapter_name_get(Evas_Object *obj, int chapter) +emotion_object_chapter_name_get(const Evas_Object *obj, int chapter) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL); if (!sd->module) return NULL; - if (!sd->video) return NULL; - return sd->module->chapter_name_get(sd->video, chapter); + if (!sd->video_data) return NULL; + return sd->module->chapter_name_get(sd->video_data, chapter); } EAPI void @@ -688,20 +1163,21 @@ emotion_object_play_speed_set(Evas_Object *obj, double speed) Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + DBG("speed=%f", speed); if (!sd->module) return; - if (!sd->video) return; - sd->module->speed_set(sd->video, speed); + if (!sd->video_data) return; + sd->module->speed_set(sd->video_data, speed); } EAPI double -emotion_object_play_speed_get(Evas_Object *obj) +emotion_object_play_speed_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0); if (!sd->module) return 0.0; - if (!sd->video) return 0.0; - return sd->module->speed_get(sd->video); + if (!sd->video_data) return 0.0; + return sd->module->speed_get(sd->video_data); } EAPI void @@ -711,12 +1187,12 @@ emotion_object_eject(Evas_Object *obj) E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); if (!sd->module) return; - if (!sd->video) return; - sd->module->eject(sd->video); + if (!sd->video_data) return; + sd->module->eject(sd->video_data); } EAPI const char * -emotion_object_title_get(Evas_Object *obj) +emotion_object_title_get(const Evas_Object *obj) { Smart_Data *sd; @@ -725,7 +1201,7 @@ emotion_object_title_get(Evas_Object *obj) } EAPI const char * -emotion_object_progress_info_get(Evas_Object *obj) +emotion_object_progress_info_get(const Evas_Object *obj) { Smart_Data *sd; @@ -734,7 +1210,7 @@ emotion_object_progress_info_get(Evas_Object *obj) } EAPI double -emotion_object_progress_status_get(Evas_Object *obj) +emotion_object_progress_status_get(const Evas_Object *obj) { Smart_Data *sd; @@ -743,7 +1219,7 @@ emotion_object_progress_status_get(Evas_Object *obj) } EAPI const char * -emotion_object_ref_file_get(Evas_Object *obj) +emotion_object_ref_file_get(const Evas_Object *obj) { Smart_Data *sd; @@ -752,7 +1228,7 @@ emotion_object_ref_file_get(Evas_Object *obj) } EAPI int -emotion_object_ref_num_get(Evas_Object *obj) +emotion_object_ref_num_get(const Evas_Object *obj) { Smart_Data *sd; @@ -761,7 +1237,7 @@ emotion_object_ref_num_get(Evas_Object *obj) } EAPI int -emotion_object_spu_button_count_get(Evas_Object *obj) +emotion_object_spu_button_count_get(const Evas_Object *obj) { Smart_Data *sd; @@ -770,7 +1246,7 @@ emotion_object_spu_button_count_get(Evas_Object *obj) } EAPI int -emotion_object_spu_button_get(Evas_Object *obj) +emotion_object_spu_button_get(const Evas_Object *obj) { Smart_Data *sd; @@ -779,58 +1255,291 @@ emotion_object_spu_button_get(Evas_Object *obj) } EAPI const char * -emotion_object_meta_info_get(Evas_Object *obj, Emotion_Meta_Info meta) +emotion_object_meta_info_get(const Evas_Object *obj, Emotion_Meta_Info meta) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL); if (!sd->module) return NULL; - if (!sd->video) return NULL; + if (!sd->video_data) return NULL; switch (meta) { case EMOTION_META_INFO_TRACK_TITLE: - return sd->module->meta_get(sd->video, META_TRACK_TITLE); - break; + return sd->module->meta_get(sd->video_data, META_TRACK_TITLE); case EMOTION_META_INFO_TRACK_ARTIST: - return sd->module->meta_get(sd->video, META_TRACK_ARTIST); - break; + return sd->module->meta_get(sd->video_data, META_TRACK_ARTIST); case EMOTION_META_INFO_TRACK_ALBUM: - return sd->module->meta_get(sd->video, META_TRACK_ALBUM); - break; + return sd->module->meta_get(sd->video_data, META_TRACK_ALBUM); case EMOTION_META_INFO_TRACK_YEAR: - return sd->module->meta_get(sd->video, META_TRACK_YEAR); - break; + return sd->module->meta_get(sd->video_data, META_TRACK_YEAR); case EMOTION_META_INFO_TRACK_GENRE: - return sd->module->meta_get(sd->video, META_TRACK_GENRE); - break; + return sd->module->meta_get(sd->video_data, META_TRACK_GENRE); case EMOTION_META_INFO_TRACK_COMMENT: - return sd->module->meta_get(sd->video, META_TRACK_COMMENT); - break; + return sd->module->meta_get(sd->video_data, META_TRACK_COMMENT); case EMOTION_META_INFO_TRACK_DISC_ID: - return sd->module->meta_get(sd->video, META_TRACK_DISCID); - break; + return sd->module->meta_get(sd->video_data, META_TRACK_DISCID); default: break; } return NULL; } +EAPI void +emotion_object_vis_set(Evas_Object *obj, Emotion_Vis visualization) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + DBG("visualization=%d", visualization); + if (!sd->module) return; + if (!sd->video_data) return; + if (!sd->module->vis_set) return; + sd->module->vis_set(sd->video_data, visualization); +} + +EAPI Emotion_Vis +emotion_object_vis_get(const Evas_Object *obj) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EMOTION_VIS_NONE); + if (!sd->module) return EMOTION_VIS_NONE; + if (!sd->video_data) return EMOTION_VIS_NONE; + if (!sd->module->vis_get) return EMOTION_VIS_NONE; + return sd->module->vis_get(sd->video_data); +} + +EAPI Eina_Bool +emotion_object_vis_supported(const Evas_Object *obj, Emotion_Vis visualization) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); + if (!sd->module) return EINA_FALSE; + if (!sd->video_data) return EINA_FALSE; + if (!sd->module->vis_supported) return EINA_FALSE; + return sd->module->vis_supported(sd->video_data, visualization); +} + +EAPI void +emotion_object_priority_set(Evas_Object *obj, Eina_Bool priority) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + if (!sd->module) return ; + if (!sd->video_data) return ; + if (!sd->module->priority_set) return ; + sd->module->priority_set(sd->video_data, priority); +} + +EAPI Eina_Bool +emotion_object_priority_get(const Evas_Object *obj) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); + if (!sd->module) return EINA_FALSE; + if (!sd->video_data) return EINA_FALSE; + if (!sd->module->priority_get) return EINA_FALSE; + return sd->module->priority_get(sd->video_data); +} + +#ifdef HAVE_EIO +static void +_eio_load_xattr_cleanup(Smart_Data *sd, Eio_File *handler) +{ + if (handler == sd->load_xattr) sd->load_xattr = NULL; + + EINA_REFCOUNT_UNREF(sd) + _smart_data_free(sd); +} + +static void +_eio_load_xattr_done(void *data, Eio_File *handler, double xattr_double) +{ + Smart_Data *sd = data; + + emotion_object_position_set(evas_object_smart_parent_get(sd->obj), xattr_double); + evas_object_smart_callback_call(evas_object_smart_parent_get(sd->obj), SIG_POSITION_LOAD_SUCCEED, NULL); + _eio_load_xattr_cleanup(sd, handler); +} + +static void +_eio_load_xattr_error(void *data, Eio_File *handler, int err __UNUSED__) +{ + Smart_Data *sd = data; + + evas_object_smart_callback_call(evas_object_smart_parent_get(sd->obj), SIG_POSITION_LOAD_FAILED, NULL); + _eio_load_xattr_cleanup(sd, handler); +} +#endif + +EAPI void +emotion_object_last_position_load(Evas_Object *obj) +{ + Smart_Data *sd; + const char *tmp; +#ifndef HAVE_EIO + double xattr; +#endif + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + if (!sd->file) return ; + + if (!strncmp(sd->file, "file://", 7)) + tmp = sd->file + 7; + else if (!strstr(sd->file, "://")) + tmp = sd->file; + else + return ; + +#ifdef HAVE_EIO + if (sd->load_xattr) return ; + + EINA_REFCOUNT_REF(sd); + + sd->load_xattr = eio_file_xattr_double_get(tmp, + "user.e.time_seek", + _eio_load_xattr_done, + _eio_load_xattr_error, + sd); +#else + if (eina_xattr_double_get(tmp, "user.e.time_seek", &xattr)) + { + emotion_object_position_set(obj, xattr); + evas_object_smart_callback_call(obj, SIG_POSITION_LOAD_SUCCEED, NULL); + } + else + { + evas_object_smart_callback_call(obj, SIG_POSITION_LOAD_FAILED, NULL); + } +#endif +} + +#ifdef HAVE_EIO +static void +_eio_save_xattr_cleanup(Smart_Data *sd, Eio_File *handler) +{ + if (handler == sd->save_xattr) sd->save_xattr = NULL; + + EINA_REFCOUNT_UNREF(sd) + _smart_data_free(sd); +} + +static void +_eio_save_xattr_done(void *data, Eio_File *handler) +{ + Smart_Data *sd = data; + + evas_object_smart_callback_call(sd->obj, SIG_POSITION_SAVE_SUCCEED, NULL); + _eio_save_xattr_cleanup(sd, handler); +} + +static void +_eio_save_xattr_error(void *data, Eio_File *handler, int err __UNUSED__) +{ + Smart_Data *sd = data; + evas_object_smart_callback_call(sd->obj, SIG_POSITION_SAVE_FAILED, NULL); + _eio_save_xattr_cleanup(sd, handler); +} +#endif + +EAPI void +emotion_object_last_position_save(Evas_Object *obj) +{ + Smart_Data *sd; + const char *tmp; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + if (!sd->file) return ; + + if (!strncmp(sd->file, "file://", 7)) + tmp = sd->file + 7; + else if (!strstr(sd->file, "://")) + tmp = sd->file; + else + return ; + +#ifdef HAVE_EIO + if (sd->save_xattr) return ; + + EINA_REFCOUNT_REF(sd); + + sd->save_xattr = eio_file_xattr_double_set(tmp, + "user.e.time_seek", + emotion_object_position_get(obj), + 0, + _eio_save_xattr_done, + _eio_save_xattr_error, + sd); +#else + if (eina_xattr_double_set(tmp, "user.e.time_seek", emotion_object_position_get(obj), 0)) + evas_object_smart_callback_call(obj, SIG_POSITION_SAVE_SUCCEED, NULL); + else + evas_object_smart_callback_call(obj, SIG_POSITION_SAVE_FAILED, NULL); +#endif +} + +EAPI void +emotion_object_suspend_set(Evas_Object *obj, Emotion_Suspend state) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + switch (state) + { + case EMOTION_WAKEUP: + /* Restore the rendering pipeline, offset and everything back to play again (this will be called automatically by play_set) */ + case EMOTION_SLEEP: + /* This destroy some part of the rendering pipeline */ + case EMOTION_DEEP_SLEEP: + /* This destroy all the rendering pipeline and just keep the last rendered image (fullscreen) */ + case EMOTION_HIBERNATE: + /* This destroy all the rendering pipeline and keep 1/4 of the last rendered image */ + default: + break; + } + sd->state = state; +} +EAPI Emotion_Suspend +motion_object_suspend_get(Evas_Object *obj) +{ + Smart_Data *sd; + E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EMOTION_WAKEUP); + return sd->state; +} /*****************************/ /* Utility calls for modules */ /*****************************/ EAPI void * -_emotion_video_get(Evas_Object *obj) +_emotion_video_get(const Evas_Object *obj) { Smart_Data *sd; E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL); - return sd->video; + return sd->video_data; +} + +static Eina_Bool +_emotion_frame_anim(void *data) +{ + Evas_Object *obj = data; + Smart_Data *sd; + + E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EINA_FALSE); + + evas_object_image_pixels_dirty_set(sd->obj, 1); + evas_object_smart_callback_call(obj, SIG_FRAME_DECODE, NULL); + sd->anim = NULL; + + return EINA_FALSE; } EAPI void @@ -839,9 +1548,8 @@ _emotion_frame_new(Evas_Object *obj) Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); -// printf("pix get set 1 %p\n", sd->obj); - evas_object_image_pixels_dirty_set(sd->obj, 1); - evas_object_smart_callback_call(obj, "frame_decode", NULL); + + if (!sd->anim) sd->anim = ecore_animator_add(_emotion_frame_anim, obj); } EAPI void @@ -855,32 +1563,49 @@ _emotion_video_pos_update(Evas_Object *obj, double pos, double len) if (len != sd->len) nlen = 1; sd->pos = pos; sd->len = len; - if (npos) evas_object_smart_callback_call(obj, "position_update", NULL); - if (nlen) evas_object_smart_callback_call(obj, "length_change", NULL); + if (npos) evas_object_smart_callback_call(obj, SIG_POSITION_UPDATE, NULL); + if (nlen) evas_object_smart_callback_call(obj, SIG_LENGTH_CHANGE, NULL); } EAPI void _emotion_frame_resize(Evas_Object *obj, int w, int h, double ratio) { Smart_Data *sd; - int iw, ih; + double tmp; int changed = 0; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); - evas_object_image_size_get(sd->obj, &iw, &ih); - if ((w != iw) || (h != ih)) + if ((w != sd->video.w) || (h != sd->video.h)) { - if (h > 0) sd->ratio = (double)w / (double)h; - else sd->ratio = 1.0; - evas_object_image_size_set(sd->obj, w, h); + sd->video.w = w; + sd->video.h = h; + _emotion_image_data_zero(sd->obj); changed = 1; } - if (ratio != sd->ratio) + if (h > 0) tmp = (double)w / (double)h; + else tmp = 1.0; + if (ratio != tmp) tmp = ratio; + if (tmp != sd->ratio) { - sd->ratio = ratio; + sd->ratio = tmp; changed = 1; } - if (changed) evas_object_smart_callback_call(obj, "frame_resize", NULL); + if (changed) + { + evas_object_size_hint_request_set(obj, w, h); + evas_object_smart_callback_call(obj, SIG_FRAME_RESIZE, NULL); + evas_object_geometry_get(obj, NULL, NULL, &w, &h); + _emotion_object_aspect_border_apply(obj, sd, w, h); + } +} + +EAPI void +_emotion_image_reset(Evas_Object *obj) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + _emotion_image_data_zero(sd->obj); } EAPI void @@ -892,20 +1617,41 @@ _emotion_decode_stop(Evas_Object *obj) if (sd->play) { sd->play = 0; - evas_object_smart_callback_call(obj, "decode_stop", NULL); + evas_object_smart_callback_call(obj, SIG_DECODE_STOP, NULL); } } EAPI void +_emotion_open_done(Evas_Object *obj) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + sd->open = 1; + + if (sd->remember_jump) + emotion_object_position_set(obj, sd->remember_jump); + if (sd->remember_play != sd->play) + emotion_object_play_set(obj, sd->remember_play); + evas_object_smart_callback_call(obj, SIG_OPEN_DONE, NULL); +} + +EAPI void +_emotion_playback_started(Evas_Object *obj) +{ + evas_object_smart_callback_call(obj, SIG_PLAYBACK_STARTED, NULL); +} + +EAPI void _emotion_playback_finished(Evas_Object *obj) { - evas_object_smart_callback_call(obj, "playback_finished", NULL); + evas_object_smart_callback_call(obj, SIG_PLAYBACK_FINISHED, NULL); } EAPI void _emotion_audio_level_change(Evas_Object *obj) { - evas_object_smart_callback_call(obj, "audio_level_change", NULL); + evas_object_smart_callback_call(obj, SIG_AUDIO_LEVEL_CHANGE, NULL); } EAPI void @@ -914,7 +1660,7 @@ _emotion_channels_change(Evas_Object *obj) Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); - evas_object_smart_callback_call(obj, "channels_change", NULL); + evas_object_smart_callback_call(obj, SIG_CHANNELS_CHANGE, NULL); } EAPI void @@ -923,33 +1669,33 @@ _emotion_title_set(Evas_Object *obj, char *title) Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); - if (sd->title) free(sd->title); + free(sd->title); sd->title = strdup(title); - evas_object_smart_callback_call(obj, "title_change", NULL); + evas_object_smart_callback_call(obj, SIG_TITLE_CHANGE, NULL); } EAPI void -_emotion_progress_set(Evas_Object *obj, char *info, double stat) +_emotion_progress_set(Evas_Object *obj, char *info, double st) { Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); - if (sd->progress.info) free(sd->progress.info); + free(sd->progress.info); sd->progress.info = strdup(info); - sd->progress.stat = stat; - evas_object_smart_callback_call(obj, "progress_change", NULL); + sd->progress.stat = st; + evas_object_smart_callback_call(obj, SIG_PROGRESS_CHANGE, NULL); } EAPI void -_emotion_file_ref_set(Evas_Object *obj, char *file, int num) +_emotion_file_ref_set(Evas_Object *obj, const char *file, int num) { Smart_Data *sd; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); - if (sd->ref.file) free(sd->ref.file); + free(sd->ref.file); sd->ref.file = strdup(file); sd->ref.num = num; - evas_object_smart_callback_call(obj, "ref_change", NULL); + evas_object_smart_callback_call(obj, SIG_REF_CHANGE, NULL); } EAPI void @@ -959,7 +1705,7 @@ _emotion_spu_button_num_set(Evas_Object *obj, int num) E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); sd->spu.button_num = num; - evas_object_smart_callback_call(obj, "button_num_change", NULL); + evas_object_smart_callback_call(obj, SIG_BUTTON_NUM_CHANGE, NULL); } EAPI void @@ -969,16 +1715,61 @@ _emotion_spu_button_set(Evas_Object *obj, int button) E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); sd->spu.button = button; - evas_object_smart_callback_call(obj, "button_change", NULL); + evas_object_smart_callback_call(obj, SIG_BUTTON_CHANGE, NULL); } +EAPI void +_emotion_seek_done(Evas_Object *obj) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + if (sd->seeking) + { + sd->seeking = 0; + if (sd->seek) emotion_object_position_set(obj, sd->seek_pos); + } +} + +EAPI void +_emotion_frame_refill(Evas_Object *obj, double w, double h) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + if (sd->fill.w != w || sd->fill.h != h) + { + Evas_Coord ow, oh; + + evas_object_geometry_get(obj, NULL, NULL, &ow, &oh); + if (w <= 0 || h <= 0) + { + double scale_w, scale_h; + + sd->fill.w = -1; + sd->fill.h = -1; + + scale_w = (double) ow / (double)(sd->video.w - sd->crop.l - sd->crop.r); + scale_h = (double) oh / (double)(sd->video.h - sd->crop.t - sd->crop.b); + + evas_object_image_fill_set(sd->obj, 0, 0, scale_w * sd->video.w, scale_h * sd->video.h); + } + else + { + sd->fill.w = w; + sd->fill.h = h; + + evas_object_image_fill_set(sd->obj, 0, 0, w * ow, h * oh); + } + } +} /****************************/ /* Internal object routines */ /****************************/ static void -_mouse_move(void *data, Evas *ev, Evas_Object *obj, void *event_info) +_mouse_move(void *data, Evas *ev __UNUSED__, Evas_Object *obj, void *event_info) { Evas_Event_Mouse_Move *e; Smart_Data *sd; @@ -988,17 +1779,17 @@ _mouse_move(void *data, Evas *ev, Evas_Object *obj, void *event_info) e = event_info; sd = data; if (!sd->module) return; - if (!sd->video) return; + if (!sd->video_data) return; evas_object_geometry_get(obj, &ox, &oy, &ow, &oh); evas_object_image_size_get(obj, &iw, &ih); if ((iw < 1) || (ih < 1)) return; x = (((int)e->cur.canvas.x - ox) * iw) / ow; y = (((int)e->cur.canvas.y - oy) * ih) / oh; - sd->module->event_mouse_move_feed(sd->video, x, y); + sd->module->event_mouse_move_feed(sd->video_data, x, y); } static void -_mouse_down(void *data, Evas *ev, Evas_Object *obj, void *event_info) +_mouse_down(void *data, Evas *ev __UNUSED__, Evas_Object *obj, void *event_info) { Evas_Event_Mouse_Down *e; Smart_Data *sd; @@ -1008,13 +1799,13 @@ _mouse_down(void *data, Evas *ev, Evas_Object *obj, void *event_info) e = event_info; sd = data; if (!sd->module) return; - if (!sd->video) return; + if (!sd->video_data) return; evas_object_geometry_get(obj, &ox, &oy, &ow, &oh); evas_object_image_size_get(obj, &iw, &ih); if ((iw < 1) || (ih < 1)) return; x = (((int)e->canvas.x - ox) * iw) / ow; y = (((int)e->canvas.y - oy) * ih) / oh; - sd->module->event_mouse_button_feed(sd->video, 1, x, y); + sd->module->event_mouse_button_feed(sd->video_data, 1, x, y); } static void @@ -1026,9 +1817,11 @@ _pos_set_job(void *data) obj = data; E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); sd->job = NULL; + if (sd->seeking) return; if (sd->seek) { - sd->module->pos_set(sd->video, sd->seek_pos); + sd->seeking = 1; + sd->module->pos_set(sd->video_data, sd->seek_pos); sd->seek = 0; } } @@ -1043,26 +1836,24 @@ _pixels_get(void *data, Evas_Object *obj) unsigned char *bgra_data; sd = data; - evas_object_image_size_get(obj, &iw, &ih); - sd->module->video_data_size_get(sd->video, &w, &h); + sd->module->video_data_size_get(sd->video_data, &w, &h); w = (w >> 1) << 1; h = (h >> 1) << 1; - if ((w != iw) || (h != ih)) - { - evas_object_image_colorspace_set(obj, EVAS_COLORSPACE_YCBCR422P601_PL); - evas_object_image_alpha_set(obj, 0); - evas_object_image_size_set(obj, w, h); - iw = w; - ih = h; - } - if ((iw < 1) || (ih < 1)) + + evas_object_image_colorspace_set(obj, EVAS_COLORSPACE_YCBCR422P601_PL); + evas_object_image_alpha_set(obj, 0); + evas_object_image_size_set(obj, w, h); + iw = w; + ih = h; + + if ((iw <= 1) || (ih <= 1)) { -// printf("pix get set 0 (1)\n"); + _emotion_image_data_zero(sd->obj); evas_object_image_pixels_dirty_set(obj, 0); } else { - format = sd->module->format_get(sd->video); + format = sd->module->format_get(sd->video_data); if ((format == EMOTION_FORMAT_YV12) || (format == EMOTION_FORMAT_I420)) { unsigned char **rows; @@ -1071,101 +1862,107 @@ _pixels_get(void *data, Evas_Object *obj) rows = evas_object_image_data_get(obj, 1); if (rows) { - if (sd->module->yuv_rows_get(sd->video, iw, ih, + if (sd->module->yuv_rows_get(sd->video_data, iw, ih, rows, &rows[ih], &rows[ih + (ih / 2)])) evas_object_image_data_update_add(obj, 0, 0, iw, ih); } evas_object_image_data_set(obj, rows); -// printf("pix get set 0 (2)\n"); evas_object_image_pixels_dirty_set(obj, 0); } else if (format == EMOTION_FORMAT_BGRA) { - if (sd->module->bgra_data_get(sd->video, &bgra_data)) + evas_object_image_colorspace_set(obj, EVAS_COLORSPACE_ARGB8888); + if (sd->module->bgra_data_get(sd->video_data, &bgra_data)) { evas_object_image_data_set(obj, bgra_data); -// printf("pix get set 0 (3)\n"); evas_object_image_pixels_dirty_set(obj, 0); } } } -// no need for this because on any new frame decode info from the decoder -// module, the previous "current frame" is released (done) for us anyway -// sd->module->frame_done(sd->video); - -/* - evas_object_image_size_get(obj, &iw, &ih); - sd->module->video_data_size_get(sd->video, &w, &h); - if ((w != iw) || (h != ih)) - { - evas_object_image_size_set(obj, w, h); - iw = w; - ih = h; - } - format = sd->module->format_get(sd->video); - if ((format == EMOTION_FORMAT_YV12) || (format == EMOTION_FORMAT_I420)) - { - unsigned char **rows; - Evas_Pixel_Import_Source ps; - - ps.format = EVAS_PIXEL_FORMAT_YUV420P_601; - ps.w = iw; - ps.h = ih; - - ps.rows = malloc(ps.h * 2 * sizeof(void *)); - if (!ps.rows) - { - sd->module->frame_done(sd->video); - return; - } - - rows = (unsigned char **)ps.rows; - - if (sd->module->yuv_rows_get(sd->video, iw, ih, - rows, - &rows[ps.h], - &rows[ps.h + (ps.h / 2)])) - evas_object_image_pixels_import(obj, &ps); - evas_object_image_pixels_dirty_set(obj, 0); - free(ps.rows); - } - else if (format == EMOTION_FORMAT_BGRA) - { - if (sd->module->bgra_data_get(sd->video, &bgra_data)); - { - evas_object_image_data_set(obj, bgra_data); - evas_object_image_pixels_dirty_set(obj, 0); - } - } - sd->module->frame_done(sd->video); - */ } /*******************************************/ /* Internal smart object required routines */ /*******************************************/ +#ifdef EMOTION_STATIC_BUILD_XINE +Eina_Bool xine_module_init(void); +#endif +#ifdef EMOTION_STATIC_BUILD_GSTREAMER +Eina_Bool gstreamer_module_init(void); +#endif +#ifdef EMOTION_STATIC_BUILD_GENERIC +Eina_Bool generic_module_init(void); +#endif + static void _smart_init(void) { + char *path; + if (smart) return; { - static const Evas_Smart_Class sc = + eina_init(); + + _log_domain = eina_log_domain_register("emotion", EINA_COLOR_LIGHTCYAN); + if (_log_domain < 0) + { + EINA_LOG_CRIT("Could not register log domain 'emotion'"); + eina_shutdown(); + return; + } + + _backends = eina_hash_string_small_new(free); + + _modules = eina_module_list_get(NULL, PACKAGE_LIB_DIR "/emotion/", 0, NULL, NULL); + + path = eina_module_environment_path_get("HOME", "/.emotion/"); + _modules = eina_module_list_get(_modules, path, 0, NULL, NULL); + if (path) free(path); + + path = eina_module_environment_path_get("EMOTION_MODULES_DIR", "/emotion/"); + _modules = eina_module_list_get(_modules, path, 0, NULL, NULL); + if (path) free(path); + + path = eina_module_symbol_path_get(emotion_object_add, "/emotion/"); + _modules = eina_module_list_get(_modules, path, 0, NULL, NULL); + if (path) free(path); + + if (!_modules) { - E_OBJ_NAME, - EVAS_SMART_CLASS_VERSION, - _smart_add, - _smart_del, - _smart_move, - _smart_resize, - _smart_show, - _smart_hide, - _smart_color_set, - _smart_clip_set, - _smart_clip_unset, - NULL - }; + ERR("No module found!"); + return; + } + + eina_module_list_load(_modules); + + /* Init static module */ +#ifdef EMOTION_STATIC_BUILD_XINE + xine_module_init(); +#endif +#ifdef EMOTION_STATIC_BUILD_GSTREAMER + gstreamer_module_init(); +#endif +#ifdef EMOTION_STATIC_BUILD_GENERIC + generic_module_init(); +#endif + + static Evas_Smart_Class sc = + EVAS_SMART_CLASS_INIT_NAME_VERSION(E_OBJ_NAME); + if (!sc.add) + { + sc.add = _smart_add; + sc.del = _smart_del; + sc.move = _smart_move; + sc.resize = _smart_resize; + sc.show = _smart_show; + sc.hide = _smart_hide; + sc.color_set = _smart_color_set; + sc.clip_set = _smart_clip_set; + sc.clip_unset = _smart_clip_unset; + sc.callbacks = _smart_callbacks; + } smart = evas_smart_class_new(&sc); } } @@ -1178,13 +1975,21 @@ _smart_add(Evas_Object * obj) sd = calloc(1, sizeof(Smart_Data)); if (!sd) return; + EINA_REFCOUNT_INIT(sd); + sd->state = EMOTION_WAKEUP; sd->obj = evas_object_image_add(evas_object_evas_get(obj)); + sd->bg = evas_object_rectangle_add(evas_object_evas_get(obj)); + evas_object_color_set(sd->bg, 0, 0, 0, 0); evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, sd); evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, sd); evas_object_image_pixels_get_callback_set(sd->obj, _pixels_get, sd); evas_object_smart_member_add(sd->obj, obj); + evas_object_smart_member_add(sd->bg, obj); + evas_object_lower(sd->bg); sd->ratio = 1.0; sd->spu.button = -1; + sd->fill.w = -1; + sd->fill.h = -1; evas_object_image_alpha_set(sd->obj, 0); pixel = evas_object_image_data_get(sd->obj, 1); if (pixel) @@ -1193,6 +1998,8 @@ _smart_add(Evas_Object * obj) evas_object_image_data_set(obj, pixel); } evas_object_smart_data_set(obj, sd); + + ecore_init(); } static void @@ -1202,26 +2009,22 @@ _smart_del(Evas_Object * obj) sd = evas_object_smart_data_get(obj); if (!sd) return; - if (sd->video) sd->module->file_close(sd->video); - _emotion_module_close(sd->module, sd->video); - evas_object_del(sd->obj); - if (sd->file) free(sd->file); - if (sd->job) ecore_job_del(sd->job); - if (sd->progress.info) free(sd->progress.info); - if (sd->ref.file) free(sd->ref.file); - free(sd); - - ecore_job_shutdown(); + EINA_REFCOUNT_UNREF(sd) + _smart_data_free(sd); } static void _smart_move(Evas_Object * obj, Evas_Coord x, Evas_Coord y) { Smart_Data *sd; + int w, h; sd = evas_object_smart_data_get(obj); if (!sd) return; - evas_object_move(sd->obj, x, y); + + evas_object_geometry_get(obj, NULL, NULL, &w, &h); + _clipper_position_size_update(obj, x, y, w, h, sd->video.w, sd->video.h); + evas_object_move(sd->bg, x, y); } static void @@ -1231,19 +2034,26 @@ _smart_resize(Evas_Object * obj, Evas_Coord w, Evas_Coord h) sd = evas_object_smart_data_get(obj); if (!sd) return; - evas_object_image_fill_set(sd->obj, 0, 0, w, h); - evas_object_resize(sd->obj, w, h); + + _emotion_object_aspect_border_apply(obj, sd, w, h); + evas_object_resize(sd->bg, w, h); } static void _smart_show(Evas_Object * obj) { Smart_Data *sd; + int a; sd = evas_object_smart_data_get(obj); if (!sd) return; evas_object_show(sd->obj); + if (sd->crop.clipper) + evas_object_show(sd->crop.clipper); + evas_object_color_get(sd->bg, NULL, NULL, NULL, &a); + if (a > 0) + evas_object_show(sd->bg); } static void @@ -1254,6 +2064,9 @@ _smart_hide(Evas_Object * obj) sd = evas_object_smart_data_get(obj); if (!sd) return; evas_object_hide(sd->obj); + if (sd->crop.clipper) + evas_object_hide(sd->crop.clipper); + evas_object_hide(sd->bg); } static void @@ -1264,6 +2077,7 @@ _smart_color_set(Evas_Object * obj, int r, int g, int b, int a) sd = evas_object_smart_data_get(obj); if (!sd) return; evas_object_color_set(sd->obj, r, g, b, a); + evas_object_color_set(sd->crop.clipper, r, g, b, a); } static void @@ -1273,7 +2087,11 @@ _smart_clip_set(Evas_Object * obj, Evas_Object * clip) sd = evas_object_smart_data_get(obj); if (!sd) return; - evas_object_clip_set(sd->obj, clip); + if (sd->crop.clipper) + evas_object_clip_set(sd->crop.clipper, clip); + else + evas_object_clip_set(sd->obj, clip); + evas_object_clip_set(sd->bg, clip); } static void @@ -1283,5 +2101,10 @@ _smart_clip_unset(Evas_Object * obj) sd = evas_object_smart_data_get(obj); if (!sd) return; - evas_object_clip_unset(sd->obj); + if (sd->crop.clipper) + evas_object_clip_unset(sd->crop.clipper); + else + evas_object_clip_unset(sd->obj); + evas_object_clip_unset(sd->bg); } + diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am index 1af8c8c..faaa146 100644 --- a/src/modules/Makefile.am +++ b/src/modules/Makefile.am @@ -1,4 +1,4 @@ MAINTAINERCLEANFILES = Makefile.in -SUBDIRS = xine gstreamer +SUBDIRS = xine gstreamer generic diff --git a/src/modules/generic/Emotion_Generic_Plugin.h b/src/modules/generic/Emotion_Generic_Plugin.h new file mode 100644 index 0000000..17bd7e9 --- /dev/null +++ b/src/modules/generic/Emotion_Generic_Plugin.h @@ -0,0 +1,144 @@ +#ifndef EMOTION_GENERIC_PLUGIN_H +#define EMOTION_GENERIC_PLUGIN_H + +#include +#include +#include +#include +#include + +#include + +#define DEFAULTWIDTH 320 +#define DEFAULTHEIGHT 240 +#define DEFAULTPITCH 4 + +typedef enum _Emotion_Generic_Cmd Emotion_Generic_Cmd; +typedef enum _Emotion_Generic_Result Emotion_Generic_Result; +typedef struct _Emotion_Generic_Video_Frame Emotion_Generic_Video_Frame; +typedef struct _Emotion_Generic_Video_Shared Emotion_Generic_Video_Shared; + +enum _Emotion_Generic_Cmd +{ + EM_CMD_INIT = 0, // param: shared memory identifier (string) + EM_CMD_PLAY, // param: position (float) + EM_CMD_STOP, // param: none + EM_CMD_FILE_SET, // param: filename (string) + EM_CMD_FILE_SET_DONE, // param: success (int) + EM_CMD_FILE_CLOSE, // param: none + EM_CMD_POSITION_SET, // param: position (float) + EM_CMD_SPEED_SET, // param: speed (float) + EM_CMD_AUDIO_MUTE_SET, // param: muted (int) + EM_CMD_VIDEO_MUTE_SET, // param: muted (int) + EM_CMD_SPU_MUTE_SET, // param: muted (int) + EM_CMD_VOLUME_SET, // param: volume (float) + EM_CMD_AUDIO_TRACK_SET, // param: track id (int) + EM_CMD_VIDEO_TRACK_SET, // param: track id (int) + EM_CMD_SPU_TRACK_SET, // param: track id (int) + EM_CMD_LAST +}; + +enum _Emotion_Generic_Result +{ + EM_RESULT_INIT = 0, // param: none + EM_RESULT_FILE_SET, // param: none + EM_RESULT_FILE_SET_DONE, // param: success (int) + EM_RESULT_PLAYBACK_STARTED, // param: none + EM_RESULT_PLAYBACK_STOPPED, // param: none + EM_RESULT_FILE_CLOSE, // param: none + EM_RESULT_FRAME_NEW, // param: none + EM_RESULT_FRAME_SIZE, // param: int, int (width, height) + EM_RESULT_LENGTH_CHANGED, // param: float + EM_RESULT_POSITION_CHANGED, // param: float + EM_RESULT_SEEKABLE_CHANGED, // param: int + EM_RESULT_AUDIO_TRACK_INFO, // param: current track, track count, track_id, track_name, track_id2, track_name2, ... + EM_RESULT_VIDEO_TRACK_INFO, // param: current track, track count, track_id, track_name, track_id2, track_name2, ... + EM_RESULT_SPU_TRACK_INFO, // param: current spu, spu count, spu_id, spu_name, spu_id2, spu_name2, ... + // (int, int, int, string, int, string, ...) + EM_RESULT_META_INFO, // param: title, artist, album, year, genre, comments, disc id, count (all int) + EM_RESULT_LAST +}; + +/* structure for frames 2 buffers to keep integrity */ +struct _Emotion_Generic_Video_Frame +{ + unsigned char *frames[3]; +}; + +/* structure for frames 2 buffers to keep integrity */ +struct _Emotion_Generic_Video_Shared +{ + int size; + int width; + int height; + int pitch; + /** + * - "emotion" is the frame from where the Emotion process is reading pixels. + * The player shouldn't touch this frame. + * - "player" is the frame where the slayer process is writing pixels. + * The emotion process shouldn't touch this frame. + * - "last" is the last frame that was rendered by the player. Emotion will + * use this frame the next time it will fetch pixels to Evas. + * - "next" is the unused frame. The player currently using the "player" + * should, after finishing this frame, set "last" to "player", and "player" + * to "next", and finally "next" to "last" so this operation can be done + * many times in case that Emotion does not request pixels fast enough. + */ + struct { + int emotion; + int player; + int last; + int next; + } frame; + Eina_Semaphore lock; + int frame_drop; +}; + +static inline int +emotion_generic_shm_get(const char *shmname, Emotion_Generic_Video_Shared **vs, Emotion_Generic_Video_Frame *vf) +{ + int shmfd = -1; + int size; + Emotion_Generic_Video_Shared *t_vs; + + shmfd = shm_open(shmname, O_RDWR, 0777); + if (shmfd == -1) + { + fprintf(stderr, "player: could not open shm: %s\n", shmname); + fprintf(stderr, "player: %s\n", strerror(errno)); + return 0; + } + + t_vs = mmap(NULL, sizeof(*t_vs), PROT_READ|PROT_WRITE, MAP_SHARED, shmfd, 0); + if (t_vs == MAP_FAILED) + { + fprintf(stderr, "player: could not map shared memory.\n"); + fprintf(stderr, "player: %s\n", strerror(errno)); + return 0; + } + size = t_vs->size; + munmap(t_vs, sizeof(*t_vs)); + t_vs = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, shmfd, 0); + if (t_vs == MAP_FAILED) + { + fprintf(stderr, "player: could not map shared memory.\n"); + fprintf(stderr, "player: %s\n", strerror(errno)); + return 0; + } + + vf->frames[0] = (unsigned char *)t_vs + sizeof(*t_vs); + vf->frames[1] = (unsigned char *)t_vs + sizeof(*t_vs) + t_vs->height * t_vs->width * t_vs->pitch; + vf->frames[2] = (unsigned char *)t_vs + sizeof(*t_vs) + 2 * t_vs->height * t_vs->width * t_vs->pitch; + + *vs = t_vs; + + return 1; +} + +static inline void +emotion_generic_shm_free(Emotion_Generic_Video_Shared *vs) +{ + munmap(vs, vs->size); +} + +#endif // EMOTION_GENERIC_PLUGIN_H diff --git a/src/modules/generic/Makefile.am b/src/modules/generic/Makefile.am new file mode 100644 index 0000000..23be987 --- /dev/null +++ b/src/modules/generic/Makefile.am @@ -0,0 +1,31 @@ +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I$(top_srcdir) \ +-I$(top_srcdir)/src/lib \ +-I$(top_srcdir)/src/modules \ +-DPACKAGE_BIN_DIR=\"$(bindir)\" \ +-DPACKAGE_LIB_DIR=\"$(libdir)\" \ +-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ +@EMOTION_CFLAGS@ \ +@EMOTION_CPPFLAGS@ \ +@EFL_EMOTION_BUILD@ + +if EMOTION_BUILD_GENERIC +if !EMOTION_STATIC_BUILD_GENERIC + +pkgdir = $(libdir)/emotion + +pkg_LTLIBRARIES = em_generic.la +includes_HEADERS = Emotion_Generic_Plugin.h +includesdir = $(includedir)/emotion-@VMAJ@ +noinst_HEADERS = emotion_generic.h + +em_generic_la_SOURCES = emotion_generic.c +em_generic_la_LIBADD = @EMOTION_LIBS@ @EFL_SHM_OPEN_LIBS@ $(top_builddir)/src/lib/libemotion.la +em_generic_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version +em_generic_la_LIBTOOLFLAGS = --tag=disable-static +em_generic_la_DEPENDENCIES = emotion_generic.h Emotion_Generic_Plugin.h + +endif +endif diff --git a/src/modules/generic/README b/src/modules/generic/README new file mode 100644 index 0000000..c2a028d --- /dev/null +++ b/src/modules/generic/README @@ -0,0 +1,79 @@ +Generic - emotion backend +========================= + +This generic player backend executes a separate player in another +process. It receives the bytes to be drawn on the emotion object through +a shared memory, and communicates with the player through a pipe, using +the player standard input/output. + +The player must communicate with emotion using the defined commands +specified in the Emotion_Generic_Plugin.h. It doesn't need to link +against emotion, just include this file for easier implementation. + + +How does it work? +================= + +When the module is initialized for an emotion object, it starts another process +that runs the specified player. The player command line is specified using: + + emotion_object_module_option_set(object, "player", ); + +A player using libvlc is being provided now, and the generic module internally +checks if the command given was "vlc", in which case it will use this provided +vlc player. + +When a file is set to this object, it will send the file name to the player, and +expect an answer that will tell that the player already decoded a bit of the +file, and the video size is already set on the module, so it can allocate a +shared memory with correct size. + +The module then allocates the memory, sends a message to the player and expect +an answer. After this last answer, the "open_done" signal is sent and the module +knows that it is ready for playing. Commands sent before the module being ready +are now applied (and play is resumed if necessary). + +During this setup stage, info about the file set will be stored in the module, +so commands like meta data get, length get and so will be available to sync +calls like emotion_object_play_length_get(); + +If the player dies for any reason, a "decode_stop" signal is sent (should change +to something more like an error signal), and if play is called again, it will be +restarted. The playback should start from the same point it was before the +player crashed, if the player supports seek on the current media format). + +TODO +==== + + - Provide better description for commands; + - Explain in details the communication emotion <-> player; + - Make more common functions for players; + - (maybe) add support for named pipes, so we don't rely on standard in/out + for communication; + - Add a detection on the player to know that the emotion process died (so it + can just exit); + - shmname should contain the child pid too; + - better names for commands, maybe add namespace everywhere; + + +questions +========= + + - Using semaphores to lock the critical region between process, and pthread + mutexes for the threads inside the player. Should move to only one type + (semphores or mutexes)? + - There are 2 inline functions insde Emotion_Generic_Plugin.h to make it easier + for the player to get the shared memory correctly. Any problem with this? + Would be good to add more functions/macros to make common tasks like + parsing commands there too? + - Should move players to another project (outside of emotion)? + + +problems +======== + - file_set has some critical time when file is not set yet when we can't call + some functions (I think only another file_set now); + - communication player -> emotion depends on '\n' to delimitate commands, will + remove this soon (fix this urgently!); + - need to implement missing APIs; + diff --git a/src/modules/generic/emotion_generic.c b/src/modules/generic/emotion_generic.c new file mode 100644 index 0000000..e4771ce --- /dev/null +++ b/src/modules/generic/emotion_generic.c @@ -0,0 +1,1794 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "Emotion.h" +#include "emotion_private.h" +#include "emotion_generic.h" + +static Eina_Prefix *pfx = NULL; + +static int _emotion_generic_log_domain = -1; +#define DBG(...) EINA_LOG_DOM_DBG(_emotion_generic_log_domain, __VA_ARGS__) +#define INF(...) EINA_LOG_DOM_INFO(_emotion_generic_log_domain, __VA_ARGS__) +#define WRN(...) EINA_LOG_DOM_WARN(_emotion_generic_log_domain, __VA_ARGS__) +#define ERR(...) EINA_LOG_DOM_ERR(_emotion_generic_log_domain, __VA_ARGS__) +#define CRITICAL(...) EINA_LOG_DOM_CRIT(_emotion_generic_log_domain, __VA_ARGS__) + + +struct _default_players { + const char *name; + const char *cmdline; +}; + +static struct _default_players players[] = { +#ifdef EMOTION_BUILD_GENERIC_VLC + { "vlc", "em_generic_vlc" }, +#endif + { NULL, NULL } +}; + +static Eina_Bool _fork_and_exec(Emotion_Generic_Video *ev); +static void em_partial_shutdown(Emotion_Generic_Video *ev); + +static Eina_Bool +_player_restart(void *data) +{ + Emotion_Generic_Video *ev = data; + + _fork_and_exec(ev); + ev->player_restart = NULL; + return EINA_FALSE; +} + +static const char * +_get_player(const char *name) +{ + const char *selected_name = NULL; + const char *libdir = eina_prefix_lib_get(pfx); + static char buf[PATH_MAX]; + int i; + + if (name) + { + for (i = 0; players[i].name; i++) + { + if (!strcmp(players[i].name, name)) + { + selected_name = players[i].cmdline; + break; + } + } + } + + if ((!selected_name) && (name)) + selected_name = name; + + if (selected_name) + { + const char *cmd; + + if (selected_name[0] == '/') cmd = selected_name; + else + { + snprintf(buf, sizeof(buf), "%s/emotion/utils/%s", + libdir, selected_name); + cmd = buf; + } + + DBG("Try generic player '%s'", cmd); + if (access(cmd, R_OK | X_OK) == 0) + { + INF("Using generic player '%s'", cmd); + return cmd; + } + } + + for (i = 0; players[i].name; i++) + { + snprintf(buf, sizeof(buf), "%s/emotion/utils/%s", + libdir, players[i].cmdline); + DBG("Try generic player '%s'", buf); + if (access(buf, R_OK | X_OK) == 0) + { + INF("Using fallback player '%s'", buf); + return buf; + } + } + + ERR("no generic player found, given name='%s'", name ? name : ""); + return NULL; +} + +static void +_player_send_cmd(Emotion_Generic_Video *ev, int cmd) +{ + if (cmd >= EM_CMD_LAST) + { + ERR("invalid command to player."); + return; + } + if (ev->fd_write == -1) + { + ERR("you should wait for emotion to be ready to take action."); + return ; + } + if (write(ev->fd_write, &cmd, sizeof(cmd)) < 0) perror("write"); +} + +static void +_player_send_int(Emotion_Generic_Video *ev, int number) +{ + if (ev->fd_write == -1) + { + ERR("you should wait for emotion to be ready to take action."); + return ; + } + if (write(ev->fd_write, &number, sizeof(number)) < 0) perror("write"); +} + +static void +_player_send_float(Emotion_Generic_Video *ev, float number) +{ + if (ev->fd_write == -1) + { + ERR("you should wait for emotion to be ready to take action."); + return ; + } + if (write(ev->fd_write, &number, sizeof(number)) < 0) perror("write"); +} + +static void +_player_send_str(Emotion_Generic_Video *ev, const char *str, Eina_Bool stringshared) +{ + int len; + + if (stringshared) + len = eina_stringshare_strlen(str) + 1; + else + len = strlen(str) + 1; + if (write(ev->fd_write, &len, sizeof(len)) < 0) perror("write"); + if (write(ev->fd_write, str, len) < 0) perror("write"); +} + +static Eina_Bool +_create_shm_data(Emotion_Generic_Video *ev, const char *shmname) +{ + int shmfd; + int npages; + size_t size; + Emotion_Generic_Video_Shared *vs; + + shmfd = shm_open(shmname, O_CREAT | O_RDWR | O_TRUNC, 0777); + if (shmfd == -1) + { + ERR("player: could not open shm: %s", shmname); + ERR("player: %s", strerror(errno)); + return 0; + } + size = 3 * (ev->w * ev->h * DEFAULTPITCH) + sizeof(*vs); + + npages = (int)(size / getpagesize()) + 1; + size = npages * getpagesize(); + + if (ftruncate(shmfd, size)) + { + ERR("error when allocating shared memory (size = %zd): " + "%s", size, strerror(errno)); + shm_unlink(shmname); + return EINA_FALSE; + } + vs = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, shmfd, 0); + if (vs == MAP_FAILED) + { + ERR("error when mapping shared memory"); + return EINA_FALSE; + } + + vs->size = size; + vs->width = ev->w; + vs->height = ev->h; + vs->pitch = DEFAULTPITCH; + vs->frame.emotion = 0; + vs->frame.player = 1; + vs->frame.last = 2; + vs->frame.next = 2; + vs->frame_drop = 0; + if (!eina_semaphore_new(&vs->lock, 1)) + { + ERR("can not create semaphore"); + return EINA_FALSE; + } + ev->frame.frames[0] = (unsigned char *)vs + sizeof(*vs); + ev->frame.frames[1] = (unsigned char *)vs + sizeof(*vs) + vs->height * vs->width * vs->pitch; + ev->frame.frames[2] = (unsigned char *)vs + sizeof(*vs) + 2 * vs->height * vs->width * vs->pitch; + + if (ev->shared) + munmap(ev->shared, ev->shared->size); + ev->shared = vs; + + return EINA_TRUE; +} + +static void +_player_new_frame(Emotion_Generic_Video *ev) +{ + if (!ev->file_ready) + return; + _emotion_frame_new(ev->obj); +} + +static void +_file_open(Emotion_Generic_Video *ev) +{ + INF("Opening file: %s", ev->filename); + ev->drop = 0; + + if (!ev->ready || !ev->filename) + return; + _player_send_cmd(ev, EM_CMD_FILE_SET); + _player_send_str(ev, ev->filename, EINA_TRUE); +} + +static void +_player_file_set_done(Emotion_Generic_Video *ev) +{ + if (ev->file_changed) + { + _file_open(ev); + ev->file_changed = EINA_FALSE; + return; + } + + if (!_create_shm_data(ev, ev->shmname)) + { + ERR("could not create shared memory."); + return; + } + _player_send_cmd(ev, EM_CMD_FILE_SET_DONE); +} + +static void +_player_ready(Emotion_Generic_Video *ev) +{ + INF("received: player ready."); + + ev->initializing = EINA_FALSE; + ev->ready = EINA_TRUE; + + if (!ev->filename) + return; + + _file_open(ev); +} + +static Eina_Bool +_player_cmd_param_read(Emotion_Generic_Video *ev, void *param, size_t size) +{ + ssize_t done, todo, i; + + /* When a parameter must be read, we cannot make sure it will be entirely + * available. Thus we store the bytes that could be read in a temp buffer, + * and when more data is read we try to complete the buffer and finally use + * the read value. + */ + if (!ev->cmd.tmp) + { + ev->cmd.tmp = malloc(size); + ev->cmd.i = 0; + ev->cmd.total = size; + } + + todo = ev->cmd.total - ev->cmd.i; + i = ev->cmd.i; + done = read(ev->fd_read, &ev->cmd.tmp[i], todo); + + if (done < 0 && errno != EINTR && errno != EAGAIN) + { + if (ev->cmd.tmp) + { + free(ev->cmd.tmp); + ev->cmd.tmp = NULL; + } + ERR("problem when reading parameter from pipe."); + ev->cmd.type = -1; + return EINA_FALSE; + } + + if (done == todo) + { + memcpy(param, ev->cmd.tmp, size); + free(ev->cmd.tmp); + ev->cmd.tmp = NULL; + return EINA_TRUE; + } + + if (done > 0) + ev->cmd.i += done; + + return EINA_FALSE; +} + +static void +_player_frame_resize(Emotion_Generic_Video *ev) +{ + int w, h; + + w = ev->cmd.param.size.width; + h = ev->cmd.param.size.height; + + INF("received frame resize: %dx%d", w, h); + ev->w = w; + ev->h = h; + ev->ratio = (float)w / h; + + if (ev->opening) + return; + + _emotion_frame_resize(ev->obj, ev->w, ev->h, ev->ratio); +} + +static void +_player_length_changed(Emotion_Generic_Video *ev) +{ + float length = ev->cmd.param.f_num; + + INF("received length changed: %0.3f", length); + + ev->len = length; + _emotion_video_pos_update(ev->obj, ev->pos, ev->len); +} + +static void +_player_position_changed(Emotion_Generic_Video *ev) +{ + float position = ev->cmd.param.f_num; + + INF("received position changed: %0.3f", position); + + ev->pos = position; + _emotion_video_pos_update(ev->obj, ev->pos, ev->len); +/* hmmm. no _emotion_progress_set() is for "buffering" progress. + if (ev->len == 0) + return; + + float progress = ev->pos / ev->len; + char buf[16]; + snprintf(buf, sizeof(buf), "%0.1f%%", progress * 100); + + _emotion_progress_set(ev->obj, buf, progress); + */ +} + +static void +_player_seekable_changed(Emotion_Generic_Video *ev) +{ + int seekable = ev->cmd.param.i_num; + + INF("received seekable changed: %d", seekable); + + seekable = !!seekable; + + ev->seekable = seekable; +} + +static void +_audio_channels_free(Emotion_Generic_Video *ev) +{ + int i; + for (i = 0; i < ev->audio_channels_count; i++) + eina_stringshare_del(ev->audio_channels[i].name); + free(ev->audio_channels); + ev->audio_channels = NULL; + ev->audio_channels_count = 0; +} + +static void +_video_channels_free(Emotion_Generic_Video *ev) +{ + int i; + for (i = 0; i < ev->video_channels_count; i++) + eina_stringshare_del(ev->video_channels[i].name); + free(ev->video_channels); + ev->video_channels = NULL; + ev->video_channels_count = 0; +} + +static void +_spu_channels_free(Emotion_Generic_Video *ev) +{ + int i; + for (i = 0; i < ev->spu_channels_count; i++) + eina_stringshare_del(ev->spu_channels[i].name); + free(ev->spu_channels); + ev->spu_channels = NULL; + ev->spu_channels_count = 0; +} + +static void +_player_tracks_info(Emotion_Generic_Video *ev, Emotion_Generic_Channel **channels, int *count, int *current) +{ + Emotion_Generic_Channel *pchannels; + int i; + + *count = ev->cmd.param.track.total; + *current = ev->cmd.param.track.current; + pchannels = ev->cmd.param.track.channels; + + INF("number of tracks: %d (current = %d):", *count, *current); + for (i = 0; i < *count; i++) + { + INF("\tchannel %d: %s", pchannels[i].id, pchannels[i].name); + } + + *channels = pchannels; +} + +static void +_player_audio_tracks_info(Emotion_Generic_Video *ev) +{ + INF("Receiving audio channels:"); + if (ev->audio_channels_count) + _audio_channels_free(ev); + + _player_tracks_info(ev, &ev->audio_channels, &ev->audio_channels_count, + &ev->audio_channel_current); +} + +static void +_player_video_tracks_info(Emotion_Generic_Video *ev) +{ + INF("Receiving video channels:"); + if (ev->video_channels_count) + _video_channels_free(ev); + + _player_tracks_info(ev, &ev->video_channels, &ev->video_channels_count, + &ev->video_channel_current); +} + +static void +_player_spu_tracks_info(Emotion_Generic_Video *ev) +{ + INF("Receiving spu channels:"); + if (ev->spu_channels_count) + _spu_channels_free(ev); + + _player_tracks_info(ev, &ev->spu_channels, &ev->spu_channels_count, + &ev->spu_channel_current); +} + +static void +_player_meta_info_free(Emotion_Generic_Video *ev) +{ + eina_stringshare_replace(&ev->meta.title, NULL); + eina_stringshare_replace(&ev->meta.artist, NULL); + eina_stringshare_replace(&ev->meta.album, NULL); + eina_stringshare_replace(&ev->meta.year, NULL); + eina_stringshare_replace(&ev->meta.genre, NULL); + eina_stringshare_replace(&ev->meta.comment, NULL); + eina_stringshare_replace(&ev->meta.disc_id, NULL); + eina_stringshare_replace(&ev->meta.count, NULL); +} + +static void +_player_meta_info_read(Emotion_Generic_Video *ev) +{ + INF("Receiving meta info:"); + _player_meta_info_free(ev); + ev->meta.title = ev->cmd.param.meta.title; + ev->meta.artist = ev->cmd.param.meta.artist; + ev->meta.album = ev->cmd.param.meta.album; + ev->meta.year = ev->cmd.param.meta.year; + ev->meta.genre = ev->cmd.param.meta.genre; + ev->meta.comment = ev->cmd.param.meta.comment; + ev->meta.disc_id = ev->cmd.param.meta.disc_id; + ev->meta.count = ev->cmd.param.meta.count; + INF("title: '%s'", ev->meta.title); + INF("artist: '%s'", ev->meta.artist); + INF("album: '%s'", ev->meta.album); + INF("year: '%s'", ev->meta.year); + INF("genre: '%s'", ev->meta.genre); + INF("comment: '%s'", ev->meta.comment); + INF("disc_id: '%s'", ev->meta.disc_id); + INF("count: '%s'", ev->meta.count); +} + +static void +_player_file_closed(Emotion_Generic_Video *ev) +{ + INF("Closed previous file."); + eina_semaphore_free(&ev->shared->lock); + ev->closing = EINA_FALSE; + + if (ev->opening) + _file_open(ev); +} + +static void +_player_open_done(Emotion_Generic_Video *ev) +{ + int success; + + success = ev->cmd.param.i_num; + shm_unlink(ev->shmname); + + if (ev->file_changed) + { + _file_open(ev); + ev->file_changed = EINA_FALSE; + return; + } + + ev->opening = EINA_FALSE; + if (!success) + { + ERR("Could not open file."); + return; + } + + ev->file_ready = EINA_TRUE; + + _emotion_open_done(ev->obj); + + if (ev->play) + { + _player_send_cmd(ev, EM_CMD_PLAY); + _player_send_float(ev, ev->pos); + } + + _player_send_cmd(ev, EM_CMD_VOLUME_SET); + _player_send_float(ev, ev->volume); + + _player_send_cmd(ev, EM_CMD_SPEED_SET); + _player_send_float(ev, ev->speed); + + int mute = ev->audio_mute; + _player_send_cmd(ev, EM_CMD_AUDIO_MUTE_SET); + _player_send_int(ev, mute); + + mute = ev->video_mute; + _player_send_cmd(ev, EM_CMD_VIDEO_MUTE_SET); + _player_send_int(ev, mute); + + mute = ev->spu_mute; + _player_send_cmd(ev, EM_CMD_SPU_MUTE_SET); + _player_send_int(ev, mute); + + INF("Open done"); +} + +static void +_player_cmd_process(Emotion_Generic_Video *ev) +{ + switch (ev->cmd.type) { + case EM_RESULT_INIT: + _player_ready(ev); + break; + case EM_RESULT_FRAME_NEW: + _player_new_frame(ev); + break; + case EM_RESULT_FILE_SET: + _player_file_set_done(ev); + break; + case EM_RESULT_FILE_SET_DONE: + _player_open_done(ev); + break; + case EM_RESULT_FILE_CLOSE: + _player_file_closed(ev); + break; + case EM_RESULT_PLAYBACK_STARTED: + _emotion_playback_started(ev->obj); + break; + case EM_RESULT_PLAYBACK_STOPPED: + ev->pos = 0; + _emotion_playback_finished(ev->obj); + _emotion_decode_stop(ev->obj); + + em_partial_shutdown(ev); + ev->player_restart = ecore_idler_add(_player_restart, ev); + break; + case EM_RESULT_FRAME_SIZE: + _player_frame_resize(ev); + break; + case EM_RESULT_LENGTH_CHANGED: + _player_length_changed(ev); + break; + case EM_RESULT_POSITION_CHANGED: + _player_position_changed(ev); + break; + case EM_RESULT_SEEKABLE_CHANGED: + _player_seekable_changed(ev); + break; + case EM_RESULT_AUDIO_TRACK_INFO: + _player_audio_tracks_info(ev); + break; + case EM_RESULT_VIDEO_TRACK_INFO: + _player_video_tracks_info(ev); + break; + case EM_RESULT_SPU_TRACK_INFO: + _player_spu_tracks_info(ev); + break; + case EM_RESULT_META_INFO: + _player_meta_info_read(ev); + break; + default: + WRN("received wrong command: %d", ev->cmd.type); + } + + ev->cmd.type = -1; +} + +static void +_player_cmd_single_int_process(Emotion_Generic_Video *ev) +{ + if (!_player_cmd_param_read(ev, &ev->cmd.param.i_num, sizeof(ev->cmd.param.i_num))) + return; + + _player_cmd_process(ev); +} + +static void +_player_cmd_single_float_process(Emotion_Generic_Video *ev) +{ + if (!_player_cmd_param_read(ev, &ev->cmd.param.f_num, sizeof(ev->cmd.param.f_num))) + return; + + _player_cmd_process(ev); +} + +static void +_player_cmd_double_int_process(Emotion_Generic_Video *ev) +{ + int param; + + if (ev->cmd.num_params == 0) + { + ev->cmd.num_params = 2; + ev->cmd.cur_param = 0; + ev->cmd.param.size.width = 0; + ev->cmd.param.size.height = 0; + } + + if (!_player_cmd_param_read(ev, ¶m, sizeof(param))) + return; + + if (ev->cmd.cur_param == 0) + ev->cmd.param.size.width = param; + else + ev->cmd.param.size.height = param; + + ev->cmd.cur_param++; + if (ev->cmd.cur_param == ev->cmd.num_params) + _player_cmd_process(ev); +} + +static void +_player_cmd_track_info(Emotion_Generic_Video *ev) +{ + int param; + int i; + + if (ev->cmd.num_params == 0) + { + ev->cmd.cur_param = 0; + ev->cmd.num_params = 2; + ev->cmd.param.track.channels = NULL; + ev->cmd.s_len = -1; + } + + while (ev->cmd.cur_param < 2) + { + if (!_player_cmd_param_read(ev, ¶m, sizeof(param))) + return; + + if (ev->cmd.cur_param == 0) + ev->cmd.param.track.current = param; + else + { + ev->cmd.param.track.total = param; + ev->cmd.num_params += param * 2; + ev->cmd.param.track.channels = + calloc(param, sizeof(*ev->cmd.param.track.channels)); + } + ev->cmd.cur_param++; + } + + if (ev->cmd.cur_param == ev->cmd.num_params) + { + _player_cmd_process(ev); + return; + } + + i = (ev->cmd.cur_param - 2) / 2; + if ((ev->cmd.cur_param % 2) == 0) // reading track id + { + if (!_player_cmd_param_read(ev, ¶m, sizeof(param))) + return; + ev->cmd.param.track.channels[i].id = param; + ev->cmd.cur_param++; + } + else // reading track name + { + char buf[PATH_MAX]; + + if (ev->cmd.s_len == -1) + { + if (!_player_cmd_param_read(ev, ¶m, sizeof(param))) + return; + ev->cmd.s_len = param; + } + + if (!_player_cmd_param_read(ev, buf, ev->cmd.s_len)) + return; + ev->cmd.param.track.channels[i].name = + eina_stringshare_add_length(buf, ev->cmd.s_len); + ev->cmd.cur_param++; + ev->cmd.s_len = -1; + } + + if (ev->cmd.cur_param == ev->cmd.num_params) + _player_cmd_process(ev); +} + +static void +_player_cmd_meta_info(Emotion_Generic_Video *ev) +{ + int param; + const char *info; + char buf[PATH_MAX]; + + if (ev->cmd.num_params == 0) + { + ev->cmd.cur_param = 0; + ev->cmd.num_params = 8; + ev->cmd.param.meta.title = NULL; + ev->cmd.param.meta.artist = NULL; + ev->cmd.param.meta.album = NULL; + ev->cmd.param.meta.year = NULL; + ev->cmd.param.meta.genre = NULL; + ev->cmd.param.meta.comment = NULL; + ev->cmd.param.meta.disc_id = NULL; + ev->cmd.param.meta.count = NULL; + ev->cmd.s_len = -1; + } + + if (ev->cmd.s_len == -1) + { + if (!_player_cmd_param_read(ev, ¶m, sizeof(param))) + return; + ev->cmd.s_len = param; + } + + if (!_player_cmd_param_read(ev, buf, ev->cmd.s_len)) + return; + + info = eina_stringshare_add_length(buf, ev->cmd.s_len); + ev->cmd.s_len = -1; + + if (ev->cmd.cur_param == 0) + ev->cmd.param.meta.title = info; + else if (ev->cmd.cur_param == 1) + ev->cmd.param.meta.artist = info; + else if (ev->cmd.cur_param == 2) + ev->cmd.param.meta.album = info; + else if (ev->cmd.cur_param == 3) + ev->cmd.param.meta.year = info; + else if (ev->cmd.cur_param == 4) + ev->cmd.param.meta.genre = info; + else if (ev->cmd.cur_param == 5) + ev->cmd.param.meta.comment = info; + else if (ev->cmd.cur_param == 6) + ev->cmd.param.meta.disc_id = info; + else if (ev->cmd.cur_param == 7) + ev->cmd.param.meta.count = info; + + ev->cmd.cur_param++; + + if (ev->cmd.cur_param == 8) + _player_cmd_process(ev); +} + +static void +_player_cmd_read(Emotion_Generic_Video *ev) +{ + if (ev->cmd.type < 0) + { + if (!_player_cmd_param_read(ev, &ev->cmd.type, sizeof(ev->cmd.type))) + return; + ev->cmd.num_params = 0; + } + + switch (ev->cmd.type) { + case EM_RESULT_INIT: + case EM_RESULT_FILE_SET: + case EM_RESULT_PLAYBACK_STARTED: + case EM_RESULT_PLAYBACK_STOPPED: + case EM_RESULT_FILE_CLOSE: + case EM_RESULT_FRAME_NEW: + _player_cmd_process(ev); + break; + case EM_RESULT_FILE_SET_DONE: + case EM_RESULT_SEEKABLE_CHANGED: + _player_cmd_single_int_process(ev); + break; + case EM_RESULT_LENGTH_CHANGED: + case EM_RESULT_POSITION_CHANGED: + _player_cmd_single_float_process(ev); + break; + case EM_RESULT_FRAME_SIZE: + _player_cmd_double_int_process(ev); + break; + case EM_RESULT_AUDIO_TRACK_INFO: + case EM_RESULT_VIDEO_TRACK_INFO: + case EM_RESULT_SPU_TRACK_INFO: + _player_cmd_track_info(ev); + break; + case EM_RESULT_META_INFO: + _player_cmd_meta_info(ev); + break; + + default: + WRN("received wrong command: %d", ev->cmd.type); + ev->cmd.type = -1; + } +} + +static Eina_Bool +_player_cmd_handler_cb(void *data, Ecore_Fd_Handler *fd_handler) +{ + Emotion_Generic_Video *ev = data; + + if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR)) + { + ERR("an error occurred on fd_read %d.", ev->fd_read); + return ECORE_CALLBACK_CANCEL; + } + + _player_cmd_read(ev); + + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool +_player_data_cb(void *data, int type __UNUSED__, void *event) +{ + Ecore_Exe_Event_Data *ev = event; + Emotion_Generic_Video *evideo = data; + int i; + + if (ev->exe != evideo->player.exe) + { + INF("slave != ev->exe"); + return ECORE_CALLBACK_PASS_ON; + } + + for (i = 0; ev->lines[i].line; i++) + INF("received input from player: \"%s\"", ev->lines[i].line); + + return ECORE_CALLBACK_DONE; +} + +static Eina_Bool +_player_add_cb(void *data, int type __UNUSED__, void *event) +{ + Ecore_Exe_Event_Add *event_add = event; + Ecore_Exe *player = event_add->exe; + Emotion_Generic_Video *ev = data; + + if (ev->player.exe != player) + { + INF("ev->player != player."); + return ECORE_CALLBACK_PASS_ON; + } + + _player_send_cmd(ev, EM_CMD_INIT); + _player_send_str(ev, ev->shmname, EINA_TRUE); + + return ECORE_CALLBACK_DONE; +} + +static Eina_Bool +_player_del_cb(void *data, int type __UNUSED__, void *event __UNUSED__) +{ + Ecore_Exe_Event_Del *event_del = event; + Ecore_Exe *player = event_del->exe; + Emotion_Generic_Video *ev = data; + + if (ev->player.exe != player) + { + INF("ev->player != player."); + return ECORE_CALLBACK_PASS_ON; + } + + ERR("player died."); + + ev->player.exe = NULL; + ev->ready = EINA_FALSE; + ev->file_ready = EINA_FALSE; + ecore_main_fd_handler_del(ev->fd_handler); + close(ev->fd_read); + close(ev->fd_write); + ev->fd_read = -1; + ev->fd_write = -1; + _emotion_decode_stop(ev->obj); + + return ECORE_CALLBACK_DONE; +} + +static Eina_Bool +_player_exec(Emotion_Generic_Video *ev) +{ + int pipe_out[2]; + int pipe_in[2]; + char buf[PATH_MAX]; + + if (pipe(pipe_out) == -1) + { + ERR("could not create pipe for communication emotion -> player: %s", strerror(errno)); + return EINA_FALSE; + } + + if (pipe(pipe_in) == -1) + { + ERR("could not create pipe for communication player -> emotion: %s", strerror(errno)); + close(pipe_out[0]); + close(pipe_out[1]); + return EINA_FALSE; + } + + snprintf(buf, sizeof(buf), "%s %d %d\n", ev->cmdline, pipe_out[0], pipe_in[1]); + + ev->player.exe = ecore_exe_pipe_run( + buf, + ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_WRITE | + ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_NOT_LEADER, + ev); + + INF("created pipe emotion -> player: %d -> %d", pipe_out[1], pipe_out[0]); + INF("created pipe player -> emotion: %d -> %d", pipe_in[1], pipe_in[0]); + + close(pipe_in[1]); + close(pipe_out[0]); + + if (!ev->player.exe) + { + close(pipe_in[0]); + close(pipe_out[1]); + return EINA_FALSE; + } + + ev->fd_read = pipe_in[0]; + ev->fd_write = pipe_out[1]; + + ev->fd_handler = ecore_main_fd_handler_add( + ev->fd_read, ECORE_FD_READ | ECORE_FD_ERROR, _player_cmd_handler_cb, ev, + NULL, NULL); + + return EINA_TRUE; +} + +static Eina_Bool +_fork_and_exec(Emotion_Generic_Video *ev) +{ + char shmname[256]; + struct timeval tv; + + gettimeofday(&tv, NULL); + snprintf(shmname, sizeof(shmname), "/em-generic-shm_%d_%d", + (int)tv.tv_sec, (int)tv.tv_usec); + + ev->shmname = eina_stringshare_add(shmname); + + ev->player_add = ecore_event_handler_add( + ECORE_EXE_EVENT_ADD, _player_add_cb, ev); + ev->player_del = ecore_event_handler_add( + ECORE_EXE_EVENT_DEL, _player_del_cb, ev); + ev->player_data = ecore_event_handler_add( + ECORE_EXE_EVENT_DATA, _player_data_cb, ev); + + if (!_player_exec(ev)) + { + ERR("could not start player."); + return EINA_FALSE; + } + + ev->initializing = EINA_TRUE; + + return EINA_TRUE; +} + +static unsigned char +em_init(Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt) +{ + Emotion_Generic_Video *ev; + const char *player; + + if (!emotion_video) return 0; + player = _get_player(opt ? opt->player : NULL); + if (!player) return 0; + + ev = (Emotion_Generic_Video *)calloc(1, sizeof(*ev)); + if (!ev) return 0; + + ev->fd_read = -1; + ev->fd_write = -1; + ev->speed = 1.0; + ev->volume = 0.5; + ev->audio_mute = EINA_FALSE; + ev->cmd.type = -1; + + ev->obj = obj; + ev->cmdline = eina_stringshare_add(player); + *emotion_video = ev; + + return _fork_and_exec(ev); +} + +static void +em_partial_shutdown(Emotion_Generic_Video *ev) +{ + _emotion_image_reset(ev->obj); + + if (ev->player.exe) + { + ecore_exe_terminate(ev->player.exe); + ecore_exe_free(ev->player.exe); + ev->player.exe = NULL; + } + + if (ev->shared) + munmap(ev->shared, ev->shared->size); + ev->shared = NULL; + + if (ev->fd_read >= 0) + close(ev->fd_read); + ev->fd_read = -1; + if (ev->fd_write >= 0) + close(ev->fd_write); + ev->fd_write = -1; + if (ev->fd_handler) + ecore_main_fd_handler_del(ev->fd_handler); + ev->fd_handler = NULL; + + if (ev->player_add) ecore_event_handler_del(ev->player_add); + ev->player_add = NULL; + if (ev->player_data) ecore_event_handler_del(ev->player_data); + ev->player_data = NULL; + if (ev->player_del) ecore_event_handler_del(ev->player_del); + ev->player_del = NULL; + if (ev->player_restart) ecore_idler_del(ev->player_restart); + ev->player_restart = NULL; +} + +static int +em_shutdown(void *data) +{ + Emotion_Generic_Video *ev = data; + + if (!ev) return 0; + + eina_stringshare_del(ev->cmdline); + eina_stringshare_del(ev->shmname); + + em_partial_shutdown(ev); + + return 1; +} + +static unsigned char +em_file_open(const char *file, Evas_Object *obj __UNUSED__, void *data) +{ + Emotion_Generic_Video *ev = data; + INF("file set: %s", file); + if (!ev) return 0; + + eina_stringshare_replace(&ev->filename, file); + + ev->pos = 0; + ev->w = 0; + ev->h = 0; + ev->ratio = 1; + ev->len = 0; + + if (ev->ready && ev->opening) + { + INF("file changed while opening."); + ev->file_changed = EINA_TRUE; + return 1; + } + + ev->opening = EINA_TRUE; + + if (!ev->closing) + _file_open(ev); + + return 1; +} + +static void +em_file_close(void *data) +{ + Emotion_Generic_Video *ev = data; + + if (!ev || !ev->filename) return; + + INF("file close: %s", ev->filename); + + eina_stringshare_replace(&ev->filename, NULL); + + ev->file_ready = EINA_FALSE; + _audio_channels_free(ev); + _video_channels_free(ev); + _spu_channels_free(ev); + _player_meta_info_free(ev); + + if (ev->opening) + return; + + _player_send_cmd(ev, EM_CMD_FILE_CLOSE); + ev->closing = EINA_TRUE; +} + +static Emotion_Format +em_format_get(void *ef __UNUSED__) +{ + return EMOTION_FORMAT_BGRA; +} + +static void +em_video_data_size_get(void *data, int *w, int *h) +{ + Emotion_Generic_Video *ev = data; + + if (!ev) return; + if (w) *w = ev->w; + if (h) *h = ev->h; +} + +static void +em_play(void *data, double pos) +{ + Emotion_Generic_Video *ev = data; + + if (!ev) + return; + + ev->play = EINA_TRUE; + INF("play: %0.3f", pos); + + if (ev->initializing || ev->opening) + return; + + if (ev->ready) + { + _player_send_cmd(ev, EM_CMD_PLAY); + _player_send_float(ev, ev->pos); + return; + } + + if (!_player_exec(ev)) + ERR("could not start player."); +} + +static void +em_stop(void *data) +{ + Emotion_Generic_Video *ev = data; + + if (!ev) + return; + + ev->play = EINA_FALSE; + + if (!ev->file_ready) + return; + + _player_send_cmd(ev, EM_CMD_STOP); + _emotion_decode_stop(ev->obj); +} + +static void +em_size_get(void *data, int *w, int *h) +{ + Emotion_Generic_Video *ev = data; + if (w) *w = ev->w; + if (h) *h = ev->h; +} + +static void +em_pos_set(void *data, double pos) +{ + Emotion_Generic_Video *ev = data; + float position = pos; + + if (!ev->file_ready) + return; + + _player_send_cmd(ev, EM_CMD_POSITION_SET); + _player_send_float(ev, position); + _emotion_seek_done(ev->obj); +} + +static double +em_len_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->len; +} + +static double +em_buffer_size_get(void *data __UNUSED__) +{ + return 1.0; +} + +static int +em_fps_num_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return (int)(ev->fps * 1000.0); +} + +static int +em_fps_den_get(void *ef __UNUSED__) +{ + return 1000; +} + +static double +em_fps_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->fps; +} + +static double +em_pos_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->pos; +} + +static void +em_vis_set(void *ef __UNUSED__, Emotion_Vis vis __UNUSED__) +{ +} + +static Emotion_Vis +em_vis_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->vis; +} + +static Eina_Bool +em_vis_supported(void *ef __UNUSED__, Emotion_Vis vis __UNUSED__) +{ + return EINA_FALSE; +} + +static double +em_ratio_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->ratio; +} + +static int em_video_handled(void *ef __UNUSED__) +{ + fprintf(stderr, "video handled!\n"); + return 1; +} + +static int em_audio_handled(void *ef __UNUSED__) +{ + fprintf(stderr, "audio handled!\n"); + return 1; +} + +static int em_seekable(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->seekable; +} + +static void em_frame_done(void *ef __UNUSED__) +{ +} + +static int +em_yuv_rows_get(void *data __UNUSED__, int w __UNUSED__, int h __UNUSED__, unsigned char **yrows __UNUSED__, unsigned char **urows __UNUSED__, unsigned char **vrows __UNUSED__) +{ + return 0; +} + +static int +em_bgra_data_get(void *data, unsigned char **bgra_data) +{ + Emotion_Generic_Video *ev = data; + + if (!ev || !ev->file_ready) + return 0; + + // lock frame here + if (!eina_semaphore_lock(&ev->shared->lock)) + return 0; + + // send current frame to emotion + if (ev->shared->frame.emotion != ev->shared->frame.last) + { + ev->shared->frame.next = ev->shared->frame.emotion; + ev->shared->frame.emotion = ev->shared->frame.last; + } + *bgra_data = ev->frame.frames[ev->shared->frame.emotion]; + + if (ev->shared->frame_drop > 1) + WRN("dropped frames: %d", ev->shared->frame_drop - 1); + ev->shared->frame_drop = 0; + + // unlock frame here + eina_semaphore_release(&ev->shared->lock, 1); + ev->drop = 0; + + return 1; +} + +static void +em_event_feed(void *ef __UNUSED__, int event __UNUSED__) +{ +} + +static void +em_event_mouse_button_feed(void *ef __UNUSED__, int button __UNUSED__, int x __UNUSED__, int y __UNUSED__) +{ +} + +static void +em_event_mouse_move_feed(void *ef __UNUSED__, int x __UNUSED__, int y __UNUSED__) +{ +} + +static int +em_video_channel_count(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->video_channels_count; +} + +static void +em_video_channel_set(void *data, int channel) +{ + Emotion_Generic_Video *ev = data; + + if (channel < 0 || channel >= ev->video_channels_count) + { + WRN("video channel out of range."); + return; + } + + _player_send_cmd(ev, EM_CMD_VIDEO_TRACK_SET); + _player_send_int(ev, ev->video_channels[channel].id); + ev->video_channel_current = channel; +} + +static int +em_video_channel_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->video_channel_current; +} + +static const char * +em_video_channel_name_get(void *data, int channel) +{ + Emotion_Generic_Video *ev = data; + + if (channel < 0 || channel >= ev->video_channels_count) + { + WRN("video channel out of range."); + return NULL; + } + + return ev->video_channels[channel].name; +} + +static void +em_video_channel_mute_set(void *data, int mute) +{ + Emotion_Generic_Video *ev = data; + + ev->video_mute = !!mute; + + if (!ev || !ev->file_ready) + return; + + _player_send_cmd(ev, EM_CMD_VIDEO_MUTE_SET); + _player_send_int(ev, mute); +} + +static int +em_video_channel_mute_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->video_mute; +} + +static int +em_audio_channel_count(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->audio_channels_count; +} + +static void +em_audio_channel_set(void *data, int channel) +{ + Emotion_Generic_Video *ev = data; + + if (channel < 0 || channel >= ev->audio_channels_count) + { + WRN("audio channel out of range."); + return; + } + + _player_send_cmd(ev, EM_CMD_AUDIO_TRACK_SET); + _player_send_int(ev, ev->audio_channels[channel].id); + ev->audio_channel_current = channel; +} + +static int +em_audio_channel_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->audio_channel_current; +} + +static const char * +em_audio_channel_name_get(void *data, int channel) +{ + Emotion_Generic_Video *ev = data; + + if (channel < 0 || channel >= ev->audio_channels_count) + { + WRN("audio channel out of range."); + return NULL; + } + + return ev->audio_channels[channel].name; +} + +static void +em_audio_channel_mute_set(void *data, int mute) +{ + Emotion_Generic_Video *ev = data; + + ev->audio_mute = !!mute; + + if (!ev || !ev->file_ready) + return; + + _player_send_cmd(ev, EM_CMD_AUDIO_MUTE_SET); + _player_send_int(ev, mute); +} + +static int +em_audio_channel_mute_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->audio_mute; +} + +static void +em_audio_channel_volume_set(void *data, double vol) +{ + Emotion_Generic_Video *ev = data; + + if (vol > 1.0) vol = 1.0; + if (vol < 0.0) vol = 0.0; + + ev->volume = vol; + + if (!ev || !ev->file_ready) + return; + + _player_send_cmd(ev, EM_CMD_VOLUME_SET); + _player_send_float(ev, ev->volume); +} + +static double +em_audio_channel_volume_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->volume; +} + +static int +em_spu_channel_count(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->spu_channels_count; +} + +static void +em_spu_channel_set(void *data, int channel) +{ + Emotion_Generic_Video *ev = data; + + if (channel < 0 || channel >= ev->spu_channels_count) + { + WRN("spu channel out of range."); + return; + } + + _player_send_cmd(ev, EM_CMD_SPU_TRACK_SET); + _player_send_int(ev, ev->spu_channels[channel].id); + ev->spu_channel_current = channel; +} + +static int +em_spu_channel_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->spu_channel_current; +} + +static const char * +em_spu_channel_name_get(void *data, int channel) +{ + Emotion_Generic_Video *ev = data; + + if (channel < 0 || channel >= ev->spu_channels_count) + { + WRN("spu channel out of range."); + return NULL; + } + + return ev->spu_channels[channel].name; +} + +static void +em_spu_channel_mute_set(void *data, int mute) +{ + Emotion_Generic_Video *ev = data; + + ev->spu_mute = !!mute; + + if (!ev || !ev->file_ready) + return; + + _player_send_cmd(ev, EM_CMD_SPU_MUTE_SET); + _player_send_int(ev, mute); +} + +static int +em_spu_channel_mute_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->spu_mute; +} + +static int +em_chapter_count(void *ef __UNUSED__) +{ + int num = 0; + return num; +} + +static void +em_chapter_set(void *ef __UNUSED__, int chapter __UNUSED__) +{ +} + +static int +em_chapter_get(void *ef __UNUSED__) +{ + int num = 0; + return num; +} + +static const char * +em_chapter_name_get(void *ef __UNUSED__, int chapter __UNUSED__) +{ + return NULL; +} + +static void +em_speed_set(void *data, double speed) +{ + Emotion_Generic_Video *ev = data; + float rate = speed; + ev->speed = rate; + + if (!ev || !ev->file_ready) + return; + + _player_send_cmd(ev, EM_CMD_SPEED_SET); + _player_send_float(ev, rate); +} + +static double +em_speed_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return (double)ev->speed; +} + +static int +em_eject(void *ef __UNUSED__) +{ + return 1; +} + +static const char * +em_meta_get(void *data, int meta) +{ + Emotion_Generic_Video *ev = data; + + switch (meta) { + case EMOTION_META_INFO_TRACK_TITLE: + return ev->meta.title; + case EMOTION_META_INFO_TRACK_ARTIST: + return ev->meta.artist; + case EMOTION_META_INFO_TRACK_ALBUM: + return ev->meta.album; + case EMOTION_META_INFO_TRACK_YEAR: + return ev->meta.year; + case EMOTION_META_INFO_TRACK_GENRE: + return ev->meta.genre; + case EMOTION_META_INFO_TRACK_COMMENT: + return ev->meta.comment; + case EMOTION_META_INFO_TRACK_DISC_ID: + return ev->meta.disc_id; + case EMOTION_META_INFO_TRACK_COUNT: + return ev->meta.count; + } + + return NULL; +} + +static Emotion_Video_Module em_module = +{ + em_init, /* init */ + em_shutdown, /* shutdown */ + em_file_open, /* file_open */ + em_file_close, /* file_close */ + em_play, /* play */ + em_stop, /* stop */ + em_size_get, /* size_get */ + em_pos_set, /* pos_set */ + em_len_get, /* len_get */ + em_buffer_size_get, /* buffer_size_get */ + em_fps_num_get, /* fps_num_get */ + em_fps_den_get, /* fps_den_get */ + em_fps_get, /* fps_get */ + em_pos_get, /* pos_get */ + em_vis_set, /* vis_set */ + em_vis_get, /* vis_get */ + em_vis_supported, /* vis_supported */ + em_ratio_get, /* ratio_get */ + em_video_handled, /* video_handled */ + em_audio_handled, /* audio_handled */ + em_seekable, /* seekable */ + em_frame_done, /* frame_done */ + em_format_get, /* format_get */ + em_video_data_size_get, /* video_data_size_get */ + em_yuv_rows_get, /* yuv_rows_get */ + em_bgra_data_get, /* bgra_data_get */ + em_event_feed, /* event_feed */ + em_event_mouse_button_feed, /* event_mouse_button_feed */ + em_event_mouse_move_feed, /* event_mouse_move_feed */ + em_video_channel_count, /* video_channel_count */ + em_video_channel_set, /* video_channel_set */ + em_video_channel_get, /* video_channel_get */ + em_video_channel_name_get, /* video_channel_name_get */ + em_video_channel_mute_set, /* video_channel_mute_set */ + em_video_channel_mute_get, /* video_channel_mute_get */ + em_audio_channel_count, /* audio_channel_count */ + em_audio_channel_set, /* audio_channel_set */ + em_audio_channel_get, /* audio_channel_get */ + em_audio_channel_name_get, /* audio_channel_name_get */ + em_audio_channel_mute_set, /* audio_channel_mute_set */ + em_audio_channel_mute_get, /* audio_channel_mute_get */ + em_audio_channel_volume_set, /* audio_channel_volume_set */ + em_audio_channel_volume_get, /* audio_channel_volume_get */ + em_spu_channel_count, /* spu_channel_count */ + em_spu_channel_set, /* spu_channel_set */ + em_spu_channel_get, /* spu_channel_get */ + em_spu_channel_name_get, /* spu_channel_name_get */ + em_spu_channel_mute_set, /* spu_channel_mute_set */ + em_spu_channel_mute_get, /* spu_channel_mute_get */ + em_chapter_count, /* chapter_count */ + em_chapter_set, /* chapter_set */ + em_chapter_get, /* chapter_get */ + em_chapter_name_get, /* chapter_name_get */ + em_speed_set, /* speed_set */ + em_speed_get, /* speed_get */ + em_eject, /* eject */ + em_meta_get, /* meta_get */ + NULL, /* priority_set */ + NULL, /* priority_get */ + NULL /* handle */ +}; + +static Eina_Bool +module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt) +{ + if (!module) { + return EINA_FALSE; + } + + if (_emotion_generic_log_domain < 0) + { + eina_threads_init(); + eina_log_threads_enable(); + _emotion_generic_log_domain = eina_log_domain_register + ("emotion-generic", EINA_COLOR_LIGHTCYAN); + if (_emotion_generic_log_domain < 0) + { + EINA_LOG_CRIT("Could not register log domain 'emotion-generic'"); + return EINA_FALSE; + } + } + + + if (!em_module.init(obj, video, opt)) { + return EINA_FALSE; + } + + *module = &em_module; + + return EINA_TRUE; +} + +static void module_close(Emotion_Video_Module *module __UNUSED__, void *video) +{ + em_module.shutdown(video); +} + + +Eina_Bool +generic_module_init(void) +{ + if (!pfx) + { + pfx = eina_prefix_new(NULL, emotion_object_add, + "EMOTION", "emotion", NULL, + PACKAGE_BIN_DIR, + PACKAGE_LIB_DIR, + PACKAGE_DATA_DIR, + ""); + if (!pfx) return EINA_FALSE; + } + return _emotion_module_register("generic", module_open, module_close); +} + +static void +generic_module_shutdown(void) +{ + if (pfx) + { + eina_prefix_free(pfx); + pfx = NULL; + } + _emotion_module_unregister("generic"); +} + +#ifndef EMOTION_STATIC_BUILD_GENERIC + +EINA_MODULE_INIT(generic_module_init); +EINA_MODULE_SHUTDOWN(generic_module_shutdown); + +#endif + diff --git a/src/modules/generic/emotion_generic.h b/src/modules/generic/emotion_generic.h new file mode 100644 index 0000000..ed3bdb0 --- /dev/null +++ b/src/modules/generic/emotion_generic.h @@ -0,0 +1,112 @@ +#ifndef EMOTION_GENERIC_H +#define EMOTION_GENERIC_H + +#include "Emotion_Generic_Plugin.h" + +/* default values */ + +typedef struct _Emotion_Generic_Video Emotion_Generic_Video; +typedef struct _Emotion_Generic_Player Emotion_Generic_Player; +typedef struct _Emotion_Generic_Cmd_Buffer Emotion_Generic_Cmd_Buffer; +typedef struct _Emotion_Generic_Channel Emotion_Generic_Channel; +typedef struct _Emotion_Generic_Meta Emotion_Generic_Meta; + +struct _Emotion_Generic_Player +{ + Ecore_Exe *exe; +}; + +struct _Emotion_Generic_Channel +{ + int id; + const char *name; +}; + +struct _Emotion_Generic_Meta +{ + const char *title; + const char *artist; + const char *album; + const char *year; + const char *genre; + const char *comment; + const char *disc_id; + const char *count; +}; + +struct _Emotion_Generic_Cmd_Buffer +{ + char *tmp; + int type; + ssize_t i, total; + int s_len; + int num_params, cur_param; + int padding; + union { + struct { + int width; + int height; + } size; + int i_num; + float f_num; + struct { + int total; + int current; + Emotion_Generic_Channel *channels; + } track; + Emotion_Generic_Meta meta; + } param; +}; + +/* emotion/generic main structure */ +struct _Emotion_Generic_Video +{ + const char *cmdline; + const char *shmname; + + Emotion_Generic_Player player; + Emotion_Generic_Cmd_Buffer cmd; + Ecore_Event_Handler *player_add, *player_del, *player_data; + Ecore_Idler *player_restart; + int drop; + int fd_read, fd_write; + Ecore_Fd_Handler *fd_handler; + + const char *filename; + volatile double len; + volatile double pos; + double fps; + double ratio; + int w, h; + Evas_Object *obj; + Emotion_Generic_Video_Shared *shared; + Emotion_Generic_Video_Frame frame; + volatile int fq; + float volume; + float speed; + Emotion_Vis vis; + Eina_Bool initializing : 1; + Eina_Bool ready : 1; + Eina_Bool play : 1; + Eina_Bool video_mute : 1; + Eina_Bool audio_mute : 1; + Eina_Bool spu_mute : 1; + Eina_Bool seekable : 1; + volatile Eina_Bool opening : 1; + volatile Eina_Bool closing : 1; + Eina_Bool file_changed : 1; + Eina_Bool file_ready : 1; + int audio_channels_count; + int audio_channel_current; + Emotion_Generic_Channel *audio_channels; + int video_channels_count; + int video_channel_current; + Emotion_Generic_Channel *video_channels; + int spu_channels_count; + int spu_channel_current; + Emotion_Generic_Channel *spu_channels; + Emotion_Generic_Meta meta; +}; + +#endif + diff --git a/src/modules/gstreamer/Makefile.am b/src/modules/gstreamer/Makefile.am index f3519af..3672510 100644 --- a/src/modules/gstreamer/Makefile.am +++ b/src/modules/gstreamer/Makefile.am @@ -1,4 +1,3 @@ - MAINTAINERCLEANFILES = Makefile.in AM_CPPFLAGS = \ @@ -7,27 +6,32 @@ AM_CPPFLAGS = \ -DPACKAGE_BIN_DIR=\"$(bindir)\" \ -DPACKAGE_LIB_DIR=\"$(libdir)\" \ -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ -@EVAS_CFLAGS@ \ -@ECORE_CFLAGS@ \ -@GST_CFLAGS@ +@EMOTION_CFLAGS@ \ +@EMOTION_CPPFLAGS@ \ +@EFL_EMOTION_BUILD@ \ +@GSTREAMER_CFLAGS@ \ +@GSTREAMER_INTERFACE_CFLAGS@ \ +@ECORE_X_CFLAGS@ -if BUILD_GSTREAMER_MODULE +if EMOTION_BUILD_GSTREAMER +if !EMOTION_STATIC_BUILD_GSTREAMER pkgdir = $(libdir)/emotion pkg_LTLIBRARIES = gstreamer.la gstreamer_la_SOURCES = \ emotion_gstreamer.c \ -emotion_gstreamer.h \ -emotion_gstreamer_pipeline.c \ -emotion_gstreamer_pipeline.h \ -emotion_gstreamer_pipeline_cdda.c \ -emotion_gstreamer_pipeline_dvd.c \ -emotion_gstreamer_pipeline_file.c \ -emotion_gstreamer_pipeline_uri.c -gstreamer_la_LIBADD = @EVAS_LIBS@ @ECORE_LIBS@ @GST_LIBS@ $(top_builddir)/src/lib/libemotion.la -gstreamer_la_LDFLAGS = -module -avoid-version +emotion_sink.c \ +emotion_alloc.c \ +emotion_fakeeos.c \ +emotion_convert.c + +gstreamer_la_LIBADD = @EMOTION_LIBS@ @ECORE_X_LIBS@ @GSTREAMER_LIBS@ @GSTREAMER_INTERFACE_LIBS@ $(top_builddir)/src/lib/libemotion.la +gstreamer_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version gstreamer_la_LIBTOOLFLAGS = --tag=disable-static gstreamer_la_DEPENDENCIES = $(top_builddir)/config.h -endif \ No newline at end of file +endif +endif + +EXTRA_DIST = emotion_gstreamer.h diff --git a/src/modules/gstreamer/emotion_alloc.c b/src/modules/gstreamer/emotion_alloc.c new file mode 100644 index 0000000..05062bd --- /dev/null +++ b/src/modules/gstreamer/emotion_alloc.c @@ -0,0 +1,91 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include +#include + +#ifdef HAVE_ECORE_X +# include +# include +# ifdef HAVE_XOVERLAY_H +# include +# endif +#endif + +#include "Emotion.h" +#include "emotion_gstreamer.h" + +Emotion_Gstreamer_Buffer * +emotion_gstreamer_buffer_alloc(EvasVideoSinkPrivate *sink, + GstBuffer *buffer, + Eina_Bool preroll) +{ + Emotion_Gstreamer_Buffer *send; + + if (!sink->ev) return NULL; + + send = malloc(sizeof (Emotion_Gstreamer_Buffer)); + if (!send) return NULL; + + send->sink = sink; + send->frame = gst_buffer_ref(buffer); + send->preroll = preroll; + send->force = EINA_FALSE; + sink->ev->out++; + send->ev = sink->ev; + + return send; +} + +void +emotion_gstreamer_buffer_free(Emotion_Gstreamer_Buffer *send) +{ + send->ev->in++; + + if (send->ev->in == send->ev->out + && send->ev->threads == NULL + && send->ev->delete_me) + em_shutdown(send->ev); + + gst_buffer_unref(send->frame); + free(send); +} + +Emotion_Gstreamer_Message * +emotion_gstreamer_message_alloc(Emotion_Gstreamer_Video *ev, + GstMessage *msg) +{ + Emotion_Gstreamer_Message *send; + + if (!ev) return NULL; + + send = malloc(sizeof (Emotion_Gstreamer_Message)); + if (!send) return NULL; + + ev->out++; + send->ev = ev; + send->msg = gst_message_ref(msg); + + return send; +} + +void +emotion_gstreamer_message_free(Emotion_Gstreamer_Message *send) +{ + send->ev->in++; + + if (send->ev->in == send->ev->out + && send->ev->threads == NULL + && send->ev->delete_me) + em_shutdown(send->ev); + + gst_message_unref(send->msg); + free(send); +} diff --git a/src/modules/gstreamer/emotion_convert.c b/src/modules/gstreamer/emotion_convert.c new file mode 100644 index 0000000..3d3b46e --- /dev/null +++ b/src/modules/gstreamer/emotion_convert.c @@ -0,0 +1,252 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include +#include +#include +#include + +#ifdef HAVE_ECORE_X +# include +# include +# ifdef HAVE_XOVERLAY_H +# include +# endif +#endif + +#include "Emotion.h" +#include "emotion_gstreamer.h" + +static inline void +_evas_video_bgrx_step(unsigned char *evas_data, const unsigned char *gst_data, + unsigned int w, unsigned int h __UNUSED__, unsigned int output_height, unsigned int step) +{ + unsigned int x; + unsigned int y; + + for (y = 0; y < output_height; ++y) + { + for (x = 0; x < w; x++) + { + evas_data[0] = gst_data[0]; + evas_data[1] = gst_data[1]; + evas_data[2] = gst_data[2]; + evas_data[3] = 255; + gst_data += step; + evas_data += 4; + } + } +} + +static void +_evas_video_bgr(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h, unsigned int output_height) +{ + _evas_video_bgrx_step(evas_data, gst_data, w, h, output_height, 3); +} + +static void +_evas_video_bgrx(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h, unsigned int output_height) +{ + _evas_video_bgrx_step(evas_data, gst_data, w, h, output_height, 4); +} + +static void +_evas_video_bgra(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h __UNUSED__, unsigned int output_height) +{ + unsigned int x; + unsigned int y; + + for (y = 0; y < output_height; ++y) + { + unsigned char alpha; + + for (x = 0; x < w; ++x) + { + alpha = gst_data[3]; + evas_data[0] = (gst_data[0] * alpha) / 255; + evas_data[1] = (gst_data[1] * alpha) / 255; + evas_data[2] = (gst_data[2] * alpha) / 255; + evas_data[3] = alpha; + gst_data += 4; + evas_data += 4; + } + } +} + +static void +_evas_video_i420(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h, unsigned int output_height) +{ + const unsigned char **rows; + unsigned int i, j; + unsigned int rh; + unsigned int stride_y, stride_uv; + + rh = output_height; + + rows = (const unsigned char **)evas_data; + + stride_y = GST_ROUND_UP_4(w); + stride_uv = GST_ROUND_UP_8(w) / 2; + + for (i = 0; i < rh; i++) + rows[i] = &gst_data[i * stride_y]; + + for (j = 0; j < (rh / 2); j++, i++) + rows[i] = &gst_data[h * stride_y + j * stride_uv]; + + for (j = 0; j < (rh / 2); j++, i++) + rows[i] = &gst_data[h * stride_y + + (rh / 2) * stride_uv + + j * stride_uv]; +} + +static void +_evas_video_yv12(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h, unsigned int output_height) +{ + const unsigned char **rows; + unsigned int i, j; + unsigned int rh; + unsigned int stride_y, stride_uv; + + rh = output_height; + + rows = (const unsigned char **)evas_data; + + stride_y = GST_ROUND_UP_4(w); + stride_uv = GST_ROUND_UP_8(w) / 2; + + for (i = 0; i < rh; i++) + rows[i] = &gst_data[i * stride_y]; + + for (j = 0; j < (rh / 2); j++, i++) + rows[i] = &gst_data[h * stride_y + + (rh / 2) * stride_uv + + j * stride_uv]; + + for (j = 0; j < (rh / 2); j++, i++) + rows[i] = &gst_data[h * stride_y + j * stride_uv]; +} + +static void +_evas_video_yuy2(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h __UNUSED__, unsigned int output_height) +{ + const unsigned char **rows; + unsigned int i; + unsigned int stride; + + rows = (const unsigned char **)evas_data; + + stride = GST_ROUND_UP_4(w * 2); + + for (i = 0; i < output_height; i++) + rows[i] = &gst_data[i * stride]; +} + +static void +_evas_video_nv12(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h __UNUSED__, unsigned int output_height) +{ + const unsigned char **rows; + unsigned int i, j; + unsigned int rh; + + rh = output_height; + + rows = (const unsigned char **)evas_data; + + for (i = 0; i < rh; i++) + rows[i] = &gst_data[i * w]; + + for (j = 0; j < (rh / 2); j++, i++) + rows[i] = &gst_data[rh * w + j * w]; +} + +static void +_evas_video_mt12(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h, unsigned int output_height __UNUSED__) +{ + const unsigned char **rows; + unsigned int i; + unsigned int j; + + rows = (const unsigned char **)evas_data; + + for (i = 0; i < (h / 32) / 2; i++) + rows[i] = &gst_data[i * w * 2 * 32]; + + if ((h / 32) % 2) + { + rows[i] = &gst_data[i * w * 2 * 32]; + i++; + } + + for (j = 0; j < ((h / 2) / 32) / 2; ++j, ++i) + rows[i] = &gst_data[h * w + j * (w / 2) * 2 * 16]; +} + +void +_evas_video_st12_multiplane(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h, unsigned int output_height __UNUSED__) +{ + const GstMultiPlaneImageBuffer *mp_buf = (const GstMultiPlaneImageBuffer *) gst_data; + const unsigned char **rows; + unsigned int i; + unsigned int j; + + rows = (const unsigned char **)evas_data; + + for (i = 0; i < (h / 32) / 2; i++) + rows[i] = mp_buf->uaddr[0] + i * w * 2 * 32; + if ((h / 32) % 2) + { + rows[i] = mp_buf->uaddr[0] + i * w * 2 * 32; + i++; + } + + for (j = 0; j < ((h / 2) / 16) / 2; j++, i++) + { + rows[i] = mp_buf->uaddr[1] + j * w * 2 * 16 * 2; + } + if (((h / 2) / 16) % 2) + rows[i] = mp_buf->uaddr[1] + j * w * 2 * 16 * 2; +} + +void +_evas_video_st12(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w __UNUSED__, unsigned int h, unsigned int output_height __UNUSED__) +{ + const SCMN_IMGB *imgb = (const SCMN_IMGB *) gst_data; + const unsigned char **rows; + unsigned int i, j; + + rows = (const unsigned char **)evas_data; + + for (i = 0; i < (h / 32) / 2; i++) + rows[i] = imgb->uaddr[0] + i * imgb->stride[0] * 2 * 32; + if ((h / 32) % 2) + { + rows[i] = imgb->uaddr[0] + i * imgb->stride[0] * 2 * 32; + i++; + } + + for (j = 0; j < (unsigned int) imgb->elevation[1] / 32 / 2; j++, i++) + rows[i] = imgb->uaddr[1] + j * imgb->stride[1] * 32 * 2; + if ((imgb->elevation[1] / 32) % 2) + rows[i++] = imgb->uaddr[1] + j * imgb->stride[1] * 32 * 2; +} + +const ColorSpace_FourCC_Convertion colorspace_fourcc_convertion[] = { + { "I420", GST_MAKE_FOURCC('I', '4', '2', '0'), EVAS_COLORSPACE_YCBCR422P601_PL, _evas_video_i420, EINA_TRUE }, + { "YV12", GST_MAKE_FOURCC('Y', 'V', '1', '2'), EVAS_COLORSPACE_YCBCR422P601_PL, _evas_video_yv12, EINA_TRUE }, + { "YUY2", GST_MAKE_FOURCC('Y', 'U', 'Y', '2'), EVAS_COLORSPACE_YCBCR422601_PL, _evas_video_yuy2, EINA_FALSE }, + { "NV12", GST_MAKE_FOURCC('N', 'V', '1', '2'), EVAS_COLORSPACE_YCBCR420NV12601_PL, _evas_video_nv12, EINA_TRUE }, + { "TM12", GST_MAKE_FOURCC('T', 'M', '1', '2'), EVAS_COLORSPACE_YCBCR420TM12601_PL, _evas_video_mt12, EINA_TRUE }, + { NULL, 0, 0, NULL, 0 } +}; + +const ColorSpace_Format_Convertion colorspace_format_convertion[] = { + { "BGR", GST_VIDEO_FORMAT_BGR, EVAS_COLORSPACE_ARGB8888, _evas_video_bgr }, + { "BGRx", GST_VIDEO_FORMAT_BGRx, EVAS_COLORSPACE_ARGB8888, _evas_video_bgrx }, + { "BGRA", GST_VIDEO_FORMAT_BGRA, EVAS_COLORSPACE_ARGB8888, _evas_video_bgra }, + { NULL, 0, 0, NULL } +}; diff --git a/src/modules/gstreamer/emotion_fakeeos.c b/src/modules/gstreamer/emotion_fakeeos.c new file mode 100644 index 0000000..a9e1bbe --- /dev/null +++ b/src/modules/gstreamer/emotion_fakeeos.c @@ -0,0 +1,71 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include +#include +#include +#include + +#ifdef HAVE_ECORE_X +# include +# include +# ifdef HAVE_XOVERLAY_H +# include +# endif +#endif + +#include "Emotion.h" +#include "emotion_gstreamer.h" + +typedef struct _FakeEOSBin +{ + GstBin parent; +} FakeEOSBin; + +typedef struct _FakeEOSBinClass +{ + GstBinClass parent; +} FakeEOSBinClass; + +GST_BOILERPLATE(FakeEOSBin, fakeeos_bin, GstBin, + GST_TYPE_BIN); + +static void +fakeeos_bin_handle_message(GstBin * bin, GstMessage * message) +{ + /* FakeEOSBin *fakeeos = (FakeEOSBin *)(bin); */ + + switch (GST_MESSAGE_TYPE(message)) { + case GST_MESSAGE_EOS: + /* what to do here ? just returning at the moment */ + return ; + default: + break; + } + + GST_BIN_CLASS(parent_class)->handle_message(bin, message); +} + +static void +fakeeos_bin_base_init(gpointer g_class __UNUSED__) +{ +} + +static void +fakeeos_bin_class_init(FakeEOSBinClass * klass) +{ + GstBinClass *gstbin_class = GST_BIN_CLASS(klass); + + gstbin_class->handle_message = + GST_DEBUG_FUNCPTR (fakeeos_bin_handle_message); +} + +static void +fakeeos_bin_init(FakeEOSBin *src __UNUSED__, + FakeEOSBinClass *klass __UNUSED__) +{ +} diff --git a/src/modules/gstreamer/emotion_gstreamer.c b/src/modules/gstreamer/emotion_gstreamer.c index 4bb6348..8ec71fb 100644 --- a/src/modules/gstreamer/emotion_gstreamer.c +++ b/src/modules/gstreamer/emotion_gstreamer.c @@ -1,18 +1,44 @@ -/* - * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 - */ -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif #include +#include +#include +#include + +#define HTTP_STREAM 0 +#define RTSP_STREAM 1 +#include +#include +#include +#include +#include + +#ifdef HAVE_ECORE_X +# include +# include +# ifdef HAVE_XOVERLAY_H +# include +# endif +#endif + #include "Emotion.h" #include "emotion_private.h" #include "emotion_gstreamer.h" -#include "emotion_gstreamer_pipeline.h" +Eina_Bool window_manager_video = EINA_FALSE; +int _emotion_gstreamer_log_domain = -1; +Eina_Bool debug_fps = EINA_FALSE; +Eina_Bool _ecore_x_available = EINA_FALSE; + +static Ecore_Idler *restart_idler; /* Callbacks to get the eos */ -static int _eos_timer_fct (void *data); -static int _em_fd_ev_active (void *data, Ecore_Fd_Handler *fdh); static void _for_each_tag (GstTagList const* list, gchar const* tag, void *data); static void _free_metadata (Emotion_Gstreamer_Metadata *m); @@ -20,9 +46,7 @@ static void _free_metadata (Emotion_Gstreamer_Metadata *m); static unsigned char em_init (Evas_Object *obj, void **emotion_video, - Emotion_Module_Options *opt); - -static int em_shutdown (void *video); + Emotion_Module_Options *opt); static unsigned char em_file_open (const char *file, Evas_Object *obj, @@ -42,11 +66,11 @@ static void em_size_get (void *video, static void em_pos_set (void *video, double pos); -static void em_vis_set (void *video, - Emotion_Vis vis); static double em_len_get (void *video); +static double em_buffer_size_get (void *video); + static int em_fps_num_get (void *video); static int em_fps_den_get (void *video); @@ -55,8 +79,14 @@ static double em_fps_get (void *video); static double em_pos_get (void *video); +static void em_vis_set (void *video, + Emotion_Vis vis); + static Emotion_Vis em_vis_get (void *video); +static Eina_Bool em_vis_supported (void *video, + Emotion_Vis vis); + static double em_ratio_get (void *video); static int em_video_handled (void *video); @@ -165,6 +195,16 @@ static int em_eject (void *video); static const char *em_meta_get (void *video, int meta); +static void em_priority_set (void *video, + Eina_Bool pri); +static Eina_Bool em_priority_get (void *video); + +static GstBusSyncReply _eos_sync_fct(GstBus *bus, + GstMessage *message, + gpointer data); + +static Eina_Bool _em_restart_stream(void *data); + /* Module interface */ static Emotion_Video_Module em_module = @@ -177,13 +217,15 @@ static Emotion_Video_Module em_module = em_stop, /* stop */ em_size_get, /* size_get */ em_pos_set, /* pos_set */ - em_vis_set, /* vis_set */ em_len_get, /* len_get */ + em_buffer_size_get, /* buffer_size_get */ em_fps_num_get, /* fps_num_get */ em_fps_den_get, /* fps_den_get */ em_fps_get, /* fps_get */ em_pos_get, /* pos_get */ + em_vis_set, /* vis_set */ em_vis_get, /* vis_get */ + em_vis_supported, /* vis_supported */ em_ratio_get, /* ratio_get */ em_video_handled, /* video_handled */ em_audio_handled, /* audio_handled */ @@ -224,17 +266,87 @@ static Emotion_Video_Module em_module = em_speed_get, /* speed_get */ em_eject, /* eject */ em_meta_get, /* meta_get */ + em_priority_set, /* priority_set */ + em_priority_get, /* priority_get */ NULL /* handle */ }; +static int priority_overide = 0; + +static Emotion_Video_Stream * +emotion_video_stream_new(Emotion_Gstreamer_Video *ev) +{ + Emotion_Video_Stream *vstream; + + if (!ev) return NULL; + + vstream = (Emotion_Video_Stream *)calloc(1, sizeof(Emotion_Video_Stream)); + if (!vstream) return NULL; + + ev->video_streams = eina_list_append(ev->video_streams, vstream); + if (eina_error_get()) + { + free(vstream); + return NULL; + } + return vstream; +} + +static const char * +emotion_visualization_element_name_get(Emotion_Vis visualisation) +{ + switch (visualisation) + { + case EMOTION_VIS_NONE: + return NULL; + case EMOTION_VIS_GOOM: + return "goom"; + case EMOTION_VIS_LIBVISUAL_BUMPSCOPE: + return "libvisual_bumpscope"; + case EMOTION_VIS_LIBVISUAL_CORONA: + return "libvisual_corona"; + case EMOTION_VIS_LIBVISUAL_DANCING_PARTICLES: + return "libvisual_dancingparticles"; + case EMOTION_VIS_LIBVISUAL_GDKPIXBUF: + return "libvisual_gdkpixbuf"; + case EMOTION_VIS_LIBVISUAL_G_FORCE: + return "libvisual_G-Force"; + case EMOTION_VIS_LIBVISUAL_GOOM: + return "libvisual_goom"; + case EMOTION_VIS_LIBVISUAL_INFINITE: + return "libvisual_infinite"; + case EMOTION_VIS_LIBVISUAL_JAKDAW: + return "libvisual_jakdaw"; + case EMOTION_VIS_LIBVISUAL_JESS: + return "libvisual_jess"; + case EMOTION_VIS_LIBVISUAL_LV_ANALYSER: + return "libvisual_lv_analyzer"; + case EMOTION_VIS_LIBVISUAL_LV_FLOWER: + return "libvisual_lv_flower"; + case EMOTION_VIS_LIBVISUAL_LV_GLTEST: + return "libvisual_lv_gltest"; + case EMOTION_VIS_LIBVISUAL_LV_SCOPE: + return "libvisual_lv_scope"; + case EMOTION_VIS_LIBVISUAL_MADSPIN: + return "libvisual_madspin"; + case EMOTION_VIS_LIBVISUAL_NEBULUS: + return "libvisual_nebulus"; + case EMOTION_VIS_LIBVISUAL_OINKSIE: + return "libvisual_oinksie"; + case EMOTION_VIS_LIBVISUAL_PLASMA: + return "libvisual_plazma"; + default: + return "goom"; + } +} + static unsigned char -em_init(Evas_Object *obj, - void **emotion_video, - Emotion_Module_Options *opt) +em_init(Evas_Object *obj, + void **emotion_video, + Emotion_Module_Options *opt __UNUSED__) { Emotion_Gstreamer_Video *ev; GError *error; - int fds[2]; if (!emotion_video) return 0; @@ -243,59 +355,107 @@ em_init(Evas_Object *obj, if (!ev) return 0; ev->obj = obj; - ev->obj_data = NULL; /* Initialization of gstreamer */ if (!gst_init_check(NULL, NULL, &error)) - goto failure_gstreamer; - - /* We allocate the sinks lists */ - ev->video_sinks = ecore_list_new(); - if (!ev->video_sinks) - goto failure_video_sinks; - ecore_list_free_cb_set(ev->video_sinks, ECORE_FREE_CB(free)); - ev->audio_sinks = ecore_list_new(); - if (!ev->audio_sinks) - goto failure_audio_sinks; - ecore_list_free_cb_set(ev->audio_sinks, ECORE_FREE_CB(free)); - - *emotion_video = ev; + goto failure; /* Default values */ ev->ratio = 1.0; - ev->video_sink_nbr = 0; - ev->audio_sink_nbr = 0; - ev->vis = EMOTION_VIS_GOOM; + ev->vis = EMOTION_VIS_NONE; + ev->volume = 0.8; + ev->play_started = 0; + ev->delete_me = EINA_FALSE; + ev->threads = NULL; - /* Create the file descriptors */ - if (pipe(fds) == 0) - { - ev->fd_ev_read = fds[0]; - ev->fd_ev_write = fds[1]; - fcntl(ev->fd_ev_read, F_SETFL, O_NONBLOCK); - ev->fd_ev_handler = ecore_main_fd_handler_add(ev->fd_ev_read, - ECORE_FD_READ, - _em_fd_ev_active, - ev, NULL, NULL); - ecore_main_fd_handler_active_set(ev->fd_ev_handler, ECORE_FD_READ); - } - else - goto failure_pipe; + *emotion_video = ev; return 1; -failure_pipe: - ecore_list_destroy(ev->audio_sinks); -failure_audio_sinks: - ecore_list_destroy(ev->video_sinks); -failure_video_sinks: -failure_gstreamer: +failure: free(ev); return 0; } -static int +static void +em_cleanup(Emotion_Gstreamer_Video *ev) +{ + Emotion_Audio_Stream *astream; + Emotion_Video_Stream *vstream; + + if (ev->send) + { + emotion_gstreamer_buffer_free(ev->send); + ev->send = NULL; + } + + if (ev->eos_bus) + { + gst_object_unref(GST_OBJECT(ev->eos_bus)); + ev->eos_bus = NULL; + } + + if (ev->metadata) + { + _free_metadata(ev->metadata); + ev->metadata = NULL; + } + + if (ev->last_buffer) + { + gst_buffer_unref(ev->last_buffer); + ev->last_buffer = NULL; + } + + if (!ev->stream) + { + evas_object_image_video_surface_set(emotion_object_image_get(ev->obj), NULL); + ev->stream = EINA_TRUE; + } + + if (ev->pipeline) + { + gstreamer_video_sink_new(ev, ev->obj, NULL); + + g_object_set(G_OBJECT(ev->esink), "ev", NULL, NULL); + g_object_set(G_OBJECT(ev->esink), "evas-object", NULL, NULL); + gst_element_set_state(ev->pipeline, GST_STATE_NULL); + gst_object_unref(ev->pipeline); + + ev->pipeline = NULL; + ev->sink = NULL; + + if (ev->eteepad) gst_object_unref(ev->eteepad); + ev->eteepad = NULL; + if (ev->xvteepad) gst_object_unref(ev->xvteepad); + ev->xvteepad = NULL; + if (ev->xvpad) gst_object_unref(ev->xvpad); + ev->xvpad = NULL; + + ev->src_width = 0; + ev->src_height = 0; + +#ifdef HAVE_ECORE_X + fprintf(stderr, "destroying window: %i\n", ev->win); + if (ev->win) ecore_x_window_free(ev->win); + ev->win = 0; +#endif + } + + if (restart_idler) + { + ecore_idler_del(restart_idler); + restart_idler = NULL; + } + + EINA_LIST_FREE(ev->audio_streams, astream) + free(astream); + EINA_LIST_FREE(ev->video_streams, vstream) + free(vstream); +} + +int em_shutdown(void *video) { Emotion_Gstreamer_Video *ev; @@ -304,16 +464,24 @@ em_shutdown(void *video) if (!ev) return 0; - ecore_main_fd_handler_del(ev->fd_ev_handler); + if (ev->threads) + { + Ecore_Thread *t; - close(ev->fd_ev_write); - close(ev->fd_ev_read); + EINA_LIST_FREE(ev->threads, t) + ecore_thread_cancel(t); - /* FIXME: and the evas object ? */ - if (ev->obj_data) free(ev->obj_data); + ev->delete_me = EINA_TRUE; + return EINA_FALSE; + } + + if (ev->in != ev->out) + { + ev->delete_me = EINA_TRUE; + return EINA_FALSE; + } - ecore_list_destroy(ev->video_sinks); - ecore_list_destroy(ev->audio_sinks); + em_cleanup(ev); free(ev); @@ -323,133 +491,64 @@ em_shutdown(void *video) static unsigned char em_file_open(const char *file, - Evas_Object *obj, - void *video) + Evas_Object *obj, + void *video) { Emotion_Gstreamer_Video *ev; + Eina_Strbuf *sbuf = NULL; + const char *uri; ev = (Emotion_Gstreamer_Video *)video; - ev->pipeline = gst_pipeline_new("pipeline"); + if (!file) return EINA_FALSE; + if (strstr(file, "://") == NULL) + { + sbuf = eina_strbuf_new(); + eina_strbuf_append(sbuf, "file://"); + if (strncmp(file, "./", 2) == 0) + file += 2; + if (strstr(file, ":/") != NULL) + { /* We absolutely need file:///C:/ under Windows, so adding it here */ + eina_strbuf_append(sbuf, "/"); + } + else if (*file != '/') + { + char tmp[PATH_MAX]; + + if (getcwd(tmp, PATH_MAX)) + { + eina_strbuf_append(sbuf, tmp); + eina_strbuf_append(sbuf, "/"); + } + } + eina_strbuf_append(sbuf, file); + } + + ev->play_started = 0; + ev->pipeline_parsed = 0; + + uri = sbuf ? eina_strbuf_string_get(sbuf) : file; + DBG("setting file to '%s'", uri); + ev->pipeline = gstreamer_video_sink_new(ev, obj, uri); + if (sbuf) eina_strbuf_free(sbuf); + if (!ev->pipeline) - return 0; + return EINA_FALSE; ev->eos_bus = gst_pipeline_get_bus(GST_PIPELINE(ev->pipeline)); if (!ev->eos_bus) { - gst_object_unref(ev->pipeline); - return 0; + ERR("could not get the bus"); + return EINA_FALSE; } + gst_bus_set_sync_handler(ev->eos_bus, _eos_sync_fct, ev); + /* Evas Object */ ev->obj = obj; - /* CD Audio */ - if (strstr(file, "cdda://")) - { - const char *device = NULL; - unsigned int track = 1; - - device = file + strlen("cdda://"); - if (device[0] == '/') - { - char *tmp; - - if ((tmp = strchr(device, '?')) || (tmp = strchr(device, '#'))) - { - sscanf(tmp + 1, "%d", &track); - tmp[0] = '\0'; - } - } - else - { - device = NULL; - sscanf(file, "cdda://%d", &track); - } - fprintf(stderr, "[Emotion] [gst] build CD Audio pipeline\n"); - if (!(emotion_pipeline_cdda_build(ev, device, track))) - { - fprintf(stderr, "[Emotion] [gst] error while building CD Audio pipeline\n"); - gst_object_unref(ev->pipeline); - return 0; - } - } - /* Dvd */ - else if (strstr(file, "dvd://")) - { - - fprintf(stderr, "[Emotion] [gst] build DVD pipeline\n"); - if (!(emotion_pipeline_dvd_build(ev, NULL))) - { - fprintf(stderr, "[Emotion] [gst] error while building DVD pipeline\n"); - gst_object_unref(ev->pipeline); - return 0; - } - } - /* http */ - else if (strstr(file, "http://")) - { - fprintf(stderr, "[Emotion] [gst] build URI pipeline\n"); - if (!(emotion_pipeline_uri_build(ev, file))) - { - fprintf(stderr, "[Emotion] [gst] error while building URI pipeline\n"); - gst_object_unref(ev->pipeline); - return 0; - } - } - /* Normal media file */ - else - { - const char *filename; - - filename = strstr(file, "file://") - ? file + strlen("file://") - : file; - - fprintf(stderr, "[Emotion] [gst] build file pipeline\n"); - if (!(emotion_pipeline_file_build(ev, filename))) - { - fprintf(stderr, "[Emotion] [gst] error while building File pipeline\n"); - gst_object_unref(ev->pipeline); - return 0; - } - } - ev->position = 0.0; - { - /* on recapitule : */ - Emotion_Video_Sink *vsink; - Emotion_Audio_Sink *asink; - - vsink = (Emotion_Video_Sink *)ecore_list_first_goto(ev->video_sinks); - if (vsink) - { - fprintf(stderr, "video : \n"); - fprintf(stderr, " size : %dx%d\n", vsink->width, vsink->height); - fprintf(stderr, " fps : %d/%d\n", vsink->fps_num, vsink->fps_den); - fprintf(stderr, " fourcc : %" GST_FOURCC_FORMAT "\n", GST_FOURCC_ARGS(vsink->fourcc)); - fprintf(stderr, " length : %" GST_TIME_FORMAT "\n\n", - GST_TIME_ARGS((guint64)(vsink->length_time * GST_SECOND))); - } - - asink = (Emotion_Audio_Sink *)ecore_list_first_goto(ev->audio_sinks); - if (asink) - { - fprintf(stderr, "audio : \n"); - fprintf(stderr, " chan : %d\n", asink->channels); - fprintf(stderr, " rate : %d\n", asink->samplerate); - fprintf(stderr, " length : %" GST_TIME_FORMAT "\n\n", - GST_TIME_ARGS((guint64)(asink->length_time * GST_SECOND))); - } - } - - if (ev->metadata) - _free_metadata(ev->metadata); - ev->metadata = calloc(1, sizeof(Emotion_Gstreamer_Metadata)); - - _eos_timer_fct(ev); - return 1; } @@ -462,49 +561,33 @@ em_file_close(void *video) if (!ev) return; - /* we clear the sink lists */ - ecore_list_clear(ev->video_sinks); - ecore_list_clear(ev->audio_sinks); - - /* shutdown eos */ - if (ev->eos_timer) + if (ev->threads) { - ecore_timer_del(ev->eos_timer); - ev->eos_timer = NULL; - } + Ecore_Thread *t; - if (ev->eos_bus) - { - gst_object_unref(GST_OBJECT(ev->eos_bus)); - ev->eos_bus = NULL; + EINA_LIST_FREE(ev->threads, t) + ecore_thread_cancel(t); } - if (ev->metadata) - { - _free_metadata(ev->metadata); - ev->metadata = NULL; - } + em_cleanup(ev); - if (ev->pipeline) - { - gst_element_set_state(ev->pipeline, GST_STATE_NULL); - gst_object_unref(ev->pipeline); - ev->pipeline = NULL; - } + ev->pipeline_parsed = EINA_FALSE; + ev->play_started = 0; } static void em_play(void *video, - double pos) + double pos __UNUSED__) { Emotion_Gstreamer_Video *ev; ev = (Emotion_Gstreamer_Video *)video; - gst_element_set_state(ev->pipeline, GST_STATE_PLAYING); - ev->play = 1; + if (!ev->pipeline) return ; - /* eos */ - ev->eos_timer = ecore_timer_add(0.1, _eos_timer_fct, ev); + if (ev->pipeline_parsed) + gst_element_set_state(ev->pipeline, GST_STATE_PLAYING); + ev->play = 1; + ev->play_started = 1; } static void @@ -514,114 +597,148 @@ em_stop(void *video) ev = (Emotion_Gstreamer_Video *)video; - /* shutdown eos */ - if (ev->eos_timer) - { - ecore_timer_del(ev->eos_timer); - ev->eos_timer = NULL; - } + if (!ev->pipeline) return ; - gst_element_set_state(ev->pipeline, GST_STATE_PAUSED); + if (ev->pipeline_parsed) + gst_element_set_state(ev->pipeline, GST_STATE_PAUSED); ev->play = 0; } static void em_size_get(void *video, - int *width, - int *height) + int *width, + int *height) { Emotion_Gstreamer_Video *ev; - Emotion_Video_Sink *vsink; + Emotion_Video_Stream *vstream; ev = (Emotion_Gstreamer_Video *)video; - vsink = (Emotion_Video_Sink *)ecore_list_index_goto(ev->video_sinks, ev->video_sink_nbr); - if (vsink) - { - if (width) *width = vsink->width; - if (height) *height = vsink->height; - } - else + if (!_emotion_gstreamer_video_pipeline_parse(ev, EINA_FALSE)) + goto on_error; + + vstream = eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1); + if (vstream) { - if (width) *width = 0; - if (height) *height = 0; + if (width) *width = vstream->width; + if (height) *height = vstream->height; + + return ; } + + on_error: + if (width) *width = 0; + if (height) *height = 0; } static void em_pos_set(void *video, - double pos) + double pos) { Emotion_Gstreamer_Video *ev; - Emotion_Video_Sink *vsink; - Emotion_Audio_Sink *asink; ev = (Emotion_Gstreamer_Video *)video; - if (ev->seek_to_pos == pos) return; + if (!ev->pipeline) return ; - vsink = (Emotion_Video_Sink *)ecore_list_index_goto(ev->video_sinks, ev->video_sink_nbr); - asink = (Emotion_Audio_Sink *)ecore_list_index_goto(ev->video_sinks, ev->audio_sink_nbr); + if (ev->play) + gst_element_set_state(ev->pipeline, GST_STATE_PAUSED); - if (vsink) - { - gst_element_seek(vsink->sink, 1.0, - GST_FORMAT_TIME, - GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH, - GST_SEEK_TYPE_SET, - (gint64)(pos * (double)GST_SECOND), - GST_SEEK_TYPE_NONE, -1); - } - if (asink) - { - gst_element_seek(asink->sink, 1.0, - GST_FORMAT_TIME, - GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH, - GST_SEEK_TYPE_SET, - (gint64)(pos * (double)GST_SECOND), - GST_SEEK_TYPE_NONE, -1); - } - ev->seek_to_pos = pos; + gst_element_seek(ev->pipeline, 1.0, + GST_FORMAT_TIME, + GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH, + GST_SEEK_TYPE_SET, + (gint64)(pos * (double)GST_SECOND), + GST_SEEK_TYPE_NONE, -1); + + if (ev->play) + gst_element_set_state(ev->pipeline, GST_STATE_PLAYING); } -static void -em_vis_set(void *video, - Emotion_Vis vis) +static double +em_len_get(void *video) { Emotion_Gstreamer_Video *ev; + Emotion_Video_Stream *vstream; + Emotion_Audio_Stream *astream; + Eina_List *l; + GstFormat fmt; + gint64 val; + gboolean ret; - ev = (Emotion_Gstreamer_Video *)video; + ev = video; + fmt = GST_FORMAT_TIME; - if (ev->vis == vis) return; - ev->vis = vis; + if (!ev->pipeline) return 0.0; + + ret = gst_element_query_duration(ev->pipeline, &fmt, &val); + if (!ret) + goto fallback; + + if (fmt != GST_FORMAT_TIME) + { + DBG("requrested duration in time, but got %s instead.", + gst_format_get_name(fmt)); + goto fallback; + } + + if (val <= 0.0) + goto fallback; + + return val / 1000000000.0; + + fallback: + if (!_emotion_gstreamer_video_pipeline_parse(ev, EINA_FALSE)) + return 0.0; + + EINA_LIST_FOREACH(ev->audio_streams, l, astream) + if (astream->length_time >= 0) + return astream->length_time; + + EINA_LIST_FOREACH(ev->video_streams, l, vstream) + if (vstream->length_time >= 0) + return vstream->length_time; + + return 0.0; } static double -em_len_get(void *video) +em_buffer_size_get(void *video) { Emotion_Gstreamer_Video *ev; - Emotion_Video_Sink *vsink; - ev = (Emotion_Gstreamer_Video *)video; + GstQuery *query; + gboolean busy; + gint percent; - vsink = (Emotion_Video_Sink *)ecore_list_index_goto(ev->video_sinks, ev->video_sink_nbr); - if (vsink) - return (double)vsink->length_time; + ev = video; - return 0.0; + if (!ev->pipeline) return 0.0; + + query = gst_query_new_buffering(GST_FORMAT_DEFAULT); + if (gst_element_query(ev->pipeline, query)) + gst_query_parse_buffering_percent(query, &busy, &percent); + else + percent = 100; + + gst_query_unref(query); + return ((float)(percent)) / 100.0; } static int em_fps_num_get(void *video) { Emotion_Gstreamer_Video *ev; - Emotion_Video_Sink *vsink; + Emotion_Video_Stream *vstream; ev = (Emotion_Gstreamer_Video *)video; - vsink = (Emotion_Video_Sink *)ecore_list_index_goto(ev->video_sinks, ev->video_sink_nbr); - if (vsink) - return vsink->fps_num; + if (!_emotion_gstreamer_video_pipeline_parse(ev, EINA_FALSE)) + return 0; + + vstream = eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1); + if (vstream) + return vstream->fps_num; return 0; } @@ -630,13 +747,16 @@ static int em_fps_den_get(void *video) { Emotion_Gstreamer_Video *ev; - Emotion_Video_Sink *vsink; + Emotion_Video_Stream *vstream; ev = (Emotion_Gstreamer_Video *)video; - vsink = (Emotion_Video_Sink *)ecore_list_index_goto(ev->video_sinks, ev->video_sink_nbr); - if (vsink) - return vsink->fps_den; + if (!_emotion_gstreamer_video_pipeline_parse(ev, EINA_FALSE)) + return 1; + + vstream = eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1); + if (vstream) + return vstream->fps_den; return 1; } @@ -645,13 +765,16 @@ static double em_fps_get(void *video) { Emotion_Gstreamer_Video *ev; - Emotion_Video_Sink *vsink; + Emotion_Video_Stream *vstream; ev = (Emotion_Gstreamer_Video *)video; - vsink = (Emotion_Video_Sink *)ecore_list_index_goto(ev->video_sinks, ev->video_sink_nbr); - if (vsink) - return (double)vsink->fps_num / (double)vsink->fps_den; + if (!_emotion_gstreamer_video_pipeline_parse(ev, EINA_FALSE)) + return 0.0; + + vstream = eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1); + if (vstream) + return (double)vstream->fps_num / (double)vstream->fps_den; return 0.0; } @@ -660,12 +783,41 @@ static double em_pos_get(void *video) { Emotion_Gstreamer_Video *ev; + GstFormat fmt; + gint64 val; + gboolean ret; - ev = (Emotion_Gstreamer_Video *)video; + ev = video; + fmt = GST_FORMAT_TIME; + + if (!ev->pipeline) return 0.0; + + ret = gst_element_query_position(ev->pipeline, &fmt, &val); + if (!ret) + return ev->position; + if (fmt != GST_FORMAT_TIME) + { + ERR("requrested position in time, but got %s instead.", + gst_format_get_name(fmt)); + return ev->position; + } + + ev->position = val / 1000000000.0; return ev->position; } +static void +em_vis_set(void *video, + Emotion_Vis vis) +{ + Emotion_Gstreamer_Video *ev; + + ev = (Emotion_Gstreamer_Video *)video; + + ev->vis = vis; +} + static Emotion_Vis em_vis_get(void *video) { @@ -676,6 +828,27 @@ em_vis_get(void *video) return ev->vis; } +static Eina_Bool +em_vis_supported(void *ef __UNUSED__, Emotion_Vis vis) +{ + const char *name; + GstElementFactory *factory; + + if (vis == EMOTION_VIS_NONE) + return EINA_TRUE; + + name = emotion_visualization_element_name_get(vis); + if (!name) + return EINA_FALSE; + + factory = gst_element_factory_find(name); + if (!factory) + return EINA_FALSE; + + gst_object_unref(factory); + return EINA_TRUE; +} + static double em_ratio_get(void *video) { @@ -693,7 +866,9 @@ em_video_handled(void *video) ev = (Emotion_Gstreamer_Video *)video; - if (ecore_list_empty_is(ev->video_sinks)) + _emotion_gstreamer_video_pipeline_parse(ev, EINA_FALSE); + + if (!eina_list_count(ev->video_streams)) return 0; return 1; @@ -706,54 +881,52 @@ em_audio_handled(void *video) ev = (Emotion_Gstreamer_Video *)video; - if (ecore_list_empty_is(ev->audio_sinks)) + _emotion_gstreamer_video_pipeline_parse(ev, EINA_FALSE); + + if (!eina_list_count(ev->audio_streams)) return 0; return 1; } static int -em_seekable(void *video) +em_seekable(void *video __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; - return 1; } static void -em_frame_done(void *video) +em_frame_done(void *video __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; } static Emotion_Format em_format_get(void *video) { Emotion_Gstreamer_Video *ev; - Emotion_Video_Sink *vsink; + Emotion_Video_Stream *vstream; ev = (Emotion_Gstreamer_Video *)video; - vsink = (Emotion_Video_Sink *)ecore_list_index_goto(ev->video_sinks, ev->video_sink_nbr); - if (vsink) + if (!_emotion_gstreamer_video_pipeline_parse(ev, EINA_FALSE)) + return EMOTION_FORMAT_NONE; + + vstream = eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1); + if (vstream) { - switch (vsink->fourcc) - { - case GST_MAKE_FOURCC('I', '4', '2', '0'): - return EMOTION_FORMAT_I420; - case GST_MAKE_FOURCC('Y', 'V', '1', '2'): - return EMOTION_FORMAT_YV12; - case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'): - return EMOTION_FORMAT_YUY2; - case GST_MAKE_FOURCC('A', 'R', 'G', 'B'): - return EMOTION_FORMAT_BGRA; - default: - return EMOTION_FORMAT_NONE; - } + switch (vstream->fourcc) + { + case GST_MAKE_FOURCC('I', '4', '2', '0'): + return EMOTION_FORMAT_I420; + case GST_MAKE_FOURCC('Y', 'V', '1', '2'): + return EMOTION_FORMAT_YV12; + case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'): + return EMOTION_FORMAT_YUY2; + case GST_MAKE_FOURCC('A', 'R', 'G', 'B'): + return EMOTION_FORMAT_BGRA; + default: + return EMOTION_FORMAT_NONE; + } } return EMOTION_FORMAT_NONE; } @@ -762,106 +935,58 @@ static void em_video_data_size_get(void *video, int *w, int *h) { Emotion_Gstreamer_Video *ev; - Emotion_Video_Sink *vsink; + Emotion_Video_Stream *vstream; ev = (Emotion_Gstreamer_Video *)video; - vsink = (Emotion_Video_Sink *)ecore_list_index_goto(ev->video_sinks, ev->video_sink_nbr); - if (vsink) - { - *w = vsink->width; - *h = vsink->height; - } - else + if (ev->pipeline && (!ev->video_stream_nbr || !ev->video_streams)) + if (!_emotion_gstreamer_video_pipeline_parse(ev, EINA_FALSE)) + goto on_error; + + vstream = eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1); + if (vstream) { - *w = 0; - *h = 0; + *w = vstream->width; + *h = vstream->height; + + return ; } + + on_error: + *w = 0; + *h = 0; } static int -em_yuv_rows_get(void *video, - int w, - int h, - unsigned char **yrows, - unsigned char **urows, - unsigned char **vrows) +em_yuv_rows_get(void *video __UNUSED__, + int w __UNUSED__, + int h __UNUSED__, + unsigned char **yrows __UNUSED__, + unsigned char **urows __UNUSED__, + unsigned char **vrows __UNUSED__) { - Emotion_Gstreamer_Video *ev; - int i; - - ev = (Emotion_Gstreamer_Video *)video; - - if (ev->obj_data) - { - if (em_format_get(video) == EMOTION_FORMAT_I420) - { - for (i = 0; i < h; i++) - yrows[i] = &ev->obj_data[i * w]; - - for (i = 0; i < (h / 2); i++) - urows[i] = &ev->obj_data[h * w + i * (w / 2)]; - - for (i = 0; i < (h / 2); i++) - vrows[i] = &ev->obj_data[h * w + h * (w /4) + i * (w / 2)]; - } - else if (em_format_get(video) == EMOTION_FORMAT_YV12) - { - for (i = 0; i < h; i++) - yrows[i] = &ev->obj_data[i * w]; - - for (i = 0; i < (h / 2); i++) - vrows[i] = &ev->obj_data[h * w + i * (w / 2)]; - - for (i = 0; i < (h / 2); i++) - urows[i] = &ev->obj_data[h * w + h * (w /4) + i * (w / 2)]; - } - else - return 0; - - return 1; - } - return 0; } static int -em_bgra_data_get(void *video, unsigned char **bgra_data) +em_bgra_data_get(void *video __UNUSED__, unsigned char **bgra_data __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; - - if (ev->obj_data && em_format_get(video) == EMOTION_FORMAT_BGRA) - { - *bgra_data = ev->obj_data; - return 1; - } return 0; } static void -em_event_feed(void *video, int event) +em_event_feed(void *video __UNUSED__, int event __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; } static void -em_event_mouse_button_feed(void *video, int button, int x, int y) +em_event_mouse_button_feed(void *video __UNUSED__, int button __UNUSED__, int x __UNUSED__, int y __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; } static void -em_event_mouse_move_feed(void *video, int x, int y) +em_event_mouse_move_feed(void *video __UNUSED__, int x __UNUSED__, int y __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; } /* Video channels */ @@ -872,18 +997,22 @@ em_video_channel_count(void *video) ev = (Emotion_Gstreamer_Video *)video; - return ecore_list_count(ev->video_sinks); + _emotion_gstreamer_video_pipeline_parse(ev, EINA_FALSE); + + return eina_list_count(ev->video_streams); } static void -em_video_channel_set(void *video, - int channel) +em_video_channel_set(void *video __UNUSED__, + int channel __UNUSED__) { +#if 0 Emotion_Gstreamer_Video *ev; ev = (Emotion_Gstreamer_Video *)video; if (channel < 0) channel = 0; +#endif /* FIXME: a faire... */ } @@ -894,23 +1023,21 @@ em_video_channel_get(void *video) ev = (Emotion_Gstreamer_Video *)video; - return ev->video_sink_nbr; + _emotion_gstreamer_video_pipeline_parse(ev, EINA_FALSE); + + return ev->video_stream_nbr; } static const char * -em_video_channel_name_get(void *video, - int channel) +em_video_channel_name_get(void *video __UNUSED__, + int channel __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; - return NULL; } static void em_video_channel_mute_set(void *video, - int mute) + int mute) { Emotion_Gstreamer_Video *ev; @@ -938,18 +1065,22 @@ em_audio_channel_count(void *video) ev = (Emotion_Gstreamer_Video *)video; - return ecore_list_count(ev->audio_sinks); + _emotion_gstreamer_video_pipeline_parse(ev, EINA_FALSE); + + return eina_list_count(ev->audio_streams); } static void -em_audio_channel_set(void *video, - int channel) +em_audio_channel_set(void *video __UNUSED__, + int channel __UNUSED__) { +#if 0 Emotion_Gstreamer_Video *ev; ev = (Emotion_Gstreamer_Video *)video; if (channel < -1) channel = -1; +#endif /* FIXME: a faire... */ } @@ -960,42 +1091,38 @@ em_audio_channel_get(void *video) ev = (Emotion_Gstreamer_Video *)video; - return ev->audio_sink_nbr; + _emotion_gstreamer_video_pipeline_parse(ev, EINA_FALSE); + + return ev->audio_stream_nbr; } static const char * -em_audio_channel_name_get(void *video, - int channel) +em_audio_channel_name_get(void *video __UNUSED__, + int channel __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; - return NULL; } +#define GST_PLAY_FLAG_AUDIO (1 << 1) + static void em_audio_channel_mute_set(void *video, - int mute) + int mute) { + /* NOTE: at first I wanted to completly shutdown the audio path on mute, + but that's not possible as the audio sink could be the clock source + for the pipeline (at least that's the case on some of the hardware + I have been tested emotion on. + */ Emotion_Gstreamer_Video *ev; - GstElement *volume; ev = (Emotion_Gstreamer_Video *)video; - if (ev->audio_mute == mute) - return; + if (!ev->pipeline) return ; ev->audio_mute = mute; - volume = gst_bin_get_by_name(GST_BIN(ev->pipeline), "volume"); - if (!volume) return; - - if (mute) - g_object_set(G_OBJECT(volume), "volume", 0.0, NULL); - else - g_object_set(G_OBJECT(volume), "volume", ev->volume * 10.0, NULL); - gst_object_unref(volume); + g_object_set(G_OBJECT(ev->pipeline), "mute", !!mute, NULL); } static int @@ -1010,23 +1137,20 @@ em_audio_channel_mute_get(void *video) static void em_audio_channel_volume_set(void *video, - double vol) + double vol) { Emotion_Gstreamer_Video *ev; - GstElement *volume; ev = (Emotion_Gstreamer_Video *)video; + if (!ev->pipeline) return ; + if (vol < 0.0) vol = 0.0; if (vol > 1.0) vol = 1.0; ev->volume = vol; - volume = gst_bin_get_by_name(GST_BIN(ev->pipeline), "volume"); - if (!volume) return; - g_object_set(G_OBJECT(volume), "volume", - vol * 10.0, NULL); - gst_object_unref(volume); + g_object_set(G_OBJECT(ev->pipeline), "volume", vol, NULL); } static double @@ -1042,122 +1166,76 @@ em_audio_channel_volume_get(void *video) /* spu stuff */ static int -em_spu_channel_count(void *video) +em_spu_channel_count(void *video __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; - return 0; } static void -em_spu_channel_set(void *video, int channel) +em_spu_channel_set(void *video __UNUSED__, int channel __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; } static int -em_spu_channel_get(void *video) +em_spu_channel_get(void *video __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; - return 1; } static const char * -em_spu_channel_name_get(void *video, int channel) +em_spu_channel_name_get(void *video __UNUSED__, int channel __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; return NULL; } static void -em_spu_channel_mute_set(void *video, int mute) +em_spu_channel_mute_set(void *video __UNUSED__, int mute __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; } static int -em_spu_channel_mute_get(void *video) +em_spu_channel_mute_get(void *video __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; - return 0; } static int -em_chapter_count(void *video) +em_chapter_count(void *video __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; return 0; } static void -em_chapter_set(void *video, int chapter) +em_chapter_set(void *video __UNUSED__, int chapter __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; } static int -em_chapter_get(void *video) +em_chapter_get(void *video __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; - return 0; } static const char * -em_chapter_name_get(void *video, int chapter) +em_chapter_name_get(void *video __UNUSED__, int chapter __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; - return NULL; } static void -em_speed_set(void *video, double speed) +em_speed_set(void *video __UNUSED__, double speed __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; } static double -em_speed_get(void *video) +em_speed_get(void *video __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; - return 1.0; } static int -em_eject(void *video) +em_eject(void *video __UNUSED__) { - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; - return 1; } @@ -1165,7 +1243,7 @@ static const char * em_meta_get(void *video, int meta) { Emotion_Gstreamer_Video *ev; - const char *str; + const char *str = NULL; ev = (Emotion_Gstreamer_Video *)video; @@ -1173,63 +1251,237 @@ em_meta_get(void *video, int meta) switch (meta) { case META_TRACK_TITLE: - str = ev->metadata->title; - break; + str = ev->metadata->title; + break; case META_TRACK_ARTIST: - str = ev->metadata->artist; - break; + str = ev->metadata->artist; + break; case META_TRACK_ALBUM: - str = ev->metadata->album; - break; + str = ev->metadata->album; + break; case META_TRACK_YEAR: - str = ev->metadata->year; - break; + str = ev->metadata->year; + break; case META_TRACK_GENRE: - str = ev->metadata->genre; - break; + str = ev->metadata->genre; + break; case META_TRACK_COMMENT: - str = ev->metadata->comment; - break; + str = ev->metadata->comment; + break; case META_TRACK_DISCID: - str = ev->metadata->disc_id; - break; + str = ev->metadata->disc_id; + break; default: - break; + break; } return str; } -unsigned char +static void +em_priority_set(void *video, Eina_Bool pri) +{ + Emotion_Gstreamer_Video *ev; + + ev = video; + if (priority_overide > 3) return ; /* If we failed to much to create that pipeline, let's don't wast our time anymore */ + + if (ev->priority != pri && ev->pipeline) + { + if (ev->threads) + { + Ecore_Thread *t; + + EINA_LIST_FREE(ev->threads, t) + ecore_thread_cancel(t); + } + em_cleanup(ev); + restart_idler = ecore_idler_add(_em_restart_stream, ev); + } + ev->priority = pri; +} + +static Eina_Bool +em_priority_get(void *video) +{ + Emotion_Gstreamer_Video *ev; + + ev = video; + return !ev->stream; +} + +#ifdef HAVE_ECORE_X +static Eina_Bool +_ecore_event_x_destroy(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__) +{ + Ecore_X_Event_Window_Destroy *ev = event; + + fprintf(stderr, "killed window: %x (%x)\n", ev->win, ev->event_win); + + return EINA_TRUE; +} +#endif + +static Eina_Bool module_open(Evas_Object *obj, - Emotion_Video_Module **module, - void **video, - Emotion_Module_Options *opt) + const Emotion_Video_Module **module, + void **video, + Emotion_Module_Options *opt) { +#ifdef HAVE_ECORE_X + Ecore_X_Window *roots; + int num; +#endif + if (!module) - return 0; + return EINA_FALSE; + + if (_emotion_gstreamer_log_domain < 0) + { + eina_threads_init(); + eina_log_threads_enable(); + _emotion_gstreamer_log_domain = eina_log_domain_register + ("emotion-gstreamer", EINA_COLOR_LIGHTCYAN); + if (_emotion_gstreamer_log_domain < 0) + { + EINA_LOG_CRIT("Could not register log domain 'emotion-gstreamer'"); + return EINA_FALSE; + } + } if (!em_module.init(obj, video, opt)) - return 0; + return EINA_FALSE; + +#ifdef HAVE_ECORE_X + ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _ecore_event_x_destroy, NULL); +#endif + + if (getenv("EMOTION_FPS_DEBUG")) debug_fps = EINA_TRUE; + + eina_threads_init(); + +#ifdef HAVE_ECORE_X + if (ecore_x_init(NULL) > 0) + { + _ecore_x_available = EINA_TRUE; + } + + /* Check if the window manager is able to handle our special Xv window. */ + roots = _ecore_x_available ? ecore_x_window_root_list(&num) : NULL; + if (roots && num > 0) + { + Ecore_X_Window win, twin; + int nwins; + + nwins = ecore_x_window_prop_window_get(roots[0], + ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, + &win, 1); + if (nwins > 0) + { + nwins = ecore_x_window_prop_window_get(win, + ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, + &twin, 1); + if (nwins > 0 && twin == win) + { + Ecore_X_Atom *supported; + int supported_num; + int i; + + if (ecore_x_netwm_supported_get(roots[0], &supported, &supported_num)) + { + Eina_Bool parent = EINA_FALSE; + Eina_Bool video_position = EINA_FALSE; + + for (i = 0; i < supported_num; ++i) + { + if (supported[i] == ECORE_X_ATOM_E_VIDEO_PARENT) + parent = EINA_TRUE; + else if (supported[i] == ECORE_X_ATOM_E_VIDEO_POSITION) + video_position = EINA_TRUE; + if (parent && video_position) + break; + } + + if (parent && video_position) + { + window_manager_video = EINA_TRUE; + } + } + } + } + } + free(roots); +#endif *module = &em_module; - return 1; + return EINA_TRUE; } -void -module_close(Emotion_Video_Module *module, - void *video) +static void +module_close(Emotion_Video_Module *module __UNUSED__, + void *video) { em_module.shutdown(video); + +#ifdef HAVE_ECORE_X + if (_ecore_x_available) + { + ecore_x_shutdown(); + } +#endif + + eina_threads_shutdown(); +} + +Eina_Bool +gstreamer_module_init(void) +{ + GError *error; + + if (!gst_init_check(0, NULL, &error)) + { + EINA_LOG_CRIT("Could not init GStreamer"); + return EINA_FALSE; + } + + if (gst_plugin_register_static(GST_VERSION_MAJOR, GST_VERSION_MINOR, + "emotion-sink", + "video sink plugin for Emotion", + gstreamer_plugin_init, + VERSION, + "LGPL", + "Enlightenment", + PACKAGE, + "http://www.enlightenment.org/") == FALSE) + { + EINA_LOG_CRIT("Could not load static gstreamer video sink for Emotion."); + return EINA_FALSE; + } + + return _emotion_module_register("gstreamer", module_open, module_close); } +void +gstreamer_module_shutdown(void) +{ + _emotion_module_unregister("gstreamer"); + + gst_deinit(); +} + +#ifndef EMOTION_STATIC_BUILD_GSTREAMER + +EINA_MODULE_INIT(gstreamer_module_init); +EINA_MODULE_SHUTDOWN(gstreamer_module_shutdown); + +#endif + static void _for_each_tag(GstTagList const* list, - gchar const* tag, - void *data) + gchar const* tag, + void *data) { Emotion_Gstreamer_Video *ev; - const GValue *val; int i; int count; @@ -1239,102 +1491,101 @@ _for_each_tag(GstTagList const* list, if (!ev || !ev->metadata) return; count = gst_tag_list_get_tag_size(list, tag); - val = gst_tag_list_get_value_index(list, tag, 0); for (i = 0; i < count; i++) { - if (!strcmp(tag, GST_TAG_TITLE)) - { - char *str; - if (ev->metadata->title) g_free(ev->metadata->title); - if (gst_tag_list_get_string(list, GST_TAG_TITLE, &str)) - ev->metadata->title = str; - else - ev->metadata->title = NULL; - break; - } - if (!strcmp(tag, GST_TAG_ALBUM)) - { - gchar *str; - if (ev->metadata->album) g_free(ev->metadata->album); - if (gst_tag_list_get_string(list, GST_TAG_ALBUM, &str)) - ev->metadata->album = str; - else - ev->metadata->album = NULL; - break; - } - if (!strcmp(tag, GST_TAG_ARTIST)) - { - gchar *str; - if (ev->metadata->artist) g_free( ev->metadata->artist); - if (gst_tag_list_get_string(list, GST_TAG_ARTIST, &str)) - ev->metadata->artist = str; - else - ev->metadata->artist = NULL; - break; - } - if (!strcmp(tag, GST_TAG_GENRE)) - { - gchar *str; - if (ev->metadata->genre) g_free( ev->metadata->genre); - if (gst_tag_list_get_string(list, GST_TAG_GENRE, &str)) - ev->metadata->genre = str; - else - ev->metadata->genre = NULL; - break; - } - if (!strcmp(tag, GST_TAG_COMMENT)) - { - gchar *str; - if (ev->metadata->comment) g_free(ev->metadata->comment); - if (gst_tag_list_get_string(list, GST_TAG_COMMENT, &str)) - ev->metadata->comment = str; - else - ev->metadata->comment = NULL; - break; - } - if (!strcmp(tag, GST_TAG_DATE)) - { - gchar *str; - const GValue *date; - if (ev->metadata->year) g_free(ev->metadata->year); - date = gst_tag_list_get_value_index(list, GST_TAG_DATE, 0); - if (date) + if (!strcmp(tag, GST_TAG_TITLE)) + { + char *str; + g_free(ev->metadata->title); + if (gst_tag_list_get_string(list, GST_TAG_TITLE, &str)) + ev->metadata->title = str; + else + ev->metadata->title = NULL; + break; + } + if (!strcmp(tag, GST_TAG_ALBUM)) + { + gchar *str; + g_free(ev->metadata->album); + if (gst_tag_list_get_string(list, GST_TAG_ALBUM, &str)) + ev->metadata->album = str; + else + ev->metadata->album = NULL; + break; + } + if (!strcmp(tag, GST_TAG_ARTIST)) + { + gchar *str; + g_free(ev->metadata->artist); + if (gst_tag_list_get_string(list, GST_TAG_ARTIST, &str)) + ev->metadata->artist = str; + else + ev->metadata->artist = NULL; + break; + } + if (!strcmp(tag, GST_TAG_GENRE)) + { + gchar *str; + g_free(ev->metadata->genre); + if (gst_tag_list_get_string(list, GST_TAG_GENRE, &str)) + ev->metadata->genre = str; + else + ev->metadata->genre = NULL; + break; + } + if (!strcmp(tag, GST_TAG_COMMENT)) + { + gchar *str; + g_free(ev->metadata->comment); + if (gst_tag_list_get_string(list, GST_TAG_COMMENT, &str)) + ev->metadata->comment = str; + else + ev->metadata->comment = NULL; + break; + } + if (!strcmp(tag, GST_TAG_DATE)) + { + gchar *str; + const GValue *date; + g_free(ev->metadata->year); + date = gst_tag_list_get_value_index(list, GST_TAG_DATE, 0); + if (date) str = g_strdup_value_contents(date); - else - str = NULL; - ev->metadata->year = str; - break; - } - - if (!strcmp(tag, GST_TAG_TRACK_NUMBER)) - { - gchar *str; - const GValue *track; - if (ev->metadata->count) g_free( ev->metadata->count); - track = gst_tag_list_get_value_index(list, GST_TAG_TRACK_NUMBER, 0); - if (track) - str = g_strdup_value_contents(track); - else - str = NULL; - ev->metadata->count = str; - break; - } + else + str = NULL; + ev->metadata->year = str; + break; + } + + if (!strcmp(tag, GST_TAG_TRACK_NUMBER)) + { + gchar *str; + const GValue *track; + g_free(ev->metadata->count); + track = gst_tag_list_get_value_index(list, GST_TAG_TRACK_NUMBER, 0); + if (track) + str = g_strdup_value_contents(track); + else + str = NULL; + ev->metadata->count = str; + break; + } #ifdef GST_TAG_CDDA_CDDB_DISCID - if (!strcmp(tag, GST_TAG_CDDA_CDDB_DISCID)) - { - gchar *str; - const GValue *discid; - if (ev->metadata->disc_id) g_free(ev->metadata->disc_id); - discid = gst_tag_list_get_value_index(list, GST_TAG_CDDA_CDDB_DISCID, 0); - if (discid) - str = g_strdup_value_contents(discid); - else - str = NULL; - ev->metadata->disc_id = str; - break; - } + if (!strcmp(tag, GST_TAG_CDDA_CDDB_DISCID)) + { + gchar *str; + const GValue *discid; + g_free(ev->metadata->disc_id); + discid = gst_tag_list_get_value_index(list, GST_TAG_CDDA_CDDB_DISCID, 0); + if (discid) + str = g_strdup_value_contents(discid); + else + str = NULL; + ev->metadata->disc_id = str; + break; + } #endif } @@ -1345,96 +1596,541 @@ _free_metadata(Emotion_Gstreamer_Metadata *m) { if (!m) return; - if (m->title) g_free(m->title); - if (m->album) g_free(m->album); - if (m->artist) g_free(m->artist); - if (m->genre) g_free(m->genre); - if (m->comment) g_free(m->comment); - if (m->year) g_free(m->year); - if (m->count) g_free(m->count); - if (m->disc_id) g_free(m->disc_id); + g_free(m->title); + g_free(m->album); + g_free(m->artist); + g_free(m->genre); + g_free(m->comment); + g_free(m->year); + g_free(m->count); + g_free(m->disc_id); free(m); } -static int -_em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh) +static Eina_Bool +_em_restart_stream(void *data) { - int fd; - int len; - void *buf[2]; - unsigned char *frame_data; Emotion_Gstreamer_Video *ev; - GstBuffer *buffer; ev = data; - fd = ecore_main_fd_handler_fd_get(fdh); - while ((len = read(fd, buf, sizeof(buf))) > 0) + ev->pipeline = gstreamer_video_sink_new(ev, ev->obj, ev->uri); + + if (ev->pipeline) { - if (len == sizeof(buf)) - { - Emotion_Video_Sink *vsink; - - frame_data = buf[0]; - buffer = buf[1]; - _emotion_frame_new(ev->obj); - vsink = (Emotion_Video_Sink *)ecore_list_index_goto(ev->video_sinks, ev->video_sink_nbr); - if (vsink) _emotion_video_pos_update(ev->obj, ev->position, vsink->length_time); - } + ev->eos_bus = gst_pipeline_get_bus(GST_PIPELINE(ev->pipeline)); + if (!ev->eos_bus) + { + ERR("could not get the bus"); + return EINA_FALSE; + } + + gst_bus_set_sync_handler(ev->eos_bus, _eos_sync_fct, ev); } - return 1; + + restart_idler = NULL; + + return ECORE_CALLBACK_CANCEL; } -static int -_eos_timer_fct(void *data) +static Eina_Bool +_video_size_get(GstElement *elem, int *width, int *height) { + GstIterator *itr = NULL; + GstCaps *caps; + GstStructure *str; + gpointer pad; + Eina_Bool ret = EINA_FALSE; + + itr = gst_element_iterate_src_pads(elem); + while(gst_iterator_next(itr, &pad) && !ret) + { + caps = gst_pad_get_caps(GST_PAD(pad)); + str = gst_caps_get_structure(caps, 0); + if (g_strrstr(gst_structure_get_name(str), "video")) + { + if (gst_structure_get_int(str, "width", width) && gst_structure_get_int(str, "height", height)) + ret = EINA_TRUE; + } + gst_caps_unref(caps); + gst_object_unref(pad); + } + gst_iterator_free(itr); + + return ret; +} + +static void +_main_frame_resize(void *data) +{ + Emotion_Gstreamer_Video *ev = data; + double ratio; + + ratio = (double)ev->src_width / (double)ev->src_height; + _emotion_frame_resize(ev->obj, ev->src_width, ev->src_height, ratio); +} + +static void +_no_more_pads(GstElement *decodebin, gpointer data) +{ + GstIterator *itr = NULL; + gpointer elem; + Emotion_Gstreamer_Video *ev = data; + + itr = gst_bin_iterate_elements(GST_BIN(decodebin)); + while(gst_iterator_next(itr, &elem)) + { + if(_video_size_get(GST_ELEMENT(elem), &ev->src_width, &ev->src_height)) + { + ecore_main_loop_thread_safe_call_async(_main_frame_resize, ev); + gst_object_unref(elem); + break; + } + gst_object_unref(elem); + } + gst_iterator_free(itr); +} + +static void +_eos_main_fct(void *data) +{ + Emotion_Gstreamer_Message *send; Emotion_Gstreamer_Video *ev; GstMessage *msg; - ev = (Emotion_Gstreamer_Video *)data; - while ((msg = gst_bus_poll(ev->eos_bus, GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_TAG, 0))) + send = data; + ev = send->ev; + msg = send->msg; + + if (ev->play_started && !ev->delete_me) { - switch (GST_MESSAGE_TYPE(msg)) - { - case GST_MESSAGE_ERROR: - { - gchar *debug; - GError *err; - - gst_message_parse_error(msg, &err, &debug); - g_free(debug); - - g_print("Error: %s\n", err->message); - g_error_free(err); - - break; - } - case GST_MESSAGE_EOS: - if (ev->eos_timer) - { - ecore_timer_del(ev->eos_timer); - ev->eos_timer = NULL; - } - ev->play = 0; - _emotion_decode_stop(ev->obj); - _emotion_playback_finished(ev->obj); - break; - case GST_MESSAGE_TAG: - { - GstTagList *new_tags; - gst_message_parse_tag(msg, &new_tags); - if (new_tags) - { - gst_tag_list_foreach(new_tags, (GstTagForeachFunc)_for_each_tag, ev); - gst_tag_list_free(new_tags); - } - break; - } - default: - break; - } - gst_message_unref(msg); + _emotion_playback_started(ev->obj); + ev->play_started = 0; } - return 1; + + switch (GST_MESSAGE_TYPE(msg)) + { + case GST_MESSAGE_EOS: + if (!ev->delete_me) + { + ev->play = 0; + _emotion_decode_stop(ev->obj); + _emotion_playback_finished(ev->obj); + } + break; + case GST_MESSAGE_TAG: + if (!ev->delete_me) + { + GstTagList *new_tags; + gst_message_parse_tag(msg, &new_tags); + if (new_tags) + { + gst_tag_list_foreach(new_tags, + (GstTagForeachFunc)_for_each_tag, + ev); + gst_tag_list_free(new_tags); + } + } + break; + case GST_MESSAGE_ASYNC_DONE: + if (!ev->delete_me) _emotion_seek_done(ev->obj); + break; + case GST_MESSAGE_STREAM_STATUS: + break; + case GST_MESSAGE_STATE_CHANGED: + if (!ev->delete_me) + { + if (!g_signal_handlers_disconnect_by_func(msg->src, _no_more_pads, ev)) + g_signal_connect(msg->src, "no-more-pads", G_CALLBACK(_no_more_pads), ev); + } + break; + case GST_MESSAGE_ERROR: + em_cleanup(ev); + + if (ev->priority) + { + ERR("Switching back to canvas rendering."); + ev->priority = EINA_FALSE; + priority_overide++; + + restart_idler = ecore_idler_add(_em_restart_stream, ev); + } + break; + default: + ERR("bus say: %s [%i - %s]", + GST_MESSAGE_SRC_NAME(msg), + GST_MESSAGE_TYPE(msg), + GST_MESSAGE_TYPE_NAME(msg)); + break; + } + + emotion_gstreamer_message_free(send); +} + +static GstBusSyncReply +_eos_sync_fct(GstBus *bus __UNUSED__, GstMessage *msg, gpointer data) +{ + Emotion_Gstreamer_Video *ev = data; + Emotion_Gstreamer_Message *send; + + switch (GST_MESSAGE_TYPE(msg)) + { + case GST_MESSAGE_EOS: + case GST_MESSAGE_TAG: + case GST_MESSAGE_ASYNC_DONE: + case GST_MESSAGE_STREAM_STATUS: + INF("bus say: %s [%i - %s]", + GST_MESSAGE_SRC_NAME(msg), + GST_MESSAGE_TYPE(msg), + GST_MESSAGE_TYPE_NAME(msg)); + send = emotion_gstreamer_message_alloc(ev, msg); + + if (send) ecore_main_loop_thread_safe_call_async(_eos_main_fct, send); + + break; + + case GST_MESSAGE_STATE_CHANGED: + { + GstState old_state, new_state; + + gst_message_parse_state_changed(msg, &old_state, &new_state, NULL); + INF("Element %s changed state from %s to %s.", + GST_OBJECT_NAME(msg->src), + gst_element_state_get_name(old_state), + gst_element_state_get_name(new_state)); + + if (!strncmp(GST_OBJECT_NAME(msg->src), "decodebin", 9) && !strcmp(gst_element_state_get_name(new_state), "READY")) + { + send = emotion_gstreamer_message_alloc(ev, msg); + + if (send) ecore_main_loop_thread_safe_call_async(_eos_main_fct, send); + } + break; + } + case GST_MESSAGE_ERROR: + { + GError *error; + gchar *debug; + + gst_message_parse_error(msg, &error, &debug); + ERR("ERROR from element %s: %s", GST_OBJECT_NAME(msg->src), error->message); + ERR("Debugging info: %s", (debug) ? debug : "none"); + g_error_free(error); + g_free(debug); + + if (strncmp(GST_OBJECT_NAME(msg->src), "xvimagesink", 11) == 0) + { + send = emotion_gstreamer_message_alloc(ev, msg); + + if (send) ecore_main_loop_thread_safe_call_async(_eos_main_fct, send); + } + break; + } + case GST_MESSAGE_WARNING: + { + GError *error; + gchar *debug; + + gst_message_parse_warning(msg, &error, &debug); + WRN("WARNING from element %s: %s", GST_OBJECT_NAME(msg->src), error->message); + WRN("Debugging info: %s", (debug) ? debug : "none"); + g_error_free(error); + g_free(debug); + break; + } + default: + WRN("bus say: %s [%i - %s]", + GST_MESSAGE_SRC_NAME(msg), + GST_MESSAGE_TYPE(msg), + GST_MESSAGE_TYPE_NAME(msg)); + break; + } + + gst_message_unref(msg); + + return GST_BUS_DROP; +} + +Eina_Bool +_emotion_gstreamer_video_pipeline_parse(Emotion_Gstreamer_Video *ev, + Eina_Bool force) +{ + gboolean res; + int i; + + if (ev->pipeline_parsed) + return EINA_TRUE; + + if (force && ev->threads) + { + Ecore_Thread *t; + + EINA_LIST_FREE(ev->threads, t) + ecore_thread_cancel(t); + } + + if (ev->threads) + return EINA_FALSE; + + res = gst_element_get_state(ev->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + if (res == GST_STATE_CHANGE_NO_PREROLL) + { + gst_element_set_state(ev->pipeline, GST_STATE_PLAYING); + + res = gst_element_get_state(ev->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + } + + /** NOTE: you need to set: GST_DEBUG_DUMP_DOT_DIR=/tmp EMOTION_ENGINE=gstreamer to save the $EMOTION_GSTREAMER_DOT file in '/tmp' */ + /** then call dot -Tpng -oemotion_pipeline.png /tmp/$TIMESTAMP-$EMOTION_GSTREAMER_DOT.dot */ + if (getenv("EMOTION_GSTREAMER_DOT")) + GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(ev->pipeline), + GST_DEBUG_GRAPH_SHOW_ALL, + getenv("EMOTION_GSTREAMER_DOT")); + + if (!(res == GST_STATE_CHANGE_SUCCESS + || res == GST_STATE_CHANGE_NO_PREROLL)) + { + ERR("Unable to get GST_CLOCK_TIME_NONE."); + return EINA_FALSE; + } + + g_object_get(G_OBJECT(ev->pipeline), + "n-audio", &ev->audio_stream_nbr, + "n-video", &ev->video_stream_nbr, + NULL); + + if ((ev->video_stream_nbr == 0) && (ev->audio_stream_nbr == 0)) + { + ERR("No audio nor video stream found"); + return EINA_FALSE; + } + + /* video stream */ + for (i = 0; i < ev->video_stream_nbr; i++) + { + Emotion_Video_Stream *vstream; + GstPad *pad = NULL; + GstCaps *caps; + GstStructure *structure; + GstQuery *query; + const GValue *val; + gchar *str; + + gdouble length_time = 0.0; + gint width; + gint height; + gint fps_num; + gint fps_den; + guint32 fourcc = 0; + + g_signal_emit_by_name(ev->pipeline, "get-video-pad", i, &pad); + if (!pad) + continue; + + caps = gst_pad_get_negotiated_caps(pad); + if (!caps) + goto unref_pad_v; + structure = gst_caps_get_structure(caps, 0); + str = gst_caps_to_string(caps); + + if (!gst_structure_get_int(structure, "width", &width)) + goto unref_caps_v; + if (!gst_structure_get_int(structure, "height", &height)) + goto unref_caps_v; + if (!gst_structure_get_fraction(structure, "framerate", &fps_num, &fps_den)) + goto unref_caps_v; + + if (g_str_has_prefix(str, "video/x-raw-yuv")) + { + val = gst_structure_get_value(structure, "format"); + fourcc = gst_value_get_fourcc(val); + } + else if (g_str_has_prefix(str, "video/x-raw-rgb")) + fourcc = GST_MAKE_FOURCC('A', 'R', 'G', 'B'); + else + goto unref_caps_v; + + query = gst_query_new_duration(GST_FORMAT_TIME); + if (gst_pad_peer_query(pad, query)) + { + gint64 t; + + gst_query_parse_duration(query, NULL, &t); + length_time = (double)t / (double)GST_SECOND; + } + else + goto unref_query_v; + + vstream = emotion_video_stream_new(ev); + if (!vstream) goto unref_query_v; + + vstream->length_time = length_time; + vstream->width = width; + vstream->height = height; + vstream->fps_num = fps_num; + vstream->fps_den = fps_den; + vstream->fourcc = fourcc; + vstream->index = i; + + unref_query_v: + gst_query_unref(query); + unref_caps_v: + gst_caps_unref(caps); + unref_pad_v: + gst_object_unref(pad); + } + + /* Audio streams */ + for (i = 0; i < ev->audio_stream_nbr; i++) + { + Emotion_Audio_Stream *astream; + GstPad *pad; + GstCaps *caps; + GstStructure *structure; + GstQuery *query; + + gdouble length_time = 0.0; + gint channels; + gint samplerate; + + g_signal_emit_by_name(ev->pipeline, "get-audio-pad", i, &pad); + if (!pad) + continue; + + caps = gst_pad_get_negotiated_caps(pad); + if (!caps) + goto unref_pad_a; + structure = gst_caps_get_structure(caps, 0); + + if (!gst_structure_get_int(structure, "channels", &channels)) + goto unref_caps_a; + if (!gst_structure_get_int(structure, "rate", &samplerate)) + goto unref_caps_a; + + query = gst_query_new_duration(GST_FORMAT_TIME); + if (gst_pad_peer_query(pad, query)) + { + gint64 t; + + gst_query_parse_duration(query, NULL, &t); + length_time = (double)t / (double)GST_SECOND; + } + else + goto unref_query_a; + + astream = calloc(1, sizeof(Emotion_Audio_Stream)); + if (!astream) continue; + ev->audio_streams = eina_list_append(ev->audio_streams, astream); + if (eina_error_get()) + { + free(astream); + continue; + } + + astream->length_time = length_time; + astream->channels = channels; + astream->samplerate = samplerate; + + unref_query_a: + gst_query_unref(query); + unref_caps_a: + gst_caps_unref(caps); + unref_pad_a: + gst_object_unref(pad); + } + + /* Visualization sink */ + if (ev->video_stream_nbr == 0) + { + GstElement *vis = NULL; + Emotion_Video_Stream *vstream; + Emotion_Audio_Stream *astream; + gint flags; + const char *vis_name; + + if (!(vis_name = emotion_visualization_element_name_get(ev->vis))) + { + WRN("pb vis name %d", ev->vis); + goto finalize; + } + + astream = eina_list_data_get(ev->audio_streams); + + vis = gst_element_factory_make(vis_name, "vissink"); + vstream = emotion_video_stream_new(ev); + if (!vstream) + goto finalize; + else + DBG("could not create visualization stream"); + + vstream->length_time = astream->length_time; + vstream->width = 320; + vstream->height = 200; + vstream->fps_num = 25; + vstream->fps_den = 1; + vstream->fourcc = GST_MAKE_FOURCC('A', 'R', 'G', 'B'); + + g_object_set(G_OBJECT(ev->pipeline), "vis-plugin", vis, NULL); + g_object_get(G_OBJECT(ev->pipeline), "flags", &flags, NULL); + flags |= 0x00000008; + g_object_set(G_OBJECT(ev->pipeline), "flags", flags, NULL); + } + + finalize: + + ev->video_stream_nbr = eina_list_count(ev->video_streams); + ev->audio_stream_nbr = eina_list_count(ev->audio_streams); + + if (ev->video_stream_nbr == 1) + { + Emotion_Video_Stream *vstream; + + vstream = eina_list_data_get(ev->video_streams); + ev->ratio = (double)vstream->width / (double)vstream->height; + _emotion_frame_resize(ev->obj, vstream->width, vstream->height, ev->ratio); + } + + { + /* on recapitule : */ + Emotion_Video_Stream *vstream; + Emotion_Audio_Stream *astream; + + vstream = eina_list_data_get(ev->video_streams); + if (vstream) + { + DBG("video size=%dx%d, fps=%d/%d, " + "fourcc=%"GST_FOURCC_FORMAT", length=%"GST_TIME_FORMAT, + vstream->width, vstream->height, vstream->fps_num, vstream->fps_den, + GST_FOURCC_ARGS(vstream->fourcc), + GST_TIME_ARGS((guint64)(vstream->length_time * GST_SECOND))); + } + + astream = eina_list_data_get(ev->audio_streams); + if (astream) + { + DBG("audio channels=%d, rate=%d, length=%"GST_TIME_FORMAT, + astream->channels, astream->samplerate, + GST_TIME_ARGS((guint64)(astream->length_time * GST_SECOND))); + } + } + + if (ev->metadata) + _free_metadata(ev->metadata); + ev->metadata = calloc(1, sizeof(Emotion_Gstreamer_Metadata)); + + ev->pipeline_parsed = EINA_TRUE; + + em_audio_channel_volume_set(ev, ev->volume); + em_audio_channel_mute_set(ev, ev->audio_mute); + + if (ev->play_started) + { + _emotion_playback_started(ev->obj); + ev->play_started = 0; + } + + _emotion_open_done(ev->obj); + + return EINA_TRUE; } diff --git a/src/modules/gstreamer/emotion_gstreamer.h b/src/modules/gstreamer/emotion_gstreamer.h index b335604..9c7455d 100644 --- a/src/modules/gstreamer/emotion_gstreamer.h +++ b/src/modules/gstreamer/emotion_gstreamer.h @@ -1,46 +1,40 @@ -/* - * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 - */ #ifndef __EMOTION_GSTREAMER_H__ #define __EMOTION_GSTREAMER_H__ +typedef void (*Evas_Video_Convert_Cb)(unsigned char *evas_data, + const unsigned char *gst_data, + unsigned int w, + unsigned int h, + unsigned int output_height); -#include -#include -#include - -#define HTTP_STREAM 0 -#define RTSP_STREAM 1 -#include - -#include "emotion_private.h" - - -typedef struct _Emotion_Video_Sink Emotion_Video_Sink; +typedef struct _EvasVideoSinkPrivate EvasVideoSinkPrivate; +typedef struct _EvasVideoSink EvasVideoSink; +typedef struct _EvasVideoSinkClass EvasVideoSinkClass; +typedef struct _Emotion_Gstreamer_Video Emotion_Gstreamer_Video; +typedef struct _Emotion_Audio_Stream Emotion_Audio_Stream; +typedef struct _Emotion_Gstreamer_Metadata Emotion_Gstreamer_Metadata; +typedef struct _Emotion_Gstreamer_Buffer Emotion_Gstreamer_Buffer; +typedef struct _Emotion_Gstreamer_Message Emotion_Gstreamer_Message; +typedef struct _Emotion_Video_Stream Emotion_Video_Stream; -struct _Emotion_Video_Sink +struct _Emotion_Video_Stream { - GstElement *sink; gdouble length_time; gint width; gint height; gint fps_num; gint fps_den; guint32 fourcc; + int index; }; -typedef struct _Emotion_Audio_Sink Emotion_Audio_Sink; - -struct _Emotion_Audio_Sink +struct _Emotion_Audio_Stream { - GstElement *sink; gdouble length_time; gint channels; gint samplerate; }; -typedef struct _Emotion_Gstreamer_Metadata Emotion_Gstreamer_Metadata; - struct _Emotion_Gstreamer_Metadata { char *title; @@ -53,28 +47,36 @@ struct _Emotion_Gstreamer_Metadata char *disc_id; }; - -typedef struct _Emotion_Gstreamer_Video Emotion_Gstreamer_Video; - struct _Emotion_Gstreamer_Video { /* Gstreamer elements */ GstElement *pipeline; + GstElement *sink; + GstElement *esink; + GstElement *xvsink; + GstElement *tee; + GstElement *convert; + + GstPad *eteepad; + GstPad *xvteepad; + GstPad *xvpad; + Eina_List *threads; /* eos */ GstBus *eos_bus; - Ecore_Timer *eos_timer; - /* Sinks */ - Ecore_List *video_sinks; - Ecore_List *audio_sinks; + /* Strams */ + Eina_List *video_streams; + Eina_List *audio_streams; - int video_sink_nbr; - int audio_sink_nbr; + int video_stream_nbr; + int audio_stream_nbr; + + /* We need to keep a copy of the last inserted buffer as evas doesn't copy YUV data around */ + GstBuffer *last_buffer; /* Evas object */ Evas_Object *obj; - unsigned char *obj_data; /* Characteristics of stream */ double position; @@ -83,27 +85,246 @@ struct _Emotion_Gstreamer_Video volatile int seek_to; volatile int get_poslen; - volatile double seek_to_pos; - - int fd_ev_read; - int fd_ev_write; - Ecore_Fd_Handler *fd_ev_handler; Emotion_Gstreamer_Metadata *metadata; +#ifdef HAVE_ECORE_X + Ecore_X_Window win; +#endif + + const char *uri; + + Emotion_Gstreamer_Buffer *send; + + EvasVideoSinkPrivate *sink_data; + Emotion_Vis vis; - unsigned char play : 1; - unsigned char video_mute : 1; - unsigned char audio_mute : 1; + int in; + int out; + + int frames; + int flapse; + double rtime; + double rlapse; + + struct + { + double width; + double height; + } fill; + + Eina_Bool play : 1; + Eina_Bool play_started : 1; + Eina_Bool video_mute : 1; + Eina_Bool audio_mute : 1; + Eina_Bool pipeline_parsed : 1; + Eina_Bool delete_me : 1; + Eina_Bool samsung : 1; + Eina_Bool kill_buffer : 1; + Eina_Bool stream : 1; + Eina_Bool priority : 1; + + int src_width; + int src_height; +}; + +struct _EvasVideoSink { + /*< private >*/ + GstVideoSink parent; + EvasVideoSinkPrivate *priv; +}; + +struct _EvasVideoSinkClass { + /*< private >*/ + GstVideoSinkClass parent_class; +}; + +struct _EvasVideoSinkPrivate { + EINA_REFCOUNT; + + Evas_Object *o; + + Emotion_Gstreamer_Video *ev; + + Evas_Video_Convert_Cb func; + + unsigned int width; + unsigned int height; + unsigned int source_height; + Evas_Colorspace eformat; + + Eina_Lock m; + Eina_Condition c; + + // If this is TRUE all processing should finish ASAP + // This is necessary because there could be a race between + // unlock() and render(), where unlock() wins, signals the + // GCond, then render() tries to render a frame although + // everything else isn't running anymore. This will lead + // to deadlocks because render() holds the stream lock. + // + // Protected by the buffer mutex + Eina_Bool unlocked : 1; + Eina_Bool samsung : 1; /** ST12 will only define a Samsung specific GstBuffer */ }; -unsigned char module_open(Evas_Object *obj, - Emotion_Video_Module **module, - void **video, Emotion_Module_Options *opt); +struct _Emotion_Gstreamer_Buffer +{ + Emotion_Gstreamer_Video *ev; + EvasVideoSinkPrivate *sink; + + GstBuffer *frame; -void module_close(Emotion_Video_Module *module, - void *video); + Eina_Bool preroll : 1; + Eina_Bool force : 1; +}; + +struct _Emotion_Gstreamer_Message +{ + Emotion_Gstreamer_Video *ev; + + GstMessage *msg; +}; + +extern Eina_Bool window_manager_video; +extern Eina_Bool debug_fps; +extern int _emotion_gstreamer_log_domain; +extern Eina_Bool _ecore_x_available; +#define DBG(...) EINA_LOG_DOM_DBG(_emotion_gstreamer_log_domain, __VA_ARGS__) +#define INF(...) EINA_LOG_DOM_INFO(_emotion_gstreamer_log_domain, __VA_ARGS__) +#define WRN(...) EINA_LOG_DOM_WARN(_emotion_gstreamer_log_domain, __VA_ARGS__) +#define ERR(...) EINA_LOG_DOM_ERR(_emotion_gstreamer_log_domain, __VA_ARGS__) +#define CRITICAL(...) EINA_LOG_DOM_CRIT(_emotion_gstreamer_log_domain, __VA_ARGS__) + +#define EVAS_TYPE_VIDEO_SINK evas_video_sink_get_type() + +GType fakeeos_bin_get_type(void); + +#define EVAS_VIDEO_SINK(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + EVAS_TYPE_VIDEO_SINK, EvasVideoSink)) + +#define EVAS_VIDEO_SINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + EVAS_TYPE_VIDEO_SINK, EvasVideoSinkClass)) + +#define EVAS_IS_VIDEO_SINK(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), \ + EVAS_TYPE_VIDEO_SINK)) + +#define EVAS_IS_VIDEO_SINK_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), \ + EVAS_TYPE_VIDEO_SINK)) + +#define EVAS_VIDEO_SINK_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), \ + EVAS_TYPE_VIDEO_SINK, EvasVideoSinkClass)) + +#define GST_TYPE_FAKEEOS_BIN fakeeos_bin_get_type() + +GstElement *gstreamer_video_sink_new(Emotion_Gstreamer_Video *ev, + Evas_Object *obj, + const char *uri); + +gboolean gstreamer_plugin_init(GstPlugin *plugin); + +Emotion_Gstreamer_Buffer *emotion_gstreamer_buffer_alloc(EvasVideoSinkPrivate *sink, + GstBuffer *buffer, + Eina_Bool preroll); +void emotion_gstreamer_buffer_free(Emotion_Gstreamer_Buffer *send); + +Emotion_Gstreamer_Message *emotion_gstreamer_message_alloc(Emotion_Gstreamer_Video *ev, + GstMessage *msg); +void emotion_gstreamer_message_free(Emotion_Gstreamer_Message *send); +Eina_Bool _emotion_gstreamer_video_pipeline_parse(Emotion_Gstreamer_Video *ev, + Eina_Bool force); + +int em_shutdown(void *video); + +typedef struct _ColorSpace_FourCC_Convertion ColorSpace_FourCC_Convertion; +typedef struct _ColorSpace_Format_Convertion ColorSpace_Format_Convertion; + +struct _ColorSpace_FourCC_Convertion +{ + const char *name; + guint32 fourcc; + Evas_Colorspace eformat; + Evas_Video_Convert_Cb func; + Eina_Bool force_height; +}; + +struct _ColorSpace_Format_Convertion +{ + const char *name; + GstVideoFormat format; + Evas_Colorspace eformat; + Evas_Video_Convert_Cb func; +}; + +extern const ColorSpace_FourCC_Convertion colorspace_fourcc_convertion[]; +extern const ColorSpace_Format_Convertion colorspace_format_convertion[]; + +/** Samsung specific infrastructure - do not touch, do not modify */ +#define MPLANE_IMGB_MAX_COUNT 4 +#define SCMN_IMGB_MAX_PLANE 4 + +typedef struct _GstMultiPlaneImageBuffer GstMultiPlaneImageBuffer; +typedef struct _SCMN_IMGB SCMN_IMGB; + +struct _GstMultiPlaneImageBuffer +{ + GstBuffer buffer; + + /* width of each image plane */ + gint width[MPLANE_IMGB_MAX_COUNT]; + /* height of each image plane */ + gint height[MPLANE_IMGB_MAX_COUNT]; + /* stride of each image plane */ + gint stride[MPLANE_IMGB_MAX_COUNT]; + /* elevation of each image plane */ + gint elevation[MPLANE_IMGB_MAX_COUNT]; + /* user space address of each image plane */ + gpointer uaddr[MPLANE_IMGB_MAX_COUNT]; + /* Index of real address of each image plane, if needs */ + gpointer index[MPLANE_IMGB_MAX_COUNT]; + /* left postion, if needs */ + gint x; + /* top position, if needs */ + gint y; + /* to align memory */ + gint __dummy2; + /* arbitrary data */ + gint data[16]; +}; + +struct _SCMN_IMGB +{ + /* width of each image plane */ + int width[SCMN_IMGB_MAX_PLANE]; + /* height of each image plane */ + int height[SCMN_IMGB_MAX_PLANE]; + /* stride of each image plane */ + int stride[SCMN_IMGB_MAX_PLANE]; + /* elevation of each image plane */ + int elevation[SCMN_IMGB_MAX_PLANE]; + /* user space address of each image plane */ + void * uaddr[SCMN_IMGB_MAX_PLANE]; + /* physical address of each image plane, if needs */ + void * p[SCMN_IMGB_MAX_PLANE]; + /* color space type of image */ + int cs; + /* left postion, if needs */ + int x; + /* top position, if needs */ + int y; + /* to align memory */ + int __dummy2; + /* arbitrary data */ + int data[16]; +}; +void _evas_video_st12_multiplane(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w, unsigned int h, unsigned int output_height __UNUSED__); +void _evas_video_st12(unsigned char *evas_data, const unsigned char *gst_data, unsigned int w __UNUSED__, unsigned int h, unsigned int output_height __UNUSED__); #endif /* __EMOTION_GSTREAMER_H__ */ diff --git a/src/modules/gstreamer/emotion_sink.c b/src/modules/gstreamer/emotion_sink.c new file mode 100644 index 0000000..17a1bc5 --- /dev/null +++ b/src/modules/gstreamer/emotion_sink.c @@ -0,0 +1,1391 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#define HTTP_STREAM 0 +#define RTSP_STREAM 1 +#include +#include +#include +#include +#include + +#ifdef HAVE_ECORE_X +# include +# include +# ifdef HAVE_XOVERLAY_H +# include +# endif +#endif + +#include "Emotion.h" +#include "emotion_private.h" +#include "emotion_gstreamer.h" + +static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE("sink", + GST_PAD_SINK, GST_PAD_ALWAYS, + GST_STATIC_CAPS(GST_VIDEO_CAPS_YUV("{ I420, YV12, YUY2, NV12, ST12, TM12 }") ";" + GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_BGR ";" GST_VIDEO_CAPS_BGRA)); + +GST_DEBUG_CATEGORY_STATIC(evas_video_sink_debug); +#define GST_CAT_DEFAULT evas_video_sink_debug + +enum { + REPAINT_REQUESTED, + LAST_SIGNAL +}; + +enum { + PROP_0, + PROP_EVAS_OBJECT, + PROP_WIDTH, + PROP_HEIGHT, + PROP_EV, + PROP_LAST +}; + +static guint evas_video_sink_signals[LAST_SIGNAL] = { 0, }; + +#define _do_init(bla) \ + GST_DEBUG_CATEGORY_INIT(evas_video_sink_debug, \ + "emotion-sink", \ + 0, \ + "emotion video sink") + +GST_BOILERPLATE_FULL(EvasVideoSink, + evas_video_sink, + GstVideoSink, + GST_TYPE_VIDEO_SINK, + _do_init); + + +static void unlock_buffer_mutex(EvasVideoSinkPrivate* priv); +static void evas_video_sink_main_render(void *data); +static void evas_video_sink_samsung_main_render(void *data); + +static void +evas_video_sink_base_init(gpointer g_class) +{ + GstElementClass* element_class; + + element_class = GST_ELEMENT_CLASS(g_class); + gst_element_class_add_pad_template(element_class, gst_static_pad_template_get(&sinktemplate)); + gst_element_class_set_details_simple(element_class, "Evas video sink", + "Sink/Video", "Sends video data from a GStreamer pipeline to an Evas object", + "Vincent Torri "); +} + +static void +evas_video_sink_init(EvasVideoSink* sink, EvasVideoSinkClass* klass __UNUSED__) +{ + EvasVideoSinkPrivate* priv; + + INF("sink init"); + sink->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE(sink, EVAS_TYPE_VIDEO_SINK, EvasVideoSinkPrivate); + priv->o = NULL; + priv->width = 0; + priv->height = 0; + priv->func = NULL; + priv->eformat = EVAS_COLORSPACE_ARGB8888; + priv->samsung = EINA_FALSE; + eina_lock_new(&priv->m); + eina_condition_new(&priv->c, &priv->m); + priv->unlocked = EINA_FALSE; +} + +/**** Object methods ****/ +static void +_cleanup_priv(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) +{ + EvasVideoSinkPrivate* priv; + + priv = data; + + eina_lock_take(&priv->m); + if (priv->o == obj) + priv->o = NULL; + eina_lock_release(&priv->m); +} + +static void +evas_video_sink_set_property(GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + EvasVideoSink* sink; + EvasVideoSinkPrivate* priv; + + sink = EVAS_VIDEO_SINK (object); + priv = sink->priv; + + switch (prop_id) { + case PROP_EVAS_OBJECT: + eina_lock_take(&priv->m); + evas_object_event_callback_del(priv->o, EVAS_CALLBACK_FREE, _cleanup_priv); + priv->o = g_value_get_pointer (value); + INF("sink set Evas_Object %p.", priv->o); + evas_object_event_callback_add(priv->o, EVAS_CALLBACK_FREE, _cleanup_priv, priv); + eina_lock_release(&priv->m); + break; + case PROP_EV: + INF("sink set ev."); + eina_lock_take(&priv->m); + priv->ev = g_value_get_pointer (value); + if (priv->ev) + priv->ev->samsung = EINA_TRUE; + eina_lock_release(&priv->m); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + ERR("invalid property"); + break; + } +} + +static void +evas_video_sink_get_property(GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + EvasVideoSink* sink; + EvasVideoSinkPrivate* priv; + + sink = EVAS_VIDEO_SINK (object); + priv = sink->priv; + + switch (prop_id) { + case PROP_EVAS_OBJECT: + INF("sink get property."); + eina_lock_take(&priv->m); + g_value_set_pointer(value, priv->o); + eina_lock_release(&priv->m); + break; + case PROP_WIDTH: + INF("sink get width."); + eina_lock_take(&priv->m); + g_value_set_int(value, priv->width); + eina_lock_release(&priv->m); + break; + case PROP_HEIGHT: + INF("sink get height."); + eina_lock_take(&priv->m); + g_value_set_int (value, priv->height); + eina_lock_release(&priv->m); + break; + case PROP_EV: + INF("sink get ev."); + eina_lock_take(&priv->m); + g_value_set_pointer (value, priv->ev); + eina_lock_release(&priv->m); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + ERR("invalide property"); + break; + } +} + +static void +evas_video_sink_dispose(GObject* object) +{ + EvasVideoSink* sink; + EvasVideoSinkPrivate* priv; + + INF("dispose."); + + sink = EVAS_VIDEO_SINK(object); + priv = sink->priv; + + eina_lock_free(&priv->m); + eina_condition_free(&priv->c); + + G_OBJECT_CLASS(parent_class)->dispose(object); +} + + +/**** BaseSink methods ****/ + +gboolean evas_video_sink_set_caps(GstBaseSink *bsink, GstCaps *caps) +{ + EvasVideoSink* sink; + EvasVideoSinkPrivate* priv; + GstStructure *structure; + GstVideoFormat format; + guint32 fourcc; + unsigned int i; + + sink = EVAS_VIDEO_SINK(bsink); + priv = sink->priv; + + structure = gst_caps_get_structure(caps, 0); + + if (gst_structure_get_int(structure, "width", (int*) &priv->width) + && gst_structure_get_int(structure, "height", (int*) &priv->height) + && gst_structure_get_fourcc(structure, "format", &fourcc)) + { + priv->source_height = priv->height; + + for (i = 0; colorspace_fourcc_convertion[i].name != NULL; ++i) + if (fourcc == colorspace_fourcc_convertion[i].fourcc) + { + fprintf(stderr, "Found '%s'\n", colorspace_fourcc_convertion[i].name); + priv->eformat = colorspace_fourcc_convertion[i].eformat; + priv->func = colorspace_fourcc_convertion[i].func; + if (colorspace_fourcc_convertion[i].force_height) + { + priv->height = (priv->height >> 1) << 1; + } + if (priv->ev) + priv->ev->kill_buffer = EINA_TRUE; + return TRUE; + } + + if (fourcc == GST_MAKE_FOURCC('S', 'T', '1', '2')) + { + fprintf(stderr, "Found '%s'\n", "ST12"); + priv->eformat = EVAS_COLORSPACE_YCBCR420TM12601_PL; + priv->samsung = EINA_TRUE; + priv->func = NULL; + if (priv->ev) + { + priv->ev->samsung = EINA_TRUE; + priv->ev->kill_buffer = EINA_TRUE; + } + return TRUE; + } + } + + INF("fallback code !"); + if (!gst_video_format_parse_caps(caps, &format, (int*) &priv->width, (int*) &priv->height)) + { + ERR("Unable to parse caps."); + return FALSE; + } + + priv->source_height = priv->height; + + for (i = 0; colorspace_format_convertion[i].name != NULL; ++i) + if (format == colorspace_format_convertion[i].format) + { + fprintf(stderr, "Found '%s'\n", colorspace_format_convertion[i].name); + priv->eformat = colorspace_format_convertion[i].eformat; + priv->func = colorspace_format_convertion[i].func; + if (priv->ev) + priv->ev->kill_buffer = EINA_FALSE; + return TRUE; + } + + ERR("unsupported : %d\n", format); + return FALSE; +} + +static gboolean +evas_video_sink_start(GstBaseSink* base_sink) +{ + EvasVideoSinkPrivate* priv; + gboolean res = TRUE; + + INF("sink start"); + + priv = EVAS_VIDEO_SINK(base_sink)->priv; + eina_lock_take(&priv->m); + if (!priv->o) + res = FALSE; + else + priv->unlocked = EINA_FALSE; + eina_lock_release(&priv->m); + return res; +} + +static gboolean +evas_video_sink_stop(GstBaseSink* base_sink) +{ + EvasVideoSinkPrivate* priv = EVAS_VIDEO_SINK(base_sink)->priv; + + INF("sink stop"); + + unlock_buffer_mutex(priv); + return TRUE; +} + +static gboolean +evas_video_sink_unlock(GstBaseSink* object) +{ + EvasVideoSink* sink; + + INF("sink unlock"); + + sink = EVAS_VIDEO_SINK(object); + + unlock_buffer_mutex(sink->priv); + + return GST_CALL_PARENT_WITH_DEFAULT(GST_BASE_SINK_CLASS, unlock, + (object), TRUE); +} + +static gboolean +evas_video_sink_unlock_stop(GstBaseSink* object) +{ + EvasVideoSink* sink; + EvasVideoSinkPrivate* priv; + + sink = EVAS_VIDEO_SINK(object); + priv = sink->priv; + + INF("sink unlock stop"); + + eina_lock_take(&priv->m); + priv->unlocked = FALSE; + eina_lock_release(&priv->m); + + return GST_CALL_PARENT_WITH_DEFAULT(GST_BASE_SINK_CLASS, unlock_stop, + (object), TRUE); +} + +static GstFlowReturn +evas_video_sink_preroll(GstBaseSink* bsink, GstBuffer* buffer) +{ + Emotion_Gstreamer_Buffer *send; + EvasVideoSinkPrivate *priv; + EvasVideoSink *sink; + + INF("sink preroll %p [%i]", GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer)); + + sink = EVAS_VIDEO_SINK(bsink); + priv = sink->priv; + + if (GST_BUFFER_SIZE(buffer) <= 0 && !priv->samsung) + { + WRN("empty buffer"); + return GST_FLOW_OK; + } + + send = emotion_gstreamer_buffer_alloc(priv, buffer, EINA_TRUE); + + if (send) + { + if (priv->samsung) + { + if (!priv->func) + { + GstStructure *structure; + GstCaps *caps; + gboolean is_multiplane = FALSE; + + caps = GST_BUFFER_CAPS(buffer); + structure = gst_caps_get_structure (caps, 0); + gst_structure_get_boolean(structure, "multiplane", &is_multiplane); + gst_caps_unref(caps); + + if (is_multiplane) + priv->func = _evas_video_st12_multiplane; + else + priv->func = _evas_video_st12; + } + + ecore_main_loop_thread_safe_call_async(evas_video_sink_samsung_main_render, send); + } + else + ecore_main_loop_thread_safe_call_async(evas_video_sink_main_render, send); + } + + return GST_FLOW_OK; +} + +static GstFlowReturn +evas_video_sink_render(GstBaseSink* bsink, GstBuffer* buffer) +{ + Emotion_Gstreamer_Buffer *send; + EvasVideoSinkPrivate *priv; + EvasVideoSink *sink; + + INF("sink render %p", buffer); + + sink = EVAS_VIDEO_SINK(bsink); + priv = sink->priv; + + eina_lock_take(&priv->m); + + if (priv->unlocked) { + ERR("LOCKED"); + eina_lock_release(&priv->m); + return GST_FLOW_OK; + } + + send = emotion_gstreamer_buffer_alloc(priv, buffer, EINA_FALSE); + if (!send) { + eina_lock_release(&priv->m); + return GST_FLOW_ERROR; + } + + if (priv->samsung) + { + if (!priv->func) + { + GstStructure *structure; + GstCaps *caps; + gboolean is_multiplane = FALSE; + + caps = GST_BUFFER_CAPS(buffer); + structure = gst_caps_get_structure (caps, 0); + gst_structure_get_boolean(structure, "multiplane", &is_multiplane); + gst_caps_unref(caps); + + if (is_multiplane) + priv->func = _evas_video_st12_multiplane; + else + priv->func = _evas_video_st12; + } + + ecore_main_loop_thread_safe_call_async(evas_video_sink_samsung_main_render, send); + } + else + ecore_main_loop_thread_safe_call_async(evas_video_sink_main_render, send); + + eina_condition_wait(&priv->c); + eina_lock_release(&priv->m); + + return GST_FLOW_OK; +} + +static void +_update_emotion_fps(Emotion_Gstreamer_Video *ev) +{ + double tim; + + if (!debug_fps) return ; + + tim = ecore_time_get(); + ev->frames++; + + if (ev->rlapse == 0.0) + { + ev->rlapse = tim; + ev->flapse = ev->frames; + } + else if ((tim - ev->rlapse) >= 0.5) + { + printf("FRAME: %i, FPS: %3.1f\n", + ev->frames, + (ev->frames - ev->flapse) / (tim - ev->rlapse)); + ev->rlapse = tim; + ev->flapse = ev->frames; + } +} + +static void +evas_video_sink_samsung_main_render(void *data) +{ + Emotion_Gstreamer_Buffer *send; + Emotion_Video_Stream *vstream; + EvasVideoSinkPrivate *priv = NULL; + GstBuffer* buffer; + unsigned char *evas_data; + const guint8 *gst_data; + GstFormat fmt = GST_FORMAT_TIME; + gint64 pos; + Eina_Bool preroll = EINA_FALSE; + int stride, elevation; + Evas_Coord w, h; + + send = data; + + if (!send) goto exit_point; + + priv = send->sink; + buffer = send->frame; + preroll = send->preroll; + + /* frame after cleanup */ + if (!preroll && !send->ev->last_buffer) + { + priv = NULL; + goto exit_point; + } + + if (!priv || !priv->o || priv->unlocked) + goto exit_point; + + if (send->ev->send) + { + emotion_gstreamer_buffer_free(send->ev->send); + send->ev->send = NULL; + } + + if (!send->ev->stream && !send->force) + { + send->ev->send = send; + _emotion_frame_new(send->ev->obj); + goto exit_stream; + } + + _emotion_gstreamer_video_pipeline_parse(send->ev, EINA_TRUE); + + /* Getting stride to compute the right size and then fill the object properly */ + /* Y => [0] and UV in [1] */ + if (priv->func == _evas_video_st12_multiplane) + { + const GstMultiPlaneImageBuffer *mp_buf = (const GstMultiPlaneImageBuffer *) buffer; + + stride = mp_buf->stride[0]; + elevation = mp_buf->elevation[0]; + priv->width = mp_buf->width[0]; + priv->height = mp_buf->height[0]; + + gst_data = (const guint8 *) mp_buf; + } + else + { + const SCMN_IMGB *imgb = (const SCMN_IMGB *) GST_BUFFER_MALLOCDATA(buffer); + + stride = imgb->stride[0]; + elevation = imgb->elevation[0]; + priv->width = imgb->width[0]; + priv->height = imgb->height[0]; + + gst_data = (const guint8 *) imgb; + } + + evas_object_geometry_get(priv->o, NULL, NULL, &w, &h); + + send->ev->fill.width = (double) stride / priv->width; + send->ev->fill.height = (double) elevation / priv->height; + + evas_object_image_alpha_set(priv->o, 0); + evas_object_image_colorspace_set(priv->o, priv->eformat); + evas_object_image_size_set(priv->o, stride, elevation); + + _update_emotion_fps(send->ev); + + evas_data = evas_object_image_data_get(priv->o, 1); + + if (priv->func) + priv->func(evas_data, gst_data, stride, elevation, elevation); + else + WRN("No way to decode %x colorspace !", priv->eformat); + + evas_object_image_data_set(priv->o, evas_data); + evas_object_image_data_update_add(priv->o, 0, 0, priv->width, priv->height); + evas_object_image_pixels_dirty_set(priv->o, 0); + + if (!preroll && send->ev->play_started) + { + _emotion_playback_started(send->ev->obj); + send->ev->play_started = 0; + } + + if (!send->force) + { + _emotion_frame_new(send->ev->obj); + } + + vstream = eina_list_nth(send->ev->video_streams, send->ev->video_stream_nbr - 1); + + gst_element_query_position(send->ev->pipeline, &fmt, &pos); + send->ev->position = (double)pos / (double)GST_SECOND; + + if (vstream) + { + vstream->width = priv->width; + vstream->height = priv->height; + + _emotion_video_pos_update(send->ev->obj, send->ev->position, vstream->length_time); + } + + send->ev->ratio = (double) priv->width / (double) priv->height; + _emotion_frame_refill(send->ev->obj, send->ev->fill.width, send->ev->fill.height); + _emotion_frame_resize(send->ev->obj, priv->width, priv->height, send->ev->ratio); + + buffer = gst_buffer_ref(buffer); + if (send->ev->last_buffer) gst_buffer_unref(send->ev->last_buffer); + send->ev->last_buffer = buffer; + + exit_point: + emotion_gstreamer_buffer_free(send); + + exit_stream: + if (priv) + { + if (preroll || !priv->o) return; + + if (!priv->unlocked) + eina_condition_signal(&priv->c); + } +} + +static void +evas_video_sink_main_render(void *data) +{ + Emotion_Gstreamer_Buffer *send; + Emotion_Gstreamer_Video *ev = NULL; + Emotion_Video_Stream *vstream; + EvasVideoSinkPrivate *priv = NULL; + GstBuffer *buffer; + unsigned char *evas_data; + GstFormat fmt = GST_FORMAT_TIME; + gint64 pos; + Eina_Bool preroll = EINA_FALSE; + + send = data; + + if (!send) goto exit_point; + + priv = send->sink; + buffer = send->frame; + preroll = send->preroll; + ev = send->ev; + + /* frame after cleanup */ + if (!preroll && !ev->last_buffer) + { + priv = NULL; + goto exit_point; + } + + if (!priv || !priv->o || priv->unlocked) + goto exit_point; + + if (ev->send && send != ev->send) + { + emotion_gstreamer_buffer_free(ev->send); + ev->send = NULL; + } + + if (!ev->stream && !send->force) + { + ev->send = send; + _emotion_frame_new(ev->obj); + evas_object_image_data_update_add(priv->o, 0, 0, priv->width, priv->height); + goto exit_stream; + } + + _emotion_gstreamer_video_pipeline_parse(ev, EINA_TRUE); + + INF("sink main render [%i, %i] (source height: %i)", priv->width, priv->height, priv->source_height); + + evas_object_image_alpha_set(priv->o, 0); + evas_object_image_colorspace_set(priv->o, priv->eformat); + evas_object_image_size_set(priv->o, priv->width, priv->height); + + evas_data = evas_object_image_data_get(priv->o, 1); + + if (priv->func) + priv->func(evas_data, GST_BUFFER_DATA(buffer), priv->width, priv->source_height, priv->height); + else + WRN("No way to decode %x colorspace !", priv->eformat); + + evas_object_image_data_set(priv->o, evas_data); + evas_object_image_data_update_add(priv->o, 0, 0, priv->width, priv->height); + evas_object_image_pixels_dirty_set(priv->o, 0); + + _update_emotion_fps(ev); + + if (!preroll && ev->play_started) + { + _emotion_playback_started(ev->obj); + ev->play_started = 0; + } + + if (!send->force) + { + _emotion_frame_new(ev->obj); + } + + gst_element_query_position(ev->pipeline, &fmt, &pos); + ev->position = (double)pos / (double)GST_SECOND; + + vstream = eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1); + + if (vstream) + { + vstream->width = priv->width; + vstream->height = priv->height; + _emotion_video_pos_update(ev->obj, ev->position, vstream->length_time); + } + + ev->ratio = (double) priv->width / (double) priv->height; + + _emotion_frame_resize(ev->obj, priv->width, priv->height, ev->ratio); + + buffer = gst_buffer_ref(buffer); + if (ev->last_buffer) gst_buffer_unref(ev->last_buffer); + ev->last_buffer = buffer; + + exit_point: + emotion_gstreamer_buffer_free(send); + + exit_stream: + if (priv) + { + if (preroll || !priv->o) return; + + if (!priv->unlocked) + eina_condition_signal(&priv->c); + } +} + +static void +unlock_buffer_mutex(EvasVideoSinkPrivate* priv) +{ + priv->unlocked = EINA_TRUE; + + eina_condition_signal(&priv->c); +} + +static void +marshal_VOID__MINIOBJECT(GClosure * closure, GValue * return_value __UNUSED__, + guint n_param_values, const GValue * param_values, + gpointer invocation_hint __UNUSED__, gpointer marshal_data) +{ + typedef void (*marshalfunc_VOID__MINIOBJECT) (gpointer obj, gpointer arg1, gpointer data2); + marshalfunc_VOID__MINIOBJECT callback; + GCClosure *cc; + gpointer data1, data2; + + cc = (GCClosure *) closure; + + g_return_if_fail(n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA(closure)) { + data1 = closure->data; + data2 = g_value_peek_pointer(param_values + 0); + } else { + data1 = g_value_peek_pointer(param_values + 0); + data2 = closure->data; + } + callback = (marshalfunc_VOID__MINIOBJECT) (marshal_data ? marshal_data : cc->callback); + + callback(data1, gst_value_get_mini_object(param_values + 1), data2); +} + +static void +evas_video_sink_class_init(EvasVideoSinkClass* klass) +{ + GObjectClass* gobject_class; + GstBaseSinkClass* gstbase_sink_class; + + gobject_class = G_OBJECT_CLASS(klass); + gstbase_sink_class = GST_BASE_SINK_CLASS(klass); + + g_type_class_add_private(klass, sizeof(EvasVideoSinkPrivate)); + + gobject_class->set_property = evas_video_sink_set_property; + gobject_class->get_property = evas_video_sink_get_property; + + g_object_class_install_property (gobject_class, PROP_EVAS_OBJECT, + g_param_spec_pointer ("evas-object", "Evas Object", + "The Evas object where the display of the video will be done", + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, PROP_WIDTH, + g_param_spec_int ("width", "Width", + "The width of the video", + 0, 65536, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_HEIGHT, + g_param_spec_int ("height", "Height", + "The height of the video", + 0, 65536, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_EV, + g_param_spec_pointer ("ev", "Emotion_Gstreamer_Video", + "THe internal data of the emotion object", + G_PARAM_READWRITE)); + + gobject_class->dispose = evas_video_sink_dispose; + + gstbase_sink_class->set_caps = evas_video_sink_set_caps; + gstbase_sink_class->stop = evas_video_sink_stop; + gstbase_sink_class->start = evas_video_sink_start; + gstbase_sink_class->unlock = evas_video_sink_unlock; + gstbase_sink_class->unlock_stop = evas_video_sink_unlock_stop; + gstbase_sink_class->render = evas_video_sink_render; + gstbase_sink_class->preroll = evas_video_sink_preroll; + + evas_video_sink_signals[REPAINT_REQUESTED] = g_signal_new("repaint-requested", + G_TYPE_FROM_CLASS(klass), + (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + 0, + 0, + 0, + marshal_VOID__MINIOBJECT, + G_TYPE_NONE, 1, GST_TYPE_BUFFER); +} + +gboolean +gstreamer_plugin_init (GstPlugin * plugin) +{ + return gst_element_register (plugin, + "emotion-sink", + GST_RANK_NONE, + EVAS_TYPE_VIDEO_SINK); +} + +static void +_emotion_gstreamer_pause(void *data, Ecore_Thread *thread) +{ + Emotion_Gstreamer_Video *ev = data; + gboolean res; + + if (ecore_thread_check(thread) || !ev->pipeline) return ; + + gst_element_set_state(ev->pipeline, GST_STATE_PAUSED); + res = gst_element_get_state(ev->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + if (res == GST_STATE_CHANGE_NO_PREROLL) + { + gst_element_set_state(ev->pipeline, GST_STATE_PLAYING); + gst_element_get_state(ev->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + } +} + +static void +_emotion_gstreamer_cancel(void *data, Ecore_Thread *thread) +{ + Emotion_Gstreamer_Video *ev = data; + + ev->threads = eina_list_remove(ev->threads, thread); + + if (getenv("EMOTION_GSTREAMER_DOT")) GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(ev->pipeline), GST_DEBUG_GRAPH_SHOW_ALL, getenv("EMOTION_GSTREAMER_DOT")); + + if (ev->in == ev->out && ev->delete_me) + em_shutdown(ev); +} + +static void +_emotion_gstreamer_end(void *data, Ecore_Thread *thread) +{ + Emotion_Gstreamer_Video *ev = data; + + ev->threads = eina_list_remove(ev->threads, thread); + + if (ev->play) + { + gst_element_set_state(ev->pipeline, GST_STATE_PLAYING); + ev->play_started = 1; + } + + if (getenv("EMOTION_GSTREAMER_DOT")) GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(ev->pipeline), GST_DEBUG_GRAPH_SHOW_ALL, getenv("EMOTION_GSTREAMER_DOT")); + + if (ev->in == ev->out && ev->delete_me) + em_shutdown(ev); + else + _emotion_gstreamer_video_pipeline_parse(data, EINA_TRUE); +} + +static void +_video_resize(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_Surface *surface __UNUSED__, + Evas_Coord w, Evas_Coord h) +{ +#ifdef HAVE_ECORE_X + Emotion_Gstreamer_Video *ev = data; + + ecore_x_window_resize(ev->win, w, h); + fprintf(stderr, "resize: %i, %i\n", w, h); +#endif +} + +static void +_video_move(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_Surface *surface __UNUSED__, + Evas_Coord x, Evas_Coord y) +{ +#ifdef HAVE_ECORE_X + Emotion_Gstreamer_Video *ev = data; + unsigned int pos[2]; + + fprintf(stderr, "move: %i, %i\n", x, y); + pos[0] = x; pos[1] = y; + ecore_x_window_prop_card32_set(ev->win, ECORE_X_ATOM_E_VIDEO_POSITION, pos, 2); +#endif +} + +#if 0 +/* Much better idea to always feed the XvImageSink and let him handle optimizing the rendering as we do */ +static void +_block_pad_unlink_cb(GstPad *pad, gboolean blocked, gpointer user_data) +{ + if (blocked) + { + Emotion_Gstreamer_Video *ev = user_data; + GstEvent *gev; + + gst_pad_unlink(ev->xvteepad, ev->xvpad); + gev = gst_event_new_eos(); + gst_pad_send_event(ev->xvpad, gev); + gst_pad_set_blocked_async(pad, FALSE, _block_pad_unlink_cb, NULL); + } +} + +static void +_block_pad_link_cb(GstPad *pad, gboolean blocked, gpointer user_data) +{ + if (blocked) + { + Emotion_Gstreamer_Video *ev = user_data; + + gst_pad_link(ev->xvteepad, ev->xvpad); + if (ev->play) + gst_element_set_state(ev->xvsink, GST_STATE_PLAYING); + else + gst_element_set_state(ev->xvsink, GST_STATE_PAUSED); + gst_pad_set_blocked_async(pad, FALSE, _block_pad_link_cb, NULL); + } +} +#endif + +static void +_video_show(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_Surface *surface __UNUSED__) +{ +#ifdef HAVE_ECORE_X + Emotion_Gstreamer_Video *ev = data; + + fprintf(stderr, "show xv\n"); + ecore_x_window_show(ev->win); +#endif + /* gst_pad_set_blocked_async(ev->xvteepad, TRUE, _block_pad_link_cb, ev); */ +} + +static void +_video_hide(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_Surface *surface __UNUSED__) +{ +#ifdef HAVE_ECORE_X + Emotion_Gstreamer_Video *ev = data; + + fprintf(stderr, "hide xv\n"); + ecore_x_window_hide(ev->win); +#endif + /* gst_pad_set_blocked_async(ev->xvteepad, TRUE, _block_pad_unlink_cb, ev); */ +} + +static void +_video_update_pixels(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_Surface *surface __UNUSED__) +{ + Emotion_Gstreamer_Video *ev = data; + Emotion_Gstreamer_Buffer *send; + EvasVideoSinkPrivate *priv = NULL; + + if (!ev->send) return ; + + send = ev->send; + priv = send->sink; + send->force = EINA_TRUE; + ev->send = NULL; + + if (priv->samsung) + evas_video_sink_samsung_main_render(send); + else + evas_video_sink_main_render(send); +} + +static void +_image_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) +{ + Emotion_Gstreamer_Video *ev = data; + Evas_Coord width, height; + int image_area, src_area; + double ratio; + + GstElementFactory *cfactory = NULL; + GstElement *convert = NULL, *filter = NULL, *queue = NULL; + GstPad *pad = NULL, *teepad = NULL; + GstCaps *caps = NULL; + Eina_List *l, *engines; + const char *ename, *engine = NULL; + + evas_object_geometry_get(obj, NULL, NULL, &width, &height); + image_area = width * height; + src_area = ev->src_width * ev->src_height; + ratio = (double)image_area / (double)src_area; + + // when an image is much smaller than original video size, + // add fimcconvert element to the pipeline + if (ratio < 0.8 && ev->stream && !ev->convert) + { + cfactory = gst_element_factory_find("fimcconvert"); + if (!cfactory) return; + + convert = gst_element_factory_create(cfactory, NULL); + if (!convert) return; + + // add capsfilter to limit size and formats based on the backend + filter = gst_element_factory_make("capsfilter", "fimccapsfilter"); + if (!filter) + { + gst_object_unref(convert); + return; + } + + engines = evas_render_method_list(); + EINA_LIST_FOREACH(engines, l, ename) + { + if (evas_render_method_lookup(ename) == + evas_output_method_get(evas_object_evas_get(obj))) + { + engine = ename; + break; + } + } + + if (strstr(engine, "software") != NULL) + { + caps = gst_caps_new_simple("video/x-raw-rgb", + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + NULL); + } + else if (strstr(engine, "gl") != NULL) + { + caps = gst_caps_new_simple("video/x-raw-yuv", + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + NULL); + } + g_object_set(G_OBJECT(filter), "caps", caps, NULL); + gst_caps_unref(caps); + + // add new elements to the pipeline + queue = gst_bin_get_by_name(GST_BIN(ev->sink), "equeue"); + gst_element_unlink(ev->tee, queue); + gst_element_release_request_pad(ev->tee, ev->eteepad); + gst_object_unref(ev->eteepad); + + gst_bin_add_many(GST_BIN(ev->sink), convert, filter, NULL); + gst_element_link_many(ev->tee, convert, filter, queue, NULL); + + pad = gst_element_get_pad(convert, "sink"); + teepad = gst_element_get_request_pad(ev->tee, "src%d"); + gst_pad_link(teepad, pad); + gst_object_unref(pad); + + gst_element_sync_state_with_parent(convert); + gst_element_sync_state_with_parent(filter); + + ev->eteepad = teepad; + ev->convert = convert; + evas_render_method_list_free(engines); + + INF("add fimcconvert element. video size: %dx%d. emotion object size: %dx%d", + ev->src_width, ev->src_height, width, height); + } + // set size again to the capsfilter when the image is resized + else if (ev->convert) + { + filter = gst_bin_get_by_name(GST_BIN(ev->sink), "fimccapsfilter"); + + engines = evas_render_method_list(); + EINA_LIST_FOREACH(engines, l, ename) + { + if (evas_render_method_lookup(ename) == + evas_output_method_get(evas_object_evas_get(obj))) + { + engine = ename; + break; + } + } + + if (strstr(engine, "software") != NULL) + { + caps = gst_caps_new_simple("video/x-raw-rgb", + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + NULL); + } + else if (strstr(engine, "gl") != NULL) + { + caps = gst_caps_new_simple("video/x-raw-yuv", + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + NULL); + } + + g_object_set(G_OBJECT(filter), "caps", caps, NULL); + gst_caps_unref(caps); + evas_render_method_list_free(engines); + + INF("set capsfilter size again:. video size: %dx%d. emotion object size: %dx%d", + ev->src_width, ev->src_height, width, height); + } +} + +GstElement * +gstreamer_video_sink_new(Emotion_Gstreamer_Video *ev, + Evas_Object *o, + const char *uri) +{ + GstElement *playbin; + GstElement *bin = NULL; + GstElement *esink = NULL; + GstElement *xvsink = NULL; + GstElement *tee = NULL; + GstElement *queue = NULL; + Evas_Object *obj; + GstPad *pad; + GstPad *teepad; + int flags; + const char *launch; +#if defined HAVE_ECORE_X && defined HAVE_XOVERLAY_H + const char *engine = NULL; + Eina_List *engines; +#endif + + obj = emotion_object_image_get(o); + if (!obj) + { + ERR("Not Evas_Object specified"); + return NULL; + } + + if (!uri) + return NULL; + + launch = emotion_webcam_custom_get(uri); + if (launch) + { + GError *error = NULL; + + playbin = gst_parse_bin_from_description(launch, 1, &error); + if (!playbin) + { + ERR("Unable to setup command : '%s' got error '%s'.", launch, error->message); + g_error_free(error); + return NULL; + } + if (error) + { + WRN("got recoverable error '%s' for command : '%s'.", error->message, launch); + g_error_free(error); + } + } + else + { + playbin = gst_element_factory_make("playbin2", "playbin"); + if (!playbin) + { + ERR("Unable to create 'playbin' GstElement."); + return NULL; + } + } + + bin = gst_bin_new(NULL); + if (!bin) + { + ERR("Unable to create GstBin !"); + goto unref_pipeline; + } + + tee = gst_element_factory_make("tee", NULL); + if (!tee) + { + ERR("Unable to create 'tee' GstElement."); + goto unref_pipeline; + } + +#if defined HAVE_ECORE_X && defined HAVE_XOVERLAY_H + if (window_manager_video) + { + Eina_List *l; + const char *ename; + + engines = evas_render_method_list(); + + EINA_LIST_FOREACH(engines, l, ename) + { + if (evas_render_method_lookup(ename) == + evas_output_method_get(evas_object_evas_get(obj))) + { + engine = ename; + break; + } + } + + if (ev->priority && engine && strstr(engine, "_x11") != NULL) + { + Ecore_Evas *ee; + Evas_Coord x, y, w, h; + Ecore_X_Window win; + Ecore_X_Window parent; + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj)); + + if (w < 4) w = 4; + if (h < 2) h = 2; + + /* Here we really need to have the help of the window manager, this code will change when we update E17. */ + parent = (Ecore_X_Window) ecore_evas_window_get(ee); + fprintf(stderr, "parent: %x\n", parent); + + win = ecore_x_window_new(0, x, y, w, h); + fprintf(stderr, "creating window: %x [%i, %i, %i, %i]\n", win, x, y, w, h); + if (win) + { + Ecore_X_Window_State state[] = { ECORE_X_WINDOW_STATE_SKIP_TASKBAR, ECORE_X_WINDOW_STATE_SKIP_PAGER }; + + ecore_x_netwm_window_state_set(win, state, 2); + ecore_x_window_hide(win); + xvsink = gst_element_factory_make("xvimagesink", NULL); + if (xvsink) + { + unsigned int pos[2]; + +#ifdef HAVE_X_OVERLAY_SET + gst_x_overlay_set_window_handle(GST_X_OVERLAY(xvsink), win); +#else + gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(xvsink), win); +#endif + ev->win = win; + + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_VIDEO_PARENT, &parent, 1); + + pos[0] = x; pos[1] = y; + ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_E_VIDEO_POSITION, pos, 2); + } + else + { + fprintf(stderr, "destroying win: %x\n", win); + ecore_x_window_free(win); + } + } + } + evas_render_method_list_free(engines); + } +#else +# warning "missing: ecore_x OR xoverlay" +#endif + + esink = gst_element_factory_make("emotion-sink", "sink"); + if (!esink) + { + ERR("Unable to create 'emotion-sink' GstElement."); + goto unref_pipeline; + } + + g_object_set(G_OBJECT(esink), "evas-object", obj, NULL); + g_object_set(G_OBJECT(esink), "ev", ev, NULL); + + evas_object_image_pixels_get_callback_set(obj, NULL, NULL); + evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _image_resize, ev); + + /* We need queue to force each video sink to be in its own thread */ + queue = gst_element_factory_make("queue", "equeue"); + if (!queue) + { + ERR("Unable to create 'queue' GstElement."); + goto unref_pipeline; + } + + gst_bin_add_many(GST_BIN(bin), tee, queue, esink, NULL); + gst_element_link_many(queue, esink, NULL); + + /* link both sink to GstTee */ + pad = gst_element_get_pad(queue, "sink"); + teepad = gst_element_get_request_pad(tee, "src%d"); + gst_pad_link(teepad, pad); + gst_object_unref(pad); + + ev->eteepad = teepad; + + if (xvsink) + { + GstElement *fakeeos; + + queue = gst_element_factory_make("queue", "xvqueue"); + fakeeos = GST_ELEMENT(GST_BIN(g_object_new(GST_TYPE_FAKEEOS_BIN, "name", "eosbin", NULL))); + if (queue && fakeeos) + { + GstPad *queue_pad; + + gst_bin_add_many(GST_BIN(bin), fakeeos, NULL); + + gst_bin_add_many(GST_BIN(fakeeos), queue, xvsink, NULL); + gst_element_link_many(queue, xvsink, NULL); + queue_pad = gst_element_get_pad(queue, "sink"); + gst_element_add_pad(fakeeos, gst_ghost_pad_new("sink", queue_pad)); + + pad = gst_element_get_pad(fakeeos, "sink"); + teepad = gst_element_get_request_pad(tee, "src%d"); + gst_pad_link(teepad, pad); + + xvsink = fakeeos; + + ev->xvteepad = teepad; + ev->xvpad = pad; + } + else + { + if (fakeeos) gst_object_unref(fakeeos); + if (queue) gst_object_unref(queue); + gst_object_unref(xvsink); + xvsink = NULL; + } + } + + teepad = gst_element_get_pad(tee, "sink"); + gst_element_add_pad(bin, gst_ghost_pad_new("sink", teepad)); + gst_object_unref(teepad); + +#define GST_PLAY_FLAG_NATIVE_VIDEO (1 << 6) +#define GST_PLAY_FLAG_DOWNLOAD (1 << 7) +#define GST_PLAY_FLAG_AUDIO (1 << 1) +#define GST_PLAY_FLAG_NATIVE_AUDIO (1 << 5) + + if (launch) + { + g_object_set(G_OBJECT(playbin), "sink", bin, NULL); + } + else + { + g_object_get(G_OBJECT(playbin), "flags", &flags, NULL); + g_object_set(G_OBJECT(playbin), "flags", flags | GST_PLAY_FLAG_NATIVE_VIDEO | GST_PLAY_FLAG_DOWNLOAD | GST_PLAY_FLAG_NATIVE_AUDIO, NULL); + g_object_set(G_OBJECT(playbin), "video-sink", bin, NULL); + g_object_set(G_OBJECT(playbin), "uri", uri, NULL); + } + + evas_object_image_pixels_get_callback_set(obj, NULL, NULL); + + ev->stream = EINA_TRUE; + + if (xvsink) + { + Evas_Video_Surface video; + + video.version = EVAS_VIDEO_SURFACE_VERSION; + video.data = ev; + video.parent = NULL; + video.move = _video_move; + video.resize = _video_resize; + video.show = _video_show; + video.hide = _video_hide; + video.update_pixels = _video_update_pixels; + + evas_object_image_video_surface_set(obj, &video); + ev->stream = EINA_FALSE; + } + + eina_stringshare_replace(&ev->uri, uri); + ev->pipeline = playbin; + ev->sink = bin; + ev->esink = esink; + ev->xvsink = xvsink; + ev->tee = tee; + ev->threads = eina_list_append(ev->threads, + ecore_thread_run(_emotion_gstreamer_pause, + _emotion_gstreamer_end, + _emotion_gstreamer_cancel, + ev)); + + /** NOTE: you need to set: GST_DEBUG_DUMP_DOT_DIR=/tmp EMOTION_ENGINE=gstreamer to save the $EMOTION_GSTREAMER_DOT file in '/tmp' */ + /** then call dot -Tpng -oemotion_pipeline.png /tmp/$TIMESTAMP-$EMOTION_GSTREAMER_DOT.dot */ + if (getenv("EMOTION_GSTREAMER_DOT")) GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(playbin), GST_DEBUG_GRAPH_SHOW_ALL, getenv("EMOTION_GSTREAMER_DOT")); + + return playbin; + + unref_pipeline: + gst_object_unref(xvsink); + gst_object_unref(esink); + gst_object_unref(tee); + gst_object_unref(bin); + gst_object_unref(playbin); + return NULL; +} diff --git a/src/modules/xine/Makefile.am b/src/modules/xine/Makefile.am index 6ae4990..baf8fec 100644 --- a/src/modules/xine/Makefile.am +++ b/src/modules/xine/Makefile.am @@ -1,4 +1,3 @@ - MAINTAINERCLEANFILES = Makefile.in AM_CPPFLAGS = \ @@ -8,23 +7,25 @@ AM_CPPFLAGS = \ -DPACKAGE_BIN_DIR=\"$(bindir)\" \ -DPACKAGE_LIB_DIR=\"$(libdir)\" \ -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ -@EVAS_CFLAGS@ \ -@ECORE_CFLAGS@ \ +@EMOTION_CFLAGS@ \ +@EMOTION_CPPFLAGS@ \ +@EFL_EMOTION_BUILD@ \ @XINE_CFLAGS@ -if BUILD_XINE_MODULE +if EMOTION_BUILD_XINE +if !EMOTION_STATIC_BUILD_XINE pkgdir = $(libdir)/emotion pkg_LTLIBRARIES = xine.la -xine_la_SOURCES = \ +xine_la_SOURCES = \ emotion_xine.c \ emotion_xine.h \ emotion_xine_vo_out.c -xine_la_LIBADD = @EVAS_LIBS@ @ECORE_LIBS@ @XINE_LIBS@ $(top_builddir)/src/lib/libemotion.la -lpthread -xine_la_LDFLAGS = -module -avoid-version +xine_la_LIBADD = @EMOTION_LIBS@ @XINE_LIBS@ $(top_builddir)/src/lib/libemotion.la -lpthread +xine_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version xine_la_LIBTOOLFLAGS = --tag=disable-static -xine_la_DEPENDENCIES = $(top_builddir)/config.h endif +endif diff --git a/src/modules/xine/emotion_xine.c b/src/modules/xine/emotion_xine.c index 41624af..dd4a3a5 100644 --- a/src/modules/xine/emotion_xine.c +++ b/src/modules/xine/emotion_xine.c @@ -1,7 +1,17 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + #include "Emotion.h" #include "emotion_private.h" #include "emotion_xine.h" +int _emotion_xine_log_domain = -1; + /* module api */ static unsigned char em_init (Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt); static int em_shutdown (void *ef); @@ -11,13 +21,15 @@ static void em_play (void *ef, double pos); static void em_stop (void *ef); static void em_size_get (void *ef, int *w, int *h); static void em_pos_set (void *ef, double pos); -static void em_vis_set (void *ef, Emotion_Vis vis); +static double em_buffer_size_get (void *ef); static double em_len_get (void *ef); static int em_fps_num_get (void *ef); static int em_fps_den_get (void *ef); static double em_fps_get (void *ef); static double em_pos_get (void *ef); +static void em_vis_set (void *ef, Emotion_Vis vis); static Emotion_Vis em_vis_get (void *ef); +static Eina_Bool em_vis_supported (void *ef, Emotion_Vis vis); static double em_ratio_get (void *ef); static int em_seekable (void *ef); static void em_frame_done (void *ef); @@ -60,10 +72,10 @@ static const char *em_meta_get (void *ef, int meta); /* internal util calls */ static void *_em_slave (void *par); static void _em_slave_event (void *data, int type, void *arg); -static int _em_fd_active (void *data, Ecore_Fd_Handler *fdh); +static Eina_Bool _em_fd_active (void *data, Ecore_Fd_Handler *fdh); static void _em_event (void *data, const xine_event_t *event); static void _em_module_event (void *data, int type); -static int _em_fd_ev_active (void *data, Ecore_Fd_Handler *fdh); +static Eina_Bool _em_fd_ev_active (void *data, Ecore_Fd_Handler *fdh); //static int _em_timer (void *data); static void *_em_get_pos_len_th(void *par); static void _em_get_pos_len (Emotion_Xine_Video *ev); @@ -111,11 +123,11 @@ _em_slave(void *par) xine_config_update_entry(ev->decoder, &cf); } } - printf("OPEN VIDEO PLUGIN...\n"); + DBG("OPEN VIDEO PLUGIN..."); if (!ev->opt_no_video) ev->video = xine_open_video_driver(ev->decoder, "emotion", XINE_VISUAL_TYPE_NONE, ev); - printf("RESULT: xine_open_video_driver() = %p\n", ev->video); + DBG("RESULT: xine_open_video_driver() = %p", ev->video); // Let xine autodetect the best audio output driver if (!ev->opt_no_audio) ev->audio = xine_open_audio_driver(ev->decoder, NULL, ev); @@ -135,31 +147,31 @@ _em_slave(void *par) case 3: /* shutdown */ { _em_module_event(ev, 3); - printf("EX shutdown stop\n"); + DBG("shutdown stop"); xine_stop(ev->stream); // pthread_mutex_lock(&(ev->get_pos_len_mutex)); if (!ev->get_pos_thread_deleted) { - printf("closing get_pos thread, %p\n", ev); + DBG("closing get_pos thread, %p", ev); pthread_mutex_lock(&(ev->get_pos_len_mutex)); pthread_cond_broadcast(&(ev->get_pos_len_cond)); pthread_mutex_unlock(&(ev->get_pos_len_mutex)); while (ev->get_poslen); } - printf("EX dispose %p\n", ev); + DBG("dispose %p", ev); xine_dispose(ev->stream); - printf("EX dispose evq %p\n", ev); + DBG("dispose evq %p", ev); xine_event_dispose_queue(ev->queue); - printf("EX close video drv %p\n", ev); + DBG("close video drv %p", ev); if (ev->video) xine_close_video_driver(ev->decoder, ev->video); - printf("EX wait for vo to go\n"); + DBG("wait for vo to go"); while (ev->have_vo); - printf("EX vo gone\n"); - printf("EX close audio drv %p\n", ev); + DBG("vo gone"); + DBG("close audio drv %p", ev); if (ev->audio) xine_close_audio_driver(ev->decoder, ev->audio); - printf("EX xine exit %p\n", ev); + DBG("xine exit %p", ev); xine_exit(ev->decoder); - printf("EX DONE %p\n", ev); + DBG("DONE %p", ev); close(ev->fd_write); close(ev->fd_read); close(ev->fd_ev_write); @@ -182,7 +194,7 @@ _em_slave(void *par) char *file; file = eev->xine_event; - printf("OPN STREAM %s\n", file); + DBG("OPEN STREAM %s", file); if (xine_open(ev->stream, file)) { if (xine_get_pos_length(ev->stream, &pos_stream, &pos_time, &length_time)) @@ -214,19 +226,20 @@ _em_slave(void *par) ev->ratio = (double)v / 10000.0; ev->just_loaded = 1; ev->get_poslen = 0; + xine_set_param(ev->stream, XINE_PARAM_AUDIO_VOLUME, ev->volume * 100); } _em_module_event(ev, 2); /* event - open done */ } break; case 11: /* file close */ { - printf("EX done %p\n", ev); + DBG("done %p", ev); em_frame_done(ev); - printf("EX stop %p\n", ev); + DBG("stop %p", ev); xine_stop(ev->stream); - printf("EX close %p\n", ev); + DBG("close %p", ev); xine_close(ev->stream); - printf("EX close done %p\n", ev); + DBG("close done %p", ev); _em_module_event(ev, 11); } break; @@ -282,16 +295,12 @@ _em_slave(void *par) double pos; pos = *((double *)eev->xine_event); - if (ev->seeked_pos != ev->seek_to_pos) - { - if (ev->no_time) - xine_play(ev->stream, pos * 65535, 0); - else - xine_play(ev->stream, 0, pos * 1000); - if (!ev->play) - xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE); - ev->seeked_pos = ev->seek_to_pos; - } + if (ev->no_time) + xine_play(ev->stream, pos * 65535, 0); + else + xine_play(ev->stream, 0, pos * 1000); + if (!ev->play) + xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE); _em_module_event(ev, 6); } break; @@ -315,12 +324,7 @@ _em_slave(void *par) break; case 10: /* vol */ { - double vol; - - vol = *((double *)eev->xine_event); - if (vol < 0.0) vol = 0.0; - if (vol > 1.0) vol = 1.0; - xine_set_param(ev->stream, XINE_PARAM_AUDIO_VOLUME, vol * 100); + xine_set_param(ev->stream, XINE_PARAM_AUDIO_VOLUME, ev->volume * 100); _em_module_event(ev, 10); } break; @@ -363,7 +367,7 @@ _em_slave_event(void *data, int type, void *arg) new_ev->xine_event = arg; buf[0] = data; buf[1] = new_ev; - write(ev->fd_slave_write, buf, sizeof(buf)); + if (write(ev->fd_slave_write, buf, sizeof(buf)) < 0) perror("write"); } static unsigned char @@ -403,6 +407,7 @@ em_init(Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt) ev->fd_slave_write = fds[1]; fcntl(ev->fd_slave_write, F_SETFL, O_NONBLOCK); } + ev->volume = 0.8; ev->delete_me = 0; ev->get_pos_thread_deleted = 0; ev->opening = 1; @@ -421,6 +426,8 @@ em_init(Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt) pthread_create(&ev->slave_th, NULL, _em_slave, ev); pthread_detach(ev->slave_th); _em_slave_event(ev, 1, NULL); + + ev->buffer = 1.0; *emotion_video = ev; return 1; @@ -434,18 +441,25 @@ em_shutdown(void *ef) ev = (Emotion_Xine_Video *)ef; ev->closing = 1; ev->delete_me = 1; - printf("EXM del fds %p\n", ev); + DBG("del fds %p", ev); ecore_main_fd_handler_del(ev->fd_handler); + ev->fd_handler = NULL; ecore_main_fd_handler_del(ev->fd_ev_handler); + ev->fd_ev_handler = NULL; + if (ev->anim) + { + ecore_animator_del(ev->anim); + ev->anim = NULL; + } ev->closing = 1; _em_slave_event(ev, 3, NULL); - printf("EXM done %p\n", ev); + DBG("done %p", ev); return 1; } static unsigned char -em_file_open(const char *file, Evas_Object *obj, void *ef) +em_file_open(const char *file, Evas_Object *obj __UNUSED__, void *ef) { Emotion_Xine_Video *ev; @@ -507,31 +521,27 @@ em_pos_set(void *ef, double pos) double *ppos; ev = (Emotion_Xine_Video *)ef; - if (pos == ev->seek_to_pos) return; ppos = malloc(sizeof(double)); *ppos = pos; - ev->seek_to_pos = pos; _em_slave_event(ev, 6, ppos); } -static void -em_vis_set(void *ef, - Emotion_Vis vis) +static double +em_len_get(void *ef) { Emotion_Xine_Video *ev; ev = (Emotion_Xine_Video *)ef; - if (ev->vis == vis) return; - ev->vis = vis; + return ev->len; } static double -em_len_get(void *ef) +em_buffer_size_get(void *ef) { Emotion_Xine_Video *ev; ev = (Emotion_Xine_Video *)ef; - return ev->len; + return ev->buffer; } static int @@ -544,11 +554,8 @@ em_fps_num_get(void *ef) } static int -em_fps_den_get(void *ef) +em_fps_den_get(void *ef __UNUSED__) { - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; return 10000; } @@ -567,9 +574,20 @@ em_pos_get(void *ef) Emotion_Xine_Video *ev; ev = (Emotion_Xine_Video *)ef; + _em_get_pos_len(ev); return ev->pos; } +static void +em_vis_set(void *ef, Emotion_Vis vis) +{ + Emotion_Xine_Video *ev; + + ev = (Emotion_Xine_Video *)ef; + if (ev->vis == vis) return; + ev->vis = vis; +} + static Emotion_Vis em_vis_get(void *ef) { @@ -580,6 +598,12 @@ em_vis_get(void *ef) return ev->vis; } +static Eina_Bool +em_vis_supported(void *ef __UNUSED__, Emotion_Vis vis __UNUSED__) +{ + return EINA_FALSE; +} + static double em_ratio_get(void *ef) { @@ -667,7 +691,7 @@ em_video_data_size_get(void *ef, int *w, int *h) } static int -em_yuv_rows_get(void *ef, int w, int h, unsigned char **yrows, unsigned char **urows, unsigned char **vrows) +em_yuv_rows_get(void *ef, int w __UNUSED__, int h, unsigned char **yrows, unsigned char **urows, unsigned char **vrows) { Emotion_Xine_Video *ev; volatile Emotion_Xine_Video_Frame *fr; @@ -810,7 +834,7 @@ em_event_feed(void *ef, int event) } static void -em_event_mouse_button_feed(void *ef, int button, int x, int y) +em_event_mouse_button_feed(void *ef, int button __UNUSED__, int x, int y) { Emotion_Xine_Video *ev; xine_event_t xine_event; @@ -885,11 +909,8 @@ em_video_channel_get(void *ef) } static const char * -em_video_channel_name_get(void *ef, int channel) +em_video_channel_name_get(void *ef __UNUSED__, int channel __UNUSED__) { - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; return NULL; } @@ -978,12 +999,13 @@ static void em_audio_channel_volume_set(void *ef, double vol) { Emotion_Xine_Video *ev; - double *ppos; + if (vol < 0.0) vol = 0.0; + else if (vol > 1.0) vol = 1.0; + ev = (Emotion_Xine_Video *)ef; - ppos = malloc(sizeof(double)); - *ppos = vol; - _em_slave_event(ev, 10, ppos); + ev->volume = vol; + _em_slave_event(ev, 10, NULL); } static double @@ -992,8 +1014,9 @@ em_audio_channel_volume_get(void *ef) Emotion_Xine_Video *ev; ev = (Emotion_Xine_Video *)ef; - if (ev->opening || (!ev->play_ok)) return 0; - return (double)xine_get_param(ev->stream, XINE_PARAM_AUDIO_VOLUME) / 100.0; + if (ev->opening || (!ev->play_ok)) return ev->volume; + ev->volume = xine_get_param(ev->stream, XINE_PARAM_AUDIO_VOLUME) / 100.0; + return ev->volume; } static int @@ -1072,45 +1095,30 @@ em_chapter_count(void *ef) } static void -em_chapter_set(void *ef, int chapter) +em_chapter_set(void *ef __UNUSED__, int chapter __UNUSED__) { - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; } static int -em_chapter_get(void *ef) +em_chapter_get(void *ef __UNUSED__) { - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; return 0; } static const char * -em_chapter_name_get(void *ef, int chapter) +em_chapter_name_get(void *ef __UNUSED__, int chapter __UNUSED__) { - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; return NULL; } static void -em_speed_set(void *ef, double speed) +em_speed_set(void *ef __UNUSED__, double speed __UNUSED__) { - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; } static double -em_speed_get(void *ef) +em_speed_get(void *ef __UNUSED__) { - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; return 1.0; } @@ -1160,20 +1168,20 @@ em_meta_get(void *ef, int meta) return NULL; } -static int +static Eina_Bool _em_fd_active(void *data, Ecore_Fd_Handler *fdh) { void *buf; int fd, len; Emotion_Xine_Video_Frame *fr; - Emotion_Xine_Video *ev; - ev = data; fd = ecore_main_fd_handler_fd_get(fdh); while ((len = read(fd, &buf, sizeof(buf))) > 0) { if (len == sizeof(buf)) { + Emotion_Xine_Video *ev; + fr = buf; ev = _emotion_video_get(fr->obj); if (ev) @@ -1192,7 +1200,8 @@ _em_fd_active(void *data, Ecore_Fd_Handler *fdh) } } } - return 1; + return EINA_TRUE; + data = NULL; } static void @@ -1219,7 +1228,7 @@ _em_event(void *data, const xine_event_t *event) } buf[0] = data; buf[1] = new_ev; - write(ev->fd_ev_write, buf, sizeof(buf)); + if (write(ev->fd_ev_write, buf, sizeof(buf)) < 0) perror("write"); } static void @@ -1236,22 +1245,31 @@ _em_module_event(void *data, int type) new_ev->type = -1; buf[0] = data; buf[1] = new_ev; - write(ev->fd_ev_write, buf, sizeof(buf)); + if (write(ev->fd_ev_write, buf, sizeof(buf)) < 0) perror("write"); } -static int -_em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh) +static Eina_Bool +_em_audio_only_poller(void *data) { Emotion_Xine_Video *ev; - int fd, len; - void *buf[2]; ev = data; + _em_get_pos_len(ev); + return EINA_TRUE; +} + +static Eina_Bool +_em_fd_ev_active(void *data __UNUSED__, Ecore_Fd_Handler *fdh) +{ + int fd, len; + void *buf[2]; + fd = ecore_main_fd_handler_fd_get(fdh); while ((len = read(fd, buf, sizeof(buf))) > 0) { if (len == sizeof(buf)) { + Emotion_Xine_Video *ev; Emotion_Xine_Event *eev; ev = buf[0]; @@ -1265,20 +1283,56 @@ _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh) break; case 2: /* open done */ ev->play_ok = 1; + if (ev->anim) + { + ecore_animator_del(ev->anim); + ev->anim = NULL; + } + _emotion_open_done(ev->obj); + _emotion_frame_resize(ev->obj, ev->w, ev->h, ev->ratio); break; case 3: /* shutdown done */ + if (ev->anim) + { + ecore_animator_del(ev->anim); + ev->anim = NULL; + } ev->play_ok = 1; break; case 4: /* play done */ ev->play_ok = 1; + if (ev->anim) + { + ecore_animator_del(ev->anim); + ev->anim = NULL; + } + if ((!(xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_VIDEO) && + xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_HANDLED))) && + (xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_AUDIO) && + xine_get_stream_info(ev->stream, XINE_STREAM_INFO_AUDIO_HANDLED))) + ev->anim = ecore_animator_add(_em_audio_only_poller, ev); + _emotion_playback_started(ev->obj); break; case 5: /* stop done */ + if (ev->anim) + { + ecore_animator_del(ev->anim); + ev->anim = NULL; + } ev->play_ok = 1; break; case 6: /* seek done */ ev->play_ok = 1; + _emotion_seek_done(ev->obj); + _em_get_pos_len(ev); + _emotion_video_pos_update(ev->obj, ev->pos, ev->len); break; case 7: /* eject done */ + if (ev->anim) + { + ecore_animator_del(ev->anim); + ev->anim = NULL; + } ev->play_ok = 1; break; case 8: /* spu mute done */ @@ -1291,8 +1345,20 @@ _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh) ev->play_ok = 1; break; case 11: /* close done */ + if (ev->anim) + { + ecore_animator_del(ev->anim); + ev->anim = NULL; + } ev->play_ok = 1; break; + case 15: /* get pos done */ + if (ev->last_pos != ev->pos) + { + ev->last_pos = ev->pos; + _emotion_video_pos_update(ev->obj, ev->pos, ev->len); + } + break; default: break; } @@ -1322,29 +1388,18 @@ _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh) } break; case XINE_EVENT_FRAME_FORMAT_CHANGE: - { - xine_format_change_data_t *e; - - e = (xine_format_change_data_t *)eev->xine_event; - } break; case XINE_EVENT_UI_MESSAGE: { - xine_ui_message_data_t *e; - - e = (xine_ui_message_data_t *)eev->xine_event; - printf("EV: UI Message [FIXME: break this out to emotion api]\n"); + WRN("UI Message [FIXME: break this out to emotion api]"); // e->type = error type(XINE_MSG_NO_ERROR, XINE_MSG_GENERAL_WARNING, XINE_MSG_UNKNOWN_HOST etc.) // e->messages is a list of messages DOUBLE null terminated } break; case XINE_EVENT_AUDIO_LEVEL: { - xine_audio_level_data_t *e; - - e = (xine_audio_level_data_t *)eev->xine_event; _emotion_audio_level_change(ev->obj); - printf("EV: Audio Level [FIXME: break this out to emotion api]\n"); + WRN("Audio Level [FIXME: break this out to emotion api]"); // e->left (0->100) // e->right // e->mute @@ -1355,15 +1410,16 @@ _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh) xine_progress_data_t *e; e = (xine_progress_data_t *)eev->xine_event; - printf("PROGRESS: %i\n", e->percent); + DBG("PROGRESS: %i", e->percent); + ev->buffer = e->percent; _emotion_progress_set(ev->obj, (char *)e->description, (double)e->percent / 100.0); } break; - case XINE_EVENT_MRL_REFERENCE: + case XINE_EVENT_MRL_REFERENCE_EXT: { - xine_mrl_reference_data_t *e; + xine_mrl_reference_data_ext_t *e; - e = (xine_mrl_reference_data_t *)eev->xine_event; + e = (xine_mrl_reference_data_ext_t *)eev->xine_event; _emotion_file_ref_set(ev->obj, e->mrl, e->alternative); } break; @@ -1391,13 +1447,13 @@ _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh) xine_dropped_frames_t *e; e = (xine_dropped_frames_t *)eev->xine_event; - printf("EV: Dropped Frames (skipped %i) (discarded %i) [FIXME: break this out to the emotion api]\n", e->skipped_frames, e->discarded_frames); + WRN("Dropped Frames (skipped %i) (discarded %i) [FIXME: break this out to the emotion api]", e->skipped_frames, e->discarded_frames); // e->skipped_frames = % frames skipped * 10 // e->discarded_frames = % frames skipped * 10 } break; default: - // printf("EV: unknown event type %i\n", eev->type); + // DBG("unknown event type %i", eev->type); break; } } @@ -1405,7 +1461,7 @@ _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh) free(eev); } } - return 1; + return EINA_TRUE; } static void * @@ -1442,7 +1498,8 @@ _em_get_pos_len_th(void *par) } } ev->get_poslen = 0; - //printf("get pos %3.3f\n", ev->pos); + _em_module_event(ev, 15); /* event - getpos done */ + //DBG("get pos %3.3f", ev->pos); } if (ev->delete_me) { @@ -1456,7 +1513,7 @@ _em_get_pos_len_th(void *par) static void _em_get_pos_len(Emotion_Xine_Video *ev) { - if (ev->get_poslen) return; + if (!ev->play_ok) return; ev->get_poslen = 1; pthread_mutex_lock(&(ev->get_pos_len_mutex)); pthread_cond_broadcast(&(ev->get_pos_len_cond)); @@ -1473,13 +1530,15 @@ static Emotion_Video_Module em_module = em_stop, /* stop */ em_size_get, /* size_get */ em_pos_set, /* pos_set */ - em_vis_set, /* vis_set */ em_len_get, /* len_get */ + em_buffer_size_get, /* buffer_size_get */ em_fps_num_get, /* fps_num_get */ em_fps_den_get, /* fps_den_get */ em_fps_get, /* fps_get */ em_pos_get, /* pos_get */ + em_vis_set, /* vis_set */ em_vis_get, /* vis_get */ + em_vis_supported, /* vis_supported */ em_ratio_get, /* ratio_get */ em_video_handled, /* video_handled */ em_audio_handled, /* audio_handled */ @@ -1520,29 +1579,62 @@ static Emotion_Video_Module em_module = em_speed_get, /* speed_get */ em_eject, /* eject */ em_meta_get, /* meta_get */ - + NULL, /* priority_set */ + NULL, /* priority_get */ NULL /* handle */ }; -unsigned char +static Eina_Bool module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt) { if (!module) - return 0; - + return EINA_FALSE; + + if (_emotion_xine_log_domain < 0) + { + eina_threads_init(); + eina_log_threads_enable(); + _emotion_xine_log_domain = eina_log_domain_register + ("emotion-xine", EINA_COLOR_LIGHTCYAN); + if (_emotion_xine_log_domain < 0) + { + EINA_LOG_CRIT("Could not register log domain 'emotion-xine'"); + return EINA_FALSE; + } + } + if (!em_module.init(obj, video, opt)) - return 0; + return EINA_FALSE; *module = &em_module; - return 1; + return EINA_TRUE; } -void -module_close(Emotion_Video_Module *module, void *video) +static void +module_close(Emotion_Video_Module *module __UNUSED__, void *video) { em_module.shutdown(video); } +Eina_Bool +xine_module_init(void) +{ + return _emotion_module_register("xine", module_open, module_close); +} + +void +xine_module_shutdown(void) +{ + _emotion_module_unregister("xine"); +} + +#ifndef EMOTION_STATIC_BUILD_XINE + +EINA_MODULE_INIT(xine_module_init); +EINA_MODULE_SHUTDOWN(xine_module_shutdown); + +#endif + #if 0 void em_debug(Emotion_Xine_Video *ev) @@ -1585,48 +1677,46 @@ em_debug(Emotion_Xine_Video *ev) spu_channel = xine_get_param(ev->stream, XINE_PARAM_SPU_CHANNEL); video_ratio = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_RATIO); audio_mode = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_AUDIO_MODE); - printf("has_chapters = %i\n", has_chapters); - printf("max_spu = %i\n", max_spu); - printf("max_audio = %i\n", max_audio); - printf("video_channels = %i\n", video_channels); - printf("video_streams = %i\n", video_streams); - printf("video_seekable = %i\n", video_seekable); - printf("title = %s\n", title); - printf("comment = %s\n", comment); - printf("artist = %s\n", artist); - printf("genre = %s\n", genre); - printf("album = %s\n", album); - printf("year = %s\n", year); - printf("cdindex_discid = %s\n", cdindex_discid); - printf("video_channel = %i\n", video_channel); - printf("audio_channel = %i\n", audio_channel); - printf("spu_channels = %i\n", spu_channel); - printf("video_ratio = %i\n", video_ratio); - printf("audio_mode = %i\n", audio_mode); + DBG("has_chapters = %i", has_chapters); + DBG("max_spu = %i", max_spu); + DBG("max_audio = %i", max_audio); + DBG("video_channels = %i", video_channels); + DBG("video_streams = %i", video_streams); + DBG("video_seekable = %i", video_seekable); + DBG("title = %s", title); + DBG("comment = %s", comment); + DBG("artist = %s", artist); + DBG("genre = %s", genre); + DBG("album = %s", album); + DBG("year = %s", year); + DBG("cdindex_discid = %s", cdindex_discid); + DBG("video_channel = %i", video_channel); + DBG("audio_channel = %i", audio_channel); + DBG("spu_channels = %i", spu_channel); + DBG("video_ratio = %i", video_ratio); + DBG("audio_mode = %i", audio_mode); { int i; for (i = 0; i <= max_audio; i++) { char lang[XINE_LANG_MAX + 1]; - + char buf[128] = "NONE"; + lang[0] = 0; - printf(" AUDIO %i = ", i); if (xine_get_audio_lang(ev->stream, i, lang)) - printf("%s\n", lang); - else - printf("NONE\n"); + eina_strlcpy(buf, lang, sizeof(buf)); + DBG(" AUDIO %i = %s", i, buf); } for (i = 0; i <= max_spu; i++) { char lang[XINE_LANG_MAX + 1]; - + char buf[128] = "NONE"; + lang[0] = 0; - printf(" SPU %i = ", i); if (xine_get_spu_lang(ev->stream, i, lang)) - printf("%s\n", lang); - else - printf("NONE\n"); + eina_strlcpy(buf, lang, sizeof(buf)); + DBG(" SPU %i = %s", i, buf); } } } diff --git a/src/modules/xine/emotion_xine.h b/src/modules/xine/emotion_xine.h index 8a9efcc..c1cae2e 100644 --- a/src/modules/xine/emotion_xine.h +++ b/src/modules/xine/emotion_xine.h @@ -20,6 +20,9 @@ struct _Emotion_Xine_Video xine_event_queue_t *queue; volatile double len; volatile double pos; + volatile double last_pos; + volatile double volume; + volatile double buffer; double fps; double ratio; int w, h; @@ -29,23 +32,22 @@ struct _Emotion_Xine_Video volatile int spu_channel; volatile int audio_channel; volatile int video_channel; - volatile double seek_to_pos; - volatile double seeked_pos; volatile int fq; Emotion_Vis vis; - int fd_read; + int fd_read; int fd_write; Ecore_Fd_Handler *fd_handler; int fd_ev_read; int fd_ev_write; Ecore_Fd_Handler *fd_ev_handler; + Ecore_Animator *anim; unsigned char play : 1; unsigned char just_loaded : 1; unsigned char video_mute : 1; unsigned char audio_mute : 1; unsigned char spu_mute : 1; - unsigned char opt_no_video : 1; - unsigned char opt_no_audio : 1; + Eina_Bool opt_no_video : 1; + Eina_Bool opt_no_audio : 1; volatile unsigned char delete_me : 1; volatile unsigned char no_time : 1; volatile unsigned char opening : 1; @@ -86,7 +88,11 @@ struct _Emotion_Xine_Event int mtype; }; -unsigned char module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt); -void module_close(Emotion_Video_Module *module, void *video); +extern int _emotion_xine_log_domain; +#define DBG(...) EINA_LOG_DOM_DBG(_emotion_xine_log_domain, __VA_ARGS__) +#define INF(...) EINA_LOG_DOM_INFO(_emotion_xine_log_domain, __VA_ARGS__) +#define WRN(...) EINA_LOG_DOM_WARN(_emotion_xine_log_domain, __VA_ARGS__) +#define ERR(...) EINA_LOG_DOM_ERR(_emotion_xine_log_domain, __VA_ARGS__) +#define CRITICAL(...) EINA_LOG_DOM_CRIT(_emotion_xine_log_domain, __VA_ARGS__) #endif diff --git a/src/modules/xine/emotion_xine_vo_out.c b/src/modules/xine/emotion_xine_vo_out.c index 439ae92..3ae8e1c 100644 --- a/src/modules/xine/emotion_xine_vo_out.c +++ b/src/modules/xine/emotion_xine_vo_out.c @@ -1,11 +1,20 @@ /***************************************************************************/ /*** emotion xine display engine ***/ /***************************************************************************/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include #include #include #include +#include +#include +#include + +#include "Emotion.h" #include "emotion_private.h" #include "emotion_xine.h" @@ -60,6 +69,8 @@ struct _Emotion_Lut uint8_t foo : 8; } __attribute__ ((packed)); +typedef void (*done_func_type)(void *data); + /***************************************************************************/ static void *_emotion_class_init (xine_t *xine, void *visual); static void _emotion_class_dispose (video_driver_class_t *driver_class); @@ -111,16 +122,21 @@ plugin_info_t emotion_xine_plugin_info[] = /***************************************************************************/ static void * -_emotion_class_init(xine_t *xine, void *visual) +_emotion_class_init(xine_t *xine, void *visual __UNUSED__) { Emotion_Class *cl; -// printf("emotion: _emotion_class_init()\n"); - cl = (Emotion_Class *) xine_xmalloc(sizeof(Emotion_Class)); +// DBG(""); + cl = (Emotion_Class *) malloc(sizeof(Emotion_Class)); if (!cl) return NULL; cl->driver_class.open_plugin = _emotion_open; +#if XINE_MAJOR_VERSION < 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION < 2) cl->driver_class.get_identifier = _emotion_class_identifier_get; cl->driver_class.get_description = _emotion_class_description_get; +#else + cl->driver_class.identifier = _emotion_class_identifier_get(NULL); + cl->driver_class.description = _emotion_class_description_get(NULL); +#endif cl->driver_class.dispose = _emotion_class_dispose; cl->config = xine->config; cl->xine = xine; @@ -138,20 +154,14 @@ _emotion_class_dispose(video_driver_class_t *driver_class) } static char * -_emotion_class_identifier_get(video_driver_class_t *driver_class) +_emotion_class_identifier_get(video_driver_class_t *driver_class __UNUSED__) { - Emotion_Class *cl; - - cl = (Emotion_Class *)driver_class; return "emotion"; } static char * -_emotion_class_description_get(video_driver_class_t *driver_class) +_emotion_class_description_get(video_driver_class_t *driver_class __UNUSED__) { - Emotion_Class *cl; - - cl = (Emotion_Class *)driver_class; return "Emotion xine video output plugin"; } @@ -164,8 +174,8 @@ _emotion_open(video_driver_class_t *driver_class, const void *visual) cl = (Emotion_Class *)driver_class; /* visual here is the data ptr passed to xine_open_video_driver() */ -// printf("emotion: _emotion_open()\n"); - dv = (Emotion_Driver *)xine_xmalloc(sizeof(Emotion_Driver)); +// DBG(""); + dv = (Emotion_Driver *)malloc(sizeof(Emotion_Driver)); if (!dv) return NULL; dv->config = cl->config; @@ -186,7 +196,7 @@ _emotion_open(video_driver_class_t *driver_class, const void *visual) dv->vo_driver.redraw_needed = _emotion_redraw; dv->ev = (Emotion_Xine_Video *)visual; dv->ev->have_vo = 1; - printf("emotion: _emotion_open = %p\n", &dv->vo_driver); + DBG("vo_driver = %p", &dv->vo_driver); return &dv->vo_driver; } @@ -197,40 +207,31 @@ _emotion_dispose(vo_driver_t *vo_driver) dv = (Emotion_Driver *)vo_driver; dv->ev->have_vo = 0; - printf("emotion: _emotion_dispose(%p)\n", dv); + DBG("vo_driver = %p", dv); free(dv); } /***************************************************************************/ static int -_emotion_redraw(vo_driver_t *vo_driver) +_emotion_redraw(vo_driver_t *vo_driver __UNUSED__) { - Emotion_Driver *dv; - - dv = (Emotion_Driver *)vo_driver; -// printf("emotion: _emotion_redraw()\n"); +// DBG(""); return 0; } /***************************************************************************/ static uint32_t -_emotion_capabilities_get(vo_driver_t *vo_driver) +_emotion_capabilities_get(vo_driver_t *vo_driver __UNUSED__) { - Emotion_Driver *dv; - - dv = (Emotion_Driver *)vo_driver; -// printf("emotion: _emotion_capabilities_get()\n"); +// DBG(""); return VO_CAP_YV12 | VO_CAP_YUY2; } /***************************************************************************/ static int -_emotion_gui_data_exchange(vo_driver_t *vo_driver, int data_type, void *data) +_emotion_gui_data_exchange(vo_driver_t *vo_driver __UNUSED__, int data_type, void *data __UNUSED__) { - Emotion_Driver *dv; - - dv = (Emotion_Driver *)vo_driver; -// printf("emotion: _emotion_gui_data_exchange()\n"); +// DBG(""); switch (data_type) { case XINE_GUI_SEND_COMPLETION_EVENT: @@ -258,13 +259,13 @@ _emotion_property_set(vo_driver_t *vo_driver, int property, int value) Emotion_Driver *dv; dv = (Emotion_Driver *)vo_driver; -// printf("emotion: _emotion_property_set()\n"); +// DBG(""); switch (property) { case VO_PROP_ASPECT_RATIO: if (value >= XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; -// printf("DRIVER RATIO SET %i!\n", value); +// DBG("DRIVER RATIO SET %i!", value); dv->ratio = value; break; default: @@ -279,7 +280,7 @@ _emotion_property_get(vo_driver_t *vo_driver, int property) Emotion_Driver *dv; dv = (Emotion_Driver *)vo_driver; -// printf("emotion: _emotion_property_get()\n"); +// DBG(""); switch (property) { case VO_PROP_ASPECT_RATIO: @@ -292,26 +293,21 @@ _emotion_property_get(vo_driver_t *vo_driver, int property) } static void -_emotion_property_min_max_get(vo_driver_t *vo_driver, int property, int *min, int *max) +_emotion_property_min_max_get(vo_driver_t *vo_driver __UNUSED__, int property __UNUSED__, int *min, int *max) { - Emotion_Driver *dv; - - dv = (Emotion_Driver *)vo_driver; -// printf("emotion: _emotion_property_min_max_get()\n"); +// DBG(""); *min = 0; *max = 0; } /***************************************************************************/ static vo_frame_t * -_emotion_frame_alloc(vo_driver_t *vo_driver) +_emotion_frame_alloc(vo_driver_t *vo_driver __UNUSED__) { - Emotion_Driver *dv; Emotion_Frame *fr; - dv = (Emotion_Driver *)vo_driver; -// printf("emotion: _emotion_frame_alloc()\n"); - fr = (Emotion_Frame *)xine_xmalloc(sizeof(Emotion_Frame)); +// DBG(""); + fr = (Emotion_Frame *)calloc(1, sizeof(Emotion_Frame)); if (!fr) return NULL; fr->vo_frame.base[0] = NULL; @@ -333,13 +329,13 @@ _emotion_frame_dispose(vo_frame_t *vo_frame) Emotion_Frame *fr; fr = (Emotion_Frame *)vo_frame; -// printf("emotion: _emotion_frame_dispose()\n"); +// DBG(""); _emotion_frame_data_free(fr); free(fr); } static void -_emotion_frame_format_update(vo_driver_t *vo_driver, vo_frame_t *vo_frame, uint32_t width, uint32_t height, double ratio, int format, int flags) +_emotion_frame_format_update(vo_driver_t *vo_driver, vo_frame_t *vo_frame, uint32_t width, uint32_t height, double ratio, int format, int flags __UNUSED__) { Emotion_Driver *dv; Emotion_Frame *fr; @@ -347,10 +343,10 @@ _emotion_frame_format_update(vo_driver_t *vo_driver, vo_frame_t *vo_frame, uint3 dv = (Emotion_Driver *)vo_driver; fr = (Emotion_Frame *)vo_frame; - if ((fr->width != width) || (fr->height != height) || + if ((fr->width != (int)width) || (fr->height != (int)height) || (fr->format != format) || (!fr->vo_frame.base[0])) { -// printf("emotion: _emotion_frame_format_update()\n"); +// DBG(""); _emotion_frame_data_free(fr); fr->width = width; @@ -415,12 +411,12 @@ _emotion_frame_format_update(vo_driver_t *vo_driver, vo_frame_t *vo_frame, uint3 break; } if (((format == XINE_IMGFMT_YV12) - && ((fr->vo_frame.base[0] == NULL) - || (fr->vo_frame.base[1] == NULL) - || (fr->vo_frame.base[2] == NULL))) + && ((!fr->vo_frame.base[0]) + || (!fr->vo_frame.base[1]) + || (!fr->vo_frame.base[2]))) || ((format == XINE_IMGFMT_YUY2) - && ((fr->vo_frame.base[0] == NULL) - || (fr->frame.bgra_data == NULL)))) + && ((!fr->vo_frame.base[0]) + || (!fr->frame.bgra_data)))) { _emotion_frame_data_free(fr); } @@ -437,15 +433,13 @@ _emotion_frame_display(vo_driver_t *vo_driver, vo_frame_t *vo_frame) dv = (Emotion_Driver *)vo_driver; fr = (Emotion_Frame *)vo_frame; -// printf("emotion: _emotion_frame_display()\n"); -// printf("EX VO: fq %i %p\n", dv->ev->fq, dv->ev); +// DBG("fq %i %p", dv->ev->fq, dv->ev); // if my frame queue is too deep ( > 4 frames) simply block and wait for them // to drain // while (dv->ev->fq > 4) usleep(1); if (dv->ev) { void *buf; - int ret; if (dv->ev->closing) return; if (fr->format == XINE_IMGFMT_YUY2) @@ -455,11 +449,11 @@ _emotion_frame_display(vo_driver_t *vo_driver, vo_frame_t *vo_frame) buf = &(fr->frame); fr->frame.timestamp = (double)fr->vo_frame.vpts / 90000.0; - fr->frame.done_func = _emotion_frame_data_unlock; + fr->frame.done_func = (done_func_type)_emotion_frame_data_unlock; fr->frame.done_data = fr; -// printf("FRAME FOR %p\n", dv->ev); - ret = write(dv->ev->fd_write, &buf, sizeof(void *)); -// printf("-- FRAME DEC %p == %i\n", fr->frame.obj, ret); +// DBG("FRAME FOR %p", dv->ev); + if (write(dv->ev->fd_write, &buf, sizeof(void *)) < 0) perror("write"); +// DBG("-- FRAME DEC %p == %i", fr->frame.obj, ret); fr->in_use = 1; dv->ev->fq++; } @@ -468,12 +462,9 @@ _emotion_frame_display(vo_driver_t *vo_driver, vo_frame_t *vo_frame) } static void -_emotion_frame_field(vo_frame_t *vo_frame, int which_field) +_emotion_frame_field(vo_frame_t *vo_frame __UNUSED__, int which_field __UNUSED__) { - Emotion_Frame *fr; - - fr = (Emotion_Frame *)vo_frame; -// printf("emotion: _emotion_frame_field()\n"); +// DBG(""); } /***************************************************************************/ @@ -500,7 +491,7 @@ _emotion_frame_data_free(Emotion_Frame *fr) static void _emotion_frame_data_unlock(Emotion_Frame *fr) { -// printf("emotion: _emotion_frame_data_unlock()\n"); +// DBG(""); if (fr->in_use) { fr->vo_frame.free(&fr->vo_frame); @@ -510,36 +501,24 @@ _emotion_frame_data_unlock(Emotion_Frame *fr) /***************************************************************************/ static void -_emotion_overlay_begin(vo_driver_t *vo_driver, vo_frame_t *vo_frame, int changed) +_emotion_overlay_begin(vo_driver_t *vo_driver __UNUSED__, vo_frame_t *vo_frame __UNUSED__, int changed __UNUSED__) { - Emotion_Driver *dv; - Emotion_Frame *fr; - - dv = (Emotion_Driver *)vo_driver; - fr = (Emotion_Frame *)vo_frame; -// printf("emotion: _emotion_overlay_begin()\n"); +// DBG(""); } static void -_emotion_overlay_end(vo_driver_t *vo_driver, vo_frame_t *vo_frame) +_emotion_overlay_end(vo_driver_t *vo_driver __UNUSED__, vo_frame_t *vo_frame __UNUSED__) { - Emotion_Driver *dv; - Emotion_Frame *fr; - - dv = (Emotion_Driver *)vo_driver; - fr = (Emotion_Frame *)vo_frame; -// printf("emotion: _emotion_overlay_end()\n"); +// DBG(""); } static void -_emotion_overlay_blend(vo_driver_t *vo_driver, vo_frame_t *vo_frame, vo_overlay_t *vo_overlay) +_emotion_overlay_blend(vo_driver_t *vo_driver __UNUSED__, vo_frame_t *vo_frame, vo_overlay_t *vo_overlay __UNUSED__) { - Emotion_Driver *dv; Emotion_Frame *fr; - dv = (Emotion_Driver *)vo_driver; fr = (Emotion_Frame *)vo_frame; -// printf("emotion: _emotion_overlay_blend()\n"); +// DBG(""); _emotion_overlay_blend_yuv(fr->vo_frame.base, vo_overlay, fr->width, fr->height, fr->vo_frame.pitches); -- 2.7.4