Tizen 2.1 base
authorJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:53:14 +0000 (01:53 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:53:14 +0000 (01:53 +0900)
152 files changed:
AUTHORS
COPYING
ChangeLog
Makefile.am
NEWS
README
TC/README [new file with mode: 0644]
TC/_export_env.sh [new file with mode: 0755]
TC/build.sh [new file with mode: 0755]
TC/clean.sh [new file with mode: 0755]
TC/emotion/common.h [new file with mode: 0644]
TC/emotion/emotion_private.h [new file with mode: 0644]
TC/emotion/test.avi [new file with mode: 0644]
TC/emotion/tslist [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_audio_level_change.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_channels_change.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_decode_stop.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_file_ref_set.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_frame_new.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_frame_refill.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_frame_resize.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_init.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_module_register.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_module_unregister.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_add.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_audio_channel_count.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_audio_mute_set_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_audio_volume_set_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_bg_color_set.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_border_set.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_event_simple_send.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_file_set_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_image_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_init.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_keep_aspect_set.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_last_position_save_load.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_meta_info_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_module_option_set.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_play_length_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_play_set_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_play_speed_set_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_position_set_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_progress_info_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_progress_status_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_ratio_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_ref_file_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_ref_num_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_seekable_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_size_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_smooth_scale_set.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_spu_button_count_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_spu_button_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_spu_channel_count.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_title_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_video_channel_count.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_video_mute_set_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_vis_set_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_object_vis_supported.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_open_done.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_playback_finished.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_playback_started.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_progress_set.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_seek_done.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_shutdown.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_spu_button_num_set.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_spu_button_set.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_title_set.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_video_get.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_video_pos_update.c [new file with mode: 0644]
TC/emotion/utc_UIFW_emotion_webcam_custom_get.c [new file with mode: 0644]
TC/execute.sh [new file with mode: 0755]
TC/tet_scen [new file with mode: 0644]
TC/tetbuild.cfg [new file with mode: 0755]
TC/tetclean.cfg [new file with mode: 0755]
TC/tetexec.cfg [new file with mode: 0755]
autogen.sh
configure.ac [new file with mode: 0644]
data/Makefile.am
data/e_logo.png
data/icon.edc [new file with mode: 0644]
data/theme.edc
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control
debian/libemotion0-dev.install [new file with mode: 0644]
debian/libemotion0-gstreamer.install [new file with mode: 0644]
debian/libemotion0.install
debian/rules [changed mode: 0644->0755]
doc/Doxyfile.in [new file with mode: 0644]
doc/Makefile.am [new file with mode: 0644]
doc/e.css
doc/examples.dox [new file with mode: 0644]
doc/foot.html
doc/head.html
doc/img/e.png [new file with mode: 0644]
doc/img/edoxy.css [new file with mode: 0644]
doc/img/emotion_ratio.eps [new file with mode: 0644]
doc/img/emotion_ratio.png [new file with mode: 0644]
doc/img/foot_bg.png [new file with mode: 0644]
doc/img/head_bg.png [new file with mode: 0644]
doc/img/header_menu_background.png [new file with mode: 0644]
doc/img/header_menu_background_last.png [new file with mode: 0644]
doc/img/header_menu_current_background.png [new file with mode: 0644]
doc/img/header_menu_unselected_background.png [new file with mode: 0644]
doc/img/logo.png [new file with mode: 0644]
emotion-gstreamer.manifest [new file with mode: 0644]
emotion.manifest [new file with mode: 0644]
emotion.pc.in
emotion.spec.in
m4/ac_attribute.m4 [new file with mode: 0644]
m4/efl_binary.m4 [new file with mode: 0644]
m4/efl_doxygen.m4 [new file with mode: 0644]
m4/efl_edje_external.m4 [new file with mode: 0644]
m4/efl_examples.m4 [new file with mode: 0644]
m4/efl_shm_open.m4 [new file with mode: 0644]
m4/emotion_check.m4 [new file with mode: 0644]
packaging/emotion.spec [new file with mode: 0644]
src/Makefile.am
src/bin/Makefile.am
src/bin/emotion_test_main.c
src/edje_external/Makefile.am [new file with mode: 0644]
src/edje_external/emotion.c [new file with mode: 0644]
src/examples/Makefile.am [new file with mode: 0644]
src/examples/emotion_basic_example.c [new file with mode: 0644]
src/examples/emotion_border_example.c [new file with mode: 0644]
src/examples/emotion_generic_example.c [new file with mode: 0644]
src/examples/emotion_signals_example.c [new file with mode: 0644]
src/generic_players/Makefile.am [new file with mode: 0644]
src/generic_players/vlc/Makefile.am [new file with mode: 0644]
src/generic_players/vlc/emotion_generic_vlc.c [new file with mode: 0644]
src/lib/Emotion.h
src/lib/Makefile.am
src/lib/emotion_main.c [new file with mode: 0644]
src/lib/emotion_private.h
src/lib/emotion_smart.c
src/modules/Makefile.am
src/modules/generic/Emotion_Generic_Plugin.h [new file with mode: 0644]
src/modules/generic/Makefile.am [new file with mode: 0644]
src/modules/generic/README [new file with mode: 0644]
src/modules/generic/emotion_generic.c [new file with mode: 0644]
src/modules/generic/emotion_generic.h [new file with mode: 0644]
src/modules/gstreamer/Makefile.am
src/modules/gstreamer/emotion_alloc.c [new file with mode: 0644]
src/modules/gstreamer/emotion_convert.c [new file with mode: 0644]
src/modules/gstreamer/emotion_fakeeos.c [new file with mode: 0644]
src/modules/gstreamer/emotion_gstreamer.c
src/modules/gstreamer/emotion_gstreamer.h
src/modules/gstreamer/emotion_sink.c [new file with mode: 0644]
src/modules/xine/Makefile.am
src/modules/xine/emotion_xine.c
src/modules/xine/emotion_xine.h
src/modules/xine/emotion_xine_vo_out.c

diff --git a/AUTHORS b/AUTHORS
index 9ba33c3..c2579a8 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,3 +1,10 @@
-The Rasterman (Carsten Haitzler) <raster@rasterman.com>
-doursse (Vincent Torri) <torri@maths.univ-evry.fr>
-captainigloo
+Carsten Haitzler <raster@rasterman.com>
+Vincent Torri <torri@maths.univ-evry.fr>
+Nicolas Aguirre <aguirre.nicolas@gmail.com>
+Sebastian Dransfeld <sd@tango.flipp.net>
+Cedric Bail <cedric.bail@free.fr>
+Rafael Antognolli <antognolli@profusion.mobi>
+Jérôme Pinot <ngc891@gmail.com>
+Pierre Le Magourou <pierre.lemagourou@openwide.fr>
+Hugo Camboulive <hugo.camboulive@zodiacaerospace.com>
+Sohyun Kim <anna1014.kim@samsung.com>
diff --git a/COPYING b/COPYING
index 474fcc5..aab8362 100644 (file)
--- 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.
index e47b581..af65492 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,36 +1,60 @@
-2007-10-31  Vincent Torri  <doursse at users dot sf dot net>
-
-       * 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  <doursse at users dot sf dot net>
-
-       * 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.
index 6d2fd00..248f9bd 100644 (file)
@@ -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 (file)
--- 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 (file)
--- 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 (file)
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 (executable)
index 0000000..4215842
--- /dev/null
@@ -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 (executable)
index 0000000..28a7d2a
--- /dev/null
@@ -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 (executable)
index 0000000..e171e93
--- /dev/null
@@ -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 (file)
index 0000000..1b4f989
--- /dev/null
@@ -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 (file)
index 0000000..6595436
--- /dev/null
@@ -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 (file)
index 0000000..b60a3d7
Binary files /dev/null and b/TC/emotion/test.avi differ
diff --git a/TC/emotion/tslist b/TC/emotion/tslist
new file mode 100644 (file)
index 0000000..f2fb627
--- /dev/null
@@ -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 (file)
index 0000000..de4a19a
--- /dev/null
@@ -0,0 +1,37 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..9956c83
--- /dev/null
@@ -0,0 +1,37 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..01a63a9
--- /dev/null
@@ -0,0 +1,37 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..6831a47
--- /dev/null
@@ -0,0 +1,37 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..ab8c131
--- /dev/null
@@ -0,0 +1,37 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..4225ad3
--- /dev/null
@@ -0,0 +1,51 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..3350fa6
--- /dev/null
@@ -0,0 +1,51 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..1570acc
--- /dev/null
@@ -0,0 +1,29 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..92292ae
--- /dev/null
@@ -0,0 +1,54 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..a55f0f5
--- /dev/null
@@ -0,0 +1,55 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..5b4142a
--- /dev/null
@@ -0,0 +1,45 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..979b2e0
--- /dev/null
@@ -0,0 +1,41 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..63b8f48
--- /dev/null
@@ -0,0 +1,60 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..7cc40f4
--- /dev/null
@@ -0,0 +1,63 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..9e5e468
--- /dev/null
@@ -0,0 +1,65 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..914fd20
--- /dev/null
@@ -0,0 +1,63 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..60f073b
--- /dev/null
@@ -0,0 +1,39 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..a299b02
--- /dev/null
@@ -0,0 +1,76 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..63894a5
--- /dev/null
@@ -0,0 +1,41 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..6ce39bf
--- /dev/null
@@ -0,0 +1,70 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..b96dfbf
--- /dev/null
@@ -0,0 +1,59 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..53c0cb4
--- /dev/null
@@ -0,0 +1,47 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..5ea4854
--- /dev/null
@@ -0,0 +1,52 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..8cd4821
--- /dev/null
@@ -0,0 +1,50 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..d38ff5e
--- /dev/null
@@ -0,0 +1,43 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..8375783
--- /dev/null
@@ -0,0 +1,63 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..5dab151
--- /dev/null
@@ -0,0 +1,45 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..fefedce
--- /dev/null
@@ -0,0 +1,45 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..795604f
--- /dev/null
@@ -0,0 +1,42 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..e94611e
--- /dev/null
@@ -0,0 +1,46 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..779859f
--- /dev/null
@@ -0,0 +1,43 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..3103059
--- /dev/null
@@ -0,0 +1,42 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..d337125
--- /dev/null
@@ -0,0 +1,41 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..366b216
--- /dev/null
@@ -0,0 +1,41 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..93fceec
--- /dev/null
@@ -0,0 +1,46 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..7907cf4
--- /dev/null
@@ -0,0 +1,42 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..9dc0528
--- /dev/null
@@ -0,0 +1,41 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..097858f
--- /dev/null
@@ -0,0 +1,42 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..be764db
--- /dev/null
@@ -0,0 +1,41 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..b9772e0
--- /dev/null
@@ -0,0 +1,41 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..7e1a4d1
--- /dev/null
@@ -0,0 +1,41 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..6666696
--- /dev/null
@@ -0,0 +1,60 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..40d64c5
--- /dev/null
@@ -0,0 +1,111 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..722ec89
--- /dev/null
@@ -0,0 +1,68 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..a8de5aa
--- /dev/null
@@ -0,0 +1,37 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..b752e3b
--- /dev/null
@@ -0,0 +1,37 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..2996028
--- /dev/null
@@ -0,0 +1,37 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..91c58ff
--- /dev/null
@@ -0,0 +1,37 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..4884033
--- /dev/null
@@ -0,0 +1,37 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..656db50
--- /dev/null
@@ -0,0 +1,31 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..ff296dd
--- /dev/null
@@ -0,0 +1,37 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..34a316b
--- /dev/null
@@ -0,0 +1,37 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..035fed3
--- /dev/null
@@ -0,0 +1,37 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..397f906
--- /dev/null
@@ -0,0 +1,42 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..f75b8f3
--- /dev/null
@@ -0,0 +1,48 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (file)
index 0000000..d5e00c0
--- /dev/null
@@ -0,0 +1,47 @@
+#include <tet_api.h>
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <signal.h>
+#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 (executable)
index 0000000..ce3421b
--- /dev/null
@@ -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 (file)
index 0000000..2309232
--- /dev/null
@@ -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 (executable)
index 0000000..f7eda55
--- /dev/null
@@ -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 (executable)
index 0000000..02d7030
--- /dev/null
@@ -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 (executable)
index 0000000..ef3e452
--- /dev/null
@@ -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 ?
index 995ff2f..00116ea 100755 (executable)
@@ -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 (file)
index 0000000..13b09c2
--- /dev/null
@@ -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 <stdio.h>
+#include <linux/videodev2.h>
+       ]],
+       [[
+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
index 5121518..6e5ce6f 100644 (file)
@@ -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
index 54100d5..0b79b69 100644 (file)
Binary files a/data/e_logo.png and b/data/e_logo.png differ
diff --git a/data/icon.edc b/data/icon.edc
new file mode 100644 (file)
index 0000000..0a3ea3d
--- /dev/null
@@ -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";
+            }
+         }
+      }
+   }
+}
index a3c28a0..63e732d 100644 (file)
@@ -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 (file)
index 0000000..80b0bb3
--- /dev/null
@@ -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 <mjae.lee@samsung.com>  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 <mjae.lee@samsung.com>  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 <jae.hwan.kim@samsung.com>  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 <jh0506.yun@samsung.com>  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 <jh0506.yun@samsung.com>  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 <jh0506.yun@samsung.com>  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 <jh0506.yun@samsung.com>  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 <jh0506.yun@samsung.com>  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 <jh0506.yun@samsung.com>  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 <jae.hwan.kim@samsung.com>  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 <jae.hwan.kim@samsung.com>  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 <mj.mccormack@samsung.com>  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 <mj.mccormack@samsung.com>  Mon, 14 Nov 2011 18:54:14 +0900
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..1e8b314
--- /dev/null
@@ -0,0 +1 @@
+6
index ed7a589..fe0d60e 100644 (file)
@@ -1,27 +1,30 @@
 Source: emotion
 Priority: optional
 Section: libs
-Maintainer: Falko Schmidt <falko@alphagemini.org>
-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 <jae.hwan.kim@samsung.com>, Myoungwoon Kim <myoungwoon.kim@samsung.com>, Jeonghyun Yun <jh0506.yun@samsung.com>
+Original-Maintainer: Falko Schmidt <falko@alphagemini.org>
+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 (file)
index 0000000..b8d218e
--- /dev/null
@@ -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 (file)
index 0000000..8494825
--- /dev/null
@@ -0,0 +1 @@
+debian/tmp/usr/lib/emotion/*gstreamer*.so
index 7945678..c688e77 100644 (file)
@@ -1 +1,3 @@
 debian/tmp/usr/lib/libemotion.so.*
+debian/tmp/usr/bin/emotion_*
+debian/tmp/usr/share/emotion/data/theme.edj
old mode 100644 (file)
new mode 100755 (executable)
index 378c8aa..49e465a
@@ -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 (file)
index 0000000..907be04
--- /dev/null
@@ -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 (file)
index 0000000..f5cdc41
--- /dev/null
@@ -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
index 604ee7f..2dd6b44 100644 (file)
--- a/doc/e.css
+++ b/doc/e.css
+/*
+    Author:
+        Andres Blanc <andresblanc@gmail.com>
+       DaveMDS Andreoli <dave@gurumeditation.it>
+
+    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 (file)
index 0000000..5e193f1
--- /dev/null
@@ -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.
+ */
index 0d3303d..d43cf8f 100644 (file)
@@ -1,6 +1,18 @@
+ <div id="push"></div>
+ </div> <!-- #content -->
+  </div> <!-- .layout -->
+ </div> <!-- #container -->
+  <div id="footer">
+    <table><tr>
+      <td class="copyright">Copyright &copy;$year Enlightenment</td>
+      <td class="generated">Docs generated $datetime</td>
+    </tr></table>
   </div>
-  <hr />
-  <p class="tiny">Copyright &copy; Enlightenment.org</p>
-  <p class="tiny">$projectname Documentation Generated: $datetime</p>
- </body>
+
+
+</body>
 </html>
index c79a91d..16696c4 100644 (file)
@@ -1,43 +1,68 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
 <html>
- <head>
-  <title>$title</title>
-  <link href="e.css" rel="stylesheet" type="text/css" />
- </head>
+<head>
+    <title>$title</title>
+    <meta http-equiv="content-type" content="text/html;charset=UTF-8">
+    <meta name="author" content="Andres Blanc" >
+    
+    <link rel="icon" href="img/favicon.png" type="image/x-icon">
+    <link rel="shortcut icon" href="img/favicon.png" type="image/x-icon">
+    <link rel="icon" href="img/favicon.png" type="image/ico">
+    <link rel="shortcut icon" href="img/favicon.png" type="image/ico">
+
+    <link rel="stylesheet" type="text/css" href="e.css">
+    <link rel="stylesheet" type="text/css" href="edoxy.css">
+</head>
 
 <body>
- <table width="100%" border="0" cellpadding="0" cellspacing="0">
-  <tr>
-   <td class="t" width="50%" valign="top" align="left">
-     <table width="100px" height="100px" border="0" cellpadding="0" cellspacing="0">
-     <tr><td class="lnav"><a class="nav" href="http://web.enlightenment.org/p.php?p=index">Home</a></td></tr>
-     <tr><td class="lnav"><a class="nav" href="http://web.enlightenment.org/p.php?p=news">News</a></td></tr>
-     <tr><td class="lnav"><a class="nav" href="http://web.enlightenment.org/p.php?p=about">About</a></td></tr>
-     <tr><td class="rnav"><a class="nav" href="http://web.enlightenment.org/p.php?p=download">Download</a></td></tr>
-    </table>
-   </td>
-   <td class="tl" width="612" height="250" valign="bottom" align="center">
-    <img src="_.gif" width="612" height="1" />
-    <table border="0" cellpadding="0" cellspacing="4px">
-     <tr>
-      <td class='nav'><a class='nav' href="index.html">Main&nbsp;Page</a></td>
-      <td class="nav"><a class="nav" href="emotion_8c.html">API Reference</a></td>
-      <td class="nav"><a class="nav" href="pages.html">Related Pages</a></td>
-     </tr>
-    </table>
-    <hr />
-   </td>
-   <td class="t" width="50%" valign="top" align="right">
-    <table width="100px" height="100px" border="0" cellpadding="0" cellspacing="0">
-     <tr><td class="rnav"><a class="nav" href="http://web.enlightenment.org/p.php?p=support">Support</a></td></tr>
-     <tr><td class="lnav"><a class="nav" href="http://web.enlightenment.org/p.php?p=contribute">Contribute</a></td></tr>
-     <tr><td class="lnav"><a class="nav" href="http://web.enlightenment.org/p.php?p=contact">Contact</a></td></tr>
-     <tr><td class="lnav"><a class="nav" href="http://trac.enlightenment.org/e">Tracker</a></td></tr>
-    </table>
-   </td>
-  </tr>
- </table>
-
- <div class="main">
+
+<div id="container">
+
+<div id="header">
+<div class="layout">
+    
+    <h1><span>Enlightenment</span></h1>
+    <h2><span>Beauty at your fingertips</span></h2>
+
+    <table cellspacing="0" cellpadding="0" width="100%"><tr>
+      <td id="header_logo">
+        <a href="http://www.enlightenment.org"></a>
+      </td>
+      <td id="header_menu">
+        <table cellspacing="0" cellpadding="0" align="right"><tr>
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=home">Home</a></td> 
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=news">News</a></td> 
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=about">About</a></td> 
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=download">Download</a></td> 
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=support">Support</a></td> 
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=contribute">Contribute</a></td> 
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=contact">Contact</a></td> 
+          <td class="nav_passive"><a class="nav_passive" href="http://trac.enlightenment.org/e">Tracker</a></td>
+          <td class="nav_passive"><a class="nav_passive" href="http://www.enlightenment.org/p.php?p=docs">Docs</a></td> 
+        </tr></table>          
+      </td>
+      <td id="header_last"></td>
+    </tr></table>
+
+    <div class="doxytitle">
+        $projectname Documentation <small>at $date</small>
+    </div>
+
+    <div class="menu-container">
+        <div class="submenu">
+            <ul class="current">
+                <li><a href="files.html">Files</a></li>
+                <li><a href="globals.html">Globals</a></li>
+                <li><a href="modules.html">Modules</a></li>
+                <li><a href="pages.html">Related Pages</a></li>
+               <li class="current"><a  href="index.html">Main Page</a></li>
+            </ul>
+        </div>
+    </div>
+
+
+    <div class="clear"></div>
+</div>
+</div>
+
+<div id="content">
+<div class="layout">
diff --git a/doc/img/e.png b/doc/img/e.png
new file mode 100644 (file)
index 0000000..d42aeb4
Binary files /dev/null and b/doc/img/e.png differ
diff --git a/doc/img/edoxy.css b/doc/img/edoxy.css
new file mode 100644 (file)
index 0000000..311ca23
--- /dev/null
@@ -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 (file)
index 0000000..624196b
--- /dev/null
@@ -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 (file)
index 0000000..4ae37fd
Binary files /dev/null and b/doc/img/emotion_ratio.png differ
diff --git a/doc/img/foot_bg.png b/doc/img/foot_bg.png
new file mode 100644 (file)
index 0000000..b24f3a4
Binary files /dev/null and b/doc/img/foot_bg.png differ
diff --git a/doc/img/head_bg.png b/doc/img/head_bg.png
new file mode 100644 (file)
index 0000000..081dc13
Binary files /dev/null and b/doc/img/head_bg.png differ
diff --git a/doc/img/header_menu_background.png b/doc/img/header_menu_background.png
new file mode 100644 (file)
index 0000000..e978743
Binary files /dev/null and b/doc/img/header_menu_background.png differ
diff --git a/doc/img/header_menu_background_last.png b/doc/img/header_menu_background_last.png
new file mode 100644 (file)
index 0000000..88c116c
Binary files /dev/null and b/doc/img/header_menu_background_last.png differ
diff --git a/doc/img/header_menu_current_background.png b/doc/img/header_menu_current_background.png
new file mode 100644 (file)
index 0000000..de97c92
Binary files /dev/null and b/doc/img/header_menu_current_background.png differ
diff --git a/doc/img/header_menu_unselected_background.png b/doc/img/header_menu_unselected_background.png
new file mode 100644 (file)
index 0000000..50e5fd8
Binary files /dev/null and b/doc/img/header_menu_unselected_background.png differ
diff --git a/doc/img/logo.png b/doc/img/logo.png
new file mode 100644 (file)
index 0000000..b3884a5
Binary files /dev/null and b/doc/img/logo.png differ
diff --git a/emotion-gstreamer.manifest b/emotion-gstreamer.manifest
new file mode 100644 (file)
index 0000000..97e8c31
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_"/>
+       </request>
+</manifest>
diff --git a/emotion.manifest b/emotion.manifest
new file mode 100644 (file)
index 0000000..97e8c31
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_"/>
+       </request>
+</manifest>
index f628489..5126c3b 100644 (file)
@@ -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@
index cc08edf..c6fa495 100644 (file)
@@ -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 (file)
index 0000000..3926d23
--- /dev/null
@@ -0,0 +1,46 @@
+dnl Copyright (C) 2004-2008 Kim Woelders
+dnl Copyright (C) 2008 Vincent Torri <vtorri at univ-evry dot fr>
+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 <stdlib.h>
+
+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 (file)
index 0000000..b9c9fd1
--- /dev/null
@@ -0,0 +1,44 @@
+dnl Copyright (C) 2010 Vincent Torri <vtorri at univ-evry dot fr>
+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 (file)
index 0000000..7324af3
--- /dev/null
@@ -0,0 +1,94 @@
+dnl Copyright (C) 2008 Vincent Torri <vtorri at univ-evry dot fr>
+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 (file)
index 0000000..703f83e
--- /dev/null
@@ -0,0 +1,56 @@
+dnl Copyright (C) 2010-2011 Vincent Torri <vtorri at univ-evry dot fr>
+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 (file)
index 0000000..2a809ad
--- /dev/null
@@ -0,0 +1,63 @@
+dnl Copyright (C) 2008 Vincent Torri <vtorri at univ-evry dot fr>
+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 (file)
index 0000000..0bf1b0b
--- /dev/null
@@ -0,0 +1,69 @@
+dnl Copyright (C) 2010 Vincent Torri <vtorri at univ-evry dot fr>
+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 <sys/mman.h>
+#include <sys/stat.h>        /* For mode constants */
+#include <fcntl.h>           /* 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 <sys/mman.h>
+#include <sys/stat.h>        /* For mode constants */
+#include <fcntl.h>           /* 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 (file)
index 0000000..043ae44
--- /dev/null
@@ -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 (file)
index 0000000..30b06c7
--- /dev/null
@@ -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
index 2ab111e..4082c3a 100644 (file)
@@ -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
index a90d598..79dd4e3 100644 (file)
@@ -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
index 16bb1a5..13380d6 100644 (file)
@@ -1,22 +1,45 @@
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 
-#if defined(HAVE_ECORE_X_H) || defined(HAVE_ECORE_FB_H)
-
 #include <Evas.h>
 #include <Ecore.h>
-#ifndef FB_ONLY
-#include <Ecore_X.h>
-#else
-#include <Ecore_Fb.h>
-#endif
+#include <Ecore_Getopt.h>
 #include <Ecore_Evas.h>
 #include <Edje.h>
 
 #include "Emotion.h"
 
+static const Ecore_Getopt options = {
+   "emotion_test",
+   "%prog [options] <filename>",
+   "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 : "<auto>");
+   printf("emotion backend: %s\n", backend ? backend : "<auto>");
+   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 (file)
index 0000000..9b36faf
--- /dev/null
@@ -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 (file)
index 0000000..d7fc012
--- /dev/null
@@ -0,0 +1,516 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <Edje.h>
+
+#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 (file)
index 0000000..7476f08
--- /dev/null
@@ -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 (file)
index 0000000..7e3e4c2
--- /dev/null
@@ -0,0 +1,81 @@
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <stdio.h>
+
+#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 <filename>\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 (file)
index 0000000..9df53f4
--- /dev/null
@@ -0,0 +1,238 @@
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <stdio.h>
+#include <string.h>
+
+#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 <filename>\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 (file)
index 0000000..b838286
--- /dev/null
@@ -0,0 +1,233 @@
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#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 <filename>\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 (file)
index 0000000..2469c46
--- /dev/null
@@ -0,0 +1,173 @@
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Emotion.h>
+#include <stdio.h>
+
+#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 <filename> [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 (file)
index 0000000..bbdd8c3
--- /dev/null
@@ -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 (file)
index 0000000..5cda1b9
--- /dev/null
@@ -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 (file)
index 0000000..583036d
--- /dev/null
@@ -0,0 +1,873 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <poll.h>
+
+#include <sys/prctl.h>
+#include <signal.h>
+
+#include <vlc/vlc.h>
+
+#include <Emotion_Generic_Plugin.h>
+
+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 <fd read> <fd write>\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
index e55757f..361e4e5 100644 (file)
@@ -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 <raster@rasterman.com>
+ * @author Vincent Torri <torri@maths.univ-evry.fr>
+ * @author Nicolas Aguirre <aguirre.nicolas@gmail.com>
+ * @author Sebastian Dransfeld <sd@tango.flipp.net>
+ * @author Cedric Bail <cedric.bail@free.fr>
+ * 
+ * Please contact <enlightenment-devel@lists.sourceforge.net> to get in
+ * contact with the developers and maintainers.
+ * 
+ */
+
+#include <Evas.h>
+
 #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
 # else
 #  define EAPI
 # endif
-#endif
+#endif /* ! _WIN32 */
 
-#include <Evas.h>
+/**
+ * @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
index 34a4a2e..a2d2198 100644 (file)
@@ -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 (file)
index 0000000..52b1baa
--- /dev/null
@@ -0,0 +1,484 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#elif !defined alloca
+# ifdef __GNUC__
+#  define alloca __builtin_alloca
+# elif defined _AIX
+#  define alloca __alloca
+# elif defined _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# elif !defined HAVE_ALLOCA
+#  ifdef  __cplusplus
+extern "C"
+#  endif
+void *alloca (size_t);
+# endif
+#endif
+
+#include <stdio.h>
+
+#ifdef EMOTION_HAVE_EEZE
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <sys/ioctl.h>
+# ifdef HAVE_V4L2
+#  include <linux/videodev2.h>
+# endif
+
+# include <Ecore.h>
+# include <Eeze.h>
+#endif
+
+#include <Eet.h>
+
+#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--;
+}
index 4d92561..cf24c75 100644 (file)
@@ -1,18 +1,6 @@
 #ifndef EMOTION_PRIVATE_H
 #define EMOTION_PRIVATE_H
 
-#include <Evas.h>
-#include <Ecore.h>
-#include <Ecore_Job.h>
-#include <Ecore_Data.h>
-#include <Ecore_Str.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "config.h"
-
 #define META_TRACK_TITLE 1
 #define META_TRACK_ARTIST 2
 #define META_TRACK_GENRE 3
 #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
index 5943820..48eafda 100644 (file)
@@ -1,6 +1,24 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <Evas.h>
+#include <Ecore.h>
+
+#ifdef HAVE_EIO
+# include <math.h>
+# include <Eio.h>
+#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; \
       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);
 }
+
index 1af8c8c..faaa146 100644 (file)
@@ -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 (file)
index 0000000..17bd7e9
--- /dev/null
@@ -0,0 +1,144 @@
+#ifndef EMOTION_GENERIC_PLUGIN_H
+#define EMOTION_GENERIC_PLUGIN_H
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <Eina.h>
+
+#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 (file)
index 0000000..23be987
--- /dev/null
@@ -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 (file)
index 0000000..c2a028d
--- /dev/null
@@ -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", <command>);
+
+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 (file)
index 0000000..e4771ce
--- /dev/null
@@ -0,0 +1,1794 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <Eina.h>
+#include <Evas.h>
+#include <Ecore.h>
+
+#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, &param, 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, &param, 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, &param, 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, &param, 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, &param, 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 (file)
index 0000000..ed3bdb0
--- /dev/null
@@ -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
+
index f3519af..3672510 100644 (file)
@@ -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 (file)
index 0000000..05062bd
--- /dev/null
@@ -0,0 +1,91 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <Eina.h>
+#include <Evas.h>
+#include <Ecore.h>
+
+#include <glib.h>
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/video/gstvideosink.h>
+
+#ifdef HAVE_ECORE_X
+# include <Ecore_X.h>
+# include <Ecore_Evas.h>
+# ifdef HAVE_XOVERLAY_H
+#  include <gst/interfaces/xoverlay.h>
+# 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 (file)
index 0000000..3d3b46e
--- /dev/null
@@ -0,0 +1,252 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <Eina.h>
+#include <Evas.h>
+
+#include <glib.h>
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/video/gstvideosink.h>
+
+#ifdef HAVE_ECORE_X
+# include <Ecore_X.h>
+# include <Ecore_Evas.h>
+# ifdef HAVE_XOVERLAY_H
+#  include <gst/interfaces/xoverlay.h>
+# 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 (file)
index 0000000..a9e1bbe
--- /dev/null
@@ -0,0 +1,71 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <Eina.h>
+#include <Evas.h>
+
+#include <glib.h>
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/video/gstvideosink.h>
+
+#ifdef HAVE_ECORE_X
+# include <Ecore_X.h>
+# include <Ecore_Evas.h>
+# ifdef HAVE_XOVERLAY_H
+#  include <gst/interfaces/xoverlay.h>
+# 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__)
+{
+}
index 4bb6348..8ec71fb 100644 (file)
@@ -1,18 +1,44 @@
-/*
- * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
- */
-#include <unistd.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
 #include <fcntl.h>
 
+#include <Eina.h>
+#include <Evas.h>
+#include <Ecore.h>
+
+#define HTTP_STREAM 0
+#define RTSP_STREAM 1
+#include <glib.h>
+#include <gst/gst.h>
+#include <glib-object.h>
+#include <gst/video/gstvideosink.h>
+#include <gst/video/video.h>
+
+#ifdef HAVE_ECORE_X
+# include <Ecore_X.h>
+# include <Ecore_Evas.h>
+# ifdef HAVE_XOVERLAY_H
+#  include <gst/interfaces/xoverlay.h>
+# 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;
 }
index b335604..9c7455d 100644 (file)
@@ -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 <Evas.h>
-#include <Ecore.h>
-#include <Ecore_Data.h>
-
-#define HTTP_STREAM 0
-#define RTSP_STREAM 1
-#include <gst/gst.h>
-
-#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 (file)
index 0000000..17a1bc5
--- /dev/null
@@ -0,0 +1,1391 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <Eina.h>
+#include <Evas.h>
+#include <Ecore.h>
+
+#define HTTP_STREAM 0
+#define RTSP_STREAM 1
+#include <glib.h>
+#include <gst/gst.h>
+#include <glib-object.h>
+#include <gst/video/gstvideosink.h>
+#include <gst/video/video.h>
+
+#ifdef HAVE_ECORE_X
+# include <Ecore_X.h>
+# include <Ecore_Evas.h>
+# ifdef HAVE_XOVERLAY_H
+#  include <gst/interfaces/xoverlay.h>
+# 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 <vtorri@univ-evry.fr>");
+}
+
+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;
+}
index 6ae4990..baf8fec 100644 (file)
@@ -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
index 41624af..dd4a3a5 100644 (file)
@@ -1,7 +1,17 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <Eina.h>
+#include <Evas.h>
+#include <Ecore.h>
+
 #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);
          }
      }
 }
index 8a9efcc..c1cae2e 100644 (file)
@@ -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
index 439ae92..3ae8e1c 100644 (file)
@@ -1,11 +1,20 @@
 /***************************************************************************/
 /***                  emotion xine display engine                        ***/
 /***************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
 
+#include <Eina.h>
+#include <Evas.h>
+#include <Ecore.h>
+
+#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);