Olena-patches
Threads by month
- ----- 2025 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions

last-svn-commit-702-g1b4ffab Fix Paths in scripts and build systems.
by Guillaume Lazzara 11 Apr '11
by Guillaume Lazzara 11 Apr '11
11 Apr '11
* segmentation/segmentation.pro,
* segmentation/segmentation.sh,
* segmentation2dt/segmentation2dt.pro,
* segmentation2dt/segmentation2dt.sh,
* viewer/viewer.pro: Here.
* anapath/anapath.sh: New.
---
igr/ChangeLog | 10 ++++++++++
igr/anapath/anapath.sh | 4 ++++
igr/segmentation/segmentation.pro | 2 +-
igr/segmentation/segmentation.sh | 2 +-
igr/segmentation2dt/segmentation2dt.pro | 4 ++--
igr/segmentation2dt/segmentation2dt.sh | 2 +-
igr/viewer/viewer.pro | 2 +-
7 files changed, 20 insertions(+), 6 deletions(-)
create mode 100755 igr/anapath/anapath.sh
diff --git a/igr/ChangeLog b/igr/ChangeLog
index 9298ac3..f915752 100644
--- a/igr/ChangeLog
+++ b/igr/ChangeLog
@@ -1,3 +1,13 @@
+2010-11-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Fix Paths in scripts and build systems.
+
+ * segmentation/segmentation.pro,
+ * segmentation/segmentation.sh,
+ * segmentation2dt/segmentation2dt.pro,
+ * segmentation2dt/segmentation2dt.sh,
+ * viewer/viewer.pro: Here.
+
2010-11-16 Guillaume Lazzara <z(a)lrde.epita.fr>
Update build system to use MLN_WO_GLOBAL_VARS.
diff --git a/igr/anapath/anapath.sh b/igr/anapath/anapath.sh
new file mode 100755
index 0000000..b1c0c85
--- /dev/null
+++ b/igr/anapath/anapath.sh
@@ -0,0 +1,4 @@
+#!/bin/zsh
+source ~/.zshrc
+/home/inca/olena/igr/anapath/anapath
+
diff --git a/igr/segmentation/segmentation.pro b/igr/segmentation/segmentation.pro
index 4a0f003..743ce04 100644
--- a/igr/segmentation/segmentation.pro
+++ b/igr/segmentation/segmentation.pro
@@ -5,7 +5,7 @@
TEMPLATE = app
TARGET =
DEPENDPATH += . src ui
-#INCLUDEPATH += . src $(PWD)/../../ $(PWD)/.. $(PWD)/../shared $(OLN)/milena /home/inca/local/include
+#INCLUDEPATH += . src $(PWD)/../../ $(PWD)/.. $(PWD)/../shared $(OLN)/milena /home/inca/local/include /usr/local/qwt-5.0.2/include
INCLUDEPATH += . src $(PWD)/.. $(PWD)/../shared $(OLN)/milena
DEFINES= NDEBUG MLN_WO_GLOBAL_VARS
diff --git a/igr/segmentation/segmentation.sh b/igr/segmentation/segmentation.sh
index ea2f160..32a8c5c 100755
--- a/igr/segmentation/segmentation.sh
+++ b/igr/segmentation/segmentation.sh
@@ -1,3 +1,3 @@
#!/bin/zsh
source ~/.zshrc
-/home/inca/olena/trunk/milena/sandbox/lazzara/igr/gui/segmentation/segmentation
+/home/inca/olena/igr/segmentation/segmentation
diff --git a/igr/segmentation2dt/segmentation2dt.pro b/igr/segmentation2dt/segmentation2dt.pro
index d7ce7e6..69456f1 100644
--- a/igr/segmentation2dt/segmentation2dt.pro
+++ b/igr/segmentation2dt/segmentation2dt.pro
@@ -5,14 +5,14 @@
TEMPLATE = app
TARGET =
DEPENDPATH += . src ui
-#INCLUDEPATH += . src $(PWD)/../../ $(PWD)/.. $(PWD)/../shared $(OLN)/milena /home/inca/local/include
+#INCLUDEPATH += . src $(PWD)/../../ $(PWD)/.. $(PWD)/../shared $(OLN)/milena /home/inca/local/include /usr/local/qwt-5.0.2/include
INCLUDEPATH += . src $(PWD)/.. $(PWD)/../shared $(OLN)/milena
DEFINES= NDEBUG MLN_WO_GLOBAL_VARS
QMAKE_CXX += -O2
-#LIBS += -L/home/inca/local/lib -lgdcmCommon -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lgdcmexpat -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmopenjpeg -lgdcmuuid -lgdcmzlib -lqwt-qt4
+#LIBS += -L/home/inca/local/lib -lgdcmCommon -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lgdcmexpat -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmopenjpeg -lgdcmuuid -lgdcmzlib -L/usr/local/qwt-5.0.2/lib -lqwt
LIBS += -lgdcmCommon -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lqwt-qt4
diff --git a/igr/segmentation2dt/segmentation2dt.sh b/igr/segmentation2dt/segmentation2dt.sh
index 54b0a37..9ceeeef 100755
--- a/igr/segmentation2dt/segmentation2dt.sh
+++ b/igr/segmentation2dt/segmentation2dt.sh
@@ -1,4 +1,4 @@
#!/bin/zsh
source ~/.zshrc
-/home/inca/olena/trunk/milena/sandbox/lazzara/igr/gui/segmentation2dt/segmentation2dt
+/home/inca/olena/igr/segmentation2dt/segmentation2dt
diff --git a/igr/viewer/viewer.pro b/igr/viewer/viewer.pro
index b384b8f..ef01446 100644
--- a/igr/viewer/viewer.pro
+++ b/igr/viewer/viewer.pro
@@ -6,7 +6,7 @@ TEMPLATE = app
TARGET =
DEPENDPATH += . src ui
INCLUDEPATH += . src ../shared ../ $(OLN)/milena
-#INCLUDEPATH += . src ../shared ../ $(OLN)/milena /home/inca/local/include
+#INCLUDEPATH += . src ../shared ../ $(OLN) /home/inca/local/include
DEFINES= NDEBUG MLN_WO_GLOBAL_VARS
--
1.5.6.5
1
0
* mln/convert/from_to.hxx: Add forward declarations.
* mln/convert/impl/all.hh: Include from_to_builtins.hh.
* mln/convert/impl/from_to_builtins.hh: New. Add new from_to
overloads for builtin types.
---
milena/ChangeLog | 11 +++
milena/mln/convert/from_to.hxx | 17 ++++-
milena/mln/convert/impl/all.hh | 4 +-
.../{from_int_to_value.hh => from_to_builtins.hh} | 82 ++++++++------------
4 files changed, 61 insertions(+), 53 deletions(-)
copy milena/mln/convert/impl/{from_int_to_value.hh => from_to_builtins.hh} (56%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 23fa923..7268baf 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,14 @@
+2011-01-13 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add more from_to overloads.
+
+ * mln/convert/from_to.hxx: Add forward declarations.
+
+ * mln/convert/impl/all.hh: Include from_to_builtins.hh.
+
+ * mln/convert/impl/from_to_builtins.hh: New. Add new from_to
+ overloads for builtin types.
+
2010-04-07 Guillaume Lazzara <z(a)lrde.epita.fr>
Add an image loader in the anapath GUI.
diff --git a/milena/mln/convert/from_to.hxx b/milena/mln/convert/from_to.hxx
index cc7cc15..b6ecfc5 100644
--- a/milena/mln/convert/from_to.hxx
+++ b/milena/mln/convert/from_to.hxx
@@ -1,4 +1,4 @@
-// Copyright (C) 2008, 2009, 2010 EPITA Research and Development
+// Copyright (C) 2008, 2009, 2010, 2011 EPITA Research and Development
// Laboratory (LRDE)
//
// This file is part of Olena.
@@ -211,6 +211,21 @@ namespace mln
template <unsigned n>
void from_to_(const value::int_u<n>& from, double& to_);
+ /// float -> double
+ template <typename V>
+ void
+ from_to(const float& from, double& to);
+
+ /// bool -> double
+ template <typename V>
+ void
+ from_to(const bool& from, double& to);
+
+ /// unsigned -> double
+ template <typename V>
+ void
+ from_to(const unsigned& from, double& to);
+
// label -> int_u.
template <unsigned n>
void
diff --git a/milena/mln/convert/impl/all.hh b/milena/mln/convert/impl/all.hh
index 7c3405b..10a98ed 100644
--- a/milena/mln/convert/impl/all.hh
+++ b/milena/mln/convert/impl/all.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009, 2011 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -36,6 +37,7 @@
# include <mln/convert/impl/from_image_to_site_set.hh>
# include <mln/convert/impl/from_int_to_value.hh>
# include <mln/convert/impl/from_site_set_to_image.hh>
+# include <mln/convert/impl/from_to_builtins.hh>
# include <mln/convert/impl/from_unsigned_to_value.hh>
# include <mln/convert/impl/from_value_to_value.hh>
diff --git a/milena/mln/convert/impl/from_int_to_value.hh b/milena/mln/convert/impl/from_to_builtins.hh
similarity index 56%
copy from milena/mln/convert/impl/from_int_to_value.hh
copy to milena/mln/convert/impl/from_to_builtins.hh
index 30840b3..ddad7b9 100644
--- a/milena/mln/convert/impl/from_int_to_value.hh
+++ b/milena/mln/convert/impl/from_to_builtins.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -23,89 +23,69 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_CONVERT_IMPL_FROM_INT_TO_VALUE_HH
-# define MLN_CONVERT_IMPL_FROM_INT_TO_VALUE_HH
+#ifndef MLN_CONVERT_IMPL_FROM_TO_BUILTINS_HH
+# define MLN_CONVERT_IMPL_FROM_TO_BUILTINS_HH
/// \file
///
-/// General conversion procedure from a int to a value.
+/// Conversion procedure from builtins to builtins.
///
/// \todo Augment code + add checks.
-# include <utility>
-# include <mln/value/concept/integer.hh>
-# include <mln/core/concept/value.hh>
-# include <mln/math/round.hh>
-
-
-
-
namespace mln
{
namespace convert
{
- /// Conversion of a int \p from towards a value \p to.
+ /// Conversion of a float \p from towards a double \p to.
+ template <typename V>
+ void
+ from_to(const float& from, double& to);
+
+ /// Conversion of a bool \p from towards a double \p to.
template <typename V>
void
- from_to(const int& from, Value<V>& to);
+ from_to(const bool& from, double& to);
+
+ /// Conversion of an unsigned \p from towards a double \p to.
+ template <typename V>
+ void
+ from_to(const unsigned& from, double& to);
# ifndef MLN_INCLUDE_ONLY
- namespace impl
+ namespace over_load
{
- // Case 1:
-
- template <typename V>
- inline
- void
- from_int_to_value(const int& from,
- mln::value::Integer<V>& to)
- {
- exact(to) = from;
- }
+ // Facades.
- // Default: no conversion defined.
- template <typename V>
+ // float->double
inline
void
- from_int_to_value(const int& from,
- Value<V>& to)
+ from_to_(const float& from, double& to)
{
- mlc_abort(V)::check();
+ to = from;
}
- } // end of namespace mln::convert::impl
-
-
- namespace internal
- {
-
- template <typename V>
+ // bool->double
inline
void
- from_int_to_value_dispatch(const int& from, Value<V>& to)
+ from_to_(const bool& from,
+ double& to)
{
- impl::from_int_to_value(from, exact(to));
+ to = from;
}
- } // end of namespace mln::convert::internal
-
-
- namespace over_load
- {
-
- // Facades.
- // int-> Value
- template <typename V>
+ // unsigned->double
+ inline
void
- from_to_(const int& from, Value<V>& to)
+ from_to_(const unsigned& from,
+ double& to)
{
- internal::from_int_to_value_dispatch(from, to);
+ to = from;
}
} // end of namespace mln::convert::over_load
@@ -117,4 +97,4 @@ namespace mln
} // end of namespace mln
-#endif // ! MLN_CONVERT_IMPL_FROM_INT_TO_VALUE_HH
+#endif // ! MLN_CONVERT_IMPL_FROM_TO_BUILTINS_HH
--
1.5.6.5
1
0

11 Apr '11
* igr/segmentation/src/mln_data.cc
* igr/segmentation2dt/src/mln_data.cc
* igr/shared/src/igr_types.hh
* igr/viewer/src/mln_data.cc
---
igr/ChangeLog | 9 +++++++++
igr/segmentation/src/mln_data.cc | 8 ++++----
igr/segmentation2dt/src/mln_data.cc | 2 +-
igr/shared/src/igr_types.hh | 4 ++--
igr/viewer/src/mln_data.cc | 23 ++++++++++++-----------
5 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/igr/ChangeLog b/igr/ChangeLog
index f915752..1a38d23 100644
--- a/igr/ChangeLog
+++ b/igr/ChangeLog
@@ -1,3 +1,12 @@
+2011-01-13 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Use int_u16 instead of int_u12.
+
+ * igr/segmentation/src/mln_data.cc
+ * igr/segmentation2dt/src/mln_data.cc
+ * igr/shared/src/igr_types.hh
+ * igr/viewer/src/mln_data.cc
+
2010-11-18 Guillaume Lazzara <z(a)lrde.epita.fr>
Fix Paths in scripts and build systems.
diff --git a/igr/segmentation/src/mln_data.cc b/igr/segmentation/src/mln_data.cc
index 0254d98..ca4af30 100644
--- a/igr/segmentation/src/mln_data.cc
+++ b/igr/segmentation/src/mln_data.cc
@@ -54,7 +54,7 @@ namespace igr
void mln_data::load_pgm(const QString& filename)
{
- image2d<value::int_u12> tmp;
+ image2d<value::int_u16> tmp;
io::pgm::load(tmp, filename.toStdString());
if (!tmp.is_valid())
@@ -81,7 +81,7 @@ namespace igr
if (header.dim == 2)
{
- image2d<value::int_u12> tmp;
+ image2d<value::int_u16> tmp;
io::dicom::load(tmp, filename.toStdString());
if (!tmp.is_valid())
@@ -119,7 +119,7 @@ namespace igr
io::dump::dump_header
header = io::dump::get_header(filename.toStdString());
- if (header.value_type != "int_u12")
+ if (header.value_type != "int_u16")
{
QString msg("Image value type not supported : %1");
msg.arg(header.value_type.c_str());
@@ -129,7 +129,7 @@ namespace igr
if (header.dim == 2)
{
- image2d<value::int_u12> tmp;
+ image2d<value::int_u16> tmp;
io::dump::load(tmp, filename.toStdString());
if (!tmp.is_valid())
diff --git a/igr/segmentation2dt/src/mln_data.cc b/igr/segmentation2dt/src/mln_data.cc
index 160363f..b49be39 100644
--- a/igr/segmentation2dt/src/mln_data.cc
+++ b/igr/segmentation2dt/src/mln_data.cc
@@ -91,7 +91,7 @@ namespace igr
io::dump::dump_header
header = io::dump::get_header(filename.toStdString());
- if (header.value_type != "int_u12")
+ if (header.value_type != "int_u16" || header.value_type != "int_u12")
{
QString msg("Image value type not supported : %1");
msg.arg(header.value_type.c_str());
diff --git a/igr/shared/src/igr_types.hh b/igr/shared/src/igr_types.hh
index 5154b6b..6c10b52 100644
--- a/igr/shared/src/igr_types.hh
+++ b/igr/shared/src/igr_types.hh
@@ -4,7 +4,7 @@
# include <shared/src/color.hh>
# include <mln/value/label_16.hh>
-# include <mln/value/int_u12.hh>
+# include <mln/value/int_u16.hh>
# include <mln/value/int_u8.hh>
@@ -14,7 +14,7 @@ namespace igr
using namespace mln;
// Data type of original DICOM files.
- typedef value::int_u12 input_data_t;
+ typedef value::int_u16 input_data_t;
// Data type of DICOM images loaded in memories.
typedef value::int_u8 input_mem_data_t;
diff --git a/igr/viewer/src/mln_data.cc b/igr/viewer/src/mln_data.cc
index 4ba3864..e1ae0b1 100644
--- a/igr/viewer/src/mln_data.cc
+++ b/igr/viewer/src/mln_data.cc
@@ -27,6 +27,7 @@
#include <mln/data/convert.hh>
#include <mln/data/stretch.hh>
#include <mln/value/int_u8.hh>
+#include <mln/value/int_u16.hh>
#include <mln/extension/adjust.hh>
#include <mln/io/dump/all.hh>
@@ -73,7 +74,7 @@ namespace igr
void mln_data::load_pgm(const QString& filename)
{
- image2d<value::int_u12> tmp;
+ image2d<value::int_u16> tmp;
io::pgm::load(tmp, filename.toStdString());
if (!tmp.is_valid())
@@ -100,9 +101,9 @@ namespace igr
if (header.dim == 2)
{
- if (header.value_type == "int_u12")
+ if (header.value_type == "int_u16")
{
- image2d<value::int_u12> tmp;
+ image2d<value::int_u16> tmp;
io::raw::load(tmp, filename.toStdString());
if (!tmp.is_valid())
@@ -146,9 +147,9 @@ namespace igr
}
else if (header.dim == 3)
{
- if (header.value_type == "int_u12")
+ if (header.value_type == "int_u16")
{
- image2d<value::int_u12> tmp;
+ image2d<value::int_u16> tmp;
io::raw::load(tmp, filename.toStdString());
if (!tmp.is_valid())
@@ -211,7 +212,7 @@ namespace igr
if (header.dim == 2)
{
- image2d<value::int_u12> tmp;
+ image2d<value::int_u16> tmp;
io::dicom::load(tmp, filename.toStdString());
if (!tmp.is_valid())
@@ -224,7 +225,7 @@ namespace igr
}
else if (header.dim == 3)
{
- image3d<value::int_u12> tmp;
+ image3d<value::int_u16> tmp;
io::dicom::load(tmp, filename.toStdString());
in_ = data::convert(double(), tmp);
@@ -254,9 +255,9 @@ namespace igr
if (header.dim == 2)
{
- if (header.value_type == "int_u12")
+ if (header.value_type == "int_u16")
{
- image2d<value::int_u12> tmp;
+ image2d<value::int_u16> tmp;
io::dump::load(tmp, filename.toStdString());
if (!tmp.is_valid())
@@ -279,9 +280,9 @@ namespace igr
}
else if (header.dim == 3)
{
- if (header.value_type == "int_u12")
+ if (header.value_type == "int_u16")
{
- image2d<value::int_u12> tmp;
+ image2d<value::int_u16> tmp;
io::dicom::load(tmp, filename.toStdString());
in_ = make::image3d(data::convert(double(), tmp));
--
1.5.6.5
1
0

last-svn-commit-705-gdab5d67 mln/io/dicom/load.hh: Fix invalid image loading.
by Guillaume Lazzara 11 Apr '11
by Guillaume Lazzara 11 Apr '11
11 Apr '11
---
milena/ChangeLog | 4 ++++
milena/mln/io/dicom/load.hh | 15 +++++++++++++--
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 7268baf..994efe7 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,7 @@
+2011-01-27 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ * mln/io/dicom/load.hh: Fix invalid image loading.
+
2011-01-13 Guillaume Lazzara <z(a)lrde.epita.fr>
Add more from_to overloads.
diff --git a/milena/mln/io/dicom/load.hh b/milena/mln/io/dicom/load.hh
index f250a16..1823b18 100644
--- a/milena/mln/io/dicom/load.hh
+++ b/milena/mln/io/dicom/load.hh
@@ -40,7 +40,6 @@
# include <gdcm-2.0/gdcmDataSet.h>
# include <gdcm-2.0/gdcmAttribute.h>
-
namespace mln
{
@@ -107,6 +106,9 @@ namespace mln
abort();
}
+ // FIXME: Check image.GetPixelFormat() with mln_value(I)
+ // quantification.
+
//gdcm::File &file = r.GetFile();
//gdcm::DataSet& ds = file.GetDataSet();
@@ -132,7 +134,9 @@ namespace mln
if (mln_site_(I)::dim != ndims)
{
- std::cerr << "error: dimension mismatch" << std::endl;
+ std::cerr << "error: dimension mismatch. Found "
+ << ndims << " but expected " << mln_site_(I)::dim
+ << std::endl;
abort();
}
@@ -155,6 +159,13 @@ namespace mln
initialize(ima, result);
mln_piter(I) p(ima.domain());
unsigned int index = 0;
+
+ // FIXME: HACK. We may prefer to change the way we access the
+ // data instead of swapping that information. If swap is not
+ // performed, the loaded image is rotated and symmetrized.
+ std::swap(vdims[0], vdims[1]);
+
+ // int k = 0;
for_all(p)
{
index = 0;
--
1.5.6.5
1
0
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch igr has been created
at dab5d674ff5a32dbbba0dbe53543864f89d405cc (commit)
- Log -----------------------------------------------------------------
dab5d67 mln/io/dicom/load.hh: Fix invalid image loading.
881edd2 Use int_u16 instead of int_u12.
04cf923 Add more from_to overloads.
1b4ffab Fix Paths in scripts and build systems.
722f33d Update build system to use MLN_WO_GLOBAL_VARS.
8df88e3 Move IGR code from milena/sandbox to igr's private module.
319827a lazzara/igr/gui/segmentation/src/task_widget.cc: Avoid a warning.
90ac1e4 Update code with nslices() instead of nslis().
a0aa478 Store loaded image with double value type.
27c8f05 Add save button for function plots.
9dd5ec1 Add function visualization in the mean region widget.
aa8417d Allow to save results filtered differently in the 3D segmentation tool.
181a278 lazzara/igr/gui/segmentation/src/main_window.cc: Avoid a warning in 2D segmentation tool.
a54cebf Add missing defines in headers.
687f97b Split compilation of files including Milena's headers.
62569b3 Add an image loader in the anapath GUI.
1d4349d Fix compilation
522f81f Add a tool to superpose segmentation images.
b6b6df1 Update GUI according last IGR's needs.
cdda6fe Add specific routines in mln.
adea41d Add a tool for anapath filtering.
ed2fd90 Remove deprecated IGR's segmentation tool.
b394deb Improve IGR's segmentation tools.
1e5f309 Improve 2D+t segmentation tool.
6374b5e Improve the display of the normalized image.
9b9e09a Thread image loading.
db74d4f Cleanup I/O and documentation in IGR's code.
f1c1798 Add new GUIs for IGR.
-----------------------------------------------------------------------
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0

05 Apr '11
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch unstable/scribo has been updated
via f5a185dfd59d5ed9f804d92262899f0cada75631 (commit)
via f553aa713bf237a24615fa71bd1e21e67fe37de4 (commit)
via 78843e4f50230c6019cd151c18e27e8090a2c177 (commit)
via ddcab202ab8ccfac3b4ead5b19e69a0d0ecd58b5 (commit)
via af0fa024f48e7449fa1355c7e752d297b9fb2781 (commit)
via b8e866eb546766ab5028bc4c1f018db95dccd855 (commit)
via 0012ddf9c6f6b0e233b280f73cc79efc1feee114 (commit)
via 9cfcb85e161a9bc030cd64ce24c4fa53012b04f8 (commit)
via 59dd55445ad87980e12ad98e57f5c3ad4093637b (commit)
from 57a4952e7ad3d3abda896726c512f4e95bc504cd (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
f5a185d Regen generated files.
f553aa7 configure.ac: Configure scribo/tests/estim.
78843e4 Compute font and boldness data.
ddcab20 mln/accu/stat/median_h.hh: Add missing operator=().
af0fa02 configure.ac: configure scribo/tests/primitive/extract.
b8e866e Add a new alignments extraction routine.
0012ddf Update dmax functors interface.
9cfcb85 Various fixes in Scribo.
59dd554 scribo/text/extract_lines_wo_merge.hh: New line extraction routine.
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 12 +-
configure.ac | 2 +
milena/ChangeLog | 4 +
milena/mln/accu/stat/median_h.hh | 19 +-
scribo/ChangeLog | 144 +++
scribo/headers.mk | 13 +
scribo/scribo/core/component_features_data.hh | 68 ++
scribo/scribo/core/component_info.hh | 40 +-
scribo/scribo/core/component_set.hh | 21 +-
scribo/scribo/core/def/color_type.hh | 48 +
scribo/scribo/core/line_info.hh | 174 +++-
scribo/scribo/core/line_set.hh | 17 +
scribo/scribo/core/object_groups.hh | 14 +-
scribo/scribo/core/object_links.hh | 11 +
scribo/scribo/core/paragraph_info.hh | 102 ++-
scribo/scribo/core/paragraph_set.hh | 11 +
scribo/scribo/debug/links_image.hh | 9 +-
scribo/scribo/debug/text_color_image.hh | 100 ++
scribo/scribo/estim/components_features.hh | 169 +++
scribo/scribo/estim/font_boldness.hh | 215 ++++
scribo/scribo/estim/font_color.hh | 206 ++++
scribo/scribo/estim/internal/compute_skeleton.hh | 112 ++
scribo/scribo/filter/object_groups_small.hh | 30 +-
scribo/scribo/filter/objects_h_thick.hh | 42 +-
scribo/scribo/filter/objects_h_thin.hh | 6 +-
scribo/scribo/filter/objects_v_thick.hh | 42 +-
scribo/scribo/filter/objects_v_thin.hh | 6 +-
.../io/xml/internal/extended_page_xml_visitor.hh | 9 +-
scribo/scribo/io/xml/internal/full_xml_visitor.hh | 33 +-
scribo/scribo/preprocessing/rotate_90.hh | 2 +
scribo/scribo/primitive/extract/alignments.hh | 1106 ++++++++++++++++++++
scribo/scribo/primitive/extract/components.hh | 70 +-
scribo/scribo/primitive/extract/non_text.hh | 2 -
.../scribo/primitive/link/internal/dmax_default.hh | 16 +-
.../primitive/link/internal/dmax_functor_base.hh | 13 +-
.../scribo/primitive/link/internal/dmax_hrules.hh | 100 ++
.../link/internal/dmax_width_and_height.hh | 11 +-
.../primitive/link/internal/dmax_width_only.hh | 7 +-
.../primitive/link/internal/link_functor_base.hh | 7 +-
.../link_single_dmax_ratio_aligned_base.hh | 5 -
.../link_single_dmax_ratio_aligned_delta_base.hh | 159 +++
.../link/internal/link_single_dmax_ratio_base.hh | 3 +-
.../link/merge_double_link_closest_aligned.hh | 157 +++
scribo/scribo/text/extract_lines.hh | 30 +-
scribo/scribo/text/extract_lines_with_features.hh | 131 +++
scribo/scribo/text/extract_lines_wo_merge.hh | 189 ++++
scribo/scribo/toolchain/content_in_doc.hh | 4 +-
.../toolchain/internal/content_in_doc_functor.hh | 3 +-
scribo/src/debug/Makefile.am | 16 +
scribo/src/debug/show_components_boldness.cc | 72 ++
scribo/src/debug/show_components_color.cc | 73 ++
scribo/src/debug/show_groups_bboxes.cc | 16 +-
scribo/src/debug/show_lines_boldness.cc | 199 ++++
scribo/src/preprocessing/denoise_fg.cc | 6 +-
scribo/src/primitive/extract/Makefile.am | 11 +
scribo/src/primitive/extract/alignments.cc | 89 ++
scribo/tests/Makefile.am | 5 +-
scribo/tests/data.hh.in | 6 +-
scribo/tests/estim/Makefile.am | 29 +
scribo/tests/estim/font_boldness.cc | 46 +
scribo/tests/estim/font_color.cc | 48 +
scribo/tests/img/alignment_1.png | Bin 0 -> 3145 bytes
scribo/tests/img/alignment_2.png | Bin 0 -> 3147 bytes
scribo/tests/img/alignment_3.png | Bin 0 -> 3145 bytes
scribo/tests/img/alignment_4.png | Bin 0 -> 3155 bytes
scribo/tests/img/phillip.pbm | Bin 0 -> 1633 bytes
scribo/tests/img/phillip.ppm | 5 +
scribo/tests/primitive/Makefile.am | 4 +-
scribo/tests/primitive/extract/Makefile.am | 33 +
scribo/tests/primitive/extract/alignment_1.ref.pbm | 5 +
scribo/tests/primitive/extract/alignment_2.ref.pbm | 5 +
scribo/tests/primitive/extract/alignment_3.ref.pbm | 5 +
scribo/tests/primitive/extract/alignment_4.ref.pbm | 5 +
scribo/tests/primitive/extract/alignments.cc | 76 ++
scribo/tests/toolchain/nepomuk/Makefile.am | 2 +
scribo/tests/unit_test/unit-tests.mk | 24 +
76 files changed, 4314 insertions(+), 160 deletions(-)
create mode 100644 scribo/scribo/core/component_features_data.hh
create mode 100644 scribo/scribo/core/def/color_type.hh
create mode 100644 scribo/scribo/debug/text_color_image.hh
create mode 100644 scribo/scribo/estim/components_features.hh
create mode 100644 scribo/scribo/estim/font_boldness.hh
create mode 100644 scribo/scribo/estim/font_color.hh
create mode 100644 scribo/scribo/estim/internal/compute_skeleton.hh
create mode 100644 scribo/scribo/primitive/extract/alignments.hh
create mode 100644 scribo/scribo/primitive/link/internal/dmax_hrules.hh
create mode 100644 scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh
create mode 100644 scribo/scribo/primitive/link/merge_double_link_closest_aligned.hh
create mode 100644 scribo/scribo/text/extract_lines_with_features.hh
create mode 100644 scribo/scribo/text/extract_lines_wo_merge.hh
create mode 100644 scribo/src/debug/show_components_boldness.cc
create mode 100644 scribo/src/debug/show_components_color.cc
create mode 100644 scribo/src/debug/show_lines_boldness.cc
create mode 100644 scribo/src/primitive/extract/alignments.cc
create mode 100644 scribo/tests/estim/Makefile.am
create mode 100644 scribo/tests/estim/font_boldness.cc
create mode 100644 scribo/tests/estim/font_color.cc
create mode 100644 scribo/tests/img/alignment_1.png
create mode 100644 scribo/tests/img/alignment_2.png
create mode 100644 scribo/tests/img/alignment_3.png
create mode 100644 scribo/tests/img/alignment_4.png
create mode 100644 scribo/tests/img/phillip.pbm
create mode 100644 scribo/tests/img/phillip.ppm
create mode 100644 scribo/tests/primitive/extract/Makefile.am
create mode 100644 scribo/tests/primitive/extract/alignment_1.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignment_2.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignment_3.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignment_4.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignments.cc
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0
* headers.mk,
* tests/unit_test/unit-tests.mk: Regen.
---
scribo/ChangeLog | 7 +++++++
scribo/headers.mk | 13 +++++++++++++
scribo/tests/unit_test/unit-tests.mk | 24 ++++++++++++++++++++++++
3 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 2fc8d6d..fa834fa 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,12 @@
2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Regen generated files.
+
+ * headers.mk,
+ * tests/unit_test/unit-tests.mk: Regen.
+
+2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Compute font and boldness data.
* scribo/core/component_features_data.hh,
diff --git a/scribo/headers.mk b/scribo/headers.mk
index ebe14ee..47b4bdd 100644
--- a/scribo/headers.mk
+++ b/scribo/headers.mk
@@ -19,12 +19,14 @@ scribo/convert/from_qimage.hh \
scribo/convert/to_base64.hh \
scribo/core/all.hh \
scribo/core/central_sites.hh \
+scribo/core/component_features_data.hh \
scribo/core/component_info.hh \
scribo/core/component_set.hh \
scribo/core/concept/dmax_functor.hh \
scribo/core/concept/link_functor.hh \
scribo/core/concept/serializable.hh \
scribo/core/concept/serialize_visitor.hh \
+scribo/core/def/color_type.hh \
scribo/core/def/lbl_type.hh \
scribo/core/document.hh \
scribo/core/erase_objects.hh \
@@ -59,11 +61,16 @@ scribo/debug/save_comp_diff.hh \
scribo/debug/save_label_image.hh \
scribo/debug/save_table_image.hh \
scribo/debug/text_areas_image.hh \
+scribo/debug/text_color_image.hh \
scribo/debug/usage.hh \
scribo/draw/all.hh \
scribo/draw/bounding_box_links.hh \
scribo/draw/bounding_boxes.hh \
scribo/draw/groups_bboxes.hh \
+scribo/estim/components_features.hh \
+scribo/estim/font_boldness.hh \
+scribo/estim/font_color.hh \
+scribo/estim/internal/compute_skeleton.hh \
scribo/estim/object_groups_v_thickness.hh \
scribo/filter/all.hh \
scribo/filter/common/objects_photo.hh \
@@ -134,6 +141,7 @@ scribo/preprocessing/homogeneous_contrast.hh \
scribo/preprocessing/rotate_90.hh \
scribo/preprocessing/split_bg_fg.hh \
scribo/primitive/all.hh \
+scribo/primitive/extract/alignments.hh \
scribo/primitive/extract/all.hh \
scribo/primitive/extract/canvas.hh \
scribo/primitive/extract/cells.hh \
@@ -178,6 +186,7 @@ scribo/primitive/link/compute_several.hh \
scribo/primitive/link/internal/compute_anchor.hh \
scribo/primitive/link/internal/dmax_default.hh \
scribo/primitive/link/internal/dmax_functor_base.hh \
+scribo/primitive/link/internal/dmax_hrules.hh \
scribo/primitive/link/internal/dmax_width_and_height.hh \
scribo/primitive/link/internal/dmax_width_only.hh \
scribo/primitive/link/internal/find_link.hh \
@@ -186,8 +195,10 @@ scribo/primitive/link/internal/link_functor_base.hh \
scribo/primitive/link/internal/link_several_dmax_base.hh \
scribo/primitive/link/internal/link_single_dmax_base.hh \
scribo/primitive/link/internal/link_single_dmax_ratio_aligned_base.hh \
+scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh \
scribo/primitive/link/internal/link_single_dmax_ratio_base.hh \
scribo/primitive/link/merge_double_link.hh \
+scribo/primitive/link/merge_double_link_closest_aligned.hh \
scribo/primitive/link/with_graph.hh \
scribo/primitive/link/with_rag.hh \
scribo/primitive/link/with_several_graphes.hh \
@@ -230,6 +241,8 @@ scribo/text/all.hh \
scribo/text/clean.hh \
scribo/text/clean_inplace.hh \
scribo/text/extract_lines.hh \
+scribo/text/extract_lines_with_features.hh \
+scribo/text/extract_lines_wo_merge.hh \
scribo/text/link_lines.hh \
scribo/text/look_like_text_lines.hh \
scribo/text/merging.hh \
diff --git a/scribo/tests/unit_test/unit-tests.mk b/scribo/tests/unit_test/unit-tests.mk
index 3785fab..c654084 100644
--- a/scribo/tests/unit_test/unit-tests.mk
+++ b/scribo/tests/unit_test/unit-tests.mk
@@ -106,12 +106,14 @@ scribo_canvas_integral_browsing \
scribo_convert_to_base64 \
scribo_core_all \
scribo_core_central_sites \
+scribo_core_component_features_data \
scribo_core_component_info \
scribo_core_component_set \
scribo_core_concept_dmax_functor \
scribo_core_concept_link_functor \
scribo_core_concept_serializable \
scribo_core_concept_serialize_visitor \
+scribo_core_def_color_type \
scribo_core_def_lbl_type \
scribo_core_document \
scribo_core_erase_objects \
@@ -146,12 +148,16 @@ scribo_debug_save_comp_diff \
scribo_debug_save_label_image \
scribo_debug_save_table_image \
scribo_debug_text_areas_image \
+scribo_debug_text_color_image \
scribo_debug_usage \
scribo_draw_all \
scribo_draw_bounding_box_links \
scribo_draw_bounding_boxes \
scribo_draw_groups_bboxes \
+scribo_estim_components_features \
+scribo_estim_font_boldness \
scribo_estim_font_color \
+scribo_estim_internal_compute_skeleton \
scribo_estim_object_groups_v_thickness \
scribo_filter_all \
scribo_filter_common_objects_photo \
@@ -220,6 +226,7 @@ scribo_preprocessing_homogeneous_contrast \
scribo_preprocessing_rotate_90 \
scribo_preprocessing_split_bg_fg \
scribo_primitive_all \
+scribo_primitive_extract_alignments \
scribo_primitive_extract_all \
scribo_primitive_extract_canvas \
scribo_primitive_extract_cells \
@@ -263,6 +270,7 @@ scribo_primitive_link_compute \
scribo_primitive_link_internal_compute_anchor \
scribo_primitive_link_internal_dmax_default \
scribo_primitive_link_internal_dmax_functor_base \
+scribo_primitive_link_internal_dmax_hrules \
scribo_primitive_link_internal_dmax_width_and_height \
scribo_primitive_link_internal_dmax_width_only \
scribo_primitive_link_internal_find_link \
@@ -270,8 +278,10 @@ scribo_primitive_link_internal_link_functor_base \
scribo_primitive_link_internal_link_several_dmax_base \
scribo_primitive_link_internal_link_single_dmax_base \
scribo_primitive_link_internal_link_single_dmax_ratio_aligned_base \
+scribo_primitive_link_internal_link_single_dmax_ratio_aligned_delta_base \
scribo_primitive_link_internal_link_single_dmax_ratio_base \
scribo_primitive_link_merge_double_link \
+scribo_primitive_link_merge_double_link_closest_aligned \
scribo_primitive_link_with_graph \
scribo_primitive_link_with_rag \
scribo_primitive_link_with_several_graphes \
@@ -312,6 +322,8 @@ scribo_text_all \
scribo_text_clean \
scribo_text_clean_inplace \
scribo_text_extract_lines \
+scribo_text_extract_lines_with_features \
+scribo_text_extract_lines_wo_merge \
scribo_text_link_lines \
scribo_text_look_like_text_lines \
scribo_text_merging \
@@ -338,12 +350,14 @@ scribo_canvas_integral_browsing_SOURCES = scribo_canvas_integral_browsing.cc
scribo_convert_to_base64_SOURCES = scribo_convert_to_base64.cc
scribo_core_all_SOURCES = scribo_core_all.cc
scribo_core_central_sites_SOURCES = scribo_core_central_sites.cc
+scribo_core_component_features_data_SOURCES = scribo_core_component_features_data.cc
scribo_core_component_info_SOURCES = scribo_core_component_info.cc
scribo_core_component_set_SOURCES = scribo_core_component_set.cc
scribo_core_concept_dmax_functor_SOURCES = scribo_core_concept_dmax_functor.cc
scribo_core_concept_link_functor_SOURCES = scribo_core_concept_link_functor.cc
scribo_core_concept_serializable_SOURCES = scribo_core_concept_serializable.cc
scribo_core_concept_serialize_visitor_SOURCES = scribo_core_concept_serialize_visitor.cc
+scribo_core_def_color_type_SOURCES = scribo_core_def_color_type.cc
scribo_core_def_lbl_type_SOURCES = scribo_core_def_lbl_type.cc
scribo_core_document_SOURCES = scribo_core_document.cc
scribo_core_erase_objects_SOURCES = scribo_core_erase_objects.cc
@@ -378,12 +392,16 @@ scribo_debug_save_comp_diff_SOURCES = scribo_debug_save_comp_diff.cc
scribo_debug_save_label_image_SOURCES = scribo_debug_save_label_image.cc
scribo_debug_save_table_image_SOURCES = scribo_debug_save_table_image.cc
scribo_debug_text_areas_image_SOURCES = scribo_debug_text_areas_image.cc
+scribo_debug_text_color_image_SOURCES = scribo_debug_text_color_image.cc
scribo_debug_usage_SOURCES = scribo_debug_usage.cc
scribo_draw_all_SOURCES = scribo_draw_all.cc
scribo_draw_bounding_box_links_SOURCES = scribo_draw_bounding_box_links.cc
scribo_draw_bounding_boxes_SOURCES = scribo_draw_bounding_boxes.cc
scribo_draw_groups_bboxes_SOURCES = scribo_draw_groups_bboxes.cc
+scribo_estim_components_features_SOURCES = scribo_estim_components_features.cc
+scribo_estim_font_boldness_SOURCES = scribo_estim_font_boldness.cc
scribo_estim_font_color_SOURCES = scribo_estim_font_color.cc
+scribo_estim_internal_compute_skeleton_SOURCES = scribo_estim_internal_compute_skeleton.cc
scribo_estim_object_groups_v_thickness_SOURCES = scribo_estim_object_groups_v_thickness.cc
scribo_filter_all_SOURCES = scribo_filter_all.cc
scribo_filter_common_objects_photo_SOURCES = scribo_filter_common_objects_photo.cc
@@ -452,6 +470,7 @@ scribo_preprocessing_homogeneous_contrast_SOURCES = scribo_preprocessing_homogen
scribo_preprocessing_rotate_90_SOURCES = scribo_preprocessing_rotate_90.cc
scribo_preprocessing_split_bg_fg_SOURCES = scribo_preprocessing_split_bg_fg.cc
scribo_primitive_all_SOURCES = scribo_primitive_all.cc
+scribo_primitive_extract_alignments_SOURCES = scribo_primitive_extract_alignments.cc
scribo_primitive_extract_all_SOURCES = scribo_primitive_extract_all.cc
scribo_primitive_extract_canvas_SOURCES = scribo_primitive_extract_canvas.cc
scribo_primitive_extract_cells_SOURCES = scribo_primitive_extract_cells.cc
@@ -495,6 +514,7 @@ scribo_primitive_link_compute_SOURCES = scribo_primitive_link_compute.cc
scribo_primitive_link_internal_compute_anchor_SOURCES = scribo_primitive_link_internal_compute_anchor.cc
scribo_primitive_link_internal_dmax_default_SOURCES = scribo_primitive_link_internal_dmax_default.cc
scribo_primitive_link_internal_dmax_functor_base_SOURCES = scribo_primitive_link_internal_dmax_functor_base.cc
+scribo_primitive_link_internal_dmax_hrules_SOURCES = scribo_primitive_link_internal_dmax_hrules.cc
scribo_primitive_link_internal_dmax_width_and_height_SOURCES = scribo_primitive_link_internal_dmax_width_and_height.cc
scribo_primitive_link_internal_dmax_width_only_SOURCES = scribo_primitive_link_internal_dmax_width_only.cc
scribo_primitive_link_internal_find_link_SOURCES = scribo_primitive_link_internal_find_link.cc
@@ -502,8 +522,10 @@ scribo_primitive_link_internal_link_functor_base_SOURCES = scribo_primitive_link
scribo_primitive_link_internal_link_several_dmax_base_SOURCES = scribo_primitive_link_internal_link_several_dmax_base.cc
scribo_primitive_link_internal_link_single_dmax_base_SOURCES = scribo_primitive_link_internal_link_single_dmax_base.cc
scribo_primitive_link_internal_link_single_dmax_ratio_aligned_base_SOURCES = scribo_primitive_link_internal_link_single_dmax_ratio_aligned_base.cc
+scribo_primitive_link_internal_link_single_dmax_ratio_aligned_delta_base_SOURCES = scribo_primitive_link_internal_link_single_dmax_ratio_aligned_delta_base.cc
scribo_primitive_link_internal_link_single_dmax_ratio_base_SOURCES = scribo_primitive_link_internal_link_single_dmax_ratio_base.cc
scribo_primitive_link_merge_double_link_SOURCES = scribo_primitive_link_merge_double_link.cc
+scribo_primitive_link_merge_double_link_closest_aligned_SOURCES = scribo_primitive_link_merge_double_link_closest_aligned.cc
scribo_primitive_link_with_graph_SOURCES = scribo_primitive_link_with_graph.cc
scribo_primitive_link_with_rag_SOURCES = scribo_primitive_link_with_rag.cc
scribo_primitive_link_with_several_graphes_SOURCES = scribo_primitive_link_with_several_graphes.cc
@@ -544,6 +566,8 @@ scribo_text_all_SOURCES = scribo_text_all.cc
scribo_text_clean_SOURCES = scribo_text_clean.cc
scribo_text_clean_inplace_SOURCES = scribo_text_clean_inplace.cc
scribo_text_extract_lines_SOURCES = scribo_text_extract_lines.cc
+scribo_text_extract_lines_with_features_SOURCES = scribo_text_extract_lines_with_features.cc
+scribo_text_extract_lines_wo_merge_SOURCES = scribo_text_extract_lines_wo_merge.cc
scribo_text_link_lines_SOURCES = scribo_text_link_lines.cc
scribo_text_look_like_text_lines_SOURCES = scribo_text_look_like_text_lines.cc
scribo_text_merging_SOURCES = scribo_text_merging.cc
--
1.5.6.5
1
0

last-svn-commit-832-gb8e866e Add a new alignments extraction routine.
by Guillaume Lazzara 05 Apr '11
by Guillaume Lazzara 05 Apr '11
05 Apr '11
* scribo/primitive/extract/alignments.hh,
* scribo/primitive/link/internal/dmax_hrules.hh,
* scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh,
* scribo/primitive/link/merge_double_link_closest_aligned.hh: New.
* src/primitive/extract/alignments.cc: New example.
* tests/data.hh.in: Add a new macro.
* tests/img/alignment_1.png,
* tests/img/alignment_2.png,
* tests/img/alignment_3.png,
* tests/img/alignment_4.png,
* tests/primitive/extract/alignment_1.ref.pbm,
* tests/primitive/extract/alignment_2.ref.pbm,
* tests/primitive/extract/alignment_3.ref.pbm,
* tests/primitive/extract/alignment_4.ref.pbm: New auxiliary data
for tests.
* src/primitive/extract/Makefile.am,
* tests/primitive/Makefile.am,
* tests/primitive/extract/Makefile.am: Add new targets.
* tests/primitive/extract/alignments.cc: New test.
---
scribo/ChangeLog | 29 +
scribo/scribo/primitive/extract/alignments.hh | 1106 ++++++++++++++++++++
.../scribo/primitive/link/internal/dmax_hrules.hh | 100 ++
.../link_single_dmax_ratio_aligned_delta_base.hh | 159 +++
.../link/merge_double_link_closest_aligned.hh | 157 +++
scribo/src/primitive/extract/Makefile.am | 11 +
scribo/src/primitive/extract/alignments.cc | 89 ++
scribo/tests/data.hh.in | 6 +-
scribo/tests/img/alignment_1.png | Bin 0 -> 3145 bytes
scribo/tests/img/alignment_2.png | Bin 0 -> 3147 bytes
scribo/tests/img/alignment_3.png | Bin 0 -> 3145 bytes
scribo/tests/img/alignment_4.png | Bin 0 -> 3155 bytes
scribo/tests/primitive/Makefile.am | 4 +-
scribo/tests/primitive/extract/Makefile.am | 33 +
scribo/tests/primitive/extract/alignment_1.ref.pbm | 5 +
scribo/tests/primitive/extract/alignment_2.ref.pbm | 5 +
scribo/tests/primitive/extract/alignment_3.ref.pbm | 5 +
scribo/tests/primitive/extract/alignment_4.ref.pbm | 5 +
scribo/tests/primitive/extract/alignments.cc | 76 ++
19 files changed, 1788 insertions(+), 2 deletions(-)
create mode 100644 scribo/scribo/primitive/extract/alignments.hh
create mode 100644 scribo/scribo/primitive/link/internal/dmax_hrules.hh
create mode 100644 scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh
create mode 100644 scribo/scribo/primitive/link/merge_double_link_closest_aligned.hh
create mode 100644 scribo/src/primitive/extract/alignments.cc
create mode 100644 scribo/tests/img/alignment_1.png
create mode 100644 scribo/tests/img/alignment_2.png
create mode 100644 scribo/tests/img/alignment_3.png
create mode 100644 scribo/tests/img/alignment_4.png
create mode 100644 scribo/tests/primitive/extract/Makefile.am
create mode 100644 scribo/tests/primitive/extract/alignment_1.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignment_2.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignment_3.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignment_4.ref.pbm
create mode 100644 scribo/tests/primitive/extract/alignments.cc
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 8acfc4e..4592e73 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,34 @@
2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add a new alignments extraction routine.
+
+ * scribo/primitive/extract/alignments.hh,
+ * scribo/primitive/link/internal/dmax_hrules.hh,
+ * scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh,
+ * scribo/primitive/link/merge_double_link_closest_aligned.hh: New.
+
+ * src/primitive/extract/alignments.cc: New example.
+
+ * tests/data.hh.in: Add a new macro.
+
+ * tests/img/alignment_1.png,
+ * tests/img/alignment_2.png,
+ * tests/img/alignment_3.png,
+ * tests/img/alignment_4.png,
+ * tests/primitive/extract/alignment_1.ref.pbm,
+ * tests/primitive/extract/alignment_2.ref.pbm,
+ * tests/primitive/extract/alignment_3.ref.pbm,
+ * tests/primitive/extract/alignment_4.ref.pbm: New auxiliary data
+ for tests.
+
+ * src/primitive/extract/Makefile.am,
+ * tests/primitive/Makefile.am,
+ * tests/primitive/extract/Makefile.am: Add new targets.
+
+ * tests/primitive/extract/alignments.cc: New test.
+
+2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Update dmax functors interface.
* scribo/primitive/link/internal/dmax_default.hh,
diff --git a/scribo/scribo/primitive/extract/alignments.hh b/scribo/scribo/primitive/extract/alignments.hh
new file mode 100644
index 0000000..5314683
--- /dev/null
+++ b/scribo/scribo/primitive/extract/alignments.hh
@@ -0,0 +1,1106 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_EXTRACT_ALIGNMENTS_HH
+# define SCRIBO_PRIMITIVE_EXTRACT_ALIGNMENTS_HH
+
+#include <iostream>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/data/convert.hh>
+
+#include <mln/value/rgb8.hh>
+#include <mln/value/label_16.hh>
+#include <mln/value/int_u.hh>
+#include <mln/literal/colors.hh>
+
+#include <mln/util/array.hh>
+#include <mln/util/couple.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/ppm/save.hh>
+
+#include <mln/labeling/colorize.hh>
+
+#include <mln/util/couple.hh>
+
+#include <scribo/core/def/lbl_type.hh>
+#include <scribo/primitive/extract/components.hh>
+#include <scribo/filter/object_links_aligned.hh>
+#include <scribo/filter/object_groups_small.hh>
+#include <scribo/preprocessing/denoise_fg.hh>
+// #include <scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh>
+// #include <scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh>
+#include <scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh>
+#include <scribo/primitive/link/internal/dmax_default.hh>
+#include <scribo/primitive/link/internal/dmax_hrules.hh>
+#include <scribo/primitive/link/merge_double_link_closest_aligned.hh>
+
+#include <scribo/debug/usage.hh>
+#include <scribo/debug/links_image.hh>
+
+
+#include <scribo/core/document.hh>
+#include <scribo/core/component_set.hh>
+#include <scribo/core/line_set.hh>
+#include <scribo/primitive/extract/components.hh>
+#include <scribo/primitive/group/from_single_link.hh>
+#include <scribo/primitive/group/apply.hh>
+#include <scribo/primitive/link/with_single_left_link_dmax_ratio.hh>
+#include <scribo/primitive/link/with_single_right_link_dmax_ratio.hh>
+#include <scribo/primitive/link/merge_double_link.hh>
+#include <scribo/primitive/link/internal/dmax_width_and_height.hh>
+
+#include <scribo/preprocessing/rotate_90.hh>
+#include <scribo/filter/object_links_bbox_h_ratio.hh>
+
+# include <scribo/primitive/extract/separators.hh>
+# include <scribo/primitive/extract/vertical_separators.hh>
+# include <scribo/primitive/extract/horizontal_separators.hh>
+# include <scribo/primitive/extract/separators_nonvisible.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace extract
+ {
+
+ /*! \brief Find page delimitors from tabstops and whitespaces.
+
+ \pre Separators should be removed from input document image .
+
+ \pre Text in \p doc must be constructed from Components
+ grouped by lines with a very strict criterion in order to keep
+ spaces between words and paragraphs. This first grouping is
+ necessary to avoid false positive (e.g. inside the text
+ blocks).
+
+ \pre \p doc must have text (has_text() returns true).
+
+
+ Internal description :
+ ----------------------
+
+ 1) Build an image of line bboxes
+ 2) For TOP and BOTTOM
+ 2.a) Link bboxes. Links are validated only if :
+ - Alignment difference is less than \p delta_pixel.
+ - Bboxes are not too far
+ - No component is located at 5 pixels along the aligned side.
+ 2.b) Invalidates groups if there are less than 3 links
+ 2.c) Invalidates groups if a component is located at a specific
+ distance from the aligned side.
+
+ This method handles skewed alignments and draw skew lines if
+ possible. Examples :
+
+ |x |x
+ | x \x
+ | x -> \x
+ | x \x
+
+
+ \fixme Because the first link step at step 2.a check aligment
+ between only 2 components and not the whole group, we may
+ retrieve alignment patterns such this one :
+
+ |x
+ | x
+ | x
+ | x
+ |x
+
+ Here, the 'x' are aligned pair by pair but globally they are
+ not. Here we cannot draw skewed lines without processing every
+ links and look for that pattern. More over, in step 2.c
+ alignment is validated by looking for other components in the
+ supposed "whitespace area" from the aligned side. With such an
+ alignment there are more chances that a component intersect
+ with that line. Here, we would like to split links/alignement
+ in two groups in order to get something like that :
+
+ \x
+ \x
+ \x
+ /x
+ /x
+
+
+
+ \param[in] doc A document information with text lines.
+
+ \param[in] dmax_ratio The ratio used to compute the maximum
+ lookup distance while linking up components.
+
+ \param[in] delta_pixel The maximum number of pixels allowed
+ for alignment delta precision.
+
+ */
+ template <typename L>
+ mln::util::couple<component_set<L>, mln_ch_value(L,bool)>
+ alignments(const document<L>& doc,
+ float dmax_ratio, unsigned delta_pixel);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::primitive::extract
+
+ } // end of namespace scribo::primitive
+
+
+
+
+ namespace internal
+ {
+
+ template <typename V>
+ point2d
+ point_row_adjust(const point2d& pi, const image2d<V>& ima)
+ {
+ if (ima.domain().has(pi))
+ return pi;
+
+ point2d po = pi;
+
+ if (po.row() < ima.domain().pmin().row())
+ while (!ima.domain().has(po))
+ ++po.row();
+ else
+ while (!ima.domain().has(po))
+ --po.row();
+
+ return po;
+ }
+
+ template <typename V>
+ point2d
+ point_col_adjust(const point2d& pi, const image2d<V>& ima)
+ {
+ if (ima.domain().has(pi))
+ return pi;
+
+ point2d po = pi;
+
+ if (po.col() < ima.domain().pmin().col())
+ while (!ima.domain().has(po))
+ ++po.col();
+ else
+ while (!ima.domain().has(po))
+ --po.col();
+
+ return po;
+ }
+
+ } // end of namespace scribo::internal
+
+
+
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ namespace internal
+ {
+
+ template <typename L, typename F>
+ class single_right_dmax_ratio_aligned_delta_functor
+ : public link_single_dmax_ratio_aligned_delta_base<L, F, single_right_dmax_ratio_aligned_delta_functor<L,F> >
+ {
+ typedef single_right_dmax_ratio_aligned_delta_functor<L,F> self_t;
+ typedef link_single_dmax_ratio_aligned_delta_base<L, F, self_t> super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ single_right_dmax_ratio_aligned_delta_functor(
+ const component_set<L>& components,
+ const DMax_Functor<F>& dmax_f,
+ unsigned delta,
+ anchor::Direction delta_direction,
+ const L& bbox_ima,
+ unsigned delta_ws_lookup)
+ : super_(components, dmax_f, delta, delta_direction),
+ bbox_ima_(bbox_ima), delta_ws_lookup_(delta_ws_lookup)
+ {
+ debug_ = data::convert(value::rgb8(), data::convert(bool(), bbox_ima));
+ }
+
+ void compute_next_site_(P& p)
+ {
+ ++p.col();
+ }
+
+
+ inline
+ bool
+ valid_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ anchor::Type anchor)
+ {
+ if (!super_::valid_link_(current_object, start_point, p, anchor))
+ return false;
+
+ mln_value(L) nbh = this->labeled_image_(p);
+
+ switch(anchor)
+ {
+ // Top
+ case anchor::StrictTopCenter:
+ {
+ point2d p(std::min(this->components_(current_object).bbox().pmin().row(),
+ this->components_(nbh).bbox().pmin().row()) - delta_ws_lookup_,
+ this->components_(current_object).bbox().pmin().col());
+ p = scribo::internal::point_row_adjust(p, bbox_ima_);
+
+ for (; p.col() <= this->components_(nbh).bbox().pmax().col()
+ && (bbox_ima_(p) == 0);)
+ {
+ debug_(p) = literal::violet;
+ ++p.col();
+ }
+
+ return bbox_ima_(p) == 0;
+ }
+
+ // Bottom
+ case anchor::StrictBottomCenter:
+ {
+ point2d p(std::max(this->components_(current_object).bbox().pmax().row(),
+ this->components_(nbh).bbox().pmax().row()) + delta_ws_lookup_,
+ this->components_(current_object).bbox().pmin().col());
+ p = scribo::internal::point_row_adjust(p, bbox_ima_);
+
+ for (; p.col() <= this->components_(nbh).bbox().pmax().col()
+ && (bbox_ima_(p) == 0);)
+ {
+ debug_(p) = literal::violet;
+ ++p.col();
+ }
+
+ return bbox_ima_(p) == 0;
+ }
+
+ default:
+ trace::warning("anchor not handled!");
+ }
+
+ return false;
+ }
+
+
+ L bbox_ima_;
+ unsigned delta_ws_lookup_;
+
+ image2d<value::rgb8> debug_;
+ };
+
+
+ template <typename L, typename F>
+ class single_left_dmax_ratio_aligned_delta_functor
+ : public link_single_dmax_ratio_aligned_delta_base<L, F, single_left_dmax_ratio_aligned_delta_functor<L,F> >
+ {
+ typedef single_left_dmax_ratio_aligned_delta_functor<L,F> self_t;
+ typedef link_single_dmax_ratio_aligned_delta_base<L, F, self_t> super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ single_left_dmax_ratio_aligned_delta_functor(
+ const component_set<L>& components,
+ const DMax_Functor<F>& dmax_f,
+ unsigned delta,
+ anchor::Direction delta_direction,
+ const L& bbox_ima,
+ unsigned delta_ws_lookup)
+ : super_(components, dmax_f, delta, delta_direction),
+ bbox_ima_(bbox_ima), delta_ws_lookup_(delta_ws_lookup)
+ {
+ debug_ = data::convert(value::rgb8(), data::convert(bool(), bbox_ima));
+ }
+
+ void compute_next_site_(P& p)
+ {
+ --p.col();
+ }
+
+
+ inline
+ bool
+ valid_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ anchor::Type anchor)
+ {
+ if (!super_::valid_link_(current_object, start_point, p, anchor))
+ return false;
+
+ mln_value(L) nbh = this->labeled_image_(p);
+
+ switch (anchor)
+ {
+
+ // Top
+ case anchor::StrictTopCenter:
+ {
+ point2d p(std::min(this->components_(nbh).bbox().pmin().row(),
+ this->components_(current_object).bbox().pmin().row()) - delta_ws_lookup_,
+ this->components_(current_object).bbox().pmax().col());
+ p = scribo::internal::point_row_adjust(p, bbox_ima_);
+
+ for (; p.col() > this->components_(nbh).bbox().pmin().col()
+ && (bbox_ima_(p) == 0);)
+ {
+ debug_(p) = literal::violet;
+ --p.col();
+ }
+
+ return bbox_ima_(p) == 0;
+ }
+
+ // Bottom
+ case anchor::StrictBottomCenter:
+ {
+ point2d p(std::max(this->components_(nbh).bbox().pmax().row(),
+ this->components_(current_object).bbox().pmax().row()) + delta_ws_lookup_,
+ this->components_(current_object).bbox().pmax().col());
+ p = scribo::internal::point_row_adjust(p, bbox_ima_);
+
+ for (; p.col() > this->components_(nbh).bbox().pmin().col()
+ && (bbox_ima_(p) == 0);)
+ {
+ debug_(p) = literal::violet;
+ --p.col();
+ }
+
+ return bbox_ima_(p) == 0;
+ }
+
+ default:
+ trace::warning("anchor not handled!");
+ }
+
+ return false;
+ }
+
+
+ L bbox_ima_;
+ unsigned delta_ws_lookup_;
+
+ image2d<value::rgb8> debug_;
+ };
+
+
+ } // end of namespace scribo::primitive::link::internal
+
+ } // end of namespace scribo::primitive::link
+
+
+ namespace extract
+ {
+
+ namespace internal
+ {
+
+ template <typename L>
+ bool pass_comp_criterion(const line_info<L>& line)
+ {
+ return line.bbox().height() < 301;// (line.pixel_area() < 10000);
+ }
+
+
+
+ bool
+ is_valid_left_right_skewed_delimitor(const box2d& brot,
+ const image2d<bool> input,
+ unsigned local_delta)
+ {
+ if (brot.pmax().col() - brot.pmin().col() > 6)
+ {
+ point2d
+ p1 = brot.pmin(),
+ p2 = brot.pmax();
+
+ // Handle left to right alignment
+ p1.col() -= local_delta;
+ p2.col() -= local_delta;
+ p_line2d l2d(p1, p2);
+ mln_piter_(p_line2d) p(l2d);
+ for_all(p)
+ if (input(p))
+ return false;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ bool
+ is_valid_right_left_skewed_delimitor(const box2d& brot,
+ const image2d<bool> input,
+ unsigned local_delta)
+ {
+ if (brot.pmax().col() - brot.pmin().col() > 6)
+ {
+ point2d
+ p1 = brot.pmin(),
+ p2 = brot.pmax();
+
+ // Handle right to left alignment
+ p1.col() = brot.pmax().col() - local_delta;
+ p2.col() = brot.pmin().col() - local_delta;
+ p_line2d l2d(p1, p2);
+ mln_piter_(p_line2d) p(l2d);
+ for_all(p)
+ if (input(p))
+ return false;
+
+ return true;
+ }
+
+ return false;
+ }
+
+
+ box2d fast_rotate_positive(const box2d& box, const box2d& rbox)
+ {
+ box2d b(point2d(box.pmin().col(),
+ rbox.ncols() - box.pmin().row() - 1),
+ point2d(box.pmax().col(),
+ rbox.ncols() - box.pmax().row() - 1));
+ return b;
+ }
+
+ box2d fast_rotate_negative(const box2d& box, const box2d& rbox)
+ {
+ // std::cout << point2d(rbox.ncols() - box.pmin().col() - 1,
+ // box.pmin().row())
+ // << " - "
+ // << point2d(rbox.ncols() - box.pmax().col() - 1,
+ // box.pmax().row()) << std::endl;
+
+ // std::cout << box << " - " << rbox << std::endl;
+
+ // box2d b(point2d(rbox.ncols() - box.pmin().col() - 1,
+ // box.pmin().row()),
+ // point2d(rbox.ncols() - box.pmax().col() - 1,
+ // box.pmax().row()));
+
+ mln::def::coord max_row = rbox.ncols() - box.pmin().col() - 1;
+ mln::def::coord min_row = rbox.ncols() - box.pmax().col() - 1;
+// if (min_row > max_row)
+ //std::swap(min_row, max_row);
+
+ box2d b(point2d(min_row,
+ box.pmin().row()),
+ point2d(max_row,
+ box.pmax().row()));
+
+ return b;
+ }
+
+ } // end of namespace scribo::primitive::extract
+
+
+ /////////////
+ // FACADES //
+ /////////////
+
+
+ template <typename L>
+ mln::util::couple<component_set<L>, mln_ch_value(L,bool)>
+ alignments(const document<L>& doc,
+ float dmax_ratio, unsigned delta_pixel)
+ {
+ trace::entering("scribo::primitive::extract::alignments");
+ mln_precondition(doc.is_valid());
+ mln_precondition(doc.has_text());
+ const mln_ch_value(L,bool)& input = doc.binary_image();
+
+ unsigned min_card = 3;
+ unsigned delta = 5;
+
+ // 0. Get low level structures in document data.
+ typedef mln_value(L) V;
+ const object_groups<L>& groups = doc.paragraphs().lines().groups();
+ const line_set<L>& lines = doc.lines();
+
+
+ // 1. Construct an image of group bounding boxes.
+ //
+ // This image is used later to group bounding boxes. It is
+ // rotated in order to make grouping faster (linear memory
+ // reading).
+ //
+ box2d rbbox = box2d(input.domain().pmin(),
+ point2d(input.domain().pmax().col(),
+ input.domain().pmax().row()));
+
+ L bbox_ima(rbbox);
+ data::fill(bbox_ima, 0);
+ for_all_lines(l, lines)
+ if (lines(l).is_valid()
+ && internal::pass_comp_criterion(lines(l)))
+ mln::draw::box(bbox_ima,
+ internal::fast_rotate_positive(lines(l).bbox(),
+ rbbox),
+ lines(l).id().value());
+
+
+ // Compute component information
+ //
+ // FIXME: not useful since we have all required information
+ // in the line_set. However a component_set is needed in link
+ // functors...
+ component_set<L>
+ components = component_set<L>(bbox_ima, lines.nelements());
+
+
+ // Dmax functor used for TOP and BOTTOM links.
+ primitive::link::internal::dmax_hrules dmax_func(dmax_ratio, 100);
+
+
+ // Output image
+ image2d<bool> delimitors;
+ initialize(delimitors, input);
+ data::fill(delimitors, false);
+
+# ifndef SCRIBO_NDEBUG
+ image2d<value::rgb8> debug;
+ initialize(debug, components.labeled_image());
+ data::fill(debug, literal::black);
+ scribo::draw::bounding_boxes(debug, components, literal::blue);
+# endif // ! SCRIBO_NDEBUG
+
+
+
+
+ // 2.1. BEGIN OF TOP LINKS PROCESSING
+ {
+ object_links<L> top_links;
+
+ object_groups<L>
+ top_groups,
+ old_top_groups;
+
+ util::array<unsigned> top_group_size;
+
+ typedef mln::accu::stat::median_h<value::int_u<12u> > median_t;
+ mln::util::array<median_t>
+ top_median_char_width,
+ top_median_char_space;
+
+ mln::util::array<unsigned> top_max_char_width;
+
+
+
+ // 2.1.1. Find TOP links.
+ {
+ object_links<L> right, left;
+
+ // link right
+ {
+ primitive::link::internal::single_right_dmax_ratio_aligned_delta_functor<
+ L,primitive::link::internal::dmax_hrules>
+ functor(components, dmax_func, delta_pixel, anchor::Vertical, bbox_ima, delta);
+
+ right = primitive::link::compute(functor, anchor::StrictTopCenter);
+ }
+
+ // Link left
+ {
+ primitive::link::internal::single_left_dmax_ratio_aligned_delta_functor<
+ L,primitive::link::internal::dmax_hrules>
+ functor(components, dmax_func, delta_pixel, anchor::Vertical, bbox_ima, delta);
+
+ left = primitive::link::compute(functor, anchor::StrictTopCenter);
+ }
+
+ // Merge links
+ top_links = primitive::link::merge_double_link_closest_aligned(left, right,
+ anchor::StrictTopCenter);
+
+ // Remove groups with not enough links.
+ old_top_groups = primitive::group::from_single_link(top_links);
+ top_groups = filter::object_groups_small(old_top_groups, min_card,
+ top_group_size);
+
+
+ // Compute char_width and char_space statistics.
+ //
+ // Here, we also compute max_char_width, in case other
+ // statistics are not significant enough for next steps.
+ //
+ // To avoid biased statistics, char_space and char_width are
+ // used from lines with at least 2 components.
+ //
+ top_median_char_space.resize(top_groups.nelements());
+ top_median_char_width.resize(top_groups.nelements());
+ top_max_char_width.resize(top_groups.nelements());
+
+ for_all_groups(g, top_groups)
+ if (top_groups.is_valid(g))
+ {
+ if (lines(g).card() > 1)
+ {
+ top_median_char_space(top_groups(g)).take(lines(g).char_space());
+ top_median_char_width(top_groups(g)).take(lines(g).char_width());
+ }
+ else if (top_max_char_width(top_groups(g)) < lines(g).char_width())
+ top_max_char_width(top_groups(g)) = lines(g).char_width();
+ }
+
+ }
+
+
+ // 2.1.2. Check TOP whitespaces
+ {
+ util::array<accu::shape::bbox<point2d> >
+ group_bbox(top_groups.nelements());
+
+ // Compute group bboxes
+ for_all_links(l, top_links)
+ if (top_links.is_valid(l))
+ {
+ point2d p = components(top_links(l)).bbox().pmax();
+ p.row() = components(top_links(l)).bbox().pmin().row();
+
+ if (top_groups.is_valid(l)
+ && top_group_size(old_top_groups(l)) > 2)
+ {
+ group_bbox(top_groups(l)).take(p);
+ group_bbox(top_groups(l)).take(components(l).bbox().pmin());
+
+# ifndef SCRIBO_NDEBUG
+ // Draw first component bbox.
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(l).component_ids()[0]).bbox(),
+ rbbox),
+ literal::cyan);
+
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(top_links(l)).component_ids()[0]).bbox(),
+ rbbox),
+ literal::cyan);
+# endif // ! SCRIBO_NDEBUG
+ }
+
+# ifndef SCRIBO_NDEBUG
+ else if (top_group_size(old_top_groups(l)) > 1)
+ {
+ mln::draw::line(debug,
+ components(l).bbox().pmin(),
+ p,
+ literal::orange);
+
+ // Draw first component bbox.
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(l).component_ids()[0]).bbox(),
+ rbbox),
+ literal::cyan);
+
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(top_links(l)).component_ids()[0]).bbox(),
+ rbbox),
+ literal::cyan);
+
+ }
+# endif // ! SCRIBO_NDEBUG
+ }
+
+
+ // Looking for whitespaces (if needed)
+ for_all_elements(c, group_bbox)
+ if (group_bbox(c).to_result().is_valid())
+ {
+ unsigned ldelta = delta;
+ // Handle low connection groups.
+ if (top_group_size(c) >= 3 && top_group_size(c) < 5)
+ {
+ // Stats are not reliable, prefer using max char width.
+ if (top_median_char_width(c).card() == 0)
+ ldelta = top_max_char_width(c) * 2;
+ else
+ ldelta = 1.2 * top_median_char_width(c) + top_median_char_space(c);
+
+ point2d p(group_bbox(c).to_result().pmin().row() - ldelta,
+ group_bbox(c).to_result().pmin().col());
+ p = scribo::internal::point_row_adjust(p, bbox_ima);
+
+ // Checking whitespace area
+ for (; p.col() <= group_bbox(c).to_result().pmax().col()
+ && (bbox_ima(p) == 0);)
+ ++p.col();
+
+ if (bbox_ima(p) != 0)
+ {
+# ifndef SCRIBO_NDEBUG
+ mln::draw::line(debug,
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmin().row() - ldelta,
+ group_bbox(c).to_result().pmin().col()), debug),
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmin().row() - ldelta,
+ group_bbox(c).to_result().pmax().col()), debug),
+ literal::red);
+# endif // ! SCRIBO_NDEBUG
+
+ continue;
+ }
+ }
+
+
+ box2d
+ brot = internal::fast_rotate_negative(group_bbox(c).to_result(),
+ rbbox);
+
+ // Checking if the delimitor is skewed.
+ if (internal::is_valid_left_right_skewed_delimitor(brot, input,
+ delta))
+ {
+ mln::draw::line(delimitors,
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmin().row(),
+ brot.pmin().col() - delta), delimitors),
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmax().row(),
+ brot.pmax().col() - delta), delimitors),
+ true);
+ }
+ else if (internal::is_valid_right_left_skewed_delimitor(brot, input,
+ delta))
+ {
+ mln::draw::line(delimitors,
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmin().row(),
+ brot.pmax().col() - delta), delimitors),
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmax().row(),
+ brot.pmin().col() - delta), delimitors),
+ true);
+ }
+ else
+ {
+ mln::draw::line(delimitors,
+ scribo::internal::point_col_adjust(point2d(brot.pmin().row(),
+ brot.pmin().col() - delta), delimitors),
+ scribo::internal::point_col_adjust(point2d(brot.pmax().row(),
+ brot.pmin().col() - delta), delimitors),
+ true);
+ }
+
+# ifndef SCRIBO_NDEBUG
+ mln::draw::line(debug,
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmin().row() - ldelta,
+ group_bbox(c).to_result().pmin().col()), debug),
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmin().row() - ldelta,
+ group_bbox(c).to_result().pmax().col()), debug),
+ literal::green);
+# endif // ! SCRIBO_NDEBUG
+
+ }
+ }
+
+ } // END OF TOP LINKS PROCESSING
+
+
+
+ // 2.2. BEGIN OF BOTTOM LINKS PROCESSING
+ {
+ object_links<L> bot_links;
+
+ object_groups<L>
+ bot_groups,
+ old_bot_groups;
+
+ util::array<unsigned> bot_group_size;
+
+ typedef mln::accu::stat::median_h<value::int_u<12u> > median_t;
+ mln::util::array<median_t>
+ bot_median_char_width,
+ bot_median_char_space;
+
+ mln::util::array<unsigned> bot_max_char_width;
+
+ // 2.2.1. Find BOTTOM links.
+ {
+ object_links<L> right, left;
+
+ // link right
+ {
+ primitive::link::internal::single_right_dmax_ratio_aligned_delta_functor<
+ L,primitive::link::internal::dmax_hrules>
+ functor(components, dmax_func, delta_pixel, anchor::Vertical,
+ bbox_ima, delta);
+
+ right = primitive::link::compute(functor, anchor::StrictBottomCenter);
+ }
+
+ // Link left
+ {
+ primitive::link::internal::single_left_dmax_ratio_aligned_delta_functor<
+ L,primitive::link::internal::dmax_hrules>
+ functor(components, dmax_func, delta_pixel, anchor::Vertical,
+ bbox_ima, delta);
+
+ left = primitive::link::compute(functor, anchor::StrictBottomCenter);
+ }
+
+ // Merge links
+ bot_links = primitive::link::merge_double_link_closest_aligned(left, right,
+ anchor::StrictBottomCenter);
+
+ // Remove groups with not enough links.
+ old_bot_groups = primitive::group::from_single_link(bot_links);
+ bot_groups = filter::object_groups_small(old_bot_groups, min_card,
+ bot_group_size);
+
+ bot_median_char_space.resize(bot_groups.nelements());
+ bot_median_char_width.resize(bot_groups.nelements());
+ bot_max_char_width.resize(bot_groups.nelements());
+
+ for_all_groups(g, bot_groups)
+ if (bot_groups.is_valid(g))
+ {
+ if (lines(g).card() > 1)
+ {
+ bot_median_char_space(bot_groups(g)).take(lines(g).char_space());
+ bot_median_char_width(bot_groups(g)).take(lines(g).char_width());
+ }
+ // This data will be used if alignments are made with single
+ // components only.
+ else if (bot_max_char_width(bot_groups(g)) < lines(g).char_width())
+ bot_max_char_width(bot_groups(g)) = lines(g).char_width();
+ }
+ }
+
+
+ // 2.2.2. Check BOTTOM whitespaces
+ {
+ util::array<accu::shape::bbox<point2d> >
+ group_bbox(bot_groups.nelements());
+
+ // Compute group bboxes
+ for_all_links(l, bot_links)
+ if (bot_links.is_valid(l))
+ {
+ point2d p = components(l).bbox().pmin();
+ p.row() = components(l).bbox().pmax().row();
+
+ if (bot_groups.is_valid(l)
+ && bot_group_size(old_bot_groups(l)) > 2)
+ {
+ group_bbox(bot_groups(l)).take(p);
+ group_bbox(bot_groups(l)).take(
+ components(bot_links(l)).bbox().pmax());
+
+# ifndef SCRIBO_NDEBUG
+ // Draw first component box
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(l).component_ids()[lines(l).card() - 1]).bbox(),
+ rbbox),
+ literal::cyan);
+
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(bot_links(l)).component_ids()[lines(bot_links(l)).card() - 1]).bbox(),
+ rbbox),
+ literal::cyan);
+# endif // ! SCRIBO_NDEBUG
+ }
+
+# ifndef SCRIBO_NDEBUG
+ else if (bot_group_size(old_bot_groups(l)) > 1)
+ {
+ mln::draw::line(debug,
+ p,
+ components(bot_links(l)).bbox().pmax(),
+ literal::orange);
+
+ // Draw first component box
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(l).component_ids()[lines(l).card() - 1]).bbox(),
+ rbbox),
+ literal::cyan);
+
+ mln::draw::box(debug,
+ internal::fast_rotate_positive(
+ groups.components()(lines(bot_links(l)).component_ids()[lines(bot_links(l)).card() - 1]).bbox(),
+ rbbox),
+ literal::cyan);
+ }
+# endif // ! SCRIBO_NDEBUG
+ }
+
+
+ // Looking for whitespaces
+ for_all_elements(c, group_bbox)
+ if (group_bbox(c).is_valid())
+ {
+ unsigned ldelta = delta;
+ if (bot_group_size(c) >= 3 && bot_group_size(c) < 5)
+ {
+ // Stats are not reliable, prefer using max char width.
+ if (bot_median_char_width(c).card() == 0)
+ ldelta = bot_max_char_width(c) * 2;
+ else
+ ldelta = 1.2 * bot_median_char_width(c)
+ + bot_median_char_space(c);
+
+ point2d p(group_bbox(c).to_result().pmax().row() + ldelta,
+ group_bbox(c).to_result().pmin().col());
+ p = scribo::internal::point_row_adjust(p, bbox_ima);
+
+ // Checking whitespace area
+ for (; p.col() <= group_bbox(c).to_result().pmax().col()
+ && (bbox_ima(p) == 0);)
+ ++p.col();
+
+ if (bbox_ima(p) != 0)
+ {
+# ifndef SCRIBO_NDEBUG
+ mln::draw::line(debug,
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmax().row() + ldelta,
+ group_bbox(c).to_result().pmin().col()), debug),
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmax().row() + ldelta,
+ group_bbox(c).to_result().pmax().col()), debug),
+ literal::red);
+# endif // ! SCRIBO_NDEBUG
+
+ continue;
+ }
+ }
+
+ box2d
+ brot = internal::fast_rotate_negative(group_bbox(c).to_result(),
+ rbbox);
+
+ if (internal::is_valid_left_right_skewed_delimitor(brot, input,
+ - delta))
+ {
+ mln::draw::line(delimitors,
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmin().row(),
+ brot.pmin().col() + delta),
+ delimitors),
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmax().row(),
+ brot.pmax().col() + delta),
+ delimitors),
+ true);
+ }
+ else if (internal::is_valid_right_left_skewed_delimitor(brot,
+ input,
+ - delta))
+ {
+ mln::draw::line(delimitors,
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmin().row(),
+ brot.pmax().col() + delta),
+ delimitors),
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmax().row(),
+ brot.pmin().col() + delta),
+ delimitors),
+ true);
+ }
+ else
+ {
+ mln::draw::line(delimitors,
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmin().row(),
+ brot.pmax().col() + delta),
+ delimitors),
+ scribo::internal::point_col_adjust(
+ point2d(brot.pmax().row(),
+ brot.pmax().col() + delta),
+ delimitors),
+ true);
+ }
+
+# ifndef SCRIBO_NDEBUG
+ mln::draw::line(debug,
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmax().row() + ldelta,
+ group_bbox(c).to_result().pmin().col()), debug),
+ scribo::internal::point_row_adjust(
+ point2d(group_bbox(c).to_result().pmax().row() + ldelta,
+ group_bbox(c).to_result().pmax().col()), debug),
+ literal::green);
+# endif // ! SCRIBO_NDEBUG
+ }
+ }
+
+ } // END OF BOTTOM LINKS PROCESSING
+
+
+ V ndelim;
+ component_set<L>
+ delim_comps = primitive::extract::components(delimitors, c8(), ndelim);
+
+ mln::util::couple<component_set<L>, mln_ch_value(L,bool)>
+ output(delim_comps, delimitors);
+
+# ifndef SCRIBO_NDEBUG
+ debug = preprocessing::rotate_90(debug, true);
+ debug::logger().log_image(debug::All,
+ debug, "alignments_debug");
+# endif // ! SCRIBO_NDEBUG
+
+ trace::exiting("scribo::primitive::extract::alignments");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::primitive::extract
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_PRIMITIVE_EXTRACT_ALIGNMENTS_HH
diff --git a/scribo/scribo/primitive/link/internal/dmax_hrules.hh b/scribo/scribo/primitive/link/internal/dmax_hrules.hh
new file mode 100644
index 0000000..24de6ca
--- /dev/null
+++ b/scribo/scribo/primitive/link/internal/dmax_hrules.hh
@@ -0,0 +1,100 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_INTERNAL_DMAX_HRULES_HH
+# define SCRIBO_PRIMITIVE_LINK_INTERNAL_DMAX_HRULES_HH
+
+/// \file
+///
+/// Default class for dmax functors.
+
+# include <scribo/primitive/link/internal/dmax_functor_base.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ namespace internal
+ {
+
+
+ /// \brief Base class for dmax functors.
+ class dmax_hrules : public dmax_functor_base<dmax_hrules>
+ {
+ typedef dmax_functor_base<dmax_hrules> super_;
+
+ public:
+ dmax_hrules(float dmax_factor, unsigned fixed_dmax);
+ float compute_(const box2d& b) const;
+
+ protected:
+ using super_::dmax_factor_;
+ unsigned fixed_dmax_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ inline
+ dmax_hrules::dmax_hrules(float dmax_factor, unsigned fixed_dmax)
+ : super_(dmax_factor), fixed_dmax_(fixed_dmax)
+ {
+ }
+
+
+ inline
+ float
+ dmax_hrules::compute_(const box2d& b) const
+ {
+ float
+ w = b.width();
+
+ if (w < 15)
+ return fixed_dmax_;
+
+ return (w / 2.0f) + (dmax_factor_ * w);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::primitive::link::internal
+
+ } // end of namespace scribo::primitive::link
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_PRIMITIVE_LINK_INTERNAL_DMAX_HRULES_HH
diff --git a/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh
new file mode 100644
index 0000000..c7ef021
--- /dev/null
+++ b/scribo/scribo/primitive/link/internal/link_single_dmax_ratio_aligned_delta_base.hh
@@ -0,0 +1,159 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_DELTA_BASE_HH_
+# define SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_DELTA_BASE_HH_
+
+/// \file
+///
+/// \brief Base class for link functors using bounding box center,
+/// a proportional max distance and alignment criterion.
+
+
+# include <mln/accu/center.hh>
+# include <mln/labeling/compute.hh>
+# include <mln/math/abs.hh>
+# include <mln/math/max.hh>
+# include <mln/util/array.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/draw/line.hh>
+# include <mln/literal/colors.hh>
+# include <mln/norm/l1.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/tag/anchor.hh>
+# include <scribo/core/component_set.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/concept/dmax_functor.hh>
+
+# include <scribo/debug/logger.hh>
+
+# include <scribo/primitive/link/internal/link_single_dmax_ratio_base.hh>
+# include <scribo/filter/internal/component_aligned.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ namespace internal
+ {
+ using namespace scribo::debug;
+
+
+ template <typename L, typename F, typename E>
+ class link_single_dmax_ratio_aligned_delta_base
+ : public link_single_dmax_ratio_base<L, F, E>
+ {
+ typedef link_single_dmax_ratio_base<L, F, E> super_;
+
+ public:
+ typedef mln_site(L) P;
+
+ link_single_dmax_ratio_aligned_delta_base(
+ const component_set<L>& components,
+ const DMax_Functor<F>& dmax_f,
+ int delta_pixel,
+ anchor::Direction delta_direction)
+ : super_(components, anchor::Horizontal, exact(dmax_f)),
+ delta_pixel_(delta_pixel), delta_direction_(delta_direction)
+ {
+
+ }
+
+
+ mln_site(L)
+ start_point_(unsigned current_object, anchor::Type anchor)
+ {
+ return link::internal::compute_anchor(this->components_,
+ current_object, anchor);
+ }
+
+
+ inline
+ bool
+ valid_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ anchor::Type anchor)
+ {
+ if (!super_::valid_link_(current_object, start_point, p, anchor))
+ return false;
+
+ // We can assume that the current site 'p' points to an
+ // object different from the background.
+
+ mln_site(L)
+ p1 = compute_anchor(this->components_, current_object, anchor),
+ p2 = compute_anchor(this->components_, this->labeled_image_(p),
+ anchor);
+
+ return std::abs(p1[this->delta_direction_]
+ - p2[this->delta_direction_]) <= delta_pixel_;
+ }
+
+
+ void validate_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ anchor::Type anchor)
+ {
+ super_::validate_link_(current_object, start_point, p, anchor);
+ }
+
+ void invalidate_link_(unsigned current_object,
+ const P& start_point,
+ const P& p,
+ anchor::Type anchor)
+ {
+ super_::invalidate_link_(current_object, start_point, p, anchor);
+ }
+
+ int delta_pixel_;
+ anchor::Direction delta_direction_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::primitive::link::internal
+
+ } // end of namespace scribo::primitive::link
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+
+#endif // SCRIBO_PRIMITIVE_LINK_INTERNAL_LINK_SINGLE_DMAX_RATIO_ALIGNED_DELTA_BASE_HH_
diff --git a/scribo/scribo/primitive/link/merge_double_link_closest_aligned.hh b/scribo/scribo/primitive/link/merge_double_link_closest_aligned.hh
new file mode 100644
index 0000000..6c6e67f
--- /dev/null
+++ b/scribo/scribo/primitive/link/merge_double_link_closest_aligned.hh
@@ -0,0 +1,157 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+/// \file
+///
+/// \brief Merge two object links data based on distance and angle.
+
+#ifndef SCRIBO_PRIMITIVE_LINK_MERGE_DOUBLE_LINK_CLOSEST_ALIGNED_HH
+# define SCRIBO_PRIMITIVE_LINK_MERGE_DOUBLE_LINK_CLOSEST_ALIGNED_HH
+
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/tag/anchor.hh>
+# include <scribo/filter/internal/alignment_angle.hh>
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace link
+ {
+
+ /*! \brief Merge two object links data based on distance and angle.
+
+ Performs an 'OR' operation on the links according distance and
+ angle criterion.
+
+ If a component has several incoming links, only the link for
+ which the the object is the closest or the angle performed
+ between the two bboxes is the lower, will be preserved.
+ */
+ template <typename L>
+ object_links<L>
+ merge_double_link_closest_aligned(const object_links<L>& left,
+ const object_links<L>& right,
+ anchor::Type anchor_angle);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename L>
+ object_links<L>
+ merge_double_link_closest_aligned(const object_links<L>& left,
+ const object_links<L>& right,
+ anchor::Type anchor_angle)
+ {
+ trace::entering("scribo::primitive::link::merge_double_link_closest_aligned");
+ mln_precondition(left.is_valid());
+ mln_precondition(right.is_valid());
+
+
+ const component_set<L>& components = left.components();
+
+ mln::util::array<mln::util::couple<unsigned, float> > align_data;
+ align_data.resize(value::next(left.nelements()));
+ for (unsigned i = 0; i < align_data.nelements(); ++i)
+ {
+ align_data(i).first() = mln_max(unsigned);
+ align_data(i).second() = 360;
+ }
+
+ object_links<L> output = right.duplicate();
+
+ // Init alignment data.
+ for_all_links(l, output)
+ if (right(l) != l)
+ {
+ //FIXME Handle the case when a component is included in another one ?
+
+ // Update distance
+ align_data(l).first()
+ = std::abs(components(l).bbox().pcenter().col()
+ - components(right(l)).bbox().pcenter().col());
+
+ // Update angle
+ align_data(l).second()
+ = filter::internal::alignment_angle(components,
+ l,
+ right(l),
+ anchor_angle);
+ }
+ else
+ {
+ // Update distance
+ align_data(l).first() = mln_max(unsigned);
+
+ // Update angle
+ align_data(l).second() = 360.f;
+ }
+
+
+
+ // Trying to improve results with left links.
+ for_all_links(l, left)
+ if (left(l) != l && left(l) != right(l))
+ {
+ unsigned dh = std::abs(components(l).bbox().pcenter().col()
+ - components(left(l)).bbox().pcenter().col());
+
+ float alpha
+ = filter::internal::alignment_angle(components,
+ l,
+ left(l),
+ anchor_angle);
+
+ if (right(left(l)) == left(l))
+ {
+ output(left(l)) = l;
+ //output.update_link(left(l), l);
+ }
+ else if ((dh < align_data(left(l)).first() * 0.66f)
+ || (alpha < align_data(left(l)).second()))
+ {
+ output(left(l)) = l;
+ //output.update_link(left(l), l);
+ align_data(left(l)).first() = dh;
+ align_data(left(l)).second() = alpha;
+ }
+ }
+
+ trace::exiting("scribo::primitive::link::merge_double_link_closest_aligned");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::primitive::link
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_PRIMITIVE_LINK_MERGE_DOUBLE_LINK_CLOSEST_ALIGNED_HH
diff --git a/scribo/src/primitive/extract/Makefile.am b/scribo/src/primitive/extract/Makefile.am
index 22d6bfd..fef405a 100644
--- a/scribo/src/primitive/extract/Makefile.am
+++ b/scribo/src/primitive/extract/Makefile.am
@@ -34,3 +34,14 @@ separators_nonvisible_SOURCES = separators_nonvisible.cc
thick_vlines_SOURCES = thick_vlines.cc
thick_hlines_SOURCES = thick_hlines.cc
lines_pattern_SOURCES = lines_pattern.cc
+
+
+if HAVE_MAGICKXX
+
+ noinst_PROGRAMS += alignments
+ alignments_SOURCES = alignments.cc
+ alignments_CPPFLAGS = $(AM_CPPFLAGS) \
+ $(MAGICKXX_CPPFLAGS)
+ alignments_LDFLAGS = $(AM_LDFLAGS) \
+ $(MAGICKXX_LDFLAGS)
+endif HAVE_MAGICKXX
\ No newline at end of file
diff --git a/scribo/src/primitive/extract/alignments.cc b/scribo/src/primitive/extract/alignments.cc
new file mode 100644
index 0000000..2508ec9
--- /dev/null
+++ b/scribo/src/primitive/extract/alignments.cc
@@ -0,0 +1,89 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/io/pbm/all.hh>
+#include <mln/data/convert.hh>
+#include <mln/util/timer.hh>
+
+#include <scribo/text/extract_lines_wo_merge.hh>
+#include <scribo/primitive/extract/alignments.hh>
+#include <scribo/debug/usage.hh>
+
+const char *args_desc[][2] =
+{
+ { "input.pbm", "A binary image without vertical or horizontal separators." },
+ { "output.pbm", "Output image." },
+ { "enable_debug", "0 or 1 (default 0)" },
+ {0, 0}
+};
+
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+ using namespace scribo;
+
+ if (argc != 3 && argc != 4)
+ return scribo::debug::usage(argv,
+ "Extract delimitors based on alignments.",
+ "input.pbm output.pbm [enable_debug]",
+ args_desc);
+
+ trace::entering("main");
+
+ if (argc > 3 && atoi(argv[3]))
+ scribo::debug::logger().set_level(scribo::debug::All);
+
+ float dmax_ratio = 3;
+ unsigned delta_pixel = 3;
+
+ typedef image2d<scribo::def::lbl_type> L;
+ document<L> doc(argv[1]);
+ doc.open();
+
+ // Vertical and horizontal separators
+ image2d<bool> input = data::convert(bool(), doc.image());
+ image2d<bool> separators = primitive::extract::separators(input, 81);
+ input = primitive::remove::separators(input, separators);
+ input = preprocessing::denoise_fg(input, c8(), 3);
+ doc.set_binary_image(input);
+
+ // Extract lines
+ line_set<L>
+ lines = scribo::text::extract_lines_wo_merge(doc, c8(), separators);
+ doc.set_paragraphs(scribo::make::paragraph(lines));
+
+ util::timer t;
+ t.start();
+ mln::util::couple<component_set<L>, mln_ch_value_(L,bool)>
+ res = primitive::extract::alignments(doc, dmax_ratio, delta_pixel);
+ t.stop();
+ std::cout << t << std::endl;
+
+ io::pbm::save(res.second(), argv[2]);
+
+ trace::exiting("main");
+}
diff --git a/scribo/tests/data.hh.in b/scribo/tests/data.hh.in
index 6a6f95f..501fbea 100644
--- a/scribo/tests/data.hh.in
+++ b/scribo/tests/data.hh.in
@@ -1,4 +1,5 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2011 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -36,4 +37,7 @@
/// \brief The absolute path to the img directory of Scribo.
# define SCRIBO_IMG_DIR "@abs_top_srcdir@/scribo/tests/img"
+/// \brief The absolute path to the test directory of Scribo.
+# define SCRIBO_TESTS_DIR "@abs_top_srcdir@/scribo/tests/"
+
#endif // ! SCRIBO_TESTS_DATA_HH
diff --git a/scribo/tests/img/alignment_1.png b/scribo/tests/img/alignment_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..f4592429963506e1c987e2b18b0969ad04a9bde0
GIT binary patch
literal 3145
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
literal 0
HcmV?d00001
diff --git a/scribo/tests/img/alignment_2.png b/scribo/tests/img/alignment_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..9c828bb44984051f862879836b2904a1176695c2
GIT binary patch
literal 3147
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
literal 0
HcmV?d00001
diff --git a/scribo/tests/img/alignment_3.png b/scribo/tests/img/alignment_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..67c20308a0693278a5c16af4f4f9f014f30a2f8b
GIT binary patch
literal 3145
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
literal 0
HcmV?d00001
diff --git a/scribo/tests/img/alignment_4.png b/scribo/tests/img/alignment_4.png
new file mode 100644
index 0000000000000000000000000000000000000000..df3d395baa7c9f0fa905c6e7d941b36ee3ab705e
GIT binary patch
literal 3155
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
literal 0
HcmV?d00001
diff --git a/scribo/tests/primitive/Makefile.am b/scribo/tests/primitive/Makefile.am
index 82c773a..2b88bed 100644
--- a/scribo/tests/primitive/Makefile.am
+++ b/scribo/tests/primitive/Makefile.am
@@ -1,4 +1,5 @@
-# Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE).
+# Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+# (LRDE).
#
# This file is part of Olena.
#
@@ -17,5 +18,6 @@
include $(top_srcdir)/scribo/tests/tests.mk
SUBDIRS = \
+ extract \
link
diff --git a/scribo/tests/primitive/extract/Makefile.am b/scribo/tests/primitive/extract/Makefile.am
new file mode 100644
index 0000000..97eb43f
--- /dev/null
+++ b/scribo/tests/primitive/extract/Makefile.am
@@ -0,0 +1,33 @@
+# Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
+include $(top_srcdir)/scribo/tests/tests.mk
+
+check_PROGRAMS =
+
+if HAVE_MAGICKXX
+
+check_PROGRAMS = alignments
+alignments_SOURCES = alignments.cc
+alignments_CPPFLAGS = $(AM_CPPFLAGS) \
+ $(MAGICKXX_CPPFLAGS) \
+ -DSCRIBO_NDEBUG
+alignments_LDFLAGS = $(LDFLAGS) \
+ $(MAGICKXX_LDFLAGS)
+
+endif HAVE_MAGICKXX
+
+TESTS = $(check_PROGRAMS)
diff --git a/scribo/tests/primitive/extract/alignment_1.ref.pbm b/scribo/tests/primitive/extract/alignment_1.ref.pbm
new file mode 100644
index 0000000..ad657f2
--- /dev/null
+++ b/scribo/tests/primitive/extract/alignment_1.ref.pbm
@@ -0,0 +1,5 @@
+P4
+# Generated by Milena 1.0 http://olena.lrde.epita.fr
+# EPITA Research and Development Laboratory (LRDE)
+436 216
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð
\ No newline at end of file
diff --git a/scribo/tests/primitive/extract/alignment_2.ref.pbm b/scribo/tests/primitive/extract/alignment_2.ref.pbm
new file mode 100644
index 0000000..e1e07c3
--- /dev/null
+++ b/scribo/tests/primitive/extract/alignment_2.ref.pbm
@@ -0,0 +1,5 @@
+P4
+# Generated by Milena 1.0 http://olena.lrde.epita.fr
+# EPITA Research and Development Laboratory (LRDE)
+436 216
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð
\ No newline at end of file
diff --git a/scribo/tests/primitive/extract/alignment_3.ref.pbm b/scribo/tests/primitive/extract/alignment_3.ref.pbm
new file mode 100644
index 0000000..0bd1d34
--- /dev/null
+++ b/scribo/tests/primitive/extract/alignment_3.ref.pbm
@@ -0,0 +1,5 @@
+P4
+# Generated by Milena 1.0 http://olena.lrde.epita.fr
+# EPITA Research and Development Laboratory (LRDE)
+436 216
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð
\ No newline at end of file
diff --git a/scribo/tests/primitive/extract/alignment_4.ref.pbm b/scribo/tests/primitive/extract/alignment_4.ref.pbm
new file mode 100644
index 0000000..a0830ea
--- /dev/null
+++ b/scribo/tests/primitive/extract/alignment_4.ref.pbm
@@ -0,0 +1,5 @@
+P4
+# Generated by Milena 1.0 http://olena.lrde.epita.fr
+# EPITA Research and Development Laboratory (LRDE)
+436 216
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð
\ No newline at end of file
diff --git a/scribo/tests/primitive/extract/alignments.cc b/scribo/tests/primitive/extract/alignments.cc
new file mode 100644
index 0000000..7bd82fb
--- /dev/null
+++ b/scribo/tests/primitive/extract/alignments.cc
@@ -0,0 +1,76 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+// \file
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/io/pbm/load.hh>
+
+#include <scribo/core/document.hh>
+#include <scribo/core/paragraph_set.hh>
+#include <scribo/text/extract_lines_wo_merge.hh>
+#include <scribo/primitive/extract/alignments.hh>
+
+#include "tests/data.hh"
+
+
+int main()
+{
+ using namespace mln;
+ using namespace scribo;
+
+ typedef image2d<scribo::def::lbl_type> L;
+
+ for (unsigned i = 1; i < 5; ++i)
+ {
+ std::ostringstream os;
+ os << SCRIBO_IMG_DIR << "/alignment_" << i << ".png";
+
+ document<L> doc(os.str().c_str());
+ doc.open();
+ doc.set_binary_image(data::convert(bool(), doc.image()));
+
+ // Extract lines
+ line_set<L>
+ lines = scribo::text::extract_lines_wo_merge(doc, c8());
+ doc.set_paragraphs(scribo::make::paragraph(lines));
+
+ // Find alignments
+ mln::util::couple<component_set<L>, mln_ch_value_(L,bool)>
+ res = primitive::extract::alignments(doc, 3, 3);
+
+ std::ostringstream os_out;
+ image2d<bool> ref;
+ os_out << SCRIBO_TESTS_DIR << "/primitive/extract/alignment_"
+ << i << ".ref.pbm";
+
+ io::pbm::save(res.second(), "res.pbm");
+ io::pbm::load(ref, os_out.str().c_str());
+
+ mln_assertion(ref == res.second());
+ }
+
+}
--
1.5.6.5
1
0

05 Apr '11
* scribo/core/component_features_data.hh,
* scribo/core/component_info.hh,
* scribo/core/line_info.hh,
* scribo/core/paragraph_info.hh,
* scribo/core/paragraph_set.hh: Add support for text features in
core structures.
* scribo/debug/text_color_image.hh: New debug routine.
* scribo/estim/components_features.hh:
* scribo/estim/font_boldness.hh,
* scribo/estim/font_color.hh,
* scribo/estim/internal/compute_skeleton.hh: New.
* scribo/io/xml/internal/extended_page_xml_visitor.hh,
* scribo/io/xml/internal/full_xml_visitor.hh: Use text features in
XML.
* scribo/primitive/extract/components.hh,
* scribo/text/extract_lines.hh: Add new overloads
* scribo/text/extract_lines_with_features.hh: New.
* scribo/toolchain/internal/content_in_doc_functor.hh: Update call
to extract::components.
* src/debug/Makefile.am,
* src/debug/show_components_boldness.cc,
* src/debug/show_components_color.cc,
* src/debug/show_lines_boldness.cc: New debug examples.
* tests/Makefile.am,
* tests/estim/Makefile.am,
* tests/estim/font_boldness.cc,
* tests/estim/font_color.cc: New tests.
* tests/img/phillip.pbm,
* tests/img/phillip.ppm: New test data.
---
scribo/ChangeLog | 43 ++++
scribo/scribo/core/component_features_data.hh | 68 ++++++
scribo/scribo/core/component_info.hh | 40 ++++-
scribo/scribo/core/line_info.hh | 118 +++++++++++-
scribo/scribo/core/paragraph_info.hh | 102 +++++++++-
scribo/scribo/core/paragraph_set.hh | 11 +
scribo/scribo/debug/text_color_image.hh | 100 +++++++++
scribo/scribo/estim/components_features.hh | 169 +++++++++++++++
scribo/scribo/estim/font_boldness.hh | 215 ++++++++++++++++++++
scribo/scribo/estim/font_color.hh | 206 +++++++++++++++++++
scribo/scribo/estim/internal/compute_skeleton.hh | 112 ++++++++++
.../io/xml/internal/extended_page_xml_visitor.hh | 9 +-
scribo/scribo/io/xml/internal/full_xml_visitor.hh | 33 ++--
scribo/scribo/primitive/extract/components.hh | 70 ++++---
scribo/scribo/text/extract_lines.hh | 22 ++
scribo/scribo/text/extract_lines_with_features.hh | 131 ++++++++++++
.../toolchain/internal/content_in_doc_functor.hh | 3 +-
scribo/src/debug/Makefile.am | 16 ++
scribo/src/debug/show_components_boldness.cc | 72 +++++++
scribo/src/debug/show_components_color.cc | 73 +++++++
scribo/src/debug/show_lines_boldness.cc | 199 ++++++++++++++++++
scribo/tests/Makefile.am | 5 +-
scribo/tests/estim/Makefile.am | 29 +++
scribo/tests/estim/font_boldness.cc | 46 ++++
scribo/tests/estim/font_color.cc | 48 +++++
scribo/tests/img/phillip.pbm | Bin 0 -> 1633 bytes
scribo/tests/img/phillip.ppm | 5 +
27 files changed, 1895 insertions(+), 50 deletions(-)
create mode 100644 scribo/scribo/core/component_features_data.hh
create mode 100644 scribo/scribo/debug/text_color_image.hh
create mode 100644 scribo/scribo/estim/components_features.hh
create mode 100644 scribo/scribo/estim/font_boldness.hh
create mode 100644 scribo/scribo/estim/font_color.hh
create mode 100644 scribo/scribo/estim/internal/compute_skeleton.hh
create mode 100644 scribo/scribo/text/extract_lines_with_features.hh
create mode 100644 scribo/src/debug/show_components_boldness.cc
create mode 100644 scribo/src/debug/show_components_color.cc
create mode 100644 scribo/src/debug/show_lines_boldness.cc
create mode 100644 scribo/tests/estim/Makefile.am
create mode 100644 scribo/tests/estim/font_boldness.cc
create mode 100644 scribo/tests/estim/font_color.cc
create mode 100644 scribo/tests/img/phillip.pbm
create mode 100644 scribo/tests/img/phillip.ppm
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 4592e73..2fc8d6d 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,48 @@
2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Compute font and boldness data.
+
+ * scribo/core/component_features_data.hh,
+ * scribo/core/component_info.hh,
+ * scribo/core/line_info.hh,
+ * scribo/core/paragraph_info.hh,
+ * scribo/core/paragraph_set.hh: Add support for text features in
+ core structures.
+
+ * scribo/debug/text_color_image.hh: New debug routine.
+
+ * scribo/estim/components_features.hh:
+ * scribo/estim/font_boldness.hh,
+ * scribo/estim/font_color.hh,
+ * scribo/estim/internal/compute_skeleton.hh: New.
+
+ * scribo/io/xml/internal/extended_page_xml_visitor.hh,
+ * scribo/io/xml/internal/full_xml_visitor.hh: Use text features in
+ XML.
+
+ * scribo/primitive/extract/components.hh,
+ * scribo/text/extract_lines.hh: Add new overloads
+
+ * scribo/text/extract_lines_with_features.hh: New.
+
+ * scribo/toolchain/internal/content_in_doc_functor.hh: Update call
+ to extract::components.
+
+ * src/debug/Makefile.am,
+ * src/debug/show_components_boldness.cc,
+ * src/debug/show_components_color.cc,
+ * src/debug/show_lines_boldness.cc: New debug examples.
+
+ * tests/Makefile.am,
+ * tests/estim/Makefile.am,
+ * tests/estim/font_boldness.cc,
+ * tests/estim/font_color.cc: New tests.
+
+ * tests/img/phillip.pbm,
+ * tests/img/phillip.ppm: New test data.
+
+2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add a new alignments extraction routine.
* scribo/primitive/extract/alignments.hh,
diff --git a/scribo/scribo/core/component_features_data.hh b/scribo/scribo/core/component_features_data.hh
new file mode 100644
index 0000000..f5ba60f
--- /dev/null
+++ b/scribo/scribo/core/component_features_data.hh
@@ -0,0 +1,68 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_CORE_COMPONENT_FEATURES_DATA_HH
+# define SCRIBO_CORE_COMPONENT_FEATURES_DATA_HH
+
+/// \file
+///
+/// \brief Component features data structure.
+
+
+# include <scribo/core/def/color_type.hh>
+
+namespace scribo
+{
+
+ struct component_features_data
+ {
+ bool valid;
+ scribo::def::color_type color;
+ float boldness;
+ };
+
+
+ std::ostream&
+ operator<<(std::ostream& ostr, const component_features_data& data);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr, const component_features_data& data)
+ {
+ return ostr << "features["
+ << "valid=" << data.valid
+ << ", color=" << data.color
+ << ", boldness=" << data.boldness
+ << "]" << std::endl;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_CORE_COMPONENT_FEATURES_DATA_HH
diff --git a/scribo/scribo/core/component_info.hh b/scribo/scribo/core/component_info.hh
index f825aee..164a242 100644
--- a/scribo/scribo/core/component_info.hh
+++ b/scribo/scribo/core/component_info.hh
@@ -36,6 +36,7 @@
# include <mln/core/alias/point2d.hh>
# include <mln/util/object_id.hh>
+# include <scribo/core/component_features_data.hh>
# include <scribo/core/concept/serializable.hh>
# include <scribo/core/tag/component.hh>
# include <scribo/core/tag/line.hh>
@@ -64,6 +65,13 @@ namespace scribo
// The number of pixels in this component.
unsigned card() const;
+
+ bool has_features() const;
+ void update_features(const component_features_data& features);
+
+ const component_features_data& features() const;
+
+
component::Tag tag() const;
void update_tag(component::Tag tag);
@@ -72,12 +80,14 @@ namespace scribo
bool is_valid() const;
- private:
+ protected:
component_id_t id_;
mln::box2d bbox_;
mln::point2d mass_center_;
unsigned card_;
+ component_features_data features_;
+
component::Tag tag_;
component::Type type_;
};
@@ -106,9 +116,12 @@ namespace scribo
unsigned card,
component::Type type)
: id_(id), bbox_(bbox), mass_center_(mass_center), card_(card),
- tag_(component::None), type_(type)
+ type_(type)
{
-
+ if (!bbox.is_valid())
+ tag_ = component::Ignored;
+ else
+ tag_ = component::None;
}
@@ -142,6 +155,26 @@ namespace scribo
return card_;
}
+ inline
+ bool
+ component_info::has_features() const
+ {
+ return features_.valid;
+ }
+
+ inline
+ void
+ component_info::update_features(const component_features_data& features)
+ {
+ features_ = features;
+ }
+
+ inline
+ const component_features_data&
+ component_info::features() const
+ {
+ return features_;
+ }
inline
component::Tag
@@ -193,6 +226,7 @@ namespace scribo
<< ", mass_center=" << info.mass_center()
<< ", card=" << info.card()
<< ", tag=" << info.tag()
+ << ", features=" << info.features()
<< ")" << std::endl;
}
diff --git a/scribo/scribo/core/line_info.hh b/scribo/scribo/core/line_info.hh
index 749e627..73d7856 100644
--- a/scribo/scribo/core/line_info.hh
+++ b/scribo/scribo/core/line_info.hh
@@ -43,10 +43,13 @@
# include <mln/core/alias/box2d.hh>
# include <mln/core/alias/point2d.hh>
# include <mln/accu/stat/median_h.hh>
+# include <mln/accu/stat/mean.hh>
# include <mln/accu/shape/bbox.hh>
# include <mln/math/min.hh>
# include <mln/util/object_id.hh>
# include <mln/value/int_u.hh>
+# include <mln/math/sqr.hh>
+# include <mln/value/rgb8.hh>
# include <scribo/core/tag/component.hh>
# include <scribo/core/tag/line.hh>
@@ -69,6 +72,7 @@ namespace scribo
namespace internal
{
+
/// Data structure for \c scribo::line_info<I>.
template <typename L>
struct line_info_data
@@ -120,6 +124,14 @@ namespace scribo
bool indented_;
+ float boldness_;
+ float boldness_reliability_;
+
+ mln::value::rgb8 color_;
+
+ // sqrt(Max(VAR(R), VAR(G), VAR(B)))
+ float color_reliability_;
+
std::string text_;
std::string html_text_;
@@ -128,6 +140,19 @@ namespace scribo
};
+
+ // Functor used to sort components ids.
+ // Order by location from left to right.
+ template <typename L>
+ struct sort_comp_ids
+ {
+ sort_comp_ids(const component_set<L>& comp_set);
+ bool operator()(const component_id_t& l, const component_id_t& r) const;
+
+ component_set<L> comps_;
+ };
+
+
} // end of namespace scribo::internal
@@ -181,6 +206,12 @@ namespace scribo
unsigned pixel_area() const;
+ float boldness() const;
+ float boldness_reliability() const;
+
+ const mln::value::rgb8& color() const;
+ float color_reliability() const;
+
int baseline() const;
int meanline() const;
int ascent() const;
@@ -530,6 +561,38 @@ namespace scribo
template <typename L>
+ float
+ line_info<L>::boldness() const
+ {
+ return data_->boldness_;
+ }
+
+
+ template <typename L>
+ float
+ line_info<L>::boldness_reliability() const
+ {
+ return data_->boldness_reliability_;
+ }
+
+
+ template <typename L>
+ const mln::value::rgb8&
+ line_info<L>::color() const
+ {
+ return data_->color_;
+ }
+
+
+ template <typename L>
+ float
+ line_info<L>::color_reliability() const
+ {
+ return data_->color_reliability_;
+ }
+
+
+ template <typename L>
int
line_info<L>::baseline() const
{
@@ -919,6 +982,20 @@ namespace scribo
char_space,
char_width;
+ // FIXME: we should use the median for computing the line
+ // color. Means should be kept for variance computation.
+ mln::accu::stat::mean<mln::value::int_u<8> >
+ color_red,
+ color_green,
+ color_blue,
+ boldness;
+
+ float
+ sum2_red = 0,
+ sum2_green = 0,
+ sum2_blue = 0,
+ sum2_boldness = 0;
+
unsigned pixel_area = 0;
mln::accu::shape::bbox<P> bbox;
@@ -941,8 +1018,8 @@ namespace scribo
ref_line = mln::math::min(comp_set(c).bbox().pmin().row(), ref_line);
}
- // FIXME: compute font color!
+ unsigned used_comps = 0;
for_all_elements(i, data_->components_)
{
unsigned c = data_->components_(i);
@@ -959,6 +1036,22 @@ namespace scribo
if (comp_set(c).type() == component::Punctuation)
continue;
+ // This component will be used for stats, the counter is
+ // incremented.
+ ++used_comps;
+
+ // Compute boldness
+ boldness.take(comp_set(c).features().boldness);
+ sum2_boldness += mln::math::sqr<float>(comp_set(c).features().boldness);
+
+ // Compute color
+ color_red.take(comp_set(c).features().color.red());
+ color_green.take(comp_set(c).features().color.green());
+ color_blue.take(comp_set(c).features().color.blue());
+
+ sum2_red += mln::math::sqr<unsigned>(comp_set(c).features().color.red());
+ sum2_green += mln::math::sqr<unsigned>(comp_set(c).features().color.green());
+ sum2_blue += mln::math::sqr<unsigned>(comp_set(c).features().color.blue());
// FIXME: we must guaranty here that the relationship is from
@@ -1018,6 +1111,25 @@ namespace scribo
data_->components_.hook_std_vector_().end(),
internal::sort_comp_ids<L>(comp_set));
+ // Boldness
+ data_->boldness_ = boldness.to_result();
+ data_->boldness_reliability_ = std::sqrt(sum2_boldness);
+
+ // Color
+ data_->color_ = mln::value::rgb8(color_red, color_green, color_blue);
+
+ // FIXME: we may prefer using the non-biased variance.
+ float
+ var_red = sum2_red / (float)(used_comps)
+ - mln::math::sqr<float>(color_red.to_result()),
+ var_green = sum2_green / (float)(used_comps)
+ - mln::math::sqr<float>(color_green.to_result()),
+ var_blue = sum2_blue / (float)(used_comps)
+ - mln::math::sqr<float>(color_blue.to_result());
+
+ data_->color_reliability_ = std::sqrt(std::max(var_red,
+ std::max(var_green, var_blue)));
+
// Char space
if (char_space.card() < 2)
data_->char_space_ = 0;
@@ -1074,6 +1186,10 @@ namespace scribo
<< ", type=" << info.type()
<< ", bbox=" << info.bbox()
<< ", ebbox=" << info.ebbox()
+ << ", boldness=" << info.boldness()
+ << ", boldness_reliability=" << info.boldness_reliability()
+ << ", color=" << info.color()
+ << ", color_reliability=" << info.color_reliability()
<< ", components=" << info.component_ids()
<< ", baseline=" << info.baseline()
<< ", meanline=" << info.meanline()
diff --git a/scribo/scribo/core/paragraph_info.hh b/scribo/scribo/core/paragraph_info.hh
index f4b1309..2a9b626 100644
--- a/scribo/scribo/core/paragraph_info.hh
+++ b/scribo/scribo/core/paragraph_info.hh
@@ -44,6 +44,13 @@ namespace scribo
paragraph_info();
paragraph_info(const line_links<L>& llinks);
+ /*! \brief Add a new line to this paragraph
+
+ This method is provided for an incremental construction.
+
+ Once this method has been called, needs_stats_update() will
+ return true until force_stats_update() is called.
+ */
void add_line(const line_info<L>& line);
const mln::box2d& bbox() const;
@@ -54,12 +61,25 @@ namespace scribo
unsigned nlines() const;
+ // FIXME: add boldness?
+
+ const mln::value::rgb8& color() const;
+ float color_reliability() const;
+
bool is_valid() const;
+ bool needs_stats_update() const;
+ void force_stats_update();
+
private:
mln::util::array<line_id_t> line_ids_;
mln::accu::shape::bbox<mln_site(L)> bbox_;
line_links<L> llinks_;
+
+ mln::value::rgb8 color_;
+ float color_reliability_;
+
+ bool needs_stats_update_;
};
@@ -68,12 +88,13 @@ namespace scribo
template <typename L>
paragraph_info<L>::paragraph_info()
+ : needs_stats_update_(false)
{
}
template <typename L>
paragraph_info<L>::paragraph_info(const line_links<L>& llinks)
- : llinks_(llinks)
+ : llinks_(llinks), needs_stats_update_(false)
{
}
@@ -83,6 +104,9 @@ namespace scribo
{
line_ids_.append(line.id());
bbox_.take(line.bbox());
+
+ // More data may need to be updated!
+ needs_stats_update_ = true;
}
template <typename L>
@@ -115,12 +139,86 @@ namespace scribo
}
template <typename L>
+ const mln::value::rgb8&
+ paragraph_info<L>::color() const
+ {
+ return color_;
+ }
+
+
+ template <typename L>
+ float
+ paragraph_info<L>::color_reliability() const
+ {
+ return color_reliability_;
+ }
+
+ template <typename L>
bool
paragraph_info<L>::is_valid() const
{
return llinks_.is_valid();
}
+ template <typename L>
+ bool
+ paragraph_info<L>::needs_stats_update() const
+ {
+ return needs_stats_update_;
+ }
+
+ template <typename L>
+ void
+ paragraph_info<L>::force_stats_update()
+ {
+ if (!needs_stats_update_)
+ return;
+
+ const line_set<L>& lines = llinks_.lines();
+
+ mln::accu::stat::mean<mln::value::int_u<8> >
+ color_red,
+ color_green,
+ color_blue;
+
+ float
+ sum2_red = 0,
+ sum2_green = 0,
+ sum2_blue = 0;
+
+ for_all_elements(e, line_ids_)
+ {
+ unsigned lid = line_ids_(e);
+
+ color_red.take(lines(lid).color().red());
+ color_green.take(lines(lid).color().green());
+ color_blue.take(lines(lid).color().blue());
+ sum2_red += mln::math::sqr<unsigned>(lines(lid).color().red());
+ sum2_green += mln::math::sqr<unsigned>(lines(lid).color().green());
+ sum2_blue += mln::math::sqr<unsigned>(lines(lid).color().blue());
+ }
+
+ color_ = mln::value::rgb8(color_red.to_result(),
+ color_green.to_result(),
+ color_blue.to_result());
+
+ float
+ var_red = sum2_red / (float)line_ids_.nelements()
+ - mln::math::sqr<float>(color_red.to_result()),
+ var_green = sum2_green / (float)line_ids_.nelements()
+ - mln::math::sqr<float>(color_green.to_result()),
+ var_blue = sum2_blue / (float)line_ids_.nelements()
+ - mln::math::sqr<float>(color_blue.to_result());
+
+ color_reliability_ = std::sqrt(std::max(var_red,
+ std::max(var_green, var_blue)));
+
+ // Update color
+
+ // FIXME: Update paragraph stats
+
+ needs_stats_update_ = false;
+ }
template <typename L>
std::ostream&
@@ -129,6 +227,8 @@ namespace scribo
return ostr << "paragraph_info("
<< "line_ids=" << info.line_ids()
<< ", bbox=" << info.bbox()
+ << ", color=" << info.color()
+ << ", color_reliability=" << info.color_reliability()
<< ")" << std::endl;
}
diff --git a/scribo/scribo/core/paragraph_set.hh b/scribo/scribo/core/paragraph_set.hh
index f081472..ec9f51b 100644
--- a/scribo/scribo/core/paragraph_set.hh
+++ b/scribo/scribo/core/paragraph_set.hh
@@ -95,6 +95,11 @@ namespace scribo
scribo::paragraph_set<L>
paragraph(const line_links<L>& llinks);
+ /// \brief Construct a paragraph set from line set information.
+ template <typename L>
+ scribo::paragraph_set<L>
+ paragraph(const scribo::line_set<L>& lines);
+
} // end of namespace scribo::make
@@ -239,6 +244,9 @@ namespace scribo
parset(par_id).add_line(lines(l));
}
+ for_all_paragraphs(p, parset)
+ parset(p).force_stats_update();
+
return parset;
}
@@ -264,6 +272,9 @@ namespace scribo
parset(par_id).add_line(lines(l));
}
+ for_all_paragraphs(p, parset)
+ parset(p).force_stats_update();
+
return parset;
}
diff --git a/scribo/scribo/debug/text_color_image.hh b/scribo/scribo/debug/text_color_image.hh
new file mode 100644
index 0000000..f8d76c8
--- /dev/null
+++ b/scribo/scribo/debug/text_color_image.hh
@@ -0,0 +1,100 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEBUG_TEXT_COLOR_IMAGE_HH
+# define SCRIBO_DEBUG_TEXT_COLOR_IMAGE_HH
+
+/// \file
+///
+/// Draw text components with their respective colors.
+
+# include <mln/core/image/image2d.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/data/fill.hh>
+# include <mln/literal/white.hh>
+# include <mln/util/array.hh>
+
+# include <mln/pw/all.hh>
+# include <mln/core/image/dmorph/image_if.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/document.hh>
+
+namespace scribo
+{
+
+ namespace debug
+ {
+ using namespace mln;
+
+ template <typename L>
+ image2d<value::rgb8>
+ text_color_image(const document<L>& doc);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename L>
+ image2d<mln::value::rgb8>
+ text_color_image(const document<L>& doc)
+ {
+ image2d<value::rgb8> debug;
+ initialize(debug, doc.binary_image());
+ data::fill(debug, literal::white);
+
+ const paragraph_set<L>& parset = doc.paragraphs();
+ const line_set<L>& lines = doc.lines();
+ const component_set<L>& comp_set = lines.components();
+ const L& lbl = comp_set.labeled_image();
+
+ for_all_paragraphs(p, parset)
+ {
+ const mln::util::array<line_id_t>& line_ids = parset(p).line_ids();
+
+ for_all_paragraph_lines(lid, line_ids)
+ {
+ line_id_t l = line_ids(lid);
+ const mln::util::array<component_id_t>& comps = lines(l).component_ids();
+
+ for_all_elements(e, comps)
+ {
+ unsigned comp_id = comps(e);
+ data::fill(((debug | comp_set(comp_id).bbox()).rw() | (pw::value(lbl) == pw::cst(comp_id))).rw(),
+ parset(p).color());
+ }
+
+ }
+ }
+
+ return debug;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::debug
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_DEBUG_TEXT_COLOR_IMAGE_HH
diff --git a/scribo/scribo/estim/components_features.hh b/scribo/scribo/estim/components_features.hh
new file mode 100644
index 0000000..ee34123
--- /dev/null
+++ b/scribo/scribo/estim/components_features.hh
@@ -0,0 +1,169 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_ESTIM_COMPONENT_FEATURES_HH
+# define SCRIBO_ESTIM_COMPONENT_FEATURES_HH
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/topo/skeleton/crest.hh>
+# include <mln/topo/skeleton/is_simple_point.hh>
+# include <mln/transform/distance_front.hh>
+# include <mln/logical/not.hh>
+# include <mln/make/w_window2d_int.hh>
+# include <mln/value/int_u8.hh>
+# include <mln/arith/revert.hh>
+# include <mln/morpho/skeleton_constrained.hh>
+# include <mln/core/routine/extend.hh>
+# include <mln/labeling/blobs.hh>
+# include <mln/accu/stat/mean.hh>
+
+
+# include <mln/data/compute.hh>
+# include <mln/io/pbm/save.hh>
+# include <mln/io/pgm/save.hh>
+# include <mln/util/timer.hh>
+
+# include <scribo/core/component_set.hh>
+# include <scribo/estim/font_color.hh>
+# include <scribo/estim/font_boldness.hh>
+
+#include <mln/data/convert.hh>
+
+
+namespace scribo
+{
+
+ namespace estim
+ {
+
+ using namespace mln;
+
+ /// \brief Compute components features.
+ ///
+ /// \sa component_features_data
+ //
+ template <typename I, typename J, typename L>
+ component_set<L>
+ components_features(const Image<I>& input, const Image<J>& bin_input,
+ const component_set<L>& components);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I, typename J, typename L>
+ component_set<L>
+ components_features(const Image<I>& input, const Image<J>& bin_input,
+ const component_set<L>& components)
+ {
+ trace::entering("scribo::estim::components_features");
+
+ component_set<L> output = components.duplicate();
+
+ component_features_data features;
+ features.valid = true;
+
+ typedef mln_concrete(J) B;
+ B skel;
+ L skel_lbl;
+ mln_value(L) nlabels;
+
+ util::timer t;
+ t.start();
+ {
+ int psi = 7;
+ int vals[] = { 0, 9, 0, 9, 0,
+ 9, 6, 4, 6, 9,
+ 0, 4, 0, 4, 0,
+ 9, 6, 4, 6, 9,
+ 0, 9, 0, 9, 0 };
+
+ typedef mln_ch_value(I,value::int_u8) dist_t;
+ dist_t
+ dist = transform::distance_front(logical::not_(bin_input), c8(),
+ mln::make::w_window2d_int(vals),
+ mln_max(value::int_u8));
+ t.stop();
+ std::cout << "Distance front " << t << std::endl;
+ t.restart();
+
+ dist_t dist_map = arith::revert(dist);
+
+ t.stop();
+ std::cout << "Revert " << t << std::endl;
+ t.restart();
+
+ B K = topo::skeleton::crest(bin_input, dist, c8(), psi);
+
+ t.stop();
+ std::cout << "Crest " << t << std::endl;
+ t.restart();
+
+ skel =
+ morpho::skeleton_constrained(bin_input, c8(),
+ topo::skeleton::is_simple_point<B,neighb2d>,
+ extend(K, false), dist_map);
+
+ t.stop();
+ std::cout << "Skeleton constrained " << t << std::endl;
+ }
+ t.restart();
+
+ const L& lbl = output.labeled_image();
+
+ for_all_comps(c, output)
+ {
+ // Estimate component color
+ features.color = data::compute(accu::meta::stat::mean(),
+ ((input | output(c).bbox())
+ | (pw::value(lbl) == pw::cst(c)
+ && pw::value(skel))));
+
+
+ // Estimate component boldness
+ features.boldness = internal::boldness_from_lbl(
+ (lbl | output(c).bbox()) | (pw::value(lbl) == pw::cst(c)),
+ (skel | output(c).bbox()) | (pw::value(lbl) == pw::cst(c)));
+
+ output(c).update_features(features);
+ }
+
+
+ t.stop();
+ std::cout << "compute color and boldness " << t << std::endl;
+
+ trace::exiting("scribo::estim::components_features");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::estim
+
+} // end of namespace scribo
+
+# endif // ! SCRIBO_ESTIM_COMPONENT_FEATURES_HH
diff --git a/scribo/scribo/estim/font_boldness.hh b/scribo/scribo/estim/font_boldness.hh
new file mode 100644
index 0000000..0b145bf
--- /dev/null
+++ b/scribo/scribo/estim/font_boldness.hh
@@ -0,0 +1,215 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_ESTIM_FONT_BOLDNESS_HH
+# define SCRIBO_ESTIM_FONT_BOLDNESS_HH
+
+/// \file
+///
+/// \brief Estimate the font color.
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+
+# include <mln/labeling/blobs.hh>
+# include <mln/accu/stat/mean.hh>
+# include <mln/value/next.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/def/lbl_type.hh>
+# include <scribo/estim/internal/compute_skeleton.hh>
+
+
+namespace scribo
+{
+
+ namespace estim
+ {
+
+ using namespace mln;
+
+ /// \brief Estimate the font color.
+ //
+ template <typename I>
+ float
+ font_boldness(const Image<I>& text_ima);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+
+ template <typename I, typename J>
+ float
+ boldness_from_lbl(const Image<I>& ima_lbl_,
+ const Image<J>& skel_)
+ {
+ trace::entering("scribo::estim::internal::boldness_from_lbl");
+
+ const I& ima_lbl = exact(ima_lbl_);
+ const J& skel = exact(skel_);
+ mln_precondition(ima_lbl.is_valid());
+ mln_precondition(skel.is_valid());
+
+ mln_piter(I) p(ima_lbl.domain());
+ int skel_p = 0, ima_p = 0;
+
+ for_all(p)
+ {
+ if (skel(p))
+ ++skel_p;
+
+ if (ima_lbl(p))
+ ++ima_p;
+ }
+
+ float res = ima_p / (float) skel_p;
+
+ trace::exiting("scribo::estim::internal::boldness_from_lbl");
+ return res;
+ }
+
+
+ // FIXME: this version is invalid!!! It supposes that image and
+ // skeleton labeling associate the same id to a component and
+ // its corresponding skeleton. This is wrong!
+ template <typename I, typename J>
+ float
+ boldness_from_lbl(const Image<I>& ima_lbl_,
+ const mln_value(I)& nlabels,
+ const Image<J>& skel_lbl_)
+ {
+ trace::entering("scribo::estim::internal::boldness_from_lbl");
+
+ const I& ima_lbl = exact(ima_lbl_);
+ const J& skel_lbl = exact(skel_lbl_);
+ mln_precondition(ima_lbl.is_valid());
+ mln_precondition(skel_lbl.is_valid());
+
+ mln_piter(I) p(ima_lbl.domain());
+ std::vector<int> skel_p(value::next(nlabels), 0);
+ std::vector<int> ima_p(value::next(nlabels), 0);
+
+ for_all(p)
+ {
+ int val = skel_lbl(p);
+
+ if (val)
+ ++skel_p[val];
+
+ val = ima_lbl(p);
+
+ if (val)
+ ++ima_p[val];
+ }
+
+ accu::stat::mean<float> mean;
+ for_all_ncomponents(i, nlabels)
+ mean.take(ima_p[i] / skel_p[i]);
+
+ // double variance = 0.;
+ // for (unsigned int i = 0; i < nlabels; ++i)
+ // variance += ((ima_p[i] / skel_p[i]) - mean.to_result()) * ((ima_p[i] / skel_p[i]) - mean.to_result());
+
+ // variance /= nlabels;
+
+ trace::exiting("scribo::estim::internal::boldness_from_lbl");
+ return mean.to_result();
+ }
+
+ } // end of namespace scribo::estim::internal
+
+
+ // IMPLEMENTATIONS
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I>
+ float
+ font_boldness(const Image<I>& ima_)
+ {
+ trace::entering("scribo::estim::impl::generic::font_boldness");
+
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+ mlc_is(mln_value(I), bool)::check();
+
+ typedef scribo::def::lbl_type V;
+ typedef mln_ch_value(I,V) L;
+
+ mln_concrete(I) skel = internal::compute_skeleton(ima);
+
+ V nslabels;
+ L slbl = labeling::blobs(skel, c8(), nslabels);
+
+ V nlabels;
+ L lbl = labeling::blobs(ima, c8(), nlabels);
+
+ float
+ output = internal::boldness_from_lbl(lbl, nlabels, slbl);
+
+ trace::exiting("scribo::estim::impl::generic::font_boldness");
+ return output;
+ }
+
+ } // end of namespace scribo::estim::generic::impl
+
+ } // end of namespace scribo::estim::impl
+
+
+
+ // FACADE
+
+ template <typename I>
+ float
+ font_boldness(const Image<I>& ima)
+ {
+ trace::entering("scribo::estim::font_boldness");
+
+ mln_precondition(exact(ima).is_valid());
+ mlc_is(mln_value(I), bool)::check();
+
+ float output = impl::generic::font_boldness(ima);
+
+ trace::exiting("scribo::estim::font_boldness");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::estim
+
+} // end of namespace scribo
+
+# endif // ! SCRIBO_ESTIM_FONT_BOLDNESS_HH
+
+
+
diff --git a/scribo/scribo/estim/font_color.hh b/scribo/scribo/estim/font_color.hh
new file mode 100644
index 0000000..9a3c429
--- /dev/null
+++ b/scribo/scribo/estim/font_color.hh
@@ -0,0 +1,206 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_ESTIM_FONT_COLOR_HH
+# define SCRIBO_ESTIM_FONT_COLOR_HH
+
+/// \file
+///
+/// \brief Estimate the font color.
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/value/int_u8.hh>
+# include <mln/labeling/compute.hh>
+# include <mln/accu/stat/mean.hh>
+# include <mln/accu/stat/median_h.hh>
+# include <mln/value/int_u12.hh>
+# include <mln/value/rgb8.hh>
+
+# include <scribo/estim/internal/compute_skeleton.hh>
+
+
+namespace scribo
+{
+
+ namespace estim
+ {
+
+ using namespace mln;
+
+ /// \brief Estimate the font color.
+ //
+ template <typename I, typename J>
+ mln_value(I)
+ font_color(const Image<I>& text_ima, const Image<J>& bin_text_ima);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I, typename J>
+ mln_value(I)
+ font_color_rgb(const Image<I>& text_ima_,
+ const Image<J>& bin_text_ima_)
+ {
+ trace::entering("scribo::estim::impl::font_color_rgb");
+
+ typedef mln_value(I) V1;
+ typedef mln_value(J) V2;
+ //mlc_is(V1, value::rgb)::check();
+ mlc_is(V2, bool)::check();
+
+ const I& text_ima = exact(text_ima_);
+ const J& bin_text_ima = exact(bin_text_ima_);
+
+ mln_concrete(J) skel = internal::compute_skeleton(bin_text_ima);
+
+ value::int_u8 nlabels = 0;
+ mln_ch_value(I,value::int_u8)
+ lbl = labeling::blobs(skel, c8(), nlabels);
+
+ util::array<algebra::vec<3u, float> > res =
+ labeling::compute(accu::meta::stat::mean(), text_ima, lbl, nlabels);
+
+ accu::stat::median_h<value::int_u12> m_red;
+ accu::stat::median_h<value::int_u12> m_green;
+ accu::stat::median_h<value::int_u12> m_blue;
+ m_red.init();
+ m_green.init();
+ m_blue.init();
+
+ mln_value(I) med_rgb;
+
+ for (unsigned int i = 1; i <= nlabels; ++i)
+ {
+ m_red.take(res[i][0]);
+ m_green.take(res[i][1]);
+ m_blue.take(res[i][2]);
+ }
+
+ med_rgb.red() = m_red.to_result();
+ med_rgb.green() = m_green.to_result();
+ med_rgb.blue() = m_blue.to_result();
+
+ trace::exiting("scribo::estim::impl::font_color_rgb");
+ return med_rgb;
+ }
+
+
+ template <typename I, typename J>
+ mln_value(I)
+ font_color_grayscale(const Image<I>& text_ima_,
+ const Image<J>& bin_text_ima_)
+ {
+ trace::entering("scribo::estim::impl::font_color_grayscale");
+
+ typedef mln_value(I) V1;
+ typedef mln_value(J) V2;
+ //mlc_is(V1, value::rgb)::check();
+ mlc_is(V2, bool)::check();
+
+ const I& text_ima = exact(text_ima_);
+ const J& bin_text_ima = exact(bin_text_ima_);
+
+ mln_concrete(J) skel = internal::compute_skeleton(bin_text_ima);
+
+ value::int_u8 nlabels = 0;
+ mln_ch_value(J,value::int_u8) lbl = labeling::blobs(skel, c8(), nlabels);
+
+ util::array<algebra::vec<3u, float> > res =
+ labeling::compute(accu::meta::stat::mean(), text_ima, lbl, nlabels);
+
+ accu::stat::median_h<value::int_u12> m_val;
+ m_val.init();
+
+ mln_value(I) med_val;
+ for (unsigned int i = 1; i <= nlabels; ++i)
+ m_val.take(res[i][0]);
+
+ med_val = m_val.to_result();
+
+ trace::exiting("scribo::estim::impl::font_color_grayscale");
+ return med_val;
+ }
+
+ } // end of namespace scribo::estim::impl
+
+
+ // DISPATCH
+
+ namespace internal
+ {
+
+ template <typename I, typename J>
+ mln_value(I)
+ font_color_dispatch(const value::rgb8&,
+ const Image<I>& text_ima, const Image<J>& bin_text_ima)
+ {
+ return impl::font_color_rgb(exact(text_ima), exact(bin_text_ima));
+ }
+
+
+ template <typename V, typename I, typename J>
+ mln_value(I)
+ font_color_dispatch(const V&,
+ const Image<I>& text_ima, const Image<J>& bin_text_ima)
+ {
+ return impl::font_color_grayscale(exact(text_ima), exact(bin_text_ima));
+ }
+
+
+ template <typename I, typename J>
+ mln_value(I)
+ font_color_dispatch(const Image<I>& text_ima, const Image<J>& bin_text_ima)
+ {
+ return font_color_dispatch(mln_value(I)(), text_ima, bin_text_ima);
+ }
+
+ } // end of namespace scribo::estim::internal
+
+
+ // FACADE
+
+ template <typename I, typename J>
+ mln_value(I)
+ font_color(const Image<I>& text_ima, const Image<J>& bin_text_ima)
+ {
+ trace::entering("scribo::estim::font_color");
+
+ mln_value(I) output = internal::font_color_dispatch(text_ima, bin_text_ima);
+
+ trace::exiting("scribo::estim::font_color");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::estim
+
+} // end of namespace scribo
+
+# endif // ! SCRIBO_ESTIM_FONT_COLOR_HH
diff --git a/scribo/scribo/estim/internal/compute_skeleton.hh b/scribo/scribo/estim/internal/compute_skeleton.hh
new file mode 100644
index 0000000..52ecf01
--- /dev/null
+++ b/scribo/scribo/estim/internal/compute_skeleton.hh
@@ -0,0 +1,112 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_ESTIM_INTERNAL_COMPUTE_SKELETON_HH
+# define SCRIBO_ESTIM_INTERNAL_COMPUTE_SKELETON_HH
+
+/// \file
+///
+/// \brief Compute a skeleton useful for font estimations.
+
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/topo/skeleton/crest.hh>
+# include <mln/topo/skeleton/is_simple_point.hh>
+# include <mln/transform/distance_front.hh>
+# include <mln/logical/not.hh>
+# include <mln/make/w_window2d_int.hh>
+# include <mln/value/int_u8.hh>
+# include <mln/arith/revert.hh>
+# include <mln/morpho/skeleton_constrained.hh>
+# include <mln/core/routine/extend.hh>
+# include <mln/labeling/blobs.hh>
+# include <mln/accu/stat/mean.hh>
+# include <mln/value/rgb8.hh>
+
+
+namespace scribo
+{
+
+ namespace estim
+ {
+
+ namespace internal
+ {
+ using namespace mln;
+
+
+ /// \brief Compute a skeleton useful for font estimations.
+ //
+ template <typename I>
+ mln_concrete(I)
+ compute_skeleton(const Image<I>& input);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I>
+ mln_concrete(I)
+ compute_skeleton(const Image<I>& input_)
+ {
+ trace::entering("scribo::estim::internal::compute_skeleton");
+
+ const I& input = exact(input_);
+ mlc_is(mln_value(I), bool)::check();
+ mln_precondition(input.is_valid());
+
+ int psi = 7;
+ int vals[] = { 0, 9, 0, 9, 0,
+ 9, 6, 4, 6, 9,
+ 0, 4, 0, 4, 0,
+ 9, 6, 4, 6, 9,
+ 0, 9, 0, 9, 0 };
+
+ mln_ch_value(I,value::int_u8)
+ dist = transform::distance_front(logical::not_(input), c8(),
+ mln::make::w_window2d_int(vals),
+ mln_max(value::int_u8));
+
+ mln_ch_value(I,value::int_u8) dist_map = arith::revert(dist);
+ mln_concrete(I) K = topo::skeleton::crest(input, dist, c8(), psi);
+
+ mln_concrete(I) skel =
+ morpho::skeleton_constrained(input, c8(),
+ topo::skeleton::is_simple_point<I,neighb2d>,
+ extend(K, false), dist_map);
+
+ trace::exiting("scribo::estim::internal::compute_skeleton");
+ return skel;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::estim::internal
+
+ } // end of namespace scribo::estim
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_ESTIM_INTERNAL_COMPUTE_SKELETON_HH
diff --git a/scribo/scribo/io/xml/internal/extended_page_xml_visitor.hh b/scribo/scribo/io/xml/internal/extended_page_xml_visitor.hh
index 44d8342..b906a4a 100644
--- a/scribo/scribo/io/xml/internal/extended_page_xml_visitor.hh
+++ b/scribo/scribo/io/xml/internal/extended_page_xml_visitor.hh
@@ -234,7 +234,10 @@ namespace scribo
<< "\" kerning=\"" << lines(fid).char_space();
// EXTENSIONS - Not officially supported
- output << "\" baseline=\"" << lines(fid).baseline()
+ // FIXME: add boldness?
+ output << "\" color=\"" << parset(p).color()
+ << "\" color_reliability=\"" << parset(p).color_reliability()
+ << "\" baseline=\"" << lines(fid).baseline()
<< "\" meanline=\"" << lines(fid).meanline()
<< "\" x_height=\"" << lines(fid).x_height()
<< "\" d_height=\"" << lines(fid).d_height()
@@ -271,6 +274,10 @@ namespace scribo
output << " <line ";
output << "id=\"" << line.id()
+ << "\" boldness=\"" << line.boldness()
+ << "\" boldness_reliability=\"" << line.boldness_reliability()
+ << "\" color=\"" << line.color()
+ << "\" color_reliability=\"" << line.color_reliability()
<< "\" txt_orientation=\"" << line.orientation()
<< "\" txt_reading_orientation=\"" << line.reading_orientation()
<< "\" txt_reading_direction=\"" << line.reading_direction()
diff --git a/scribo/scribo/io/xml/internal/full_xml_visitor.hh b/scribo/scribo/io/xml/internal/full_xml_visitor.hh
index 28f43e9..bba7691 100644
--- a/scribo/scribo/io/xml/internal/full_xml_visitor.hh
+++ b/scribo/scribo/io/xml/internal/full_xml_visitor.hh
@@ -251,20 +251,21 @@ namespace scribo
output << " <component_set nelements=\"" << comp_set.nelements()
<< "\">" << std::endl;
for_all_comps(c, comp_set)
- {
- output << " <component_info"
- << " id=\"" << comp_set(c).id()
- << "\" mass_center_x=\"" << comp_set(c).mass_center().col()
- << "\" mass_center_y=\"" << comp_set(c).mass_center().row()
- << "\" card=\"" << comp_set(c).card()
- << "\" tag=\"" << comp_set(c).tag()
- << "\" type=\"" << comp_set(c).type()
- << "\" pmin_x=\"" << comp_set(c).bbox().pmin().col()
- << "\" pmin_y=\"" << comp_set(c).bbox().pmin().row()
- << "\" pmax_x=\"" << comp_set(c).bbox().pmax().col()
- << "\" pmax_y=\"" << comp_set(c).bbox().pmax().row()
- << "\"/>" << std::endl;
- }
+ if (comp_set(c).is_valid())
+ {
+ output << " <component_info"
+ << " id=\"" << comp_set(c).id()
+ << "\" mass_center_x=\"" << comp_set(c).mass_center().col()
+ << "\" mass_center_y=\"" << comp_set(c).mass_center().row()
+ << "\" card=\"" << comp_set(c).card()
+ << "\" tag=\"" << comp_set(c).tag()
+ << "\" type=\"" << comp_set(c).type()
+ << "\" pmin_x=\"" << comp_set(c).bbox().pmin().col()
+ << "\" pmin_y=\"" << comp_set(c).bbox().pmin().row()
+ << "\" pmax_x=\"" << comp_set(c).bbox().pmax().col()
+ << "\" pmax_y=\"" << comp_set(c).bbox().pmax().row()
+ << "\"/>" << std::endl;
+ }
// Save labeled image
@@ -426,6 +427,10 @@ namespace scribo
output << " <line " << std::endl;
output << "id=\"" << line.id()
+ << "\" boldness=\"" << line.boldness()
+ << "\" boldness_reliability=\"" << line.boldness_reliability()
+ << "\" color=\"" << line.color()
+ << "\" color_reliability=\"" << line.color_reliability()
<< "\" txt_orientation=\"" << line.orientation()
<< "\" txt_reading_orientation=\"" << line.reading_orientation()
<< "\" txt_reading_direction=\"" << line.reading_direction()
diff --git a/scribo/scribo/primitive/extract/components.hh b/scribo/scribo/primitive/extract/components.hh
index 849dd7b..fe2b523 100644
--- a/scribo/scribo/primitive/extract/components.hh
+++ b/scribo/scribo/primitive/extract/components.hh
@@ -48,6 +48,7 @@
# include <mln/extension/fill.hh>
# include <scribo/core/component_set.hh>
+# include <scribo/estim/components_features.hh>
@@ -73,51 +74,64 @@ namespace scribo
///
/// \return An image of labeled components.
//
+ template <typename I, typename J, typename N, typename V>
+ inline
+ component_set<mln_ch_value(I,V)>
+ components(const Image<I>& input, const Image<J>& binary_input,
+ const Neighborhood<N>& nbh, V& ncomponents,
+ component::Type type = component::Undefined);
+
+
template <typename I, typename N, typename V>
inline
component_set<mln_ch_value(I,V)>
- components(const Image<I>& input,
+ components(const Image<I>& binary_input,
const Neighborhood<N>& nbh, V& ncomponents,
component::Type type = component::Undefined);
# ifndef MLN_INCLUDE_ONLY
-
- namespace internal
+ template <typename I, typename J, typename N, typename V>
+ inline
+ component_set<mln_ch_value(I,V)>
+ components(const Image<I>& input, const Image<J>& binary_input,
+ const Neighborhood<N>& nbh, V& ncomponents,
+ component::Type type = component::Undefined)
{
+ trace::entering("scribo::components");
- template <typename I, typename N, typename V>
- inline
- void
- components_tests(const Image<I>& input,
- const Neighborhood<N>& nbh, V& ncomponents,
- component::Type type)
- {
- mlc_equal(mln_value(I),bool)::check();
+ mlc_equal(mln_value(J),bool)::check();
// mlc_is_a(V, mln::value::Symbolic)::check();
- mln_precondition(exact(input).is_valid());
- mln_precondition(exact(nbh).is_valid());
- (void) input;
- (void) nbh;
- (void) ncomponents;
- (void) type;
- }
+ mln_precondition(exact(input).is_valid());
+ mln_precondition(exact(binary_input).is_valid());
+ mln_precondition(exact(nbh).is_valid());
+ typedef mln_ch_value(I,V) L;
+ component_set<L>
+ output = extract::components(binary_input, nbh, ncomponents, type);
- } // end of namespace scribo::primitive::extract::internal
+ output = estim::components_features(input, binary_input, output);
+
+ trace::exiting("scribo::components");
+ return output;
+ }
template <typename I, typename N, typename V>
inline
component_set<mln_ch_value(I,V)>
- components(const Image<I>& input,
+ components(const Image<I>& binary_input,
const Neighborhood<N>& nbh, V& ncomponents,
component::Type type = component::Undefined)
{
trace::entering("scribo::components");
- internal::components_tests(input, nbh, ncomponents, type);
+ mlc_equal(mln_value(I),bool)::check();
+// mlc_is_a(V, mln::value::Symbolic)::check();
+ mln_precondition(exact(binary_input).is_valid());
+ mln_precondition(exact(nbh).is_valid());
+
typedef mln_ch_value(I,V) L;
typedef mln::accu::shape::bbox<mln_site(L)> bbox_accu_t;
@@ -125,14 +139,15 @@ namespace scribo
typedef mln::accu::pair<bbox_accu_t, center_accu_t> pair_accu_t;
// Setting extension value.
- extension::fill(input, 0);
+ extension::fill(binary_input, false);
mln::util::couple<L,
- mln::util::couple<mln::util::array<mln_result(pair_accu_t)>,
- mln::util::array<pair_accu_t> > >
-
- results = labeling::value_and_compute(input, true, nbh, ncomponents,
- pair_accu_t());
+ mln::util::couple<
+ mln::util::array<mln_result(pair_accu_t)>,
+ mln::util::array<pair_accu_t> > >
+ results = labeling::value_and_compute(binary_input, true, nbh,
+ ncomponents,
+ pair_accu_t());
component_set<L>
output(results.first(), ncomponents, results.second().second(), type);
@@ -141,6 +156,7 @@ namespace scribo
return output;
}
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::primitive::extract
diff --git a/scribo/scribo/text/extract_lines.hh b/scribo/scribo/text/extract_lines.hh
index 53fd742..3e9254a 100644
--- a/scribo/scribo/text/extract_lines.hh
+++ b/scribo/scribo/text/extract_lines.hh
@@ -81,6 +81,12 @@ namespace scribo
extract_lines(const Image<I>& input, const Neighborhood<N>& nbh);
+ /// \overload
+ template <typename L>
+ line_set<mln_ch_value(L,scribo::def::lbl_type)>
+ extract_lines(const component_set<L>& input);
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -119,6 +125,22 @@ namespace scribo
if (exact(separators).is_valid())
comps.add_separators(separators);
+ line_set<mln_ch_value(I,scribo::def::lbl_type)>
+ lines = extract_lines(comps);
+
+ trace::exiting("scribo::text::extract_lines");
+ return lines;
+ }
+
+
+ template <typename L>
+ line_set<mln_ch_value(L,scribo::def::lbl_type)>
+ extract_lines(const component_set<L>& comps)
+ {
+ trace::entering("scribo::text::extract_lines");
+
+ mln_precondition(comps.is_valid());
+
/// Linking potential comps
object_links<L>
left_link = primitive::link::with_single_left_link_dmax_ratio(
diff --git a/scribo/scribo/text/extract_lines_with_features.hh b/scribo/scribo/text/extract_lines_with_features.hh
new file mode 100644
index 0000000..fd413eb
--- /dev/null
+++ b/scribo/scribo/text/extract_lines_with_features.hh
@@ -0,0 +1,131 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_TEXT_EXTRACT_LINES_WITH_FEATURES_HH
+# define SCRIBO_TEXT_EXTRACT_LINES_WITH_FEATURES_HH
+
+/// \file
+///
+/// Extract line of text bounding boxes.
+
+
+# include <mln/core/concept/image.hh>
+
+# include <scribo/text/extract_lines.hh>
+
+
+namespace scribo
+{
+
+ namespace text
+ {
+
+ using namespace mln;
+
+ /// Extract lines of text in a binary image.
+ /*!
+ ** \param[in] input Original color image.
+ ** \param[in] input_binary A binary image.
+ ** \param[in] nbh A neighborhood used for labeling.
+ ** \param[in] separators A binary image with separator information.
+ **
+ ** \return A set of lines.
+ */
+ template <typename I, typename J, typename N>
+ line_set<mln_ch_value(I,scribo::def::lbl_type)>
+ extract_lines_with_features(const Image<I>& input,
+ const Image<J>& input_binary,
+ const Neighborhood<N>& nbh,
+ const mln_ch_value(I,bool)& separators);
+
+
+ /// \overload
+ template <typename I, typename J, typename N>
+ line_set<mln_ch_value(I,scribo::def::lbl_type)>
+ extract_lines_with_features(const Image<I>& input,
+ const Image<J>& input_binary,
+ const Neighborhood<N>& nbh);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I, typename J, typename N>
+ line_set<mln_ch_value(I,scribo::def::lbl_type)>
+ extract_lines_with_features(const Image<I>& input,
+ const Image<J>& input_binary,
+ const Neighborhood<N>& nbh)
+ {
+ mln_ch_value(I,bool) seps;
+ return extract_lines_with_features(input, input_binary, nbh, seps);
+ }
+
+
+ template <typename I, typename J, typename N>
+ line_set<mln_ch_value(I,scribo::def::lbl_type)>
+ extract_lines_with_features(const Image<I>& input_,
+ const Image<J>& input_binary_,
+ const Neighborhood<N>& nbh_,
+ const mln_ch_value(I,bool)& separators)
+ {
+ trace::entering("scribo::text::extract_lines_with_features");
+
+ const I& input = exact(input_);
+ const J& input_binary = exact(input_binary_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(input_binary.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ /// Finding comps.
+ typedef mln_ch_value(I,scribo::def::lbl_type) L;
+ scribo::def::lbl_type ncomps;
+ component_set<L>
+ comps = scribo::primitive::extract::components(input, input_binary,
+ nbh, ncomps);
+
+ /// First filtering.
+ comps = scribo::filter::components_small(comps, 3);
+
+ /// Use separators.
+ if (exact(separators).is_valid())
+ comps.add_separators(separators);
+
+ line_set<mln_ch_value(I,scribo::def::lbl_type)>
+ lines = extract_lines(comps);
+
+ trace::exiting("scribo::text::extract_lines_with_features");
+ return lines;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::text
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_TEXT_EXTRACT_LINES_WITH_FEATURES_HH
diff --git a/scribo/scribo/toolchain/internal/content_in_doc_functor.hh b/scribo/scribo/toolchain/internal/content_in_doc_functor.hh
index 624a54e..0a920a6 100644
--- a/scribo/scribo/toolchain/internal/content_in_doc_functor.hh
+++ b/scribo/scribo/toolchain/internal/content_in_doc_functor.hh
@@ -254,7 +254,8 @@ namespace scribo
V ncomponents;
component_set<L>
- components = scribo::primitive::extract::components(input_cleaned,
+ components = scribo::primitive::extract::components(original_image,
+ input_cleaned,
c8(),
ncomponents);
diff --git a/scribo/src/debug/Makefile.am b/scribo/src/debug/Makefile.am
index 60d7afa..be8bb78 100644
--- a/scribo/src/debug/Makefile.am
+++ b/scribo/src/debug/Makefile.am
@@ -22,6 +22,7 @@ noinst_PROGRAMS = \
show_groups_bboxes \
show_info_x_height \
show_info_median_inter_characters \
+ show_lines_boldness \
show_separators \
show_links_left_right_links_validation \
show_links_bbox_h_ratio \
@@ -54,6 +55,7 @@ show_components_bboxes_SOURCES = show_components_bboxes.cc
show_groups_bboxes_SOURCES = show_groups_bboxes.cc
show_info_x_height_SOURCES = show_info_x_height.cc
show_info_median_inter_characters_SOURCES = show_info_median_inter_characters.cc
+show_lines_boldness_SOURCES = show_lines_boldness.cc
show_separators_SOURCES = show_separators.cc
show_links_left_right_links_validation_SOURCES = show_links_left_right_links_validation.cc
show_links_bbox_h_ratio_SOURCES = show_links_bbox_h_ratio.cc
@@ -83,6 +85,20 @@ show_objects_thin_SOURCES = show_objects_thin.cc
if HAVE_MAGICKXX
+ noinst_PROGRAMS += show_components_color
+ show_components_color_SOURCES = show_components_color.cc
+ show_components_color_CPPFLAGS = $(AM_CPPFLAGS) \
+ $(MAGICKXX_CPPFLAGS)
+ show_components_color_LDFLAGS = $(AM_LDFLAGS) \
+ $(MAGICKXX_LDFLAGS)
+
+ noinst_PROGRAMS += show_components_boldness
+ show_components_boldness_SOURCES = show_components_boldness.cc
+ show_components_boldness_CPPFLAGS = $(AM_CPPFLAGS) \
+ $(MAGICKXX_CPPFLAGS)
+ show_components_boldness_LDFLAGS = $(AM_LDFLAGS) \
+ $(MAGICKXX_LDFLAGS)
+
if HAVE_QT
noinst_PROGRAMS += show_paragraph_blocks
diff --git a/scribo/src/debug/show_components_boldness.cc b/scribo/src/debug/show_components_boldness.cc
new file mode 100644
index 0000000..f9aca3f
--- /dev/null
+++ b/scribo/src/debug/show_components_boldness.cc
@@ -0,0 +1,72 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+#include <mln/pw/all.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/io/magick/load.hh>
+#include <mln/value/int_u.hh>
+#include <mln/literal/colors.hh>
+#include <mln/draw/box.hh>
+
+#include <scribo/core/component_set.hh>
+#include <scribo/primitive/extract/components.hh>
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+ using namespace scribo;
+
+ if (argc != 4)
+ {
+ std::cerr << "Usage : " << argv[0] << " input.* input.pbm out.pgm" << std::endl;
+ return 1;
+ }
+
+ Magick::InitializeMagick(0);
+
+ typedef mln::value::int_u<30> V;
+ typedef image2d<V> L;
+
+ image2d<value::rgb8> input;
+ io::magick::load(input, argv[1]);
+
+ image2d<bool> input_bin;
+ io::pbm::load(input_bin, argv[2]);
+
+ V ncomponents;
+ component_set<L>
+ components = scribo::primitive::extract::components(input, input_bin, c8(),
+ ncomponents);
+
+ image2d<value::int_u8> output;
+ initialize(output, input);
+ data::fill(output, 0);
+
+ const L& lbl = components.labeled_image();
+ for_all_comps(c, components)
+ if (components(c).is_valid())
+ {
+ data::fill(((output | components(c).bbox()).rw()
+ | (pw::value(lbl) == pw::cst(c))).rw(),
+ components(c).features().boldness);
+ }
+
+ io::pgm::save(output, argv[3]);
+}
diff --git a/scribo/src/debug/show_components_color.cc b/scribo/src/debug/show_components_color.cc
new file mode 100644
index 0000000..a13b85b
--- /dev/null
+++ b/scribo/src/debug/show_components_color.cc
@@ -0,0 +1,73 @@
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+#include <mln/pw/all.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/io/magick/load.hh>
+#include <mln/value/int_u.hh>
+#include <mln/literal/colors.hh>
+#include <mln/draw/box.hh>
+
+#include <scribo/core/component_set.hh>
+#include <scribo/primitive/extract/components.hh>
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+ using namespace scribo;
+
+ if (argc != 4)
+ {
+ std::cerr << "Usage : " << argv[0] << " input.* input.pbm out.ppm" << std::endl;
+ return 1;
+ }
+
+ Magick::InitializeMagick(0);
+
+ typedef mln::value::int_u<30> V;
+ typedef image2d<V> L;
+
+ image2d<value::rgb8> input;
+ io::magick::load(input, argv[1]);
+
+ image2d<bool> input_bin;
+ io::pbm::load(input_bin, argv[2]);
+
+ V ncomponents;
+ component_set<L>
+ components = scribo::primitive::extract::components(input, input_bin, c8(),
+ ncomponents);
+
+ image2d<value::rgb8> output;
+ initialize(output, input);
+ data::fill(output, literal::white);
+
+ const L& lbl = components.labeled_image();
+ for_all_comps(c, components)
+ if (components(c).is_valid())
+ {
+ data::fill(((output | components(c).bbox()).rw()
+ | (pw::value(lbl) == pw::cst(c))).rw(),
+ components(c).features().color);
+ }
+
+ io::ppm::save(output, argv[3]);
+}
diff --git a/scribo/src/debug/show_lines_boldness.cc b/scribo/src/debug/show_lines_boldness.cc
new file mode 100644
index 0000000..a3815c0
--- /dev/null
+++ b/scribo/src/debug/show_lines_boldness.cc
@@ -0,0 +1,199 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <iostream>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/value/int_u16.hh>
+#include <mln/draw/box_plain.hh>
+#include <mln/pw/all.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+#include <mln/data/convert.hh>
+#include <mln/literal/colors.hh>
+
+#include <scribo/text/recognition.hh>
+
+#include <scribo/debug/usage.hh>
+
+#include <scribo/core/document.hh>
+#include <scribo/core/component_set.hh>
+#include <scribo/core/object_links.hh>
+#include <scribo/core/object_groups.hh>
+
+#include <scribo/text/extract_lines_with_features.hh>
+#include <scribo/estim/components_features.hh>
+
+#include <scribo/io/xml/save.hh>
+
+
+const char *args_desc[][2] =
+{
+ {0, 0}
+};
+
+
+
+int main(int argc, char* argv[])
+{
+ using namespace scribo;
+ using namespace mln;
+
+ if (argc != 3)
+ return scribo::debug::usage(argv,
+ "Show text lines",
+ "input.pbm out_prefix",
+ args_desc);
+
+ trace::entering("main");
+
+ image2d<bool> input;
+ mln::io::pbm::load(input, argv[1]);
+
+ std::string prefix = argv[2];
+
+ typedef image2d<scribo::def::lbl_type> L;
+
+ // Extract lines
+ line_set<L>
+ lines = text::extract_lines_with_features(
+ data::convert(value::rgb8(), input), input, c8());
+ const component_set<L>& comp_set = lines.components();
+
+ mln::math::round<unsigned> round;
+
+ // Min boldness / line
+ {
+ image2d<value::int_u8> min_boldness;
+ initialize(min_boldness, input);
+
+ data::fill(min_boldness, 0);
+ for_all_lines(l, lines)
+ if (lines(l).is_textline())
+ {
+ float min = 65000;
+
+ // Compute min
+ for_all_line_comps(cid, lines(l).component_ids())
+ {
+ unsigned id = lines(l).component_ids()(cid);
+ if (comp_set(id).features().boldness < min)
+ min = comp_set(id).features().boldness;
+ }
+
+ // Draw
+ for_all_line_comps(cid, lines(l).component_ids())
+ {
+ unsigned id = lines(l).component_ids()(cid);
+ data::fill(((min_boldness | comp_set(id).bbox()).rw()
+ | (pw::value(comp_set.labeled_image()) == pw::cst(id))).rw(), round(min));
+ }
+
+ }
+
+ mln::io::pgm::save(min_boldness, prefix + "_min_boldness.pgm");
+ }
+
+ // Max boldness / line
+ {
+ image2d<value::int_u8> max_boldness;
+ initialize(max_boldness, input);
+
+ data::fill(max_boldness, 0);
+ for_all_lines(l, lines)
+ if (lines(l).is_textline())
+ {
+ float max = 65000;
+
+ // Compute max
+ for_all_line_comps(cid, lines(l).component_ids())
+ {
+ unsigned id = lines(l).component_ids()(cid);
+ if (comp_set(id).features().boldness < max)
+ max = comp_set(id).features().boldness;
+ }
+
+ // Draw
+ for_all_line_comps(cid, lines(l).component_ids())
+ {
+ unsigned id = lines(l).component_ids()(cid);
+ data::fill(((max_boldness | comp_set(id).bbox()).rw()
+ | (pw::value(comp_set.labeled_image()) == pw::cst(id))).rw(), round(max));
+ }
+
+ }
+
+ mln::io::pgm::save(max_boldness, prefix + "_max_boldness.pgm");
+ }
+
+
+ // Mean boldness / line
+ {
+ image2d<value::int_u8> min_boldness;
+ initialize(min_boldness, input);
+
+ data::fill(min_boldness, 0);
+ for_all_lines(l, lines)
+ if (lines(l).is_textline())
+ {
+ // Draw
+ for_all_line_comps(cid, lines(l).component_ids())
+ {
+ unsigned id = lines(l).component_ids()(cid);
+ data::fill(((min_boldness | comp_set(id).bbox()).rw()
+ | (pw::value(comp_set.labeled_image()) == pw::cst(id))).rw(), round(lines(l).boldness()));
+ }
+
+ }
+
+ mln::io::pgm::save(min_boldness, prefix + "_mean_boldness.pgm");
+ }
+
+ // Stddev boldness / line
+ {
+ image2d<value::int_u8> min_boldness;
+ initialize(min_boldness, input);
+
+ data::fill(min_boldness, 0);
+ for_all_lines(l, lines)
+ if (lines(l).is_textline())
+ {
+ // Draw
+ for_all_line_comps(cid, lines(l).component_ids())
+ {
+ unsigned id = lines(l).component_ids()(cid);
+ data::fill(((min_boldness | comp_set(id).bbox()).rw()
+ | (pw::value(comp_set.labeled_image()) == pw::cst(id))).rw(), round(lines(l).boldness_reliability()));
+ }
+
+ }
+
+ mln::io::pgm::save(min_boldness, prefix + "_stddev_boldness.pgm");
+ }
+
+
+ trace::exiting("main");
+}
+
diff --git a/scribo/tests/Makefile.am b/scribo/tests/Makefile.am
index 09768b1..1f227b7 100644
--- a/scribo/tests/Makefile.am
+++ b/scribo/tests/Makefile.am
@@ -1,5 +1,5 @@
-# Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-# (LRDE).
+# Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+# Laboratory (LRDE).
#
# This file is part of Olena.
#
@@ -31,6 +31,7 @@ SUBDIRS = \
binarization \
convert \
core \
+ estim \
filter \
preprocessing \
primitive \
diff --git a/scribo/tests/estim/Makefile.am b/scribo/tests/estim/Makefile.am
new file mode 100644
index 0000000..1c39ab6
--- /dev/null
+++ b/scribo/tests/estim/Makefile.am
@@ -0,0 +1,29 @@
+# Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+#
+
+## Process this file through Automake to create Makefile.in.
+
+include $(top_srcdir)/scribo/tests/tests.mk
+
+check_PROGRAMS = \
+ font_color \
+ font_boldness
+
+font_color_SOURCES = font_color.cc
+font_boldness_SOURCES = font_boldness.cc
+
+TESTS = $(check_PROGRAMS)
diff --git a/scribo/tests/estim/font_boldness.cc b/scribo/tests/estim/font_boldness.cc
new file mode 100644
index 0000000..9e85795
--- /dev/null
+++ b/scribo/tests/estim/font_boldness.cc
@@ -0,0 +1,46 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE).
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
+/// \file
+
+#include <cstdio>
+#include <cstdlib>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/data/compare.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/pbm/load.hh>
+
+#include <mln/value/rgb8.hh>
+
+#include <scribo/estim/font_boldness.hh>
+
+#include "tests/data.hh"
+
+using namespace mln;
+
+int main()
+{
+ image2d<bool> input;
+ io::pbm::load(input, SCRIBO_IMG_DIR "/phillip.pbm");
+
+ float val = scribo::estim::font_boldness(input);
+
+ mln_assertion(((int)(val * 100) / 100.f) == 18.44f);
+
+ return 0;
+}
diff --git a/scribo/tests/estim/font_color.cc b/scribo/tests/estim/font_color.cc
new file mode 100644
index 0000000..45c453d
--- /dev/null
+++ b/scribo/tests/estim/font_color.cc
@@ -0,0 +1,48 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE).
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
+/// \file
+
+#include <cstdio>
+#include <cstdlib>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/data/compare.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/pbm/load.hh>
+
+#include <mln/value/rgb8.hh>
+
+#include <scribo/estim/font_color.hh>
+
+#include "tests/data.hh"
+
+using namespace mln;
+
+int main()
+{
+ image2d<value::rgb8> input_rgb;
+ io::ppm::load(input_rgb, SCRIBO_IMG_DIR "/phillip.ppm");
+ image2d<bool> input_bin;
+ io::pbm::load(input_bin, SCRIBO_IMG_DIR "/phillip.pbm");
+
+ value::rgb8 val = scribo::estim::font_color(input_rgb, input_bin);
+
+ mln_assertion(val == value::rgb8(77, 146, 140));
+
+ return 0;
+}
diff --git a/scribo/tests/img/phillip.pbm b/scribo/tests/img/phillip.pbm
new file mode 100644
index 0000000000000000000000000000000000000000..ed60f945bbe7a0bf176fcb69695be9ed2ab9ac47
GIT binary patch
literal 1633
zcmdth&x#W<90%}(912C4M@YbnUb-&G`sZK}b`fEPW$^)=wIjPw+fs|TAZGT>=27As
z<d{Qj{Qi=ecE(mudND&v=ab+3GWlh4@pyb+y{hKbs$5r7b#<%W+{~(Zsg5U)l)7H8
zm(P!m79^9|YFbUI<;}XBd|2VBvy0bnU#iRMQ&q0sU#oIHRj1YGYPMK@tmbQVUS2Jb
zbg{Zs56&-7&mNACpPZ<ZXXE&vwI6%y@g_zay$L$V-Jpdw#u}?#k=3&zHuzg>xOSsX
z`9WnnHM>}5+6>6usbfsnDQ|s18$;^bcW_0WVr?Yt-q*=S-=){7;a#)RN}g`+`l^4U
zI>+*1tQJlq2al9LYy^I-wpuiW<xn1&ww|7Zz7RF3h}<*XEE%+cGB#>Bo=p0V8LDgZ
zZJ;b`om6aac~q)Z_LY4Zks(KIno&&|p0dC^DLUno4YXz~@BpDss<ZNt<QEmB`NEo!
zIb|rq$fF1Jo@$?zMo5u6M#iEqNQN4BTA*q<78OFQ3>05b-BO06PSOZAxYZ4*B&D7;
zMyw~goeESLJ3UaDE3{QjSzOk;R<+Yk;^WPVnF8`+>-q}8Dtn5$Q9bvRYPVJ6@L@R#
z6TZ`Qe5`QTlfda1Q9QQAU`Em+Fea%oeML2JAhsHD1QDCmw2Gr;jT1g87SU_@o%}sa
fwAZ>rG#qepc%Se7g6czg?Y~lUXtwW%@K5#=Ut6W*
literal 0
HcmV?d00001
diff --git a/scribo/tests/img/phillip.ppm b/scribo/tests/img/phillip.ppm
new file mode 100644
index 0000000..d668fcf
--- /dev/null
+++ b/scribo/tests/img/phillip.ppm
@@ -0,0 +1,5 @@
+P6
+# CREATOR: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2)
+176 69
+255
+ýõóýôóýõñüóñýõòýõôýõóþõóÿøöÿùöÿù÷ÿùöÿ÷ôÿöôÿøôÿ÷ôÿøôÿùõÿùôÿùôÿùöÿù÷ÿøöÿ÷öÿøöÿú÷ÿúøÿúøÿùøÿúøÿúøÿùøÿù÷ÿüùÿüùÿû÷þøõýöôþ÷öÿùøÿù÷ÿúøÿûøÿûøÿûøÿýúÿýûÿþüÿþüÿþýÿþüÿýûÿþüÿþýÿÿþÿÿþÿÿýÿÿýÿþýÿþûÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþþþýýüûÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþöóþõóýõñüôñýõòýõôýöôýöóÿøöÿùöÿùöÿøöÿøõÿøôþøôþ÷ôÿùôþøõþøóþ÷óÿùöÿù÷þøöþ÷õÿ÷õÿùõÿùöÿùöÿù÷ÿúøÿúøÿùøÿùøÿüøÿûøÿüøþúöýøöþø÷ÿúùÿúøÿúøÿúøþù÷ýöôÿúøÿûúÿþýÿþüÿýûÿýúÿýûÿþüÿþüÿýûÿÿþÿÿýÿÿýÿþýÿþüÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿþþÿþýÿþýÿþýÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýöóþôóþöóþöóþøõþ÷õýöóýõôÿ÷öÿúöÿù÷ÿøöÿøöÿ÷ôþøõþ÷õÿùöþ÷õþ÷óýöóÿøõÿú÷þùöþøôþ÷ôÿ÷õÿú÷ÿúøÿûùÿûùÿûùÿúùÿúùÿûøÿûøÿüùÿüùÿûøÿúøÿúùÿúùÿûøÿúøþù÷ý÷öÿúùÿüûÿþûÿþüÿýúÿýúÿýúÿýúÿüúÿûúÿþýÿþýÿÿýÿÿýÿÿýÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿþÿþþÿþýÿþýÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿþýÿþýÿþýÿýýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿþþÿþþÿÿÿÿÿÿÿþþÿþþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþýöôþöôþ÷ôÿ÷óÿù÷ÿù÷þøõþ÷õÿ÷õÿùöÿù÷ÿùöÿøöÿ÷õþøõþ÷ôÿøõÿùöþùõý÷ôÿ÷öÿú÷þù÷þ÷õþ÷õÿùøÿüúÿüúÿüúÿûúÿûúÿúùÿúøÿù÷ÿûùÿüùÿú÷ÿúøÿúøÿûùÿüùÿüùÿûúÿüúÿûùÿüûÿþüÿýûÿýûÿýúÿûùÿûùÿûùÿûùÿúùÿüûÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿþÿÿýÿÿýÿÿþÿþþÿþþÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿýýÿýþÿþþÿþþÿþþþþýþþþÿþþÿþþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþþ÷õþöõþøôÿöóÿùöÿù÷ÿùöÿøõÿøõÿùöÿù÷ÿù÷ÿøöÿùõþøôþöóÿùôÿùöÿúöÿùöÿùøÿûøþúøþ÷õþøõÿù÷ÿúùÿûøÿúøÿùøÿùøþøöþøöÿù÷ÿûùÿüùÿú÷ÿúøÿûøÿýúÿýùÿýùÿþüÿþüÿýûÿýüÿþüÿýûÿþûÿýúÿûùÿûùÿûùÿûùÿüúÿüûÿþýÿþýÿÿýÿÿýÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿýýÿûýÿþþþþþþýýþýýþûûÿýþÿþþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿþõóÿ÷ôÿùôÿ÷ôÿùöÿùöÿùöÿùöÿøõÿùõÿù÷ÿøöÿøöÿùõþùôþ÷ôÿúöÿûøÿû÷ÿúöÿøöÿúøÿùøÿøöÿøöþøöþù÷ÿú÷þø÷þø÷ÿùøþùöþù÷ÿûøÿýùÿüùÿûøÿûùÿûùÿýûÿûùÿüúÿþüÿþüÿþüÿýûÿüúÿüùÿýûÿþúþûøý÷öÿøöÿüúÿýûÿýüÿþýÿÿýÿÿýÿþýÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿþýÿÿýÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿþþÿþþÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿþþÿþþÿþþþþþýûüþûüþýýþüýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýôòþõóÿøóÿ÷ôþùöþøõþøõþøöÿ÷õÿ÷ôÿ÷õÿøöÿøõÿùõÿùõÿùöÿú÷ÿúöÿùõÿøôÿ÷õþù÷þøöÿø÷ÿù÷þù÷þù÷ÿøöþøöþø÷ÿùøÿúøÿúùÿüùÿüùÿüùÿûùÿûúÿüúÿýúÿûùÿûùÿýûÿþüÿþûÿýûÿüúÿüúÿýûÿýúþûøý÷õþøöÿýûÿýûÿþýÿþýÿýûÿýûÿþýÿþýÿÿþÿÿþÿÿýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿþþÿþýÿÿüÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþþÿÿþÿÿþÿÿþÿþþÿþþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿþþÿþþÿÿÿÿÿþÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿþþÿþýÿýýþýýüúûûúùþýýýûýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýöòüóòýõòÿöóþùöþøõþùõþøõÿöôþöóþöóÿ÷õÿ÷õÿøôÿùõÿùõÿùõÿùõþ÷óþ÷óþöôý÷ôý÷ôÿøöÿù÷ÿùöþøõþ÷ôýöôÿøöÿøøÿùøÿù÷ÿúøÿûùÿüùÿûùÿûùÿüùÿûúÿúùÿúøÿûùÿýûÿüúÿûúÿýüÿýûÿýúÿýúÿýúþüøþûøÿüùÿüùÿüøÿüöÿûõÿüúÿÿüÿÿþÿÿþÿÿþÿÿýÿþþÿþþÿþþÿþþÿþþÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿýÿÿûÿþ÷ÿúôÿøòÿü÷ÿÿüÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿÿÿþþÿþþÿþþÿþýÿýýÿþüÿüøÿúöÿøöÿýûÿÿþÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿýÿÿýÿÿþÿÿýÿÿüÿÿûÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿþÿÿýÿþüÿüùÿûõÿüôÿþøÿÿúÿÿþÿÿÿÿÿþÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþýýþûüýüüûùúûùùÿüüÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý÷óüõòüôòÿõôÿùõÿøõÿøõÿ÷ôþôòýôòþöóÿ÷õÿ÷õÿøõÿùõÿøõÿùõÿùöþùöýøôýõóûôòýöôÿù÷ÿùöþøõý÷óýöóüõóþøõþø÷ÿù÷ÿùöÿùöÿûùÿûùÿûùÿúùÿûùÿûùÿúùÿûùÿúúÿûúÿûúÿûúÿþýÿýüÿúùÿúùÿüùÿû÷ÿúóþöìýòãúìÙöäÒúïæÿûøÿýúÿþýÿÿþÿþýÿþýÿþþÿþþÿþþÿþþÿþþÿýþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿþûÿüôþøßûðË÷äË÷ÖÅûç×ÿòðÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿþþÿúúÿø÷ÿòðÿééþáÚýàÎûÞÄúßÖÿùóÿÿþÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿýÿþüÿüûÿüøÿúòÿùåÿùßÿøÓÿøêÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿþÿýûÿöîþëÕýÞÂýèœýîÓÿéÙÿûõÿþüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿþþþüýýùúýüûûøúûøùÿüüÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøõÿøôþ÷óþöóþùôþøõÿøôÿ÷óþôòýõòÿ÷õÿ÷öÿøöÿøõÿøôÿøõÿùöÿú÷ÿú÷ÿùöýöóúñïûñîþòïþõðþõðýõïýôïþóîþôðþòñþõòþõñþöòþ÷öÿøöÿøöÿø÷ÿúùÿùøÿùøÿüúÿûûÿüûÿûúÿûúÿüûÿûúÿúùþùöüôí÷ëÞðâÕäÑÆÕŹş²µ¹ŽÓÚÚüú÷ÿýúÿþýÿÿýÿþüÿþûÿþþÿþþÿÿÿÿÿþÿþþÿýþÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿþþÿýüÿÿþÿýûüôðòáÛÛÕÃŒ¶©§¶±ŠŠÉÅ»íÜÙÿùñÿþúÿÿþÿÿþÿÿþÿÿþÿÿþÿýüÿööýääùÒÍòÀÀêÉœÞÁ³Ì±¿À¯ÁÔÒðôôÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿþýþúöýìéúãäôçÛìÜÑãÚºÓͺÇɯÑËØÿüûÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿþÿýûþôïöçÔÛÍ®Á¿§³¯·ŽÓŽŽóîèÿ÷òÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿýÿÿýÿÿÿÿþþÿýýÿûýÿþýÿþþÿþþÿþþÿþýÿþýÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ôÿ÷óþ÷óýõóþøõþøôÿøôÿ÷õÿöõÿøõÿ÷õÿöõÿöôþ÷ôþ÷óÿøôÿøõÿù÷ÿøõþöóûíêöÛØôØÓ÷ÖÑ÷ßÖ÷ç×÷ê×øãÖ÷ØÏøÛÕ÷ÓÑ÷娸䨸ëÜúåâüíçþðîþõóÿøöþù÷þ÷öÿúøÿúúÿûúÿúúÿûúÿûúÿù÷þ÷ö÷ðíÞÔÌÀ³©§±Š€€|¢{¯šÀÕ×üú÷ÿþûÿþýÿþýÿþüÿþüÿÿþÿÿþÿÿÿÿÿÿÿþþÿþýÿþýÿþþÿÿþÿÿþÿÿÿÿÿþÿÿþÿþþÿþýÿþýüùôèàÓ¶°«
²šr€oªp§ªåãÃýøëÿþýÿþýÿþþÿþþÿÿýÿüúúìçäȹČ®«y|ÊÐêòöÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿþýûùóåßÖž»¹®¡³¢€x¡}µ¢§ÉÙúúúÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿþÿüúüçä뺷¹·Šr¢oi°¡v¥Š¹µæÉÇÿööÿþýÿþýÿþýÿþþÿûûÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿþþÿþýÿþýÿþþÿÿýÿþýþüüþüüÿþýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþõóÿöóþ÷óýöóÿ÷ôÿøöÿøõÿøõÿøõÿ÷ôÿöôÿöôÿöóþöóþöóÿøôÿøõÿù÷ÿøõýôïñÝØ×µ°Åµ«Ç±ªÈ»²Ì¿±É¿Èµ¯Æ¬§Èž±Ê°ªÌIJϻ®Òįڷ³åοðÖÐ÷çÚûæãþóîýöôþ÷öÿúùÿúùÿúùÿúúþúúý÷÷úñðäÛÛ¡ŽŽsY`Uer²¬ÈÜÜýûøÿþûÿýüÿýýÿþýÿþýÿþþÿþþÿýýÿýýÿþþÿýýÿýýÿþþÿþþÿþýÿÿþÿÿþÿÿþÿÿÿÿÿþþüûôðìŸËÇqQTRYY}¬Å°íìâÿüüÿþþÿþþÿþþÿþýýüúïåâž²wmbeU¡n¢ÄÔïõùÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿþþûôôàÑѬ€dZ¢i aŠag¶ªµÛâýûúÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþýúøïÞÚ·§¥m©¢UL UJ `h¥ª°·òãêýö÷ÿýýÿþýÿüûÿûûÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþýýþýüþýýÿþýÿýýþûüûùúÿûûÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýôòýôòþõóþõóþöóÿ÷õÿøôÿ÷ôÿøõÿ÷ôÿöôÿ÷õÿöôÿöóÿöóÿøõÿùöÿù÷þøöûóîâÙΡ€|}w|tz{|¡§Ž©¡ËœªâŸ¹öæÙûòðýôóý÷÷ÿ÷÷ÿ÷÷ÿøùþúúýø÷÷ìëÐÅÅx¡UFYTc¹ÙèâþûùÿþüÿýüÿüûÿþýÿþýÿþþÿþþÿýýÿýýÿþþÿýþÿþþÿþþÿþþÿþýÿÿþÿþþÿþþÿÿÿÿþýûõôßÐТ«QMWOZ
Xk
ªÍÙÖÿúûÿÿþÿþýÿþýÿýüûù÷àÝÛ§€a¡cVaYt¬ÇÕøùúÿýýÿûýÿûýÿþþÿþýÿüüùñòÍÌÉmš] XbZ`zº¡ÎååþûûÿüýÿýþÿþþÿþÿÿýþÿüüúõóÖÕΡTVS]JY ^€ÐÆÏûööÿýýÿþþÿýýÿýýÿþþÿþþÿþþÿþþÿþþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþýýþýüþýüþüüþûüþûýýûûÿüýÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿÿûòïüóñþõóþõóþöóÿöôÿ÷óÿöóÿöôÿ÷ôÿöôÿ÷õÿöõÿöôÿ÷óÿöôÿ÷õÿ÷öþ÷ô÷òíÓÙÌ}£UUHKGWR
QRR
P
PT[i ÏÇœîØÕûîéýõöÿ÷øÿöøÿùùÿúùþøöóêåÁºµfTSYTY¿¶éñêþüúÿþûÿýûÿüûÿýûÿþýÿþþÿþþÿþýÿþýÿüüÿüþÿþþÿÿþÿÿýÿþýÿþýÿþþÿþþÿþýÿüûøôñËÏÌl¥X£RQRKR\i «ÍÒú÷ùÿþýÿýýÿþýþýüøóòÕÔ×~£§[X_bTk®§œÖÛýùúÿýýÿûúÿûýÿþþÿþýþüûóì윌ŸcVQJ¢IU¥¢°¯Üèêþüûÿüýÿýþÿýþÿýþÿüüþùùñå깎Â`¡ AI§<DBN\r« «ÃÑúõõÿþýÿþþÿþþÿýþÿþþÿþþÿþþÿþþÿþþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿþþÿýýþýüþûüýüûýúüþýýÿüýÿýýÿþþÿþþÿþþÿþýÿÿþÿÿþúñîýóñþ÷óþ÷óÿ÷óÿ÷ôÿ÷óÿôóÿõóÿ÷óÿöôÿöôÿõôÿöôþ÷óþôóþõôþõôýôòòêèÀÈÃiNLB@DUKGGQ
NQKVNZb¢À°°ñßÙýôôÿ÷øÿ÷øÿùúÿùùý÷ôîèÞŽŸ©aV]QOU¥¡ÉÈóöòÿýûÿþüÿýüÿüüÿýüÿþýÿþþÿýýÿýýÿþýÿüüÿüþÿýþÿýýÿüûÿüûÿûüÿÿþÿþþÿýýÿûûøöòÆ×Ïg V£HMYT SRgÆÌöõ÷ÿüüÿýýÿþýýûúòçè÷Án¡c_\R`m·ªÑããþúúÿüüÿùúÿûüÿüûÿûûþûùíðã©Â¬fc¢[BHU¢º±ëîíÿûúÿýþÿýýÿýýÿýþÿúüýøúìêì«ÁÂZ£RLMQ£QV£S]£ºÉöööÿþýÿüüÿûüÿýýÿýýÿþýÿÿýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþþþþþüüýüûýûüýüüþüüÿüüÿüýÿýýÿþýÿþýÿÿþÿÿþúóðþôòÿ÷óÿ÷óþ÷óþöóþöóþõóÿ÷óÿöóÿöôÿöõÿöõÿøõþ÷ôþõóþõóýôóûòðëÞÞ¯š®YMKJEORSEFRNYRWDQI\ÎŒÂøîêýôõþöøÿøøþ÷÷ûóñäÛÓŽTLWMXZ«š²ÐØûù÷ÿýûÿþüÿýûÿüüÿûüÿþýÿþþÿýýÿüüÿüüÿýýÿýþÿþþÿýýÿüûÿüüÿýüÿÿþÿþþÿýýÿúúùøõÍàÞh¥®Q¢QUYQVJe£¡ÊÐõõ÷ÿüûÿüûÿýúýûøïçæ³¶ºVbVTPh»žàéêþúúÿüüÿùúÿûüÿûûÿúúüõôã×Õ©§gabQ¢¢JS«®€ÏÇõöóÿûúÿýþÿýýÿüýÿýþÿûýýøúðëì¶¿ÃZ£^LRPWZb^©¬€Ïàùùùÿþýÿýüÿûûÿûýÿýýÿþüÿþüÿÿþÿÿþÿÿþÿÿýÿþþÿþþÿÿÿÿÿþÿþýÿþýÿÿþÿþþÿþþÿÿÿÿþþþûûþûüþüüþûûÿûûÿüýÿüýÿþýÿÿþÿÿþÿÿÿþõóþôóþ÷óþöòþöòþõóþóòþõôÿ÷ôÿöóÿöôÿööÿöõÿ÷õÿøöÿ÷õþöôþôôùóïãÙÙŠSKGLKXOSLEKFXOSBL>KW §æàØûññþö÷ýööýõõùðíÛÑÉŠKEOQ[h®±ÂÙåýúùÿüúÿüúÿüûÿüüÿüüÿýýÿýýÿýûÿüüÿûüÿüýÿýýÿýýÿüýÿûüÿþýÿÿýÿÿþÿþþþýýþúúûùøÜéé²»Wb`aSTNh³Ž»Úàû÷ùÿûûÿüúÿûùüùõèæÛ«£OZWYV
cžÂîððÿúûÿýüÿúûÿùúÿ÷ùþøø÷îìÑÉÁz¢_W`OKg©°ÂÞÔüù÷ÿùúÿùûÿúüþùûþøûþøûü÷ùòòòÄÜ×c²£^OOY\OM¢g¯®Áßëüúúÿýýÿýýÿüüÿýýÿýýÿýüÿþýÿÿþÿÿþÿÿþÿÿýÿþþÿþþÿÿÿÿÿþÿþýÿþþÿþýÿþýÿþýÿþþþýýýúúýøúþûûþûûþüüþüýÿüýþþüþþüÿÿþÿÿÿÿ÷óþõòþöòþöòþöòþöóþôóÿ÷õÿøõÿ÷õÿööþöõþõôÿöôÿ÷õÿöôÿöôþõô÷òíÛÜÓ£€PJQHNRO¡©O¡ŽQ ºS¢»NšºB€±QTQFNGERuÇÎÀöîëýõõýööüóóõìêÐÆÃn?JNWQ|©¶Ôåìüùøþúúÿûúÿüúÿûûÿüûÿûûÿûûÿúúÿùûÿûûÿúûÿúûÿúûÿûüÿûýÿýýÿþþÿþþÿþþþýýþúúþùúñöõ²ÖÛa°¿Wš«UNNFY§ŽÏÛâîðýùúÿúûÿûûþùùøòíÙÜÉ©KT
XMYl¬ÌØöôõÿûûÿúüÿüüþùûûöùû÷÷îìèÀÄ·gTSWNN€u«ÂÓåéýùøÿúúþúûþ÷úþøúû÷úü÷ùú÷ùöö÷ßííÒÖ^·YCQQNW¬ÀÇ×ãîòýúûýûûþûüÿýýÿüýÿýýÿûúÿûúÿûûÿýýÿÿþÿþýÿüüÿýýÿýüÿþýÿýýÿüýÿýüÿýúÿýúþýüýüûýùùúøøúøøýùúþúûþûûÿûýþûüþúùÿÿþÿÿÿÿ÷óþõòþöòþöòþöòþöôÿ÷ôÿ÷ôÿ÷ôÿ÷ôÿõôþöõþõôÿõóþõôþõóþõóýôòõîéÍÓÇrJ@WOTX}¹ÆÊÝËÞÍßÎÛvÃÎiª³[IGMREO
c¿²ïëçûóôýööûóôïêé¿ÃÄ^9OFQD¯œâëïýøøþúúÿúúþúùýøùÿüúÿüûþúúþùúþøûþùûþùúý÷ùûõ÷ûõ÷ûöøýøùÿúüÿýüÿûûÿýüÿûûÿúûüüûäóó¢ÚákºÂQ«G¯¬J«šXžŸÍÛÖëòöö÷þùûÿüüÿüûüöôïáßų°l]WYLRd±ž¿ÚäûøøÿûüÿúûÿùúþøùûöøùõõììåµÈ±eR WIRJ«Ææìñûùùÿúúþûûþøúþøúú÷ùúôøüøùûøøôõ÷ÕêíËÕi¬ŽJ§X£[޵n»¿Òã×íòöøùýùúýúúþûûÿúúþùúþúúýùùúõöþøøÿûýÿþýÿþýÿüüÿýüÿýüÿýûþüúþùùÿûúÿúúÿùúþûúýúúýùúüùùûøùýúúýøùþüýÿýýÿýüÿýûÿÿþÿþþÿöóÿöóþ÷óýõòýôñþöôÿ÷ôÿöôÿöóÿöóþõóþõôþôôÿõóþõôþôóýóóûòñîå⻞žaRD]UVlª€»ÓÕàêíäëïäëïÜéíÉáåŠÏÔr±ŽFDFPFL
W²¬êèåùóóûööúòóçà⬶œU?QBWO¢ŸÃìïñûö÷þúúÿúúþúùþùùÿûúþûúþùúþùúýùúüøúþúúýøùùõ÷öóôöóôùôõýøùÿûûÿüûÿüüÿúûÿýüþýýúüûçôóÃâä£ÓÚÕÚ×Ú¶ßæÜíñõö÷üøùþùúÿûûþüûùóòêâÞ³¶®SSGKDZqŽÂÕåïþúûÿûüþùûýøúýöøü÷øöððâÚØ¯£Q
MeMZJ¥ÅÓíïôýùúþøúý÷ùý÷ùþùúýøúüøùüùùüøùú÷øôõ÷ÞìïºÞãÑÞÑß¢ÚæÆæìçõøûûûüùûýùúþûûþûûþùúýøùùöøüøùûøøüøùÿûüÿúûÿúûÿýüÿýüÿýüÿýüþüûÿüûÿýûÿüúÿúùþüùýûúþûúýúûþúûüùúû÷øýùüþüüþûüÿýýÿþþÿþýýôòþõòþ÷óýõòüôòþöôþöóþõóÿöôÿöôþõôþôóýôóþôóþôóþôóýóóùñðèßÛª§©WWNcX\³ª×ßÝóïð÷ñóùóô÷òòðïïÞæåªÌÈ[£E=IFKUª«æçäøóóúôõøððÞ×Ú£±NMP>R^££®ÎÎòòòùôöüøøýø÷ýööýöõþöõü÷õý÷÷ýøøü÷øúöøýùúþùúý÷øúööúööûööýøùÿúúþúúþùúÿùúÿüûÿüýþýýýüúö÷÷éñôãîòåïñïóôù÷øýøùü÷ùþúúÿûûþûúûöõéæâ€®¬OL:36Y±Äèíóþùûÿûýþùüýøúùóöüö÷õêíØÇÊJ;PFM`ªÓØòñõþùùýøùýøùýøùþúüþûüýûüüúûüøùûøùù÷øöôöîòôêôôíö÷ñ÷ùøøúýüýþüüýúüþûüþüüþúúþùùúöøùöøýøúþûùþùúþúûýùùûöøÿúûÿýýÿýüÿýüÿüüÿýýÿýûþüùþù÷þûøÿûúþúùûø÷ýùùüøùûøùûøúþùûþùûÿýúÿýýÿýýúòðþôòþ÷óþöóþ÷ôþõóþôóþõóÿ÷õÿ÷õþöôþõóýõôýõóýôóüóòûòò÷ïîáÜÕ§ VROXV
Yº·æèæõïïúòôûóôùòò÷ðððìëÑÚÔy¥¡JA>MDSª¯äåäøóóúôõõííÖÌËGO
KBIp¢ŠÅÛÚ÷õôúôôùòóúëêùàß÷ÙØùØÔ÷ßÖúêÞýñéüððùôõúõöýöøýö÷þøøýùøýøøýøøýø÷ûö÷ýö÷þö÷ÿ÷öþ÷öýööÿúùþùùû÷øøôö÷ôõøôôûö÷ýùùýùúÿûüþûúúö÷÷òóàåâ·®IBC15X¥ÁÊóòôúõùÿúýþûýýøúùô÷ùõ÷òìíÏÌÌlCJHCKr£ÁÛÝû÷ùþüúþûúþúúþûúþùùþùúþùúýûúýùúýøùü÷øùôõ÷ôôúøøþüùþûüþúûÿûûþùûþùûþûûþûúýúùýø÷ûõöùòöþö÷ÿõõÿñïþåäýöôûöøþúúÿüüÿüúÿüúþüùþùöþùïýöæûð×ùçÜþôæýùóû÷öýùøüùùûøùûøúþûüþýüþûúÿûúÿýûúñïþõóþ÷óþõóþöôþõóþôóÿöôÿ÷öÿ÷õþöôþöôÿ÷öþ÷õýöóûòòúññöîìÙÕÍ¡RHNKT\§ÃÈðìì÷ññüóõûóôúóóúóóöîîßÚÖ¡KM
<J@S¶²åæåùóõúõöõîìÎÍÁqJSLQJ¥³ÙäæúõóøèéòÑ×ìÍÉßž³Ó¹³Î¶«ÎŸ²ÛÁµåÈÂóÐÖöïéöòðùóõýõ÷ÿùùþùùýøöûõíúñèõíæôæâ÷ßàøÔÙ÷ØÚ÷ÔÛûëåøòì÷ëè÷áãøééøððûööýøùþúûÿüýþûúùõöóêíÕÊÒz¡ŠSEB
/G]¯¢ŽÕ×øô÷úõøþøûÿûüþùûüöøùõöíëêÁËÊfJL?G?~¥ÔàãüùúÿýýÿüüÿôöþãêûèêûòïüôòûóîúìëúßäùåèôÚáøíëûøñÿ÷ðÿóòÿóôÿùúþùúþúûþüýþüüýúùý÷÷üõôöìí÷ßåôÄÓðÎÐæžŸöìíùóöýøøþùøûöóùóïüöíöðáîæ»æÏ«ßÆÚ§éɬòÒ×ùòîüù÷üùøýùùýúüþýýþüüþúûÿþþÿÿýüóñþõóþõòýõòþöóþõôþõôÿöôþöôþöõþõõþõõÿ÷öÿøöþ÷õûóòûòòôêéÍÃÁp OHYTWgšª¹ÐØôîïùòóüóöýôõüôõüôõøðïá×ÓGNFN
JY·éêèùóõùóõñëçÃŲgQ^S\M
±Ãæêë÷ñèíÜÍÐ±š¬²Š{v šŒ®ªáØÀóäáøòôþöøÿùùþùøùòêê߯ÕȮ˶¬ÄµªÅ©£Ä«€Å± ÉŽªÐ«Ïù̺¯É°¯ÎÁœãâÜùôôþøúÿûûÿüýþüûûøöðéæÅžcVD
J|J[o¯£Ìâàüøùü÷ùûöùþúûýøúüöø÷ñóçäߪŸµULUHS?€£Ÿ²ãëëüøøÿùúþû÷øìåçȺÚγÛÏ·Öɵ֞«Õ³¥Óš Øœ¥ÓŒšÚÊ«ÞÌ·ÜÀ©à޶ôÔÓÿùøÿúüÿüýÿýþÿýýþûùýôíùçÚíÐ¶ÞÆµœ®¥¬²€ŠÖÍß÷óõùôõúñïñãÕåÏŒÒݪš€sm
r©€³¬ÔÍ·ñïäùõôüùúüùúýøùþúûÿýüÿÿÿÿÿÿýõñþõóþõòýôñþõóþõôÿöôÿõôþõóþöôþõõþôôÿ÷öþ÷õþöôýóóûòñðå圱Ž[FHW`^w޳ÉÙáöïðûóôüôöüôõûóôúóó÷îìÛÖÏ
MJHPQ]ÆÁîíëøòó÷ñòèâÞ®Ž©ZS\SRSœÍèâáâÚÎÀÀ¶aZLRZ^hu¡¬¡áËÓúóóýõ÷ýõøþøöòå௚}¥upifro{mrs§žÓÛøõöþøúþùûÿüýÿüüýúøðêåž»¯ZV
MSI^¯±áëêþúûýøúýöùþúûþùúý÷ø÷ïïÞÎÊ¢OGXJJPªÌÉñôôûöøûöùü÷ôéçÛ©·¢x|rvhfrltpt²³ÈÕÒþùøÿûüÿûüÿýþÿýüýöííÞÅÏœ°Š¬jav¶ÂÙøóõùïìíÏÎÏ¥ iO71A
L_gª¡ÐÞÍñëäúø÷ýùùùöøü÷øÿýýÿÿþÿÿÿþ÷óþõóþõòþôòþõóþõôþöôÿ÷õÿ÷öÿ÷öÿööÿööÿ÷÷þõóüóòüóòúòðêæâ޲Q6BSXXµºÛãéùóóüôõýôöûóôùñò÷îïñæåÊÂÁrSHMKUd€ÊÍñíî÷òóóîïàÚØ¡JLKM
Da °ÃÕºÁ¥¯«n MB@NVYS~ZM
l³³»ôååùóôûóöüööìå८£]\KE:?G[NU
Ll£¯ÐàøôöþùûþùûÿúýÿüüýùõëêÜ€œSNJ?G\ŽœðóòÿûûþúüþøûÿûüÿûüþùùöñìÕÓÁyCCLSSg«¶ØØúùúýøúü÷øøñîÝØÇ³ZU§E>JENAR5NgŽ·ÄÛÝýøøÿûûÿûüÿûûýúøìï᫜€qY
QL¡EW©ÅòêéêÑÀŸ¹s=A
<E
>LFA?¢^®«ÖÃÀöñîü÷øû÷÷úö÷þüüÿþýÿÿþÿøôþ÷óþõòþõòþöóþöôþöôÿ÷ôÿ÷õÿöõÿööÿööÿööþôóûòñûóòøñîãàÛ³¬R:BDJT¯»ééìûóóûóôýôôûòóùððôêéæÚÓ«©¬VTD
N
LUr§ŽÃÖÝóîñöðòóîïÚ×ÖBD;L@jš®ŠYJ8==OTZ
HVDU
€ªâÖÙøñóûóõúõöáäâššZVHB825IFUHt¢®ÄØæúööþùúþøúÿúüÿùúüóðàÕ̬QEH3CMª¥Ì×÷÷÷ÿüüþûýþúüÿýüÿüüýööñíêÊÍŸpCN<TGm°ÊÝæüøúþùûýøøöììÎÜf XP\:L0C;OAip¶ÆÖæëüøøÿøúÿùûþøùü÷öèîâÇ©B3E
L\`«ÃçßÛœŸ²kWPG
9C2<1I
>M
M¶¯ëæèõòóöñóúõøýúúÿþýÿÿþÿ÷ôþ÷óþöóþöóþöóþöôÿöôÿõóÿõôÿõôÿõöÿõõÿõôþõóýôóüóò÷îëÚÓÌŠ P?L
=FV ¹ÁïëìýóòüóóýóóûòñöéèíÒÐÒÀ¬LZCH
KSŒÉÛæìöðòõîñòëíÐÌÐsIE>OAdzc@K:EIMPP9L
<Fn¢€ÑÌÎúòóüô÷öóõÓãâr®«L]O>>/3M
HSL}²°Ôáêü÷÷ý÷øýö÷þùùüöøøïëÒÇŒz¥VCTBBZ¡³¿ÚçýúúÿýýÿüýÿûýÿýýÿûúýöõïêâœÊªjTXG^Lw¯œÜæðýøúýöùúôöíåäµ°^M?_UUJ\BOJ\ªÈåíóþùùÿøúÿøúþøùüõöçèâ¥À«U8~I=EW² r98;LTKCZ;A 9Tx]€ áÝç÷ööøôöú÷ùúøùÿþýÿþþÿöóþöóþöóþöóþ÷ôÿöôþõôþôóþôóþôóþõôþóóþóôÿõôÿõóþôòõéæÎÁºmIHK=I[гÉÈòëëúîìõéçûèæöãÙíÎÄѱ¥ ¡dU`GC
C`§ËÓìîñ÷ðòõîïíâ䟲ŸaMMPTDOPJL€EаM²ŽF§®<¢GQ>3D>Ab§¥ÁÌÊúóóüõøõñõÌåèaºÅF§·V©¶NŽEªG1CJ?BS¿ºâèìúôõúôõ÷òôúõöùóõñëêÃÅÁcC:IC>g€»Ðàìû÷úÿûýÿûýÿüþÿýýÿûûüòñæÍЊTDIFGRÂÎêïõûöùúôø÷ôöìîî¥ÎÏ9±Œ;©¹B²P ŽEªBCB:~QQhŒÓõõ÷ÿúúÿùúÿøúþøùüø÷íîé²ÎœR¢@HNSK^_<@5²D»_«œN€·@«±8 CJ
GO\9f¯ªÄÐàõóôüøùýûûþüüÿýüÿýýþöóþõòýõòþõóþöóþõóþõóþôóþóóýóòþôóýóóþóóþôôþôóüóññç⟜³bARDEOiœººíÓÑðÒÏìÖÆìÌÁÜÉÄ«iIUVP>Iq²ŽÍÞâóðòôîñòêìæÙÚ®ªQRMRUG>IB¡f·Á
ÍÚ¡ØáÑÜw¿ÎXŠS:6AVFd¢¢¹ÐÌøóóüõøøô÷âíñ©ÙæÓâ¢ÖâÐÜŒÅ`8<B;D[Äœêíí÷óóöòóöñóùôööóóçççÅŸO9M>G
H~£ŸãéðüøúÿúýÿûþÿýþÿýýþüüûòïÝÏÍH~RGMOk¢ÍÑôóöüöùü÷úúöøóóöÑéî¡Úæ ÙåÐáËÚ ²Y`
MGC}B[ª°Òßú÷ùÿùúÿøúÿøúÿøúýùø÷íéñ®_KFC3B{W]XT¬kÀÛ¡ÕçÀâë¿àèË×hM¢
EJ§|<=MnаÅÑòóòúöøþûûþûûÿúûÿýüþöòþôòýôñýôòþôòþôóþõóþôôþôóýóòþóóüóòýóòþôóýôóúñðëãÞ®œ®`JXCMRd»ª¥À¯ªŒ·£¯€Š~SL@UOS@_§ÊÒæìîôðòôîñòêìâ×ÓHRJRL~J
5MeŽŒÖáØéîçïñåðñÎâä¶¶T=ODR=c¥ŒÒÕøóôýöøüöøø÷øîóöìòõèðòßëëÂÒËl;<<>@`¢¡°ÏÊññï÷òôøôõöòóøóõòïðÜÞß¹¶LCT
79K¡ÃËòóõþùûÿùüÿúýÿûþÿýýþûûõðîÏÏÎyDaG¡J<gœÓÛú÷øþùúýøúû÷ùùõøõõùðôøñõøíóõäæé³·¿JCBYE
L
f©Ëáéüøùûô÷ÿöúÿúúÿøúþøøõì麜·A€CEa|MZIK @®ÅÇØÕèðñóôñîòòñóèìíÅÆKNLS=5;¥€ÊÖòóóûøùþúûþûûÿúúÿüýýõñýôóþôóýôòüóñþôôÿõôÿõôÿõôþôóþóóüóòüóòþôóýôòùîîåÙØ®£VRWJOVQnxzjXMPFC<FHPL¢µÃËÞéóñò÷ñó÷ðòõîíßÛÎKQLQLO?d¯Ž¯ÖÝæîñ÷óô÷óôøóóðîêœÉŸ[>T>FAk©ÆÕÜùóôþøùþùùþúúþùúýùùøõõïêæÅÀ·dEK?@?e©ªÅÛÚõóòúôöúôöøóõúô÷ôîîÖÊÏ¥NIT9FXµÖÑùööýøùýõùÿøúÿûýÿýüþûùôïìÅÔÈlLYQDEv¥£ÑÜÞü÷ùþøúü÷ùû÷ùüöùúöúýøüýúúúøøìéç°±K=@]@@xª Þèêý÷ùýøùÿøúÿûüÿúûþøøôêæœšTWAKFD~H
[œÙÚèïøõöûö÷öòõöóõôïðÕÎÊp
F=y:
.AY£ÏÐñóóûøùþúûÿýüÿùúÿûüýóñýóñýôòýôòüôñÿõôþôôþôóÿôóþóóþóóþôôþôôýôóüóñøëëÜÍÏQZVQMTMU]
XRAC>IB@:KT§sŒÇžÙßçêïõñòùòôúòô÷ìêÖÆœxN
HQIU
T`¡Í×ãêîöóôûôöùõõ÷òòòîêÆÒÀ`?B<>Ku³ÑÚåøñôÿøûÿúúÿùùþøøýø÷ûöõîéã¶¹©[X
GDCItž»Óâäöóóúõ÷úõ÷ûöøûöøôïîÎÉÊlFO
HJPl€ ÈÜÚúö÷üöøýõøÿøûÿüýÿýüý÷õðáá¶®ž] X[PCD{»·àèçùôöüøùþ÷úýøùý÷ùûöúþúýþûûüú÷äèáž±>-€ ?B?O®ëîîý÷úþøúÿùûÿúýÿúüýùøíê䊷©B9
B|CB}<FvœÀÍàéøó÷ýùùûöøûôöùôööòòäÞØ:L{K42PÇØïóóýøùÿúûþýûþüûÿûûýôñýôñýôñýóòþôòþõóþôóüóñþóòþôóýòóþõõþôõýóòüòñõëêÑÇÊsMZMTMOKK[QaOT;J:IC\«y¹ÅžÚæéîðôðò÷òóúóõüôõõìèÊŒŽdQ=L>YM±¶Ñâéõñôøóõûõ÷úööøòóíæä¹¿²ZF:;:
Q}³Äßåîùô÷þ÷ùÿøùÿøùþøøûôõøòóæáÝ£€V_ISF^¹Äáéê÷óóý÷øýøúýøùü÷øñîë¿ÇœaMK2C
Dz¡šÔÞàü÷øý÷ùýöùþ÷ûÿûýÿýüý÷ôëÝ×€M_BM;M¿ÁèíîûõùýøúÿùûþùúýøùýøúÿùûþøúüôòàÔÊ«L
FJ5?E«ÇŸõôóûõøüõøÿùûþøûþöúüòóãÕΚY{~QtR3yI
{:]¬Óßòòóùóöþúúýöøüö÷÷óô÷óòäÚÓG K5TF\ÆÔõö÷þúûÿüüþýûþùúÿúýþöóÿ÷ôþöóýóñýóñþôóýóòûòïýóñüóòúñòþóôþóóýóòûñññèæÄÆÅhO]JRCKGO]RaK\IL7Hš`®»ÀÒÀÝæìðñøòó÷ñó÷ðòøòôûóóðèä¶Ž¬VO=M7]
Rª«ŠÏÑïðòúôö÷òôùóõúõöøóóçÞÛ¢¡P~S>
BEXÅËíîòúô÷ûô÷ÿøùþøùü÷øúôöôóòÝàÛ§BMMQ@_ÂÓêîïøõõýöøþúúüö÷ùõõëëã®È®QNLB
XL¢·Áâèìýøùý÷ùüôúü÷ûÿúüþüúûöñãâÒDYAT<Uš£ÌÖìïòüöùþøúþøûþøûýøúýøúÿûüþøù÷íëÒ¶Žk O:7/MSж³ÕÙúöøû÷ùü÷ùÿûýþûüþ÷ùùïðÔÌÎj©@H>3U}F œÒãîóüøøü÷øüöùýö÷üõööòõù÷öçéàªIY
=T>S¡¢ ÆÝõõ÷ýùúÿýýþýüþúùÿúýþ÷óÿ÷ôÿøõþõòýôòþôóüôòüòñýóñüóñüóòþóôþôóýóòüñðìßݱ²µbRXKLAIQU\TVAFM¢PŠ€VޱvÀÍŠÔߨèîóóõûôôûóóøñòôïñôïñõîïæâà«PKCF?]o¶ÁÏâæøóöùóô÷òôøòóöòôöòñãàÝ QOCCK^¢ËÐóñóûô÷ûöøýøùþøùüöøûõ÷óíïÖÌÏr€>G?D
A_«¡·ÒáõõôùõöúôöýøøùôõöîðãÒÏ¡\KDCVd§É×ðñôýøùü÷ùüôøüöùýöùþøøøõïÙàÊzEX{T}IJn¡¬žÒÞíðó÷ñöþøúþøúþùûþûúþúúÿûûþùøõð뿹®ZFBH4D]§žÄÛâú÷ùýøúþùûÿûüþúûýõøöïðÍÇÅb\E2)<\¢±Öèýúûþüüýùúü÷ùüö÷üô÷øôùúøöèêߪAA=ZvK
m®ÄÛïïóúøùþýýýüûü÷ùþùûÿøôÿøõÿøôþõóþóóÿôóþõóþõóþôòýóòÿõôÿõõÿöõþõôûðïäÒÒŠ\UQMGIL¥ X±Ž]±a§°]Ž\¯ŒW±ÇW·ËqÁÍÍÕšÖÝÉãêåîðùöõþø÷þööýõõúóóöòòôðññéìÚÎÔ
§¥MIIDM_¢ÂÔíïñûõöùòõúôöúõööóôòðîÛàÕ¢SEMFUkŸÑÖøôõþ÷ùý÷ùýøùþøùý÷ùüö÷òëëÌÄÉg©?@=BUq·§Ðãèüùøüö÷üö÷ýö÷ùôõóìîÚÐÉKV@JVt³×åõóøûõúüöùüõøûõøùôøü÷÷õíêÉÈœZQTX;Lk¶»Ëàèíîóóîôü÷úýøúþùüÿüûÿúûÿúúþúøðð髌ªZID7AN}¢ÂÛåíú÷ùýöùýöùÿûüþûüýùøòïë·Ç»_@£A
ARds¬ÖèîþýýÿýýþûüþüüþúúýúùüøùøõôßáÙu¬C
DGXG[·¬¹Úçïñôüùùþüüüúùú÷ùúöùÿøóÿ÷óþöòþôòþóòÿôóÿöõÿøõÿ÷ôÿõôÿõõÿõõÿõõþöõúïìÛÎÉNTKNN|byŒ³ÏÖÌÛÐÛÓÞ€Øâ°ÜéµÝéÄâìÛëîéïïôóôúôôýõôþ÷÷þööþ÷÷ýõõüöõùôôóëìÍÁÈmOBH>Ne¬€žÖàúööþøøüöøýøùýùøû÷öñïìÉÑÇcP:PFaw®§Õáàý÷øÿøúþøúþùúþùúüö÷úôôòì霶œ_G?
CC
KŽ«ãìíþûùþùøþùùýøøúöõñíîÍÐÊg;[7GBv³Íáìüùùü÷ùýùúýøúü÷øü÷ùýø÷óáß· §NQFR2V»Ãâíðîðôíìõ÷ó÷ý÷úþûüÿüüÿüýÿýýýøøêæá·€WGH7TN«ÁÔçëðøõöýöùþûüÿýýÿüýýööíáÝŠ¶«VLPA€C2š£~Áœóôôÿþþÿýýÿùûÿýýÿûûþûúþüû÷ïïÔŒŸi£G4¥7Q \t»®Ñéïûúûþüýþûûüúùýùúýøûÿ÷óÿöòþôñýôñýôñÿöôÿøõÿ÷õÿ÷õÿöôþõõþôóþóòýóó÷îèÑÐÀnEUOUT~oµÓÍçðïèñòèðòêòòíòòòóôôôô÷ööúööûöôü÷öýöõýõõþööþööÿö÷ÿ÷÷þø÷ýøöõíêÅŸºaWEJ
5PwªÚæèþùøÿùùÿ÷øÿùùþùùü÷õïäà·©ªZ_<KF`
Áµéïëÿøúÿùúÿúûÿüüþûûý÷÷ûôóîíã°·°WOF<JOž¹óòñÿüùÿüùÿûúþúùûöôðîíŸÐÈ_;J
>[T±Žãìïþüüþûüþüýþúüþúúþúúþùøðëé®8D>]:£eÆÇîòõðò÷íì÷÷óùý÷úÿüýÿýýÿýþÿþýüóðÛ¿ÇwQHC@G_¢¢±×Þóóõü÷øþùüÿûýÿüýÿüüýôóãÌÅ
¢P:§¢MLfW¡¥©ÐÌýúøÿýýÿûýÿúüÿüýÿûûÿûûþúûöðîÊÄÂS XMOII¢r»¶ãòôÿþýÿþýþûûþúúÿúúÿþýÿöóþõóþõóÿõóÿöóÿ÷õÿ÷öÿ÷öÿ÷öÿöôþôôýóòüññüòññéãÂÁ³\T\
YW[
y¡€ÓÞÛüöôýøöý÷öý÷öýø÷ý÷÷þööþùøþøøþ÷õÿøøþø÷þ÷÷þööþöõÿö÷ÿø÷ÿùøþøöóîæ¹À²[UXMAO޳åçèÿøøþùùþôøÿùùþùùü÷ôéãÚ€£Z\HNK]££ÊÊööóÿøúÿúûÿüüÿýüÿûúþùøüóòèÜ×®«XKE>RV£Š§ÆÊøôóÿûúÿýúÿýûþüúûöõíÞ⬪·RMM>YdÈÀóöôÿýýÿýýÿýþÿýýÿûüÿûûýúùèé犯2<GC<f ²ÎÓóô÷òóøöñùýùýþüýÿüýÿþþÿýýÿüúûõòÌËË\GWZVW£mŠŠÆàäýùøþùúÿúýÿýþÿüýÿüüý÷óÞÓÁlT@VNOa¡²ÂÛÜþûùÿýýÿýýÿüýÿýýÿýüÿüüþüûõî쌶»TZM7¡Qb»·ôöôÿþýÿþýÿÿýÿþüÿþüÿÿþÿ÷óþõóþõóÿõóÿõóÿöôÿ÷öÿ÷öÿ÷õþõóþôóýõóýôòýòðíãݯ«©L]`aK] ¹ºãéåþøöÿøöÿ÷öÿøöÿøöÿøøÿøøÿúùÿùøÿùöÿùøÿ÷öþøøþ÷÷þ÷öþ÷öþøøÿù÷ýöóíáØŠ³£[QbPOT€¡§ÉÅðïîþööþùùþ÷ùÿùøþ÷÷ùõòãæÖ©YQ[P
KXš·ÐÚüù÷ÿùúÿùúÿüûÿûúÿúøþú÷ûòíÝËÁ©Y=W?M`©ŸÕÔüööÿûùÿûùÿýûþüûýøôçÝÙ£©KPL~LMh«ÒÇöôóÿûþÿþþÿþþÿýþÿýýÿüüü÷õÙÔÍ]¢£4D^GOjŽÈÞÚúøøýúúýùúÿþþÿýþÿýüÿýûÿýýþùùùõí¿ÇžgN¢OA€IV©ãêêþúùÿüüÿüýÿýýÿüûÿúúûôìÉÅV7£<3<Yµáéìÿýüÿþþÿþýÿýþÿþþÿþýÿüúþú÷òìãšÁžQYc
b]UŽª¥ÒÎýüøÿÿýÿÿýÿÿýÿÿþÿÿþÿÿþÿõóÿöóÿ÷óþõóþõóÿõôÿöõÿöõÿ÷õþöôþöôÿ÷õÿöôýóñëâÜ ¢N`
Vh
MdÈÌîðîþ÷öÿ÷õÿøõÿøöÿøöÿøøÿøøÿùùÿùøÿù÷ÿøøÿ÷÷ÿúùÿúùÿù÷þø÷þúøÿù÷üóïäÍÆ¢[ObQ\f¯±ÅÝÚûøõþøøÿùúÿúùÿùøþ÷÷õñîØÝÒo©RLP>F`§²ÍÝçþùùÿøúÿøúÿúûÿûúþúøþ÷õûóíОm>2eJRp«ŸÖåæþøøÿûùÿûùÿüúÿúøýøóàáÔyKU<
FBl¢¢ÅÚÕüøöÿüþÿþþÿþþÿýþÿûúþúùùìèëPC6LC\yޱáìêþýüÿýüÿüüÿþþÿýýÿýüÿýûÿúúþ÷øòïæ¡ÃµRCWKVD£šººíòïÿûúÿüýÿüýÿýüÿüúþùøõïçµÄ®XNV}1G9§ œÐïóóÿþýÿÿþÿþþÿýþÿÿþÿþýÿüûýóïæŸÁ ®\B€£EH§\b²œÈæçÿýúÿÿþÿÿþÿÿþÿÿýÿÿÿÿÿþÿôóÿöôÿ÷ôþõóþõóÿõôÿôôÿöõÿ÷öÿ÷õÿöõÿöõþõôüôñæâÝŠ§R_Rj_i¢šÍÙõóñýõõÿøöÿøöÿùøÿùøÿøøÿøøÿùøÿø÷ÿø÷ÿøøÿøøÿúøÿúùÿù÷ÿøøÿúøþù÷úñîØÊŸsPL\Ncz®»ÞééþúùÿùúÿùúÿùúÿúùýöõðçèÅ·Œ^ UUJ;Hw·»âëðÿùúÿùûÿùûÿúüÿüúþù÷ýöõùòêÀ¯[/CWPcªÅëðñÿúúÿüùþûùþùøý÷õùõíÕáÃd¢J REJPyª®Ùäãÿüùÿýýÿþýÿþþÿýþÿüüþûøøñ௱GPCTPb¿ÄõøöÿÿýÿþýÿýýÿþþÿþýÿþýÿýüÿûúýôòåÎÊ¡SBUB Pc ¥ÐÉùùöÿüûÿüýÿüýÿýüÿüûþøöìÕÔ¢¥^
D{A/NT §Ôáø÷ùÿýýÿÿþÿþþÿþþÿÿþÿþýÿýüüôëÒŪhRJiyNXm·ÌàðóÿÿýÿÿÿÿÿÿÿÿþÿÿýÿÿÿÿÿþÿöóÿöôÿøóþôòþõòÿõôÿôôÿöõÿöôÿöôÿõôÿöóþõòúðìØÑÎz ^[T`kv ÁÓÜ÷óñýõõÿù÷ÿø÷ÿø÷ÿú÷ÿùùÿùøÿù÷ÿø÷ÿø÷ÿøøÿø÷ÿù÷ÿùøÿù÷ÿùøÿúøþù÷÷òïÉÎÂhUSUS]¬Áíïðÿùùÿùùÿ÷øÿöøÿúùý÷õîçæ°®³Y£DRI>WÀÅïñóÿùúÿúüÿüüÿüüÿüûþ÷÷ýõõóêå§Œ¬L3R^Lc¢œÒöôöÿûüÿüùþüùþø÷ûôóõìåÅœ±T¡U^ TT P¡|œÌëððÿüúÿûýÿþýÿþþÿþþÿþýþýúðñß³VYBIKPªŠËÝýüùÿÿþÿþþÿýþÿÿþÿþþÿþýÿþýþúúûóðÜÎÄqA:PRMZ¢ŒŒÜäþüùÿýüÿýýÿýýÿýýÿüüýùøéàÛDJ
MNVf¢¥³×äýúúÿýûÿþþÿÿþÿÿþÿÿþÿþüþûø÷æâµ·€YVMXšNW±£Ðáøúøÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿ÷ôÿ÷óÿöóþôòþõòÿõôÿõôÿõôþõóþôóþôóÿõóþõòöëäȹµfc[Z[hzšªÖâãúõóþøöÿøöÿø÷ÿøöÿù÷ÿøùÿøøÿùøÿùøÿùøÿøùÿø÷ÿù÷ÿùøÿùøÿùøÿø÷þøõôíêžÄŸf_XO_d¡ÀÏ÷ôõÿúùÿúùÿøøÿ÷ùÿúùþúøíêä²±P5RBRešÆÌ÷óôÿúúÿøúÿúúÿúúÿüûþúøýóòèÎÑ«I@Pb\g€ÎÝû÷ùÿûúÿüùÿüùþùøüôóñæÝ®€P `O¢VTbÇ×ùööÿüüÿüýÿýýÿýûÿþþÿþýýú÷çéÐ{µYO~^KLZ²°ÃßêÿýúÿþüÿýýÿûýÿÿÿÿþþÿþýÿþüþúúøóìÍÈ·iQND¥GNp¶ÖåëÿýüÿþûÿþþÿþýÿýýÿüüýøõÜØÕn? <<¡X~U~ÏãäþûûÿýûÿþþÿþþÿÿþÿÿþÿþüýöòäÉÈŽPX{VQ¥ntÀšÍèíÿýüÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿöóÿöóÿõóÿôóþõóþôôÿõôÿöôþõôþõóþôóÿõôþõòñæÜެ§W_U[Xe¿µæìéþøõÿø÷ÿù÷ÿùøÿùöÿúùÿøøÿöøÿø÷ÿùøÿùøÿúøÿøøÿøøÿøøÿúøÿúøÿø÷ýöôíÞÞ®]
__YcnªµÕØýøøÿüûÿúùÿøøÿøùÿùùý÷ôçßÚ³¯R;O<Zm§šœÐÔûõõÿúúÿùûÿúûÿûûÿýûþüùüóðßÍÍtLK
O^^n©£ÆÝäþøùÿüüÿýüÿüúþúùýøõðêà¥Oh\c>l¡²ÐâþøøÿýüÿýþÿýýÿýüÿýýþüüúðïÖº¹j^
CZH£Fn³œÔæíÿûùÿüüÿýýÿýýÿýýÿüüÿûûÿþüþûùõóí³ÎŒLFWJUFzšÄçîóÿüüÿûúÿýýÿýþÿþýþýûøóòÃÔÔQ>V<Y;£«r³°ßëêþúùÿüûÿûüÿýüÿþþÿýýþùöúëݰ¯ciJV:¥y²
ÇËíôôÿüúÿþýÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿöóÿöôÿöòþôòþôóþôôÿôôÿöôÿöõÿ÷ôÿöôþ÷ôüôðëâÕªS]T\PdÆžîðêÿ÷õÿúøÿúøÿúøÿûøÿûùÿøøÿõ÷ÿ÷÷ÿùøÿúøÿúøÿùøÿøøÿ÷øÿúùÿûúÿùøý÷ôæÚÖWX]]`tªÎáÜÿøøÿûúÿùùÿøøÿøùÿøøüñíØŸ¿n¥€[VZKWtްÕááþøøÿûûÿûüÿûüÿûýÿýüþüúúôðÐËËk\£QMT]| £Ùæèÿúùÿýýÿþüÿýûÿüúþû÷ìíÞ§RcTdLt ÇÒãÿ÷öÿùøÿúúÿûùÿûúÿüüþûûúñíŶ³VSQXPR³ºåìîþùöÿüøÿýúÿýüÿýüÿüüÿûúÿüúþùøîßܬRS]KDI¡ÄÒôöùÿüüÿúøÿûýÿûýÿüüþúùïàݱ§±\(B
?JQ˯ô÷ðþúúÿüûÿûüÿùùÿøøþ÷öüÝØÞŒ¢AIB }T;g¹·ÞåýûúÿûúÿþýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿõóÿõóþöòþóñþõóþõôþôóÿõôÿöõÿöôþöôýöóúñíâÙ̬]^ZUWg®ÊÁõóîþöôÿù÷ÿùøÿùøÿúøÿúøþøøþ÷øÿùøÿùøÿú÷ÿûùÿúùÿùùÿøøÿûùÿüûþúùûöñÜÙÊuXNX`Y¢¢áèãÿøøÿùùÿúùÿùùÿùùþøøúïéÅŽ¬cQ^^WY·ŒæììÿúúÿúûÿûýÿúûÿùûÿüûþýúöôîžÊÁT[¢UJVe¯®ëïîÿûúÿüûÿþûÿþûÿýûýûøææÛ}S
XZ_Ng§ÏÂÈþèÜþØÓÿîâÿ÷òÿúúÿùûþûú÷óñ»º¹\
_aH¢¡FI¬±ïêÚþñàÿõÚÿöêÿüúÿþýÿýýÿüýÿýüýúøèÖÕM¡WKbK^¢ ÑÛüùúÿýüÿýûÿþþÿýýÿüüþùøìäÚ¬¯?37ROS€Ë»úóìÿüúÿýüÿûûþøøýòìúèØåÕÄW¡U}HQGŠ£I©ªËÜìôôÿþüÿþûÿþýÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿþôòþôòþôòþóòÿ÷õþ÷ôþõôÿõôÿõôþôóþôóýôòøíêÕÇŸr£YSZS
io€¡ÁÕÑùõòþöôÿø÷ÿùùÿùøÿù÷ÿù÷þøøþøøÿúøÿúøÿú÷ÿûúÿúúÿúúÿúùÿúùÿúúþùùùóìËÔŸcX
VUkX °Žîîëÿùùÿúúÿûúÿúúÿúúþùøôí䯻§ZGVJR^ŸÌññòÿúúÿûüÿüýÿúûÿúúÿûúþú÷òå߀¶®PVPELZÈÀöõôÿûûÿûûÿûûÿþüÿþýýõòÜÉÊtš^R RGTRÝ̮۵€ÑÖÃðìçÿùøÿúüþúûöôò±ÈÃ`H[EUM|ÈÍ¢âħÙÐÛÃÅÿòóÿÿþÿþþÿþþÿþýýûøÞÜÛzZiS€bC§n£œÙÝþúúÿþýÿþýÿþþÿþþÿýýýúöãÛÈQ\
?¢1E a²í·ŸþñâÿòóÿïñþÛß÷ØÇÛ§oC¡K3¡MG€£uµ·Éêîÿþûÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿþôòþôñþôòþôóÿ÷öÿ÷öÿ÷õÿöôÿõôþôóþôóýôòôêçÄ»·aSNZYnsµ¶Óãàú÷ôÿø÷ÿùøÿúøÿúøÿù÷ÿùøþùøþøøÿúøÿúøÿúùÿûúÿúùÿúùÿúùÿûùÿùøþ÷öóçà·¶¬\\hYla£ ËÆöôñÿúúÿûúÿúúÿûûÿûûþ÷öëßÚ¹¡\JKBL^€£ŽÍÞúö÷ÿûûÿýüÿûûÿúúÿúúþúùýõóéÜÑ©€OXMKP
e¡¥·×Óý÷÷ÿýüÿýüÿýüÿýüÿûûýôòÕÆÊjRM
WZ`Dg~ ¡®³ÐÝ×ÿúøÿûüþúûóñð¥ÃÂa=fASFMg v©©¶ñíìÿÿþÿÿþÿþýÿüûüúöÎßÑkQš¡LNbQ¥£©ÖæëÿýþÿþýÿýüÿýýÿþýÿýüüùõÑÝÅdAXD
S|
1PS¢ŠÉÀ·Û¹áœŒÍ€µ®šS¢ WEX>¢QQ¯Å ׿úýüÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿöóÿõóÿõóÿöôÿ÷õÿ÷õÿ÷ôÿöôÿöõÿ÷ôþöóýõòðé篎¶^PS^[m}žÀàééüùöÿùùÿùøÿúøÿúøÿûøÿûúÿúùÿúùÿúùÿùùÿúùÿúúÿûùÿûùÿûúÿúùÿù÷þ÷ôîâÚ€ _ad\bm¡®·ÙÚüøõÿúúÿüûÿüüÿýýþüüüõóâÑÐy®^PJPKkµ²ËÞêþùúÿüûÿýüÿûûÿúûÿúúþûùýõðÞÖÉn M¢`[RTr«ÎààÿúúÿþþÿþýÿþýÿýûþûúüóðÖÄÇjVHIcNNZY_hª§¹ÖËÿú÷ÿüüþûûôðî¥ÄÁaIaSgYcN£ST¢äÞßÿýýÿüýÿûüþúùøíè·ÃŽc^`]hN€ŠŸ³ìòòÿþÿÿþþÿýüÿûýÿþýþýüûìçÁ³p
hWF30A^egn hQ£PU`kaK?¡¡Lº§ÏÝêöøÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöôÿöôÿöôÿöôÿöôÿ÷õÿ÷ôÿ÷öÿø÷ÿùöþøõýôòêÜߎ·fQ`QRf»Ííððýøöÿùøÿùøÿúùÿúøÿûøÿûùÿúùÿúùÿùùÿùùÿûùÿûúÿüúÿûùÿûúÿúùÿúøýøôèä×^£XYdbtµÎàèþúùÿûûÿýüÿýýÿýüþüûûôòÒÈÈq©W\OZVµžàìñÿúüÿýüÿýýÿüüÿüûÿûúþúùûöïÎØÀaU jbWQ {£ºâêíÿýýÿþþÿýýÿüúÿûúþúùüõñÝÖÓsG OJdTªM H¡PSlšÏÁÿúóÿýýþüüùõóµÁÁh
c
e¡^Y
XTd`bs«šÒØÓÿúøÿüûÿûüþøõðÙÓ¡¥O£OC[`iŠÊÉúú÷ÿþþÿþýÿýýÿûýÿýþþüüôäß§£Yb
K`KZQO9¢GG€M~N`C£NS«? ;gº
ÎÝÝòõÿþýÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþöóÿöóÿöóÿöóÿöóÿöõÿ÷öÿøöÿù÷ÿøöþ÷õüòñàÏÖµfLhFQdšÄÖöóòý÷öÿù÷ÿùøÿûùÿûùÿûøÿûøÿùùÿùùÿùùÿûúÿûùÿúùÿüúÿûùÿúúÿúúÿüúýùöÚåØxZa[£ka¢}¥¿áêðÿüüÿüüÿþüÿýýÿýüþûûúöõÂÎÐnR[DTWŠš¿Âòõõÿûýÿýýÿþþÿýýÿûüÿüûþùù÷îé¶À¶a^TN \]¥ÀÒñõöÿþýÿýþÿýýÿüúÿýüÿýûýüøêçá£@ŠS@]X¡]N¥`UŠ¡g£Âœù÷óÿýýþüüüøõÉÖÐa°RHebiP€dI§Rf«²ÆÌÎÿú÷ÿýûÿüûþûöèáÒ~Q`
@ bJšcš©ÐØýùøÿûûÿûúÿûýÿüýÿýýþúûîæáNi~NX?£[Xm~AM
5£OE§`PicŠW€I¹šÅØÝò÷ÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþõòÿöóÿ÷óÿöóÿöóÿöôÿöõÿøöÿùöÿ÷õþöõûóòÚÞâtœÉg«³U©±f©Sš\ªµmžŸÄÚäûöôÿù÷ÿúøÿúùÿüùÿûùÿûùÿûùÿúùÿùøÿúùÿúùÿúøÿúùÿýúÿüúÿûúÿûúÿüúýûøÔëäk±µ]£²m¥[®Žk²^·»ÈÖñõöÿüûÿýúÿýûÿýýÿýýþüüùùø¶ÖÝk ±V¬¶`š®TžœP³¹X»Â¥ÏÖûùøÿýýÿþýÿþþÿýýÿüüÿûúþúùôðì¥ÅÆ_޶NŽŽK¯·J©³]§°i¯°¥Õâûûúÿþýÿþþÿýýÿüûÿûúÿÿýþþúùôò¿ÖÛVºÇ_UgC¢MN\ai§žÍôõöÿþýÿýýýüûèïïÍÒWšE¡fO¢WI^I`^µÃœ×âÿúúÿþýÿýüþüùáèß|°D³P²³9žŽLš®N«¬o€ÀÆÜîþûúÿûûÿüúÿýýÿýýÿûüþùùäèâxOQ?g
L`4ŠŽQ«<©šYUq
Yb;Eµ§Cœ³sÊךàëéööÿþýÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþôòÿöôÿøôÿöóÿöóÿöôÿöôÿøöÿøöÿøöþøöüöóèíî©×àÐØÐ×Ð×ÕÖ¢ÙÜÝßãìïý÷õþù÷ÿú÷ÿúøÿú÷ÿú÷ÿûøÿüùÿûùÿùøÿúùÿùøÿúøÿûúÿýùÿûøÿýûÿýûÿýûýüùçõð ÕÜÏÙ ÓÛ×ÝŠÜÞ¡ÜáÇçíûúúÿüúÿýúÿüúÿûúÿûûþûûûúùÔéíŠÐÛ×Þ€ÙÜ€ÞâÞâ€ÞäÓéîþûûÿþþÿþþÿÿþÿþþÿýüÿüûþûúúøöÏèè€ßáÝàÚÞÑÛ¡ÕÜšÙÞÓìðþýüÿþýÿþþÿþýÿýûÿýûÿþýÿþüýúùïö÷¯áæÁÈbŽŒXެE©²C²J©žc²¹n·ÂÉÕÅàìüûûÿþþÿþþþýýúúùÖíðÉÒX»ÂN®¹Uг[ ±Y£·]°µV·ÀtÀÇÔáßîõÿþýÿÿþÿþüþüùíöô§ØâÓÝÕÝÖàÖÝÑÝ¢ÓåçñøÿûûÿüüÿýûÿýýÿýýþûüüòòÕÆÐgO\JY¢AWµ©¢ØÚÎÒUŽÂjª©Qš«M·«@Œ±DºžG¿¿mÎÑ×âÎìóûÿýÿÿýÿÿýÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþôòÿöôÿøôÿõóÿöóÿöôÿøõÿøöÿøöÿøöÿøöþøõûöôïòòíóñëòðêñðêóòíôòðöóùöõü÷öþøõþøõÿø÷ÿøöÿùöÿú÷ÿüùÿûùÿúøÿúøÿùøÿûùÿüúÿüùÿùøÿýúÿüúÿüúþüúûüøêóõèòóéôôêõöìõöíø÷öúùÿýüÿýûÿýûÿüúÿûúÿûûÿûüþüû÷ù÷ëõõêõõëõõì÷÷íùùîøø÷úùÿüûÿüüÿþþÿþþÿÿþÿþýÿþýÿþüþýûöûùìø÷ëø÷ì÷÷èôöëõöë÷÷õøùÿþýÿþþÿþþÿÿýÿþüÿþüÿþýÿþýþþüýýüñø÷Öíí»ãæšÞàÔßÒà ×ä·àèÊçíæòóöúúÿþýÿþþÿþþÿþþþþýùüûâñïÂçë®àèÓáÑá Øå¯àçÂéîØðïêööúüýÿÿþÿÿþÿþýþþýýþüóúùðøöêõõð÷øòù÷ïø÷óøøüüüÿüýÿýýÿýýÿýýÿýýþüüøê廣«F FH
bRWuŒ²äðîëôóÌëð«áéÞèÚæØé¬ãíŸéñÚóöùýûÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöôÿ÷ôÿøôÿ÷ôÿ÷ôÿ÷ôÿøöÿøöÿøöÿøöÿøöÿù÷þøöþùõþùôýøõý÷ôþùöÿûöÿú÷ÿúøþú÷þøõþøôÿø÷ÿø÷ÿú÷ÿú÷ÿûøÿúøÿúøÿùøÿùøÿúøÿüúþüùþùøÿûúÿüúÿüúÿýûÿýúþûúþûúÿüûÿýüÿýüÿþüÿþýÿþýÿýûÿûùÿýüÿýüÿýüÿýþÿþýþþüþüûÿüúÿûúÿûüÿÿýÿþýÿýüÿüüÿûüÿþþÿþÿÿþþÿþþÿþþÿÿýÿÿýÿþýÿþüÿþýþþýþþüÿþýþýýþýýÿþýÿþþÿþþÿýýÿþüÿþüÿþþÿÿþÿÿþÿþýþüûûüúõøøðø÷êöøéöøî÷øóùúùûûýýüÿþüÿþýÿÿþÿÿþÿÿÿÿÿþþþþüýü÷üûôúúî÷øí÷øðùùôúúøûúûûúþþýÿþþÿÿþÿÿþÿÿþÿÿþÿÿþþþþþþþýþþþþþþýýþýýþþýÿþýÿýþÿþþÿþþÿþþÿþýþüüõí䥣£LozS]=¡T£ÄÆøù÷þýüýþýüþýûþýúþüúþüýþüþþýþþýþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöôÿ÷ôÿùõÿøõÿøôÿøôÿùöÿøöÿøöÿùöÿùöÿù÷ÿù÷ÿûöÿûöÿû÷ÿú÷ÿûøÿüøÿûøÿú÷ÿú÷ÿú÷ÿøöÿù÷ÿúøÿú÷ÿùöÿù÷ÿùøÿùøÿùøÿùøÿû÷ÿûùþüùþúøÿúúÿýûÿýûÿýüÿþûÿýüÿýüÿþýÿÿýÿÿþÿþýÿþüÿþûÿýûÿüûÿþýÿþýÿþýÿþýÿÿýÿÿýÿþýÿýûÿüúÿüüÿÿþÿÿýÿþýÿýýÿýýÿþýÿþþÿþýÿþýÿþþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿýÿÿþÿþýÿþþÿÿþÿþýÿþýÿýýÿþüÿþüÿþýÿýüÿþüÿþüÿýüÿþüÿýüÿþüÿþýÿþýÿþýÿþýÿþýÿþþÿþýÿþýÿþþÿýýÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿþýÿþþÿþýÿþýÿþýÿýüÿýüÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿþþÿÿþÿþýÿþýÿþþÿþþÿþþÿþþþüúîçÐCVENSc£©Æ×þüúÿþüÿÿþÿÿþþÿþþÿþþÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷óÿ÷ôÿùõÿøõÿøõÿøöÿøöÿùöÿúöÿùöÿùöÿøöÿù÷ÿûøÿûøÿú÷ÿú÷ÿú÷ÿû÷ÿû÷ÿúøÿúøÿù÷ÿøöÿûùÿýùÿúøÿøõÿùöÿùøÿûùÿûùÿúøÿû÷ÿûùÿüúÿüúÿüúÿþûÿýüÿýûÿýûÿýûÿýûÿþûÿÿýÿÿþÿÿýÿþüÿþüÿýûÿþüÿþýÿþüÿþýÿþýÿþýÿÿýÿÿýÿþýÿþüÿþýÿÿþÿÿýÿÿþÿþþÿþýÿþýÿþþÿþýÿþýÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿÿþÿÿþÿþýÿþýÿþýÿþýÿÿýÿþþÿþýÿþýÿþýÿþýÿþýÿþýÿÿýÿÿþÿÿþÿþþÿþþÿÿýÿÿþÿÿþÿÿþÿþþÿþýÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿþÿþýÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿþþÿþþÿýþÿýþÿþþþþþýøóÞÛÃr]
gVW¢YZ¶ÄËáíÿþýÿþýÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ÷óþõóÿùôÿùõÿúöÿùöÿøöÿùöÿøõÿøõÿù÷ÿøõÿøõÿú÷ÿú÷ÿú÷ÿùöÿùöÿúöÿûöÿúøþúøþø÷ÿøöÿýúÿüùÿúøÿùöÿûøÿúùÿýûÿüúÿûùÿûøÿýúÿýûÿýûÿüûÿýûÿýüÿýûÿýûÿýûÿýûÿþüÿÿþÿÿþÿÿýÿÿýÿþýÿýûÿþüÿþüÿþüÿþüÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿþþÿþþÿÿþÿÿþÿþþÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿþþÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿýÿÿþÿÿþÿþýÿýûÿýûÿÿýÿÿýÿÿÿÿþþÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿþÿþþÿþþÿþþÿþýþýýýïêС\^}S€L
P€hlœÍáð÷ÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿýÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþøóþõóÿøôÿøõÿùöÿùöÿùöÿøöÿ÷õÿøõÿø÷ÿ÷õÿ÷õÿúöÿú÷ÿú÷ÿû÷þøöþ÷ôÿùöÿùøþúøþø÷ÿúøÿûøÿú÷ÿúùÿúøÿúùÿúúÿüúÿûúÿûùÿûùÿýúÿýûÿýûÿüûÿýûÿþýÿþûÿþûÿþüÿýúÿþýÿÿþÿÿþÿÿþÿþýÿýüÿýüÿþüÿþüÿþûÿýûÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿÿýÿÿþÿÿþÿÿÿÿÿþÿþþÿþþÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿÿýÿÿþÿÿþÿÿþÿÿþÿÿýÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿþÿþþÿþýÿÿþÿþþÿýþÿþþÿþþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿþþÿýüÿýüÿÿýÿÿþÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿþýÿýüÿýüÿÿýÿÿýÿÿÿÿþþÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿþÿþþÿþþÿþýÿþûþýýüõñ¹¶¯LjRnI¥£\~ÂÚòøúÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ôÿ÷óÿøôÿøôÿùöÿùöÿøöÿøöÿùöÿù÷ÿøöÿ÷õÿ÷õÿúöÿûøÿûøÿûöþøõþöóÿùõÿù÷þú÷þøøÿûøÿù÷ÿøöÿù÷þùöþøöÿûùÿúùÿúùÿúúÿýúÿýúÿýúÿýúÿýûÿýûÿþüÿþüÿþûÿþüÿýûÿýüÿÿýÿÿýÿÿýÿþüÿüúÿýúÿýûÿýüÿýûÿþüÿþýÿýüÿýüÿÿýÿÿýÿÿþÿÿþÿÿýÿÿýÿÿýÿþýÿþþÿÿþÿþþÿþþÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿÿýÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿþýÿþýÿÿÿÿÿÿÿþþÿþýÿÿþÿþþÿþþÿþþÿþþÿÿÿÿÿÿÿÿþÿÿþÿþþÿþÿÿÿÿÿþþÿýüÿþüÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿþÿþþÿþýÿÿýÿÿþÿÿþÿÿÿÿÿþÿÿþÿþþÿþþÿÿÿÿÿÿÿþþÿüýÿüüÿþüþýüõòî§ŠŠKcO¥U I¡j¡¿Öüüüÿÿýÿÿýÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþöóÿöòÿøóÿøôÿùöÿù÷ÿøöÿøöÿú÷ÿúöÿúöÿøöÿøöÿúöÿû÷ÿû÷ÿúöþù÷þøôÿøôþù÷þùöþø÷ÿúøÿúøÿù÷ÿøöþøõþ÷õÿøøþùøþùøÿúùÿüùÿüùÿýúÿüúÿûùÿûùÿüúÿýüÿýúÿýúÿýûÿýûÿÿüÿþûÿþüÿþüÿýûÿüúÿûúÿýüÿûúÿþýÿþüÿýûÿýûÿþûÿþûÿþýÿþþÿÿþÿþýÿýûÿþýÿþþÿÿþÿþþÿþþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿýÿþþÿýýÿüýÿÿþÿÿýÿÿüÿþüÿþüÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿþÿþýÿýüÿþþÿÿÿÿÿþÿþþÿþþÿÿÿÿþþÿþþÿÿþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿýÿÿþÿÿþÿÿþÿþþÿýýÿýýÿþþÿþþÿÿþÿþýÿüüÿýüÿþýþýüìîêx°¬SKW ZY¡Zª »Øãþýýÿÿýÿÿýÿÿþÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþöòþõòÿ÷òÿøõÿùöÿú÷ÿú÷ÿùöÿùöÿùõÿúöÿú÷ÿùöÿùöÿú÷ÿú÷ÿú÷ÿûøÿùõþöôþø÷þù÷þù÷ÿúøÿûùÿûùÿúùÿù÷þ÷õþ÷÷þùøþøøþøøÿúøÿúøÿüùÿýúÿûúÿûùÿùøÿûúÿýúÿþûÿþüÿþüÿþüÿþüÿþüÿþüÿþýÿýüÿûûÿþüÿüûÿýüÿþýÿþüÿýúÿýúÿýûÿýüÿþýÿþþÿÿýÿýüÿþýÿþþÿþþÿþýÿþýÿýýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿÿýÿÿþÿÿýÿÿýÿþþÿþýÿþýÿÿüÿÿüÿÿüÿþüÿþþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿýþÿþþÿÿþÿþýÿýýÿþþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿûûÿþýÿÿþÿÿþÿÿþÿÿþÿþþÿýýÿýýÿþþÿþþÿûûÿüüÿýýÿþýÿöòÛ²ÁecB€RJ£
_fŽ¡×êçþüüÿþþÿÿþÿÿþÿÿþÿþþÿþþÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþøóþöóÿøóÿùôÿùöÿúøÿú÷ÿùöÿøöÿøôÿù÷ÿûùÿúøÿùõÿû÷ÿùøÿúøÿúøÿúöþùöþùøÿúùÿúøÿúøÿúùÿûøÿúùÿù÷þú÷þùøþøøþøøþøøÿùøÿúøÿúùÿüúÿýûÿýúÿúùÿüúÿþûÿþüÿþüÿþüÿþýÿþýÿþüÿþüÿþüÿþüÿýûÿýûÿýüÿþýÿþþÿýûÿûùÿüûÿýüÿýýÿþþÿþþÿüúÿýüÿþýÿþþÿþþÿþýÿþýÿýýÿýýÿþþÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿþÿÿýÿþýÿþýÿÿýÿÿýÿþýÿüýÿþýÿÿüÿÿüÿÿýÿûûÿûûÿþýÿÿþÿÿýÿÿýÿÿþÿþþÿþþÿÿÿÿÿþÿþþÿþÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿÿÿÿÿÿÿþÿþýÿþýÿþþÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿþýÿþýÿÿþÿÿÿÿþþÿþþÿþþÿÿýþøðÁ³¶E¢ŠPFf[¡iqž¹ìòòþýüÿþþÿÿüÿøóÿúùÿþýÿÿþÿÿÿÿþþÿþþÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷óÿøôÿøôÿ÷óÿøôÿù÷ÿú÷ÿùöÿøöÿøöÿù÷ÿûøÿúøÿùõÿúöÿ÷õÿùöÿù÷ÿù÷ÿú÷ÿú÷ÿúøþù÷þù÷ÿù÷ÿøöÿùøÿúøÿûùÿùùþøøýøøþøøÿùøÿùøÿúøÿüùÿüúÿüúÿûúÿûúÿüùÿýúÿýúÿýûÿþüÿþýÿþüÿþüÿþüÿþüÿûûÿüûÿýüÿþýÿþýÿýúÿúùÿüûÿûüÿþýÿüüÿüüÿüúÿþüÿþýÿþþÿüýÿþýÿþþÿþýÿþýÿþþÿÿþÿÿþÿÿþÿÿýÿÿýÿýüÿýüÿýýÿþýÿÿþÿÿþÿýýÿýýÿþýÿþûÿþýÿÿüÿýûÿýüÿþýÿþûÿþûÿÿüÿþýÿþþÿþÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿþÿÿþÿþûÿüúÿüúÿþýÿÿþÿÿþÿÿþÿþþÿþýÿýýÿýýÿþýÿþþÿþþÿþþÿÿÿÿýýÿýýÿþûùùê°±£il?ª¡;®©WžUž±ÉÎúø÷þþýÿÿþÿýùùëæýóõþþýÿÿþÿÿÿÿþþÿþþÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷óÿøôÿøóþõóþ÷óÿùöÿùöÿùöÿùöÿùõÿùõÿú÷ÿúøÿú÷ÿùöþõóþøõÿùöÿùöÿúöÿú÷ÿú÷þùöþùöÿùöÿ÷öÿø÷ÿù÷ÿù÷ÿùøþøøþ÷øþøøÿù÷ÿù÷ÿùøÿúøÿúùÿûúÿûúÿûúÿüùÿüùÿýûÿýüÿýüÿýûÿýûÿýüÿýüÿþúÿûúÿüûÿüúÿüûÿýûÿüúÿúùÿüúÿûúÿýüýùùþúùÿþüÿÿýÿþýÿýýÿüýÿþþÿýþÿýüÿýüÿþþÿÿÿÿÿþÿÿüÿþûÿþýÿþýÿþýÿþýÿþþÿÿþÿþýÿûûÿüûÿýûÿýûÿþüÿþûÿýûÿþýÿÿýÿþûÿþüÿÿüÿþýÿþþÿþÿÿÿÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿþÿÿýÿþûÿþüÿþýÿþýÿÿþÿÿþÿÿþÿþþÿþýÿýýÿýýÿþýÿþýÿþýÿþþÿþýÿûûÿüûÿýúóùéĵQ¶»TœÊUÅÖcÇÚÕÜÚâÑêñýûùþþýÿÿþÿýùþøóþø÷þþýÿÿþÿÿþÿÿýÿÿþÿÿþÿÿýÿÿýÿþþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿøóÿøôÿøóþõóþøôÿøõÿøõÿùöÿøõÿøôÿøõÿùöÿù÷ÿù÷ÿúöþøõþú÷ÿúøÿù÷ÿú÷ÿú÷þù÷þøöþù÷ÿùøÿù÷ÿù÷ÿøöþ÷öþööþõ÷þø÷þúøÿù÷ÿù÷ÿúøÿùøÿúùÿûúÿüûÿüûÿýúÿüúÿýûÿýûÿüûÿûûÿýûÿýüÿýüÿýúÿûúÿûúÿüúÿüúÿýûÿüûÿüûÿýûÿýûÿýüþûúþûúÿþýÿÿþÿþýÿýýÿýýÿþþÿþþÿýüÿýüÿþþÿÿþÿÿþÿÿýÿþýÿþýÿÿþÿÿþÿÿþÿÿþÿÿþÿþýÿýýÿýüÿýûÿýüÿþüÿþüÿþýÿþýÿÿþÿÿýÿÿýÿÿýÿþýÿþþÿÿÿÿÿÿÿþýÿþþÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿþÿýûÿúúÿýüÿþýÿÿþÿýþÿþþÿÿþÿþþÿþýÿÿýÿÿýÿÿþÿÿþÿÿþÿÿþÿÿþÿÿÿÿþýÿýýÿýýÿûúÿýüÿþýÿþþÿþýÿýýÿýýÿýúóúôØà¢ÞçŠàé»äðÙïõëööòøöûüûþýüÿþþÿþþÿýýÿþüÿýüÿþþÿÿÿÿÿþÿþýÿþýÿüûÿûûÿýýÿþþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿøôÿøõÿøóÿöóÿøôÿöõÿøõÿùöÿøôÿøôÿùõÿùöÿøöÿùöÿúöÿúöÿùöÿù÷ÿùöÿùöÿø÷þø÷ý÷öþ÷öþø÷ÿø÷ÿù÷ÿø÷þ÷öþõöþö÷þùøÿúùÿú÷ÿúøÿúøÿúøÿûùÿýúÿýúÿýûÿûùÿûùÿûúÿüûÿüûÿúúÿýúÿýûÿüûÿüúÿúùÿúùÿüúÿýûÿûûÿýüÿþýÿþýÿýüÿþýÿþüÿýüÿþûÿýüÿüüÿýýÿýüÿþüÿþýÿþýÿþýÿþþÿþüÿþýÿÿþÿÿþÿÿþÿÿþÿþþÿþþÿþþÿþûÿþýÿÿþÿþþÿþýÿþûÿýûÿþýÿÿþÿÿþÿÿþÿÿþÿÿýÿÿýÿþýÿþþÿÿÿÿÿþÿþýÿþþÿýýÿýýÿýýÿþýÿÿþÿÿþÿýüÿüùÿýüÿþýÿúúÿúúÿýýÿþýÿþýÿþþÿÿþÿÿþÿÿþÿÿÿÿÿþÿþýÿþþÿÿþÿþýÿþýÿûûÿúúÿýüÿýüÿýýÿþþÿþþÿþþÿþýýþýïùúòøøðõöôö÷ûûúýüûþýüþýüÿþýÿþþÿûüÿþýÿÿýÿþýÿþýÿþýÿþþÿþþÿþýÿýûÿýýÿÿÿÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ
\ No newline at end of file
--
1.5.6.5
1
0

last-svn-commit-836-gf553aa7 configure.ac: Configure scribo/tests/estim.
by Guillaume Lazzara 05 Apr '11
by Guillaume Lazzara 05 Apr '11
05 Apr '11
---
ChangeLog | 10 +++++++---
configure.ac | 1 +
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 97445bc..31d498c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,10 @@
2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr>
- * configure.ac: configure scribo/tests/primitive/extract.
+ * configure.ac: Configure scribo/tests/estim.
+
+2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ * configure.ac: Configure scribo/tests/primitive/extract.
2011-02-17 Guillaume Lazzara <z(a)lrde.epita.fr>
@@ -8,11 +12,11 @@
2011-02-17 Guillaume Lazzara <z(a)lrde.epita.fr>
- * configure.ac: scribo/src/primitive/remove.
+ * configure.ac: Configure scribo/src/primitive/remove.
2011-02-17 Guillaume Lazzara <z(a)lrde.epita.fr>
- * configure.ac: configure scribo/tests/convert.
+ * configure.ac: Configure scribo/tests/convert.
2011-03-14 Thierry GERAUD <thierry.geraud(a)lrde.epita.fr>
diff --git a/configure.ac b/configure.ac
index 9f4c16a..189d905 100644
--- a/configure.ac
+++ b/configure.ac
@@ -346,6 +346,7 @@ AC_CONFIG_FILES([
scribo/tests/binarization/Makefile
scribo/tests/convert/Makefile
scribo/tests/core/Makefile
+ scribo/tests/estim/Makefile
scribo/tests/filter/Makefile
scribo/tests/preprocessing/Makefile
scribo/tests/primitive/Makefile
--
1.5.6.5
1
0