summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/json/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
commite6918187568dbd01842d8d1d2c808ce16a894239 (patch)
tree64f88b554b444a49f656b6c656111a145cbbaa28 /src/boost/libs/json/test
parentInitial commit. (diff)
downloadceph-upstream/18.2.2.tar.xz
ceph-upstream/18.2.2.zip
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/json/test')
-rw-r--r--src/boost/libs/json/test/CMakeLists.txt42
-rw-r--r--src/boost/libs/json/test/Jamfile70
-rw-r--r--src/boost/libs/json/test/README.md36
-rw-r--r--src/boost/libs/json/test/array.cpp1291
-rw-r--r--src/boost/libs/json/test/basic_parser.cpp1651
-rw-r--r--src/boost/libs/json/test/checking_resource.hpp63
-rw-r--r--src/boost/libs/json/test/cmake_install_test/CMakeLists.txt18
-rw-r--r--src/boost/libs/json/test/cmake_install_test/main.cpp13
-rw-r--r--src/boost/libs/json/test/doc_background.cpp205
-rw-r--r--src/boost/libs/json/test/doc_forward_conversion.cpp101
-rw-r--r--src/boost/libs/json/test/doc_parsing.cpp254
-rw-r--r--src/boost/libs/json/test/doc_quick_look.cpp333
-rw-r--r--src/boost/libs/json/test/doc_serializing.cpp75
-rw-r--r--src/boost/libs/json/test/doc_storage_ptr.cpp176
-rw-r--r--src/boost/libs/json/test/doc_uses_allocator.cpp77
-rw-r--r--src/boost/libs/json/test/doc_using_numbers.cpp193
-rw-r--r--src/boost/libs/json/test/double.cpp434
-rw-r--r--src/boost/libs/json/test/error.cpp88
-rw-r--r--src/boost/libs/json/test/fwd.cpp14
-rw-r--r--src/boost/libs/json/test/json.cpp40
-rw-r--r--src/boost/libs/json/test/kind.cpp53
-rw-r--r--src/boost/libs/json/test/limits.cpp400
-rw-r--r--src/boost/libs/json/test/main.cpp31
-rw-r--r--src/boost/libs/json/test/make-pvs.py117
-rw-r--r--src/boost/libs/json/test/make-strings.py17
-rw-r--r--src/boost/libs/json/test/memory_resource.cpp109
-rw-r--r--src/boost/libs/json/test/monotonic_resource.cpp311
-rw-r--r--src/boost/libs/json/test/natvis.cpp115
-rw-r--r--src/boost/libs/json/test/null_resource.cpp45
-rw-r--r--src/boost/libs/json/test/object.cpp1554
-rw-r--r--src/boost/libs/json/test/parse-vectors.hpp1470
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_number_double_huge_neg_exp.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_number_huge_exp.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_number_neg_int_huge_exp.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_number_pos_double_huge_exp.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_number_real_neg_overflow.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_number_real_pos_overflow.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_number_real_underflow.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_number_too_big_neg_int.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_number_too_big_pos_int.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_number_very_big_negative_int.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_object_key_lone_2nd_surrogate.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_1st_surrogate_but_2nd_missing.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_1st_valid_surrogate_2nd_invalid.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_UTF-16LE_with_BOM.jsonbin0 -> 12 bytes
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_UTF-8_invalid_sequence.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_UTF8_surrogate_U+D800.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogate_and_escape_valid.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogate_pair.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogates_escape_valid.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_invalid_lonely_surrogate.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_invalid_surrogate.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_invalid_utf-8.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_inverted_surrogates_U+1D11E.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_iso_latin_1.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_lone_second_surrogate.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_lone_utf8_continuation_byte.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_not_in_unicode_range.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_2_bytes.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_6_bytes.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_6_bytes_null.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_truncated-utf-8.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_utf16BE_no_BOM.jsonbin0 -> 10 bytes
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_string_utf16LE_no_BOM.jsonbin0 -> 10 bytes
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_structure_500_nested_arrays.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/i_structure_UTF-8_BOM_empty_object.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_1_true_without_comma.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_a_invalid_utf8.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_colon_instead_of_comma.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_comma_after_close.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_comma_and_number.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_double_comma.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_double_extra_comma.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_extra_close.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_extra_comma.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_incomplete.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_incomplete_invalid_value.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_inner_array_no_comma.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_invalid_utf8.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_items_separated_by_semicolon.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_just_comma.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_just_minus.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_missing_value.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_newlines_unclosed.json3
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_number_and_comma.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_number_and_several_commas.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_spaces_vertical_tab_formfeed.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_star_inside.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_unclosed.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_unclosed_trailing_comma.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_unclosed_with_new_lines.json3
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_array_unclosed_with_object_inside.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail01.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail02.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail03.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail04.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail05.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail06.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail07.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail08.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail09.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail10.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail11.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail12.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail13.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail14.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail15.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail16.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail17.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail19.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail20.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail21.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail22.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail23.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail24.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail25.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail26.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail27.json2
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail28.json2
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail29.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail30.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail31.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_fail32.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_incomplete_false.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_incomplete_null.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_incomplete_true.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_multidigit_number_then_00.jsonbin0 -> 4 bytes
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_++.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_+1.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_+Inf.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_-01.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_-1.0..json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_-2..json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_-NaN.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_.-1.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_.2e-3.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_0.1.2.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_0.3e+.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_0.3e.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_0.e1.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_0_capital_E+.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_0_capital_E.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_0e+.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_0e.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_1.0e+.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_1.0e-.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_1.0e.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_1_000.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_1eE2.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_2.e+3.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_2.e-3.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_2.e3.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_9.e+.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_Inf.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_NaN.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_U+FF11_fullwidth_digit_one.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_expression.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_hex_1_digit.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_hex_2_digits.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_infinity.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_invalid+-.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_invalid-negative-real.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-bigger-int.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-exponent.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-int.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_minus_infinity.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_minus_sign_with_trailing_garbage.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_minus_space_1.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_neg_int_starting_with_zero.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_neg_real_without_int_part.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_neg_with_garbage_at_end.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_real_garbage_after_e.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_real_with_invalid_utf8_after_e.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_real_without_fractional_part.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_starting_with_dot.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_with_alpha.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_with_alpha_char.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_number_with_leading_zero.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_bad_value.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_bracket_key.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_comma_instead_of_colon.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_double_colon.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_emoji.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_garbage_at_end.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_key_with_single_quotes.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_lone_continuation_byte_in_key_and_trailing_comma.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_missing_colon.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_missing_key.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_missing_semicolon.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_missing_value.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_no-colon.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_non_string_key.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_non_string_key_but_huge_number_instead.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_repeated_null_null.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_several_trailing_commas.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_single_quote.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_trailing_comma.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_trailing_comment.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_open.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_slash_open.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_slash_open_incomplete.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_two_commas_in_a_row.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_unquoted_key.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_unterminated-value.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_with_single_string.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_object_with_trailing_garbage.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_single_space.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u1.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u1x.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_accentuated_char_no_quotes.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_backslash_00.jsonbin0 -> 6 bytes
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_escape_x.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_escaped_backslash_bad.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_escaped_ctrl_char_tab.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_escaped_emoji.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_incomplete_escape.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_incomplete_escaped_character.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_incomplete_surrogate.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_incomplete_surrogate_escape_invalid.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_invalid-utf-8-in-escape.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_invalid_backslash_esc.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_invalid_unicode_escape.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_invalid_utf8_after_escape.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_leading_uescaped_thinspace.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_no_quotes_with_bad_escape.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_single_doublequote.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_single_quote.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_single_string_no_double_quotes.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_start_escape_unclosed.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_unescaped_crtl_char.jsonbin0 -> 7 bytes
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_unescaped_newline.json2
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_unescaped_tab.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_unicode_CapitalU.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_string_with_trailing_garbage.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_100000_opening_arrays.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_U+2060_word_joined.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_UTF8_BOM_no_data.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_angle_bracket_..json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_angle_bracket_null.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_array_trailing_garbage.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_array_with_extra_array_close.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_array_with_unclosed_string.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_ascii-unicode-identifier.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_capitalized_True.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_close_unopened_array.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_comma_instead_of_closing_brace.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_double_array.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_end_array.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_incomplete_UTF8_BOM.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_lone-invalid-utf-8.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_lone-open-bracket.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_no_data.json0
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_null-byte-outside-string.jsonbin0 -> 3 bytes
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_number_with_trailing_garbage.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_object_followed_by_closing_object.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_object_unclosed_no_value.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_object_with_comment.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_object_with_trailing_garbage.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_open_array_apostrophe.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_open_array_comma.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_open_array_object.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_open_array_open_object.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_open_array_open_string.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_open_array_string.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_open_object.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_open_object_close_array.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_open_object_comma.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_open_object_open_array.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_open_object_open_string.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_open_object_string_with_apostrophes.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_open_open.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_single_eacute.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_single_star.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_trailing_#.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_uescaped_LF_before_string.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_partial_null.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_unfinished_false.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_unfinished_true.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_unclosed_object.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_unicode-identifier.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_whitespace_U+2060_word_joiner.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/n_structure_whitespace_formfeed.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_array_arraysWithSpaces.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_array_empty-string.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_array_empty.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_array_ending_with_newline.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_array_false.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_array_heterogeneous.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_array_null.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_array_with_1_and_newline.json2
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_array_with_leading_space.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_array_with_several_null.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_array_with_trailing_space.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_0e+1.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_0e1.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_after_space.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_double_close_to_zero.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_int_with_exp.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_minus_zero.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_negative_int.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_negative_one.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_negative_zero.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_real_capital_e.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_real_capital_e_neg_exp.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_real_capital_e_pos_exp.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_real_exponent.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_real_fraction_exponent.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_real_neg_exp.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_real_pos_exponent.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_simple_int.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_number_simple_real.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_object.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_object_basic.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_object_duplicated_key.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_object_duplicated_key_and_value.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_object_empty.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_object_empty_key.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_object_escaped_null_in_key.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_object_extreme_numbers.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_object_long_strings.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_object_simple.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_object_string_unicode.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_object_with_newlines.json3
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_pass01.json58
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_pass02.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_pass03.json6
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_1_2_3_bytes_UTF-8_sequences.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_accepted_surrogate_pair.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_accepted_surrogate_pairs.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_allowed_escapes.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_backslash_and_u_escaped_zero.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_backslash_doublequotes.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_comments.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_double_escape_a.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_double_escape_n.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_escaped_control_character.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_escaped_noncharacter.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_in_array.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_in_array_with_leading_space.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_last_surrogates_1_and_2.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_nbsp_uescaped.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_nonCharacterInUTF-8_U+10FFFF.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_nonCharacterInUTF-8_U+FFFF.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_null_escape.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_one-byte-utf-8.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_pi.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_reservedCharacterInUTF-8_U+1BFFF.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_simple_ascii.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_space.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_three-byte-utf-8.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_two-byte-utf-8.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_u+2028_line_sep.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_u+2029_par_sep.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_uEscape.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_uescaped_newline.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_unescaped_char_delete.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_unicode.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_unicodeEscapedBackslash.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_unicode_2.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_unicode_U+10FFFE_nonchar.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_unicode_U+1FFFE_nonchar.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_unicode_U+2064_invisible_plus.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_unicode_U+FDD0_nonchar.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_unicode_U+FFFE_nonchar.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_unicode_escaped_double_quote.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_utf8.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_string_with_del_character.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_structure_lonely_false.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_structure_lonely_int.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_structure_lonely_negative_real.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_structure_lonely_null.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_structure_lonely_string.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_structure_lonely_true.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_structure_string_empty.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_structure_trailing_newline.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_structure_true_in_array.json1
-rw-r--r--src/boost/libs/json/test/parse-vectors/y_structure_whitespace_array.json1
-rw-r--r--src/boost/libs/json/test/parse.cpp180
-rw-r--r--src/boost/libs/json/test/parser.cpp395
-rw-r--r--src/boost/libs/json/test/pilfer.cpp30
-rw-r--r--src/boost/libs/json/test/pointer.cpp248
-rw-r--r--src/boost/libs/json/test/ryu/d2s_intrinsics_test.cpp56
-rw-r--r--src/boost/libs/json/test/ryu/d2s_table_test.cpp106
-rw-r--r--src/boost/libs/json/test/ryu/d2s_test.cpp277
-rw-r--r--src/boost/libs/json/test/ryu/gtest.hpp34
-rw-r--r--src/boost/libs/json/test/serialize.cpp68
-rw-r--r--src/boost/libs/json/test/serializer.cpp565
-rw-r--r--src/boost/libs/json/test/snippets.cpp903
-rw-r--r--src/boost/libs/json/test/static_resource.cpp129
-rw-r--r--src/boost/libs/json/test/storage_ptr.cpp214
-rw-r--r--src/boost/libs/json/test/stream_parser.cpp1284
-rw-r--r--src/boost/libs/json/test/string.cpp2814
-rw-r--r--src/boost/libs/json/test/string_view.cpp11
-rw-r--r--src/boost/libs/json/test/system_error.cpp11
-rw-r--r--src/boost/libs/json/test/test.hpp1163
-rw-r--r--src/boost/libs/json/test/test_suite.hpp758
-rw-r--r--src/boost/libs/json/test/value.cpp2186
-rw-r--r--src/boost/libs/json/test/value_from.cpp308
-rw-r--r--src/boost/libs/json/test/value_ref.cpp404
-rw-r--r--src/boost/libs/json/test/value_stack.cpp127
-rw-r--r--src/boost/libs/json/test/value_to.cpp128
-rw-r--r--src/boost/libs/json/test/visit.cpp92
408 files changed, 22303 insertions, 0 deletions
diff --git a/src/boost/libs/json/test/CMakeLists.txt b/src/boost/libs/json/test/CMakeLists.txt
new file mode 100644
index 000000000..91b96fc03
--- /dev/null
+++ b/src/boost/libs/json/test/CMakeLists.txt
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+# Copyright (c) 2021 DMitry Arkhipov (grisumbras@gmail.com)
+#
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#
+# Official repository: https://github.com/boostorg/json
+#
+
+
+if(NOT TARGET tests)
+ add_custom_target(tests)
+ set_property(TARGET tests PROPERTY FOLDER _deps)
+endif()
+
+
+file(GLOB_RECURSE BOOST_JSON_TESTS_FILES CONFIGURE_DEPENDS Jamfile *.cpp *.hpp)
+list(FILTER BOOST_JSON_TESTS_FILES EXCLUDE REGEX cmake_install_test/.*$)
+
+source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES ${BOOST_JSON_TESTS_FILES})
+add_executable(boost_json-tests ${BOOST_JSON_TESTS_FILES})
+target_include_directories(boost_json-tests PRIVATE .)
+target_link_libraries(boost_json-tests PRIVATE Boost::json)
+add_test(NAME boost_json-tests COMMAND boost_json-tests)
+add_dependencies(tests boost_json-tests)
+
+
+source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES limits.cpp main.cpp)
+source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/../src PREFIX "" FILES ../src/src.cpp)
+add_executable(boost_json-limits limits.cpp main.cpp ../src/src.cpp Jamfile)
+boost_json_setup_properties(boost_json-limits)
+
+target_compile_definitions(boost_json-limits PRIVATE
+ BOOST_JSON_MAX_STRING_SIZE=1000
+ BOOST_JSON_MAX_STRUCTURED_SIZE=20
+ BOOST_JSON_STACK_BUFFER_SIZE=256
+ BOOST_JSON_NO_LIB=1
+)
+
+add_test(NAME boost_json-limits COMMAND boost_json-limits)
+add_dependencies(tests boost_json-limits)
diff --git a/src/boost/libs/json/test/Jamfile b/src/boost/libs/json/test/Jamfile
new file mode 100644
index 000000000..ed26d0233
--- /dev/null
+++ b/src/boost/libs/json/test/Jamfile
@@ -0,0 +1,70 @@
+#
+# Copyright (c) 2013-2019 Vinnie Falco (vinnie.falco@gmail.com)
+#
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#
+# Official repository: https://github.com/boostorg/json
+#
+
+import testing ;
+
+local SOURCES =
+ array.cpp
+ basic_parser.cpp
+ doc_background.cpp
+ doc_forward_conversion.cpp
+ doc_parsing.cpp
+ doc_quick_look.cpp
+ doc_serializing.cpp
+ doc_storage_ptr.cpp
+ doc_uses_allocator.cpp
+ doc_using_numbers.cpp
+ double.cpp
+ error.cpp
+ fwd.cpp
+ json.cpp
+ kind.cpp
+ memory_resource.cpp
+ monotonic_resource.cpp
+ natvis.cpp
+ null_resource.cpp
+ object.cpp
+ parse.cpp
+ parser.cpp
+ pilfer.cpp
+ pointer.cpp
+ serialize.cpp
+ serializer.cpp
+ snippets.cpp
+ static_resource.cpp
+ storage_ptr.cpp
+ stream_parser.cpp
+ string.cpp
+ string_view.cpp
+ system_error.cpp
+ value.cpp
+ value_from.cpp
+ value_stack.cpp
+ value_to.cpp
+ value_ref.cpp
+ visit.cpp
+ ryu/d2s_intrinsics_test.cpp
+ ryu/d2s_table_test.cpp
+ ryu/d2s_test.cpp
+ ;
+
+project : requirements <include>. ;
+
+for local f in $(SOURCES)
+{
+ run $(f) main.cpp /boost/json//boost_json ;
+}
+
+run limits.cpp main.cpp /boost/json//json_sources
+ : requirements
+ <define>BOOST_JSON_SOURCE
+ <define>BOOST_JSON_MAX_STRING_SIZE=1000
+ <define>BOOST_JSON_MAX_STRUCTURED_SIZE=20
+ <define>BOOST_JSON_STACK_BUFFER_SIZE=256
+ ;
diff --git a/src/boost/libs/json/test/README.md b/src/boost/libs/json/test/README.md
new file mode 100644
index 000000000..77a970931
--- /dev/null
+++ b/src/boost/libs/json/test/README.md
@@ -0,0 +1,36 @@
+# JSON Parse Test Vectors
+
+The files in the direectory parse-vectors come from this project:
+
+JSON Test Suite
+
+A comprehensive test suite for RFC 8259 compliant JSON parsers
+
+https://github.com/nst/JSONTestSuite
+
+These files are covered by the following copyright and MIT License,
+reproduced from the original project:
+
+---
+
+MIT License
+
+Copyright (c) 2016 Nicolas Seriot
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/src/boost/libs/json/test/array.cpp b/src/boost/libs/json/test/array.cpp
new file mode 100644
index 000000000..1cc87566c
--- /dev/null
+++ b/src/boost/libs/json/test/array.cpp
@@ -0,0 +1,1291 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/array.hpp>
+
+#include <boost/json/monotonic_resource.hpp>
+
+#include <forward_list>
+#include <list>
+#include <iterator>
+
+#include "test.hpp"
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+BOOST_STATIC_ASSERT( std::is_nothrow_destructible<array>::value );
+BOOST_STATIC_ASSERT( std::is_nothrow_move_constructible<array>::value );
+
+class array_test
+{
+public:
+ using init_list =
+ std::initializer_list<value_ref>;
+
+ string_view const str_;
+
+ array_test()
+ : str_(
+ "abcdefghijklmnopqrstuvwxyz")
+ {
+ // ensure this string does
+ // not fit in the SBO area.
+ BOOST_ASSERT(str_.size() >
+ string().capacity());
+
+ }
+
+ void
+ check(array const& a)
+ {
+ BOOST_TEST(a.size() == 3);
+ BOOST_TEST(a[0].is_number());
+ BOOST_TEST(a[1].is_bool());
+ BOOST_TEST(a[2].is_string());
+ }
+
+ void
+ check(
+ array const& a,
+ storage_ptr const& sp)
+ {
+ check(a);
+ check_storage(a, sp);
+ }
+
+ void
+ testDestroy()
+ {
+ {
+ monotonic_resource mr;
+ array a(&mr);
+ a.reserve(3);
+ }
+ {
+ monotonic_resource mr;
+ array a(&mr);
+ a.resize(3);
+ a.clear();
+ }
+ }
+
+ void
+ testCtors()
+ {
+ // ~array()
+ {
+ // implied
+ }
+
+ // array()
+ {
+ array a;
+ BOOST_TEST(a.empty());
+ BOOST_TEST(a.size() == 0);
+ }
+
+ // array(storage_ptr)
+ {
+ array a(storage_ptr{});
+ check_storage(a, storage_ptr{});
+ }
+
+ // array(size_type, value, storage)
+ {
+ // default storage
+ {
+ array a(3, true);
+ BOOST_TEST(a.size() == 3);
+ for(auto const& v : a)
+ BOOST_TEST(v.is_bool());
+ check_storage(a, storage_ptr{});
+ }
+
+ // construct with zero `true` values
+ {
+ array(0, true);
+ }
+
+ // construct with three `true` values
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a(3, true, sp);
+ BOOST_TEST(a.size() == 3);
+ check_storage(a, sp);
+ });
+ }
+
+ // array(size_type, storage)
+ {
+ // default storage
+ {
+ array a(3);
+ BOOST_TEST(a.size() == 3);
+ for(auto const& v : a)
+ BOOST_TEST(v.is_null());
+ check_storage(a, storage_ptr{});
+ }
+
+ // zero size
+ {
+ array a(0);
+ BOOST_TEST(a.empty());
+ }
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a(3, sp);
+ BOOST_TEST(a.size() == 3);
+ for(auto const& v : a)
+ BOOST_TEST(v.is_null());
+ check_storage(a, sp);
+ });
+ }
+
+ // array(InputIt, InputIt, storage)
+ {
+ // empty range
+ {
+ // random-access iterator
+ std::vector<value> i1;
+ array a1(i1.begin(), i1.end());
+ BOOST_TEST(a1.empty());
+
+ // bidirectional iterator
+ std::list<value> i2;
+ array a2(i2.begin(), i2.end());
+ BOOST_TEST(a2.empty());
+
+ // forward iterator
+ std::forward_list<value> i3;
+ array a3(i3.begin(), i3.end());
+ BOOST_TEST(a3.empty());
+
+ // input iterator
+ auto const it = make_input_iterator(i3.begin());
+ array a4(it, it);
+ BOOST_TEST(a4.empty());
+ }
+
+ // default storage
+ {
+ init_list init{ 0, 1, str_, 3, 4 };
+ array a(init.begin(), init.end());
+ check_storage(a, storage_ptr{});
+ BOOST_TEST(a[0].as_int64() == 0);
+ BOOST_TEST(a[1].as_int64() == 1);
+ BOOST_TEST(a[2].as_string() == str_);
+ BOOST_TEST(a[3].as_int64() == 3);
+ BOOST_TEST(a[4].as_int64() == 4);
+ }
+
+ // random iterator
+ fail_loop([&](storage_ptr const& sp)
+ {
+ init_list init{ 1, true, str_ };
+ array a(init.begin(), init.end(), sp);
+ check(a);
+ check_storage(a, sp);
+ });
+
+ // input iterator
+ fail_loop([&](storage_ptr const& sp)
+ {
+ init_list init{ 1, true, str_ };
+ array a(
+ make_input_iterator(init.begin()),
+ make_input_iterator(init.end()), sp);
+ check(a);
+ check_storage(a, sp);
+ });
+ }
+
+ // array(array const&)
+ {
+ {
+ array a1;
+ array a2(a1);
+ }
+
+ {
+ array a1;
+ array a2({ 1, true, str_ });
+ a2 = a1;
+ }
+
+ {
+ init_list init{ 1, true, str_ };
+ array a1(init.begin(), init.end());
+ array a2(a1);
+ check(a2);
+ check_storage(a2, storage_ptr{});
+ }
+ }
+
+ // array(array const&, storage)
+ fail_loop([&](storage_ptr const& sp)
+ {
+ init_list init{ 1, true, str_ };
+ array a1(init.begin(), init.end());
+ array a2(a1, sp);
+ check(a2);
+ check_storage(a2, sp);
+ });
+
+ // array(pilfered<array>)
+ {
+ {
+ init_list init{ 1, true, str_ };
+ array a1(init.begin(), init.end());
+ array a2(pilfer(a1));
+ BOOST_TEST(a1.empty());
+ check(a2);
+ check_storage(a2, storage_ptr{});
+ }
+
+ // ensure pilfered-from objects
+ // are trivially destructible
+ {
+ array a1(make_shared_resource<
+ monotonic_resource>());
+ array a2(pilfer(a1));
+ BOOST_TEST(a1.storage().get() ==
+ storage_ptr().get());
+ }
+ }
+
+ // array(array&&)
+ {
+ init_list init{ 1, true, str_ };
+ array a1(init.begin(), init.end());
+ array a2 = std::move(a1);
+ BOOST_TEST(a1.empty());
+ check(a2);
+ check_storage(a2, storage_ptr{});
+ }
+
+ // array(array&&, storage)
+ {
+ {
+ init_list init{ 1, true, str_ };
+ array a1(init.begin(), init.end());
+ array a2(
+ std::move(a1), storage_ptr{});
+ BOOST_TEST(a1.empty());
+ check(a2);
+ check_storage(a1, storage_ptr{});
+ check_storage(a2, storage_ptr{});
+ }
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ init_list init{ 1, true, str_ };
+ array a1(init.begin(), init.end());
+ array a2(std::move(a1), sp);
+ BOOST_TEST(! a1.empty());
+ check(a2);
+ check_storage(a1, storage_ptr{});
+ check_storage(a2, sp);
+ });
+ }
+
+ // array(init_list, storage)
+ {
+ // default storage
+ {
+ array a({1, true, str_});
+ check(a);
+ check_storage(a, storage_ptr{});
+ }
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a({1, true, str_}, sp);
+ check(a, sp);
+ check_storage(a, sp);
+ });
+ }
+ }
+
+ void
+ testAssign()
+ {
+ // operator=(array const&)
+ {
+ {
+ array a1({1, true, str_});
+ array a2({nullptr, object{}, 1.f});
+ a2 = a1;
+ check(a1);
+ check(a2);
+ check_storage(a1, storage_ptr{});
+ check_storage(a2, storage_ptr{});
+ }
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a1({1, true, str_});
+ array a2({nullptr, object{}, 1.f}, sp);
+ a2 = a1;
+ check(a1);
+ check(a2);
+ check_storage(a1, storage_ptr{});
+ check_storage(a2, sp);
+ });
+
+ // self-assign
+ {
+ array a({1, true, str_});
+ auto& a1 = a;
+ auto& a2 = a;
+ a1 = a2;
+ check(a);
+ }
+
+ // copy from child
+ {
+ array a({1, {1,2,3}, 3});
+ a = a.at(1).as_array();
+ BOOST_TEST(
+ a == array({1, 2, 3}));
+ }
+ }
+
+ // operator=(array&&)
+ {
+ {
+ array a1({1, true, str_});
+ array a2({nullptr, object{}, 1.f});
+ a2 = std::move(a1);
+ BOOST_TEST(a1.empty());
+ check(a2);
+ }
+
+ // empty
+ {
+ array a1;
+ array a2;
+ a2 = std::move(a1);
+ BOOST_TEST(a1.empty());
+ BOOST_TEST(a2.empty());
+ }
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a1({1, true, str_});
+ array a2({nullptr, object{}, 1.f}, sp);
+ a2 = std::move(a1);
+ check(a1);
+ check(a2);
+ check_storage(a1, storage_ptr{});
+ check_storage(a2, sp);
+ });
+
+ // self-move
+ {
+ array a({1, true, str_});
+ auto& a1 = a;
+ auto& a2 = a;
+ a1 = std::move(a2);
+ check(a);
+ }
+
+ // move from child
+ {
+ array a({1, {1,2,3}, 3});
+ a = std::move(a.at(1).as_array());
+ BOOST_TEST(
+ a == array({1, 2, 3}));
+ }
+ }
+
+ // operator=(init_list)
+ {
+ {
+ array a;
+ a = {};
+ }
+
+ {
+ array a({ 1, true, str_ });
+ a = {};
+ }
+
+ {
+ init_list init{ 1, true, str_ };
+ array a({nullptr, object{}, 1.f});
+ a = init;
+ check(a);
+ check_storage(a, storage_ptr{});
+ }
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ init_list init{ 1, true, str_ };
+ array a({nullptr, object{}, 1.f}, sp);
+ a = init;
+ check(a);
+ check_storage(a, sp);
+ });
+ }
+ }
+
+ void
+ testGetStorage()
+ {
+ // storage()
+ {
+ // implied
+ }
+ }
+
+ void
+ testAccess()
+ {
+ // at(pos)
+ {
+ array a({1, true, str_});
+ BOOST_TEST(a.at(0).is_number());
+ BOOST_TEST(a.at(1).is_bool());
+ BOOST_TEST(a.at(2).is_string());
+ try
+ {
+ a.at(3);
+ BOOST_TEST_FAIL();
+ }
+ catch(std::out_of_range const&)
+ {
+ BOOST_TEST_PASS();
+ }
+ }
+
+ // at(pos) const
+ {
+ array const a({1, true, str_});
+ BOOST_TEST(a.at(0).is_number());
+ BOOST_TEST(a.at(1).is_bool());
+ BOOST_TEST(a.at(2).is_string());
+ try
+ {
+ a.at(3);
+ BOOST_TEST_FAIL();
+ }
+ catch(std::out_of_range const&)
+ {
+ BOOST_TEST_PASS();
+ }
+ }
+
+ // operator[&](size_type)
+ {
+ array a({1, true, str_});
+ BOOST_TEST(a[0].is_number());
+ BOOST_TEST(a[1].is_bool());
+ BOOST_TEST(a[2].is_string());
+ }
+
+ // operator[&](size_type) const
+ {
+ array const a({1, true, str_});
+ BOOST_TEST(a[0].is_number());
+ BOOST_TEST(a[1].is_bool());
+ BOOST_TEST(a[2].is_string());
+ }
+
+ // front()
+ {
+ array a({1, true, str_});
+ BOOST_TEST(a.front().is_number());
+ }
+
+ // front() const
+ {
+ array const a({1, true, str_});
+ BOOST_TEST(a.front().is_number());
+ }
+
+ // back()
+ {
+ array a({1, true, str_});
+ BOOST_TEST(a.back().is_string());
+ }
+
+ // back() const
+ {
+ array const a({1, true, str_});
+ BOOST_TEST(a.back().is_string());
+ }
+
+ // if_contains()
+ // if_contains() const
+ {
+ {
+ array a({1, true, str_});
+ BOOST_TEST(a.if_contains(1)->is_bool());
+ BOOST_TEST(a.if_contains(3) == nullptr);
+ }
+ {
+ array const a({1, true, str_});
+ BOOST_TEST(a.if_contains(1)->is_bool());
+ BOOST_TEST(a.if_contains(3) == nullptr);
+ }
+ }
+
+ // data()
+ {
+ {
+ array a({1, true, str_});
+ BOOST_TEST(a.data() == &a[0]);
+ }
+ {
+ array a;
+ BOOST_TEST(
+ a.data() == a.begin());
+ }
+ }
+
+ // data() const
+ {
+ {
+ array const a({1, true, str_});
+ BOOST_TEST(a.data() == &a[0]);
+ }
+ {
+ array const a{};
+ BOOST_TEST(
+ a.data() == a.begin());
+ }
+ }
+ }
+
+ void
+ testIterators()
+ {
+ array a({1, true, str_});
+ auto const& ac(a);
+
+ {
+ auto it = a.begin();
+ BOOST_TEST(it->is_number()); ++it;
+ BOOST_TEST(it->is_bool()); it++;
+ BOOST_TEST(it->is_string()); ++it;
+ BOOST_TEST(it == a.end());
+ }
+ {
+ auto it = a.cbegin();
+ BOOST_TEST(it->is_number()); ++it;
+ BOOST_TEST(it->is_bool()); it++;
+ BOOST_TEST(it->is_string()); ++it;
+ BOOST_TEST(it == a.cend());
+ }
+ {
+ auto it = ac.begin();
+ BOOST_TEST(it->is_number()); ++it;
+ BOOST_TEST(it->is_bool()); it++;
+ BOOST_TEST(it->is_string()); ++it;
+ BOOST_TEST(it == ac.end());
+ }
+ {
+ auto it = a.end();
+ --it; BOOST_TEST(it->is_string());
+ it--; BOOST_TEST(it->is_bool());
+ --it; BOOST_TEST(it->is_number());
+ BOOST_TEST(it == a.begin());
+ }
+ {
+ auto it = a.cend();
+ --it; BOOST_TEST(it->is_string());
+ it--; BOOST_TEST(it->is_bool());
+ --it; BOOST_TEST(it->is_number());
+ BOOST_TEST(it == a.cbegin());
+ }
+ {
+ auto it = ac.end();
+ --it; BOOST_TEST(it->is_string());
+ it--; BOOST_TEST(it->is_bool());
+ --it; BOOST_TEST(it->is_number());
+ BOOST_TEST(it == ac.begin());
+ }
+
+ {
+ auto it = a.rbegin();
+ BOOST_TEST(it->is_string()); ++it;
+ BOOST_TEST(it->is_bool()); it++;
+ BOOST_TEST(it->is_number()); ++it;
+ BOOST_TEST(it == a.rend());
+ }
+ {
+ auto it = a.crbegin();
+ BOOST_TEST(it->is_string()); ++it;
+ BOOST_TEST(it->is_bool()); it++;
+ BOOST_TEST(it->is_number()); ++it;
+ BOOST_TEST(it == a.crend());
+ }
+ {
+ auto it = ac.rbegin();
+ BOOST_TEST(it->is_string()); ++it;
+ BOOST_TEST(it->is_bool()); it++;
+ BOOST_TEST(it->is_number()); ++it;
+ BOOST_TEST(it == ac.rend());
+ }
+ {
+ auto it = a.rend();
+ --it; BOOST_TEST(it->is_number());
+ it--; BOOST_TEST(it->is_bool());
+ --it; BOOST_TEST(it->is_string());
+ BOOST_TEST(it == a.rbegin());
+ }
+ {
+ auto it = a.crend();
+ --it; BOOST_TEST(it->is_number());
+ it--; BOOST_TEST(it->is_bool());
+ --it; BOOST_TEST(it->is_string());
+ BOOST_TEST(it == a.crbegin());
+ }
+ {
+ auto it = ac.rend();
+ --it; BOOST_TEST(it->is_number());
+ it--; BOOST_TEST(it->is_bool());
+ --it; BOOST_TEST(it->is_string());
+ BOOST_TEST(it == ac.rbegin());
+ }
+
+ {
+ array a2;
+ array const& ca2(a2);
+ BOOST_TEST(std::distance(
+ a2.begin(), a2.end()) == 0);
+ BOOST_TEST(std::distance(
+ ca2.begin(), ca2.end()) == 0);
+ BOOST_TEST(std::distance(
+ ca2.cbegin(), ca2.cend()) == 0);
+ BOOST_TEST(std::distance(
+ a2.rbegin(), a2.rend()) == 0);
+ BOOST_TEST(std::distance(
+ ca2.rbegin(), ca2.rend()) == 0);
+ BOOST_TEST(std::distance(
+ ca2.crbegin(), ca2.crend()) == 0);
+ }
+ }
+
+ void
+ testCapacity()
+ {
+ // empty()
+ {
+ {
+ array a;
+ BOOST_TEST(a.empty());
+ a.emplace_back(1);
+ BOOST_TEST(! a.empty());
+ }
+
+ {
+ array a({1, 2});
+ BOOST_TEST(! a.empty());
+ a.clear();
+ BOOST_TEST(a.empty());
+ BOOST_TEST(a.capacity() > 0);
+ }
+ }
+
+ // size()
+ {
+ array a;
+ BOOST_TEST(a.size() == 0);
+ a.emplace_back(1);
+ BOOST_TEST(a.size() == 1);
+ }
+
+ // max_size()
+ {
+ array a;
+ BOOST_TEST(a.max_size() > 0);
+ }
+
+ // reserve()
+ {
+ {
+ array a;
+ a.reserve(0);
+ }
+
+ {
+ array a(3);
+ a.reserve(1);
+ }
+
+ {
+ array a(3);
+ a.reserve(0);
+ }
+
+ {
+ array a;
+ a.reserve(50);
+ BOOST_TEST(a.capacity() >= 50);
+ }
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a(4, 'c', sp);
+ a.reserve(a.capacity() + 1);
+ auto const new_cap = a.capacity();
+ // 1.5x growth
+ BOOST_TEST(new_cap == 6);
+ a.reserve(new_cap + 1);
+ BOOST_TEST(a.capacity() == 9);
+ });
+ }
+
+ // capacity()
+ {
+ array a;
+ BOOST_TEST(a.capacity() == 0);
+ }
+
+ // shrink_to_fit()
+ {
+ {
+ array a(1);
+ a.shrink_to_fit();
+ BOOST_TEST(a.size() == 1);
+ BOOST_TEST(a.capacity() >= 1);
+ }
+
+ {
+ array a(2, 'c');
+ BOOST_TEST(a.capacity() == 2);
+ a.erase(a.begin());
+ a.shrink_to_fit();
+ BOOST_TEST(a.capacity() == 1);
+ }
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a(1, sp);
+ a.resize(a.capacity());
+ a.shrink_to_fit();
+ BOOST_TEST(a.size() == a.capacity());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a(sp);
+ a.reserve(10);
+ BOOST_TEST(a.capacity() >= 10);
+ a.shrink_to_fit();
+ BOOST_TEST(a.capacity() == 0);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a(4, sp);
+ a.reserve(a.capacity() * 2);
+ BOOST_TEST(a.capacity() >= 4);
+ a.shrink_to_fit();
+ if(a.capacity() != a.size())
+ throw test_failure{};
+ });
+ }
+ }
+
+ void
+ testModifiers()
+ {
+ // clear
+ {
+ {
+ array a;
+ BOOST_TEST(a.size() == 0);
+ BOOST_TEST(a.capacity() == 0);
+ a.clear();
+ BOOST_TEST(a.size() == 0);
+ BOOST_TEST(a.capacity() == 0);
+ }
+ {
+ array a({1, true, str_});
+ a.clear();
+ BOOST_TEST(a.size() == 0);
+ BOOST_TEST(a.capacity() > 0);
+ }
+ }
+
+ // insert(const_iterator, value_type const&)
+ {
+ // fast path
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a({1, 2, 3}, sp);
+ a.pop_back();
+ BOOST_TEST(
+ a.capacity() > a.size());
+ a.insert(a.begin(), 1);
+ BOOST_TEST(
+ a == array({1, 1, 2}));
+ });
+
+ // self-insert
+ {
+ array a = {1, 2, 3};
+ a.insert(a.begin(), a[1]);
+ BOOST_TEST(
+ a == array({2, 1, 2, 3}));
+ }
+
+ // fail
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a({1, str_}, sp);
+ value v(true);
+ a.insert(a.begin() + 1, v);
+ check(a);
+ check_storage(a, sp);
+ });
+ }
+
+ // insert(const_iterator, value_type&&)
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a({1, str_}, sp);
+ value v(true);
+ a.insert(
+ a.begin() + 1, std::move(v));
+ check(a);
+ check_storage(a, sp);
+ });
+
+ // insert(const_iterator, size_type, value_type const&)
+ {
+ // fast path
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a({1, str_}, sp);
+ a.reserve(3);
+ BOOST_TEST(
+ a.capacity() > a.size());
+ a.insert(&a[1], 1, true);
+ check(a);
+ });
+
+ // zero
+ {
+ array a(3);
+ a.insert(&a[1], 0, true);
+ BOOST_TEST(a.size() == 3);
+ }
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ value v({1,2,3});
+ array a({1, str_}, sp);
+ a.insert(a.begin() + 1, 3, v);
+ BOOST_TEST(a[0].is_number());
+ BOOST_TEST(a[1].as_array().size() == 3);
+ BOOST_TEST(a[2].as_array().size() == 3);
+ BOOST_TEST(a[3].as_array().size() == 3);
+ BOOST_TEST(a[4].is_string());
+ });
+ }
+
+ // insert(const_iterator, InputIt, InputIt)
+ {
+ // random iterator
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::initializer_list<
+ value> init = {1, true};
+ array a({str_}, sp);
+ a.insert(a.begin(),
+ init.begin(), init.end());
+ check(a);
+ });
+
+ // random iterator (multiple growth)
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::initializer_list<value_ref> init = {
+ 1, str_, true, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30 };
+ array a(sp);
+ a.insert(a.begin(),
+ init.begin(), init.end());
+ BOOST_TEST(a.size() == init.size());
+ BOOST_TEST(a.capacity() == init.size());
+ });
+
+ // input iterator (empty range)
+ {
+ std::initializer_list<value_ref> init;
+ array a;
+ a.insert(a.begin(),
+ make_input_iterator(init.begin()),
+ make_input_iterator(init.end()));
+ BOOST_TEST(a.empty());
+ }
+
+ // input iterator
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::initializer_list<
+ value> init = {1, true};
+ array a({str_}, sp);
+ a.insert(a.begin(),
+ make_input_iterator(init.begin()),
+ make_input_iterator(init.end()));
+ check(a);
+ });
+
+ // input iterator (multiple growth)
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::initializer_list<value_ref> init =
+ {1, true, 1, 2, 3, 4, 5, 6, 7};
+ array a({str_}, sp);
+ a.insert(a.begin(),
+ make_input_iterator(init.begin()),
+ make_input_iterator(init.end()));
+ BOOST_TEST(a.size() == init.size() + 1);
+ });
+
+ // backward relocate
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::initializer_list<value_ref> init = {1, 2};
+ array a({"a", "b", "c", "d", "e"}, sp);
+ a.insert(
+ a.begin() + 1,
+ init.begin(), init.end());
+ });
+ }
+
+ // insert(const_iterator, init_list)
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a({0, 3, 4}, sp);
+ auto it = a.insert(
+ a.begin() + 1, {1, str_});
+ BOOST_TEST(it == a.begin() + 1);
+ BOOST_TEST(a[0].as_int64() == 0);
+ BOOST_TEST(a[1].as_int64() == 1);
+ BOOST_TEST(a[2].as_string() == str_);
+ BOOST_TEST(a[3].as_int64() == 3);
+ BOOST_TEST(a[4].as_int64() == 4);
+ });
+
+ // emplace(const_iterator, arg)
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a({0, 2, 3, 4}, sp);
+ auto it = a.emplace(
+ a.begin() + 1, str_);
+ BOOST_TEST(it == a.begin() + 1);
+ BOOST_TEST(a[0].as_int64() == 0);
+ BOOST_TEST(a[1].as_string() == str_);
+ BOOST_TEST(a[2].as_int64() == 2);
+ BOOST_TEST(a[3].as_int64() == 3);
+ BOOST_TEST(a[4].as_int64() == 4);
+ });
+
+ // erase(pos)
+ {
+ array a({1, true, nullptr, str_});
+ a.erase(a.begin() + 2);
+ check(a);
+ }
+
+ // erase(first, last)
+ {
+ array a({1, true, nullptr, 1.f, str_});
+ a.erase(
+ a.begin() + 2,
+ a.begin() + 4);
+ check(a);
+ }
+
+ // push_back(value const&)
+ {
+ // fast path
+ {
+ array a = {1, 2, 3};
+ a.pop_back();
+ BOOST_TEST(
+ a.capacity() > a.size());
+ a.push_back(1);
+ BOOST_TEST(a ==
+ array({1, 2, 1}));
+ }
+
+ // self push_back
+ {
+ array a = {1, 2, 3};
+ a.push_back(a[1]);
+ BOOST_TEST(a ==
+ array({1, 2, 3, 2}));
+ }
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a({1, true}, sp);
+ value v(str_);
+ a.push_back(v);
+ BOOST_TEST(
+ v.as_string() == str_);
+ check(a);
+ check_storage(a, sp);
+ });
+ }
+
+ // push_back(value&&)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a({1, true}, sp);
+ value v(str_);
+ a.push_back(std::move(v));
+ check(a);
+ check_storage(a, sp);
+ });
+ }
+
+ // emplace_back(arg)
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a({1, true}, sp);
+ a.emplace_back(str_);
+ check(a);
+ check_storage(a, sp);
+ });
+
+ // pop_back()
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a({1, true, str_, nullptr}, sp);
+ a.pop_back();
+ check(a);
+ check_storage(a, sp);
+ });
+
+ // resize(size_type)
+ {
+ value v(array{});
+ v.as_array().emplace_back(1);
+ v.as_array().emplace_back(true);
+ v.as_array().emplace_back(str_);
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a(5, sp);
+ a.resize(3);
+ BOOST_TEST(a.size() == 3);
+ check_storage(a, sp);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a(sp);
+ a.resize(3);
+ BOOST_TEST(a.size() == 3);
+ check_storage(a, sp);
+ });
+ }
+
+ // resize(size_type, value_type const&)
+ {
+ value v(array{});
+ v.as_array().emplace_back(1);
+ v.as_array().emplace_back(true);
+ v.as_array().emplace_back(str_);
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a(5, v, sp);
+ a.resize(3, v);
+ BOOST_TEST(a.size() == 3);
+ check_storage(a, sp);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a(3, v, sp);
+ a.resize(5, v);
+ BOOST_TEST(a.size() == 5);
+ check_storage(a, sp);
+ });
+ }
+
+ // swap
+ {
+ // same storage
+ {
+ array a1({1, true, str_});
+ array a2 = {1.};
+ a1.swap(a2);
+ check(a2);
+ BOOST_TEST(a1.size() == 1);
+ BOOST_TEST(a1.front().is_number());
+ BOOST_TEST(a1.front().as_double() == 1.);
+ }
+
+ // different storage
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a1({1, true, str_}, sp);
+ array a2 = {1.};
+ a1.swap(a2);
+ check(a2);
+ BOOST_TEST(a1.size() == 1);
+ });
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a1 = {1.};
+ array a2({1, true, str_}, sp);
+ a1.swap(a2);
+ check(a1);
+ BOOST_TEST(a2.size() == 1);
+ });
+ }
+ }
+
+ void
+ testExceptions()
+ {
+ // operator=(array const&)
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a0({1, true, str_});
+ array a1;
+ array a(sp);
+ a.emplace_back(nullptr);
+ a = a0;
+ a1 = a;
+ check(a1);
+ });
+
+ // operator=(init_list)
+ fail_loop([&](storage_ptr const& sp)
+ {
+ init_list init{ 1, true, str_ };
+ array a1;
+ array a(sp);
+ a.emplace_back(nullptr);
+ a = init;
+ a1 = a;
+ check(a1);
+ });
+
+ // insert(const_iterator, count, value_type const&)
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a1;
+ array a({1, true}, sp);
+ a.insert(a.begin() + 1,
+ 3, nullptr);
+ a1 = a;
+ BOOST_TEST(a1.size() == 5);
+ BOOST_TEST(a1[0].is_number());
+ BOOST_TEST(a1[1].is_null());
+ BOOST_TEST(a1[2].is_null());
+ BOOST_TEST(a1[3].is_null());
+ BOOST_TEST(a1[4].is_bool());
+ });
+
+ // insert(const_iterator, InputIt, InputIt)
+ fail_loop([&](storage_ptr const& sp)
+ {
+ init_list init{ 1, true, str_ };
+ array a1;
+ array a(sp);
+ a.insert(a.end(),
+ init.begin(), init.end());
+ a1 = a;
+ check(a1);
+ });
+
+ // emplace(const_iterator, arg)
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a1;
+ array a({1, nullptr}, sp);
+ a.emplace(a.begin() + 1, true);
+ a1 = a;
+ BOOST_TEST(a1.size() == 3);
+ BOOST_TEST(a1[0].is_number());
+ BOOST_TEST(a1[1].is_bool());
+ BOOST_TEST(a1[2].is_null());
+ });
+
+ // emplace(const_iterator, arg)
+ fail_loop([&](storage_ptr const& sp)
+ {
+ array a1;
+ array a({1, str_}, sp);
+ a.emplace(a.begin() + 1, true);
+ a1 = a;
+ check(a1);
+ BOOST_TEST(a1.size() == 3);
+ BOOST_TEST(a1[0].is_number());
+ BOOST_TEST(a1[1].is_bool());
+ BOOST_TEST(a1[2].is_string());
+ });
+ }
+
+ void
+ testEquality()
+ {
+ BOOST_TEST(array({}) == array({}));
+ BOOST_TEST(array({}) != array({1,2}));
+ BOOST_TEST(array({1,2,3}) == array({1,2,3}));
+ BOOST_TEST(array({1,2,3}) != array({1,2}));
+ BOOST_TEST(array({1,2,3}) != array({3,2,1}));
+ }
+
+ void
+ testHash()
+ {
+ BOOST_TEST(check_hash_equal(
+ array{}, array()));
+ BOOST_TEST(check_hash_equal(
+ array{1,1}, array{1,1}));
+ BOOST_TEST(check_hash_equal(
+ array{1,1}, array{1,1}));
+ BOOST_TEST(expect_hash_not_equal(
+ array{1,1}, array{1,2}));
+ BOOST_TEST(check_hash_equal(
+ array{"a", "b", 17},
+ array{"a", "b", 17U}));
+ BOOST_TEST(expect_hash_not_equal(
+ array{"a", "b", nullptr},
+ array{nullptr, "a", "b"}));
+ }
+
+ void
+ run()
+ {
+ testDestroy();
+ testCtors();
+ testAssign();
+ testGetStorage();
+ testAccess();
+ testIterators();
+ testCapacity();
+ testModifiers();
+ testExceptions();
+ testEquality();
+ testHash();
+ }
+};
+
+TEST_SUITE(array_test, "boost.json.array");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/basic_parser.cpp b/src/boost/libs/json/test/basic_parser.cpp
new file mode 100644
index 000000000..6f25111d1
--- /dev/null
+++ b/src/boost/libs/json/test/basic_parser.cpp
@@ -0,0 +1,1651 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/basic_parser_impl.hpp>
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "parse-vectors.hpp"
+#include "test.hpp"
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+BOOST_STATIC_ASSERT( std::is_nothrow_destructible<basic_parser<int>>::value );
+
+namespace base64 {
+
+std::size_t constexpr
+decoded_size(std::size_t n)
+{
+ return n / 4 * 3; // requires n&3==0, smaller
+}
+
+signed char const*
+get_inverse()
+{
+ static signed char constexpr tab[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0-15
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32-47
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 48-63
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80-95
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112-127
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128-143
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144-159
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160-175
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176-191
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192-207
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208-223
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 240-255
+ };
+ return &tab[0];
+}
+
+std::pair<std::size_t, std::size_t>
+decode(void* dest, char const* src, std::size_t len)
+{
+ char* out = static_cast<char*>(dest);
+ auto in = reinterpret_cast<unsigned char const*>(src);
+ unsigned char c3[3], c4[4];
+ int i = 0;
+ int j = 0;
+
+ auto const inverse = base64::get_inverse();
+
+ while(len-- && *in != '=')
+ {
+ auto const v = inverse[*in];
+ if(v == -1)
+ break;
+ ++in;
+ c4[i] = v;
+ if(++i == 4)
+ {
+ c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4);
+ c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
+ c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
+
+ for(i = 0; i < 3; i++)
+ *out++ = c3[i];
+ i = 0;
+ }
+ }
+
+ if(i)
+ {
+ c3[0] = ( c4[0] << 2) + ((c4[1] & 0x30) >> 4);
+ c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
+ c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
+
+ for(j = 0; j < i - 1; j++)
+ *out++ = c3[j];
+ }
+
+ return {out - static_cast<char*>(dest),
+ in - reinterpret_cast<unsigned char const*>(src)};
+}
+
+} // base64
+
+namespace {
+
+bool
+validate( string_view s )
+{
+ // Parse with the null parser and return false on error
+ null_parser p;
+ error_code ec;
+ p.write( s.data(), s.size(), ec );
+ if( ec )
+ return false;
+
+ // The string is valid JSON.
+ return true;
+}
+
+parse_options
+make_options(
+ bool comments,
+ bool commas,
+ bool utf8)
+{
+ parse_options opt;
+ opt.allow_comments = comments;
+ opt.allow_trailing_commas = commas;
+ opt.allow_invalid_utf8 = utf8;
+ return opt;
+}
+
+} // (anon)
+
+class basic_parser_test
+{
+public:
+ ::test_suite::log_type log;
+
+ void
+ grind_one(
+ string_view s,
+ bool good,
+ parse_options po)
+ {
+ error_code ec;
+ fail_parser p(po);
+ p.write(false,
+ s.data(), s.size(), ec);
+ BOOST_TEST((good && !ec) ||
+ (! good && ec));
+ }
+
+ void
+ grind_one(
+ string_view s,
+ bool good,
+ const std::vector<parse_options>& configs)
+ {
+ for (const parse_options& po : configs)
+ grind_one(s, good, po);
+ }
+
+ void
+ grind(
+ string_view s,
+ bool good,
+ parse_options po)
+ {
+ grind_one(s, good, po);
+
+ // split/errors matrix
+ if(! s.empty())
+ {
+ for(std::size_t i = 1;
+ i < s.size(); ++i)
+ {
+ for(std::size_t j = 1;;++j)
+ {
+ error_code ec;
+ fail_parser p(j, po);
+ p.write(true, s.data(), i, ec);
+ if(ec == error::test_failure)
+ continue;
+ if(! ec)
+ {
+ p.write(false, s.data() + i,
+ s.size() - i, ec);
+ if(ec == error::test_failure)
+ continue;
+ }
+ BOOST_TEST((good && !ec) || (
+ ! good && ec));
+ break;
+ }
+ }
+ }
+
+ // split/exceptions matrix
+ if(! s.empty())
+ {
+ for(std::size_t i = 1;
+ i < s.size(); ++i)
+ {
+ for(std::size_t j = 1;;++j)
+ {
+ error_code ec;
+ throw_parser p(j, po);
+ try
+ {
+ p.write(
+ true, s.data(), i, ec);
+ if(! ec)
+ p.write(
+ false, s.data() + i,
+ s.size() - i, ec);
+ BOOST_TEST((good && !ec) || (
+ ! good && ec));
+ break;
+ }
+ catch(test_exception const&)
+ {
+ continue;
+ }
+ catch(std::exception const& e)
+ {
+ BOOST_TEST_FAIL();
+ log << " " <<
+ e.what() << std::endl;
+ }
+ }
+ }
+ }
+ }
+
+ void
+ grind(
+ string_view s,
+ bool good,
+ const std::vector<parse_options>& configs)
+ {
+ for (const parse_options& po : configs)
+ grind(s, good, po);
+ }
+
+ void
+ bad(string_view s)
+ {
+ grind(s, false, parse_options());
+ }
+
+ void
+ good(string_view s)
+ {
+ grind(s, true, parse_options());
+ }
+
+ void
+ bad(
+ string_view s,
+ const parse_options& po)
+ {
+ grind(s, false, po);
+ }
+
+ void
+ good(
+ string_view s,
+ const parse_options& po)
+ {
+ grind(s, true, po);
+ }
+
+ void
+ bad_one(
+ string_view s,
+ const parse_options& po)
+ {
+ grind_one(s, false, po);
+ }
+
+ void
+ good_one(
+ string_view s,
+ const parse_options& po)
+ {
+ grind_one(s, true, po);
+ }
+
+ void
+ bad_one(string_view s)
+ {
+ grind_one(s, false, parse_options());
+ }
+
+ void
+ good_one(string_view s)
+ {
+ grind_one(s, true, parse_options());
+ }
+
+ //------------------------------------------------------
+
+ void
+ testNull()
+ {
+ good("null");
+ good(" null");
+ good("null ");
+ good("\tnull");
+ good("null\t");
+ good("\r\n\t null\r\n\t ");
+
+ bad ("n ");
+ bad ("nu ");
+ bad ("nul ");
+ bad ("n--- ");
+ bad ("nu-- ");
+ bad ("nul- ");
+
+ bad ("NULL");
+ bad ("Null");
+ bad ("nulls");
+ }
+
+ void
+ testBoolean()
+ {
+ good("true");
+ good(" true");
+ good("true ");
+ good("\ttrue");
+ good("true\t");
+ good("\r\n\t true\r\n\t ");
+
+ bad ("t ");
+ bad ("tr ");
+ bad ("tru ");
+ bad ("t--- ");
+ bad ("tr-- ");
+ bad ("tru- ");
+ bad ("TRUE");
+ bad ("True");
+ bad ("truer");
+
+ good("false");
+ good(" false");
+ good("false ");
+ good("\tfalse");
+ good("false\t");
+ good("\r\n\t false\r\n\t ");
+
+ bad ("f ");
+ bad ("fa ");
+ bad ("fal ");
+ bad ("fals ");
+ bad ("f---- ");
+ bad ("fa--- ");
+ bad ("fal-- ");
+ bad ("fals- ");
+ bad ("FALSE");
+ bad ("False");
+ bad ("falser");
+ }
+
+ void
+ testString()
+ {
+ good(R"jv( "x" )jv");
+ good(R"jv( "xy" )jv");
+ good(R"jv( "x y" )jv");
+
+ // escapes
+ good(R"jv(" \" ")jv");
+ good(R"jv(" \\ ")jv");
+ good(R"jv(" \/ ")jv");
+ good(R"jv(" \b ")jv");
+ good(R"jv(" \f ")jv");
+ good(R"jv(" \n ")jv");
+ good(R"jv(" \r ")jv");
+ good(R"jv(" \t ")jv");
+
+ // utf-16 escapes
+ good(R"jv( " \u0000 " )jv");
+ good(R"jv( " \ud7ff " )jv");
+ good(R"jv( " \ue000 " )jv");
+ good(R"jv( " \uffff " )jv");
+ good(R"jv( " \ud800\udc00 " )jv");
+ good(R"jv( " \udbff\udfff " )jv");
+ good(R"jv( " \n\u0000 " )jv");
+
+ // escape in key
+ good(R"jv( {" \n":null} )jv");
+
+ // incomplete
+ bad ("\"");
+
+ // illegal control character
+ bad ({ "\"" "\x00" "\"", 3 });
+ bad ("\"" "\x1f" "\"");
+ bad ("\"" "\\n" "\x1f" "\"");
+
+ // incomplete escape
+ bad (R"jv( "\" )jv");
+
+ // invalid escape
+ bad (R"jv( "\z" )jv");
+
+ // utf-16 escape, fast path,
+ // invalid surrogate
+ bad (R"jv( " \u---- " )jv");
+ bad (R"jv( " \ud--- " )jv");
+ bad (R"jv( " \ud8-- " )jv");
+ bad (R"jv( " \ud80- " )jv");
+ // invalid low surrogate
+ bad (R"jv( " \ud800------ " )jv");
+ bad (R"jv( " \ud800\----- " )jv");
+ bad (R"jv( " \ud800\u---- " )jv");
+ bad (R"jv( " \ud800\ud--- " )jv");
+ bad (R"jv( " \ud800\udc-- " )jv");
+ bad (R"jv( " \ud800\udc0- " )jv");
+ // illegal leading surrogate
+ bad (R"jv( " \udc00 " )jv");
+ bad (R"jv( " \udfff " )jv");
+ // illegal trailing surrogate
+ bad (R"jv( " \ud800\udbff " )jv");
+ bad (R"jv( " \ud800\ue000 " )jv");
+ }
+
+ void
+ testNumber()
+ {
+ good("0");
+ good("0 ");
+ good("0e0 ");
+ good("0E0 ");
+ good("0e00 ");
+ good("0E01 ");
+ good("0e+0 ");
+ good("0e-0 ");
+ good("0.0 ");
+ good("0.01 ");
+ good("0.0e0 ");
+ good("0.01e+0 ");
+ good("0.02E-0 ");
+ good("1 ");
+ good("12 ");
+ good("1e0 ");
+ good("1E0 ");
+ good("1e00 ");
+ good("1E01 ");
+ good("1e+0 ");
+ good("1e-0 ");
+ good("1.0 ");
+ good("1.01 ");
+ good("1.0e0 ");
+ good("1.01e+0 ");
+ good("1.02E-0 ");
+ good("1.0");
+
+ good("-0 ");
+ good("-0e0 ");
+ good("-0E0 ");
+ good("-0e00 ");
+ good("-0E01 ");
+ good("-0e+0 ");
+ good("-0e-0 ");
+ good("-0.0 ");
+ good("-0.01 ");
+ good("-0.0e0 ");
+ good("-0.01e+0 ");
+ good("-0.02E-0 ");
+ good("-1 ");
+ good("-12 ");
+ good("-1 ");
+ good("-1e0 ");
+ good("-1E0 ");
+ good("-1e00 ");
+ good("-1E01 ");
+ good("-1e+0 ");
+ good("-1e-0 ");
+ good("-1.0 ");
+ good("-1.01 ");
+ good("-1.0e0 ");
+ good("-1.01e+0 ");
+ good("-1.02E-0 ");
+ good("-1.0");
+
+ good("1.1e309 ");
+ good("9223372036854775807 ");
+ good("-9223372036854775807 ");
+ good("18446744073709551615 ");
+ good("-18446744073709551615 ");
+
+ good("1234567890123456");
+ good("-1234567890123456");
+ good("10000000000000000000000000");
+
+ good("0.900719925474099178 ");
+
+ // non-significant digits
+ good("1000000000000000000000000 ");
+ good("1000000000000000000000000e1 ");
+ good("1000000000000000000000000.0 ");
+ good("1000000000000000000000000.00 ");
+ good("1000000000000000000000000.000000000001");
+ good("1000000000000000000000000.0e1 ");
+ good("1000000000000000000000000.0 ");
+
+ good("1000000000.1000000000 ");
+
+ bad("");
+ bad("- ");
+ bad("00 ");
+ bad("01 ");
+ bad("00. ");
+ bad("00.0 ");
+ bad("-00 ");
+ bad("-01 ");
+ bad("-00. ");
+ bad("-00.0 ");
+ bad("1a ");
+ bad("-a ");
+ bad(". ");
+ bad("1. ");
+ bad("1+ ");
+ bad("0.0+ ");
+ bad("0.0e+ ");
+ bad("0.0e- ");
+ bad("0.0e0- ");
+ bad("0.0e ");
+ bad("1eX ");
+ bad("1000000000000000000000000.e ");
+ bad("0.");
+ bad("0.0e+");
+ bad("0.0e2147483648");
+ }
+
+ void
+ testArray()
+ {
+ good("[]");
+ good("[ ]");
+ good("[ \t ]");
+ good("[ \"\" ]");
+ good("[ \" \" ]");
+ good("[ \"x\" ]");
+ good("[ \"x\", \"y\" ]");
+ good("[1,2,3]");
+ good(" [1,2,3]");
+ good("[1,2,3] ");
+ good(" [1,2,3] ");
+ good("[1,2,3]");
+ good("[ 1,2,3]");
+ good("[1 ,2,3]");
+ good("[1, 2,3]");
+ good("[1,2 ,3]");
+ good("[1,2, 3]");
+ good("[1,2,3 ]");
+ good(" [ 1 , 2 \t\n , \n3]");
+
+ bad ("[");
+ bad (" [");
+ bad (" []]");
+ bad ("[{]");
+ bad (R"jv( [ null ; 1 ] )jv");
+ }
+
+ void
+ testObject()
+ {
+ good("{}");
+ good("{ }");
+ good("{ \t }");
+ good("{\"x\":null}");
+ good("{ \"x\":null}");
+ good("{\"x\" :null}");
+ good("{\"x\": null}");
+ good("{\"x\":null }");
+ good("{ \"x\" : null }");
+ good("{ \"x\" : {} }");
+ good("{ \"x\" : [] }");
+ good("{ \"x\" : { \"y\" : null } }");
+ good("{ \"x\" : [{}] }");
+ good("{\"x\\ny\\u0022\":null}");
+ good("{ \"x\":1, \"y\":null}");
+ good("{\"x\":1,\"y\":2,\"z\":3}");
+ good(" {\"x\":1,\"y\":2,\"z\":3}");
+ good("{\"x\":1,\"y\":2,\"z\":3} ");
+ good(" {\"x\":1,\"y\":2,\"z\":3} ");
+ good("{ \"x\":1,\"y\":2,\"z\":3}");
+ good("{\"x\" :1,\"y\":2,\"z\":3}");
+ good("{\"x\":1 ,\"y\":2,\"z\":3}");
+ good("{\"x\":1,\"y\" :2,\"z\":3}");
+ good("{\"x\":1,\"y\": 2,\"z\":3}");
+ good("{\"x\":1,\"y\":2 ,\"z\":3}");
+ good("{\"x\":1,\"y\":2, \"z\":3}");
+ good("{\"x\":1,\"y\":2, \"z\" :3}");
+ good("{\"x\":1,\"y\":2, \"z\": 3}");
+ good("{\"x\":1,\"y\":2, \"z\":3 }");
+ good(" \t { \"x\" \n : 1, \"y\" :2, \"z\" : 3} \n");
+
+ good("[{\"x\":[{\"y\":null}]}]");
+
+ bad ("{");
+ bad (" {");
+ bad (" {}}");
+ bad ("{{}}");
+ bad ("{[]}");
+
+ bad (R"jv( {"x";null} )jv");
+ bad (R"jv( {"x":null . "y":0} )jv");
+ }
+
+ void
+ testParser()
+ {
+ auto const check =
+ [this]( string_view s,
+ bool done)
+ {
+ fail_parser p;
+ error_code ec;
+ p.write_some(
+ true,
+ s.data(), s.size(),
+ ec);
+ if(! BOOST_TEST(! ec))
+ {
+ log << " failed to parse: " << s << '\n';
+ return;
+ }
+ BOOST_TEST(done == p.done());
+ };
+
+ // done()
+
+ check("{}", true);
+ check("{} ", true);
+ check("{}x", true);
+ check("{} x", true);
+
+ check("[]", true);
+ check("[] ", true);
+ check("[]x", true);
+ check("[] x", true);
+
+ check("\"a\"", true);
+ check("\"a\" ", true);
+ check("\"a\"x", true);
+ check("\"a\" x", true);
+
+ check("0", false);
+ check("0 ", true);
+ check("0x", true);
+ check("0 x", true);
+ check("0.", false);
+ check("0.0", false);
+ check("0.0 ", true);
+ check("0.0 x", true);
+
+ check("true", true);
+ check("true ", true);
+ check("truex", true);
+ check("true x", true);
+
+ check("false", true);
+ check("false ", true);
+ check("falsex", true);
+ check("false x", true);
+
+ check("null", true);
+ check("null ", true);
+ check("nullx", true);
+ check("null x", true);
+
+ // flush
+ {
+ {
+ for(auto esc :
+ { "\\\"", "\\\\", "\\/", "\\b",
+ "\\f", "\\n", "\\r", "\\t", "\\u0000"
+ })
+ {
+ std::string const big =
+ "\\\"" + std::string(
+ BOOST_JSON_STACK_BUFFER_SIZE-4, '*') + esc;
+ std::string const s =
+ "{\"" + big + "\":\"" + big + "\"}";
+ good_one(s);
+ }
+ }
+ {
+ std::string big;
+ big = "\\\"" +
+ std::string(
+ BOOST_JSON_STACK_BUFFER_SIZE+ 1, '*');
+ std::string s;
+ s = "{\"" + big + "\":\"" + big + "\"}";
+ good_one(s);
+ }
+ }
+
+ // no input
+ {
+ error_code ec;
+ fail_parser p;
+ p.write(false, nullptr, 0, ec);
+ BOOST_TEST(ec);
+ }
+ }
+
+ void
+ testMembers()
+ {
+ fail_parser p;
+ std::size_t n;
+ error_code ec;
+ n = p.write_some(true, "null", 4, ec );
+ if(BOOST_TEST(! ec))
+ {
+ BOOST_TEST(n == 4);
+ BOOST_TEST(p.done());
+ n = p.write_some(false, " \t42", 4, ec);
+ BOOST_TEST(n == 2);
+ BOOST_TEST(! ec);
+ }
+ p.reset();
+ n = p.write_some(false, "[1,2,3]", 7, ec);
+ if(BOOST_TEST(! ec))
+ {
+ BOOST_TEST(n == 7);
+ BOOST_TEST(p.done());
+ }
+ }
+
+ void
+ testParseVectors()
+ {
+ std::vector<parse_options> all_configs =
+ {
+ make_options(false, false, true),
+ make_options(true, false, true),
+ make_options(false, true, true),
+ make_options(true, true, true),
+ make_options(false, false, false),
+ make_options(true, false, false),
+ make_options(false, true, false),
+ make_options(true, true, false)
+ };
+ parse_vectors pv;
+ for(auto const& v : pv)
+ {
+ // skip these , because basic_parser
+ // doesn't have a max_depth setting.
+ if( v.name == "structure_100000_opening_arrays" ||
+ v.name == "structure_open_array_object")
+ {
+ continue;
+ }
+ for (const parse_options& po : all_configs)
+ {
+ if(v.result == 'i')
+ {
+ error_code ec;
+ fail_parser p(po);
+ p.write(
+ false,
+ v.text.data(),
+ v.text.size(),
+ ec);
+ if(! ec)
+ good_one(v.text, po);
+ else
+ bad_one(v.text, po);
+ }
+ else if(v.result == 'y')
+ good_one(v.text, po);
+ else
+ bad_one(v.text, po);
+ }
+ }
+ }
+
+ // https://github.com/boostorg/json/issues/13
+ void
+ testIssue13()
+ {
+ validate("\"~QQ36644632 {n");
+ }
+
+ void
+ testIssue20()
+ {
+ string_view s =
+ "WyL//34zOVx1ZDg0ZFx1ZGM4M2RcdWQ4M2RcdWRlM2M4dWRlMTlcdWQ4M2RcdWRlMzlkZWUzOVx1"
+ "ZDg0ZFx1ZGM4M2RcdWQ4M2RcdWRlMzlcXHVkY2M4M1x1ZDg5ZFx1ZGUzOVx1ZDgzZFx1ZGUzOWRb"
+ "IGZhbHNlLDMzMzMzMzMzMzMzMzMzMzMzNDMzMzMzMTY1MzczNzMwLDMzMzMzMzMzMzMzMzMzMzMz"
+ "MzM3ODAsMzMzMzMzMzMzMzM0MzMzMzMxNjUzNzM3MzAsMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz"
+ "MzM3ODAsMzMzMzMzMzMzMzMzMzQzMzMzMzE2NTM3MzczMCwzMzMzMzMzMzMzMzMzMzMzMzMzNzgw"
+ "LDMzMzMzMzM4MzU1MzMwNzQ3NDYwLDMzMTY2NTAwMDAzMzMzMzMwNzQ3MzMzMzMzMzc3OSwzMzMz"
+ "MzMzMzMzMzMzMzMzNDMzMzMzMzMwNzQ3NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMz"
+ "MzMzMzMzMzMzMzA4ODM1NTMzMDc0Mzc4MCwzMzMzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAs"
+ "MzMzMzMzMzMxNjY1MDAwMDMzMzMzNDc0NjAsMzMzMzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMz"
+ "MzMzMzM3MzMzMzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQz"
+ "MzMzMzMwNzQ3NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzNzgw"
+ "LDMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwzMzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3"
+ "NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMwNzQ3NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzNzgw"
+ "LDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0Mzc4MCwzMzMzMzMzMzMzMzMzMzMzMzMwODgzNTUz"
+ "MzA3NDM3ODAsMzMzMzMzMzMzMzMzMzMzMDg4MzU1MzMwNzQ3NDYwLDMzMzMzMzMzMzMzMDczMzM3"
+ "NDc0NjAsMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwz"
+ "MzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMzMDc0"
+ "NzQ2MCwzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM3ODAsMzMzMzMzMzMzMzMzMzMzMDg4"
+ "MzU1MzMwNzQzNzgwLDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwzMzMzMzMzMzMzMzMz"
+ "MzMzMzM0MjQ3LDMzMzMzMzMzMzMzMzMzMzQzMzMzMzMzMzMzMzMzMzM3MzMzMzQzMzMzMzMzMDc0"
+ "NzQ2MCwzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwz"
+ "MzE2NjUwMDAwMzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMwNzQ3"
+ "NDYwLDMzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0Mzc4"
+ "MCwzMzMzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAsMzMzMzMzMzMzLDMzMzMzMzMzMzMzMzMz"
+ "MzMzMzM3ODAsMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAsMzMxNjY1"
+ "MDAwMDMzMzMzMzA3NDczMzMzMzMzNzc5LDMzMzMzMzMzMzM3ODAsMzMzMzMzMzgzNTUzMzA3NDc0"
+ "NjAsMzMxNjY1MDAwMDMzMzMzMzA3NDczMzMzMzMzNzc5LDMzMzMzMzMzMzMzMzMzMzM0MzMzMzMz"
+ "MzA3NDc0NjAsMzMzMzMzMzMzMzMzMzMzMzMzMzM3ODAsMzMzMzMzMzMzMzMzMzMzMDg4MzU1MzMw"
+ "NzQzNzgwLDMzMzMzMzMzMzMzMzMzMzA4ODM1NTMzMDc0NzQ2MCwzMzMzMzMzMzE2NjUwMDAwMzMz"
+ "MzM0NzQ2MCwzMzMzMzMzMzMzMzMzMzMzMzMzNzgwLDMzMzMzMzMzMzMzMzM0MzMzMzMxNjUzNzM3"
+ "MzAsMzMzMzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzODM1NTMzMDc0NzQ2MCwzMzE2NjUwMDAw"
+ "MzMzMzMzMDc0NzMzMzMzMzM3NzksMzMzMzMzMzMzMzMzMzMzMzQzMzMzMzMzMDc0NzQ2MCwzMzMz"
+ "MzMzMzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDM3ODAsMzMzMzMz"
+ "MzMzMzMzMzMzMDg4MzU1MzMwNzQ3NDYwLDMzMzMzMzMzMTY2NTAwMDAzMzMzMzQ3NDYwLDMzMzMz"
+ "MzMzMzMzMzMzMzMzMzM3ODAsMzMzMzMzMzMzMzMzNzMzMzM0MzMzMzMzMzA3NDc0NjAsMzMzMzMz"
+ "MzMzMzMzMzMzMzMzMzc4MCwzMzMzMzMzMzMzMzMwODgzNTUzMzA3NDc0NjAsMzMxNjY1MDAwMDMz"
+ "MzMzMzA3NDczMzMzMzMzNzc5LDMzMzMzMzMzMzMzMzMzMzM0MzMzMzNcdWQ4N2RcdWRlZGV1ZGM4"
+ "ZGUzOVx1ZDg0ZFx1ZGM4M2RcdWQ4OGRcdWRlMzlcdWQ4OWRcdWRlMjM5MzMzZWUzOVxk";
+ auto const len = base64::decoded_size(s.size());
+ std::unique_ptr<char[]> p(new char[len]);
+ base64::decode(
+ p.get(), s.data(), s.size());
+ string_view const js(p.get(), len);
+ BOOST_TEST(! validate(js));
+ }
+
+ void
+ testIssue113()
+ {
+ string_view s =
+ "\"\\r\\n section id='description'>\\r\\nAll mbers form the uncountable set "
+ "\\u211D. Among its subsets, relatively simple are the convex sets, each expressed "
+ "as a range between two real numbers <i>a</i> and <i>b</i> where <i>a</i> \\u2264 <i>"
+ "b</i>. There are actually four cases for the meaning of \\\"between\\\", depending "
+ "on open or closed boundary:\\r\\n\\r\\n<ul>\\r\\n <li>[<i>a</i>, <i>b</i>]: {<i>"
+ "x</i> | <i>a</i> \\u2264 <i>x</i> and <i>x</i> \\u2264 <i>b</i> }</li>\\r\\n <li>"
+ "(<i>a</i>, <i>b</i>): {<i>x</i> | <i>a</i> < <i>x</i> and <i>x</i> < <i>b</i> }"
+ "</li>\\r\\n <li>[<i>a</i>, <i>b</i>): {<i>x</i> | <i>a</i> \\u2264 <i>x</i> and "
+ "<i>x</i> < <i>b</i> }</li>\\r\\n <li>(<i>a</i>, <i>b</i>]: {<i>x</i> | <i>a</i> "
+ "< <i>x</i> and <i>x</i> \\u2264 <i>b</i> }</li>\\r\\n</ul>\\r\\n\\r\\nNote that "
+ "if <i>a</i> = <i>b</i>, of the four only [<i>a</i>, <i>a</i>] would be non-empty."
+ "\\r\\n\\r\\n<strong>Task</strong>\\r\\n\\r\\n<ul>\\r\\n <li>Devise a way to "
+ "represent any set of real numbers, for the definition of \\\"any\\\" in the "
+ "implementation notes below.</li>\\r\\n <li>Provide methods for these common "
+ "set operations (<i>x</i> is a real number; <i>A</i> and <i>B</i> are sets):</li>"
+ "\\r\\n <ul>\\r\\n <li>\\r\\n <i>x</i> \\u2208 <i>A</i>: determine if <i>"
+ "x</i> is an element of <i>A</i><br>\\r\\n example: 1 is in [1, 2), while 2, "
+ "3, ... are not.\\r\\n </li>\\r\\n <li>\\r\\n <i>A</i> \\u222A <i>B</i>: "
+ "union of <i>A</i> and <i>B</i>, i.e. {<i>x</i> | <i>x</i> \\u2208 <i>A</i> or <i>x"
+ "</i> \\u2208 <i>B</i>}<br>\\r\\n example: [0, 2) \\u222A (1, 3) = [0, 3); "
+ "[0, 1) \\u222A (2, 3] = well, [0, 1) \\u222A (2, 3]\\r\\n </li>\\r\\n <li>"
+ "\\r\\n <i>A</i> \\u2229 <i>B</i>: intersection of <i>A</i> and <i>B</i>, i.e. "
+ "{<i>x</i> | <i>x</i> \\u2208 <i>A</i> and <i>x</i> \\u2208 <i>B</i>}<br>\\r\\n "
+ "example: [0, 2) \\u2229 (1, 3) = (1, 2); [0, 1) \\u2229 (2, 3] = empty set\\r\\n "
+ "</li>\\r\\n <li>\\r\\n <i>A</i> - <i>B</i>: difference between <i>A</i> and "
+ "<i>B</i>, also written as <i>A</i> \\\\ <i>B</i>, i.e. {<i>x</i> | <i>x</i> \\u2208 "
+ "<i>A</i> and <i>x</i> \\u2209 <i>B</i>}<br>\\r\\n example: [0, 2) \\u2212 (1, "
+ "3) = [0, 1]\\r\\n </li>\\r\\n </ul>\\r\\n</ul>\\r\\n</section>\\r\\n\"\n";
+ good_one(s);
+ }
+
+ class comment_parser
+ {
+ struct handler
+ {
+ constexpr static std::size_t max_object_size = std::size_t(-1);
+ constexpr static std::size_t max_array_size = std::size_t(-1);
+ constexpr static std::size_t max_key_size = std::size_t(-1);
+ constexpr static std::size_t max_string_size = std::size_t(-1);
+
+ std::string captured = "";
+ bool on_document_begin( error_code& ) { return true; }
+ bool on_document_end( error_code& ) { return true; }
+ bool on_object_begin( error_code& ) { return true; }
+ bool on_object_end( std::size_t, error_code& ) { return true; }
+ bool on_array_begin( error_code& ) { return true; }
+ bool on_array_end( std::size_t, error_code& ) { return true; }
+ bool on_key_part( string_view, std::size_t, error_code& ) { return true; }
+ bool on_key( string_view, std::size_t, error_code& ) { return true; }
+ bool on_string_part( string_view, std::size_t, error_code& ) { return true; }
+ bool on_string( string_view, std::size_t, error_code& ) { return true; }
+ bool on_number_part( string_view, error_code&) { return true; }
+ bool on_int64( std::int64_t, string_view, error_code& ) { return true; }
+ bool on_uint64( std::uint64_t, string_view, error_code& ) { return true; }
+ bool on_double( double, string_view, error_code& ) { return true; }
+ bool on_bool( bool, error_code& ) { return true; }
+ bool on_null( error_code& ) { return true; }
+ bool on_comment_part( string_view s, error_code& )
+ {
+ captured.append(s.data(), s.size());
+ return true;
+ }
+ bool on_comment( string_view s, error_code& )
+ {
+ captured.append(s.data(), s.size());
+ return true;
+ }
+ };
+
+ basic_parser<handler> p_;
+
+ public:
+ comment_parser()
+ : p_(make_options(true, false, false))
+ {
+ }
+
+ std::size_t
+ write(
+ char const* data,
+ std::size_t size,
+ error_code& ec)
+ {
+ auto const n = p_.write_some(
+ false, data, size, ec);
+ if(! ec && n < size)
+ ec = error::extra_data;
+ return n;
+ }
+
+ string_view
+ captured() const noexcept
+ {
+ return p_.handler().captured;
+ }
+ };
+
+ void
+ testComments()
+ {
+ parse_options disabled;
+ parse_options enabled;
+ enabled.allow_comments = true;
+
+ const auto replace_and_test =
+ [&](string_view s)
+ {
+ static std::vector<string_view> comments =
+ {
+ "//\n",
+ "// \n",
+ "//aaaa\n",
+ "// aaaa\n",
+ "// /* \n",
+ "// /**/ \n",
+ "/**/",
+ "/*//*/",
+ "/*/*/",
+ "/******/",
+ "/*** ***/",
+ "/**aaaa***/",
+ "/*** aaaa***/"
+ };
+
+ std::string formatted = "";
+ std::string just_comments = "";
+ std::size_t guess = std::count(
+ s.begin(), s.end(), '@') * 12;
+ formatted.reserve(guess + s.size());
+ just_comments.reserve(guess);
+ std::size_t n = 0;
+ for (char c : s)
+ {
+ if (c == '@')
+ {
+ string_view com =
+ comments[((formatted.size() + n) % s.size()) % comments.size()];
+ formatted.append(com.data(), n = com.size());
+ just_comments.append(com.data(), com.size());
+ continue;
+ }
+ formatted += c;
+ }
+ bad(formatted, disabled);
+ good(formatted, enabled);
+
+ {
+ // test the handler
+ comment_parser p;
+ error_code ec;
+ p.write( formatted.data(), formatted.size(), ec );
+ BOOST_TEST(! ec);
+ BOOST_TEST(p.captured() == just_comments);
+ }
+ };
+
+ replace_and_test("@1");
+ replace_and_test("1@");
+ replace_and_test("@1@");
+ replace_and_test("[@1]");
+ replace_and_test("[1@]");
+ replace_and_test("[1,2@]");
+ replace_and_test("[1,@2]");
+ replace_and_test("[1@,2]");
+ replace_and_test("@[@1@,@2@]@");
+ replace_and_test("{@\"a\":1}");
+ replace_and_test("{\"a\"@:1}");
+ replace_and_test("{\"a\":1@}");
+ replace_and_test("{\"a\":1@,\"b\":2}");
+ replace_and_test("{\"a\":1,@\"b\":2}");
+ replace_and_test("@{@\"a\"@:@1@,@\"b\"@:@2@}");
+
+ // no following token
+ bad("1/", enabled);
+ // bad second token
+ bad("1/x", enabled);
+ // no comment close
+ bad("1/*", enabled);
+ bad("1/**", enabled);
+ bad("[1 //, 2]", enabled);
+
+ // just comment
+ bad("//\n", enabled);
+ bad("//", enabled);
+ bad("/**/", enabled);
+
+ // no newline at EOF
+ good("1//", enabled);
+ }
+
+ void
+ testAllowTrailing()
+ {
+ parse_options disabled;
+ parse_options enabled;
+ enabled.allow_trailing_commas = true;
+
+ bad("[1,]", disabled);
+ good("[1,]", enabled);
+
+ bad("[1,[],]", disabled);
+ good("[1,[],]", enabled);
+
+ bad("[1,{},]", disabled);
+ good("[1,{},]", enabled);
+
+ bad("[1,{\"a\":1,},]", disabled);
+ good("[1,{\"a\":1,},]", enabled);
+
+ bad("{\"a\":1,}", disabled);
+ good("{\"a\":1,}", enabled);
+
+ bad("{\"a\":[1,],}", disabled);
+ good("{\"a\":[1,],}", enabled);
+
+ bad("{\"a\":[],}", disabled);
+ good("{\"a\":[],}", enabled);
+
+ bad("{\"a\":[{}, [1,]],}", disabled);
+ good("{\"a\":[{}, [1,]],}", enabled);
+
+ bad("[[[[[[[],],],],],],]", disabled);
+ good("[[[[[[[],],],],],],]", enabled);
+
+ bad("{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{},},},},},},}", disabled);
+ good("{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{},},},},},},}", enabled);
+ }
+
+ class utf8_parser
+ {
+ struct handler
+ {
+ constexpr static std::size_t max_object_size = std::size_t(-1);
+ constexpr static std::size_t max_array_size = std::size_t(-1);
+ constexpr static std::size_t max_key_size = std::size_t(-1);
+ constexpr static std::size_t max_string_size = std::size_t(-1);
+
+ std::string captured = "";
+ bool on_document_begin( error_code& ) { return true; }
+ bool on_document_end( error_code& ) { return true; }
+ bool on_object_begin( error_code& ) { return true; }
+ bool on_object_end( std::size_t, error_code& ) { return true; }
+ bool on_array_begin( error_code& ) { return true; }
+ bool on_array_end( std::size_t, error_code& ) { return true; }
+ bool on_key_part( string_view, std::size_t, error_code& ) { return true; }
+ bool on_key( string_view, std::size_t, error_code& ) { return true; }
+ bool on_string_part( string_view sv, std::size_t, error_code& )
+ {
+ captured.append(sv.data(), sv.size());
+ return true;
+ }
+ bool on_string( string_view sv, std::size_t, error_code& )
+ {
+ captured.append(sv.data(), sv.size());
+ return true;
+ }
+ bool on_number_part( string_view, error_code&) { return true; }
+ bool on_int64( std::int64_t, string_view, error_code& ) { return true; }
+ bool on_uint64( std::uint64_t, string_view, error_code& ) { return true; }
+ bool on_double( double, string_view, error_code& ) { return true; }
+ bool on_bool( bool, error_code& ) { return true; }
+ bool on_null( error_code& ) { return true; }
+ bool on_comment_part( string_view, error_code& ) { return true; }
+ bool on_comment( string_view, error_code& ) { return true; }
+ };
+
+ basic_parser<handler> p_;
+
+ public:
+ utf8_parser()
+ : p_(parse_options())
+ {
+ }
+
+ std::size_t
+ write(
+ bool more,
+ char const* data,
+ std::size_t size,
+ error_code& ec)
+ {
+ auto const n = p_.write_some(
+ more, data, size, ec);
+ if(! ec && n < size)
+ ec = error::extra_data;
+ return n;
+ }
+
+ string_view
+ captured() const noexcept
+ {
+ return p_.handler().captured;
+ }
+ };
+
+ void
+ testUTF8Validation()
+ {
+ good("\"\xc2\x80----------\"");
+ good("\"\xc2\xbf----------\"");
+ good("\"\xdf\x80----------\"");
+ good("\"\xdf\xbf----------\"");
+
+ good("\"\xcf\x90----------\"");
+
+ good("\"\xe0\xa0\x80----------\"");
+ good("\"\xe0\xa0\xbf----------\"");
+ good("\"\xe0\xbf\x80----------\"");
+ good("\"\xe0\xbf\xbf----------\"");
+
+ good("\"\xe0\xb0\x90----------\"");
+
+ good("\"\xe1\x80\x80----------\"");
+ good("\"\xe1\xbf\x80----------\"");
+ good("\"\xec\x80\x80----------\"");
+ good("\"\xec\xbf\x80----------\"");
+ good("\"\xe1\x80\xbf----------\"");
+ good("\"\xe1\xbf\xbf----------\"");
+ good("\"\xec\x80\xbf----------\"");
+ good("\"\xec\xbf\xbf----------\"");
+
+ good("\"\xe6\x90\x90----------\"");
+
+ good("\"\xed\x80\x80----------\"");
+ good("\"\xed\x80\xbf----------\"");
+ good("\"\xed\x9f\x80----------\"");
+ good("\"\xed\x9f\xbf----------\"");
+
+ good("\"\xed\x90\x90----------\"");
+
+ good("\"\xee\x80\x80----------\"");
+ good("\"\xee\xbf\x80----------\"");
+ good("\"\xef\x80\x80----------\"");
+ good("\"\xef\xbf\x80----------\"");
+ good("\"\xee\x80\xbf----------\"");
+ good("\"\xee\xbf\xbf----------\"");
+ good("\"\xef\x80\xbf----------\"");
+ good("\"\xef\xbf\xbf----------\"");
+
+ good("\"\xee\x90\x90----------\"");
+ good("\"\xef\x90\x90----------\"");
+
+ good("\"\xf0\x90\x80\x80----------\"");
+ good("\"\xf0\x90\xbf\x80----------\"");
+ good("\"\xf0\x90\xbf\xbf----------\"");
+ good("\"\xf0\x90\x80\xbf----------\"");
+ good("\"\xf0\xbf\x80\x80----------\"");
+ good("\"\xf0\xbf\xbf\x80----------\"");
+ good("\"\xf0\xbf\xbf\xbf----------\"");
+ good("\"\xf0\xbf\x80\xbf----------\"");
+
+ good("\"\xf0\xA0\x90\x90----------\"");
+
+ good("\"\xf4\x80\x80\x80----------\"");
+ good("\"\xf4\x80\xbf\x80----------\"");
+ good("\"\xf4\x80\xbf\xbf----------\"");
+ good("\"\xf4\x80\x80\xbf----------\"");
+ good("\"\xf4\x8f\x80\x80----------\"");
+ good("\"\xf4\x8f\xbf\x80----------\"");
+ good("\"\xf4\x8f\xbf\xbf----------\"");
+ good("\"\xf4\x8f\x80\xbf----------\"");
+
+ good("\"\xf4\x88\x90\x90----------\"");
+
+ good("\"\xf1\x80\x80\x80----------\"");
+ good("\"\xf1\x80\xbf\x80----------\"");
+ good("\"\xf1\x80\xbf\xbf----------\"");
+ good("\"\xf1\x80\x80\xbf----------\"");
+ good("\"\xf1\xbf\x80\x80----------\"");
+ good("\"\xf1\xbf\xbf\x80----------\"");
+ good("\"\xf1\xbf\xbf\xbf----------\"");
+ good("\"\xf1\xbf\x80\xbf----------\"");
+ good("\"\xf3\x80\x80\x80----------\"");
+ good("\"\xf3\x80\xbf\x80----------\"");
+ good("\"\xf3\x80\xbf\xbf----------\"");
+ good("\"\xf3\x80\x80\xbf----------\"");
+ good("\"\xf3\xbf\x80\x80----------\"");
+ good("\"\xf3\xbf\xbf\x80----------\"");
+ good("\"\xf3\xbf\xbf\xbf----------\"");
+ good("\"\xf3\xbf\x80\xbf----------\"");
+
+ good("\"\xf2\x90\x90\x90----------\"");
+
+ bad("\"\xc0\x80----------\"");
+ bad("\"\xc2\xc0----------\"");
+ bad("\"\xef\x80----------\"");
+ bad("\"\xdf\x70----------\"");
+
+ bad("\"\xff\x90----------\"");
+
+ bad("\"\xe0\x9f\x80----------\"");
+ bad("\"\xe0\xa0\xfe----------\"");
+ bad("\"\xc0\xff\xff----------\"");
+ bad("\"\xc0\xbf\x76----------\"");
+
+ bad("\"\xe0\xde\x90----------\"");
+
+ bad("\"\xe1\x80\x7f----------\"");
+ bad("\"\xe1\x7f\x80----------\"");
+ bad("\"\xec\xff\x80----------\"");
+ bad("\"\xef\x7f\x80----------\"");
+ bad("\"\xe1\x80\xff----------\"");
+ bad("\"\xe1\xbf\x0f----------\"");
+ bad("\"\xec\x01\xff----------\"");
+ bad("\"\xec\xff\xff----------\"");
+
+ bad("\"\xe6\x60\x90----------\"");
+
+ bad("\"\xed\x7f\x80----------\"");
+ bad("\"\xed\xa0\xbf----------\"");
+ bad("\"\xed\xbf\x80----------\"");
+ bad("\"\xed\x9f\x7f----------\"");
+
+ bad("\"\xed\xce\xbf----------\"");
+
+ bad("\"\xee\x7f\x80----------\"");
+ bad("\"\xee\xcc\x80----------\"");
+ bad("\"\xef\x80\xcc----------\"");
+ bad("\"\xef\xbf\x0a----------\"");
+ bad("\"\xee\x50\xbf----------\"");
+ bad("\"\xee\xef\xbf----------\"");
+ bad("\"\xef\xf0\xff----------\"");
+ bad("\"\xef\xaa\xee----------\"");
+
+ bad("\"\xc0\x90\x90----------\"");
+ bad("\"\xc1\x90\x90----------\"");
+
+ bad("\"\xff\x90\x80\x80----------\"");
+ bad("\"\xfe\x90\xbf\x80----------\"");
+ bad("\"\xfd\x90\xbf\xbf----------\"");
+ bad("\"\xf0\xff\x80\xbf----------\"");
+ bad("\"\xf0\xfe\x80\x80----------\"");
+ bad("\"\xf0\xfd\xbf\x80----------\"");
+ bad("\"\xf0\x90\x80\xff----------\"");
+ bad("\"\xf0\x90\x5f\x80----------\"");
+
+ bad("\"\xf4\x70\x80\x80----------\"");
+ bad("\"\xf4\x80\x70\x80----------\"");
+ bad("\"\xf4\x80\xbf\x70----------\"");
+ bad("\"\xf4\xce\x80\xbf----------\"");
+ bad("\"\xf4\x8f\xce\x80----------\"");
+ bad("\"\xf4\x8f\xbf\xce----------\"");
+
+ bad("\"\xf1\x7f\xbf\xbf----------\"");
+ bad("\"\xf2\x80\x7f\xbf----------\"");
+ bad("\"\xf3\x80\xbf\xce----------\"");
+
+ // utf8 after escape
+ good("\"\\u0000 \xf3\xbf\x80\xbf\xf3\xbf\x80\xbf\"");
+ good("\"\\ud7ff\xf4\x80\xbf\xbf \"");
+ good("\"\\ue000 \xef\xbf\x80\"");
+ good("\"\xef\xbf\x80 \\uffff \xef\xbf\x80\"");
+ good("\"\xc2\x80\xc2\x80\xc2\x80\xc2\x80\xc2\x80\\ud800\\udc00 \"");
+ good("\"\\udbff\\udfff \xe1\x80\xbf \\udbff\\udfff \xe1\x80\xbf\"");
+ good("\"\\u0000\xe1\x80\xbf \"");
+ bad("\"\\t\\t\xf4\x70\x80\x80----------\"");
+ bad("\"\\n\xf4\x80\x70\x80----------\"");
+ bad("\"\\n\xf4\x80\xbf\x70-\\n\xf4\x80\xbf\x70\"");
+
+ const auto check =
+ [this](string_view expected)
+ {
+ good(expected);
+ for (std::size_t write_size : {2, 4, 8})
+ {
+ utf8_parser p;
+ for(std::size_t i = 0; i < expected.size(); i += write_size)
+ {
+ error_code ec;
+ write_size = (std::min)(write_size, expected.size() - i);
+ auto more = (i < expected.size() - write_size);
+ auto written = p.write(more,
+ expected.data() + i, write_size, ec);
+ BOOST_TEST(written == write_size);
+ BOOST_TEST(! ec);
+ }
+ BOOST_TEST(p.captured() ==
+ expected.substr(1, expected.size() - 2));
+ }
+ };
+
+ check("\"\xd1\x82\"");
+ check("\"\xd1\x82\xd0\xb5\xd1\x81\xd1\x82\"");
+ check("\"\xc3\x0b1""and\xc3\xba\"");
+ }
+
+ void
+ testMaxDepth()
+ {
+ {
+ string_view s = "[[[[[]]]]]";
+ parse_options opt;
+ opt.max_depth = 4;
+ null_parser p(opt);
+ error_code ec;
+ p.write(s.data(), s.size(), ec);
+ BOOST_TEST(ec == error::too_deep);
+ BOOST_TEST(ec.has_location());
+ }
+ {
+ string_view s = "[[[[]]], [[[[]]]]]";
+ parse_options opt;
+ opt.max_depth = 4;
+ null_parser p(opt);
+ error_code ec;
+ p.write(s.data(), s.size(), ec);
+ BOOST_TEST(ec == error::too_deep);
+ BOOST_TEST(ec.has_location());
+ }
+ {
+ string_view s =
+ "{\"a\":{\"b\":{\"c\":{}}},\"b\":{\"c\":{\"d\":{\"e\":{}}}}}";
+ parse_options opt;
+ opt.max_depth = 4;
+ null_parser p(opt);
+ error_code ec;
+ p.write(s.data(), s.size(), ec);
+ BOOST_TEST(ec == error::too_deep);
+ BOOST_TEST(ec.has_location());
+ }
+ {
+ string_view s =
+ "{\"a\":{\"b\":{\"c\":{\"d\":{}}}}}";
+ parse_options opt;
+ opt.max_depth = 4;
+ null_parser p(opt);
+ error_code ec;
+ p.write(s.data(), s.size(), ec);
+ BOOST_TEST(ec == error::too_deep);
+ BOOST_TEST(ec.has_location());
+ }
+ }
+
+ class literal_parser
+ {
+ struct handler
+ {
+ constexpr static std::size_t max_object_size = std::size_t(-1);
+ constexpr static std::size_t max_array_size = std::size_t(-1);
+ constexpr static std::size_t max_key_size = std::size_t(-1);
+ constexpr static std::size_t max_string_size = std::size_t(-1);
+
+ std::string captured = "";
+ bool on_document_begin( error_code& ) { return true; }
+ bool on_document_end( error_code& ) { return true; }
+ bool on_object_begin( error_code& ) { return true; }
+ bool on_object_end( std::size_t, error_code& ) { return true; }
+ bool on_array_begin( error_code& ) { return true; }
+ bool on_array_end( std::size_t, error_code& ) { return true; }
+ bool on_key_part( string_view, std::size_t, error_code& ) { return true; }
+ bool on_key( string_view, std::size_t, error_code& ) { return true; }
+ bool on_string_part( string_view, std::size_t, error_code& ) { return true; }
+ bool on_string( string_view, std::size_t, error_code& ) { return true; }
+ bool on_number_part( string_view sv, error_code&)
+ {
+ captured.append(sv.data(), sv.size());
+ return true;
+ }
+ bool on_int64( std::int64_t, string_view sv, error_code& )
+ {
+ captured.append(sv.data(), sv.size());
+ captured += 's';
+ return true;
+ }
+ bool on_uint64( std::uint64_t, string_view sv, error_code& )
+ {
+ captured.append(sv.data(), sv.size());
+ captured += 'u';
+ return true;
+ }
+ bool on_double( double, string_view sv, error_code& )
+ {
+ captured.append(sv.data(), sv.size());
+ captured += 'd';
+ return true;
+ }
+ bool on_bool( bool, error_code& ) { return true; }
+ bool on_null( error_code& ) { return true; }
+ bool on_comment_part( string_view, error_code& ) { return true; }
+ bool on_comment( string_view, error_code& ) { return true; }
+ };
+
+ basic_parser<handler> p_;
+
+ public:
+ literal_parser()
+ : p_(make_options(true, false, false))
+ {
+ }
+
+ std::size_t
+ write(
+ bool more,
+ char const* data,
+ std::size_t size,
+ error_code& ec)
+ {
+ auto const n = p_.write_some(
+ more, data, size, ec);
+ if(! ec && n < size)
+ ec = error::extra_data;
+ return n;
+ }
+
+ string_view
+ captured()
+ {
+ return p_.handler().captured;
+ }
+ };
+
+ void
+ testNumberLiteral()
+ {
+ const auto check =
+ [](string_view expected)
+ {
+ string_view sv = expected;
+ sv.remove_suffix(1);
+ for(std::size_t i = 0;
+ i < sv.size(); ++i)
+ {
+ literal_parser p;
+ error_code ec;
+ if(i != 0)
+ {
+ p.write(true,
+ sv.data(), i, ec);
+ }
+ if(BOOST_TEST(! ec))
+ {
+ p.write(false,
+ sv.data() + i,
+ sv.size() - i, ec);
+ }
+ BOOST_TEST(! ec);
+ BOOST_TEST(p.captured() == expected);
+ }
+ };
+
+ check("1s");
+ check("-1s");
+ check("0s");
+ check("0s");
+ check("123456s");
+ check("-123456s");
+ check("9223372036854775808u");
+
+ check("1.0d");
+ check("-1.0d");
+ check("0.0d");
+ check("1.0e3d");
+ check("1e1d");
+ check("1e+1d");
+ check("1e-1d");
+ check("-100000000000000000000000d");
+ check("100000000000000000000000d");
+ check("10000000000.10000000000000d");
+ check("-10000000000.10000000000000d");
+ check("1000000000000000.0e1000000d");
+ }
+
+ void
+ testStickyErrors()
+ {
+ {
+ null_parser p;
+ error_code ec;
+ p.write("*", 1, ec);
+ BOOST_TEST(ec);
+ error_code ec2;
+ p.write("[]", 2, ec2);
+ BOOST_TEST(ec2 == ec);
+ p.reset();
+ p.write("[]", 2, ec2);
+ BOOST_TEST(! ec2);
+ }
+
+ // exceptions do not cause UB
+ {
+ throw_parser p(1);
+ try
+ {
+ error_code ec;
+ p.write(false, "null", 4, ec);
+ BOOST_TEST_FAIL();
+ }
+ catch(std::exception const&)
+ {
+ error_code ec;
+ p.write(false, "null", 4, ec);
+ BOOST_TEST(ec == error::exception);
+ BOOST_TEST(ec.has_location());
+ }
+ }
+ }
+
+#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
+ using SV = std::string_view;
+#else
+ using SV = string_view;
+#endif
+ // The null parser, but uses std type equivalents
+ class std_null_parser
+ {
+ struct handler
+ {
+ constexpr static std::size_t max_object_size = std::size_t(-1);
+ constexpr static std::size_t max_array_size = std::size_t(-1);
+ constexpr static std::size_t max_key_size = std::size_t(-1);
+ constexpr static std::size_t max_string_size = std::size_t(-1);
+
+ bool on_document_begin( std::error_code& ) { return true; }
+ bool on_document_end( std::error_code& ) { return true; }
+ bool on_object_begin( std::error_code& ) { return true; }
+ bool on_object_end( std::size_t, std::error_code& ) { return true; }
+ bool on_array_begin( std::error_code& ) { return true; }
+ bool on_array_end( std::size_t, std::error_code& ) { return true; }
+ bool on_key_part( SV, std::size_t, std::error_code& ) { return true; }
+ bool on_key( SV, std::size_t, std::error_code& ) { return true; }
+ bool on_string_part( SV, std::size_t, std::error_code& ) { return true; }
+ bool on_string( SV, std::size_t, std::error_code& ) { return true; }
+ bool on_number_part( SV, std::error_code&) { return true; }
+ bool on_int64( std::int64_t, SV, std::error_code& ) { return true; }
+ bool on_uint64( std::uint64_t, SV, std::error_code& ) { return true; }
+ bool on_double( double, SV, std::error_code& ) { return true; }
+ bool on_bool( bool, std::error_code& ) { return true; }
+ bool on_null( std::error_code& ) { return true; }
+ bool on_comment_part( SV, std::error_code& ) { return true; }
+ bool on_comment( SV, std::error_code& ) { return true; }
+ };
+
+ basic_parser<handler> p_;
+
+ public:
+ std_null_parser()
+ : p_(parse_options())
+ {
+ }
+
+ explicit
+ std_null_parser(parse_options po)
+ : p_(po)
+ {
+ }
+
+ void
+ reset()
+ {
+ p_.reset();
+ }
+
+ std::size_t
+ write(
+ SV s,
+ std::error_code& ec)
+ {
+ auto const n = p_.write_some(
+ false, s.data(), s.size(), ec);
+ if(! ec && n < s.size())
+ ec = error::extra_data;
+ return n;
+ }
+ };
+
+ void testStdTypes()
+ {
+ std_null_parser p;
+ std::error_code ec;
+ std::string const doc = "{}";
+ p.write(doc, ec);
+ if(! BOOST_TEST(! ec))
+ {
+ log << " failed to parse: " << doc << '\n';
+ return;
+ }
+ }
+
+ void
+ run()
+ {
+ testNull();
+ testBoolean();
+ testString();
+ testNumber();
+ testArray();
+ testObject();
+ testParser();
+ testMembers();
+ testParseVectors();
+ testIssue13();
+ testIssue20();
+ testIssue113();
+ testAllowTrailing();
+ testComments();
+ testUTF8Validation();
+ testMaxDepth();
+ testNumberLiteral();
+ testStickyErrors();
+ testStdTypes();
+ }
+};
+
+TEST_SUITE(basic_parser_test, "boost.json.basic_parser");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/checking_resource.hpp b/src/boost/libs/json/test/checking_resource.hpp
new file mode 100644
index 000000000..077f8ba7f
--- /dev/null
+++ b/src/boost/libs/json/test/checking_resource.hpp
@@ -0,0 +1,63 @@
+//
+// Copyright (c) 2021 Dmitry Arkhipov (grisumbras@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#ifndef BOOST_JSON_CHECKING_RESOURCE_HPP
+#define BOOST_JSON_CHECKING_RESOURCE_HPP
+
+#include <boost/json/storage_ptr.hpp>
+#include <map>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+class checking_resource
+ : public memory_resource
+{
+ storage_ptr upstream_;
+ std::map<void const*, std::pair<std::size_t, std::size_t>> allocs_;
+
+public:
+ explicit checking_resource(storage_ptr upstream = {}) noexcept
+ : upstream_(std::move(upstream))
+ {}
+
+private:
+ void* do_allocate(std::size_t size, std::size_t alignment) override
+ {
+ void* result = upstream_->allocate(size, alignment);
+ allocs_.emplace(result, std::make_pair(size, alignment));
+ return result;
+ }
+
+ void do_deallocate(void* ptr, std::size_t size, std::size_t alignment)
+ override
+ {
+ auto const it = allocs_.find(ptr);
+ if( BOOST_TEST(it != allocs_.end()) )
+ {
+ BOOST_TEST(size == it->second.first);
+ BOOST_TEST(alignment == it->second.second);
+
+ allocs_.erase(it);
+ }
+
+ return upstream_->deallocate(ptr, size, alignment);
+ }
+
+ bool do_is_equal(memory_resource const& other) const noexcept
+ override
+ {
+ return this == &other;
+ }
+};
+
+BOOST_JSON_NS_END
+
+#endif // BOOST_JSON_CHECKING_RESOURCE_HPP
diff --git a/src/boost/libs/json/test/cmake_install_test/CMakeLists.txt b/src/boost/libs/json/test/cmake_install_test/CMakeLists.txt
new file mode 100644
index 000000000..fb7ef02c6
--- /dev/null
+++ b/src/boost/libs/json/test/cmake_install_test/CMakeLists.txt
@@ -0,0 +1,18 @@
+# Copyright 2018 Peter Dimov
+# Copyright 2018 Richard Hodges
+# Distributed under the Boost Software License, Version 1.0.
+# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
+
+cmake_minimum_required(VERSION 3.5...3.16)
+
+project(cmake_install_test LANGUAGES CXX)
+
+find_package(boost_json REQUIRED)
+
+add_executable(main main.cpp)
+target_link_libraries(main Boost::json)
+
+enable_testing()
+add_test(NAME main COMMAND main)
+
+add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>) \ No newline at end of file
diff --git a/src/boost/libs/json/test/cmake_install_test/main.cpp b/src/boost/libs/json/test/cmake_install_test/main.cpp
new file mode 100644
index 000000000..29f40f64c
--- /dev/null
+++ b/src/boost/libs/json/test/cmake_install_test/main.cpp
@@ -0,0 +1,13 @@
+// Copyright 2018 Peter Dimov
+// Copyright 2020 Richard Hodges
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/json.hpp>
+#include <cstdio>
+
+int main()
+{
+ const boost::json::value value = boost::json::parse("{ \"test\": true }");
+ std::puts(boost::json::to_string(value).c_str());
+}
diff --git a/src/boost/libs/json/test/doc_background.cpp b/src/boost/libs/json/test/doc_background.cpp
new file mode 100644
index 000000000..45313dbe8
--- /dev/null
+++ b/src/boost/libs/json/test/doc_background.cpp
@@ -0,0 +1,205 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#include <boost/json/monotonic_resource.hpp>
+#include <boost/json/static_resource.hpp>
+#include <boost/json/value.hpp>
+#include <boost/container/pmr/vector.hpp>
+#include <vector>
+
+#include "test_suite.hpp"
+
+#ifdef assert
+#undef assert
+#endif
+#define assert BOOST_TEST
+
+BOOST_JSON_NS_BEGIN
+
+namespace doc_background {
+
+namespace background {
+template<class T>
+using vector = boost::container::pmr::vector<T>;
+} // background
+
+//----------------------------------------------------------
+
+namespace std {
+template<class T>
+using allocator = ::std::allocator<T>;
+} // std
+
+//[doc_background_1
+namespace std {
+
+template< class T, class Allocator = std::allocator< T > >
+class vector;
+
+} // namespace std
+//]
+
+//----------------------------------------------------------
+
+//[doc_background_2
+namespace std {
+
+template< class T, class Allocator >
+class vector
+{
+public:
+ explicit vector( Allocator const& alloc );
+
+ //...
+//]
+};
+
+template<class T, class A>
+vector<T,A>::vector(A const&){}
+}
+
+//----------------------------------------------------------
+
+//[doc_background_3
+namespace std {
+namespace pmr {
+
+class memory_resource
+{
+public:
+ virtual ~memory_resource();
+
+ void* allocate ( size_t bytes, size_t alignment );
+ void deallocate( void* p, size_t bytes, size_t alignment );
+ bool is_equal ( const memory_resource& other ) const;
+
+protected:
+ virtual void* do_allocate ( size_t bytes, size_t alignment ) = 0;
+ virtual void do_deallocate( void* p, size_t bytes, size_t alignment ) = 0;
+ virtual bool do_is_equal ( memory_resource const& other ) const noexcept = 0;
+};
+
+} // namespace pmr
+} // namespace std
+//]
+
+//----------------------------------------------------------
+
+//[doc_background_4
+
+namespace std {
+namespace pmr {
+
+template< class T >
+using vector = std::vector< T, polymorphic_allocator< T > >;
+
+} // namespace pmr
+} // namespace std
+
+//]
+
+//----------------------------------------------------------
+
+static void set1() {
+using namespace background;
+
+//----------------------------------------------------------
+{
+struct T {};
+//[doc_background_5
+// A type of memory resource
+monotonic_resource mr;
+
+// Construct a vector using the monotonic buffer resource
+vector< T > v1(( polymorphic_allocator< T >(&mr) ));
+
+// Or this way, since construction from memory_resource* is implicit:
+vector< T > v2( &mr );
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_background_6
+{
+ // A type of memory resource which uses a stack buffer
+ unsigned char temp[4096];
+ static_resource mr( temp, sizeof(temp) );
+
+ // Construct a vector using the static buffer resource
+ vector< value > v( &mr );
+
+ // The vector will allocate from `temp` first, and then the heap.
+}
+//]
+}
+//----------------------------------------------------------
+
+} // set1
+
+//----------------------------------------------------------
+
+struct my_resource : memory_resource
+{
+ void* do_allocate ( size_t, size_t ) override { return 0; }
+ void do_deallocate( void*, size_t, size_t ) override {}
+ bool do_is_equal ( memory_resource const& ) const noexcept override { return true; }
+};
+//[doc_background_7
+namespace my_library {
+
+std::pmr::vector<char> get_chars1()
+{
+ // This leaks memory because `v` does not own the memory resource
+ std::pmr::vector<char> v( new my_resource );
+
+ return v;
+}
+
+} // my_library
+//]
+
+//----------------------------------------------------------
+
+//[doc_background_8
+namespace my_library {
+
+std::pmr::vector<char> get_chars2()
+{
+ // Declare a local memory resource
+ my_resource mr;
+
+ // Construct a vector that uses our resource
+ std::pmr::vector<char> v( &mr );
+
+ // Undefined behavior, `mr` goes out of scope!
+ return v;
+}
+
+} // my_library
+//]
+
+//----------------------------------------------------------
+
+} // doc_background
+
+class doc_background_test
+{
+public:
+ void
+ run()
+ {
+ using namespace doc_background;
+ (void)&set1;
+ BOOST_TEST_PASS();
+ }
+};
+
+TEST_SUITE(doc_background_test, "boost.json.doc_background");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/doc_forward_conversion.cpp b/src/boost/libs/json/test/doc_forward_conversion.cpp
new file mode 100644
index 000000000..4017d7011
--- /dev/null
+++ b/src/boost/libs/json/test/doc_forward_conversion.cpp
@@ -0,0 +1,101 @@
+//
+// Copyright (c) 2021 Dmitry Arkhipov (grisumbras@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+//[doc_forward_conversion_1
+namespace boost {
+namespace json {
+
+class value;
+
+struct value_from_tag;
+
+template< class T >
+struct value_to_tag;
+
+template< class T >
+T value_to( const value& v );
+
+template<class T>
+void value_from( T&& t, value& jv );
+
+}
+}
+//]
+
+#include <string>
+
+namespace thirdparty {
+
+struct customer
+{
+ std::uint64_t id;
+ std::string name;
+ bool late;
+
+ customer() = default;
+
+ customer( std::uint64_t i, const std::string& n, bool l )
+ : id( i ), name( n ), late( l ) { }
+};
+
+} // namespace thirdparty
+
+//[doc_forward_conversion_2
+namespace thirdparty {
+
+template< class JsonValue >
+customer tag_invoke( const boost::json::value_to_tag<customer>&, const JsonValue& jv )
+{
+ std::uint64_t id = boost::json::value_to<std::uint64_t>( jv.at( "id" ) );
+ std::string name = boost::json::value_to< std::string >( jv.at( "name" ) );
+ bool late = boost::json::value_to<bool>( jv.at( "late" ) );
+ return customer(id, std::move(name), late);
+}
+
+template< class JsonValue >
+void tag_invoke( const boost::json::value_from_tag&, JsonValue& jv, const customer& c)
+{
+ auto& obj = jv.emplace_object();
+ boost::json::value_from(c.id, obj["id"]);
+ boost::json::value_from(c.name, obj["name"]);
+ boost::json::value_from(c.late, obj["late"]);
+}
+
+}
+//]
+
+
+#include <boost/json/value_from.hpp>
+#include <boost/json/value_to.hpp>
+
+#include "test_suite.hpp"
+
+
+BOOST_JSON_NS_BEGIN
+
+class doc_forward_conversion
+{
+public:
+ void
+ run()
+ {
+ value const jv{ { "id", 1 }, { "name", "Carl" }, { "late", true } };
+ auto const c = value_to<thirdparty::customer>( jv );
+ BOOST_TEST( c.id == 1 );
+ BOOST_TEST( c.name == "Carl" );
+ BOOST_TEST( c.late );
+
+ value const jv2 = value_from( c );
+ BOOST_TEST( jv == jv2 );
+ }
+};
+
+TEST_SUITE(doc_forward_conversion, "boost.json.doc_forward_conversion");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/doc_parsing.cpp b/src/boost/libs/json/test/doc_parsing.cpp
new file mode 100644
index 000000000..de064d3c1
--- /dev/null
+++ b/src/boost/libs/json/test/doc_parsing.cpp
@@ -0,0 +1,254 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#include <boost/json/monotonic_resource.hpp>
+#include <boost/json/null_resource.hpp>
+#include <boost/json/parse.hpp>
+#include <boost/json/parser.hpp>
+#include <boost/json/static_resource.hpp>
+#include <boost/json/stream_parser.hpp>
+
+#include <iostream>
+#include <string>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+//----------------------------------------------------------
+
+static void set1() {
+
+//----------------------------------------------------------
+{
+//[doc_parsing_1
+value jv = parse( "[1,2,3,4,5]" );
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_parsing_2
+error_code ec;
+value jv = parse( "[1,2,3,4,5]", ec );
+if( ec )
+ std::cout << "Parsing failed: " << ec.message() << "\n";
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_parsing_3
+try
+{
+ error_code ec;
+ value jv = parse( "[1,2,3,4,5]", ec );
+ if( ec )
+ std::cout << "Parsing failed: " << ec.message() << "\n";
+}
+catch( std::bad_alloc const& e)
+{
+ std::cout << "Parsing failed: " << e.what() << "\n";
+}
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_parsing_4
+{
+ monotonic_resource mr;
+
+ value const jv = parse( "[1,2,3,4,5]", &mr );
+}
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_parsing_5
+parse_options opt; // all extensions default to off
+opt.allow_comments = true; // permit C and C++ style comments to appear in whitespace
+opt.allow_trailing_commas = true; // allow an additional trailing comma in object and array element lists
+opt.allow_invalid_utf8 = true; // skip utf-8 validation of keys and strings
+
+value jv = parse( "[1,2,3,] // comment ", storage_ptr(), opt );
+//]
+}
+//----------------------------------------------------------
+{
+#if __cpp_designated_initializers >= 201707L
+//[doc_parsing_6
+value jv = parse( "[1,2,3,] // comment ", storage_ptr(),
+ {
+ .allow_comments = true, // permit C and C++ style comments to appear in whitespace
+ .allow_trailing_commas = true, // allow a trailing comma in object and array lists
+ .allow_invalid_utf8 = true // skip utf-8 validation of keys and strings
+ });
+//]
+#endif
+}
+//----------------------------------------------------------
+
+} // set1
+
+//----------------------------------------------------------
+//[doc_parsing_7
+class connection
+{
+ parser p_; // persistent data member
+
+public:
+ void do_read( string_view s ) // called for each complete message from the network
+ {
+ p_.reset(); // start parsing a new JSON using the default resource
+ p_.write( s ); // parse the buffer, using exceptions to indicate error
+ do_rpc( p_.release() ); // process the command
+ }
+
+ void do_rpc( value jv );
+};
+//]
+
+//----------------------------------------------------------
+
+static void set2() {
+
+//----------------------------------------------------------
+{
+//[doc_parsing_8
+stream_parser p;
+error_code ec;
+string_view s = "[1,2,3] %HOME%";
+std::size_t n = p.write_some( s, ec );
+assert( ! ec && p.done() && n == 8 );
+s = s.substr( n );
+value jv = p.release();
+assert( s == "%HOME%" );
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_parsing_9
+parse_options opt; // All extensions default to off
+opt.allow_comments = true; // Permit C and C++ style comments to appear in whitespace
+opt.allow_trailing_commas = true; // Allow an additional trailing comma in object and array element lists
+opt.allow_invalid_utf8 = true; // Skip utf-8 validation of keys and strings
+stream_parser p( storage_ptr(), opt ); // The stream_parser will use the options
+//]
+}
+//----------------------------------------------------------
+
+} // set2
+
+//----------------------------------------------------------
+//[doc_parsing_10
+value read_json( std::istream& is, error_code& ec )
+{
+ stream_parser p;
+ std::string line;
+ while( std::getline( is, line ) )
+ {
+ p.write( line, ec );
+ if( ec )
+ return nullptr;
+ }
+ p.finish( ec );
+ if( ec )
+ return nullptr;
+ return p.release();
+}
+//]
+
+//----------------------------------------------------------
+
+static void set3() {
+
+//----------------------------------------------------------
+{
+//[doc_parsing_11
+{
+ monotonic_resource mr;
+
+ stream_parser p;
+ p.reset( &mr ); // Use mr for the resulting value
+ p.write( "[1,2,3,4,5]" ); // Parse the input JSON
+ value const jv = p.release(); // Retrieve the result
+ assert( *jv.storage() == mr ); // Same memory resource
+}
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_parsing_12
+unsigned char temp[ 4096 ]; // Declare our buffer
+stream_parser p(
+ storage_ptr(), // Default memory resource
+ parse_options{}, // Default parse options (strict parsing)
+ temp); // Use our buffer for temporary storage
+//]
+}
+//----------------------------------------------------------
+
+} // set3
+
+//----------------------------------------------------------
+
+//[doc_parsing_13
+/* Parse JSON and invoke the handler
+
+ This function parses the JSON specified in `s`
+ and invokes the handler, whose signature must
+ be equivalent to:
+
+ void( value const& jv );
+
+ The operation is guaranteed not to perform any
+ dynamic memory allocations. However, some
+ implementation-defined upper limits on the size
+ of the input JSON and the size of the resulting
+ value are imposed.
+
+ Upon error, an exception is thrown.
+*/
+template< class Handler >
+void do_rpc( string_view s, Handler&& handler )
+{
+ unsigned char temp[ 4096 ]; // The parser will use this storage for its temporary needs
+ parser p( // Construct a strict parser using the temp buffer and no dynamic memory
+ get_null_resource(), // The null resource never dynamically allocates memory
+ parse_options(), // Default constructed parse options allow only standard JSON
+ temp );
+
+ unsigned char buf[ 16384 ]; // Now we need a buffer to hold the actual JSON values
+ static_resource mr2( buf ); // The static resource is monotonic, using only a caller-provided buffer
+ p.reset( &mr2 ); // Use the static resource for producing the value
+ p.write( s ); // Parse the entire string we received from the network client
+
+ // Retrieve the value and invoke the handler with it.
+ // The value will use `buf` for storage. The handler
+ // must not take ownership, since monotonic resources
+ // are inefficient with mutation.
+ handler( p.release() );
+}
+//]
+
+//----------------------------------------------------------
+
+class doc_parsing_test
+{
+public:
+ void
+ run()
+ {
+ (void)&set1;
+ (void)&set2;
+ (void)&set3;
+ }
+};
+
+TEST_SUITE(doc_parsing_test, "boost.json.doc_parsing");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/doc_quick_look.cpp b/src/boost/libs/json/test/doc_quick_look.cpp
new file mode 100644
index 000000000..64318c5e7
--- /dev/null
+++ b/src/boost/libs/json/test/doc_quick_look.cpp
@@ -0,0 +1,333 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#include <boost/json.hpp>
+#include <boost/container/pmr/vector.hpp>
+#include <iostream>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+static void set1() {
+
+//----------------------------------------------------------
+{
+//[doc_quick_look_1
+object obj; // construct an empty object
+obj[ "pi" ] = 3.141; // insert a double
+obj[ "happy" ] = true; // insert a bool
+obj[ "name" ] = "Boost"; // insert a string
+obj[ "nothing" ] = nullptr; // insert a null
+obj[ "answer" ].emplace_object()["everything"] = 42; // insert an object with 1 element
+obj[ "list" ] = { 1, 0, 2 }; // insert an array with 3 elements
+obj[ "object" ] = { {"currency", "USD"}, {"value", 42.99} }; // insert an object with 2 elements
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_quick_look_2
+value jv = {
+ { "pi", 3.141 },
+ { "happy", true },
+ { "name", "Boost" },
+ { "nothing", nullptr },
+ { "answer", {
+ { "everything", 42 } } },
+ {"list", {1, 0, 2}},
+ {"object", {
+ { "currency", "USD" },
+ { "value", 42.99 }
+ } }
+ };
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_quick_look_3
+array arr; // construct an empty array
+arr = { 1, 2, 3 }; // replace the contents with 3 elements
+value jv1( arr ); // this makes a copy of the array
+value jv2( std::move(arr) ); // this performs a move-construction
+
+assert( arr.empty() ); // moved-from arrays become empty
+arr = { nullptr, true, "boost" }; // fill in the array again
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_quick_look_4
+{
+ unsigned char buf[ 4096 ]; // storage for our array
+ static_resource mr( buf ); // memory resource which uses buf
+ array arr( &mr ); // construct using the memory resource
+ arr = { 1, 2, 3 }; // all allocated memory comes from `buf`
+}
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_quick_look_5
+{
+ monotonic_resource mr; // memory resource optimized for insertion
+ array arr( &mr ); // construct using the memory resource
+ arr.resize( 1 ); // make space for one element
+ arr[ 0 ] = { 1, 2, 3 }; // assign an array to element 0
+ assert( *arr[0].storage() == *arr.storage() ); // same memory resource
+}
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_quick_look_6
+{
+ monotonic_resource mr;
+ boost::container::pmr::vector< value > vv( &mr );
+ vv.resize( 3 );
+
+ // The memory resource of the container is propagated to each element
+ assert( *vv.get_allocator().resource() == *vv[0].storage() );
+ assert( *vv.get_allocator().resource() == *vv[1].storage() );
+ assert( *vv.get_allocator().resource() == *vv[2].storage() );
+}
+//]
+}
+//----------------------------------------------------------
+
+} // set1()
+
+//----------------------------------------------------------
+
+//[doc_quick_look_7
+value f()
+{
+ // create a reference-counted memory resource
+ storage_ptr sp = make_shared_resource< monotonic_resource >();
+
+ // construct with shared ownership of the resource
+ value jv( sp );
+
+ // assign an array with 3 elements, the monotonic resource will be used
+ jv = { 1, 2, 3 };
+
+ // The caller receives the value, which still owns the resource
+ return jv;
+}
+//]
+//----------------------------------------------------------
+
+static void set2() {
+
+//----------------------------------------------------------
+{
+//[doc_quick_look_8
+value jv = parse( "[1, 2, 3]" );
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_quick_look_9
+error_code ec;
+value jv = parse( R"( "Hello, world!" )", ec );
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_quick_look_10
+unsigned char buf[ 4096 ];
+static_resource mr( buf );
+parse_options opt;
+opt.allow_comments = true;
+opt.allow_trailing_commas = true;
+value jv = parse( "[1, 2, 3, ] // array ", &mr, opt );
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_quick_look_11
+stream_parser p;
+error_code ec;
+p.reset();
+p.write( "[1, 2 ", ec );
+if( ! ec )
+ p.write( ", 3]", ec );
+if( ! ec )
+ p.finish( ec );
+if( ec )
+ return;
+value jv = p.release();
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_quick_look_12
+value jv = { 1, 2, 3 };
+std::string s = serialize( jv ); // produces "[1,2,3]"
+//]
+}
+//----------------------------------------------------------
+{
+value jv;
+//[doc_quick_look_13
+serializer sr;
+sr.reset( &jv ); // prepare to output `jv`
+do
+{
+ char buf[ 16 ];
+ std::cout << sr.read( buf );
+}
+while( ! sr.done() );
+//]
+}
+//----------------------------------------------------------
+
+} // set2()
+
+//----------------------------------------------------------
+
+//[doc_quick_look_14
+namespace my_app {
+
+struct customer
+{
+ int id;
+ std::string name;
+ bool current;
+};
+
+} // namespace my_app
+//]
+
+//----------------------------------------------------------
+
+//[doc_quick_look_15
+namespace my_app {
+
+void tag_invoke( value_from_tag, value& jv, customer const& c )
+{
+ jv = {
+ { "id" , c.id },
+ { "name", c.name },
+ { "current", c.current }
+ };
+}
+
+} // namespace my_app
+//]
+
+static void set3() {
+
+//----------------------------------------------------------
+{
+//[doc_quick_look_16
+my_app::customer c{ 1001, "Boost", true };
+std::cout << serialize( value_from( c ) );
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_quick_look_17
+std::vector< my_app::customer > vc;
+//...
+value jv = value_from( vc );
+//]
+}
+//----------------------------------------------------------
+
+} // set3()
+
+//----------------------------------------------------------
+
+//[doc_quick_look_18
+namespace my_app {
+
+// This helper function deduces the type and assigns the value with the matching key
+template<class T>
+void extract( object const& obj, T& t, string_view key )
+{
+ t = value_to<T>( obj.at( key ) );
+}
+
+customer tag_invoke( value_to_tag< customer >, value const& jv )
+{
+ customer c;
+ object const& obj = jv.as_object();
+ extract( obj, c.id, "id" );
+ extract( obj, c.name, "name" );
+ extract( obj, c.current, "current" );
+ return c;
+}
+
+} // namespace my_app
+//]
+
+//----------------------------------------------------------
+
+namespace my_app_2 {
+namespace my_app { using boost::json::my_app::customer; }
+//[doc_quick_look_19
+namespace my_app {
+
+customer tag_invoke( value_to_tag< customer >, value const& jv )
+{
+ object const& obj = jv.as_object();
+ return customer {
+ value_to<int>( obj.at( "id" ) ),
+ value_to<std::string>( obj.at( "name" ) ),
+ value_to<bool>( obj.at( "current" ) )
+ };
+}
+
+} // namespace my_app
+//]
+} // my_app_2
+
+//----------------------------------------------------------
+
+static void set4() {
+using namespace my_app;
+
+//----------------------------------------------------------
+{
+//[doc_quick_look_20
+json::value jv;
+//...
+customer c( value_to<customer>(jv) );
+//]
+}
+//----------------------------------------------------------
+{
+json::value jv;
+//[doc_quick_look_21
+std::vector< customer > vc = value_to< std::vector< customer > >( jv );
+//]
+}
+//----------------------------------------------------------
+
+//----------------------------------------------------------
+
+} // set4
+
+class doc_quick_look_test
+{
+public:
+ void
+ run()
+ {
+ (void)&set1;
+ (void)&set2;
+ (void)&set3;
+ (void)&set4;
+ BOOST_TEST_PASS();
+ }
+};
+
+TEST_SUITE(doc_quick_look_test, "boost.json.doc_quick_look");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/doc_serializing.cpp b/src/boost/libs/json/test/doc_serializing.cpp
new file mode 100644
index 000000000..8d1dc4566
--- /dev/null
+++ b/src/boost/libs/json/test/doc_serializing.cpp
@@ -0,0 +1,75 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#include <boost/json/serialize.hpp>
+#include <boost/json/serializer.hpp>
+
+#include <iostream>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+//----------------------------------------------------------
+
+static void set1() {
+
+//----------------------------------------------------------
+{
+//[doc_serializing_1
+value jv = { 1, 2, 3, 4, 5 };
+
+std::cout << jv << "\n";
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_serializing_2
+value jv = { 1, 2, 3, 4, 5 };
+
+std::string s = serialize( jv );
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_serializing_3
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_serializing_4
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_serializing_5
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_serializing_6
+//]
+}
+//----------------------------------------------------------
+
+} // set1
+
+class doc_serializing_test
+{
+public:
+ void
+ run()
+ {
+ (void)&set1;
+ }
+};
+
+TEST_SUITE(doc_serializing_test, "boost.json.doc_serializing");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/doc_storage_ptr.cpp b/src/boost/libs/json/test/doc_storage_ptr.cpp
new file mode 100644
index 000000000..a13c851d1
--- /dev/null
+++ b/src/boost/libs/json/test/doc_storage_ptr.cpp
@@ -0,0 +1,176 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#include <boost/json/monotonic_resource.hpp>
+#include <boost/json/parse.hpp>
+#include <boost/json/static_resource.hpp>
+#include <boost/json/storage_ptr.hpp>
+#include <boost/json/value.hpp>
+
+#include <iostream>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+//----------------------------------------------------------
+
+static void set1() {
+
+//----------------------------------------------------------
+{
+//[doc_storage_ptr_1
+storage_ptr sp1;
+storage_ptr sp2;
+
+assert( sp1.get() != nullptr ); // always points to a valid resource
+assert( sp1.get() == sp2.get() ); // both point to the default resource
+assert( *sp1.get() == *sp2.get() ); // the default resource compares equal
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_storage_ptr_2
+array arr; // default construction
+object obj;
+string str;
+value jv;
+
+assert( jv.storage().get() == storage_ptr().get() ); // uses the default memory resource
+assert( jv.storage().get() == arr.storage().get() ); // both point to the default resource
+assert( *arr.storage() == *obj.storage() ); // containers use equivalent resources
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_storage_ptr_3
+monotonic_resource mr;
+
+value const jv = parse( "[1,2,3]", &mr );
+//]
+}
+//----------------------------------------------------------
+
+} // set1
+
+//----------------------------------------------------------
+
+//[doc_storage_ptr_4
+value parse_value( string_view s)
+{
+ return parse( s, make_shared_resource< monotonic_resource >() );
+}
+//]
+
+//----------------------------------------------------------
+
+//[doc_storage_ptr_5
+template< class Handler >
+void do_rpc( string_view s, Handler&& h )
+{
+ unsigned char buffer[ 8192 ]; // Small stack buffer to avoid most allocations during parse
+ monotonic_resource mr( buffer ); // This resource will use our local buffer first
+ value const jv = parse( s, &mr ); // Parse the input string into a value that uses our resource
+ h( jv ); // Call the handler to perform the RPC command
+}
+//]
+
+//----------------------------------------------------------
+
+void set2() {
+
+//----------------------------------------------------------
+{
+//[doc_storage_ptr_6
+unsigned char buffer[ 8192 ];
+static_resource mr( buffer ); // The resource will use our local buffer
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_storage_ptr_7
+monotonic_resource mr;
+array arr( &mr ); // construct an array using our resource
+arr.emplace_back( "boost" ); // insert a string
+assert( *arr[0].as_string().storage() == mr ); // the resource is propagated to the string
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_storage_ptr_8
+{
+ monotonic_resource mr;
+
+ array arr( &mr ); // construct an array using our resource
+
+ assert( ! arr.storage().is_shared() ); // no shared ownership
+}
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_storage_ptr_9
+storage_ptr sp = make_shared_resource< monotonic_resource >();
+
+string str( sp );
+
+assert( sp.is_shared() ); // shared ownership
+assert( str.storage().is_shared() ); // shared ownership
+//]
+}
+//----------------------------------------------------------
+
+} // set2
+
+//----------------------------------------------------------
+//[doc_storage_ptr_10
+class logging_resource : public memory_resource
+{
+private:
+ void* do_allocate( std::size_t bytes, std::size_t align ) override
+ {
+ std::cout << "Allocating " << bytes << " bytes with alignment " << align << '\n';
+
+ return ::operator new( bytes );
+ }
+
+ void do_deallocate( void* ptr, std::size_t bytes, std::size_t align ) override
+ {
+ std::cout << "Deallocating " << bytes << " bytes with alignment " << align << " @ address " << ptr << '\n';
+
+ return ::operator delete( ptr );
+ }
+
+ bool do_is_equal( memory_resource const& other ) const noexcept override
+ {
+ // since the global allocation and deallocation functions are used,
+ // any instance of a logging_resource can deallocate memory allocated
+ // by another instance of a logging_resource
+
+ return dynamic_cast< logging_resource const* >( &other ) != nullptr;
+ }
+};
+//]
+
+//----------------------------------------------------------
+
+class doc_storage_ptr_test
+{
+public:
+ void
+ run()
+ {
+ (void)&set1;
+ BOOST_TEST_PASS();
+ }
+};
+
+TEST_SUITE(doc_storage_ptr_test, "boost.json.doc_storage_ptr");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/doc_uses_allocator.cpp b/src/boost/libs/json/test/doc_uses_allocator.cpp
new file mode 100644
index 000000000..72aa93ef7
--- /dev/null
+++ b/src/boost/libs/json/test/doc_uses_allocator.cpp
@@ -0,0 +1,77 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#include <boost/json/memory_resource.hpp>
+#include <boost/json/monotonic_resource.hpp>
+#include <boost/json/value.hpp>
+#include <vector>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+//----------------------------------------------------------
+
+static void set1() {
+
+//----------------------------------------------------------
+{
+//[doc_uses_allocator_1
+// We want to use this resource for all the containers
+monotonic_resource mr;
+
+// Declare a vector of JSON values
+std::vector< value, polymorphic_allocator< value > > v( &mr );
+
+// The polymorphic allocator will use our resource
+assert( v.get_allocator().resource() == &mr );
+
+// Add a string to the vector
+v.emplace_back( "boost" );
+
+// The vector propagates the memory resource to the string
+assert( v[0].storage().get() == &mr );
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_uses_allocator_2
+// This vector will use the default memory resource
+std::vector< value, polymorphic_allocator < value > > v;
+
+// This value will same memory resource as the vector
+value jv( v.get_allocator() );
+
+// However, ownership is not transferred,
+assert( ! jv.storage().is_shared() );
+
+// and deallocate is never null
+assert( ! jv.storage().is_deallocate_trivial() );
+//]
+}
+//----------------------------------------------------------
+
+} // set1
+
+//----------------------------------------------------------
+
+class doc_uses_allocator_test
+{
+public:
+ void
+ run()
+ {
+ (void)&set1;
+ BOOST_TEST_PASS();
+ }
+};
+
+TEST_SUITE(doc_uses_allocator_test, "boost.json.doc_uses_allocator");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/doc_using_numbers.cpp b/src/boost/libs/json/test/doc_using_numbers.cpp
new file mode 100644
index 000000000..6dfc8e445
--- /dev/null
+++ b/src/boost/libs/json/test/doc_using_numbers.cpp
@@ -0,0 +1,193 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#include <boost/json/parse.hpp>
+#include <boost/json/value.hpp>
+#include <boost/json/value_to.hpp>
+
+#include "test_suite.hpp"
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4101)
+# pragma warning(disable: 4189) // local variable is initialized but not referenced
+#elif defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wunused"
+# pragma clang diagnostic ignored "-Wunused-variable"
+#elif defined(__GNUC__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wunused"
+# pragma GCC diagnostic ignored "-Wunused-variable"
+#endif
+
+BOOST_JSON_NS_BEGIN
+
+//----------------------------------------------------------
+
+static void set1() {
+
+//----------------------------------------------------------
+{
+//[doc_using_numbers_1
+// construction from int
+value jv1 = 1;
+
+assert( jv1.is_int64() );
+
+// construction from unsigned int
+value jv2 = 2u;
+
+assert( jv2.is_uint64() );
+
+// construction from double
+value jv3 = 3.0;
+
+assert( jv3.is_double() );
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_using_numbers_2
+
+value jv = 1;
+
+assert( jv.is_int64() );
+
+// jv.kind() != kind::uint64; throws
+std::uint64_t r1 = jv.as_uint64();
+
+// jv.kind() != kind::uint64; the behavior is undefined
+std::uint64_t r2 = jv.get_uint64();
+
+// if_double will always return nullptr, branch is not taken
+if(double* d = jv.if_double())
+ assert( false );
+
+//]
+};
+//----------------------------------------------------------
+{
+//[doc_using_numbers_3
+struct convert_int64
+{
+ value jv;
+
+ operator int() const
+ {
+ return value_to< int >( this->jv );
+ }
+};
+//]
+}
+//----------------------------------------------------------
+try
+{
+//[doc_using_numbers_4
+ value jv1 = 404;
+
+ assert( jv1.is_int64() );
+
+ // ok, identity conversion
+ std::int64_t r1 = value_to< std::int64_t >( jv1 );
+
+ // loss of data, throws system_error
+ char r2 = value_to< char >( jv1 );
+
+ // ok, no loss of data
+ double r3 = value_to< double >( jv1 );
+
+ value jv2 = 1.23;
+
+ assert( jv1.is_double() );
+
+ // ok, same as static_cast<float>( jv2.get_double() )
+ float r4 = value_to< float >( jv2 );
+
+ // not exact, throws system_error
+ int r5 = value_to< int >( jv2 );
+
+ value jv3 = {1, 2, 3};
+
+ assert( ! jv3.is_number() );
+
+ // not a number, throws system_error
+ int r6 = value_to< int >( jv3 );
+//]
+}
+catch(...)
+{
+}
+//----------------------------------------------------------
+{
+//[doc_using_numbers_5
+
+value jv = 10.5;
+
+error_code ec;
+
+// ok, conversion is exact
+float r1 = jv.to_number< float >( ec );
+
+assert( ! ec );
+
+// error, conversion is non-exact
+int r2 = jv.to_number< int >( ec );
+
+assert( ec == error::not_exact );
+
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_using_numbers_6
+value jv = parse("[-42, 100, 10.25, -299999999999999999998, 2e32]");
+
+array ja = jv.as_array();
+
+// represented by std::int64_t
+assert( ja[0].is_int64() );
+
+// represented by std::int64_t
+assert( ja[1].is_int64() );
+
+// contains decimal point, represented as double
+assert( ja[2].is_double() );
+
+// less than INT64_MIN, represented as double
+assert( ja[3].is_double() );
+
+// contains exponent, represented as double
+assert( ja[4].is_double() );
+//]
+}
+//----------------------------------------------------------
+{
+//[doc_using_numbers_7
+//]
+}
+//----------------------------------------------------------
+
+} // set1
+
+//----------------------------------------------------------
+
+class doc_using_numbers_test
+{
+public:
+ void
+ run()
+ {
+ (void)&set1;
+ }
+};
+
+TEST_SUITE(doc_using_numbers_test, "boost.json.doc_using_numbers");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/double.cpp b/src/boost/libs/json/test/double.cpp
new file mode 100644
index 000000000..4bb77c4bd
--- /dev/null
+++ b/src/boost/libs/json/test/double.cpp
@@ -0,0 +1,434 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#include <boost/json/stream_parser.hpp>
+#include <boost/json/parse.hpp>
+#include <boost/json/serialize.hpp>
+
+#include <iostream>
+#include <random>
+#include <cinttypes>
+
+#include "parse-vectors.hpp"
+#include "test.hpp"
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+template<std::size_t N, class... Args>
+void
+sprintf(char (&buf)[N],
+ char const* format, Args&&... args)
+{
+#ifdef _MSC_VER
+ sprintf_s(buf, format,
+ std::forward<Args>(args)...);
+#else
+ std::sprintf(buf, format,
+ std::forward<Args>(args)...);
+#endif
+}
+
+class double_test
+{
+public:
+ struct f_boost
+ {
+ static
+ string_view
+ name() noexcept
+ {
+ return "boost";
+ }
+
+ double
+ operator()(string_view s) const
+ {
+ BOOST_TEST_CHECKPOINT();
+ error_code ec;
+ stream_parser p;
+ p.write(s.data(), s.size(), ec);
+ if(BOOST_TEST(! ec))
+ p.finish(ec);
+ if(! BOOST_TEST(! ec))
+ return 0;
+ auto const jv = p.release();
+ double const d = jv.as_double();
+ grind_double(s, d);
+ return d;
+ }
+ };
+
+ bool
+ within_1ulp(double x, double y)
+ {
+ std::uint64_t bx, by;
+ std::memcpy(&bx, &x, sizeof(x));
+ std::memcpy(&by, &y, sizeof(y));
+
+ auto diff = bx - by;
+ switch (diff)
+ {
+ case 0:
+ case 1:
+ case 0xffffffffffffffff:
+ return true;
+ default:
+ break;
+ }
+ return false;
+ }
+
+ static
+ value
+ from_string_test(
+ string_view s,
+ storage_ptr sp = {},
+ const parse_options& po = parse_options())
+ {
+ stream_parser p(storage_ptr(), po);
+ error_code ec;
+ p.reset(std::move(sp));
+ p.write(s.data(), s.size(), ec);
+ if(BOOST_TEST(! ec))
+ p.finish(ec);
+ BOOST_TEST(! ec);
+ return p.release();
+ }
+
+ void
+ static
+ check_round_trip(value const& jv1,
+ const parse_options& po = parse_options())
+ {
+ auto const s2 =
+ //to_string_test(jv1); // use this if serializer is broken
+ serialize(jv1);
+ auto jv2 =
+ from_string_test(s2, {}, po);
+ BOOST_TEST(equal(jv1, jv2));
+ }
+
+ template<class F>
+ void
+ static
+ grind_one(
+ string_view s,
+ storage_ptr sp,
+ F const& f,
+ const parse_options& po = parse_options())
+ {
+ auto const jv =
+ from_string_test(s, sp, po);
+ f(jv, po);
+ }
+
+ static
+ void
+ grind_one(string_view s)
+ {
+ auto const jv =
+ from_string_test(s);
+ check_round_trip(jv);
+ }
+
+ template<class F>
+ static
+ void
+ grind(string_view s, F const& f,
+ const parse_options& po = parse_options())
+ {
+ try
+ {
+ grind_one(s, {}, f, po);
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ grind_one(s, sp, f, po);
+ });
+
+ if(s.size() > 1)
+ {
+ // Destroy the stream_parser at every
+ // split point to check leaks.
+ for(std::size_t i = 1;
+ i < s.size(); ++i)
+ {
+ fail_resource mr;
+ mr.fail_max = 0;
+ stream_parser p(storage_ptr(), po);
+ error_code ec;
+ p.reset(&mr);
+ p.write(s.data(), i, ec);
+ if(BOOST_TEST(! ec))
+ p.write(
+ s.data() + i,
+ s.size() - i, ec);
+ if(BOOST_TEST(! ec))
+ p.finish(ec);
+ if(BOOST_TEST(! ec))
+ f(p.release(), po);
+ }
+ }
+ }
+ catch(std::exception const&)
+ {
+ BOOST_TEST_FAIL();
+ }
+ }
+
+ static
+ void
+ grind(string_view s,
+ const parse_options& po = parse_options())
+ {
+ grind(s,
+ [](value const& jv, const parse_options& po)
+ {
+ check_round_trip(jv, po);
+ }, po);
+ }
+
+ static
+ void
+ grind_double(string_view s, double v)
+ {
+ grind(s,
+ [v](value const& jv, const parse_options&)
+ {
+ if(! BOOST_TEST(jv.is_double()))
+ return;
+ BOOST_TEST(jv.get_double() == v);
+ });
+ }
+
+ // Verify that f converts to the
+ // same double produced by `strtod`.
+ // Requires `s` is not represented by an integral type.
+ template<class F>
+ void
+ fc(std::string const& s, F const& f)
+ {
+ char* str_end;
+ double const need =
+ std::strtod(s.c_str(), &str_end);
+ // BOOST_TEST(str_end == &s.back() + 1);
+ double const got = f(s);
+ auto same = got == need;
+ auto close = same ?
+ true : within_1ulp(got, need);
+
+ if( !BOOST_TEST(close) )
+ {
+ std::cerr << "Failure on '" << s << "': " << got << " != " << need << "\n";
+ }
+ }
+
+ void
+ fc(std::string const& s)
+ {
+ fc(s, f_boost{});
+ fc(s + std::string( 64, ' ' ), f_boost{});
+ }
+
+ void
+ testDouble()
+ {
+ grind_double("-1.010", -1.01);
+ grind_double("-0.010", -0.01);
+ grind_double("-0.0", -0.0);
+ grind_double("-0e0", -0.0);
+ grind_double( "18.4", 18.4);
+ grind_double("-18.4", -18.4);
+ grind_double( "18446744073709551616", 1.8446744073709552e+19);
+ grind_double("-18446744073709551616", -1.8446744073709552e+19);
+ grind_double( "18446744073709551616.0", 1.8446744073709552e+19);
+ grind_double( "18446744073709551616.00009", 1.8446744073709552e+19);
+ grind_double( "1844674407370955161600000", 1.8446744073709552e+24);
+ grind_double("-1844674407370955161600000", -1.8446744073709552e+24);
+ grind_double( "1844674407370955161600000.0", 1.8446744073709552e+24);
+ grind_double( "1844674407370955161600000.00009", 1.8446744073709552e+24);
+ grind_double( "19700720435664.186294290058937593e13", 1.9700720435664185e+26);
+
+ grind_double( "1.0", 1.0);
+ grind_double( "1.1", 1.1);
+ grind_double( "1.11", 1.11);
+ grind_double( "1.11111", 1.11111);
+ grind_double( "11.1111", 11.1111);
+ grind_double( "111.111", 111.111);
+
+ fc("-0.9999999999999999999999");
+ fc("-0.9999999999999999");
+ fc("-0.9007199254740991");
+ fc("-0.999999999999999");
+ fc("-0.99999999999999");
+ fc("-0.9999999999999");
+ fc("-0.999999999999");
+ fc("-0.99999999999");
+ fc("-0.9999999999");
+ fc("-0.999999999");
+ fc("-0.99999999");
+ fc("-0.9999999");
+ fc("-0.999999");
+ fc("-0.99999");
+ fc("-0.9999");
+ fc("-0.8125");
+ fc("-0.999");
+ fc("-0.99");
+ fc("-1.0");
+ fc("-0.9");
+ fc("-0.0");
+ fc("0.0");
+ fc("0.9");
+ fc("0.99");
+ fc("0.999");
+ fc("0.8125");
+ fc("0.9999");
+ fc("0.99999");
+ fc("0.999999");
+ fc("0.9999999");
+ fc("0.99999999");
+ fc("0.999999999");
+ fc("0.9999999999");
+ fc("0.99999999999");
+ fc("0.999999999999");
+ fc("0.9999999999999");
+ fc("0.99999999999999");
+ fc("0.999999999999999");
+ fc("0.9007199254740991");
+ fc("0.9999999999999999");
+ fc("0.9999999999999999999999");
+ fc("0.999999999999999999999999999");
+
+ fc("-1e308");
+ fc("-1e-308");
+ fc("-9999e300");
+ fc("-999e100");
+ fc("-99e10");
+ fc("-9e1");
+ fc("9e1");
+ fc("99e10");
+ fc("999e100");
+ fc("9999e300");
+ fc("999999999999999999.0");
+ fc("999999999999999999999.0");
+ fc("999999999999999999999e5");
+ fc("999999999999999999999.0e5");
+
+ fc("0.00000000000000001");
+
+ fc("-1e-1");
+ fc("-1e0");
+ fc("-1e1");
+ fc("0e0");
+ fc("1e0");
+ fc("1e10");
+
+ fc("0."
+ "00000000000000000000000000000000000000000000000000" // 50 zeroes
+ "1e50");
+ fc("-0."
+ "00000000000000000000000000000000000000000000000000" // 50 zeroes
+ "1e50");
+
+ fc("0."
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000" // 500 zeroes
+ "1e600");
+ fc("-0."
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000" // 500 zeroes
+ "1e600");
+
+ fc("0e"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000" // 500 zeroes
+ );
+ }
+
+ void checkAccuracy(const char* nm, int max_ulp)
+ {
+ double x = std::strtod( nm, 0 );
+ double y = boost::json::parse( nm ).as_double();
+ std::uint64_t bx, by;
+ std::memcpy( &bx, &x, sizeof(x) );
+ std::memcpy( &by, &y, sizeof(y) );
+ std::int64_t diff = bx - by;
+ if (!BOOST_TEST(std::abs( diff ) <= max_ulp))
+ std::fprintf(stderr,
+ "%s: difference %" PRId64 " ulp\n"
+ " strtod: %.13a %.16g\n"
+ " boost.json: %.13a %.16g\n\n",
+ nm, diff, x, x, y, y );
+ }
+
+ void
+ testWithinULP()
+ {
+ std::mt19937_64 rng;
+
+ checkAccuracy("10199214983525025199.13135016100190689227e-308", 2);
+
+ for( int i = 0; i < 1000000; ++i )
+ {
+ unsigned long long x1 = rng();
+ unsigned long long x2 = rng();
+ int x3 = std::uniform_int_distribution<>( -308, +308 )( rng );
+
+ char buffer[ 128 ];
+ sprintf( buffer, "%llu.%llue%d", x1, x2, x3 );
+
+ checkAccuracy( buffer, 2 );
+ }
+
+ for( int i = -326; i <= +309; ++i )
+ {
+ char buffer[ 128 ];
+ sprintf( buffer, "1e%d", i );
+
+ checkAccuracy( buffer, 0 );
+ }
+ };
+
+ void
+ run()
+ {
+ testDouble();
+ testWithinULP();
+ }
+};
+
+TEST_SUITE(double_test, "boost.json.double");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/error.cpp b/src/boost/libs/json/test/error.cpp
new file mode 100644
index 000000000..dc267159c
--- /dev/null
+++ b/src/boost/libs/json/test/error.cpp
@@ -0,0 +1,88 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/error.hpp>
+
+#include <memory>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+class error_test
+{
+public:
+ void check(error e)
+ {
+ auto const ec = make_error_code(e);
+ BOOST_TEST(ec.category().name() != nullptr);
+ BOOST_TEST(! ec.message().empty());
+ BOOST_TEST(ec.category().default_error_condition(
+ static_cast<int>(e)).category() == ec.category());
+ }
+
+ void check(condition c, error e)
+ {
+ {
+ auto const ec = make_error_code(e);
+ BOOST_TEST(ec.category().name() != nullptr);
+ BOOST_TEST(! ec.message().empty());
+ BOOST_TEST(ec == c);
+ }
+ {
+ auto ec = make_error_condition(c);
+ BOOST_TEST(ec.category().name() != nullptr);
+ BOOST_TEST(! ec.message().empty());
+ BOOST_TEST(ec == c);
+ }
+ }
+
+ void
+ run()
+ {
+ check(condition::parse_error, error::syntax);
+ check(condition::parse_error, error::extra_data);
+ check(condition::parse_error, error::incomplete);
+ check(condition::parse_error, error::exponent_overflow);
+ check(condition::parse_error, error::too_deep);
+ check(condition::parse_error, error::illegal_leading_surrogate);
+ check(condition::parse_error, error::illegal_trailing_surrogate);
+ check(condition::parse_error, error::expected_hex_digit);
+ check(condition::parse_error, error::expected_utf16_escape);
+ check(condition::parse_error, error::object_too_large);
+ check(condition::parse_error, error::array_too_large);
+ check(condition::parse_error, error::key_too_large);
+ check(condition::parse_error, error::string_too_large);
+ check(condition::parse_error, error::exception);
+
+ check(condition::assign_error, error::not_number);
+ check(condition::assign_error, error::not_exact);
+
+ check(condition::pointer_parse_error, error::missing_slash);
+ check(condition::pointer_parse_error, error::invalid_escape);
+
+ check(condition::pointer_use_error, error::token_not_number);
+ check(condition::pointer_use_error, error::value_is_scalar);
+ check(condition::pointer_use_error, error::not_found);
+ check(condition::pointer_use_error, error::token_overflow);
+ check(condition::pointer_use_error, error::past_the_end);
+
+ check(error::test_failure);
+
+ // check std interop
+ std::error_code const ec = error::syntax;
+ BOOST_TEST(ec == error::syntax);
+ BOOST_TEST(ec == condition::parse_error);
+ }
+};
+
+TEST_SUITE(error_test, "boost.json.error");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/fwd.cpp b/src/boost/libs/json/test/fwd.cpp
new file mode 100644
index 000000000..75063e629
--- /dev/null
+++ b/src/boost/libs/json/test/fwd.cpp
@@ -0,0 +1,14 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/fwd.hpp>
+
+// make sure declarations are consistent
+#include <boost/json.hpp>
diff --git a/src/boost/libs/json/test/json.cpp b/src/boost/libs/json/test/json.cpp
new file mode 100644
index 000000000..8fd9e9219
--- /dev/null
+++ b/src/boost/libs/json/test/json.cpp
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json.hpp>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+struct json_test
+{
+ ::test_suite::log_type log;
+
+ void
+ run()
+ {
+ log <<
+ "sizeof(alignof)\n"
+ " object == " << sizeof(object) << " (" << alignof(object) << ")\n"
+ " value_type == " << sizeof(object::value_type) << " (" << alignof(object::value_type) << ")\n"
+ " array == " << sizeof(array) << " (" << alignof(array) << ")\n"
+ " string == " << sizeof(string) << " (" << alignof(string) << ")\n"
+ " value == " << sizeof(value) << " (" << alignof(value) << ")\n"
+ " serializer == " << sizeof(serializer) << "\n"
+ " stream_parser == " << sizeof(stream_parser)
+ ;
+ BOOST_TEST_PASS();
+ }
+};
+
+TEST_SUITE(json_test, "boost.json.zsizes");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/kind.cpp b/src/boost/libs/json/test/kind.cpp
new file mode 100644
index 000000000..c7c644bf4
--- /dev/null
+++ b/src/boost/libs/json/test/kind.cpp
@@ -0,0 +1,53 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/kind.hpp>
+
+#include <boost/json/string_view.hpp>
+
+#include <type_traits>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+class kind_test
+{
+public:
+ BOOST_STATIC_ASSERT(
+ std::is_enum<kind>::value);
+
+ void
+ check(kind k, string_view s)
+ {
+ BOOST_TEST(
+ to_string(k) == s);
+ std::stringstream ss;
+ ss << k;
+ BOOST_TEST(ss.str() == s);
+ }
+
+ void
+ run()
+ {
+ check(kind::array, "array");
+ check(kind::object, "object");
+ check(kind::string, "string");
+ check(kind::int64, "int64");
+ check(kind::uint64, "uint64");
+ check(kind::double_, "double");
+ check(kind::bool_, "bool");
+ check(kind::null, "null");
+ }
+};
+
+TEST_SUITE(kind_test, "boost.json.kind");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/limits.cpp b/src/boost/libs/json/test/limits.cpp
new file mode 100644
index 000000000..40f2cb99a
--- /dev/null
+++ b/src/boost/libs/json/test/limits.cpp
@@ -0,0 +1,400 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#include <boost/json/array.hpp>
+#include <boost/json/object.hpp>
+#include <boost/json/string.hpp>
+#include <boost/json/value.hpp>
+#include <boost/json/parse.hpp>
+#include <boost/json/stream_parser.hpp>
+
+#include <vector>
+
+#include "test_suite.hpp"
+#include "test.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+/*
+ This translation unit exercises code paths
+ related to library limits such as max string
+ length.
+*/
+
+class limits_test
+{
+public:
+ void
+ testValue()
+ {
+ // object too large
+ {
+ std::initializer_list<std::pair<
+ string_view, value_ref>> init = {
+ { "1", 1},{ "2", 2},{ "3", 3},{ "4", 4},{ "5", 5},
+ { "6", 6},{ "7", 7},{ "8", 8},{ "9", 9},{"10",10},
+ {"11",11},{"12",12},{"13",13},{"14",14},{"15",15},
+ {"16",16},{"17",17},{"18",18},{"19",19},{"10",10},
+ {"21",21},{"22",22},{"23",23},{"24",24},{"25",25},
+ {"26",26},{"27",27},{"28",28},{"29",29},{"30",30},
+ {"31",31}};
+ BOOST_TEST(init.size() > object::max_size());
+ BOOST_TEST_THROWS(value{init}, std::length_error);
+ }
+ }
+
+ void
+ testObject()
+ {
+ // max_size()
+ {
+ BOOST_TEST_THROWS(
+ object(object::max_size()+1),
+ std::length_error);
+ }
+
+ // object(), max size
+ {
+ std::initializer_list<std::pair<
+ string_view, value_ref>> init = {
+ { "1", 1},{ "2", 2},{ "3", 3},{ "4", 4},{ "5", 5},
+ { "6", 6},{ "7", 7},{ "8", 8},{ "9", 9},{"10",10},
+ {"11",11},{"12",12},{"13",13},{"14",14},{"15",15},
+ {"16",16},{"17",17},{"18",18},{"19",19},{"10",10},
+ {"21",21},{"22",22},{"23",23},{"24",24},{"25",25},
+ {"26",26},{"27",27},{"28",28},{"29",29},{"30",30},
+ {"31",31}};
+ BOOST_TEST(init.size() > object::max_size());
+ BOOST_TEST_THROWS(
+ object(init),
+ std::length_error);
+ BOOST_TEST_THROWS(
+ object(init.begin(), init.end()),
+ std::length_error);
+ BOOST_TEST_THROWS(
+ object(
+ make_input_iterator(init.begin()),
+ make_input_iterator(init.end())),
+ std::length_error);
+ }
+
+ // reserve(), max size
+ {
+ object o;
+ BOOST_TEST_THROWS(
+ o.reserve(o.max_size() + 1),
+ std::length_error);
+ }
+
+ // insert(), max size
+ {
+ std::initializer_list<std::pair<
+ string_view, value_ref>> init = {
+ { "1", 1},{ "2", 2},{ "3", 3},{ "4", 4},{ "5", 5},
+ { "6", 6},{ "7", 7},{ "8", 8},{ "9", 9},{"10",10},
+ {"11",11},{"12",12},{"13",13},{"14",14},{"15",15},
+ {"16",16},{"17",17},{"18",18},{"19",19},{"10",10},
+ {"21",21},{"22",22},{"23",23},{"24",24},{"25",25},
+ {"26",26},{"27",27},{"28",28},{"29",29},{"30",30},
+ {"31",31}};
+ BOOST_TEST(init.size() > object::max_size());
+ object o;
+ BOOST_TEST_THROWS(
+ o.insert(init),
+ std::length_error);
+ BOOST_TEST_THROWS(
+ o.insert(init.begin(), init.end()),
+ std::length_error);
+ BOOST_TEST_THROWS(
+ o.insert(
+ make_input_iterator(init.begin()),
+ make_input_iterator(init.end())),
+ std::length_error);
+ }
+
+ // max key size
+ {
+ std::string const big(
+ string::max_size() + 1, '*');
+ BOOST_TEST_THROWS(
+ object({ {big, nullptr} }),
+ std::length_error);
+ }
+
+ // reserve
+ {
+ object obj;
+ BOOST_TEST_THROWS(
+ obj.reserve(object::max_size() + 1),
+ std::length_error);
+ }
+ }
+
+ void
+ testArray()
+ {
+ {
+ BOOST_TEST_THROWS(
+ array(
+ array::max_size()+1,
+ value(nullptr)),
+ std::length_error);
+ }
+
+ {
+ std::vector<int> v(
+ array::max_size()+1, 42);
+ BOOST_TEST_THROWS(
+ array(v.begin(), v.end()),
+ std::length_error);
+ }
+
+ {
+ std::vector<int> v(
+ array::max_size()+1, 42);
+ BOOST_TEST_THROWS(array(
+ make_input_iterator(v.begin()),
+ make_input_iterator(v.end())),
+ std::length_error);
+ }
+
+ {
+ array a;
+ BOOST_TEST_THROWS(
+ a.insert(a.begin(),
+ array::max_size() + 1,
+ nullptr),
+ std::length_error);
+ }
+ }
+
+ void
+ testString()
+ {
+ // strings
+ {
+ {
+ string s;
+ BOOST_TEST_THROWS(
+ (s.resize(s.max_size() + 1)),
+ std::length_error);
+ }
+
+ {
+ string s;
+ s.resize(100);
+ BOOST_TEST_THROWS(
+ (s.append(s.max_size() - 1, '*')),
+ std::length_error);
+ }
+
+ {
+ string s;
+ s.resize(s.max_size() - 5);
+ BOOST_TEST_THROWS(
+ (s.replace(0, 1, s.subview(0, 10))),
+ std::length_error);
+ }
+
+ {
+ string s;
+ s.resize(s.max_size() - 5);
+ BOOST_TEST_THROWS(
+ (s.replace(0, 1, 10, 'a')),
+ std::length_error);
+ }
+
+ {
+ string s;
+ s.resize(s.max_size() - 5);
+ BOOST_TEST_THROWS(
+ (s.insert(0, s.subview(0, 10))),
+ std::length_error);
+ }
+
+ #if 0
+ {
+ // VFALCO tsan doesn't like this
+ string s;
+ try
+ {
+ s.resize(s.max_size() - 1);
+ }
+ catch(std::exception const&)
+ {
+ }
+ }
+ #endif
+ }
+
+ // string in parser
+ {
+ stream_parser p;
+ std::string const big(
+ string::max_size() + 1, '*');
+ auto const js =
+ "\"" + big + "\":null";
+ error_code ec;
+ auto jv = parse(js, ec);
+ BOOST_TEST(ec == error::string_too_large);
+ BOOST_TEST(ec.has_location());
+ }
+
+ // key in parser
+ {
+ stream_parser p;
+ std::string const big(
+ string::max_size() + 1, '*');
+ auto const js =
+ "{\"" + big + "\":null}";
+ error_code ec;
+ auto jv = parse(js, ec);
+ BOOST_TEST(ec == error::key_too_large);
+ BOOST_TEST(ec.has_location());
+ }
+ }
+
+ void
+ testParser()
+ {
+ // string buffer flush
+ {
+ string_view s =
+ "\"\\na\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\"";
+ error_code ec;
+ auto jv = parse(s, ec);
+ BOOST_TEST(! ec);
+ }
+ // overflow in on_key_part
+ {
+ error_code ec;
+ std::string big;
+ big = "\\b";
+ big += std::string(
+ string::max_size()*2, '*');
+ auto const js =
+ "{\"" + big + "\":null}";
+ auto jv = parse(js, ec);
+ BOOST_TEST(ec == error::key_too_large);
+ BOOST_TEST(ec.has_location());
+ }
+
+ // overflow in on_key
+ {
+ error_code ec;
+ std::string big;
+ big = "\\b";
+ big += std::string(
+ (string::max_size()*3)/2, '*');
+ auto const js =
+ "{\"" + big + "\":null}";
+ auto jv = parse(js, ec);
+ BOOST_TEST(ec == error::key_too_large);
+ BOOST_TEST(ec.has_location());
+ }
+
+ // overflow in on_string_part
+ {
+ error_code ec;
+ std::string big;
+ big = "\\b";
+ big += std::string(
+ string::max_size()*2, '*');
+ auto const js =
+ "\"" + big + "\"";
+ auto jv = parse(js, ec);
+ BOOST_TEST(ec == error::string_too_large);
+ BOOST_TEST(ec.has_location());
+ }
+
+ // overflow in on_string
+ {
+ error_code ec;
+ std::string big;
+ big = "\\b";
+ big += std::string(
+ (string::max_size()*3)/2, '*');
+ auto const js =
+ "\"" + big + "\"";
+ auto jv = parse(js, ec);
+ BOOST_TEST(ec == error::string_too_large);
+ BOOST_TEST(ec.has_location());
+ }
+
+
+ // object overflow
+ {
+ error_code ec;
+ string_view s = R"({
+ "00":0,"01":0,"02":0,"03":0,"04":0,"05":0,"06":0,"07":0,"08":0,"09":0,
+ "10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,
+ "20":0
+ })";
+
+ auto jv = parse(s, ec);
+ BOOST_TEST(ec == error::object_too_large);
+ BOOST_TEST(ec.has_location());
+ }
+
+ // array overflow
+ {
+ error_code ec;
+ string_view s = "["
+ "0,0,0,0,0,0,0,0,0,0,"
+ "0,0,0,0,0,0,0,0,0,0,"
+ "0"
+ "]";
+ auto jv = parse(s, ec);
+ BOOST_TEST(ec == error::array_too_large);
+ BOOST_TEST(ec.has_location());
+ }
+ }
+
+ void
+ run()
+ {
+ #if ! defined(BOOST_JSON_NO_MAX_STRUCTURED_SIZE) && \
+ ! defined(BOOST_JSON_NO_MAX_STRING_SIZE) && \
+ ! defined(BOOST_JSON_NO_MAX_STACK_SIZE) && \
+ ! defined(BOOST_JSON_NO_STACK_BUFFER_SIZE)
+
+ //testValue();
+ testObject();
+ testArray();
+ testString();
+ testParser();
+
+ #else
+ BOOST_TEST_PASS();
+ #endif
+ }
+};
+
+TEST_SUITE(limits_test, "boost.json.limits");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/main.cpp b/src/boost/libs/json/test/main.cpp
new file mode 100644
index 000000000..6ee59cdf6
--- /dev/null
+++ b/src/boost/libs/json/test/main.cpp
@@ -0,0 +1,31 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#include "test_suite.hpp"
+
+#include <iostream>
+#ifdef _MSC_VER
+#include <crtdbg.h>
+#endif
+
+// Simple main used to produce stand
+// alone executables that run unit tests.
+int main(int argc, char const* const* argv)
+{
+#ifdef _MSC_VER
+ {
+ int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+ flags |= _CRTDBG_LEAK_CHECK_DF;
+ _CrtSetDbgFlag(flags);
+ }
+#endif
+
+ ::test_suite::debug_stream log(std::cerr);
+ return ::test_suite::run(log, argc, argv);
+}
diff --git a/src/boost/libs/json/test/make-pvs.py b/src/boost/libs/json/test/make-pvs.py
new file mode 100644
index 000000000..74e6cdb2e
--- /dev/null
+++ b/src/boost/libs/json/test/make-pvs.py
@@ -0,0 +1,117 @@
+# Build test vector variable
+
+import os
+
+def chex(c):
+ d1 = ord(c)/16;
+ d2 = ord(c)%16;
+ d = "0123456789ABCDEF";
+ s = "\\x" + d[d1:d1+1] + d[d2:d2+1];
+ return s;
+
+def escape(c):
+ if c == ' ' or c == '\t':
+ return c;
+ elif c == '\"':
+ return "\\\"";
+ elif c == '\\':
+ return "\\\\";
+ n = ord(c);
+ if n >= 32 and n <= 127:
+ return c;
+ return chex(c) + "\"\"";
+
+def tocpp(s):
+ v0 = ""
+ v = "\"";
+ for c in s:
+ v = v + escape(c);
+ if len(v) > 80:
+ if len(v0) > 50000:
+ return v0 + v + "\"";
+ v0 += v + "\"\n \"";
+ v = "";
+ return v0 + v + "\"";
+
+def do_files(directory):
+ for root, directories, files in os.walk(directory):
+ for filename in files:
+ filepath = os.path.join(root, filename)
+ with open(filepath, 'r') as file:
+ data = file.read();
+ print(" { '" + filename[0:1] + "', \"" + filename[2:-5] + "\", lit(" + tocpp(data) + ") },");
+
+print("""
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#ifndef PARSE_VECTORS
+#define PARSE_VECTORS
+
+#include <boost/utility/string_view.hpp>
+#include <cstdlib>
+#include <type_traits>
+
+struct parse_vectors
+{
+ struct item
+ {
+ char result;
+ ::boost::string_view name;
+ ::boost::string_view text;
+ };
+
+ using iterator = item const*;
+
+ iterator begin() const noexcept
+ {
+ return first_;
+ }
+
+ iterator end() const noexcept
+ {
+ return last_;
+ }
+
+ std::size_t
+ size() const noexcept
+ {
+ return last_ - first_;
+ }
+
+ inline parse_vectors() noexcept;
+
+private:
+ template<std::size_t N>
+ static
+ ::boost::string_view
+ lit(char const (&s)[N])
+ {
+ return {s, N - 1};
+ }
+
+ iterator first_;
+ iterator last_;
+};
+
+parse_vectors::
+parse_vectors() noexcept
+{
+ static item const list[] = {""");
+
+do_files("parse-vectors");
+
+print(""" { ' ', "", "" }
+ };
+ first_ = &list[0];
+ last_ = &list[std::extent<
+ decltype(list)>::value - 1];
+}
+
+#endif""");
diff --git a/src/boost/libs/json/test/make-strings.py b/src/boost/libs/json/test/make-strings.py
new file mode 100644
index 000000000..c8c1a9d84
--- /dev/null
+++ b/src/boost/libs/json/test/make-strings.py
@@ -0,0 +1,17 @@
+# Build array of random strings
+
+import os
+import random
+from random import randint
+
+def randstr():
+ letters = "0123456789!@#$%^&*()_-+=[]{}|;:,<.>/?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ return ''.join(random.choice(letters) for i in range(randint(1, 2000)));
+
+print "[";
+for i in range(1000):
+ print "\"", randstr(), "\",";
+print "\"", randstr(), "\"";
+print "]";
+
+
diff --git a/src/boost/libs/json/test/memory_resource.cpp b/src/boost/libs/json/test/memory_resource.cpp
new file mode 100644
index 000000000..b68cffaf9
--- /dev/null
+++ b/src/boost/libs/json/test/memory_resource.cpp
@@ -0,0 +1,109 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/memory_resource.hpp>
+#include <boost/json/monotonic_resource.hpp>
+#include <boost/json/value.hpp>
+#include <boost/container/pmr/vector.hpp>
+#include <vector>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+class memory_resource_test
+{
+public:
+ void
+ testBoostPmr()
+ {
+ using allocator_type =
+ polymorphic_allocator<value>;
+
+ // pass polymorphic_allocator
+ // where storage_ptr is expected
+ {
+ monotonic_resource mr;
+ value jv( allocator_type{&mr} );
+ object o( allocator_type{&mr} );
+ array a( allocator_type{&mr} );
+ string s( allocator_type{&mr} );
+ }
+ {
+ monotonic_resource mr;
+ allocator_type a(&mr);
+
+ boost::container::pmr::vector<value> v1(a);
+ v1.resize(3);
+ BOOST_TEST(v1[1].storage().get() == &mr);
+
+ std::vector<value, allocator_type> v2(3, {}, a);
+ BOOST_TEST(v2[1].storage().get() == &mr);
+ }
+ }
+
+ // These are here instead of the type-specific
+ // test TUs, so that we only need to link to
+ // Boost.Container from one file.
+ void
+ testPmr()
+ {
+ // array
+ {
+ // get_allocator
+ {
+ monotonic_resource mr;
+ array a(&mr);
+ BOOST_TEST(a.get_allocator().resource() == &mr);
+ }
+ }
+
+ // object
+ {
+ // get_allocator
+ {
+ monotonic_resource mr;
+ object o(&mr);
+ BOOST_TEST(o.get_allocator().resource() == &mr);
+ }
+ }
+
+ // string
+ {
+ // get_allocator
+ {
+ monotonic_resource mr;
+ string s(&mr);
+ BOOST_TEST(s.get_allocator().resource() == &mr);
+ }
+ }
+
+ // value
+ {
+ // get_allocator
+ {
+ monotonic_resource mr;
+ value jv(&mr);
+ BOOST_TEST(jv.get_allocator().resource() == &mr);
+ }
+ }
+ }
+
+ void
+ run()
+ {
+ testBoostPmr();
+ testPmr();
+ }
+};
+
+TEST_SUITE(memory_resource_test, "boost.json.memory_resource");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/monotonic_resource.cpp b/src/boost/libs/json/test/monotonic_resource.cpp
new file mode 100644
index 000000000..6bf391718
--- /dev/null
+++ b/src/boost/libs/json/test/monotonic_resource.cpp
@@ -0,0 +1,311 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/monotonic_resource.hpp>
+
+#include <boost/json/null_resource.hpp>
+#include <boost/json/parse.hpp>
+#include <boost/json/serialize.hpp>
+#include <boost/json/detail/align.hpp>
+#include <iostream>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+BOOST_STATIC_ASSERT( std::is_nothrow_destructible<monotonic_resource>::value );
+
+class monotonic_resource_test
+{
+private:
+ bool
+ in_buffer(
+ void* ptr,
+ void* buffer,
+ std::size_t buffer_size)
+ {
+ using ptr_t = const volatile unsigned char*;
+ return reinterpret_cast<ptr_t>(ptr) >= reinterpret_cast<ptr_t>(buffer) &&
+ reinterpret_cast<ptr_t>(ptr) < reinterpret_cast<ptr_t>(buffer) + buffer_size;
+ }
+
+ bool
+ all_alloc_in_same_block(
+ monotonic_resource& mr,
+ std::size_t bytes,
+ std::size_t align)
+ {
+ // base of the block
+ auto first = mr.allocate(align, align);
+ bool result = true;
+ for (auto allocs = (bytes - align) / align; allocs; --allocs)
+ result &= in_buffer(mr.allocate(align, align), first, bytes);
+ return result;
+ }
+
+public:
+ void
+ testJavadocs()
+ {
+ //--------------------------------------
+
+ unsigned char buf[4000];
+ monotonic_resource mr( buf );
+
+ // Parse the string, using our memory resource
+ auto const jv = parse( "[1,2,3]", &mr );
+
+ // Print the JSON
+ std::cout << jv;
+
+ //--------------------------------------
+ }
+
+ void
+ testMembers()
+ {
+ // ~monotonic_resource
+ {
+ // implied
+ }
+
+ // monotonic_resource(size_t, storage_ptr)
+ {
+ {
+ monotonic_resource mr(1);
+ }
+ {
+ monotonic_resource mr(5000);
+ }
+ {
+ monotonic_resource mr(
+ 1, get_null_resource());
+ }
+ {
+ monotonic_resource mr(
+ 5000, get_null_resource());
+ }
+ }
+
+ // monotonic_resource(unsigned char*, size_t, storage_ptr)
+ {
+ {
+ unsigned char buf[2000];
+ monotonic_resource mr(
+ &buf[0], sizeof(buf));
+ }
+ {
+ unsigned char buf[2000];
+ monotonic_resource mr(
+ &buf[0], sizeof(buf),
+ get_null_resource());
+ }
+ }
+
+ // monotonic_resource(unsigned char[N], storage_ptr)
+ {
+ {
+ unsigned char buf[2000];
+ monotonic_resource mr(buf);
+ }
+ {
+ unsigned char buf[2000];
+ monotonic_resource mr(buf,
+ get_null_resource());
+ }
+ }
+
+ #ifdef __cpp_lib_byte
+ // monotonic_resource(std::byte[N], storage_ptr)
+ {
+ {
+ std::byte buf[2000];
+ monotonic_resource mr(buf);
+ }
+
+ {
+ std::byte buf[2000];
+ monotonic_resource mr(buf,
+ get_null_resource());
+ }
+ }
+ #endif
+
+ // monotonic_resource(unsigned char[N], std::size_t, storage_ptr)
+ {
+ {
+ unsigned char buf[2000];
+ monotonic_resource mr(buf, 1000);
+ }
+ {
+ unsigned char buf[2000];
+ monotonic_resource mr(buf, 1000,
+ get_null_resource());
+ }
+ }
+
+ #ifdef __cpp_lib_byte
+ // monotonic_resource(unsigned char[N], std::size_t, storage_ptr)
+ {
+ {
+ std::byte buf[2000];
+ monotonic_resource mr(buf, 1000);
+ }
+ {
+ std::byte buf[2000];
+ monotonic_resource mr(buf, 1000,
+ get_null_resource());
+ }
+ }
+ #endif
+
+ // release()
+ {
+ unsigned char buf[10];
+ monotonic_resource mr(
+ buf, sizeof(buf));
+ (void)mr.allocate(10,1);
+ mr.release();
+ (void)mr.allocate(10,1);
+ }
+
+ // coverage
+ {
+ monotonic_resource mr(std::size_t(-1)-2);
+ }
+ }
+
+ void
+ testGeneral()
+ {
+ // test that each block gets filled to capacity
+ // and if the growth factor is correct
+ {
+ monotonic_resource mr;
+ BOOST_TEST(all_alloc_in_same_block(mr, 1024, 1));
+ BOOST_TEST(all_alloc_in_same_block(mr, 2048, 2));
+ BOOST_TEST(all_alloc_in_same_block(mr, 4096, 1));
+ BOOST_TEST(all_alloc_in_same_block(mr, 8192, 4));
+ BOOST_TEST(all_alloc_in_same_block(mr, 16384, 1));
+ BOOST_TEST(all_alloc_in_same_block(mr, 32768, 8));
+ BOOST_TEST(all_alloc_in_same_block(mr, 65536, 1));
+ }
+ // test if each allocation is aligned correctly
+ {
+ monotonic_resource mr;
+ for (std::size_t i = 0; i < 4096; ++i)
+ {
+ const auto size = ((i * 3) % 32) + 1;
+ std::size_t next = 1;
+ for (auto mod = i % alignof(detail::max_align_t);
+ mod; mod >>= 1, next <<= 1);
+ const auto align = (std::max)(next,
+ std::size_t(1));
+ BOOST_TEST(!(reinterpret_cast<std::uintptr_t>(mr.allocate(size, align)) % align));
+ }
+ }
+ // test if user provided sizes are correctly rounded
+ {
+ {
+ monotonic_resource mr(10);
+ BOOST_TEST(all_alloc_in_same_block(mr, 1024, 1));
+ }
+ {
+ monotonic_resource mr(1025);
+ BOOST_TEST(all_alloc_in_same_block(mr, 2048, 1));
+ }
+ {
+ monotonic_resource mr(4000);
+ BOOST_TEST(all_alloc_in_same_block(mr, 4096, 1));
+ }
+ }
+ // test if sizes are correctly determined from initial buffers
+ {
+ {
+ unsigned char buf[512];
+ monotonic_resource mr(buf, 512);
+ BOOST_TEST(all_alloc_in_same_block(mr, 512, 1));
+ BOOST_TEST(all_alloc_in_same_block(mr, 1024, 1));
+ }
+ {
+ unsigned char buf[2048];
+ monotonic_resource mr(buf, 2048);
+ BOOST_TEST(all_alloc_in_same_block(mr, 2048, 1));
+ BOOST_TEST(all_alloc_in_same_block(mr, 4096, 1));
+ }
+ {
+ unsigned char buf[4000];
+ monotonic_resource mr(buf, 4000);
+ BOOST_TEST(all_alloc_in_same_block(mr, 4000, 1));
+ BOOST_TEST(all_alloc_in_same_block(mr, 4096, 1));
+ }
+ }
+ // test if allocations that exceed the block size cause rounding to occur
+ {
+ {
+ monotonic_resource mr;
+ auto p = mr.allocate(2048);
+ (void)p;
+ BOOST_TEST(all_alloc_in_same_block(mr, 4096, 1));
+ }
+ {
+ monotonic_resource mr;
+ void* p;
+ p = mr.allocate(2000, 1);
+ p = mr.allocate(48, 1);
+ (void)p;
+ BOOST_TEST(all_alloc_in_same_block(mr, 4096, 1));
+ }
+ }
+ }
+
+ void
+ testStorage()
+ {
+ auto jv = parse(
+R"xx({
+ "glossary": {
+ "title": "example glossary",
+ "GlossDiv": {
+ "title": "S",
+ "GlossList": {
+ "GlossEntry": {
+ "ID": "SGML",
+ "SortAs": "SGML",
+ "GlossTerm": "Standard Generalized Markup Language",
+ "Acronym": "SGML",
+ "Abbrev": "ISO 8879:1986",
+ "GlossDef": {
+ "para": "A meta-markup language, used to create markup languages such as DocBook.",
+ "GlossSeeAlso": ["GML", "XML"]
+ },
+ "GlossSee": "markup"
+ }
+ }
+ }
+ }
+})xx"
+ , make_shared_resource<monotonic_resource>());
+ BOOST_TEST_PASS();
+ }
+
+ void
+ run()
+ {
+ testMembers();
+ testStorage();
+ testGeneral();
+ }
+};
+
+TEST_SUITE(monotonic_resource_test, "boost.json.monotonic_resource");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/natvis.cpp b/src/boost/libs/json/test/natvis.cpp
new file mode 100644
index 000000000..81fc1c9a9
--- /dev/null
+++ b/src/boost/libs/json/test/natvis.cpp
@@ -0,0 +1,115 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#include <boost/json/value.hpp>
+
+#include <boost/json/monotonic_resource.hpp>
+#include <boost/json/static_resource.hpp>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+class natvis_test
+{
+public:
+ static
+ value
+ make_key(string_view s)
+ {
+ value jv;
+ detail::access::construct_value(
+ &jv, s, storage_ptr());
+ return jv;
+ }
+
+ void
+ run()
+ {
+ // These variables may be inspected in the
+ // Visual Studio IDE to verify that the .natvis
+ // file is working correctly
+
+ value jv0 = nullptr;
+ value jv1 = true;
+ value jv2 = -1;
+ value jv3 = 42u;
+ value jv4 = 3.141;
+ value jv5 = "string";
+ value jv6 = make_key("key");
+ value jv7 = "dynamically-allocated-string";
+ value jv8 = { 1, 2, 3 };
+ value jv9 = { {"a",1}, {"b",2}, {"c",3} };
+
+ string& x0 = jv5.get_string(); (void)x0;
+ string& x1 = jv6.get_string(); (void)x1;
+ string& x2 = jv7.get_string(); (void)x2;
+ array& x3 = jv8.get_array(); (void)x3;
+ object& x4 = jv9.get_object(); (void)x4;
+
+ array y0;
+ y0.emplace_back(jv0);
+ y0.emplace_back(jv1);
+ y0.emplace_back(jv2);
+ y0.emplace_back(jv4);
+ y0.emplace_back(jv5);
+ y0.emplace_back(jv6);
+ y0.emplace_back(jv7);
+ y0.emplace_back(jv8);
+ y0.emplace_back(jv9);
+
+ object y1;
+ y1.emplace("a", jv0);
+ y1.emplace("b", jv1);
+ y1.emplace("c", jv2);
+ y1.emplace("d", jv4);
+ y1.emplace("f", jv5);
+ y1.emplace("g", jv6);
+ y1.emplace("h", jv7);
+ y1.emplace("i", jv8);
+ y1.emplace("j", jv9);
+
+ key_value_pair& z0 = y1.begin()[0]; (void)z0;
+ key_value_pair& z1 = y1.begin()[1]; (void)z1;
+ key_value_pair& z2 = y1.begin()[2]; (void)z2;
+ key_value_pair& z3 = y1.begin()[3]; (void)z3;
+ key_value_pair& z4 = y1.begin()[4]; (void)z4;
+ key_value_pair& z5 = y1.begin()[5]; (void)z5;
+ key_value_pair& z6 = y1.begin()[6]; (void)z6;
+ key_value_pair& z7 = y1.begin()[7]; (void)z7;
+ key_value_pair& z8 = y1.begin()[8]; (void)z8;
+
+ {
+ auto sp = y1.storage();
+ }
+ {
+ unsigned char buf[1024];
+ storage_ptr sp;
+ sp = make_shared_resource<
+ monotonic_resource>();
+ sp = make_shared_resource<
+ static_resource>(buf);
+ sp = {};
+ }
+ {
+ unsigned char buf[1024];
+ monotonic_resource mr1;
+ static_resource mr2(buf);
+ storage_ptr sp;
+
+ sp = &mr1;
+ sp = &mr2;
+ sp = {};
+ }
+ }
+};
+
+TEST_SUITE(natvis_test, "json.natvis");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/null_resource.cpp b/src/boost/libs/json/test/null_resource.cpp
new file mode 100644
index 000000000..8b4056449
--- /dev/null
+++ b/src/boost/libs/json/test/null_resource.cpp
@@ -0,0 +1,45 @@
+//
+// Copyright (c) 2020 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/null_resource.hpp>
+
+#include <boost/json/storage_ptr.hpp>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+class null_resource_test
+{
+public:
+ void
+ test()
+ {
+ auto& mr = *get_null_resource();
+ BOOST_TEST_THROWS(
+ mr.allocate(16),
+ std::bad_alloc);
+ char buf[128];
+ // no-op
+ mr.deallocate(&buf[0], 128);
+ BOOST_TEST(
+ mr == *get_null_resource());
+ }
+
+ void
+ run()
+ {
+ test();
+ }
+};
+
+TEST_SUITE(null_resource_test, "boost.json.null_resource");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/object.cpp b/src/boost/libs/json/test/object.cpp
new file mode 100644
index 000000000..1186fa6dd
--- /dev/null
+++ b/src/boost/libs/json/test/object.cpp
@@ -0,0 +1,1554 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/object.hpp>
+
+#include <boost/json/monotonic_resource.hpp>
+#include <boost/json/parse.hpp>
+#include <boost/json/serialize.hpp>
+
+#include <cmath>
+#include <forward_list>
+#include <map>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "test.hpp"
+#include "test_suite.hpp"
+#include "checking_resource.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+BOOST_STATIC_ASSERT( std::is_nothrow_destructible<object>::value );
+BOOST_STATIC_ASSERT( std::is_nothrow_move_constructible<object>::value );
+
+class object_test
+{
+public:
+ static
+ constexpr
+ std::size_t
+ size0_ =
+ detail::small_object_size_ - 2;
+
+ static
+ constexpr
+ std::size_t
+ size1_ = size0_ + 4;
+
+ test_suite::log_type log;
+ string_view const str_;
+
+ using init_list =
+ std::initializer_list<
+ std::pair<string_view, value_ref>>;
+
+#define DECLARE_INIT_LISTS \
+ init_list i0_ = { \
+ { "0", 0 }, { "1", 1 }, { "2", 2 }, { "3", 3 }, { "4", 4 }, \
+ { "5", 5 }, { "6", 6 }, { "7", 7 }, { "8", 8 }, { "9", 9 }, \
+ { "10", 10 }, { "11", 11 }, { "12", 12 }, { "13", 13 }, { "14", 14 }, \
+ { "15", 15 } }; \
+ init_list i1_ = { \
+ { "0", 0 }, { "1", 1 }, { "2", 2 }, { "3", 3 }, { "4", 4 }, \
+ { "5", 5 }, { "6", 6 }, { "7", 7 }, { "8", 8 }, { "9", 9 }, \
+ { "10", 10 }, { "11", 11 }, { "12", 12 }, { "13", 13 }, { "14", 14 }, \
+ { "15", 15 }, { "16", 16 }, { "17", 17 }, { "18", 18 }, { "19", 19 } }
+
+ string_view const s0_ =
+ R"({"0":0,"1":1,"2":2,"3":3,"4":4,)"
+ R"("5":5,"6":6,"7":7,"8":8,"9":9,)"
+ R"("10":10,"11":11,"12":12,"13":13,"14":14,)"
+ R"("15":15})";
+
+ string_view const s1_ =
+ R"({"0":0,"1":1,"2":2,"3":3,"4":4,)"
+ R"("5":5,"6":6,"7":7,"8":8,"9":9,)"
+ R"("10":10,"11":11,"12":12,"13":13,"14":14,)"
+ R"("15":15,"16":16,"17":17,"18":18,"19":19})";
+
+ object_test()
+ : str_("abcdefghijklmnopqrstuvwxyz")
+ {
+ // ensure this string does
+ // not fit in the SBO area.
+ BOOST_ASSERT(str_.size() >
+ string().capacity());
+
+ DECLARE_INIT_LISTS;
+
+ BOOST_TEST(
+ i0_.size() == size0_);
+ BOOST_TEST(
+ i1_.size() == size1_);
+ }
+
+ template<class T, class U, class = void>
+ struct is_equal_comparable : std::false_type {};
+
+ template<class T, class U>
+ struct is_equal_comparable<T, U, detail::void_t<decltype(
+ std::declval<T const&>() == std::declval<U const&>()
+ )>> : std::true_type {};
+
+ template<class T, class U, class = void>
+ struct is_unequal_comparable : std::false_type {};
+
+ template<class T, class U>
+ struct is_unequal_comparable<T, U, detail::void_t<decltype(
+ std::declval<T const&>() != std::declval<U const&>()
+ )>> : std::true_type {};
+
+ BOOST_STATIC_ASSERT( std::is_constructible<object::iterator, object::iterator>::value);
+ BOOST_STATIC_ASSERT(! std::is_constructible<object::iterator, object::const_iterator>::value);
+
+ BOOST_STATIC_ASSERT( std::is_constructible<object::const_iterator, object::iterator>::value);
+ BOOST_STATIC_ASSERT( std::is_constructible<object::const_iterator, object::const_iterator>::value);
+
+ BOOST_STATIC_ASSERT( std::is_assignable<object::iterator&, object::iterator>::value);
+ BOOST_STATIC_ASSERT(! std::is_assignable<object::iterator&, object::const_iterator>::value);
+
+ BOOST_STATIC_ASSERT( std::is_assignable<object::const_iterator&, object::iterator>::value);
+ BOOST_STATIC_ASSERT( std::is_assignable<object::const_iterator&, object::const_iterator>::value);
+
+ BOOST_STATIC_ASSERT(is_equal_comparable<object::iterator, object::iterator>::value);
+ BOOST_STATIC_ASSERT(is_equal_comparable<object::iterator, object::const_iterator>::value);
+
+ BOOST_STATIC_ASSERT(is_equal_comparable<object::const_iterator, object::iterator>::value);
+ BOOST_STATIC_ASSERT(is_equal_comparable<object::const_iterator, object::const_iterator>::value);
+
+ BOOST_STATIC_ASSERT(is_unequal_comparable<object::iterator, object::iterator>::value);
+ BOOST_STATIC_ASSERT(is_unequal_comparable<object::iterator, object::const_iterator>::value);
+
+ BOOST_STATIC_ASSERT(is_unequal_comparable<object::const_iterator, object::iterator>::value);
+ BOOST_STATIC_ASSERT(is_unequal_comparable<object::const_iterator, object::const_iterator>::value);
+
+ BOOST_STATIC_ASSERT( std::is_constructible<object::reverse_iterator, object::reverse_iterator>::value);
+ // std::reverse_iterator ctor is not SFINAEd
+ //BOOST_STATIC_ASSERT(! std::is_constructible<object::reverse_iterator, object::const_reverse_iterator>::value);
+
+ BOOST_STATIC_ASSERT( std::is_constructible<object::const_reverse_iterator, object::reverse_iterator>::value);
+ BOOST_STATIC_ASSERT( std::is_constructible<object::const_reverse_iterator, object::const_reverse_iterator>::value);
+
+ BOOST_STATIC_ASSERT( std::is_assignable<object::reverse_iterator&, object::reverse_iterator>::value);
+ // std::reverse_iterator assignment is not SFINAEd
+ //BOOST_STATIC_ASSERT(! std::is_assignable<object::reverse_iterator&, object::const_reverse_iterator>::value);
+
+ BOOST_STATIC_ASSERT( std::is_assignable<object::const_reverse_iterator&, object::reverse_iterator>::value);
+ BOOST_STATIC_ASSERT( std::is_assignable<object::const_reverse_iterator&, object::const_reverse_iterator>::value);
+
+ BOOST_STATIC_ASSERT(is_equal_comparable<object::reverse_iterator, object::reverse_iterator>::value);
+ BOOST_STATIC_ASSERT(is_equal_comparable<object::reverse_iterator, object::const_reverse_iterator>::value);
+
+ BOOST_STATIC_ASSERT(is_equal_comparable<object::const_reverse_iterator, object::reverse_iterator>::value);
+ BOOST_STATIC_ASSERT(is_equal_comparable<object::const_reverse_iterator, object::const_reverse_iterator>::value);
+
+ BOOST_STATIC_ASSERT(is_unequal_comparable<object::reverse_iterator, object::reverse_iterator>::value);
+ BOOST_STATIC_ASSERT(is_unequal_comparable<object::reverse_iterator, object::const_reverse_iterator>::value);
+
+ BOOST_STATIC_ASSERT(is_unequal_comparable<object::const_reverse_iterator, object::reverse_iterator>::value);
+ BOOST_STATIC_ASSERT(is_unequal_comparable<object::const_reverse_iterator, object::const_reverse_iterator>::value);
+
+ static
+ void
+ check(
+ object const& o,
+ string_view s,
+ std::size_t capacity = 0)
+ {
+ BOOST_TEST(
+ parse(serialize(o)).as_object() ==
+ parse(s).as_object());
+ if(capacity != 0)
+ BOOST_TEST(o.capacity() == capacity);
+ }
+
+ static
+ void
+ check(
+ object const& o,
+ std::size_t capacity)
+ {
+ BOOST_TEST(! o.empty());
+ BOOST_TEST(o.size() == 3);
+ BOOST_TEST(
+ o.capacity() == capacity);
+ BOOST_TEST(o.at("a").as_int64() == 1);
+ BOOST_TEST(o.at("b").as_bool());
+ BOOST_TEST(o.at("c").as_string() == "hello");
+ check_storage(o, o.storage());
+ }
+
+ void
+ testDtor()
+ {
+ // ~object()
+ {
+ object o;
+ }
+ }
+
+ void
+ testCtors()
+ {
+ DECLARE_INIT_LISTS;
+
+ // object(detail::unchecked_object&&)
+ {
+ // small
+ {
+ value const jv = parse(s0_);
+ check(jv.as_object(), s0_, i0_.size());
+ }
+
+ // small, duplicate
+ {
+ value const jv = parse(
+ R"({"0":0,"1":1,"2":2,"3":3,"4":4,)"
+ R"("5":5,"6":6,"7":7,"8":8,"9":9,)"
+ R"("10":10,"11":11,"12":12,"13":13,"14":14,)"
+ R"("15":15,"10":10})");
+ check(jv.as_object(), s0_, i0_.size() + 1);
+ }
+
+ // large
+ {
+ value const jv = parse(s1_);
+ check(jv.as_object(), s1_, i1_.size());
+ }
+
+ // large, duplicate
+ {
+ value const jv = parse(
+ R"({"0":0,"1":1,"2":2,"3":3,"4":4,)"
+ R"("5":5,"6":6,"7":7,"8":8,"9":9,)"
+ R"("10":10,"11":11,"12":12,"13":13,"14":14,)"
+ R"("15":15,"16":16,"17":17,"18":18,"19":19,"10":10})");
+ check(jv.as_object(), s1_, i1_.size() + 1);
+ }
+ }
+
+ // object()
+ {
+ object o;
+ BOOST_TEST(o.empty());
+ BOOST_TEST(o.size() == 0);
+ BOOST_TEST(o.capacity() == 0);
+ }
+
+ // object(storage_ptr)
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(sp);
+ check_storage(o, sp);
+ BOOST_TEST(o.empty());
+ BOOST_TEST(o.size() == 0);
+ BOOST_TEST(o.capacity() == 0);
+ });
+
+ // object(std::size_t, storage_ptr)
+ {
+ // small
+ {
+ object o(size0_);
+ BOOST_TEST(o.empty());
+ BOOST_TEST(o.size() == 0);
+ BOOST_TEST(o.capacity() == size0_);
+ }
+
+ // small
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(size0_, sp);
+ check_storage(o, sp);
+ BOOST_TEST(o.empty());
+ BOOST_TEST(o.size() == 0);
+ BOOST_TEST(o.capacity() == size0_);
+ });
+
+ // large
+ {
+ object o(size1_);
+ BOOST_TEST(o.empty());
+ BOOST_TEST(o.size() == 0);
+ BOOST_TEST(o.capacity() == size1_);
+ }
+
+ // large
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(size1_, sp);
+ check_storage(o, sp);
+ BOOST_TEST(o.empty());
+ BOOST_TEST(o.size() == 0);
+ BOOST_TEST(o.capacity() == size1_);
+ });
+ }
+
+ // object(InputIt, InputIt, size_type, storage_ptr)
+ {
+ // empty range
+ {
+ // random-access iterator
+ std::vector<std::pair<string_view, value>> i1;
+ object o1(i1.begin(), i1.end());
+ BOOST_TEST(o1.empty());
+
+ // bidirectional iterator
+ std::map<string_view, value> i2;
+ object o2(i2.begin(), i2.end());
+ BOOST_TEST(o2.empty());
+
+ // forward iterator
+ std::forward_list<std::pair<string_view, value>> i3;
+ object o3(i3.begin(), i3.end());
+ BOOST_TEST(o3.empty());
+
+ // input iterator
+ auto const it = make_input_iterator(i3.begin());
+ object o4(it, it);
+ BOOST_TEST(o4.empty());
+ }
+
+ // small
+ {
+ object o(i0_.begin(), i0_.end());
+ check(o, s0_, i0_.size());
+ }
+
+ // small, ForwardIterator
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(i0_.begin(), i0_.end(), size0_ + 1, sp);
+ BOOST_TEST(! o.empty());
+ check(o, s0_, size0_ + 1);
+ check_storage(o, sp);
+ });
+
+ // small, InputIterator
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(
+ make_input_iterator(i0_.begin()),
+ make_input_iterator(i0_.end()), size0_ + 1, sp);
+ BOOST_TEST(! o.empty());
+ BOOST_TEST(o.capacity() == size0_ + 1);
+ check(o, s0_, size0_ + 1);
+ check_storage(o, sp);
+ });
+
+ // large
+ {
+ object o(i1_.begin(), i1_.end());
+ check(o, s1_, i1_.size());
+ }
+
+ // large, ForwardIterator
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(i1_.begin(), i1_.end(), size1_ + 1, sp);
+ BOOST_TEST(! o.empty());
+ BOOST_TEST(o.capacity() == size1_ + 1);
+ check(o, s1_, size1_ + 1);
+ check_storage(o, sp);
+ });
+
+ // large, InputIterator
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(
+ make_input_iterator(i1_.begin()),
+ make_input_iterator(i1_.end()), size1_ + 1, sp);
+ BOOST_TEST(! o.empty());
+ BOOST_TEST(o.capacity() == size1_ + 1);
+ check(o, s1_, size1_ + 1);
+ check_storage(o, sp);
+ });
+ }
+
+ // object(object&&)
+ {
+ object o1(i0_);
+ check(o1, s0_);
+ auto const sp =
+ storage_ptr{};
+ object o2(std::move(o1));
+ BOOST_TEST(o1.empty());
+ BOOST_TEST(o1.size() == 0);
+ check(o2, s0_);
+ check_storage(o1, sp);
+ check_storage(o2, sp);
+ }
+
+ // object(object&&, storage_ptr)
+ {
+ // small
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o1(i0_);
+ object o2(std::move(o1), sp);
+ BOOST_TEST(! o1.empty());
+ check(o2, s0_, i0_.size());
+ check_storage(o1,
+ storage_ptr{});
+ check_storage(o2, sp);
+ });
+
+ // large
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o1(i1_);
+ object o2(std::move(o1), sp);
+ BOOST_TEST(! o1.empty());
+ check(o2, s1_, i1_.size());
+ check_storage(o1,
+ storage_ptr{});
+ check_storage(o2, sp);
+ });
+ }
+
+ // object(pilfered<object>)
+ {
+ {
+ auto const sp =
+ make_shared_resource<unique_resource>();
+ object o1(i0_, sp);
+ object o2(pilfer(o1));
+ BOOST_TEST(
+ o1.storage() == storage_ptr());
+ BOOST_TEST(
+ *o2.storage() == *sp);
+ BOOST_TEST(o1.empty());
+ check(o2, s0_, i0_.size());
+ }
+
+ // ensure pilfered-from objects
+ // are trivially destructible
+ {
+ object o1(make_shared_resource<
+ monotonic_resource>());
+ object o2(pilfer(o1));
+ BOOST_TEST(o1.storage().get() ==
+ storage_ptr().get());
+ }
+ }
+
+ auto const sp =
+ make_shared_resource<
+ unique_resource>();
+ auto const sp0 = storage_ptr{};
+
+ // object(object const&)
+ {
+ // small
+ {
+ object o1(i0_);
+ object o2(o1);
+ BOOST_TEST(! o1.empty());
+ check(o2, s0_, i0_.size());
+ }
+
+ // large
+ {
+ object o1(i1_);
+ object o2(o1);
+ BOOST_TEST(! o1.empty());
+ check(o2, s1_, i1_.size());
+ }
+ }
+
+ // object(object const&, storage_ptr)
+ {
+ // small
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o1(i0_);
+ object o2(o1, sp);
+ BOOST_TEST(! o1.empty());
+ check(o2, s0_, i0_.size());
+ check_storage(o2, sp);
+ });
+
+ // large
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o1(i1_);
+ object o2(o1, sp);
+ BOOST_TEST(! o1.empty());
+ check(o2, s1_, i1_.size());
+ check_storage(o2, sp);
+ });
+ }
+
+ // object(initializer_list, storage_ptr)
+ {
+ // small
+ {
+ object o(i0_);
+ check(o, s0_, i0_.size());
+ }
+
+ // small
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(i0_, sp);
+ check(o, s0_, i0_.size());
+ check_storage(o, sp);
+ });
+
+ // large
+ {
+ object o(i1_);
+ check(o, s1_, i1_.size());
+ }
+
+ // large
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(i1_, sp);
+ check(o, s1_, i1_.size());
+ check_storage(o, sp);
+ });
+ }
+
+ // object(initializer_list, std::size_t, storage_ptr)
+ {
+ // small
+ {
+ object o(i0_, size0_ + 1);
+ check(o, s0_, size0_ + 1);
+ }
+
+ // small
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(i0_, size0_ + 1, sp);
+ BOOST_TEST(
+ *o.storage() == *sp);
+ check(o, s0_, size0_ + 1);
+ });
+ }
+
+ // operator=(object const&)
+ {
+ {
+ object o1(i0_);
+ object o2;
+ o2 = o1;
+ check(o1, s0_, i0_.size());
+ check(o2, s0_, i0_.size());
+ check_storage(o1,
+ storage_ptr{});
+ check_storage(o2,
+ storage_ptr{});
+ }
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o1(i0_);
+ object o2(sp);
+ o2 = o1;
+ check(o1, s0_, i0_.size());
+ check(o2, s0_, i0_.size());
+ check_storage(o1,
+ storage_ptr{});
+ check_storage(o2, sp);
+ });
+
+ // self-assign
+ {
+ object o1(i0_);
+ object const& o2(o1);
+ o1 = o2;
+ check(o1, s0_, i0_.size());
+ }
+
+ // copy from child
+ {
+ object o({
+ {"a", 1}, {"b",
+ { {"a", 1}, {"b", true}, {"c", "hello"} }
+ }, {"c", "hello"}});
+ o = o["b"].as_object();
+ check(o, 3);
+ }
+ }
+
+ // operator=(object&&)
+ {
+ {
+ object o1({
+ {"a", 1},
+ {"b", true},
+ {"c", "hello"}});
+ object o2;
+ o2 = std::move(o1);
+ check(o2, 3);
+ BOOST_TEST(o1.empty());
+ check_storage(o1,
+ storage_ptr{});
+ check_storage(o2,
+ storage_ptr{});
+ }
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o1({
+ {"a", 1},
+ {"b", true},
+ {"c", "hello"}});
+ object o2(sp);
+ o2 = std::move(o1);
+ check(o1, 3);
+ check(o2, 3);
+ check_storage(o1,
+ storage_ptr{});
+ check_storage(o2, sp);
+ });
+
+ // self-move
+ {
+ object o1({
+ {"a", 1},
+ {"b", true},
+ {"c", "hello"}});
+ object const& o2(o1);
+ o1 = std::move(o2);
+ check(o1, 3);
+ }
+
+ // move from child
+ {
+ object o({
+ {"a", 1}, {"b",
+ { {"a", 1}, {"b", true}, {"c", "hello"} }
+ }, {"c", "hello"}});
+ o = std::move(o["b"].as_object());
+ check(o, 3);
+ }
+ }
+
+ // operator=(initializer_list)
+ {
+ {
+ object o;
+ o = {
+ {"a", 1},
+ {"b", true},
+ {"c", "hello"} },
+ check(o, 3);
+ check_storage(o,
+ storage_ptr{});
+ }
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(sp);
+ o = {
+ {"a", 1},
+ {"b", true},
+ {"c", "hello"} },
+ BOOST_TEST(
+ *o.storage() == *sp);
+ check(o, 3);
+ check_storage(o, sp);
+ });
+
+ // assign from child
+ {
+ object o = {
+ { "k1", 1 },
+ { "k2", 2 },
+ { "k3", 3 } };
+ o = { { "k2", o["k2"] } };
+ BOOST_TEST(
+ o == object({ { "k2", 2 } }));
+ }
+ }
+ }
+
+ void
+ testIterators()
+ {
+ object o({
+ {"a", 1},
+ {"b", true},
+ {"c", "hello"}});
+ auto const& co = o;
+ object no;
+ auto const& cno = no;
+
+ // empty container
+ {
+ BOOST_TEST(no.begin() == no.end());
+ BOOST_TEST(cno.begin() == cno.end());
+ BOOST_TEST(no.cbegin() == no.cend());
+ }
+
+ // begin()
+ {
+ auto it = o.begin();
+ BOOST_TEST(it->key() == "a"); ++it;
+ BOOST_TEST(it->key() == "b"); it++;
+ BOOST_TEST(it->key() == "c"); ++it;
+ BOOST_TEST(it == o.end());
+ }
+
+ // begin() const
+ {
+ auto it = co.begin();
+ BOOST_TEST(it->key() == "a"); ++it;
+ BOOST_TEST(it->key() == "b"); it++;
+ BOOST_TEST(it->key() == "c"); ++it;
+ BOOST_TEST(it == co.end());
+ }
+
+ // cbegin()
+ {
+ auto it = o.cbegin();
+ BOOST_TEST(it->key() == "a"); ++it;
+ BOOST_TEST(it->key() == "b"); it++;
+ BOOST_TEST(it->key() == "c"); ++it;
+ BOOST_TEST(it == o.cend());
+ }
+
+ // end()
+ {
+ auto it = o.end();
+ --it; BOOST_TEST(it->key() == "c");
+ it--; BOOST_TEST(it->key() == "b");
+ --it; BOOST_TEST(it->key() == "a");
+ BOOST_TEST(it == o.begin());
+ }
+
+ // end() const
+ {
+ auto it = co.end();
+ --it; BOOST_TEST(it->key() == "c");
+ it--; BOOST_TEST(it->key() == "b");
+ --it; BOOST_TEST(it->key() == "a");
+ BOOST_TEST(it == co.begin());
+ }
+
+ // cend()
+ {
+ auto it = o.cend();
+ --it; BOOST_TEST(it->key() == "c");
+ it--; BOOST_TEST(it->key() == "b");
+ --it; BOOST_TEST(it->key() == "a");
+ BOOST_TEST(it == o.cbegin());
+ }
+
+ // rbegin()
+ {
+ auto it = o.rbegin();
+ BOOST_TEST(it->key() == "c"); ++it;
+ BOOST_TEST(it->key() == "b"); it++;
+ BOOST_TEST(it->key() == "a"); ++it;
+ BOOST_TEST(it == o.rend());
+ }
+
+ // rbegin() const
+ {
+ auto it = co.rbegin();
+ BOOST_TEST(it->key() == "c"); ++it;
+ BOOST_TEST(it->key() == "b"); it++;
+ BOOST_TEST(it->key() == "a"); ++it;
+ BOOST_TEST(it == co.rend());
+ }
+
+ // crbegin()
+ {
+ auto it = o.crbegin();
+ BOOST_TEST(it->key() == "c"); ++it;
+ BOOST_TEST(it->key() == "b"); it++;
+ BOOST_TEST(it->key() == "a"); ++it;
+ BOOST_TEST(it == o.crend());
+ }
+
+ // rend()
+ {
+ auto it = o.rend();
+ --it; BOOST_TEST(it->key() == "a");
+ it--; BOOST_TEST(it->key() == "b");
+ --it; BOOST_TEST(it->key() == "c");
+ BOOST_TEST(it == o.rbegin());
+ }
+
+ // rend() const
+ {
+ auto it = co.rend();
+ --it; BOOST_TEST(it->key() == "a");
+ it--; BOOST_TEST(it->key() == "b");
+ --it; BOOST_TEST(it->key() == "c");
+ BOOST_TEST(it == co.rbegin());
+ }
+
+ // crend()
+ {
+ auto it = o.crend();
+ --it; BOOST_TEST(it->key() == "a");
+ it--; BOOST_TEST(it->key() == "b");
+ --it; BOOST_TEST(it->key() == "c");
+ BOOST_TEST(it == o.crbegin());
+ }
+ }
+
+ //------------------------------------------------------
+
+ void
+ testCapacity()
+ {
+ BOOST_TEST(
+ object{}.size() < object{}.max_size());
+ }
+
+ //------------------------------------------------------
+
+ void
+ testModifiers()
+ {
+ DECLARE_INIT_LISTS;
+
+ // clear
+ {
+ // empty
+ {
+ object o;
+ o.clear();
+ BOOST_TEST(o.empty());
+ }
+
+ // small
+ {
+ object o(i0_);
+ BOOST_TEST(! o.empty());
+ o.clear();
+ BOOST_TEST(o.empty());
+ }
+
+ // large
+ {
+ object o(i1_);
+ BOOST_TEST(! o.empty());
+ o.clear();
+ BOOST_TEST(o.empty());
+ }
+ }
+
+ // insert(P&&)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(sp);
+ auto result = o.insert(
+ std::make_pair("x", 1));
+ BOOST_TEST(result.second);
+ BOOST_TEST(result.first->key() == "x");
+ BOOST_TEST(result.first->value().as_int64() == 1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(sp);
+ auto const p = std::make_pair("x", 1);
+ auto result = o.insert(p);
+ BOOST_TEST(result.second);
+ BOOST_TEST(result.first->key() == "x");
+ BOOST_TEST(result.first->value().as_int64() == 1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o({
+ {"a", 1},
+ {"b", 2},
+ {"c", 3}}, sp);
+ auto const result = o.insert(
+ std::make_pair("b", 4));
+ BOOST_TEST(
+ result.first->value().as_int64() == 2);
+ BOOST_TEST(! result.second);
+ });
+
+ // insert child
+ {
+ object o = {
+ { "k1", 1 },
+ { "k2", 2 },
+ { "k3", 3 } };
+ o.insert(std::pair<
+ string_view, value&>(
+ "k4", o["k2"]));
+ BOOST_TEST(o == object({
+ { "k1", 1 },
+ { "k2", 2 },
+ { "k3", 3 },
+ { "k4", 2 }}));
+ }
+ }
+
+ // insert(InputIt, InputIt)
+ {
+ // small
+ {
+ // ForwardIterator
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(sp);
+ o.insert(i0_.begin(), i0_.end());
+ check(o, s0_);
+ });
+
+ // InputIterator
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(sp);
+ o.insert(
+ make_input_iterator(i0_.begin()),
+ make_input_iterator(i0_.end()));
+ check(o, s0_);
+ });
+
+ // existing duplicate key, ForwardIterator
+ {
+ object o({{"0",0},{"1",1},{"2",2}});
+ init_list i = {{"2",nullptr},{"3",3}};
+ o.insert(i.begin(), i.end());
+ BOOST_TEST(o.capacity() <=
+ detail::small_object_size_);
+ check(o, R"({"0":0,"1":1,"2":2,"3":3})");
+ }
+
+ // existing duplicate key, InputIterator
+ {
+ object o({{"0",0},{"1",1},{"2",2}});
+ init_list i = {{"2",nullptr},{"3",3}};
+ o.insert(
+ make_input_iterator(i.begin()),
+ make_input_iterator(i.end()));
+ BOOST_TEST(o.capacity() <=
+ detail::small_object_size_);
+ check(o, R"({"0":0,"1":1,"2":2,"3":3})");
+ }
+
+ // new duplicate key, ForwardIterator
+ {
+ object o({{"0",0},{"1",1},{"2",2}});
+ init_list i = {{"3",3},{"4",4},{"3",5}};
+ o.insert(i.begin(), i.end());
+ BOOST_TEST(o.capacity() <=
+ detail::small_object_size_);
+ check(o, R"({"0":0,"1":1,"2":2,"3":3,"4":4})");
+ }
+
+ // new duplicate key, InputIterator
+ {
+ object o({{"0",0},{"1",1},{"2",2}});
+ init_list i = {{"3",3},{"4",4},{"3",5}};
+ o.insert(
+ make_input_iterator(i.begin()),
+ make_input_iterator(i.end()));
+ BOOST_TEST(o.capacity() <=
+ detail::small_object_size_);
+ check(o, R"({"0":0,"1":1,"2":2,"3":3,"4":4})");
+ }
+ }
+
+ // large, ForwardIterator
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(sp);
+ o.insert(i1_.begin(), i1_.end());
+ check(o, s1_);
+ });
+
+ // large, InputIterator
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(sp);
+ o.insert(
+ make_input_iterator(i1_.begin()),
+ make_input_iterator(i1_.end()));
+ check(o, s1_);
+ });
+ }
+
+ // insert(initializer_list)
+ {
+ // small
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(sp);
+ o.insert(i0_);
+ check(o, s0_);
+ });
+
+ // small, existing duplicate
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o({{"0",0},{"1",1},/*{"2",2},*/{"3",3},{"4",4}}, sp);
+ BOOST_TEST(o.capacity() <= detail::small_object_size_);
+ o.insert({{"2",2},{"3",3}});
+ BOOST_TEST(o.capacity() <= detail::small_object_size_);
+ check(o, R"({"0":0,"1":1,"2":2,"3":3,"4":4})");
+ });
+
+ // small, new duplicate
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o({{"0",0},{"1",1},/*{"2",2},{"3",3},*/{"4",4}}, sp);
+ BOOST_TEST(o.capacity() <= detail::small_object_size_);
+ o.insert({{"2",2},{"3",3},{"2",2}});
+ BOOST_TEST(o.capacity() <= detail::small_object_size_);
+ check(o, R"({"0":0,"1":1,"2":2,"3":3,"4":4})");
+ });
+
+ // large
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(sp);
+ o.insert(i1_);
+ check(o, s1_);
+ });
+
+ // large, existing duplicate
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o({
+ {"0",0},{"1",1},{"2",2},{"3",3},{"4",4},
+ {"5",5},{"6",6},{"7",7},{"8",8},{"9",9},
+ /*{"10",10},*/{"11",11},{"12",12},{"13",13},{"14",14},
+ {"15",15},{"16",16},{"17",17},{"18",18},{"19",19}}, sp);
+ BOOST_TEST(o.capacity() > detail::small_object_size_);
+ o.insert({{"10",10},{"11",11}});
+ BOOST_TEST(o.capacity() > detail::small_object_size_);
+ check(o, s1_);
+ });
+
+ // large, new duplicate
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o({
+ {"0",0},{"1",1},{"2",2},{"3",3},{"4",4},
+ {"5",5},{"6",6},{"7",7},{"8",8},{"9",9},
+ /*{"10",10},{"11",11},*/{"12",12},{"13",13},{"14",14},
+ {"15",15},{"16",16},{"17",17},{"18",18},{"19",19}},
+ detail::small_object_size_ + 1, sp);
+ BOOST_TEST(o.capacity() > detail::small_object_size_);
+ o.insert({{"10",10},{"11",11},{"10",10}});
+ BOOST_TEST(o.capacity() > detail::small_object_size_);
+ check(o, s1_);
+ });
+
+ // do rollback in ~revert_insert
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(sp);
+ o.insert({
+ { "a", { 1, 2, 3, 4 } } });
+ });
+
+ // insert child
+ {
+ object o = {
+ { "k1", 1 },
+ { "k2", 2 },
+ { "k3", 3 } };
+ o.insert({
+ { "k4", o["k2"] } });
+ BOOST_TEST(o == object({
+ { "k1", 1 },
+ { "k2", 2 },
+ { "k3", 3 },
+ { "k4", 2 }}));
+ }
+ }
+
+ // insert_or_assign(key, o);
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o({{"a", 1}}, sp);
+ o.insert_or_assign("a", str_);
+ BOOST_TEST(o["a"].is_string());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o({
+ {"a", 1},
+ {"b", 2},
+ {"c", 3}}, sp);
+ o.insert_or_assign("d", str_);
+ BOOST_TEST(o["d"].is_string());
+ BOOST_TEST(o.size() == 4);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o({{"a", 1}}, sp);
+ o.insert_or_assign("b", true);
+ o.insert_or_assign("c", "hello");
+ check(o, 3);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o({{"a", 1}}, sp);
+ BOOST_TEST(
+ ! o.insert_or_assign("a", 2).second);
+ BOOST_TEST(o["a"].as_int64() == 2);
+ });
+
+ // insert child
+ {
+ object o = {
+ { "k1", 1 },
+ { "k2", 2 },
+ { "k3", 3 } };
+ o.insert_or_assign(
+ "k4", o["k2"]);
+ BOOST_TEST(o == object({
+ { "k1", 1 },
+ { "k2", 2 },
+ { "k3", 3 },
+ { "k4", 2 }}));
+ }
+ }
+
+ // emplace(key, arg)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o(sp);
+ o.emplace("a", 1);
+ o.emplace("b", true);
+ o.emplace("c", "hello");
+ check(o, 3);
+ });
+
+ // emplace child
+ {
+ object o = {
+ { "k1", 1 },
+ { "k2", 2 },
+ { "k3", 3 } };
+ o.emplace(
+ "k4", o["k2"]);
+ BOOST_TEST(o == object({
+ { "k1", 1 },
+ { "k2", 2 },
+ { "k3", 3 },
+ { "k4", 2 }}));
+ }
+ }
+
+ // erase(pos)
+ {
+ // small
+ {
+ object o(i0_);
+ auto it = o.erase(o.find("10"));
+ BOOST_TEST(it->key() == "15");
+ BOOST_TEST(
+ it->value().as_int64() == 15);
+ BOOST_TEST(serialize(o) ==
+ R"({"0":0,"1":1,"2":2,"3":3,"4":4,)"
+ R"("5":5,"6":6,"7":7,"8":8,"9":9,)"
+ R"("15":15,"11":11,"12":12,"13":13,"14":14})");
+ }
+
+ // large
+ {
+ object o(i1_);
+ auto it = o.erase(o.find("10"));
+ BOOST_TEST(it->key() == "19");
+ BOOST_TEST(
+ it->value().as_int64() == 19);
+ BOOST_TEST(serialize(o) ==
+ R"({"0":0,"1":1,"2":2,"3":3,"4":4,)"
+ R"("5":5,"6":6,"7":7,"8":8,"9":9,)"
+ R"("19":19,"11":11,"12":12,"13":13,"14":14,)"
+ R"("15":15,"16":16,"17":17,"18":18})");
+ }
+ }
+
+ // erase(key)
+ {
+ {
+ object o({
+ {"a", 1},
+ {"b", true},
+ {"c", "hello"}});
+ BOOST_TEST(o.erase("b2") == 0);
+ check(o, 3);
+ }
+
+ {
+ object o({
+ {"a", 1},
+ {"b", true},
+ {"b2", 2},
+ {"c", "hello"}});
+ BOOST_TEST(o.erase("b2") == 1);
+ check(o, 4);
+ }
+ }
+
+ // swap(object&)
+ {
+ {
+ object o1 = {{"a",1}, {"b",true}, {"c", "hello"}};
+ object o2 = {{"d",{1,2,3}}};
+ swap(o1, o2);
+ BOOST_TEST(o1.size() == 1);
+ BOOST_TEST(o2.size() == 3);
+ BOOST_TEST(o1.count("d") == 1);
+ }
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o1 = {{"a",1}, {"b",true}, {"c", "hello"}};
+ object o2({{"d",{1,2,3}}}, sp);
+ swap(o1, o2);
+ BOOST_TEST(o1.size() == 1);
+ BOOST_TEST(o2.size() == 3);
+ BOOST_TEST(o1.count("d") == 1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ object o1({{"d",{1,2,3}}}, sp);
+ object o2 = {{"a",1}, {"b",true}, {"c", "hello"}};
+ swap(o1, o2);
+ BOOST_TEST(o1.size() == 3);
+ BOOST_TEST(o2.size() == 1);
+ BOOST_TEST(o2.count("d") == 1);
+ });
+ }
+ }
+
+ //------------------------------------------------------
+
+ void
+ testLookup()
+ {
+ object o0;
+ object o1({
+ {"a", 1},
+ {"b", true},
+ {"c", "hello"}});
+ auto const& co0 = o0;
+ auto const& co1 = o1;
+
+ // at(key)
+ {
+ BOOST_TEST(
+ o1.at("a").is_number());
+ BOOST_TEST_THROWS((o1.at("d")),
+ std::out_of_range);
+ }
+
+ // at(key) const
+ {
+ BOOST_TEST(
+ co1.at("a").is_number());
+ BOOST_TEST_THROWS((co1.at("d")),
+ std::out_of_range);
+ }
+
+ // operator[&](key)
+ {
+ object o({
+ {"a", 1},
+ {"b", true},
+ {"c", "hello"}});
+ BOOST_TEST(o.count("d") == 0);;
+ BOOST_TEST(o["a"].is_number());
+ BOOST_TEST(o["d"].is_null());
+ BOOST_TEST(o.count("d") == 1);
+ }
+
+ // count(key)
+ {
+ BOOST_TEST(o1.count("a") == 1);
+ BOOST_TEST(o1.count("d") == 0);
+ BOOST_TEST(o1.count("e") == 0);
+ }
+
+ // find(key)
+ // find(key) const
+ {
+ BOOST_TEST(
+ o0.find("") == o0.end());
+ BOOST_TEST(
+ o1.find("a")->key() == "a");
+ BOOST_TEST(
+ o1.find("e") == o1.end());
+
+ BOOST_TEST(
+ co0.find("") == co0.end());
+ BOOST_TEST(
+ co1.find("a")->key() == "a");
+ BOOST_TEST(
+ co1.find("e") == o1.end());
+ }
+
+ // contains(key)
+ {
+ BOOST_TEST(o1.contains("a"));
+ BOOST_TEST(! o1.contains("e"));
+ BOOST_TEST(! object().contains(""));
+ }
+
+ // if_contains(key)
+ // if_contains(key) const
+ {
+ BOOST_TEST(o1.if_contains("a")->is_int64());
+ BOOST_TEST(o1.if_contains("e") == nullptr);
+ BOOST_TEST(co1.if_contains("a")->is_int64());
+ BOOST_TEST(co1.if_contains("e") == nullptr);
+
+ *o1.if_contains("a") = 2;
+ BOOST_TEST(co1.if_contains("a")->as_int64() == 2);
+ }
+ }
+
+ void
+ testHashPolicy()
+ {
+ // reserve(size_type)
+ {
+ {
+ object o;
+ for(std::size_t i = 0; i < 10; ++i)
+ o.emplace(std::to_string(i), i);
+ o.reserve(15);
+ BOOST_TEST(o.capacity() >= 15);
+ o.reserve(20);
+ BOOST_TEST(o.capacity() >= 20);
+ }
+
+ {
+ object o;
+ o.reserve(3);
+ BOOST_TEST(o.capacity() == 3);
+ o.reserve(7);
+ BOOST_TEST(o.capacity() == 7);
+ }
+ }
+ }
+
+ //------------------------------------------------------
+
+ void
+ testImplementation()
+ {
+ // insert duplicate keys
+ {
+ object o({
+ {"a", 1},
+ {"b", true},
+ {"b", {1,2,3}},
+ {"c", "hello"}});
+ BOOST_TEST(o.at("a").as_int64() == 1);
+ BOOST_TEST(o.at("b").as_bool() == true);
+ BOOST_TEST(o.at("c").as_string() == "hello");
+ }
+
+ // destroy key_value_pair array with need_free=false
+ {
+ monotonic_resource mr;
+ object o({
+ {"a", 1},
+ {"b", true},
+ {"b", {1,2,3}},
+ {"c", "hello"}}, &mr);
+ }
+ }
+
+ static
+ string_view
+ make_key(
+ std::size_t i,
+ char* buf)
+ {
+ int constexpr base = 62;
+ char const* const alphabet =
+ "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
+ char* dest = buf;
+ do
+ {
+ *dest++ = alphabet[i%base];
+ i /= base;
+ }
+ while(i);
+ return { buf, static_cast<
+ std::size_t>(dest-buf) };
+ }
+
+ void
+ testCollisions()
+ {
+ int constexpr buckets =
+ detail::small_object_size_ + 1;
+ int constexpr collisions = 3;
+
+ //DECLARE_INIT_LISTS;
+
+ // find a set of keys that collide
+ std::vector<std::string> v;
+ object o;
+ o.reserve(buckets);
+ {
+ BOOST_TEST(
+ o.capacity() == buckets);
+ char buf[26];
+ auto const match =
+ o.t_->digest("0") % buckets;
+ v.push_back("0");
+ std::size_t i = 1;
+ for(;;)
+ {
+ auto s = make_key(i, buf);
+ if((o.t_->digest(s) %
+ buckets) == match)
+ {
+ v.push_back(std::string(
+ s.data(), s.size()));
+ if(v.size() >= collisions)
+ break;
+ }
+ ++i;
+ }
+ }
+
+ // ensure collisions are distinguishable
+ {
+ o.clear();
+ BOOST_TEST(
+ (o.t_->digest(v[0]) % buckets) ==
+ (o.t_->digest(v[1]) % buckets));
+ BOOST_TEST(
+ (o.t_->digest(v[1]) % buckets) ==
+ (o.t_->digest(v[2]) % buckets));
+ o.emplace(v[0], 1);
+ o.emplace(v[1], 2);
+ o.emplace(v[2], 3);
+ BOOST_TEST(o.at(v[0]).to_number<int>() == 1);
+ BOOST_TEST(o.at(v[1]).to_number<int>() == 2);
+ BOOST_TEST(o.at(v[2]).to_number<int>() == 3);
+ }
+
+ // erase k1
+ {
+ o.clear();
+ o.emplace(v[0], 1);
+ o.emplace(v[1], 2);
+ o.emplace(v[2], 3);
+ o.erase(v[0]);
+ BOOST_TEST(o.at(v[1]).to_number<int>() == 2);
+ BOOST_TEST(o.at(v[2]).to_number<int>() == 3);
+ }
+
+ // erase k2
+ {
+ o.clear();
+ o.emplace(v[0], 1);
+ o.emplace(v[1], 2);
+ o.emplace(v[2], 3);
+ o.erase(v[1]);
+ BOOST_TEST(o.at(v[0]).to_number<int>() == 1);
+ BOOST_TEST(o.at(v[2]).to_number<int>() == 3);
+ }
+
+ // erase k3
+ {
+ o.clear();
+ o.emplace(v[0], 1);
+ o.emplace(v[1], 2);
+ o.emplace(v[2], 3);
+ o.erase(v[2]);
+ BOOST_TEST(o.at(v[0]).to_number<int>() == 1);
+ BOOST_TEST(o.at(v[1]).to_number<int>() == 2);
+ }
+ }
+
+ void
+ testEquality()
+ {
+ BOOST_TEST(object({}) == object({}));
+ BOOST_TEST(object({}) != object({{"1",1},{"2",2}}));
+ BOOST_TEST(object({{"1",1},{"2",2},{"3",3}}) == object({{"1",1},{"2",2},{"3",3}}));
+ BOOST_TEST(object({{"1",1},{"2",2},{"3",3}}) != object({{"1",1},{"2",2}}));
+ BOOST_TEST(object({{"1",1},{"2",2},{"3",3}}) == object({{"3",3},{"2",2},{"1",1}}));
+ }
+
+ void
+ testAllocation()
+ {
+ {
+ checking_resource res;
+ object o(&res);
+ o.reserve(1);
+ }
+
+ {
+ checking_resource res;
+ object o(&res);
+ o.reserve(1000);
+ }
+
+ {
+ checking_resource res;
+ object o({std::make_pair("one", 1)}, &res);
+ }
+ }
+
+ void
+ testHash()
+ {
+ BOOST_TEST(check_hash_equal(
+ object(), object({})));
+ BOOST_TEST(expect_hash_not_equal(
+ object(), object({{"1",1},{"2",2}})));
+ BOOST_TEST(check_hash_equal(
+ object({{"a",1}, {"b",2}, {"c",3}}),
+ object({{"b",2}, {"c",3}, {"a",1}})));
+ BOOST_TEST(expect_hash_not_equal(
+ object({{"a",1}, {"b",2}, {"c",3}}),
+ object({{"b",2}, {"c",3}})));
+ }
+
+ void
+ run()
+ {
+ testDtor();
+ testCtors();
+ testIterators();
+ testCapacity();
+ testModifiers();
+ testLookup();
+ testHashPolicy();
+ testImplementation();
+ testCollisions();
+ testEquality();
+ testAllocation();
+ testHash();
+ }
+};
+
+TEST_SUITE(object_test, "boost.json.object");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/parse-vectors.hpp b/src/boost/libs/json/test/parse-vectors.hpp
new file mode 100644
index 000000000..dc120d966
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors.hpp
@@ -0,0 +1,1470 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#ifndef PARSE_VECTORS
+#define PARSE_VECTORS
+
+#include <boost/json/detail/config.hpp>
+#include <cstdlib>
+#include <type_traits>
+
+BOOST_JSON_NS_BEGIN
+
+struct parse_vectors
+{
+ struct item
+ {
+ char result;
+ string_view name;
+ string_view text;
+ };
+
+ using iterator = item const*;
+
+ iterator begin() const noexcept
+ {
+ return first_;
+ }
+
+ iterator end() const noexcept
+ {
+ return last_;
+ }
+
+ std::size_t
+ size() const noexcept
+ {
+ return last_ - first_;
+ }
+
+ inline parse_vectors() noexcept;
+
+private:
+ template<std::size_t N>
+ static
+ string_view
+ lit(char const (&s)[N])
+ {
+ return {s, N - 1};
+ }
+
+ iterator first_;
+ iterator last_;
+};
+
+parse_vectors::
+parse_vectors() noexcept
+{
+ static item const list[] = {
+ { 'i', "number_double_huge_neg_exp", lit("[123.456e-789]") },
+ { 'i', "number_huge_exp", lit("[0.4e006699999999999999999999999999999999999999999999999999999999999999999999999"
+ "99999999999999999999999999999999999999999999969999999006]") },
+ { 'i', "number_neg_int_huge_exp", lit("[-1e+9999]") },
+ { 'i', "number_pos_double_huge_exp", lit("[1.5e+9999]") },
+ { 'i', "number_real_neg_overflow", lit("[-123123e100000]") },
+ { 'i', "number_real_pos_overflow", lit("[123123e100000]") },
+ { 'i', "number_real_underflow", lit("[123e-10000000]") },
+ { 'i', "number_too_big_neg_int", lit("[-123123123123123123123123123123]") },
+ { 'i', "number_too_big_pos_int", lit("[100000000000000000000]") },
+ { 'i', "number_very_big_negative_int", lit("[-237462374673276894279832749832423479823246327846]") },
+ { 'i', "object_key_lone_2nd_surrogate", lit("{\"\\uDFAA\":0}") },
+ { 'i', "string_1st_surrogate_but_2nd_missing", lit("[\"\\uDADA\"]") },
+ { 'i', "string_1st_valid_surrogate_2nd_invalid", lit("[\"\\uD888\\u1234\"]") },
+ { 'i', "string_incomplete_surrogates_escape_valid", lit("[\"\\uD800\\uD800\\n\"]") },
+ { 'i', "string_incomplete_surrogate_and_escape_valid", lit("[\"\\uD800\\n\"]") },
+ { 'i', "string_incomplete_surrogate_pair", lit("[\"\\uDd1ea\"]") },
+ { 'i', "string_invalid_lonely_surrogate", lit("[\"\\ud800\"]") },
+ { 'i', "string_invalid_surrogate", lit("[\"\\ud800abc\"]") },
+ { 'i', "string_invalid_utf-8", lit("[\"\xFF""\"]") },
+ { 'i', "string_inverted_surrogates_U+1D11E", lit("[\"\\uDd1e\\uD834\"]") },
+ { 'i', "string_iso_latin_1", lit("[\"\xE9""\"]") },
+ { 'i', "string_lone_second_surrogate", lit("[\"\\uDFAA\"]") },
+ { 'i', "string_lone_utf8_continuation_byte", lit("[\"\x81""\"]") },
+ { 'i', "string_not_in_unicode_range", lit("[\"\xF4""\xBF""\xBF""\xBF""\"]") },
+ { 'i', "string_overlong_sequence_2_bytes", lit("[\"\xC0""\xAF""\"]") },
+ { 'i', "string_overlong_sequence_6_bytes", lit("[\"\xFC""\x83""\xBF""\xBF""\xBF""\xBF""\"]") },
+ { 'i', "string_overlong_sequence_6_bytes_null", lit("[\"\xFC""\x80""\x80""\x80""\x80""\x80""\"]") },
+ { 'i', "string_truncated-utf-8", lit("[\"\xE0""\xFF""\"]") },
+ { 'i', "string_UTF-16LE_with_BOM", lit("\xFF""\xFE""[\x00""\"\x00""\xE9""\x00""\"\x00""]\x00""") },
+ { 'i', "string_UTF-8_invalid_sequence", lit("[\"\xE6""\x97""\xA5""\xD1""\x88""\xFA""\"]") },
+ { 'i', "string_utf16BE_no_BOM", lit("\x00""[\x00""\"\x00""\xE9""\x00""\"\x00""]") },
+ { 'i', "string_utf16LE_no_BOM", lit("[\x00""\"\x00""\xE9""\x00""\"\x00""]\x00""") },
+ { 'i', "string_UTF8_surrogate_U+D800", lit("[\"\xED""\xA0""\x80""\"]") },
+ { 'i', "structure_500_nested_arrays", lit("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
+ "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
+ "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
+ "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
+ "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
+ "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
+ "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]") },
+ { 'i', "structure_UTF-8_BOM_empty_object", lit("\xEF""\xBB""\xBF""{}") },
+ { 'n', "array_1_true_without_comma", lit("[1 true]") },
+ { 'n', "array_a_invalid_utf8", lit("[a\xE5""]") },
+ { 'n', "array_colon_instead_of_comma", lit("[\"\": 1]") },
+ { 'n', "array_comma_after_close", lit("[\"\"],") },
+ { 'n', "array_comma_and_number", lit("[,1]") },
+ { 'n', "array_double_comma", lit("[1,,2]") },
+ { 'n', "array_double_extra_comma", lit("[\"x\",,]") },
+ { 'n', "array_extra_close", lit("[\"x\"]]") },
+ { 'n', "array_incomplete", lit("[\"x\"") },
+ { 'n', "array_incomplete_invalid_value", lit("[x") },
+ { 'n', "array_inner_array_no_comma", lit("[3[4]]") },
+ { 'n', "array_invalid_utf8", lit("[\xFF""]") },
+ { 'n', "array_items_separated_by_semicolon", lit("[1:2]") },
+ { 'n', "array_just_comma", lit("[,]") },
+ { 'n', "array_just_minus", lit("[-]") },
+ { 'n', "array_misclosed", lit("[}") },
+ { 'n', "array_missing_value", lit("[ , \"\"]") },
+ { 'n', "array_newlines_unclosed", lit("[\"a\",\x0A""4\x0A"",1,") },
+ { 'n', "array_number_and_several_commas", lit("[1,,]") },
+ { 'n', "array_spaces_vertical_tab_formfeed", lit("[\"\x0B""a\"\\f]") },
+ { 'n', "array_star_inside", lit("[*]") },
+ { 'n', "array_unclosed", lit("[\"\"") },
+ { 'n', "array_unclosed_trailing_comma", lit("[1,") },
+ { 'n', "array_unclosed_with_new_lines", lit("[1,\x0A""1\x0A"",1") },
+ { 'n', "array_unclosed_with_object_inside", lit("[{}") },
+ { 'n', "fail01", lit("[\"mismatch\"}") },
+ { 'n', "fail02", lit("[\"Unclosed array\"") },
+ { 'n', "fail03", lit("{unquoted_key: \"keys must be quoted\"}") },
+ { 'n', "fail05", lit("[\"double extra comma\",,]") },
+ { 'n', "fail06", lit("[ , \"<-- missing value\"]") },
+ { 'n', "fail07", lit("[\"Comma after the close\"],") },
+ { 'n', "fail08", lit("[\"Extra close\"]]") },
+ { 'n', "fail10", lit("{\"Extra value after close\": true} \"misplaced quoted value\"") },
+ { 'n', "fail11", lit("{\"Illegal expression\": 1 + 2}") },
+ { 'n', "fail12", lit("{\"Illegal invocation\": alert()}") },
+ { 'n', "fail13", lit("{\"Numbers cannot have leading zeroes\": 013}") },
+ { 'n', "fail14", lit("{\"Numbers cannot be hex\": 0x14}") },
+ { 'n', "fail15", lit("[\"Illegal backslash escape: \\x15\"]") },
+ { 'n', "fail16", lit("[\\naked]") },
+ { 'n', "fail17", lit("[\"Illegal backslash escape: \\017\"]") },
+ { 'n', "fail19", lit("{\"Missing colon\" null}") },
+ { 'n', "fail20", lit("{\"Double colon\":: null}") },
+ { 'n', "fail21", lit("{\"Comma instead of colon\", null}") },
+ { 'n', "fail22", lit("[\"Colon instead of comma\": false]") },
+ { 'n', "fail23", lit("[\"Bad value\", truth]") },
+ { 'n', "fail24", lit("['single quote']") },
+ { 'n', "fail25", lit("[\" tab character in string \"]") },
+ { 'n', "fail26", lit("[\"tab\\ character\\ in\\ string\\ \"]") },
+ { 'n', "fail27", lit("[\"line\x0A""break\"]") },
+ { 'n', "fail28", lit("[\"line\\\x0A""break\"]") },
+ { 'n', "fail29", lit("[0e]") },
+ { 'n', "fail30", lit("[0e+]") },
+ { 'n', "fail31", lit("[0e+-1]") },
+ { 'n', "fail32", lit("{\"Comma instead if closing brace\": true,") },
+ { 'n', "incomplete_false", lit("[fals]") },
+ { 'n', "incomplete_null", lit("[nul]") },
+ { 'n', "incomplete_true", lit("[tru]") },
+ { 'n', "multidigit_number_then_00", lit("123\x00""") },
+ { 'n', "number_++", lit("[++1234]") },
+ { 'n', "number_+1", lit("[+1]") },
+ { 'n', "number_+Inf", lit("[+Inf]") },
+ { 'n', "number_-01", lit("[-01]") },
+ { 'n', "number_-1.0.", lit("[-1.0.]") },
+ { 'n', "number_-2.", lit("[-2.]") },
+ { 'n', "number_-NaN", lit("[-NaN]") },
+ { 'n', "number_.-1", lit("[.-1]") },
+ { 'n', "number_.2e-3", lit("[.2e-3]") },
+ { 'n', "number_0.1.2", lit("[0.1.2]") },
+ { 'n', "number_0.3e+", lit("[0.3e+]") },
+ { 'n', "number_0.3e", lit("[0.3e]") },
+ { 'n', "number_0.e1", lit("[0.e1]") },
+ { 'n', "number_0e+", lit("[0e+]") },
+ { 'n', "number_0e", lit("[0e]") },
+ { 'n', "number_0_capital_E+", lit("[0E+]") },
+ { 'n', "number_0_capital_E", lit("[0E]") },
+ { 'n', "number_1.0e+", lit("[1.0e+]") },
+ { 'n', "number_1.0e-", lit("[1.0e-]") },
+ { 'n', "number_1.0e", lit("[1.0e]") },
+ { 'n', "number_1eE2", lit("[1eE2]") },
+ { 'n', "number_1_000", lit("[1 000.0]") },
+ { 'n', "number_2.e+3", lit("[2.e+3]") },
+ { 'n', "number_2.e-3", lit("[2.e-3]") },
+ { 'n', "number_2.e3", lit("[2.e3]") },
+ { 'n', "number_9.e+", lit("[9.e+]") },
+ { 'n', "number_expression", lit("[1+2]") },
+ { 'n', "number_hex_1_digit", lit("[0x1]") },
+ { 'n', "number_hex_2_digits", lit("[0x42]") },
+ { 'n', "number_Inf", lit("[Inf]") },
+ { 'n', "number_infinity", lit("[Infinity]") },
+ { 'n', "number_invalid+-", lit("[0e+-1]") },
+ { 'n', "number_invalid-negative-real", lit("[-123.123foo]") },
+ { 'n', "number_invalid-utf-8-in-bigger-int", lit("[123\xE5""]") },
+ { 'n', "number_invalid-utf-8-in-exponent", lit("[1e1\xE5""]") },
+ { 'n', "number_invalid-utf-8-in-int", lit("[0\xE5""]\x0A""") },
+ { 'n', "number_minus_infinity", lit("[-Infinity]") },
+ { 'n', "number_minus_sign_with_trailing_garbage", lit("[-foo]") },
+ { 'n', "number_minus_space_1", lit("[- 1]") },
+ { 'n', "number_NaN", lit("[NaN]") },
+ { 'n', "number_neg_int_starting_with_zero", lit("[-012]") },
+ { 'n', "number_neg_real_without_int_part", lit("[-.123]") },
+ { 'n', "number_neg_with_garbage_at_end", lit("[-1x]") },
+ { 'n', "number_real_garbage_after_e", lit("[1ea]") },
+ { 'n', "number_real_without_fractional_part", lit("[1.]") },
+ { 'n', "number_real_with_invalid_utf8_after_e", lit("[1e\xE5""]") },
+ { 'n', "number_starting_with_dot", lit("[.123]") },
+ { 'n', "number_U+FF11_fullwidth_digit_one", lit("[\xEF""\xBC""\x91""]") },
+ { 'n', "number_with_alpha", lit("[1.2a-3]") },
+ { 'n', "number_with_alpha_char", lit("[1.8011670033376514H-308]") },
+ { 'n', "number_with_leading_zero", lit("[012]") },
+ { 'n', "object_bad_value", lit("[\"x\", truth]") },
+ { 'n', "object_bracket_key", lit("{[: \"x\"}\x0A""") },
+ { 'n', "object_comma_instead_of_colon", lit("{\"x\", null}") },
+ { 'n', "object_comma_after_colon", lit("{\"x\":, \"y\":1}") },
+ { 'n', "object_double_colon", lit("{\"x\"::\"b\"}") },
+ { 'n', "object_emoji", lit("{\xF0""\x9F""\x87""\xA8""\xF0""\x9F""\x87""\xAD""}") },
+ { 'n', "object_garbage_at_end", lit("{\"a\":\"a\" 123}") },
+ { 'n', "object_just_comma", lit("{,}") },
+ { 'n', "object_key_with_single_quotes", lit("{key: 'value'}") },
+ { 'n', "object_missing_colon", lit("{\"a\" b}") },
+ { 'n', "object_missing_key", lit("{:\"b\"}") },
+ { 'n', "object_missing_semicolon", lit("{\"a\" \"b\"}") },
+ { 'n', "object_missing_value", lit("{\"a\":") },
+ { 'n', "object_no-colon", lit("{\"a\"") },
+ { 'n', "object_non_string_key", lit("{1:1}") },
+ { 'n', "object_non_string_key_but_huge_number_instead", lit("{9999E9999:1}") },
+ { 'n', "object_repeated_null_null", lit("{null:null,null:null}") },
+ { 'n', "object_several_trailing_commas", lit("{\"id\":0,,,,,}") },
+ { 'n', "object_single_quote", lit("{'a':0}") },
+ { 'n', "object_trailing_comment_open", lit("{\"a\":\"b\"}/**//") },
+ { 'n', "object_trailing_comment_slash_open_incomplete", lit("{\"a\":\"b\"}/") },
+ { 'n', "object_two_commas_in_a_row", lit("{\"a\":\"b\",,\"c\":\"d\"}") },
+ { 'n', "object_unquoted_key", lit("{a: \"b\"}") },
+ { 'n', "object_unterminated-value", lit("{\"a\":\"a") },
+ { 'n', "object_with_single_string", lit("{ \"foo\" : \"bar\", \"a\" }") },
+ { 'n', "object_with_trailing_garbage", lit("{\"a\":\"b\"}#") },
+ { 'n', "single_space", lit(" ") },
+ { 'n', "string_1_surrogate_then_escape", lit("[\"\\uD800\\\"]") },
+ { 'n', "string_1_surrogate_then_escape_u", lit("[\"\\uD800\\u\"]") },
+ { 'n', "string_1_surrogate_then_escape_u1", lit("[\"\\uD800\\u1\"]") },
+ { 'n', "string_1_surrogate_then_escape_u1x", lit("[\"\\uD800\\u1x\"]") },
+ { 'n', "string_accentuated_char_no_quotes", lit("[\xC3""\xA9""]") },
+ { 'n', "string_backslash_00", lit("[\"\\\x00""\"]") },
+ { 'n', "string_escaped_backslash_bad", lit("[\"\\\\\\\"]") },
+ { 'n', "string_escaped_ctrl_char_tab", lit("[\"\\ \"]") },
+ { 'n', "string_escaped_emoji", lit("[\"\\\xF0""\x9F""\x8C""\x80""\"]") },
+ { 'n', "string_escape_x", lit("[\"\\x00\"]") },
+ { 'n', "string_incomplete_escape", lit("[\"\\\"]") },
+ { 'n', "string_incomplete_escaped_character", lit("[\"\\u00A\"]") },
+ { 'n', "string_incomplete_surrogate", lit("[\"\\uD834\\uDd\"]") },
+ { 'n', "string_incomplete_surrogate_escape_invalid", lit("[\"\\uD800\\uD800\\x\"]") },
+ { 'n', "string_invalid-utf-8-in-escape", lit("[\"\\u\xE5""\"]") },
+ { 'n', "string_invalid_backslash_esc", lit("[\"\\a\"]") },
+ { 'n', "string_invalid_unicode_escape", lit("[\"\\uqqqq\"]") },
+ { 'n', "string_invalid_utf8_after_escape", lit("[\"\\\xE5""\"]") },
+ { 'n', "string_leading_uescaped_thinspace", lit("[\\u0020\"asd\"]") },
+ { 'n', "string_no_quotes_with_bad_escape", lit("[\\n]") },
+ { 'n', "string_single_doublequote", lit("\"") },
+ { 'n', "string_single_quote", lit("['single quote']") },
+ { 'n', "string_single_string_no_double_quotes", lit("abc") },
+ { 'n', "string_start_escape_unclosed", lit("[\"\\") },
+ { 'n', "string_unescaped_crtl_char", lit("[\"a\x00""a\"]") },
+ { 'n', "string_unescaped_newline", lit("[\"new\x0A""line\"]") },
+ { 'n', "string_unescaped_tab", lit("[\" \"]") },
+ { 'n', "string_unicode_CapitalU", lit("\"\\UA66D\"") },
+ { 'n', "string_with_trailing_garbage", lit("\"\"x") },
+ { 'n', "structure_100000_opening_arrays", lit("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+ "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[") },
+ { 'n', "structure_angle_bracket_.", lit("<.>") },
+ { 'n', "structure_angle_bracket_null", lit("[<null>]") },
+ { 'n', "structure_array_trailing_garbage", lit("[1]x") },
+ { 'n', "structure_array_with_extra_array_close", lit("[1]]") },
+ { 'n', "structure_array_with_unclosed_string", lit("[\"asd]") },
+ { 'n', "structure_ascii-unicode-identifier", lit("a\xC3""\xA5""") },
+ { 'n', "structure_capitalized_True", lit("[True]") },
+ { 'n', "structure_close_unopened_array", lit("1]") },
+ { 'n', "structure_comma_instead_of_closing_brace", lit("{\"x\": true,") },
+ { 'n', "structure_double_array", lit("[][]") },
+ { 'n', "structure_end_array", lit("]") },
+ { 'n', "structure_incomplete_UTF8_BOM", lit("\xEF""\xBB""{}") },
+ { 'n', "structure_lone-invalid-utf-8", lit("\xE5""") },
+ { 'n', "structure_lone-open-bracket", lit("[") },
+ { 'n', "structure_no_data", lit("") },
+ { 'n', "structure_null-byte-outside-string", lit("[\x00""]") },
+ { 'n', "structure_number_with_trailing_garbage", lit("2@") },
+ { 'n', "structure_object_followed_by_closing_object", lit("{}}") },
+ { 'n', "structure_object_unclosed_no_value", lit("{\"\":") },
+ { 'n', "structure_object_with_trailing_garbage", lit("{\"a\": true} \"x\"") },
+ { 'n', "structure_open_array_apostrophe", lit("['") },
+ { 'n', "structure_open_array_comma", lit("[,") },
+ { 'n', "structure_open_array_object", lit("[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":["
+ "{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\""
+ ":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\""
+ "\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[{\"\":[") },
+ { 'n', "structure_open_array_open_object", lit("[{") },
+ { 'n', "structure_open_array_open_string", lit("[\"a") },
+ { 'n', "structure_open_array_string", lit("[\"a\"") },
+ { 'n', "structure_open_object", lit("{") },
+ { 'n', "structure_open_object_close_array", lit("{]") },
+ { 'n', "structure_open_object_comma", lit("{,") },
+ { 'n', "structure_open_object_open_array", lit("{[") },
+ { 'n', "structure_open_object_open_string", lit("{\"a") },
+ { 'n', "structure_open_object_string_with_apostrophes", lit("{'a'") },
+ { 'n', "structure_open_open", lit("[\"\\{[\"\\{[\"\\{[\"\\{") },
+ { 'n', "structure_single_eacute", lit("\xE9""") },
+ { 'n', "structure_single_star", lit("*") },
+ { 'n', "structure_trailing_#", lit("{\"a\":\"b\"}#{}") },
+ { 'n', "structure_U+2060_word_joined", lit("[\xE2""\x81""\xA0""]") },
+ { 'n', "structure_uescaped_LF_before_string", lit("[\\u000A\"\"]") },
+ { 'n', "structure_unclosed_array", lit("[1") },
+ { 'n', "structure_unclosed_array_partial_null", lit("[ false, nul") },
+ { 'n', "structure_unclosed_array_unfinished_false", lit("[ true, fals") },
+ { 'n', "structure_unclosed_array_unfinished_true", lit("[ false, tru") },
+ { 'n', "structure_unclosed_object", lit("{\"asd\":\"asd\"") },
+ { 'n', "structure_unicode-identifier", lit("\xC3""\xA5""") },
+ { 'n', "structure_UTF8_BOM_no_data", lit("\xEF""\xBB""\xBF""") },
+ { 'n', "structure_whitespace_formfeed", lit("[\x0C""]") },
+ { 'n', "structure_whitespace_U+2060_word_joiner", lit("[\xE2""\x81""\xA0""]") },
+ { 'y', "array_arraysWithSpaces", lit("[[] ]") },
+ { 'y', "array_empty-string", lit("[\"\"]") },
+ { 'y', "array_empty", lit("[]") },
+ { 'y', "array_ending_with_newline", lit("[\"a\"]") },
+ { 'y', "array_false", lit("[false]") },
+ { 'y', "array_heterogeneous", lit("[null, 1, \"1\", {}]") },
+ { 'y', "array_null", lit("[null]") },
+ { 'y', "array_with_1_and_newline", lit("[1\x0A""]") },
+ { 'y', "array_with_leading_space", lit(" [1]") },
+ { 'y', "array_with_several_null", lit("[1,null,null,null,2]") },
+ { 'y', "array_with_trailing_space", lit("[2] ") },
+ { 'y', "number", lit("[123e65]") },
+ { 'y', "number_0e+1", lit("[0e+1]") },
+ { 'y', "number_0e1", lit("[0e1]") },
+ { 'y', "number_after_space", lit("[ 4]") },
+ { 'y', "number_double_close_to_zero", lit("[-0.0000000000000000000000000000000000000000000000000000000000000000000000000000"
+ "01]\x0A""") },
+ { 'y', "number_int_with_exp", lit("[20e1]") },
+ { 'y', "number_minus_zero", lit("[-0]") },
+ { 'y', "number_negative_int", lit("[-123]") },
+ { 'y', "number_negative_one", lit("[-1]") },
+ { 'y', "number_negative_zero", lit("[-0]") },
+ { 'y', "number_real_capital_e", lit("[1E22]") },
+ { 'y', "number_real_capital_e_neg_exp", lit("[1E-2]") },
+ { 'y', "number_real_capital_e_pos_exp", lit("[1E+2]") },
+ { 'y', "number_real_exponent", lit("[123e45]") },
+ { 'y', "number_real_fraction_exponent", lit("[123.456e78]") },
+ { 'y', "number_real_neg_exp", lit("[1e-2]") },
+ { 'y', "number_real_pos_exponent", lit("[1e+2]") },
+ { 'y', "number_simple_int", lit("[123]") },
+ { 'y', "number_simple_real", lit("[123.456789]") },
+ { 'y', "object", lit("{\"asd\":\"sdf\", \"dfg\":\"fgh\"}") },
+ { 'y', "object_basic", lit("{\"asd\":\"sdf\"}") },
+ { 'y', "object_duplicated_key", lit("{\"a\":\"b\",\"a\":\"c\"}") },
+ { 'y', "object_duplicated_key_and_value", lit("{\"a\":\"b\",\"a\":\"b\"}") },
+ { 'y', "object_empty", lit("{}") },
+ { 'y', "object_empty_key", lit("{\"\":0}") },
+ { 'y', "object_escaped_null_in_key", lit("{\"foo\\u0000bar\": 42}") },
+ { 'y', "object_extreme_numbers", lit("{ \"min\": -1.0e+28, \"max\": 1.0e+28 }") },
+ { 'y', "object_long_strings", lit("{\"x\":[{\"id\": \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"}], \"id\": \"xxxxx"
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"}") },
+ { 'y', "object_simple", lit("{\"a\":[]}") },
+ { 'y', "object_string_unicode", lit("{\"title\":\"\\u041f\\u043e\\u043b\\u0442\\u043e\\u0440\\u0430 \\u0417\\u0435\\u"
+ "043c\\u043b\\u0435\\u043a\\u043e\\u043f\\u0430\" }") },
+ { 'y', "object_with_newlines", lit("{\x0A""\"a\": \"b\"\x0A""}") },
+ { 'y', "pass01", lit("[\x0A"" \"JSON Test Pattern pass1\",\x0A"" {\"object with 1 member\":[\"ar"
+ "ray with 1 element\"]},\x0A"" {},\x0A"" [],\x0A"" -42,\x0A"" true,\x0A"""
+ " false,\x0A"" null,\x0A"" {\x0A"" \"integer\": 1234567890,\x0A"" "
+ " \"real\": -9876.543210,\x0A"" \"e\": 0.123456789e-12,\x0A"" "
+ "\"E\": 1.234567890E+34,\x0A"" \"\": 23456789012E66,\x0A"" \"zero\""
+ ": 0,\x0A"" \"one\": 1,\x0A"" \"space\": \" \",\x0A"" \"quote"
+ "\": \"\\\"\",\x0A"" \"backslash\": \"\\\\\",\x0A"" \"controls\": \""
+ "\\b\\f\\n\\r\\t\",\x0A"" \"slash\": \"/ & \\/\",\x0A"" \"alpha\": \""
+ "abcdefghijklmnopqrstuvwyz\",\x0A"" \"ALPHA\": \"ABCDEFGHIJKLMNOPQRSTUVWYZ\""
+ ",\x0A"" \"digit\": \"0123456789\",\x0A"" \"0123456789\": \"digit\","
+ "\x0A"" \"special\": \"`1~!@#$%^&*()_+-={':[,]}|;.</>?\",\x0A"" \"he"
+ "x\": \"\\u0123\\u4567\\u89AB\\uCDEF\\uabcd\\uef4A\",\x0A"" \"true\": true,"
+ "\x0A"" \"false\": false,\x0A"" \"null\": null,\x0A"" \"array"
+ "\":[ ],\x0A"" \"object\":{ },\x0A"" \"address\": \"50 St. James S"
+ "treet\",\x0A"" \"url\": \"http://www.JSON.org/\",\x0A"" \"comment\""
+ ": \"// /* <!-- --\",\x0A"" \"# -- --> */\": \" \",\x0A"" \" s p a c"
+ " e d \" :[1,2 , 3\x0A""\x0A"",\x0A""\x0A""4 , 5 , 6 ,7 "
+ " ],\"compact\":[1,2,3,4,5,6,7],\x0A"" \"jsontext\": \"{\\\"object wi"
+ "th 1 member\\\":[\\\"array with 1 element\\\"]}\",\x0A"" \"quotes\": \"&#3"
+ "4; \\u0022 %22 0x22 034 &#x22;\",\x0A"" \"\\/\\\\\\\"\\uCAFE\\uBABE\\uAB98"
+ "\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?\"\x0A"": \"A "
+ "key can be any string\"\x0A"" },\x0A"" 0.5 ,98.6\x0A"",\x0A""99.44\x0A"",\x0A"""
+ "\x0A""1066,\x0A""1e1,\x0A""0.1e1,\x0A""1e-1,\x0A""1e00,2e+00,2e-00\x0A"",\"rosebu"
+ "d\"]") },
+ { 'y', "pass02", lit("[[[[[[[[[[[[[[[[[[[\"Not too deep\"]]]]]]]]]]]]]]]]]]]") },
+ { 'y', "pass03", lit("{\x0A"" \"JSON Test Pattern pass3\": {\x0A"" \"The outermost value\": "
+ "\"must be an object or array.\",\x0A"" \"In this test\": \"It is an object"
+ ".\"\x0A"" }\x0A""}\x0A""") },
+ { 'y', "string_1_2_3_bytes_UTF-8_sequences", lit("[\"\\u0060\\u012a\\u12AB\"]") },
+ { 'y', "string_accepted_surrogate_pair", lit("[\"\\uD801\\udc37\"]") },
+ { 'y', "string_accepted_surrogate_pairs", lit("[\"\\ud83d\\ude39\\ud83d\\udc8d\"]") },
+ { 'y', "string_allowed_escapes", lit("[\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"]") },
+ { 'y', "string_backslash_and_u_escaped_zero", lit("[\"\\\\u0000\"]") },
+ { 'y', "string_backslash_doublequotes", lit("[\"\\\"\"]") },
+ { 'y', "string_comments", lit("[\"a/*b*/c/*d//e\"]") },
+ { 'y', "string_double_escape_a", lit("[\"\\\\a\"]") },
+ { 'y', "string_double_escape_n", lit("[\"\\\\n\"]") },
+ { 'y', "string_escaped_control_character", lit("[\"\\u0012\"]") },
+ { 'y', "string_escaped_noncharacter", lit("[\"\\uFFFF\"]") },
+ { 'y', "string_in_array", lit("[\"asd\"]") },
+ { 'y', "string_in_array_with_leading_space", lit("[ \"asd\"]") },
+ { 'y', "string_last_surrogates_1_and_2", lit("[\"\\uDBFF\\uDFFF\"]") },
+ { 'y', "string_nbsp_uescaped", lit("[\"new\\u00A0line\"]") },
+ { 'y', "string_nonCharacterInUTF-8_U+10FFFF", lit("[\"\xF4""\x8F""\xBF""\xBF""\"]") },
+ { 'y', "string_nonCharacterInUTF-8_U+FFFF", lit("[\"\xEF""\xBF""\xBF""\"]") },
+ { 'y', "string_null_escape", lit("[\"\\u0000\"]") },
+ { 'y', "string_one-byte-utf-8", lit("[\"\\u002c\"]") },
+ { 'y', "string_pi", lit("[\"\xCF""\x80""\"]") },
+ { 'y', "string_reservedCharacterInUTF-8_U+1BFFF", lit("[\"\xF0""\x9B""\xBF""\xBF""\"]") },
+ { 'y', "string_simple_ascii", lit("[\"asd \"]") },
+ { 'y', "string_space", lit("\" \"") },
+ { 'y', "string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF", lit("[\"\\uD834\\uDd1e\"]") },
+ { 'y', "string_three-byte-utf-8", lit("[\"\\u0821\"]") },
+ { 'y', "string_two-byte-utf-8", lit("[\"\\u0123\"]") },
+ { 'y', "string_u+2028_line_sep", lit("[\"\xE2""\x80""\xA8""\"]") },
+ { 'y', "string_u+2029_par_sep", lit("[\"\xE2""\x80""\xA9""\"]") },
+ { 'y', "string_uEscape", lit("[\"\\u0061\\u30af\\u30EA\\u30b9\"]") },
+ { 'y', "string_uescaped_newline", lit("[\"new\\u000Aline\"]") },
+ { 'y', "string_unescaped_char_delete", lit("[\"\"]") },
+ { 'y', "string_unicode", lit("[\"\\uA66D\"]") },
+ { 'y', "string_unicodeEscapedBackslash", lit("[\"\\u005C\"]") },
+ { 'y', "string_unicode_2", lit("[\"\xE2""\x8D""\x82""\xE3""\x88""\xB4""\xE2""\x8D""\x82""\"]") },
+ { 'y', "string_unicode_escaped_double_quote", lit("[\"\\u0022\"]") },
+ { 'y', "string_unicode_U+10FFFE_nonchar", lit("[\"\\uDBFF\\uDFFE\"]") },
+ { 'y', "string_unicode_U+1FFFE_nonchar", lit("[\"\\uD83F\\uDFFE\"]") },
+ { 'y', "string_unicode_U+200B_ZERO_WIDTH_SPACE", lit("[\"\\u200B\"]") },
+ { 'y', "string_unicode_U+2064_invisible_plus", lit("[\"\\u2064\"]") },
+ { 'y', "string_unicode_U+FDD0_nonchar", lit("[\"\\uFDD0\"]") },
+ { 'y', "string_unicode_U+FFFE_nonchar", lit("[\"\\uFFFE\"]") },
+ { 'y', "string_utf8", lit("[\"\xE2""\x82""\xAC""\xF0""\x9D""\x84""\x9E""\"]") },
+ { 'y', "string_with_del_character", lit("[\"aa\"]") },
+ { 'y', "structure_lonely_false", lit("false") },
+ { 'y', "structure_lonely_int", lit("42") },
+ { 'y', "structure_lonely_negative_real", lit("-0.1") },
+ { 'y', "structure_lonely_null", lit("null") },
+ { 'y', "structure_lonely_string", lit("\"asd\"") },
+ { 'y', "structure_lonely_true", lit("true") },
+ { 'y', "structure_string_empty", lit("\"\"") },
+ { 'y', "structure_trailing_newline", lit("[\"a\"]\x0A""") },
+ { 'y', "structure_true_in_array", lit("[true]") },
+ { 'y', "structure_whitespace_array", lit(" [] ") },
+ { ' ', "", "" }
+ };
+ first_ = &list[0];
+ last_ = &list[std::extent<
+ decltype(list)>::value - 1];
+}
+
+BOOST_JSON_NS_END
+
+#endif
diff --git a/src/boost/libs/json/test/parse-vectors/i_number_double_huge_neg_exp.json b/src/boost/libs/json/test/parse-vectors/i_number_double_huge_neg_exp.json
new file mode 100644
index 000000000..ae4c7b71f
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_number_double_huge_neg_exp.json
@@ -0,0 +1 @@
+[123.456e-789] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_number_huge_exp.json b/src/boost/libs/json/test/parse-vectors/i_number_huge_exp.json
new file mode 100644
index 000000000..9b5efa236
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_number_huge_exp.json
@@ -0,0 +1 @@
+[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_number_neg_int_huge_exp.json b/src/boost/libs/json/test/parse-vectors/i_number_neg_int_huge_exp.json
new file mode 100644
index 000000000..3abd58a5c
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_number_neg_int_huge_exp.json
@@ -0,0 +1 @@
+[-1e+9999] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_number_pos_double_huge_exp.json b/src/boost/libs/json/test/parse-vectors/i_number_pos_double_huge_exp.json
new file mode 100644
index 000000000..e10a7eb62
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_number_pos_double_huge_exp.json
@@ -0,0 +1 @@
+[1.5e+9999] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_number_real_neg_overflow.json b/src/boost/libs/json/test/parse-vectors/i_number_real_neg_overflow.json
new file mode 100644
index 000000000..3d628a994
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_number_real_neg_overflow.json
@@ -0,0 +1 @@
+[-123123e100000] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_number_real_pos_overflow.json b/src/boost/libs/json/test/parse-vectors/i_number_real_pos_overflow.json
new file mode 100644
index 000000000..54d7d3dcd
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_number_real_pos_overflow.json
@@ -0,0 +1 @@
+[123123e100000] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_number_real_underflow.json b/src/boost/libs/json/test/parse-vectors/i_number_real_underflow.json
new file mode 100644
index 000000000..c5236eb26
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_number_real_underflow.json
@@ -0,0 +1 @@
+[123e-10000000] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_number_too_big_neg_int.json b/src/boost/libs/json/test/parse-vectors/i_number_too_big_neg_int.json
new file mode 100644
index 000000000..dfa384619
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_number_too_big_neg_int.json
@@ -0,0 +1 @@
+[-123123123123123123123123123123] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_number_too_big_pos_int.json b/src/boost/libs/json/test/parse-vectors/i_number_too_big_pos_int.json
new file mode 100644
index 000000000..338a8c3c0
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_number_too_big_pos_int.json
@@ -0,0 +1 @@
+[100000000000000000000] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_number_very_big_negative_int.json b/src/boost/libs/json/test/parse-vectors/i_number_very_big_negative_int.json
new file mode 100644
index 000000000..e2d9738c2
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_number_very_big_negative_int.json
@@ -0,0 +1 @@
+[-237462374673276894279832749832423479823246327846] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_object_key_lone_2nd_surrogate.json b/src/boost/libs/json/test/parse-vectors/i_object_key_lone_2nd_surrogate.json
new file mode 100644
index 000000000..5be7ebaf9
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_object_key_lone_2nd_surrogate.json
@@ -0,0 +1 @@
+{"\uDFAA":0} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_1st_surrogate_but_2nd_missing.json b/src/boost/libs/json/test/parse-vectors/i_string_1st_surrogate_but_2nd_missing.json
new file mode 100644
index 000000000..3b9e37c67
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_1st_surrogate_but_2nd_missing.json
@@ -0,0 +1 @@
+["\uDADA"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_1st_valid_surrogate_2nd_invalid.json b/src/boost/libs/json/test/parse-vectors/i_string_1st_valid_surrogate_2nd_invalid.json
new file mode 100644
index 000000000..487592832
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_1st_valid_surrogate_2nd_invalid.json
@@ -0,0 +1 @@
+["\uD888\u1234"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_UTF-16LE_with_BOM.json b/src/boost/libs/json/test/parse-vectors/i_string_UTF-16LE_with_BOM.json
new file mode 100644
index 000000000..2a79c0629
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_UTF-16LE_with_BOM.json
Binary files differ
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_UTF-8_invalid_sequence.json b/src/boost/libs/json/test/parse-vectors/i_string_UTF-8_invalid_sequence.json
new file mode 100644
index 000000000..e2a968a15
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_UTF-8_invalid_sequence.json
@@ -0,0 +1 @@
+["日шú"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_UTF8_surrogate_U+D800.json b/src/boost/libs/json/test/parse-vectors/i_string_UTF8_surrogate_U+D800.json
new file mode 100644
index 000000000..916bff920
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_UTF8_surrogate_U+D800.json
@@ -0,0 +1 @@
+["í €"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogate_and_escape_valid.json b/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogate_and_escape_valid.json
new file mode 100644
index 000000000..3cb11d229
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogate_and_escape_valid.json
@@ -0,0 +1 @@
+["\uD800\n"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogate_pair.json b/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogate_pair.json
new file mode 100644
index 000000000..38ec23bb0
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogate_pair.json
@@ -0,0 +1 @@
+["\uDd1ea"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogates_escape_valid.json b/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogates_escape_valid.json
new file mode 100644
index 000000000..c9cd6f6c3
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_incomplete_surrogates_escape_valid.json
@@ -0,0 +1 @@
+["\uD800\uD800\n"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_invalid_lonely_surrogate.json b/src/boost/libs/json/test/parse-vectors/i_string_invalid_lonely_surrogate.json
new file mode 100644
index 000000000..3abbd8d8d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_invalid_lonely_surrogate.json
@@ -0,0 +1 @@
+["\ud800"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_invalid_surrogate.json b/src/boost/libs/json/test/parse-vectors/i_string_invalid_surrogate.json
new file mode 100644
index 000000000..ffddc04f5
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_invalid_surrogate.json
@@ -0,0 +1 @@
+["\ud800abc"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_invalid_utf-8.json b/src/boost/libs/json/test/parse-vectors/i_string_invalid_utf-8.json
new file mode 100644
index 000000000..8e45a7eca
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_invalid_utf-8.json
@@ -0,0 +1 @@
+["ÿ"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_inverted_surrogates_U+1D11E.json b/src/boost/libs/json/test/parse-vectors/i_string_inverted_surrogates_U+1D11E.json
new file mode 100644
index 000000000..0d5456cc3
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_inverted_surrogates_U+1D11E.json
@@ -0,0 +1 @@
+["\uDd1e\uD834"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_iso_latin_1.json b/src/boost/libs/json/test/parse-vectors/i_string_iso_latin_1.json
new file mode 100644
index 000000000..9389c9823
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_iso_latin_1.json
@@ -0,0 +1 @@
+["é"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_lone_second_surrogate.json b/src/boost/libs/json/test/parse-vectors/i_string_lone_second_surrogate.json
new file mode 100644
index 000000000..1dbd397f3
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_lone_second_surrogate.json
@@ -0,0 +1 @@
+["\uDFAA"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_lone_utf8_continuation_byte.json b/src/boost/libs/json/test/parse-vectors/i_string_lone_utf8_continuation_byte.json
new file mode 100644
index 000000000..729337c0a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_lone_utf8_continuation_byte.json
@@ -0,0 +1 @@
+[""] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_not_in_unicode_range.json b/src/boost/libs/json/test/parse-vectors/i_string_not_in_unicode_range.json
new file mode 100644
index 000000000..df90a2916
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_not_in_unicode_range.json
@@ -0,0 +1 @@
+["ô¿¿¿"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_2_bytes.json b/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_2_bytes.json
new file mode 100644
index 000000000..c8cee5e0a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_2_bytes.json
@@ -0,0 +1 @@
+["À¯"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_6_bytes.json b/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_6_bytes.json
new file mode 100644
index 000000000..9a91da791
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_6_bytes.json
@@ -0,0 +1 @@
+["üƒ¿¿¿¿"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_6_bytes_null.json b/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_6_bytes_null.json
new file mode 100644
index 000000000..d24fffdd9
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_overlong_sequence_6_bytes_null.json
@@ -0,0 +1 @@
+["ü€€€€€"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_truncated-utf-8.json b/src/boost/libs/json/test/parse-vectors/i_string_truncated-utf-8.json
new file mode 100644
index 000000000..63c7777fb
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_truncated-utf-8.json
@@ -0,0 +1 @@
+["àÿ"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_utf16BE_no_BOM.json b/src/boost/libs/json/test/parse-vectors/i_string_utf16BE_no_BOM.json
new file mode 100644
index 000000000..57e5392ff
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_utf16BE_no_BOM.json
Binary files differ
diff --git a/src/boost/libs/json/test/parse-vectors/i_string_utf16LE_no_BOM.json b/src/boost/libs/json/test/parse-vectors/i_string_utf16LE_no_BOM.json
new file mode 100644
index 000000000..c49c1b25d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_string_utf16LE_no_BOM.json
Binary files differ
diff --git a/src/boost/libs/json/test/parse-vectors/i_structure_500_nested_arrays.json b/src/boost/libs/json/test/parse-vectors/i_structure_500_nested_arrays.json
new file mode 100644
index 000000000..711840589
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_structure_500_nested_arrays.json
@@ -0,0 +1 @@
+[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/i_structure_UTF-8_BOM_empty_object.json b/src/boost/libs/json/test/parse-vectors/i_structure_UTF-8_BOM_empty_object.json
new file mode 100644
index 000000000..22fdca1b2
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/i_structure_UTF-8_BOM_empty_object.json
@@ -0,0 +1 @@
+{} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_1_true_without_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_1_true_without_comma.json
new file mode 100644
index 000000000..c14e3f6b1
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_1_true_without_comma.json
@@ -0,0 +1 @@
+[1 true] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_a_invalid_utf8.json b/src/boost/libs/json/test/parse-vectors/n_array_a_invalid_utf8.json
new file mode 100644
index 000000000..38a86e2e6
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_a_invalid_utf8.json
@@ -0,0 +1 @@
+[aå] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_colon_instead_of_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_colon_instead_of_comma.json
new file mode 100644
index 000000000..0d02ad448
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_colon_instead_of_comma.json
@@ -0,0 +1 @@
+["": 1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_comma_after_close.json b/src/boost/libs/json/test/parse-vectors/n_array_comma_after_close.json
new file mode 100644
index 000000000..2ccba8d95
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_comma_after_close.json
@@ -0,0 +1 @@
+[""], \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_comma_and_number.json b/src/boost/libs/json/test/parse-vectors/n_array_comma_and_number.json
new file mode 100644
index 000000000..d2c84e374
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_comma_and_number.json
@@ -0,0 +1 @@
+[,1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_double_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_double_comma.json
new file mode 100644
index 000000000..0431712bc
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_double_comma.json
@@ -0,0 +1 @@
+[1,,2] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_double_extra_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_double_extra_comma.json
new file mode 100644
index 000000000..3f01d3129
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_double_extra_comma.json
@@ -0,0 +1 @@
+["x",,] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_extra_close.json b/src/boost/libs/json/test/parse-vectors/n_array_extra_close.json
new file mode 100644
index 000000000..c12f9fae1
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_extra_close.json
@@ -0,0 +1 @@
+["x"]] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_extra_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_extra_comma.json
new file mode 100644
index 000000000..5f8ce18e4
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_extra_comma.json
@@ -0,0 +1 @@
+["",] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_incomplete.json b/src/boost/libs/json/test/parse-vectors/n_array_incomplete.json
new file mode 100644
index 000000000..cc65b0b51
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_incomplete.json
@@ -0,0 +1 @@
+["x" \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_incomplete_invalid_value.json b/src/boost/libs/json/test/parse-vectors/n_array_incomplete_invalid_value.json
new file mode 100644
index 000000000..c21a8f6cf
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_incomplete_invalid_value.json
@@ -0,0 +1 @@
+[x \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_inner_array_no_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_inner_array_no_comma.json
new file mode 100644
index 000000000..c70b71647
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_inner_array_no_comma.json
@@ -0,0 +1 @@
+[3[4]] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_invalid_utf8.json b/src/boost/libs/json/test/parse-vectors/n_array_invalid_utf8.json
new file mode 100644
index 000000000..6099d3441
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_invalid_utf8.json
@@ -0,0 +1 @@
+[ÿ] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_items_separated_by_semicolon.json b/src/boost/libs/json/test/parse-vectors/n_array_items_separated_by_semicolon.json
new file mode 100644
index 000000000..d4bd7314c
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_items_separated_by_semicolon.json
@@ -0,0 +1 @@
+[1:2] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_just_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_just_comma.json
new file mode 100644
index 000000000..9d7077c68
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_just_comma.json
@@ -0,0 +1 @@
+[,] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_just_minus.json b/src/boost/libs/json/test/parse-vectors/n_array_just_minus.json
new file mode 100644
index 000000000..29501c6ca
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_just_minus.json
@@ -0,0 +1 @@
+[-] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_missing_value.json b/src/boost/libs/json/test/parse-vectors/n_array_missing_value.json
new file mode 100644
index 000000000..3a6ba86f3
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_missing_value.json
@@ -0,0 +1 @@
+[ , ""] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_newlines_unclosed.json b/src/boost/libs/json/test/parse-vectors/n_array_newlines_unclosed.json
new file mode 100644
index 000000000..646680065
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_newlines_unclosed.json
@@ -0,0 +1,3 @@
+["a",
+4
+,1, \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_number_and_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_number_and_comma.json
new file mode 100644
index 000000000..13f6f1d18
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_number_and_comma.json
@@ -0,0 +1 @@
+[1,] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_number_and_several_commas.json b/src/boost/libs/json/test/parse-vectors/n_array_number_and_several_commas.json
new file mode 100644
index 000000000..0ac408cb8
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_number_and_several_commas.json
@@ -0,0 +1 @@
+[1,,] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_spaces_vertical_tab_formfeed.json b/src/boost/libs/json/test/parse-vectors/n_array_spaces_vertical_tab_formfeed.json
new file mode 100644
index 000000000..6cd7cf585
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_spaces_vertical_tab_formfeed.json
@@ -0,0 +1 @@
+[" a"\f] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_star_inside.json b/src/boost/libs/json/test/parse-vectors/n_array_star_inside.json
new file mode 100644
index 000000000..5a5194647
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_star_inside.json
@@ -0,0 +1 @@
+[*] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_unclosed.json b/src/boost/libs/json/test/parse-vectors/n_array_unclosed.json
new file mode 100644
index 000000000..060733059
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_unclosed.json
@@ -0,0 +1 @@
+["" \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_unclosed_trailing_comma.json b/src/boost/libs/json/test/parse-vectors/n_array_unclosed_trailing_comma.json
new file mode 100644
index 000000000..6604698ff
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_unclosed_trailing_comma.json
@@ -0,0 +1 @@
+[1, \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_unclosed_with_new_lines.json b/src/boost/libs/json/test/parse-vectors/n_array_unclosed_with_new_lines.json
new file mode 100644
index 000000000..4f61de3fb
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_unclosed_with_new_lines.json
@@ -0,0 +1,3 @@
+[1,
+1
+,1 \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_array_unclosed_with_object_inside.json b/src/boost/libs/json/test/parse-vectors/n_array_unclosed_with_object_inside.json
new file mode 100644
index 000000000..043a87e2d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_array_unclosed_with_object_inside.json
@@ -0,0 +1 @@
+[{} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail01.json b/src/boost/libs/json/test/parse-vectors/n_fail01.json
new file mode 100644
index 000000000..ca5eb19dc
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail01.json
@@ -0,0 +1 @@
+["mismatch"} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail02.json b/src/boost/libs/json/test/parse-vectors/n_fail02.json
new file mode 100644
index 000000000..6b7c11e5a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail02.json
@@ -0,0 +1 @@
+["Unclosed array" \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail03.json b/src/boost/libs/json/test/parse-vectors/n_fail03.json
new file mode 100644
index 000000000..168c81eb7
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail03.json
@@ -0,0 +1 @@
+{unquoted_key: "keys must be quoted"} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail04.json b/src/boost/libs/json/test/parse-vectors/n_fail04.json
new file mode 100644
index 000000000..9de168bf3
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail04.json
@@ -0,0 +1 @@
+["extra comma",] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail05.json b/src/boost/libs/json/test/parse-vectors/n_fail05.json
new file mode 100644
index 000000000..ddf3ce3d2
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail05.json
@@ -0,0 +1 @@
+["double extra comma",,] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail06.json b/src/boost/libs/json/test/parse-vectors/n_fail06.json
new file mode 100644
index 000000000..ed91580e1
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail06.json
@@ -0,0 +1 @@
+[ , "<-- missing value"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail07.json b/src/boost/libs/json/test/parse-vectors/n_fail07.json
new file mode 100644
index 000000000..8a96af3e4
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail07.json
@@ -0,0 +1 @@
+["Comma after the close"], \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail08.json b/src/boost/libs/json/test/parse-vectors/n_fail08.json
new file mode 100644
index 000000000..b28479c6e
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail08.json
@@ -0,0 +1 @@
+["Extra close"]] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail09.json b/src/boost/libs/json/test/parse-vectors/n_fail09.json
new file mode 100644
index 000000000..5815574f3
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail09.json
@@ -0,0 +1 @@
+{"Extra comma": true,} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail10.json b/src/boost/libs/json/test/parse-vectors/n_fail10.json
new file mode 100644
index 000000000..5d8c0047b
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail10.json
@@ -0,0 +1 @@
+{"Extra value after close": true} "misplaced quoted value" \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail11.json b/src/boost/libs/json/test/parse-vectors/n_fail11.json
new file mode 100644
index 000000000..76eb95b45
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail11.json
@@ -0,0 +1 @@
+{"Illegal expression": 1 + 2} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail12.json b/src/boost/libs/json/test/parse-vectors/n_fail12.json
new file mode 100644
index 000000000..77580a452
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail12.json
@@ -0,0 +1 @@
+{"Illegal invocation": alert()} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail13.json b/src/boost/libs/json/test/parse-vectors/n_fail13.json
new file mode 100644
index 000000000..379406b59
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail13.json
@@ -0,0 +1 @@
+{"Numbers cannot have leading zeroes": 013} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail14.json b/src/boost/libs/json/test/parse-vectors/n_fail14.json
new file mode 100644
index 000000000..0ed366b38
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail14.json
@@ -0,0 +1 @@
+{"Numbers cannot be hex": 0x14} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail15.json b/src/boost/libs/json/test/parse-vectors/n_fail15.json
new file mode 100644
index 000000000..fc8376b60
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail15.json
@@ -0,0 +1 @@
+["Illegal backslash escape: \x15"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail16.json b/src/boost/libs/json/test/parse-vectors/n_fail16.json
new file mode 100644
index 000000000..3fe21d4b5
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail16.json
@@ -0,0 +1 @@
+[\naked] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail17.json b/src/boost/libs/json/test/parse-vectors/n_fail17.json
new file mode 100644
index 000000000..62b9214ae
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail17.json
@@ -0,0 +1 @@
+["Illegal backslash escape: \017"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail19.json b/src/boost/libs/json/test/parse-vectors/n_fail19.json
new file mode 100644
index 000000000..3b9c46fa9
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail19.json
@@ -0,0 +1 @@
+{"Missing colon" null} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail20.json b/src/boost/libs/json/test/parse-vectors/n_fail20.json
new file mode 100644
index 000000000..27c1af3e7
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail20.json
@@ -0,0 +1 @@
+{"Double colon":: null} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail21.json b/src/boost/libs/json/test/parse-vectors/n_fail21.json
new file mode 100644
index 000000000..62474573b
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail21.json
@@ -0,0 +1 @@
+{"Comma instead of colon", null} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail22.json b/src/boost/libs/json/test/parse-vectors/n_fail22.json
new file mode 100644
index 000000000..a7752581b
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail22.json
@@ -0,0 +1 @@
+["Colon instead of comma": false] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail23.json b/src/boost/libs/json/test/parse-vectors/n_fail23.json
new file mode 100644
index 000000000..494add1ca
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail23.json
@@ -0,0 +1 @@
+["Bad value", truth] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail24.json b/src/boost/libs/json/test/parse-vectors/n_fail24.json
new file mode 100644
index 000000000..caff239bf
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail24.json
@@ -0,0 +1 @@
+['single quote'] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail25.json b/src/boost/libs/json/test/parse-vectors/n_fail25.json
new file mode 100644
index 000000000..8b7ad23e0
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail25.json
@@ -0,0 +1 @@
+[" tab character in string "] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail26.json b/src/boost/libs/json/test/parse-vectors/n_fail26.json
new file mode 100644
index 000000000..845d26a6a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail26.json
@@ -0,0 +1 @@
+["tab\ character\ in\ string\ "] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail27.json b/src/boost/libs/json/test/parse-vectors/n_fail27.json
new file mode 100644
index 000000000..6b01a2ca4
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail27.json
@@ -0,0 +1,2 @@
+["line
+break"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail28.json b/src/boost/libs/json/test/parse-vectors/n_fail28.json
new file mode 100644
index 000000000..621a0101c
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail28.json
@@ -0,0 +1,2 @@
+["line\
+break"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail29.json b/src/boost/libs/json/test/parse-vectors/n_fail29.json
new file mode 100644
index 000000000..47ec421bb
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail29.json
@@ -0,0 +1 @@
+[0e] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail30.json b/src/boost/libs/json/test/parse-vectors/n_fail30.json
new file mode 100644
index 000000000..8ab0bc4b8
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail30.json
@@ -0,0 +1 @@
+[0e+] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail31.json b/src/boost/libs/json/test/parse-vectors/n_fail31.json
new file mode 100644
index 000000000..1cce602b5
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail31.json
@@ -0,0 +1 @@
+[0e+-1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_fail32.json b/src/boost/libs/json/test/parse-vectors/n_fail32.json
new file mode 100644
index 000000000..45cba7396
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_fail32.json
@@ -0,0 +1 @@
+{"Comma instead if closing brace": true, \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_incomplete_false.json b/src/boost/libs/json/test/parse-vectors/n_incomplete_false.json
new file mode 100644
index 000000000..eb18c6a14
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_incomplete_false.json
@@ -0,0 +1 @@
+[fals] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_incomplete_null.json b/src/boost/libs/json/test/parse-vectors/n_incomplete_null.json
new file mode 100644
index 000000000..c18ef5385
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_incomplete_null.json
@@ -0,0 +1 @@
+[nul] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_incomplete_true.json b/src/boost/libs/json/test/parse-vectors/n_incomplete_true.json
new file mode 100644
index 000000000..f451ac6d2
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_incomplete_true.json
@@ -0,0 +1 @@
+[tru] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_multidigit_number_then_00.json b/src/boost/libs/json/test/parse-vectors/n_multidigit_number_then_00.json
new file mode 100644
index 000000000..c22507b86
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_multidigit_number_then_00.json
Binary files differ
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_++.json b/src/boost/libs/json/test/parse-vectors/n_number_++.json
new file mode 100644
index 000000000..bdb62aaf4
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_++.json
@@ -0,0 +1 @@
+[++1234] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_+1.json b/src/boost/libs/json/test/parse-vectors/n_number_+1.json
new file mode 100644
index 000000000..3cbe58c92
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_+1.json
@@ -0,0 +1 @@
+[+1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_+Inf.json b/src/boost/libs/json/test/parse-vectors/n_number_+Inf.json
new file mode 100644
index 000000000..871ae14d5
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_+Inf.json
@@ -0,0 +1 @@
+[+Inf] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_-01.json b/src/boost/libs/json/test/parse-vectors/n_number_-01.json
new file mode 100644
index 000000000..0df32bac8
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_-01.json
@@ -0,0 +1 @@
+[-01] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_-1.0..json b/src/boost/libs/json/test/parse-vectors/n_number_-1.0..json
new file mode 100644
index 000000000..7cf55a85a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_-1.0..json
@@ -0,0 +1 @@
+[-1.0.] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_-2..json b/src/boost/libs/json/test/parse-vectors/n_number_-2..json
new file mode 100644
index 000000000..9be84365d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_-2..json
@@ -0,0 +1 @@
+[-2.] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_-NaN.json b/src/boost/libs/json/test/parse-vectors/n_number_-NaN.json
new file mode 100644
index 000000000..f61615d40
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_-NaN.json
@@ -0,0 +1 @@
+[-NaN] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_.-1.json b/src/boost/libs/json/test/parse-vectors/n_number_.-1.json
new file mode 100644
index 000000000..1c9f2dd1b
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_.-1.json
@@ -0,0 +1 @@
+[.-1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_.2e-3.json b/src/boost/libs/json/test/parse-vectors/n_number_.2e-3.json
new file mode 100644
index 000000000..c6c976f25
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_.2e-3.json
@@ -0,0 +1 @@
+[.2e-3] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0.1.2.json b/src/boost/libs/json/test/parse-vectors/n_number_0.1.2.json
new file mode 100644
index 000000000..c83a25621
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_0.1.2.json
@@ -0,0 +1 @@
+[0.1.2] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0.3e+.json b/src/boost/libs/json/test/parse-vectors/n_number_0.3e+.json
new file mode 100644
index 000000000..a55a1bfef
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_0.3e+.json
@@ -0,0 +1 @@
+[0.3e+] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0.3e.json b/src/boost/libs/json/test/parse-vectors/n_number_0.3e.json
new file mode 100644
index 000000000..3dd5df4b3
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_0.3e.json
@@ -0,0 +1 @@
+[0.3e] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0.e1.json b/src/boost/libs/json/test/parse-vectors/n_number_0.e1.json
new file mode 100644
index 000000000..c92c71ccb
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_0.e1.json
@@ -0,0 +1 @@
+[0.e1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0_capital_E+.json b/src/boost/libs/json/test/parse-vectors/n_number_0_capital_E+.json
new file mode 100644
index 000000000..3ba2c7d6d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_0_capital_E+.json
@@ -0,0 +1 @@
+[0E+] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0_capital_E.json b/src/boost/libs/json/test/parse-vectors/n_number_0_capital_E.json
new file mode 100644
index 000000000..5301840d1
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_0_capital_E.json
@@ -0,0 +1 @@
+[0E] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0e+.json b/src/boost/libs/json/test/parse-vectors/n_number_0e+.json
new file mode 100644
index 000000000..8ab0bc4b8
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_0e+.json
@@ -0,0 +1 @@
+[0e+] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_0e.json b/src/boost/libs/json/test/parse-vectors/n_number_0e.json
new file mode 100644
index 000000000..47ec421bb
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_0e.json
@@ -0,0 +1 @@
+[0e] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_1.0e+.json b/src/boost/libs/json/test/parse-vectors/n_number_1.0e+.json
new file mode 100644
index 000000000..cd84b9f69
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_1.0e+.json
@@ -0,0 +1 @@
+[1.0e+] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_1.0e-.json b/src/boost/libs/json/test/parse-vectors/n_number_1.0e-.json
new file mode 100644
index 000000000..4eb7afa0f
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_1.0e-.json
@@ -0,0 +1 @@
+[1.0e-] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_1.0e.json b/src/boost/libs/json/test/parse-vectors/n_number_1.0e.json
new file mode 100644
index 000000000..21753f4c7
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_1.0e.json
@@ -0,0 +1 @@
+[1.0e] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_1_000.json b/src/boost/libs/json/test/parse-vectors/n_number_1_000.json
new file mode 100644
index 000000000..7b18b66b3
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_1_000.json
@@ -0,0 +1 @@
+[1 000.0] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_1eE2.json b/src/boost/libs/json/test/parse-vectors/n_number_1eE2.json
new file mode 100644
index 000000000..4318a341d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_1eE2.json
@@ -0,0 +1 @@
+[1eE2] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_2.e+3.json b/src/boost/libs/json/test/parse-vectors/n_number_2.e+3.json
new file mode 100644
index 000000000..4442f394d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_2.e+3.json
@@ -0,0 +1 @@
+[2.e+3] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_2.e-3.json b/src/boost/libs/json/test/parse-vectors/n_number_2.e-3.json
new file mode 100644
index 000000000..a65060edf
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_2.e-3.json
@@ -0,0 +1 @@
+[2.e-3] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_2.e3.json b/src/boost/libs/json/test/parse-vectors/n_number_2.e3.json
new file mode 100644
index 000000000..66f7cf701
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_2.e3.json
@@ -0,0 +1 @@
+[2.e3] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_9.e+.json b/src/boost/libs/json/test/parse-vectors/n_number_9.e+.json
new file mode 100644
index 000000000..732a7b11c
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_9.e+.json
@@ -0,0 +1 @@
+[9.e+] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_Inf.json b/src/boost/libs/json/test/parse-vectors/n_number_Inf.json
new file mode 100644
index 000000000..c40c734c3
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_Inf.json
@@ -0,0 +1 @@
+[Inf] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_NaN.json b/src/boost/libs/json/test/parse-vectors/n_number_NaN.json
new file mode 100644
index 000000000..499231790
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_NaN.json
@@ -0,0 +1 @@
+[NaN] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_U+FF11_fullwidth_digit_one.json b/src/boost/libs/json/test/parse-vectors/n_number_U+FF11_fullwidth_digit_one.json
new file mode 100644
index 000000000..b14587e5e
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_U+FF11_fullwidth_digit_one.json
@@ -0,0 +1 @@
+[1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_expression.json b/src/boost/libs/json/test/parse-vectors/n_number_expression.json
new file mode 100644
index 000000000..76fdbc8a4
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_expression.json
@@ -0,0 +1 @@
+[1+2] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_hex_1_digit.json b/src/boost/libs/json/test/parse-vectors/n_number_hex_1_digit.json
new file mode 100644
index 000000000..3b214880c
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_hex_1_digit.json
@@ -0,0 +1 @@
+[0x1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_hex_2_digits.json b/src/boost/libs/json/test/parse-vectors/n_number_hex_2_digits.json
new file mode 100644
index 000000000..83e516ab0
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_hex_2_digits.json
@@ -0,0 +1 @@
+[0x42] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_infinity.json b/src/boost/libs/json/test/parse-vectors/n_number_infinity.json
new file mode 100644
index 000000000..8c2baf783
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_infinity.json
@@ -0,0 +1 @@
+[Infinity] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_invalid+-.json b/src/boost/libs/json/test/parse-vectors/n_number_invalid+-.json
new file mode 100644
index 000000000..1cce602b5
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_invalid+-.json
@@ -0,0 +1 @@
+[0e+-1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_invalid-negative-real.json b/src/boost/libs/json/test/parse-vectors/n_number_invalid-negative-real.json
new file mode 100644
index 000000000..5fc3c1efb
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_invalid-negative-real.json
@@ -0,0 +1 @@
+[-123.123foo] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-bigger-int.json b/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-bigger-int.json
new file mode 100644
index 000000000..3b97e580e
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-bigger-int.json
@@ -0,0 +1 @@
+[123å] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-exponent.json b/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-exponent.json
new file mode 100644
index 000000000..ea35d723c
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-exponent.json
@@ -0,0 +1 @@
+[1e1å] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-int.json b/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-int.json
new file mode 100644
index 000000000..371226e4c
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_invalid-utf-8-in-int.json
@@ -0,0 +1 @@
+[0å]
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_minus_infinity.json b/src/boost/libs/json/test/parse-vectors/n_number_minus_infinity.json
new file mode 100644
index 000000000..cf4133d22
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_minus_infinity.json
@@ -0,0 +1 @@
+[-Infinity] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_minus_sign_with_trailing_garbage.json b/src/boost/libs/json/test/parse-vectors/n_number_minus_sign_with_trailing_garbage.json
new file mode 100644
index 000000000..a6d8e78e7
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_minus_sign_with_trailing_garbage.json
@@ -0,0 +1 @@
+[-foo] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_minus_space_1.json b/src/boost/libs/json/test/parse-vectors/n_number_minus_space_1.json
new file mode 100644
index 000000000..9a5ebedf6
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_minus_space_1.json
@@ -0,0 +1 @@
+[- 1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_neg_int_starting_with_zero.json b/src/boost/libs/json/test/parse-vectors/n_number_neg_int_starting_with_zero.json
new file mode 100644
index 000000000..67af0960a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_neg_int_starting_with_zero.json
@@ -0,0 +1 @@
+[-012] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_neg_real_without_int_part.json b/src/boost/libs/json/test/parse-vectors/n_number_neg_real_without_int_part.json
new file mode 100644
index 000000000..1f2a43496
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_neg_real_without_int_part.json
@@ -0,0 +1 @@
+[-.123] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_neg_with_garbage_at_end.json b/src/boost/libs/json/test/parse-vectors/n_number_neg_with_garbage_at_end.json
new file mode 100644
index 000000000..2aa73119f
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_neg_with_garbage_at_end.json
@@ -0,0 +1 @@
+[-1x] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_real_garbage_after_e.json b/src/boost/libs/json/test/parse-vectors/n_number_real_garbage_after_e.json
new file mode 100644
index 000000000..9213dfca8
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_real_garbage_after_e.json
@@ -0,0 +1 @@
+[1ea] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_real_with_invalid_utf8_after_e.json b/src/boost/libs/json/test/parse-vectors/n_number_real_with_invalid_utf8_after_e.json
new file mode 100644
index 000000000..1e52ef964
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_real_with_invalid_utf8_after_e.json
@@ -0,0 +1 @@
+[1eå] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_real_without_fractional_part.json b/src/boost/libs/json/test/parse-vectors/n_number_real_without_fractional_part.json
new file mode 100644
index 000000000..1de287cf8
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_real_without_fractional_part.json
@@ -0,0 +1 @@
+[1.] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_starting_with_dot.json b/src/boost/libs/json/test/parse-vectors/n_number_starting_with_dot.json
new file mode 100644
index 000000000..f682dbdce
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_starting_with_dot.json
@@ -0,0 +1 @@
+[.123] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_with_alpha.json b/src/boost/libs/json/test/parse-vectors/n_number_with_alpha.json
new file mode 100644
index 000000000..1e42d8182
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_with_alpha.json
@@ -0,0 +1 @@
+[1.2a-3] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_with_alpha_char.json b/src/boost/libs/json/test/parse-vectors/n_number_with_alpha_char.json
new file mode 100644
index 000000000..b79daccb8
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_with_alpha_char.json
@@ -0,0 +1 @@
+[1.8011670033376514H-308] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_number_with_leading_zero.json b/src/boost/libs/json/test/parse-vectors/n_number_with_leading_zero.json
new file mode 100644
index 000000000..7106da1f3
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_number_with_leading_zero.json
@@ -0,0 +1 @@
+[012] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_bad_value.json b/src/boost/libs/json/test/parse-vectors/n_object_bad_value.json
new file mode 100644
index 000000000..a03a8c03b
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_bad_value.json
@@ -0,0 +1 @@
+["x", truth] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_bracket_key.json b/src/boost/libs/json/test/parse-vectors/n_object_bracket_key.json
new file mode 100644
index 000000000..cc443b483
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_bracket_key.json
@@ -0,0 +1 @@
+{[: "x"}
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_comma_instead_of_colon.json b/src/boost/libs/json/test/parse-vectors/n_object_comma_instead_of_colon.json
new file mode 100644
index 000000000..8d5637708
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_comma_instead_of_colon.json
@@ -0,0 +1 @@
+{"x", null} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_double_colon.json b/src/boost/libs/json/test/parse-vectors/n_object_double_colon.json
new file mode 100644
index 000000000..80e8c7b89
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_double_colon.json
@@ -0,0 +1 @@
+{"x"::"b"} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_emoji.json b/src/boost/libs/json/test/parse-vectors/n_object_emoji.json
new file mode 100644
index 000000000..cb4078eaa
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_emoji.json
@@ -0,0 +1 @@
+{🇨🇭} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_garbage_at_end.json b/src/boost/libs/json/test/parse-vectors/n_object_garbage_at_end.json
new file mode 100644
index 000000000..80c42cbad
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_garbage_at_end.json
@@ -0,0 +1 @@
+{"a":"a" 123} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_key_with_single_quotes.json b/src/boost/libs/json/test/parse-vectors/n_object_key_with_single_quotes.json
new file mode 100644
index 000000000..77c327599
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_key_with_single_quotes.json
@@ -0,0 +1 @@
+{key: 'value'} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_lone_continuation_byte_in_key_and_trailing_comma.json b/src/boost/libs/json/test/parse-vectors/n_object_lone_continuation_byte_in_key_and_trailing_comma.json
new file mode 100644
index 000000000..aa2cb637c
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_lone_continuation_byte_in_key_and_trailing_comma.json
@@ -0,0 +1 @@
+{"¹":"0",} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_missing_colon.json b/src/boost/libs/json/test/parse-vectors/n_object_missing_colon.json
new file mode 100644
index 000000000..b98eff62d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_missing_colon.json
@@ -0,0 +1 @@
+{"a" b} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_missing_key.json b/src/boost/libs/json/test/parse-vectors/n_object_missing_key.json
new file mode 100644
index 000000000..b4fb0f528
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_missing_key.json
@@ -0,0 +1 @@
+{:"b"} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_missing_semicolon.json b/src/boost/libs/json/test/parse-vectors/n_object_missing_semicolon.json
new file mode 100644
index 000000000..e3451384f
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_missing_semicolon.json
@@ -0,0 +1 @@
+{"a" "b"} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_missing_value.json b/src/boost/libs/json/test/parse-vectors/n_object_missing_value.json
new file mode 100644
index 000000000..3ef538a60
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_missing_value.json
@@ -0,0 +1 @@
+{"a": \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_no-colon.json b/src/boost/libs/json/test/parse-vectors/n_object_no-colon.json
new file mode 100644
index 000000000..f3797b357
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_no-colon.json
@@ -0,0 +1 @@
+{"a" \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_non_string_key.json b/src/boost/libs/json/test/parse-vectors/n_object_non_string_key.json
new file mode 100644
index 000000000..b9945b34b
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_non_string_key.json
@@ -0,0 +1 @@
+{1:1} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_non_string_key_but_huge_number_instead.json b/src/boost/libs/json/test/parse-vectors/n_object_non_string_key_but_huge_number_instead.json
new file mode 100644
index 000000000..b37fa86c0
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_non_string_key_but_huge_number_instead.json
@@ -0,0 +1 @@
+{9999E9999:1} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_repeated_null_null.json b/src/boost/libs/json/test/parse-vectors/n_object_repeated_null_null.json
new file mode 100644
index 000000000..f7d2959d0
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_repeated_null_null.json
@@ -0,0 +1 @@
+{null:null,null:null} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_several_trailing_commas.json b/src/boost/libs/json/test/parse-vectors/n_object_several_trailing_commas.json
new file mode 100644
index 000000000..3c9afe8dc
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_several_trailing_commas.json
@@ -0,0 +1 @@
+{"id":0,,,,,} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_single_quote.json b/src/boost/libs/json/test/parse-vectors/n_object_single_quote.json
new file mode 100644
index 000000000..e5cdf976a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_single_quote.json
@@ -0,0 +1 @@
+{'a':0} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_trailing_comma.json b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comma.json
new file mode 100644
index 000000000..a4b025094
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comma.json
@@ -0,0 +1 @@
+{"id":0,} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment.json b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment.json
new file mode 100644
index 000000000..a372c6553
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment.json
@@ -0,0 +1 @@
+{"a":"b"}/**/ \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_open.json b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_open.json
new file mode 100644
index 000000000..d557f41ca
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_open.json
@@ -0,0 +1 @@
+{"a":"b"}/**// \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_slash_open.json b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_slash_open.json
new file mode 100644
index 000000000..e335136c0
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_slash_open.json
@@ -0,0 +1 @@
+{"a":"b"}// \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_slash_open_incomplete.json b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_slash_open_incomplete.json
new file mode 100644
index 000000000..d892e49f1
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_trailing_comment_slash_open_incomplete.json
@@ -0,0 +1 @@
+{"a":"b"}/ \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_two_commas_in_a_row.json b/src/boost/libs/json/test/parse-vectors/n_object_two_commas_in_a_row.json
new file mode 100644
index 000000000..7c639ae64
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_two_commas_in_a_row.json
@@ -0,0 +1 @@
+{"a":"b",,"c":"d"} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_unquoted_key.json b/src/boost/libs/json/test/parse-vectors/n_object_unquoted_key.json
new file mode 100644
index 000000000..8ba137293
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_unquoted_key.json
@@ -0,0 +1 @@
+{a: "b"} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_unterminated-value.json b/src/boost/libs/json/test/parse-vectors/n_object_unterminated-value.json
new file mode 100644
index 000000000..7fe699a6a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_unterminated-value.json
@@ -0,0 +1 @@
+{"a":"a \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_with_single_string.json b/src/boost/libs/json/test/parse-vectors/n_object_with_single_string.json
new file mode 100644
index 000000000..d63f7fbb7
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_with_single_string.json
@@ -0,0 +1 @@
+{ "foo" : "bar", "a" } \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_object_with_trailing_garbage.json b/src/boost/libs/json/test/parse-vectors/n_object_with_trailing_garbage.json
new file mode 100644
index 000000000..787c8f0a8
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_object_with_trailing_garbage.json
@@ -0,0 +1 @@
+{"a":"b"}# \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_single_space.json b/src/boost/libs/json/test/parse-vectors/n_single_space.json
new file mode 100644
index 000000000..0519ecba6
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_single_space.json
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape.json b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape.json
new file mode 100644
index 000000000..acec66d8f
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape.json
@@ -0,0 +1 @@
+["\uD800\"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u.json b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u.json
new file mode 100644
index 000000000..e834b05e9
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u.json
@@ -0,0 +1 @@
+["\uD800\u"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u1.json b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u1.json
new file mode 100644
index 000000000..a04cd3489
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u1.json
@@ -0,0 +1 @@
+["\uD800\u1"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u1x.json b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u1x.json
new file mode 100644
index 000000000..bfbd23409
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_1_surrogate_then_escape_u1x.json
@@ -0,0 +1 @@
+["\uD800\u1x"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_accentuated_char_no_quotes.json b/src/boost/libs/json/test/parse-vectors/n_string_accentuated_char_no_quotes.json
new file mode 100644
index 000000000..fd6895693
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_accentuated_char_no_quotes.json
@@ -0,0 +1 @@
+[é] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_backslash_00.json b/src/boost/libs/json/test/parse-vectors/n_string_backslash_00.json
new file mode 100644
index 000000000..b5bf267b5
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_backslash_00.json
Binary files differ
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_escape_x.json b/src/boost/libs/json/test/parse-vectors/n_string_escape_x.json
new file mode 100644
index 000000000..fae291938
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_escape_x.json
@@ -0,0 +1 @@
+["\x00"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_escaped_backslash_bad.json b/src/boost/libs/json/test/parse-vectors/n_string_escaped_backslash_bad.json
new file mode 100644
index 000000000..016fcb47e
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_escaped_backslash_bad.json
@@ -0,0 +1 @@
+["\\\"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_escaped_ctrl_char_tab.json b/src/boost/libs/json/test/parse-vectors/n_string_escaped_ctrl_char_tab.json
new file mode 100644
index 000000000..f35ea382b
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_escaped_ctrl_char_tab.json
@@ -0,0 +1 @@
+["\ "] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_escaped_emoji.json b/src/boost/libs/json/test/parse-vectors/n_string_escaped_emoji.json
new file mode 100644
index 000000000..a27775421
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_escaped_emoji.json
@@ -0,0 +1 @@
+["\🌀"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_incomplete_escape.json b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_escape.json
new file mode 100644
index 000000000..3415c33ca
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_escape.json
@@ -0,0 +1 @@
+["\"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_incomplete_escaped_character.json b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_escaped_character.json
new file mode 100644
index 000000000..0f2197ea2
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_escaped_character.json
@@ -0,0 +1 @@
+["\u00A"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_incomplete_surrogate.json b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_surrogate.json
new file mode 100644
index 000000000..75504a656
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_surrogate.json
@@ -0,0 +1 @@
+["\uD834\uDd"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_incomplete_surrogate_escape_invalid.json b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_surrogate_escape_invalid.json
new file mode 100644
index 000000000..bd9656060
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_incomplete_surrogate_escape_invalid.json
@@ -0,0 +1 @@
+["\uD800\uD800\x"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_invalid-utf-8-in-escape.json b/src/boost/libs/json/test/parse-vectors/n_string_invalid-utf-8-in-escape.json
new file mode 100644
index 000000000..0c4300643
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_invalid-utf-8-in-escape.json
@@ -0,0 +1 @@
+["\uå"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_invalid_backslash_esc.json b/src/boost/libs/json/test/parse-vectors/n_string_invalid_backslash_esc.json
new file mode 100644
index 000000000..d1eb60921
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_invalid_backslash_esc.json
@@ -0,0 +1 @@
+["\a"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_invalid_unicode_escape.json b/src/boost/libs/json/test/parse-vectors/n_string_invalid_unicode_escape.json
new file mode 100644
index 000000000..7608cb6ba
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_invalid_unicode_escape.json
@@ -0,0 +1 @@
+["\uqqqq"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_invalid_utf8_after_escape.json b/src/boost/libs/json/test/parse-vectors/n_string_invalid_utf8_after_escape.json
new file mode 100644
index 000000000..2f757a25b
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_invalid_utf8_after_escape.json
@@ -0,0 +1 @@
+["\å"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_leading_uescaped_thinspace.json b/src/boost/libs/json/test/parse-vectors/n_string_leading_uescaped_thinspace.json
new file mode 100644
index 000000000..7b297c636
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_leading_uescaped_thinspace.json
@@ -0,0 +1 @@
+[\u0020"asd"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_no_quotes_with_bad_escape.json b/src/boost/libs/json/test/parse-vectors/n_string_no_quotes_with_bad_escape.json
new file mode 100644
index 000000000..01bc70aba
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_no_quotes_with_bad_escape.json
@@ -0,0 +1 @@
+[\n] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_single_doublequote.json b/src/boost/libs/json/test/parse-vectors/n_string_single_doublequote.json
new file mode 100644
index 000000000..9d68933c4
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_single_doublequote.json
@@ -0,0 +1 @@
+" \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_single_quote.json b/src/boost/libs/json/test/parse-vectors/n_string_single_quote.json
new file mode 100644
index 000000000..caff239bf
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_single_quote.json
@@ -0,0 +1 @@
+['single quote'] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_single_string_no_double_quotes.json b/src/boost/libs/json/test/parse-vectors/n_string_single_string_no_double_quotes.json
new file mode 100644
index 000000000..f2ba8f84a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_single_string_no_double_quotes.json
@@ -0,0 +1 @@
+abc \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_start_escape_unclosed.json b/src/boost/libs/json/test/parse-vectors/n_string_start_escape_unclosed.json
new file mode 100644
index 000000000..db62a46fc
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_start_escape_unclosed.json
@@ -0,0 +1 @@
+["\ \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_unescaped_crtl_char.json b/src/boost/libs/json/test/parse-vectors/n_string_unescaped_crtl_char.json
new file mode 100644
index 000000000..9f2134807
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_unescaped_crtl_char.json
Binary files differ
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_unescaped_newline.json b/src/boost/libs/json/test/parse-vectors/n_string_unescaped_newline.json
new file mode 100644
index 000000000..700d36086
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_unescaped_newline.json
@@ -0,0 +1,2 @@
+["new
+line"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_unescaped_tab.json b/src/boost/libs/json/test/parse-vectors/n_string_unescaped_tab.json
new file mode 100644
index 000000000..160264a2d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_unescaped_tab.json
@@ -0,0 +1 @@
+[" "] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_unicode_CapitalU.json b/src/boost/libs/json/test/parse-vectors/n_string_unicode_CapitalU.json
new file mode 100644
index 000000000..17332bb17
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_unicode_CapitalU.json
@@ -0,0 +1 @@
+"\UA66D" \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_string_with_trailing_garbage.json b/src/boost/libs/json/test/parse-vectors/n_string_with_trailing_garbage.json
new file mode 100644
index 000000000..efe3bd272
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_string_with_trailing_garbage.json
@@ -0,0 +1 @@
+""x \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_100000_opening_arrays.json b/src/boost/libs/json/test/parse-vectors/n_structure_100000_opening_arrays.json
new file mode 100644
index 000000000..a4823eecc
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_100000_opening_arrays.json
@@ -0,0 +1 @@
+[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_U+2060_word_joined.json b/src/boost/libs/json/test/parse-vectors/n_structure_U+2060_word_joined.json
new file mode 100644
index 000000000..81156a699
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_U+2060_word_joined.json
@@ -0,0 +1 @@
+[â ] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_UTF8_BOM_no_data.json b/src/boost/libs/json/test/parse-vectors/n_structure_UTF8_BOM_no_data.json
new file mode 100644
index 000000000..5f282702b
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_UTF8_BOM_no_data.json
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_angle_bracket_..json b/src/boost/libs/json/test/parse-vectors/n_structure_angle_bracket_..json
new file mode 100644
index 000000000..a56fef0b0
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_angle_bracket_..json
@@ -0,0 +1 @@
+<.> \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_angle_bracket_null.json b/src/boost/libs/json/test/parse-vectors/n_structure_angle_bracket_null.json
new file mode 100644
index 000000000..617f26254
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_angle_bracket_null.json
@@ -0,0 +1 @@
+[<null>] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_array_trailing_garbage.json b/src/boost/libs/json/test/parse-vectors/n_structure_array_trailing_garbage.json
new file mode 100644
index 000000000..5a745e6f3
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_array_trailing_garbage.json
@@ -0,0 +1 @@
+[1]x \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_array_with_extra_array_close.json b/src/boost/libs/json/test/parse-vectors/n_structure_array_with_extra_array_close.json
new file mode 100644
index 000000000..6cfb1398d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_array_with_extra_array_close.json
@@ -0,0 +1 @@
+[1]] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_array_with_unclosed_string.json b/src/boost/libs/json/test/parse-vectors/n_structure_array_with_unclosed_string.json
new file mode 100644
index 000000000..ba6b1788b
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_array_with_unclosed_string.json
@@ -0,0 +1 @@
+["asd] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_ascii-unicode-identifier.json b/src/boost/libs/json/test/parse-vectors/n_structure_ascii-unicode-identifier.json
new file mode 100644
index 000000000..ef2ab62fe
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_ascii-unicode-identifier.json
@@ -0,0 +1 @@
+aå \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_capitalized_True.json b/src/boost/libs/json/test/parse-vectors/n_structure_capitalized_True.json
new file mode 100644
index 000000000..7cd88469a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_capitalized_True.json
@@ -0,0 +1 @@
+[True] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_close_unopened_array.json b/src/boost/libs/json/test/parse-vectors/n_structure_close_unopened_array.json
new file mode 100644
index 000000000..d2af0c646
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_close_unopened_array.json
@@ -0,0 +1 @@
+1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_comma_instead_of_closing_brace.json b/src/boost/libs/json/test/parse-vectors/n_structure_comma_instead_of_closing_brace.json
new file mode 100644
index 000000000..ac61b8200
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_comma_instead_of_closing_brace.json
@@ -0,0 +1 @@
+{"x": true, \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_double_array.json b/src/boost/libs/json/test/parse-vectors/n_structure_double_array.json
new file mode 100644
index 000000000..058d1626e
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_double_array.json
@@ -0,0 +1 @@
+[][] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_end_array.json b/src/boost/libs/json/test/parse-vectors/n_structure_end_array.json
new file mode 100644
index 000000000..54caf60b1
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_end_array.json
@@ -0,0 +1 @@
+] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_incomplete_UTF8_BOM.json b/src/boost/libs/json/test/parse-vectors/n_structure_incomplete_UTF8_BOM.json
new file mode 100644
index 000000000..bfcdd514f
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_incomplete_UTF8_BOM.json
@@ -0,0 +1 @@
+ï»{} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_lone-invalid-utf-8.json b/src/boost/libs/json/test/parse-vectors/n_structure_lone-invalid-utf-8.json
new file mode 100644
index 000000000..8b1296cad
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_lone-invalid-utf-8.json
@@ -0,0 +1 @@
+å \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_lone-open-bracket.json b/src/boost/libs/json/test/parse-vectors/n_structure_lone-open-bracket.json
new file mode 100644
index 000000000..8e2f0bef1
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_lone-open-bracket.json
@@ -0,0 +1 @@
+[ \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_no_data.json b/src/boost/libs/json/test/parse-vectors/n_structure_no_data.json
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_no_data.json
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_null-byte-outside-string.json b/src/boost/libs/json/test/parse-vectors/n_structure_null-byte-outside-string.json
new file mode 100644
index 000000000..326db1442
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_null-byte-outside-string.json
Binary files differ
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_number_with_trailing_garbage.json b/src/boost/libs/json/test/parse-vectors/n_structure_number_with_trailing_garbage.json
new file mode 100644
index 000000000..0746539d2
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_number_with_trailing_garbage.json
@@ -0,0 +1 @@
+2@ \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_object_followed_by_closing_object.json b/src/boost/libs/json/test/parse-vectors/n_structure_object_followed_by_closing_object.json
new file mode 100644
index 000000000..aa9ebaec5
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_object_followed_by_closing_object.json
@@ -0,0 +1 @@
+{}} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_object_unclosed_no_value.json b/src/boost/libs/json/test/parse-vectors/n_structure_object_unclosed_no_value.json
new file mode 100644
index 000000000..17d045147
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_object_unclosed_no_value.json
@@ -0,0 +1 @@
+{"": \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_object_with_comment.json b/src/boost/libs/json/test/parse-vectors/n_structure_object_with_comment.json
new file mode 100644
index 000000000..ed1b569b7
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_object_with_comment.json
@@ -0,0 +1 @@
+{"a":/*comment*/"b"} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_object_with_trailing_garbage.json b/src/boost/libs/json/test/parse-vectors/n_structure_object_with_trailing_garbage.json
new file mode 100644
index 000000000..9ca2336d7
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_object_with_trailing_garbage.json
@@ -0,0 +1 @@
+{"a": true} "x" \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_array_apostrophe.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_apostrophe.json
new file mode 100644
index 000000000..8bebe3af0
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_apostrophe.json
@@ -0,0 +1 @@
+[' \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_array_comma.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_comma.json
new file mode 100644
index 000000000..6295fdc36
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_comma.json
@@ -0,0 +1 @@
+[, \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_array_object.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_object.json
new file mode 100644
index 000000000..e870445b2
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_object.json
@@ -0,0 +1 @@
+[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_array_open_object.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_open_object.json
new file mode 100644
index 000000000..7a63c8c57
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_open_object.json
@@ -0,0 +1 @@
+[{ \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_array_open_string.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_open_string.json
new file mode 100644
index 000000000..9822a6baf
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_open_string.json
@@ -0,0 +1 @@
+["a \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_array_string.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_string.json
new file mode 100644
index 000000000..42a619362
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_array_string.json
@@ -0,0 +1 @@
+["a" \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_object.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_object.json
new file mode 100644
index 000000000..81750b96f
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_object.json
@@ -0,0 +1 @@
+{ \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_object_close_array.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_close_array.json
new file mode 100644
index 000000000..eebc700a1
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_close_array.json
@@ -0,0 +1 @@
+{] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_object_comma.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_comma.json
new file mode 100644
index 000000000..47bc9106f
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_comma.json
@@ -0,0 +1 @@
+{, \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_object_open_array.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_open_array.json
new file mode 100644
index 000000000..381ede5de
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_open_array.json
@@ -0,0 +1 @@
+{[ \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_object_open_string.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_open_string.json
new file mode 100644
index 000000000..328c30cd7
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_open_string.json
@@ -0,0 +1 @@
+{"a \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_object_string_with_apostrophes.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_string_with_apostrophes.json
new file mode 100644
index 000000000..9dba17090
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_object_string_with_apostrophes.json
@@ -0,0 +1 @@
+{'a' \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_open_open.json b/src/boost/libs/json/test/parse-vectors/n_structure_open_open.json
new file mode 100644
index 000000000..841fd5f86
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_open_open.json
@@ -0,0 +1 @@
+["\{["\{["\{["\{ \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_single_eacute.json b/src/boost/libs/json/test/parse-vectors/n_structure_single_eacute.json
new file mode 100644
index 000000000..92a39f398
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_single_eacute.json
@@ -0,0 +1 @@
+é \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_single_star.json b/src/boost/libs/json/test/parse-vectors/n_structure_single_star.json
new file mode 100644
index 000000000..f59ec20aa
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_single_star.json
@@ -0,0 +1 @@
+* \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_trailing_#.json b/src/boost/libs/json/test/parse-vectors/n_structure_trailing_#.json
new file mode 100644
index 000000000..898611087
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_trailing_#.json
@@ -0,0 +1 @@
+{"a":"b"}#{} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_uescaped_LF_before_string.json b/src/boost/libs/json/test/parse-vectors/n_structure_uescaped_LF_before_string.json
new file mode 100644
index 000000000..df2f0f242
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_uescaped_LF_before_string.json
@@ -0,0 +1 @@
+[\u000A""] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array.json b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array.json
new file mode 100644
index 000000000..11209515c
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array.json
@@ -0,0 +1 @@
+[1 \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_partial_null.json b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_partial_null.json
new file mode 100644
index 000000000..0d591762c
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_partial_null.json
@@ -0,0 +1 @@
+[ false, nul \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_unfinished_false.json b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_unfinished_false.json
new file mode 100644
index 000000000..a2ff8504a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_unfinished_false.json
@@ -0,0 +1 @@
+[ true, fals \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_unfinished_true.json b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_unfinished_true.json
new file mode 100644
index 000000000..3149e8f5a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_array_unfinished_true.json
@@ -0,0 +1 @@
+[ false, tru \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_object.json b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_object.json
new file mode 100644
index 000000000..694d69dbd
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_unclosed_object.json
@@ -0,0 +1 @@
+{"asd":"asd" \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_unicode-identifier.json b/src/boost/libs/json/test/parse-vectors/n_structure_unicode-identifier.json
new file mode 100644
index 000000000..7284aea33
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_unicode-identifier.json
@@ -0,0 +1 @@
+Ã¥ \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_whitespace_U+2060_word_joiner.json b/src/boost/libs/json/test/parse-vectors/n_structure_whitespace_U+2060_word_joiner.json
new file mode 100644
index 000000000..81156a699
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_whitespace_U+2060_word_joiner.json
@@ -0,0 +1 @@
+[â ] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/n_structure_whitespace_formfeed.json b/src/boost/libs/json/test/parse-vectors/n_structure_whitespace_formfeed.json
new file mode 100644
index 000000000..a9ea535d1
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/n_structure_whitespace_formfeed.json
@@ -0,0 +1 @@
+[ ] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_array_arraysWithSpaces.json b/src/boost/libs/json/test/parse-vectors/y_array_arraysWithSpaces.json
new file mode 100644
index 000000000..582290798
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_array_arraysWithSpaces.json
@@ -0,0 +1 @@
+[[] ] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_array_empty-string.json b/src/boost/libs/json/test/parse-vectors/y_array_empty-string.json
new file mode 100644
index 000000000..93b6be2bc
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_array_empty-string.json
@@ -0,0 +1 @@
+[""] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_array_empty.json b/src/boost/libs/json/test/parse-vectors/y_array_empty.json
new file mode 100644
index 000000000..0637a088a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_array_empty.json
@@ -0,0 +1 @@
+[] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_array_ending_with_newline.json b/src/boost/libs/json/test/parse-vectors/y_array_ending_with_newline.json
new file mode 100644
index 000000000..eac5f7b46
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_array_ending_with_newline.json
@@ -0,0 +1 @@
+["a"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_array_false.json b/src/boost/libs/json/test/parse-vectors/y_array_false.json
new file mode 100644
index 000000000..67b2f0760
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_array_false.json
@@ -0,0 +1 @@
+[false] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_array_heterogeneous.json b/src/boost/libs/json/test/parse-vectors/y_array_heterogeneous.json
new file mode 100644
index 000000000..d3c1e2648
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_array_heterogeneous.json
@@ -0,0 +1 @@
+[null, 1, "1", {}] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_array_null.json b/src/boost/libs/json/test/parse-vectors/y_array_null.json
new file mode 100644
index 000000000..500db4a86
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_array_null.json
@@ -0,0 +1 @@
+[null] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_array_with_1_and_newline.json b/src/boost/libs/json/test/parse-vectors/y_array_with_1_and_newline.json
new file mode 100644
index 000000000..994825500
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_array_with_1_and_newline.json
@@ -0,0 +1,2 @@
+[1
+] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_array_with_leading_space.json b/src/boost/libs/json/test/parse-vectors/y_array_with_leading_space.json
new file mode 100644
index 000000000..18bfe6422
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_array_with_leading_space.json
@@ -0,0 +1 @@
+ [1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_array_with_several_null.json b/src/boost/libs/json/test/parse-vectors/y_array_with_several_null.json
new file mode 100644
index 000000000..99f6c5d1d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_array_with_several_null.json
@@ -0,0 +1 @@
+[1,null,null,null,2] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_array_with_trailing_space.json b/src/boost/libs/json/test/parse-vectors/y_array_with_trailing_space.json
new file mode 100644
index 000000000..de9e7a944
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_array_with_trailing_space.json
@@ -0,0 +1 @@
+[2] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number.json b/src/boost/libs/json/test/parse-vectors/y_number.json
new file mode 100644
index 000000000..e5f5cc334
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number.json
@@ -0,0 +1 @@
+[123e65] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_0e+1.json b/src/boost/libs/json/test/parse-vectors/y_number_0e+1.json
new file mode 100644
index 000000000..d1d396706
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_0e+1.json
@@ -0,0 +1 @@
+[0e+1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_0e1.json b/src/boost/libs/json/test/parse-vectors/y_number_0e1.json
new file mode 100644
index 000000000..3283a7936
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_0e1.json
@@ -0,0 +1 @@
+[0e1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_after_space.json b/src/boost/libs/json/test/parse-vectors/y_number_after_space.json
new file mode 100644
index 000000000..623570d96
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_after_space.json
@@ -0,0 +1 @@
+[ 4] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_double_close_to_zero.json b/src/boost/libs/json/test/parse-vectors/y_number_double_close_to_zero.json
new file mode 100644
index 000000000..96555ff78
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_double_close_to_zero.json
@@ -0,0 +1 @@
+[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001]
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_int_with_exp.json b/src/boost/libs/json/test/parse-vectors/y_number_int_with_exp.json
new file mode 100644
index 000000000..a4ca9e754
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_int_with_exp.json
@@ -0,0 +1 @@
+[20e1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_minus_zero.json b/src/boost/libs/json/test/parse-vectors/y_number_minus_zero.json
new file mode 100644
index 000000000..37af1312a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_minus_zero.json
@@ -0,0 +1 @@
+[-0] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_negative_int.json b/src/boost/libs/json/test/parse-vectors/y_number_negative_int.json
new file mode 100644
index 000000000..8e30f8bd9
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_negative_int.json
@@ -0,0 +1 @@
+[-123] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_negative_one.json b/src/boost/libs/json/test/parse-vectors/y_number_negative_one.json
new file mode 100644
index 000000000..99d21a2a0
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_negative_one.json
@@ -0,0 +1 @@
+[-1] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_negative_zero.json b/src/boost/libs/json/test/parse-vectors/y_number_negative_zero.json
new file mode 100644
index 000000000..37af1312a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_negative_zero.json
@@ -0,0 +1 @@
+[-0] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e.json b/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e.json
new file mode 100644
index 000000000..6edbdfcb1
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e.json
@@ -0,0 +1 @@
+[1E22] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e_neg_exp.json b/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e_neg_exp.json
new file mode 100644
index 000000000..0a01bd3ef
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e_neg_exp.json
@@ -0,0 +1 @@
+[1E-2] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e_pos_exp.json b/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e_pos_exp.json
new file mode 100644
index 000000000..5a8fc0972
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_real_capital_e_pos_exp.json
@@ -0,0 +1 @@
+[1E+2] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_real_exponent.json b/src/boost/libs/json/test/parse-vectors/y_number_real_exponent.json
new file mode 100644
index 000000000..da2522d61
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_real_exponent.json
@@ -0,0 +1 @@
+[123e45] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_real_fraction_exponent.json b/src/boost/libs/json/test/parse-vectors/y_number_real_fraction_exponent.json
new file mode 100644
index 000000000..3944a7a45
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_real_fraction_exponent.json
@@ -0,0 +1 @@
+[123.456e78] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_real_neg_exp.json b/src/boost/libs/json/test/parse-vectors/y_number_real_neg_exp.json
new file mode 100644
index 000000000..ca40d3c25
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_real_neg_exp.json
@@ -0,0 +1 @@
+[1e-2] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_real_pos_exponent.json b/src/boost/libs/json/test/parse-vectors/y_number_real_pos_exponent.json
new file mode 100644
index 000000000..343601d51
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_real_pos_exponent.json
@@ -0,0 +1 @@
+[1e+2] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_simple_int.json b/src/boost/libs/json/test/parse-vectors/y_number_simple_int.json
new file mode 100644
index 000000000..e47f69afc
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_simple_int.json
@@ -0,0 +1 @@
+[123] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_number_simple_real.json b/src/boost/libs/json/test/parse-vectors/y_number_simple_real.json
new file mode 100644
index 000000000..b02878e5f
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_number_simple_real.json
@@ -0,0 +1 @@
+[123.456789] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_object.json b/src/boost/libs/json/test/parse-vectors/y_object.json
new file mode 100644
index 000000000..78262eda3
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_object.json
@@ -0,0 +1 @@
+{"asd":"sdf", "dfg":"fgh"} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_object_basic.json b/src/boost/libs/json/test/parse-vectors/y_object_basic.json
new file mode 100644
index 000000000..646bbe7bb
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_object_basic.json
@@ -0,0 +1 @@
+{"asd":"sdf"} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_object_duplicated_key.json b/src/boost/libs/json/test/parse-vectors/y_object_duplicated_key.json
new file mode 100644
index 000000000..bbc2e1ce4
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_object_duplicated_key.json
@@ -0,0 +1 @@
+{"a":"b","a":"c"} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_object_duplicated_key_and_value.json b/src/boost/libs/json/test/parse-vectors/y_object_duplicated_key_and_value.json
new file mode 100644
index 000000000..211581c20
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_object_duplicated_key_and_value.json
@@ -0,0 +1 @@
+{"a":"b","a":"b"} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_object_empty.json b/src/boost/libs/json/test/parse-vectors/y_object_empty.json
new file mode 100644
index 000000000..9e26dfeeb
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_object_empty.json
@@ -0,0 +1 @@
+{} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_object_empty_key.json b/src/boost/libs/json/test/parse-vectors/y_object_empty_key.json
new file mode 100644
index 000000000..c0013d3b8
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_object_empty_key.json
@@ -0,0 +1 @@
+{"":0} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_object_escaped_null_in_key.json b/src/boost/libs/json/test/parse-vectors/y_object_escaped_null_in_key.json
new file mode 100644
index 000000000..593f0f67f
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_object_escaped_null_in_key.json
@@ -0,0 +1 @@
+{"foo\u0000bar": 42} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_object_extreme_numbers.json b/src/boost/libs/json/test/parse-vectors/y_object_extreme_numbers.json
new file mode 100644
index 000000000..a0d3531c3
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_object_extreme_numbers.json
@@ -0,0 +1 @@
+{ "min": -1.0e+28, "max": 1.0e+28 } \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_object_long_strings.json b/src/boost/libs/json/test/parse-vectors/y_object_long_strings.json
new file mode 100644
index 000000000..bdc4a0871
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_object_long_strings.json
@@ -0,0 +1 @@
+{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_object_simple.json b/src/boost/libs/json/test/parse-vectors/y_object_simple.json
new file mode 100644
index 000000000..dacac917f
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_object_simple.json
@@ -0,0 +1 @@
+{"a":[]} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_object_string_unicode.json b/src/boost/libs/json/test/parse-vectors/y_object_string_unicode.json
new file mode 100644
index 000000000..8effdb297
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_object_string_unicode.json
@@ -0,0 +1 @@
+{"title":"\u041f\u043e\u043b\u0442\u043e\u0440\u0430 \u0417\u0435\u043c\u043b\u0435\u043a\u043e\u043f\u0430" } \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_object_with_newlines.json b/src/boost/libs/json/test/parse-vectors/y_object_with_newlines.json
new file mode 100644
index 000000000..246ec6b34
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_object_with_newlines.json
@@ -0,0 +1,3 @@
+{
+"a": "b"
+} \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_pass01.json b/src/boost/libs/json/test/parse-vectors/y_pass01.json
new file mode 100644
index 000000000..70e268543
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_pass01.json
@@ -0,0 +1,58 @@
+[
+ "JSON Test Pattern pass1",
+ {"object with 1 member":["array with 1 element"]},
+ {},
+ [],
+ -42,
+ true,
+ false,
+ null,
+ {
+ "integer": 1234567890,
+ "real": -9876.543210,
+ "e": 0.123456789e-12,
+ "E": 1.234567890E+34,
+ "": 23456789012E66,
+ "zero": 0,
+ "one": 1,
+ "space": " ",
+ "quote": "\"",
+ "backslash": "\\",
+ "controls": "\b\f\n\r\t",
+ "slash": "/ & \/",
+ "alpha": "abcdefghijklmnopqrstuvwyz",
+ "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
+ "digit": "0123456789",
+ "0123456789": "digit",
+ "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
+ "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
+ "true": true,
+ "false": false,
+ "null": null,
+ "array":[ ],
+ "object":{ },
+ "address": "50 St. James Street",
+ "url": "http://www.JSON.org/",
+ "comment": "// /* <!-- --",
+ "# -- --> */": " ",
+ " s p a c e d " :[1,2 , 3
+
+,
+
+4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],
+ "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
+ "quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
+ "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
+: "A key can be any string"
+ },
+ 0.5 ,98.6
+,
+99.44
+,
+
+1066,
+1e1,
+0.1e1,
+1e-1,
+1e00,2e+00,2e-00
+,"rosebud"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_pass02.json b/src/boost/libs/json/test/parse-vectors/y_pass02.json
new file mode 100644
index 000000000..d3c63c7ad
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_pass02.json
@@ -0,0 +1 @@
+[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_pass03.json b/src/boost/libs/json/test/parse-vectors/y_pass03.json
new file mode 100644
index 000000000..4528d51f1
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_pass03.json
@@ -0,0 +1,6 @@
+{
+ "JSON Test Pattern pass3": {
+ "The outermost value": "must be an object or array.",
+ "In this test": "It is an object."
+ }
+}
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_1_2_3_bytes_UTF-8_sequences.json b/src/boost/libs/json/test/parse-vectors/y_string_1_2_3_bytes_UTF-8_sequences.json
new file mode 100644
index 000000000..9967ddeb8
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_1_2_3_bytes_UTF-8_sequences.json
@@ -0,0 +1 @@
+["\u0060\u012a\u12AB"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_accepted_surrogate_pair.json b/src/boost/libs/json/test/parse-vectors/y_string_accepted_surrogate_pair.json
new file mode 100644
index 000000000..996875cc8
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_accepted_surrogate_pair.json
@@ -0,0 +1 @@
+["\uD801\udc37"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_accepted_surrogate_pairs.json b/src/boost/libs/json/test/parse-vectors/y_string_accepted_surrogate_pairs.json
new file mode 100644
index 000000000..3401021ec
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_accepted_surrogate_pairs.json
@@ -0,0 +1 @@
+["\ud83d\ude39\ud83d\udc8d"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_allowed_escapes.json b/src/boost/libs/json/test/parse-vectors/y_string_allowed_escapes.json
new file mode 100644
index 000000000..7f495532f
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_allowed_escapes.json
@@ -0,0 +1 @@
+["\"\\\/\b\f\n\r\t"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_backslash_and_u_escaped_zero.json b/src/boost/libs/json/test/parse-vectors/y_string_backslash_and_u_escaped_zero.json
new file mode 100644
index 000000000..d4439eda7
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_backslash_and_u_escaped_zero.json
@@ -0,0 +1 @@
+["\\u0000"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_backslash_doublequotes.json b/src/boost/libs/json/test/parse-vectors/y_string_backslash_doublequotes.json
new file mode 100644
index 000000000..ae03243b6
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_backslash_doublequotes.json
@@ -0,0 +1 @@
+["\""] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_comments.json b/src/boost/libs/json/test/parse-vectors/y_string_comments.json
new file mode 100644
index 000000000..2260c20c2
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_comments.json
@@ -0,0 +1 @@
+["a/*b*/c/*d//e"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_double_escape_a.json b/src/boost/libs/json/test/parse-vectors/y_string_double_escape_a.json
new file mode 100644
index 000000000..6715d6f40
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_double_escape_a.json
@@ -0,0 +1 @@
+["\\a"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_double_escape_n.json b/src/boost/libs/json/test/parse-vectors/y_string_double_escape_n.json
new file mode 100644
index 000000000..44ca56c4d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_double_escape_n.json
@@ -0,0 +1 @@
+["\\n"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_escaped_control_character.json b/src/boost/libs/json/test/parse-vectors/y_string_escaped_control_character.json
new file mode 100644
index 000000000..5b014a9c2
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_escaped_control_character.json
@@ -0,0 +1 @@
+["\u0012"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_escaped_noncharacter.json b/src/boost/libs/json/test/parse-vectors/y_string_escaped_noncharacter.json
new file mode 100644
index 000000000..2ff52e2c5
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_escaped_noncharacter.json
@@ -0,0 +1 @@
+["\uFFFF"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_in_array.json b/src/boost/libs/json/test/parse-vectors/y_string_in_array.json
new file mode 100644
index 000000000..21d7ae4cd
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_in_array.json
@@ -0,0 +1 @@
+["asd"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_in_array_with_leading_space.json b/src/boost/libs/json/test/parse-vectors/y_string_in_array_with_leading_space.json
new file mode 100644
index 000000000..9e1887c1e
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_in_array_with_leading_space.json
@@ -0,0 +1 @@
+[ "asd"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_last_surrogates_1_and_2.json b/src/boost/libs/json/test/parse-vectors/y_string_last_surrogates_1_and_2.json
new file mode 100644
index 000000000..3919cef76
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_last_surrogates_1_and_2.json
@@ -0,0 +1 @@
+["\uDBFF\uDFFF"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_nbsp_uescaped.json b/src/boost/libs/json/test/parse-vectors/y_string_nbsp_uescaped.json
new file mode 100644
index 000000000..2085ab1a1
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_nbsp_uescaped.json
@@ -0,0 +1 @@
+["new\u00A0line"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_nonCharacterInUTF-8_U+10FFFF.json b/src/boost/libs/json/test/parse-vectors/y_string_nonCharacterInUTF-8_U+10FFFF.json
new file mode 100644
index 000000000..059e4d9dd
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_nonCharacterInUTF-8_U+10FFFF.json
@@ -0,0 +1 @@
+["ô¿¿"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_nonCharacterInUTF-8_U+FFFF.json b/src/boost/libs/json/test/parse-vectors/y_string_nonCharacterInUTF-8_U+FFFF.json
new file mode 100644
index 000000000..4c913bd41
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_nonCharacterInUTF-8_U+FFFF.json
@@ -0,0 +1 @@
+["ï¿¿"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_null_escape.json b/src/boost/libs/json/test/parse-vectors/y_string_null_escape.json
new file mode 100644
index 000000000..c1ad84404
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_null_escape.json
@@ -0,0 +1 @@
+["\u0000"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_one-byte-utf-8.json b/src/boost/libs/json/test/parse-vectors/y_string_one-byte-utf-8.json
new file mode 100644
index 000000000..157185923
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_one-byte-utf-8.json
@@ -0,0 +1 @@
+["\u002c"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_pi.json b/src/boost/libs/json/test/parse-vectors/y_string_pi.json
new file mode 100644
index 000000000..9df11ae88
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_pi.json
@@ -0,0 +1 @@
+["Ï€"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_reservedCharacterInUTF-8_U+1BFFF.json b/src/boost/libs/json/test/parse-vectors/y_string_reservedCharacterInUTF-8_U+1BFFF.json
new file mode 100644
index 000000000..10a33a171
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_reservedCharacterInUTF-8_U+1BFFF.json
@@ -0,0 +1 @@
+["𛿿"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_simple_ascii.json b/src/boost/libs/json/test/parse-vectors/y_string_simple_ascii.json
new file mode 100644
index 000000000..8cadf7d05
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_simple_ascii.json
@@ -0,0 +1 @@
+["asd "] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_space.json b/src/boost/libs/json/test/parse-vectors/y_string_space.json
new file mode 100644
index 000000000..efd782cc3
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_space.json
@@ -0,0 +1 @@
+" " \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json b/src/boost/libs/json/test/parse-vectors/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json
new file mode 100644
index 000000000..7620b6655
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json
@@ -0,0 +1 @@
+["\uD834\uDd1e"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_three-byte-utf-8.json b/src/boost/libs/json/test/parse-vectors/y_string_three-byte-utf-8.json
new file mode 100644
index 000000000..108f1d67d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_three-byte-utf-8.json
@@ -0,0 +1 @@
+["\u0821"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_two-byte-utf-8.json b/src/boost/libs/json/test/parse-vectors/y_string_two-byte-utf-8.json
new file mode 100644
index 000000000..461503c31
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_two-byte-utf-8.json
@@ -0,0 +1 @@
+["\u0123"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_u+2028_line_sep.json b/src/boost/libs/json/test/parse-vectors/y_string_u+2028_line_sep.json
new file mode 100644
index 000000000..897b6021a
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_u+2028_line_sep.json
@@ -0,0 +1 @@
+["
"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_u+2029_par_sep.json b/src/boost/libs/json/test/parse-vectors/y_string_u+2029_par_sep.json
new file mode 100644
index 000000000..8cd998c89
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_u+2029_par_sep.json
@@ -0,0 +1 @@
+["
"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_uEscape.json b/src/boost/libs/json/test/parse-vectors/y_string_uEscape.json
new file mode 100644
index 000000000..f7b41a02f
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_uEscape.json
@@ -0,0 +1 @@
+["\u0061\u30af\u30EA\u30b9"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_uescaped_newline.json b/src/boost/libs/json/test/parse-vectors/y_string_uescaped_newline.json
new file mode 100644
index 000000000..3a5a220b6
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_uescaped_newline.json
@@ -0,0 +1 @@
+["new\u000Aline"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unescaped_char_delete.json b/src/boost/libs/json/test/parse-vectors/y_string_unescaped_char_delete.json
new file mode 100644
index 000000000..7d064f498
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_unescaped_char_delete.json
@@ -0,0 +1 @@
+[""] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode.json
new file mode 100644
index 000000000..3598095b7
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode.json
@@ -0,0 +1 @@
+["\uA66D"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicodeEscapedBackslash.json b/src/boost/libs/json/test/parse-vectors/y_string_unicodeEscapedBackslash.json
new file mode 100644
index 000000000..0bb3b51e7
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_unicodeEscapedBackslash.json
@@ -0,0 +1 @@
+["\u005C"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_2.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_2.json
new file mode 100644
index 000000000..a7dcb9768
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_2.json
@@ -0,0 +1 @@
+["â‚㈴â‚"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+10FFFE_nonchar.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+10FFFE_nonchar.json
new file mode 100644
index 000000000..9a8370b96
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+10FFFE_nonchar.json
@@ -0,0 +1 @@
+["\uDBFF\uDFFE"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+1FFFE_nonchar.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+1FFFE_nonchar.json
new file mode 100644
index 000000000..c51f8ae45
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+1FFFE_nonchar.json
@@ -0,0 +1 @@
+["\uD83F\uDFFE"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json
new file mode 100644
index 000000000..626d5f815
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json
@@ -0,0 +1 @@
+["\u200B"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+2064_invisible_plus.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+2064_invisible_plus.json
new file mode 100644
index 000000000..1e23972c6
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+2064_invisible_plus.json
@@ -0,0 +1 @@
+["\u2064"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+FDD0_nonchar.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+FDD0_nonchar.json
new file mode 100644
index 000000000..18ef151b4
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+FDD0_nonchar.json
@@ -0,0 +1 @@
+["\uFDD0"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+FFFE_nonchar.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+FFFE_nonchar.json
new file mode 100644
index 000000000..13d261fda
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_U+FFFE_nonchar.json
@@ -0,0 +1 @@
+["\uFFFE"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_unicode_escaped_double_quote.json b/src/boost/libs/json/test/parse-vectors/y_string_unicode_escaped_double_quote.json
new file mode 100644
index 000000000..4e6257856
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_unicode_escaped_double_quote.json
@@ -0,0 +1 @@
+["\u0022"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_utf8.json b/src/boost/libs/json/test/parse-vectors/y_string_utf8.json
new file mode 100644
index 000000000..40878435f
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_utf8.json
@@ -0,0 +1 @@
+["€ð„ž"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_string_with_del_character.json b/src/boost/libs/json/test/parse-vectors/y_string_with_del_character.json
new file mode 100644
index 000000000..8bd24907d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_string_with_del_character.json
@@ -0,0 +1 @@
+["aa"] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_lonely_false.json b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_false.json
new file mode 100644
index 000000000..02e4a84d6
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_false.json
@@ -0,0 +1 @@
+false \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_lonely_int.json b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_int.json
new file mode 100644
index 000000000..f70d7bba4
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_int.json
@@ -0,0 +1 @@
+42 \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_lonely_negative_real.json b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_negative_real.json
new file mode 100644
index 000000000..b5135a207
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_negative_real.json
@@ -0,0 +1 @@
+-0.1 \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_lonely_null.json b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_null.json
new file mode 100644
index 000000000..ec747fa47
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_null.json
@@ -0,0 +1 @@
+null \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_lonely_string.json b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_string.json
new file mode 100644
index 000000000..b6e982ca9
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_string.json
@@ -0,0 +1 @@
+"asd" \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_lonely_true.json b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_true.json
new file mode 100644
index 000000000..f32a5804e
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_structure_lonely_true.json
@@ -0,0 +1 @@
+true \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_string_empty.json b/src/boost/libs/json/test/parse-vectors/y_structure_string_empty.json
new file mode 100644
index 000000000..3cc762b55
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_structure_string_empty.json
@@ -0,0 +1 @@
+"" \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_trailing_newline.json b/src/boost/libs/json/test/parse-vectors/y_structure_trailing_newline.json
new file mode 100644
index 000000000..0c3426d4c
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_structure_trailing_newline.json
@@ -0,0 +1 @@
+["a"]
diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_true_in_array.json b/src/boost/libs/json/test/parse-vectors/y_structure_true_in_array.json
new file mode 100644
index 000000000..de601e305
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_structure_true_in_array.json
@@ -0,0 +1 @@
+[true] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse-vectors/y_structure_whitespace_array.json b/src/boost/libs/json/test/parse-vectors/y_structure_whitespace_array.json
new file mode 100644
index 000000000..2bedf7f2d
--- /dev/null
+++ b/src/boost/libs/json/test/parse-vectors/y_structure_whitespace_array.json
@@ -0,0 +1 @@
+ [] \ No newline at end of file
diff --git a/src/boost/libs/json/test/parse.cpp b/src/boost/libs/json/test/parse.cpp
new file mode 100644
index 000000000..d07e0ed6a
--- /dev/null
+++ b/src/boost/libs/json/test/parse.cpp
@@ -0,0 +1,180 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/parse.hpp>
+
+#include <boost/json/serialize.hpp>
+
+#include <string>
+
+#include "test.hpp"
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+class parse_test
+{
+public:
+ bool hasLocation(std::error_code const&)
+ {
+ return true;
+ }
+
+ bool hasLocation(error_code const& ec)
+ {
+ return ec.has_location();
+ }
+
+ template <class ErrorCode>
+ void
+ good_impl(string_view s)
+ {
+ ErrorCode ec;
+ auto jv = parse(s, ec);
+ if(! BOOST_TEST(! ec))
+ return;
+ BOOST_TEST(
+ serialize(jv) == s);
+ }
+
+ template <class ErrorCode>
+ void
+ bad_impl(string_view s)
+ {
+ ErrorCode ec;
+ auto jv = parse(s, ec);
+ BOOST_TEST(ec);
+ BOOST_TEST(hasLocation(ec));
+ }
+
+ void
+ good(string_view s)
+ {
+ good_impl<error_code>(s);
+ good_impl<std::error_code>(s);
+ }
+
+ void
+ bad(string_view s)
+ {
+ bad_impl<error_code>(s);
+ bad_impl<std::error_code>(s);
+ }
+
+ void
+ testParse()
+ {
+ good("null");
+ good("[1,2,3]");
+ bad ("[1,2,3] #");
+ bad ("555415214748364655415E2147483646");
+ bad ("9.88874836020e-2147483640");
+ }
+
+ void
+ testMemoryUsage()
+ {
+ // string
+ {
+ std::string s(10000, '*');
+ s.insert(s.begin(), '\"');
+ s.append(1, '\"');
+
+ fail_resource mr1;
+ value jv1 = parse(s, &mr1);
+
+ fail_resource mr2;
+ value jv2(jv1, &mr2);
+ BOOST_TEST(mr1.bytes == mr2.bytes);
+
+ fail_resource mr3;
+ value jv3(&mr3);
+ jv3 = jv1;
+ BOOST_TEST(mr1.bytes == mr3.bytes);
+ }
+
+ // array
+ {
+ {
+ fail_resource mr1;
+ value jv1 = parse("[1]", &mr1);
+
+ fail_resource mr2;
+ value jv2(jv1, &mr2);
+ BOOST_TEST(mr1.bytes == mr2.bytes);
+
+ fail_resource mr3;
+ value jv3(&mr3);
+ jv3 = jv1;
+ BOOST_TEST(mr1.bytes == mr3.bytes);
+ }
+ {
+ std::string s;
+ s = "1,2,3,4";
+ s = s + "," + s;
+ s = s + "," + s;
+ s = s + "," + s;
+ s = s + "," + s;
+ s = s + "," + s;
+ s = s + "," + s;
+ s = s + "," + s;
+ s = s + "," + s;
+ s = "[[" + s + "]]";
+
+ fail_resource mr1;
+ value jv1 = parse(s, &mr1);
+
+ fail_resource mr2;
+ value jv2(jv1, &mr2);
+ BOOST_TEST(mr1.bytes == mr2.bytes);
+
+ fail_resource mr3;
+ value jv3(&mr3);
+ jv3 = jv1;
+ BOOST_TEST(mr1.bytes == mr3.bytes);
+ }
+ }
+
+ // object
+ {
+ std::string s;
+ s = "{\"0\":null";
+ for(int i = 1; i < 1000; ++i)
+ s +=
+ ",\"" +
+ std::to_string(i) +
+ "\":null";
+ s.append("}");
+
+ fail_resource mr1;
+ value jv1 = parse(s, &mr1);
+
+ fail_resource mr2;
+ value jv2(jv1, &mr2);
+ BOOST_TEST(mr1.bytes == mr2.bytes);
+
+ fail_resource mr3;
+ value jv3(&mr3);
+ jv3 = jv1;
+ BOOST_TEST(mr1.bytes == mr3.bytes);
+ }
+ }
+
+ void
+ run()
+ {
+ testParse();
+ testMemoryUsage();
+ }
+};
+
+TEST_SUITE(parse_test, "boost.json.parse");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/parser.cpp b/src/boost/libs/json/test/parser.cpp
new file mode 100644
index 000000000..9282a4c0d
--- /dev/null
+++ b/src/boost/libs/json/test/parser.cpp
@@ -0,0 +1,395 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/parser.hpp>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+class parser_test
+{
+public:
+ bool
+ hasLocation(std::error_code const&)
+ {
+ return true;
+ }
+
+ bool
+ hasLocation(error_code const& ec)
+ {
+ return ec.has_location();
+ }
+
+ void
+ testCtors()
+ {
+ // parser(parser const&)
+ BOOST_STATIC_ASSERT(
+ ! std::is_copy_constructible<parser>::value);
+
+ // operator=(parser const&)
+ BOOST_STATIC_ASSERT(
+ ! std::is_copy_assignable<parser>::value);
+
+ // ~parser()
+ {
+ // implied
+ }
+
+ // parser(storage_ptr, parse_options, unsigned char*, size_t)
+ {
+ unsigned char buf[256];
+ parser p(
+ storage_ptr(),
+ parse_options(),
+ &buf[0],
+ sizeof(buf));
+ }
+
+ // parser()
+ {
+ parser p;
+ }
+
+ // parser(storage_ptr, parse_options)
+ {
+ parser p(storage_ptr{}, parse_options());
+ }
+
+ // parser(storage_ptr)
+ {
+ parser p(storage_ptr{});
+ }
+
+ // parser(storage_ptr, parse_options, unsigned char[])
+ {
+ unsigned char buf[256];
+ parser p(
+ storage_ptr(),
+ parse_options(),
+ buf);
+ }
+
+ #if defined(__cpp_lib_byte)
+ // parser(storage_ptr, parse_options, std::byte*, size_t)
+ {
+ std::byte buf[256];
+ parser p(
+ storage_ptr(),
+ parse_options(),
+ &buf[0],
+ sizeof(buf));
+ }
+
+ // parser(storage_ptr, parse_options, std::byte[])
+ {
+ std::byte buf[256];
+ parser p(
+ storage_ptr(),
+ parse_options(),
+ buf);
+ }
+ #endif
+
+ // parser(storage_ptr, parse_options, unsigned char[], size_t)
+ {
+ unsigned char buf[256];
+ parser p(
+ storage_ptr(),
+ parse_options(),
+ buf,
+ sizeof(buf));
+ }
+
+ #if defined(__cpp_lib_byte)
+ // parser(storage_ptr, parse_options, std::byte[], size_t)
+ {
+ std::byte buf[256];
+ parser p(
+ storage_ptr(),
+ parse_options(),
+ buf,
+ sizeof(buf));
+ }
+ #endif
+ }
+
+ template <class ErrorCode>
+ void
+ testMembers()
+ {
+ // reset
+ {
+ parser p;
+ p.reset();
+ }
+
+ // write_some(char const*, size_t, ErrorCode&)
+ {
+ // valid json
+ {
+ parser p;
+ ErrorCode ec;
+ auto const n =
+ p.write_some("null", 4, ec);
+ BOOST_TEST(! ec);
+ BOOST_TEST(n == 4);
+ }
+
+ // valid json with trailing space
+ {
+ parser p;
+ ErrorCode ec;
+ auto const n =
+ p.write_some("null ", 5, ec);
+ BOOST_TEST(! ec);
+ BOOST_TEST(n == 5);
+ }
+
+ // valid json with invalid trailing char
+ {
+ parser p;
+ ErrorCode ec;
+ auto const n =
+ p.write_some("null*", 5, ec);
+ BOOST_TEST(! ec);
+ BOOST_TEST(n == 4);
+ }
+
+ // partial json
+ {
+ parser p;
+ ErrorCode ec;
+ p.write_some("nul", 3, ec);
+ BOOST_TEST(ec);
+ }
+ }
+
+ // write_some(string_view, ErrorCode&)
+ {
+ // valid json
+ {
+ parser p;
+ ErrorCode ec;
+ auto const n =
+ p.write_some("null", ec);
+ BOOST_TEST(! ec);
+ BOOST_TEST(n == 4);
+ }
+
+ // partial json
+ {
+ parser p;
+ ErrorCode ec;
+ p.write_some("nul", ec);
+ BOOST_TEST(ec);
+ }
+ }
+
+ // write_some(char const*, size_t)
+ {
+ // valid json with trailing space
+ {
+ parser p;
+ auto const n =
+ p.write_some("null ", 5);
+ BOOST_TEST(n == 5);
+ }
+
+ // partial json
+ {
+ parser p;
+ BOOST_TEST_THROWS(
+ p.write_some("nul", 3),
+ system_error);
+ }
+ }
+
+ // write_some(string_view)
+ {
+ // valid json with trailing space
+ {
+ parser p;
+ auto const n =
+ p.write_some("null ");
+ BOOST_TEST(n == 5);
+ }
+
+ // partial json
+ {
+ parser p;
+ BOOST_TEST_THROWS(
+ p.write_some("nul"),
+ system_error);
+ }
+ }
+
+ //--------------------------------------------------
+
+ // write(char const*, size_t, ErrorCode&)
+ {
+ // valid json
+ {
+ parser p;
+ ErrorCode ec;
+ auto const n =
+ p.write("null", 4, ec);
+ BOOST_TEST(! ec);
+ BOOST_TEST(n == 4);
+ }
+
+ // valid json with trailing space
+ {
+ parser p;
+ ErrorCode ec;
+ auto const n =
+ p.write("null ", 5, ec);
+ BOOST_TEST(! ec);
+ BOOST_TEST(n == 5);
+ }
+
+ // valid json with invalid trailing char
+ {
+ parser p;
+ ErrorCode ec;
+ p.write("null*", 5, ec);
+ BOOST_TEST(ec);
+ }
+
+ // partial json
+ {
+ parser p;
+ ErrorCode ec;
+ p.write("nul", 3, ec);
+ BOOST_TEST(ec);
+ }
+ }
+
+ // write(string_view, ErrorCode&)
+ {
+ // valid json
+ {
+ parser p;
+ ErrorCode ec;
+ auto const n =
+ p.write("null", ec);
+ BOOST_TEST(! ec);
+ BOOST_TEST(n == 4);
+ }
+
+ // partial json
+ {
+ parser p;
+ ErrorCode ec;
+ p.write("nul", ec);
+ BOOST_TEST(ec);
+ }
+ }
+
+ // write(char const*, size_t)
+ {
+ // valid json with trailing space
+ {
+ parser p;
+ auto const n =
+ p.write("null ", 5);
+ BOOST_TEST(n == 5);
+ }
+
+ // valid json with invalid trailing char
+ {
+ parser p;
+ BOOST_TEST_THROWS(
+ p.write("null*", 5),
+ system_error);
+ }
+
+ // partial json
+ {
+ parser p;
+ BOOST_TEST_THROWS(
+ p.write("nul", 3),
+ system_error);
+ }
+ }
+
+ // write(string_view)
+ {
+ // valid json with trailing space
+ {
+ parser p;
+ auto const n =
+ p.write("null ");
+ BOOST_TEST(n == 5);
+ }
+
+ // valid json with invalid trailing char
+ {
+ parser p;
+ BOOST_TEST_THROWS(
+ p.write("null*"),
+ system_error);
+ }
+
+ // partial json
+ {
+ parser p;
+ BOOST_TEST_THROWS(
+ p.write("nul"),
+ system_error);
+ }
+ }
+
+ // release
+ {
+ // valid json
+ {
+ parser p;
+ p.write("[1,2,3]");
+ BOOST_TEST(p.release() ==
+ value({1,2,3}));
+ }
+
+ // release with no write
+ {
+ parser p;
+ BOOST_TEST_THROWS(
+ p.release(),
+ system_error);
+ }
+
+ // release after error
+ {
+ parser p;
+ ErrorCode ec;
+ p.write("nul", ec);
+ BOOST_TEST(ec);
+ BOOST_TEST(hasLocation(ec));
+ BOOST_TEST_THROWS(
+ p.release(),
+ system_error);
+ }
+ }
+ }
+
+ void
+ run()
+ {
+ testCtors();
+ testMembers<error_code>();
+ testMembers<std::error_code>();
+ }
+};
+
+TEST_SUITE(parser_test, "boost.json.parser");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/pilfer.cpp b/src/boost/libs/json/test/pilfer.cpp
new file mode 100644
index 000000000..01c321955
--- /dev/null
+++ b/src/boost/libs/json/test/pilfer.cpp
@@ -0,0 +1,30 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/pilfer.hpp>
+
+// VFALCO This fails to compile in msvc:
+// https://godbolt.org/z/8q6K8e
+#if 0
+namespace boost {
+namespace json {
+
+namespace detail {
+struct V{};
+} // detail
+
+namespace detail {
+struct T{};
+} // detail
+struct U : detail::T{};
+
+} // json
+} // boost
+#endif
diff --git a/src/boost/libs/json/test/pointer.cpp b/src/boost/libs/json/test/pointer.cpp
new file mode 100644
index 000000000..889e5dd6d
--- /dev/null
+++ b/src/boost/libs/json/test/pointer.cpp
@@ -0,0 +1,248 @@
+//
+// Copyright (c) 2022 Dmitry Arkhipov (grisumbras@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#include <boost/json/value.hpp>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+
+class pointer_test
+{
+ bool
+ hasLocation(error_code const& ec)
+ {
+ return ec.has_location();
+ }
+
+ bool
+ hasLocation(std::error_code const&)
+ {
+ return true;
+ }
+
+ value
+ testValue() const
+ {
+ return value{
+ {"foo", {"bar", "baz", "baf"}},
+ {"", 0},
+ {"a/b", 1},
+ {"c%d", 2},
+ {"e^f", 3},
+ {"g|h", 4},
+ {"i\\j", 5},
+ {"k\"l", 6},
+ {" ", 7},
+ {"m~n", 8},
+ {"x", object{{"y", "z"}}},
+ };
+ }
+
+ value
+ bigObject() const
+ {
+ object result;
+ for (int i = 0; i < 50; ++i)
+ {
+ result.emplace(std::to_string(i), i);
+ }
+ return result;
+ }
+
+public:
+ void
+ testRootPointer()
+ {
+ value const jv = testValue();
+ BOOST_TEST(&jv.at_pointer("") == &jv);
+ }
+
+ void
+ testChildPointer()
+ {
+ value const jv = testValue();
+ BOOST_TEST(&jv.at_pointer("/foo")== &jv.at("foo"));
+ BOOST_TEST(&jv.at_pointer("/c%d")== &jv.at("c%d"));
+ BOOST_TEST(&jv.at_pointer("/e^f")== &jv.at("e^f"));
+ BOOST_TEST(&jv.at_pointer("/g|h")== &jv.at("g|h"));
+ BOOST_TEST(&jv.at_pointer("/")== &jv.at(""));
+ BOOST_TEST(&jv.at_pointer("/i\\j")== &jv.at("i\\j"));
+ BOOST_TEST(&jv.at_pointer("/k\"l")== &jv.at("k\"l"));
+ BOOST_TEST(&jv.at_pointer("/ ")== &jv.at(" "));
+ }
+
+ void
+ testEscaped()
+ {
+ value const jv = testValue();
+ BOOST_TEST(&jv.at_pointer("/a~1b")== &jv.at("a/b"));
+ BOOST_TEST(&jv.at_pointer("/m~0n")== &jv.at("m~n"));
+ }
+
+ void
+ testNested()
+ {
+ value const jv = testValue();
+ BOOST_TEST(&jv.at_pointer("/foo/0") == &jv.at("foo").at(0));
+ BOOST_TEST(&jv.at_pointer("/foo/1") == &jv.at("foo").at(1));
+ BOOST_TEST(&jv.at_pointer("/x/y") == &jv.at("x").at("y"));
+
+ {
+ value v1;
+ object& o1 = v1.emplace_object();
+ object& o2 = (o1["very"] = value()).emplace_object();
+ object& o3 = (o2["deep"] = value()).emplace_object();
+
+ array& a1 = (o3["path"] = value()).emplace_array();
+ a1.emplace_back(value());
+
+ array& a2 = a1.emplace_back(value()).emplace_array();
+ a2.emplace_back(value());
+ a2.emplace_back(value());
+
+ array& a3 = a2.emplace_back(value()).emplace_array();
+ object& o4 = a3.emplace_back(value()).emplace_object();
+ object& o5 = (o4["0"] = value()).emplace_object();
+ value& v2 = o5["fin"] = value();
+
+ BOOST_TEST(&v1.at_pointer("/very/deep/path/1/2/0/0/fin") == &v2);
+ }
+ }
+
+ void
+ testErrors()
+ {
+ value const jv = testValue();
+ BOOST_TEST_THROWS(jv.at_pointer("foo"), system_error);
+ BOOST_TEST_THROWS(jv.at_pointer("/fo"), system_error);
+ BOOST_TEST_THROWS(jv.at_pointer("/m~"), system_error);
+ BOOST_TEST_THROWS(jv.at_pointer("/m~n"), system_error);
+ BOOST_TEST_THROWS(jv.at_pointer("/foo/bar"), system_error);
+ BOOST_TEST_THROWS(jv.at_pointer("/foo/"), system_error);
+ BOOST_TEST_THROWS(jv.at_pointer("/foo/01"), system_error);
+ BOOST_TEST_THROWS(jv.at_pointer("/foo/2b"), system_error);
+ BOOST_TEST_THROWS(jv.at_pointer("/x/y/z"), system_error);
+ }
+
+ template<class ErrorCode>
+ void
+ testNonThrowing()
+ {
+ value jv = testValue();
+ ErrorCode ec = error::syntax;
+ BOOST_TEST(jv.find_pointer("/foo/0", ec) == &jv.at("foo").at(0));
+ BOOST_TEST(!ec);
+
+ auto const& cjv = jv;
+ ec = error::syntax;
+ BOOST_TEST(cjv.find_pointer("/foo/1", ec) == &jv.at("foo").at(1));
+ BOOST_TEST(!ec);
+
+ jv.find_pointer("foo", ec);
+ BOOST_TEST(ec == error::missing_slash);
+ BOOST_TEST(hasLocation(ec));
+
+ jv.find_pointer("/fo", ec);
+ BOOST_TEST(ec == error::not_found);
+ BOOST_TEST(hasLocation(ec));
+
+ jv.find_pointer("/foo/25", ec);
+ BOOST_TEST(ec == error::not_found);
+ BOOST_TEST(hasLocation(ec));
+
+ value(object()).find_pointer("/foo", ec);
+ BOOST_TEST(ec == error::not_found);
+ BOOST_TEST(hasLocation(ec));
+
+ bigObject().find_pointer("/foo", ec);
+ BOOST_TEST(ec == error::not_found);
+ BOOST_TEST(hasLocation(ec));
+
+ jv.find_pointer("/m~", ec);
+ BOOST_TEST(ec == error::invalid_escape);
+ BOOST_TEST(hasLocation(ec));
+
+ jv.find_pointer("/m~n", ec);
+ BOOST_TEST(ec == error::invalid_escape);
+ BOOST_TEST(hasLocation(ec));
+
+ jv.find_pointer("/foo/bar", ec);
+ BOOST_TEST(ec == error::token_not_number);
+ BOOST_TEST(hasLocation(ec));
+
+ jv.find_pointer("/foo/", ec);
+ BOOST_TEST(ec == error::token_not_number);
+ BOOST_TEST(hasLocation(ec));
+
+ jv.find_pointer("/foo/01", ec);
+ BOOST_TEST(ec == error::token_not_number);
+ BOOST_TEST(hasLocation(ec));
+
+ jv.find_pointer("/foo/2b", ec);
+ BOOST_TEST(ec == error::token_not_number);
+ BOOST_TEST(hasLocation(ec));
+
+ jv.find_pointer("/foo/2.", ec);
+ BOOST_TEST(ec == error::token_not_number);
+ BOOST_TEST(hasLocation(ec));
+
+ jv.find_pointer("/foo/-", ec);
+ BOOST_TEST(ec == error::past_the_end);
+ BOOST_TEST(hasLocation(ec));
+
+ jv.find_pointer("/foo/-/x", ec);
+ BOOST_TEST(ec == error::past_the_end);
+ BOOST_TEST(hasLocation(ec));
+
+ jv.find_pointer("/foo/-1", ec);
+ BOOST_TEST(ec == error::token_not_number);
+ BOOST_TEST(hasLocation(ec));
+
+ jv.find_pointer("/x/y/z", ec);
+ BOOST_TEST(ec == error::value_is_scalar);
+ BOOST_TEST(hasLocation(ec));
+
+ string s = "/foo/";
+ s += std::to_string((std::numeric_limits<std::size_t>::max)());
+ if ( '9' == s[s.size() - 1] )
+ {
+ for (std::size_t i = 6; i < s.size(); ++i)
+ {
+ s[i] = '0';
+ }
+ s[5] = '1';
+ s += "0";
+ }
+ else
+ {
+ ++s[s.size() - 1];
+ }
+ jv.find_pointer(s, ec);
+ BOOST_TEST(ec == error::token_overflow);
+ BOOST_TEST(hasLocation(ec));
+ }
+
+ void
+ run()
+ {
+ testRootPointer();
+ testChildPointer();
+ testEscaped();
+ testNested();
+ testErrors();
+ testNonThrowing<error_code>();
+ testNonThrowing<std::error_code>();
+ }
+};
+
+TEST_SUITE(pointer_test, "boost.json.pointer");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/ryu/d2s_intrinsics_test.cpp b/src/boost/libs/json/test/ryu/d2s_intrinsics_test.cpp
new file mode 100644
index 000000000..bb492cc71
--- /dev/null
+++ b/src/boost/libs/json/test/ryu/d2s_intrinsics_test.cpp
@@ -0,0 +1,56 @@
+// Copyright 2018 Ulf Adams
+//
+// The contents of this file may be used under the terms of the Apache License,
+// Version 2.0.
+//
+// (See accompanying file LICENSE-Apache or copy at
+// http://www.apache.org/licenses/LICENSE-2.0)
+//
+// Alternatively, the contents of this file may be used under the terms of
+// the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE-Boost or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+//
+// Unless required by applicable law or agreed to in writing, this software
+// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.
+
+/*
+ This is a derivative work
+*/
+
+#include <boost/json/detail/ryu/detail/d2s_intrinsics.hpp>
+#include "gtest.hpp"
+#include <math.h>
+
+BOOST_JSON_NS_BEGIN
+namespace detail {
+
+namespace ryu {
+namespace detail {
+
+TEST(D2sIntrinsicsTest, mod1e9) {
+ ASSERT_EQ(0, mod1e9(0));
+ ASSERT_EQ(1, mod1e9(1));
+ ASSERT_EQ(2, mod1e9(2));
+ ASSERT_EQ(10, mod1e9(10));
+ ASSERT_EQ(100, mod1e9(100));
+ ASSERT_EQ(1000, mod1e9(1000));
+ ASSERT_EQ(10000, mod1e9(10000));
+ ASSERT_EQ(100000, mod1e9(100000));
+ ASSERT_EQ(1000000, mod1e9(1000000));
+ ASSERT_EQ(10000000, mod1e9(10000000));
+ ASSERT_EQ(100000000, mod1e9(100000000));
+ ASSERT_EQ(0, mod1e9(1000000000));
+ ASSERT_EQ(0, mod1e9(2000000000));
+ ASSERT_EQ(1, mod1e9(1000000001));
+ ASSERT_EQ(1234, mod1e9(1000001234));
+ ASSERT_EQ(123456789, mod1e9(12345123456789ull));
+ ASSERT_EQ(123456789, mod1e9(123456789123456789ull));
+}
+
+} // detail
+} // ryu
+
+} // detail
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/ryu/d2s_table_test.cpp b/src/boost/libs/json/test/ryu/d2s_table_test.cpp
new file mode 100644
index 000000000..226a2fc64
--- /dev/null
+++ b/src/boost/libs/json/test/ryu/d2s_table_test.cpp
@@ -0,0 +1,106 @@
+// Copyright 2018 Ulf Adams
+//
+// The contents of this file may be used under the terms of the Apache License,
+// Version 2.0.
+//
+// (See accompanying file LICENSE-Apache or copy at
+// http://www.apache.org/licenses/LICENSE-2.0)
+//
+// Alternatively, the contents of this file may be used under the terms of
+// the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE-Boost or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+//
+// Unless required by applicable law or agreed to in writing, this software
+// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.
+
+/*
+ This is a derivative work
+*/
+
+#if defined(__SIZEOF_INT128__) && !defined(_MSC_VER) && !defined(RYU_ONLY_64_BIT_OPS)
+#define BOOST_JSON_RYU_HAS_UINT128
+#elif defined(_MSC_VER) && !defined(RYU_ONLY_64_BIT_OPS) && defined(_M_X64) \
+ && !defined(__clang__) // https://bugs.llvm.org/show_bug.cgi?id=37755
+#define BOOST_JSON_RYU_HAS_64_BIT_INTRINSICS
+#endif
+
+// We want to test the size-optimized case here.
+#if !defined(BOOST_JSON_RYU_OPTIMIZE_SIZE)
+#define BOOST_JSON_RYU_OPTIMIZE_SIZE
+#endif
+#include <boost/json/detail/ryu/detail/d2s.hpp>
+#include <boost/json/detail/ryu/detail/d2s_full_table.hpp>
+#include <array>
+#include <cstdint>
+#include <cmath>
+#include "gtest.hpp"
+
+BOOST_JSON_NS_BEGIN
+namespace detail {
+
+namespace ryu {
+namespace detail {
+
+TEST(D2sTableTest, double_computePow5) {
+ for (int i = 0; i < 326; i++) {
+ uint64_t m[2];
+ double_computePow5(i, m);
+ ASSERT_EQ(m[0], DOUBLE_POW5_SPLIT()[i][0]);
+ ASSERT_EQ(m[1], DOUBLE_POW5_SPLIT()[i][1]);
+ }
+}
+
+TEST(D2sTableTest, compute_offsets_for_double_computePow5) {
+ uint32_t totalErrors = 0;
+ uint32_t offsets[13] = {0};
+ for (int i = 0; i < 326; i++) {
+ uint64_t m[2];
+ double_computePow5(i, m);
+ if (m[0] != DOUBLE_POW5_SPLIT()[i][0]) {
+ offsets[i / POW5_TABLE_SIZE] |= 1 << (i % POW5_TABLE_SIZE);
+ totalErrors++;
+ }
+ }
+ if (totalErrors != 0) {
+ for (int i = 0; i < 13; i++) {
+ printf("0x%08x,\n", offsets[i]);
+ }
+ }
+ ASSERT_EQ(totalErrors, 0);
+}
+
+TEST(D2sTableTest, double_computeInvPow5) {
+ for (int i = 0; i < 292; i++) {
+ uint64_t m[2];
+ double_computeInvPow5(i, m);
+ ASSERT_EQ(m[0], DOUBLE_POW5_INV_SPLIT()[i][0]);
+ ASSERT_EQ(m[1], DOUBLE_POW5_INV_SPLIT()[i][1]);
+ }
+}
+
+TEST(D2sTableTest, compute_offsets_for_double_computeInvPow5) {
+ uint32_t totalErrors = 0;
+ uint32_t offsets[20] = {0};
+ for (int i = 0; i < 292; i++) {
+ uint64_t m[2];
+ double_computeInvPow5(i, m);
+ if (m[0] != DOUBLE_POW5_INV_SPLIT()[i][0]) {
+ offsets[i / 16] |= ((DOUBLE_POW5_INV_SPLIT()[i][0] - m[0]) & 3) << ((i % 16) << 1);
+ totalErrors++;
+ }
+ }
+ if (totalErrors != 0) {
+ for (int i = 0; i < 20; i++) {
+ printf("0x%08x,\n", offsets[i]);
+ }
+ }
+ ASSERT_EQ(totalErrors, 0);
+}
+
+} // detail
+} // ryu
+
+} // detail
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/ryu/d2s_test.cpp b/src/boost/libs/json/test/ryu/d2s_test.cpp
new file mode 100644
index 000000000..e5d969d07
--- /dev/null
+++ b/src/boost/libs/json/test/ryu/d2s_test.cpp
@@ -0,0 +1,277 @@
+// Copyright 2018 Ulf Adams
+//
+// The contents of this file may be used under the terms of the Apache License,
+// Version 2.0.
+//
+// (See accompanying file LICENSE-Apache or copy at
+// http://www.apache.org/licenses/LICENSE-2.0)
+//
+// Alternatively, the contents of this file may be used under the terms of
+// the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE-Boost or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+//
+// Unless required by applicable law or agreed to in writing, this software
+// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.
+
+/*
+ This is a derivative work
+*/
+
+#include <boost/json/detail/ryu/ryu.hpp>
+#include <array>
+#include <cmath>
+#include "gtest.hpp"
+
+BOOST_JSON_NS_BEGIN
+namespace detail {
+
+namespace ryu {
+
+static double int64Bits2Double(uint64_t bits) {
+ double f;
+ memcpy(&f, &bits, sizeof(double));
+ return f;
+}
+
+static double ieeeParts2Double(const bool sign, const uint32_t ieeeExponent, const uint64_t ieeeMantissa) {
+ BOOST_ASSERT(ieeeExponent <= 2047);
+ BOOST_ASSERT(ieeeMantissa <= ((std::uint64_t)1 << 53) - 1);
+ return int64Bits2Double(((std::uint64_t)sign << 63) | ((std::uint64_t)ieeeExponent << 52) | ieeeMantissa);
+}
+
+char const* d2s_test_helper(char* result, double f) {
+ int index = d2s_buffered_n(f, result);
+ result[index] = '\0';
+ return result;
+}
+
+TEST(D2sTest, Basic) {
+ std::array<char, 25> buffer;
+ ASSERT_STREQ("0E0", d2s_test_helper(buffer.data(), 0.0));
+ ASSERT_STREQ("-0E0", d2s_test_helper(buffer.data(), -0.0));
+ ASSERT_STREQ("1E0", d2s_test_helper(buffer.data(), 1.0));
+ ASSERT_STREQ("-1E0", d2s_test_helper(buffer.data(), -1.0));
+ ASSERT_STREQ("NaN", d2s_test_helper(buffer.data(), NAN));
+ ASSERT_STREQ("Infinity", d2s_test_helper(buffer.data(), INFINITY));
+ ASSERT_STREQ("-Infinity", d2s_test_helper(buffer.data(), -INFINITY));
+}
+
+TEST(D2sTest, SwitchToSubnormal) {
+ std::array<char, 25> buffer;
+ ASSERT_STREQ("2.2250738585072014E-308", d2s_test_helper(buffer.data(), 2.2250738585072014E-308));
+}
+
+TEST(D2sTest, MinAndMax) {
+ std::array<char, 25> buffer;
+ ASSERT_STREQ("1.7976931348623157E308", d2s_test_helper(buffer.data(), int64Bits2Double(0x7fefffffffffffff)));
+ ASSERT_STREQ("5E-324", d2s_test_helper(buffer.data(), int64Bits2Double(1)));
+}
+
+TEST(D2sTest, LotsOfTrailingZeros) {
+ std::array<char, 25> buffer;
+ ASSERT_STREQ("2.9802322387695312E-8", d2s_test_helper(buffer.data(), 2.98023223876953125E-8));
+}
+
+TEST(D2sTest, Regression) {
+ std::array<char, 25> buffer;
+ ASSERT_STREQ("-2.109808898695963E16", d2s_test_helper(buffer.data(), -2.109808898695963E16));
+ ASSERT_STREQ("4.940656E-318", d2s_test_helper(buffer.data(), 4.940656E-318));
+ ASSERT_STREQ("1.18575755E-316", d2s_test_helper(buffer.data(), 1.18575755E-316));
+ ASSERT_STREQ("2.989102097996E-312", d2s_test_helper(buffer.data(), 2.989102097996E-312));
+ ASSERT_STREQ("9.0608011534336E15", d2s_test_helper(buffer.data(), 9.0608011534336E15));
+ ASSERT_STREQ("4.708356024711512E18", d2s_test_helper(buffer.data(), 4.708356024711512E18));
+ ASSERT_STREQ("9.409340012568248E18", d2s_test_helper(buffer.data(), 9.409340012568248E18));
+ ASSERT_STREQ("1.2345678E0", d2s_test_helper(buffer.data(), 1.2345678));
+}
+
+TEST(D2sTest, LooksLikePow5) {
+ std::array<char, 25> buffer;
+ // These numbers have a mantissa that is a multiple of the largest power of 5 that fits,
+ // and an exponent that causes the computation for q to result in 22, which is a corner
+ // case for Ryu.
+ ASSERT_STREQ("5.764607523034235E39", d2s_test_helper(buffer.data(), int64Bits2Double(0x4830F0CF064DD592)));
+ ASSERT_STREQ("1.152921504606847E40", d2s_test_helper(buffer.data(), int64Bits2Double(0x4840F0CF064DD592)));
+ ASSERT_STREQ("2.305843009213694E40", d2s_test_helper(buffer.data(), int64Bits2Double(0x4850F0CF064DD592)));
+}
+
+TEST(D2sTest, OutputLength) {
+ std::array<char, 25> buffer;
+ ASSERT_STREQ("1E0", d2s_test_helper(buffer.data(), 1)); // already tested in Basic
+ ASSERT_STREQ("1.2E0", d2s_test_helper(buffer.data(), 1.2));
+ ASSERT_STREQ("1.23E0", d2s_test_helper(buffer.data(), 1.23));
+ ASSERT_STREQ("1.234E0", d2s_test_helper(buffer.data(), 1.234));
+ ASSERT_STREQ("1.2345E0", d2s_test_helper(buffer.data(), 1.2345));
+ ASSERT_STREQ("1.23456E0", d2s_test_helper(buffer.data(), 1.23456));
+ ASSERT_STREQ("1.234567E0", d2s_test_helper(buffer.data(), 1.234567));
+ ASSERT_STREQ("1.2345678E0", d2s_test_helper(buffer.data(), 1.2345678)); // already tested in Regression
+ ASSERT_STREQ("1.23456789E0", d2s_test_helper(buffer.data(), 1.23456789));
+ ASSERT_STREQ("1.234567895E0", d2s_test_helper(buffer.data(), 1.234567895)); // 1.234567890 would be trimmed
+ ASSERT_STREQ("1.2345678901E0", d2s_test_helper(buffer.data(), 1.2345678901));
+ ASSERT_STREQ("1.23456789012E0", d2s_test_helper(buffer.data(), 1.23456789012));
+ ASSERT_STREQ("1.234567890123E0", d2s_test_helper(buffer.data(), 1.234567890123));
+ ASSERT_STREQ("1.2345678901234E0", d2s_test_helper(buffer.data(), 1.2345678901234));
+ ASSERT_STREQ("1.23456789012345E0", d2s_test_helper(buffer.data(), 1.23456789012345));
+ ASSERT_STREQ("1.234567890123456E0", d2s_test_helper(buffer.data(), 1.234567890123456));
+ ASSERT_STREQ("1.2345678901234567E0", d2s_test_helper(buffer.data(), 1.2345678901234567));
+
+ // Test 32-bit chunking
+ ASSERT_STREQ("4.294967294E0", d2s_test_helper(buffer.data(), 4.294967294)); // 2^32 - 2
+ ASSERT_STREQ("4.294967295E0", d2s_test_helper(buffer.data(), 4.294967295)); // 2^32 - 1
+ ASSERT_STREQ("4.294967296E0", d2s_test_helper(buffer.data(), 4.294967296)); // 2^32
+ ASSERT_STREQ("4.294967297E0", d2s_test_helper(buffer.data(), 4.294967297)); // 2^32 + 1
+ ASSERT_STREQ("4.294967298E0", d2s_test_helper(buffer.data(), 4.294967298)); // 2^32 + 2
+}
+
+// Test min, max shift values in shiftright128
+TEST(D2sTest, MinMaxShift) {
+ std::array<char, 25> buffer;
+ const uint64_t maxMantissa = ((std::uint64_t)1 << 53) - 1;
+
+ // 32-bit opt-size=0: 49 <= dist <= 50
+ // 32-bit opt-size=1: 30 <= dist <= 50
+ // 64-bit opt-size=0: 50 <= dist <= 50
+ // 64-bit opt-size=1: 30 <= dist <= 50
+ ASSERT_STREQ("1.7800590868057611E-307", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 4, 0)));
+ // 32-bit opt-size=0: 49 <= dist <= 49
+ // 32-bit opt-size=1: 28 <= dist <= 49
+ // 64-bit opt-size=0: 50 <= dist <= 50
+ // 64-bit opt-size=1: 28 <= dist <= 50
+ ASSERT_STREQ("2.8480945388892175E-306", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 6, maxMantissa)));
+ // 32-bit opt-size=0: 52 <= dist <= 53
+ // 32-bit opt-size=1: 2 <= dist <= 53
+ // 64-bit opt-size=0: 53 <= dist <= 53
+ // 64-bit opt-size=1: 2 <= dist <= 53
+ ASSERT_STREQ("2.446494580089078E-296", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 41, 0)));
+ // 32-bit opt-size=0: 52 <= dist <= 52
+ // 32-bit opt-size=1: 2 <= dist <= 52
+ // 64-bit opt-size=0: 53 <= dist <= 53
+ // 64-bit opt-size=1: 2 <= dist <= 53
+ ASSERT_STREQ("4.8929891601781557E-296", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 40, maxMantissa)));
+
+ // 32-bit opt-size=0: 57 <= dist <= 58
+ // 32-bit opt-size=1: 57 <= dist <= 58
+ // 64-bit opt-size=0: 58 <= dist <= 58
+ // 64-bit opt-size=1: 58 <= dist <= 58
+ ASSERT_STREQ("1.8014398509481984E16", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 1077, 0)));
+ // 32-bit opt-size=0: 57 <= dist <= 57
+ // 32-bit opt-size=1: 57 <= dist <= 57
+ // 64-bit opt-size=0: 58 <= dist <= 58
+ // 64-bit opt-size=1: 58 <= dist <= 58
+ ASSERT_STREQ("3.6028797018963964E16", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 1076, maxMantissa)));
+ // 32-bit opt-size=0: 51 <= dist <= 52
+ // 32-bit opt-size=1: 51 <= dist <= 59
+ // 64-bit opt-size=0: 52 <= dist <= 52
+ // 64-bit opt-size=1: 52 <= dist <= 59
+ ASSERT_STREQ("2.900835519859558E-216", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 307, 0)));
+ // 32-bit opt-size=0: 51 <= dist <= 51
+ // 32-bit opt-size=1: 51 <= dist <= 59
+ // 64-bit opt-size=0: 52 <= dist <= 52
+ // 64-bit opt-size=1: 52 <= dist <= 59
+ ASSERT_STREQ("5.801671039719115E-216", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 306, maxMantissa)));
+
+ // https://github.com/ulfjack/ryu/commit/19e44d16d80236f5de25800f56d82606d1be00b9#commitcomment-30146483
+ // 32-bit opt-size=0: 49 <= dist <= 49
+ // 32-bit opt-size=1: 44 <= dist <= 49
+ // 64-bit opt-size=0: 50 <= dist <= 50
+ // 64-bit opt-size=1: 44 <= dist <= 50
+ ASSERT_STREQ("3.196104012172126E-27", d2s_test_helper(buffer.data(), ieeeParts2Double(false, 934, 0x000FA7161A4D6E0Cu)));
+}
+
+TEST(D2sTest, SmallIntegers) {
+ std::array<char, 25> buffer;
+ ASSERT_STREQ("9.007199254740991E15", d2s_test_helper(buffer.data(), 9007199254740991.0)); // 2^53-1
+ ASSERT_STREQ("9.007199254740992E15", d2s_test_helper(buffer.data(), 9007199254740992.0)); // 2^53
+
+ ASSERT_STREQ("1E0", d2s_test_helper(buffer.data(), 1.0e+0));
+ ASSERT_STREQ("1.2E1", d2s_test_helper(buffer.data(), 1.2e+1));
+ ASSERT_STREQ("1.23E2", d2s_test_helper(buffer.data(), 1.23e+2));
+ ASSERT_STREQ("1.234E3", d2s_test_helper(buffer.data(), 1.234e+3));
+ ASSERT_STREQ("1.2345E4", d2s_test_helper(buffer.data(), 1.2345e+4));
+ ASSERT_STREQ("1.23456E5", d2s_test_helper(buffer.data(), 1.23456e+5));
+ ASSERT_STREQ("1.234567E6", d2s_test_helper(buffer.data(), 1.234567e+6));
+ ASSERT_STREQ("1.2345678E7", d2s_test_helper(buffer.data(), 1.2345678e+7));
+ ASSERT_STREQ("1.23456789E8", d2s_test_helper(buffer.data(), 1.23456789e+8));
+ ASSERT_STREQ("1.23456789E9", d2s_test_helper(buffer.data(), 1.23456789e+9));
+ ASSERT_STREQ("1.234567895E9", d2s_test_helper(buffer.data(), 1.234567895e+9));
+ ASSERT_STREQ("1.2345678901E10", d2s_test_helper(buffer.data(), 1.2345678901e+10));
+ ASSERT_STREQ("1.23456789012E11", d2s_test_helper(buffer.data(), 1.23456789012e+11));
+ ASSERT_STREQ("1.234567890123E12", d2s_test_helper(buffer.data(), 1.234567890123e+12));
+ ASSERT_STREQ("1.2345678901234E13", d2s_test_helper(buffer.data(), 1.2345678901234e+13));
+ ASSERT_STREQ("1.23456789012345E14", d2s_test_helper(buffer.data(), 1.23456789012345e+14));
+ ASSERT_STREQ("1.234567890123456E15", d2s_test_helper(buffer.data(), 1.234567890123456e+15));
+
+ // 10^i
+ ASSERT_STREQ("1E0", d2s_test_helper(buffer.data(), 1.0e+0));
+ ASSERT_STREQ("1E1", d2s_test_helper(buffer.data(), 1.0e+1));
+ ASSERT_STREQ("1E2", d2s_test_helper(buffer.data(), 1.0e+2));
+ ASSERT_STREQ("1E3", d2s_test_helper(buffer.data(), 1.0e+3));
+ ASSERT_STREQ("1E4", d2s_test_helper(buffer.data(), 1.0e+4));
+ ASSERT_STREQ("1E5", d2s_test_helper(buffer.data(), 1.0e+5));
+ ASSERT_STREQ("1E6", d2s_test_helper(buffer.data(), 1.0e+6));
+ ASSERT_STREQ("1E7", d2s_test_helper(buffer.data(), 1.0e+7));
+ ASSERT_STREQ("1E8", d2s_test_helper(buffer.data(), 1.0e+8));
+ ASSERT_STREQ("1E9", d2s_test_helper(buffer.data(), 1.0e+9));
+ ASSERT_STREQ("1E10", d2s_test_helper(buffer.data(), 1.0e+10));
+ ASSERT_STREQ("1E11", d2s_test_helper(buffer.data(), 1.0e+11));
+ ASSERT_STREQ("1E12", d2s_test_helper(buffer.data(), 1.0e+12));
+ ASSERT_STREQ("1E13", d2s_test_helper(buffer.data(), 1.0e+13));
+ ASSERT_STREQ("1E14", d2s_test_helper(buffer.data(), 1.0e+14));
+ ASSERT_STREQ("1E15", d2s_test_helper(buffer.data(), 1.0e+15));
+
+ // 10^15 + 10^i
+ ASSERT_STREQ("1.000000000000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+0));
+ ASSERT_STREQ("1.00000000000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+1));
+ ASSERT_STREQ("1.0000000000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+2));
+ ASSERT_STREQ("1.000000000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+3));
+ ASSERT_STREQ("1.00000000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+4));
+ ASSERT_STREQ("1.0000000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+5));
+ ASSERT_STREQ("1.000000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+6));
+ ASSERT_STREQ("1.00000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+7));
+ ASSERT_STREQ("1.0000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+8));
+ ASSERT_STREQ("1.000001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+9));
+ ASSERT_STREQ("1.00001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+10));
+ ASSERT_STREQ("1.0001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+11));
+ ASSERT_STREQ("1.001E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+12));
+ ASSERT_STREQ("1.01E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+13));
+ ASSERT_STREQ("1.1E15", d2s_test_helper(buffer.data(), 1.0e+15 + 1.0e+14));
+
+ // Largest power of 2 <= 10^(i+1)
+ ASSERT_STREQ("8E0", d2s_test_helper(buffer.data(), 8.0));
+ ASSERT_STREQ("6.4E1", d2s_test_helper(buffer.data(), 64.0));
+ ASSERT_STREQ("5.12E2", d2s_test_helper(buffer.data(), 512.0));
+ ASSERT_STREQ("8.192E3", d2s_test_helper(buffer.data(), 8192.0));
+ ASSERT_STREQ("6.5536E4", d2s_test_helper(buffer.data(), 65536.0));
+ ASSERT_STREQ("5.24288E5", d2s_test_helper(buffer.data(), 524288.0));
+ ASSERT_STREQ("8.388608E6", d2s_test_helper(buffer.data(), 8388608.0));
+ ASSERT_STREQ("6.7108864E7", d2s_test_helper(buffer.data(), 67108864.0));
+ ASSERT_STREQ("5.36870912E8", d2s_test_helper(buffer.data(), 536870912.0));
+ ASSERT_STREQ("8.589934592E9", d2s_test_helper(buffer.data(), 8589934592.0));
+ ASSERT_STREQ("6.8719476736E10", d2s_test_helper(buffer.data(), 68719476736.0));
+ ASSERT_STREQ("5.49755813888E11", d2s_test_helper(buffer.data(), 549755813888.0));
+ ASSERT_STREQ("8.796093022208E12", d2s_test_helper(buffer.data(), 8796093022208.0));
+ ASSERT_STREQ("7.0368744177664E13", d2s_test_helper(buffer.data(), 70368744177664.0));
+ ASSERT_STREQ("5.62949953421312E14", d2s_test_helper(buffer.data(), 562949953421312.0));
+ ASSERT_STREQ("9.007199254740992E15", d2s_test_helper(buffer.data(), 9007199254740992.0));
+
+ // 1000 * (Largest power of 2 <= 10^(i+1))
+ ASSERT_STREQ("8E3", d2s_test_helper(buffer.data(), 8.0e+3));
+ ASSERT_STREQ("6.4E4", d2s_test_helper(buffer.data(), 64.0e+3));
+ ASSERT_STREQ("5.12E5", d2s_test_helper(buffer.data(), 512.0e+3));
+ ASSERT_STREQ("8.192E6", d2s_test_helper(buffer.data(), 8192.0e+3));
+ ASSERT_STREQ("6.5536E7", d2s_test_helper(buffer.data(), 65536.0e+3));
+ ASSERT_STREQ("5.24288E8", d2s_test_helper(buffer.data(), 524288.0e+3));
+ ASSERT_STREQ("8.388608E9", d2s_test_helper(buffer.data(), 8388608.0e+3));
+ ASSERT_STREQ("6.7108864E10", d2s_test_helper(buffer.data(), 67108864.0e+3));
+ ASSERT_STREQ("5.36870912E11", d2s_test_helper(buffer.data(), 536870912.0e+3));
+ ASSERT_STREQ("8.589934592E12", d2s_test_helper(buffer.data(), 8589934592.0e+3));
+ ASSERT_STREQ("6.8719476736E13", d2s_test_helper(buffer.data(), 68719476736.0e+3));
+ ASSERT_STREQ("5.49755813888E14", d2s_test_helper(buffer.data(), 549755813888.0e+3));
+ ASSERT_STREQ("8.796093022208E15", d2s_test_helper(buffer.data(), 8796093022208.0e+3));
+}
+
+} // ryu
+
+} // detail
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/ryu/gtest.hpp b/src/boost/libs/json/test/ryu/gtest.hpp
new file mode 100644
index 000000000..582cebe21
--- /dev/null
+++ b/src/boost/libs/json/test/ryu/gtest.hpp
@@ -0,0 +1,34 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#ifndef GTEST_HPP
+#define GTEST_HPP
+
+#include <boost/json/detail/config.hpp>
+#include <boost/json/string_view.hpp>
+
+#include "test_suite.hpp"
+
+#define TEST(s1,s2) \
+struct s1 ## _ ## s2 ## _test; \
+TEST_SUITE(s1 ## _ ## s2 ## _test, "boost.Ryu." #s1 "." #s2); \
+struct s1 ## _ ## s2 ## _test { \
+ void run(); }; void s1 ## _ ## s2 ## _test::run()
+
+#define EXPECT_STREQ(s1, s2) \
+ BOOST_TEST(::boost::json::string_view(s1) == \
+ ::boost::json::string_view(s2))
+
+#define ASSERT_STREQ(s1, s2) \
+ { auto const s1_ = (s1); auto const s2_ = (s2); \
+ EXPECT_STREQ(s1_, s2_); }
+
+#define ASSERT_EQ(e1, e2) BOOST_TEST((e1)==(e2))
+
+#endif
diff --git a/src/boost/libs/json/test/serialize.cpp b/src/boost/libs/json/test/serialize.cpp
new file mode 100644
index 000000000..0bbde7032
--- /dev/null
+++ b/src/boost/libs/json/test/serialize.cpp
@@ -0,0 +1,68 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/serialize.hpp>
+
+#include <boost/json/parse.hpp>
+#include <boost/json/static_resource.hpp>
+#include <sstream>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+class serialize_test
+{
+public:
+ template<class T>
+ static
+ std::string
+ print(T const& t)
+ {
+ std::stringstream ss;
+ ss << t;
+ return ss.str();
+ }
+
+ void
+ testSerialize()
+ {
+ {
+ value const jv = { 1, 2, 3 };
+ BOOST_TEST(serialize(jv) == "[1,2,3]");
+ BOOST_TEST(print(jv) == "[1,2,3]");
+ }
+ {
+ array const arr = { 1, 2 ,3 };
+ BOOST_TEST(serialize(arr) == "[1,2,3]");
+ BOOST_TEST(print(arr) == "[1,2,3]");
+ }
+ {
+ object const obj = { {"k1",1}, {"k2",2} };
+ BOOST_TEST(serialize(obj) == "{\"k1\":1,\"k2\":2}");
+ BOOST_TEST(print(obj) == "{\"k1\":1,\"k2\":2}");
+ }
+ {
+ string const str = "123";
+ BOOST_TEST(serialize(str) == "\"123\"");
+ BOOST_TEST(print(str) == "\"123\"");
+ }
+ }
+
+ void
+ run()
+ {
+ testSerialize();
+ }
+};
+
+TEST_SUITE(serialize_test, "boost.json.serialize");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/serializer.cpp b/src/boost/libs/json/test/serializer.cpp
new file mode 100644
index 000000000..7a78f0f2f
--- /dev/null
+++ b/src/boost/libs/json/test/serializer.cpp
@@ -0,0 +1,565 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/serializer.hpp>
+
+#include <boost/json/parse.hpp>
+#include <boost/json/serialize.hpp>
+#include <iostream>
+
+#include "parse-vectors.hpp"
+#include "test.hpp"
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+BOOST_STATIC_ASSERT( std::is_nothrow_destructible<serializer>::value );
+
+class serializer_test
+{
+public:
+ //------------------------------------------------------
+
+ // From the javadoc
+
+ void print( std::ostream& os, value const& jv)
+ {
+ serializer sr;
+ sr.reset( &jv );
+ while( ! sr.done() )
+ {
+ char buf[ 4000 ];
+ os << sr.read( buf );
+ }
+ }
+
+ //------------------------------------------------------
+
+ ::test_suite::log_type log;
+
+ void
+ grind_one(
+ string_view s,
+ value const& jv,
+ string_view name = {})
+ {
+ {
+ error_code ec;
+ auto const s1 = serialize(jv);
+ auto const jv2 = parse(s1, ec);
+ if(! BOOST_TEST(equal(jv, jv2)))
+ {
+ if(name.empty())
+ log <<
+ " " << s << "\n"
+ " " << s1 <<
+ std::endl;
+ else
+ log << name << ":\n"
+ " " << s << "\n"
+ " " << s1 <<
+ std::endl;
+ }
+ }
+
+ // large buffer
+ {
+ error_code ec;
+ serializer sr;
+ sr.reset(&jv);
+ string js;
+ js.reserve(4096);
+ js.grow(sr.read(
+ js.data(), js.capacity()).size());
+
+ auto const s1 = serialize(jv);
+ auto const jv2 = parse(s1, ec);
+ BOOST_TEST(equal(jv, jv2));
+ }
+ }
+
+ void
+ grind(
+ string_view s0,
+ value const& jv,
+ string_view name = {})
+ {
+ grind_one(s0, jv, name);
+
+ auto const s1 = serialize(jv);
+ for(std::size_t i = 1;
+ i < s1.size(); ++i)
+ {
+ serializer sr;
+ sr.reset(&jv);
+ string s2;
+ s2.reserve(s1.size());
+ s2.grow(sr.read(
+ s2.data(), i).size());
+ auto const dump =
+ [&]
+ {
+ if(name.empty())
+ log <<
+ " " << s0 << "\n"
+ " " << s1 << "\n"
+ " " << s2 << std::endl;
+ else
+ log << name << ":\n"
+ " " << s0 << "\n"
+ " " << s1 << "\n"
+ " " << s2 << std::endl;
+ };
+ if(! BOOST_TEST(
+ s2.size() == i))
+ {
+ dump();
+ break;
+ }
+ s2.grow(sr.read(
+ s2.data() + i,
+ s1.size() - i).size());
+ if(! BOOST_TEST(
+ s2.size() == s1.size()))
+ {
+ dump();
+ break;
+ }
+ if(! BOOST_TEST(s2 == s1))
+ {
+ dump();
+ break;
+ }
+ }
+ }
+
+ //------------------------------------------------------
+
+ void
+ testNull()
+ {
+ check("null");
+ }
+
+ void
+ testBoolean()
+ {
+ check("true");
+ check("false");
+ }
+
+ void
+ testString()
+ {
+ check("\"\"");
+ check("\"x\"");
+ check("\"xyz\"");
+ check("\"x z\"");
+
+ // escapes
+ check("\"\\\"\""); // double quote
+ check("\"\\\\\""); // backslash
+ check("\"\\b\""); // backspace
+ check("\"\\f\""); // formfeed
+ check("\"\\n\""); // newline
+ check("\"\\r\""); // carriage return
+ check("\"\\t\""); // horizontal tab
+
+ // control characters
+ check("\"\\u0000\"");
+ check("\"\\u0001\"");
+ check("\"\\u0002\"");
+ check("\"\\u0003\"");
+ check("\"\\u0004\"");
+ check("\"\\u0005\"");
+ check("\"\\u0006\"");
+ check("\"\\u0007\"");
+ check("\"\\u0008\"");
+ check("\"\\u0009\"");
+ check("\"\\u000a\"");
+ check("\"\\u000b\"");
+ check("\"\\u000c\"");
+ check("\"\\u000d\"");
+ check("\"\\u000e\"");
+ check("\"\\u000f\"");
+ check("\"\\u0010\"");
+ check("\"\\u0011\"");
+ check("\"\\u0012\"");
+ check("\"\\u0013\"");
+ check("\"\\u0014\"");
+ check("\"\\u0015\"");
+ check("\"\\u0016\"");
+ check("\"\\u0017\"");
+ check("\"\\u0018\"");
+ check("\"\\u0019\"");
+ check("\"\\u0020\"");
+ check("\"\\u0021\"");
+ }
+
+ void
+ testNumber()
+ {
+ // VFALCO These don't perfectly round-trip,
+ // because the representations are not exact.
+ // The test needs to do a better job of comparison.
+
+ check("-999999999999999999999");
+ check("-100000000000000000009");
+ check("-10000000000000000000");
+ //check("-9223372036854775809");
+ check("-9223372036854775808");
+ check("-9223372036854775807");
+ check("-999999999999999999");
+ check("-99999999999999999");
+ check("-9999999999999999");
+ check("-999999999999999");
+ check("-99999999999999");
+ check("-9999999999999");
+ check("-999999999999");
+ check("-99999999999");
+ check("-9999999999");
+ check("-999999999");
+ check("-99999999");
+ check("-9999999");
+ check("-999999");
+ check("-99999");
+ check("-9999");
+ check("-999");
+ check("-99");
+ check("-9");
+ check("-0");
+ check("-0.0");
+ check( "0");
+ check( "9");
+ check( "99");
+ check( "999");
+ check( "9999");
+ check( "99999");
+ check( "999999");
+ check( "9999999");
+ check( "99999999");
+ check( "999999999");
+ check( "9999999999");
+ check( "99999999999");
+ check( "999999999999");
+ check( "9999999999999");
+ check( "99999999999999");
+ check( "999999999999999");
+ check( "9999999999999999");
+ check( "99999999999999999");
+ check( "999999999999999999");
+ check( "9223372036854775807");
+ check( "9223372036854775808");
+ check( "9999999999999999999");
+ check( "18446744073709551615");
+ //check( "18446744073709551616");
+ check( "99999999999999999999");
+ check( "999999999999999999999");
+ check( "1000000000000000000000");
+ check( "9999999999999999999999");
+ check( "99999999999999999999999");
+
+ //check("-0.9999999999999999999999");
+ check("-0.9999999999999999");
+ //check("-0.9007199254740991");
+ //check("-0.999999999999999");
+ //check("-0.99999999999999");
+ //check("-0.9999999999999");
+ //check("-0.999999999999");
+ //check("-0.99999999999");
+ //check("-0.9999999999");
+ //check("-0.999999999");
+ //check("-0.99999999");
+ //check("-0.9999999");
+ //check("-0.999999");
+ //check("-0.99999");
+ //check("-0.9999");
+ //check("-0.8125");
+ //check("-0.999");
+ //check("-0.99");
+ check("-1.0");
+ check("-0.9");
+ check("-0.0");
+ check( "0.0");
+ check( "0.9");
+ //check( "0.99");
+ //check( "0.999");
+ //check( "0.8125");
+ //check( "0.9999");
+ //check( "0.99999");
+ //check( "0.999999");
+ //check( "0.9999999");
+ //check( "0.99999999");
+ //check( "0.999999999");
+ //check( "0.9999999999");
+ //check( "0.99999999999");
+ //check( "0.999999999999");
+ //check( "0.9999999999999");
+ //check( "0.99999999999999");
+ //check( "0.999999999999999");
+ //check( "0.9007199254740991");
+ check( "0.9999999999999999");
+ //check( "0.9999999999999999999999");
+ //check( "0.999999999999999999999999999");
+
+ check("-1e308");
+ check("-1e-308");
+ //check("-9999e300");
+ //check("-999e100");
+ //check("-99e10");
+ check("-9e1");
+ check( "9e1");
+ //check( "99e10");
+ //check( "999e100");
+ //check( "9999e300");
+ check( "999999999999999999.0");
+ check( "999999999999999999999.0");
+ check( "999999999999999999999e5");
+ check( "999999999999999999999.0e5");
+
+ check("-1e-1");
+ check("-1e0");
+ check("-1e1");
+ check( "0e0");
+ check( "1e0");
+ check( "1e10");
+ }
+
+ void
+ testArray()
+ {
+ check("[]");
+ check("[[]]");
+ check("[[],[],[]]");
+ check("[[[[[[[[[[]]]]]]]]]]");
+ check("[{}]");
+ check("[{},{}]");
+ check("[1,2,3,4,5]");
+ check("[true,false,null]");
+ }
+
+ void
+ testObject()
+ {
+ check("{}");
+ check("{\"x\":1}");
+ check("{\"x\":[]}");
+ check("{\"x\":1,\"y\":null}");
+ }
+
+ //------------------------------------------------------
+
+ void
+ testMembers()
+ {
+ // serializer()
+ {
+ serializer sr;
+
+ char buf[32];
+ BOOST_TEST(sr.read(buf) == "null");
+ }
+
+ // done()
+ {
+ value jv = 1;
+ serializer sr;
+ sr.reset(&jv);
+ BOOST_TEST(! sr.done());
+ char buf[32];
+ BOOST_TEST(sr.read(buf) == "1");
+ BOOST_TEST(sr.done());
+ }
+
+ // read()
+ {
+ value jv = 1;
+ serializer sr;
+ sr.reset(&jv);
+ char buf[1024];
+ auto const s = sr.read(buf);
+ BOOST_TEST(sr.done());
+ BOOST_TEST(s == "1");
+ }
+
+ // checked read()
+ {
+ serializer sr;
+ char buf[100];
+ BOOST_TEST(sr.read(buf, 50) == "null");
+ }
+
+ // reset(value)
+ {
+ char buf[100];
+ serializer sr;
+ value jv = { 1, 2, 3 };
+ sr.reset(&jv);
+ BOOST_TEST(sr.read(buf) == "[1,2,3]");
+ }
+
+ // reset(array)
+ {
+ char buf[100];
+ serializer sr;
+ array arr = { 1, 2, 3 };
+ sr.reset(&arr);
+ BOOST_TEST(sr.read(buf) == "[1,2,3]");
+ }
+
+ // reset(object)
+ {
+ char buf[100];
+ serializer sr;
+ object obj = { {"k1",1}, {"k2",2} };
+ sr.reset(&obj);
+ BOOST_TEST(sr.read(buf) == "{\"k1\":1,\"k2\":2}");
+ }
+
+ // reset(string)
+ {
+ char buf[100];
+ serializer sr;
+ string str = "123";
+ sr.reset(&str);
+ BOOST_TEST(sr.read(buf) == "\"123\"");
+ }
+ }
+
+ void
+ check(
+ string_view s,
+ string_view name = {})
+ {
+ try
+ {
+ auto const jv = parse(s);
+ grind(s, jv, name);
+ }
+ catch(std::exception const&)
+ {
+ BOOST_TEST_FAIL();
+ }
+ }
+
+ void
+ testVectors()
+ {
+#if 0
+ check(
+ R"xx({
+ "glossary": {
+ "title": "example glossary",
+ "GlossDiv": {
+ "title": "S",
+ "GlossList": {
+ "GlossEntry": {
+ "ID": "SGML",
+ "SortAs": "SGML",
+ "GlossTerm": "Standard Generalized Markup Language",
+ "Acronym": "SGML",
+ "Abbrev": "ISO 8879:1986",
+ "GlossDef": {
+ "para": "A meta-markup language, used to create markup languages such as DocBook.",
+ "GlossSeeAlso": ["GML", "XML"]
+ },
+ "GlossSee": "markup"
+ }
+ }
+ }
+ }
+ })xx");
+#endif
+
+ parse_vectors const pv;
+ for(auto const e : pv)
+ {
+ if(e.result != 'y')
+ continue;
+ // skip these failures for now
+ if(
+ e.name == "number" ||
+ e.name == "number_real_exponent" ||
+ e.name == "number_real_fraction_exponent" ||
+ e.name == "number_simple_real" ||
+ e.name == "object_extreme_numbers" ||
+ e.name == "pass01"
+ )
+ continue;
+ check(e.text, e.name);
+ }
+ }
+
+ std::string
+ to_ostream(value const& jv)
+ {
+ std::stringstream ss;
+ ss << jv;
+ return ss.str();
+ }
+
+ void
+ testOstream()
+ {
+ for(string_view js : {
+ "{\"1\":{},\"2\":[],\"3\":\"x\",\"4\":1,"
+ "\"5\":-1,\"6\":144.0,\"7\":false,\"8\":null}",
+ "[1,2,3,4,5]"
+ })
+ {
+ error_code ec;
+ auto const jv1 = parse(js, ec);
+ if(! BOOST_TEST(! ec))
+ return;
+ auto const jv2 =
+ parse(to_ostream(jv1), ec);
+ if(! BOOST_TEST(! ec))
+ return;
+ if(! BOOST_TEST(equal(jv1, jv2)))
+ log <<
+ " " << js << "\n"
+ " " << jv1 << "\n"
+ " " << jv2 <<
+ std::endl;
+ }
+ }
+
+ void
+ testNumberRoundTrips()
+ {
+ // no decimal or exponent parsed as integer
+ BOOST_TEST(parse("-0").as_int64() == 0);
+ BOOST_TEST(serialize(parse("-0")) == "0");
+ BOOST_TEST(parse("-0.0").as_double() == -0);
+ BOOST_TEST(serialize(parse("0.0")) == "0E0");
+ BOOST_TEST(parse("0.0").as_double() == 0);
+ BOOST_TEST(serialize(parse("-0.0")) == "-0E0");
+ }
+
+ void
+ run()
+ {
+ testNull();
+ testBoolean();
+ testString();
+ testNumber();
+ testArray();
+ testObject();
+
+ testMembers();
+ testVectors();
+ testOstream();
+ testNumberRoundTrips();
+ }
+};
+
+TEST_SUITE(serializer_test, "boost.json.serializer");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/snippets.cpp b/src/boost/libs/json/test/snippets.cpp
new file mode 100644
index 000000000..5d7893f3a
--- /dev/null
+++ b/src/boost/libs/json/test/snippets.cpp
@@ -0,0 +1,903 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#include <boost/json.hpp>
+
+#include <algorithm>
+#include <cmath>
+#include <complex>
+#include <iostream>
+#include <map>
+#include <numeric>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "test_suite.hpp"
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4101)
+#elif defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wunused"
+# pragma clang diagnostic ignored "-Wmismatched-tags"
+#elif defined(__GNUC__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wunused"
+#endif
+
+//[snippet_conv_3
+
+template< std::size_t N >
+struct static_string { };
+
+namespace std
+{
+
+template< std::size_t N >
+class hash< static_string< N > >
+{
+public:
+ std::size_t
+ operator()(const static_string< N >& str ) const noexcept
+ {
+ return std::hash< std::string >()( str );
+ }
+};
+
+} // std
+
+//]
+
+BOOST_JSON_NS_BEGIN
+
+//[snippet_conv_4
+
+template< class T >
+void
+tag_invoke( const value_from_tag&, value& jv, std::complex< T > const& t)
+{
+ // Store a complex number as a 2-element array
+ // with the real part followed by the imaginary part
+ jv = { t.real(), t.imag() };
+}
+
+template< class T >
+std::complex< T >
+tag_invoke( const value_to_tag< std::complex< T > >&, value const& jv )
+{
+ return std::complex< T >(
+ jv.as_array().at(0).to_number< T >(),
+ jv.as_array().at(1).to_number< T >());
+}
+
+//]
+
+namespace {
+
+void
+usingStrings()
+{
+ {
+ //[snippet_strings_1
+
+ string str1; // empty string, uses the default memory resource
+
+ string str2( make_shared_resource<monotonic_resource>() ); // empty string, uses a counted monotonic resource
+
+ //]
+ }
+ {
+ //[snippet_strings_2
+
+ std::string sstr1 = "helloworld";
+ std::string sstr2 = "world";
+
+ json::string jstr1 = "helloworld";
+ json::string jstr2 = "world";
+
+ assert( jstr2.insert(0, jstr1.subview(0, 5)) == "helloworld" );
+
+ // this is equivalent to
+ assert( sstr2.insert(0, sstr1, 0, 5) == "helloworld" );
+
+ //]
+ }
+ {
+ //[snippet_strings_3
+
+ std::string sstr = "hello";
+
+ json::string jstr = "hello";
+
+ assert(sstr.append({'w', 'o', 'r', 'l', 'd'}) == "helloworld");
+
+ // such syntax is inefficient, and the same can
+ // be achieved with a character array.
+
+ assert(jstr.append("world") == "helloworld");
+
+ //]
+ }
+
+ {
+ //[snippet_strings_4
+
+ json::string str = "Boost.JSON";
+ json::string_view sv = str;
+
+ // all of these call compare(string_view)
+ str.compare(sv);
+
+ str.compare(sv.substr(0, 5));
+
+ str.compare(str);
+
+ str.compare("Boost");
+
+ //]
+ }
+}
+
+//----------------------------------------------------------
+
+void
+usingValues()
+{
+ {
+ //[snippet_value_1
+
+ value jv1;
+ value jv2( nullptr );
+
+ assert( jv1.is_null() );
+ assert( jv2.is_null() );
+
+ //]
+ }
+ {
+ //[snippet_value_2
+
+ value jv( object_kind );
+
+ assert( jv.kind() == kind::object );
+ assert( jv.is_object() );
+ assert( ! jv.is_number() );
+
+ //]
+ }
+ {
+ auto f = []{
+ //[snippet_value_3
+
+ value jv( object_kind );
+
+ if( auto p = jv.if_object() )
+ return p->size();
+
+ //]
+ return std::size_t(0);
+ };
+ (void)f;
+ }
+ {
+ //[snippet_value_4
+
+ value jv;
+ jv = value( array_kind );
+
+ assert( jv.is_array() );
+
+ jv.emplace_string();
+
+ assert( jv.is_string() );
+
+ //]
+ }
+ {
+ //[snippet_value_5
+
+ value jv;
+ jv.emplace_string() = "Hello, world!";
+
+ int64_t& num = jv.emplace_int64();
+ num = 1;
+
+ assert( jv.is_int64() );
+
+ //]
+ }
+ {
+ try
+ {
+ //[snippet_value_6
+
+ value jv( true );
+ jv.as_bool() = true;
+
+ jv.as_string() = "Hello, world!"; // throws an exception
+
+ //]
+ }
+ catch(...)
+ {
+ }
+ }
+ {
+ //[snippet_value_7
+
+ value jv( string_kind );
+ if( string* str = jv.if_string() )
+ *str = "Hello, world!";
+
+ //]
+ }
+ {
+ //[snippet_value_8
+
+ value jv( string_kind );
+
+ // The compiler's static analysis can see that
+ // a null pointer is never dereferenced.
+ *jv.if_string() = "Hello, world!";
+
+ //]
+ }
+}
+
+//----------------------------------------------------------
+
+void
+usingInitLists()
+{
+ {
+ //[snippet_init_list_1
+
+ value jv = {
+ { "name", "John Doe" },
+ { "active", true },
+ { "associated-accounts", nullptr },
+ { "total-balance", 330.00 },
+ { "account-balances", { 84, 120, 126 } } };
+
+ //]
+ }
+
+ {
+ //[snippet_init_list_2
+
+ value jv = { true, 2, "hello", nullptr };
+
+ assert( jv.is_array() );
+
+ assert( jv.as_array().size() == 4 );
+
+ assert( serialize(jv) == "[true,2,\"hello\",null]" );
+
+ //]
+ }
+
+ {
+ //[snippet_init_list_3
+
+ value jv = { true, 2, "hello", { "bye", nullptr, false } };
+
+ assert( jv.is_array() );
+
+ assert( jv.as_array().back().is_array() );
+
+ assert( serialize(jv) == "[true,2,\"hello\",[\"bye\",null,false]]" );
+
+ //]
+ }
+
+ {
+ //[snippet_init_list_4
+
+ // Should this be an array or an object?
+ value jv = { { "hello", 42 }, { "world", 43 } };
+
+ //]
+ }
+
+ {
+ //[snippet_init_list_5
+
+ value jv1 = { { "hello", 42 }, { "world", 43 } };
+
+ assert( jv1.is_object() );
+
+ assert( jv1.as_object().size() == 2 );
+
+ assert( serialize(jv1) == R"({"hello":42,"world":43})" );
+
+ // All of the following are arrays
+
+ value jv2 = { { "make", "Tesla" }, { "model", 3 }, "black" };
+
+ value jv3 = { { "library", "JSON" }, { "Boost", "C++", "Fast", "JSON" } };
+
+ value jv4 = { { "color", "blue" }, { 1, "red" } };
+
+ assert( jv2.is_array() && jv3.is_array() && jv4.is_array() );
+
+ //]
+ }
+
+ {
+ //[snippet_init_list_6
+
+ value jv = { { "hello", 42 }, array{ "world", 43 } };
+
+ assert( jv.is_array() );
+
+ array& ja = jv.as_array();
+
+ assert( ja[0].is_array() && ja[1].is_array());
+
+ assert ( serialize(jv) == R"([["hello",42],["world",43]])" );
+
+ //]
+
+ (void)ja;
+ }
+
+ {
+ //[snippet_init_list_7
+
+ value jv = { { "mercury", 36 }, { "venus", 67 }, { "earth", 93 } };
+
+ assert( jv.is_object() );
+
+ assert( serialize(jv) == "{\"mercury\":36,\"venus\":67,\"earth\":93}" );
+
+ array ja = { { "mercury", 36 }, { "venus", 67 }, { "earth", 93 } };
+
+ assert( serialize(ja) == "[[\"mercury\",36],[\"venus\",67],[\"earth\",93]]" );
+
+ //]
+
+ (void)ja;
+ }
+
+ {
+ //[snippet_init_list_8
+
+ object jo = { { "mercury", { { "distance", 36 } } }, { "venus", { 67, "million miles" } }, { "earth", 93 } };
+
+ assert( jo["mercury"].is_object() );
+
+ assert( jo["venus"].is_array() );
+
+ //]
+ }
+
+ {
+ //[snippet_init_list_9
+
+ object jo1 = { { "john", 100 }, { "dave", 500 }, { "joe", 300 } };
+
+ value jv = { { "clients", std::move(jo1) } };
+
+ object& jo2 = jv.as_object()["clients"].as_object();
+
+ assert( ! jo2.empty() && jo1.empty() );
+
+ assert( serialize(jv) == R"({"clients":{"john":100,"dave":500,"joe":300}})" );
+
+ //]
+
+ (void)jo2;
+ }
+}
+
+//----------------------------------------------------------
+
+void
+usingArrays()
+{
+ {
+ //[snippet_arrays_1
+
+ array arr1; // empty array, uses the default memory resource
+
+ array arr2( make_shared_resource<monotonic_resource>() ); // empty array, uses a counted monotonic resource
+
+ //]
+ }
+ {
+ //[snippet_arrays_2
+
+ array arr( { "Hello", 42, true } );
+
+ //]
+ }
+ try
+ {
+ //[snippet_arrays_3
+
+ array arr;
+
+ arr.emplace_back( "Hello" );
+ arr.emplace_back( 42 );
+ arr.emplace_back( true );
+
+ //]
+
+ //[snippet_arrays_4
+
+ assert( arr[0].as_string() == "Hello" );
+
+ // The following line throws std::out_of_range, since the index is out of range
+ arr.at( 3 ) = nullptr;
+
+ //]
+ }
+ catch (...)
+ {
+ }
+}
+
+//----------------------------------------------------------
+
+void
+usingObjects()
+{
+ {
+ //[snippet_objects_1
+
+ object obj1; // empty object, uses the default memory resource
+
+ object obj2( make_shared_resource<monotonic_resource>() ); // empty object, uses a counted monotonic resource
+
+ //]
+ }
+ {
+ //[snippet_objects_2
+
+ object obj( {{"key1", "value1" }, { "key2", 42 }, { "key3", false }} );
+
+ //]
+ }
+ {
+ //[snippet_objects_3
+
+ object obj;
+
+ obj.emplace( "key1", "value1" );
+ obj.emplace( "key2", 42 );
+ obj.emplace( "key3", false );
+
+ //]
+ }
+ try
+ {
+ //[snippet_objects_4
+
+ object obj;
+
+ obj["key1"] = "value1";
+ obj["key2"] = 42;
+ obj["key3"] = false;
+
+ // The following line throws std::out_of_range, since the key does not exist
+ obj.at( "key4" );
+
+ //]
+ }
+ catch (...)
+ {
+ }
+}
+
+//----------------------------------------------------------
+
+//[snippet_conv_2
+
+template< class T >
+void identity_swap( T& a, T& b )
+{
+ // introduces the declaration of
+ // std::swap into this scope
+ using std::swap;
+ if( &a == &b )
+ return;
+ // the overload set will contain std::swap,
+ // any declarations of swap within the enclosing
+ // namespace, and any declarations of swap within
+ // the namespaces associated with T
+ swap( a, b );
+}
+
+//]
+
+//[snippet_conv_5
+
+template< class T >
+struct vec3
+{
+ T x, y, z;
+};
+
+template< class T >
+void tag_invoke( const value_from_tag&, value& jv, const vec3<T>& vec )
+{
+ jv = {
+ { "x", vec.x },
+ { "y", vec.y },
+ { "z", vec.z }
+ };
+}
+
+//]
+
+#ifdef BOOST_JSON_DOCS
+//[snippet_conv_7
+
+template< class T, typename std::enable_if<
+ std::is_floating_point< T >::value>::type* = nullptr >
+void tag_invoke( const value_from_tag&, value& jv, T t )
+{
+ jv = std::llround( t );
+}
+
+//]
+#endif
+
+//[snippet_conv_10
+
+struct customer
+{
+ std::uint64_t id;
+ std::string name;
+ bool late;
+
+ customer() = default;
+
+ customer( std::uint64_t i, const std::string& n, bool l )
+ : id( i ), name( n ), late( l ) { }
+
+ explicit customer( value const& );
+};
+
+void tag_invoke( const value_from_tag&, value& jv, customer const& c )
+{
+ // Assign a JSON value
+ jv = {
+ { "id", c.id },
+ { "name", c.name },
+ { "late", c.late }
+ };
+}
+
+//]
+
+//[snippet_conv_14
+
+customer tag_invoke( const value_to_tag<customer>&, const value& jv )
+{
+ // at() throws if `jv` is not an object, or if the key is not found.
+ // as_uint64() will throw if the value is not an unsigned 64-bit integer.
+ std::uint64_t id = jv.at( "id" ).as_uint64();
+
+ // We already know that jv is an object from
+ // the previous call to jv.as_object() succeeding,
+ // now we use jv.get_object() which skips the
+ // check. value_to will throw if jv.kind() != kind::string
+ std::string name = value_to< std::string >( jv.get_object().at( "name" ) );
+
+ // id and name are constructed from JSON in the member
+ // initializer list above, but we can also use regular
+ // assignments in the body of the function as shown below.
+ // as_bool() will throw if kv.kind() != kind::bool
+ bool late = jv.get_object().at( "late" ).as_bool();
+
+ return customer(id, name, late);
+}
+
+//]
+
+void
+usingExchange()
+{
+ {
+ //[snippet_conv_1
+
+ std::vector< int > v1{ 1, 2, 3, 4 };
+
+ // Convert the vector to a JSON array
+ value jv = value_from( v1 );
+
+ assert( jv.is_array() );
+
+ array& ja = jv.as_array();
+
+ assert( ja.size() == 4 );
+
+ for ( std::size_t i = 0; i < v1.size(); ++i )
+ assert( v1[i] == ja[i].as_int64() );
+
+ // Convert back to vector< int >
+ std::vector< int > v2 = value_to< std::vector< int > >( jv );
+
+ assert( v1 == v2 );
+
+ //]
+
+ (void)ja;
+ }
+ {
+ //[snippet_conv_6
+
+ vec3< int > pos = { 4, 1, 4 };
+
+ value jv = value_from( pos );
+
+ assert( serialize( jv ) == "{\"x\":4,\"y\":1,\"z\":4}" );
+
+ //]
+ }
+ {
+ //[snippet_conv_8
+
+ value jv = value_from( 1.5 ); // error
+
+ //]
+ }
+ {
+ //[snippet_conv_9
+
+ std::map< std::string, vec3< int > > positions = {
+ { "Alex", { 42, -60, 18 } },
+ { "Blake", { 300, -60, -240} },
+ { "Carol", { -60, 30, 30 } }
+ };
+
+ // conversions are applied recursively;
+ // the key type and value type will be converted
+ // using value_from as well
+ value jv = value_from( positions );
+
+ assert( jv.is_object() );
+
+ object& jo = jv.as_object();
+
+ assert( jo.size() == 3 );
+
+ // The sum of the coordinates is 0
+ assert( std::accumulate( jo.begin(), jo.end(), std::int64_t(0),
+ []( std::int64_t total, const key_value_pair& jp )
+ {
+ assert ( jp.value().is_object() );
+
+ const object& pos = jp.value().as_object();
+
+ return total + pos.at( "x" ).as_int64() +
+ pos.at( "y" ).as_int64() +
+ pos.at( "z" ).as_int64();
+
+ } ) == 0 );
+
+ //]
+
+ (void)jo;
+ }
+ {
+ //[snippet_conv_11
+
+ std::vector< customer > customers = {
+ customer( 0, "Alison", false ),
+ customer( 1, "Bill", false ),
+ customer( 3, "Catherine", true ),
+ customer( 4, "Doug", false )
+ };
+
+ storage_ptr sp = make_shared_resource< monotonic_resource >();
+
+ value jv = value_from( customers, sp );
+
+ assert( jv.storage() == sp );
+
+ assert( jv.is_array() );
+
+ //]
+ }
+
+ {
+ //[snippet_conv_12
+
+ // Satisfies both FromMapLike and FromContainerLike
+ std::unordered_map< std::string, bool > available_tools = {
+ { "Crowbar", true },
+ { "Hammer", true },
+ { "Drill", true },
+ { "Saw", false },
+ };
+
+ value jv = value_from( available_tools );
+
+ assert( jv.is_object() );
+
+ //]
+ }
+ {
+ //[snippet_conv_13
+
+ std::complex< double > c1 = { 3.14159, 2.71828 };
+
+ // Convert a complex number to JSON
+ value jv = value_from( c1 );
+
+ assert ( jv.is_array() );
+
+ // Convert back to a complex number
+
+ std::complex< double > c2 = value_to< std::complex< double > >( jv );
+
+ //]
+
+ (void)c2;
+ }
+ {
+ //[snippet_conv_15
+
+ customer c1( 5, "Ed", false );
+
+ // Convert customer to value
+ value jv = value_from( c1 );
+
+ // Convert the result back to customer
+ customer c2 = value_to< customer >( jv );
+
+ // The resulting customer is unchanged
+ assert( c1.name == c2.name );
+
+ //]
+ }
+ {
+ //[snippet_conv_16
+
+ value available_tools = {
+ { "Crowbar", true },
+ { "Hammer", true },
+ { "Drill", true },
+ { "Saw", false }
+ };
+
+ assert( available_tools.is_object() );
+
+ auto as_map = value_to< std::map< std::string, bool > >( available_tools );
+
+ assert( available_tools.as_object().size() == as_map.size() );
+
+ //]
+ }
+}
+
+void
+usingPointer()
+{
+ //[snippet_pointer_1
+ value jv = { {"one", 1}, {"two", 2} };
+ assert( jv.at("one") == jv.at_pointer("/one") );
+
+ jv.at_pointer("/one") = {{"foo", "bar"}};
+ assert( jv.at("one").at("foo") == jv.at_pointer("/one/foo") );
+
+ jv.at_pointer("/one/foo") = {true, 4, "qwerty"};
+ assert( jv.at("one").at("foo").at(1) == jv.at_pointer("/one/foo/1") );
+ //]
+
+ value* elem1 = [&]() -> value*
+ {
+ //[snippet_pointer_2
+ object* obj = jv.if_object();
+ if( !obj )
+ return nullptr;
+
+ value* val = obj->if_contains("one");
+ if( !val )
+ return nullptr;
+
+ obj = val->if_object();
+ if( !obj )
+ return nullptr;
+
+ val = obj->if_contains("foo");
+ if( !val )
+ return nullptr;
+
+ array* arr = val->if_array();
+ if( !arr )
+ return nullptr;
+
+ return arr->if_contains(1);
+ //]
+ }();
+
+ value* elem2 = [&]() -> value*
+ {
+ //[snippet_pointer_3
+ error_code ec;
+ return jv.find_pointer("/one/foo/1", ec);
+ //]
+ }();
+
+ (void)elem1;
+ (void)elem2;
+ assert( elem1 == elem2 );
+}
+
+BOOST_STATIC_ASSERT(
+ has_value_from<customer>::value);
+
+BOOST_STATIC_ASSERT(
+ has_value_from<std::complex<float>>::value);
+BOOST_STATIC_ASSERT(
+ has_value_from<std::complex<double>>::value);
+
+BOOST_STATIC_ASSERT(
+ has_value_to<std::complex<float>>::value);
+BOOST_STATIC_ASSERT(
+ has_value_to<std::complex<double>>::value);
+
+} // (anon)
+
+} // json
+} // boost
+
+//----------------------------------------------------------
+
+
+namespace {
+
+class my_non_deallocating_resource { };
+
+} // (anon)
+
+//[snippet_allocators_14
+namespace boost {
+namespace json {
+
+template<>
+struct is_deallocate_trivial< my_non_deallocating_resource >
+{
+ static constexpr bool value = true;
+};
+
+} // json
+} // boost
+
+//]
+
+namespace boost {
+namespace json {
+
+class snippets_test
+{
+public:
+ void
+ run()
+ {
+ usingValues();
+ usingInitLists();
+ usingExchange();
+ usingArrays();
+ usingObjects();
+ usingStrings();
+ usingPointer();
+
+ BOOST_TEST_PASS();
+ }
+};
+
+TEST_SUITE(snippets_test, "boost.json.snippets");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/static_resource.cpp b/src/boost/libs/json/test/static_resource.cpp
new file mode 100644
index 000000000..c21fb0b65
--- /dev/null
+++ b/src/boost/libs/json/test/static_resource.cpp
@@ -0,0 +1,129 @@
+//
+// Copyright (c) 2020 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/static_resource.hpp>
+
+#include <boost/json/parse.hpp>
+#include <boost/json/serialize.hpp>
+#include <iostream>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+BOOST_STATIC_ASSERT( std::is_nothrow_destructible<static_resource>::value );
+
+class static_resource_test
+{
+public:
+ void
+ testJavadocs()
+ {
+ //--------------------------------------
+
+ unsigned char buf[ 4000 ];
+ static_resource mr( buf );
+
+ // Parse the string, using our memory resource
+ value jv = parse( "[1,2,3]", &mr );
+
+ // Print the JSON
+ std::cout << jv;
+
+ //--------------------------------------
+ }
+
+ void
+ test()
+ {
+ // static_resource(unsigned char*, size_t)
+ {
+ unsigned char buf[1000];
+ static_resource mr(
+ &buf[0], sizeof(buf));
+ BOOST_TEST(serialize(parse(
+ "[1,2,3]", &mr)) == "[1,2,3]");
+ }
+
+ #if defined(__cpp_lib_byte)
+ // static_resource(std::byte*, size_t)
+ {
+ std::byte buf[1000];
+ static_resource mr(
+ &buf[0], sizeof(buf));
+ BOOST_TEST(serialize(parse(
+ "[1,2,3]", &mr)) == "[1,2,3]");
+ }
+ #endif
+
+ // static_resource(unsigned char[N])
+ {
+ unsigned char buf[10];
+ static_resource mr(buf);
+ BOOST_TEST_THROWS(
+ serialize(parse("[1,2,3]", &mr)),
+ std::bad_alloc);
+ }
+
+ #if defined(__cpp_lib_byte)
+ // static_resource(std::byte[N])
+ {
+ std::byte buf[10];
+ static_resource mr(buf);
+ BOOST_TEST_THROWS(
+ serialize(parse("[1,2,3]", &mr)),
+ std::bad_alloc);
+ }
+ #endif
+
+ // static_resource(unsigned char[N], size_t)
+ {
+ unsigned char buf[1000];
+ static_resource mr(
+ buf, 500);
+ BOOST_TEST(serialize(parse(
+ "[1,2,3]", &mr)) == "[1,2,3]");
+ }
+
+ #if defined(__cpp_lib_byte)
+ // static_resource(std::byte[N])
+ {
+ std::byte buf[1000];
+ static_resource mr(
+ buf, 500);
+ BOOST_TEST(serialize(parse(
+ "[1,2,3]", &mr)) == "[1,2,3]");
+ }
+ #endif
+
+ // release()
+ {
+ unsigned char buf[10];
+ static_resource mr(
+ buf, sizeof(buf));
+ (void)mr.allocate(10,1);
+ BOOST_TEST_THROWS(
+ mr.allocate(10,1),
+ std::bad_alloc);
+ mr.release();
+ (void)mr.allocate(10,1);
+ }
+ }
+
+ void
+ run()
+ {
+ test();
+ }
+};
+
+TEST_SUITE(static_resource_test, "boost.json.static_resource");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/storage_ptr.cpp b/src/boost/libs/json/test/storage_ptr.cpp
new file mode 100644
index 000000000..3669c4096
--- /dev/null
+++ b/src/boost/libs/json/test/storage_ptr.cpp
@@ -0,0 +1,214 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/storage_ptr.hpp>
+
+#include <type_traits>
+
+#include "test.hpp"
+#include "test_suite.hpp"
+
+//----------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4702) // unreachable code
+#endif
+
+BOOST_JSON_NS_BEGIN
+
+BOOST_STATIC_ASSERT(
+ std::is_nothrow_move_constructible<storage_ptr>::value);
+
+class storage_ptr_test
+{
+public:
+ static value jv1;
+ static value jv2;
+
+ struct throwing
+ : memory_resource
+ {
+ throwing()
+ {
+ throw std::exception{};
+ }
+
+ void*
+ do_allocate(
+ std::size_t,
+ std::size_t) override
+ {
+ return nullptr;
+ }
+
+ void
+ do_deallocate(
+ void*,
+ std::size_t,
+ std::size_t) noexcept override
+ {
+ }
+
+ bool
+ do_is_equal(
+ memory_resource const& mr) const noexcept override
+ {
+ return this == &mr;
+ }
+ };
+
+ void
+ testMembers()
+ {
+ auto const dsp = storage_ptr{};
+ auto const usp =
+ make_shared_resource<unique_resource>();
+
+ // ~storage_ptr()
+ {
+ // implied
+ }
+
+ // storage_ptr()
+ {
+ storage_ptr sp;
+ BOOST_TEST(sp.get());
+ }
+
+ // storage_ptr(storage_ptr&&)
+ {
+ storage_ptr sp1 = dsp;
+ storage_ptr sp2(std::move(sp1));
+ BOOST_TEST(sp1.get());
+ BOOST_TEST(*sp2 == *dsp);
+ }
+
+ // storage_ptr(storage_ptr const&)
+ {
+ storage_ptr sp1 = dsp;
+ storage_ptr sp2(sp1);
+ BOOST_TEST(sp1 == sp2);
+ }
+
+ // operator=(storage_ptr&&)
+ {
+ storage_ptr sp1(dsp);
+ storage_ptr sp2(usp);
+ sp2 = std::move(sp1);
+ BOOST_TEST(*sp2 == *dsp);
+ }
+
+ // operator=(storage_ptr const&)
+ {
+ storage_ptr sp1(dsp);
+ storage_ptr sp2(usp);
+ sp2 = sp1;
+ BOOST_TEST(*sp1 == *sp2);
+ }
+
+ // get()
+ {
+ {
+ storage_ptr sp(dsp);
+ BOOST_TEST(sp.get() == dsp.get());
+ }
+ }
+
+ // operator->()
+ {
+ storage_ptr sp(dsp);
+ BOOST_TEST(sp.operator->() == dsp.get());
+ }
+
+ // operator*()
+ {
+ storage_ptr sp(dsp);
+ BOOST_TEST(&sp.operator*() == dsp.get());
+ }
+
+ // exception in make_storage
+ {
+ BOOST_TEST_THROWS(
+ make_shared_resource<throwing>(),
+ std::exception);
+ }
+ }
+
+ // https://github.com/boostorg/json/pull/182
+ void
+ testPull182()
+ {
+ struct other
+ {
+ virtual void f() {}
+ };
+
+ struct my_resource
+ : other
+ , memory_resource
+ {
+ void*
+ do_allocate(
+ std::size_t,
+ std::size_t) override
+ {
+ return nullptr;
+ }
+
+ void
+ do_deallocate(
+ void*,
+ std::size_t,
+ std::size_t) noexcept override
+ {
+ }
+
+ bool
+ do_is_equal(
+ memory_resource const&) const noexcept override
+ {
+ return true;
+ }
+ };
+
+ my_resource mr;
+ BOOST_TEST(storage_ptr(&mr).get() == &mr);
+ }
+
+ void
+ testInitOrder()
+ {
+ BOOST_ASSERT(jv1.storage() == jv2.storage());
+ BOOST_TEST(! jv1.storage().is_deallocate_trivial());
+ BOOST_TEST(! jv1.storage().is_shared());
+ }
+
+ void
+ run()
+ {
+ storage_ptr sp;
+
+ testMembers();
+ testPull182();
+ testInitOrder();
+ }
+};
+
+value storage_ptr_test::jv1 = {1, 2, 3};
+value storage_ptr_test::jv2 = {1, 2, 3};
+
+TEST_SUITE(storage_ptr_test, "boost.json.storage_ptr");
+
+BOOST_JSON_NS_END
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
diff --git a/src/boost/libs/json/test/stream_parser.cpp b/src/boost/libs/json/test/stream_parser.cpp
new file mode 100644
index 000000000..7c92960d9
--- /dev/null
+++ b/src/boost/libs/json/test/stream_parser.cpp
@@ -0,0 +1,1284 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/stream_parser.hpp>
+
+#include <boost/json/monotonic_resource.hpp>
+#include <boost/json/parse.hpp>
+#include <boost/json/serialize.hpp>
+
+#include <sstream>
+#include <iostream>
+
+#include "parse-vectors.hpp"
+#include "test.hpp"
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+BOOST_STATIC_ASSERT( std::is_nothrow_destructible<stream_parser>::value );
+
+class stream_parser_test
+{
+public:
+ ::test_suite::log_type log;
+
+ //------------------------------------------------------
+
+ void
+ testCtors()
+ {
+ // stream_parser(stream_parser const&)
+ BOOST_STATIC_ASSERT(
+ ! std::is_copy_constructible<stream_parser>::value);
+
+ // operator=(stream_parser const&)
+ BOOST_STATIC_ASSERT(
+ ! std::is_copy_assignable<stream_parser>::value);
+
+ // ~stream_parser()
+ {
+ {
+ stream_parser p;
+ }
+
+ {
+ stream_parser p;
+ p.reset(make_shared_resource<
+ monotonic_resource>());
+ }
+ }
+
+ // stream_parser(storage_ptr, parse_options, unsigned char*, size_t)
+ {
+ unsigned char buf[256];
+ stream_parser p(
+ storage_ptr(),
+ parse_options(),
+ &buf[0],
+ sizeof(buf));
+ }
+
+ // stream_parser()
+ {
+ stream_parser p;
+ }
+
+ // stream_parser(storage_ptr, parse_options)
+ {
+ stream_parser p(storage_ptr{}, parse_options());
+ }
+
+ // stream_parser(storage_ptr)
+ {
+ stream_parser p(storage_ptr{});
+ }
+
+ // stream_parser(storage_ptr, parse_options, unsigned char[])
+ {
+ unsigned char buf[256];
+ stream_parser p(
+ storage_ptr(),
+ parse_options(),
+ buf);
+ }
+
+ #if defined(__cpp_lib_byte)
+ // stream_parser(storage_ptr, parse_options, std::byte*, size_t)
+ {
+ std::byte buf[256];
+ stream_parser p(
+ storage_ptr(),
+ parse_options(),
+ &buf[0],
+ sizeof(buf));
+ }
+
+ // stream_parser(storage_ptr, parse_options, std::byte[])
+ {
+ std::byte buf[256];
+ stream_parser p(
+ storage_ptr(),
+ parse_options(),
+ buf);
+ }
+ #endif
+
+ // stream_parser(storage_ptr, parse_options, unsigned char[], size_t)
+ {
+ unsigned char buf[256];
+ stream_parser p(
+ storage_ptr(),
+ parse_options(),
+ buf,
+ sizeof(buf));
+ }
+
+ #if defined(__cpp_lib_byte)
+ // stream_parser(storage_ptr, parse_options, std::byte[], size_t)
+ {
+ std::byte buf[256];
+ stream_parser p(
+ storage_ptr(),
+ parse_options(),
+ buf,
+ sizeof(buf));
+ }
+ #endif
+ }
+
+ void
+ testMembers()
+ {
+ // write_some(char const*, size_t, error_code&)
+ // write_some(char const*, size_t, std::error_code&)
+ // write_some(string_view, error_code&)
+ // write_some(string_view, std::error_code&)
+ {
+ {
+ stream_parser p;
+ error_code ec;
+ BOOST_TEST(p.write_some(
+ "[]*", ec) == 2);
+ BOOST_TEST(! ec);
+ }
+ {
+ stream_parser p;
+ std::error_code ec;
+ BOOST_TEST(p.write_some(
+ "[]*", ec) == 2);
+ BOOST_TEST(! ec);
+ }
+ {
+ stream_parser p;
+ error_code ec;
+ BOOST_TEST(p.write_some(
+ "[*", ec) == 1);
+ BOOST_TEST(ec);
+ }
+ {
+ stream_parser p;
+ std::error_code ec;
+ BOOST_TEST(p.write_some(
+ "[*", ec) == 1);
+ BOOST_TEST(ec);
+ }
+ }
+
+ // write_some(char const*, size_t)
+ // write_some(string_view)
+ {
+ {
+ stream_parser p;
+ BOOST_TEST(
+ p.write_some("[]*") == 2);
+ }
+ {
+ stream_parser p;
+ BOOST_TEST_THROWS(
+ p.write_some("[*"),
+ system_error);
+ }
+ }
+
+ // write(char const*, size_t, error_code&)
+ // write(char const*, size_t, std::error_code&)
+ // write(string_view, error_code&)
+ // write(string_view, std::error_code&)
+ {
+ {
+ stream_parser p;
+ error_code ec;
+ BOOST_TEST(p.write(
+ "null", ec) == 4);
+ BOOST_TEST(! ec);
+ }
+ {
+ stream_parser p;
+ std::error_code ec;
+ BOOST_TEST(p.write(
+ "null", ec) == 4);
+ BOOST_TEST(! ec);
+ }
+ {
+ stream_parser p;
+ error_code ec;
+ p.write("[]*", ec),
+ BOOST_TEST(
+ ec == error::extra_data);
+ BOOST_TEST(ec.has_location());
+ }
+ {
+ stream_parser p;
+ std::error_code ec;
+ p.write("[]*", ec),
+ BOOST_TEST(ec == error::extra_data);
+ }
+ }
+
+ // write(char const*, size_t)
+ // write(string_view)
+ {
+ {
+ stream_parser p;
+ BOOST_TEST(p.write(
+ "null") == 4);
+ }
+ {
+ stream_parser p;
+ BOOST_TEST_THROWS(
+ p.write("[]*"),
+ system_error);
+ }
+ }
+
+ // finish()
+ // finish(error_code&)
+ // finish(std::error_code&)
+ {
+ {
+ stream_parser p;
+ p.write("1");
+ BOOST_TEST(! p.done());
+ p.finish();
+ BOOST_TEST(p.done());
+ }
+ {
+ stream_parser p;
+ BOOST_TEST(! p.done());
+ p.write("1.");
+ BOOST_TEST_THROWS(
+ p.finish(),
+ system_error);
+ }
+ {
+ stream_parser p;
+ p.write("[1,2");
+ error_code ec;
+ p.finish(ec);
+ BOOST_TEST(
+ ec == error::incomplete);
+ BOOST_TEST(ec.has_location());
+ }
+ {
+ stream_parser p;
+ p.write("[1,2");
+ error_code ec;
+ p.finish(ec);
+ BOOST_TEST_THROWS(
+ p.finish(),
+ system_error);
+ }
+ {
+ stream_parser p;
+ p.write("[1,2");
+ std::error_code ec;
+ p.finish(ec);
+ BOOST_TEST(ec == error::incomplete);
+ }
+ {
+ stream_parser p;
+ p.write("[1,2");
+ std::error_code ec;
+ p.finish(ec);
+ BOOST_TEST_THROWS(
+ p.finish(),
+ system_error);
+ }
+ }
+
+ // release()
+ {
+ {
+ stream_parser p;
+ BOOST_TEST(
+ p.write_some("[") == 1);
+ BOOST_TEST(! p.done());
+ BOOST_TEST_THROWS(
+ p.release(),
+ system_error);
+ }
+ {
+ stream_parser p;
+ BOOST_TEST(
+ p.write_some("[]*") == 2);
+ BOOST_TEST(p.done());
+ p.release();
+ }
+ {
+ stream_parser p;
+ p.write("[");
+ BOOST_TEST(! p.done());
+ BOOST_TEST_THROWS(
+ p.release(),
+ system_error);
+ }
+ {
+ stream_parser p;
+ error_code ec;
+ p.write("[]*", ec);
+ BOOST_TEST(
+ ec == error::extra_data);
+ BOOST_TEST(ec.has_location());
+ BOOST_TEST(! p.done());
+ BOOST_TEST_THROWS(
+ p.release(),
+ system_error);
+ }
+ }
+ }
+
+ //------------------------------------------------------
+
+ static
+ value
+ from_string_test(
+ string_view s,
+ storage_ptr sp = {},
+ const parse_options& po = parse_options())
+ {
+ stream_parser p(storage_ptr(), po);
+ error_code ec;
+ p.reset(std::move(sp));
+ p.write(s.data(), s.size(), ec);
+ if(BOOST_TEST(! ec))
+ p.finish(ec);
+ BOOST_TEST(! ec);
+ return p.release();
+ }
+
+ void
+ static
+ check_round_trip(value const& jv1,
+ const parse_options& po = parse_options())
+ {
+ auto const s2 =
+ //to_string_test(jv1); // use this if serializer is broken
+ serialize(jv1);
+ auto jv2 =
+ from_string_test(s2, {}, po);
+ BOOST_TEST(equal(jv1, jv2));
+ }
+
+ template<class F>
+ void
+ static
+ grind_one(
+ string_view s,
+ storage_ptr sp,
+ F const& f,
+ const parse_options& po = parse_options())
+ {
+ auto const jv =
+ from_string_test(s, sp, po);
+ f(jv, po);
+ }
+
+ static
+ void
+ grind_one(string_view s)
+ {
+ auto const jv =
+ from_string_test(s);
+ check_round_trip(jv);
+ }
+
+ template<class F>
+ static
+ void
+ grind(string_view s, F const& f,
+ const parse_options& po = parse_options())
+ {
+ try
+ {
+ grind_one(s, {}, f, po);
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ grind_one(s, sp, f, po);
+ });
+
+ if(s.size() > 1)
+ {
+ // Destroy the stream_parser at every
+ // split point to check leaks.
+ for(std::size_t i = 1;
+ i < s.size(); ++i)
+ {
+ fail_resource mr;
+ mr.fail_max = 0;
+ stream_parser p(storage_ptr(), po);
+ error_code ec;
+ p.reset(&mr);
+ p.write(s.data(), i, ec);
+ if(BOOST_TEST(! ec))
+ p.write(
+ s.data() + i,
+ s.size() - i, ec);
+ if(BOOST_TEST(! ec))
+ p.finish(ec);
+ if(BOOST_TEST(! ec))
+ f(p.release(), po);
+ }
+ }
+ }
+ catch(std::exception const&)
+ {
+ BOOST_TEST_FAIL();
+ }
+ }
+
+ static
+ void
+ grind(string_view s,
+ const parse_options& po = parse_options())
+ {
+ grind(s,
+ [](value const& jv, const parse_options& po)
+ {
+ check_round_trip(jv, po);
+ }, po);
+ }
+
+ static
+ void
+ grind_int64(string_view s, int64_t v)
+ {
+ grind(s,
+ [v](value const& jv, const parse_options&)
+ {
+ if(! BOOST_TEST(jv.is_int64()))
+ return;
+ BOOST_TEST(jv.get_int64() == v);
+ });
+ }
+
+ static
+ void
+ grind_uint64(string_view s, uint64_t v)
+ {
+ grind(s,
+ [v](value const& jv, const parse_options&)
+ {
+ if(! BOOST_TEST(jv.is_uint64()))
+ return;
+ BOOST_TEST(jv.get_uint64() == v);
+ });
+ }
+
+ static
+ void
+ grind_double(string_view s, double v)
+ {
+ grind(s,
+ [v](value const& jv, const parse_options&)
+ {
+ if(! BOOST_TEST(jv.is_double()))
+ return;
+ BOOST_TEST(jv.get_double() == v);
+ });
+ }
+
+ //------------------------------------------------------
+
+ void
+ testNull()
+ {
+ grind("null");
+ grind(" null");
+ grind(" null");
+ grind("null\n");
+ grind("null\n\n");
+ grind("\r null\t ");
+ }
+
+ void
+ testBool()
+ {
+ grind("true");
+ grind(" true");
+ grind(" true");
+ grind("true\n");
+ grind("true\n\n");
+ grind("\r true\t ");
+
+ grind("false");
+ grind(" false");
+ grind(" false");
+ grind("false\n");
+ grind("false\n\n");
+ grind("\r false\t ");
+ }
+
+ //------------------------------------------------------
+
+ void
+ testString()
+ {
+ grind("\"\"");
+ grind("\"x\"");
+ grind(" \"x\"");
+ grind(" \"x\"");
+ grind("\"x\"\n");
+ grind("\"x\"\n\n");
+ grind("\r \"x\"\t ");
+
+ grind("\"abcdefghij\"");
+ grind("\""
+ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
+ "\"");
+ grind("\""
+ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
+ "\"");
+
+ // escapes
+ grind("\"\\\"\"");
+ grind("\"\\\\\"");
+ grind("\"\\/\"");
+ grind("\"\\b\"");
+ grind("\"\\f\"");
+ grind("\"\\n\"");
+ grind("\"\\r\"");
+ grind("\"\\t\"");
+
+ // unicode
+ grind("\"\\u0000\"");
+ grind("\"\\ud7fF\"");
+ grind("\"\\ue000\"");
+ grind("\"\\ufFfF\"");
+ grind("\"\\ud800\\udc00\"");
+ grind("\"\\udbff\\udffF\"");
+
+ // big string
+ {
+ std::string const big(4000, '*');
+ {
+ std::string js;
+ js = "\"" + big + "\"";
+ auto const N = js.size() / 2;
+ error_code ec;
+ stream_parser p;
+ p.write(js.data(), N, ec);
+ if(BOOST_TEST(! ec))
+ {
+ p.write(js.data() + N,
+ js.size() - N, ec);
+ if(BOOST_TEST(! ec))
+ p.finish(ec);
+ if(BOOST_TEST(! ec))
+ check_round_trip(
+ p.release());
+ }
+ }
+ }
+ }
+
+ //------------------------------------------------------
+
+ struct f_boost
+ {
+ static
+ string_view
+ name() noexcept
+ {
+ return "boost";
+ }
+
+ double
+ operator()(string_view s) const
+ {
+ BOOST_TEST_CHECKPOINT();
+ error_code ec;
+ stream_parser p;
+ p.write(s.data(), s.size(), ec);
+ if(BOOST_TEST(! ec))
+ p.finish(ec);
+ if(! BOOST_TEST(! ec))
+ return 0;
+ auto const jv = p.release();
+ double const d = jv.as_double();
+ grind_double(s, d);
+ return d;
+ }
+ };
+
+ bool
+ within_1ulp(double x, double y)
+ {
+ std::uint64_t bx, by;
+ std::memcpy(&bx, &x, sizeof(x));
+ std::memcpy(&by, &y, sizeof(y));
+
+ auto diff = bx - by;
+ switch (diff)
+ {
+ case 0:
+ case 1:
+ case 0xffffffffffffffff:
+ return true;
+ default:
+ break;
+ }
+ return false;
+ }
+
+ // Verify that f converts to the
+ // same double produced by `strtod`.
+ // Requires `s` is not represented by an integral type.
+ template<class F>
+ void
+ fc(std::string const& s, F const& f)
+ {
+ char* str_end;
+ double const need =
+ std::strtod(s.c_str(), &str_end);
+ // BOOST_TEST(str_end == &s.back() + 1);
+ double const got = f(s);
+ auto same = got == need;
+ auto close = same ?
+ true : within_1ulp(got, need);
+
+ if( !BOOST_TEST(close) )
+ {
+ std::cerr << "Failure on '" << s << "': " << got << " != " << need << "\n";
+ }
+ }
+
+ void
+ fc(std::string const& s)
+ {
+ fc(s, f_boost{});
+ fc(s + std::string( 64, ' ' ), f_boost{});
+ }
+
+ void
+ testNumber()
+ {
+ grind("0");
+ grind(" 0");
+ grind(" 0");
+ grind("0\n");
+ grind("0\n\n");
+ grind("\r 0\t ");
+
+ grind_int64( "-9223372036854775808", INT64_MIN);
+ grind_int64( "-9223372036854775807", -9223372036854775807);
+ grind_int64( "-999999999999999999", -999999999999999999);
+ grind_int64( "-99999999999999999", -99999999999999999);
+ grind_int64( "-9999999999999999", -9999999999999999);
+ grind_int64( "-999999999999999", -999999999999999);
+ grind_int64( "-99999999999999", -99999999999999);
+ grind_int64( "-9999999999999", -9999999999999);
+ grind_int64( "-999999999999", -999999999999);
+ grind_int64( "-99999999999", -99999999999);
+ grind_int64( "-9999999999", -9999999999);
+ grind_int64( "-999999999", -999999999);
+ grind_int64( "-99999999", -99999999);
+ grind_int64( "-9999999", -9999999);
+ grind_int64( "-999999", -999999);
+ grind_int64( "-99999", -99999);
+ grind_int64( "-9999", -9999);
+ grind_int64( "-999", -999);
+ grind_int64( "-99", -99);
+ grind_int64( "-9", -9);
+ grind_int64( "-0", 0);
+ grind_int64( "0", 0);
+ grind_int64( "1", 1);
+ grind_int64( "9", 9);
+ grind_int64( "99", 99);
+ grind_int64( "999", 999);
+ grind_int64( "9999", 9999);
+ grind_int64( "99999", 99999);
+ grind_int64( "999999", 999999);
+ grind_int64( "9999999", 9999999);
+ grind_int64( "99999999", 99999999);
+ grind_int64( "999999999", 999999999);
+ grind_int64( "9999999999", 9999999999);
+ grind_int64( "99999999999", 99999999999);
+ grind_int64( "999999999999", 999999999999);
+ grind_int64( "9999999999999", 9999999999999);
+ grind_int64( "99999999999999", 99999999999999);
+ grind_int64( "999999999999999", 999999999999999);
+ grind_int64( "9999999999999999", 9999999999999999);
+ grind_int64( "99999999999999999", 99999999999999999);
+ grind_int64( "999999999999999999", 999999999999999999);
+ grind_int64( "9223372036854775807", INT64_MAX);
+
+ grind_uint64( "9223372036854775808", 9223372036854775808ULL);
+ grind_uint64( "9999999999999999999", 9999999999999999999ULL);
+ grind_uint64( "18446744073709551615", UINT64_MAX);
+
+ grind_double("-1.010", -1.01);
+ grind_double("-0.010", -0.01);
+ grind_double("-0.0", -0.0);
+ grind_double("-0e0", -0.0);
+ grind_double( "18446744073709551616", 1.8446744073709552e+19);
+ grind_double("-18446744073709551616", -1.8446744073709552e+19);
+ grind_double( "18446744073709551616.0", 1.8446744073709552e+19);
+ grind_double( "18446744073709551616.00009", 1.8446744073709552e+19);
+ grind_double( "1844674407370955161600000", 1.8446744073709552e+24);
+ grind_double("-1844674407370955161600000", -1.8446744073709552e+24);
+ grind_double( "1844674407370955161600000.0", 1.8446744073709552e+24);
+ grind_double( "1844674407370955161600000.00009", 1.8446744073709552e+24);
+
+ grind_double( "1.0", 1.0);
+ grind_double( "1.1", 1.1);
+ grind_double( "1.11", 1.11);
+ grind_double( "1.11111", 1.11111);
+ grind_double( "11.1111", 11.1111);
+ grind_double( "111.111", 111.111);
+
+ fc("-999999999999999999999");
+ fc("-100000000000000000009");
+ fc("-10000000000000000000");
+ fc("-9223372036854775809");
+
+ fc("18446744073709551616");
+ fc("99999999999999999999");
+ fc("999999999999999999999");
+ fc("1000000000000000000000");
+ fc("9999999999999999999999");
+ fc("99999999999999999999999");
+
+ fc("-0.9999999999999999999999");
+ fc("-0.9999999999999999");
+ fc("-0.9007199254740991");
+ fc("-0.999999999999999");
+ fc("-0.99999999999999");
+ fc("-0.9999999999999");
+ fc("-0.999999999999");
+ fc("-0.99999999999");
+ fc("-0.9999999999");
+ fc("-0.999999999");
+ fc("-0.99999999");
+ fc("-0.9999999");
+ fc("-0.999999");
+ fc("-0.99999");
+ fc("-0.9999");
+ fc("-0.8125");
+ fc("-0.999");
+ fc("-0.99");
+ fc("-1.0");
+ fc("-0.9");
+ fc("-0.0");
+ fc("0.0");
+ fc("0.9");
+ fc("0.99");
+ fc("0.999");
+ fc("0.8125");
+ fc("0.9999");
+ fc("0.99999");
+ fc("0.999999");
+ fc("0.9999999");
+ fc("0.99999999");
+ fc("0.999999999");
+ fc("0.9999999999");
+ fc("0.99999999999");
+ fc("0.999999999999");
+ fc("0.9999999999999");
+ fc("0.99999999999999");
+ fc("0.999999999999999");
+ fc("0.9007199254740991");
+ fc("0.9999999999999999");
+ fc("0.9999999999999999999999");
+ fc("0.999999999999999999999999999");
+
+ fc("-1e308");
+ fc("-1e-308");
+ fc("-9999e300");
+ fc("-999e100");
+ fc("-99e10");
+ fc("-9e1");
+ fc("9e1");
+ fc("99e10");
+ fc("999e100");
+ fc("9999e300");
+ fc("999999999999999999.0");
+ fc("999999999999999999999.0");
+ fc("999999999999999999999e5");
+ fc("999999999999999999999.0e5");
+
+ fc("0.00000000000000001");
+
+ fc("-1e-1");
+ fc("-1e0");
+ fc("-1e1");
+ fc("0e0");
+ fc("1e0");
+ fc("1e10");
+
+ fc("0."
+ "00000000000000000000000000000000000000000000000000" // 50 zeroes
+ "1e50");
+ fc("-0."
+ "00000000000000000000000000000000000000000000000000" // 50 zeroes
+ "1e50");
+
+ fc("0."
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000" // 500 zeroes
+ "1e600");
+ fc("-0."
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000" // 500 zeroes
+ "1e600");
+
+ fc("0e"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000" // 500 zeroes
+ );
+ }
+
+ //------------------------------------------------------
+
+ void
+ testArray()
+ {
+ grind("[]");
+ grind(" []");
+ grind("[] ");
+ grind(" [] ");
+ grind(" [ ] ");
+ grind("[1]");
+ grind("[ 1]");
+ grind("[1 ]");
+ grind("[ 1 ]");
+ grind("[1,2]");
+ grind("[ 1,2]");
+ grind("[1 ,2]");
+ grind("[1, 2]");
+ grind("[1,2 ]");
+ grind("[ 1 ,2]");
+ grind("[1 , 2]");
+ grind("[1, 2 ]");
+
+ grind("[[]]");
+ grind("[[],[]]");
+ grind("[[],[],[]]");
+ grind("[[[]],[[],[]],[[],[],[]]]");
+ grind("[{},[],\"x\",1,-1,1.0,true,null]");
+
+ // depth
+ {
+ error_code ec;
+ parse_options opt;
+ opt.max_depth = 0;
+ stream_parser p(storage_ptr(), opt);
+ p.write("[]", 2, ec);
+ BOOST_TEST(
+ ec == error::too_deep);
+ BOOST_TEST(ec.has_location());
+ }
+ }
+
+ //------------------------------------------------------
+
+ void
+ testObject()
+ {
+ grind("{}");
+ grind(" {}");
+ grind("{} ");
+ grind(" {} ");
+ grind(" { } ");
+ grind("{\"1\":1}");
+ grind("{ \"1\":1}");
+ grind("{\"1\" :1}");
+ grind("{\"1\": 1}");
+ grind("{\"1\":1 }");
+ grind("{ \"1\" :1 }");
+ grind("{\"1\" : 1 }");
+ grind("{\"1\":1,\"2\":2}");
+ grind("{\"1\":1, \"2\":2}");
+ grind("{\"1\":1, \"2\" : 2 }");
+
+ grind("{\"\":[]}");
+ grind("{\"1\":[],\"2\":[]}");
+
+ grind(
+ "{\"1\":{\"2\":{}},\"3\":{\"4\":{},\"5\":{}},"
+ "\"6\":{\"7\":{},\"8\":{},\"9\":{}}}");
+
+ grind(
+ "{\"1\":{},\"2\":[],\"3\":\"x\",\"4\":1,"
+ "\"5\":-1,\"6\":1.0,\"7\":false,\"8\":null}");
+
+ // big keys
+ {
+ std::string const big(4000, '*');
+ {
+ std::string js;
+ js = "{\"" + big + "\":null}";
+ grind(js);
+ }
+
+ {
+ std::string js;
+ js = "{\"x\":\"" + big + "\"}";
+ grind(js);
+ }
+
+ {
+ std::string js;
+ js = "{\"" + big + "\":\"" + big + "\"}";
+ grind(js);
+ }
+ }
+
+ // depth
+ {
+ error_code ec;
+ parse_options opt;
+ opt.max_depth = 0;
+ stream_parser p(storage_ptr(), opt);
+ p.write("{}", 2, ec);
+ BOOST_TEST(
+ ec == error::too_deep);
+ BOOST_TEST(ec.has_location());
+ }
+ }
+
+ //------------------------------------------------------
+
+ void
+ testFreeFunctions()
+ {
+ string_view const js =
+ "{\"1\":{},\"2\":[],\"3\":\"x\",\"4\":1,"
+ "\"5\":-1,\"6\":1.0,\"7\":false,\"8\":null}";
+
+ // parse(string_view, error_code)
+ {
+ {
+ error_code ec;
+ auto jv = parse(js, ec);
+ BOOST_TEST(! ec);
+ check_round_trip(jv);
+ }
+ {
+ error_code ec;
+ auto jv = parse("xxx", ec);
+ BOOST_TEST(ec);
+ BOOST_TEST(ec.has_location());
+ BOOST_TEST(jv.is_null());
+ }
+ }
+
+ // parse(string_view, storage_ptr, error_code)
+ {
+ {
+ error_code ec;
+ monotonic_resource mr;
+ auto jv = parse(js, ec, &mr);
+ BOOST_TEST(! ec);
+ //check_round_trip(jv);
+ }
+
+ {
+ error_code ec;
+ monotonic_resource mr;
+ auto jv = parse("xxx", ec, &mr);
+ BOOST_TEST(ec);
+ BOOST_TEST(ec.has_location());
+ BOOST_TEST(jv.is_null());
+ }
+ }
+
+ // parse(string_view)
+ {
+ {
+ check_round_trip(
+ parse(js));
+ }
+
+ {
+ value jv;
+ BOOST_TEST_THROWS(
+ jv = parse("{,"),
+ system_error);
+ }
+ }
+
+ // parse(string_view, storage_ptr)
+ {
+ {
+ monotonic_resource mr;
+ check_round_trip(parse(js, &mr));
+ }
+
+ {
+ monotonic_resource mr;
+ value jv;
+ BOOST_TEST_THROWS(
+ jv = parse("xxx", &mr),
+ system_error);
+ }
+ }
+ }
+
+ void
+ testSampleJson()
+ {
+ string_view in =
+R"xx({
+ "glossary": {
+ "title": "example glossary",
+ "GlossDiv": {
+ "title": "S",
+ "GlossList": {
+ "GlossEntry": {
+ "ID": "SGML",
+ "SortAs": "SGML",
+ "GlossTerm": "Standard Generalized Markup Language",
+ "Acronym": "SGML",
+ "Abbrev": "ISO 8879:1986",
+ "GlossDef": {
+ "para": "A meta-markup language, used to create markup languages such as DocBook.",
+ "GlossSeeAlso": ["GML", "XML"]
+ },
+ "GlossSee": "markup"
+ }
+ }
+ }
+ }
+})xx";
+ string_view out =
+ "{\"glossary\":{\"title\":\"example glossary\",\"GlossDiv\":"
+ "{\"title\":\"S\",\"GlossList\":{\"GlossEntry\":{\"ID\":\"SGML\","
+ "\"SortAs\":\"SGML\",\"GlossTerm\":\"Standard Generalized Markup "
+ "Language\",\"Acronym\":\"SGML\",\"Abbrev\":\"ISO 8879:1986\","
+ "\"GlossDef\":{\"para\":\"A meta-markup language, used to create "
+ "markup languages such as DocBook.\",\"GlossSeeAlso\":[\"GML\",\"XML\"]},"
+ "\"GlossSee\":\"markup\"}}}}}";
+ storage_ptr sp =
+ make_shared_resource<monotonic_resource>();
+ stream_parser p(sp);
+ error_code ec;
+ p.write(in.data(), in.size(), ec);
+ if(BOOST_TEST(! ec))
+ p.finish(ec);
+ if(BOOST_TEST(! ec))
+ BOOST_TEST(serialize(p.release()) == out);
+ }
+
+ void
+ testTrailingCommas()
+ {
+ parse_options enabled;
+ enabled.allow_trailing_commas = true;
+
+ grind("[1,]", enabled);
+ grind("[1, 2,]", enabled);
+ grind("{\"a\": 1,}", enabled);
+ grind("{\"a\": 1, \"b\": 2,}", enabled);
+ }
+
+ void
+ testComments()
+ {
+ parse_options enabled;
+ enabled.allow_comments = true;
+
+ grind("[/* c */1]", enabled);
+ grind("[1/* c */]", enabled);
+ grind("[1] /* c */", enabled);
+ grind("/* c */ [1]", enabled);
+ grind("[1/* c */, 2]", enabled);
+ grind("[1, /* c */ 2]", enabled);
+
+ grind("// c++ \n[1]", enabled);
+ grind("[1] // c++ \n", enabled);
+ grind("[1] // c++", enabled);
+ grind("[// c++ \n1]", enabled);
+ grind("[1// c++ \n]", enabled);
+ grind("[1// c++ \n, 2]", enabled);
+ grind("[1, // c++ \n 2]", enabled);
+
+ grind("{/* c */\"a\":1}", enabled);
+ grind("{\"a\":1/* c */}", enabled);
+ grind("{\"a\":1} /* c */", enabled);
+ grind("/* c */ {\"a\":1}", enabled);
+ grind("{\"a\":1/* c */, \"b\":1}", enabled);
+ grind("{\"a\":1, /* c */ \"b\":1}", enabled);
+ grind("{\"a\"/* c */:1}", enabled);
+ grind("{\"a\":/* c */1}", enabled);
+
+ grind("// c++ \n{\"a\":1}", enabled);
+ grind("{\"a\":1} // c++ \n", enabled);
+ grind("{\"a\":1} // c++", enabled);
+ grind("{// c++ \n\"a\":1}", enabled);
+ grind("{\"a\":1// c++ \n}", enabled);
+ grind("{\"a\":1// c++ \n, \"b\":2}", enabled);
+ grind("{\"a\":1, // c++ \n \"b\":2}", enabled);
+ grind("{\"a\"// c++ \n:1}", enabled);
+ grind("{\"a\":// c++ \n1}", enabled);
+ }
+
+ void
+ testUnicodeStrings()
+ {
+ // Embedded NULL correctly converted
+ {
+ auto expected = string_view("Hello\x00World", 11);
+ {
+ auto s = string_view(R"json("Hello\u0000World")json");
+ grind(s);
+ BOOST_TEST(json::parse(s).as_string() == expected);
+ }
+ {
+ auto s = string_view(R"json(["Hello\u0000World"])json");
+ grind(s);
+ BOOST_TEST(json::parse(s).as_array().at(0).as_string() == expected);
+ }
+ }
+
+ // surrogate pairs correctly converted to UTF-8
+ {
+ auto expected = string_view("\xF0\x9D\x84\x9E", 4);
+ {
+ auto s = string_view(R"json("\uD834\uDD1E")json");
+ grind(s);
+ BOOST_TEST(json::parse(s).as_string() == expected);
+ }
+ {
+ auto s = string_view(R"json(["\uD834\uDD1E"])json");
+ grind(s);
+ BOOST_TEST(json::parse(s).as_array().at(0).as_string() == expected);
+ }
+ }
+ }
+
+ void
+ testDupeKeys()
+ {
+ {
+ value jv = parse(R"({"a":1,"b":2,"a":3})");
+ object& jo = jv.as_object();
+ BOOST_TEST(jo.size() == 2);
+ BOOST_TEST(jo.at("a").as_int64() == 3);
+ BOOST_TEST(jo.at("b").as_int64() == 2);
+ }
+ {
+ value jv = parse(R"({"a":1,"a":3,"b":2})");
+ object& jo = jv.as_object();
+ BOOST_TEST(jo.size() == 2);
+ BOOST_TEST(jo.at("a").as_int64() == 3);
+ BOOST_TEST(jo.at("b").as_int64() == 2);
+ }
+ {
+ value jv = parse(R"({"a":1,"a":3,"b":2,"a":4})");
+ object& jo = jv.as_object();
+ BOOST_TEST(jo.size() == 2);
+ BOOST_TEST(jo.at("a").as_int64() == 4);
+ BOOST_TEST(jo.at("b").as_int64() == 2);
+ }
+ {
+ value jv = parse(R"({"a":1,"a":3,"b":2,"a":4,"b":5})");
+ object& jo = jv.as_object();
+ BOOST_TEST(jo.size() == 2);
+ BOOST_TEST(jo.at("a").as_int64() == 4);
+ BOOST_TEST(jo.at("b").as_int64() == 5);
+ }
+ }
+
+ //------------------------------------------------------
+
+ // https://github.com/boostorg/json/issues/15
+ void
+ testIssue15()
+ {
+ BOOST_TEST(
+ json::parse("{\"port\": 12345}")
+ .as_object()
+ .at("port")
+ .as_int64() == 12345);
+ }
+
+ // https://github.com/boostorg/json/issues/45
+ void
+ testIssue45()
+ {
+ struct T
+ {
+ value jv;
+
+ T(value jv_)
+ : jv(jv_)
+ {
+ }
+ };
+
+ auto const jv = parse("[]");
+ auto const t = T{jv};
+ BOOST_TEST(serialize(t.jv) == "[]");
+ }
+
+ //------------------------------------------------------
+
+ void
+ run()
+ {
+ testCtors();
+ testMembers();
+
+ testNull();
+ testBool();
+ testString();
+ testNumber();
+ testArray();
+ testObject();
+
+ testFreeFunctions();
+ testSampleJson();
+ testUnicodeStrings();
+ testTrailingCommas();
+ testComments();
+ testDupeKeys();
+ testIssue15();
+ testIssue45();
+ }
+};
+
+TEST_SUITE(stream_parser_test, "boost.json.stream_parser");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/string.cpp b/src/boost/libs/json/test/string.cpp
new file mode 100644
index 000000000..390d67038
--- /dev/null
+++ b/src/boost/libs/json/test/string.cpp
@@ -0,0 +1,2814 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/string.hpp>
+
+#include <boost/json/monotonic_resource.hpp>
+#include <boost/json/parse.hpp>
+
+#include <numeric>
+#include <sstream>
+#include <string>
+#include <stdint.h>
+#include <unordered_set>
+
+#include "test.hpp"
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+BOOST_STATIC_ASSERT( std::is_nothrow_destructible<string>::value );
+BOOST_STATIC_ASSERT( std::is_nothrow_move_constructible<string>::value );
+
+class string_test
+{
+public:
+
+#if BOOST_JSON_ARCH == 64
+# define INIT1 { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n' }
+# define INIT2 { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O' }
+#elif BOOST_JSON_ARCH == 32
+# define INIT1 { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }
+# define INIT2 { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K' }
+#else
+# error Unknown architecture
+#endif
+
+ struct test_vectors
+ {
+ // fit in sbo
+ string_view v1; // "abc...
+
+ // dynamic alloc
+ string_view v2; // "ABC...
+
+ std::string const s1;
+ std::string const s2;
+
+ test_vectors()
+ : s1([&]
+ {
+ std::string s;
+ s.resize(string{}.capacity());
+ std::iota(s.begin(), s.end(), 'a');
+ return s;
+ }())
+ , s2([&]
+ {
+ std::string s;
+ s.resize(string{}.capacity() + 1);
+ std::iota(s.begin(), s.end(), 'A');
+ return s;
+ }())
+ {
+ v1 = s1;
+ v2 = s2;
+
+ BOOST_TEST(std::string(INIT1) == s1);
+ BOOST_TEST(std::string(INIT2) == s2);
+ }
+ };
+
+ static
+ string_view
+ last_of(
+ string_view s,
+ std::size_t n)
+ {
+ return s.substr(s.size() - n);
+ }
+
+ void
+ testConstruction()
+ {
+ test_vectors const t;
+
+ // string()
+ {
+ string s;
+ }
+
+ // string(storage_ptr)
+ {
+ auto const sp =
+ make_shared_resource<unique_resource>();
+ string s(sp);
+ BOOST_TEST(s.empty());
+ BOOST_TEST(*s.storage() == *sp.get());
+ }
+
+ // string(size_type, char, storage_ptr)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ BOOST_TEST(s == std::string(t.v1.size(), '*'));
+ });
+
+ {
+ string s(t.v2.size(), '*');
+ BOOST_TEST(s == std::string(t.v2.size(), '*'));
+ }
+ }
+
+ // string(char const*, storage_ptr)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.s1.c_str(), sp);
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.s2.c_str(), sp);
+ BOOST_TEST(s == t.v2);
+ });
+
+ {
+ string s(t.s1.c_str());
+ BOOST_TEST(s == t.v1);
+ }
+
+ {
+ string s(t.s2.c_str());
+ BOOST_TEST(s == t.v2);
+ }
+ }
+
+ // string(char const*, size_type, storage_ptr)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.s1.c_str(), 3, sp);
+ BOOST_TEST(s == "abc");
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.s2.c_str(), 3, sp);
+ BOOST_TEST(s == "ABC");
+ });
+
+ {
+ string s(t.s1.c_str(), 3);
+ BOOST_TEST(s == "abc");
+ }
+
+ {
+ string s(t.s2.c_str(), 3);
+ BOOST_TEST(s == "ABC");
+ }
+ }
+
+ // string(InputIt, InputIt, storage_ptr)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.begin(), t.v1.end(), sp);
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.begin(), t.v2.end(), sp);
+ BOOST_TEST(s == t.v2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(
+ make_input_iterator(t.v1.begin()),
+ make_input_iterator(t.v1.end()), sp);
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(
+ make_input_iterator(t.v2.begin()),
+ make_input_iterator(t.v2.end()), sp);
+ BOOST_TEST(s == t.v2);
+ });
+
+ {
+ string s(t.v1.begin(), t.v1.end());
+ BOOST_TEST(s == t.v1);
+ }
+
+ {
+ string s(t.v2.begin(), t.v2.end());
+ BOOST_TEST(s == t.v2);
+ }
+
+ {
+ string s(
+ make_input_iterator(t.v1.begin()),
+ make_input_iterator(t.v1.end()));
+ BOOST_TEST(s == t.v1);
+ }
+
+ {
+ string s(
+ make_input_iterator(t.v2.begin()),
+ make_input_iterator(t.v2.end()));
+ BOOST_TEST(s == t.v2);
+ }
+ }
+
+ // string(string)
+ {
+ {
+ string const s0(t.v1);
+ string s(s0);
+ BOOST_TEST(s == t.v1);
+ }
+
+ {
+ string const s0(t.v2);
+ string s(s0);
+ BOOST_TEST(s == t.v2);
+ }
+ }
+
+ // string(string, storage_ptr)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string const s0(t.v1);
+ string s(s0, sp);
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string const s0(t.v2);
+ string s(s0, sp);
+ BOOST_TEST(s == t.v2);
+ });
+ }
+
+ // string(pilfered<string>)
+ {
+ {
+ string s1(t.v1);
+ string s2(pilfer(s1));
+ BOOST_TEST(s2 == t.v1);
+ BOOST_TEST(s1.empty());
+ BOOST_TEST(
+ s1.storage() == storage_ptr());
+ }
+
+ {
+ string s1(t.v2);
+ string s2(pilfer(s1));
+ BOOST_TEST(s2 == t.v2);
+ BOOST_TEST(s1.empty());
+ BOOST_TEST(
+ s1.storage() == storage_ptr());
+ }
+
+ // ensure pilfered-from objects
+ // are trivially destructible
+ {
+ string s1(make_shared_resource<
+ monotonic_resource>());
+ string s2(pilfer(s1));
+ BOOST_TEST(s1.storage().get() ==
+ storage_ptr().get());
+ }
+ }
+
+ // string(string&&)
+ {
+ {
+ string s1(t.v1);
+ string s2(std::move(s1));
+ BOOST_TEST(s2 == t.v1);
+ BOOST_TEST(s1.empty());
+ BOOST_TEST(
+ *s1.storage() ==
+ *s2.storage());
+ }
+
+ {
+ string s1(t.v2);
+ string s2(std::move(s1));
+ BOOST_TEST(s2 == t.v2);
+ BOOST_TEST(s1.empty());
+ BOOST_TEST(
+ *s1.storage() ==
+ *s2.storage());
+ }
+ }
+
+ // string(string&&, storage_ptr)
+ {
+ // same storage
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s1(t.v1, sp);
+ string s2(std::move(s1), sp);
+ BOOST_TEST(s2 == t.v1);
+ BOOST_TEST(s1.empty());
+ BOOST_TEST(
+ *s1.storage() ==
+ *s2.storage());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s1(t.v2, sp);
+ string s2(std::move(s1));
+ BOOST_TEST(s2 == t.v2);
+ BOOST_TEST(s1.empty());
+ BOOST_TEST(
+ *s1.storage() ==
+ *s2.storage());
+ });
+
+ // different storage
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s1(t.v1);
+ string s2(std::move(s1), sp);
+ BOOST_TEST(s2 == t.v1);
+ BOOST_TEST(s1 == t.v1);
+ BOOST_TEST(
+ *s1.storage() !=
+ *s2.storage());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s1(t.v2);
+ string s2(std::move(s1), sp);
+ BOOST_TEST(s2 == t.v2);
+ BOOST_TEST(s1 == t.v2);
+ BOOST_TEST(
+ *s1.storage() !=
+ *s2.storage());
+ });
+ }
+
+ // string(string_view, storage_ptr)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ BOOST_TEST(s == t.v2);
+ });
+
+ {
+ string s(t.v1);
+ BOOST_TEST(s == t.v1);
+ }
+
+ {
+ string s(t.v2);
+ BOOST_TEST(s == t.v2);
+ }
+ }
+ }
+
+ void
+ testAssignment()
+ {
+ test_vectors const t;
+
+ // operator=(string)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v1.size(), '*');
+ string s(c, sp);
+ string const s2(t.v1);
+ s = s2;
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v2.size(), '*');
+ string s(c, sp);
+ string const s2(t.v1);
+ s = s2;
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v1.size(), '*');
+ string s(c, sp);
+ string const s2(t.v2);
+ s = s2;
+ BOOST_TEST(s == t.v2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v2.size(), '*');
+ string s(c, sp);
+ string const s2(t.v2);
+ s = s2;
+ BOOST_TEST(s == t.v2);
+ });
+ }
+
+ // operator=(string&&)
+ {
+ // same storage
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v1.size(), '*');
+ string s(c, sp);
+ string s2(t.v1, sp);
+ s = std::move(s2);
+ BOOST_TEST(s == t.v1);
+ BOOST_TEST(s2.empty());
+ BOOST_TEST(
+ *s.storage() ==
+ *s2.storage());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v2.size(), '*');
+ string s(c, sp);
+ string s2(t.v1, sp);
+ s = std::move(s2);
+ BOOST_TEST(s == t.v1);
+ BOOST_TEST(s2.empty());
+ BOOST_TEST(
+ *s.storage() ==
+ *s2.storage());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v1.size(), '*');
+ string s(c, sp);
+ string s2(t.v2, sp);
+ s = std::move(s2);
+ BOOST_TEST(s == t.v2);
+ BOOST_TEST(s2.empty());
+ BOOST_TEST(
+ *s.storage() ==
+ *s2.storage());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v2.size(), '*');
+ string s(c, sp);
+ string s2(t.v2, sp);
+ s = std::move(s2);
+ BOOST_TEST(s == t.v2);
+ BOOST_TEST(s2.empty());
+ BOOST_TEST(
+ *s.storage() ==
+ *s2.storage());
+ });
+
+ // different storage
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v1.size(), '*');
+ string s(c, sp);
+ string s2(t.v1);
+ s = std::move(s2);
+ BOOST_TEST(s == t.v1);
+ BOOST_TEST(s2 == t.v1);
+ BOOST_TEST(
+ *s.storage() !=
+ *s2.storage());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v2.size(), '*');
+ string s(c, sp);
+ string s2(t.v1);
+ s = std::move(s2);
+ BOOST_TEST(s == t.v1);
+ BOOST_TEST(s2 == t.v1);
+ BOOST_TEST(
+ *s.storage() !=
+ *s2.storage());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v1.size(), '*');
+ string s(c, sp);
+ string s2(t.v2);
+ s = std::move(s2);
+ BOOST_TEST(s == t.v2);
+ BOOST_TEST(s2 == t.v2);
+ BOOST_TEST(
+ *s.storage() !=
+ *s2.storage());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v2.size(), '*');
+ string s(c, sp);
+ string s2(t.v2);
+ s = std::move(s2);
+ BOOST_TEST(s == t.v2);
+ BOOST_TEST(s2 == t.v2);
+ BOOST_TEST(
+ *s.storage() !=
+ *s2.storage());
+ });
+ }
+
+ // operator=(char const*)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ s = t.s1.c_str();
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), '*', sp);
+ s = t.s1.c_str();
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ s = t.s2.c_str();
+ BOOST_TEST(s == t.v2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), '*', sp);
+ s = t.s2.c_str();
+ BOOST_TEST(s == t.v2);
+ });
+ }
+
+ // operator=(string_view)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ s = t.v1;
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), '*', sp);
+ s = t.v1;
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ s = t.v2;
+ BOOST_TEST(s == t.v2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), '*', sp);
+ s = t.v2;
+ BOOST_TEST(s == t.v2);
+ });
+ }
+ }
+
+ void
+ testAssign()
+ {
+ test_vectors const t;
+
+ // assign(size_type, char)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), 'x', sp);
+ s.assign(t.v1.size(), '*');
+ BOOST_TEST(
+ s == std::string(t.v1.size(), '*'));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), 'x', sp);
+ s.assign(t.v1.size(), '*');
+ BOOST_TEST(
+ s == std::string(t.v1.size(), '*'));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), 'x', sp);
+ s.assign(t.v2.size(), '*');
+ BOOST_TEST(
+ s == std::string(t.v2.size(), '*'));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), 'x', sp);
+ s.assign(t.v2.size(), '*');
+ BOOST_TEST(
+ s == std::string(t.v2.size(), '*'));
+ });
+ }
+
+ // assign(string)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), 'x', sp);
+ s.assign(string(t.v1.size(), '*'));
+ BOOST_TEST(
+ s == std::string(t.v1.size(), '*'));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), 'x', sp);
+ s.assign(string(t.v1.size(), '*'));
+ BOOST_TEST(
+ s == std::string(t.v1.size(), '*'));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), 'x', sp);
+ s.assign(string(t.v2.size(), '*'));
+ BOOST_TEST(
+ s == std::string(t.v2.size(), '*'));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), 'x', sp);
+ s.assign(string(t.v2.size(), '*'));
+ BOOST_TEST(
+ s == std::string(t.v2.size(), '*'));
+ });
+
+ // self-assign
+ {
+ string s(t.v1);
+ s = static_cast<string const&>(s);
+ BOOST_TEST(s == t.v1);
+ }
+ }
+
+ // assign(string&&)
+ {
+ // same storage
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v1.size(), '*');
+ string s(c, sp);
+ string s2(t.v1, sp);
+ s.assign(std::move(s2));
+ BOOST_TEST(s == t.v1);
+ BOOST_TEST(s2.empty());
+ BOOST_TEST(
+ *s.storage() ==
+ *s2.storage());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v2.size(), '*');
+ string s(c, sp);
+ string s2(t.v1, sp);
+ s.assign(std::move(s2));
+ BOOST_TEST(s == t.v1);
+ BOOST_TEST(s2.empty());
+ BOOST_TEST(
+ *s.storage() ==
+ *s2.storage());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v1.size(), '*');
+ string s(c, sp);
+ string s2(t.v2, sp);
+ s.assign(std::move(s2));
+ BOOST_TEST(s == t.v2);
+ BOOST_TEST(s2.empty());
+ BOOST_TEST(
+ *s.storage() ==
+ *s2.storage());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v2.size(), '*');
+ string s(c, sp);
+ string s2(t.v2, sp);
+ s.assign(std::move(s2));
+ BOOST_TEST(s == t.v2);
+ BOOST_TEST(s2.empty());
+ BOOST_TEST(
+ *s.storage() ==
+ *s2.storage());
+ });
+
+ // different storage
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v1.size(), '*');
+ string s(c, sp);
+ string s2(t.v1);
+ s.assign(std::move(s2));
+ BOOST_TEST(s == t.v1);
+ BOOST_TEST(s2 == t.v1);
+ BOOST_TEST(
+ *s.storage() !=
+ *s2.storage());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v2.size(), '*');
+ string s(c, sp);
+ string s2(t.v1);
+ s.assign(std::move(s2));
+ BOOST_TEST(s == t.v1);
+ BOOST_TEST(s2 == t.v1);
+ BOOST_TEST(
+ *s.storage() !=
+ *s2.storage());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v1.size(), '*');
+ string s(c, sp);
+ string s2(t.v2);
+ s.assign(std::move(s2));
+ BOOST_TEST(s == t.v2);
+ BOOST_TEST(s2 == t.v2);
+ BOOST_TEST(
+ *s.storage() !=
+ *s2.storage());
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string c(t.v2.size(), '*');
+ string s(c, sp);
+ string s2(t.v2);
+ s.assign(std::move(s2));
+ BOOST_TEST(s == t.v2);
+ BOOST_TEST(s2 == t.v2);
+ BOOST_TEST(
+ *s.storage() !=
+ *s2.storage());
+ });
+ }
+
+ // assign(char const*, size_type)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ s.assign(t.s1.c_str(), 3);
+ BOOST_TEST(s == "abc");
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), '*', sp);
+ s.assign(t.s1.c_str(), 3);
+ BOOST_TEST(s == "abc");
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ s.assign(t.s2.c_str(), 3);
+ BOOST_TEST(s == "ABC");
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), '*', sp);
+ s.assign(t.s2.c_str(), 3);
+ BOOST_TEST(s == "ABC");
+ });
+ };
+
+ // assign(char const* s)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ s.assign(t.s1.c_str());
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), '*', sp);
+ s.assign(t.s1.c_str());
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ s.assign(t.s2.c_str());
+ BOOST_TEST(s == t.v2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), '*', sp);
+ s.assign(t.s2.c_str());
+ BOOST_TEST(s == t.v2);
+ });
+ }
+
+ // assign(InputIt, InputIt)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ s.assign(t.s1.begin(), t.s1.end());
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), '*', sp);
+ s.assign(t.s1.begin(), t.s1.end());
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ s.assign(
+ make_input_iterator(t.s1.begin()),
+ make_input_iterator(t.s1.end()));
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), '*', sp);
+ s.assign(
+ make_input_iterator(t.s1.begin()),
+ make_input_iterator(t.s1.end()));
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ s.assign(t.s2.begin(), t.s2.end());
+ BOOST_TEST(s == t.v2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), '*', sp);
+ s.assign(t.s2.begin(), t.s2.end());
+ BOOST_TEST(s == t.v2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ s.assign(
+ make_input_iterator(t.s2.begin()),
+ make_input_iterator(t.s2.end()));
+ BOOST_TEST(s == t.v2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), '*', sp);
+ s.assign(
+ make_input_iterator(t.s2.begin()),
+ make_input_iterator(t.s2.end()));
+ BOOST_TEST(s == t.v2);
+ });
+
+ // empty range
+ {
+ string s(t.v1);
+ s.assign(t.s1.begin(), t.s1.begin());
+ BOOST_TEST(s.empty());
+ }
+
+ // empty range
+ {
+ string s(t.v1);
+ s.assign(
+ make_input_iterator(t.s1.begin()),
+ make_input_iterator(t.s1.begin()));
+ BOOST_TEST(s.empty());
+ }
+ }
+
+ // assign(string_view)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ s.assign(t.v1);
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), '*', sp);
+ s.assign(t.v1);
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1.size(), '*', sp);
+ s.assign(t.v2);
+ BOOST_TEST(s == t.v2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2.size(), '*', sp);
+ s.assign(t.v2);
+ BOOST_TEST(s == t.v2);
+ });
+ }
+ }
+
+ void
+ testConversion()
+ {
+ test_vectors const t;
+
+ string s(t.s1);
+ auto const& cs(s);
+
+ char const* chars = cs.c_str();
+ BOOST_TEST(chars == t.s1);
+ json::string_view sv = cs;
+ BOOST_TEST(sv == t.s1);
+#if ! defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
+ std::string_view std_sv = cs;
+ BOOST_TEST(std_sv == t.s1);
+#endif
+
+ s = t.s2;
+
+ chars = cs.c_str();
+ BOOST_TEST(chars == t.s2);
+ sv = cs;
+ BOOST_TEST(sv == t.s2);
+#if ! defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
+ std_sv = cs;
+ BOOST_TEST(std_sv == t.s2);
+#endif
+ }
+
+ void
+ testElementAccess()
+ {
+ test_vectors const t;
+
+ string s1(t.v1);
+ string s2(t.v2);
+ auto const& cs1(s1);
+ auto const& cs2(s2);
+
+ // at(size_type)
+ {
+ BOOST_TEST(s1.at(1) == 'b');
+ s1.at(1) = '*';
+ BOOST_TEST(s1.at(1) == '*');
+ s1.at(1) = 'b';
+ BOOST_TEST(s1.at(1) == 'b');
+
+ BOOST_TEST(s2.at(1) == 'B');
+ s2.at(1) = '*';
+ BOOST_TEST(s2.at(1) == '*');
+ s2.at(1) = 'B';
+ BOOST_TEST(s2.at(1) == 'B');
+
+ BOOST_TEST_THROWS(s1.at(s2.size()),
+ std::out_of_range);
+ }
+
+ // at(size_type) const
+ {
+ BOOST_TEST(cs1.at(1) == 'b');
+ BOOST_TEST(cs2.at(1) == 'B');
+
+ BOOST_TEST_THROWS(cs1.at(cs2.size()),
+ std::out_of_range);
+ }
+
+ // operator[&](size_type)
+ {
+ BOOST_TEST(s1[1] == 'b');
+ s1[1] = '*';
+ BOOST_TEST(s1[1] == '*');
+ s1[1] = 'b';
+ BOOST_TEST(s1[1] == 'b');
+
+ BOOST_TEST(s2[1] == 'B');
+ s2[1] = '*';
+ BOOST_TEST(s2[1] == '*');
+ s2[1] = 'B';
+ BOOST_TEST(s2[1] == 'B');
+ }
+
+ // operator[&](size_type) const
+ {
+ BOOST_TEST(cs1[1] == 'b');
+ BOOST_TEST(cs2[1] == 'B');
+ }
+
+ // front()
+ {
+ BOOST_TEST(s1.front() == 'a');
+ s1.front() = '*';
+ BOOST_TEST(s1.front() == '*');
+ s1.front() = 'a';
+ BOOST_TEST(s1.front() == 'a');
+
+ BOOST_TEST(s2.front() == 'A');
+ s2.front() = '*';
+ BOOST_TEST(s2.front() == '*');
+ s2.front() = 'A';
+ BOOST_TEST(s2.front() == 'A');
+ }
+
+ // front() const
+ {
+ BOOST_TEST(cs1.front() == 'a');
+ BOOST_TEST(cs2.front() == 'A');
+ }
+
+ // back()
+ {
+ auto const ch1 = s1.at(s1.size()-1);
+ auto const ch2 = s2.at(s2.size()-1);
+
+ BOOST_TEST(s1.back() == ch1);
+ s1.back() = '*';
+ BOOST_TEST(s1.back() == '*');
+ s1.back() = ch1;
+ BOOST_TEST(s1.back() == ch1);
+
+ BOOST_TEST(s2.back() == ch2);
+ s2.back() = '*';
+ BOOST_TEST(s2.back() == '*');
+ s2.back() = ch2;
+ BOOST_TEST(s2.back() == ch2);
+ }
+
+ // back() const
+ {
+ auto const ch1 = s1.at(s1.size()-1);
+ auto const ch2 = s2.at(s2.size()-1);
+
+ BOOST_TEST(cs1.back() == ch1);
+ BOOST_TEST(cs2.back() == ch2);
+ }
+
+ // data()
+ {
+ BOOST_TEST(
+ string_view(s1.data()) == t.v1);
+ BOOST_TEST(
+ string_view(s2.data()) == t.v2);
+ }
+ // data() const
+ {
+ BOOST_TEST(
+ string_view(cs1.data()) == t.v1);
+ BOOST_TEST(
+ string_view(cs2.data()) == t.v2);
+ }
+
+ // c_str()
+ {
+ BOOST_TEST(
+ string_view(cs1.c_str()) == t.v1);
+ BOOST_TEST(
+ string_view(cs2.c_str()) == t.v2);
+ }
+
+ // operator string_view()
+ {
+ BOOST_TEST(
+ string_view(cs1) == t.v1);
+ BOOST_TEST(
+ string_view(cs2) == t.v2);
+ }
+ }
+
+ void
+ testIterators()
+ {
+ string s = "abc";
+ auto const& ac(s);
+
+ {
+ auto it = s.begin();
+ BOOST_TEST(*it == 'a'); ++it;
+ BOOST_TEST(*it == 'b'); it++;
+ BOOST_TEST(*it == 'c'); ++it;
+ BOOST_TEST(it == s.end());
+ }
+ {
+ auto it = s.cbegin();
+ BOOST_TEST(*it == 'a'); ++it;
+ BOOST_TEST(*it == 'b'); it++;
+ BOOST_TEST(*it == 'c'); ++it;
+ BOOST_TEST(it == s.cend());
+ }
+ {
+ auto it = ac.begin();
+ BOOST_TEST(*it == 'a'); ++it;
+ BOOST_TEST(*it == 'b'); it++;
+ BOOST_TEST(*it == 'c'); ++it;
+ BOOST_TEST(it == ac.end());
+ }
+ {
+ auto it = s.end();
+ --it; BOOST_TEST(*it == 'c');
+ it--; BOOST_TEST(*it == 'b');
+ --it; BOOST_TEST(*it == 'a');
+ BOOST_TEST(it == s.begin());
+ }
+ {
+ auto it = s.cend();
+ --it; BOOST_TEST(*it == 'c');
+ it--; BOOST_TEST(*it == 'b');
+ --it; BOOST_TEST(*it == 'a');
+ BOOST_TEST(it == s.cbegin());
+ }
+ {
+ auto it = ac.end();
+ --it; BOOST_TEST(*it == 'c');
+ it--; BOOST_TEST(*it == 'b');
+ --it; BOOST_TEST(*it == 'a');
+ BOOST_TEST(it == ac.begin());
+ }
+
+ {
+ auto it = s.rbegin();
+ BOOST_TEST(*it == 'c'); ++it;
+ BOOST_TEST(*it == 'b'); it++;
+ BOOST_TEST(*it == 'a'); ++it;
+ BOOST_TEST(it == s.rend());
+ }
+ {
+ auto it = s.crbegin();
+ BOOST_TEST(*it == 'c'); ++it;
+ BOOST_TEST(*it == 'b'); it++;
+ BOOST_TEST(*it == 'a'); ++it;
+ BOOST_TEST(it == s.crend());
+ }
+ {
+ auto it = ac.rbegin();
+ BOOST_TEST(*it == 'c'); ++it;
+ BOOST_TEST(*it == 'b'); it++;
+ BOOST_TEST(*it == 'a'); ++it;
+ BOOST_TEST(it == ac.rend());
+ }
+ {
+ auto it = s.rend();
+ --it; BOOST_TEST(*it == 'a');
+ it--; BOOST_TEST(*it == 'b');
+ --it; BOOST_TEST(*it == 'c');
+ BOOST_TEST(it == s.rbegin());
+ }
+ {
+ auto it = s.crend();
+ --it; BOOST_TEST(*it == 'a');
+ it--; BOOST_TEST(*it == 'b');
+ --it; BOOST_TEST(*it == 'c');
+ BOOST_TEST(it == s.crbegin());
+ }
+ {
+ auto it = ac.rend();
+ --it; BOOST_TEST(*it == 'a');
+ it--; BOOST_TEST(*it == 'b');
+ --it; BOOST_TEST(*it == 'c');
+ BOOST_TEST(it == ac.rbegin());
+ }
+
+ {
+ string s2;
+ string const& cs2(s2);
+ BOOST_TEST(std::distance(
+ s2.begin(), s2.end()) == 0);
+ BOOST_TEST(std::distance(
+ cs2.begin(), cs2.end()) == 0);
+ BOOST_TEST(std::distance(
+ s2.rbegin(), s2.rend()) == 0);
+ BOOST_TEST(std::distance(
+ cs2.rbegin(), cs2.rend()) == 0);
+ }
+ }
+
+ void
+ testCapacity()
+ {
+ test_vectors const t;
+
+ // empty()
+ {
+ {
+ string s;
+ BOOST_TEST(s.empty());
+ }
+ {
+ string s = "abc";
+ BOOST_TEST(! s.empty());
+ }
+ }
+
+ // size()
+ // max_size()
+ {
+ string s = "abc";
+ BOOST_TEST(s.size() == 3);
+ BOOST_TEST(s.max_size() < string::npos);
+ }
+
+ // reserve(size_type)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(sp);
+ s.append(t.v1);
+ s.append(t.v2);
+
+ s.reserve(0);
+ BOOST_TEST(s.size() ==
+ t.v1.size() + t.v2.size());
+
+ s.reserve(t.v1.size() + t.v2.size());
+ BOOST_TEST(s.size() ==
+ t.v1.size() + t.v2.size());
+
+ s.reserve(s.size() * 2);
+ BOOST_TEST(s.capacity() >
+ t.v1.size() + t.v2.size());
+
+ s.resize(t.v1.size());
+ s.reserve(t.v1.size());
+ BOOST_TEST(s == t.v1);
+ });
+ }
+
+ // capacity()
+ {
+ // implied
+ }
+
+ // shrink_to_fit()
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(sp);
+ string::size_type cap;
+
+ cap = s.capacity();
+ s.shrink_to_fit();
+ BOOST_TEST(s.capacity() == cap);
+
+ s.reserve(s.capacity() + 1);
+ s.shrink_to_fit();
+ BOOST_TEST(s.capacity() == cap);
+
+ s.resize(cap * 3, '*');
+ cap = s.capacity();
+ s.resize(cap - 1);
+ s.shrink_to_fit();
+ BOOST_TEST(s.capacity() == cap);
+
+ s.resize(cap / 2);
+ BOOST_TEST(s.capacity() == cap);
+
+ s.shrink_to_fit();
+ BOOST_TEST(s.capacity() < cap);
+ });
+ }
+
+ void
+ testClear()
+ {
+ test_vectors const t;
+
+ // clear()
+ {
+ {
+ string s(t.v1);
+ s.clear();
+ BOOST_TEST(s.empty());
+ BOOST_TEST(s.size() == 0);
+ BOOST_TEST(s.capacity() > 0);
+ }
+
+ {
+ string s(t.v2);
+ s.clear();
+ BOOST_TEST(s.empty());
+ BOOST_TEST(s.size() == 0);
+ BOOST_TEST(s.capacity() > 0);
+ }
+ }
+ }
+
+ void
+ testInsert()
+ {
+ test_vectors const t;
+
+ // insert(size_type, size_type, char)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.insert(1, 3, '*');
+ BOOST_TEST(s == std::string(
+ t.v1).insert(1, 3, '*'));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.insert(1, 3, '*');
+ BOOST_TEST(s == std::string(
+ t.v2).insert(1, 3, '*'));
+ });
+
+ // pos out of range
+ {
+ string s(t.v1);
+ BOOST_TEST_THROWS(
+ (s.insert(s.size() + 2, 1, '*')),
+ std::out_of_range);
+ }
+
+ // size > max_size
+ {
+ string s(t.v1);
+ BOOST_TEST_THROWS(
+ (s.insert(1, s.max_size(), 'a')),
+ std::length_error);
+ }
+ }
+
+ // insert(size_type, char const*)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.insert(1, "***");
+ BOOST_TEST(s == std::string(
+ t.v1).insert(1, "***"));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.insert(1, "***");
+ BOOST_TEST(s == std::string(
+ t.v2).insert(1, "***"));
+ });
+
+ // pos out of range
+ {
+ string s(t.v1);
+ BOOST_TEST_THROWS(
+ (s.insert(s.size() + 2, "*")),
+ std::out_of_range);
+ }
+ }
+
+ // insert(size_type, char const*, size_type)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.insert(1, "*****");
+ BOOST_TEST(s == std::string(
+ t.v1).insert(1, "*****"));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.insert(1, "*****");
+ BOOST_TEST(s == std::string(
+ t.v2).insert(1, "*****"));
+ });
+ }
+
+ // insert(size_type, string const&)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.insert(1, string(t.v2));
+ BOOST_TEST(s == std::string(
+ t.v1).insert(1, t.s2));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.insert(1, string(t.v1));
+ BOOST_TEST(s == std::string(
+ t.v2).insert(1, t.s1));
+ });
+ }
+
+ //// KRYSTIAN These tests are superseded by the new string_view overloads
+ //// insert(size_type, string const&, size_type, size_type)
+ //{
+ // fail_loop([&](storage_ptr const& sp)
+ // {
+ // string s(t.v1, sp);
+ // s.insert(1, string(t.v2), 1, 3);
+ // BOOST_TEST(s == std::string(
+ // t.v1).insert(1, t.s2, 1, 3));
+ // });
+
+ // fail_loop([&](storage_ptr const& sp)
+ // {
+ // string s(t.v2, sp);
+ // s.insert(1, string(t.v1), 1, 3);
+ // BOOST_TEST(s == std::string(
+ // t.v2).insert(1, t.s1, 1, 3));
+ // });
+
+ // fail_loop([&](storage_ptr const& sp)
+ // {
+ // string s(t.v1, sp);
+ // s.insert(1, string(t.v2), 1);
+ // BOOST_TEST(s == std::string(
+ // t.v1).insert(1, t.s2, 1, std::string::npos));
+ // });
+
+ // fail_loop([&](storage_ptr const& sp)
+ // {
+ // string s(t.v2, sp);
+ // s.insert(1, string(t.v1), 1);
+ // BOOST_TEST(s == std::string(
+ // t.v2).insert(1, t.s1, 1, std::string::npos));
+ // });
+ //}
+
+ // insert(size_type, char)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ BOOST_TEST(
+ s.insert(2, '*')[2] == '*');
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ BOOST_TEST(
+ s.insert(2, '*')[2] == '*');
+ });
+ }
+
+ // insert(const_iterator, size_type, char)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ BOOST_TEST(string_view(
+ &(s.insert(2, 3, '*')[2]), 5) ==
+ "***cd");
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ BOOST_TEST(string_view(
+ &(s.insert(2, 3, '*')[2]), 5) ==
+ "***CD");
+ });
+ }
+
+ // insert(const_iterator, InputIt, InputIt)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.insert(2, t.s2.begin(), t.s2.end());
+ std::string cs(t.s1);
+ cs.insert(2, &t.s2[0], t.s2.size());
+ BOOST_TEST(s == cs);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.insert(2, t.s1.begin(), t.s1.end());
+ std::string cs(t.s2);
+ cs.insert(2, &t.s1[0], t.s1.size());
+ BOOST_TEST(s == cs);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.insert(2,
+ make_input_iterator(t.s2.begin()),
+ make_input_iterator(t.s2.end()));
+ std::string cs(t.s1);
+ cs.insert(2, &t.s2[0], t.s2.size());
+ BOOST_TEST(s == cs);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.insert(2,
+ make_input_iterator(t.s1.begin()),
+ make_input_iterator(t.s1.end()));
+ std::string cs(t.s2);
+ cs.insert(2, &t.s1[0], t.s1.size());
+ BOOST_TEST(s == cs);
+ });
+ }
+
+ // insert(const_iterator, string_view)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.insert(2, string_view(t.v2));
+ std::string cs(t.v1);
+ cs.insert(2, t.s2);
+ BOOST_TEST(s == cs);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.insert(2, string_view(t.v1));
+ std::string cs(t.v2);
+ cs.insert(2, t.s1);
+ BOOST_TEST(s == cs);
+ });
+ }
+
+ // insert(const_iterator, string_view)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.insert(2, string_view(t.v2).substr(2, 3));
+ std::string cs(t.v1);
+ cs.insert(2, t.s2, 2, 3);
+ BOOST_TEST(s == cs);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.insert(2, string_view(t.v1).substr(2, 3));
+ std::string cs(t.v2);
+ cs.insert(2, t.s1, 2, 3);
+ BOOST_TEST(s == cs);
+ });
+ }
+
+ // insert(size_type, char const*)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.insert(1, "***");
+ BOOST_TEST(s == std::string(
+ t.v1).insert(1, "***"));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.insert(1, "***");
+ BOOST_TEST(s == std::string(
+ t.v2).insert(1, "***"));
+ });
+
+ // pos out of range
+ {
+ string s(t.v1);
+ BOOST_TEST_THROWS(
+ (s.insert(s.size() + 2, "*")),
+ std::out_of_range);
+ }
+ }
+
+ // insert tests for when source is within destination
+ {
+ // start before splice point
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.reserve(s.size() + 10);
+ s.insert(4, s.subview(0, 3));
+ std::string cs(t.v1);
+ cs.insert(4, cs.substr(0, 3));
+ BOOST_TEST(s == cs);
+ });
+
+ // start after splice point
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.reserve(s.size() + 10);
+ s.insert(0, s.subview(3, 3));
+ std::string cs(t.v1);
+ cs.insert(0, cs.substr(3, 3));
+ BOOST_TEST(s == cs);
+ });
+
+ // insert pos bisects the inserted string
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.reserve(s.size() + 10);
+ s.insert(2, s.subview(0, 5));
+ std::string cs(t.v1);
+ cs.insert(2, cs.substr(0, 5));
+ BOOST_TEST(s == cs);
+ });
+ }
+
+ // insert reallocation test
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ std::string cs(t.v2);
+ const auto view = t.v2.substr(0, 4);
+ s.append(s);
+ cs.append(cs);
+ s.insert(2, view);
+ cs.insert(2, view.data(), view.size());
+ BOOST_TEST(s == cs);
+ });
+ }
+ }
+
+ void
+ testErase()
+ {
+ test_vectors const t;
+
+ // erase(size_type, size_type)
+ {
+ {
+ string s(t.v1);
+ s.erase(1, 3);
+ BOOST_TEST(s ==
+ std::string(t.v1).erase(1, 3));
+ }
+
+ {
+ string s(t.v2);
+ s.erase(1, 3);
+ BOOST_TEST(s ==
+ std::string(t.v2).erase(1, 3));
+ }
+
+ {
+ string s(t.v1);
+ s.erase(3);
+ BOOST_TEST(s ==
+ std::string(t.v1).erase(3));
+ }
+
+ {
+ string s(t.v2);
+ s.erase(3);
+ BOOST_TEST(s ==
+ std::string(t.v2).erase(3));
+ }
+
+ {
+ string s(t.v1);
+ s.erase();
+ BOOST_TEST(s ==
+ std::string(t.v1).erase());
+ }
+
+ {
+ string s(t.v2);
+ s.erase();
+ BOOST_TEST(s ==
+ std::string(t.v2).erase());
+ }
+
+ {
+ string s(t.v1);
+ BOOST_TEST_THROWS(
+ (s.erase(t.v1.size() + 1, 1)),
+ std::out_of_range);
+ }
+ }
+
+ // iterator erase(const_iterator)
+ {
+ {
+ string s(t.v1);
+ std::string s2(t.v1);
+ s.erase(s.begin() + 3);
+ s2.erase(s2.begin() + 3);
+ BOOST_TEST(s == s2);
+ }
+
+ {
+ string s(t.v2);
+ std::string s2(t.v2);
+ s.erase(s.begin() + 3);
+ s2.erase(s2.begin() + 3);
+ BOOST_TEST(s == s2);
+ }
+ }
+
+ // iterator erase(const_iterator, const_iterator)
+ {
+ string s(t.v1);
+ std::string s2(t.v1);
+ s.erase(s.begin() + 1, s.begin() + 3);
+ s2.erase(s2.begin() + 1, s2.begin() + 3);
+ BOOST_TEST(s == s2);
+ }
+ }
+
+ void
+ testPushPop()
+ {
+ test_vectors const t;
+
+ // push_back(char)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(sp);
+ for(auto ch : t.v1)
+ s.push_back(ch);
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(sp);
+ for(auto ch : t.v2)
+ s.push_back(ch);
+ BOOST_TEST(s == t.v2);
+ });
+ }
+
+ // pop_back(char)
+ {
+ {
+ string s(t.v1);
+ while(! s.empty())
+ s.pop_back();
+ BOOST_TEST(s.empty());
+ BOOST_TEST(s.capacity() > 0);
+ }
+
+ {
+ string s(t.v2);
+ while(! s.empty())
+ s.pop_back();
+ BOOST_TEST(s.empty());
+ BOOST_TEST(s.capacity() > 0);
+ }
+ }
+ }
+
+ void
+ testAppend()
+ {
+ test_vectors const t;
+
+ // append(size_type, char)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.append(t.v2.size(), '*');
+ BOOST_TEST(s == t.s1 +
+ std::string(t.v2.size(), '*'));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.append(t.v1.size(), '*');
+ BOOST_TEST(s == t.s2 +
+ std::string(t.v1.size(), '*'));
+ });
+ }
+
+ // append(string_view)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.append(string(t.v2));
+ BOOST_TEST(s == t.s1 + t.s2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.append(string(t.v1));
+ BOOST_TEST(s == t.s2 + t.s1);
+ });
+ }
+
+ // append(string_view)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.append(string(t.v2).subview(3));
+ BOOST_TEST(s == t.s1 + t.s2.substr(3));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.append(string(t.v1).subview(3));
+ BOOST_TEST(s == t.s2 + t.s1.substr(3));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.append(string(t.v2).subview(2, 3));
+ BOOST_TEST(s == t.s1 + t.s2.substr(2, 3));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.append(string(t.v1).subview(2, 3));
+ BOOST_TEST(s == t.s2 + t.s1.substr(2, 3));
+ });
+ }
+
+ // append(char const*)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.append(t.s2.c_str());
+ BOOST_TEST(s == t.s1 + t.s2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.append(t.s1.c_str());
+ BOOST_TEST(s == t.s2 + t.s1);
+ });
+ }
+
+ // append(InputIt, InputIt)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.append(t.s2.begin(), t.s2.end());
+ BOOST_TEST(s == t.s1 + t.s2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.append(t.s1.begin(), t.s1.end());
+ BOOST_TEST(s == t.s2 + t.s1);
+ });
+
+ // Fails on Visual Studio 2017 C++2a Strict
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.append(
+ make_input_iterator(t.s2.begin()),
+ make_input_iterator(t.s2.end()));
+ BOOST_TEST(s == t.s1 + t.s2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.append(
+ make_input_iterator(t.s1.begin()),
+ make_input_iterator(t.s1.end()));
+ BOOST_TEST(s == t.s2 + t.s1);
+ });
+ }
+
+ // append(string_view)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.append(t.v2);
+ BOOST_TEST(s == t.s1 + t.s2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.append(t.v1);
+ BOOST_TEST(s == t.s2 + t.s1);
+ });
+ }
+
+ // append(string_view)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.append(t.v2.substr(2));
+ BOOST_TEST(s == t.s1 + t.s2.substr(2));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.append(t.v1.substr(2));
+ BOOST_TEST(s == t.s2 + t.s1.substr(2));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s.append(t.v2.substr(2, 3));
+ BOOST_TEST(s == t.s1 + t.s2.substr(2, 3));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s.append(t.v1.substr(2, 3));
+ BOOST_TEST(s == t.s2 + t.s1.substr(2, 3));
+ });
+ }
+ }
+
+ void
+ testPlusEquals()
+ {
+ test_vectors const t;
+
+ // operator+=(string)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s += string(t.v2);
+ BOOST_TEST(s == t.s1 + t.s2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s += string(t.v1);
+ BOOST_TEST(s == t.s2 + t.s1);
+ });
+ }
+
+ // operator+=(char)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(sp);
+ for(auto ch : t.v1)
+ s += ch;
+ BOOST_TEST(s == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(sp);
+ for(auto ch : t.v2)
+ s += ch;
+ BOOST_TEST(s == t.v2);
+ });
+ }
+
+ // operator+=(char const*)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s += t.s2.c_str();
+ BOOST_TEST(s == t.s1 + t.s2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s += t.s1.c_str();
+ BOOST_TEST(s == t.s2 + t.s1);
+ });
+ }
+
+ // operator+=(string_view)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v1, sp);
+ s += t.v2;
+ BOOST_TEST(s == t.s1 + t.s2);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ s += t.v1;
+ BOOST_TEST(s == t.s2 + t.s1);
+ });
+ }
+ }
+
+ void
+ testCompare()
+ {
+ test_vectors const t;
+ string const v1 = t.v1;
+
+ // compare(string)
+ BOOST_TEST(v1.compare(string("aaaaaaa")) > 0);
+ BOOST_TEST(v1.compare(string(t.v1)) == 0);
+ BOOST_TEST(v1.compare(string("bbbbbbb")) < 0);
+
+ // compare(char const*)
+ BOOST_TEST(v1.compare("aaaaaaa") > 0);
+ BOOST_TEST(v1.compare(t.s1.c_str()) == 0);
+ BOOST_TEST(v1.compare("bbbbbbb") < 0);
+
+ // compare(string_view s)
+ BOOST_TEST(v1.compare(string_view("aaaaaaa")) > 0);
+ BOOST_TEST(v1.compare(t.v1) == 0);
+ BOOST_TEST(v1.compare(string_view("bbbbbbb")) < 0);
+ }
+
+ void
+ testStartEndsWith()
+ {
+ test_vectors const t;
+ string const v1 = t.v1;
+ string const v2 = t.v2;
+
+ // starts_with(string_view)
+ {
+ BOOST_TEST(v1.starts_with(string_view("abc")));
+ BOOST_TEST(v2.starts_with(string_view("ABC")));
+ BOOST_TEST(! v1.starts_with(string_view("xyz")));
+ BOOST_TEST(! v2.starts_with(string_view("XYZ")));
+ }
+
+ // starts_with(char)
+ {
+ BOOST_TEST(v1.starts_with('a'));
+ BOOST_TEST(v2.starts_with('A'));
+ BOOST_TEST(! v1.starts_with('x'));
+ BOOST_TEST(! v2.starts_with('X'));
+ }
+
+ // starts_with(char const*)
+ {
+ BOOST_TEST(v1.starts_with("abc"));
+ BOOST_TEST(v2.starts_with("ABC"));
+ BOOST_TEST(! v1.starts_with("xyz"));
+ BOOST_TEST(! v2.starts_with("XYZ"));
+ }
+
+ // ends_with(string_view)
+ {
+ BOOST_TEST(v1.ends_with(last_of(t.s1,3)));
+ BOOST_TEST(v2.ends_with(last_of(t.s2,3)));
+ BOOST_TEST(! v1.ends_with(string_view("abc")));
+ BOOST_TEST(! v2.ends_with(string_view("ABC")));
+ }
+
+ // ends_with(char)
+ {
+ BOOST_TEST(v1.ends_with(last_of(t.s1, 1)[0]));
+ BOOST_TEST(v2.ends_with(last_of(t.s2, 1)[0]));
+ BOOST_TEST(! v1.ends_with('a'));
+ BOOST_TEST(! v2.ends_with('A'));
+ }
+
+ // ends_with(char const*)
+ {
+ BOOST_TEST(v1.ends_with(last_of(t.s1, 3).data()));
+ BOOST_TEST(v2.ends_with(last_of(t.s2, 3).data()));
+ BOOST_TEST(! v1.ends_with("abc"));
+ BOOST_TEST(! v2.ends_with("ABC"));
+ }
+ }
+
+ void
+ testReplace()
+ {
+ test_vectors const t;
+
+ // replace(std::size_t, std::size_t, string_view)
+ {
+ // pos out of range
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ BOOST_TEST_THROWS(s.replace(s.size() + 1, 1, t.v2),
+ std::out_of_range);
+ });
+
+ // outside, shrink
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(s2.replace(0, 4, t.v2.substr(4, 2)) ==
+ s1.replace(0, 4, t.v2.data() + 4, 2));
+ });
+
+ // outside, grow
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(s2.replace(0, 1, t.v2.substr(0)) ==
+ s1.replace(0, 1, t.v2.data(), t.v2.size()));
+ });
+
+ // outside, grow, reallocate
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ s1.append(s1);
+ s2.append(s2);
+ BOOST_TEST(s2.replace(0, 1, t.v2.substr(0)) ==
+ s1.replace(0, 1, t.v2.data(), t.v2.size()));
+ });
+
+ // outside, same
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(s2.replace(0, 2, t.v2.substr(0, 2)) ==
+ s1.replace(0, 2, t.v2.data(), 2));
+ });
+
+ // replace tests for full coverage
+
+ // inside, no effect
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(s2.replace(0, 4, s2.subview(0, 4)) ==
+ s1.replace(0, 4, s1.data() + 0, 4));
+ });
+
+ // inside, shrink, split
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(s2.replace(1, 4, s2.subview(4, 2)) ==
+ s1.replace(1, 4, s1.data() + 4, 2));
+ });
+
+ // inside, grow no reallocate, split
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(s2.replace(1, 1, s2.subview(0)) ==
+ s1.replace(1, 1, s1.data(), s1.size()));
+ });
+
+ // inside, reallocate, split
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ s1.append(s1);
+ s2.append(s2);
+ BOOST_TEST(s2.replace(1, 1, s2.subview(0)) ==
+ s1.replace(1, 1, s1.data(), s1.size()));
+ });
+
+ // inside, same, split
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(s2.replace(1, 2, s2.subview(0, 2)) ==
+ s1.replace(1, 2, s1.data(), 2));
+ });
+ }
+
+ // replace(const_iterator, const_iterator, string_view)
+ {
+ // outside, shrink
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(
+ s2.replace(
+ s2.begin(),
+ s2.begin() + 4,
+ t.v2.substr(4, 2)) ==
+ s1.replace(0,
+ 4, t.v2.data() + 4,
+ 2));
+ });
+
+ // outside, grow
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(
+ s2.replace(
+ s2.begin(),
+ s2.begin() + 1,
+ t.v2.substr(0)) ==
+ s1.replace(0,
+ 1, t.v2.data(),
+ t.v2.size()));
+ });
+
+ // outside, same
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(
+ s2.replace(
+ s2.begin(),
+ s2.begin() + 2,
+ t.v2.substr(0, 2)) ==
+ s1.replace(
+ 0, 2,
+ t.v2.data(),
+ 2));
+ });
+
+ // inside, shrink
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(
+ s2.replace(
+ s2.begin() + 1,
+ s2.begin() + 5,
+ s2.subview(4, 2)) ==
+ s1.replace(
+ 1, 4,
+ s1.data() + 4,
+ 2));
+ });
+
+ // inside, grow
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(
+ s2.replace(
+ s2.begin() + 1,
+ s2.begin() + 2,
+ s2.subview(0)) ==
+ s1.replace(
+ 1, 1,
+ s1.data(),
+ s1.size()));
+ });
+
+ // inside, same
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(
+ s2.replace(
+ s2.begin() + 1,
+ s2.begin() + 3,
+ s2.subview(0, 2)) ==
+ s1.replace(
+ 1, 2,
+ s1.data(),
+ 2));
+ });
+ }
+
+ // replace(std::size_t, std::size_t, std::size_t, char)
+ {
+ // grow, no realloc
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(s2.replace(0, 4, 10, 'a') ==
+ s1.replace(0, 4, 10, 'a'));
+ });
+
+ // grow, realloc
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ const auto grow = (std::max)(s1.capacity(), s2.capacity());
+ BOOST_TEST(s2.replace(0, 4, grow, 'a') ==
+ s1.replace(0, 4, grow, 'a'));
+ });
+
+ // no change in size
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(s2.replace(0, 1, 1, 'a') ==
+ s1.replace(0, 1, 1, 'a'));
+ });
+
+ // pos out of range
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(t.v2, sp);
+ BOOST_TEST_THROWS(s.replace(s.size() + 1, 1, 1, 'a'),
+ std::out_of_range);
+ });
+ }
+
+ // replace(const_iterator, const_iterator, std::size_t, char)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ std::string s1(t.v2.data(), t.v2.size());
+ string s2(t.v2, sp);
+ BOOST_TEST(
+ s2.replace(s2.begin(), s2.begin() + 4, 10, 'a') ==
+ s1.replace(0, 4, 10, 'a'));
+ });
+ }
+ }
+
+ void
+ testSubStr()
+ {
+ test_vectors const t;
+ string const s1 = t.v1;
+ string const s2 = t.v2;
+
+ // subview(size_type, size_type)
+ BOOST_TEST(s1.subview() == t.v1);
+ BOOST_TEST(s1.subview(1) == t.v1.substr(1));
+ BOOST_TEST(s1.subview(1, 3) == t.v1.substr(1, 3));
+ BOOST_TEST(s2.subview() == t.v2);
+ BOOST_TEST(s2.subview(1) == t.v2.substr(1));
+ BOOST_TEST(s2.subview(1, 3) == t.v2.substr(1, 3));
+ }
+
+ void
+ testCopy()
+ {
+ test_vectors const t;
+
+ // copy(char*, count, pos)
+ {
+ {
+ string s(t.v1);
+ std::string d;
+ d.resize(s.size());
+ s.copy(&d[0], d.size(), 0);
+ BOOST_TEST(d == t.v1);
+ }
+
+ {
+ string s(t.v1);
+ std::string d;
+ d.resize(s.size());
+ s.copy(&d[0], d.size());
+ BOOST_TEST(d == t.v1);
+ }
+ }
+ }
+
+ void
+ testResize()
+ {
+ test_vectors const t;
+
+ // resize(size_type)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(sp);
+ s.resize(t.v1.size());
+ BOOST_TEST(s.size() == t.v1.size());
+ BOOST_TEST(s == string(t.v1.size(), '\0'));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(sp);
+ s.resize(t.v2.size());
+ BOOST_TEST(s.size() == t.v2.size());
+ BOOST_TEST(s == string(t.v2.size(), '\0'));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(sp);
+ s.resize(t.v1.size());
+ s.resize(t.v2.size());
+ BOOST_TEST(s == string(t.v2.size(), '\0'));
+ s.resize(t.v1.size());
+ BOOST_TEST(s == string(t.v1.size(), '\0'));
+ });
+ }
+
+ // resize(size_type, char)
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(sp);
+ s.resize(t.v1.size(), '*');
+ BOOST_TEST(s.size() == t.v1.size());
+ BOOST_TEST(s == string(t.v1.size(), '*'));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(sp);
+ s.resize(t.v2.size(), '*');
+ BOOST_TEST(s.size() == t.v2.size());
+ BOOST_TEST(s == string(t.v2.size(), '*'));
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s(sp);
+ s.resize(t.v1.size(), '*');
+ s.resize(t.v2.size(), '*');
+ BOOST_TEST(s == string(t.v2.size(), '*'));
+ s.resize(t.v1.size());
+ BOOST_TEST(s == string(t.v1.size(), '*'));
+ });
+ }
+ }
+
+ void
+ testSwap()
+ {
+ test_vectors const t;
+
+ // swap
+ {
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s1(t.v1, sp);
+ string s2(t.v2, sp);
+ s1.swap(s2);
+ BOOST_TEST(s1 == t.v2);
+ BOOST_TEST(s2 == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s1(t.v1, sp);
+ string s2(t.v2, sp);
+ swap(s1, s2);
+ BOOST_TEST(s1 == t.v2);
+ BOOST_TEST(s2 == t.v1);
+ });
+
+ fail_loop([&](storage_ptr const& sp)
+ {
+ string s1(t.v1);
+ string s2(t.v2, sp);
+ s1.swap(s2);
+ BOOST_TEST(s1 == t.v2);
+ BOOST_TEST(s2 == t.v1);
+ });
+ }
+ }
+
+ void
+ testFind()
+ {
+ test_vectors const t;
+ string const s1 = t.v1;
+
+ // find(string_view, size_type)
+ BOOST_TEST(s1.find("bcd") == 1);
+ BOOST_TEST(s1.find("cde") == 2);
+
+ BOOST_TEST(s1.find("bcd", 0) == 1);
+ BOOST_TEST(s1.find("cde", 1) == 2);
+ BOOST_TEST(s1.find("efg", 5) == string::npos);
+
+ // find(char, size_type)
+ BOOST_TEST(s1.find('b') == 1);
+ BOOST_TEST(s1.find('c', 1) == 2);
+ BOOST_TEST(s1.find('e', 5) == string::npos);
+ }
+
+ void
+ testRfind()
+ {
+ test_vectors const t;
+ string const s1 = t.v1;
+
+ // rfind(string_view, size_type)
+ BOOST_TEST(s1.rfind("bcd") == 1);
+ BOOST_TEST(s1.rfind("cde") == 2);
+
+ BOOST_TEST(s1.rfind("bcd", 1) == 1);
+ BOOST_TEST(s1.rfind("cde", 2) == 2);
+ BOOST_TEST(s1.rfind("efg", 3) == string::npos);
+
+ // rfind(char, size_type)
+ BOOST_TEST(s1.rfind('b') == 1);
+ BOOST_TEST(s1.rfind('c', 2) == 2);
+ BOOST_TEST(s1.rfind('e', 3) == string::npos);
+ }
+
+ void
+ testFindFirstOf()
+ {
+ test_vectors const t;
+ string const s1 = t.v1;
+
+ // find_first_of(string_view, size_type)
+ BOOST_TEST(s1.find_first_of("bcd") == 1);
+ BOOST_TEST(s1.find_first_of("cde") == 2);
+
+ BOOST_TEST(s1.find_first_of("bcd", 0) == 1);
+ BOOST_TEST(s1.find_first_of("cde", 1) == 2);
+ BOOST_TEST(s1.find_first_of("efg", 7) == string::npos);
+ }
+
+ void
+ testFindFirstNotOf()
+ {
+ test_vectors const t;
+ string const s1 = t.v1;
+
+ // find_first_not_of(string_view, size_type)
+ BOOST_TEST(s1.find_first_not_of("abc") == 3);
+ BOOST_TEST(s1.find_first_not_of("cde") == 0);
+
+ BOOST_TEST(s1.find_first_not_of("bcd", 0) == 0);
+ BOOST_TEST(s1.find_first_not_of("cde", 2) == 5);
+
+ // find_first_not_of(char, size_type)
+ BOOST_TEST(s1.find_first_not_of('b') == 0);
+ BOOST_TEST(s1.find_first_not_of('a', 0) == 1);
+ BOOST_TEST(s1.find_first_not_of('e', 4) == 5);
+ }
+
+ void
+ testFindLastOf()
+ {
+ test_vectors const t;
+ string const s1 = t.v1;
+
+ // find_last_of(string_view, size_type)
+ BOOST_TEST(s1.find_last_of("bcd") == 3);
+ BOOST_TEST(s1.find_last_of("cde") == 4);
+
+ BOOST_TEST(s1.find_last_of("bcd", 3) == 3);
+ BOOST_TEST(s1.find_last_of("cde", 5) == 4);
+ BOOST_TEST(s1.find_last_of("efg", 3) == string::npos);
+ }
+
+ void
+ testFindLastNotOf()
+ {
+ test_vectors const t;
+ string const s1 = t.v1;
+
+ // find_last_not_of(string_view, size_type)
+ BOOST_TEST(s1.find_last_not_of("abc", 3) == 3);
+ BOOST_TEST(s1.find_last_not_of("bcd", 3) == 0);
+
+ BOOST_TEST(s1.find_last_not_of("efg", 4) == 3);
+ BOOST_TEST(s1.find_last_not_of("abc", 2) == string::npos);
+
+ // find_first_not_of(char, size_type)
+ BOOST_TEST(s1.find_last_not_of('a', 3) == 3);
+ BOOST_TEST(s1.find_last_not_of('e', 4) == 3);
+ BOOST_TEST(s1.find_last_not_of('a', 0) == string::npos);
+ }
+
+ void
+ testNonMembers()
+ {
+ test_vectors const t;
+ string const s1(t.v1);
+ string const s2(t.v2);
+ auto const v1(t.v1);
+ auto const v2(t.v2);
+ auto const c1 = t.s1.c_str();
+ auto const c2 = t.s2.c_str();
+
+ BOOST_TEST(! operator< (s1, s2));
+ BOOST_TEST(! operator< (s1, v2));
+ BOOST_TEST(! operator< (s1, c2));
+ BOOST_TEST(! operator<=(s1, s2));
+ BOOST_TEST(! operator<=(s1, v2));
+ BOOST_TEST(! operator<=(s1, c2));
+ BOOST_TEST(! operator==(s1, s2));
+ BOOST_TEST(! operator==(s1, v2));
+ BOOST_TEST(! operator==(s1, c2));
+ BOOST_TEST( operator!=(s1, s2));
+ BOOST_TEST( operator!=(s1, v2));
+ BOOST_TEST( operator!=(s1, c2));
+ BOOST_TEST( operator>=(s1, s2));
+ BOOST_TEST( operator>=(s1, v2));
+ BOOST_TEST( operator>=(s1, c2));
+ BOOST_TEST( operator> (s1, s2));
+ BOOST_TEST( operator> (s1, v2));
+ BOOST_TEST( operator> (s1, c2));
+
+ BOOST_TEST( operator< (s2, s1));
+ BOOST_TEST( operator< (s2, v1));
+ BOOST_TEST( operator< (s2, c1));
+ BOOST_TEST( operator<=(s2, s1));
+ BOOST_TEST( operator<=(s2, v1));
+ BOOST_TEST( operator<=(s2, c1));
+ BOOST_TEST( operator!=(s2, s1));
+ BOOST_TEST( operator!=(s2, v1));
+ BOOST_TEST( operator!=(s2, c1));
+ BOOST_TEST(! operator==(s2, s1));
+ BOOST_TEST(! operator==(s2, v1));
+ BOOST_TEST(! operator==(s2, c1));
+ BOOST_TEST(! operator>=(s2, s1));
+ BOOST_TEST(! operator>=(s2, v1));
+ BOOST_TEST(! operator>=(s2, c1));
+ BOOST_TEST(! operator> (s2, s1));
+ BOOST_TEST(! operator> (s2, v1));
+ BOOST_TEST(! operator> (s2, c1));
+
+ BOOST_TEST( operator< (s2, s1));
+ BOOST_TEST( operator< (v2, s1));
+ BOOST_TEST( operator< (c2, s1));
+ BOOST_TEST( operator<=(s2, s1));
+ BOOST_TEST( operator<=(v2, s1));
+ BOOST_TEST( operator<=(c2, s1));
+ BOOST_TEST( operator!=(s2, s1));
+ BOOST_TEST( operator!=(v2, s1));
+ BOOST_TEST( operator!=(c2, s1));
+ BOOST_TEST(! operator==(s2, s1));
+ BOOST_TEST(! operator==(v2, s1));
+ BOOST_TEST(! operator==(c2, s1));
+ BOOST_TEST(! operator>=(s2, s1));
+ BOOST_TEST(! operator>=(v2, s1));
+ BOOST_TEST(! operator>=(c2, s1));
+ BOOST_TEST(! operator> (s2, s1));
+ BOOST_TEST(! operator> (v2, s1));
+ BOOST_TEST(! operator> (c2, s1));
+
+ BOOST_TEST(! operator< (s1, s2));
+ BOOST_TEST(! operator< (v1, s2));
+ BOOST_TEST(! operator< (c1, s2));
+ BOOST_TEST(! operator<=(s1, s2));
+ BOOST_TEST(! operator<=(v1, s2));
+ BOOST_TEST(! operator<=(c1, s2));
+ BOOST_TEST(! operator==(s1, s2));
+ BOOST_TEST(! operator==(v1, s2));
+ BOOST_TEST(! operator==(c1, s2));
+ BOOST_TEST( operator!=(s1, s2));
+ BOOST_TEST( operator!=(v1, s2));
+ BOOST_TEST( operator!=(c1, s2));
+ BOOST_TEST( operator>=(s1, s2));
+ BOOST_TEST( operator>=(v1, s2));
+ BOOST_TEST( operator>=(c1, s2));
+ BOOST_TEST( operator> (s1, s2));
+ BOOST_TEST( operator> (v1, s2));
+ BOOST_TEST( operator> (c1, s2));
+ }
+
+ void
+ testHash()
+ {
+ // libstdc++ 4.8 bug
+#if !defined(__GNUC__) || (__GNUC__ > 4 || \
+ (__GNUC__ == 4 && __GNUC_MINOR__ > 8))
+ {
+ std::unordered_set<string> us;
+ us.emplace("first");
+ us.emplace("second");
+ }
+ {
+ std::unordered_set<string>(
+ 0,
+ std::hash<string>(32));
+ }
+#endif
+ {
+ std::hash<string> h1(32);
+ std::hash<string> h2(h1);
+ std::hash<string> h3(59);
+ h1 = h3;
+ h2 = h3;
+ (void)h2;
+ }
+ }
+
+ void
+ run()
+ {
+ testConstruction();
+ testAssignment();
+ testAssign();
+ testConversion();
+ testElementAccess();
+ testIterators();
+ testCapacity();
+
+ testClear();
+ testInsert();
+ testErase();
+ testPushPop();
+ testAppend();
+ testPlusEquals();
+ testCompare();
+ testStartEndsWith();
+ testReplace();
+ testSubStr();
+ testCopy();
+ testResize();
+ testSwap();
+
+ testFind();
+ testRfind();
+ testFindFirstOf();
+ testFindFirstNotOf();
+ testFindLastOf();
+ testFindLastNotOf();
+
+ testNonMembers();
+
+ testHash();
+ }
+};
+
+TEST_SUITE(string_test, "boost.json.string");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/string_view.cpp b/src/boost/libs/json/test/string_view.cpp
new file mode 100644
index 000000000..671132c3f
--- /dev/null
+++ b/src/boost/libs/json/test/string_view.cpp
@@ -0,0 +1,11 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/string_view.hpp>
diff --git a/src/boost/libs/json/test/system_error.cpp b/src/boost/libs/json/test/system_error.cpp
new file mode 100644
index 000000000..4b34ec799
--- /dev/null
+++ b/src/boost/libs/json/test/system_error.cpp
@@ -0,0 +1,11 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/system_error.hpp>
diff --git a/src/boost/libs/json/test/test.hpp b/src/boost/libs/json/test/test.hpp
new file mode 100644
index 000000000..fe6dd540c
--- /dev/null
+++ b/src/boost/libs/json/test/test.hpp
@@ -0,0 +1,1163 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#ifndef BOOST_JSON_TEST_HPP
+#define BOOST_JSON_TEST_HPP
+
+#include <boost/json/basic_parser.hpp>
+#include <boost/json/value.hpp>
+#include <boost/json/serializer.hpp>
+#include <boost/json/storage_ptr.hpp>
+#include <boost/json/detail/format.hpp>
+
+#include <cstddef>
+#include <iterator>
+#include <memory>
+#include <type_traits>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+//----------------------------------------------------------
+
+struct test_failure : std::exception
+{
+ virtual
+ char const*
+ what() const noexcept override
+ {
+ return "test failure";
+ }
+};
+
+struct fail_resource
+ : memory_resource
+{
+ std::size_t fail_max = 0;
+ std::size_t fail = 0;
+ std::size_t nalloc = 0;
+ std::size_t bytes = 0;
+
+ ~fail_resource()
+ {
+ BOOST_TEST(nalloc == 0);
+ }
+
+ void*
+ do_allocate(
+ std::size_t n,
+ std::size_t) override
+ {
+ if(++fail == fail_max)
+ {
+ ++fail_max;
+ fail = 0;
+ throw test_failure{};
+ }
+ auto p = ::operator new(n);
+ ++nalloc;
+ bytes += n;
+ return p;
+ }
+
+ void
+ do_deallocate(
+ void* p,
+ std::size_t n,
+ std::size_t) noexcept override
+ {
+ if(BOOST_TEST(nalloc > 0))
+ --nalloc;
+ bytes -= n;
+ ::operator delete(p);
+ }
+
+ bool
+ do_is_equal(
+ memory_resource const& mr) const noexcept override
+ {
+ return this == &mr;
+ }
+};
+
+template<class F>
+void
+fail_loop(F&& f)
+{
+ fail_resource ss;
+ ss.fail_max = 1;
+ while(ss.fail < 200)
+ {
+ try
+ {
+ f(&ss);
+ }
+ catch(test_failure const&)
+ {
+ continue;
+ }
+ break;
+ }
+ BOOST_TEST(ss.fail < 200);
+}
+
+//----------------------------------------------------------
+
+struct unique_resource
+ : memory_resource
+{
+ unique_resource() = default;
+
+ void*
+ do_allocate(
+ std::size_t n,
+ std::size_t) override
+ {
+ return ::operator new(n);
+ }
+
+ void
+ do_deallocate(
+ void* p,
+ std::size_t,
+ std::size_t) noexcept override
+ {
+ return ::operator delete(p);
+ }
+
+ bool
+ do_is_equal(
+ memory_resource const& mr) const noexcept override
+ {
+ return this == &mr;
+ }
+};
+
+//----------------------------------------------------------
+
+// The null parser discards all the data
+
+class null_parser
+{
+ struct handler
+ {
+ constexpr static std::size_t max_object_size = std::size_t(-1);
+ constexpr static std::size_t max_array_size = std::size_t(-1);
+ constexpr static std::size_t max_key_size = std::size_t(-1);
+ constexpr static std::size_t max_string_size = std::size_t(-1);
+
+ bool on_document_begin( error_code& ) { return true; }
+ bool on_document_end( error_code& ) { return true; }
+ bool on_object_begin( error_code& ) { return true; }
+ bool on_object_end( std::size_t, error_code& ) { return true; }
+ bool on_array_begin( error_code& ) { return true; }
+ bool on_array_end( std::size_t, error_code& ) { return true; }
+ bool on_key_part( string_view, std::size_t, error_code& ) { return true; }
+ bool on_key( string_view, std::size_t, error_code& ) { return true; }
+ bool on_string_part( string_view, std::size_t, error_code& ) { return true; }
+ bool on_string( string_view, std::size_t, error_code& ) { return true; }
+ bool on_number_part( string_view, error_code&) { return true; }
+ bool on_int64( std::int64_t, string_view, error_code& ) { return true; }
+ bool on_uint64( std::uint64_t, string_view, error_code& ) { return true; }
+ bool on_double( double, string_view, error_code& ) { return true; }
+ bool on_bool( bool, error_code& ) { return true; }
+ bool on_null( error_code& ) { return true; }
+ bool on_comment_part( string_view, error_code& ) { return true; }
+ bool on_comment( string_view, error_code& ) { return true; }
+ };
+
+ basic_parser<handler> p_;
+
+public:
+ null_parser()
+ : p_(parse_options())
+ {
+ }
+
+ explicit
+ null_parser(parse_options po)
+ : p_(po)
+ {
+ }
+
+ void
+ reset()
+ {
+ p_.reset();
+ }
+
+ std::size_t
+ write(
+ char const* data,
+ std::size_t size,
+ error_code& ec)
+ {
+ auto const n = p_.write_some(
+ false, data, size, ec);
+ if(! ec && n < size)
+ ec = error::extra_data;
+ return n;
+ }
+};
+
+//----------------------------------------------------------
+
+class fail_parser
+{
+ struct handler
+ {
+ constexpr static std::size_t max_object_size = std::size_t(-1);
+ constexpr static std::size_t max_array_size = std::size_t(-1);
+ constexpr static std::size_t max_key_size = std::size_t(-1);
+ constexpr static std::size_t max_string_size = std::size_t(-1);
+
+ std::size_t n;
+
+ handler()
+ : n(std::size_t(-1))
+ {
+ }
+
+ bool
+ maybe_fail(error_code& ec)
+ {
+ if(n && --n > 0)
+ return true;
+ ec = error::test_failure;
+ return false;
+ }
+
+ bool
+ on_document_begin(
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_document_end(
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_object_begin(
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_object_end(
+ std::size_t,
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_array_begin(
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_array_end(
+ std::size_t,
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_key_part(
+ string_view,
+ std::size_t,
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_key(
+ string_view,
+ std::size_t,
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_string_part(
+ string_view,
+ std::size_t,
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_string(
+ string_view,
+ std::size_t,
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_number_part(
+ string_view,
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_int64(
+ int64_t,
+ string_view,
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_uint64(
+ uint64_t,
+ string_view,
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_double(
+ double,
+ string_view,
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_bool(
+ bool,
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_null(error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_comment_part(
+ string_view,
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+
+ bool
+ on_comment(
+ string_view,
+ error_code& ec)
+ {
+ return maybe_fail(ec);
+ }
+ };
+
+ basic_parser<handler> p_;
+
+public:
+ fail_parser()
+ : p_(parse_options())
+ {
+ }
+
+ explicit
+ fail_parser(
+ std::size_t n,
+ parse_options po = parse_options())
+ : p_(po)
+ {
+ p_.handler().n = n;
+ }
+
+ explicit
+ fail_parser(parse_options po)
+ : p_(po)
+ {
+ }
+
+ void
+ reset()
+ {
+ p_.reset();
+ }
+
+ bool
+ done() const noexcept
+ {
+ return p_.done();
+ }
+
+ std::size_t
+ write_some(
+ bool more,
+ char const* data,
+ std::size_t size,
+ error_code& ec)
+ {
+ return p_.write_some(
+ more, data, size, ec);
+ }
+
+ std::size_t
+ write(
+ bool more,
+ char const* data,
+ std::size_t size,
+ error_code& ec)
+ {
+ auto const n = p_.write_some(
+ more, data, size, ec);
+ if(! ec && n < size)
+ ec = error::extra_data;
+ return n;
+ }
+};
+
+//----------------------------------------------------------
+
+struct test_exception
+ : std::exception
+{
+ char const*
+ what() const noexcept
+ {
+ return "test exception";
+ }
+};
+
+// Exercises every exception path
+class throw_parser
+{
+ struct handler
+ {
+ constexpr static std::size_t max_object_size = std::size_t(-1);
+ constexpr static std::size_t max_array_size = std::size_t(-1);
+ constexpr static std::size_t max_key_size = std::size_t(-1);
+ constexpr static std::size_t max_string_size = std::size_t(-1);
+
+ std::size_t n;
+
+ handler()
+ : n(std::size_t(-1))
+ {
+ }
+
+ bool
+ maybe_throw()
+ {
+ if(n && --n > 0)
+ return true;
+ throw test_exception{};
+ }
+
+ bool
+ on_document_begin(
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_document_end(
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_object_begin(
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_object_end(
+ std::size_t,
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_array_begin(
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_array_end(
+ std::size_t,
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_key_part(
+ string_view,
+ std::size_t,
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_key(
+ string_view,
+ std::size_t,
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_string_part(
+ string_view,
+ std::size_t,
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_string(
+ string_view,
+ std::size_t,
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_number_part(
+ string_view,
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_int64(
+ int64_t,
+ string_view,
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_uint64(
+ uint64_t,
+ string_view,
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_double(
+ double,
+ string_view,
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_bool(
+ bool,
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_null(error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_comment_part(
+ string_view,
+ error_code&)
+ {
+ return maybe_throw();
+ }
+
+ bool
+ on_comment(
+ string_view,
+ error_code&)
+ {
+ return maybe_throw();
+ }
+ };
+
+ basic_parser<handler> p_;
+
+public:
+ throw_parser()
+ : p_(parse_options())
+ {
+ }
+
+ explicit
+ throw_parser(
+ std::size_t n,
+ parse_options po = parse_options())
+ : p_(po)
+ {
+ p_.handler().n = n;
+ }
+
+ explicit
+ throw_parser(parse_options po)
+ : p_(po)
+ {
+ }
+
+ void
+ reset() noexcept
+ {
+ p_.reset();
+ }
+
+ std::size_t
+ write(
+ bool more,
+ char const* data,
+ std::size_t size,
+ error_code& ec)
+ {
+ auto const n = p_.write_some(
+ more, data, size, ec);
+ if(! ec && n < size)
+ ec = error::extra_data;
+ return n;
+ }
+};
+
+//----------------------------------------------------------
+
+// wrap an iterator to make an input iterator
+template<class FwdIt>
+class input_iterator
+{
+ FwdIt it_;
+
+public:
+ using value_type = typename std::iterator_traits<FwdIt>::value_type;
+ using pointer = typename std::iterator_traits<FwdIt>::pointer;
+ using reference = typename std::iterator_traits<FwdIt>::reference;
+ using difference_type = typename std::iterator_traits<FwdIt>::difference_type;
+ using iterator_category = std::input_iterator_tag;
+
+ input_iterator() = default;
+ input_iterator(input_iterator const&) = default;
+ input_iterator& operator=(
+ input_iterator const&) = default;
+
+ input_iterator(FwdIt it)
+ : it_(it)
+ {
+ }
+
+ input_iterator&
+ operator++() noexcept
+ {
+ ++it_;
+ return *this;
+ }
+
+ input_iterator
+ operator++(int) noexcept
+ {
+ auto tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ pointer
+ operator->() const noexcept
+ {
+ return it_.operator->();
+ }
+
+ reference
+ operator*() const noexcept
+ {
+ return *it_;
+ }
+
+ bool
+ operator==(input_iterator other) const noexcept
+ {
+ return it_ == other.it_;
+ }
+
+ bool
+ operator!=(input_iterator other) const noexcept
+ {
+ return it_ != other.it_;
+ }
+};
+
+template<class FwdIt>
+input_iterator<FwdIt>
+make_input_iterator(FwdIt it)
+{
+ return input_iterator<FwdIt>(it);
+}
+
+//----------------------------------------------------------
+
+inline
+bool
+equal_storage(
+ value const& v,
+ storage_ptr const& sp);
+
+inline
+bool
+equal_storage(
+ object const& o,
+ storage_ptr const& sp)
+{
+ if(*o.storage() != *sp)
+ return false;
+ for(auto const& e : o)
+ if(! equal_storage(e.value(), sp))
+ return false;
+ return true;
+}
+
+inline
+bool
+equal_storage(
+ array const& a,
+ storage_ptr const& sp)
+{
+ if(*a.storage() != *sp)
+ return false;
+ for(auto const& v : a)
+ if(! equal_storage(v, sp))
+ return false;
+ return true;
+}
+
+bool
+equal_storage(
+ value const& v,
+ storage_ptr const& sp)
+{
+ switch(v.kind())
+ {
+ case json::kind::object:
+ if(*v.as_object().storage() != *sp)
+ return false;
+ return equal_storage(v.as_object(), sp);
+
+ case json::kind::array:
+ if(*v.as_array().storage() != *sp)
+ return false;
+ return equal_storage(v.as_array(), sp);
+
+ case json::kind::string:
+ return *v.as_string().storage() == *sp;
+
+ case json::kind::int64:
+ case json::kind::uint64:
+ case json::kind::double_:
+ case json::kind::bool_:
+ case json::kind::null:
+ break;
+ }
+
+ return *v.storage() == *sp;
+}
+
+inline
+void
+check_storage(
+ object const& o,
+ storage_ptr const& sp)
+{
+ BOOST_TEST(equal_storage(o, sp));
+}
+
+inline
+void
+check_storage(
+ array const& a,
+ storage_ptr const& sp)
+{
+ BOOST_TEST(equal_storage(a, sp));
+}
+
+inline
+void
+check_storage(
+ value const& v,
+ storage_ptr const& sp)
+{
+ BOOST_TEST(equal_storage(v, sp));
+}
+
+//----------------------------------------------------------
+
+namespace detail {
+
+inline
+void
+to_string_test(
+ string& dest,
+ json::value const& jv)
+{
+ switch(jv.kind())
+ {
+ case kind::object:
+ {
+ dest.push_back('{');
+ auto const& obj(
+ jv.get_object());
+ auto it = obj.begin();
+ if(it != obj.end())
+ {
+ goto obj_first;
+ while(it != obj.end())
+ {
+ dest.push_back(',');
+ obj_first:
+ dest.push_back('\"');
+ dest.append(it->key());
+ dest.push_back('\"');
+ dest.push_back(':');
+ to_string_test(
+ dest, it->value());
+ ++it;
+ }
+ }
+ dest.push_back('}');
+ break;
+ }
+
+ case kind::array:
+ {
+ dest.push_back('[');
+ auto const& arr(
+ jv.get_array());
+ auto it = arr.begin();
+ if(it != arr.end())
+ {
+ goto arr_first;
+ while(it != arr.end())
+ {
+ dest.push_back(',');
+ arr_first:
+ to_string_test(
+ dest, *it);
+ ++it;
+ }
+ }
+ dest.push_back(']');
+ break;
+ }
+
+ case kind::string:
+ #if 1
+ // safe, but doesn't handle escsapes
+ dest.push_back('\"');
+ dest.append(jv.get_string());
+ dest.push_back('\"');
+ #else
+ dest.append(serialize(jv));
+ #endif
+ break;
+
+ case kind::int64:
+ {
+ char buf[detail::max_number_chars];
+ auto const n =
+ detail::format_int64(
+ buf, jv.as_int64());
+ dest.append(string_view(buf).substr(0, n));
+ break;
+ }
+
+ case kind::uint64:
+ {
+ char buf[detail::max_number_chars];
+ auto const n =
+ detail::format_uint64(
+ buf, jv.as_uint64());
+ dest.append(string_view(buf).substr(0, n));
+ break;
+ }
+
+ case kind::double_:
+ {
+ char buf[detail::max_number_chars];
+ auto const n =
+ detail::format_double(
+ buf, jv.as_double());
+ dest.append(string_view(buf).substr(0, n));
+ break;
+ }
+
+ case kind::bool_:
+ if(jv.as_bool())
+ dest.append("true");
+ else
+ dest.append("false");
+ break;
+
+ case kind::null:
+ dest.append("null");
+ break;
+
+ default:
+ // should never get here
+ dest.append("?");
+ break;
+ }
+}
+
+} // detail
+
+inline
+string
+to_string_test(
+ json::value const& jv)
+{
+ string s;
+ s.reserve(1024);
+ detail::to_string_test(s, jv);
+ return s;
+}
+
+//----------------------------------------------------------
+
+inline
+bool
+equal(
+ value const& lhs,
+ value const& rhs)
+{
+ if(lhs.kind() != rhs.kind())
+ return false;
+ switch(lhs.kind())
+ {
+ case kind::object:
+ {
+ auto const& obj1 =
+ lhs.get_object();
+ auto const& obj2 =
+ rhs.get_object();
+ auto n = obj1.size();
+ if(obj2.size() != n)
+ return false;
+ auto it1 = obj1.begin();
+ auto it2 = obj2.begin();
+ while(n--)
+ {
+ if( it1->key() !=
+ it2->key())
+ return false;
+ if(! equal(
+ it1->value(),
+ it2->value()))
+ return false;
+ ++it1;
+ ++it2;
+ }
+ return true;
+ }
+
+ case kind::array:
+ {
+ auto const& arr1 =
+ lhs.get_array();
+ auto const& arr2 =
+ rhs.get_array();
+ auto n = arr1.size();
+ if(arr2.size() != n)
+ return false;
+ auto it1 = arr1.begin();
+ auto it2 = arr2.begin();
+ while(n--)
+ if(! equal(*it1++, *it2++))
+ return false;
+ return true;
+ }
+
+ case kind::string:
+ return
+ lhs.get_string() ==
+ rhs.get_string();
+
+ case kind::double_:
+ return
+ lhs.get_double() ==
+ rhs.get_double();
+
+ case kind::int64:
+ return
+ lhs.get_int64() ==
+ rhs.get_int64();
+
+ case kind::uint64:
+ return
+ lhs.get_uint64() ==
+ rhs.get_uint64();
+
+ case kind::bool_:
+ return
+ lhs.get_bool() ==
+ rhs.get_bool();
+
+ case kind::null:
+ return true;
+ }
+
+ return false;
+}
+
+template<typename T>
+inline
+bool
+check_hash_equal(
+ T const& lhs,
+ T const& rhs)
+{
+ if(lhs == rhs){
+ return (std::hash<T>{}(lhs) == std::hash<T>{}(rhs));
+ }
+ return false; // ensure lhs == rhs intention
+}
+
+template<typename T, typename U>
+inline
+bool
+check_hash_equal(
+ T const& lhs,
+ U const& rhs)
+{
+ if(lhs == rhs){
+ return (std::hash<value>{}(lhs) == std::hash<value>{}(rhs));
+ }
+ return false; // ensure lhs == rhs intention
+}
+
+template<typename T>
+inline
+bool
+expect_hash_not_equal(
+ T const& lhs,
+ T const& rhs)
+{
+ if(std::hash<T>{}(lhs) != std::hash<T>{}(rhs)){
+ return lhs != rhs;
+ }
+ return true; // pass if hash values collide
+}
+
+template<typename T, typename U>
+inline
+bool
+expect_hash_not_equal(
+ T const& lhs,
+ U const& rhs)
+{
+ if(std::hash<value>{}(lhs) != std::hash<value>{}(rhs)){
+ return lhs != rhs;
+ }
+ return true; // pass if hash values collide
+}
+//----------------------------------------------------------
+
+namespace detail {
+
+inline
+void
+check_array_impl(int, value const&)
+{
+}
+
+template<class Arg>
+void
+check_array_impl(
+ int i, value const& jv,
+ Arg const& arg)
+{
+ BOOST_TEST(equal(jv.at(i), arg));
+}
+
+template<
+ class Arg0,
+ class Arg1,
+ class... Argn>
+void
+check_array_impl(
+ int i, value const& jv,
+ Arg0 const& arg0,
+ Arg1 const& arg1,
+ Argn const&... argn)
+{
+ BOOST_TEST(equal(jv.at(i), arg0));
+ BOOST_TEST(equal(jv.at(i + 1), arg1));
+ check_array_impl(i + 2, jv, argn...);
+}
+
+} // detail
+
+template<class... Argn>
+static
+void
+check_array(
+ value const& jv,
+ Argn const&... argn)
+{
+ if(! BOOST_TEST(jv.is_array()))
+ return;
+ if(! BOOST_TEST(sizeof...(argn) ==
+ jv.get_array().size()))
+ return;
+ detail::check_array_impl(0, jv, argn...);
+}
+
+//----------------------------------------------------------
+
+BOOST_JSON_NS_END
+
+#endif
diff --git a/src/boost/libs/json/test/test_suite.hpp b/src/boost/libs/json/test/test_suite.hpp
new file mode 100644
index 000000000..990737430
--- /dev/null
+++ b/src/boost/libs/json/test/test_suite.hpp
@@ -0,0 +1,758 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+#ifndef TEST_SUITE_HPP
+#define TEST_SUITE_HPP
+
+#include <algorithm>
+#include <atomic>
+#include <chrono>
+#include <cstdlib>
+#include <cstring>
+#include <iomanip>
+#include <ios>
+#include <memory>
+#include <ostream>
+#include <sstream>
+#include <streambuf>
+#include <stdexcept>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#ifdef _MSC_VER
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <debugapi.h>
+#endif
+
+// This is a derivative work
+// Copyright 2002-2018 Peter Dimov
+// Copyright (c) 2002, 2009, 2014 Peter Dimov
+// Copyright (2) Beman Dawes 2010, 2011
+// Copyright (3) Ion Gaztanaga 2013
+//
+// Copyright 2018 Glen Joseph Fernandes
+// (glenjofe@gmail.com)
+
+namespace test_suite {
+
+//----------------------------------------------------------
+
+#ifdef _MSC_VER
+
+namespace detail {
+
+template<
+ class CharT, class Traits, class Allocator>
+class debug_streambuf
+ : public std::basic_stringbuf<
+ CharT, Traits, Allocator>
+{
+ using ostream =
+ std::basic_ostream<CharT, Traits>;
+
+ ostream& os_;
+ bool dbg_;
+
+ template<class T>
+ void write(T const*) = delete;
+
+ void write(char const* s)
+ {
+ if(dbg_)
+ ::OutputDebugStringA(s);
+ os_ << s;
+ }
+
+ void write(wchar_t const* s)
+ {
+ if(dbg_)
+ ::OutputDebugStringW(s);
+ os_ << s;
+ }
+
+public:
+ explicit
+ debug_streambuf(ostream& os)
+ : os_(os)
+ , dbg_(::IsDebuggerPresent() != 0)
+ {
+ }
+
+ ~debug_streambuf()
+ {
+ sync();
+ }
+
+ int
+ sync() override
+ {
+ write(this->str().c_str());
+ this->str("");
+ return 0;
+ }
+};
+
+/** std::ostream with Visual Studio IDE redirection.
+
+ Instances of this stream wrap a specified `std::ostream`
+ (such as `std::cout` or `std::cerr`). If the IDE debugger
+ is attached when the stream is created, output will be
+ additionally copied to the Visual Studio Output window.
+*/
+template<
+ class CharT,
+ class Traits = std::char_traits<CharT>,
+ class Allocator = std::allocator<CharT>
+>
+class basic_debug_stream
+ : public std::basic_ostream<CharT, Traits>
+{
+ detail::debug_streambuf<
+ CharT, Traits, Allocator> buf_;
+
+public:
+ /** Construct a stream.
+
+ @param os The output stream to wrap.
+ */
+ explicit
+ basic_debug_stream(std::ostream& os)
+ : std::basic_ostream<CharT, Traits>(&buf_)
+ , buf_(os)
+ {
+ if(os.flags() & std::ios::unitbuf)
+ std::unitbuf(*this);
+ }
+};
+
+} // detail
+
+using debug_stream = detail::basic_debug_stream<char>;
+using debug_wstream = detail::basic_debug_stream<wchar_t>;
+
+#else
+
+using debug_stream = std::ostream&;
+using debug_wstream = std::wostream&;
+
+#endif
+
+//----------------------------------------------------------
+
+namespace detail {
+
+struct suite_info
+{
+ char const* name;
+ void (*run)();
+};
+
+class runner;
+
+inline
+runner*&
+current() noexcept;
+
+inline
+void
+debug_break()
+{
+#ifdef _MSC_VER
+ ::DebugBreak();
+#else
+ //?? profit?
+#endif
+}
+
+//----------------------------------------------------------
+
+struct checkpoint
+{
+ char const* const file;
+ int const line;
+ std::size_t const id;
+
+ static
+ checkpoint*&
+ current() noexcept
+ {
+ static checkpoint* p = nullptr;
+ return p;
+ }
+
+ checkpoint(
+ char const* file_,
+ int line_,
+ std::size_t id_ = 0)
+ : file(file_)
+ , line(line_)
+ , id([]
+ {
+ static std::size_t n = 0;
+ return ++n;
+ }())
+ , prev_(current())
+ {
+ current() = this;
+ if(id_ == id)
+ debug_break();
+ }
+
+ ~checkpoint()
+ {
+ current() = prev_;
+ }
+
+private:
+ checkpoint* prev_;
+};
+
+//----------------------------------------------------------
+
+class runner
+{
+ runner* saved_;
+
+public:
+ runner() noexcept
+ : saved_(current())
+ {
+ current() = this;
+ }
+
+ virtual
+ ~runner()
+ {
+ current() = saved_;
+ }
+
+ virtual void on_begin(char const* name) = 0;
+ virtual void on_end() = 0;
+
+ virtual void note(char const* msg) = 0;
+ virtual void pass(char const* expr, char const* file, int line, char const* func) = 0;
+ virtual void fail(char const* expr, char const* file, int line, char const* func) = 0;
+
+ template<class Bool
+#if 0
+ ,class = typename std::enable_if<
+ std::is_convertible<bool, Bool>::Value>::type
+#endif
+ >
+ bool
+ maybe_fail(
+ Bool cond,
+ char const* expr,
+ char const* file,
+ int line,
+ char const* func)
+ {
+ if(!!cond)
+ {
+ pass(expr, file, line, func);
+ return true;
+ }
+ fail(expr, file, line, func);
+ return false;
+ }
+
+ void
+ run(suite_info const& si)
+ {
+ on_begin(si.name);
+ si.run();
+ on_end();
+ }
+};
+
+runner*&
+current() noexcept
+{
+ static runner* p = nullptr;
+ return p;
+}
+
+//----------------------------------------------------------
+
+using clock_type =
+ std::chrono::steady_clock;
+
+struct elapsed
+{
+ clock_type::duration d;
+};
+
+inline
+std::ostream&
+operator<<(
+ std::ostream& os,
+ elapsed const& e)
+{
+ using namespace std::chrono;
+ auto const ms = duration_cast<
+ milliseconds>(e.d);
+ if(ms < seconds{1})
+ {
+ os << ms.count() << "ms";
+ }
+ else
+ {
+ std::streamsize width{
+ os.width()};
+ std::streamsize precision{
+ os.precision()};
+ os << std::fixed <<
+ std::setprecision(1) <<
+ (ms.count() / 1000.0) << "s";
+ os.precision(precision);
+ os.width(width);
+ }
+ return os;
+}
+
+class simple_runner : public runner
+{
+ struct summary
+ {
+ char const* name;
+ clock_type::time_point start;
+ clock_type::duration elapsed;
+ std::atomic<std::size_t> failed;
+ std::atomic<std::size_t> total;
+
+ summary(summary const& other) noexcept
+ : name(other.name)
+ , start(other.start)
+ , elapsed(other.elapsed)
+ , failed(other.failed.load())
+ , total(other.total.load())
+ {
+ }
+
+ explicit
+ summary(char const* name_) noexcept
+ : name(name_)
+ , start(clock_type::now())
+ , failed(0)
+ , total(0)
+ {
+ }
+ };
+
+ summary all_;
+ std::ostream& log_;
+ std::vector<summary> v_;
+
+public:
+ explicit
+ simple_runner(
+ std::ostream& log)
+ : all_("(all)")
+ , log_(log)
+ {
+ std::unitbuf(log_);
+ v_.reserve(256);
+ }
+
+ ~simple_runner()
+ {
+ log_ <<
+ elapsed{clock_type::now() -
+ all_.start } << ", " <<
+ v_.size() << " suites, " <<
+ all_.failed.load() << " failures, " <<
+ all_.total.load() << " total." <<
+ std::endl;
+ }
+
+ // true if no failures
+ bool
+ success() const noexcept
+ {
+ return all_.failed.load() == 0;
+ }
+
+ void
+ on_begin(char const* name) override
+ {
+ v_.emplace_back(name);
+ log_ << name << "\n";
+ }
+
+ void
+ on_end() override
+ {
+ v_.back().elapsed =
+ clock_type::now() -
+ v_.back().start;
+ }
+
+ void
+ note(char const* msg) override
+ {
+ log_ << msg << "\n";
+ }
+
+ char const*
+ filename(
+ char const* file)
+ {
+ auto const p0 = file;
+ auto p = p0 + std::strlen(file);
+ while(p-- != p0)
+ {
+ #ifdef _MSC_VER
+ if(*p == '\\')
+ #else
+ if(*p == '/')
+ #endif
+ break;
+ }
+ return p + 1;
+ }
+
+ void
+ pass(
+ char const*,
+ char const*,
+ int,
+ char const*) override
+ {
+ ++all_.total;
+ ++v_.back().total;
+ }
+
+ void
+ fail(
+ char const* expr,
+ char const* file,
+ int line,
+ char const*) override
+ {
+ ++all_.failed;
+ ++v_.back().total;
+ ++v_.back().failed;
+ auto const id = ++all_.total;
+ auto const cp =
+ checkpoint::current();
+ if(cp)
+ log_ <<
+ "case " << cp->id <<
+ "(#" << id << ") " <<
+ filename(cp->file) <<
+ "(" << cp->line << ") "
+ "failed: " << expr << "\n";
+ else
+ log_ <<
+ "#" << id <<
+ " " << filename(file) <<
+ "(" << line << ") "
+ "failed: " << expr << "\n";
+ }
+};
+
+//----------------------------------------------------------
+
+template<
+ class CharT,
+ class Traits = std::char_traits<CharT>,
+ class Allocator = std::allocator<CharT>
+>
+class log_ostream
+ : public std::basic_ostream<CharT, Traits>
+{
+ struct buffer_type :
+ std::basic_stringbuf<
+ CharT, Traits, Allocator>
+ {
+ ~buffer_type()
+ {
+ sync();
+ }
+
+ int
+ sync() override
+ {
+ auto const& s = this->str();
+ if(s.size() > 0)
+ current()->note(s.c_str());
+ this->str("");
+ return 0;
+ }
+ };
+
+ buffer_type buf_;
+
+public:
+ log_ostream()
+ : std::basic_ostream<
+ CharT, Traits>(&buf_)
+ {
+ }
+};
+
+//----------------------------------------------------------
+
+class suite_list
+{
+ static std::size_t const max_size_ = 256;
+ std::size_t count_ = 0;
+ suite_info data_[max_size_];
+
+public:
+ void
+ insert(suite_info inf)
+ {
+ #ifndef BOOST_NO_EXCEPTIONS
+ if(count_ == max_size_)
+ throw std::length_error(
+ "too many test suites");
+ #endif
+ data_[count_++] = inf;
+ }
+
+ suite_info const*
+ begin() const noexcept
+ {
+ return data_;
+ }
+
+ suite_info const*
+ end() const noexcept
+ {
+ return begin() + count_;
+ }
+
+ void
+ sort()
+ {
+ std::sort(
+ data_,
+ data_ + count_,
+ []( detail::suite_info const& lhs,
+ detail::suite_info const& rhs)
+ {
+ return std::lexicographical_compare(
+ lhs.name, lhs.name + std::strlen(lhs.name),
+ rhs.name, rhs.name + std::strlen(rhs.name));
+ });
+ }
+};
+
+inline
+suite_list&
+suites()
+{
+ static suite_list list;
+ return list;
+}
+
+//----------------------------------------------------------
+
+template<class T>
+struct instance
+{
+ explicit
+ instance(
+ char const* name) noexcept
+ {
+ suites().insert(suite_info{
+ name, &instance::run });
+ }
+
+ static
+ void
+ run()
+ {
+ auto const saved =
+ current();
+ //current()->os_
+ T().run();
+ current() = saved;
+ }
+};
+
+//----------------------------------------------------------
+
+inline
+void
+current_function_helper()
+{
+#if defined(__GNUC__) || \
+ (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || \
+ (defined(__ICC) && (__ICC >= 600)) || \
+ defined(__ghs__) || \
+ defined(__clang__)
+# define TEST_SUITE_FUNCTION __PRETTY_FUNCTION__
+
+#elif defined(__DMC__) && (__DMC__ >= 0x810)
+# define TEST_SUITE_FUNCTION __PRETTY_FUNCTION__
+
+#elif defined(__FUNCSIG__)
+# define TEST_SUITE_FUNCTION __FUNCSIG__
+
+#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || \
+ (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
+# define TEST_SUITE_FUNCTION __FUNCTION__
+
+#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
+# define TEST_SUITE_FUNCTION __FUNC__
+
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
+# define TEST_SUITE_FUNCTION __func__
+
+#elif defined(__cplusplus) && (__cplusplus >= 201103)
+# define TEST_SUITE_FUNCTION __func__
+
+#else
+# define TEST_SUITE_FUNCTION "(unknown)"
+
+#endif
+}
+
+} // detail
+
+//----------------------------------------------------------
+
+/** The type of log for output to the currently running suite.
+*/
+using log_type = detail::log_ostream<char>;
+
+#define BOOST_TEST_CHECKPOINT(...) \
+ ::test_suite::detail::checkpoint \
+ _BOOST_TEST_CHECKPOINT ## __LINE__ ( \
+ __FILE__, __LINE__, __VA_ARGS__ + 0)
+
+#define BOOST_TEST(expr) \
+ ::test_suite::detail::current()->maybe_fail( \
+ (expr), #expr, __FILE__, __LINE__, TEST_SUITE_FUNCTION)
+
+#define BOOST_ERROR(msg) \
+ ::test_suite::detail::current()->fail( \
+ msg, __FILE__, __LINE__, TEST_SUITE_FUNCTION)
+
+#define BOOST_TEST_PASS() \
+ ::test_suite::detail::current()->pass( \
+ "", __FILE__, __LINE__, TEST_SUITE_FUNCTION)
+
+#define BOOST_TEST_FAIL() \
+ ::test_suite::detail::current()->fail( \
+ "", __FILE__, __LINE__, TEST_SUITE_FUNCTION)
+
+#define BOOST_TEST_NOT(expr) BOOST_TEST(!(expr))
+
+#ifndef BOOST_NO_EXCEPTIONS
+# define BOOST_TEST_THROWS( expr, except ) \
+ try { \
+ (void)(expr); \
+ ::test_suite::detail::current()->fail ( \
+ #except, __FILE__, __LINE__, \
+ TEST_SUITE_FUNCTION); \
+ } \
+ catch(except const&) { \
+ ::test_suite::detail::current()->pass( \
+ #except, __FILE__, __LINE__, \
+ TEST_SUITE_FUNCTION); \
+ } \
+ catch(...) { \
+ ::test_suite::detail::current()->fail( \
+ #except, __FILE__, __LINE__, \
+ TEST_SUITE_FUNCTION); \
+ }
+
+# define BOOST_TEST_THROWS_WITH_LOCATION( expr ) \
+ try \
+ { \
+ expr; \
+ ::test_suite::detail::current()->fail( \
+ "system_error", __FILE__, __LINE__, \
+ TEST_SUITE_FUNCTION); \
+ } \
+ catch (::boost::json::system_error const& exc) \
+ { \
+ ::test_suite::detail::current()->maybe_fail( \
+ exc.code().has_location(), "has_location()", __FILE__, __LINE__, \
+ TEST_SUITE_FUNCTION); \
+ } \
+ catch(...) { \
+ ::test_suite::detail::current()->fail( \
+ "system_error", __FILE__, __LINE__, \
+ TEST_SUITE_FUNCTION); \
+ }
+
+#else
+ #define BOOST_TEST_THROWS( expr, except )
+ #define BOOST_TEST_THROWS_WITH_LOCATION(expr)
+#endif
+
+#define TEST_SUITE(type, name) \
+ static ::test_suite::detail::instance<type> type##_(name)
+
+inline
+int
+run(std::ostream& log,
+ int argc, char const* const* argv)
+{
+ if(argc == 2)
+ {
+ std::string arg(argv[1]);
+ if(arg == "-h" || arg == "--help")
+ {
+ log <<
+ "Usage:\n"
+ " " << argv[0] << ": { <suite-name>... }" <<
+ std::endl;
+ return EXIT_SUCCESS;
+ }
+ }
+
+ using namespace ::test_suite;
+
+ detail::simple_runner runner(log);
+ detail::suites().sort();
+ if(argc == 1)
+ {
+ for(auto const& e : detail::suites())
+ runner.run(e);
+ }
+ else
+ {
+ std::vector<std::string> args;
+ args.reserve(argc - 1);
+ for(int i = 0; i < argc - 1; ++i)
+ args.push_back(argv[i + 1]);
+ for(auto const& e : detail::suites())
+ {
+ std::string s(e.name);
+ if(std::find_if(
+ args.begin(), args.end(),
+ [&](std::string const& arg)
+ {
+ if(arg.size() > s.size())
+ return false;
+ return s.compare(
+ s.size() - arg.size(),
+ arg.size(),
+ arg.data(),
+ arg.size()) == 0;
+ }) != args.end())
+ {
+ runner.run(e);
+ }
+ }
+ }
+ return runner.success() ?
+ EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+} // test_suite
+
+#endif
diff --git a/src/boost/libs/json/test/value.cpp b/src/boost/libs/json/test/value.cpp
new file mode 100644
index 000000000..52684fe25
--- /dev/null
+++ b/src/boost/libs/json/test/value.cpp
@@ -0,0 +1,2186 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/value.hpp>
+
+#include <boost/json/monotonic_resource.hpp>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "test.hpp"
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+BOOST_STATIC_ASSERT( std::is_nothrow_destructible<value>::value );
+BOOST_STATIC_ASSERT( std::is_nothrow_move_constructible<value>::value );
+
+namespace {
+
+template<class T>
+static
+T max_of()
+{
+ return (std::numeric_limits<T>::max)();
+}
+
+template<class T>
+static
+T min_of()
+{
+ return (std::numeric_limits<T>::min)();
+}
+
+} // (anon)
+
+class value_test
+{
+public:
+ //BOOST_STATIC_ASSERT(has_value_from<short>::value);
+
+ string_view const str_;
+
+ value_test()
+ : str_(
+ "abcdefghijklmnopqrstuvwxyz")
+ {
+ // ensure this string does
+ // not fit in the SBO area.
+ BOOST_ASSERT(str_.size() >
+ string().capacity());
+ }
+
+ //------------------------------------------------------
+
+ void
+ testSpecial()
+ {
+ auto dsp = storage_ptr{};
+ auto sp = make_shared_resource<unique_resource>();
+
+ // ~value()
+ {
+ value(object{});
+ value(array{});
+ value(string{});
+ value(std::int64_t(0));
+ value(std::uint64_t(0));
+ value(double(0));
+ value(true);
+ value(nullptr);
+ }
+
+ // value()
+ {
+ value jv;
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+
+ // value(storage_ptr)
+ {
+ value jv(sp);
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+
+ // value(pilfered<value>)
+ {
+ {
+ value jv1(object{});
+ value jv2(pilfer(jv1));
+ BOOST_TEST(jv2.is_object());
+ }
+ {
+ value jv1(array{});
+ value jv2(pilfer(jv1));
+ BOOST_TEST(jv2.is_array());
+ }
+ {
+ value jv1(string{});
+ value jv2(pilfer(jv1));
+ BOOST_TEST(jv2.is_string());
+ }
+ {
+ value jv1(std::int64_t{});
+ value jv2(pilfer(jv1));
+ BOOST_TEST(jv2.is_int64());
+ }
+ {
+ value jv1(std::uint64_t{});
+ value jv2(pilfer(jv1));
+ BOOST_TEST(jv2.is_uint64());
+ }
+ {
+ value jv1(double{});
+ value jv2(pilfer(jv1));
+ BOOST_TEST(jv2.is_double());
+ }
+ {
+ value jv1(true);
+ value jv2(pilfer(jv1));
+ BOOST_TEST(jv2.is_bool());
+ }
+ {
+ value jv1(nullptr);
+ value jv2(pilfer(jv1));
+ BOOST_TEST(jv2.is_null());
+ }
+
+ // ensure pilfered-from objects
+ // are trivially destructible
+ {
+ value v1(make_shared_resource<
+ monotonic_resource>());
+ value v2(pilfer(v1));
+ BOOST_TEST(v1.storage().get() ==
+ storage_ptr().get());
+ }
+ }
+
+ // value(value const&)
+ {
+ {
+ value jv1(object{});
+ value jv2(jv1);
+ BOOST_TEST(jv2.is_object());
+ }
+ {
+ value jv1(array{});
+ value jv2(jv1);
+ BOOST_TEST(jv2.is_array());
+ }
+ {
+ value jv1(string{});
+ value jv2(jv1);
+ BOOST_TEST(jv2.is_string());
+ }
+ {
+ value jv1(std::int64_t{});
+ value jv2(jv1);
+ BOOST_TEST(jv2.is_int64());
+ }
+ {
+ value jv1(std::uint64_t{});
+ value jv2(jv1);
+ BOOST_TEST(jv2.is_uint64());
+ }
+ {
+ value jv1(double{});
+ value jv2(jv1);
+ BOOST_TEST(jv2.is_double());
+ }
+ {
+ value jv1(true);
+ value jv2(jv1);
+ BOOST_TEST(jv2.is_bool());
+ }
+ {
+ value jv1(nullptr);
+ value jv2(jv1);
+ BOOST_TEST(jv2.is_null());
+ }
+ }
+
+ // value(value const&, storage_ptr)
+ {
+ {
+ value jv1(object{});
+ value jv2(jv1, sp);
+ BOOST_TEST(jv2.is_object());
+ BOOST_TEST(*jv2.storage() == *sp);
+ }
+ {
+ value jv1(array{});
+ value jv2(jv1, sp);
+ BOOST_TEST(jv2.is_array());
+ BOOST_TEST(*jv2.storage() == *sp);
+ }
+ {
+ value jv1(string{});
+ value jv2(jv1, sp);
+ BOOST_TEST(jv2.is_string());
+ BOOST_TEST(*jv2.storage() == *sp);
+ }
+ {
+ value jv1(std::int64_t{});
+ value jv2(jv1, sp);
+ BOOST_TEST(jv2.is_int64());
+ BOOST_TEST(*jv2.storage() == *sp);
+ }
+ {
+ value jv1(std::uint64_t{});
+ value jv2(jv1, sp);
+ BOOST_TEST(jv2.is_uint64());
+ BOOST_TEST(*jv2.storage() == *sp);
+ }
+ {
+ value jv1(double{});
+ value jv2(jv1, sp);
+ BOOST_TEST(jv2.is_double());
+ BOOST_TEST(*jv2.storage() == *sp);
+ }
+ {
+ value jv1(true);
+ value jv2(jv1, sp);
+ BOOST_TEST(jv2.is_bool());
+ BOOST_TEST(*jv2.storage() == *sp);
+ }
+ {
+ value jv1(nullptr);
+ value jv2(jv1, sp);
+ BOOST_TEST(jv2.is_null());
+ BOOST_TEST(*jv2.storage() == *sp);
+ }
+ }
+
+ // value(value&&)
+ {
+ {
+ value jv1(object{});
+ value jv2(std::move(jv1));
+ BOOST_TEST(jv2.is_object());
+ }
+ {
+ value jv1(array{});
+ value jv2(std::move(jv1));
+ BOOST_TEST(jv2.is_array());
+ }
+ {
+ value jv1(string{});
+ value jv2(std::move(jv1));
+ BOOST_TEST(jv2.is_string());
+ }
+ {
+ value jv1(std::int64_t{});
+ value jv2(std::move(jv1));
+ BOOST_TEST(jv2.is_int64());
+ }
+ {
+ value jv1(std::uint64_t{});
+ value jv2(std::move(jv1));
+ BOOST_TEST(jv2.is_uint64());
+ }
+ {
+ value jv1(double{});
+ value jv2(std::move(jv1));
+ BOOST_TEST(jv2.is_double());
+ }
+ {
+ value jv1(true);
+ value jv2(std::move(jv1));
+ BOOST_TEST(jv2.is_bool());
+ }
+ {
+ value jv1(nullptr);
+ value jv2(std::move(jv1));
+ BOOST_TEST(jv2.is_null());
+ }
+ }
+
+ // value(value&&, storage_ptr)
+ {
+ {
+ value jv1(object{});
+ value jv2(std::move(jv1), sp);
+ BOOST_TEST(jv2.is_object());
+ }
+ {
+ value jv1(array{});
+ value jv2(std::move(jv1), sp);
+ BOOST_TEST(jv2.is_array());
+ }
+ {
+ value jv1(string{});
+ value jv2(std::move(jv1), sp);
+ BOOST_TEST(jv2.is_string());
+ }
+ {
+ value jv1(std::int64_t{});
+ value jv2(std::move(jv1), sp);
+ BOOST_TEST(jv2.is_int64());
+ }
+ {
+ value jv1(std::uint64_t{});
+ value jv2(std::move(jv1), sp);
+ BOOST_TEST(jv2.is_uint64());
+ }
+ {
+ value jv1(double{});
+ value jv2(std::move(jv1), sp);
+ BOOST_TEST(jv2.is_double());
+ }
+ {
+ value jv1(true);
+ value jv2(std::move(jv1), sp);
+ BOOST_TEST(jv2.is_bool());
+ }
+ {
+ value jv1(nullptr);
+ value jv2(std::move(jv1), sp);
+ BOOST_TEST(jv2.is_null());
+ }
+ }
+ }
+
+ void
+ testConversion()
+ {
+ auto dsp = storage_ptr{};
+ auto sp = make_shared_resource<unique_resource>();
+
+ // value(object)
+ // value(object, storage_ptr)
+ // value(object_kind, storage_ptr)
+ {
+ {
+ auto jv = value(object());
+ BOOST_TEST(jv.is_object());
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+ {
+ auto jv = value(object(sp));
+ BOOST_TEST(jv.is_object());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ {
+ auto jv = value(object(), sp);
+ BOOST_TEST(jv.is_object());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ {
+ auto jv = value(object_kind);
+ BOOST_TEST(jv.is_object());
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+ {
+ auto jv = value(object_kind, sp);
+ BOOST_TEST(jv.is_object());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ {
+ // verify moved from
+ object obj{{"a", 1}, {"b", 2}};
+ BOOST_TEST(obj.capacity() > 0);
+ value jv(std::move(obj), {});
+ BOOST_TEST(obj.capacity() == 0);
+ }
+ }
+
+ // value(array)
+ // value(array, storage_ptr)
+ // value(object_kind, storage_ptr)
+ {
+ {
+ auto jv = value(array());
+ BOOST_TEST(jv.is_array());
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+ {
+ auto jv = value(array(sp));
+ BOOST_TEST(jv.is_array());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ {
+ auto jv = value(array(), sp);
+ BOOST_TEST(jv.is_array());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ {
+ auto jv = value(array_kind);
+ BOOST_TEST(jv.is_array());
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+ {
+ auto jv = value(array_kind, sp);
+ BOOST_TEST(jv.is_array());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ }
+
+ // value(string)
+ // value(string, storage_ptr)
+ {
+ {
+ auto jv = value(string());
+ BOOST_TEST(jv.is_string());
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+ {
+ auto jv = value(string(sp));
+ BOOST_TEST(jv.is_string());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ {
+ auto jv = value(string(), sp);
+ BOOST_TEST(jv.is_string());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ }
+
+ // value(int64)
+ // value(int64, storage_ptr)
+ {
+ {
+ auto jv = value(std::int64_t{-65536});
+ BOOST_TEST(jv.is_int64());
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+ {
+ auto jv = value(std::int64_t{-65536}, sp);
+ BOOST_TEST(jv.is_int64());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ }
+
+ // value(uint64)
+ // value(uint64, storage_ptr)
+ {
+ {
+ auto jv = value(std::uint64_t{65536});
+ BOOST_TEST(jv.is_uint64());
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+ {
+ auto jv = value(std::uint64_t{65536}, sp);
+ BOOST_TEST(jv.is_uint64());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ }
+
+ // value(double)
+ // value(double, storage_ptr)
+ {
+ {
+ auto jv = value(double{3.141});
+ BOOST_TEST(jv.is_double());
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+ {
+ auto jv = value(double{3.141}, sp);
+ BOOST_TEST(jv.is_double());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ }
+
+ // value(bool)
+ // value(bool, storage_ptr)
+ {
+ {
+ auto jv = value(true);
+ BOOST_TEST(jv.is_bool());
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+ {
+ auto jv = value(true, sp);
+ BOOST_TEST(jv.is_bool());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ }
+
+ // value(nullptr_t)
+ // value(nullptr_t, storage_ptr)
+ {
+ {
+ auto jv = value(nullptr);
+ BOOST_TEST(jv.is_null());
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+ {
+ auto jv = value(nullptr, sp);
+ BOOST_TEST(jv.is_null());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ }
+
+ // value(initializer_list)
+ // value(initializer_list, storage_ptr)
+ {
+ {
+ value jv({1, 2, 3});
+ BOOST_TEST(jv.is_array());
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+ {
+ value jv({1, 2, 3}, sp);
+ BOOST_TEST(jv.is_array());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ {
+ value jv({{"a",1},{"b",2},{"c",3}});
+ BOOST_TEST(jv.is_object());
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+ {
+ value jv({{"a",1},{"b",2},{"c",3}}, sp);
+ BOOST_TEST(jv.is_object());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ }
+ }
+
+ void
+ testAssignment()
+ {
+ auto dsp = storage_ptr{};
+ auto sp = make_shared_resource<unique_resource>();
+
+ // operator=(value const&)
+ {
+ {
+ value jv1(object{});
+ value jv2;
+ jv2 = jv1;
+ BOOST_TEST(jv2.is_object());
+ }
+ {
+ value jv1(array{});
+ value jv2;
+ jv2 = jv1;
+ BOOST_TEST(jv2.is_array());
+ }
+ {
+ value jv1(string{});
+ value jv2;
+ jv2 = jv1;
+ BOOST_TEST(jv2.is_string());
+ }
+ {
+ value jv1(std::int64_t{});
+ value jv2;
+ jv2 = jv1;
+ BOOST_TEST(jv2.is_int64());
+ }
+ {
+ value jv1(std::uint64_t{});
+ value jv2;
+ jv2 = jv1;
+ BOOST_TEST(jv2.is_uint64());
+ }
+ {
+ value jv1(double{});
+ value jv2;
+ jv2 = jv1;
+ BOOST_TEST(jv2.is_double());
+ }
+ {
+ value jv1(true);
+ value jv2;
+ jv2 = jv1;
+ BOOST_TEST(jv2.is_bool());
+ }
+ {
+ value jv1(nullptr);
+ value jv2;
+ jv2 = jv1;
+ BOOST_TEST(jv2.is_null());
+ }
+
+ fail_loop([&](storage_ptr const sp)
+ {
+ value jv1({1, 2, 3, 4, 5});
+ value jv2(sp);
+ jv2 = jv1;
+ BOOST_TEST(jv2.as_array().size() == 5);
+ });
+
+ fail_loop([&](storage_ptr const sp)
+ {
+ value jv1({
+ {"a",1},{"b",2},{"c",3}});
+ value jv2(sp);
+ jv2 = jv1;
+ BOOST_TEST(jv2.as_object().size() == 3);
+ });
+
+ fail_loop([&](storage_ptr const sp)
+ {
+ value jv1(str_);
+ value jv2(sp);
+ jv2 = jv1;
+ BOOST_TEST(jv2.as_string() == str_);
+ });
+
+ // self-assign
+ {
+ value jv = { 1, 2, 3 };
+ jv = static_cast<value const&>(jv);
+ BOOST_TEST(jv == value({1, 2, 3}));
+ }
+
+ // copy from child
+ {
+ value jv = { 1, 2, 3 };
+ jv = jv.at(1);
+ BOOST_TEST(
+ *jv.if_int64() == 2);
+ }
+ }
+
+ // operator=(value&&)
+ {
+ {
+ value jv;
+ jv = value(object{});
+ BOOST_TEST(jv.is_object());
+ }
+ {
+ value jv;
+ jv = value(array{});
+ BOOST_TEST(jv.is_array());
+ }
+ {
+ value jv;
+ jv = value(string{});
+ BOOST_TEST(jv.is_string());
+ }
+ {
+ value jv;
+ jv = value(std::int64_t{});
+ BOOST_TEST(jv.is_int64());
+ }
+ {
+ value jv;
+ jv = value(std::uint64_t{});
+ BOOST_TEST(jv.is_uint64());
+ }
+ {
+ value jv;
+ jv = value(double{});
+ BOOST_TEST(jv.is_double());
+ }
+ {
+ value jv;
+ jv = value(true);
+ BOOST_TEST(jv.is_bool());
+ }
+ {
+ value jv;
+ jv = value(nullptr);
+ BOOST_TEST(jv.is_null());
+ }
+
+ fail_loop([&](storage_ptr const sp)
+ {
+ value jv(sp);
+ jv = value({
+ { {"a",1}, {"b",2u} },
+ { 1, 2 },
+ "hello",
+ 1,
+ 2u,
+ 3.,
+ true,
+ nullptr
+ });
+ BOOST_TEST(jv.as_array().size() == 8);
+ });
+
+ fail_loop([&](storage_ptr const sp)
+ {
+ value jv(sp);
+ jv = value({
+ { "aa", { {"a",1}, {"b",2u} } },
+ { "bb", { 1, 2 } },
+ { "cc", "hello" },
+ { "dd", 1 },
+ { "ee", 2u },
+ { "ff", 3. },
+ { "gg", true },
+ { "hh", nullptr },
+ });
+ BOOST_TEST(jv.as_object().size() == 8);
+ });
+
+ fail_loop([&](storage_ptr const sp)
+ {
+ value jv(sp);
+ jv = value(str_);
+ BOOST_TEST(jv.as_string() == str_);
+ });
+
+ // self-move
+ {
+ value jv = { 1, 2, 3 };
+ value* p = &jv;
+ jv = std::move(*p);
+ BOOST_TEST(jv == value({1, 2, 3}));
+ }
+
+ // move from child
+ {
+ value jv = { 1, 2, 3 };
+ jv = std::move(jv.at(1));
+ BOOST_TEST(
+ *jv.if_int64() == 2);
+ }
+ }
+
+ // operator=(initializer_list)
+ {
+ value jv;
+ jv = {1, 2, 3};
+ BOOST_TEST(jv.is_array());
+ BOOST_TEST(*jv.storage() == *dsp);
+ BOOST_TEST(jv.at(0).as_int64() == 1);
+ BOOST_TEST(jv.at(1).as_int64() == 2);
+ BOOST_TEST(jv.at(2).as_int64() == 3);
+ }
+
+ // operator=(nullptr_t)
+ {
+ {
+ value jv = 1;
+ BOOST_TEST(! jv.is_null());
+ jv = nullptr;
+ BOOST_TEST(jv.is_null());
+ }
+ {
+ value jv = "string";
+ BOOST_TEST(! jv.is_null());
+ jv = nullptr;
+ BOOST_TEST(jv.is_null());
+ }
+ }
+
+ // operator=(bool)
+ {
+ {
+ value jv = 1;
+ BOOST_TEST(! jv.is_bool());
+ jv = true;
+ BOOST_TEST(jv.is_bool());
+ }
+ {
+ value jv = "string";
+ BOOST_TEST(! jv.is_bool());
+ jv = true;
+ BOOST_TEST(jv.is_bool());
+ }
+ }
+
+ // operator=(int64)
+ {
+ {
+ value jv = false;
+ BOOST_TEST(! jv.is_int64());
+ jv = std::int64_t{-65536};
+ BOOST_TEST(jv.is_int64());
+ }
+ {
+ value jv = "string";
+ BOOST_TEST(! jv.is_int64());
+ jv = std::int64_t{-65536};
+ BOOST_TEST(jv.is_int64());
+ }
+ }
+
+ // operator=(uint64)
+ {
+ {
+ value jv = false;
+ BOOST_TEST(! jv.is_uint64());
+ jv = std::uint64_t{65536};
+ BOOST_TEST(jv.is_uint64());
+ }
+ {
+ value jv = "string";
+ BOOST_TEST(! jv.is_uint64());
+ jv = std::uint64_t{65536};
+ BOOST_TEST(jv.is_uint64());
+ }
+ }
+
+ // operator=(double)
+ {
+ {
+ value jv = false;
+ BOOST_TEST(! jv.is_double());
+ jv = double{3.141};
+ BOOST_TEST(jv.is_double());
+ }
+ {
+ value jv = "string";
+ BOOST_TEST(! jv.is_double());
+ jv = double{3.141};
+ BOOST_TEST(jv.is_double());
+ }
+ }
+
+ // operator=(string)
+ {
+ {
+ value jv;
+ jv = string();
+ BOOST_TEST(jv.is_string());
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+ {
+ value jv(sp);
+ jv = string();
+ BOOST_TEST(jv.is_string());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ }
+
+ // operator=(array)
+ {
+ {
+ value jv;
+ jv = array();
+ BOOST_TEST(jv.is_array());
+ BOOST_TEST(*jv.storage() == *dsp);
+ }
+ {
+ value jv(sp);
+ jv = array();
+ BOOST_TEST(jv.is_array());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ }
+
+ // operator=(object)
+ {
+ {
+ value jv;
+ jv = object();
+ BOOST_TEST(*jv.storage() == *dsp);
+ BOOST_TEST(jv.is_object());
+ }
+ {
+ value jv(sp);
+ jv = object();
+ BOOST_TEST(jv.is_object());
+ BOOST_TEST(*jv.storage() == *sp);
+ }
+ }
+ }
+
+ void
+ testModifiers()
+ {
+ // emplace
+ {
+ BOOST_TEST(value().emplace_object().empty());
+ BOOST_TEST(value().emplace_array().empty());
+ BOOST_TEST(value().emplace_string().empty());
+ BOOST_TEST(value().emplace_int64() == 0);
+ BOOST_TEST(value().emplace_uint64() == 0);
+ BOOST_TEST(value().emplace_double() == 0);
+ BOOST_TEST(value().emplace_bool() = true);
+ {
+ value jv(object_kind);
+ jv.emplace_null();
+ BOOST_TEST(jv.is_null());
+ }
+ {
+ value jv(array_kind);
+ jv.emplace_null();
+ BOOST_TEST(jv.is_null());
+ }
+ {
+ value jv(string_kind);
+ jv.emplace_null();
+ BOOST_TEST(jv.is_null());
+ }
+ {
+ value jv(-1);
+ jv.emplace_null();
+ BOOST_TEST(jv.is_null());
+ }
+ {
+ value jv(1U);
+ jv.emplace_null();
+ BOOST_TEST(jv.is_null());
+ }
+ {
+ value jv(1.0);
+ jv.emplace_null();
+ BOOST_TEST(jv.is_null());
+ }
+ {
+ value jv(false);
+ jv.emplace_null();
+ BOOST_TEST(jv.is_null());
+ }
+ {
+ value jv;
+ jv.emplace_null();
+ BOOST_TEST(jv.is_null());
+ }
+ }
+
+ // swap
+ {
+ {
+ // self-swap
+ value jv;
+ swap(jv, jv);
+ }
+ {
+ value jv1(1);
+ value jv2("abc");
+ BOOST_TEST(
+ *jv1.storage() == *jv2.storage());
+ swap(jv1, jv2);
+ BOOST_TEST(jv1.as_string() == "abc");
+ BOOST_TEST(jv2.as_int64() == 1);
+ }
+
+ // different storage
+ fail_loop([&](storage_ptr const& sp)
+ {
+ value jv1(1);
+ value jv2("abc", sp);
+ BOOST_TEST(
+ *jv1.storage() != *jv2.storage());
+ swap(jv1, jv2);
+ BOOST_TEST(jv1.as_string() == "abc");
+ BOOST_TEST(jv2.as_int64() == 1);
+ });
+ }
+ }
+
+ template<typename T>
+ using tt = T;
+
+ void
+ testExchange()
+ {
+ // string{}
+ {
+ BOOST_TEST(value("abc").is_string());
+ BOOST_TEST(value(std::string()).is_string());
+ BOOST_TEST(value(string_view()).is_string());
+
+ { value jv; BOOST_TEST((jv = "abc").is_string()); }
+ { value jv; BOOST_TEST((jv = std::string()).is_string()); }
+ { value jv; BOOST_TEST((jv = string_view()).is_string()); }
+ }
+
+ // numbers
+ {
+ BOOST_TEST(value(tt<signed char>{}).is_int64());
+ BOOST_TEST(value(tt<short>{}).is_int64());
+ BOOST_TEST(value(tt<int>{}).is_int64());
+ BOOST_TEST(value(tt<long>{}).is_int64());
+ BOOST_TEST(value(tt<long long>{}).is_int64());
+ BOOST_TEST(value(tt<unsigned char>{}).is_uint64());
+ BOOST_TEST(value(tt<unsigned short>{}).is_uint64());
+ BOOST_TEST(value(tt<unsigned int>{}).is_uint64());
+ BOOST_TEST(value(tt<unsigned long>{}).is_uint64());
+ BOOST_TEST(value(tt<unsigned long long>{}).is_uint64());
+ BOOST_TEST(value(tt<float>{}).is_double());
+ BOOST_TEST(value(tt<double>{}).is_double());
+
+ { value jv; BOOST_TEST((jv = tt<signed char>{}).is_int64()); }
+ { value jv; BOOST_TEST((jv = tt<short>{}).is_int64()); }
+ { value jv; BOOST_TEST((jv = tt<int>{}).is_int64()); }
+ { value jv; BOOST_TEST((jv = tt<long>{}).is_int64()); }
+ { value jv; BOOST_TEST((jv = tt<long long>{}).is_int64()); }
+ { value jv; BOOST_TEST((jv = tt<unsigned char>{}).is_uint64()); }
+ { value jv; BOOST_TEST((jv = tt<unsigned short>{}).is_uint64()); }
+ { value jv; BOOST_TEST((jv = tt<unsigned int>{}).is_uint64()); }
+ { value jv; BOOST_TEST((jv = tt<unsigned long>{}).is_uint64()); }
+ { value jv; BOOST_TEST((jv = tt<unsigned long long>{}).is_uint64()); }
+ { value jv; BOOST_TEST((jv = tt<float>{}).is_double()); }
+ { value jv; BOOST_TEST((jv = tt<double>{}).is_double()); }
+ }
+
+ // bool
+ {
+ BOOST_TEST(value(true).is_bool());
+ BOOST_TEST(value(false).is_bool());
+
+ { value jv; BOOST_TEST((jv = true).is_bool()); }
+ { value jv; BOOST_TEST((jv = false).is_bool()); }
+ }
+
+ // nullptr
+ {
+ BOOST_TEST(value(nullptr).is_null());
+
+ { value jv("x"); BOOST_TEST((jv = nullptr).is_null()); }
+ }
+
+ // VFALCO TODO store()
+ }
+
+ void
+ testObservers()
+ {
+ value const obj(object{});
+ value const arr(array{});
+ value const str(string{});
+ value const i64(std::int64_t{});
+ value const u64(std::uint64_t{});
+ value const dub(double{});
+ value const boo(true);
+ value const nul(nullptr);
+
+ // kind()
+ {
+ BOOST_TEST(obj.kind() == kind::object);
+ BOOST_TEST(arr.kind() == kind::array);
+ BOOST_TEST(str.kind() == kind::string);
+ BOOST_TEST(i64.kind() == kind::int64);
+ BOOST_TEST(u64.kind() == kind::uint64);
+ BOOST_TEST(dub.kind() == kind::double_);
+ BOOST_TEST(boo.kind() == kind::bool_);
+ BOOST_TEST(nul.kind() == kind::null);
+ }
+
+ // is_object()
+ {
+ BOOST_TEST( obj.is_object());
+ BOOST_TEST(! arr.is_object());
+ BOOST_TEST(! str.is_object());
+ BOOST_TEST(! i64.is_object());
+ BOOST_TEST(! u64.is_object());
+ BOOST_TEST(! dub.is_object());
+ BOOST_TEST(! boo.is_object());
+ BOOST_TEST(! nul.is_object());
+ }
+
+ // is_array()
+ {
+ BOOST_TEST(! obj.is_array());
+ BOOST_TEST( arr.is_array());
+ BOOST_TEST(! str.is_array());
+ BOOST_TEST(! i64.is_array());
+ BOOST_TEST(! u64.is_array());
+ BOOST_TEST(! dub.is_array());
+ BOOST_TEST(! boo.is_array());
+ BOOST_TEST(! nul.is_array());
+ }
+
+ // is_string()
+ {
+ BOOST_TEST(! obj.is_string());
+ BOOST_TEST(! arr.is_string());
+ BOOST_TEST( str.is_string());
+ BOOST_TEST(! i64.is_string());
+ BOOST_TEST(! u64.is_string());
+ BOOST_TEST(! dub.is_string());
+ BOOST_TEST(! boo.is_string());
+ BOOST_TEST(! nul.is_string());
+ }
+
+ // is_int64()
+ {
+ BOOST_TEST(! obj.is_int64());
+ BOOST_TEST(! arr.is_int64());
+ BOOST_TEST(! str.is_int64());
+ BOOST_TEST( i64.is_int64());
+ BOOST_TEST(! u64.is_int64());
+ BOOST_TEST(! dub.is_int64());
+ BOOST_TEST(! boo.is_int64());
+ BOOST_TEST(! nul.is_int64());
+ }
+
+ // is_uint64()
+ {
+ BOOST_TEST(! obj.is_uint64());
+ BOOST_TEST(! arr.is_uint64());
+ BOOST_TEST(! str.is_uint64());
+ BOOST_TEST(! i64.is_uint64());
+ BOOST_TEST( u64.is_uint64());
+ BOOST_TEST(! dub.is_uint64());
+ BOOST_TEST(! boo.is_uint64());
+ BOOST_TEST(! nul.is_uint64());
+ }
+
+ // is_double()
+ {
+ BOOST_TEST(! obj.is_double());
+ BOOST_TEST(! arr.is_double());
+ BOOST_TEST(! str.is_double());
+ BOOST_TEST(! i64.is_double());
+ BOOST_TEST(! u64.is_double());
+ BOOST_TEST( dub.is_double());
+ BOOST_TEST(! boo.is_double());
+ BOOST_TEST(! nul.is_double());
+ }
+
+ // is_bool()
+ {
+ BOOST_TEST(! obj.is_bool());
+ BOOST_TEST(! arr.is_bool());
+ BOOST_TEST(! str.is_bool());
+ BOOST_TEST(! i64.is_bool());
+ BOOST_TEST(! u64.is_bool());
+ BOOST_TEST(! dub.is_bool());
+ BOOST_TEST( boo.is_bool());
+ BOOST_TEST(! nul.is_bool());
+ }
+
+ // is_null()
+ {
+ BOOST_TEST(! obj.is_null());
+ BOOST_TEST(! arr.is_null());
+ BOOST_TEST(! str.is_null());
+ BOOST_TEST(! i64.is_null());
+ BOOST_TEST(! u64.is_null());
+ BOOST_TEST(! dub.is_null());
+ BOOST_TEST(! boo.is_null());
+ BOOST_TEST( nul.is_null());
+ }
+
+ // is_number()
+ {
+ BOOST_TEST(! obj.is_number());
+ BOOST_TEST(! arr.is_number());
+ BOOST_TEST(! str.is_number());
+ BOOST_TEST( i64.is_number());
+ BOOST_TEST( u64.is_number());
+ BOOST_TEST( dub.is_number());
+ BOOST_TEST(! boo.is_number());
+ BOOST_TEST(! nul.is_number());
+ }
+
+ // is_primitive()
+ {
+ BOOST_TEST(! obj.is_primitive());
+ BOOST_TEST(! arr.is_primitive());
+ BOOST_TEST( str.is_primitive());
+ BOOST_TEST( i64.is_primitive());
+ BOOST_TEST( u64.is_primitive());
+ BOOST_TEST( dub.is_primitive());
+ BOOST_TEST( boo.is_primitive());
+ BOOST_TEST( nul.is_primitive());
+ }
+
+ // is_structured()
+ {
+ BOOST_TEST( obj.is_structured());
+ BOOST_TEST( arr.is_structured());
+ BOOST_TEST(! str.is_structured());
+ BOOST_TEST(! i64.is_structured());
+ BOOST_TEST(! u64.is_structured());
+ BOOST_TEST(! dub.is_structured());
+ BOOST_TEST(! boo.is_structured());
+ BOOST_TEST(! nul.is_structured());
+ }
+ }
+
+ //------------------------------------------------------
+ //
+ // Accessors
+ //
+ //------------------------------------------------------
+
+ void
+ testGetStorage()
+ {
+ auto const sp =
+ make_shared_resource<unique_resource>();
+
+ value obj(object{}, sp);
+ value arr(array{}, sp);
+ value str(string{}, sp);
+ value i64(std::int64_t{}, sp);
+ value u64(std::uint64_t{}, sp);
+ value dub(double{}, sp);
+ value boo(true, sp);
+ value nul(nullptr, sp);
+
+ // storage()
+ {
+ BOOST_TEST(*obj.storage() == *sp);
+ BOOST_TEST(*arr.storage() == *sp);
+ BOOST_TEST(*str.storage() == *sp);
+ BOOST_TEST(*i64.storage() == *sp);
+ BOOST_TEST(*u64.storage() == *sp);
+ BOOST_TEST(*dub.storage() == *sp);
+ BOOST_TEST(*boo.storage() == *sp);
+ BOOST_TEST(*nul.storage() == *sp);
+ }
+ }
+
+ void
+ testIf()
+ {
+ value obj(object{});
+ value arr(array{});
+ value str(string{});
+ value i64(std::int64_t{});
+ value u64(std::uint64_t{});
+ value dub(double{});
+ value boo(true);
+ value nul(nullptr);
+
+ auto const& cobj(obj);
+ auto const& carr(arr);
+ auto const& cstr(str);
+ auto const& ci64(i64);
+ auto const& cu64(u64);
+ auto const& cdub(dub);
+ auto const& cboo(boo);
+ auto const& cnul(nul);
+
+ // if_object()
+ {
+ BOOST_TEST(obj.if_object() != nullptr);
+ BOOST_TEST(arr.if_object() == nullptr);
+ BOOST_TEST(str.if_object() == nullptr);
+ BOOST_TEST(i64.if_object() == nullptr);
+ BOOST_TEST(u64.if_object() == nullptr);
+ BOOST_TEST(dub.if_object() == nullptr);
+ BOOST_TEST(boo.if_object() == nullptr);
+ BOOST_TEST(nul.if_object() == nullptr);
+ }
+
+ // if_object() const
+ {
+ BOOST_TEST(cobj.if_object() != nullptr);
+ BOOST_TEST(carr.if_object() == nullptr);
+ BOOST_TEST(cstr.if_object() == nullptr);
+ BOOST_TEST(ci64.if_object() == nullptr);
+ BOOST_TEST(cu64.if_object() == nullptr);
+ BOOST_TEST(cdub.if_object() == nullptr);
+ BOOST_TEST(cboo.if_object() == nullptr);
+ BOOST_TEST(cnul.if_object() == nullptr);
+ }
+
+ // if_array()
+ {
+ BOOST_TEST(obj.if_array() == nullptr);
+ BOOST_TEST(arr.if_array() != nullptr);
+ BOOST_TEST(str.if_array() == nullptr);
+ BOOST_TEST(i64.if_array() == nullptr);
+ BOOST_TEST(u64.if_array() == nullptr);
+ BOOST_TEST(dub.if_array() == nullptr);
+ BOOST_TEST(boo.if_array() == nullptr);
+ BOOST_TEST(nul.if_array() == nullptr);
+ }
+
+ // if_array() const
+ {
+ BOOST_TEST(cobj.if_array() == nullptr);
+ BOOST_TEST(carr.if_array() != nullptr);
+ BOOST_TEST(cstr.if_array() == nullptr);
+ BOOST_TEST(ci64.if_array() == nullptr);
+ BOOST_TEST(cu64.if_array() == nullptr);
+ BOOST_TEST(cdub.if_array() == nullptr);
+ BOOST_TEST(cboo.if_array() == nullptr);
+ BOOST_TEST(cnul.if_array() == nullptr);
+ }
+
+ // if_string()
+ {
+ BOOST_TEST(obj.if_string() == nullptr);
+ BOOST_TEST(arr.if_string() == nullptr);
+ BOOST_TEST(str.if_string() != nullptr);
+ BOOST_TEST(i64.if_string() == nullptr);
+ BOOST_TEST(u64.if_string() == nullptr);
+ BOOST_TEST(dub.if_string() == nullptr);
+ BOOST_TEST(boo.if_string() == nullptr);
+ BOOST_TEST(nul.if_string() == nullptr);
+ }
+
+ // if_string() const
+ {
+ BOOST_TEST(cobj.if_string() == nullptr);
+ BOOST_TEST(carr.if_string() == nullptr);
+ BOOST_TEST(cstr.if_string() != nullptr);
+ BOOST_TEST(ci64.if_string() == nullptr);
+ BOOST_TEST(cu64.if_string() == nullptr);
+ BOOST_TEST(cdub.if_string() == nullptr);
+ BOOST_TEST(cboo.if_string() == nullptr);
+ BOOST_TEST(cnul.if_string() == nullptr);
+ }
+
+ // if_int64()
+ {
+ BOOST_TEST(obj.if_int64() == nullptr);
+ BOOST_TEST(arr.if_int64() == nullptr);
+ BOOST_TEST(str.if_int64() == nullptr);
+ BOOST_TEST(i64.if_int64() != nullptr);
+ BOOST_TEST(u64.if_int64() == nullptr);
+ BOOST_TEST(dub.if_int64() == nullptr);
+ BOOST_TEST(boo.if_int64() == nullptr);
+ BOOST_TEST(nul.if_int64() == nullptr);
+ }
+
+ // if_int64() const
+ {
+ BOOST_TEST(cobj.if_int64() == nullptr);
+ BOOST_TEST(carr.if_int64() == nullptr);
+ BOOST_TEST(cstr.if_int64() == nullptr);
+ BOOST_TEST(ci64.if_int64() != nullptr);
+ BOOST_TEST(cu64.if_int64() == nullptr);
+ BOOST_TEST(cdub.if_int64() == nullptr);
+ BOOST_TEST(cboo.if_int64() == nullptr);
+ BOOST_TEST(cnul.if_int64() == nullptr);
+ }
+
+ // if_uint64()
+ {
+ BOOST_TEST(obj.if_uint64() == nullptr);
+ BOOST_TEST(arr.if_uint64() == nullptr);
+ BOOST_TEST(str.if_uint64() == nullptr);
+ BOOST_TEST(i64.if_uint64() == nullptr);
+ BOOST_TEST(u64.if_uint64() != nullptr);
+ BOOST_TEST(dub.if_uint64() == nullptr);
+ BOOST_TEST(boo.if_uint64() == nullptr);
+ BOOST_TEST(nul.if_uint64() == nullptr);
+ }
+
+ // if_uint64() const
+ {
+ BOOST_TEST(cobj.if_uint64() == nullptr);
+ BOOST_TEST(carr.if_uint64() == nullptr);
+ BOOST_TEST(cstr.if_uint64() == nullptr);
+ BOOST_TEST(ci64.if_uint64() == nullptr);
+ BOOST_TEST(cu64.if_uint64() != nullptr);
+ BOOST_TEST(cdub.if_uint64() == nullptr);
+ BOOST_TEST(cboo.if_uint64() == nullptr);
+ BOOST_TEST(cnul.if_uint64() == nullptr);
+ }
+
+ // if_double()
+ {
+ BOOST_TEST(obj.if_double() == nullptr);
+ BOOST_TEST(arr.if_double() == nullptr);
+ BOOST_TEST(str.if_double() == nullptr);
+ BOOST_TEST(i64.if_double() == nullptr);
+ BOOST_TEST(u64.if_double() == nullptr);
+ BOOST_TEST(dub.if_double() != nullptr);
+ BOOST_TEST(boo.if_double() == nullptr);
+ BOOST_TEST(nul.if_double() == nullptr);
+ }
+
+ // if_double() const
+ {
+ BOOST_TEST(cobj.if_double() == nullptr);
+ BOOST_TEST(carr.if_double() == nullptr);
+ BOOST_TEST(cstr.if_double() == nullptr);
+ BOOST_TEST(ci64.if_double() == nullptr);
+ BOOST_TEST(cu64.if_double() == nullptr);
+ BOOST_TEST(cdub.if_double() != nullptr);
+ BOOST_TEST(cboo.if_double() == nullptr);
+ BOOST_TEST(cnul.if_double() == nullptr);
+ }
+
+ // if_bool()
+ {
+ BOOST_TEST(obj.if_bool() == nullptr);
+ BOOST_TEST(arr.if_bool() == nullptr);
+ BOOST_TEST(str.if_bool() == nullptr);
+ BOOST_TEST(i64.if_bool() == nullptr);
+ BOOST_TEST(u64.if_bool() == nullptr);
+ BOOST_TEST(dub.if_bool() == nullptr);
+ BOOST_TEST(boo.if_bool() != nullptr);
+ BOOST_TEST(nul.if_bool() == nullptr);
+ }
+
+ // if_bool() const
+ {
+ BOOST_TEST(cobj.if_bool() == nullptr);
+ BOOST_TEST(carr.if_bool() == nullptr);
+ BOOST_TEST(cstr.if_bool() == nullptr);
+ BOOST_TEST(ci64.if_bool() == nullptr);
+ BOOST_TEST(cu64.if_bool() == nullptr);
+ BOOST_TEST(cdub.if_bool() == nullptr);
+ BOOST_TEST(cboo.if_bool() != nullptr);
+ BOOST_TEST(cnul.if_bool() == nullptr);
+ }
+ }
+
+ void
+ testToNumber()
+ {
+#define EQAL(T) BOOST_TEST(jv.to_number<T>() == V)
+#define EQUS(T) BOOST_TEST((V >= 0) && jv.to_number<T>() == static_cast<std::uint64_t>(V))
+#define EQUF(T) BOOST_TEST(static_cast<float>(V) == static_cast<float>(jv.to_number<T>()))
+#define THRO(T) BOOST_TEST_THROWS_WITH_LOCATION(jv.to_number<T>());
+
+ BOOST_TEST_THROWS_WITH_LOCATION(value(nullptr).to_number<int>());
+ BOOST_TEST_THROWS_WITH_LOCATION(value(false).to_number<int>());
+ BOOST_TEST_THROWS_WITH_LOCATION(value(string_kind).to_number<int>());
+ BOOST_TEST_THROWS_WITH_LOCATION(value(array_kind).to_number<int>());
+ BOOST_TEST_THROWS_WITH_LOCATION(value(object_kind).to_number<int>());
+
+ BOOST_TEST_THROWS_WITH_LOCATION(value(nullptr).to_number<unsigned>());
+ BOOST_TEST_THROWS_WITH_LOCATION(value(false).to_number<unsigned>());
+ BOOST_TEST_THROWS_WITH_LOCATION(value(string_kind).to_number<unsigned>());
+ BOOST_TEST_THROWS_WITH_LOCATION(value(array_kind).to_number<unsigned>());
+ BOOST_TEST_THROWS_WITH_LOCATION(value(object_kind).to_number<unsigned>());
+
+ BOOST_TEST_THROWS_WITH_LOCATION(value(nullptr).to_number<double>());
+ BOOST_TEST_THROWS_WITH_LOCATION(value(false).to_number<double>());
+ BOOST_TEST_THROWS_WITH_LOCATION(value(string_kind).to_number<double>());
+ BOOST_TEST_THROWS_WITH_LOCATION(value(array_kind).to_number<double>());
+ BOOST_TEST_THROWS_WITH_LOCATION(value(object_kind).to_number<double>());
+
+ {
+ unsigned char V = 0;
+ value const jv(V);
+ EQAL(std::int8_t);
+ EQAL(std::int16_t);
+ EQAL(std::int32_t);
+ EQAL(std::int64_t);
+ EQAL(std::uint8_t);
+ EQAL(std::uint16_t);
+ EQAL(std::uint32_t);
+ EQAL(std::uint64_t);
+ EQAL(float);
+ EQAL(double);
+ }
+ {
+ auto V = max_of<std::int8_t>();
+ value const jv(V);
+ EQAL(std::int8_t);
+ EQAL(std::int16_t);
+ EQAL(std::int32_t);
+ EQAL(std::int64_t);
+ EQAL(std::uint8_t);
+ EQAL(std::uint16_t);
+ EQUS(std::uint32_t);
+ EQUS(std::uint64_t);
+ EQAL(float);
+ EQAL(double);
+ }
+ {
+ auto V = max_of<std::int16_t>();
+ value const jv(V);
+ THRO(std::int8_t);
+ EQAL(std::int16_t);
+ EQAL(std::int32_t);
+ EQAL(std::int64_t);
+ THRO(std::uint8_t);
+ EQAL(std::uint16_t);
+ EQUS(std::uint32_t);
+ EQUS(std::uint64_t);
+ EQAL(float);
+ EQAL(double);
+ }
+ {
+ auto V = max_of<std::int32_t>();
+ value const jv(V);
+ THRO(std::int8_t);
+ THRO(std::int16_t);
+ EQAL(std::int32_t);
+ EQAL(std::int64_t);
+ THRO(std::uint8_t);
+ THRO(std::uint16_t);
+ EQUS(std::uint32_t);
+ EQUS(std::uint64_t);
+ EQUF(float);
+ EQAL(double);
+ }
+ {
+ auto V = max_of<std::int64_t>();
+ value const jv(V);
+ THRO(std::int8_t);
+ THRO(std::int16_t);
+ THRO(std::int32_t);
+ EQAL(std::int64_t);
+ THRO(std::uint8_t);
+ THRO(std::uint16_t);
+ THRO(std::uint32_t);
+ EQUS(std::uint64_t);
+ EQUF(float);
+ EQUF(double);
+ }
+ //---
+ {
+ auto V = max_of<std::uint8_t>();
+ value const jv(V);
+ THRO(std::int8_t);
+ EQAL(std::int16_t);
+ EQAL(std::int32_t);
+ EQAL(std::int64_t);
+ EQAL(std::uint8_t);
+ EQAL(std::uint16_t);
+ EQAL(std::uint32_t);
+ EQAL(std::uint64_t);
+ EQAL(float);
+ EQAL(double);
+ }
+ {
+ auto V = max_of<std::uint16_t>();
+ value const jv(V);
+ THRO(std::int8_t);
+ THRO(std::int16_t);
+ EQAL(std::int32_t);
+ EQAL(std::int64_t);
+ THRO(std::uint8_t);
+ EQAL(std::uint16_t);
+ EQAL(std::uint32_t);
+ EQAL(std::uint64_t);
+ EQAL(float);
+ EQAL(double);
+ }
+ {
+ auto V = max_of<std::uint32_t>();
+ value const jv(V);
+ THRO(std::int8_t);
+ THRO(std::int16_t);
+ THRO(std::int32_t);
+ EQAL(std::int64_t);
+ THRO(std::uint8_t);
+ THRO(std::uint16_t);
+ EQAL(std::uint32_t);
+ EQAL(std::uint64_t);
+ EQUF(float);
+ EQAL(double);
+ }
+ {
+ auto V = max_of<std::uint64_t>();
+ value const jv(V);
+ THRO(std::int8_t);
+ THRO(std::int16_t);
+ THRO(std::int32_t);
+ THRO(std::int64_t);
+ THRO(std::uint8_t);
+ THRO(std::uint16_t);
+ THRO(std::uint32_t);
+ EQAL(std::uint64_t);
+ EQUF(float);
+ EQUF(double);
+ }
+ //---
+ {
+ auto V = min_of<std::int8_t>();
+ value const jv(V);
+ EQAL(std::int8_t);
+ EQAL(std::int16_t);
+ EQAL(std::int32_t);
+ EQAL(std::int64_t);
+ THRO(std::uint8_t);
+ THRO(std::uint16_t);
+ THRO(std::uint32_t);
+ THRO(std::uint64_t);
+ EQAL(float);
+ EQAL(double);
+ }
+ {
+ auto V = min_of<std::int16_t>();
+ value const jv(V);
+ THRO(std::int8_t);
+ EQAL(std::int16_t);
+ EQAL(std::int32_t);
+ EQAL(std::int64_t);
+ THRO(std::uint8_t);
+ THRO(std::uint16_t);
+ THRO(std::uint32_t);
+ THRO(std::uint64_t);
+ EQAL(float);
+ EQAL(double);
+ }
+ {
+ auto V = min_of<std::int32_t>();
+ value const jv(V);
+ THRO(std::int8_t);
+ THRO(std::int16_t);
+ EQAL(std::int32_t);
+ EQAL(std::int64_t);
+ THRO(std::uint8_t);
+ THRO(std::uint16_t);
+ THRO(std::uint32_t);
+ THRO(std::uint64_t);
+ EQUF(float);
+ EQAL(double);
+ }
+ {
+ auto V = min_of<std::int64_t>();
+ value const jv(V);
+ THRO(std::int8_t);
+ THRO(std::int16_t);
+ THRO(std::int32_t);
+ EQAL(std::int64_t);
+ THRO(std::uint8_t);
+ THRO(std::uint16_t);
+ THRO(std::uint32_t);
+ THRO(std::uint64_t);
+ EQUF(float);
+ EQUF(double);
+ }
+ //---
+ {
+ auto V = double(1.5);
+ value const jv(V);
+ THRO(std::int8_t);
+ THRO(std::int16_t);
+ THRO(std::int32_t);
+ THRO(std::int64_t);
+ THRO(std::uint8_t);
+ THRO(std::uint16_t);
+ THRO(std::uint32_t);
+ THRO(std::uint64_t);
+ EQAL(float);
+ EQAL(double);
+ }
+ {
+ auto V = double(2.0);
+ value const jv(V);
+ EQAL(std::int8_t);
+ EQAL(std::int16_t);
+ EQAL(std::int32_t);
+ EQAL(std::int64_t);
+ EQAL(std::uint8_t);
+ EQAL(std::uint16_t);
+ EQAL(std::uint32_t);
+ EQAL(std::uint64_t);
+ EQAL(float);
+ EQAL(double);
+ }
+ {
+ auto V = double(-4.0);
+ value const jv(V);
+ EQAL(std::int8_t);
+ EQAL(std::int16_t);
+ EQAL(std::int32_t);
+ EQAL(std::int64_t);
+ THRO(std::uint8_t);
+ THRO(std::uint16_t);
+ THRO(std::uint32_t);
+ THRO(std::uint64_t);
+ EQAL(float);
+ EQAL(double);
+ }
+
+ {
+ error_code ec;
+ value(nullptr).to_number<double>(ec);
+ BOOST_TEST(ec == error::not_number);
+ BOOST_TEST(ec.has_location());
+ }
+
+ {
+ std::error_code ec;
+ value(nullptr).to_number<double>(ec);
+ BOOST_TEST(error::not_number == ec);
+ }
+ }
+
+ void
+ testAs()
+ {
+ value obj(object{});
+ value arr(array{});
+ value str(string{});
+ value i64(std::int64_t{});
+ value u64(std::uint64_t{});
+ value dub(double{});
+ value boo(true);
+ value nul(nullptr);
+
+ auto const& cobj(obj);
+ auto const& carr(arr);
+ auto const& cstr(str);
+ auto const& ci64(i64);
+ auto const& cu64(u64);
+ auto const& cdub(dub);
+ auto const& cboo(boo);
+ auto const& cnul(nul);
+
+ // as_object()
+ {
+ object& x = obj.as_object();
+ BOOST_TEST_THROWS(arr.as_object(), std::invalid_argument);
+ BOOST_TEST_THROWS(str.as_object(), std::invalid_argument);
+ BOOST_TEST_THROWS(i64.as_object(), std::invalid_argument);
+ BOOST_TEST_THROWS(u64.as_object(), std::invalid_argument);
+ BOOST_TEST_THROWS(dub.as_object(), std::invalid_argument);
+ BOOST_TEST_THROWS(boo.as_object(), std::invalid_argument);
+ BOOST_TEST_THROWS(nul.as_object(), std::invalid_argument);
+ (void)x;
+ }
+
+ // as_object() const
+ {
+ object const& x = cobj.as_object();
+ BOOST_TEST_THROWS(carr.as_object(), std::invalid_argument);
+ BOOST_TEST_THROWS(cstr.as_object(), std::invalid_argument);
+ BOOST_TEST_THROWS(ci64.as_object(), std::invalid_argument);
+ BOOST_TEST_THROWS(cu64.as_object(), std::invalid_argument);
+ BOOST_TEST_THROWS(cdub.as_object(), std::invalid_argument);
+ BOOST_TEST_THROWS(cboo.as_object(), std::invalid_argument);
+ BOOST_TEST_THROWS(cnul.as_object(), std::invalid_argument);
+ (void)x;
+ }
+
+ // as_array()
+ {
+ BOOST_TEST_THROWS(obj.as_array(), std::invalid_argument);
+ array& x = arr.as_array();
+ BOOST_TEST_THROWS(str.as_array(), std::invalid_argument);
+ BOOST_TEST_THROWS(i64.as_array(), std::invalid_argument);
+ BOOST_TEST_THROWS(u64.as_array(), std::invalid_argument);
+ BOOST_TEST_THROWS(dub.as_array(), std::invalid_argument);
+ BOOST_TEST_THROWS(boo.as_array(), std::invalid_argument);
+ BOOST_TEST_THROWS(nul.as_array(), std::invalid_argument);
+ (void)x;
+ }
+
+ // as_array() const
+ {
+ BOOST_TEST_THROWS(cobj.as_array(), std::invalid_argument);
+ array const& x = carr.as_array();
+ BOOST_TEST_THROWS(cstr.as_array(), std::invalid_argument);
+ BOOST_TEST_THROWS(ci64.as_array(), std::invalid_argument);
+ BOOST_TEST_THROWS(cu64.as_array(), std::invalid_argument);
+ BOOST_TEST_THROWS(cdub.as_array(), std::invalid_argument);
+ BOOST_TEST_THROWS(cboo.as_array(), std::invalid_argument);
+ BOOST_TEST_THROWS(cnul.as_array(), std::invalid_argument);
+ (void)x;
+ }
+
+ // as_string()
+ {
+ BOOST_TEST_THROWS(obj.as_string(), std::invalid_argument);
+ BOOST_TEST_THROWS(arr.as_string(), std::invalid_argument);
+ string& x = str.as_string();
+ BOOST_TEST_THROWS(i64.as_string(), std::invalid_argument);
+ BOOST_TEST_THROWS(u64.as_string(), std::invalid_argument);
+ BOOST_TEST_THROWS(dub.as_string(), std::invalid_argument);
+ BOOST_TEST_THROWS(boo.as_string(), std::invalid_argument);
+ BOOST_TEST_THROWS(nul.as_string(), std::invalid_argument);
+ (void)x;
+ }
+
+ // as_string() const
+ {
+ BOOST_TEST_THROWS(cobj.as_string(), std::invalid_argument);
+ BOOST_TEST_THROWS(carr.as_string(), std::invalid_argument);
+ string const& x = cstr.as_string();
+ BOOST_TEST_THROWS(ci64.as_string(), std::invalid_argument);
+ BOOST_TEST_THROWS(cu64.as_string(), std::invalid_argument);
+ BOOST_TEST_THROWS(cdub.as_string(), std::invalid_argument);
+ BOOST_TEST_THROWS(cboo.as_string(), std::invalid_argument);
+ BOOST_TEST_THROWS(cnul.as_string(), std::invalid_argument);
+ (void)x;
+ }
+
+ // as_int64()
+ {
+ BOOST_TEST_THROWS(obj.as_int64(), std::invalid_argument);
+ BOOST_TEST_THROWS(arr.as_int64(), std::invalid_argument);
+ BOOST_TEST_THROWS(str.as_int64(), std::invalid_argument);
+ std::int64_t& x = i64.as_int64();
+ BOOST_TEST_THROWS(u64.as_int64(), std::invalid_argument);
+ BOOST_TEST_THROWS(dub.as_int64(), std::invalid_argument);
+ BOOST_TEST_THROWS(boo.as_int64(), std::invalid_argument);
+ BOOST_TEST_THROWS(nul.as_int64(), std::invalid_argument);
+ (void)x;
+ }
+
+ // as_int64() const
+ {
+ BOOST_TEST_THROWS(cobj.as_int64(), std::invalid_argument);
+ BOOST_TEST_THROWS(carr.as_int64(), std::invalid_argument);
+ BOOST_TEST_THROWS(cstr.as_int64(), std::invalid_argument);
+ std::int64_t const& x = ci64.as_int64();
+ BOOST_TEST_THROWS(cu64.as_int64(), std::invalid_argument);
+ BOOST_TEST_THROWS(cdub.as_int64(), std::invalid_argument);
+ BOOST_TEST_THROWS(cboo.as_int64(), std::invalid_argument);
+ BOOST_TEST_THROWS(cnul.as_int64(), std::invalid_argument);
+ (void)x;
+ }
+
+ // as_uint64()
+ {
+ BOOST_TEST_THROWS(obj.as_uint64(), std::invalid_argument);
+ BOOST_TEST_THROWS(arr.as_uint64(), std::invalid_argument);
+ BOOST_TEST_THROWS(str.as_uint64(), std::invalid_argument);
+ BOOST_TEST_THROWS(i64.as_uint64(), std::invalid_argument);
+ std::uint64_t& x = u64.as_uint64();
+ BOOST_TEST_THROWS(dub.as_uint64(), std::invalid_argument);
+ BOOST_TEST_THROWS(boo.as_uint64(), std::invalid_argument);
+ BOOST_TEST_THROWS(nul.as_uint64(), std::invalid_argument);
+ (void)x;
+ }
+
+ // as_uint64() const
+ {
+ BOOST_TEST_THROWS(cobj.as_uint64(), std::invalid_argument);
+ BOOST_TEST_THROWS(carr.as_uint64(), std::invalid_argument);
+ BOOST_TEST_THROWS(cstr.as_uint64(), std::invalid_argument);
+ BOOST_TEST_THROWS(ci64.as_uint64(), std::invalid_argument);
+ std::uint64_t const& x = cu64.as_uint64();
+ BOOST_TEST_THROWS(cdub.as_uint64(), std::invalid_argument);
+ BOOST_TEST_THROWS(cboo.as_uint64(), std::invalid_argument);
+ BOOST_TEST_THROWS(cnul.as_uint64(), std::invalid_argument);
+ (void)x;
+ }
+
+ // as_double()
+ {
+ BOOST_TEST_THROWS(obj.as_double(), std::invalid_argument);
+ BOOST_TEST_THROWS(arr.as_double(), std::invalid_argument);
+ BOOST_TEST_THROWS(str.as_double(), std::invalid_argument);
+ BOOST_TEST_THROWS(i64.as_double(), std::invalid_argument);
+ BOOST_TEST_THROWS(u64.as_double(), std::invalid_argument);
+ double& x = dub.as_double();
+ BOOST_TEST_THROWS(boo.as_double(), std::invalid_argument);
+ BOOST_TEST_THROWS(nul.as_double(), std::invalid_argument);
+ (void)x;
+ }
+
+ // as_double() const
+ {
+ BOOST_TEST_THROWS(cobj.as_double(), std::invalid_argument);
+ BOOST_TEST_THROWS(carr.as_double(), std::invalid_argument);
+ BOOST_TEST_THROWS(cstr.as_double(), std::invalid_argument);
+ BOOST_TEST_THROWS(ci64.as_double(), std::invalid_argument);
+ BOOST_TEST_THROWS(cu64.as_double(), std::invalid_argument);
+ double const& x = cdub.as_double();
+ BOOST_TEST_THROWS(cboo.as_double(), std::invalid_argument);
+ BOOST_TEST_THROWS(cnul.as_double(), std::invalid_argument);
+ (void)x;
+ }
+
+ // as_bool()
+ {
+ BOOST_TEST_THROWS(obj.as_bool(), std::invalid_argument);
+ BOOST_TEST_THROWS(arr.as_bool(), std::invalid_argument);
+ BOOST_TEST_THROWS(str.as_bool(), std::invalid_argument);
+ BOOST_TEST_THROWS(i64.as_bool(), std::invalid_argument);
+ BOOST_TEST_THROWS(u64.as_bool(), std::invalid_argument);
+ BOOST_TEST_THROWS(dub.as_bool(), std::invalid_argument);
+ bool& x = boo.as_bool();
+ BOOST_TEST_THROWS(nul.as_bool(), std::invalid_argument);
+ (void)x;
+ }
+
+ // as_bool() const
+ {
+ BOOST_TEST_THROWS(cobj.as_bool(), std::invalid_argument);
+ BOOST_TEST_THROWS(carr.as_bool(), std::invalid_argument);
+ BOOST_TEST_THROWS(cstr.as_bool(), std::invalid_argument);
+ BOOST_TEST_THROWS(ci64.as_bool(), std::invalid_argument);
+ BOOST_TEST_THROWS(cu64.as_bool(), std::invalid_argument);
+ BOOST_TEST_THROWS(cdub.as_bool(), std::invalid_argument);
+ bool const&x = cboo.as_bool();
+ BOOST_TEST_THROWS(cnul.as_bool(), std::invalid_argument);
+ (void)x;
+ }
+ }
+
+ void
+ testGet()
+ {
+ value obj(object{});
+ value arr(array{});
+ value str(string{});
+ value i64(std::int64_t{});
+ value u64(std::uint64_t{});
+ value dub(double{});
+ value boo(true);
+
+ auto const& cobj(obj);
+ auto const& carr(arr);
+ auto const& cstr(str);
+ auto const& ci64(i64);
+ auto const& cu64(u64);
+ auto const& cdub(dub);
+ auto const& cboo(boo);
+
+ // get_object()
+ // get_array()
+ // get_string()
+ // get_int64()
+ // get_uint64()
+ // get_double()
+ // get_bool()
+ {
+ object& xobj = obj.get_object();
+ array& xarr = arr.get_array();
+ string& xstr = str.get_string();
+ std::int64_t& xi64 = i64.get_int64();
+ std::uint64_t& xu64 = u64.get_uint64();
+ double& xdub = dub.get_double();
+ bool& xboo = boo.get_bool();
+
+ (void)(xobj);
+ (void)(xarr);
+ (void)(xstr);
+ (void)(xi64);
+ (void)(xu64);
+ (void)(xdub);
+ (void)(xboo);
+ }
+
+ // get_object() const
+ // get_array() const
+ // get_string() const
+ // get_int64() const
+ // get_uint64() const
+ // get_double() const
+ // get_bool() const
+ {
+ object const& xobj = cobj.get_object();
+ array const& xarr = carr.get_array();
+ string const& xstr = cstr.get_string();
+ std::int64_t
+ const& xi64 = ci64.get_int64();
+ std::uint64_t
+ const& xu64 = cu64.get_uint64();
+ double const& xdub = cdub.get_double();
+ bool const& xboo = cboo.get_bool();
+
+ (void)(xobj);
+ (void)(xarr);
+ (void)(xstr);
+ (void)(xi64);
+ (void)(xu64);
+ (void)(xdub);
+ (void)(xboo);
+ }
+ }
+
+ void
+ testAt()
+ {
+ // object
+ BOOST_TEST(value(
+ {{"k1", "value"}, {"k2", nullptr}}
+ ).at("k1").as_string() == "value");
+ BOOST_TEST_THROWS(value(
+ {{"k1", "value"}, {"k2", nullptr}}
+ ).at("null"),
+ std::out_of_range);
+
+ // array
+ BOOST_TEST(
+ value({true,2,"3"}).at(1).as_int64() == 2);
+
+ BOOST_TEST_THROWS( value({false,2,false}).at(4), std::out_of_range );
+ BOOST_TEST_THROWS( value({false,2,"3"}).at(4), std::out_of_range );
+ BOOST_TEST_THROWS( value({false,false}).at(4), std::out_of_range );
+ BOOST_TEST_THROWS( value({false,2}).at(4), std::out_of_range );
+ BOOST_TEST_THROWS( value({false,2,"3",nullptr}).at(4), std::out_of_range );
+ BOOST_TEST_THROWS( value({2,false,"3"}).at(4), std::out_of_range );
+ BOOST_TEST_THROWS( value({true,2,"3"}).at(4), std::out_of_range );
+ }
+
+ //------------------------------------------------------
+
+ void
+ testKeyValuePair()
+ {
+ using kvp = key_value_pair;
+
+ kvp v1("key", "value");
+ kvp v2(v1);
+ BOOST_TEST(v2.key() == "key");
+ BOOST_TEST(
+ v2.value().get_string() == "value");
+ kvp v3(std::move(v2));
+ BOOST_TEST(v3.key() == "key");
+ BOOST_TEST(
+ v3.value().get_string() == "value");
+ BOOST_TEST(std::memcmp(
+ v3.key_c_str(), "key\0", 4) == 0);
+
+ BOOST_STATIC_ASSERT(std::tuple_size<key_value_pair>::value == 2);
+ BOOST_TEST(get<0>(v3) == "key");
+ BOOST_TEST(
+ get<1>(v3).get_string() == "value");
+
+ BOOST_STATIC_ASSERT(std::is_same<
+ decltype(get<1>(std::declval<kvp>())), json::value&&>::value);
+
+#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
+ auto const [kc, vc] = v1;
+ static_assert(std::is_same<decltype(kc), string_view const>::value);
+ static_assert(std::is_same<decltype(vc), value const&>::value);
+ BOOST_TEST(kc == "key");
+ BOOST_TEST(&vc != &v1.value());
+
+ auto& [kr, vr] = v1;
+ static_assert(std::is_same<decltype(kr), string_view const>::value);
+ static_assert(std::is_same<decltype(vr), value&>::value);
+ BOOST_TEST(kr == "key");
+ BOOST_TEST(&vr == &v1.value());
+
+ auto const& [kcr, vcr] = v1;
+ static_assert(std::is_same<decltype(kcr), string_view const>::value);
+ static_assert(std::is_same<decltype(vcr), value const&>::value);
+ BOOST_TEST(kcr == "key");
+ BOOST_TEST(&vcr == &v1.value());
+
+ const kvp v4("const key", "const value");
+ auto& [ckr, cvr] = v4;
+ static_assert(std::is_same<decltype(ckr), string_view const>::value);
+ static_assert(std::is_same<decltype(cvr), value const&>::value);
+ BOOST_TEST(ckr == "const key");
+ BOOST_TEST(&cvr == &v4.value());
+#endif
+ }
+
+ //------------------------------------------------------
+
+ void
+ testStdConstruction()
+ {
+ {
+ value jv(std::string("test"));
+ }
+ }
+
+ void
+ testInitList()
+ {
+ check_array(value{0,0,0}, 0, 0, 0);
+ check_array(value{false,false,false}, false, false, false);
+ check_array(value{false,2,false}, false, 2, false);
+ check_array(value{false,2,"3"}, false, 2, "3");
+ check_array(value{false,false}, false, false);
+ check_array(value{false,2}, false, 2);
+ check_array(value{false,2,"3",nullptr}, false, 2, "3", nullptr);
+ check_array(value{2,false,"3"}, 2, false, "3");
+ check_array(value{true,2,"3"}, true, 2, "3");
+ }
+
+ //------------------------------------------------------
+
+ void
+ testEquality()
+ {
+ BOOST_TEST(value(nullptr) == value(nullptr));
+ BOOST_TEST(value(nullptr) != value(true));
+
+ BOOST_TEST(value(false) == value(false));
+ BOOST_TEST(value(true) != value(false));
+ BOOST_TEST(value(true) != value(nullptr));
+
+ BOOST_TEST(value( 1) == value( 1));
+ BOOST_TEST(value( 1) != value( 2));
+ BOOST_TEST(value(-1) == value(-1));
+ BOOST_TEST(value(-1) != value(-2));
+ BOOST_TEST(value(-1) != value( 2));
+ BOOST_TEST(value( 1) == value( 1UL));
+ BOOST_TEST(value( 1) != value( 2UL));
+ BOOST_TEST(value(-1) != value( 1UL));
+ BOOST_TEST(value(-1) != value(nullptr));
+
+ BOOST_TEST(value(1UL) == value( 1UL));
+ BOOST_TEST(value(1UL) != value( 2UL));
+ BOOST_TEST(value(1UL) == value( 1));
+ BOOST_TEST(value(1UL) != value(-1));
+ BOOST_TEST(value(1UL) != value(nullptr));
+
+ BOOST_TEST(value(1.5) == value(1.5));
+ BOOST_TEST(value(1.5) != value(2.5));
+ BOOST_TEST(value(1.5) != value(false));
+ BOOST_TEST(value(2.0) != value(2));
+
+ BOOST_TEST(value("abc") == value("abc"));
+ BOOST_TEST(value("abc") != value("xyz"));
+ BOOST_TEST(value("abc") != value("x"));
+ BOOST_TEST(value("abc") != value(nullptr));
+
+ BOOST_TEST(value({1,2,3}) == value({1,2,3}));
+ BOOST_TEST(value({1,2,3}) != value({2,3,1}));
+ BOOST_TEST(value({1,2,3}) != value({2,3,4}));
+ BOOST_TEST(value({1,2,3}) != value(nullptr));
+ BOOST_TEST(value({
+ {"a",1}, {"b",2}, {"c",3} }) == value({
+ {"a",1}, {"b",2}, {"c",3} }));
+ BOOST_TEST(value({
+ {"a",1}, {"b",2}, {"c",3} }) == value({
+ {"c",3}, {"a",1}, {"b",2} }));
+ BOOST_TEST(value({
+ {"a",1}, {"b",2}, {"c",3} }) != value({
+ {"b",1}, {"c",2}, {"d",3} }));
+ BOOST_TEST(value({
+ {"a",1}, {"b",2}, {"c",3} }) != value({
+ {"a",2}, {"b",3}, {"c",4} }));
+ BOOST_TEST(value({
+ {"a",1}, {"b",2}, {"c",3} }) != value(nullptr));
+ }
+
+ void
+ testHash()
+ {
+ BOOST_TEST(check_hash_equal(value(nullptr), value(nullptr)));
+ BOOST_TEST(check_hash_equal(value(nullptr), value()));
+ BOOST_TEST(check_hash_equal(value(nullptr), value{}));
+ BOOST_TEST(expect_hash_not_equal(value(nullptr), value({})));
+ BOOST_TEST(expect_hash_not_equal(value(nullptr), value({object()})));
+ BOOST_TEST(expect_hash_not_equal(value(nullptr), value(true)));
+ BOOST_TEST(expect_hash_not_equal(value(nullptr), value(false)));
+ BOOST_TEST(expect_hash_not_equal(value(nullptr), value(0)));
+ BOOST_TEST(expect_hash_not_equal(value(nullptr), value(0UL)));
+ BOOST_TEST(expect_hash_not_equal(value(nullptr), value(0.0)));
+ BOOST_TEST(expect_hash_not_equal(value(nullptr), value("")));
+
+ BOOST_TEST(check_hash_equal(value(true), value(true)));
+ BOOST_TEST(check_hash_equal(value(false), value(false)));
+ BOOST_TEST(expect_hash_not_equal(value(false), value(true)));
+ BOOST_TEST(expect_hash_not_equal(value(false), value(0)));
+ BOOST_TEST(expect_hash_not_equal(value(false), value(0UL)));
+ BOOST_TEST(expect_hash_not_equal(value(false), value(0.0)));
+ BOOST_TEST(expect_hash_not_equal(value(true), value(1)));
+ BOOST_TEST(expect_hash_not_equal(value(true), value(1UL)));
+ BOOST_TEST(expect_hash_not_equal(value(true), value(1.0)));
+
+ BOOST_TEST(check_hash_equal(value(2021), value(2021UL)));
+ BOOST_TEST(expect_hash_not_equal(value(2021U), value(-2021)));
+ BOOST_TEST(expect_hash_not_equal(value(2021UL), value(2021.0)));
+
+ BOOST_TEST(expect_hash_not_equal(value({}), value({object()})));
+ BOOST_TEST(expect_hash_not_equal(value({}), value("")));
+ BOOST_TEST(expect_hash_not_equal(value({object()}), value("")));
+
+ BOOST_TEST(check_hash_equal(
+ value({{"a",1}, {"b",2}, {"c",3}}),
+ value({{"b",2}, {"c",3}, {"a",1}})));
+ BOOST_TEST(expect_hash_not_equal(
+ value({{"a",1}, {"b",2}, {"c",3}}),
+ object({{"b",2}, {"c",3}, {"a",1}})));
+ BOOST_TEST(expect_hash_not_equal(
+ value({{"a",1}, {"b",2}, {"c",3}}),
+ value({{"b",2}, {"c",3}})));
+ BOOST_TEST(check_hash_equal(
+ value({"a", "b", 17}),
+ value({"a", "b", 17U})));
+ BOOST_TEST(expect_hash_not_equal(
+ value({"a", "b", 17}),
+ array({"a", "b", 17})));
+ BOOST_TEST(expect_hash_not_equal(
+ value({"a", "b", 17}),
+ value({17, "a", "b"})));
+ BOOST_TEST(expect_hash_not_equal(
+ value({"a", "b"}),
+ value({{"a", "b"}})));
+ }
+
+ //------------------------------------------------------
+
+ void
+ run()
+ {
+ testSpecial();
+ testConversion();
+ testAssignment();
+ testModifiers();
+ testExchange();
+ testObservers();
+ testGetStorage();
+ testIf();
+ testToNumber();
+ testAs();
+ testGet();
+ testAt();
+ testKeyValuePair();
+ testStdConstruction();
+ testInitList();
+ testEquality();
+ testHash();
+ }
+};
+
+TEST_SUITE(value_test, "boost.json.value");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/value_from.cpp b/src/boost/libs/json/test/value_from.cpp
new file mode 100644
index 000000000..b4b45ac0a
--- /dev/null
+++ b/src/boost/libs/json/test/value_from.cpp
@@ -0,0 +1,308 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/value_from.hpp>
+
+#include <boost/json/value.hpp> // prevent intellisense bugs
+#include <boost/json/serialize.hpp>
+
+#include "test_suite.hpp"
+
+#include <array>
+#include <string>
+#include <vector>
+#include <tuple>
+#include <map>
+#include <unordered_map>
+
+//----------------------------------------------------------
+
+namespace value_from_test_ns {
+
+//----------------------------------------------------------
+
+struct T1
+{
+ int i = 42;
+};
+
+void
+tag_invoke(
+ ::boost::json::value_from_tag,
+ ::boost::json::value& jv,
+ T1 const& t)
+{
+ jv = t.i;
+}
+
+//----------------------------------------------------------
+
+// member function
+// uses generic algorithms
+struct T2
+{
+ std::vector<int> v;
+ std::string s;
+
+ T2()
+ : v({1,2,3, 4})
+ , s("test")
+ {
+ }
+};
+
+void
+tag_invoke(
+ ::boost::json::value_from_tag,
+ ::boost::json::value& jv,
+ T2 const& t)
+{
+ jv = { t.v, t.s };
+}
+
+struct T3
+{
+};
+
+BOOST_STATIC_ASSERT(! ::boost::json::has_value_from<T3>::value);
+
+struct T4
+{
+ operator ::boost::json::value()
+ {
+ return nullptr;
+ }
+};
+
+BOOST_STATIC_ASSERT(! ::boost::json::has_value_from<T4>::value);
+
+//----------------------------------------------------------
+
+struct T5 : std::vector<int>
+{
+ using std::vector<int>::vector;
+};
+
+void
+tag_invoke(
+ ::boost::json::value_from_tag,
+ ::boost::json::value& jv,
+ T5 const&)
+{
+ jv = "T5";
+}
+
+
+//----------------------------------------------------------
+
+} // value_from_test_ns
+
+template<class T>
+static
+void
+check(
+ ::boost::json::string_view s,
+ T const& t)
+{
+ {
+ auto const jv = value_from(t,
+ ::boost::json::storage_ptr{});
+ auto const js =
+ ::boost::json::serialize(jv);
+ BOOST_TEST(js == s);
+ }
+ {
+ auto const jv =
+ ::boost::json::value_from(t);
+ auto const js =
+ ::boost::json::serialize(jv);
+ BOOST_TEST(js == s);
+ }
+}
+
+BOOST_JSON_NS_BEGIN
+
+namespace {
+
+template<class T>
+static
+void
+testValueCtor(T const& t)
+{
+ BOOST_TEST( serialize(value_from(t)) == serialize(value(t)) );
+}
+
+template<class T>
+static
+void
+testValueCtor()
+{
+ testValueCtor(T{});
+}
+
+} // namespace
+
+// integral
+BOOST_STATIC_ASSERT(has_value_from<int>::value);
+BOOST_STATIC_ASSERT(has_value_from<int&>::value);
+BOOST_STATIC_ASSERT(has_value_from<int&&>::value);
+// array
+BOOST_STATIC_ASSERT(has_value_from<int[4]>::value);
+BOOST_STATIC_ASSERT(has_value_from<int(&)[4]>::value);
+BOOST_STATIC_ASSERT(has_value_from<int(&&)[4]>::value);
+// forward range
+BOOST_STATIC_ASSERT(has_value_from<std::vector<int>>::value);
+BOOST_STATIC_ASSERT(has_value_from<std::vector<int>&>::value);
+BOOST_STATIC_ASSERT(has_value_from<std::vector<int>&&>::value);
+// tuple-like
+BOOST_STATIC_ASSERT(has_value_from<std::tuple<int, int>>::value);
+BOOST_STATIC_ASSERT(has_value_from<std::tuple<int, int>&>::value);
+BOOST_STATIC_ASSERT(has_value_from<std::tuple<int, int>&&>::value);
+BOOST_STATIC_ASSERT(has_value_from<key_value_pair>::value);
+BOOST_STATIC_ASSERT(has_value_from<key_value_pair&>::value);
+BOOST_STATIC_ASSERT(has_value_from<key_value_pair&&>::value);
+
+// object-like
+BOOST_STATIC_ASSERT(has_value_from<std::map<string_view, int>>::value);
+
+class value_from_test
+{
+public:
+ static
+ void
+ testValueCtors()
+ {
+ // value_from supports every value constructor
+
+ testValueCtor<value>();
+
+ char const* s = "5";
+ testValueCtor(s);
+ }
+
+ static
+ void
+ testGeneral()
+ {
+ {
+ int a[4] = {1, 2, 3, 4};
+ value b{1, 2, 3, 4};
+ value c = value_from(a);
+ BOOST_TEST(c.is_array());
+ BOOST_TEST(serialize(c) == serialize(b));
+ }
+ {
+ std::tuple<int, string, int, bool> a{1, "2", 42, true};
+ value b{1, "2", 42, true};
+ value c = value_from(a);
+ BOOST_TEST(c.is_array());
+ BOOST_TEST(serialize(c) == serialize(b));
+ }
+ {
+ std::array<int, 1000> a;
+ a.fill(0);
+
+ value b;
+ array& b_arr = b.emplace_array();
+ b_arr.insert(b_arr.end(), a.begin(), a.end());
+
+ BOOST_TEST(value_from(a) == b);
+ }
+ {
+ std::pair<int, string> a{1, string("2")};
+ value b{1, "2"};
+ value c = value_from(a);
+ BOOST_TEST(c.is_array());
+ BOOST_TEST(serialize(c) == serialize(b));
+ }
+ {
+ // ensures that this isn't parsed as a key value pair
+ std::pair<string_view, int> a{"2", 1};
+ value b{"2", 1};
+ value c = value_from(a);
+ BOOST_TEST(c.is_array());
+ BOOST_TEST(serialize(c) == serialize(b));
+ }
+ {
+ key_value_pair a{"2", 1};
+ value b{"2", 1};
+ value c = value_from(a);
+ BOOST_TEST(c.is_array());
+ BOOST_TEST(serialize(c) == serialize(b));
+ }
+ }
+
+ static
+ void
+ testAssociative()
+ {
+ {
+ std::map<string_view, int> a =
+ {{"a", 1}, {"b", 2}, {"c", 3}};
+ value b = {{"a", 1}, {"b", 2}, {"c", 3}};
+ value c = value_from(a);
+ BOOST_TEST(c.is_object());
+ BOOST_TEST(a.size() == c.as_object().size());
+ BOOST_TEST(b.as_object().size() == c.as_object().size());
+ }
+ {
+ std::unordered_map<std::string, int> a =
+ {{"a", 1}, {"b", 2}, {"c", 3}};
+ value b = {{"a", 1}, {"b", 2}, {"c", 3}};
+ value c = value_from(a);
+ BOOST_TEST(c.is_object());
+ BOOST_TEST(a.size() == c.as_object().size());
+ BOOST_TEST(b.as_object().size() == c.as_object().size());
+ }
+ {
+ std::map<int, int> a =
+ {{1, 1}, {2, 2}, {3, 3}};
+ value b = {{1, 1}, {2, 2}, {3, 3}};
+ value c = value_from(a);
+ BOOST_TEST(!c.is_object());
+ BOOST_TEST(a.size() == c.as_array().size());
+ BOOST_TEST(b.as_array().size() == c.as_array().size());
+ }
+ {
+ std::unordered_map<int, int> a =
+ {{1, 1}, {2, 2}, {3, 3}};
+ value b = {{1, 1}, {2, 2}, {3, 3}};
+ value c = value_from(a);
+ BOOST_TEST(!c.is_object());
+ BOOST_TEST(a.size() == c.as_array().size());
+ BOOST_TEST(b.as_array().size() == c.as_array().size());
+ }
+ }
+
+ static
+ void
+ testPreferUserCustomizations()
+ {
+ value_from_test_ns::T5 t5;
+ BOOST_TEST((::boost::json::value_from(t5) == "T5"));
+ }
+
+ void
+ run()
+ {
+ check("42", ::value_from_test_ns::T1{});
+ check("[[1,2,3,4],\"test\"]", ::value_from_test_ns::T2{});
+
+ testValueCtors();
+ testGeneral();
+ testAssociative();
+ testPreferUserCustomizations();
+ }
+};
+
+TEST_SUITE(value_from_test, "boost.json.value_from");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/value_ref.cpp b/src/boost/libs/json/test/value_ref.cpp
new file mode 100644
index 000000000..86e3a4fce
--- /dev/null
+++ b/src/boost/libs/json/test/value_ref.cpp
@@ -0,0 +1,404 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/value_ref.hpp>
+
+#include <boost/json/value.hpp>
+#include <boost/json/serialize.hpp>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+//----------------------------------------------------------
+
+// From the javadoc
+
+ class my_type
+ {
+ json::value jv_;
+
+ public:
+ my_type( std::initializer_list< json::value_ref > init )
+ : jv_(init)
+ {
+ }
+ };
+
+//----------------------------------------------------------
+
+class value_ref_test
+{
+public:
+ using init_list =
+ std::initializer_list<value_ref>;
+
+ void
+ testCtors()
+ {
+ // scalars
+ (void)value_ref((signed char)1);
+ (void)value_ref((short)1);
+ (void)value_ref((int)1);
+ (void)value_ref((long)1);
+ (void)value_ref((long long)1);
+ (void)value_ref((unsigned char)1);
+ (void)value_ref((unsigned short)1);
+ (void)value_ref((unsigned int)1);
+ (void)value_ref((unsigned long)1);
+ (void)value_ref((unsigned long long)1);
+ (void)value_ref((float)1.);
+ (void)value_ref((double)1.);
+ (void)value_ref(true);
+ (void)value_ref(nullptr);
+
+ // string_view, char const*
+ (void)(value_ref)string_view("test");
+ (void)(value_ref)("test");
+
+ // init-list
+ value_ref({1,2,3,4,5});
+
+ // value
+ (value_ref)value();
+ {
+ value jv;
+ (value_ref)jv;
+ }
+ {
+ value const jv;
+ (value_ref)jv;
+ }
+
+ // object
+ (value_ref)object();
+ {
+ object o;
+ (value_ref)o;
+ }
+ {
+ object const o{};
+ (value_ref)o;
+ }
+
+ // array
+ (value_ref)object();
+ {
+ array a;
+ (value_ref)a;
+ }
+ {
+ array const a{};
+ (value_ref)a;
+ }
+
+ // string
+ (value_ref)string();
+ {
+ string s;
+ (value_ref)s;
+ }
+ {
+ string const s{};
+ (value_ref)s;
+ }
+
+ // construct from a const rvalue
+ {
+ const value val;
+ (void)value_ref(std::move(val));
+ }
+ }
+
+ void
+ testInitList()
+ {
+ // string_view, char const*
+ (void)init_list{string_view("test")};
+ (void)init_list{"test"};
+
+ // scalars
+ (void)init_list{(short)1};
+ (void)init_list{(int)1};
+ (void)init_list{(long)1};
+ (void)init_list{(long long)1};
+ (void)init_list{(unsigned short)1};
+ (void)init_list{(unsigned int)1};
+ (void)init_list{(unsigned long)1};
+ (void)init_list{(unsigned long long)1};
+ (void)init_list{(float)1.};
+ (void)init_list{(double)1.};
+ (void)init_list{true};
+ (void)init_list{nullptr};
+
+ // bool
+ {
+ bool b = true;
+ auto const cb = b;
+ BOOST_TEST(value_ref::make_value(init_list{b}, {}).at(0).is_bool());
+ BOOST_TEST(value_ref::make_value(init_list{cb}, {}).at(0).is_bool());
+ }
+
+ // value
+ (void)init_list{value()};
+ {
+ value jv;
+ (void)init_list{jv};
+ }
+ {
+ value const jv{};
+ (void)init_list{jv};
+ }
+
+ // object
+ (void)init_list{object()};
+ {
+ object o;
+ (void)init_list{o};
+ }
+ {
+ object const o{};
+ (void)init_list{o};
+ }
+
+ // array
+ (void)init_list{object()};
+ {
+ array a;
+ (void)init_list{a};
+ }
+ {
+ array const a{};
+ (void)init_list{a};
+ }
+
+ // string
+ (void)init_list{string()};
+ {
+ string s;
+ (void)init_list{s};
+ }
+ {
+ string const s{};
+ (void)init_list{s};
+ }
+
+ // init_list
+ (void)init_list{{1,2,3,4,5}};
+ (void)init_list{{{1,2},{3,4,5}}};
+ (void)init_list{{1,2,{3,{4,5}}}};
+
+ {
+ init_list init =
+ { { "key", true } };
+ (void)init;
+ }
+ }
+
+ void
+ make_value(
+ init_list init,
+ string_view s)
+ {
+ auto const jv =
+ value_ref(init).make_value({});
+ auto const js = serialize(jv);
+ BOOST_TEST(js == s);
+ }
+
+ void
+ testMakeValue()
+ {
+ // scalars
+ make_value({(short)-1}, "[-1]");
+ make_value({(int)-2}, "[-2]");
+ make_value({(long)-3}, "[-3]");
+ make_value({(long long)-4}, "[-4]");
+ make_value({(unsigned short)1}, "[1]");
+ make_value({(unsigned int)2}, "[2]");
+ make_value({(unsigned long)3}, "[3]");
+ make_value({(unsigned long long)4}, "[4]");
+ //make_value({(float)1.}, "[1]");
+ //make_value({(double)1.}, "[1]");
+ make_value({true}, "[true]");
+ make_value({nullptr}, "[null]");
+
+ // string_view
+ make_value({string_view("5")}, "[\"5\"]");
+ make_value({"6"}, "[\"6\"]");
+
+ // value
+ {
+ make_value({value(1)}, "[1]");
+ value const v(1);
+ make_value({v}, "[1]");
+ make_value({value(2)}, "[2]");
+ }
+
+ // object
+ {
+ make_value({object({{"k1",1},{"k2",2}})}, "[{\"k1\":1,\"k2\":2}]");
+ object const obj({{"k1",1},{"k2",2}});
+ make_value({obj}, "[{\"k1\":1,\"k2\":2}]");
+ }
+
+ // array
+ {
+ make_value({array({1,2,3})}, "[[1,2,3]]");
+ array const arr({1,2,3});
+ make_value({arr}, "[[1,2,3]]");
+ }
+
+ // string
+ {
+ make_value({string("test")}, "[\"test\"]");
+ string const str("test");
+ make_value({str}, "[\"test\"]");
+ }
+
+ // init list with size != 2
+ {
+ make_value({{1,2,3}}, "[[1,2,3]]");
+ }
+
+ // `string` as key
+ {
+ make_value({
+ {string("k1"), 1},
+ {string("k2"), 2}},
+ "{\"k1\":1,\"k2\":2}");
+ }
+
+ // object/array conversion
+
+ make_value(
+ {1,2,{3,{4,5}}},
+ "[1,2,[3,[4,5]]]" );
+
+ make_value(
+ {{"k1",1}},
+ "{\"k1\":1}");
+
+ make_value(
+ {{"k1",1}, {"k2",2}},
+ "{\"k1\":1,\"k2\":2}");
+
+ make_value(
+ {{"k1",1}, {"k2",{{"k3",3}, {"k4",4}}}},
+ "{\"k1\":1,\"k2\":{\"k3\":3,\"k4\":4}}");
+
+ make_value({value(1)}, "[1]");
+ make_value({array({1,2,3,4})}, "[[1,2,3,4]]");
+ }
+
+ using kv_init_list =
+ std::initializer_list<
+ std::pair<string_view, value_ref>>;
+
+ void
+ make_object(
+ kv_init_list init,
+ string_view s)
+ {
+ auto const jv = value(object(init));
+ auto const js = serialize(jv);
+ BOOST_TEST(js == s);
+ }
+
+ void
+ testObjects()
+ {
+ make_object({
+ {"k1",1}
+ }, "{\"k1\":1}");
+ make_object({
+ {"k1",1}, {"k2",2}
+ }, "{\"k1\":1,\"k2\":2}");
+ make_object({
+ {"k1", {1,2}}, {"k2", {1,2,3}}
+ }, "{\"k1\":[1,2],\"k2\":[1,2,3]}");
+ make_object({
+ {"k1", {{"k2",2}, {"k3",3}}}
+ }, "{\"k1\":{\"k2\":2,\"k3\":3}}");
+ }
+
+ void
+ testMoveFrom()
+ {
+ {
+ string a = "abcdefghijklmnopqrstuvwxyz";
+ BOOST_TEST(!a.empty());
+ array b{std::move(a), string()};
+ BOOST_TEST(a.empty());
+ }
+ {
+ string a = "abcdefghijklmnopqrstuvwxyz";
+ BOOST_TEST(!a.empty());
+ array b{a, string()};
+ BOOST_TEST(!a.empty());
+ }
+ {
+ string const a = "abcdefghijklmnopqrstuvwxyz";
+ BOOST_TEST(!a.empty());
+ array b{a, string()};
+ BOOST_TEST(!a.empty());
+ }
+ {
+ array a{value()};
+ BOOST_TEST(a.begin() != a.end());
+ array b{std::move(a), array()};
+ BOOST_TEST(a.begin() == a.end());
+ }
+ {
+ array a{value()};
+ BOOST_TEST(a.begin() != a.end());
+ array b{a, array()};
+ BOOST_TEST(a.begin() != a.end());
+ }
+ {
+ const array a{value()};
+ BOOST_TEST(a.begin() != a.end());
+ array b{a, array()};
+ BOOST_TEST(a.begin() != a.end());
+ }
+ {
+ object a{{"a", 1}, {"b", 2}};
+ BOOST_TEST(a.capacity() > 0);
+ array b{std::move(a), object()};
+ BOOST_TEST(a.capacity() == 0);
+ }
+ {
+ object a{{"a", 1}, {"b", 2}};
+ BOOST_TEST(a.capacity() > 0);
+ array b{a, object()};
+ BOOST_TEST(a.capacity() > 0);
+ }
+ {
+ const object a{{"a", 1}, {"b", 2}};
+ BOOST_TEST(a.capacity() > 0);
+ array b{a, object()};
+ BOOST_TEST(a.capacity() > 0);
+ }
+ }
+
+ void
+ run()
+ {
+ testCtors();
+ testInitList();
+ testMakeValue();
+ testObjects();
+ testMoveFrom();
+ }
+};
+
+TEST_SUITE(value_ref_test, "boost.json.value_ref");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/value_stack.cpp b/src/boost/libs/json/test/value_stack.cpp
new file mode 100644
index 000000000..56169d389
--- /dev/null
+++ b/src/boost/libs/json/test/value_stack.cpp
@@ -0,0 +1,127 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/value_stack.hpp>
+
+#include <boost/json/serialize.hpp>
+#include <boost/json/static_resource.hpp>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+BOOST_STATIC_ASSERT( std::is_nothrow_destructible<value_stack>::value );
+
+class value_stack_test
+{
+public:
+ // This is from the javadoc
+ void
+ testValueStack()
+ {
+
+ //----------------------------------
+ // value_stack
+ {
+ // This example builds a json::value without any dynamic memory allocations:
+
+ // Construct the value stack using a local buffer
+ unsigned char temp[4096];
+ value_stack st( storage_ptr(), temp, sizeof(temp) );
+
+ // Create a static resource with a local initial buffer
+ unsigned char buf[4096];
+ static_resource mr( buf, sizeof(buf) );
+
+ // All values on the stack will use `mr`
+ st.reset(&mr);
+
+ // Push the key/value pair "a":1.
+ st.push_key("a");
+ st.push_int64(1);
+
+ // Push "b":null
+ st.push_key("b");
+ st.push_null();
+
+ // Push "c":"hello"
+ st.push_key("c");
+ st.push_string("hello");
+
+ // Pop the three key/value pairs and push an object with those three values.
+ st.push_object(3);
+
+ // Pop the object from the stack and take ownership.
+ value jv = st.release();
+
+ assert( serialize(jv) == "{\"a\":1,\"b\":null,\"c\":\"hello\"}" );
+
+ // At this point we could re-use the stack by calling reset
+ }
+
+ //----------------------------------
+ // value_stack::push_array
+ {
+ value_stack st;
+
+ // reset must be called first or else the behavior is undefined
+ st.reset();
+
+ // Place three values on the stack
+ st.push_int64( 1 );
+ st.push_int64( 2 );
+ st.push_int64( 3 );
+
+ // Remove the 3 values, and push an array with those 3 elements on the stack
+ st.push_array( 3 );
+
+ // Pop the object from the stack and take ownership.
+ value jv = st.release();
+
+ assert( serialize(jv) == "[1,2,3]" );
+
+ // At this point, reset must be called again to use the stack
+ }
+
+ //----------------------------------
+ // value_stack::push_object
+ {
+ value_stack st;
+
+ // reset must be called first or else the behavior is undefined
+ st.reset();
+
+ // Place a key/value pair onto the stack
+ st.push_key( "x" );
+ st.push_bool( true );
+
+ // Replace the key/value pair with an object containing a single element
+ st.push_object( 1 );
+
+ // Pop the object from the stack and take ownership.
+ value jv = st.release();
+
+ assert( serialize(jv) == "{\"x\":true}" );
+
+ // At this point, reset must be called again to use the stack
+ }
+
+ }
+
+ void
+ run()
+ {
+ testValueStack();
+ }
+};
+
+TEST_SUITE(value_stack_test, "boost.json.value_stack");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/value_to.cpp b/src/boost/libs/json/test/value_to.cpp
new file mode 100644
index 000000000..f4d05fb97
--- /dev/null
+++ b/src/boost/libs/json/test/value_to.cpp
@@ -0,0 +1,128 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/value_to.hpp>
+
+#include "test_suite.hpp"
+
+#include <array>
+#include <map>
+#include <unordered_map>
+#include <vector>
+
+BOOST_JSON_NS_BEGIN
+
+
+template <class T, class = void>
+struct can_apply_value_to
+ : std::false_type
+{
+};
+
+template <class T>
+struct can_apply_value_to<T, detail::void_t<decltype(
+ value_to<int>(std::declval<T>()))
+>>
+ : std::true_type
+{
+};
+
+BOOST_STATIC_ASSERT(!can_apply_value_to<int>::value);
+
+
+class value_to_test
+{
+public:
+
+ template<class T>
+ void
+ check(T t)
+ {
+ BOOST_TEST(value_to<T>(value_from(t)) == t);
+ }
+
+ void
+ testNumberCast()
+ {
+ check((short)-1);
+ check((int)-2);
+ check((long)-3);
+ check((long long)-4);
+ check((unsigned short)1);
+ check((unsigned int)2);
+ check((unsigned long)3);
+ check((unsigned long long)4);
+ check((float)1.5);
+ check((double)2.5);
+ check(true);
+ }
+
+ void
+ testJsonTypes()
+ {
+ value_to<object>(value(object_kind));
+ value_to<array>(value(array_kind));
+ value_to<string>(value(string_kind));
+ }
+
+ void
+ testGenerics()
+ {
+ check(std::string("test"));
+ check(std::map<std::string, int>
+ {
+ {"a", 1}, {"b", 2}, {"c", 3}
+ });
+ check(std::unordered_map<std::string, int>
+ {
+ { "a", 1 }, {"b", 2}, {"c", 3}
+ });
+ check(std::vector<int>{1, 2, 3, 4});
+ check(std::make_pair(std::string("test"), 5));
+ check(std::make_tuple(std::string("outer"),
+ std::make_pair(std::string("test"), 5)));
+ check(std::map<int, int>
+ {
+ {2, 4}, {3, 9}, {5, 25}
+ });
+
+ {
+ std::array<int, 1000> arr;
+ arr.fill(0);
+ check(arr);
+ }
+
+ BOOST_TEST_THROWS(
+ (value_to<std::tuple<int, int>>(value{1, 2, 3})),
+ std::invalid_argument);
+ BOOST_TEST_THROWS(
+ (value_to<std::tuple<int, int, int, int>>(value{1, 2, 3})),
+ std::invalid_argument);
+
+ BOOST_TEST_THROWS(
+ (value_to<std::array<int, 4>>(value{1, 2, 3})),
+ std::invalid_argument);
+ BOOST_TEST_THROWS(
+ (value_to<std::array<int, 4>>(value{1, 2, 3, 4, 5})),
+ std::invalid_argument);
+ }
+
+ void
+ run()
+ {
+ testNumberCast();
+ testJsonTypes();
+ testGenerics();
+ }
+};
+
+TEST_SUITE(value_to_test, "boost.json.value_to");
+
+BOOST_JSON_NS_END
diff --git a/src/boost/libs/json/test/visit.cpp b/src/boost/libs/json/test/visit.cpp
new file mode 100644
index 000000000..3d589031a
--- /dev/null
+++ b/src/boost/libs/json/test/visit.cpp
@@ -0,0 +1,92 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/json
+//
+
+// Test that header file is self-contained.
+#include <boost/json/visit.hpp>
+
+#include "test_suite.hpp"
+
+BOOST_JSON_NS_BEGIN
+
+class visit_test
+{
+public:
+ template<class T>
+ void
+ check_const(kind k, T t)
+ {
+ struct f
+ {
+ kind k;
+ bool operator()(std::nullptr_t) { return k == kind::null; }
+ bool operator()(bool) { return k == kind::bool_; }
+ bool operator()(std::int64_t) { return k == kind::int64; }
+ bool operator()(std::uint64_t) { return k == kind::uint64; }
+ bool operator()(double) { return k == kind::double_; }
+ bool operator()(string const&) { return k == kind::string; }
+ bool operator()(array const&) { return k == kind::array; }
+ bool operator()(object const&) { return k == kind::object; }
+ bool operator()(...) { return false; }
+ };
+ value const v(t);
+ BOOST_TEST(visit(f{k}, v));
+ }
+
+ template<class T>
+ void
+ check_mutable(kind k, T t)
+ {
+ struct f
+ {
+ kind k;
+ bool operator()(std::nullptr_t) { return k == kind::null; }
+ bool operator()(bool&) { return k == kind::bool_; }
+ bool operator()(std::int64_t&) { return k == kind::int64; }
+ bool operator()(std::uint64_t&) { return k == kind::uint64; }
+ bool operator()(double&) { return k == kind::double_; }
+ bool operator()(string&) { return k == kind::string; }
+ bool operator()(array&) { return k == kind::array; }
+ bool operator()(object&) { return k == kind::object; }
+ bool operator()(...) { return false; }
+ };
+ value v(t);
+ BOOST_TEST(visit(f{k}, v));
+ }
+
+ void
+ testVisit()
+ {
+ check_const(kind::null, nullptr);
+ check_const(kind::bool_, true);
+ check_const(kind::int64, -1);
+ check_const(kind::uint64, 1U);
+ check_const(kind::double_, 3.14);
+ check_const(kind::string, string_kind);
+ check_const(kind::array, array_kind);
+ check_const(kind::object, object_kind);
+
+ check_mutable(kind::null, nullptr);
+ check_mutable(kind::bool_, true);
+ check_mutable(kind::int64, -1);
+ check_mutable(kind::uint64, 1U);
+ check_mutable(kind::double_, 3.14);
+ check_mutable(kind::string, string_kind);
+ check_mutable(kind::array, array_kind);
+ check_mutable(kind::object, object_kind);
+ }
+
+ void run()
+ {
+ testVisit();
+ }
+};
+
+TEST_SUITE(visit_test, "boost.json.visit");
+
+BOOST_JSON_NS_END