Merge: Minor fixes to support the Turing cluster
authorJean Privat <jean@pryen.org>
Mon, 10 Nov 2014 23:35:15 +0000 (18:35 -0500)
committerJean Privat <jean@pryen.org>
Mon, 10 Nov 2014 23:35:15 +0000 (18:35 -0500)
Review only the last 2 commits here and ignore the first batch of commits they are from #886.

Enables testing of sqlite, jvm and all Java FFI tests on Turing.

Pull-Request: #897
Reviewed-by: Jean Privat <jean@pryen.org>

76 files changed:
benchmarks/bench_strings.sh
benchmarks/strings/chain_concat.nit
benchmarks/strings/iteration_bench.nit
benchmarks/strings/substr_bench.nit
contrib/pep8analysis/Makefile
examples/pnacl/converter/Makefile
examples/pnacl/converter/README
lib/buffered_ropes.nit [new file with mode: 0644]
lib/bufferized_ropes.nit [deleted file]
lib/cartesian.nit [new file with mode: 0644]
lib/combinations.nit [new file with mode: 0644]
lib/java/java.nit
lib/neo4j/json_store.nit [new file with mode: 0644]
lib/neo4j/neo4j.nit
lib/perfect_hashing.nit
lib/poset.nit
lib/ropes_debug.nit
lib/splay_ropes.nit [deleted file]
lib/standard/collection/array.nit
lib/standard/math.nit
lib/standard/ropes.nit
lib/standard/standard.nit
lib/standard/stream.nit
lib/standard/string.nit
lib/string_experimentations/utf8_noindex.nit
src/compiler/abstract_compiler.nit
src/compiler/compiler_ffi.nit
src/compiler/separate_compiler.nit
src/compiler/separate_erasure_compiler.nit
src/doc/doc_pages.nit
src/interpreter/naive_interpreter.nit
src/vm.nit
tests/bench_string_append.nit
tests/example_procedural_string.nit
tests/example_string.nit
tests/sav/bench_string_append_alt1.res [new file with mode: 0644]
tests/sav/example_procedural_string_alt1.res [new file with mode: 0644]
tests/sav/example_string_alt1.res [new file with mode: 0644]
tests/sav/nitdoc_args1.res
tests/sav/nitg-e/fixme/base_conflict_submodule_name.res [deleted file]
tests/sav/nitg-e/fixme/base_conflict_submodule_name_alt1.res [deleted file]
tests/sav/nitg-e/fixme/base_conflict_submodule_name_alt2.res [deleted file]
tests/sav/nitg-g/fixme/base_conflict_submodule_name.res [deleted file]
tests/sav/nitg-g/fixme/base_conflict_submodule_name_alt1.res [deleted file]
tests/sav/nitg-g/fixme/base_conflict_submodule_name_alt2.res [deleted file]
tests/sav/nitg-s/fixme/base_conflict_submodule_name.res [deleted file]
tests/sav/nitg-s/fixme/base_conflict_submodule_name_alt1.res [deleted file]
tests/sav/nitg-s/fixme/base_conflict_submodule_name_alt2.res [deleted file]
tests/sav/nitg-sg/fixme/base_conflict_submodule_name.res [deleted file]
tests/sav/nitg-sg/fixme/base_conflict_submodule_name_alt1.res [deleted file]
tests/sav/nitg-sg/fixme/base_conflict_submodule_name_alt2.res [deleted file]
tests/sav/splay_test.res [deleted file]
tests/sav/string_trim_alt1.res [new file with mode: 0644]
tests/sav/test_ffi_c_duplicated_callback_a.res [new file with mode: 0644]
tests/sav/test_ffi_c_duplicated_callback_b.res [new file with mode: 0644]
tests/sav/test_ffi_cpp_duplicated_callback_a.res [new file with mode: 0644]
tests/sav/test_ffi_cpp_duplicated_callback_b.res [new file with mode: 0644]
tests/sav/test_new_native_alt1.res
tests/sav/test_ropes.res
tests/sav/test_ropes_alt1.res [deleted file]
tests/sav/test_ropes_alt2.res [deleted file]
tests/sav/test_string_long_alt1.res [new file with mode: 0644]
tests/sav/test_to_upper_lower_buffer_alt1.res [new file with mode: 0644]
tests/shootout_nsieve.nit
tests/splay_test.nit [deleted file]
tests/string_trim.nit
tests/test_arr_tos_ropes.nit
tests/test_ffi_c_duplicated_callback_a.nit [new file with mode: 0644]
tests/test_ffi_c_duplicated_callback_b.nit [new file with mode: 0644]
tests/test_ffi_cpp_duplicated_callback_a.nit [new file with mode: 0644]
tests/test_ffi_cpp_duplicated_callback_b.nit [new file with mode: 0644]
tests/test_flatrope.nit
tests/test_ropes.nit
tests/test_string_long.nit
tests/test_text.nit
tests/test_to_upper_lower_buffer.nit

index c327d58..0bb13a7 100755 (executable)
@@ -54,7 +54,7 @@ function bench_array()
                echo "*** Benching Array.to_s performance ***"
        fi
 
-       ../bin/nitg --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_rope.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+       ../bin/nitg --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_flatstr.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
 
        prepare_res arr_tos_ropes.out arr_tos_ropes ropes
        if $verbose; then
@@ -67,6 +67,19 @@ function bench_array()
                bench_command $i ropes$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
        done
 
+       ../bin/nitg --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_flatstr.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+
+       prepare_res arr_tos_buf_ropes.out arr_tos_buf_ropes buffered_ropes
+       if $verbose; then
+               echo "Buffered Ropes :"
+       fi
+       for i in `seq 1 "$3"`; do
+               if $verbose; then
+                       echo "String length = $i, Concats/loop = $1, Loops = $2"
+               fi
+               bench_command $i buf_ropes$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
+       done
+
        ../bin/nitg --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_flatstr.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
 
        prepare_res arr_tos_flat.out arr_tos_flat flatstring
@@ -110,7 +123,7 @@ function bench_array()
 
        prepare_res arr_tos_man_buf.out arr_tos_man_buf flatbuf_with_capacity
        if $verbose; then
-               echo "Memmove :"
+               echo "FlatBuffer.with_capacity :"
        fi
        for i in `seq 1 "$3"`; do
                if $verbose; then
@@ -119,25 +132,30 @@ function bench_array()
                bench_command $i flatbuf_with_capacity$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
        done
 
+       ../bin/nitg --global ./strings/array_tos.nit -m ./strings/array_to_s_vars/array_to_s_rope_buf.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+
+       prepare_res arr_tos_rope_buf.out arr_tos_rope_buf ropebuf
+       if $verbose; then
+               echo "RopeBuffer :"
+       fi
+       for i in `seq 1 "$3"`; do
+               if $verbose; then
+                       echo "String length = $i, Concats/loop = $1, Loops = $2"
+               fi
+               bench_command $i ropebuf$i ./array_tos --loops $2 --strlen $i --ccts $1 "NIT_GC_CHOOSER=large"
+       done
+
        plot array_tos.gnu
 }
 
 function bench_concat()
 {
-       if $verbose; then
-               echo "*** Benching concat performance ***"
-       fi
+       ../bin/nitg --global ./strings/chain_concat.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+       ../bin/nitg --global ./strings/utf_chain_concat.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
 
-       prepare_res concat_ropes.out concat_ropes ropes
        if $verbose; then
-               echo "Ropes :"
+               echo "*** Benching concat performance ***"
        fi
-       for i in `seq 1 "$1"`; do
-               if $verbose; then
-                       echo "String length = $i, Concats/loop = $2, Loops = $3"
-               fi
-               bench_command $i ropes$i ./chain_concat -m rope --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
-       done
 
        prepare_res concat_flat.out concat_flat flatstring
        if $verbose; then
@@ -172,37 +190,57 @@ function bench_concat()
                bench_command $i flatstr_utf8_noindex$i ./utf_chain_concat -m flatstr_utf8_noindex --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
        done
 
-       plot concat.gnu
-}
+       ../bin/nitg --global ./strings/chain_concat.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
 
-function bench_iteration()
-{
+       prepare_res concat_ropes.out concat_ropes ropes
        if $verbose; then
-               echo "*** Benching iteration performance ***"
+               echo "Ropes :"
        fi
+       for i in `seq 1 "$1"`; do
+               if $verbose; then
+                       echo "String length = $i, Concats/loop = $2, Loops = $3"
+               fi
+               bench_command $i ropes$i ./chain_concat -m flatstr --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+       done
 
-       prepare_res iter_ropes_iter.out iter_ropes_iter ropes_iter
+       ../bin/nitg --global ./strings/chain_concat.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+
+       prepare_res concat_buf_ropes.out concat_buf_ropes buffered_ropes
        if $verbose; then
-               echo "Ropes by iterator :"
+               echo "buffered ropes :"
        fi
        for i in `seq 1 "$1"`; do
                if $verbose; then
-                       echo "String base length = $1, Concats (depth of the rope) = $i, Loops = $3"
+                       echo "string length = $i, concats/loop = $2, loops = $3"
                fi
-               bench_command $i ropes_iter$i ./iteration_bench -m rope --iter-mode iterator --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+               bench_command $i buf_ropes$i ./chain_concat -m flatstr --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
        done
 
-       prepare_res iter_ropes_index.out iter_ropes_index ropes_index
+       ../bin/nitg --global ./strings/chain_cct_ropebuf.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+
+       prepare_res cct_buf_ropes.out cct_buf_ropes cctbuf_ropes
        if $verbose; then
-               echo "Ropes by index :"
+               echo "buffered ropes :"
        fi
        for i in `seq 1 "$1"`; do
                if $verbose; then
-                       echo "String base length = $1, Concats (depth of the rope) = $i, Loops = $3"
+                       echo "string length = $i, concats/loop = $2, loops = $3"
                fi
-               bench_command $i ropes_index$i ./iteration_bench -m rope --iter-mode index --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+               bench_command $i cctbuf_ropes$i ./chain_cct_ropebuf --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
        done
 
+       plot concat.gnu
+}
+
+function bench_iteration()
+{
+       if $verbose; then
+               echo "*** Benching iteration performance ***"
+       fi
+
+       ../bin/nitg --global ./strings/iteration_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+       ../bin/nitg --global ./strings/utf_iteration_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+
        prepare_res iter_flat_iter.out iter_flat_iter flatstring_iter
        if $verbose; then
                echo "FlatStrings by iterator :"
@@ -269,26 +307,66 @@ function bench_iteration()
                bench_command $i flatstr_index_utf8_noindex$i ./utf_iteration_bench -m flatstr_utf8_noindex --iter-mode index --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
        done
 
-       plot iter.gnu
-}
+       ../bin/nitg --global ./strings/iteration_bench.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
 
-function bench_substr()
-{
+       prepare_res iter_ropes_iter.out iter_ropes_iter ropes_iter
        if $verbose; then
-               echo "*** Benching substring performance ***"
+               echo "Ropes by iterator :"
        fi
+       for i in `seq 1 "$1"`; do
+               if $verbose; then
+                       echo "String base length = $1, Concats (depth of the rope) = $i, Loops = $3"
+               fi
+               bench_command $i ropes_iter$i ./iteration_bench -m flatstr --iter-mode iterator --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+       done
 
-       prepare_res substr_ropes.out substr_ropes ropes
+       prepare_res iter_ropes_index.out iter_ropes_index ropes_index
        if $verbose; then
-               echo "Ropes :"
+               echo "Ropes by index :"
        fi
        for i in `seq 1 "$1"`; do
                if $verbose; then
-                       echo "String length = $i, loops = $2, Loops = $3"
+                       echo "String base length = $1, Concats (depth of the rope) = $i, Loops = $3"
+               fi
+               bench_command $i ropes_index$i ./iteration_bench -m flatstr --iter-mode index --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+       done
+
+       ../bin/nitg --global ./strings/iteration_bench.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+
+       prepare_res iter_buf_ropes_iter.out iter_buf_ropes_iter buf_ropes_iter
+       if $verbose; then
+               echo "Buffered Ropes by iterator :"
+       fi
+       for i in `seq 1 "$1"`; do
+               if $verbose; then
+                       echo "String base length = $1, Concats (depth of the rope) = $i, Loops = $3"
+               fi
+               bench_command $i buf_ropes_iter$i ./iteration_bench -m flatstr --iter-mode iterator --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+       done
+
+       prepare_res iter_buf_ropes_index.out iter_buf_ropes_index buf_ropes_index
+       if $verbose; then
+               echo "Buffered Ropes by index :"
+       fi
+       for i in `seq 1 "$1"`; do
+               if $verbose; then
+                       echo "String base length = $1, Concats (depth of the rope) = $i, Loops = $3"
                fi
-               bench_command $i ropes$i ./substr_bench -m rope --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+               bench_command $i buf_ropes_index$i ./iteration_bench -m flatstr --iter-mode index --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
        done
 
+       plot iter.gnu
+}
+
+function bench_substr()
+{
+       if $verbose; then
+               echo "*** Benching substring performance ***"
+       fi
+
+       ../bin/nitg --global ./strings/substr_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+       ../bin/nitg --global ./strings/utf_substr_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+
        prepare_res substr_flat.out substr_flat flatstring
        if $verbose; then
                echo "FlatStrings :"
@@ -322,6 +400,31 @@ function bench_substr()
                bench_command $i flatstring_utf8_noindex$i ./utf_substr_bench -m flatstr_utf8_noindex --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
        done
 
+       ../bin/nitg --global ./strings/substr_bench.nit -m ../lib/standard/ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+
+       prepare_res substr_ropes.out substr_ropes ropes
+       if $verbose; then
+               echo "Ropes :"
+       fi
+       for i in `seq 1 "$1"`; do
+               if $verbose; then
+                       echo "String length = $i, loops = $2, Loops = $3"
+               fi
+               bench_command $i ropes$i ./substr_bench -m flatstr --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+       done
+
+       ../bin/nitg --global ./strings/substr_bench.nit -m ../lib/standard/ropes.nit -m ../lib/buffered_ropes.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+
+       prepare_res substr_buf_ropes.out substr_buf_ropes buf_ropes
+       if $verbose; then
+               echo "Buffered Ropes :"
+       fi
+       for i in `seq 1 "$1"`; do
+               if $verbose; then
+                       echo "String length = $i, loops = $2, Loops = $3"
+               fi
+               bench_command $i buf_ropes$i ./substr_bench -m flatstr --loops $2 --strlen $3 --ccts $i "NIT_GC_CHOOSER=large"
+       done
        plot substr.gnu
 }
 
@@ -340,17 +443,6 @@ if test $# -ne 4; then
        exit
 fi
 
-if $verbose; then
-       echo "Compiling"
-fi
-
-../bin/nitg --global ./strings/chain_concat.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-../bin/nitg --global ./strings/utf_chain_concat.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-../bin/nitg --global ./strings/iteration_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-../bin/nitg --global ./strings/utf_iteration_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-../bin/nitg --global ./strings/substr_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-../bin/nitg --global ./strings/utf_substr_bench.nit --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-
 case "$1" in
        iter) shift; bench_iteration $@ ;;
        cct) shift; bench_concat $@ ;;
index 35466f9..a45075f 100644 (file)
@@ -25,18 +25,6 @@ do
        end
 end
 
-fun bench_rope(str_size: Int, nb_ccts: Int, loops: Int)
-do
-       var lft = "a" * str_size
-
-       for i in [0..loops] do
-               var str: String = new RopeString.from(lft)
-               for j in [0..nb_ccts] do
-                       str += lft
-               end
-       end
-end
-
 fun bench_flatbuf(str_size: Int, nb_ccts: Int, loops: Int)
 do
        var lft = "a" * str_size
@@ -51,7 +39,7 @@ do
 end
 
 var opts = new OptionContext
-var mode = new OptionEnum(["rope", "flatstr", "flatbuf"], "Mode", -1, "-m")
+var mode = new OptionEnum(["flatstr", "flatbuf"], "Mode", -1, "-m")
 var nb_ccts = new OptionInt("Number of concatenations per loop", -1, "--ccts")
 var loops = new OptionInt("Number of loops to be done", -1, "--loops")
 var strlen = new OptionInt("Length of the base string", -1, "--strlen")
@@ -67,10 +55,8 @@ end
 var modval = mode.value
 
 if modval == 0 then
-       bench_rope(strlen.value, nb_ccts.value, loops.value)
-else if modval == 1 then
        bench_flatstr(strlen.value, nb_ccts.value, loops.value)
-else if modval == 2 then
+else if modval == 1 then
        bench_flatbuf(strlen.value, nb_ccts.value, loops.value)
 else
        opts.usage
index a8047d2..0e36c49 100644 (file)
@@ -13,39 +13,6 @@ module iteration_bench
 
 import opts
 
-fun bench_rope_iter(nb_cct: Int, loops: Int, strlen: Int)
-do
-       var a = "a" * strlen
-       var x:String = new RopeString.from(a)
-       for i in [0 .. nb_cct] do x += a
-       var cnt = 0
-       var c: Char
-       while cnt != loops do
-               for i in x do
-                       c = i
-               end
-               cnt += 1
-       end
-end
-
-fun bench_rope_index(nb_cct: Int, loops: Int, strlen: Int)
-do
-       var a = "a" * strlen
-       var x:String = new RopeString.from(a)
-       for i in [0 .. nb_cct] do x += a
-       var cnt = 0
-       var c: Char
-       var pos = 0
-       while cnt != loops do
-               pos = 0
-               while pos < x.length do
-                       c = x[pos]
-                       pos += 1
-               end
-               cnt += 1
-       end
-end
-
 fun bench_flatstr_iter(nb_cct: Int, loops: Int, strlen: Int)
 do
        var a = "a" * strlen
@@ -113,7 +80,7 @@ do
 end
 
 var opts = new OptionContext
-var mode = new OptionEnum(["rope", "flatstr", "flatbuf"], "Mode", -1, "-m")
+var mode = new OptionEnum(["flatstr", "flatbuf"], "Mode", -1, "-m")
 var access_mode = new OptionEnum(["iterator", "index"], "Iteration mode", -1, "--iter-mode")
 var nb_ccts = new OptionInt("Number of concatenations done to the string (in the case of the rope, this will increase its depth)", -1, "--ccts")
 var loops = new OptionInt("Number of loops to be done", -1, "--loops")
@@ -132,15 +99,6 @@ var iterval = access_mode.value
 
 if modval == 0 then
        if iterval == 0 then
-               bench_rope_iter(nb_ccts.value, loops.value, strlen.value)
-       else if iterval == 1 then
-               bench_rope_index(nb_ccts.value, loops.value, strlen.value)
-       else
-               opts.usage
-               exit(-1)
-       end
-else if modval == 1 then
-       if iterval == 0 then
                bench_flatstr_iter(nb_ccts.value, loops.value, strlen.value)
        else if iterval == 1 then
                bench_flatstr_index(nb_ccts.value, loops.value, strlen.value)
@@ -148,7 +106,7 @@ else if modval == 1 then
                opts.usage
                exit(-1)
        end
-else if modval == 2 then
+else if modval == 1 then
        if iterval == 0 then
                bench_flatbuf_iter(nb_ccts.value, loops.value, strlen.value)
        else if iterval == 1 then
index 5021e66..effb9ec 100644 (file)
@@ -13,18 +13,6 @@ module substr_bench
 
 import opts
 
-fun bench_rope(nb_cct: Int, loops: Int, strlen: Int)
-do
-       var a = "a" * strlen
-       var x:String = new RopeString.from(a)
-       for i in [0 .. nb_cct] do x += a
-       var cnt = 0
-       while cnt != loops do
-               x.substring(0,5)
-               cnt += 1
-       end
-end
-
 fun bench_flatstr(nb_cct: Int, loops: Int, strlen: Int)
 do
        var a = "a" * strlen
@@ -50,7 +38,7 @@ do
 end
 
 var opts = new OptionContext
-var mode = new OptionEnum(["rope", "flatstr", "flatbuf"], "Mode", -1, "-m")
+var mode = new OptionEnum(["flatstr", "flatbuf"], "Mode", -1, "-m")
 var nb_ccts = new OptionInt("Number of concatenations done to the string (in the case of the rope, this will increase its depth)", -1, "--ccts")
 var loops = new OptionInt("Number of loops to be done", -1, "--loops")
 var strlen = new OptionInt("Length of the base string", -1, "--strlen")
@@ -66,10 +54,8 @@ end
 var modval = mode.value
 
 if modval == 0 then
-       bench_rope(nb_ccts.value, loops.value, strlen.value)
-else if modval == 1 then
        bench_flatstr(nb_ccts.value, loops.value, strlen.value)
-else if modval == 2 then
+else if modval == 1 then
        bench_flatbuf(nb_ccts.value, loops.value, strlen.value)
 else
        opts.usage
index 6829411..c2f2669 100644 (file)
@@ -1,6 +1,6 @@
 bin/pep8analysis:
        mkdir -p bin
-       ../../bin/nitg --global -o bin/pep8analysis src/pep8analysis.nit
+       ../../bin/nitg -o bin/pep8analysis src/pep8analysis.nit
 
 doc/index.html:
        ../../bin/nitdoc src/pep8analysis.nit
index 06318b6..aee71e8 100644 (file)
@@ -1,5 +1,5 @@
 default: 
-       ../../../bin/nitg --global converter.nit
+       ../../../bin/nitg --semi-global converter.nit
 
 HTTPD_PY := python $(NACL_SDK_ROOT)/tools/httpd.py
 serve:
index 220bc8d..fa70fff 100644 (file)
@@ -5,9 +5,9 @@ Steps to make the example work :
 2. Declare the environment variable NACL_SDK_ROOT as the root of the target platform within the SDK (ex: ~/nacl_sdk/pepper_34/) :
        $ export NACL_SDK_ROOT=/path/to/nacl_sdk/pepper_[your_version]
 
-3. Compile the Nit code with: `nitg --global converter.nit` or `make`.
+3. Compile the Nit code with: `nitg --semi-global converter.nit` or `make`.
 
-You must use the '--global' option. Some features in the standard library are not supported by the NaCL platform, the global compiler do not try to compile them.
+You must use the '--semi-global' (or `--global`) option. Some features in the standard library are not supported by the NaCL platform, the global compiler do not try to compile them.
 
 4. Start a local server using: `make serve`.
 
diff --git a/lib/buffered_ropes.nit b/lib/buffered_ropes.nit
new file mode 100644 (file)
index 0000000..b287871
--- /dev/null
@@ -0,0 +1,353 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# This file is free software, which comes along with NIT.  This software 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.  You can modify it is you want,  provided this header
+# is kept unaltered, and a notification of the changes is added.
+# You  are  allowed  to  redistribute it and sell it, alone or is a part of
+# another product.
+
+# Ropes with a special kind of Leaves that act similar to a `Buffer`
+#
+# When using this module, re-allocations are limited by the introduction
+# of a larger-than-necessary buffered area for the native part of a `String`
+# in an append-only fashion.
+#
+# Concretely, when concatenating two small strings of length `n` + `m` < `maxlen`
+# What happens is that a `maxlen` byte buffer is allocated, ready to receive more
+# bytes a posteriori without necessarily reallocating a new byte array.
+#
+# Theoretically, this should lower the number of concatenations
+# and reallocations when concatenating `String` objects.
+module buffered_ropes
+
+intrude import standard::ropes
+
+# Hidden buffer, used to simulate a `FlatBuffer` on a short string.
+#
+# This is to be used by low-level APIs because of its lack of
+# safety, if you use it, make sure you know what you are doing !
+#
+# Practically, it is the underlying representation of a `Leaf` in
+# the `Rope` block, its advantage is that it saves a bit more space
+# for future concatenations, without risking to overwrite previously
+# used space, making it suitable for Strings.
+#
+# Note for future use : Should there be parallel capacity in Nit at
+# some point, this is NOT thread safe !
+private class ManualBuffer
+       var ns: NativeString is noinit
+       # Current position in the `NativeString`
+       #
+       # It is used by the clients of `ManualBuffer` as a guard
+       # to detect if the concatenation in the `ManualBuffer`
+       # is safe or not.
+       #
+       # i.e. :
+       # Say we have two strings `x` and `y` referencing the
+       # same `ManualBuffer` `b`, `y` is the concatenation of
+       # `x` and another string.
+       #
+       # If we try to concatenate a `String` `z` to `x`, a new
+       # `ManualBuffer` will be created since `pos` and `x.length`
+       # do not match.
+       #
+       # However, if we concatenate the same `String` to `y`,
+       # the contents of `z` will be copied to the `ManualBuffer`.
+       var pos = 0
+
+       init do ns = new NativeString(maxlen)
+
+       fun [](i: Int): Char do return ns[i]
+end
+
+# Simple implementation of the iterator on Substrings for `Leaf`
+#
+# Basically just returns `self` encapsulated in a `FlatString`.
+private class LeafSubstrings
+       super IndexedIterator[Text]
+
+       var str: String
+       var avail = true
+
+       init(l: Leaf) do str = new FlatString.with_infos(l.buf.ns, l.length, 0, l.length - 1)
+
+       redef fun is_ok do return avail
+
+       redef fun next do avail = false
+
+       redef fun index do return 0
+
+       redef fun item do return str
+end
+
+# Leaf of a `Rope`, used as a buffered area for speedy concatenation.
+private class Leaf
+       super RopeString
+
+       private var buf: ManualBuffer
+       private var bns: NativeString is noinit
+       redef var length: Int is noinit
+
+       redef fun empty do return new Leaf(new ManualBuffer)
+
+       redef fun to_cstring do
+               var len = length
+               var ns = new NativeString(len + 1)
+               ns[len] = '\0'
+               buf.ns.copy_to(ns, len, 0, 0)
+               return ns
+       end
+
+       redef fun substrings do return new LeafSubstrings(self)
+
+       redef fun [](i) do return buf[i]
+
+       init do
+               bns = buf.ns
+               length = buf.pos
+       end
+
+       redef fun output do new FlatString.with_infos(buf.ns, length, 0, length - 1).output
+
+       redef fun to_upper do
+               var x = new ManualBuffer
+               var nns = x.ns
+               var ns = bns
+               var mlen = length
+               for i in [0..mlen[ do
+                       nns[i] = ns[i].to_upper
+               end
+               x.pos = mlen - 1
+               return new Leaf(x)
+       end
+
+       redef fun to_lower do
+               var x = new ManualBuffer
+               var nns = x.ns
+               var ns = bns
+               var mlen = length
+               for i in [0..mlen[ do
+                       nns[i] = ns[i].to_lower
+               end
+               x.pos = mlen - 1
+               return new Leaf(x)
+       end
+
+       redef fun reversed do
+               var x = new ManualBuffer
+               var nns = x.ns
+               var ns = bns
+               var mlen = length
+               var j = mlen - 1
+               for i in [0 .. mlen[ do
+                       nns[j] = ns[i]
+                       j -= 1
+               end
+               x.pos = mlen - 1
+               return new Leaf(x)
+       end
+
+       redef fun substring(from, len) do
+               return new FlatString.with_infos(buf.ns, len, from, from + len - 1)
+       end
+
+       redef fun insert_at(s, pos) do
+               var l = substring(0, pos)
+               var r = substring_from(pos)
+               return l + s + r
+       end
+
+       redef fun +(o) do
+               var s = o.to_s
+               var slen = s.length
+               var mlen = length
+               if slen == 0 then return self
+               if mlen == 0 then return s
+               var nlen = mlen + slen
+               if nlen > maxlen then return new Concat(self, s)
+               if s isa FlatString then
+                       var bpos = buf.pos
+                       var sits = s.items
+                       if bpos == mlen then
+                               sits.copy_to(buf.ns, slen, s.index_from, bpos)
+                               buf.pos = bpos + slen
+                               return new Leaf(buf)
+                       else
+                               var b = new ManualBuffer
+                               var nbns = b.ns
+                               bns.copy_to(nbns, mlen, 0, 0)
+                               sits.copy_to(nbns, slen, s.index_from, mlen)
+                               b.pos = nlen
+                               return new Leaf(b)
+                       end
+               else if s isa Leaf then
+                       var bpos = buf.pos
+                       var sbns = s.bns
+                       if bpos == mlen then
+                               sbns.copy_to(bns, slen, 0, bpos)
+                               buf.pos += slen
+                               return new Leaf(buf)
+                       else
+                               var b = new ManualBuffer
+                               var nbns = b.ns
+                               bns.copy_to(nbns, mlen, 0, 0)
+                               sbns.copy_to(nbns, slen, 0, mlen)
+                               b.pos = nlen
+                               return new Leaf(b)
+                       end
+               else if s isa Concat then
+                       if not s.left isa Concat then
+                               return new Concat(self + s.left, s.right)
+                       end
+                       return new Concat(self, s)
+               else
+                       var bpos = buf.pos
+                       var b = buf
+                       if bpos != mlen then
+                               b = new ManualBuffer
+                               bns.copy_to(b.ns, mlen, 0, 0)
+                       end
+                       for i in s.chars do
+                               bns[bpos] = i
+                               bpos += 1
+                       end
+                       return new Leaf(b)
+               end
+       end
+end
+
+redef class Concat
+       redef fun to_cstring do
+               var len = length
+               var ns = new NativeString(len + 1)
+               ns[len] = '\0'
+               var off = 0
+               for i in substrings do
+                       var ilen = i.length
+                       if i isa FlatString then
+                               i.items.copy_to(ns, ilen, i.index_from, off)
+                       else if i isa Leaf then
+                               i.buf.ns.copy_to(ns, ilen, 0, off)
+                       else
+                               abort
+                       end
+                       off += ilen
+               end
+               return ns
+       end
+
+       redef fun +(o) do
+               var s = o.to_s
+               var mlen = length
+               var slen = s.length
+               if s isa FlatString then
+                       var r = right
+                       var rlen = r.length
+                       if rlen + slen > maxlen then return new Concat(left, new Concat(r, s))
+                       return new Concat(left, r + s)
+               else if s isa Concat then
+                       return new Concat(self, s)
+               else if s isa Leaf then
+                       var r = right
+                       var rlen = r.length
+                       if rlen + slen > maxlen then return new Concat(left, new Concat(r, s))
+                       return new Concat(left, r + s)
+               else
+                       abort
+               end
+       end
+end
+
+redef class FlatString
+       redef fun +(o) do
+               var s = o.to_s
+               var slen = s.length
+               var mlen = length
+               if slen == 0 then return self
+               if mlen == 0 then return s
+               if s isa FlatString then
+                       if slen + mlen > maxlen then return new Concat(self, s)
+                       var mits = items
+                       var sifrom = s.index_from
+                       var mifrom = index_from
+                       var sits = s.items
+                       var b = new ManualBuffer
+                       var bns = b.ns
+                       mits.copy_to(bns, mlen, mifrom, 0)
+                       sits.copy_to(bns, slen, sifrom, mlen)
+                       b.pos = mlen + slen
+                       return new Leaf(b)
+               else if s isa Concat then
+                       var sl = s.left
+                       var sllen = sl.length
+                       if sllen + mlen > maxlen then return new Concat(self, s)
+                       return new Concat(sl + self, s.right)
+               else if s isa Leaf then
+                       if slen + mlen > maxlen then return new Concat(self, s)
+                       var mits = items
+                       var mifrom = index_from
+                       var sb = s.buf
+                       var b = new ManualBuffer
+                       var bns = b.ns
+                       items.copy_to(bns, mlen, mifrom, 0)
+                       sb.ns.copy_to(bns, slen, 0, mlen)
+                       b.pos = mlen + slen
+                       return new Leaf(b)
+               else
+                       abort
+               end
+       end
+end
+
+redef class Array[E]
+
+       # Fast implementation
+       redef fun to_s do
+               var l = length
+               if l == 0 then return ""
+               if l == 1 then if self[0] == null then return "" else return self[0].to_s
+               var its = _items
+               var na = new NativeArray[String](l)
+               var i = 0
+               var sl = 0
+               var mypos = 0
+               while i < l do
+                       var itsi = its[i]
+                       if itsi == null then
+                               i += 1
+                               continue
+                       end
+                       var tmp = itsi.to_s
+                       sl += tmp.length
+                       na[mypos] = tmp
+                       i += 1
+                       mypos += 1
+               end
+               var ns = new NativeString(sl + 1)
+               ns[sl] = '\0'
+               i = 0
+               var off = 0
+               while i < mypos do
+                       var tmp = na[i]
+                       var tpl = tmp.length
+                       if tmp isa FlatString then
+                               tmp.items.copy_to(ns, tpl, tmp.index_from, off)
+                               off += tpl
+                       else
+                               for j in tmp.substrings do
+                                       var slen = j.length
+                                       if j isa FlatString then
+                                               j.items.copy_to(ns, slen, j.index_from, off)
+                                       else if j isa Leaf then
+                                               j.buf.ns.copy_to(ns, slen, 0, off)
+                                       end
+                                       off += slen
+                               end
+                       end
+                       i += 1
+               end
+               return ns.to_s_with_length(sl)
+       end
+end
diff --git a/lib/bufferized_ropes.nit b/lib/bufferized_ropes.nit
deleted file mode 100644 (file)
index 18cfa4c..0000000
+++ /dev/null
@@ -1,370 +0,0 @@
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT.  This software 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.  You can modify it if you want,  provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You  are  allowed  to  redistribute it and sell it, alone or as a part of
-# another product.
-
-# Introduces ropes with buffered leaves
-module bufferized_ropes
-
-import standard
-intrude import standard::ropes
-
-# Leaf containing a FlatBuffer to optimize concatenation operations
-private class BufferLeaf
-       super Leaf
-
-       init(val: FlatBuffer) do
-               self.str = val
-               length = str.length
-       end
-
-end
-
-redef class Concat
-       redef fun to_leaf
-       do
-               if left == null then
-                       if right == null then return new StringLeaf("".as(FlatString))
-                       return right.to_leaf
-               end
-               if right == null then return left.as(not null).to_leaf
-               if left.length + right.length < buf_len then
-                       var b = new FlatBuffer.with_capacity(buf_len)
-                       b.append(left.to_leaf.str)
-                       b.append(right.to_leaf.str)
-                       return new BufferLeaf(b)
-               else
-                       var b = new FlatBuffer.with_capacity(left.length + right.length)
-                       b.append(left.to_leaf.str)
-                       b.append(right.to_leaf.str)
-                       return new StringLeaf(b.lazy_to_s(b.length))
-               end
-       end
-end
-
-redef class FlatText
-
-       # Creates a substring, only without any copy overhead for Buffers
-       # The call to lazy_substring ensures the creation of a FlatString, which is required for Leaves.
-       private fun lazy_substring(from: Int, length: Int): FlatString is abstract
-
-       # Same as substring_from, but without copy of the data for Buffers.
-       private fun lazy_substring_from(from: Int): FlatString is abstract
-end
-
-redef class FlatBuffer
-
-       # Same as to_s, only will not copy self before returning a String.
-       private fun lazy_to_s(len: Int): FlatString
-       do
-               return new FlatString.with_infos(items, len, 0, length - 1)
-       end
-
-       redef fun lazy_substring(from,length)
-       do
-               return new FlatString.with_infos(items, length, from, from + length - 1)
-       end
-
-       redef fun lazy_substring_from(from)
-       do
-               var newlen = length - from
-               return new FlatString.with_infos(items, newlen, from, from + newlen - 1)
-       end
-
-end
-
-redef class FlatString
-
-       redef fun lazy_substring(from, len) do return substring(from,len).as(FlatString)
-
-       redef fun lazy_substring_from(from) do return substring_from(from).as(FlatString)
-
-end
-
-redef class Rope
-
-       # Empty Rope
-       init do root = new BufferLeaf(new FlatBuffer.with_capacity(buf_len))
-
-end
-
-redef class RopeString
-
-       init from(s: String) do
-               if s.length < buf_len then
-                       var b = new FlatBuffer.with_capacity(buf_len)
-                       b.append(s)
-                       root = new BufferLeaf(b)
-               else
-                       if s isa RopeString then root = s.root else root = new StringLeaf(s.as(FlatString))
-               end
-       end
-
-       redef fun +(o) do return insert_at(o.to_s, length)
-
-       # Inserts a String `str` at position `pos`
-       redef fun insert_at(str, pos)
-       do
-               if str.length == 0 then return self
-
-               assert pos >= 0 and pos <= length
-
-               if pos == length then
-                       var r = root
-                       if r isa BufferLeaf then
-                               var b = r.str.as(FlatBuffer)
-                               if r.length + str.length < b.capacity then
-                                       b.append(str)
-                                       return new RopeString.from_root(new BufferLeaf(b))
-                               end
-                       end
-               end
-
-               var path = node_at(pos)
-
-               var cct: RopeNode
-
-               if path.offset == path.leaf.length then
-                       cct = build_node_len_offset(path, str)
-               else if path.offset == 0 then
-                       cct = build_node_zero_offset(path, str)
-               else
-                       cct = build_node_other(path,str)
-               end
-
-               if path.stack.is_empty then return new RopeString.from_root(cct)
-
-               var tmp = path.stack.pop
-               var last_concat: Concat
-
-               if tmp.left then
-                       last_concat = new Concat(cct,tmp.node.right.as(not null))
-               else
-                       last_concat = new Concat(tmp.node.left.as(not null), cct)
-               end
-
-               for i in path.stack.reverse_iterator do
-                       var nod: Concat
-                       if i.left then
-                               nod = new Concat(last_concat, i.node.right.as(not null))
-                       else
-                               nod = new Concat(i.node.left.as(not null), last_concat)
-                       end
-                       last_concat = nod
-               end
-
-               return new RopeString.from_root(last_concat)
-       end
-
-       redef fun substring(pos, len)
-       do
-               if pos < 0 then
-                       len += pos
-                       pos = 0
-               end
-
-               if pos + len > length then len = length - pos
-
-               if len <= 0 then return new RopeString
-
-               var path = node_at(pos)
-
-               var lf = path.leaf
-               var offset = path.offset
-
-               var s: FlatString
-               if lf isa StringLeaf then
-                       s = lf.str.as(FlatString)
-               else
-                       s = lf.str.as(FlatBuffer).lazy_to_s(lf.length)
-               end
-
-               if path.leaf.str.length - offset > len then
-                       lf = new StringLeaf(s.substring(offset,len).as(FlatString))
-               else
-                       lf = new StringLeaf(s.substring_from(offset).as(FlatString))
-               end
-
-               var nod: RopeNode = lf
-
-               if lf.length == len then return new RopeString.from_root(lf)
-
-               var lft: nullable RopeNode
-               var rht: nullable RopeNode
-
-               for i in path.stack.reverse_iterator do
-                       if i.right then continue
-                       lft = nod
-                       rht = i.node.right
-                       nod = new Concat(lft, rht)
-               end
-
-               var ret = new RopeString
-               ret.root = nod
-
-               path = ret.node_at(len-1)
-
-               offset = path.offset
-
-               lf = path.leaf
-
-               if lf isa StringLeaf then
-                       s = lf.str.as(FlatString)
-               else
-                       s = lf.str.as(FlatBuffer).lazy_to_s(lf.length)
-               end
-
-               nod = new StringLeaf(s.substring(0, offset+1).as(FlatString))
-
-               for i in path.stack.reverse_iterator do
-                       if i.left then continue
-                       rht = nod
-                       lft = i.node.left
-                       nod = new Concat(lft, rht)
-               end
-
-               ret.root = nod
-
-               return ret
-       end
-
-       private fun build_node_zero_offset(path: Path, s: String): RopeNode
-       do
-               var finlen = path.leaf.length + s.length
-               if finlen <= buf_len then
-                       var b = new FlatBuffer.with_capacity(buf_len)
-                       b.append(s)
-                       b.append(path.leaf.str)
-                       if finlen == buf_len then return new StringLeaf(b.lazy_to_s(finlen))
-                       return new BufferLeaf(b)
-               end
-               var rht = path.leaf
-               var lft: RopeNode
-               if s isa FlatString then
-                       if s.length > buf_len then
-                               lft = new StringLeaf(s)
-                       else
-                               var b = new FlatBuffer
-                               b.append(s)
-                               lft = new BufferLeaf(b)
-                       end
-               else
-                       lft = s.as(RopeString).root
-               end
-               return new Concat(lft, rht)
-       end
-
-       private fun build_node_len_offset(path: Path, s: String): RopeNode
-       do
-               var leaf = path.leaf
-               if leaf isa BufferLeaf then
-                       if s.length > buf_len then
-                               if s isa FlatString then
-                                       return new Concat(leaf, new StringLeaf(s))
-                               else
-                                       return new Concat(leaf, s.as(Rope).root)
-                               end
-                       end
-                       var finlen = leaf.length + s.length
-                       var buf = leaf.str.as(FlatBuffer)
-                       var cap = buf.capacity
-                       # Meaning the buffer was modified elsewhere
-                       # Therefore, we create a new one
-                       if leaf.length != buf.length then
-                               var b = new FlatBuffer.with_capacity(buf_len)
-                               b.append(buf.lazy_to_s(leaf.length))
-                               buf = b
-                       end
-                       if finlen <= cap then
-                               buf.append(s)
-                               if finlen == buf_len then return new StringLeaf(buf.lazy_to_s(finlen))
-                               return new BufferLeaf(buf)
-                       else
-                               var l_len = finlen - cap
-                               buf.append(s.substring(0,l_len))
-                               var b2 = new FlatBuffer.with_capacity(buf_len)
-                               b2.append(s.substring_from(l_len))
-                               var left_leaf = new StringLeaf(buf.lazy_to_s(buf.length))
-                               var right_leaf = new BufferLeaf(b2)
-                               var cct = new Concat(left_leaf, right_leaf)
-                               return cct
-                       end
-               else
-                       var lft = leaf
-                       var rht: RopeNode
-                       if s.length >= buf_len then
-                               if s isa FlatString then rht = new StringLeaf(s) else rht = s.as(Rope).root
-                       else
-                               var buf = new FlatBuffer.with_capacity(buf_len)
-                               buf.append(s)
-                               rht = new BufferLeaf(buf)
-                       end
-                       return new Concat(lft,rht)
-               end
-       end
-
-       private fun build_node_other(path: Path,str: String): RopeNode
-       do
-               var lf = path.leaf
-               var s: FlatString
-               if lf isa BufferLeaf then
-                       var b = lf.str.as(FlatBuffer)
-                       s = b.lazy_to_s(lf.length)
-               else
-                       s = lf.str.as(FlatString)
-               end
-               var l_str = s.lazy_substring(0, path.offset)
-               var r_str = s.lazy_substring_from(path.offset)
-               if s.length + str.length < buf_len then
-                       var buf = new FlatBuffer.with_capacity(buf_len)
-                       buf.append(l_str)
-                       buf.append(str)
-                       buf.append(r_str)
-                       return new BufferLeaf(buf)
-               end
-               var child: RopeNode
-               if str isa FlatString then child = new StringLeaf(str) else child = str.as(Rope).root
-               var l_cct = new Concat(new StringLeaf(l_str), child)
-               var r_cct = new Concat(l_cct, new StringLeaf(r_str))
-               return r_cct
-       end
-
-end
-
-redef class SubstringsIterator
-
-       # Compute the bounds of the current substring and makes the substring
-       redef fun make_substring
-       do
-               var l = nodes.item
-               var s = l.str
-               var min = 0
-               var length = l.length
-               if nodes.index < pos then
-                       min = pos - nodes.index
-               end
-               substring = s.lazy_substring(min, length)
-       end
-
-end
-
-redef class ReverseSubstringsIterator
-
-       redef fun make_substring
-       do
-               var l = leaves.item
-               var s = l.str
-               if pos > (leaves.index + l.length - 1) then return
-               str = s.lazy_substring(0, (pos - leaves.index + 1))
-       end
-
-end
-
-# Default size of a buffer in a rope leaf.
-fun buf_len: Int do return 200
-
diff --git a/lib/cartesian.nit b/lib/cartesian.nit
new file mode 100644 (file)
index 0000000..7090050
--- /dev/null
@@ -0,0 +1,181 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# This file is free software, which comes along with NIT.  This software 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.  You can modify it is you want,  provided this header
+# is kept unaltered, and a notification of the changes is added.
+# You  are  allowed  to  redistribute it and sell it, alone or is a part of
+# another product.
+
+# Cartesian products on heterogeneous collections.
+#
+# This module is a proof-of-concept to propose memory-efficient views on collections.
+#
+# This is a specific alternative to `combinations`, that focuses only highly efficient
+# Cartesian products between collections of different types.
+#
+#    Collection[Int] X Collection[String] -> Collection[(Int,String)]
+#
+# However, in Nit, there in no native *tuple* type.
+# So we need a first building block, a pair.
+
+# A simple read-only pair of two elements `e` and `f`.
+class Pair[E, F]
+       # The first element of the pair
+       var e: E
+
+       # The second element of the pair
+       var f: F
+
+       # The parenthesized notation.
+       #
+       # ~~~
+       # var p = new Pair[Int, String](1, "hello")
+       # assert p.to_s == "(1,hello)"
+       # ~~~
+       redef fun to_s
+       do
+               var es = e or else ""
+               var fs = f or else ""
+               return "({es},{fs})"
+       end
+
+       # Untyped pair equality.
+       #
+       # ~~~
+       # var p1 = new Pair[Object, Object](1, 2)
+       # var p2 = new Pair[Int, Int](1, 2)
+       # var p3 = new Pair[Int, Int](1, 3)
+       #
+       # assert p1 == p2
+       # assert p2 != p3
+       # ~~~
+       #
+       # Untyped because we want that `p1 == p2` above.
+       # So the method just ignores the real types of `E` and `F`.
+       redef fun ==(o) do return o isa Pair[nullable Object, nullable Object] and e == o.e and f == o.f
+
+       redef fun hash do return e.hash * 13 + f.hash * 27 # Magic numbers are magic!
+end
+
+# A view of a Cartesian-product collection over two collections.
+#
+# A Cartesian product over two collections is just a collection of pairs.
+# Therefore, this view *contains* all the pairs of elements constructed by associating each
+# element of the first collection to each element of the second collection.
+#
+# However the view is memory-efficient and the pairs are created only when needed.
+#
+# A simple Cartesian product
+# ~~~~
+# var c1 = [1,2]
+# var c2 = ["a","b","c"]
+# var c12 = new Cartesian[Int,String](c1, c2)
+# assert c12.length    == 6
+# assert c12.join(";") == "(1,a);(1,b);(1,c);(2,a);(2,b);(2,c)" # All the 6 pairs
+# ~~~~
+#
+# Note: because it is a view, changes on the base collections are reflected on the view.
+#
+# E.g. c12 is a view on c1 and c2, so if c1 changes, then c12 "changes".
+# ~~~~
+# assert c2.pop        == "c"
+# assert c12.length    == 4
+# assert c12.join(";") == "(1,a);(1,b);(2,a);(2,b)" # All the 4 remaining pairs
+# ~~~~
+#
+# Cartesian objects are collections, so can be used to build another Cartesian object.
+# ~~~~
+# var c3 = [1000..2000[
+# var c123 = new Cartesian[Pair[Int,String],Int](c12, c3)
+# assert c123.length   == 4000
+# ~~~~
+#
+# All methods of Collection are inherited, it is so great!
+#
+# E.g. search elements?
+# ~~~~
+# var p12 = new Pair[Int,String](2,"b")
+# assert c12.has(p12)      == true
+# var p123 = new Pair[Pair[Int, String], Int](p12, 1500)
+# var p123bis = new Pair[Pair[Int, String], Int](p12, 0)
+# assert c123.has(p123)    == true
+# assert c123.has(p123bis) == false
+# ~~~~
+class Cartesian[E, F]
+       super Collection[Pair[E,F]]
+
+       # The first collection
+       var ce: Collection[E]
+
+       # The second collection
+       var cf: Collection[F]
+
+       redef fun length do return ce.length * cf.length # optional, but so efficient...
+
+       redef fun iterator do return new CartesianIterator[E,F](self)
+
+       # Returns a new Cartesian where the first collection is the second.
+       # Because the full collection is virtual, the operation is cheap!
+       fun swap: Cartesian[F, E] do return new Cartesian[F, E](cf, ce)
+end
+
+# An iterator over a `Cartesian`-product collection.
+class CartesianIterator[E,F]
+       super Iterator[Pair[E,F]]
+
+       # The associated Cartesian-product collection.
+       var collection: Cartesian[E,F]
+
+       # The iterator over the first collection of the Cartesian product.
+       # Will be used only once.
+       private var ice: Iterator[E] is noinit
+
+       # The iterator over the second collection of the Cartesian product.
+       # Will be used once for each element of the first collection.
+       private var icf: Iterator[F] is noinit
+
+       init do
+               # Initialize each iterator
+               ice = collection.ce.iterator
+               icf = collection.cf.iterator
+       end
+
+       redef fun is_ok do return ice.is_ok and icf.is_ok
+
+       redef fun item do
+               # We lazily create the pair here
+               var res = item_cache
+               if res == null then
+                       res = new Pair[E,F](ice.item, icf.item)
+                       item_cache = res
+               end
+               return res
+       end
+
+       # Cached pair created by `item` and cleared by `next`.
+       private var item_cache: nullable Pair[E,F] = null
+
+       redef fun next do
+               # Next item in the second iterator
+               icf.next
+               if not icf.is_ok then
+                       # If it is over, then reset it and advance the first iterator
+                       icf = collection.cf.iterator
+                       ice.next
+               end
+               # Reset the cache
+               item_cache = null
+       end
+
+       # First member of `item`.
+       #
+       # This method shortcut the allocation of a `Pair`, thus should be more time and memory efficient.
+       fun item_e: E do return ice.item
+
+       # Second member of `item`.
+       #
+       # This method shortcut the allocation of a `Pair`, thus should be more time and memory efficient.
+       fun item_f: E do return icf.item
+end
diff --git a/lib/combinations.nit b/lib/combinations.nit
new file mode 100644 (file)
index 0000000..4076c03
--- /dev/null
@@ -0,0 +1,439 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# This file is free software, which comes along with NIT.  This software 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.  You can modify it is you want,  provided this header
+# is kept unaltered, and a notification of the changes is added.
+# You  are  allowed  to  redistribute it and sell it, alone or is a part of
+# another product.
+
+# Cartesian products, combinations and permutation on collections.
+#
+# This module offers memory-efficient views on combinatoric collections.
+# Methods of the views create objects only when needed.
+# Moreover, produced objects during iterations are free to be collected and
+# their memory reused.
+#
+# This enable these views and method to works with very combinatoric large collections.
+#
+# When small combinatoric views need to be kept in memory (for fast access by example).
+# The `Collection::to_a` method and other related factories can be used to transform
+# the combinatoric views into extensive collections,
+module combinations
+
+redef class Collection[E]
+       # Cartesian product, over `r` times `self`.
+       #
+       # See `CartesianCollection` for details.
+       #
+       # FIXME: Cannot be used if RTA is enabled. So `niti` or `--erasure` only.
+       fun product(r: Int): Collection[SequenceRead[E]]
+       do
+               return new CartesianCollection[E]([self]*r)
+       end
+
+       # All `r`-length permutations on self (all possible ordering) without repeated elements.
+       #
+       # See `CartesianCollection` for details.
+       #
+       # FIXME: Cannot be used if RTA is enabled. So `niti` or `--erasure` only.
+       fun permutations(r: Int): Collection[SequenceRead[E]]
+       do
+               var res = new CombinationCollection[E](self, r)
+               res.are_sorted = false
+               res.are_unique = true
+               return res
+       end
+
+       # All `r`-length combinations on self (in same order) without repeated elements.
+       #
+       # See `CartesianCollection` for details.
+       #
+       # FIXME: Cannot be used if RTA is enabled. So `niti` or `--erasure` only.
+       fun combinations(r: Int): Collection[SequenceRead[E]]
+       do
+               var res = new CombinationCollection[E](self, r)
+               res.are_sorted = true
+               res.are_unique = true
+               return res
+       end
+
+       # All `r`-length combination on self (in same order) with repeated elements.
+       #
+       # See `CartesianCollection` for details.
+       #
+       # FIXME: Cannot be used if RTA is enabled. So `niti` or `--erasure` only.
+       fun combinations_with_replacement(r: Int): Collection[SequenceRead[E]]
+       do
+               var res = new CombinationCollection[E](self, r)
+               res.are_sorted = true
+               res.are_unique = false
+               return res
+       end
+end
+
+# A view of a Cartesian-product collection over homogeneous collections.
+#
+# Therefore, this view *generates* all the sequences of elements constructed by associating
+# en element for each one of the original collections.
+#
+# It is equivalent to doing nesting `for` for each collection.
+#
+# ~~~~
+# var xs = [1, 2, 3]
+# var ys = [8, 9]
+# var xys = new CartesianCollection[Int]([xs, ys])
+# assert xys.length == 6
+# assert xys.to_a == [[1,8], [1,9], [2,8], [2,9], [3,8], [3,9]]
+# ~~~~
+#
+# The pattern of the generate sequences produces a lexicographical order.
+#
+# Because it is a generator, it is memory-efficient and the sequences are created only when needed.
+#
+# Note: because it is a view, changes on the base collections are reflected on the view.
+#
+# ~~~~
+# assert xs.pop == 3
+# assert ys.pop == 9
+# assert xys.to_a == [[1,8], [2,8]]
+# ~~~~
+class CartesianCollection[E]
+       super Collection[SequenceRead[E]]
+
+       # The base collections used to generate the sequences.
+       var collections: SequenceRead[Collection[E]]
+
+       redef fun length
+       do
+               var res = 1
+               for c in collections do res = res * c.length
+               return res
+       end
+
+       redef fun iterator do return new CartesianIterator[E](self)
+end
+
+private class CartesianIterator[E]
+       super Iterator[SequenceRead[E]]
+       var collection: CartesianCollection[E]
+
+       # The array of iterations that will be increased in the lexicographic order.
+       private var iterators = new Array[Iterator[E]]
+
+       init
+       do
+               for c in collection.collections do
+                       var it = c.iterator
+                       iterators.add it
+                       if not it.is_ok then is_ok = false
+               end
+       end
+
+       redef var is_ok = true
+
+       redef fun item
+       do
+               var len = iterators.length
+               var res = new Array[E].with_capacity(len)
+               for i in [0..len[ do
+                       var it = iterators[i]
+                       res.add(it.item)
+               end
+               return res
+       end
+
+       redef fun next
+       do
+               var rank = iterators.length - 1
+
+               # Odometer-like increment starting from the last iterator
+               loop
+                       var it = iterators[rank]
+                       it.next
+                       if it.is_ok then return
+
+                       # The iterator if over
+                       if rank == 0 then
+                               # It it is the first, then the whole thing is over
+                               is_ok = false
+                               return
+                       end
+
+                       # If not, restart the iterator and increment the previous one
+                       # (like a carry)
+                       iterators[rank] = collection.collections[rank].iterator
+                       rank -= 1
+               end
+       end
+end
+
+# A view of some combinations over a base collections.
+#
+# This view *generates* some combinations and permutations on a collection.
+#
+# By default, the generated sequences are combinations:
+#
+#   * each sequence has a length of `repeat`
+#   * elements are in sorted order (see `are_sorted` for details)
+#   * no repeated element (see `are_unique` for details)
+#
+# ~~~~
+# var xs = [1, 2, 3]
+# var cxs = new CombinationCollection[Int](xs, 2)
+# assert cxs.length == 3
+# assert cxs.to_a == [[1,2], [1,3], [2,3]]
+# ~~~~
+#
+# Other kind of combinations can be generated by tweaking the attributes `are_sorted` and `are_unique`.
+#
+# * for permutation:
+#
+# ~~~~
+# cxs.are_sorted = false
+# cxs.are_unique = true
+# assert cxs.length == 6
+# assert cxs.to_a == [[1,2], [1,3], [2,1], [2,3], [3,1], [3,2]]
+# ~~~~
+#
+# * for combinations with replacement:
+#
+# ~~~~
+# cxs.are_sorted = true
+# cxs.are_unique = false
+# assert cxs.length == 6
+# assert cxs.to_a == [[1,1], [1,2], [1,3], [2,2], [2,3], [3,3]]
+# ~~~~
+#
+# * for product:
+#
+# ~~~~
+# cxs.are_sorted = false
+# cxs.are_unique = false
+# assert cxs.length == 9
+# assert cxs.to_a == [[1,1], [1,2], [1,3], [2,1], [2,2], [2,3], [3,1], [3,2], [3,3]]
+# ~~~~
+#
+# However, in the last case, a faster alternative is to use `CartesianCollection`:
+#
+# ~~~~
+# var cp = new CartesianCollection[Int]([xs] * 2)
+# assert cp.to_a == cxs.to_a
+# ~~~~
+#
+# As seen in the examples, the patterns of the generated sequences produce a lexicographical order.
+#
+# Because it is a generator, it is memory-efficient and the sequences are created only when needed.
+#
+# Note: because it is a view, changes on the base collection are reflected on the view.
+#
+# ~~~~
+# assert xs.pop == 3
+# cxs.are_sorted = true
+# cxs.are_unique = true
+# assert cxs.to_a == [[1,2]]
+# ~~~~
+class CombinationCollection[E]
+       super Collection[SequenceRead[E]]
+
+       # The base collection used to generate the sequences.
+       var collection: Collection[E]
+
+       # The maximum length of each generated sequence.
+       var repeat: Int
+
+       init
+       do
+               assert repeat >= 0
+       end
+
+       # Are the elements in the generated sequences sorted?
+       # Default `true`.
+       #
+       # When `true`, the original order is preserved.
+       #
+       # Elements are compared by their order in the base collection,
+       # not by their intrinsic value or comparability.
+       #
+       # ~~~~
+       # var xs = [1, 1, 2]
+       # var cxs = new CombinationCollection[Int](xs, 2)
+       # cxs.are_sorted = true
+       # assert cxs.to_a == [[1,1], [1,2], [1, 2]]
+       # cxs.are_sorted = false
+       # assert cxs.to_a == [[1,1], [1,2], [1, 1], [1, 2], [2, 1], [2, 1]]
+       # ~~~~
+       var are_sorted = true is writable
+
+       # Are the element in the generated sequence unique?
+       # Default `true`.
+       #
+       # When `true`, an element cannot be reused in the same sequence (no replacement).
+       #
+       # Elements are distinguished by their order in the base collection,
+       # not by their intrinsic value or equality.
+       #
+       # ~~~~
+       # var xs = [1, 1, 2]
+       # var cxs = new CombinationCollection[Int](xs, 2)
+       # cxs.are_unique = true
+       # assert cxs.to_a == [[1,1], [1,2], [1, 2]]
+       # cxs.are_unique = false
+       # assert cxs.to_a == [[1,1], [1,1], [1,2], [1,1], [1,2], [2,2]]
+       # ~~~~
+       var are_unique = true is writable
+
+       redef fun length
+       do
+               var n = collection.length
+               if are_unique then
+                       if repeat > n then
+                               return 0
+                       end
+                       if are_sorted then
+                               return n.factorial / repeat.factorial
+                       else
+                               return n.factorial / (n-repeat).factorial
+                       end
+               else
+                       if are_sorted then
+                               return (n+repeat-1).factorial / repeat.factorial / (n-1).factorial
+                       else
+                               return n ** repeat
+                       end
+               end
+       end
+
+       redef fun iterator do
+               return new CombinationIterator[E](self)
+       end
+end
+
+private class CombinationIterator[E]
+       super Iterator[SequenceRead[E]]
+       var product: CombinationCollection[E]
+
+       private var iterators = new Array[Iterator[E]]
+       private var indices = new Array[Int]
+
+       var are_sorted: Bool is noinit
+       var are_unique: Bool is noinit
+
+       init
+       do
+               are_sorted = product.are_sorted
+               are_unique = product.are_unique
+
+               for rank in [0..product.repeat[ do
+                       reset_iterator(rank)
+               end
+       end
+
+       redef var is_ok = true
+
+       redef fun item
+       do
+               var len = product.repeat
+               var res = new Array[E].with_capacity(len)
+               for i in [0..len[ do
+                       var it = iterators[i]
+                       res.add(it.item)
+               end
+               return res
+       end
+
+       redef fun next
+       do
+               var rank = product.repeat - 1
+
+               loop
+                       var it = iterators[rank]
+
+                       if are_unique and not are_sorted then
+                               var idx = indices[rank] + 1
+                               it.next
+                               var adv = next_free(rank, idx)
+                               for i in [idx..adv[ do it.next
+                               indices[rank] = adv
+                       else
+                               it.next
+                               indices[rank] += 1
+                       end
+
+                       if it.is_ok then break
+                       if rank == 0 then
+                               is_ok = false
+                               return
+                       end
+                       rank -= 1
+               end
+
+               for r in [rank+1..product.repeat[ do
+                       reset_iterator(r)
+               end
+       end
+
+       private fun next_free(rank: Int, start: Int): Int
+       do
+               loop
+                       for i in [0..rank[ do
+                               if indices[i] == start then
+                                       start += 1
+                                       continue label
+                               end
+                       end
+                       break label
+               end label
+               return start
+       end
+
+       private fun reset_iterator(rank: Int): Iterator[E]
+       do
+               var it = product.collection.iterator
+               iterators[rank] = it
+               var skip = 0
+
+               if (not are_sorted and not are_unique) or rank == 0 then
+                       # DO NOTHING
+               else if are_sorted and are_unique then
+                       skip = indices[rank-1] + 1
+               else if are_sorted then
+                       skip = indices[rank-1]
+               else
+                       skip = next_free(rank, 0)
+               end
+
+               for i in [0..skip[ do it.next
+               indices[rank] = skip
+               if not it.is_ok then is_ok = false
+               return it
+       end
+
+       fun need_skip: Bool
+       do
+               if not are_sorted and not are_unique then
+                       return false
+               else if are_sorted and are_unique then
+                       var max = -1
+                       for i in indices do
+                               if i <= max then return true
+                               max = i
+                       end
+                       return false
+               else if are_sorted then
+                       var max = -1
+                       for i in indices do
+                               if i < max then return true
+                               max = i
+                       end
+                       return false
+               else
+                       # are_unique
+                       for i in indices do
+                               if indices.count(i) > 1 then return true
+                       end
+                       return false
+               end
+       end
+end
index d9d1f27..389c6f6 100644 (file)
@@ -38,7 +38,7 @@ redef class Sys
        private var jvm_cache: nullable JavaVM = null
        private var jni_env_cache: nullable JniEnv = null
 
-       # Default Java Virtual Machine to use (will be instanciated using
+       # Default Java Virtual Machine to use (will be instantiated using
        # `create_default_jvm` if not already set)
        fun jvm: JavaVM
        do
@@ -59,13 +59,13 @@ redef class Sys
        # Sets the current default JNI env (use with `jvm=`)
        fun jni_env=(jni_env: JniEnv) do jni_env_cache = jni_env
 
-       # Called by `jvm` and `jni_env` to instanciate a Java Virual Machine.
+       # Called by `jvm` and `jni_env` to instantiate a Java Virtual Machine.
        # Used mostly for the FFI with Java.
        protected fun create_default_jvm
        do
                var builder = new JavaVMBuilder
 
-               # By default, look for Java classes in a jar file the same dir as the executable
+               # By default, look for Java classes in a jar file the same directory as the executable
                builder.options.add "-Djava.class.path={sys.program_name}.jar"
 
                var jvm = builder.create_jvm
@@ -79,7 +79,7 @@ redef class Sys
        fun load_jclass(name: NativeString): JClass import jni_env `{
                JNIEnv *nit_ffi_jni_env = Sys_jni_env(recv);
 
-               // retreive the implementation Java class
+               // retrieve the implementation Java class
                jclass java_class = (*nit_ffi_jni_env)->FindClass(nit_ffi_jni_env, name);
                if (java_class == NULL) {
                        fprintf(stderr, "Nit FFI with Java error: failed to load class.\\n");
@@ -135,6 +135,7 @@ redef class NativeString
 end
 
 redef class Text
+       # Get `self` as a `JavaString`
        fun to_java_string: JavaString do return to_cstring.to_java_string
 end
 
@@ -177,4 +178,26 @@ redef extern class JavaObject
        private fun pop_from_local_frame_with_env(jni_env: JniEnv): SELF `{
                return (*jni_env)->PopLocalFrame(jni_env, recv);
        `}
+
+       # Is `self` null in Java?
+       #
+       # Since Java type system doesn't have the same `nullable` concept as Nit's,
+       # the two systems are not directly compatible. Any Nit instances of
+       # `JavaObject` may hold a Java null.
+       #
+       # To benefit from the safer type system of Nit, it is recommended to check
+       # the return of all extern methods implemented in Java to ensure the value
+       # is not a Java null. In case it is, you should replace it by a normal Nit
+       # `null`.
+       fun is_java_null: Bool in "Java" `{ return recv == null; `}
+
+       # `JavaString` representation of `self` using Java's `toString`
+       fun to_java_string: JavaString in "Java" `{ return recv.toString(); `}
+
+       # Use Java's `toString` for any `JavaObject`
+       redef fun to_s
+       do
+               if is_java_null then return super
+               return to_java_string.to_s
+       end
 end
diff --git a/lib/neo4j/json_store.nit b/lib/neo4j/json_store.nit
new file mode 100644 (file)
index 0000000..49e055c
--- /dev/null
@@ -0,0 +1,199 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# This file is free software, which comes along with NIT. This software 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. You can modify it is you want, provided this header
+# is kept unaltered, and a notification of the changes is added.
+# You are allowed to redistribute it and sell it, alone or is a part of
+# another product.
+
+# Uses JSON as a storage medium for a Neo4j subgraph.
+module neo4j::json_store
+
+import neo4j
+private import template
+
+# A Neo4j graph that uses as a storage medium.
+#
+# The graph is stored as a JSON object with the following properties:
+#
+# * `"nodes"`: An array with all nodes. Each node is an object with the
+# following properties:
+#      * `"id"`: The ID (`Int`) that uniquely identifies the node in the current
+#      graph.
+#      * `"labels"`: An array of all applied labels.
+#      * `"properties"`: An object mapping each defined property to its value.
+# * `"links"`: An array with all relationships. Each relationship is an object
+# with the following properties:
+#      * `"type"`: The type (`String`) of the relationship.
+#      * `"properties"`: An object mapping each defined property to its value.
+#      * `"from"`: The ID (`Int`) of the source node.
+#      * `"to"`: The ID (`Int`) of the destination node.
+#
+# TODO Refine the graph API instead when it will be available.
+class JsonGraph
+       super Jsonable
+
+       # All nodes in the graph.
+       var nodes: SimpleCollection[NeoNode] = new Array[NeoNode]
+
+       # All relationships in the graph.
+       var links: SimpleCollection[NeoEdge] = new Array[NeoEdge]
+
+       # Create an empty graph.
+       init do end
+
+       # Retrieve the graph from the specified JSON value.
+       #
+       #     var graph = new JsonGraph
+       #     var a = new NeoNode
+       #     a.labels.add "Foo"
+       #     a["answer"] = 42
+       #     a["Ultimate question of"] = new JsonArray.from(["life",
+       #               "the Universe", "and Everything."])
+       #     graph.nodes.add a
+       #     var b = new NeoNode
+       #     b.labels.add "Foo"
+       #     b.labels.add "Bar"
+       #     graph.nodes.add b
+       #     graph.links.add new NeoEdge(a, "BAZ", b)
+       #     #
+       #     graph = new JsonGraph.from_json(graph.to_json)
+       #     assert 1 == graph.links.length
+       #     for link in graph.links do
+       #       assert "BAZ" == link.rel_type
+       #       assert a.labels == link.from.labels
+       #       for k, v in a.properties do assert v == link.from.properties[k]
+       #       assert b.labels == link.to.labels
+       #       for k, v in b.properties do assert v == link.to.properties[k]
+       #     end
+       #     assert 2 == graph.nodes.length
+       init from_json(t: Text) do
+               from_json_object(t.to_jsonable.as(JsonObject))
+       end
+
+       # Retrieve the graph from the specified JSON object.
+       init from_json_object(o: JsonObject) do
+               var node_by_id = new HashMap[Int, NeoNode]
+               var nodes = o["nodes"].as(JsonArray)
+               for json_node in nodes do
+                       assert json_node isa JsonObject
+                       var node = new NeoNode.from_json_object(json_node)
+                       node_by_id[json_node["id"].as(Int)] = node
+                       self.nodes.add node
+               end
+               var links = o["links"].as(JsonArray)
+               for json_link in links do
+                       assert json_link isa JsonObject
+                       var from = node_by_id[json_link["from"].as(Int)]
+                       var to = node_by_id[json_link["to"].as(Int)]
+                       var rel_type = json_link["type"].as(String)
+                       var json_properties = json_link["properties"].as(JsonObject)
+                       var link = new NeoEdge(from, rel_type, to)
+                       link.properties.recover_with(json_properties)
+                       self.links.add link
+               end
+       end
+
+       redef fun to_json do
+               var t = new Template
+               t.add "\{\"nodes\":["
+               var i = 0
+               for n in nodes do
+                       if i > 0 then t.add ","
+                       t.add n.to_json
+                       i += 1
+               end
+               t.add "],\"links\":["
+               i = 0
+               for link in links do
+                       if i > 0 then t.add ","
+                       t.add link.to_json
+                       i += 1
+               end
+               t.add "]\}"
+               return t.write_to_string
+       end
+end
+
+# Make `NeoNode` `Jsonable`.
+redef class NeoNode
+       super Jsonable
+
+       # Retrieve the node from the specified JSON value.
+       #
+       # Note: Here, the `"id"` is optional and ignored.
+       #
+       # SEE: `JsonGraph`
+       #
+       #     var node = new NeoNode.from_json("""
+       #     {
+       #       "labels": ["foo", "Bar"],
+       #       "properties": {
+       #               "baz": 42
+       #       }
+       #     }
+       #     """)
+       #     assert ["foo", "Bar"] == node.labels
+       #     assert 42 == node["baz"]
+       init from_json(t: Text) do
+               from_json_object(t.to_jsonable.as(JsonObject))
+       end
+
+       # Retrieve the node from the specified JSON value.
+       #
+       # Note: Here, the `"id"` is optional and ignored.
+       #
+       # SEE: `JsonGraph`
+       init from_json_object(o: JsonObject) do
+               init
+               var labels = o["labels"].as(JsonArray)
+               for lab in labels do self.labels.add(lab.as(String))
+               var json_properties = o["properties"].as(JsonObject)
+               properties.recover_with(json_properties)
+       end
+
+       # Get the JSON representation of `self`.
+       #
+       # SEE: `JsonGraph`
+       redef fun to_json do
+               var t = new Template
+               t.add "\{\"id\":"
+               t.add object_id.to_json
+               t.add ",\"labels\":["
+               var i = 0
+               for lab in labels do
+                       if i > 0 then t.add ","
+                       t.add lab.to_json
+                       i += 1
+               end
+               t.add "],\"properties\":"
+               t.add properties.to_json
+               t.add "}"
+               return t.write_to_string
+       end
+
+       redef fun to_s do return to_json
+end
+
+# Make `NeoEdge` `Jsonable`.
+redef class NeoEdge
+       super Jsonable
+
+       redef fun to_json do
+               var t = new Template
+               t.add "\{\"type\":"
+               t.add rel_type.to_json
+               t.add ",\"properties\":"
+               t.add properties.to_json
+               t.add ",\"from\":"
+               t.add from.object_id.to_json
+               t.add ",\"to\":"
+               t.add to.object_id.to_json
+               t.add "}"
+               return t.write_to_string
+       end
+
+       redef fun to_s do return to_json
+end
index 6629b80..b84a60b 100644 (file)
@@ -300,7 +300,7 @@ class Neo4jClient
        # Perform a `CypherQuery`
        # see: CypherQuery
        fun cypher(query: CypherQuery): Jsonable do
-               return post("{cypher_url}", query.to_json)
+               return post("{cypher_url}", query.to_rest)
        end
 
        # GET JSON data from `url`
@@ -436,8 +436,8 @@ class CypherQuery
                return self
        end
 
-       # Translate the query to JSON
-       fun to_json: JsonObject do
+       # Translate the query to the body of a corresponding Neo4j REST request.
+       fun to_rest: JsonObject do
                var obj = new JsonObject
                obj["query"] = query
                if not params.is_empty then
@@ -446,7 +446,7 @@ class CypherQuery
                return obj
        end
 
-       redef fun to_s do return to_json.to_s
+       redef fun to_s do return to_rest.to_s
 end
 
 # The fundamental units that form a graph are nodes and relationships.
@@ -546,9 +546,6 @@ abstract class NeoEntity
 
        # Is the property `key` set?
        fun has_key(key: String): Bool do return properties.has_key(key)
-
-       # Translate `self` to JSON
-       fun to_json: JsonObject do return properties
 end
 
 # Nodes are used to represent entities stored in base.
@@ -595,7 +592,7 @@ class NeoNode
                var tpl = new FlatBuffer
                tpl.append "\{"
                tpl.append "labels: [{labels.join(", ")}],"
-               tpl.append "data: {to_json}"
+               tpl.append "data: {properties.to_json}"
                tpl.append "\}"
                return tpl.write_to_string
        end
@@ -743,7 +740,8 @@ class NeoEdge
        # Get edge type
        fun rel_type: nullable String do return internal_type
 
-       redef fun to_json do
+       # Get the JSON body of a REST request that create the relationship.
+       private fun to_rest: JsonObject do
                var obj = new JsonObject
                if to.is_linked then
                        obj["to"] = to.url
@@ -891,7 +889,7 @@ class NeoBatch
                else
                        job.to = "\{{edge.from.batch_id.to_s}\}/relationships"
                end
-               job.body = edge.to_json
+               job.body = edge.to_rest
        end
 
        # Create multiple edges
@@ -902,7 +900,7 @@ class NeoBatch
                var request = new JsonPOST(client.batch_url, client.curl)
                # request.headers["X-Stream"] = "true"
                var json_jobs = new JsonArray
-               for job in jobs.values do json_jobs.add job.to_json
+               for job in jobs.values do json_jobs.add job.to_rest
                request.data = json_jobs
                var response = request.execute
                var res = client.parse_response(response)
@@ -1003,7 +1001,7 @@ class NeoJob
        var body: nullable Jsonable = null
 
        # JSON formated job
-       fun to_json: JsonObject do
+       fun to_rest: JsonObject do
                var job = new JsonObject
                job["id"] = id
                job["method"] = method
index 1a74641..9221116 100644 (file)
@@ -26,7 +26,7 @@ class Perfecthashing
        # A null value represents the upper bound of identifier
        private var interval = new List[Couple[nullable Int, nullable Int]]
 
-       # An array used as a temporary Hashtable for 
+       # An array used as a temporary Hashtable for
        # checking there is no collision between identifiers
        private var tempht = new Array[nullable Int]
 
@@ -36,9 +36,9 @@ class Perfecthashing
                # By default, all identifiers are available
                interval.push(new Couple[nullable Int, nullable Int](1, null))
        end
-       
+
        # Returns a mask composed by discriminants bits
-       # for these given identifiers 
+       # for these given identifiers
        # The mask + 1 value is the size of the hastable to create
        fun phand(ids: Array[Int]): Int
        do
@@ -59,7 +59,7 @@ class Perfecthashing
                mask = orMask.bin_xor(andMask)
 
                # Re-initialize the hashtable with null values
-               for i in [0..mask+1] do tempht[i] = null
+               for i in [0..(mask+1)] do tempht[i] = null
 
                # Optimize the already computed mask
                var newmask = 0
@@ -67,7 +67,7 @@ class Perfecthashing
                while i != 0 do
                        if mask.getbit(i) == 1 then
                                newmask = mask.bin_xor(1.lshift(i))
-                               
+
                                # If there is no collision, replace the old mask
                                if phandp(ids, newmask) then
                                        mask = newmask
@@ -92,7 +92,7 @@ class Perfecthashing
                                tempht[hv] = mask
                        end
                end
-       
+
                return true
        end
 
@@ -121,6 +121,9 @@ class Perfecthashing
                end
 
                # Resetting hashtable
+               for j in [0..(mask+1)] do tempht[j] = null
+
+               # Set the temporary hashtable for `compute_least_free_ids`
                phandp(ids, mask)
 
                # Fill the given array with n free identifiers
@@ -155,7 +158,7 @@ class Perfecthashing
                                # Tests if this id is free for this mask
                                var hv = i.bin_and(mask)
 
-                               # If the hashtable if full, push an empty item 
+                               # If the hashtable if full, push an empty item
                                if hv >= tempht.length then
                                        tempht.push(null)
                                end
@@ -163,7 +166,7 @@ class Perfecthashing
                                if tempht[hv] != mask then
                                        found = true
                                        id = i
-                               end     
+                               end
                                i = i + 1
                        end
 
@@ -179,7 +182,7 @@ class Perfecthashing
                        else
                                inter.item.first += 1
                        end
-               else 
+               else
                        if id != inter.item.first and id != inter.item.second then
                                # We need to split in two this interval
                                var last = inter.item.second
index 7a26f90..9549e48 100644 (file)
@@ -126,28 +126,40 @@ class POSet[E: Object]
                return fe.dtos.has(t)
        end
 
-       # Display the POSet in a gaphical windows.
-       # Graphviz with a working -Txlib is expected.
-       # Used fo debugging.
-       fun show_dot
+       # Write the POSet as a graphviz digraph.
+       #
+       # Nodes are identified with their `to_s`.
+       # Edges are unlabeled.
+       fun write_dot(f: OStream)
        do
-               var f = new OProcess("dot", "-Txlib")
-               #var f = stdout
                f.write "digraph \{\n"
                for x in elements.keys do
-                       f.write "\"{x}\";\n"
+                       var xstr = x.to_s.escape_to_dot
+                       f.write "\"{xstr}\";\n"
                        var xe = self.elements[x]
                        for y in xe.dtos do
+                               var ystr = y.to_s.escape_to_dot
                                if self.has_edge(y,x) then
-                                       f.write "\"{x}\" -> \"{y}\"[dir=both];\n"
+                                       f.write "\"{xstr}\" -> \"{ystr}\"[dir=both];\n"
                                else
-                                       f.write "\"{x}\" -> \"{y}\";\n"
+                                       f.write "\"{xstr}\" -> \"{ystr}\";\n"
                                end
                        end
                end
                f.write "\}\n"
-               #f.close
-               #f.wait
+       end
+
+       # Display the POSet in a graphical windows.
+       # Graphviz with a working -Txlib is expected.
+       #
+       # See `write_dot` for details.
+       fun show_dot
+       do
+               var f = new OProcess("dot", "-Txlib")
+               f.write "\}\n"
+               write_dot(f)
+               f.close
+               f.wait
        end
 
        # Compare two elements in an arbitrary total order.
index a122a02..da40da1 100644 (file)
 # Exposes methods for debugging ropes when needed.
 module ropes_debug
 
-intrude import ::standard::ropes
-import ::standard
+import standard
+intrude import standard::ropes
 
-redef class Rope
+redef class Text
        # Writes self as a dot file on the hard drive
-       fun to_dot(filepath: String): String is abstract
-end
+       private fun internal_to_dot: String is abstract
 
-redef class RopeNode
-       # Generates a dot string
-       fun to_dot(s: String): String is abstract
+       fun to_dot: String do
+               return "digraph g \{\n" + internal_to_dot + "\}\n"
+       end
 end
 
-redef class Leaf
-       redef fun to_dot(s): String
+redef class Concat
+       redef fun internal_to_dot: String
        do
-               s += "n{object_id} [label = \"{str}\" shape = rect];\n"
-               s += "n{str.object_id} -> n{object_id} [label = \"contains\"];\n"
-               s = str.to_dot(s)
+               var s = "n{object_id} [label = {length}];\n"
+               s += "n{object_id} -> n{left.object_id} [label = \"left\"];\n"
+               s += left.internal_to_dot
+               s += "n{object_id} -> n{right.object_id} [label = \"right\"];\n"
+               s += right.internal_to_dot
                return s
        end
 end
 
-redef class Concat
-       redef fun to_dot(s): String
+redef class RopeBuffer
+       redef fun internal_to_dot: String
        do
-               s += "n{object_id} [label = {length}];\n"
-               if left != null then
-                       s += "n{object_id} -> n{left.object_id} [label = \"left\"];\n"
-                       s = left.to_dot(s)
-               end
-               if right != null then
-                       s += "n{object_id} -> n{right.object_id} [label = \"right\"];\n"
-                       s = right.to_dot(s)
-               end
+               var s = "n{object_id} [label = {length}];\n"
+               s += "n{object_id} -> n{str.object_id} [label = \"str\"];\n"
+               s += str.internal_to_dot
+               s += "n{object_id} -> n{ns.object_id} [label = \"ns\"];\n"
+               s += "n{ns.object_id}[label = \"NativeString\", content=\"{ns.to_s_with_length(rpos)}\"];\n"
                return s
        end
 end
 
-redef class FlatText
-       fun to_dot(s: String): String is abstract
-end
-
 redef class FlatString
-       redef fun to_dot(s: String): String
+       redef fun internal_to_dot: String
        do
-               return s + "n{object_id} [label=\"FlatString\\nindex_from = {index_from}\\nindex_to = {index_to}\\nNativeString = {items.to_s_with_length(items.cstring_length)}\"];\n"
+               return "n{object_id} [label=\"FlatString\\nindex_from = {index_from}\\nindex_to = {index_to}\\nNativeString = {items.to_s_with_length(items.cstring_length)}\"];\n"
        end
 end
 
 redef class FlatBuffer
-       redef fun to_dot(s: String): String
+       redef fun internal_to_dot: String
        do
-               return s + "n{object_id} [label=\"FlatBuffer\\length = {length}\\ncapacity = {capacity}\\nitems = {items.to_s_with_length(items.cstring_length)}\"];\n"
+               return "n{object_id} [label=\"FlatBuffer\\length = {length}\\ncapacity = {capacity}\\nitems = {items.to_s_with_length(items.cstring_length)}\"];\n"
        end
 end
 
-redef class RopeString
-       redef fun to_dot(filepath: String)
-       do
-               var of = new OFStream.open(filepath)
-               var ret: String = new RopeString.from("digraph g \{\n")
-               ret = root.to_dot(ret).as(RopeString)
-               ret += "\}\n"
-               ret.write_to(of)
-               of.close
-               return ret
-       end
-end
-
-
diff --git a/lib/splay_ropes.nit b/lib/splay_ropes.nit
deleted file mode 100644 (file)
index e167ce7..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT.  This software 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.  You can modify it is you want,  provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You  are  allowed  to  redistribute it and sell it, alone or is a part of
-# another product.
-
-# Introduces a self-balancing method on Rope, using a Splay Tree
-module splay_ropes
-
-import standard
-intrude import standard::ropes
-
-redef class Rope
-
-       # Performs a Left rotation on node `x`
-       # Since a Rope does not have any notion of parent in its node, they need to be passed as arguments if available.
-       private fun left_rotate(r: Concat): Concat
-       do
-               var rr = r.right.as(Concat)
-               var rl = r.left
-               var pl = rr.left
-               var pr = rr.right
-               var nr = new Concat(rl, pl)
-               var np = new Concat(nr, pr)
-               return np
-       end
-
-       # Performs a Right rotation on node `r`
-       # Since a Rope does not have any notion of parent in its node, they need to be passed as arguments if available.
-       private fun right_rotate(r: Concat): Concat
-       do
-               var rl = r.left.as(Concat)
-               var rr = r.right
-               var pr = rl.right
-               var pl = rl.left
-               var nr = new Concat(pr, rr)
-               var np = new Concat(pl, nr)
-               return np
-       end
-
-       # Performs a Splay operation on a complete path
-       # The last node of the path will become the root.
-       private fun splay(path: Path): nullable Concat
-       do
-               var st = path.stack
-               if st.is_empty then return null
-               var cct = st.pop.node
-               while not st.is_empty do
-                       var tmp = st.pop
-                       var nod: Concat
-                       if tmp.left then
-                               nod = new Concat(cct, tmp.node.right)
-                               cct = right_rotate(nod)
-                       else
-                               nod = new Concat(tmp.node.left, cct)
-                               cct = left_rotate(nod)
-                       end
-               end
-               return cct
-       end
-end
-
-redef class RopeString
-
-       # Inserts a String `str` at position `pos`
-       redef fun insert_at(str, pos)
-       do
-               if str.length == 0 then return self
-               if self.length == 0 then return new RopeString.from(str)
-
-               assert pos >= 0 and pos <= length
-
-               var path = node_at(pos)
-
-               var last_concat: Concat
-
-               if path.offset == 0 then
-                       if str isa FlatString then
-                               last_concat = new Concat(new StringLeaf(str), path.leaf)
-                       else
-                               last_concat = new Concat(str.as(RopeString).root, path.leaf)
-                       end
-               else if path.offset == path.leaf.length then
-                       if str isa FlatString then
-                               last_concat = new Concat(path.leaf, new StringLeaf(str))
-                       else
-                               last_concat = new Concat(path.leaf, str.as(RopeString).root)
-                       end
-               else
-                       var s = path.leaf.str
-                       var l_half = s.substring(0, s.length - path.offset)
-                       var r_half = s.substring_from(s.length - path.offset)
-                       var cct: Concat
-                       var ll = new StringLeaf(l_half.as(FlatString))
-                       if str isa FlatString then
-                               cct = new Concat(ll, new StringLeaf(str))
-                       else
-                               cct = new Concat(ll, str.as(RopeString).root)
-                       end
-                       last_concat = new Concat(cct, new StringLeaf(r_half.as(FlatString)))
-               end
-
-               var st = path.stack
-
-               if st.is_empty then return new RopeString.from_root(last_concat)
-
-               var tmp = st.pop
-
-               if tmp.left then
-                       var n = tmp.node.right
-                       var r = new Concat(last_concat, n)
-                       st.push(new PathElement(r))
-               else
-                       var n = tmp.node.left
-                       var r = new Concat(n, last_concat)
-                       st.push(new PathElement(r))
-               end
-
-               return new RopeString.from_root(splay(path).as(not null))
-       end
-
-end
-
index de06850..7d710bd 100644 (file)
@@ -394,6 +394,26 @@ class Array[E]
                res.append(other)
                return res
        end
+
+       # Repetition of arrays.
+       #
+       # returns a new array built by concatenating `self` `repeat` times.
+       #
+       #    var a = [1,2,3]
+       #    assert (a * 0).is_empty
+       #    assert a * 1  ==  [1,2,3]
+       #    assert a * 2  ==  [1,2,3,1,2,3]
+       #    assert (a * 10).length  ==  30
+       fun *(repeat: Int): Array[E]
+       do
+               assert repeat >= 0
+               var res = new Array[E].with_capacity(length * repeat)
+               while repeat > 0 do
+                       res.add_all(self)
+                       repeat -= 1
+               end
+               return res
+       end
 end
 
 # An `Iterator` on `AbstractArray`
index a2e0966..5a980aa 100644 (file)
@@ -83,6 +83,34 @@ redef class Int
        #
        #    assert not 13.is_even
        fun is_odd: Bool do return not is_even
+
+       # Returns the `self` raised to the power of `e`.
+       #
+       #    assert 2 ** 3 == 8
+       fun **(e: Int): Int
+       do
+               return self.to_f.pow(e.to_f).to_i
+       end
+
+       # The factorial of `self` (aka `self!`)
+       #
+       # Returns `1 * 2 * 3 * ... * self-1 * self`
+       #
+       #    assert 0.factorial == 1  # by convention for an empty product
+       #    assert 1.factorial == 1
+       #    assert 4.factorial == 24
+       #    assert 9.factorial == 362880
+       fun factorial: Int
+       do
+               assert self >= 0
+               var res = 1
+               var n = self
+               while n > 0 do
+                       res = res * n
+                       n -= 1
+               end
+               return res
+       end
 end
 
 redef class Float
index ad97500..c4915fd 100644 (file)
-# This file is part of NIT ( http://www.nitlanguage.org ).
+# This file is part of NIT (http://www.nitlanguage.org).
 #
-# This file is free software, which comes along with NIT.  This software 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.  You can modify it if you want,  provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You  are  allowed  to  redistribute it and sell it, alone or as a part of
-# another product.
-
-# Nit implementation of the Ropes (see Ropes : An Alternative to Strings,
-# SOFTWARE - PRACTICE AND EXPERIENCE, VOL. 25(12), 1315 - 1330 (DECEMBER 1995)
-# Hans. J Boehm, Russ Atkinson and Michael Plass)
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
 #
-# A rope is a kind of string but instead of being flat, it relies on a binary tree structure to store data.
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Tree-based representation of a String.
+#
+# Ropes are a data structure introduced in a 1995 paper from
+# Hans J. Boehm, Russ Atkinson and Michael Plass.
+# See : `Ropes : an Alternative to Strings`, `Software - Practice and Experience,
+# Vol. 25(12), 1315-1330 (December 1995)`.
+#
+# The implementation developed here provides an automatic change
+# of data structure depending on the length of the leaves.
+#
+# The length from which a `Rope` is built from a `flat` string
+# if defined at top-level (see `maxlen`) and can be redefined by clients
+# depending on their needs (e.g. if you need to bench the speed of
+# the creation of concat nodes, lower the size of maxlen).
+#
+# A Rope as defined in the original paper is a Tree made of concatenation
+# nodes and containing `Flat` (that is Array-based) strings as Leaves.
+#
+# Example :
+#
+# `            Concat                   `
+# `          /        \                 `
+# `    Concat          Concat           `
+# `   /      \        /      \          `
+# `"My"     " Name"  " is"   " Simon."  `
+#
+# Note that the above example is not representative of the actual implementation
+# of `Ropes`, since short leaves are merged to keep the rope at an acceptable
+# height (hence, this rope here might actually be a `FlatString` !).
 module ropes
 
 intrude import string
 
-# Used when searching for a particular node
-# Returns the path to the node from the root of the rope
-# Also, the node and the offset for seeked position in the rope
-private class Path
-       # Leaf found
-       var leaf: Leaf
-       # Offset in leaf
-       var offset: Int
-       # Stack of the nodes traversed, and the path used
-       var stack: List[PathElement]
-end
+# Maxlen is the maximum length of a Leaf node
+#
+# When concatenating two leaves, if `new_length` > `maxlen`,
+# A `Concat` node is created instead
+#
+# Its purpose is to limit the depth of the `Rope` (this
+# improves performance when accessing/iterating).
+fun maxlen: Int do return 64
 
-# An element for a Path, has the concat node and whether or not
-# left or right child was visited.
-private class PathElement
-       # Visited node
-       var node: Concat
-       # Was the left child visited ?
-       var left = false
-       # Was the right child visited ?
-       var right = false
+# String using a tree-based representation with leaves as `FlatStrings`
+private abstract class Rope
+       super Text
 end
 
-# A node for a Rope
-private abstract class RopeNode
-       # Length of the node
-       var length = 0
+private abstract class RopeString
+       super Rope
+       super String
 
-       # Transforms the current node to a Leaf.
-       # This might be costly to invoke since this produces a FlatString concatenation.
-       # Can be used internally to limit the growth of the Rope when working with small leaves.
-       fun to_leaf: Leaf is abstract
+       redef fun chars is cached do return new RopeChars(self)
 end
 
-# Node that represents a concatenation between two nodes (of any RopeNode type)
+# Node that represents a concatenation between two `String`
 private class Concat
-       super RopeNode
+       super RopeString
+
+       redef var length: Int
+
+       redef fun substrings do return new RopeSubstrings(self)
+
+       redef fun empty do return ""
+
+       redef fun to_cstring is cached do
+               var len = length
+               var ns = new NativeString(len + 1)
+               ns[len] = '\0'
+               var off = 0
+               for i in substrings do
+                       var ilen = i.length
+                       i.as(FlatString).items.copy_to(ns, ilen, i.as(FlatString).index_from, off)
+                       off += ilen
+               end
+               return ns
+       end
 
        # Left child of the node
-       var left: nullable RopeNode
+       var left: String
        # Right child of the node
-       var right: nullable RopeNode
+       var right: String
 
-       init(l: nullable RopeNode, r: nullable RopeNode)
-       do
+       init(l: String, r: String) do
                left = l
                right = r
-               if l != null then length += l.length
-               if r != null then length += r.length
+               length = l.length + r.length
        end
 
-       redef fun to_leaf
-       do
-               if left == null then
-                       if right == null then return new StringLeaf("".as(FlatString))
-                       return right.to_leaf
-               end
-               if right == null then return left.as(not null).to_leaf
-               return new StringLeaf((left.to_leaf.str.as(FlatString) + right.to_leaf.str.as(FlatString)).as(FlatString))
+       redef fun output do
+               left.output
+               right.output
        end
-end
-
-# Leaf of a Rope, contains a FlatString
-private abstract class Leaf
-       super RopeNode
-
-       # Encapsulated FlatString in the leaf node
-       var str: FlatText
-
-end
 
-private class StringLeaf
-       super Leaf
+       redef fun iterator do return new RopeIter(self)
 
-       init(val: FlatString) do
-               self.str = val
-               length = str.length
+       redef fun *(i) do
+               var x: String = self
+               for j in [1 .. i[ do x += self
+               return x
        end
 
-       redef fun to_leaf do return self
-end
-
-# Used as a cache when using indexed access to a substring in the Rope
-private class LeafCache
-       # Cached leaf
-       var leaf: Leaf
-       # Position in Rope
-       var pos: Int
-end
-
-# Basic structure, binary tree with a root node.
-#
-# Also shared services by subsequent implementations.
-abstract class Rope
-       super Text
-
-       # Root node, entry point of a Rope.
-       private var root: RopeNode is noinit
-
-       # Cached version of self as a flat String
-       private var str_representation: nullable NativeString = null
-
-       private var leaf_cache: nullable LeafCache = null
-
-       # Empty Rope
-       init do root = new StringLeaf("".as(FlatString))
-
-       # Creates a new Rope with `s` as root
-       init from(s: String) do
-               if s isa RopeString then root = s.root else root = new StringLeaf(s.as(FlatString))
+       redef fun [](i) do
+               var llen = left.length
+               if i >= llen then return right[i - llen]
+               return left[i]
        end
 
-       private init from_root(r: RopeNode)
-       do
-               root = r
+       redef fun substring(from, len) do
+               var llen = left.length
+               if from < llen then
+                       if from + len < llen then return left.substring(from,len)
+                       var lsublen = llen - from
+                       return left.substring_from(from) + right.substring(0, len - lsublen)
+               else
+                       return right.substring(from - llen, len)
+               end
        end
 
-       redef fun length do return root.length
-
-       # Iterator on the nodes of the rope, in forward postfix order
-       private fun postfix(from: Int): Postfix do return new Postfix.from(self, from)
-
-       # Iterator on the leaves of the rope, forward order
-       private fun leaves(from: Int): LeavesIterator do return new LeavesIterator(self, from)
+       redef fun reversed do return new Concat(right.reversed, left.reversed)
 
-       # Iterator on the substrings from 0, in forward order
-       redef fun substrings do return new SubstringsIterator(self, 0)
-
-       # Iterator on the substrings, starting at position `from`, in forward order
-       fun substrings_from(from: Int): IndexedIterator[Text] do return new SubstringsIterator(self, from)
-
-       # Iterator on the nodes of the rope, in backwards postfix order
-       private fun reverse_postfix(from: Int): ReversePostfix do return new ReversePostfix.from(self, from)
-
-       # Iterator on the leaves of the rope, backwards order
-       private fun reverse_leaves(from: Int): ReverseLeavesIterator do return new ReverseLeavesIterator(self,from)
+       redef fun insert_at(s, pos) do
+               if pos > left.length then
+                       return left + right.insert_at(s, pos - left.length)
+               end
+               return left.insert_at(s, pos) + right
+       end
 
-       # Iterator on the substrings, in reverse order
-       fun reverse_substrings: IndexedIterator[Text] do return new ReverseSubstringsIterator(self, length-1)
+       redef fun to_upper do return new Concat(left.to_upper, right.to_upper)
 
-       # Iterator on the substrings, in reverse order, starting iteration at position `from`
-       fun reverse_substrings_from(from: Int): IndexedIterator[Text] do return new ReverseSubstringsIterator(self, from)
+       redef fun to_lower do return new Concat(left.to_lower, right.to_lower)
 
-       redef fun output
-       do
-               for i in substrings do
-                       i.output
+       redef fun +(o) do
+               var s = o.to_s
+               var mlen = length
+               var slen = s.length
+               if s isa Concat then
+                       return new Concat(self, s)
+               else
+                       var r = right
+                       var rlen = r.length
+                       if rlen + slen > maxlen then return new Concat(left, new Concat(r, s))
+                       return new Concat(left, r + s)
                end
        end
+end
 
-       redef fun to_cstring
-       do
-               if str_representation != null then return str_representation.as(not null)
+# Mutable `Rope`, optimized for concatenation operations
+#
+# A `RopeBuffer` is an efficient way of building a `String` when
+# concatenating small strings.
+#
+# It does concatenations in an optimized way by having a
+# mutable part and an immutable part built by efficiently
+# concatenating strings in chain.
+#
+# Every concatenation operation is done by copying a string to
+# the mutable part and flushing it when full.
+#
+# However, when a long string is appended to the `Buffer`,
+# the concatenation is done at it would be in a `Rope`.
+class RopeBuffer
+       super Rope
+       super Buffer
 
-               var native_final_str = calloc_string(length + 1)
+       redef fun chars: Sequence[Char] is cached do return new RopeBufferChars(self)
 
-               native_final_str[length] = '\0'
+       # The final string being built on the fly
+       private var str: String is noinit
 
-               if self.length == 0 then
-                       str_representation = native_final_str
-                       return native_final_str
-               end
+       # Current concatenation buffer
+       private var ns: NativeString is noinit
 
-               var offset = 0
+       # Next available (e.g. unset) character in the `Buffer`
+       private var rpos = 0
 
-               for i in substrings do
-                       var str = i.flatten
-                       if str isa FlatString then str.items.copy_to(native_final_str, str.length, str.index_from, offset)
-                       offset += i.length
-               end
+       # Keeps track of the buffer's currently dumped part
+       #
+       # This might happen if for instance, a String was being
+       # built by concatenating small parts of string and suddenly
+       # a long string (length > maxlen) is appended.
+       private var dumped: Int is noinit
 
-               str_representation = native_final_str
+       # Length of the complete rope
+       redef var length = 0
 
-               return native_final_str
-       end
+       # Length of the mutable part
+       #
+       # Is also used as base to compute the size of the next
+       # mutable native string (`ns`)
+       private var buf_size: Int is noinit
 
-       # Path to the Leaf for `position`
-       private fun node_at(position: Int): Path
-       do
-               assert position >= 0 and position <= length
-               if position == length then
-                       var st = new List[PathElement]
-                       stack_to_end(root,st)
-                       if not st.is_empty then
-                               var lst = st.last
-                               var lf = lst.node.right
-                               if lf != null then
-                                       return new Path(lf.as(Leaf), lf.length, st)
-                               else
-                                       lf = lst.node.left
-                                       return new Path(lf.as(Leaf), lf.length, st)
-                               end
-                       else
-                               return new Path(root.as(Leaf), length, st)
-                       end
-               end
-               return get_node_from(root, 0, position, new List[PathElement])
-       end
-
-       # Special case for when the required pos is length
-       private fun stack_to_end(nod: RopeNode, st: List[PathElement])
-       do
-               if nod isa Leaf then return
-               var n = nod.as(Concat)
-               var r = n.right
-               var ele = new PathElement(n)
-               ele.right = true
-               st.push(ele)
-               if r != null then
-                       stack_to_end(r, st)
-               end
-               return
-       end
+       redef fun substrings: Iterator[String] do return new RopeBufSubstringIterator(self)
 
-       # Builds the path to Leaf at position `seek_pos`
-       private fun get_node_from(node: RopeNode, curr_pos: Int, seek_pos: Int, stack: List[PathElement]): Path
-       do
-               assert curr_pos >= 0
-               if node isa Leaf then
-                       self.leaf_cache = new LeafCache(node, curr_pos)
-                       return new Path(node, seek_pos - curr_pos, stack)
-               end
-               node = node.as(Concat)
-
-               if node.left != null then
-                       var next_pos = curr_pos + node.left.length
-                       stack.add(new PathElement(node))
-                       if next_pos > seek_pos then
-                               stack.last.left = true
-                               return get_node_from(node.left.as(not null), curr_pos, seek_pos, stack)
-                       end
-                       stack.last.right = true
-                       return get_node_from(node.right.as(not null), next_pos, seek_pos, stack)
-               else
-                       var vis = new PathElement(node)
-                       vis.right = true
-                       stack.add(vis)
-                       return get_node_from(node.right.as(not null), curr_pos, seek_pos, stack)
-               end
+       # Builds an empty `RopeBuffer`
+       init do
+               str = ""
+               ns = new NativeString(maxlen)
+               buf_size = maxlen
+               dumped = 0
        end
 
-       redef fun ==(o)
-       do
-               if not o isa Text then return false
-               if o.length != self.length then return false
-               var oit = o.chars.iterator
-               for i in self.chars.iterator do
-                       if i != oit.item then return false
-                       oit.next
-               end
-               return true
+       # Builds a new `RopeBuffer` with `str` in it.
+       init from(str: String) do
+               self.str = str
+               ns = new NativeString(maxlen)
+               buf_size = maxlen
+               length = str.length
+               dumped = 0
        end
-end
 
-# Rope that cannot be modified
-class RopeString
-       super Rope
-       super String
+       # Resets the informations of the `Buffer`
+       #
+       # This is called when doing in-place modifications
+       # on a previously to_s'd `RopeBuffer`
+       private fun reset do
+               var nns = new NativeString(buf_size)
+               var blen = rpos - dumped
+               ns.copy_to(nns, blen, dumped, 0)
+               dumped = 0
+               rpos = blen
+               written = false
+       end
 
-       redef fun to_s do return self
+       redef fun empty do return new RopeBuffer
 
-       redef fun empty do return once new RopeString.from("")
+       redef fun clear do
+               str = ""
+               length = 0
+               rpos = 0
+       end
 
-       redef var chars: SequenceRead[Char] = new RopeStringChars(self)
+       redef fun substring(from, count) do
+               var strlen = str.length
 
-       redef fun reversed
-       do
-               var ret = empty
-               for i in substrings do
-                       ret = i.as(String).reversed + ret
+               if from < 0 then
+                       count += from
+                       if count < 0 then count = 0
+                       from = 0
                end
-               return ret
-       end
 
-       redef fun to_upper
-       do
-               var ret = empty
-               for i in substrings do
-                       ret += i.as(String).to_upper
-               end
-               return ret
-       end
+               if count > length then count = length - from
 
-       redef fun to_lower
-       do
-               var ret = empty
-               for i in substrings do
-                       ret += i.as(String).to_lower
-               end
-               return ret
-       end
+               if count == 0 then return empty
 
-       redef fun +(o) do
-               if self.length == 0 then return o.to_s
-               if o.length == 0 then return self
-               var str = o.to_s
-               if str isa FlatString then
-                       return new RopeString.from_root(new Concat(root, new StringLeaf(str)))
-               else if str isa RopeString then
-                       return new RopeString.from_root(new Concat(root, str.root))
+               if from < strlen then
+                       var subpos = strlen - from
+                       if count <= subpos then
+                               return new RopeBuffer.from(str.substring(from, count))
+                       else
+                               var l = str.substring_from(from)
+                               var rem = count - subpos
+                               var nns = new NativeString(rem)
+                               ns.copy_to(nns, rem, dumped, 0)
+                               return new RopeBuffer.from(l + nns.to_s_with_length(rem))
+                       end
                else
-                       abort
-               end
-       end
-
-       redef fun *(n)
-       do
-               var ret = new RopeString.from("")
-               for i in [0..n[ do
-                       ret = (ret + self).as(RopeString)
+                       var nns = new NativeString(count)
+                       ns.copy_to(nns, count, dumped, 0)
+                       return new RopeBuffer.from(nns.to_s_with_length(count))
                end
-               return ret
        end
 
-       # Inserts a String `str` at position `pos`
-       redef fun insert_at(str, pos)
-       do
-               if str.length == 0 then return self
-               if self.length == 0 then return new RopeString.from(str)
-
-               assert pos >= 0 and pos <= length
-
-               var path = node_at(pos)
-
-               var last_concat: Concat
-
-               if path.offset == 0 then
-                       if str isa FlatString then
-                               last_concat = new Concat(new StringLeaf(str), path.leaf)
-                       else
-                               last_concat = new Concat(str.as(RopeString).root, path.leaf)
+       redef fun append(s) do
+               var slen = s.length
+               length += slen
+               var rp = rpos
+               if s isa Rope then
+                       if rp > 0 and dumped != rp then
+                               str += new FlatString.with_infos(ns, rp - dumped, dumped, rp - 1)
+                               dumped = rp
                        end
-               else if path.offset == path.leaf.length then
-                       if str isa FlatString then
-                               last_concat = new Concat(path.leaf, new StringLeaf(str))
-                       else
-                               last_concat = new Concat(path.leaf, str.as(RopeString).root)
+                       str = str + s
+                       return
+               end
+               if slen > maxlen then
+                       if rp > 0 and dumped != rp then
+                               str += new FlatString.with_infos(ns, rp - dumped, dumped, rp - 1)
+                               dumped = rp
                        end
+                       str = str + s
+                       return
+               end
+               var remsp = buf_size - rp
+               var sits: NativeString
+               var begin: Int
+               if s isa FlatString then
+                       begin = s.index_from
+                       sits = s.items
+               else if s isa FlatBuffer then
+                       begin = 0
+                       sits = s.items
                else
-                       var s = path.leaf.str
-                       var l_half = s.substring(0, s.length - path.offset)
-                       var r_half = s.substring_from(s.length - path.offset)
-                       var cct: Concat
-                       var ll = new StringLeaf(l_half.as(FlatString))
-                       if str isa FlatString then
-                               cct = new Concat(ll, new StringLeaf(str))
+                       if slen <= remsp then
+                               for i in s.chars do
+                                       ns[rpos] = i
+                                       rpos += 1
+                               end
                        else
-                               cct = new Concat(ll, str.as(RopeString).root)
+                               var spos = 0
+                               for i in [0..remsp[ do
+                                       ns[rpos] = s[spos]
+                                       rpos += 1
+                                       spos += 1
+                               end
+                               dump_buffer
+                               while spos < slen do
+                                       ns[rpos] = s[spos]
+                                       spos += 1
+                                       rpos += 1
+                               end
                        end
-                       last_concat = new Concat(cct, new StringLeaf(r_half.as(FlatString)))
+                       return
                end
-
-               for i in path.stack.reverse_iterator do
-                       if i.left then
-                               last_concat = new Concat(last_concat, i.node.right)
+               if slen <= remsp then
+                       sits.copy_to(ns, slen, begin, rp)
+                       if rp == buf_size then
+                               rpos = buf_size
+                               dump_buffer
+                               rpos = 0
                        else
-                               last_concat = new Concat(i.node.left, last_concat)
+                               rpos += slen
                        end
+               else
+                       sits.copy_to(ns, remsp, begin, rp)
+                       rpos = buf_size
+                       dump_buffer
+                       var nlen = slen - remsp
+                       sits.copy_to(ns, nlen, begin + remsp, 0)
+                       rpos = nlen
                end
-
-               return new RopeString.from_root(last_concat)
        end
 
-       # O(log(n))
-       #
-       #     var rope = new RopeString.from("abcd")
-       #     assert rope.substring(1, 2)         ==  "bc"
-       #     assert rope.substring(-1, 2)         ==  "a"
-       #     assert rope.substring(1, 0)         ==  ""
-       #     assert rope.substring(2, 5)         ==  "cd"
-       #
-       redef fun substring(pos, len)
-       do
-               if pos < 0 then
-                       len += pos
-                       pos = 0
+       redef fun add(c) do
+               var rp = rpos
+               length += 1
+               ns[rp] = c
+               rp += 1
+               if rp == buf_size then
+                       rpos = rp
+                       dump_buffer
+                       rp = 0
                end
+               rpos = rp
+       end
 
-               if pos + len > length then len = length - pos
-
-               if len <= 0 then return new RopeString.from("")
-
-               var path = node_at(pos)
+       # Converts the Buffer to a FlatString, appends it to
+       # the final String and re-allocates a new larger Buffer.
+       private fun dump_buffer do
+               written = false
+               var nstr = new FlatString.with_infos(ns, rpos - dumped, dumped, rpos - 1)
+               str += nstr
+               var bs = buf_size
+               bs = bs * 2
+               ns = new NativeString(bs)
+               buf_size = bs
+               dumped = 0
+       end
 
-               var lf = path.leaf
-               var offset = path.offset
+       redef fun output do
+               str.output
+               new FlatString.with_infos(ns, rpos - dumped, dumped, rpos - 1).output
+       end
 
-               if path.leaf.str.length - offset > len then lf = new StringLeaf(lf.str.substring(offset,len).as(FlatString)) else lf = new StringLeaf(lf.str.substring_from(offset).as(FlatString))
+       # Enlarge is useless here since the `Buffer`
+       # part is automatically dumped when necessary.
+       #
+       # Also, since the buffer can not be overused by a
+       # single string, there is no need for manual
+       # resizing.
+       #
+       # "You have no power here !"
+       redef fun enlarge(i) do end
 
-               var nod: RopeNode = lf
+       redef fun to_s do
+               written = true
+               var nnslen = rpos - dumped
+               if nnslen == 0 then return str
+               return str + new FlatString.with_infos(ns, rpos - dumped, dumped, rpos - 1)
+       end
 
-               for i in path.stack.reverse_iterator do
-                       if i.right then continue
-                       nod = new Concat(nod, i.node.right)
+       redef fun reverse do
+               str = str.reversed
+               var nns = new NativeString(buf_size)
+               var j = rpos
+               var mits = ns
+               for i in [0 .. rpos[ do
+                       nns[i] = mits[j]
+                       j -= 1
                end
+               ns = nns
+       end
 
-               var ret = new RopeString
-               ret.root = nod
-
-               path = ret.node_at(len-1)
-
-               offset = path.offset
-               nod = new StringLeaf(path.leaf.str.substring(0, offset+1).as(FlatString))
-
-               for i in path.stack.reverse_iterator do
-                       if i.left then continue
-                       nod = new Concat(i.node.left, nod)
+       redef fun upper do
+               if written then reset
+               str = str.to_upper
+               var mits = ns
+               for i in [0 .. rpos[ do
+                       mits[i] = mits[i].to_upper
                end
+       end
 
-               ret.root = nod
-
-               return ret
+       redef fun lower do
+               if written then reset
+               str = str.to_lower
+               var mits = ns
+               for i in [0 .. rpos[ do
+                       mits[i] = mits[i].to_lower
+               end
        end
 end
 
 redef class FlatString
 
-       redef fun insert_at(s, pos)
-       do
+       redef fun insert_at(s, pos) do
+               var l = substring(0, pos)
+               var r = substring_from(pos)
+               return l + s + r
+       end
 
-               if pos == 0 then
-                       var r = new RopeString.from(s)
-                       return r + self
-               end
-               if pos == length then
-                       var r = new RopeString.from(self)
-                       return r + s
+       redef fun +(o) do
+               var s = o.to_s
+               var slen = s.length
+               var mlen = length
+               if slen == 0 then return self
+               if mlen == 0 then return s
+               var nlen = slen + mlen
+               if s isa FlatString then
+                       if nlen > maxlen then return new Concat(self, s)
+                       var mits = items
+                       var sifrom = s.index_from
+                       var mifrom = index_from
+                       var sits = s.items
+                       var ns = new NativeString(nlen + 1)
+                       mits.copy_to(ns, mlen, mifrom, 0)
+                       sits.copy_to(ns, slen, sifrom, mlen)
+                       return ns.to_s_with_length(nlen)
+               else if s isa Concat then
+                       var sl = s.left
+                       var sllen = sl.length
+                       if sllen + mlen > maxlen then return new Concat(self, s)
+                       return new Concat(self + sl, s.right)
+               else
+                       abort
                end
-
-               var l = substring(0,pos)
-               var r = substring_from(pos)
-               var ret: String = new RopeString.from(l)
-               ret += s
-               return ret + r
        end
+end
 
+# A simple linked list for use with iterators
+private class RopeIterPiece
+       # The encapsulated node of the `Rope`
+       var node: String
+       # Was its left child (if any) visited ?
+       var ldone: Bool
+       # Was its right child (if any) visited ?
+       var rdone: Bool
+       # The previous node in the list.
+       var prev: nullable RopeIterPiece
 end
 
-private class RopeStringChars
-       super SequenceRead[Char]
+# A reverse iterator capable of working with `Rope` objects
+private class RopeReviter
+       super IndexedIterator[Char]
 
-       var tgt: Rope
+       # Current NativeString
+       var ns: String
+       # Current position in NativeString
+       var pns: Int
+       # Position in the Rope (0-indexed)
+       var pos: Int
+       # Iterator on the substrings, does the Postfix part of
+       # the Rope traversal.
+       var subs: IndexedIterator[String]
 
-       redef fun [](pos)
-       do
-               assert pos < tgt.length
-               if tgt.leaf_cache != null and pos >= tgt.leaf_cache.pos and (tgt.leaf_cache.pos + tgt.leaf_cache.leaf.length) > pos then return tgt.leaf_cache.leaf.str.chars[pos - tgt.leaf_cache.pos]
-               var path = tgt.node_at(pos)
-               return path.leaf.str.chars[path.offset]
+       init(root: RopeString) do
+               pos = root.length - 1
+               subs = new ReverseRopeSubstrings(root)
+               ns = subs.item
+               pns = ns.length - 1
        end
 
-       redef fun iterator do return iterator_from(0)
-
-       redef fun iterator_from(pos) do return new RopeCharIterator(tgt, pos)
+       init from(root: RopeString, pos: Int) do
+               self.pos = pos
+               subs = new ReverseRopeSubstrings.from(root, pos)
+               ns = subs.item
+               pns = pos - subs.index
+       end
 
-       redef fun reverse_iterator do return reverse_iterator_from(tgt.length-1)
+       redef fun index do return pos
 
-       redef fun reverse_iterator_from(pos) do return new ReverseRopeCharIterator(tgt, pos)
-end
+       redef fun is_ok do return pos >= 0
 
-# Used to iterate on a Rope
-private class IteratorElement
+       redef fun item do return ns[pns]
 
-       init(e: RopeNode)
-       do
-               if e isa Leaf then
-                       left = true
-                       right = true
-               end
-               node = e
+       redef fun next do
+               pns -= 1
+               pos -= 1
+               if pns >= 0 then return
+               if not subs.is_ok then return
+               subs.next
+               if not subs.is_ok then return
+               ns = subs.item
+               pns = ns.length - 1
        end
-
-       # The node being visited
-       var node: RopeNode
-       # If the node has a left child, was it visited ?
-       var left = false
-       # If the node has a right child, was it visited ?
-       var right = false
-       # Was the current node visited ?
-       var done = false
 end
 
-# Simple Postfix iterator on the nodes of a Rope
-private class Postfix
-       super IndexedIterator[RopeNode]
-
-       # Target Rope to iterate on
-       var target: Rope
+# Forward iterator on the chars of a `Rope`
+private class RopeIter
+       super IndexedIterator[Char]
 
-       # Current position in Rope
+       # Position in current `String`
+       var pns: Int
+       # Current `String` being iterated on
+       var str: String
+       # Substrings of the Rope
+       var subs: IndexedIterator[String]
+       # Maximum position to iterate on (e.g. Rope.length)
+       var max: Int
+       # Position (char) in the Rope (0-indexed)
        var pos: Int
 
-       # Visited nodes
-       var stack = new List[IteratorElement]
+       init(root: RopeString) do
+               subs = new RopeSubstrings(root)
+               pns = 0
+               str = subs.item
+               max = root.length - 1
+               pos = 0
+       end
 
-       init from(tgt: Rope, pos: Int)
-       do
-               self.target = tgt
+       init from(root: RopeString, pos: Int) do
+               subs = new RopeSubstrings.from(root, pos)
+               pns = pos - subs.index
                self.pos = pos
-               if pos < 0 or pos >= tgt.length then return
-               var path = tgt.node_at(pos)
-               self.pos -= path.offset
-               for i in path.stack do
-                       var item = new IteratorElement(i.node)
-                       item.left = true
-                       if i.right then item.right = true
-                       stack.push item
-               end
-               var item = new IteratorElement(path.leaf)
-               item.done = true
-               stack.push item
+               str = subs.item
+               max = root.length - 1
        end
 
-       redef fun item
-       do
-               assert is_ok
-               return stack.last.node
-       end
+       redef fun item do return str[pns]
 
-       redef fun is_ok do return not stack.is_empty
+       redef fun is_ok do return pos <= max
 
        redef fun index do return pos
 
        redef fun next do
-               if stack.is_empty then return
-               if pos > target.length-1 then
-                       stack.clear
-                       return
-               end
-               var lst = stack.last
-               if lst.done then
-                       if lst.node isa Leaf then
-                               pos += lst.node.length
-                       end
-                       stack.pop
-                       next
-                       return
-               end
-               if not lst.left then
-                       lst.left = true
-                       var nod = lst.node
-                       if nod isa Concat and nod.left != null then
-                               stack.push(new IteratorElement(nod.left.as(not null)))
-                               next
-                               return
-                       end
-               end
-               if not lst.right then
-                       lst.right = true
-                       var nod = lst.node
-                       if nod isa Concat and nod.right != null then
-                               stack.push(new IteratorElement(nod.right.as(not null)))
-                               next
-                               return
-                       end
-               end
-               lst.done = true
+               pns += 1
+               pos += 1
+               if pns < subs.item.length then return
+               if not subs.is_ok then return
+               subs.next
+               if not subs.is_ok then return
+               str = subs.item
+               pns = 0
        end
 end
 
-# Iterates on the leaves (substrings) of the Rope
-class LeavesIterator
-       super IndexedIterator[Leaf]
-
-       private var nodes: Postfix
+# Substrings of a Rope (i.e. Reverse postfix iterator on leaves)
+private class ReverseRopeSubstrings
+       super IndexedIterator[String]
+
+       # Visit Stack
+       var iter: RopeIterPiece is noinit
+       # Position in `Rope`
+       var pos: Int is noinit
+
+       # Current leaf
+       var str: String is noinit
+
+       init(root: RopeString) do
+               var r = new RopeIterPiece(root, false, true, null)
+               pos = root.length - 1
+               var lnod: String = root
+               loop
+                       if lnod isa Concat then
+                               lnod = lnod.right
+                               r = new RopeIterPiece(lnod, false, true, r)
+                       else
+                               str = lnod
+                               iter = r
+                               break
+                       end
+               end
+       end
 
-       init(tgt: Rope, pos: Int)
-       do
-               nodes = tgt.postfix(pos)
+       init from(root: RopeString, pos: Int) do
+               var r = new RopeIterPiece(root, false, true, null)
+               var rnod: String = root
+               var off = pos
+               loop
+                       if rnod isa Concat then
+                               if off >= rnod.left.length then
+                                       off -= rnod.left.length
+                                       rnod = rnod.right
+                                       r = new RopeIterPiece(rnod, false, true, r)
+                               else
+                                       r.ldone = true
+                                       rnod = rnod.left
+                                       r = new RopeIterPiece(rnod, false, true, r)
+                               end
+                       else
+                               str = rnod
+                               r.ldone = true
+                               iter = r
+                               self.pos = pos - off
+                               break
+                       end
+               end
        end
 
-       redef fun is_ok do return nodes.is_ok
+       redef fun item do return str
 
-       redef fun item
-       do
-               assert is_ok
-               return nodes.item.as(Leaf)
-       end
+       redef fun index do return pos
 
-       redef fun index do return nodes.index
+       redef fun is_ok do return pos >= 0
 
-       redef fun next
-       do
-               while nodes.is_ok do
-                       nodes.next
-                       if nodes.is_ok and nodes.item isa Leaf then break
+       redef fun next do
+               if pos < 0 then return
+               var curr: nullable RopeIterPiece = iter.prev
+               var currit = curr.node
+               while curr != null do
+                       currit = curr.node
+                       if not currit isa Concat then
+                               str = currit
+                               pos -= str.length
+                               iter = curr
+                               return
+                       end
+                       if not curr.rdone then
+                               curr.rdone = true
+                               curr = new RopeIterPiece(currit.right, false, false, curr)
+                               continue
+                       end
+                       if not curr.ldone then
+                               curr.ldone = true
+                               curr = new RopeIterPiece(currit.left, false, false, curr)
+                               continue
+                       end
+                       curr = curr.prev
                end
+               pos = -1
        end
 end
 
-# Uses the leaves and calculates a new substring on each iteration
-class SubstringsIterator
-       super IndexedIterator[Text]
-
-       private var nodes: IndexedIterator[Leaf]
-
-       # Current position in Rope
-       var pos: Int
+private class RopeBufSubstringIterator
+       super Iterator[String]
 
-       # Current substring, computed from the current Leaf and indexes
-       var substring: Text
+       # Iterator on the substrings of the building string
+       var iter: Iterator[String]
+       # Makes a String out of the buffered part of the Ropebuffer
+       var nsstr: String
+       # Did we attain the buffered part ?
+       var nsstr_done = false
 
-       init(tgt: Rope, pos: Int)
-       do
-               nodes = tgt.leaves(pos)
-               self.pos = pos
-               if pos < 0 or pos >= tgt.length then return
-               make_substring
-       end
-
-       # Compute the bounds of the current substring and makes the substring
-       private fun make_substring
-       do
-               substring = nodes.item.str
-               var min = 0
-               var length = substring.length
-               if nodes.index < pos then
-                       min = pos - nodes.index
-               end
-               substring = substring.substring(min, length)
+       init(str: RopeBuffer) do
+               iter = str.str.substrings
+               nsstr = new FlatString.with_infos(str.ns, str.rpos - str.dumped, str.dumped, str.rpos - 1)
+               if str.length == 0 then nsstr_done = true
        end
 
-       redef fun is_ok do return nodes.is_ok
+       redef fun is_ok do return iter.is_ok or not nsstr_done
 
-       redef fun item
-       do
+       redef fun item do
                assert is_ok
-               return substring
+               if iter.is_ok then return iter.item
+               return nsstr
        end
 
-       redef fun index do return pos
-
-       redef fun next
-       do
-               pos += substring.length
-               nodes.next
-               if nodes.is_ok then make_substring
+       redef fun next do
+               if iter.is_ok then
+                       iter.next
+                       return
+               end
+               nsstr_done = true
        end
-
 end
 
-class RopeCharIterator
-       super IndexedIterator[Char]
-
-       var substrings: IndexedIterator[Text]
-
-       var pos: Int
-
-       var max: Int
-
-       var substr_iter: IndexedIterator[Char]
+# Substrings of a Rope (i.e. Postfix iterator on leaves)
+private class RopeSubstrings
+       super IndexedIterator[String]
+
+       # Visit Stack
+       var iter: RopeIterPiece is noinit
+       # Position in `Rope`
+       var pos: Int is noinit
+       # Maximum position in `Rope` (i.e. length - 1)
+       var max: Int is noinit
+
+       # Current leaf
+       var str: String is noinit
+
+       init(root: RopeString) do
+               var r = new RopeIterPiece(root, true, false, null)
+               pos = 0
+               max = root.length - 1
+               var rnod: String = root
+               loop
+                       if rnod isa Concat then
+                               rnod = rnod.left
+                               r = new RopeIterPiece(rnod, true, false, r)
+                       else
+                               str = rnod
+                               r.rdone = true
+                               iter = r
+                               break
+                       end
+               end
+       end
 
-       init(tgt: Rope, from: Int)
-       do
-               substrings = tgt.substrings_from(from)
-               max = tgt.length - 1
-               if not substrings.is_ok then
-                       pos = tgt.length
-                       return
+       init from(root: RopeString, pos: Int) do
+               var r = new RopeIterPiece(root, true, false, null)
+               max = root.length - 1
+               var rnod: String = root
+               var off = pos
+               loop
+                       if rnod isa Concat then
+                               if off >= rnod.left.length then
+                                       r.rdone = true
+                                       off -= rnod.left.length
+                                       rnod = rnod.right
+                                       r = new RopeIterPiece(rnod, true, false, r)
+                               else
+                                       rnod = rnod.left
+                                       r = new RopeIterPiece(rnod, true, false, r)
+                               end
+                       else
+                               str = rnod
+                               r.rdone = true
+                               iter = r
+                               self.pos = pos - off
+                               break
+                       end
                end
-               pos = from
-               substr_iter = substrings.item.chars.iterator
        end
 
-       redef fun item do return substr_iter.item
+       redef fun item do return str
 
        redef fun is_ok do return pos <= max
 
        redef fun index do return pos
 
-       redef fun next
-       do
-               pos += 1
-               if substr_iter.is_ok then
-                       substr_iter.next
-               end
-               if not substr_iter.is_ok then
-                       substrings.next
-                       if substrings.is_ok then
-                               substr_iter = substrings.item.chars.iterator
+       redef fun next do
+               pos += str.length
+               if pos > max then return
+               var it = iter.prev
+               var rnod: String = it.node
+               loop
+                       if not rnod isa Concat then
+                               it.ldone = true
+                               it.rdone = true
+                               str = rnod
+                               iter = it.as(not null)
+                               break
+                       end
+                       if not it.ldone then
+                               rnod = rnod.left
+                               it.ldone = true
+                               it = new RopeIterPiece(rnod, false, false, it)
+                       else if not it.rdone then
+                               it.rdone = true
+                               rnod = rnod.right
+                               it = new RopeIterPiece(rnod, false, false, it)
+                       else
+                               it = it.prev
+                               rnod = it.node
+                               continue
                        end
                end
        end
 end
 
-private class ReversePostfix
-       super IndexedIterator[RopeNode]
+# Implementation of a `StringCharView` for `RopeString` objects
+private class RopeChars
+       super StringCharView
 
-       var target: Rope
+       var tgt: RopeString
 
-       var pos: Int
+       init(s: RopeString) do tgt = s
 
-       var min = 0
+       redef fun [](i) do
+               return tgt[i]
+       end
 
-       var stack = new List[IteratorElement]
+       redef fun iterator_from(i) do return new RopeIter.from(tgt, i)
 
-       init from(tgt: Rope, pos: Int)
-       do
-               self.pos = pos
-               target = tgt
-               if pos < 0 or pos >= tgt.length then return
-               var path = tgt.node_at(pos)
-               self.pos -= path.offset
-               for i in path.stack do
-                       var elemt = new IteratorElement(i.node)
-                       elemt.right = true
-                       if i.left then
-                               elemt.left = true
-                       end
-                       stack.push elemt
-               end
-               stack.push(new IteratorElement(path.leaf))
-               stack.last.done = true
-       end
+       redef fun reverse_iterator_from(i) do return new RopeReviter.from(tgt, i)
 
-       redef fun item do
-               assert is_ok
-               return stack.last.node
-       end
+end
 
-       redef fun is_ok do return not stack.is_empty
+class RopeBufferIter
+       super IndexedIterator[Char]
 
-       redef fun index do return pos
+       var sit: IndexedIterator[Char]
 
-       redef fun next
-       do
-               if stack.is_empty then return
-               if pos < min then
-                       stack.clear
-                       return
-               end
-               var lst = stack.last
-               if lst.done then
-                       stack.pop
-                       next
-                       return
-               end
-               if not lst.right then
-                       var nod = lst.node.as(Concat)
-                       var rgt = nod.right
-                       lst.right = true
-                       if rgt != null then
-                               stack.push(new IteratorElement(rgt))
-                               next
-                               return
-                       end
-               end
-               if not lst.left then
-                       var nod = lst.node.as(Concat)
-                       var lft = nod.left
-                       lst.left = true
-                       if lft != null then
-                               stack.push(new IteratorElement(lft))
-                               next
-                               return
-                       end
-               end
-               if lst.node isa Leaf then pos -= lst.node.length
-               lst.done = true
-       end
-end
+       var ns: NativeString
+
+       var pns: Int
 
-private class ReverseLeavesIterator
-       super IndexedIterator[Leaf]
+       var maxpos: Int
 
-       var nodes: ReversePostfix
+       redef var index: Int
+
+       init(t: RopeBuffer) do
+               ns = t.ns
+               maxpos = t.rpos
+               sit = t.str.chars.iterator
+               pns = t.dumped
+               index = 0
+       end
 
-       init(tgt: Rope, from: Int)
-       do
-               nodes = tgt.reverse_postfix(from)
+       init from(t: RopeBuffer, pos: Int) do
+               ns = t.ns
+               maxpos = t.length
+               sit = t.str.chars.iterator_from(pos)
+               pns = pos - t.str.length
+               index = pos
        end
 
-       redef fun is_ok do return nodes.is_ok
+       redef fun is_ok do return index < maxpos
 
        redef fun item do
-               assert is_ok
-               return nodes.item.as(Leaf)
+               if sit.is_ok then return sit.item
+               return ns[pns]
        end
 
        redef fun next do
-               while nodes.is_ok do
-                       nodes.next
-                       if nodes.is_ok then if nodes.item isa Leaf then break
+               index += 1
+               if sit.is_ok then
+                       sit.next
+               else
+                       pns += 1
                end
        end
-
-       redef fun index do return nodes.index
-
 end
 
-private class ReverseSubstringsIterator
-       super IndexedIterator[Text]
+class RopeBufferReviter
+       super IndexedIterator[Char]
 
-       var leaves: ReverseLeavesIterator
+       var sit: IndexedIterator[Char]
 
-       var pos: Int
+       var ns: NativeString
+
+       var pns: Int
 
-       var str: Text
+       redef var index: Int
 
-       init(tgt: Rope, from: Int)
-       do
-               leaves = tgt.reverse_leaves(from)
-               pos = from
-               if not leaves.is_ok then return
-               str = leaves.item.str
-               make_substring
+       init(tgt: RopeBuffer) do
+               sit = tgt.str.chars.reverse_iterator
+               pns = tgt.rpos - 1
+               index = tgt.length - 1
+               ns = tgt.ns
        end
 
-       fun make_substring
-       do
-               if pos >= (leaves.index + str.length - 1) then return
-               str = str.substring(0, (pos - leaves.index + 1))
+       init from(tgt: RopeBuffer, pos: Int) do
+               sit = tgt.str.chars.reverse_iterator_from(pos - tgt.rpos - tgt.dumped)
+               pns = pos - tgt.str.length
+               index = pos
+               ns = tgt.ns
        end
 
-       redef fun is_ok do return leaves.is_ok
+       redef fun is_ok do return index > 0
 
        redef fun item do
-               assert is_ok
-               return str
+               if pns >= 0 then return ns[pns]
+               return sit.item
        end
 
-       redef fun index do return pos
-
        redef fun next do
-               pos -= str.length
-               leaves.next
-               if not leaves.is_ok then return
-               str = leaves.item.str
-               make_substring
+               index -= 1
+               if pns >= 0 then
+                       pns -= 1
+               else
+                       sit.next
+               end
        end
 end
 
-private class ReverseRopeCharIterator
-       super IndexedIterator[Char]
+# View on the chars of a `RopeBuffer`
+class RopeBufferChars
+       super BufferCharView
 
-       var substrs: IndexedIterator[Text]
+       redef type SELFTYPE: RopeBuffer
 
-       var pos: Int
-
-       var subiter: IndexedIterator[Char]
+       redef fun [](i) do
+               if i < target.str.length then
+                       return target.str[i]
+               else
+                       return target.ns[i - target.str.length]
+               end
+       end
 
-       init(tgt: Rope, from: Int)
-       do
-               substrs = tgt.reverse_substrings_from(from)
-               if not substrs.is_ok then
-                       pos = -1
-                       return
+       redef fun []=(i,c) do
+               if i == target.length then target.add c
+               if i < target.str.length then
+                       var s = target.str
+                       var l = s.substring(0, i)
+                       var r = s.substring_from(i + 1)
+                       target.str = l + c.to_s + r
+               else
+                       target.ns[i - target.str.length] = c
                end
-               subiter = substrs.item.chars.reverse_iterator
-               pos = from
        end
 
-       redef fun is_ok do return pos >= 0
+       redef fun add(c) do target.add c
 
-       redef fun item do
-               assert is_ok
-               return subiter.item
-       end
+       redef fun push(c) do target.add c
 
-       redef fun index do return pos
+       redef fun iterator_from(i) do return new RopeBufferIter.from(target, i)
 
-       redef fun next do
-               pos -= 1
-               if subiter.is_ok then subiter.next
-               if not subiter.is_ok then
-                       if substrs.is_ok then substrs.next
-                       if substrs.is_ok then subiter = substrs.item.chars.reverse_iterator
-               end
-       end
+       redef fun reverse_iterator_from(i) do return new RopeBufferReviter.from(target, i)
 end
-
index 4550113..a487d98 100644 (file)
@@ -22,9 +22,9 @@ import string_search
 import file
 import exec
 import stream
-import ropes
 import collection
 import math
+import ropes
 import kernel
 import gc
 import bitset
index 6765305..84b167a 100644 (file)
@@ -135,29 +135,6 @@ redef class Text
        redef fun write_to(stream) do stream.write(self)
 end
 
-redef class RopeNode
-       super Streamable
-end
-
-redef class Leaf
-
-       redef fun write_to(s) do s.write(str)
-end
-
-redef class Concat
-
-       redef fun write_to(s)
-       do
-               if left != null then left.write_to(s)
-               if right != null then right.write_to(s)
-       end
-end
-
-redef class RopeString
-
-       redef fun write_to(s) do root.write_to(s)
-end
-
 # Input streams with a buffer
 abstract class BufferedIStream
        super IStream
index e8e4a4e..28ad7b5 100644 (file)
@@ -494,6 +494,27 @@ abstract class Text
        #     assert "\n\"'\\\{\}".escape_to_nit      == "\\n\\\"\\'\\\\\\\{\\\}"
        fun escape_to_nit: String do return escape_more_to_c("\{\}")
 
+       # Escape to POSIX Shell (sh).
+       #
+       # Abort if the text contains a null byte.
+       #
+       #     assert "\n\"'\\\{\}0".escape_to_sh == "'\n\"'\\''\\\{\}0'"
+       fun escape_to_sh: String do
+               var b = new FlatBuffer
+               b.chars.add '\''
+               for i in [0..length[ do
+                       var c = chars[i]
+                       if c == '\'' then
+                               b.append("'\\''")
+                       else
+                               assert without_null_byte: c != '\0'
+                               b.add(c)
+                       end
+               end
+               b.chars.add '\''
+               return b.to_s
+       end
+
        # Return a string where Nit escape sequences are transformed.
        #
        #     var s = "\\n"
@@ -778,6 +799,8 @@ abstract class String
 
        fun insert_at(s: String, pos: Int): SELFTYPE is abstract
 
+       redef fun substrings: Iterator[String] is abstract
+
        # Returns a reversed version of self
        #
        #     assert "hello".reversed  == "olleh"
@@ -2098,7 +2121,6 @@ extern class NativeString `{ char* `}
        do
                assert length >= 0
                var str = new FlatString.with_infos(self, length, 0, length - 1)
-               str.real_items = self
                return str
        end
 
@@ -2108,7 +2130,8 @@ extern class NativeString `{ char* `}
                var new_self = calloc_string(length + 1)
                copy_to(new_self, length, 0, 0)
                var str = new FlatString.with_infos(new_self, length, 0, length - 1)
-               str.real_items = self
+               new_self[length] = '\0'
+               str.real_items = new_self
                return str
        end
 end
index 16c2502..c473a3c 100644 (file)
@@ -448,8 +448,8 @@ redef class FlatString
                        items.copy_to(new_str, bytelen, index_from, 0)
                        o.items.copy_to(new_str, o.bytelen, o.index_from, bytelen)
                        return new FlatString.full(new_str, 0, new_bytelen - 1, new_bytelen, newlen)
-               else if o isa RopeString then
-                       return new RopeString.from(self) + o
+               else if o isa Concat then
+                       return new Concat(self, o)
                else
                        # If it goes to this point, that means another String implementation was concerned, therefore you need to support the + operation for this variant
                        abort
@@ -519,7 +519,7 @@ redef class FlatBuffer
        redef var bytelen: Int
 
        redef init from(s) do
-               if s isa RopeString then
+               if s isa Concat then
                        with_capacity(50)
                        for i in s.substrings do self.append(i)
                end
@@ -618,7 +618,7 @@ redef class FlatBuffer
        end
 
        redef fun append(s) do
-               if s isa RopeString then
+               if s isa Concat then
                        for i in s.substrings do append i
                end
                var i = s.as(FlatString)
index 733a56e..16c0e4b 100644 (file)
@@ -284,7 +284,7 @@ class MakefileToolchain
                self.toolcontext.info("Total C source files to compile: {cfiles.length}", 2)
        end
 
-       fun makefile_name(mainmodule: MModule): String do return "{mainmodule.name}.mk"
+       fun makefile_name(mainmodule: MModule): String do return "{mainmodule.c_name}.mk"
 
        fun default_outname(mainmodule: MModule): String
        do
@@ -473,7 +473,7 @@ abstract class AbstractCompiler
        do
                if modelbuilder.toolcontext.opt_group_c_files.value then
                        if self.files.is_empty then
-                               var f = new CodeFile(mainmodule.name)
+                               var f = new CodeFile(mainmodule.c_name)
                                self.files.add(f)
                        end
                        return self.files.first
@@ -1697,7 +1697,7 @@ redef class MClassType
        do
                var res = self.c_name_cache
                if res != null then return res
-               res = "{mclass.intro_mmodule.name.to_cmangle}__{mclass.name.to_cmangle}"
+               res = "{mclass.intro_mmodule.c_name}__{mclass.name.to_cmangle}"
                self.c_name_cache = res
                return res
        end
@@ -1803,7 +1803,7 @@ redef class MClass
        fun c_name: String do
                var res = self.c_name_cache
                if res != null then return res
-               res = "{intro_mmodule.name.to_cmangle}__{name.to_cmangle}"
+               res = "{intro_mmodule.c_name}__{name.to_cmangle}"
                self.c_name_cache = res
                return res
        end
@@ -1831,7 +1831,7 @@ redef class MPropDef
        do
                var res = self.c_name_cache
                if res != null then return res
-               res = "{self.mclassdef.mmodule.name.to_cmangle}__{self.mclassdef.mclass.name.to_cmangle}__{self.mproperty.name.to_cmangle}"
+               res = "{self.mclassdef.mmodule.c_name}__{self.mclassdef.mclass.name.to_cmangle}__{self.mproperty.name.to_cmangle}"
                self.c_name_cache = res
                return res
        end
@@ -3015,6 +3015,19 @@ redef class Array[E]
 end
 
 redef class MModule
+       # Return the name of the global C identifier associated to `self`.
+       # This name is used to prefix files and other C identifiers associated with `self`.
+       var c_name: String is lazy do
+               var g = mgroup
+               var res
+               if g != null and g.mproject.name != name then
+                       res = g.mproject.name.to_cmangle + "__" + name.to_cmangle
+               else
+                       res = name.to_cmangle
+               end
+               return res
+       end
+
        # All `MProperty` associated to all `MClassDef` of `mclass`
        fun properties(mclass: MClass): Set[MProperty] do
                if not self.properties_cache.has_key(mclass) then
index 6a36b2b..b6cb920 100644 (file)
@@ -120,21 +120,21 @@ redef class AMethPropdef
                                mtype.compile_extern_type(v, ccu)
 
                                # has callbacks already been compiled? (this may very well happen with global compilation)
-                               if mmodule.check_callback_compilation(mtype) then mtype.compile_extern_helper_functions(v, ccu)
+                               mtype.compile_extern_helper_functions(v, ccu, mmodule.check_callback_compilation(mtype))
                        end
                end
 
                # compile callbacks
-               for cb in foreign_callbacks.callbacks do if mainmodule.check_callback_compilation(cb) then
-                       cb.compile_extern_callback(v, ccu)
+               for cb in foreign_callbacks.callbacks do
+                       cb.compile_extern_callback(v, ccu, mainmodule.check_callback_compilation(cb))
                end
 
-               for cb in foreign_callbacks.supers do if mainmodule.check_callback_compilation(cb) then
-                       cb.compile_extern_callback(v, ccu)
+               for cb in foreign_callbacks.supers do
+                       cb.compile_extern_callback(v, ccu, mainmodule.check_callback_compilation(cb))
                end
 
-               for cb in foreign_callbacks.casts do if mainmodule.check_callback_compilation(cb) then
-                       cb.compile_extern_callbacks(v, ccu)
+               for cb in foreign_callbacks.casts do
+                       cb.compile_extern_callbacks(v, ccu, mainmodule.check_callback_compilation(cb))
                end
 
                # manage nitni callback set
@@ -312,7 +312,7 @@ redef class MType
                ccu.header_c_types.add("#endif\n")
        end
 
-       private fun compile_extern_helper_functions(v: AbstractCompilerVisitor, ccu: CCompilationUnit)
+       private fun compile_extern_helper_functions(v: AbstractCompilerVisitor, ccu: CCompilationUnit, compile_implementation_too: Bool)
        do
                # actually, we do not need to do anything when using the bohem garbage collector
                var call_context = from_c_call_context
@@ -330,7 +330,7 @@ redef class MType
 end
 
 redef class MNullableType
-       redef fun compile_extern_helper_functions(v, ccu)
+       redef fun compile_extern_helper_functions(v, ccu, compile_implementation_too)
        do
                super
 
@@ -344,6 +344,8 @@ redef class MNullableType
                # In nitni files, #define friendly as extern
                ccu.header_decl.add("#define {base_cname} {full_cname}\n")
 
+               if not compile_implementation_too then return
+
                # FIXME: This is ugly an broke the separate compilation principle
                # The real function MUST be compiled only once, #define pragma only protect the compiler, not the loader
                # However, I am not sure of the right approach here (eg. week refs are ugly)
@@ -364,7 +366,7 @@ redef class MNullableType
 end
 
 redef class MExplicitCall
-       private fun compile_extern_callback(v: AbstractCompilerVisitor, ccu: CCompilationUnit)
+       private fun compile_extern_callback(v: AbstractCompilerVisitor, ccu: CCompilationUnit, compile_implementation_too: Bool)
        do
                var mproperty = mproperty
                assert mproperty isa MMethod
@@ -373,6 +375,8 @@ redef class MExplicitCall
                var full_friendly_csignature = mproperty.build_csignature(recv_mtype, v.compiler.mainmodule, null, long_signature, internal_call_context)
                ccu.header_decl.add("extern {full_friendly_csignature};\n")
 
+               if not compile_implementation_too then return
+
                # Internally, implement internal function
                var nitni_visitor = v.compiler.new_visitor
                nitni_visitor.frame = v.frame
@@ -424,7 +428,7 @@ redef class MExplicitCall
 end
 
 redef class MExplicitSuper
-       private fun compile_extern_callback(v: AbstractCompilerVisitor, ccu: CCompilationUnit)
+       private fun compile_extern_callback(v: AbstractCompilerVisitor, ccu: CCompilationUnit, compile_implementation_too: Bool)
        do
                var mproperty = from.mproperty
                assert mproperty isa MMethod
@@ -439,6 +443,8 @@ redef class MExplicitSuper
                var internal_cname = mproperty.build_cname(mclass_type, v.compiler.mainmodule, "___super", long_signature)
                ccu.header_decl.add("#define {friendly_cname} {internal_cname}\n")
 
+               if not compile_implementation_too then return
+
                # Internally, implement internal function
                var nitni_visitor = v.compiler.new_visitor
                nitni_visitor.frame = v.frame
@@ -477,7 +483,7 @@ redef class MExplicitSuper
 end
 
 redef class MExplicitCast
-       private fun compile_extern_callbacks(v: AbstractCompilerVisitor, ccu: CCompilationUnit)
+       private fun compile_extern_callbacks(v: AbstractCompilerVisitor, ccu: CCompilationUnit, compile_implementation_too: Bool)
        do
                var from = from
                var to = to
@@ -493,22 +499,23 @@ redef class MExplicitCast
                # In nitni files, #define friendly as extern
                ccu.header_decl.add("#define {check_cname} {v.compiler.mainmodule.name}___{check_cname}\n")
 
-               # Internally, implement internal function
-               var nitni_visitor = v.compiler.new_visitor
-               nitni_visitor.frame = v.frame
+               if compile_implementation_too then
+                       # Internally, implement internal function
+                       var nitni_visitor = v.compiler.new_visitor
+                       nitni_visitor.frame = v.frame
 
-               var full_internal_csignature = "int {v.compiler.mainmodule.name }___{from.mangled_cname}_is_a_{to.mangled_cname}({internal_call_context.name_mtype(from)} from)"
+                       var full_internal_csignature = "int {v.compiler.mainmodule.name }___{from.mangled_cname}_is_a_{to.mangled_cname}({internal_call_context.name_mtype(from)} from)"
 
-               nitni_visitor.add_decl("/* nitni check for {from} to {to} */")
-               nitni_visitor.add_decl("{full_internal_csignature} \{")
+                       nitni_visitor.add_decl("/* nitni check for {from} to {to} */")
+                       nitni_visitor.add_decl("{full_internal_csignature} \{")
 
-               #var from_var = new RuntimeVariable("from->value", from, from)
-               var from_var = nitni_visitor.var_from_c("from", from)
-               from_var = nitni_visitor.box_extern(from_var, from)
-               var recv_var = nitni_visitor.type_test(from_var, to, "FFI isa")
-               nitni_visitor.add("return {recv_var};")
+                       var from_var = nitni_visitor.var_from_c("from", from)
+                       from_var = nitni_visitor.box_extern(from_var, from)
+                       var recv_var = nitni_visitor.type_test(from_var, to, "FFI isa")
+                       nitni_visitor.add("return {recv_var};")
 
-               nitni_visitor.add("\}")
+                       nitni_visitor.add("\}")
+               end
 
                # special checks
                if from == to.as_nullable then
@@ -527,30 +534,32 @@ redef class MExplicitCast
                # In nitni files, #define friendly as extern
                ccu.header_decl.add("#define {cast_cname} {v.compiler.mainmodule.name}___{cast_cname}\n")
 
-               # Internally, implement internal function
-               nitni_visitor = v.compiler.new_visitor
-               nitni_visitor.frame = v.frame
+               if compile_implementation_too then
+                       # Internally, implement internal function
+                       var nitni_visitor = v.compiler.new_visitor
+                       nitni_visitor.frame = v.frame
 
-               full_internal_csignature = "{to.cname_blind} {v.compiler.mainmodule.name }___{from.mangled_cname}_as_{to.mangled_cname}({internal_call_context.name_mtype(from)} from)"
-               nitni_visitor.add_decl("/* nitni cast for {from} to {to} */")
-               nitni_visitor.add_decl("{full_internal_csignature} \{")
+                       var full_internal_csignature = "{to.cname_blind} {v.compiler.mainmodule.name }___{from.mangled_cname}_as_{to.mangled_cname}({internal_call_context.name_mtype(from)} from)"
+                       nitni_visitor.add_decl("/* nitni cast for {from} to {to} */")
+                       nitni_visitor.add_decl("{full_internal_csignature} \{")
 
-               from_var = nitni_visitor.var_from_c("from", from)
-               from_var = nitni_visitor.box_extern(from_var, from)
+                       var from_var = nitni_visitor.var_from_c("from", from)
+                       from_var = nitni_visitor.box_extern(from_var, from)
 
-               ## test type
-               var check = nitni_visitor.type_test(from_var, to, "FFI cast")
-               nitni_visitor.add("if (!{check}) \{")
-               nitni_visitor.add_abort("FFI cast failed")
-               nitni_visitor.add("\}")
+                       ## test type
+                       var check = nitni_visitor.type_test(from_var, to, "FFI cast")
+                       nitni_visitor.add("if (!{check}) \{")
+                       nitni_visitor.add_abort("FFI cast failed")
+                       nitni_visitor.add("\}")
 
-               ## internal cast
-               recv_var = nitni_visitor.autobox(from_var, to)
-               recv_var = nitni_visitor.unbox_extern(recv_var, to)
+                       ## internal cast
+                       var recv_var = nitni_visitor.autobox(from_var, to)
+                       recv_var = nitni_visitor.unbox_extern(recv_var, to)
 
-               nitni_visitor.ret_to_c(recv_var, to)
+                       nitni_visitor.ret_to_c(recv_var, to)
 
-               nitni_visitor.add("\}")
+                       nitni_visitor.add("\}")
+               end
 
                # special casts
                if from.as_nullable == to then
index 7509e55..491ebfe 100644 (file)
@@ -92,9 +92,11 @@ redef class ModelBuilder
                var compiler = new SeparateCompiler(mainmodule, self, runtime_type_analysis)
                compiler.compile_header
 
+               var c_name = mainmodule.c_name
+
                # compile class structures
                self.toolcontext.info("Property coloring", 2)
-               compiler.new_file("{mainmodule.name}.classes")
+               compiler.new_file("{c_name}.classes")
                compiler.do_property_coloring
                for m in mainmodule.in_importation.greaters do
                        for mclass in m.intro_mclasses do
@@ -104,21 +106,21 @@ redef class ModelBuilder
                end
 
                # The main function of the C
-               compiler.new_file("{mainmodule.name}.main")
+               compiler.new_file("{c_name}.main")
                compiler.compile_nitni_global_ref_functions
                compiler.compile_main_function
                compiler.compile_finalizer_function
 
                # compile methods
                for m in mainmodule.in_importation.greaters do
-                       self.toolcontext.info("Generate C for module {m}", 2)
-                       compiler.new_file("{m.name}.sep")
+                       self.toolcontext.info("Generate C for module {m.full_name}", 2)
+                       compiler.new_file("{m.c_name}.sep")
                        compiler.compile_module_to_c(m)
                end
 
                # compile live & cast type structures
                self.toolcontext.info("Type coloring", 2)
-               compiler.new_file("{mainmodule.name}.types")
+               compiler.new_file("{c_name}.types")
                var mtypes = compiler.do_type_coloring
                for t in mtypes do
                        compiler.compile_type_to_c(t)
index b90a8bd..233bf54 100644 (file)
@@ -67,9 +67,11 @@ redef class ModelBuilder
                var compiler = new SeparateErasureCompiler(mainmodule, self, runtime_type_analysis)
                compiler.compile_header
 
+               var c_name = mainmodule.c_name
+
                # compile class structures
                self.toolcontext.info("Property coloring", 2)
-               compiler.new_file("{mainmodule.name}.tables")
+               compiler.new_file("{c_name}.tables")
                compiler.do_property_coloring
                for m in mainmodule.in_importation.greaters do
                        for mclass in m.intro_mclasses do
@@ -79,14 +81,14 @@ redef class ModelBuilder
                compiler.compile_color_consts(compiler.vt_colors)
 
                # The main function of the C
-               compiler.new_file("{mainmodule.name}.main")
+               compiler.new_file("{c_name}.main")
                compiler.compile_nitni_global_ref_functions
                compiler.compile_main_function
 
                # compile methods
                for m in mainmodule.in_importation.greaters do
-                       self.toolcontext.info("Generate C for module {m}", 2)
-                       compiler.new_file("{m.name}.sep")
+                       self.toolcontext.info("Generate C for module {m.full_name}", 2)
+                       compiler.new_file("{m.c_name}.sep")
                        compiler.compile_module_to_c(m)
                end
 
index 78d42fb..5d71b02 100644 (file)
@@ -117,9 +117,9 @@ class Nitdoc
                end
                # copy shared files
                if ctx.opt_shareurl.value == null then
-                       sys.system("cp -r {sharedir.to_s}/* {output_dir.to_s}/")
+                       sys.system("cp -r -- {sharedir.to_s.escape_to_sh}/* {output_dir.to_s.escape_to_sh}/")
                else
-                       sys.system("cp -r {sharedir.to_s}/resources/ {output_dir.to_s}/resources/")
+                       sys.system("cp -r -- {sharedir.to_s.escape_to_sh}/resources/ {output_dir.to_s.escape_to_sh}/resources/")
                end
 
        end
@@ -311,14 +311,16 @@ abstract class NitdocPage
 
        # Clickable graphviz image using dot format
        # return null if no graph for this page
-       fun tpl_graph(dot: FlatBuffer, name: String, title: nullable String): nullable TplArticle do
+       fun tpl_graph(dot: Buffer, name: String, title: nullable String): nullable TplArticle do
                if ctx.opt_nodot.value then return null
                var output_dir = ctx.output_dir
-               var file = new OFStream.open("{output_dir}/{name}.dot")
+               var path = output_dir / name
+               var path_sh = path.escape_to_sh
+               var file = new OFStream.open("{path}.dot")
                file.write(dot)
                file.close
-               sys.system("\{ test -f {output_dir}/{name}.png && test -f {output_dir}/{name}.s.dot && diff {output_dir}/{name}.dot {output_dir}/{name}.s.dot >/dev/null 2>&1 ; \} || \{ cp {output_dir}/{name}.dot {output_dir}/{name}.s.dot && dot -Tpng -o{output_dir}/{name}.png -Tcmapx -o{output_dir}/{name}.map {output_dir}/{name}.s.dot ; \}")
-               var fmap = new IFStream.open("{output_dir}/{name}.map")
+               sys.system("\{ test -f {path_sh}.png && test -f {path_sh}.s.dot && diff -- {path_sh}.dot {path_sh}.s.dot >/dev/null 2>&1 ; \} || \{ cp -- {path_sh}.dot {path_sh}.s.dot && dot -Tpng -o{path_sh}.png -Tcmapx -o{path_sh}.map {path_sh}.s.dot ; \}")
+               var fmap = new IFStream.open("{path}.map")
                var map = fmap.read_all
                fmap.close
 
@@ -326,11 +328,12 @@ abstract class NitdocPage
                var alt = ""
                if title != null then
                        article.title = title
-                       alt = "alt='{title}'"
+                       alt = "alt='{title.html_escape}'"
                end
                article.css_classes.add "text-center"
                var content = new Template
-               content.add "<img src='{name}.png' usemap='#{name}' style='margin:auto' {alt}/>"
+               var name_html = name.html_escape
+               content.add "<img src='{name_html}.png' usemap='#{name_html}' style='margin:auto' {alt}/>"
                content.add map
                article.content = content
                return article
@@ -992,17 +995,17 @@ class NitdocModule
                        end
                end
                # build graph
-               var op = new FlatBuffer
-               var name = "dep_{mmodule.name}"
-               op.append("digraph {name} \{ rankdir=BT; node[shape=none,margin=0,width=0,height=0,fontsize=10]; edge[dir=none,color=gray]; ranksep=0.2; nodesep=0.1;\n")
+               var op = new RopeBuffer
+               var name = "dep_module_{mmodule.nitdoc_id}"
+               op.append("digraph \"{name.escape_to_dot}\" \{ rankdir=BT; node[shape=none,margin=0,width=0,height=0,fontsize=10]; edge[dir=none,color=gray]; ranksep=0.2; nodesep=0.1;\n")
                for mmodule in poset do
                        if mmodule == self.mmodule then
-                               op.append("\"{mmodule.name}\"[shape=box,margin=0.03];\n")
+                               op.append("\"{mmodule.name.escape_to_dot}\"[shape=box,margin=0.03];\n")
                        else
-                               op.append("\"{mmodule.name}\"[URL=\"{mmodule.nitdoc_url}\"];\n")
+                               op.append("\"{mmodule.name.escape_to_dot}\"[URL=\"{mmodule.nitdoc_url.escape_to_dot}\"];\n")
                        end
                        for omodule in poset[mmodule].direct_greaters do
-                               op.append("\"{mmodule.name}\"->\"{omodule.name}\";\n")
+                               op.append("\"{mmodule.name.escape_to_dot}\"->\"{omodule.name.escape_to_dot}\";\n")
                        end
                end
                op.append("\}\n")
@@ -1373,9 +1376,9 @@ class NitdocClass
                        end
                end
 
-               var op = new FlatBuffer
-               var name = "dep_{mclass.name}"
-               op.append("digraph {name} \{ rankdir=BT; node[shape=none,margin=0,width=0,height=0,fontsize=10]; edge[dir=none,color=gray]; ranksep=0.2; nodesep=0.1;\n")
+               var op = new RopeBuffer
+               var name = "dep_class_{mclass.nitdoc_id}"
+               op.append("digraph \"{name.escape_to_dot}\" \{ rankdir=BT; node[shape=none,margin=0,width=0,height=0,fontsize=10]; edge[dir=none,color=gray]; ranksep=0.2; nodesep=0.1;\n")
                var classes = poset.to_a
                var todo = new Array[MClass]
                var done = new HashSet[MClass]
@@ -1386,18 +1389,18 @@ class NitdocClass
                        if done.has(c) then continue
                        done.add c
                        if c == mclass then
-                               op.append("\"{c.name}\"[shape=box,margin=0.03];\n")
+                               op.append("\"{c.name.escape_to_dot}\"[shape=box,margin=0.03];\n")
                        else
-                               op.append("\"{c.name}\"[URL=\"{c.nitdoc_url}\"];\n")
+                               op.append("\"{c.name.escape_to_dot}\"[URL=\"{c.nitdoc_url.escape_to_dot}\"];\n")
                        end
                        var smallers = poset[c].direct_smallers
                        if smallers.length < 10 then
                                for c2 in smallers do
-                                       op.append("\"{c2.name}\"->\"{c.name}\";\n")
+                                       op.append("\"{c2.name.escape_to_dot}\"->\"{c.name.escape_to_dot}\";\n")
                                end
                                todo.add_all smallers
                        else
-                               op.append("\"...\"->\"{c.name}\";\n")
+                               op.append("\"...\"->\"{c.name.escape_to_dot}\";\n")
                        end
                end
                op.append("\}\n")
index c6687c7..86bba5f 100644 (file)
@@ -72,7 +72,9 @@ class NaiveInterpreter
        init
        do
                self.true_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, true)
+               init_instance_primitive(self.true_instance)
                self.false_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, false)
+               init_instance_primitive(self.false_instance)
                self.null_instance = new MutableInstance(mainmodule.model.null_type)
        end
 
@@ -189,22 +191,28 @@ class NaiveInterpreter
        # Return the integer instance associated with `val`.
        fun int_instance(val: Int): Instance
        do
-               var ic = self.mainmodule.get_primitive_class("Int")
-               return new PrimitiveInstance[Int](ic.mclass_type, val)
+               var ic = get_primitive_class("Int")
+               var instance = new PrimitiveInstance[Int](ic.mclass_type, val)
+               init_instance_primitive(instance)
+               return instance
        end
 
        # Return the char instance associated with `val`.
        fun char_instance(val: Char): Instance
        do
-               var ic = self.mainmodule.get_primitive_class("Char")
-               return new PrimitiveInstance[Char](ic.mclass_type, val)
+               var ic = get_primitive_class("Char")
+               var instance = new PrimitiveInstance[Char](ic.mclass_type, val)
+               init_instance_primitive(instance)
+               return instance
        end
 
        # Return the float instance associated with `val`.
        fun float_instance(val: Float): Instance
        do
-               var ic = self.mainmodule.get_primitive_class("Float")
-               return new PrimitiveInstance[Float](ic.mclass_type, val)
+               var ic = get_primitive_class("Float")
+               var instance = new PrimitiveInstance[Float](ic.mclass_type, val)
+               init_instance_primitive(instance)
+               return instance
        end
 
        # The unique instance of the `true` value.
@@ -221,8 +229,9 @@ class NaiveInterpreter
        fun array_instance(values: Array[Instance], elttype: MType): Instance
        do
                assert not elttype.need_anchor
-               var nat = new PrimitiveInstance[Array[Instance]](self.mainmodule.get_primitive_class("NativeArray").get_mtype([elttype]), values)
-               var mtype = self.mainmodule.get_primitive_class("Array").get_mtype([elttype])
+               var nat = new PrimitiveInstance[Array[Instance]](get_primitive_class("NativeArray").get_mtype([elttype]), values)
+               init_instance_primitive(nat)
+               var mtype = get_primitive_class("Array").get_mtype([elttype])
                var res = new MutableInstance(mtype)
                self.init_instance(res)
                self.send(self.force_get_primitive_method("with_native", mtype), [res, nat, self.int_instance(values.length)])
@@ -247,8 +256,10 @@ class NaiveInterpreter
        do
                var val = new FlatBuffer.from(txt)
                val.add('\0')
-               var ic = self.mainmodule.get_primitive_class("NativeString")
-               return new PrimitiveInstance[Buffer](ic.mclass_type, val)
+               var ic = get_primitive_class("NativeString")
+               var instance = new PrimitiveInstance[Buffer](ic.mclass_type, val)
+               init_instance_primitive(instance)
+               return instance
        end
 
        # Return a new String instance for `txt`
@@ -529,6 +540,16 @@ class NaiveInterpreter
                end
        end
 
+       # A hook to initialize a `PrimitiveInstance`
+       fun init_instance_primitive(recv: Instance) do end
+
+       # Return the primitive `MClass` corresponding to the `name` given in parameter
+       # `name` : name of the primitive class
+       fun get_primitive_class(name: String): MClass
+       do
+               return mainmodule.get_primitive_class(name)
+       end
+
        # This function determine the correct type according the reciever of the current definition (self).
        fun unanchor_type(mtype: MType): MType
        do
@@ -945,7 +966,9 @@ redef class AMethPropdef
                else if cname == "NativeArray" then
                        if pname == "new" then
                                var val = new Array[Instance].filled_with(v.null_instance, args[1].to_i)
-                               return new PrimitiveInstance[Array[Instance]](args[0].mtype, val)
+                               var instance = new PrimitiveInstance[Array[Instance]](args[0].mtype, val)
+                               v.init_instance_primitive(instance)
+                               return instance
                        end
                        var recvval = args.first.val.as(Array[Instance])
                        if pname == "[]" then
@@ -964,17 +987,27 @@ redef class AMethPropdef
                        end
                else if cname == "NativeFile" then
                        if pname == "native_stdout" then
-                               return new PrimitiveInstance[OStream](mpropdef.mclassdef.mclass.mclass_type, sys.stdout)
+                               var instance = new PrimitiveInstance[OStream](mpropdef.mclassdef.mclass.mclass_type, sys.stdout)
+                               v.init_instance_primitive(instance)
+                               return instance
                        else if pname == "native_stdin" then
-                               return new PrimitiveInstance[IStream](mpropdef.mclassdef.mclass.mclass_type, sys.stdin)
+                               var instance = new PrimitiveInstance[IStream](mpropdef.mclassdef.mclass.mclass_type, sys.stdin)
+                               v.init_instance_primitive(instance)
+                               return instance
                        else if pname == "native_stderr" then
-                               return new PrimitiveInstance[OStream](mpropdef.mclassdef.mclass.mclass_type, sys.stderr)
+                               var instance = new PrimitiveInstance[OStream](mpropdef.mclassdef.mclass.mclass_type, sys.stderr)
+                               v.init_instance_primitive(instance)
+                               return instance
                        else if pname == "io_open_read" then
                                var a1 = args[1].val.as(Buffer)
-                               return new PrimitiveInstance[IStream](mpropdef.mclassdef.mclass.mclass_type, new IFStream.open(a1.to_s))
+                               var instance = new PrimitiveInstance[IStream](mpropdef.mclassdef.mclass.mclass_type, new IFStream.open(a1.to_s))
+                               v.init_instance_primitive(instance)
+                               return instance
                        else if pname == "io_open_write" then
                                var a1 = args[1].val.as(Buffer)
-                               return new PrimitiveInstance[OStream](mpropdef.mclassdef.mclass.mclass_type, new OFStream.open(a1.to_s))
+                               var instance = new PrimitiveInstance[OStream](mpropdef.mclassdef.mclass.mclass_type, new OFStream.open(a1.to_s))
+                               v.init_instance_primitive(instance)
+                               return instance
                        end
                        var recvval = args.first.val
                        if pname == "io_write" then
@@ -995,10 +1028,12 @@ redef class AMethPropdef
                else if pname == "calloc_array" then
                        var recvtype = args.first.mtype.as(MClassType)
                        var mtype: MType
-                       mtype = recvtype.supertype_to(v.mainmodule, recvtype, v.mainmodule.get_primitive_class("ArrayCapable"))
+                       mtype = recvtype.supertype_to(v.mainmodule, recvtype, v.get_primitive_class("ArrayCapable"))
                        mtype = mtype.arguments.first
                        var val = new Array[Instance].filled_with(v.null_instance, args[1].to_i)
-                       return new PrimitiveInstance[Array[Instance]](v.mainmodule.get_primitive_class("NativeArray").get_mtype([mtype]), val)
+                       var instance = new PrimitiveInstance[Array[Instance]](v.get_primitive_class("NativeArray").get_mtype([mtype]), val)
+                       v.init_instance_primitive(instance)
+                       return instance
                else if pname == "native_argc" then
                        return v.int_instance(v.arguments.length)
                else if pname == "native_argv" then
@@ -1482,7 +1517,7 @@ redef class ASuperstringExpr
                        if i == null then return null
                        array.add(i)
                end
-               var i = v.array_instance(array, v.mainmodule.get_primitive_class("Object").mclass_type)
+               var i = v.array_instance(array, v.get_primitive_class("Object").mclass_type)
                var res = v.send(v.force_get_primitive_method("to_s", i.mtype), [i])
                assert res != null
                return res
index 3807ab7..9e9c778 100644 (file)
@@ -49,9 +49,9 @@ class VirtualMachine super NaiveInterpreter
 
        init(modelbuilder: ModelBuilder, mainmodule: MModule, arguments: Array[String])
        do
-               super
                var init_type = new MInitType(mainmodule.model)
                initialization_value = new MutableInstance(init_type)
+               super
        end
 
        # Subtyping test for the virtual machine
@@ -145,12 +145,30 @@ class VirtualMachine super NaiveInterpreter
 
                recv.vtable = recv.mtype.as(MClassType).mclass.vtable
 
-               assert(recv isa MutableInstance)
+               assert recv isa MutableInstance
 
                recv.internal_attributes = init_internal_attributes(initialization_value, recv.mtype.as(MClassType).mclass.all_mattributes(mainmodule, none_visibility).length)
                super
        end
 
+       # Associate a `PrimitiveInstance` to its `VTable`
+       redef fun init_instance_primitive(recv: Instance)
+       do
+               if not recv.mtype.as(MClassType).mclass.loaded then create_class(recv.mtype.as(MClassType).mclass)
+
+               recv.vtable = recv.mtype.as(MClassType).mclass.vtable
+       end
+
+       # Create a virtual table for this `MClass` if not already done
+       redef fun get_primitive_class(name: String): MClass
+       do
+               var mclass = super
+
+               if not mclass.loaded then create_class(mclass)
+
+               return mclass
+       end
+
        # Initialize the internal representation of an object (its attribute values)
        # `init_instance` is the initial value of attributes
        private fun init_internal_attributes(init_instance: Instance, size: Int): Pointer
@@ -169,6 +187,40 @@ class VirtualMachine super NaiveInterpreter
        # Creates the runtime structures for this class
        fun create_class(mclass: MClass) do     mclass.make_vt(self)
 
+       # Execute `mproperty` for a `args` (where `args[0]` is the receiver).
+       redef fun send(mproperty: MMethod, args: Array[Instance]): nullable Instance
+       do
+               var recv = args.first
+               var mtype = recv.mtype
+               var ret = send_commons(mproperty, args, mtype)
+               if ret != null then return ret
+
+               var propdef = method_dispatch(mproperty, recv.vtable.as(not null))
+
+               return self.call(propdef, args)
+       end
+
+       # Method dispatch, for a given global method `mproperty`
+       # returns the most specific local method in the class corresponding to `vtable`
+       private fun method_dispatch(mproperty: MMethod, vtable: VTable): MMethodDef
+       do
+               return method_dispatch_ph(vtable.internal_vtable, vtable.mask,
+                               mproperty.intro_mclassdef.mclass.vtable.id, mproperty.offset)
+       end
+
+       # Execute a method dispatch with perfect hashing
+       private fun method_dispatch_ph(vtable: Pointer, mask: Int, id: Int, offset: Int): MMethodDef `{
+               // Perfect hashing position
+               int hv = mask & id;
+               long unsigned int *pointer = (long unsigned int*)(((long int *)vtable)[-hv]);
+
+               // pointer+2 is the position where methods are
+               // Add the offset of property and get the method implementation
+               MMethodDef propdef = (MMethodDef)*(pointer + 2 + offset);
+
+               return propdef;
+       `}
+
        # Return the value of the attribute `mproperty` for the object `recv`
        redef fun read_attribute(mproperty: MAttribute, recv: Instance): Instance
        do
@@ -317,7 +369,12 @@ redef class MClass
                # When all super-classes have their identifiers and vtables, allocate current one
                allocate_vtable(v, ids, nb_methods, nb_attributes, offset_attributes, offset_methods)
                loaded = true
+
                # The virtual table now needs to be filled with pointer to methods
+               superclasses.add(self)
+               for cl in superclasses do
+                       fill_vtable(v, vtable.as(not null), cl)
+               end
        end
 
        # Allocate a single vtable
@@ -347,14 +404,19 @@ redef class MClass
                var self_methods = 0
                var nb_introduced_attributes = 0
 
-               # For self attributes, fixing offsets
-               var relative_offset = 0
+               # Fixing offsets for self attributes and methods
+               var relative_offset_attr = 0
+               var relative_offset_meth = 0
                for p in intro_mproperties(none_visibility) do
-                       if p isa MMethod then self_methods += 1
+                       if p isa MMethod then
+                               self_methods += 1
+                               p.offset = relative_offset_meth
+                               relative_offset_meth += 1
+                       end
                        if p isa MAttribute then
                                nb_introduced_attributes += 1
-                               p.offset = relative_offset
-                               relative_offset += 1
+                               p.offset = relative_offset_attr
+                               relative_offset_attr += 1
                        end
                end
 
@@ -374,6 +436,24 @@ redef class MClass
                vtable.internal_vtable = v.memory_manager.init_vtable(ids_total, nb_methods_total, d, vtable.mask)
        end
 
+       # Fill the vtable with methods of `self` class
+       #     `v` : Current instance of the VirtualMachine
+       #     `table` : the table of self class, will be filled with its methods
+       private fun fill_vtable(v:VirtualMachine, table: VTable, cl: MClass)
+       do
+               var methods = new Array[MMethodDef]
+               for m in cl.intro_mproperties(none_visibility) do
+                       if m isa MMethod then
+                               # `propdef` is the most specific implementation for this MMethod
+                               var propdef = m.lookup_first_definition(v.mainmodule, self.intro.bound_mtype)
+                               methods.push(propdef)
+                       end
+               end
+
+               # Call a method in C to put propdefs of self methods in the vtables
+               v.memory_manager.put_methods(vtable.internal_vtable, vtable.mask, cl.vtable.id, methods)
+       end
+
        # Computes delta for each class
        # A delta represents the offset for this group of attributes in the object
        #     `nb_attributes` : number of attributes for each class (classes are linearized from Object to current)
@@ -482,6 +562,11 @@ redef class MAttribute
        var offset: Int
 end
 
+redef class MMethod
+       # Represents the relative offset of this attribute in the runtime instance
+       var offset: Int
+end
+
 # Redef MutableInstance to improve implementation of attributes in objects
 redef class MutableInstance
 
@@ -489,6 +574,11 @@ redef class MutableInstance
        var internal_attributes: Pointer
 end
 
+# Redef to associate an `Instance` to its `VTable`
+redef class Instance
+       var vtable: nullable VTable
+end
+
 # Is the type of the initial value inside attributes
 class MInitType
        super MType
@@ -528,10 +618,6 @@ class VTable
        var classname: String is noinit
 end
 
-redef class Instance
-       var vtable: nullable VTable
-end
-
 # Handle memory, used for allocate virtual table and associated structures
 class MemoryManager
 
@@ -594,4 +680,29 @@ class MemoryManager
 
                return vtable;
        `}
+
+       # Put implementation of methods of a class in `vtable`
+       # `vtable` : Pointer to the C-virtual table
+       # `mask` : perfect-hashing mask of the class corresponding to the vtable
+       # `id` : id of the target class
+       # `methods` : array of MMethodDef of the target class
+       fun put_methods(vtable: Pointer, mask: Int, id: Int, methods: Array[MMethodDef])
+               import Array[MMethodDef].length, Array[MMethodDef].[] `{
+
+               // Get the area to fill with methods by a sequence of perfect hashing
+               int hv = mask & id;
+               long unsigned int *pointer = (long unsigned int*)(((long unsigned int *)vtable)[-hv]);
+
+               // pointer+2 is the beginning of the area for methods implementation
+               int length = Array_of_MMethodDef_length(methods);
+               long unsigned int *area = (pointer + 2);
+               int i;
+
+               for(i=0; i<length; i++)
+               {
+                       MMethodDef method = Array_of_MMethodDef__index(methods, i);
+                       area[i] = (long unsigned int)method;
+                       MMethodDef_incr_ref(method);
+               }
+       `}
 end
index 3dff2fc..c99dc83 100644 (file)
@@ -14,6 +14,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+#alt1 import standard
+#alt1 import standard::ropes
+
 var n = 7
 if not args.is_empty then
        n = args.first.to_i
@@ -22,7 +25,8 @@ end
 var s = "*"
 var i = 0
 while i < n do
-       var s2 = new FlatBuffer.from("Je dis Â«")
+       var s2: Buffer = new FlatBuffer.from("Je dis Â«")
+       #alt1 s2 = new RopeBuffer.from("Je dis Â«")
        s2.append(s)
        s2.append("» et redis Â«")
        s2.append(s)
index c00d979..e8d5c50 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+#alt1 import standard
+#alt1 import standard::ropes
+
 # A procedural program (without explicit class).
 
 fun first_word(s: String): String
 do
-       var result = new FlatBuffer
+       var result: Buffer = new FlatBuffer
+       #alt1 result = new RopeBuffer
        var i = 0
        while i < s.length and s.chars[i] != ' ' do
                result.add(s.chars[i])
index f066eac..aad8297 100644 (file)
@@ -18,6 +18,9 @@
 # It displays the value of a local variable.
 # It exhibs ways to concatenate strings.
 
+#alt1 import standard
+#alt1 import standard::ropes
+
 var a = 10
 # First way: Multiple parameters.
 # Pro: Simple.
@@ -27,7 +30,8 @@ printn("The value of a is: ", a, ".\n")
 # Second way: Build a string and display it.
 # Pro: Eiffel way (rigourous).
 # Con: Eiffel way (heavy).
-var s = new FlatBuffer.from("The value of a is: ")
+var s: Buffer = new FlatBuffer.from("The value of a is: ")
+#alt1 s = new RopeBuffer.from("The value of a is: ")
 s.append(a.to_s)
 s.append(".\n")
 printn(s)
diff --git a/tests/sav/bench_string_append_alt1.res b/tests/sav/bench_string_append_alt1.res
new file mode 100644 (file)
index 0000000..24c2167
--- /dev/null
@@ -0,0 +1,3 @@
+1092
+1365
+147447
diff --git a/tests/sav/example_procedural_string_alt1.res b/tests/sav/example_procedural_string_alt1.res
new file mode 100644 (file)
index 0000000..e965047
--- /dev/null
@@ -0,0 +1 @@
+Hello
diff --git a/tests/sav/example_string_alt1.res b/tests/sav/example_string_alt1.res
new file mode 100644 (file)
index 0000000..02444a6
--- /dev/null
@@ -0,0 +1,5 @@
+The value of a is: 10.
+The value of a is: 10.
+The value of a is: 10.
+The value of a is: 10.
+The value of a is: 10.
index 3494b3f..7b0f4e6 100644 (file)
@@ -4,34 +4,34 @@ class_module_0__Sys.html
 class_module_1__A.html
 class_module_1__B.html
 css/
-dep_A.dot
-dep_A.map
-dep_A.png
-dep_A.s.dot
-dep_B.dot
-dep_B.map
-dep_B.png
-dep_B.s.dot
-dep_Int.dot
-dep_Int.map
-dep_Int.png
-dep_Int.s.dot
-dep_Object.dot
-dep_Object.map
-dep_Object.png
-dep_Object.s.dot
-dep_Sys.dot
-dep_Sys.map
-dep_Sys.png
-dep_Sys.s.dot
-dep_module_0.dot
-dep_module_0.map
-dep_module_0.png
-dep_module_0.s.dot
-dep_module_1.dot
-dep_module_1.map
-dep_module_1.png
-dep_module_1.s.dot
+dep_class_module_0__Int.dot
+dep_class_module_0__Int.map
+dep_class_module_0__Int.png
+dep_class_module_0__Int.s.dot
+dep_class_module_0__Object.dot
+dep_class_module_0__Object.map
+dep_class_module_0__Object.png
+dep_class_module_0__Object.s.dot
+dep_class_module_0__Sys.dot
+dep_class_module_0__Sys.map
+dep_class_module_0__Sys.png
+dep_class_module_0__Sys.s.dot
+dep_class_module_1__A.dot
+dep_class_module_1__A.map
+dep_class_module_1__A.png
+dep_class_module_1__A.s.dot
+dep_class_module_1__B.dot
+dep_class_module_1__B.map
+dep_class_module_1__B.png
+dep_class_module_1__B.s.dot
+dep_module_module_0__module_0__module_0.dot
+dep_module_module_0__module_0__module_0.map
+dep_module_module_0__module_0__module_0.png
+dep_module_module_0__module_0__module_0.s.dot
+dep_module_module_1__module_1__module_1.dot
+dep_module_module_1__module_1__module_1.map
+dep_module_module_1__module_1__module_1.png
+dep_module_module_1__module_1__module_1.s.dot
 group_module_0__module_0.html
 group_module_1__module_1.html
 index.html
diff --git a/tests/sav/nitg-e/fixme/base_conflict_submodule_name.res b/tests/sav/nitg-e/fixme/base_conflict_submodule_name.res
deleted file mode 100644 (file)
index 7f85acf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Compilation error
diff --git a/tests/sav/nitg-e/fixme/base_conflict_submodule_name_alt1.res b/tests/sav/nitg-e/fixme/base_conflict_submodule_name_alt1.res
deleted file mode 100644 (file)
index 7f85acf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Compilation error
diff --git a/tests/sav/nitg-e/fixme/base_conflict_submodule_name_alt2.res b/tests/sav/nitg-e/fixme/base_conflict_submodule_name_alt2.res
deleted file mode 100644 (file)
index 7f85acf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Compilation error
diff --git a/tests/sav/nitg-g/fixme/base_conflict_submodule_name.res b/tests/sav/nitg-g/fixme/base_conflict_submodule_name.res
deleted file mode 100644 (file)
index 7f85acf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Compilation error
diff --git a/tests/sav/nitg-g/fixme/base_conflict_submodule_name_alt1.res b/tests/sav/nitg-g/fixme/base_conflict_submodule_name_alt1.res
deleted file mode 100644 (file)
index 7f85acf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Compilation error
diff --git a/tests/sav/nitg-g/fixme/base_conflict_submodule_name_alt2.res b/tests/sav/nitg-g/fixme/base_conflict_submodule_name_alt2.res
deleted file mode 100644 (file)
index 7f85acf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Compilation error
diff --git a/tests/sav/nitg-s/fixme/base_conflict_submodule_name.res b/tests/sav/nitg-s/fixme/base_conflict_submodule_name.res
deleted file mode 100644 (file)
index 7f85acf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Compilation error
diff --git a/tests/sav/nitg-s/fixme/base_conflict_submodule_name_alt1.res b/tests/sav/nitg-s/fixme/base_conflict_submodule_name_alt1.res
deleted file mode 100644 (file)
index 7f85acf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Compilation error
diff --git a/tests/sav/nitg-s/fixme/base_conflict_submodule_name_alt2.res b/tests/sav/nitg-s/fixme/base_conflict_submodule_name_alt2.res
deleted file mode 100644 (file)
index 7f85acf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Compilation error
diff --git a/tests/sav/nitg-sg/fixme/base_conflict_submodule_name.res b/tests/sav/nitg-sg/fixme/base_conflict_submodule_name.res
deleted file mode 100644 (file)
index 7f85acf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Compilation error
diff --git a/tests/sav/nitg-sg/fixme/base_conflict_submodule_name_alt1.res b/tests/sav/nitg-sg/fixme/base_conflict_submodule_name_alt1.res
deleted file mode 100644 (file)
index 7f85acf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Compilation error
diff --git a/tests/sav/nitg-sg/fixme/base_conflict_submodule_name_alt2.res b/tests/sav/nitg-sg/fixme/base_conflict_submodule_name_alt2.res
deleted file mode 100644 (file)
index 7f85acf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Compilation error
diff --git a/tests/sav/splay_test.res b/tests/sav/splay_test.res
deleted file mode 100644 (file)
index a8191ea..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-digraph g {
-[label = 6];
- ->  [label = "left"];
-[label = "AB" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = AB"];
- ->  [label = "right"];
-[label = 4];
- ->  [label = "left"];
-[label = "CD" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = CD"];
- ->  [label = "right"];
-[label = "EF" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = EF"];
-}
-
-ABCDEF
-digraph g {
-[label = 6];
- ->  [label = "left"];
-[label = 4];
- ->  [label = "left"];
-[label = "AB" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = AB"];
- ->  [label = "right"];
-[label = "CD" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = CD"];
- ->  [label = "right"];
-[label = "EF" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = EF"];
-}
-
-ABCDEF
-ABCDEFGH
-digraph g {
-[label = 8];
- ->  [label = "left"];
-[label = 6];
- ->  [label = "left"];
-[label = 4];
- ->  [label = "left"];
-[label = "AB" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = AB"];
- ->  [label = "right"];
-[label = "CD" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = CD"];
- ->  [label = "right"];
-[label = "EF" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = EF"];
- ->  [label = "right"];
-[label = "GH" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = GH"];
-}
-
-ABCDEFGH
-digraph g {
-[label = 8];
- ->  [label = "left"];
-[label = "AB" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = AB"];
- ->  [label = "right"];
-[label = 6];
- ->  [label = "left"];
-[label = 4];
- ->  [label = "left"];
-[label = "CD" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = CD"];
- ->  [label = "right"];
-[label = "EF" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = EF"];
- ->  [label = "right"];
-[label = "GH" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = GH"];
-}
-
-ABCDEFGH
-digraph g {
-[label = 8];
- ->  [label = "left"];
-[label = "AB" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = AB"];
- ->  [label = "right"];
-[label = 6];
- ->  [label = "left"];
-[label = "CD" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = CD"];
- ->  [label = "right"];
-[label = 4];
- ->  [label = "left"];
-[label = "EF" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = EF"];
- ->  [label = "right"];
-[label = "GH" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = GH"];
-}
-
-ABCDEFGH
-digraph g {
-[label = 8];
- ->  [label = "left"];
-[label = 6];
- ->  [label = "left"];
-[label = "AB" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = AB"];
- ->  [label = "right"];
-[label = 4];
- ->  [label = "left"];
-[label = "CD" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = CD"];
- ->  [label = "right"];
-[label = "EF" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = EF"];
- ->  [label = "right"];
-[label = "GH" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = GH"];
-}
-
-ABCDEFGH
-digraph g {
-[label = 8];
- ->  [label = "left"];
-[label = 6];
- ->  [label = "left"];
-[label = "AB" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = AB"];
- ->  [label = "right"];
-[label = 4];
- ->  [label = "left"];
-[label = "CD" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = CD"];
- ->  [label = "right"];
-[label = "EF" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = EF"];
- ->  [label = "right"];
-[label = "GH" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = GH"];
-}
-
-ABCDEFGH
-digraph g {
-[label = 8];
- ->  [label = "left"];
-[label = 4];
- ->  [label = "left"];
-[label = "AB" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = AB"];
- ->  [label = "right"];
-[label = "CD" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = CD"];
- ->  [label = "right"];
-[label = 4];
- ->  [label = "left"];
-[label = "EF" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = EF"];
- ->  [label = "right"];
-[label = "GH" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = GH"];
-}
-
-ABCDEFGH
-digraph g {
-[label = 8];
- ->  [label = "left"];
-[label = "AB" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = AB"];
- ->  [label = "right"];
-[label = 6];
- ->  [label = "left"];
-[label = 4];
- ->  [label = "left"];
-[label = "CD" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = CD"];
- ->  [label = "right"];
-[label = "EF" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = EF"];
- ->  [label = "right"];
-[label = "GH" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = GH"];
-}
-
-ABCDEFGH
-digraph g {
-[label = 8];
- ->  [label = "left"];
-[label = 4];
- ->  [label = "left"];
-[label = "AB" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = AB"];
- ->  [label = "right"];
-[label = "CD" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = CD"];
- ->  [label = "right"];
-[label = 4];
- ->  [label = "left"];
-[label = "EF" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = EF"];
- ->  [label = "right"];
-[label = "GH" shape = rect];
- -> [label = "contains"];
- [label="FlatString\nindex_from = 0\nindex_to = 1\nNativeString = GH"];
-}
-
diff --git a/tests/sav/string_trim_alt1.res b/tests/sav/string_trim_alt1.res
new file mode 100644 (file)
index 0000000..24d9987
--- /dev/null
@@ -0,0 +1,13 @@
+resulttrim = nono nono
+returntrim + nono nono
+thirdtrim = nono nono
+emptytrim = 
+bufferemptytrim = 
+onelettertrim = d
+oneletterbuftest = d
+twolettertrim = hg
+twoletterbuftest = hg
+firstlettertrimtest = d
+firstlettertrimbuftest = d
+lastlettertrimtest = d
+lastlettertrimbuftest = d
diff --git a/tests/sav/test_ffi_c_duplicated_callback_a.res b/tests/sav/test_ffi_c_duplicated_callback_a.res
new file mode 100644 (file)
index 0000000..479d9d1
--- /dev/null
@@ -0,0 +1 @@
+Hello from `a`.
diff --git a/tests/sav/test_ffi_c_duplicated_callback_b.res b/tests/sav/test_ffi_c_duplicated_callback_b.res
new file mode 100644 (file)
index 0000000..8c51d75
--- /dev/null
@@ -0,0 +1,2 @@
+Hello from `a`.
+Hello from `b`.
diff --git a/tests/sav/test_ffi_cpp_duplicated_callback_a.res b/tests/sav/test_ffi_cpp_duplicated_callback_a.res
new file mode 100644 (file)
index 0000000..479d9d1
--- /dev/null
@@ -0,0 +1 @@
+Hello from `a`.
diff --git a/tests/sav/test_ffi_cpp_duplicated_callback_b.res b/tests/sav/test_ffi_cpp_duplicated_callback_b.res
new file mode 100644 (file)
index 0000000..8c51d75
--- /dev/null
@@ -0,0 +1,2 @@
+Hello from `a`.
+Hello from `b`.
index cfbc1fb..bf79e4b 100644 (file)
@@ -1,4 +1,4 @@
-Runtime error: Cast failed. Expected `E`, got `Bool` (../lib/standard/collection/array.nit:769)
+Runtime error: Cast failed. Expected `E`, got `Bool` (../lib/standard/collection/array.nit:789)
 NativeString
 N
 Nit
index 7e4b7c1..8c7831d 100644 (file)
@@ -13,7 +13,6 @@ now step live...
 now step live...
  live...
 .
- live stepnow
 ...evil pets won
 n
 now step live... step live...
diff --git a/tests/sav/test_ropes_alt1.res b/tests/sav/test_ropes_alt1.res
deleted file mode 100644 (file)
index 7e4b7c1..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-NODEATTEST
-INZZ
-INDDZZ
-EEINDDZZ
-EEINDDZZFF
-eeinddzzff
-EEINDDZZFF
-FFZZDDNIEE
-hello_world.types.1.o
-now step live...
-...evil pets won
-now step live...
-now step live...
- live...
-.
- live stepnow
-...evil pets won
-n
-now step live... step live...
-w s
-ZZ
-ZZZZZZZZZZ
-ZZAAZZZZZZZZ
-NNZZAAZZZZZZZZ
-NIINZZAAZZZZZZZZ
-NINIINZZAAZZZZZZZZINZZAAZZZZZZZZ
diff --git a/tests/sav/test_ropes_alt2.res b/tests/sav/test_ropes_alt2.res
deleted file mode 100644 (file)
index 3fa08b9..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-NODEATTEST
-INZZ
-INDDZZ
-EEINDDZZ
-EEINDDZZFF
-eeinddzzff
-EEINDDZZFF
-FFZZDDNIEE
-hello_world.types.1.o
-now step live...
-...evil pets won
-now step live...
-now step live...
- live...
-.
-now step live
-...evil pets won
-n
-now step live... step live...
-w s
-ZZ
-ZZZZZZZZZZ
-ZZAAZZZZZZZZ
-NNZZAAZZZZZZZZ
-NIINZZAAZZZZZZZZ
-NINIINZZAAZZZZZZZZINZZAAZZZZZZZZ
diff --git a/tests/sav/test_string_long_alt1.res b/tests/sav/test_string_long_alt1.res
new file mode 100644 (file)
index 0000000..21373ff
--- /dev/null
@@ -0,0 +1,10000 @@
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
+Bonjour !
diff --git a/tests/sav/test_to_upper_lower_buffer_alt1.res b/tests/sav/test_to_upper_lower_buffer_alt1.res
new file mode 100644 (file)
index 0000000..e69de29
index acc2856..2137a3a 100644 (file)
@@ -17,7 +17,7 @@
 fun nsieve(n: Int): Int
 do
        var count = 0
-       var array = new FlatBuffer.with_capacity(n)
+       var array: Buffer = new FlatBuffer.with_capacity(n)
        for i in [0..n[ do
                array.chars[i] = 'o'
        end
diff --git a/tests/splay_test.nit b/tests/splay_test.nit
deleted file mode 100644 (file)
index dae8aef..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT.  This software 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.  You can modify it is you want,  provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You  are  allowed  to  redistribute it and sell it, alone or is a part of
-# another product.
-
-intrude import splay_ropes
-intrude import standard::ropes
-intrude import ropes_debug
-
-redef class Leaf
-       redef fun to_dot(s): String
-       do
-               s += "[label = \"{str}\" shape = rect];\n"
-               s += " -> [label = \"contains\"];\n"
-               s = str.to_dot(s)
-               return s
-       end
-end
-
-redef class Concat
-       redef fun to_dot(s): String
-       do
-               s += "[label = {length}];\n"
-               if left != null then
-                       s += " ->  [label = \"left\"];\n"
-                       s = left.to_dot(s)
-               end
-               if right != null then
-                       s += " ->  [label = \"right\"];\n"
-                       s = right.to_dot(s)
-               end
-               return s
-       end
-end
-
-redef class FlatString
-       redef fun to_dot(s: String): String
-       do
-               return s + " [label=\"FlatString\\nindex_from = {index_from}\\nindex_to = {index_to}\\nNativeString = {items.to_s_with_length(items.cstring_length)}\"];\n"
-       end
-end
-
-redef class FlatBuffer
-       redef fun to_dot(s: String): String
-       do
-               return s + " [label=\"FlatBuffer\\length = {length}\\ncapacity = {capacity}\\nitems = {items.to_s_with_length(items.cstring_length)}\"];\n"
-       end
-end
-
-
-redef class RopeString
-
-       redef fun to_dot(f)
-       do
-               var ret: String = new RopeString.from("digraph g \{\n")
-               ret = root.to_dot(ret).as(RopeString)
-               ret += "\}\n"
-               print ret
-               return ret
-       end
-
-end
-
-var ab = new StringLeaf("AB".as(FlatString))
-var cd = new StringLeaf("CD".as(FlatString))
-var ef = new StringLeaf("EF".as(FlatString))
-var gh = new StringLeaf("GH".as(FlatString))
-
-# Zig test
-
-var c = new Concat(cd,ef)
-c = new Concat(ab,c)
-var ro = new RopeString.from_root(c)
-
-ro.to_dot("Zig-Before_splay.dot")
-print ro
-
-var p = ro.node_at(5)
-
-ro = new RopeString.from_root(ro.splay(p).as(not null))
-
-ro.to_dot("Zig-After_splay.dot")
-print ro
-
-# Zig-zig test left left
-
-var d = new Concat(ab,cd)
-var e = new Concat(d,ef)
-var f = new Concat(e,gh)
-ro = new RopeString.from_root(f)
-
-p = ro.node_at(0)
-
-print ro
-ro.to_dot("Zig-zigll-Before_splay.dot")
-
-ro = new RopeString.from_root(ro.splay(p).as(not null))
-
-print ro
-ro.to_dot("Zig-zigll-After_splay.dot")
-
-# Zig-zig test right right
-
-d = new Concat(ef,gh)
-e = new Concat(cd,d)
-f = new Concat(ab,e)
-ro = new RopeString.from_root(f)
-
-p = ro.node_at(7)
-
-print ro
-ro.to_dot("Zig-zigrr-Before_splay.dot")
-
-ro = new RopeString.from_root(ro.splay(p).as(not null))
-
-print ro
-ro.to_dot("Zig-zigrr-After_splay.dot")
-
-# Zig-zag test left right
-
-d = new Concat(cd,ef)
-e = new Concat(ab,d)
-f = new Concat(e,gh)
-ro = new RopeString.from_root(f)
-
-p = ro.node_at(4)
-
-print ro
-ro.to_dot("Zig-zaglr-Before_splay.dot")
-
-ro = new RopeString.from_root(ro.splay(p).as(not null))
-
-print ro
-ro.to_dot("Zig-zaglr-After_splay.dot")
-
-# Zig-zag test right left
-
-d = new Concat(cd,ef)
-e = new Concat(d,gh)
-f = new Concat(ab,e)
-ro = new RopeString.from_root(f)
-
-p = ro.node_at(4)
-
-print ro
-ro.to_dot("Zig-zagrl-Before_splay.dot")
-
-ro = new RopeString.from_root(ro.splay(p).as(not null))
-
-print ro
-ro.to_dot("Zig-zagrl-After_splay.dot")
-
index 387c8b1..81ce2bd 100644 (file)
@@ -1,10 +1,12 @@
-module string_trim
+#alt1 import standard::ropes
+#alt1 import standard
 
 var trimtest = "   \t nono nono   \n \t"
 
 var subtrim = trimtest.substring(2,15)
 
-var buffertrimtest = new FlatBuffer.from(trimtest)
+var buffertrimtest: Buffer = new FlatBuffer.from(trimtest)
+#alt1 buffertrimtest = new RopeBuffer.from(trimtest)
 
 print "resulttrim = {buffertrimtest.trim}"
 
@@ -14,7 +16,8 @@ print "thirdtrim = {subtrim.trim}"
 
 var emptytrim = "         \t  "
 
-var bufferemptytest = new FlatBuffer.from(emptytrim)
+var bufferemptytest: Buffer = new FlatBuffer.from(emptytrim)
+#alt1 bufferemptytest = new RopeBuffer.from(emptytrim)
 
 print "emptytrim = {emptytrim.trim}"
 
@@ -22,7 +25,8 @@ print "bufferemptytrim = {bufferemptytest.trim}"
 
 var onelettertrim = "    \n   d      \n\t  "
 
-var oneletterbuftest = new FlatBuffer.from(onelettertrim)
+var oneletterbuftest: Buffer = new FlatBuffer.from(onelettertrim)
+#alt1 oneletterbuftest = new RopeBuffer.from(onelettertrim)
 
 print "onelettertrim = {onelettertrim.trim}"
 
@@ -30,7 +34,8 @@ print "oneletterbuftest = {oneletterbuftest.trim}"
 
 var twolettertrim = "    \n   hg      \n\t  "
 
-var twoletterbuftest = new FlatBuffer.from(twolettertrim)
+var twoletterbuftest: Buffer = new FlatBuffer.from(twolettertrim)
+#alt1 twoletterbuftest = new RopeBuffer.from(twolettertrim)
 
 print "twolettertrim = {twolettertrim.trim}"
 
@@ -38,7 +43,8 @@ print "twoletterbuftest = {twoletterbuftest.trim}"
 
 var firstlettertrim = "d                "
 
-var firstlettertrimbuf = new FlatBuffer.from(firstlettertrim)
+var firstlettertrimbuf: Buffer = new FlatBuffer.from(firstlettertrim)
+#alt1 firstlettertrimbuf = new RopeBuffer.from(firstlettertrim)
 
 print "firstlettertrimtest = {firstlettertrim.trim}"
 
@@ -46,7 +52,8 @@ print "firstlettertrimbuftest = {firstlettertrimbuf.trim}"
 
 var lastlettertrim = "                     d"
 
-var lastlettertrimbuf = new FlatBuffer.from(lastlettertrim)
+var lastlettertrimbuf: Buffer = new FlatBuffer.from(lastlettertrim)
+#alt1 lastlettertrimbuf = new RopeBuffer.from(lastlettertrim)
 
 print "lastlettertrimtest = {lastlettertrim.trim}"
 
index f9a416d..3f080c1 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-var rp: String = new RopeString.from("xxx")
-rp += "yyy"
+import standard
+intrude import standard::ropes
+
+var rp: String = new Concat("xxx", "yyy")
 rp += "zzz"
 var arr = ["FlatString", rp]
 print arr.to_s
diff --git a/tests/test_ffi_c_duplicated_callback_a.nit b/tests/test_ffi_c_duplicated_callback_a.nit
new file mode 100644 (file)
index 0000000..3347747
--- /dev/null
@@ -0,0 +1,23 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+`{
+       #include <stdio.h>
+`}
+
+fun print_a(str: String) import String.to_cstring `{
+       puts(String_to_cstring(str));
+`}
+
+print_a "Hello from `a`."
diff --git a/tests/test_ffi_c_duplicated_callback_b.nit b/tests/test_ffi_c_duplicated_callback_b.nit
new file mode 100644 (file)
index 0000000..d55db5e
--- /dev/null
@@ -0,0 +1,26 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import test_ffi_c_duplicated_callback_a
+
+`{
+       #include <stdio.h>
+`}
+
+fun print_b(str: String) import String.to_cstring `{
+       puts(String_to_cstring(str));
+`}
+
+print_a "Hello from `a`."
+print_b "Hello from `b`."
diff --git a/tests/test_ffi_cpp_duplicated_callback_a.nit b/tests/test_ffi_cpp_duplicated_callback_a.nit
new file mode 100644 (file)
index 0000000..76c1172
--- /dev/null
@@ -0,0 +1,23 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+in "C++ Header" `{
+       #include <stdio.h>
+`}
+
+fun print_a(str: String) import String.to_cstring in "C++" `{
+       puts(String_to_cstring(str));
+`}
+
+print_a "Hello from `a`."
diff --git a/tests/test_ffi_cpp_duplicated_callback_b.nit b/tests/test_ffi_cpp_duplicated_callback_b.nit
new file mode 100644 (file)
index 0000000..01eb25c
--- /dev/null
@@ -0,0 +1,26 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import test_ffi_cpp_duplicated_callback_a
+
+in "C++ header" `{
+       #include <stdio.h>
+`}
+
+fun print_b(str: String) import String.to_cstring in "C++" `{
+       puts(String_to_cstring(str));
+`}
+
+print_a "Hello from `a`."
+print_b "Hello from `b`."
index d08aa03..1e54bee 100644 (file)
@@ -12,8 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#alt1 import splay_ropes
-#alt2 import bufferized_ropes
+#alt1 import standard
+#alt1 import buffered_ropes
 
 var st = "quick brown fox over the lazy dog"
 
index 2d03f50..c8829ee 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#alt1 import splay_ropes
-#alt2 import bufferized_ropes
+import standard
+intrude import standard::ropes
 
-var x :String = new RopeString
+# Force building a Rope
+redef fun maxlen: Int do return once 2
 
-x = x + "NODE"
-x = x + "AT"
-x = x + "TEST"
+var x :String = new Concat("NODE", "AT")
+
+x += "TEST"
 
 print x
 
 var lst = new List[String]
 
-lst.push(new RopeString.from("ZZ"))
+lst.push("ZZ")
 
 lst.push((lst.last * 5))
 
@@ -41,7 +42,7 @@ var ss = lst.last.substring(4,4)
 
 print ss
 
-ss = ss.as(RopeString).insert_at("DD", 2)
+ss = ss.insert_at("DD", 2)
 
 print ss
 
@@ -67,15 +68,14 @@ print ss
 
 var atb = new Array[String]
 
-var s: String = new RopeString
-s = s + "./examples/hello_world.nit".substring(11,11) + ".types"
+var s: String = "./examples/hello_world.nit".substring(11,11) + ".types"
 s += "."
 s += "1"
 s += ".o"
 
 print s
 
-var str = new RopeString.from("now") + " step" + " live..."
+var str = "now" + " step" + " live..."
 
 print str
 
@@ -101,16 +101,13 @@ printn "\n"
 for i in str.chars.iterator_from(str.length-1) do printn i
 printn "\n"
 
-for i in str.as(RopeString).reverse_substrings_from(12) do printn i
-printn "\n"
-
 for i in str.chars.reverse_iterator do printn i
 printn "\n"
 
 for i in str.chars.reverse_iterator_from(0) do printn i
 printn "\n"
 
-var str2 = str.as(RopeString).insert_at(str.substring_from(3), 3)
+var str2 = str.insert_at(str.substring_from(3), 3)
 
 print str2
 
index 04655ba..6bfb034 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+#alt1 import standard
+#alt1 import standard::ropes
 
 var s = "Bonjour !\n"
-var r = new FlatBuffer.with_capacity(50)
-var r2 = new FlatBuffer
+var r: Buffer = new FlatBuffer.with_capacity(50)
+#alt1 r = new RopeBuffer
+var r2: Buffer = new FlatBuffer
+#alt1 r2 = new RopeBuffer
 
 var i = 0
 while i < 5000 do
index 2b6ef28..3e7da27 100644 (file)
@@ -12,7 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#alt3 import bufferized_ropes
+#alt2 import standard
+#alt2 import buffered_ropes
 
 var str = "Woe to you, oh earth and sea for the Devil sends the beast with wrath because he knows the time is short. Let him who hath understanding reckon the number of the beast, for it is a human number, its number is Six Hundred and Sixty-Six."
 var spaces = "           "
@@ -32,17 +33,11 @@ num = numstr
 #alt1 trimable.append(spaces)
 #alt1 num = new FlatBuffer.from(numstr)
 
-#alt2 txt = new RopeString.from(str)
-#alt2 trimable = new RopeString.from(spaces)
-#alt2 trimable = trimable + str
-#alt2 trimable = trimable + spaces
-#alt2 num = new RopeString.from(numstr)
-
-#alt3 txt = new RopeString.from(str)
-#alt3 trimable = new RopeString.from(spaces)
-#alt3 trimable = trimable + str
-#alt3 trimable = trimable + spaces
-#alt3 num = new RopeString.from(numstr)
+#alt3 txt = new RopeBuffer.from(str)
+#alt3 trimable = new RopeBuffer.from(spaces)
+#alt3 trimable.append(str)
+#alt3 trimable.append(spaces)
+#alt3 num = new RopeBuffer.from(numstr)
 
 # Test Text methods on all types of receivers
 
index d8b7eb5..e856eff 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-var x = new FlatBuffer.from("test")
-var y = new FlatBuffer.from("TEST")
+#alt1 import standard::ropes
+
+var x: Buffer = new FlatBuffer.from("test")
+#alt1 x = new RopeBuffer.from("test")
+var y: Buffer = new FlatBuffer.from("TEST")
+#alt1 y = new RopeBuffer.from("TEST")
 
 x.upper
 y.lower