ffi-yajl 0.0.1-universal-java → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +21 -201
  3. data/README.md +105 -10
  4. data/bin/ffi-yajl-bench +11 -11
  5. data/ext/ffi_yajl/ext/dlopen/dlopen.c +40 -0
  6. data/ext/ffi_yajl/ext/dlopen/extconf.rb +16 -0
  7. data/ext/ffi_yajl/ext/dlopen/yajl.sym +18 -0
  8. data/ext/ffi_yajl/ext/encoder/encoder.c +270 -115
  9. data/ext/ffi_yajl/ext/encoder/extconf.rb +71 -14
  10. data/ext/ffi_yajl/ext/parser/extconf.rb +71 -14
  11. data/ext/ffi_yajl/ext/parser/parser.c +85 -44
  12. data/lib/ffi_yajl/benchmark/encode.rb +39 -92
  13. data/lib/ffi_yajl/benchmark/encode_json_and_marshal.rb +23 -23
  14. data/lib/ffi_yajl/benchmark/encode_json_and_yaml.rb +24 -30
  15. data/lib/ffi_yajl/benchmark/encode_profile.rb +15 -19
  16. data/lib/ffi_yajl/benchmark/http.rb +21 -25
  17. data/lib/ffi_yajl/benchmark/parse.rb +77 -117
  18. data/lib/ffi_yajl/benchmark/parse_json_and_marshal.rb +27 -27
  19. data/lib/ffi_yajl/benchmark/parse_json_and_yaml.rb +30 -30
  20. data/lib/ffi_yajl/benchmark/parse_profile.rb +14 -18
  21. data/lib/ffi_yajl/benchmark/parse_profile_ruby_prof.rb +14 -19
  22. data/lib/ffi_yajl/benchmark/parse_stream.rb +28 -28
  23. data/lib/ffi_yajl/benchmark.rb +26 -6
  24. data/lib/ffi_yajl/encoder.rb +47 -6
  25. data/lib/ffi_yajl/ext.rb +37 -10
  26. data/lib/ffi_yajl/ffi/encoder.rb +150 -63
  27. data/lib/ffi_yajl/ffi/parser.rb +82 -64
  28. data/lib/ffi_yajl/ffi.rb +70 -46
  29. data/lib/ffi_yajl/map_library_name.rb +109 -0
  30. data/lib/ffi_yajl/parser.rb +69 -1
  31. data/lib/ffi_yajl/platform.rb +29 -0
  32. data/lib/ffi_yajl/version.rb +23 -1
  33. data/lib/ffi_yajl.rb +44 -8
  34. metadata +25 -238
  35. data/Rakefile +0 -62
  36. data/ext/libyajl2/extconf.rb +0 -65
  37. data/ext/libyajl2/vendored/.git +0 -1
  38. data/ext/libyajl2/vendored/.gitignore +0 -3
  39. data/ext/libyajl2/vendored/BUILDING +0 -23
  40. data/ext/libyajl2/vendored/BUILDING.win32 +0 -27
  41. data/ext/libyajl2/vendored/CMakeLists.txt +0 -79
  42. data/ext/libyajl2/vendored/COPYING +0 -13
  43. data/ext/libyajl2/vendored/ChangeLog +0 -175
  44. data/ext/libyajl2/vendored/README +0 -74
  45. data/ext/libyajl2/vendored/TODO +0 -9
  46. data/ext/libyajl2/vendored/YAJLDoc.cmake +0 -26
  47. data/ext/libyajl2/vendored/configure +0 -79
  48. data/ext/libyajl2/vendored/example/CMakeLists.txt +0 -23
  49. data/ext/libyajl2/vendored/example/README.md +0 -7
  50. data/ext/libyajl2/vendored/example/parse_config.c +0 -69
  51. data/ext/libyajl2/vendored/example/sample.config +0 -101
  52. data/ext/libyajl2/vendored/perf/CMakeLists.txt +0 -23
  53. data/ext/libyajl2/vendored/perf/documents.c +0 -1418
  54. data/ext/libyajl2/vendored/perf/documents.h +0 -28
  55. data/ext/libyajl2/vendored/perf/perftest.c +0 -134
  56. data/ext/libyajl2/vendored/reformatter/CMakeLists.txt +0 -39
  57. data/ext/libyajl2/vendored/reformatter/json_reformat.c +0 -194
  58. data/ext/libyajl2/vendored/src/CMakeLists.txt +0 -86
  59. data/ext/libyajl2/vendored/src/YAJL.dxy +0 -1258
  60. data/ext/libyajl2/vendored/src/api/yajl_common.h +0 -75
  61. data/ext/libyajl2/vendored/src/api/yajl_gen.h +0 -157
  62. data/ext/libyajl2/vendored/src/api/yajl_parse.h +0 -226
  63. data/ext/libyajl2/vendored/src/api/yajl_tree.h +0 -185
  64. data/ext/libyajl2/vendored/src/api/yajl_version.h.cmake +0 -23
  65. data/ext/libyajl2/vendored/src/yajl +0 -33
  66. data/ext/libyajl2/vendored/src/yajl.c +0 -175
  67. data/ext/libyajl2/vendored/src/yajl.pc.cmake +0 -9
  68. data/ext/libyajl2/vendored/src/yajl_alloc.c +0 -52
  69. data/ext/libyajl2/vendored/src/yajl_alloc.h +0 -34
  70. data/ext/libyajl2/vendored/src/yajl_buf.c +0 -103
  71. data/ext/libyajl2/vendored/src/yajl_buf.h +0 -57
  72. data/ext/libyajl2/vendored/src/yajl_bytestack.h +0 -69
  73. data/ext/libyajl2/vendored/src/yajl_encode.c +0 -220
  74. data/ext/libyajl2/vendored/src/yajl_encode.h +0 -34
  75. data/ext/libyajl2/vendored/src/yajl_gen.c +0 -354
  76. data/ext/libyajl2/vendored/src/yajl_lex.c +0 -763
  77. data/ext/libyajl2/vendored/src/yajl_lex.h +0 -117
  78. data/ext/libyajl2/vendored/src/yajl_parser.c +0 -498
  79. data/ext/libyajl2/vendored/src/yajl_parser.h +0 -78
  80. data/ext/libyajl2/vendored/src/yajl_tree.c +0 -503
  81. data/ext/libyajl2/vendored/src/yajl_version.c +0 -7
  82. data/ext/libyajl2/vendored/test/CMakeLists.txt +0 -23
  83. data/ext/libyajl2/vendored/test/cases/ac_difficult_json_c_test_case_with_comments.json +0 -1
  84. data/ext/libyajl2/vendored/test/cases/ac_difficult_json_c_test_case_with_comments.json.gold +0 -36
  85. data/ext/libyajl2/vendored/test/cases/ac_simple_with_comments.json +0 -11
  86. data/ext/libyajl2/vendored/test/cases/ac_simple_with_comments.json.gold +0 -9
  87. data/ext/libyajl2/vendored/test/cases/ag_false_then_garbage.json +0 -1
  88. data/ext/libyajl2/vendored/test/cases/ag_false_then_garbage.json.gold +0 -2
  89. data/ext/libyajl2/vendored/test/cases/ag_null_then_garbage.json +0 -1
  90. data/ext/libyajl2/vendored/test/cases/ag_null_then_garbage.json.gold +0 -2
  91. data/ext/libyajl2/vendored/test/cases/ag_true_then_garbage.json +0 -1
  92. data/ext/libyajl2/vendored/test/cases/ag_true_then_garbage.json.gold +0 -2
  93. data/ext/libyajl2/vendored/test/cases/am_eof.json +0 -1
  94. data/ext/libyajl2/vendored/test/cases/am_eof.json.gold +0 -4
  95. data/ext/libyajl2/vendored/test/cases/am_integers.json +0 -1
  96. data/ext/libyajl2/vendored/test/cases/am_integers.json.gold +0 -3
  97. data/ext/libyajl2/vendored/test/cases/am_multiple.json +0 -3
  98. data/ext/libyajl2/vendored/test/cases/am_multiple.json.gold +0 -5
  99. data/ext/libyajl2/vendored/test/cases/am_stuff.json +0 -7
  100. data/ext/libyajl2/vendored/test/cases/am_stuff.json.gold +0 -14
  101. data/ext/libyajl2/vendored/test/cases/ap_array_open.json +0 -1
  102. data/ext/libyajl2/vendored/test/cases/ap_array_open.json.gold +0 -2
  103. data/ext/libyajl2/vendored/test/cases/ap_eof_str.json +0 -1
  104. data/ext/libyajl2/vendored/test/cases/ap_eof_str.json.gold +0 -1
  105. data/ext/libyajl2/vendored/test/cases/ap_map_open.json +0 -1
  106. data/ext/libyajl2/vendored/test/cases/ap_map_open.json.gold +0 -2
  107. data/ext/libyajl2/vendored/test/cases/ap_partial_ok.json +0 -1
  108. data/ext/libyajl2/vendored/test/cases/ap_partial_ok.json.gold +0 -4
  109. data/ext/libyajl2/vendored/test/cases/array.json +0 -6
  110. data/ext/libyajl2/vendored/test/cases/array.json.gold +0 -22
  111. data/ext/libyajl2/vendored/test/cases/array_close.json +0 -1
  112. data/ext/libyajl2/vendored/test/cases/array_close.json.gold +0 -2
  113. data/ext/libyajl2/vendored/test/cases/bignums.json +0 -1
  114. data/ext/libyajl2/vendored/test/cases/bignums.json.gold +0 -5
  115. data/ext/libyajl2/vendored/test/cases/bogus_char.json +0 -4
  116. data/ext/libyajl2/vendored/test/cases/bogus_char.json.gold +0 -10
  117. data/ext/libyajl2/vendored/test/cases/codepoints_from_unicode_org.json +0 -1
  118. data/ext/libyajl2/vendored/test/cases/codepoints_from_unicode_org.json.gold +0 -2
  119. data/ext/libyajl2/vendored/test/cases/deep_arrays.json +0 -1
  120. data/ext/libyajl2/vendored/test/cases/deep_arrays.json.gold +0 -2049
  121. data/ext/libyajl2/vendored/test/cases/difficult_json_c_test_case.json +0 -1
  122. data/ext/libyajl2/vendored/test/cases/difficult_json_c_test_case.json.gold +0 -36
  123. data/ext/libyajl2/vendored/test/cases/doubles.json +0 -1
  124. data/ext/libyajl2/vendored/test/cases/doubles.json.gold +0 -7
  125. data/ext/libyajl2/vendored/test/cases/doubles_in_array.json +0 -1
  126. data/ext/libyajl2/vendored/test/cases/doubles_in_array.json.gold +0 -8
  127. data/ext/libyajl2/vendored/test/cases/empty_array.json +0 -1
  128. data/ext/libyajl2/vendored/test/cases/empty_array.json.gold +0 -3
  129. data/ext/libyajl2/vendored/test/cases/empty_string.json +0 -1
  130. data/ext/libyajl2/vendored/test/cases/empty_string.json.gold +0 -2
  131. data/ext/libyajl2/vendored/test/cases/escaped_bulgarian.json +0 -4
  132. data/ext/libyajl2/vendored/test/cases/escaped_bulgarian.json.gold +0 -7
  133. data/ext/libyajl2/vendored/test/cases/escaped_foobar.json +0 -1
  134. data/ext/libyajl2/vendored/test/cases/escaped_foobar.json.gold +0 -2
  135. data/ext/libyajl2/vendored/test/cases/false.json +0 -1
  136. data/ext/libyajl2/vendored/test/cases/false.json.gold +0 -2
  137. data/ext/libyajl2/vendored/test/cases/fg_false_then_garbage.json +0 -1
  138. data/ext/libyajl2/vendored/test/cases/fg_false_then_garbage.json.gold +0 -3
  139. data/ext/libyajl2/vendored/test/cases/fg_issue_7.json +0 -1
  140. data/ext/libyajl2/vendored/test/cases/fg_issue_7.json.gold +0 -3
  141. data/ext/libyajl2/vendored/test/cases/fg_null_then_garbage.json +0 -1
  142. data/ext/libyajl2/vendored/test/cases/fg_null_then_garbage.json.gold +0 -3
  143. data/ext/libyajl2/vendored/test/cases/fg_true_then_garbage.json +0 -1
  144. data/ext/libyajl2/vendored/test/cases/fg_true_then_garbage.json.gold +0 -3
  145. data/ext/libyajl2/vendored/test/cases/four_byte_utf8.json +0 -2
  146. data/ext/libyajl2/vendored/test/cases/four_byte_utf8.json.gold +0 -5
  147. data/ext/libyajl2/vendored/test/cases/high_overflow.json +0 -1
  148. data/ext/libyajl2/vendored/test/cases/high_overflow.json.gold +0 -2
  149. data/ext/libyajl2/vendored/test/cases/integers.json +0 -3
  150. data/ext/libyajl2/vendored/test/cases/integers.json.gold +0 -14
  151. data/ext/libyajl2/vendored/test/cases/invalid_utf8.json +0 -1
  152. data/ext/libyajl2/vendored/test/cases/invalid_utf8.json.gold +0 -3
  153. data/ext/libyajl2/vendored/test/cases/isolated_surrogate_marker.json +0 -1
  154. data/ext/libyajl2/vendored/test/cases/isolated_surrogate_marker.json.gold +0 -2
  155. data/ext/libyajl2/vendored/test/cases/leading_zero_in_number.json +0 -1
  156. data/ext/libyajl2/vendored/test/cases/leading_zero_in_number.json.gold +0 -5
  157. data/ext/libyajl2/vendored/test/cases/lonely_minus_sign.json +0 -7
  158. data/ext/libyajl2/vendored/test/cases/lonely_minus_sign.json.gold +0 -9
  159. data/ext/libyajl2/vendored/test/cases/lonely_number.json +0 -1
  160. data/ext/libyajl2/vendored/test/cases/lonely_number.json.gold +0 -2
  161. data/ext/libyajl2/vendored/test/cases/low_overflow.json +0 -1
  162. data/ext/libyajl2/vendored/test/cases/low_overflow.json.gold +0 -2
  163. data/ext/libyajl2/vendored/test/cases/map_close.json +0 -1
  164. data/ext/libyajl2/vendored/test/cases/map_close.json.gold +0 -2
  165. data/ext/libyajl2/vendored/test/cases/missing_integer_after_decimal_point.json +0 -1
  166. data/ext/libyajl2/vendored/test/cases/missing_integer_after_decimal_point.json.gold +0 -2
  167. data/ext/libyajl2/vendored/test/cases/missing_integer_after_exponent.json +0 -1
  168. data/ext/libyajl2/vendored/test/cases/missing_integer_after_exponent.json.gold +0 -2
  169. data/ext/libyajl2/vendored/test/cases/multiple.json +0 -3
  170. data/ext/libyajl2/vendored/test/cases/multiple.json.gold +0 -4
  171. data/ext/libyajl2/vendored/test/cases/non_utf8_char_in_string.json +0 -1
  172. data/ext/libyajl2/vendored/test/cases/non_utf8_char_in_string.json.gold +0 -8
  173. data/ext/libyajl2/vendored/test/cases/np_partial_bad.json +0 -1
  174. data/ext/libyajl2/vendored/test/cases/np_partial_bad.json.gold +0 -5
  175. data/ext/libyajl2/vendored/test/cases/null.json +0 -1
  176. data/ext/libyajl2/vendored/test/cases/null.json.gold +0 -2
  177. data/ext/libyajl2/vendored/test/cases/nulls_and_bools.json +0 -5
  178. data/ext/libyajl2/vendored/test/cases/nulls_and_bools.json.gold +0 -9
  179. data/ext/libyajl2/vendored/test/cases/simple.json +0 -5
  180. data/ext/libyajl2/vendored/test/cases/simple.json.gold +0 -9
  181. data/ext/libyajl2/vendored/test/cases/simple_with_comments.json +0 -11
  182. data/ext/libyajl2/vendored/test/cases/simple_with_comments.json.gold +0 -5
  183. data/ext/libyajl2/vendored/test/cases/string_invalid_escape.json +0 -1
  184. data/ext/libyajl2/vendored/test/cases/string_invalid_escape.json.gold +0 -3
  185. data/ext/libyajl2/vendored/test/cases/string_invalid_hex_char.json +0 -1
  186. data/ext/libyajl2/vendored/test/cases/string_invalid_hex_char.json.gold +0 -2
  187. data/ext/libyajl2/vendored/test/cases/string_with_escapes.json +0 -3
  188. data/ext/libyajl2/vendored/test/cases/string_with_escapes.json.gold +0 -7
  189. data/ext/libyajl2/vendored/test/cases/string_with_invalid_newline.json +0 -2
  190. data/ext/libyajl2/vendored/test/cases/string_with_invalid_newline.json.gold +0 -2
  191. data/ext/libyajl2/vendored/test/cases/three_byte_utf8.json +0 -1
  192. data/ext/libyajl2/vendored/test/cases/three_byte_utf8.json.gold +0 -7
  193. data/ext/libyajl2/vendored/test/cases/true.json +0 -1
  194. data/ext/libyajl2/vendored/test/cases/true.json.gold +0 -2
  195. data/ext/libyajl2/vendored/test/cases/unescaped_bulgarian.json +0 -1
  196. data/ext/libyajl2/vendored/test/cases/unescaped_bulgarian.json.gold +0 -4
  197. data/ext/libyajl2/vendored/test/cases/zerobyte.json +0 -1
  198. data/ext/libyajl2/vendored/test/cases/zerobyte.json.gold +0 -0
  199. data/ext/libyajl2/vendored/test/run_tests.sh +0 -94
  200. data/ext/libyajl2/vendored/test/yajl_test.c +0 -281
  201. data/ext/libyajl2/vendored/verify/CMakeLists.txt +0 -39
  202. data/ext/libyajl2/vendored/verify/json_verify.c +0 -116
  203. data/lib/ffi_yajl/json_gem.rb +0 -121
  204. data/lib/libyajl.so +0 -0
  205. data/lib/libyajl.so.2 +0 -0
  206. data/lib/libyajl.so.2.0.5 +0 -0
  207. data/lib/libyajl_s.a +0 -0
  208. data/spec/ffi_yajl/encoder_spec.rb +0 -39
  209. data/spec/ffi_yajl/json_gem_spec.rb +0 -355
  210. data/spec/ffi_yajl/parser_spec.rb +0 -78
  211. data/spec/spec_helper.rb +0 -14
@@ -1 +0,0 @@
1
- [ "foo", "bar"
@@ -1,4 +0,0 @@
1
- array open '['
2
- string: 'foo'
3
- string: 'bar'
4
- memory leaks: 0
@@ -1,6 +0,0 @@
1
- ["foo",
2
- "bar", "baz",
3
- true,false,null,{"key":"value"},
4
- [null,null,null,[]],
5
- "\n\r\\"
6
- ]
@@ -1,22 +0,0 @@
1
- array open '['
2
- string: 'foo'
3
- string: 'bar'
4
- string: 'baz'
5
- bool: true
6
- bool: false
7
- null
8
- map open '{'
9
- key: 'key'
10
- string: 'value'
11
- map close '}'
12
- array open '['
13
- null
14
- null
15
- null
16
- array open '['
17
- array close ']'
18
- array close ']'
19
- string: '
20
-
21
- array close ']'
22
- memory leaks: 0
@@ -1,2 +0,0 @@
1
- parse error: unallowed token at this point in JSON text
2
- memory leaks: 0
@@ -1 +0,0 @@
1
- [ 9223372036854775807, -9223372036854775807 ]
@@ -1,5 +0,0 @@
1
- array open '['
2
- integer: 9223372036854775807
3
- integer: -9223372036854775807
4
- array close ']'
5
- memory leaks: 0
@@ -1,4 +0,0 @@
1
- ["this","is","what","should","be",
2
- "a happy bit of json",
3
- "but someone, misspelled \"true\"", ture,
4
- "who says JSON is easy for humans to generate?"]
@@ -1,10 +0,0 @@
1
- array open '['
2
- string: 'this'
3
- string: 'is'
4
- string: 'what'
5
- string: 'should'
6
- string: 'be'
7
- string: 'a happy bit of json'
8
- string: 'but someone, misspelled "true"'
9
- lexical error: invalid string in json text.
10
- memory leaks: 0
@@ -1 +0,0 @@
1
- "\u004d\u0430\u4e8c\ud800\udf02"
@@ -1,2 +0,0 @@
1
- string: 'Mа二𐌂'
2
- memory leaks: 0
@@ -1 +0,0 @@
1
- [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]