From 223cbcff67c5780c917a9c1e3b45dedd3a49722c Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Tue, 8 Apr 2025 02:16:01 -0600 Subject: [PATCH 01/28] initial draft --- .github/README.md | 99 +++---- .github/binary.md | 64 +++++ .github/json.md | 2 + .github/workflows/build.yml | 3 +- .../main/java/alpine/binary/BinaryCodec.java | 1 - .../main/java/alpine/{ => binary}/Either.java | 2 +- .../java/alpine/binary/EitherBinaryCodec.java | 1 - .../{CodecTest.java => BinaryTest.java} | 46 ++- build.gradle.kts | 2 +- json/build.gradle.kts | 1 + .../main/java/alpine/json/ArrayElement.java | 119 ++++++++ .../main/java/alpine/json/BooleanElement.java | 29 ++ json/src/main/java/alpine/json/Element.java | 68 +++++ json/src/main/java/alpine/json/Json.java | 106 +++++++ .../src/main/java/alpine/json/JsonReader.java | 266 ++++++++++++++++++ .../src/main/java/alpine/json/JsonWriter.java | 78 +++++ .../main/java/alpine/json/NullElement.java | 14 + .../main/java/alpine/json/NumberElement.java | 29 ++ .../main/java/alpine/json/ObjectElement.java | 122 ++++++++ .../java/alpine/json/ParsingException.java | 14 + .../main/java/alpine/json/StringElement.java | 43 +++ json/src/test/java/alpine/json/JsonTest.java | 53 ++++ settings.gradle.kts | 3 +- 23 files changed, 1075 insertions(+), 90 deletions(-) create mode 100644 .github/binary.md create mode 100644 .github/json.md rename binary/src/main/java/alpine/{ => binary}/Either.java (99%) rename binary/src/test/java/alpine/binary/{CodecTest.java => BinaryTest.java} (96%) create mode 100644 json/build.gradle.kts create mode 100644 json/src/main/java/alpine/json/ArrayElement.java create mode 100644 json/src/main/java/alpine/json/BooleanElement.java create mode 100644 json/src/main/java/alpine/json/Element.java create mode 100644 json/src/main/java/alpine/json/Json.java create mode 100644 json/src/main/java/alpine/json/JsonReader.java create mode 100644 json/src/main/java/alpine/json/JsonWriter.java create mode 100644 json/src/main/java/alpine/json/NullElement.java create mode 100644 json/src/main/java/alpine/json/NumberElement.java create mode 100644 json/src/main/java/alpine/json/ObjectElement.java create mode 100644 json/src/main/java/alpine/json/ParsingException.java create mode 100644 json/src/main/java/alpine/json/StringElement.java create mode 100644 json/src/test/java/alpine/json/JsonTest.java diff --git a/.github/README.md b/.github/README.md index 2baf66c..b296034 100644 --- a/.github/README.md +++ b/.github/README.md @@ -1,5 +1,5 @@ # alpine -A binary(JSON soon™) serialization library for Java. +A binary and JSON serialization library for Java. ![](https://wakatime.com/badge/github/mudkipdev/alpine.svg) @@ -52,67 +52,46 @@ dependencies { -## Documentation -The core primitive of Alpine is a codec. A codec is something that can encode and decode an object from a byte buffer. -Netty's `ByteBuf` is used for this, however you don't need any other parts of Netty to take advantage of this system. - -You can easily create an `Integer` codec like this: -```java -public static final BinaryCodec INTEGER = new BinaryCodec<>() { - @Override - public Integer read(ByteBuf buffer) { - return buffer.readInt(); - } - - @Override - public void write(ByteBuf buffer, Integer value) { - buffer.writeInt(value); - } -}; +### JSON + +
+Gradle (Kotlin) +
+ +```kts +dependencies { + implementation("dev.mudkip:alpine-json:0.2.0") +} ``` -### Built-in codecs -There are already many built-in codecs exposed through the `BinaryCodec` class, a partial list is available below: - -| Java Type | Codec | Notes | -|-------------|-------------------|-------------------------------------------------------------------------------------| -| `boolean` | `BOOLEAN` | Encoded as `0` or `1`. | -| `byte` | `BYTE` | | -| `char` | `CHARACTER` | Encoded as a two-byte UTF-16 character. | -| `short` | `SHORT` | | -| `int` | `INTEGER` | | -| `int` | `VARINT` | [LEB128](https://en.wikipedia.org/wiki/LEB128) encoded. Uses between 1 and 5 bytes. | -| `long` | `LONG` | | -| `float` | `FLOAT` | | -| `double` | `DOUBLE` | | -| `String` | `STRING` | Encoded as UTF-8. Length-prefixed with a varint. | -| `UUID` | `UUID` | Encoded as two 64-bit integers. | - -### Templates -Complex composite types can be created using the template syntax: - -```java -public record User(String name, Gender gender, int age) { - public static final BinaryCodec CODEC = BinaryTemplate.of( - STRING, User::name, - Gender.CODEC, User::gender, - INTEGER, User::age, - // include up to 20 fields (total) - User::new); +
+ +
+Gradle (Groovy) +
+ +```groovy +dependencies { + implementation 'dev.mudkip:alpine-json:0.2.0' } ``` -### Transformations -Use these methods to map a codec to another type. -- `.array()` → `T[]` -- `.list()` → `List` -- `.nullable()` → `@Nullable T` -- `.optional()` → `Optional` -- `.map(Function, Function)` → `U` - -### There's more! -- Use `BinaryCodec.ordinal(Example.class)` to represent an enum. -- Use `BinaryCodec.unit(Example::new)` to represent singleton types. -- Use `BinaryCodec.map(keyCodec, valueCodec)` to represent a hash map. -- Use `BinaryCodec.either(leftCodec, rightCodec)` to represent something which can be one of two types. -- Use `BinaryCodec.of(Function, BiConsumer)` for an easier way to create a codec, especially if using the `::` syntax. +
+ +
+Maven +
+ +```xml + + dev.mudkip + alpine-json + 0.2.0 + +``` + +
+ +## Documentation +- [Binary](./binary.md) +- [JSON](./json.md) \ No newline at end of file diff --git a/.github/binary.md b/.github/binary.md new file mode 100644 index 0000000..3839191 --- /dev/null +++ b/.github/binary.md @@ -0,0 +1,64 @@ +# Documentation +The core primitive of Alpine is a codec. A codec is something that can encode and decode an object from a byte buffer. +Netty's `ByteBuf` is used for this, however you don't need any other parts of Netty to take advantage of this system. + +You can easily create an `Integer` codec like this: +```java +public static final BinaryCodec INTEGER = new BinaryCodec<>() { + @Override + public Integer read(ByteBuf buffer) { + return buffer.readInt(); + } + + @Override + public void write(ByteBuf buffer, Integer value) { + buffer.writeInt(value); + } +}; +``` + +### Built-in codecs +There are already many built-in codecs exposed through the `BinaryCodec` class, a partial list is available below: + +| Java Type | Codec | Notes | +|-------------|-------------------|-------------------------------------------------------------------------------------| +| `boolean` | `BOOLEAN` | Encoded as `0` or `1`. | +| `byte` | `BYTE` | | +| `char` | `CHARACTER` | Encoded as a two-byte UTF-16 character. | +| `short` | `SHORT` | | +| `int` | `INTEGER` | | +| `int` | `VARINT` | [LEB128](https://en.wikipedia.org/wiki/LEB128) encoded. Uses between 1 and 5 bytes. | +| `long` | `LONG` | | +| `float` | `FLOAT` | | +| `double` | `DOUBLE` | | +| `String` | `STRING` | Encoded as UTF-8. Length-prefixed with a varint. | +| `UUID` | `UUID` | Encoded as two 64-bit integers. | + +### Templates +Complex composite types can be created using the template syntax: + +```java +public record User(String name, Gender gender, int age) { + public static final BinaryCodec CODEC = BinaryTemplate.of( + STRING, User::name, + Gender.CODEC, User::gender, + INTEGER, User::age, + // include up to 20 fields (total) + User::new); +} +``` + +### Transformations +Use these methods to map a codec to another type. +- `.array()` → `T[]` +- `.list()` → `List` +- `.nullable()` → `@Nullable T` +- `.optional()` → `Optional` +- `.map(Function, Function)` → `U` + +### There's more! +- Use `BinaryCodec.ordinal(Example.class)` to represent an enum. +- Use `BinaryCodec.unit(Example::new)` to represent singleton types. +- Use `BinaryCodec.map(keyCodec, valueCodec)` to represent a hash map. +- Use `BinaryCodec.either(leftCodec, rightCodec)` to represent something which can be one of two types. +- Use `BinaryCodec.of(Function, BiConsumer)` for an easier way to create a codec, especially if using the `::` syntax. \ No newline at end of file diff --git a/.github/json.md b/.github/json.md new file mode 100644 index 0000000..8b075c9 --- /dev/null +++ b/.github/json.md @@ -0,0 +1,2 @@ +# Documentation +This is not finished yet. [Take a look at the source code?](../json/src/main/java/alpine/json) \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4912285..3e9d606 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,4 +30,5 @@ jobs: with: name: alpine path: | - binary/build/libs/alpine-*.*.*.jar \ No newline at end of file + binary/build/libs/binary-*.*.*.jar + json/build/libs/json-*.*.*.jar \ No newline at end of file diff --git a/binary/src/main/java/alpine/binary/BinaryCodec.java b/binary/src/main/java/alpine/binary/BinaryCodec.java index 2402480..de4b802 100644 --- a/binary/src/main/java/alpine/binary/BinaryCodec.java +++ b/binary/src/main/java/alpine/binary/BinaryCodec.java @@ -1,6 +1,5 @@ package alpine.binary; -import alpine.Either; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.Nullable; diff --git a/binary/src/main/java/alpine/Either.java b/binary/src/main/java/alpine/binary/Either.java similarity index 99% rename from binary/src/main/java/alpine/Either.java rename to binary/src/main/java/alpine/binary/Either.java index 0d4bbcf..cc095cf 100644 --- a/binary/src/main/java/alpine/Either.java +++ b/binary/src/main/java/alpine/binary/Either.java @@ -1,4 +1,4 @@ -package alpine; +package alpine.binary; import java.util.Objects; import java.util.Optional; diff --git a/binary/src/main/java/alpine/binary/EitherBinaryCodec.java b/binary/src/main/java/alpine/binary/EitherBinaryCodec.java index f8c7b0d..31683d5 100644 --- a/binary/src/main/java/alpine/binary/EitherBinaryCodec.java +++ b/binary/src/main/java/alpine/binary/EitherBinaryCodec.java @@ -1,6 +1,5 @@ package alpine.binary; -import alpine.Either; import io.netty.buffer.ByteBuf; /** diff --git a/binary/src/test/java/alpine/binary/CodecTest.java b/binary/src/test/java/alpine/binary/BinaryTest.java similarity index 96% rename from binary/src/test/java/alpine/binary/CodecTest.java rename to binary/src/test/java/alpine/binary/BinaryTest.java index 33e57e4..9be880e 100644 --- a/binary/src/test/java/alpine/binary/CodecTest.java +++ b/binary/src/test/java/alpine/binary/BinaryTest.java @@ -1,39 +1,16 @@ package alpine.binary; -import alpine.Either; import io.netty.buffer.Unpooled; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; -final class CodecTest { - static Stream arguments() { - return Stream.of( - // Boolean - Arguments.of("Boolean", BinaryCodec.BOOLEAN, false, new byte[] {0}), - Arguments.of("Boolean", BinaryCodec.BOOLEAN, true, new byte[] {1}), - - // String - Arguments.of("String", BinaryCodec.STRING, "ABC", new byte[] {3, 65, 66, 67}), - - // Either - Arguments.of( - "Either", - BinaryCodec.either(BinaryCodec.INTEGER, BinaryCodec.STRING), - Either.right("A"), - new byte[] {1, 1, 65}), - - // Optional - Arguments.of("Optional", BinaryCodec.BOOLEAN.optional(), Optional.empty(), new byte[] {0}), - Arguments.of("Optional", BinaryCodec.INTEGER.optional(), Optional.of(3), new byte[] {1, 0, 0, 0, 3})); - } - +final class BinaryTest { @ParameterizedTest(name = "{0} (encoding)") @MethodSource("arguments") void testEncoding(String label, BinaryCodec codec, T value, byte[] data) { @@ -58,4 +35,25 @@ void testDecoding(String label, BinaryCodec codec, T value, byte[] data) assert Objects.equals(actualValue, value) : String.format( "Expected %s while decoding, got %s.", value, actualValue); } + + static Stream arguments() { + return Stream.of( + // Boolean + Arguments.of("Boolean", BinaryCodec.BOOLEAN, false, new byte[] {0}), + Arguments.of("Boolean", BinaryCodec.BOOLEAN, true, new byte[] {1}), + + // String + Arguments.of("String", BinaryCodec.STRING, "ABC", new byte[] {3, 65, 66, 67}), + + // Either + Arguments.of( + "Either", + BinaryCodec.either(BinaryCodec.INTEGER, BinaryCodec.STRING), + Either.right("A"), + new byte[] {1, 1, 65}), + + // Optional + Arguments.of("Optional", BinaryCodec.BOOLEAN.optional(), Optional.empty(), new byte[] {0}), + Arguments.of("Optional", BinaryCodec.INTEGER.optional(), Optional.of(3), new byte[] {1, 0, 0, 0, 3})); + } } diff --git a/build.gradle.kts b/build.gradle.kts index 5b5828b..0792883 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ subprojects { apply(plugin = "com.vanniktech.maven.publish") group = "dev.mudkip" - version = "0.1.1" + version = "0.2.0" java.toolchain.languageVersion = JavaLanguageVersion.of(21) repositories { diff --git a/json/build.gradle.kts b/json/build.gradle.kts new file mode 100644 index 0000000..42e18dc --- /dev/null +++ b/json/build.gradle.kts @@ -0,0 +1 @@ +description = "A JSON serialization library for Java." \ No newline at end of file diff --git a/json/src/main/java/alpine/json/ArrayElement.java b/json/src/main/java/alpine/json/ArrayElement.java new file mode 100644 index 0000000..e730dec --- /dev/null +++ b/json/src/main/java/alpine/json/ArrayElement.java @@ -0,0 +1,119 @@ +package alpine.json; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.function.Consumer; +import java.util.stream.Stream; + +public final class ArrayElement implements Element, Iterable { + private final List elements; + + ArrayElement() { + this(new ArrayList<>()); + } + + ArrayElement(List elements) { + this.elements = elements; + } + + @Override + public int hashCode() { + return this.elements.hashCode(); + } + + @Override + public boolean equals(Object object) { + return this == object || (object instanceof ArrayElement element + && Objects.equals(this.elements, element.elements)); + } + + @Override + public String toString() { + return Json.write(this, Json.Formatting.PRETTY); + } + + @Override + public @NotNull Iterator iterator() { + return this.elements.iterator(); + } + + public Stream stream() { + return this.elements.stream(); + } + + public int length() { + return this.elements.size(); + } + + public @Nullable Element get(int index) { + return this.elements.get(index); + } + + public @Nullable Element first() { + return this.elements.getFirst(); + } + + public @Nullable Element last() { + return this.elements.getLast(); + } + + public boolean has(Element element) { + if (element == null) throw new IllegalArgumentException("Element cannot be null!"); + return this.elements.contains(element); + } + + public void each(Consumer consumer) { + if (consumer == null) { + throw new IllegalArgumentException("Consumer cannot be null!"); + } + + this.elements.forEach(consumer); + } + + public ArrayElement append(Element element) { + if (element == null) throw new IllegalArgumentException("Element cannot be null!"); + return this.copy(list -> list.add(element)); + } + + public ArrayElement append(boolean element) { + return this.append(Element.bool(element)); + } + + public ArrayElement append(Number element) { + return this.append(Element.number(element)); + } + + public ArrayElement append(String element) { + return this.append(Element.string(element)); + } + + public ArrayElement insert(int index, Element element) { + if (element == null) throw new IllegalArgumentException("Element cannot be null!"); + return this.copy(list -> list.add(index, element)); + } + + public ArrayElement insert(int index, boolean element) { + return this.insert(index, Element.bool(element)); + } + + public ArrayElement insert(int index, Number element) { + return this.insert(index, Element.number(element)); + } + + public ArrayElement insert(int index, String element) { + return this.insert(index, Element.string(element)); + } + + public ArrayElement clear() { + return this.copy(List::clear); + } + + private ArrayElement copy(Consumer> mutator) { + if (mutator == null) throw new IllegalArgumentException("Mutator cannot be null!"); + var list = new ArrayList<>(this.elements); + mutator.accept(list); + return new ArrayElement(list); + } +} diff --git a/json/src/main/java/alpine/json/BooleanElement.java b/json/src/main/java/alpine/json/BooleanElement.java new file mode 100644 index 0000000..48c852a --- /dev/null +++ b/json/src/main/java/alpine/json/BooleanElement.java @@ -0,0 +1,29 @@ +package alpine.json; + +public final class BooleanElement implements Element { + private final boolean value; + + BooleanElement(boolean value) { + this.value = value; + } + + @Override + public int hashCode() { + return Boolean.hashCode(this.value); + } + + @Override + public boolean equals(Object object) { + return this == object || (object instanceof BooleanElement element + && element.value == this.value); + } + + @Override + public String toString() { + return Json.write(this, Json.Formatting.PRETTY); + } + + public boolean value() { + return value; + } +} diff --git a/json/src/main/java/alpine/json/Element.java b/json/src/main/java/alpine/json/Element.java new file mode 100644 index 0000000..dfdcf0a --- /dev/null +++ b/json/src/main/java/alpine/json/Element.java @@ -0,0 +1,68 @@ +package alpine.json; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public sealed interface Element permits ArrayElement, BooleanElement, NullElement, NumberElement, ObjectElement, StringElement { + static NullElement nil() { + return NullElement.INSTANCE; + } + + static BooleanElement bool(boolean value) { + return new BooleanElement(value); + } + + static NumberElement number(double value) { + return new NumberElement(value); + } + + static NumberElement number(Number value) { + if (value == null) { + throw new IllegalArgumentException("Number value cannot be null!"); + } + + return new NumberElement(value.doubleValue()); + } + + static StringElement string(String value) { + return new StringElement(value); + } + + static ArrayElement array(List elements) { + return new ArrayElement(new ArrayList<>(elements)); + } + + static ArrayElement array() { + return new ArrayElement(); + } + + static ArrayElement array(Element... elements) { + return array(List.of(elements)); + } + + static ArrayElement array(Boolean... elements) { + return array(Arrays.stream(elements) + .map(Element::bool) + .map(Element.class::cast) + .toList()); + } + + static ArrayElement array(String... elements) { + return array(Arrays.stream(elements) + .map(Element::string) + .map(Element.class::cast) + .toList()); + } + + static ArrayElement array(Number... elements) { + return array(Arrays.stream(elements) + .map(Element::number) + .map(Element.class::cast) + .toList()); + } + + static ObjectElement object() { + return new ObjectElement(); + } +} diff --git a/json/src/main/java/alpine/json/Json.java b/json/src/main/java/alpine/json/Json.java new file mode 100644 index 0000000..ccadf6f --- /dev/null +++ b/json/src/main/java/alpine/json/Json.java @@ -0,0 +1,106 @@ +package alpine.json; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; + +public final class Json { + private static final JsonReader READER = new JsonReader(); + private static final JsonWriter WRITER = new JsonWriter(); + + // Structural + static final char BEGIN_OBJECT = '{'; + static final char END_OBJECT = '}'; + static final char BEGIN_ARRAY = '['; + static final char END_ARRAY = ']'; + static final char COMMA = ','; + static final char COLON = ':'; + + // Strings + static final char QUOTE = '"'; + static final char BACKSLASH = '\\'; + static final char SLASH = '/'; + + // Whitespace + static final char SPACE = ' '; + static final char TAB = '\t'; + static final char LINE_FEED = '\n'; + static final char CARRIAGE_RETURN = '\r'; + + // Literals + static final String NULL = "null"; + static final String TRUE = "true"; + static final String FALSE = "false"; + + // Other + static final char BACKSPACE = '\b'; + static final char FORM_FEED = '\f'; + + // Escaping + static final Map CHARACTER_TO_ESCAPE = Map.of( + QUOTE, QUOTE, + BACKSLASH, BACKSLASH, + BACKSPACE, 'b', + FORM_FEED, 'f', + LINE_FEED, 'n', + CARRIAGE_RETURN, 'r', + TAB, 't'); + + static final Map ESCAPE_TO_CHARACTER = Map.of( + 'b', BACKSPACE, + 'f', FORM_FEED, + 'n', LINE_FEED, + 'r', CARRIAGE_RETURN, + 't', TAB, + QUOTE, QUOTE, + BACKSLASH, BACKSLASH, + SLASH, SLASH); + + private Json() { + + } + + public static Element read(String string) throws ParsingException { + return READER.read(string); + } + + public static Element read(Path path) throws ParsingException { + try { + return read(Files.readString(path)); + } catch (IOException e) { + throw new RuntimeException("Failed to read JSON from file!", e); + } + } + + public static String write(Element element, Formatting formatting) { + return WRITER.write(element, formatting); + } + + public static void write(Path path, Element element, Formatting formatting) { + try { + Files.writeString(path, write(element, formatting)); + } catch (IOException e) { + throw new RuntimeException("Failed to write JSON to file!", e); + } + } + + static boolean isWhitespace(char character) { + return character == SPACE + || character == TAB + || character == LINE_FEED + || character == CARRIAGE_RETURN; + } + + public record Formatting(String indentation, String comma, String colon) { + public static final Formatting COMPACT = new Formatting( + "", + String.valueOf(COMMA), + String.valueOf(COLON)); + + public static final Formatting PRETTY = new Formatting( + String.valueOf(SPACE).repeat(4), + String.valueOf(COMMA) + SPACE, + String.valueOf(COLON) + SPACE); + } +} diff --git a/json/src/main/java/alpine/json/JsonReader.java b/json/src/main/java/alpine/json/JsonReader.java new file mode 100644 index 0000000..6971030 --- /dev/null +++ b/json/src/main/java/alpine/json/JsonReader.java @@ -0,0 +1,266 @@ +package alpine.json; + +import java.util.ArrayList; +import java.util.LinkedHashMap; + +import static alpine.json.Element.*; +import static alpine.json.Json.*; +import static java.lang.Character.isDigit; + +final class JsonReader { + private String input; + private int position; + + Element read(String input) throws ParsingException { + this.input = input.trim(); + this.position = 0; + this.skipWhitespace(); + return this.readElement(); + } + + private Element readElement() throws ParsingException { + var character = this.peek(); + + if (character == '"') { + return this.parseString(); + } else if (isDigit(character) || character == '-') { + return this.parseNumber(); + } else if (character == TRUE.charAt(0) || character == FALSE.charAt(0)) { + return this.parseBoolean(); + } else if (character == NULL.charAt(0)) { + return this.parseNull(); + } else if (character == BEGIN_ARRAY) { + return this.parseArray(); + } else if (character == BEGIN_OBJECT) { + return this.parseObject(); + } else { + throw new ParsingException("Unexpected character \"" + character + "\"!", this.position); + } + } + + private NullElement parseNull() throws ParsingException { + if (this.input.startsWith(NULL, this.position)) { + this.position += NULL.length(); + return nil(); + } + + throw new ParsingException("Failed to parse null!", this.position); + } + + private BooleanElement parseBoolean() throws ParsingException { + if (this.input.startsWith("true", this.position)) { + this.position += TRUE.length(); + return bool(true); + } else if (this.input.startsWith("false", this.position)) { + this.position += FALSE.length(); + return bool(false); + } + + throw new ParsingException("Failed to parse boolean!", this.position); + } + + private NumberElement parseNumber() throws ParsingException { + var start = this.position; + var length = this.input.length(); + + // negative sign + if (this.peek() == '-') { + this.position++; + } + + // integer part + if (this.peek() == '0') { + this.position++; + } else if (this.peek() >= '1' && this.peek() <= '9') { + while (this.position < length && isDigit(this.input.charAt(this.position))) { + this.position++; + } + } else { + throw new ParsingException("Expected a digit after the minus sign!", this.position); + } + + // fraction part + if (this.position < length && this.input.charAt(this.position) == '.') { + this.position++; + if (this.position >= length || !isDigit(this.input.charAt(this.position))) { + throw new ParsingException("Expected digit(s) after the decimal point!", this.position); + } + + while (this.position < length && isDigit(this.input.charAt(this.position))) { + this.position++; + } + } + + // exponent part + if (this.position < length && this.isExponent(this.input.charAt(this.position))) { + this.position++; + if (this.position < length && (this.input.charAt(this.position) == '+' || this.input.charAt(this.position) == '-')) { + this.position++; + } + + if (this.position >= length || !isDigit(this.input.charAt(this.position))) { + throw new ParsingException("Expected digit(s) in exponent!", this.position); + } + + while (this.position < length && isDigit(this.input.charAt(this.position))) { + this.position++; + } + } + + var text = this.input.substring(start, this.position); + + try { + return number(Double.parseDouble(text)); + } catch (NumberFormatException exception) { + throw new ParsingException("Invalid number \"" + text + "\"!", start); + } + } + + private StringElement parseString() throws ParsingException { + var builder = new StringBuilder(); + this.expect(QUOTE); + + while (true) { + if (this.position >= this.input.length()) { + throw new ParsingException("Unterminated string!", this.position); + } + + var character = this.input.charAt(this.position++); + + if (character == QUOTE) { + break; + } + + if (character == BACKSLASH) { + if (this.position >= this.input.length()) { + throw new ParsingException("Unterminated escape sequence!", this.position); + } + + var escapeCharacter = this.input.charAt(this.position++); + + if (escapeCharacter == 'u') { + if (this.position + 4 > this.input.length()) { + throw new ParsingException("Invalid unicode escape", this.position); + } + + var hex = this.input.substring(this.position, this.position + 4); + + try { + var codePoint = Integer.parseInt(hex, 16); + builder.append((char) codePoint); + } catch (NumberFormatException e) { + throw new ParsingException("Invalid unicode escape: \\u" + hex, this.position); + } + + this.position += 4; + } else { + var decoded = ESCAPE_TO_CHARACTER.get(escapeCharacter); + + if (decoded == null) { + throw new ParsingException("Invalid escape character: \\" + escapeCharacter, this.position); + } + + builder.append(decoded); + } + + } else if (Character.isISOControl(character)) { + throw new ParsingException("Unescaped control character in string!", this.position); + } else { + builder.append(character); + } + } + + return string(builder.toString()); + } + + + private ArrayElement parseArray() throws ParsingException { + var elements = new ArrayList(); + this.expect(BEGIN_ARRAY); + this.skipWhitespace(); + + if (this.peek() == END_ARRAY) { + this.position++; + return array(); + } + + while (true) { + this.skipWhitespace(); + var element = this.readElement(); + elements.add(element); + this.skipWhitespace(); + + if (this.peek() == END_ARRAY) { + this.position++; + break; + } + + this.expect(COMMA); + } + + return array(elements); + } + + private ObjectElement parseObject() throws ParsingException { + var map = new LinkedHashMap(); + this.expect(BEGIN_OBJECT); + this.skipWhitespace(); + + if (this.peek() == END_OBJECT) { + this.position++; + return new ObjectElement(map); + } + + while (true) { + this.skipWhitespace(); + + if (this.peek() != '"') { + throw new ParsingException("Expected string for object key!", this.position); + } + + var key = this.parseString().value(); + this.skipWhitespace(); + this.expect(COLON); + this.skipWhitespace(); + + var value = this.readElement(); + map.put(key, value); + this.skipWhitespace(); + + if (this.peek() == END_OBJECT) { + this.position++; + break; + } + + this.expect(COMMA); + } + + return new ObjectElement(map); + } + + private boolean isExponent(char character) { + return character == 'e' || character == 'E'; + } + + private char peek() throws ParsingException { + if (this.position >= this.input.length()) { + throw new ParsingException("Unexpected end of input!", this.position); + } + + return this.input.charAt(this.position); + } + + private void expect(char character) throws ParsingException { + if (this.peek() != character) { + throw new ParsingException("Expected '" + character + "', got '" + this.peek() + "'!", this.position); + } + + this.position++; + } + + private void skipWhitespace() { + while (this.position < this.input.length() && isWhitespace(this.input.charAt(this.position))) { + this.position++; + } + } +} diff --git a/json/src/main/java/alpine/json/JsonWriter.java b/json/src/main/java/alpine/json/JsonWriter.java new file mode 100644 index 0000000..a4e6856 --- /dev/null +++ b/json/src/main/java/alpine/json/JsonWriter.java @@ -0,0 +1,78 @@ +package alpine.json; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; + +import static alpine.json.Json.*; + +final class JsonWriter { + private static final String ESCAPED = "" + + QUOTE + BACKSLASH + BACKSPACE + FORM_FEED + + LINE_FEED + CARRIAGE_RETURN + TAB; + + String write(Element value, Formatting formatting) { + var builder = new StringBuilder(); + + switch (value) { + case NullElement ignored -> builder.append(NULL); + case BooleanElement element -> builder.append(element.value() ? TRUE : FALSE); + case NumberElement element -> this.writeNumber(builder, element.value()); + case StringElement element -> this.writeString(builder, element.value()); + case ArrayElement element -> this.writeArray(builder, element, formatting); + case ObjectElement element -> this.writeObject(builder, element, formatting); + }; + + return builder.toString(); + } + + private void writeNumber(StringBuilder builder, double value) { + if (Double.isNaN(value) || Double.isInfinite(value)) { + throw new IllegalArgumentException("NaN and infinite numbers are not allowed!"); + } + + if (value == Math.rint(value)) { + builder.append((long) value); + } else { + builder.append(value); + } + } + + private void writeString(StringBuilder builder, String string) { + builder.append(QUOTE); + + for (var character : string.toCharArray()) { + if (CHARACTER_TO_ESCAPE.containsKey(character)) { + builder.append(BACKSLASH).append(CHARACTER_TO_ESCAPE.get(character)); + } else if (Character.isISOControl(character)) { + builder.append(String.format("\\u%04X", (int) character)); + } else { + builder.append(character); + } + } + + builder.append(QUOTE); + } + + private void writeArray(StringBuilder builder, ArrayElement element, Formatting formatting) { + builder + .append(BEGIN_ARRAY) + .append(element.stream() + .map(value -> this.write(value, formatting)) + .collect(Collectors.joining(formatting.comma()))) + .append(END_ARRAY); + } + + private void writeObject(StringBuilder builder, ObjectElement element, Formatting formatting) { + var firstElement = new AtomicBoolean(true); + builder.append(BEGIN_OBJECT); + + element.each((key, value) -> { + builder.append(firstElement.get() ? "" : formatting.comma()); + this.writeString(builder, key); + firstElement.set(false); + builder.append(formatting.colon()).append(this.write(value, formatting)); + }); + + builder.append(END_OBJECT); + } +} diff --git a/json/src/main/java/alpine/json/NullElement.java b/json/src/main/java/alpine/json/NullElement.java new file mode 100644 index 0000000..c83c08c --- /dev/null +++ b/json/src/main/java/alpine/json/NullElement.java @@ -0,0 +1,14 @@ +package alpine.json; + +public final class NullElement implements Element { + static final NullElement INSTANCE = new NullElement(); + + private NullElement() { + + } + + @Override + public String toString() { + return Json.write(this, Json.Formatting.PRETTY); + } +} diff --git a/json/src/main/java/alpine/json/NumberElement.java b/json/src/main/java/alpine/json/NumberElement.java new file mode 100644 index 0000000..2fc756f --- /dev/null +++ b/json/src/main/java/alpine/json/NumberElement.java @@ -0,0 +1,29 @@ +package alpine.json; + +public final class NumberElement implements Element { + private final double value; + + NumberElement(double value) { + this.value = value; + } + + @Override + public int hashCode() { + return Double.hashCode(this.value); + } + + @Override + public boolean equals(Object object) { + return this == object || (object instanceof NumberElement element + && element.value == this.value); + } + + @Override + public String toString() { + return Json.write(this, Json.Formatting.PRETTY); + } + + public double value() { + return value; + } +} diff --git a/json/src/main/java/alpine/json/ObjectElement.java b/json/src/main/java/alpine/json/ObjectElement.java new file mode 100644 index 0000000..eafbe5d --- /dev/null +++ b/json/src/main/java/alpine/json/ObjectElement.java @@ -0,0 +1,122 @@ +package alpine.json; + +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.stream.Stream; + +public final class ObjectElement implements Element { + private final Map elements; + + ObjectElement() { + this(new LinkedHashMap<>()); + } + + ObjectElement(Map elements) { + this.elements = elements; + } + + @Override + public int hashCode() { + return this.elements.hashCode(); + } + + @Override + public boolean equals(Object object) { + return this == object || (object instanceof ObjectElement element + && Objects.equals(this.elements, element.elements)); + } + + @Override + public String toString() { + return Json.write(this, Json.Formatting.PRETTY); + } + + public Stream> stream() { + return this.elements.entrySet().stream(); + } + + public int length() { + return this.elements.size(); + } + + public @Nullable Element get(String key) { + return this.elements.get(key); + } + + public @Nullable Element get(String key, Element fallback) { + return this.elements.getOrDefault(key, fallback); + } + + @SuppressWarnings("unchecked") + public T expect(String key, Class clazz) { + var element = this.elements.get(key); + + if (element == null) { + throw new AssertionError("Expected an element for \"" + key + "\"!"); + } else if (!clazz.isInstance(element)) { + throw new AssertionError("Expected element to be a " + clazz.getSimpleName() + "!"); + } else return (T) element; + } + + public boolean has(String key) { + if (key == null) throw new IllegalArgumentException("Key cannot be null!"); + return this.elements.containsKey(key); + } + + public boolean has(Element value) { + if (value == null) throw new IllegalArgumentException("Value cannot be null!"); + return this.elements.containsValue(value); + } + + public void each(BiConsumer consumer) { + if (consumer == null) { + throw new IllegalArgumentException("Consumer cannot be null!"); + } + + this.elements.forEach(consumer); + } + + public ObjectElement set(String key, Element value) { + if (key == null) { + throw new IllegalArgumentException("Key cannot be null!"); + } else if (value == null) { + throw new IllegalArgumentException("Value cannot be null!"); + } + + return this.copy(map -> map.put(key, value)); + } + + public ObjectElement set(String key, boolean value) { + return this.set(key, Element.bool(value)); + } + + public ObjectElement set(String key, Number value) { + return this.set(key, Element.number(value)); + } + + public ObjectElement set(String key, String value) { + return this.set(key, Element.string(value)); + } + + public ObjectElement remove(String key) { + if (!this.has(key)) { + throw new IllegalStateException("Key \"" + key + "\" is not present!"); + } + + return this.copy(map -> map.remove(key)); + } + + public ObjectElement clear() { + return this.copy(Map::clear); + } + + private ObjectElement copy(Consumer> mutator) { + if (mutator == null) throw new IllegalArgumentException("Mutator cannot be null!"); + var map = new HashMap<>(this.elements); + mutator.accept(map); + return new ObjectElement(map); + } +} diff --git a/json/src/main/java/alpine/json/ParsingException.java b/json/src/main/java/alpine/json/ParsingException.java new file mode 100644 index 0000000..5bd94b3 --- /dev/null +++ b/json/src/main/java/alpine/json/ParsingException.java @@ -0,0 +1,14 @@ +package alpine.json; + +public final class ParsingException extends Exception { + private final int position; + + public ParsingException(String message, int position) { + super(message); + this.position = position; + } + + public int getPosition() { + return position; + } +} diff --git a/json/src/main/java/alpine/json/StringElement.java b/json/src/main/java/alpine/json/StringElement.java new file mode 100644 index 0000000..a78eb87 --- /dev/null +++ b/json/src/main/java/alpine/json/StringElement.java @@ -0,0 +1,43 @@ +package alpine.json; + +import java.util.Objects; + +public final class StringElement implements Element { + private final String value; + + StringElement(String value) { + if (value == null) { + throw new IllegalArgumentException("String value cannot be null!"); + } + + this.value = value; + } + + private static String prettyPrint(String string) { + return string + .replace("\n", "\\n") + .replace("\r", "\\r") + .replace("\t", "\\t") + .replace("\"", "\\\""); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object object) { + return this == object || (object instanceof StringElement element + && Objects.equals(this.value, element.value)); + } + + @Override + public String toString() { + return prettyPrint(Json.write(this, Json.Formatting.PRETTY)); + } + + public String value() { + return value; + } +} diff --git a/json/src/test/java/alpine/json/JsonTest.java b/json/src/test/java/alpine/json/JsonTest.java new file mode 100644 index 0000000..6dfc57e --- /dev/null +++ b/json/src/test/java/alpine/json/JsonTest.java @@ -0,0 +1,53 @@ +package alpine.json; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.Objects; +import java.util.stream.Stream; + +import static alpine.json.Element.*; + +final class JsonTest { + @ParameterizedTest(name = "{0} (encoding)") + @MethodSource("arguments") + void testEncoding(String label, Element element, String expected) { + var actual = Json.write(element, Json.Formatting.PRETTY); + assert Objects.equals(actual, expected) : String.format( + "Expected %s while encoding, got %s.", expected, actual); + } + + @ParameterizedTest(name = "{0} (decoding)") + @MethodSource("arguments") + void testDecoding(String label, Element element, String input) throws ParsingException { + var actual = Json.read(input); + assert Objects.equals(actual, element) : String.format( + "Expected %s while decoding, got %s.", element, actual); + } + + static Stream arguments() { + return Stream.of( + // Literals + Arguments.of("Null", nil(), "null"), + Arguments.of("True", bool(true), "true"), + Arguments.of("False", bool(false), "false"), + + // Numbers + Arguments.of("Integer Number", number(69), "69"), + Arguments.of("Decimal Number", number(1.23), "1.23"), + + // Strings + Arguments.of("String", string("Hello world!"), "\"Hello world!\""), + Arguments.of("Escaped String", string("\n\t\r\b"), "\"\\n\\t\\r\\b\""), + + // Arrays + Arguments.of("Empty Array", array(), "[]"), + Arguments.of("Number Array", array(1, 2, 3), "[1, 2, 3]"), + Arguments.of("String Array", array("a", "b", "c"), "[\"a\", \"b\", \"c\"]"), + + // Objects + Arguments.of("Empty Object", object(), "{}"), + Arguments.of("Simple Object", object().set("a", 1).set("b", 2), "{\"a\": 1, \"b\": 2}")); + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index dceea16..00cc400 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,2 +1,3 @@ rootProject.name = "alpine" -include("binary") \ No newline at end of file +include("binary") +include("json") \ No newline at end of file From bb994608e1187bd44667f07d4bca36943d8d81ec Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Tue, 8 Apr 2025 03:02:26 -0600 Subject: [PATCH 02/28] add more tests --- .../main/java/alpine/json/ArrayElement.java | 40 ++++++++++++++++++- .../main/java/alpine/json/BooleanElement.java | 2 +- json/src/main/java/alpine/json/Element.java | 8 ++-- .../src/main/java/alpine/json/JsonReader.java | 40 +++++++++++-------- .../main/java/alpine/json/NumberElement.java | 2 +- .../main/java/alpine/json/ObjectElement.java | 17 +++++++- .../java/alpine/json/ParsingException.java | 32 +++++++++++++-- .../main/java/alpine/json/StringElement.java | 2 +- json/src/test/java/alpine/json/ArrayTest.java | 39 ++++++++++++++++++ json/src/test/java/alpine/json/JsonTest.java | 17 ++++++++ .../src/test/java/alpine/json/ObjectTest.java | 32 +++++++++++++++ 11 files changed, 204 insertions(+), 27 deletions(-) create mode 100644 json/src/test/java/alpine/json/ArrayTest.java create mode 100644 json/src/test/java/alpine/json/ObjectTest.java diff --git a/json/src/main/java/alpine/json/ArrayElement.java b/json/src/main/java/alpine/json/ArrayElement.java index e730dec..f9c0f76 100644 --- a/json/src/main/java/alpine/json/ArrayElement.java +++ b/json/src/main/java/alpine/json/ArrayElement.java @@ -3,7 +3,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; import java.util.function.Consumer; import java.util.stream.Stream; @@ -43,6 +46,10 @@ public Stream stream() { return this.elements.stream(); } + public boolean empty() { + return this.length() < 1; + } + public int length() { return this.elements.size(); } @@ -51,6 +58,17 @@ public int length() { return this.elements.get(index); } + @SuppressWarnings("unchecked") + public T expect(int index, Class clazz) { + var element = this.elements.get(index); + + if (element == null) { + throw new AssertionError("Expected an element at " + index + "!"); + } else if (!clazz.isInstance(element)) { + throw new AssertionError("Expected element to be a " + clazz.getSimpleName() + "!"); + } else return (T) element; + } + public @Nullable Element first() { return this.elements.getFirst(); } @@ -106,6 +124,26 @@ public ArrayElement insert(int index, String element) { return this.insert(index, Element.string(element)); } + public ArrayElement removeAt(int index) { + return this.copy(list -> list.remove(index)); + } + + public ArrayElement remove(Element element) { + return this.copy(list -> list.remove(element)); + } + + public ArrayElement remove(boolean element) { + return this.remove(Element.bool(element)); + } + + public ArrayElement remove(Number element) { + return this.remove(Element.number(element)); + } + + public ArrayElement remove(String element) { + return this.remove(Element.string(element)); + } + public ArrayElement clear() { return this.copy(List::clear); } diff --git a/json/src/main/java/alpine/json/BooleanElement.java b/json/src/main/java/alpine/json/BooleanElement.java index 48c852a..051a608 100644 --- a/json/src/main/java/alpine/json/BooleanElement.java +++ b/json/src/main/java/alpine/json/BooleanElement.java @@ -24,6 +24,6 @@ public String toString() { } public boolean value() { - return value; + return this.value; } } diff --git a/json/src/main/java/alpine/json/Element.java b/json/src/main/java/alpine/json/Element.java index dfdcf0a..d831ecb 100644 --- a/json/src/main/java/alpine/json/Element.java +++ b/json/src/main/java/alpine/json/Element.java @@ -1,8 +1,6 @@ package alpine.json; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; public sealed interface Element permits ArrayElement, BooleanElement, NullElement, NumberElement, ObjectElement, StringElement { static NullElement nil() { @@ -65,4 +63,8 @@ static ArrayElement array(Number... elements) { static ObjectElement object() { return new ObjectElement(); } + + static ObjectElement object(Map map) { + return new ObjectElement(new LinkedHashMap<>(map)); + } } diff --git a/json/src/main/java/alpine/json/JsonReader.java b/json/src/main/java/alpine/json/JsonReader.java index 6971030..4c868dc 100644 --- a/json/src/main/java/alpine/json/JsonReader.java +++ b/json/src/main/java/alpine/json/JsonReader.java @@ -34,7 +34,7 @@ private Element readElement() throws ParsingException { } else if (character == BEGIN_OBJECT) { return this.parseObject(); } else { - throw new ParsingException("Unexpected character \"" + character + "\"!", this.position); + throw new ParsingException(this.input, "Unexpected character \"" + character + "\"!", this.position); } } @@ -44,7 +44,7 @@ private NullElement parseNull() throws ParsingException { return nil(); } - throw new ParsingException("Failed to parse null!", this.position); + throw new ParsingException(this.input, "Failed to parse null!", this.position); } private BooleanElement parseBoolean() throws ParsingException { @@ -56,7 +56,7 @@ private BooleanElement parseBoolean() throws ParsingException { return bool(false); } - throw new ParsingException("Failed to parse boolean!", this.position); + throw new ParsingException(this.input, "Failed to parse boolean!", this.position); } private NumberElement parseNumber() throws ParsingException { @@ -76,14 +76,14 @@ private NumberElement parseNumber() throws ParsingException { this.position++; } } else { - throw new ParsingException("Expected a digit after the minus sign!", this.position); + throw new ParsingException(this.input, "Expected a digit after the minus sign!", this.position); } // fraction part if (this.position < length && this.input.charAt(this.position) == '.') { this.position++; if (this.position >= length || !isDigit(this.input.charAt(this.position))) { - throw new ParsingException("Expected digit(s) after the decimal point!", this.position); + throw new ParsingException(this.input, "Expected digit(s) after the decimal point!", this.position); } while (this.position < length && isDigit(this.input.charAt(this.position))) { @@ -99,7 +99,7 @@ private NumberElement parseNumber() throws ParsingException { } if (this.position >= length || !isDigit(this.input.charAt(this.position))) { - throw new ParsingException("Expected digit(s) in exponent!", this.position); + throw new ParsingException(this.input, "Expected digit(s) in exponent!", this.position); } while (this.position < length && isDigit(this.input.charAt(this.position))) { @@ -107,22 +107,30 @@ private NumberElement parseNumber() throws ParsingException { } } + if ( + this.position < length + && !isWhitespace(this.input.charAt(this.position)) + && ",}]".indexOf(this.input.charAt(this.position)) < 0) { + throw new ParsingException(this.input, "Invalid character after number!", this.position); + } + var text = this.input.substring(start, this.position); try { return number(Double.parseDouble(text)); } catch (NumberFormatException exception) { - throw new ParsingException("Invalid number \"" + text + "\"!", start); + throw new ParsingException(this.input, "Invalid number \"" + text + "\"!", start); } } + private StringElement parseString() throws ParsingException { var builder = new StringBuilder(); this.expect(QUOTE); while (true) { if (this.position >= this.input.length()) { - throw new ParsingException("Unterminated string!", this.position); + throw new ParsingException(this.input, "Unterminated string!", this.position); } var character = this.input.charAt(this.position++); @@ -133,14 +141,14 @@ private StringElement parseString() throws ParsingException { if (character == BACKSLASH) { if (this.position >= this.input.length()) { - throw new ParsingException("Unterminated escape sequence!", this.position); + throw new ParsingException(this.input, "Unterminated escape sequence!", this.position); } var escapeCharacter = this.input.charAt(this.position++); if (escapeCharacter == 'u') { if (this.position + 4 > this.input.length()) { - throw new ParsingException("Invalid unicode escape", this.position); + throw new ParsingException(this.input, "Invalid unicode escape", this.position); } var hex = this.input.substring(this.position, this.position + 4); @@ -149,7 +157,7 @@ private StringElement parseString() throws ParsingException { var codePoint = Integer.parseInt(hex, 16); builder.append((char) codePoint); } catch (NumberFormatException e) { - throw new ParsingException("Invalid unicode escape: \\u" + hex, this.position); + throw new ParsingException(this.input, "Invalid unicode escape: \\u" + hex, this.position); } this.position += 4; @@ -157,14 +165,14 @@ private StringElement parseString() throws ParsingException { var decoded = ESCAPE_TO_CHARACTER.get(escapeCharacter); if (decoded == null) { - throw new ParsingException("Invalid escape character: \\" + escapeCharacter, this.position); + throw new ParsingException(this.input, "Invalid escape character: \\" + escapeCharacter, this.position); } builder.append(decoded); } } else if (Character.isISOControl(character)) { - throw new ParsingException("Unescaped control character in string!", this.position); + throw new ParsingException(this.input, "Unescaped control character in string!", this.position); } else { builder.append(character); } @@ -215,7 +223,7 @@ private ObjectElement parseObject() throws ParsingException { this.skipWhitespace(); if (this.peek() != '"') { - throw new ParsingException("Expected string for object key!", this.position); + throw new ParsingException(this.input, "Expected string for object key!", this.position); } var key = this.parseString().value(); @@ -244,7 +252,7 @@ private boolean isExponent(char character) { private char peek() throws ParsingException { if (this.position >= this.input.length()) { - throw new ParsingException("Unexpected end of input!", this.position); + throw new ParsingException(this.input, "Unexpected end of input!", this.position); } return this.input.charAt(this.position); @@ -252,7 +260,7 @@ private char peek() throws ParsingException { private void expect(char character) throws ParsingException { if (this.peek() != character) { - throw new ParsingException("Expected '" + character + "', got '" + this.peek() + "'!", this.position); + throw new ParsingException(this.input, "Expected '" + character + "', got '" + this.peek() + "'!", this.position); } this.position++; diff --git a/json/src/main/java/alpine/json/NumberElement.java b/json/src/main/java/alpine/json/NumberElement.java index 2fc756f..3a271de 100644 --- a/json/src/main/java/alpine/json/NumberElement.java +++ b/json/src/main/java/alpine/json/NumberElement.java @@ -24,6 +24,6 @@ public String toString() { } public double value() { - return value; + return this.value; } } diff --git a/json/src/main/java/alpine/json/ObjectElement.java b/json/src/main/java/alpine/json/ObjectElement.java index eafbe5d..6b4de45 100644 --- a/json/src/main/java/alpine/json/ObjectElement.java +++ b/json/src/main/java/alpine/json/ObjectElement.java @@ -2,7 +2,10 @@ import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.stream.Stream; @@ -38,6 +41,10 @@ public Stream> stream() { return this.elements.entrySet().stream(); } + public boolean empty() { + return this.length() < 1; + } + public int length() { return this.elements.size(); } @@ -71,6 +78,14 @@ public boolean has(Element value) { return this.elements.containsValue(value); } + public boolean has(Boolean value) { + return this.has(Element.bool(value)); + } + + public boolean has(Number value) { + return this.has(Element.number(value)); + } + public void each(BiConsumer consumer) { if (consumer == null) { throw new IllegalArgumentException("Consumer cannot be null!"); diff --git a/json/src/main/java/alpine/json/ParsingException.java b/json/src/main/java/alpine/json/ParsingException.java index 5bd94b3..3492cd1 100644 --- a/json/src/main/java/alpine/json/ParsingException.java +++ b/json/src/main/java/alpine/json/ParsingException.java @@ -1,14 +1,40 @@ package alpine.json; public final class ParsingException extends Exception { + private final String input; private final int position; - public ParsingException(String message, int position) { - super(message); + public ParsingException(String input, String message, int position) { + super(formatMessage(input, message, position)); + this.input = input; this.position = position; } + private static String formatMessage(String input, String message, int position) { + var line = 1; + var column = 1; + + if (input.isEmpty()) { + return String.format("%s (at 1:1)", message); + } + + for (var index = 0; index < position; index++) { + if (input.charAt(index) == '\n') { + line++; + column = 1; + } else { + column++; + } + } + + return String.format("%s (at %d:%d)", message, line, column); + } + + public String getInput() { + return this.input; + } + public int getPosition() { - return position; + return this.position; } } diff --git a/json/src/main/java/alpine/json/StringElement.java b/json/src/main/java/alpine/json/StringElement.java index a78eb87..85a32d9 100644 --- a/json/src/main/java/alpine/json/StringElement.java +++ b/json/src/main/java/alpine/json/StringElement.java @@ -38,6 +38,6 @@ public String toString() { } public String value() { - return value; + return this.value; } } diff --git a/json/src/test/java/alpine/json/ArrayTest.java b/json/src/test/java/alpine/json/ArrayTest.java new file mode 100644 index 0000000..d0fc9c1 --- /dev/null +++ b/json/src/test/java/alpine/json/ArrayTest.java @@ -0,0 +1,39 @@ +package alpine.json; + +import org.junit.jupiter.api.Test; + +import java.util.Objects; + +import static alpine.json.Element.*; +import static org.junit.jupiter.api.Assertions.*; + +final class ArrayTest { + @Test + void testAccess() { + assert array().empty(); + assert array(true).get(0) instanceof BooleanElement; + assert array(true).expect(0, BooleanElement.class).value(); + assertThrows(IndexOutOfBoundsException.class, () -> array().get(69)); + } + + @Test + void testInsertion() { + assert array().append("a").length() == 1; + assert array().append("b").insert(0, true).first() instanceof BooleanElement; + } + + @Test + void testRemoval() { + assert array(1, 2, 3).clear().empty(); + assert Objects.equals(array("a", "b", "c").removeAt(0), array("b", "c")); + assert Objects.equals(array("a", "b", "c").remove("b"), array("a", "c")); + assertThrows(IndexOutOfBoundsException.class, () -> array().removeAt(1)); + } + + @Test + void testContains() { + assert !array().has(nil()); + assert array(1, 2, 3).has(number(1)); + assert array("a", "b").has(string("b")); + } +} diff --git a/json/src/test/java/alpine/json/JsonTest.java b/json/src/test/java/alpine/json/JsonTest.java index 6dfc57e..a768f9f 100644 --- a/json/src/test/java/alpine/json/JsonTest.java +++ b/json/src/test/java/alpine/json/JsonTest.java @@ -1,5 +1,6 @@ package alpine.json; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -8,8 +9,23 @@ import java.util.stream.Stream; import static alpine.json.Element.*; +import static org.junit.jupiter.api.Assertions.*; final class JsonTest { + @Test + void testInvalid() { + var testCases = new String[] { + "test", + "{", "}", "[", "]", + "\"", "\"\0\"", + "123abc", "[123e]", "0.", ".0" + }; + + for (var string : testCases) { + assertThrows(ParsingException.class, () -> Json.read(string)); + } + } + @ParameterizedTest(name = "{0} (encoding)") @MethodSource("arguments") void testEncoding(String label, Element element, String expected) { @@ -36,6 +52,7 @@ static Stream arguments() { // Numbers Arguments.of("Integer Number", number(69), "69"), Arguments.of("Decimal Number", number(1.23), "1.23"), +// Arguments.of("Exponent Number", number(-1.23456789E+15), "-1.23456789E+15"), // Strings Arguments.of("String", string("Hello world!"), "\"Hello world!\""), diff --git a/json/src/test/java/alpine/json/ObjectTest.java b/json/src/test/java/alpine/json/ObjectTest.java new file mode 100644 index 0000000..7d5ffed --- /dev/null +++ b/json/src/test/java/alpine/json/ObjectTest.java @@ -0,0 +1,32 @@ +package alpine.json; + +import org.junit.jupiter.api.Test; + +import static alpine.json.Element.*; +import static org.junit.jupiter.api.Assertions.*; + +final class ObjectTest { + @Test + void testAccess() { + assert object().empty(); + } + + @Test + void testSetting() { + object().set("key", "value").expect("key", StringElement.class); + assertThrows(AssertionError.class, () -> object().set("key", "value") + .expect("key", NullElement.class)); + } + + @Test + void testContains() { + assert !object().has("key"); + assert !object().has(false); + assert object().set("key", "value").has("key"); + } + + @Test + void testRemoval() { + assert object().set("key", "value").remove("key").empty(); + } +} From bcd707bf8327847705d232bd4fa4e0d5d8ef2fb3 Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Tue, 8 Apr 2025 03:08:06 -0600 Subject: [PATCH 03/28] make copy methods public for now --- json/src/main/java/alpine/json/ArrayElement.java | 2 +- json/src/main/java/alpine/json/ObjectElement.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/json/src/main/java/alpine/json/ArrayElement.java b/json/src/main/java/alpine/json/ArrayElement.java index f9c0f76..b803305 100644 --- a/json/src/main/java/alpine/json/ArrayElement.java +++ b/json/src/main/java/alpine/json/ArrayElement.java @@ -148,7 +148,7 @@ public ArrayElement clear() { return this.copy(List::clear); } - private ArrayElement copy(Consumer> mutator) { + public ArrayElement copy(Consumer> mutator) { if (mutator == null) throw new IllegalArgumentException("Mutator cannot be null!"); var list = new ArrayList<>(this.elements); mutator.accept(list); diff --git a/json/src/main/java/alpine/json/ObjectElement.java b/json/src/main/java/alpine/json/ObjectElement.java index 6b4de45..3c11ef9 100644 --- a/json/src/main/java/alpine/json/ObjectElement.java +++ b/json/src/main/java/alpine/json/ObjectElement.java @@ -128,7 +128,7 @@ public ObjectElement clear() { return this.copy(Map::clear); } - private ObjectElement copy(Consumer> mutator) { + public ObjectElement copy(Consumer> mutator) { if (mutator == null) throw new IllegalArgumentException("Mutator cannot be null!"); var map = new HashMap<>(this.elements); mutator.accept(map); From 8ed824241aadb4fdd86f130e88047f1751881f53 Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Tue, 8 Apr 2025 03:38:47 -0600 Subject: [PATCH 04/28] make recursion depth test --- .../main/java/alpine/json/ArrayElement.java | 8 --- json/src/main/java/alpine/json/Json.java | 8 ++- json/src/test/java/alpine/json/JsonTest.java | 55 ++++++++++++++++--- 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/json/src/main/java/alpine/json/ArrayElement.java b/json/src/main/java/alpine/json/ArrayElement.java index b803305..7264066 100644 --- a/json/src/main/java/alpine/json/ArrayElement.java +++ b/json/src/main/java/alpine/json/ArrayElement.java @@ -82,14 +82,6 @@ public boolean has(Element element) { return this.elements.contains(element); } - public void each(Consumer consumer) { - if (consumer == null) { - throw new IllegalArgumentException("Consumer cannot be null!"); - } - - this.elements.forEach(consumer); - } - public ArrayElement append(Element element) { if (element == null) throw new IllegalArgumentException("Element cannot be null!"); return this.copy(list -> list.add(element)); diff --git a/json/src/main/java/alpine/json/Json.java b/json/src/main/java/alpine/json/Json.java index ccadf6f..d4c8614 100644 --- a/json/src/main/java/alpine/json/Json.java +++ b/json/src/main/java/alpine/json/Json.java @@ -92,15 +92,17 @@ static boolean isWhitespace(char character) { || character == CARRIAGE_RETURN; } - public record Formatting(String indentation, String comma, String colon) { + public record Formatting(String indentation, String newLine, String comma, String colon) { public static final Formatting COMPACT = new Formatting( "", + String.valueOf(LINE_FEED), String.valueOf(COMMA), String.valueOf(COLON)); public static final Formatting PRETTY = new Formatting( String.valueOf(SPACE).repeat(4), - String.valueOf(COMMA) + SPACE, - String.valueOf(COLON) + SPACE); + String.valueOf(LINE_FEED), + COMPACT.comma + SPACE, + COMPACT.colon + SPACE); } } diff --git a/json/src/test/java/alpine/json/JsonTest.java b/json/src/test/java/alpine/json/JsonTest.java index a768f9f..80c847c 100644 --- a/json/src/test/java/alpine/json/JsonTest.java +++ b/json/src/test/java/alpine/json/JsonTest.java @@ -6,6 +6,7 @@ import org.junit.jupiter.params.provider.MethodSource; import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; import static alpine.json.Element.*; @@ -13,15 +14,24 @@ final class JsonTest { @Test - void testInvalid() { - var testCases = new String[] { - "test", - "{", "}", "[", "]", - "\"", "\"\0\"", - "123abc", "[123e]", "0.", ".0" - }; + void testRecursion() { + try { + var element = Json.read("[".repeat(2000) + "]".repeat(2000)); + var maxDepth = traverseRecursively(element, 0) + 1; + assert maxDepth == 2000; + } catch (ParsingException e) { + throw new RuntimeException(e); + } + } - for (var string : testCases) { + @Test + void testInvalid() { + for (var string : new String[] { + "test", + "{", "}", "[", "]", + "\"", "\"\0\"", + "123abc", "[123e]", "0.", ".0" + }) { assertThrows(ParsingException.class, () -> Json.read(string)); } } @@ -31,7 +41,7 @@ void testInvalid() { void testEncoding(String label, Element element, String expected) { var actual = Json.write(element, Json.Formatting.PRETTY); assert Objects.equals(actual, expected) : String.format( - "Expected %s while encoding, got %s.", expected, actual); + "Expected %s while encoding, got %s.", '"' + expected + '"', actual); } @ParameterizedTest(name = "{0} (decoding)") @@ -57,6 +67,7 @@ static Stream arguments() { // Strings Arguments.of("String", string("Hello world!"), "\"Hello world!\""), Arguments.of("Escaped String", string("\n\t\r\b"), "\"\\n\\t\\r\\b\""), + Arguments.of("Unicode String", string("\0"), "\"\\u0000\""), // Arrays Arguments.of("Empty Array", array(), "[]"), @@ -67,4 +78,30 @@ static Stream arguments() { Arguments.of("Empty Object", object(), "{}"), Arguments.of("Simple Object", object().set("a", 1).set("b", 2), "{\"a\": 1, \"b\": 2}")); } + + private static int traverseRecursively(Element element, int currentDepth) { + return switch (element) { + case ArrayElement array -> { + var depth = new AtomicInteger(currentDepth); + + array.forEach(child -> { + depth.set(Math.max(depth.get(), traverseRecursively(child, currentDepth + 1))); + }); + + yield depth.get(); + } + + case ObjectElement object -> { + AtomicInteger depth = new AtomicInteger(currentDepth); + + object.each((key, value) -> { + depth.set(Math.max(depth.get(), traverseRecursively(value, currentDepth + 1))); + }); + + yield depth.get(); + } + + default -> currentDepth; + }; + } } From 3c6ccd6e2c22b5c896432684c7cf3c9e5e7a263b Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Tue, 8 Apr 2025 03:43:43 -0600 Subject: [PATCH 05/28] fix tests --- json/src/test/java/alpine/json/JsonTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/json/src/test/java/alpine/json/JsonTest.java b/json/src/test/java/alpine/json/JsonTest.java index 80c847c..fa86322 100644 --- a/json/src/test/java/alpine/json/JsonTest.java +++ b/json/src/test/java/alpine/json/JsonTest.java @@ -1,5 +1,6 @@ package alpine.json; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -14,6 +15,7 @@ final class JsonTest { @Test + @Disabled // max stack size varies on different jvms void testRecursion() { try { var element = Json.read("[".repeat(2000) + "]".repeat(2000)); @@ -84,9 +86,8 @@ private static int traverseRecursively(Element element, int currentDepth) { case ArrayElement array -> { var depth = new AtomicInteger(currentDepth); - array.forEach(child -> { - depth.set(Math.max(depth.get(), traverseRecursively(child, currentDepth + 1))); - }); + array.forEach(child -> depth.set(Math.max(depth.get(), + traverseRecursively(child, currentDepth + 1)))); yield depth.get(); } @@ -94,9 +95,8 @@ private static int traverseRecursively(Element element, int currentDepth) { case ObjectElement object -> { AtomicInteger depth = new AtomicInteger(currentDepth); - object.each((key, value) -> { - depth.set(Math.max(depth.get(), traverseRecursively(value, currentDepth + 1))); - }); + object.each((key, value) -> depth.set(Math.max(depth.get(), + traverseRecursively(value, currentDepth + 1)))); yield depth.get(); } From 6b84b228e16eca9eba510e252e76edf3cc487a1f Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Tue, 8 Apr 2025 03:48:45 -0600 Subject: [PATCH 06/28] fix version in readme --- .github/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/README.md b/.github/README.md index b296034..fcfb914 100644 --- a/.github/README.md +++ b/.github/README.md @@ -12,7 +12,7 @@ A binary and JSON serialization library for Java. ```kts dependencies { - implementation("dev.mudkip:alpine-binary:0.1.1") + implementation("dev.mudkip:alpine-binary:0.2.0") implementation("io.netty:netty-buffer:4.2.0.Final") } ``` @@ -25,7 +25,7 @@ dependencies { ```groovy dependencies { - implementation 'dev.mudkip:alpine-binary:0.1.1' + implementation 'dev.mudkip:alpine-binary:0.2.0' implementation 'io.netty:netty-buffer:4.2.0.Final' } ``` @@ -40,7 +40,7 @@ dependencies { dev.mudkip alpine-binary - 0.1.1 + 0.2.0 From ef95a918b129334111b7f8bce0603de3e49a9a9c Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Tue, 8 Apr 2025 09:51:17 -0600 Subject: [PATCH 07/28] fix pretty print --- json/src/main/java/alpine/json/StringElement.java | 10 +--------- json/src/test/java/alpine/json/JsonTest.java | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/json/src/main/java/alpine/json/StringElement.java b/json/src/main/java/alpine/json/StringElement.java index 85a32d9..0a383d8 100644 --- a/json/src/main/java/alpine/json/StringElement.java +++ b/json/src/main/java/alpine/json/StringElement.java @@ -13,14 +13,6 @@ public final class StringElement implements Element { this.value = value; } - private static String prettyPrint(String string) { - return string - .replace("\n", "\\n") - .replace("\r", "\\r") - .replace("\t", "\\t") - .replace("\"", "\\\""); - } - @Override public int hashCode() { return super.hashCode(); @@ -34,7 +26,7 @@ public boolean equals(Object object) { @Override public String toString() { - return prettyPrint(Json.write(this, Json.Formatting.PRETTY)); + return Json.write(this, Json.Formatting.PRETTY); } public String value() { diff --git a/json/src/test/java/alpine/json/JsonTest.java b/json/src/test/java/alpine/json/JsonTest.java index fa86322..bead0bb 100644 --- a/json/src/test/java/alpine/json/JsonTest.java +++ b/json/src/test/java/alpine/json/JsonTest.java @@ -15,7 +15,7 @@ final class JsonTest { @Test - @Disabled // max stack size varies on different jvms + @Disabled("max stack size varies on different jvms") void testRecursion() { try { var element = Json.read("[".repeat(2000) + "]".repeat(2000)); From dd1fa2c0f6b8db444d56417fee562ea0d24c6aee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 11 Apr 2025 14:52:57 +0000 Subject: [PATCH 08/28] Update junit5 monorepo to v5.12.2 --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 5b5828b..34367b0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,8 +22,8 @@ subprojects { dependencies { compileOnly("org.jetbrains:annotations:26.0.2") testImplementation("org.junit.jupiter:junit-jupiter-api:5.12.1") - testImplementation("org.junit.jupiter:junit-jupiter-params:5.12.1") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.12.1") + testImplementation("org.junit.jupiter:junit-jupiter-params:5.12.2") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.12.2") testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.12.1") } From 31cc4863f926bc5fd089a532c32de5f0f7bc6bbf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 11 Apr 2025 19:26:09 +0000 Subject: [PATCH 09/28] Update junit5 monorepo --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 34367b0..a235e09 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,10 +21,10 @@ subprojects { dependencies { compileOnly("org.jetbrains:annotations:26.0.2") - testImplementation("org.junit.jupiter:junit-jupiter-api:5.12.1") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.12.2") testImplementation("org.junit.jupiter:junit-jupiter-params:5.12.2") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.12.2") - testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.12.1") + testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.12.2") } tasks.test { From c2ecb3e4bb7bb41659f879bf8dc109dd9b121b85 Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Fri, 18 Apr 2025 00:28:32 -0600 Subject: [PATCH 10/28] add external test suite --- .../main/java/alpine/json/ArrayElement.java | 12 +++ json/src/main/java/alpine/json/Json.java | 4 + .../src/main/java/alpine/json/JsonReader.java | 2 +- .../test/java/alpine/json/ExternalTest.java | 70 ++++++++++++++++++ .../data/i_number_double_huge_neg_exp.json | 1 + .../resources/data/i_number_huge_exp.json | 1 + .../data/i_number_neg_int_huge_exp.json | 1 + .../data/i_number_pos_double_huge_exp.json | 1 + .../data/i_number_real_neg_overflow.json | 1 + .../data/i_number_real_pos_overflow.json | 1 + .../data/i_number_real_underflow.json | 1 + .../data/i_number_too_big_neg_int.json | 1 + .../data/i_number_too_big_pos_int.json | 1 + .../data/i_number_very_big_negative_int.json | 1 + .../data/i_object_key_lone_2nd_surrogate.json | 1 + ..._string_1st_surrogate_but_2nd_missing.json | 1 + ...tring_1st_valid_surrogate_2nd_invalid.json | 1 + .../data/i_string_UTF-16LE_with_BOM.json | 1 + .../data/i_string_UTF-8_invalid_sequence.json | 1 + .../data/i_string_UTF8_surrogate_U+D800.json | 1 + ...incomplete_surrogate_and_escape_valid.json | 1 + .../i_string_incomplete_surrogate_pair.json | 1 + ...ng_incomplete_surrogates_escape_valid.json | 1 + .../i_string_invalid_lonely_surrogate.json | 1 + .../data/i_string_invalid_surrogate.json | 1 + .../data/i_string_invalid_utf-8.json | 1 + .../i_string_inverted_surrogates_U+1D11E.json | 1 + .../resources/data/i_string_iso_latin_1.json | 1 + .../data/i_string_lone_second_surrogate.json | 1 + .../i_string_lone_utf8_continuation_byte.json | 1 + .../data/i_string_not_in_unicode_range.json | 1 + .../i_string_overlong_sequence_2_bytes.json | 1 + .../i_string_overlong_sequence_6_bytes.json | 1 + ...string_overlong_sequence_6_bytes_null.json | 1 + .../data/i_string_truncated-utf-8.json | 1 + .../data/i_string_utf16BE_no_BOM.json | Bin 0 -> 11 bytes .../data/i_string_utf16LE_no_BOM.json | Bin 0 -> 11 bytes .../data/i_structure_500_nested_arrays.json | 1 + .../i_structure_UTF-8_BOM_empty_object.json | 1 + .../data/n_array_1_true_without_comma.json | 1 + .../data/n_array_a_invalid_utf8.json | 1 + .../data/n_array_colon_instead_of_comma.json | 1 + .../data/n_array_comma_after_close.json | 1 + .../data/n_array_comma_and_number.json | 1 + .../resources/data/n_array_double_comma.json | 1 + .../data/n_array_double_extra_comma.json | 1 + .../resources/data/n_array_extra_close.json | 1 + .../resources/data/n_array_extra_comma.json | 1 + .../resources/data/n_array_incomplete.json | 1 + .../n_array_incomplete_invalid_value.json | 1 + .../data/n_array_inner_array_no_comma.json | 1 + .../resources/data/n_array_invalid_utf8.json | 1 + .../n_array_items_separated_by_semicolon.json | 1 + .../resources/data/n_array_just_comma.json | 1 + .../resources/data/n_array_just_minus.json | 1 + .../resources/data/n_array_missing_value.json | 1 + .../data/n_array_newlines_unclosed.json | 3 + .../data/n_array_number_and_comma.json | 1 + .../n_array_number_and_several_commas.json | 1 + .../n_array_spaces_vertical_tab_formfeed.json | 1 + .../resources/data/n_array_star_inside.json | 1 + .../test/resources/data/n_array_unclosed.json | 1 + .../data/n_array_unclosed_trailing_comma.json | 1 + .../data/n_array_unclosed_with_new_lines.json | 3 + .../n_array_unclosed_with_object_inside.json | 1 + .../resources/data/n_incomplete_false.json | 1 + .../resources/data/n_incomplete_null.json | 1 + .../resources/data/n_incomplete_true.json | 1 + .../data/n_multidigit_number_then_00.json | Bin 0 -> 4 bytes json/src/test/resources/data/n_number_++.json | 1 + json/src/test/resources/data/n_number_+1.json | 1 + .../test/resources/data/n_number_+Inf.json | 1 + .../src/test/resources/data/n_number_-01.json | 1 + .../test/resources/data/n_number_-1.0..json | 1 + .../src/test/resources/data/n_number_-2..json | 1 + .../test/resources/data/n_number_-NaN.json | 1 + .../src/test/resources/data/n_number_.-1.json | 1 + .../test/resources/data/n_number_.2e-3.json | 1 + .../test/resources/data/n_number_0.1.2.json | 1 + .../test/resources/data/n_number_0.3e+.json | 1 + .../test/resources/data/n_number_0.3e.json | 1 + .../test/resources/data/n_number_0.e1.json | 1 + .../resources/data/n_number_0_capital_E+.json | 1 + .../resources/data/n_number_0_capital_E.json | 1 + .../src/test/resources/data/n_number_0e+.json | 1 + json/src/test/resources/data/n_number_0e.json | 1 + .../test/resources/data/n_number_1.0e+.json | 1 + .../test/resources/data/n_number_1.0e-.json | 1 + .../test/resources/data/n_number_1.0e.json | 1 + .../test/resources/data/n_number_1_000.json | 1 + .../test/resources/data/n_number_1eE2.json | 1 + .../test/resources/data/n_number_2.e+3.json | 1 + .../test/resources/data/n_number_2.e-3.json | 1 + .../test/resources/data/n_number_2.e3.json | 1 + .../test/resources/data/n_number_9.e+.json | 1 + .../src/test/resources/data/n_number_Inf.json | 1 + .../src/test/resources/data/n_number_NaN.json | 1 + .../n_number_U+FF11_fullwidth_digit_one.json | 1 + .../resources/data/n_number_expression.json | 1 + .../resources/data/n_number_hex_1_digit.json | 1 + .../resources/data/n_number_hex_2_digits.json | 1 + .../resources/data/n_number_infinity.json | 1 + .../resources/data/n_number_invalid+-.json | 1 + .../data/n_number_invalid-negative-real.json | 1 + .../n_number_invalid-utf-8-in-bigger-int.json | 1 + .../n_number_invalid-utf-8-in-exponent.json | 1 + .../data/n_number_invalid-utf-8-in-int.json | 1 + .../data/n_number_minus_infinity.json | 1 + ...mber_minus_sign_with_trailing_garbage.json | 1 + .../data/n_number_minus_space_1.json | 1 + .../n_number_neg_int_starting_with_zero.json | 1 + .../n_number_neg_real_without_int_part.json | 1 + .../n_number_neg_with_garbage_at_end.json | 1 + .../data/n_number_real_garbage_after_e.json | 1 + ...number_real_with_invalid_utf8_after_e.json | 1 + ...n_number_real_without_fractional_part.json | 1 + .../data/n_number_starting_with_dot.json | 1 + .../resources/data/n_number_with_alpha.json | 1 + .../data/n_number_with_alpha_char.json | 1 + .../data/n_number_with_leading_zero.json | 1 + .../resources/data/n_object_bad_value.json | 1 + .../resources/data/n_object_bracket_key.json | 1 + .../data/n_object_comma_instead_of_colon.json | 1 + .../resources/data/n_object_double_colon.json | 1 + .../test/resources/data/n_object_emoji.json | 1 + .../data/n_object_garbage_at_end.json | 1 + .../data/n_object_key_with_single_quotes.json | 1 + ...uation_byte_in_key_and_trailing_comma.json | 1 + .../data/n_object_missing_colon.json | 1 + .../resources/data/n_object_missing_key.json | 1 + .../data/n_object_missing_semicolon.json | 1 + .../data/n_object_missing_value.json | 1 + .../resources/data/n_object_no-colon.json | 1 + .../data/n_object_non_string_key.json | 1 + ...on_string_key_but_huge_number_instead.json | 1 + .../data/n_object_repeated_null_null.json | 1 + .../n_object_several_trailing_commas.json | 1 + .../resources/data/n_object_single_quote.json | 1 + .../data/n_object_trailing_comma.json | 1 + .../data/n_object_trailing_comment.json | 1 + .../data/n_object_trailing_comment_open.json | 1 + .../n_object_trailing_comment_slash_open.json | 1 + ...railing_comment_slash_open_incomplete.json | 1 + .../data/n_object_two_commas_in_a_row.json | 1 + .../resources/data/n_object_unquoted_key.json | 1 + .../data/n_object_unterminated-value.json | 1 + .../data/n_object_with_single_string.json | 1 + .../data/n_object_with_trailing_garbage.json | 1 + .../test/resources/data/n_single_space.json | 1 + .../n_string_1_surrogate_then_escape.json | 1 + .../n_string_1_surrogate_then_escape_u.json | 1 + .../n_string_1_surrogate_then_escape_u1.json | 1 + .../n_string_1_surrogate_then_escape_u1x.json | 1 + .../n_string_accentuated_char_no_quotes.json | 1 + .../resources/data/n_string_backslash_00.json | Bin 0 -> 6 bytes .../resources/data/n_string_escape_x.json | 1 + .../data/n_string_escaped_backslash_bad.json | 1 + .../data/n_string_escaped_ctrl_char_tab.json | 1 + .../data/n_string_escaped_emoji.json | 1 + .../data/n_string_incomplete_escape.json | 1 + ...n_string_incomplete_escaped_character.json | 1 + .../data/n_string_incomplete_surrogate.json | 1 + ...g_incomplete_surrogate_escape_invalid.json | 1 + .../n_string_invalid-utf-8-in-escape.json | 1 + .../data/n_string_invalid_backslash_esc.json | 1 + .../data/n_string_invalid_unicode_escape.json | 1 + .../n_string_invalid_utf8_after_escape.json | 1 + .../n_string_leading_uescaped_thinspace.json | 1 + .../n_string_no_quotes_with_bad_escape.json | 1 + .../data/n_string_single_doublequote.json | 1 + .../resources/data/n_string_single_quote.json | 1 + ...string_single_string_no_double_quotes.json | 1 + .../data/n_string_start_escape_unclosed.json | 1 + .../data/n_string_unescaped_ctrl_char.json | Bin 0 -> 7 bytes .../data/n_string_unescaped_newline.json | 2 + .../data/n_string_unescaped_tab.json | 1 + .../data/n_string_unicode_CapitalU.json | 1 + .../data/n_string_with_trailing_garbage.json | 1 + .../n_structure_100000_opening_arrays.json | 1 + .../data/n_structure_U+2060_word_joined.json | 1 + .../data/n_structure_UTF8_BOM_no_data.json | 1 + .../data/n_structure_angle_bracket_..json | 1 + .../data/n_structure_angle_bracket_null.json | 1 + .../n_structure_array_trailing_garbage.json | 1 + ...tructure_array_with_extra_array_close.json | 1 + ..._structure_array_with_unclosed_string.json | 1 + .../n_structure_ascii-unicode-identifier.json | 1 + .../data/n_structure_capitalized_True.json | 1 + .../n_structure_close_unopened_array.json | 1 + ...ucture_comma_instead_of_closing_brace.json | 1 + .../data/n_structure_double_array.json | 1 + .../resources/data/n_structure_end_array.json | 1 + .../data/n_structure_incomplete_UTF8_BOM.json | 1 + .../data/n_structure_lone-invalid-utf-8.json | 1 + .../data/n_structure_lone-open-bracket.json | 1 + .../resources/data/n_structure_no_data.json | 0 .../n_structure_null-byte-outside-string.json | Bin 0 -> 3 bytes ...tructure_number_with_trailing_garbage.json | 1 + ...ure_object_followed_by_closing_object.json | 1 + .../n_structure_object_unclosed_no_value.json | 1 + .../data/n_structure_object_with_comment.json | 1 + ...tructure_object_with_trailing_garbage.json | 1 + .../n_structure_open_array_apostrophe.json | 1 + .../data/n_structure_open_array_comma.json | 1 + .../data/n_structure_open_array_object.json | 1 + .../n_structure_open_array_open_object.json | 1 + .../n_structure_open_array_open_string.json | 1 + .../data/n_structure_open_array_string.json | 1 + .../data/n_structure_open_object.json | 1 + .../n_structure_open_object_close_array.json | 1 + .../data/n_structure_open_object_comma.json | 1 + .../n_structure_open_object_open_array.json | 1 + .../n_structure_open_object_open_string.json | 1 + ...e_open_object_string_with_apostrophes.json | 1 + .../resources/data/n_structure_open_open.json | 1 + .../data/n_structure_single_eacute.json | 1 + .../data/n_structure_single_star.json | 1 + .../data/n_structure_trailing_#.json | 1 + ...n_structure_uescaped_LF_before_string.json | 1 + .../data/n_structure_unclosed_array.json | 1 + ...structure_unclosed_array_partial_null.json | 1 + ...cture_unclosed_array_unfinished_false.json | 1 + ...ucture_unclosed_array_unfinished_true.json | 1 + .../data/n_structure_unclosed_object.json | 1 + .../data/n_structure_unicode-identifier.json | 1 + ...ructure_whitespace_U+2060_word_joiner.json | 1 + .../data/n_structure_whitespace_formfeed.json | 1 + .../data/y_array_arraysWithSpaces.json | 1 + .../resources/data/y_array_empty-string.json | 1 + .../test/resources/data/y_array_empty.json | 1 + .../data/y_array_ending_with_newline.json | 1 + .../test/resources/data/y_array_false.json | 1 + .../resources/data/y_array_heterogeneous.json | 1 + .../src/test/resources/data/y_array_null.json | 1 + .../data/y_array_with_1_and_newline.json | 2 + .../data/y_array_with_leading_space.json | 1 + .../data/y_array_with_several_null.json | 1 + .../data/y_array_with_trailing_space.json | 1 + json/src/test/resources/data/y_number.json | 1 + .../test/resources/data/y_number_0e+1.json | 1 + .../src/test/resources/data/y_number_0e1.json | 1 + .../resources/data/y_number_after_space.json | 1 + .../data/y_number_double_close_to_zero.json | 1 + .../resources/data/y_number_int_with_exp.json | 1 + .../resources/data/y_number_minus_zero.json | 1 + .../resources/data/y_number_negative_int.json | 1 + .../resources/data/y_number_negative_one.json | 1 + .../data/y_number_negative_zero.json | 1 + .../data/y_number_real_capital_e.json | 1 + .../data/y_number_real_capital_e_neg_exp.json | 1 + .../data/y_number_real_capital_e_pos_exp.json | 1 + .../data/y_number_real_exponent.json | 1 + .../data/y_number_real_fraction_exponent.json | 1 + .../resources/data/y_number_real_neg_exp.json | 1 + .../data/y_number_real_pos_exponent.json | 1 + .../resources/data/y_number_simple_int.json | 1 + .../resources/data/y_number_simple_real.json | 1 + json/src/test/resources/data/y_object.json | 1 + .../test/resources/data/y_object_basic.json | 1 + .../data/y_object_duplicated_key.json | 1 + .../y_object_duplicated_key_and_value.json | 1 + .../test/resources/data/y_object_empty.json | 1 + .../resources/data/y_object_empty_key.json | 1 + .../data/y_object_escaped_null_in_key.json | 1 + .../data/y_object_extreme_numbers.json | 1 + .../resources/data/y_object_long_strings.json | 1 + .../test/resources/data/y_object_simple.json | 1 + .../data/y_object_string_unicode.json | 1 + .../data/y_object_with_newlines.json | 3 + .../y_string_1_2_3_bytes_UTF-8_sequences.json | 1 + .../y_string_accepted_surrogate_pair.json | 1 + .../y_string_accepted_surrogate_pairs.json | 1 + .../data/y_string_allowed_escapes.json | 1 + ...y_string_backslash_and_u_escaped_zero.json | 1 + .../data/y_string_backslash_doublequotes.json | 1 + .../resources/data/y_string_comments.json | 1 + .../data/y_string_double_escape_a.json | 1 + .../data/y_string_double_escape_n.json | 1 + .../y_string_escaped_control_character.json | 1 + .../data/y_string_escaped_noncharacter.json | 1 + .../resources/data/y_string_in_array.json | 1 + .../y_string_in_array_with_leading_space.json | 1 + .../y_string_last_surrogates_1_and_2.json | 1 + .../data/y_string_nbsp_uescaped.json | 1 + ...y_string_nonCharacterInUTF-8_U+10FFFF.json | 1 + .../y_string_nonCharacterInUTF-8_U+FFFF.json | 1 + .../resources/data/y_string_null_escape.json | 1 + .../data/y_string_one-byte-utf-8.json | 1 + json/src/test/resources/data/y_string_pi.json | 1 + ...ring_reservedCharacterInUTF-8_U+1BFFF.json | 1 + .../resources/data/y_string_simple_ascii.json | 1 + .../test/resources/data/y_string_space.json | 1 + ...rogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json | 1 + .../data/y_string_three-byte-utf-8.json | 1 + .../data/y_string_two-byte-utf-8.json | 1 + .../data/y_string_u+2028_line_sep.json | 1 + .../data/y_string_u+2029_par_sep.json | 1 + .../test/resources/data/y_string_uEscape.json | 1 + .../data/y_string_uescaped_newline.json | 1 + .../data/y_string_unescaped_char_delete.json | 1 + .../test/resources/data/y_string_unicode.json | 1 + .../y_string_unicodeEscapedBackslash.json | 1 + .../resources/data/y_string_unicode_2.json | 1 + .../y_string_unicode_U+10FFFE_nonchar.json | 1 + .../y_string_unicode_U+1FFFE_nonchar.json | 1 + ...tring_unicode_U+200B_ZERO_WIDTH_SPACE.json | 1 + ..._string_unicode_U+2064_invisible_plus.json | 1 + .../data/y_string_unicode_U+FDD0_nonchar.json | 1 + .../data/y_string_unicode_U+FFFE_nonchar.json | 1 + ...y_string_unicode_escaped_double_quote.json | 1 + .../test/resources/data/y_string_utf8.json | 1 + .../data/y_string_with_del_character.json | 1 + .../data/y_structure_lonely_false.json | 1 + .../data/y_structure_lonely_int.json | 1 + .../y_structure_lonely_negative_real.json | 1 + .../data/y_structure_lonely_null.json | 1 + .../data/y_structure_lonely_string.json | 1 + .../data/y_structure_lonely_true.json | 1 + .../data/y_structure_string_empty.json | 1 + .../data/y_structure_trailing_newline.json | 1 + .../data/y_structure_true_in_array.json | 1 + .../data/y_structure_whitespace_array.json | 1 + 322 files changed, 406 insertions(+), 1 deletion(-) create mode 100644 json/src/test/java/alpine/json/ExternalTest.java create mode 100644 json/src/test/resources/data/i_number_double_huge_neg_exp.json create mode 100644 json/src/test/resources/data/i_number_huge_exp.json create mode 100644 json/src/test/resources/data/i_number_neg_int_huge_exp.json create mode 100644 json/src/test/resources/data/i_number_pos_double_huge_exp.json create mode 100644 json/src/test/resources/data/i_number_real_neg_overflow.json create mode 100644 json/src/test/resources/data/i_number_real_pos_overflow.json create mode 100644 json/src/test/resources/data/i_number_real_underflow.json create mode 100644 json/src/test/resources/data/i_number_too_big_neg_int.json create mode 100644 json/src/test/resources/data/i_number_too_big_pos_int.json create mode 100644 json/src/test/resources/data/i_number_very_big_negative_int.json create mode 100644 json/src/test/resources/data/i_object_key_lone_2nd_surrogate.json create mode 100644 json/src/test/resources/data/i_string_1st_surrogate_but_2nd_missing.json create mode 100644 json/src/test/resources/data/i_string_1st_valid_surrogate_2nd_invalid.json create mode 100644 json/src/test/resources/data/i_string_UTF-16LE_with_BOM.json create mode 100755 json/src/test/resources/data/i_string_UTF-8_invalid_sequence.json create mode 100644 json/src/test/resources/data/i_string_UTF8_surrogate_U+D800.json create mode 100644 json/src/test/resources/data/i_string_incomplete_surrogate_and_escape_valid.json create mode 100644 json/src/test/resources/data/i_string_incomplete_surrogate_pair.json create mode 100644 json/src/test/resources/data/i_string_incomplete_surrogates_escape_valid.json create mode 100644 json/src/test/resources/data/i_string_invalid_lonely_surrogate.json create mode 100644 json/src/test/resources/data/i_string_invalid_surrogate.json create mode 100644 json/src/test/resources/data/i_string_invalid_utf-8.json create mode 100644 json/src/test/resources/data/i_string_inverted_surrogates_U+1D11E.json create mode 100644 json/src/test/resources/data/i_string_iso_latin_1.json create mode 100644 json/src/test/resources/data/i_string_lone_second_surrogate.json create mode 100644 json/src/test/resources/data/i_string_lone_utf8_continuation_byte.json create mode 100644 json/src/test/resources/data/i_string_not_in_unicode_range.json create mode 100644 json/src/test/resources/data/i_string_overlong_sequence_2_bytes.json create mode 100644 json/src/test/resources/data/i_string_overlong_sequence_6_bytes.json create mode 100644 json/src/test/resources/data/i_string_overlong_sequence_6_bytes_null.json create mode 100644 json/src/test/resources/data/i_string_truncated-utf-8.json create mode 100644 json/src/test/resources/data/i_string_utf16BE_no_BOM.json create mode 100644 json/src/test/resources/data/i_string_utf16LE_no_BOM.json create mode 100644 json/src/test/resources/data/i_structure_500_nested_arrays.json create mode 100644 json/src/test/resources/data/i_structure_UTF-8_BOM_empty_object.json create mode 100644 json/src/test/resources/data/n_array_1_true_without_comma.json create mode 100644 json/src/test/resources/data/n_array_a_invalid_utf8.json create mode 100644 json/src/test/resources/data/n_array_colon_instead_of_comma.json create mode 100644 json/src/test/resources/data/n_array_comma_after_close.json create mode 100644 json/src/test/resources/data/n_array_comma_and_number.json create mode 100644 json/src/test/resources/data/n_array_double_comma.json create mode 100644 json/src/test/resources/data/n_array_double_extra_comma.json create mode 100644 json/src/test/resources/data/n_array_extra_close.json create mode 100644 json/src/test/resources/data/n_array_extra_comma.json create mode 100644 json/src/test/resources/data/n_array_incomplete.json create mode 100644 json/src/test/resources/data/n_array_incomplete_invalid_value.json create mode 100644 json/src/test/resources/data/n_array_inner_array_no_comma.json create mode 100644 json/src/test/resources/data/n_array_invalid_utf8.json create mode 100644 json/src/test/resources/data/n_array_items_separated_by_semicolon.json create mode 100644 json/src/test/resources/data/n_array_just_comma.json create mode 100644 json/src/test/resources/data/n_array_just_minus.json create mode 100644 json/src/test/resources/data/n_array_missing_value.json create mode 100644 json/src/test/resources/data/n_array_newlines_unclosed.json create mode 100644 json/src/test/resources/data/n_array_number_and_comma.json create mode 100644 json/src/test/resources/data/n_array_number_and_several_commas.json create mode 100644 json/src/test/resources/data/n_array_spaces_vertical_tab_formfeed.json create mode 100644 json/src/test/resources/data/n_array_star_inside.json create mode 100644 json/src/test/resources/data/n_array_unclosed.json create mode 100644 json/src/test/resources/data/n_array_unclosed_trailing_comma.json create mode 100644 json/src/test/resources/data/n_array_unclosed_with_new_lines.json create mode 100644 json/src/test/resources/data/n_array_unclosed_with_object_inside.json create mode 100644 json/src/test/resources/data/n_incomplete_false.json create mode 100644 json/src/test/resources/data/n_incomplete_null.json create mode 100644 json/src/test/resources/data/n_incomplete_true.json create mode 100644 json/src/test/resources/data/n_multidigit_number_then_00.json create mode 100644 json/src/test/resources/data/n_number_++.json create mode 100644 json/src/test/resources/data/n_number_+1.json create mode 100644 json/src/test/resources/data/n_number_+Inf.json create mode 100644 json/src/test/resources/data/n_number_-01.json create mode 100644 json/src/test/resources/data/n_number_-1.0..json create mode 100644 json/src/test/resources/data/n_number_-2..json create mode 100644 json/src/test/resources/data/n_number_-NaN.json create mode 100644 json/src/test/resources/data/n_number_.-1.json create mode 100644 json/src/test/resources/data/n_number_.2e-3.json create mode 100644 json/src/test/resources/data/n_number_0.1.2.json create mode 100644 json/src/test/resources/data/n_number_0.3e+.json create mode 100644 json/src/test/resources/data/n_number_0.3e.json create mode 100644 json/src/test/resources/data/n_number_0.e1.json create mode 100644 json/src/test/resources/data/n_number_0_capital_E+.json create mode 100644 json/src/test/resources/data/n_number_0_capital_E.json create mode 100644 json/src/test/resources/data/n_number_0e+.json create mode 100644 json/src/test/resources/data/n_number_0e.json create mode 100644 json/src/test/resources/data/n_number_1.0e+.json create mode 100644 json/src/test/resources/data/n_number_1.0e-.json create mode 100644 json/src/test/resources/data/n_number_1.0e.json create mode 100644 json/src/test/resources/data/n_number_1_000.json create mode 100644 json/src/test/resources/data/n_number_1eE2.json create mode 100644 json/src/test/resources/data/n_number_2.e+3.json create mode 100644 json/src/test/resources/data/n_number_2.e-3.json create mode 100644 json/src/test/resources/data/n_number_2.e3.json create mode 100644 json/src/test/resources/data/n_number_9.e+.json create mode 100644 json/src/test/resources/data/n_number_Inf.json create mode 100644 json/src/test/resources/data/n_number_NaN.json create mode 100644 json/src/test/resources/data/n_number_U+FF11_fullwidth_digit_one.json create mode 100644 json/src/test/resources/data/n_number_expression.json create mode 100644 json/src/test/resources/data/n_number_hex_1_digit.json create mode 100644 json/src/test/resources/data/n_number_hex_2_digits.json create mode 100644 json/src/test/resources/data/n_number_infinity.json create mode 100644 json/src/test/resources/data/n_number_invalid+-.json create mode 100644 json/src/test/resources/data/n_number_invalid-negative-real.json create mode 100644 json/src/test/resources/data/n_number_invalid-utf-8-in-bigger-int.json create mode 100644 json/src/test/resources/data/n_number_invalid-utf-8-in-exponent.json create mode 100644 json/src/test/resources/data/n_number_invalid-utf-8-in-int.json create mode 100644 json/src/test/resources/data/n_number_minus_infinity.json create mode 100644 json/src/test/resources/data/n_number_minus_sign_with_trailing_garbage.json create mode 100644 json/src/test/resources/data/n_number_minus_space_1.json create mode 100644 json/src/test/resources/data/n_number_neg_int_starting_with_zero.json create mode 100644 json/src/test/resources/data/n_number_neg_real_without_int_part.json create mode 100644 json/src/test/resources/data/n_number_neg_with_garbage_at_end.json create mode 100644 json/src/test/resources/data/n_number_real_garbage_after_e.json create mode 100644 json/src/test/resources/data/n_number_real_with_invalid_utf8_after_e.json create mode 100644 json/src/test/resources/data/n_number_real_without_fractional_part.json create mode 100644 json/src/test/resources/data/n_number_starting_with_dot.json create mode 100644 json/src/test/resources/data/n_number_with_alpha.json create mode 100644 json/src/test/resources/data/n_number_with_alpha_char.json create mode 100644 json/src/test/resources/data/n_number_with_leading_zero.json create mode 100644 json/src/test/resources/data/n_object_bad_value.json create mode 100644 json/src/test/resources/data/n_object_bracket_key.json create mode 100644 json/src/test/resources/data/n_object_comma_instead_of_colon.json create mode 100644 json/src/test/resources/data/n_object_double_colon.json create mode 100644 json/src/test/resources/data/n_object_emoji.json create mode 100644 json/src/test/resources/data/n_object_garbage_at_end.json create mode 100644 json/src/test/resources/data/n_object_key_with_single_quotes.json create mode 100644 json/src/test/resources/data/n_object_lone_continuation_byte_in_key_and_trailing_comma.json create mode 100644 json/src/test/resources/data/n_object_missing_colon.json create mode 100644 json/src/test/resources/data/n_object_missing_key.json create mode 100644 json/src/test/resources/data/n_object_missing_semicolon.json create mode 100644 json/src/test/resources/data/n_object_missing_value.json create mode 100644 json/src/test/resources/data/n_object_no-colon.json create mode 100644 json/src/test/resources/data/n_object_non_string_key.json create mode 100644 json/src/test/resources/data/n_object_non_string_key_but_huge_number_instead.json create mode 100644 json/src/test/resources/data/n_object_repeated_null_null.json create mode 100644 json/src/test/resources/data/n_object_several_trailing_commas.json create mode 100644 json/src/test/resources/data/n_object_single_quote.json create mode 100644 json/src/test/resources/data/n_object_trailing_comma.json create mode 100644 json/src/test/resources/data/n_object_trailing_comment.json create mode 100644 json/src/test/resources/data/n_object_trailing_comment_open.json create mode 100644 json/src/test/resources/data/n_object_trailing_comment_slash_open.json create mode 100644 json/src/test/resources/data/n_object_trailing_comment_slash_open_incomplete.json create mode 100644 json/src/test/resources/data/n_object_two_commas_in_a_row.json create mode 100644 json/src/test/resources/data/n_object_unquoted_key.json create mode 100644 json/src/test/resources/data/n_object_unterminated-value.json create mode 100644 json/src/test/resources/data/n_object_with_single_string.json create mode 100644 json/src/test/resources/data/n_object_with_trailing_garbage.json create mode 100644 json/src/test/resources/data/n_single_space.json create mode 100644 json/src/test/resources/data/n_string_1_surrogate_then_escape.json create mode 100644 json/src/test/resources/data/n_string_1_surrogate_then_escape_u.json create mode 100644 json/src/test/resources/data/n_string_1_surrogate_then_escape_u1.json create mode 100644 json/src/test/resources/data/n_string_1_surrogate_then_escape_u1x.json create mode 100644 json/src/test/resources/data/n_string_accentuated_char_no_quotes.json create mode 100644 json/src/test/resources/data/n_string_backslash_00.json create mode 100644 json/src/test/resources/data/n_string_escape_x.json create mode 100644 json/src/test/resources/data/n_string_escaped_backslash_bad.json create mode 100644 json/src/test/resources/data/n_string_escaped_ctrl_char_tab.json create mode 100644 json/src/test/resources/data/n_string_escaped_emoji.json create mode 100644 json/src/test/resources/data/n_string_incomplete_escape.json create mode 100644 json/src/test/resources/data/n_string_incomplete_escaped_character.json create mode 100644 json/src/test/resources/data/n_string_incomplete_surrogate.json create mode 100644 json/src/test/resources/data/n_string_incomplete_surrogate_escape_invalid.json create mode 100644 json/src/test/resources/data/n_string_invalid-utf-8-in-escape.json create mode 100644 json/src/test/resources/data/n_string_invalid_backslash_esc.json create mode 100644 json/src/test/resources/data/n_string_invalid_unicode_escape.json create mode 100644 json/src/test/resources/data/n_string_invalid_utf8_after_escape.json create mode 100644 json/src/test/resources/data/n_string_leading_uescaped_thinspace.json create mode 100644 json/src/test/resources/data/n_string_no_quotes_with_bad_escape.json create mode 100644 json/src/test/resources/data/n_string_single_doublequote.json create mode 100644 json/src/test/resources/data/n_string_single_quote.json create mode 100644 json/src/test/resources/data/n_string_single_string_no_double_quotes.json create mode 100644 json/src/test/resources/data/n_string_start_escape_unclosed.json create mode 100644 json/src/test/resources/data/n_string_unescaped_ctrl_char.json create mode 100644 json/src/test/resources/data/n_string_unescaped_newline.json create mode 100644 json/src/test/resources/data/n_string_unescaped_tab.json create mode 100644 json/src/test/resources/data/n_string_unicode_CapitalU.json create mode 100644 json/src/test/resources/data/n_string_with_trailing_garbage.json create mode 100644 json/src/test/resources/data/n_structure_100000_opening_arrays.json create mode 100644 json/src/test/resources/data/n_structure_U+2060_word_joined.json create mode 100644 json/src/test/resources/data/n_structure_UTF8_BOM_no_data.json create mode 100644 json/src/test/resources/data/n_structure_angle_bracket_..json create mode 100644 json/src/test/resources/data/n_structure_angle_bracket_null.json create mode 100644 json/src/test/resources/data/n_structure_array_trailing_garbage.json create mode 100644 json/src/test/resources/data/n_structure_array_with_extra_array_close.json create mode 100644 json/src/test/resources/data/n_structure_array_with_unclosed_string.json create mode 100644 json/src/test/resources/data/n_structure_ascii-unicode-identifier.json create mode 100644 json/src/test/resources/data/n_structure_capitalized_True.json create mode 100644 json/src/test/resources/data/n_structure_close_unopened_array.json create mode 100644 json/src/test/resources/data/n_structure_comma_instead_of_closing_brace.json create mode 100644 json/src/test/resources/data/n_structure_double_array.json create mode 100644 json/src/test/resources/data/n_structure_end_array.json create mode 100644 json/src/test/resources/data/n_structure_incomplete_UTF8_BOM.json create mode 100644 json/src/test/resources/data/n_structure_lone-invalid-utf-8.json create mode 100644 json/src/test/resources/data/n_structure_lone-open-bracket.json create mode 100644 json/src/test/resources/data/n_structure_no_data.json create mode 100644 json/src/test/resources/data/n_structure_null-byte-outside-string.json create mode 100644 json/src/test/resources/data/n_structure_number_with_trailing_garbage.json create mode 100644 json/src/test/resources/data/n_structure_object_followed_by_closing_object.json create mode 100644 json/src/test/resources/data/n_structure_object_unclosed_no_value.json create mode 100644 json/src/test/resources/data/n_structure_object_with_comment.json create mode 100644 json/src/test/resources/data/n_structure_object_with_trailing_garbage.json create mode 100644 json/src/test/resources/data/n_structure_open_array_apostrophe.json create mode 100644 json/src/test/resources/data/n_structure_open_array_comma.json create mode 100644 json/src/test/resources/data/n_structure_open_array_object.json create mode 100644 json/src/test/resources/data/n_structure_open_array_open_object.json create mode 100644 json/src/test/resources/data/n_structure_open_array_open_string.json create mode 100644 json/src/test/resources/data/n_structure_open_array_string.json create mode 100644 json/src/test/resources/data/n_structure_open_object.json create mode 100644 json/src/test/resources/data/n_structure_open_object_close_array.json create mode 100644 json/src/test/resources/data/n_structure_open_object_comma.json create mode 100644 json/src/test/resources/data/n_structure_open_object_open_array.json create mode 100644 json/src/test/resources/data/n_structure_open_object_open_string.json create mode 100644 json/src/test/resources/data/n_structure_open_object_string_with_apostrophes.json create mode 100644 json/src/test/resources/data/n_structure_open_open.json create mode 100644 json/src/test/resources/data/n_structure_single_eacute.json create mode 100644 json/src/test/resources/data/n_structure_single_star.json create mode 100644 json/src/test/resources/data/n_structure_trailing_#.json create mode 100644 json/src/test/resources/data/n_structure_uescaped_LF_before_string.json create mode 100644 json/src/test/resources/data/n_structure_unclosed_array.json create mode 100644 json/src/test/resources/data/n_structure_unclosed_array_partial_null.json create mode 100644 json/src/test/resources/data/n_structure_unclosed_array_unfinished_false.json create mode 100644 json/src/test/resources/data/n_structure_unclosed_array_unfinished_true.json create mode 100644 json/src/test/resources/data/n_structure_unclosed_object.json create mode 100644 json/src/test/resources/data/n_structure_unicode-identifier.json create mode 100644 json/src/test/resources/data/n_structure_whitespace_U+2060_word_joiner.json create mode 100644 json/src/test/resources/data/n_structure_whitespace_formfeed.json create mode 100644 json/src/test/resources/data/y_array_arraysWithSpaces.json create mode 100644 json/src/test/resources/data/y_array_empty-string.json create mode 100644 json/src/test/resources/data/y_array_empty.json create mode 100644 json/src/test/resources/data/y_array_ending_with_newline.json create mode 100644 json/src/test/resources/data/y_array_false.json create mode 100644 json/src/test/resources/data/y_array_heterogeneous.json create mode 100644 json/src/test/resources/data/y_array_null.json create mode 100644 json/src/test/resources/data/y_array_with_1_and_newline.json create mode 100644 json/src/test/resources/data/y_array_with_leading_space.json create mode 100644 json/src/test/resources/data/y_array_with_several_null.json create mode 100644 json/src/test/resources/data/y_array_with_trailing_space.json create mode 100644 json/src/test/resources/data/y_number.json create mode 100644 json/src/test/resources/data/y_number_0e+1.json create mode 100644 json/src/test/resources/data/y_number_0e1.json create mode 100644 json/src/test/resources/data/y_number_after_space.json create mode 100644 json/src/test/resources/data/y_number_double_close_to_zero.json create mode 100644 json/src/test/resources/data/y_number_int_with_exp.json create mode 100644 json/src/test/resources/data/y_number_minus_zero.json create mode 100644 json/src/test/resources/data/y_number_negative_int.json create mode 100644 json/src/test/resources/data/y_number_negative_one.json create mode 100644 json/src/test/resources/data/y_number_negative_zero.json create mode 100644 json/src/test/resources/data/y_number_real_capital_e.json create mode 100644 json/src/test/resources/data/y_number_real_capital_e_neg_exp.json create mode 100644 json/src/test/resources/data/y_number_real_capital_e_pos_exp.json create mode 100644 json/src/test/resources/data/y_number_real_exponent.json create mode 100644 json/src/test/resources/data/y_number_real_fraction_exponent.json create mode 100644 json/src/test/resources/data/y_number_real_neg_exp.json create mode 100644 json/src/test/resources/data/y_number_real_pos_exponent.json create mode 100644 json/src/test/resources/data/y_number_simple_int.json create mode 100644 json/src/test/resources/data/y_number_simple_real.json create mode 100644 json/src/test/resources/data/y_object.json create mode 100644 json/src/test/resources/data/y_object_basic.json create mode 100644 json/src/test/resources/data/y_object_duplicated_key.json create mode 100644 json/src/test/resources/data/y_object_duplicated_key_and_value.json create mode 100644 json/src/test/resources/data/y_object_empty.json create mode 100644 json/src/test/resources/data/y_object_empty_key.json create mode 100644 json/src/test/resources/data/y_object_escaped_null_in_key.json create mode 100644 json/src/test/resources/data/y_object_extreme_numbers.json create mode 100644 json/src/test/resources/data/y_object_long_strings.json create mode 100644 json/src/test/resources/data/y_object_simple.json create mode 100644 json/src/test/resources/data/y_object_string_unicode.json create mode 100644 json/src/test/resources/data/y_object_with_newlines.json create mode 100644 json/src/test/resources/data/y_string_1_2_3_bytes_UTF-8_sequences.json create mode 100644 json/src/test/resources/data/y_string_accepted_surrogate_pair.json create mode 100644 json/src/test/resources/data/y_string_accepted_surrogate_pairs.json create mode 100644 json/src/test/resources/data/y_string_allowed_escapes.json create mode 100644 json/src/test/resources/data/y_string_backslash_and_u_escaped_zero.json create mode 100644 json/src/test/resources/data/y_string_backslash_doublequotes.json create mode 100644 json/src/test/resources/data/y_string_comments.json create mode 100644 json/src/test/resources/data/y_string_double_escape_a.json create mode 100644 json/src/test/resources/data/y_string_double_escape_n.json create mode 100644 json/src/test/resources/data/y_string_escaped_control_character.json create mode 100644 json/src/test/resources/data/y_string_escaped_noncharacter.json create mode 100644 json/src/test/resources/data/y_string_in_array.json create mode 100644 json/src/test/resources/data/y_string_in_array_with_leading_space.json create mode 100644 json/src/test/resources/data/y_string_last_surrogates_1_and_2.json create mode 100644 json/src/test/resources/data/y_string_nbsp_uescaped.json create mode 100644 json/src/test/resources/data/y_string_nonCharacterInUTF-8_U+10FFFF.json create mode 100644 json/src/test/resources/data/y_string_nonCharacterInUTF-8_U+FFFF.json create mode 100644 json/src/test/resources/data/y_string_null_escape.json create mode 100644 json/src/test/resources/data/y_string_one-byte-utf-8.json create mode 100644 json/src/test/resources/data/y_string_pi.json create mode 100644 json/src/test/resources/data/y_string_reservedCharacterInUTF-8_U+1BFFF.json create mode 100644 json/src/test/resources/data/y_string_simple_ascii.json create mode 100644 json/src/test/resources/data/y_string_space.json create mode 100644 json/src/test/resources/data/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json create mode 100644 json/src/test/resources/data/y_string_three-byte-utf-8.json create mode 100644 json/src/test/resources/data/y_string_two-byte-utf-8.json create mode 100644 json/src/test/resources/data/y_string_u+2028_line_sep.json create mode 100644 json/src/test/resources/data/y_string_u+2029_par_sep.json create mode 100644 json/src/test/resources/data/y_string_uEscape.json create mode 100644 json/src/test/resources/data/y_string_uescaped_newline.json create mode 100644 json/src/test/resources/data/y_string_unescaped_char_delete.json create mode 100644 json/src/test/resources/data/y_string_unicode.json create mode 100644 json/src/test/resources/data/y_string_unicodeEscapedBackslash.json create mode 100644 json/src/test/resources/data/y_string_unicode_2.json create mode 100644 json/src/test/resources/data/y_string_unicode_U+10FFFE_nonchar.json create mode 100644 json/src/test/resources/data/y_string_unicode_U+1FFFE_nonchar.json create mode 100644 json/src/test/resources/data/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json create mode 100644 json/src/test/resources/data/y_string_unicode_U+2064_invisible_plus.json create mode 100644 json/src/test/resources/data/y_string_unicode_U+FDD0_nonchar.json create mode 100644 json/src/test/resources/data/y_string_unicode_U+FFFE_nonchar.json create mode 100644 json/src/test/resources/data/y_string_unicode_escaped_double_quote.json create mode 100644 json/src/test/resources/data/y_string_utf8.json create mode 100644 json/src/test/resources/data/y_string_with_del_character.json create mode 100644 json/src/test/resources/data/y_structure_lonely_false.json create mode 100644 json/src/test/resources/data/y_structure_lonely_int.json create mode 100644 json/src/test/resources/data/y_structure_lonely_negative_real.json create mode 100644 json/src/test/resources/data/y_structure_lonely_null.json create mode 100644 json/src/test/resources/data/y_structure_lonely_string.json create mode 100644 json/src/test/resources/data/y_structure_lonely_true.json create mode 100644 json/src/test/resources/data/y_structure_string_empty.json create mode 100644 json/src/test/resources/data/y_structure_trailing_newline.json create mode 100644 json/src/test/resources/data/y_structure_true_in_array.json create mode 100644 json/src/test/resources/data/y_structure_whitespace_array.json diff --git a/json/src/main/java/alpine/json/ArrayElement.java b/json/src/main/java/alpine/json/ArrayElement.java index 7264066..b7fb977 100644 --- a/json/src/main/java/alpine/json/ArrayElement.java +++ b/json/src/main/java/alpine/json/ArrayElement.java @@ -10,6 +10,10 @@ import java.util.function.Consumer; import java.util.stream.Stream; +/** + * A JSON element which in itself stores an ordered sequence of elements. + * @author mudkip + */ public final class ArrayElement implements Element, Iterable { private final List elements; @@ -46,10 +50,18 @@ public Stream stream() { return this.elements.stream(); } + /** + * Returns whether the array is empty or not. + * @return {@code true} if the length of the array is at least 1, otherwise {@code false}. + */ public boolean empty() { return this.length() < 1; } + /** + * Returns the amount of elements that are contained in this array. + * @return The amount of elements that are contained in this array. + */ public int length() { return this.elements.size(); } diff --git a/json/src/main/java/alpine/json/Json.java b/json/src/main/java/alpine/json/Json.java index d4c8614..8692be7 100644 --- a/json/src/main/java/alpine/json/Json.java +++ b/json/src/main/java/alpine/json/Json.java @@ -85,6 +85,10 @@ public static void write(Path path, Element element, Formatting formatting) { } } + static boolean isControl(char character) { + return character <= 0x1F; + } + static boolean isWhitespace(char character) { return character == SPACE || character == TAB diff --git a/json/src/main/java/alpine/json/JsonReader.java b/json/src/main/java/alpine/json/JsonReader.java index 4c868dc..9e94f38 100644 --- a/json/src/main/java/alpine/json/JsonReader.java +++ b/json/src/main/java/alpine/json/JsonReader.java @@ -171,7 +171,7 @@ private StringElement parseString() throws ParsingException { builder.append(decoded); } - } else if (Character.isISOControl(character)) { + } else if (isControl(character)) { throw new ParsingException(this.input, "Unescaped control character in string!", this.position); } else { builder.append(character); diff --git a/json/src/test/java/alpine/json/ExternalTest.java b/json/src/test/java/alpine/json/ExternalTest.java new file mode 100644 index 0000000..235c294 --- /dev/null +++ b/json/src/test/java/alpine/json/ExternalTest.java @@ -0,0 +1,70 @@ +package alpine.json; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.charset.MalformedInputException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; +import java.util.stream.Stream; + +final class ExternalTest { + @SuppressWarnings("resource") + static Stream arguments() { + try { + var url = Objects.requireNonNull(ExternalTest.class.getResource("/data")); + + return Files.walk(Path.of(url.toURI()), 1) + .filter(Files::isRegularFile) + .filter(path -> path.getFileName().toString().endsWith(".json")) + .map(path -> { + try { + var name = path.getFileName().toString(); + var behavior = Behavior.from(path); + var string = Files.readString(path); + return Arguments.of(name, behavior, string); + } catch (MalformedInputException e) { + return null; + } catch (IOException e) { + throw new RuntimeException(e); + } + }) + .filter(Objects::nonNull); + } catch (URISyntaxException | IOException e) { + throw new RuntimeException(e); + } + } + + @ParameterizedTest(name = "{0}") + @MethodSource("arguments") + void test(String name, Behavior behavior, String string) { + try { + Json.read(string); + } catch (ParsingException e) { + if (behavior == Behavior.SHOULD_PASS) { + throw new AssertionError(name + " should have passed!", e); + } + } catch (StackOverflowError ignored) { + + } + } + + enum Behavior { + SHOULD_PASS, + SHOULD_FAIL, + ANY; + + static Behavior from(Path path) { + return switch (path.getFileName().toString().charAt(0)) { + case 'y' -> SHOULD_PASS; + case 'n' -> SHOULD_FAIL; + case 'i' -> ANY; + default -> throw new IllegalStateException("Unexpected value!"); + }; + } + } +} diff --git a/json/src/test/resources/data/i_number_double_huge_neg_exp.json b/json/src/test/resources/data/i_number_double_huge_neg_exp.json new file mode 100644 index 0000000..ae4c7b7 --- /dev/null +++ b/json/src/test/resources/data/i_number_double_huge_neg_exp.json @@ -0,0 +1 @@ +[123.456e-789] \ No newline at end of file diff --git a/json/src/test/resources/data/i_number_huge_exp.json b/json/src/test/resources/data/i_number_huge_exp.json new file mode 100644 index 0000000..9b5efa2 --- /dev/null +++ b/json/src/test/resources/data/i_number_huge_exp.json @@ -0,0 +1 @@ +[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006] \ No newline at end of file diff --git a/json/src/test/resources/data/i_number_neg_int_huge_exp.json b/json/src/test/resources/data/i_number_neg_int_huge_exp.json new file mode 100644 index 0000000..3abd58a --- /dev/null +++ b/json/src/test/resources/data/i_number_neg_int_huge_exp.json @@ -0,0 +1 @@ +[-1e+9999] \ No newline at end of file diff --git a/json/src/test/resources/data/i_number_pos_double_huge_exp.json b/json/src/test/resources/data/i_number_pos_double_huge_exp.json new file mode 100644 index 0000000..e10a7eb --- /dev/null +++ b/json/src/test/resources/data/i_number_pos_double_huge_exp.json @@ -0,0 +1 @@ +[1.5e+9999] \ No newline at end of file diff --git a/json/src/test/resources/data/i_number_real_neg_overflow.json b/json/src/test/resources/data/i_number_real_neg_overflow.json new file mode 100644 index 0000000..3d628a9 --- /dev/null +++ b/json/src/test/resources/data/i_number_real_neg_overflow.json @@ -0,0 +1 @@ +[-123123e100000] \ No newline at end of file diff --git a/json/src/test/resources/data/i_number_real_pos_overflow.json b/json/src/test/resources/data/i_number_real_pos_overflow.json new file mode 100644 index 0000000..54d7d3d --- /dev/null +++ b/json/src/test/resources/data/i_number_real_pos_overflow.json @@ -0,0 +1 @@ +[123123e100000] \ No newline at end of file diff --git a/json/src/test/resources/data/i_number_real_underflow.json b/json/src/test/resources/data/i_number_real_underflow.json new file mode 100644 index 0000000..c5236eb --- /dev/null +++ b/json/src/test/resources/data/i_number_real_underflow.json @@ -0,0 +1 @@ +[123e-10000000] \ No newline at end of file diff --git a/json/src/test/resources/data/i_number_too_big_neg_int.json b/json/src/test/resources/data/i_number_too_big_neg_int.json new file mode 100644 index 0000000..dfa3846 --- /dev/null +++ b/json/src/test/resources/data/i_number_too_big_neg_int.json @@ -0,0 +1 @@ +[-123123123123123123123123123123] \ No newline at end of file diff --git a/json/src/test/resources/data/i_number_too_big_pos_int.json b/json/src/test/resources/data/i_number_too_big_pos_int.json new file mode 100644 index 0000000..338a8c3 --- /dev/null +++ b/json/src/test/resources/data/i_number_too_big_pos_int.json @@ -0,0 +1 @@ +[100000000000000000000] \ No newline at end of file diff --git a/json/src/test/resources/data/i_number_very_big_negative_int.json b/json/src/test/resources/data/i_number_very_big_negative_int.json new file mode 100644 index 0000000..e2d9738 --- /dev/null +++ b/json/src/test/resources/data/i_number_very_big_negative_int.json @@ -0,0 +1 @@ +[-237462374673276894279832749832423479823246327846] \ No newline at end of file diff --git a/json/src/test/resources/data/i_object_key_lone_2nd_surrogate.json b/json/src/test/resources/data/i_object_key_lone_2nd_surrogate.json new file mode 100644 index 0000000..5be7eba --- /dev/null +++ b/json/src/test/resources/data/i_object_key_lone_2nd_surrogate.json @@ -0,0 +1 @@ +{"\uDFAA":0} \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_1st_surrogate_but_2nd_missing.json b/json/src/test/resources/data/i_string_1st_surrogate_but_2nd_missing.json new file mode 100644 index 0000000..3b9e37c --- /dev/null +++ b/json/src/test/resources/data/i_string_1st_surrogate_but_2nd_missing.json @@ -0,0 +1 @@ +["\uDADA"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_1st_valid_surrogate_2nd_invalid.json b/json/src/test/resources/data/i_string_1st_valid_surrogate_2nd_invalid.json new file mode 100644 index 0000000..4875928 --- /dev/null +++ b/json/src/test/resources/data/i_string_1st_valid_surrogate_2nd_invalid.json @@ -0,0 +1 @@ +["\uD888\u1234"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_UTF-16LE_with_BOM.json b/json/src/test/resources/data/i_string_UTF-16LE_with_BOM.json new file mode 100644 index 0000000..c590b6b --- /dev/null +++ b/json/src/test/resources/data/i_string_UTF-16LE_with_BOM.json @@ -0,0 +1 @@ +["é"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_UTF-8_invalid_sequence.json b/json/src/test/resources/data/i_string_UTF-8_invalid_sequence.json new file mode 100755 index 0000000..e2a968a --- /dev/null +++ b/json/src/test/resources/data/i_string_UTF-8_invalid_sequence.json @@ -0,0 +1 @@ +["日ш"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_UTF8_surrogate_U+D800.json b/json/src/test/resources/data/i_string_UTF8_surrogate_U+D800.json new file mode 100644 index 0000000..12eb6ac --- /dev/null +++ b/json/src/test/resources/data/i_string_UTF8_surrogate_U+D800.json @@ -0,0 +1 @@ +["í €"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_incomplete_surrogate_and_escape_valid.json b/json/src/test/resources/data/i_string_incomplete_surrogate_and_escape_valid.json new file mode 100644 index 0000000..3cb11d2 --- /dev/null +++ b/json/src/test/resources/data/i_string_incomplete_surrogate_and_escape_valid.json @@ -0,0 +1 @@ +["\uD800\n"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_incomplete_surrogate_pair.json b/json/src/test/resources/data/i_string_incomplete_surrogate_pair.json new file mode 100644 index 0000000..38ec23b --- /dev/null +++ b/json/src/test/resources/data/i_string_incomplete_surrogate_pair.json @@ -0,0 +1 @@ +["\uDd1ea"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_incomplete_surrogates_escape_valid.json b/json/src/test/resources/data/i_string_incomplete_surrogates_escape_valid.json new file mode 100644 index 0000000..c9cd6f6 --- /dev/null +++ b/json/src/test/resources/data/i_string_incomplete_surrogates_escape_valid.json @@ -0,0 +1 @@ +["\uD800\uD800\n"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_invalid_lonely_surrogate.json b/json/src/test/resources/data/i_string_invalid_lonely_surrogate.json new file mode 100644 index 0000000..3abbd8d --- /dev/null +++ b/json/src/test/resources/data/i_string_invalid_lonely_surrogate.json @@ -0,0 +1 @@ +["\ud800"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_invalid_surrogate.json b/json/src/test/resources/data/i_string_invalid_surrogate.json new file mode 100644 index 0000000..ffddc04 --- /dev/null +++ b/json/src/test/resources/data/i_string_invalid_surrogate.json @@ -0,0 +1 @@ +["\ud800abc"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_invalid_utf-8.json b/json/src/test/resources/data/i_string_invalid_utf-8.json new file mode 100644 index 0000000..6cb994a --- /dev/null +++ b/json/src/test/resources/data/i_string_invalid_utf-8.json @@ -0,0 +1 @@ +["ΓΏ"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_inverted_surrogates_U+1D11E.json b/json/src/test/resources/data/i_string_inverted_surrogates_U+1D11E.json new file mode 100644 index 0000000..0d5456c --- /dev/null +++ b/json/src/test/resources/data/i_string_inverted_surrogates_U+1D11E.json @@ -0,0 +1 @@ +["\uDd1e\uD834"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_iso_latin_1.json b/json/src/test/resources/data/i_string_iso_latin_1.json new file mode 100644 index 0000000..c590b6b --- /dev/null +++ b/json/src/test/resources/data/i_string_iso_latin_1.json @@ -0,0 +1 @@ +["é"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_lone_second_surrogate.json b/json/src/test/resources/data/i_string_lone_second_surrogate.json new file mode 100644 index 0000000..1dbd397 --- /dev/null +++ b/json/src/test/resources/data/i_string_lone_second_surrogate.json @@ -0,0 +1 @@ +["\uDFAA"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_lone_utf8_continuation_byte.json b/json/src/test/resources/data/i_string_lone_utf8_continuation_byte.json new file mode 100644 index 0000000..11de306 --- /dev/null +++ b/json/src/test/resources/data/i_string_lone_utf8_continuation_byte.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_not_in_unicode_range.json b/json/src/test/resources/data/i_string_not_in_unicode_range.json new file mode 100644 index 0000000..df90a29 --- /dev/null +++ b/json/src/test/resources/data/i_string_not_in_unicode_range.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_overlong_sequence_2_bytes.json b/json/src/test/resources/data/i_string_overlong_sequence_2_bytes.json new file mode 100644 index 0000000..9c97400 --- /dev/null +++ b/json/src/test/resources/data/i_string_overlong_sequence_2_bytes.json @@ -0,0 +1 @@ +["À¯"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_overlong_sequence_6_bytes.json b/json/src/test/resources/data/i_string_overlong_sequence_6_bytes.json new file mode 100644 index 0000000..5659c45 --- /dev/null +++ b/json/src/test/resources/data/i_string_overlong_sequence_6_bytes.json @@ -0,0 +1 @@ +["üƒ¿¿¿¿"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_overlong_sequence_6_bytes_null.json b/json/src/test/resources/data/i_string_overlong_sequence_6_bytes_null.json new file mode 100644 index 0000000..5615bff --- /dev/null +++ b/json/src/test/resources/data/i_string_overlong_sequence_6_bytes_null.json @@ -0,0 +1 @@ +["ü€€€€€"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_truncated-utf-8.json b/json/src/test/resources/data/i_string_truncated-utf-8.json new file mode 100644 index 0000000..cdae017 --- /dev/null +++ b/json/src/test/resources/data/i_string_truncated-utf-8.json @@ -0,0 +1 @@ +["ая"] \ No newline at end of file diff --git a/json/src/test/resources/data/i_string_utf16BE_no_BOM.json b/json/src/test/resources/data/i_string_utf16BE_no_BOM.json new file mode 100644 index 0000000000000000000000000000000000000000..a83738965dbcf339b0bb123768b739f7604bbe6f GIT binary patch literal 11 RcmZRGW>8`{yb?&n0ssw50%-sM literal 0 HcmV?d00001 diff --git a/json/src/test/resources/data/i_string_utf16LE_no_BOM.json b/json/src/test/resources/data/i_string_utf16LE_no_BOM.json new file mode 100644 index 0000000000000000000000000000000000000000..e4adf0c911b0cfa3f60ed8d1b3a514f5e38c09e2 GIT binary patch literal 11 Rcma!MP+~Z|5=g`{000lO0%-sM literal 0 HcmV?d00001 diff --git a/json/src/test/resources/data/i_structure_500_nested_arrays.json b/json/src/test/resources/data/i_structure_500_nested_arrays.json new file mode 100644 index 0000000..7118405 --- /dev/null +++ b/json/src/test/resources/data/i_structure_500_nested_arrays.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/json/src/test/resources/data/i_structure_UTF-8_BOM_empty_object.json b/json/src/test/resources/data/i_structure_UTF-8_BOM_empty_object.json new file mode 100644 index 0000000..22fdca1 --- /dev/null +++ b/json/src/test/resources/data/i_structure_UTF-8_BOM_empty_object.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_1_true_without_comma.json b/json/src/test/resources/data/n_array_1_true_without_comma.json new file mode 100644 index 0000000..c14e3f6 --- /dev/null +++ b/json/src/test/resources/data/n_array_1_true_without_comma.json @@ -0,0 +1 @@ +[1 true] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_a_invalid_utf8.json b/json/src/test/resources/data/n_array_a_invalid_utf8.json new file mode 100644 index 0000000..47c248c --- /dev/null +++ b/json/src/test/resources/data/n_array_a_invalid_utf8.json @@ -0,0 +1 @@ +[ać] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_colon_instead_of_comma.json b/json/src/test/resources/data/n_array_colon_instead_of_comma.json new file mode 100644 index 0000000..0d02ad4 --- /dev/null +++ b/json/src/test/resources/data/n_array_colon_instead_of_comma.json @@ -0,0 +1 @@ +["": 1] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_comma_after_close.json b/json/src/test/resources/data/n_array_comma_after_close.json new file mode 100644 index 0000000..2ccba8d --- /dev/null +++ b/json/src/test/resources/data/n_array_comma_after_close.json @@ -0,0 +1 @@ +[""], \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_comma_and_number.json b/json/src/test/resources/data/n_array_comma_and_number.json new file mode 100644 index 0000000..d2c84e3 --- /dev/null +++ b/json/src/test/resources/data/n_array_comma_and_number.json @@ -0,0 +1 @@ +[,1] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_double_comma.json b/json/src/test/resources/data/n_array_double_comma.json new file mode 100644 index 0000000..0431712 --- /dev/null +++ b/json/src/test/resources/data/n_array_double_comma.json @@ -0,0 +1 @@ +[1,,2] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_double_extra_comma.json b/json/src/test/resources/data/n_array_double_extra_comma.json new file mode 100644 index 0000000..3f01d31 --- /dev/null +++ b/json/src/test/resources/data/n_array_double_extra_comma.json @@ -0,0 +1 @@ +["x",,] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_extra_close.json b/json/src/test/resources/data/n_array_extra_close.json new file mode 100644 index 0000000..c12f9fa --- /dev/null +++ b/json/src/test/resources/data/n_array_extra_close.json @@ -0,0 +1 @@ +["x"]] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_extra_comma.json b/json/src/test/resources/data/n_array_extra_comma.json new file mode 100644 index 0000000..5f8ce18 --- /dev/null +++ b/json/src/test/resources/data/n_array_extra_comma.json @@ -0,0 +1 @@ +["",] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_incomplete.json b/json/src/test/resources/data/n_array_incomplete.json new file mode 100644 index 0000000..cc65b0b --- /dev/null +++ b/json/src/test/resources/data/n_array_incomplete.json @@ -0,0 +1 @@ +["x" \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_incomplete_invalid_value.json b/json/src/test/resources/data/n_array_incomplete_invalid_value.json new file mode 100644 index 0000000..c21a8f6 --- /dev/null +++ b/json/src/test/resources/data/n_array_incomplete_invalid_value.json @@ -0,0 +1 @@ +[x \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_inner_array_no_comma.json b/json/src/test/resources/data/n_array_inner_array_no_comma.json new file mode 100644 index 0000000..c70b716 --- /dev/null +++ b/json/src/test/resources/data/n_array_inner_array_no_comma.json @@ -0,0 +1 @@ +[3[4]] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_invalid_utf8.json b/json/src/test/resources/data/n_array_invalid_utf8.json new file mode 100644 index 0000000..967e286 --- /dev/null +++ b/json/src/test/resources/data/n_array_invalid_utf8.json @@ -0,0 +1 @@ +[ΓΏ] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_items_separated_by_semicolon.json b/json/src/test/resources/data/n_array_items_separated_by_semicolon.json new file mode 100644 index 0000000..d4bd731 --- /dev/null +++ b/json/src/test/resources/data/n_array_items_separated_by_semicolon.json @@ -0,0 +1 @@ +[1:2] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_just_comma.json b/json/src/test/resources/data/n_array_just_comma.json new file mode 100644 index 0000000..9d7077c --- /dev/null +++ b/json/src/test/resources/data/n_array_just_comma.json @@ -0,0 +1 @@ +[,] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_just_minus.json b/json/src/test/resources/data/n_array_just_minus.json new file mode 100644 index 0000000..29501c6 --- /dev/null +++ b/json/src/test/resources/data/n_array_just_minus.json @@ -0,0 +1 @@ +[-] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_missing_value.json b/json/src/test/resources/data/n_array_missing_value.json new file mode 100644 index 0000000..3a6ba86 --- /dev/null +++ b/json/src/test/resources/data/n_array_missing_value.json @@ -0,0 +1 @@ +[ , ""] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_newlines_unclosed.json b/json/src/test/resources/data/n_array_newlines_unclosed.json new file mode 100644 index 0000000..6466800 --- /dev/null +++ b/json/src/test/resources/data/n_array_newlines_unclosed.json @@ -0,0 +1,3 @@ +["a", +4 +,1, \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_number_and_comma.json b/json/src/test/resources/data/n_array_number_and_comma.json new file mode 100644 index 0000000..13f6f1d --- /dev/null +++ b/json/src/test/resources/data/n_array_number_and_comma.json @@ -0,0 +1 @@ +[1,] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_number_and_several_commas.json b/json/src/test/resources/data/n_array_number_and_several_commas.json new file mode 100644 index 0000000..0ac408c --- /dev/null +++ b/json/src/test/resources/data/n_array_number_and_several_commas.json @@ -0,0 +1 @@ +[1,,] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_spaces_vertical_tab_formfeed.json b/json/src/test/resources/data/n_array_spaces_vertical_tab_formfeed.json new file mode 100644 index 0000000..6cd7cf5 --- /dev/null +++ b/json/src/test/resources/data/n_array_spaces_vertical_tab_formfeed.json @@ -0,0 +1 @@ +[" a"\f] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_star_inside.json b/json/src/test/resources/data/n_array_star_inside.json new file mode 100644 index 0000000..5a51946 --- /dev/null +++ b/json/src/test/resources/data/n_array_star_inside.json @@ -0,0 +1 @@ +[*] \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_unclosed.json b/json/src/test/resources/data/n_array_unclosed.json new file mode 100644 index 0000000..0607330 --- /dev/null +++ b/json/src/test/resources/data/n_array_unclosed.json @@ -0,0 +1 @@ +["" \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_unclosed_trailing_comma.json b/json/src/test/resources/data/n_array_unclosed_trailing_comma.json new file mode 100644 index 0000000..6604698 --- /dev/null +++ b/json/src/test/resources/data/n_array_unclosed_trailing_comma.json @@ -0,0 +1 @@ +[1, \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_unclosed_with_new_lines.json b/json/src/test/resources/data/n_array_unclosed_with_new_lines.json new file mode 100644 index 0000000..4f61de3 --- /dev/null +++ b/json/src/test/resources/data/n_array_unclosed_with_new_lines.json @@ -0,0 +1,3 @@ +[1, +1 +,1 \ No newline at end of file diff --git a/json/src/test/resources/data/n_array_unclosed_with_object_inside.json b/json/src/test/resources/data/n_array_unclosed_with_object_inside.json new file mode 100644 index 0000000..043a87e --- /dev/null +++ b/json/src/test/resources/data/n_array_unclosed_with_object_inside.json @@ -0,0 +1 @@ +[{} \ No newline at end of file diff --git a/json/src/test/resources/data/n_incomplete_false.json b/json/src/test/resources/data/n_incomplete_false.json new file mode 100644 index 0000000..eb18c6a --- /dev/null +++ b/json/src/test/resources/data/n_incomplete_false.json @@ -0,0 +1 @@ +[fals] \ No newline at end of file diff --git a/json/src/test/resources/data/n_incomplete_null.json b/json/src/test/resources/data/n_incomplete_null.json new file mode 100644 index 0000000..c18ef53 --- /dev/null +++ b/json/src/test/resources/data/n_incomplete_null.json @@ -0,0 +1 @@ +[nul] \ No newline at end of file diff --git a/json/src/test/resources/data/n_incomplete_true.json b/json/src/test/resources/data/n_incomplete_true.json new file mode 100644 index 0000000..f451ac6 --- /dev/null +++ b/json/src/test/resources/data/n_incomplete_true.json @@ -0,0 +1 @@ +[tru] \ No newline at end of file diff --git a/json/src/test/resources/data/n_multidigit_number_then_00.json b/json/src/test/resources/data/n_multidigit_number_then_00.json new file mode 100644 index 0000000000000000000000000000000000000000..c22507b864f7f089c91c1eb85b1b15cc63b943a6 GIT binary patch literal 4 LcmXpsGG+h(0mJ~8 literal 0 HcmV?d00001 diff --git a/json/src/test/resources/data/n_number_++.json b/json/src/test/resources/data/n_number_++.json new file mode 100644 index 0000000..bdb62aa --- /dev/null +++ b/json/src/test/resources/data/n_number_++.json @@ -0,0 +1 @@ +[++1234] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_+1.json b/json/src/test/resources/data/n_number_+1.json new file mode 100644 index 0000000..3cbe58c --- /dev/null +++ b/json/src/test/resources/data/n_number_+1.json @@ -0,0 +1 @@ +[+1] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_+Inf.json b/json/src/test/resources/data/n_number_+Inf.json new file mode 100644 index 0000000..871ae14 --- /dev/null +++ b/json/src/test/resources/data/n_number_+Inf.json @@ -0,0 +1 @@ +[+Inf] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_-01.json b/json/src/test/resources/data/n_number_-01.json new file mode 100644 index 0000000..0df32ba --- /dev/null +++ b/json/src/test/resources/data/n_number_-01.json @@ -0,0 +1 @@ +[-01] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_-1.0..json b/json/src/test/resources/data/n_number_-1.0..json new file mode 100644 index 0000000..7cf55a8 --- /dev/null +++ b/json/src/test/resources/data/n_number_-1.0..json @@ -0,0 +1 @@ +[-1.0.] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_-2..json b/json/src/test/resources/data/n_number_-2..json new file mode 100644 index 0000000..9be8436 --- /dev/null +++ b/json/src/test/resources/data/n_number_-2..json @@ -0,0 +1 @@ +[-2.] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_-NaN.json b/json/src/test/resources/data/n_number_-NaN.json new file mode 100644 index 0000000..f61615d --- /dev/null +++ b/json/src/test/resources/data/n_number_-NaN.json @@ -0,0 +1 @@ +[-NaN] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_.-1.json b/json/src/test/resources/data/n_number_.-1.json new file mode 100644 index 0000000..1c9f2dd --- /dev/null +++ b/json/src/test/resources/data/n_number_.-1.json @@ -0,0 +1 @@ +[.-1] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_.2e-3.json b/json/src/test/resources/data/n_number_.2e-3.json new file mode 100644 index 0000000..c6c976f --- /dev/null +++ b/json/src/test/resources/data/n_number_.2e-3.json @@ -0,0 +1 @@ +[.2e-3] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_0.1.2.json b/json/src/test/resources/data/n_number_0.1.2.json new file mode 100644 index 0000000..c83a256 --- /dev/null +++ b/json/src/test/resources/data/n_number_0.1.2.json @@ -0,0 +1 @@ +[0.1.2] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_0.3e+.json b/json/src/test/resources/data/n_number_0.3e+.json new file mode 100644 index 0000000..a55a1bf --- /dev/null +++ b/json/src/test/resources/data/n_number_0.3e+.json @@ -0,0 +1 @@ +[0.3e+] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_0.3e.json b/json/src/test/resources/data/n_number_0.3e.json new file mode 100644 index 0000000..3dd5df4 --- /dev/null +++ b/json/src/test/resources/data/n_number_0.3e.json @@ -0,0 +1 @@ +[0.3e] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_0.e1.json b/json/src/test/resources/data/n_number_0.e1.json new file mode 100644 index 0000000..c92c71c --- /dev/null +++ b/json/src/test/resources/data/n_number_0.e1.json @@ -0,0 +1 @@ +[0.e1] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_0_capital_E+.json b/json/src/test/resources/data/n_number_0_capital_E+.json new file mode 100644 index 0000000..3ba2c7d --- /dev/null +++ b/json/src/test/resources/data/n_number_0_capital_E+.json @@ -0,0 +1 @@ +[0E+] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_0_capital_E.json b/json/src/test/resources/data/n_number_0_capital_E.json new file mode 100644 index 0000000..5301840 --- /dev/null +++ b/json/src/test/resources/data/n_number_0_capital_E.json @@ -0,0 +1 @@ +[0E] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_0e+.json b/json/src/test/resources/data/n_number_0e+.json new file mode 100644 index 0000000..8ab0bc4 --- /dev/null +++ b/json/src/test/resources/data/n_number_0e+.json @@ -0,0 +1 @@ +[0e+] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_0e.json b/json/src/test/resources/data/n_number_0e.json new file mode 100644 index 0000000..47ec421 --- /dev/null +++ b/json/src/test/resources/data/n_number_0e.json @@ -0,0 +1 @@ +[0e] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_1.0e+.json b/json/src/test/resources/data/n_number_1.0e+.json new file mode 100644 index 0000000..cd84b9f --- /dev/null +++ b/json/src/test/resources/data/n_number_1.0e+.json @@ -0,0 +1 @@ +[1.0e+] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_1.0e-.json b/json/src/test/resources/data/n_number_1.0e-.json new file mode 100644 index 0000000..4eb7afa --- /dev/null +++ b/json/src/test/resources/data/n_number_1.0e-.json @@ -0,0 +1 @@ +[1.0e-] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_1.0e.json b/json/src/test/resources/data/n_number_1.0e.json new file mode 100644 index 0000000..21753f4 --- /dev/null +++ b/json/src/test/resources/data/n_number_1.0e.json @@ -0,0 +1 @@ +[1.0e] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_1_000.json b/json/src/test/resources/data/n_number_1_000.json new file mode 100644 index 0000000..7b18b66 --- /dev/null +++ b/json/src/test/resources/data/n_number_1_000.json @@ -0,0 +1 @@ +[1 000.0] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_1eE2.json b/json/src/test/resources/data/n_number_1eE2.json new file mode 100644 index 0000000..4318a34 --- /dev/null +++ b/json/src/test/resources/data/n_number_1eE2.json @@ -0,0 +1 @@ +[1eE2] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_2.e+3.json b/json/src/test/resources/data/n_number_2.e+3.json new file mode 100644 index 0000000..4442f39 --- /dev/null +++ b/json/src/test/resources/data/n_number_2.e+3.json @@ -0,0 +1 @@ +[2.e+3] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_2.e-3.json b/json/src/test/resources/data/n_number_2.e-3.json new file mode 100644 index 0000000..a65060e --- /dev/null +++ b/json/src/test/resources/data/n_number_2.e-3.json @@ -0,0 +1 @@ +[2.e-3] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_2.e3.json b/json/src/test/resources/data/n_number_2.e3.json new file mode 100644 index 0000000..66f7cf7 --- /dev/null +++ b/json/src/test/resources/data/n_number_2.e3.json @@ -0,0 +1 @@ +[2.e3] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_9.e+.json b/json/src/test/resources/data/n_number_9.e+.json new file mode 100644 index 0000000..732a7b1 --- /dev/null +++ b/json/src/test/resources/data/n_number_9.e+.json @@ -0,0 +1 @@ +[9.e+] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_Inf.json b/json/src/test/resources/data/n_number_Inf.json new file mode 100644 index 0000000..c40c734 --- /dev/null +++ b/json/src/test/resources/data/n_number_Inf.json @@ -0,0 +1 @@ +[Inf] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_NaN.json b/json/src/test/resources/data/n_number_NaN.json new file mode 100644 index 0000000..4992317 --- /dev/null +++ b/json/src/test/resources/data/n_number_NaN.json @@ -0,0 +1 @@ +[NaN] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_U+FF11_fullwidth_digit_one.json b/json/src/test/resources/data/n_number_U+FF11_fullwidth_digit_one.json new file mode 100644 index 0000000..b14587e --- /dev/null +++ b/json/src/test/resources/data/n_number_U+FF11_fullwidth_digit_one.json @@ -0,0 +1 @@ +[1] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_expression.json b/json/src/test/resources/data/n_number_expression.json new file mode 100644 index 0000000..76fdbc8 --- /dev/null +++ b/json/src/test/resources/data/n_number_expression.json @@ -0,0 +1 @@ +[1+2] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_hex_1_digit.json b/json/src/test/resources/data/n_number_hex_1_digit.json new file mode 100644 index 0000000..3b21488 --- /dev/null +++ b/json/src/test/resources/data/n_number_hex_1_digit.json @@ -0,0 +1 @@ +[0x1] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_hex_2_digits.json b/json/src/test/resources/data/n_number_hex_2_digits.json new file mode 100644 index 0000000..83e516a --- /dev/null +++ b/json/src/test/resources/data/n_number_hex_2_digits.json @@ -0,0 +1 @@ +[0x42] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_infinity.json b/json/src/test/resources/data/n_number_infinity.json new file mode 100644 index 0000000..8c2baf7 --- /dev/null +++ b/json/src/test/resources/data/n_number_infinity.json @@ -0,0 +1 @@ +[Infinity] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_invalid+-.json b/json/src/test/resources/data/n_number_invalid+-.json new file mode 100644 index 0000000..1cce602 --- /dev/null +++ b/json/src/test/resources/data/n_number_invalid+-.json @@ -0,0 +1 @@ +[0e+-1] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_invalid-negative-real.json b/json/src/test/resources/data/n_number_invalid-negative-real.json new file mode 100644 index 0000000..5fc3c1e --- /dev/null +++ b/json/src/test/resources/data/n_number_invalid-negative-real.json @@ -0,0 +1 @@ +[-123.123foo] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_invalid-utf-8-in-bigger-int.json b/json/src/test/resources/data/n_number_invalid-utf-8-in-bigger-int.json new file mode 100644 index 0000000..e2edaac --- /dev/null +++ b/json/src/test/resources/data/n_number_invalid-utf-8-in-bigger-int.json @@ -0,0 +1 @@ +[123å] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_invalid-utf-8-in-exponent.json b/json/src/test/resources/data/n_number_invalid-utf-8-in-exponent.json new file mode 100644 index 0000000..71fe523 --- /dev/null +++ b/json/src/test/resources/data/n_number_invalid-utf-8-in-exponent.json @@ -0,0 +1 @@ +[1e1å] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_invalid-utf-8-in-int.json b/json/src/test/resources/data/n_number_invalid-utf-8-in-int.json new file mode 100644 index 0000000..4347600 --- /dev/null +++ b/json/src/test/resources/data/n_number_invalid-utf-8-in-int.json @@ -0,0 +1 @@ +[0å] diff --git a/json/src/test/resources/data/n_number_minus_infinity.json b/json/src/test/resources/data/n_number_minus_infinity.json new file mode 100644 index 0000000..cf4133d --- /dev/null +++ b/json/src/test/resources/data/n_number_minus_infinity.json @@ -0,0 +1 @@ +[-Infinity] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_minus_sign_with_trailing_garbage.json b/json/src/test/resources/data/n_number_minus_sign_with_trailing_garbage.json new file mode 100644 index 0000000..a6d8e78 --- /dev/null +++ b/json/src/test/resources/data/n_number_minus_sign_with_trailing_garbage.json @@ -0,0 +1 @@ +[-foo] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_minus_space_1.json b/json/src/test/resources/data/n_number_minus_space_1.json new file mode 100644 index 0000000..9a5ebed --- /dev/null +++ b/json/src/test/resources/data/n_number_minus_space_1.json @@ -0,0 +1 @@ +[- 1] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_neg_int_starting_with_zero.json b/json/src/test/resources/data/n_number_neg_int_starting_with_zero.json new file mode 100644 index 0000000..67af096 --- /dev/null +++ b/json/src/test/resources/data/n_number_neg_int_starting_with_zero.json @@ -0,0 +1 @@ +[-012] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_neg_real_without_int_part.json b/json/src/test/resources/data/n_number_neg_real_without_int_part.json new file mode 100644 index 0000000..1f2a434 --- /dev/null +++ b/json/src/test/resources/data/n_number_neg_real_without_int_part.json @@ -0,0 +1 @@ +[-.123] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_neg_with_garbage_at_end.json b/json/src/test/resources/data/n_number_neg_with_garbage_at_end.json new file mode 100644 index 0000000..2aa7311 --- /dev/null +++ b/json/src/test/resources/data/n_number_neg_with_garbage_at_end.json @@ -0,0 +1 @@ +[-1x] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_real_garbage_after_e.json b/json/src/test/resources/data/n_number_real_garbage_after_e.json new file mode 100644 index 0000000..9213dfc --- /dev/null +++ b/json/src/test/resources/data/n_number_real_garbage_after_e.json @@ -0,0 +1 @@ +[1ea] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_real_with_invalid_utf8_after_e.json b/json/src/test/resources/data/n_number_real_with_invalid_utf8_after_e.json new file mode 100644 index 0000000..e33ba80 --- /dev/null +++ b/json/src/test/resources/data/n_number_real_with_invalid_utf8_after_e.json @@ -0,0 +1 @@ +[1eň] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_real_without_fractional_part.json b/json/src/test/resources/data/n_number_real_without_fractional_part.json new file mode 100644 index 0000000..1de287c --- /dev/null +++ b/json/src/test/resources/data/n_number_real_without_fractional_part.json @@ -0,0 +1 @@ +[1.] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_starting_with_dot.json b/json/src/test/resources/data/n_number_starting_with_dot.json new file mode 100644 index 0000000..f682dbd --- /dev/null +++ b/json/src/test/resources/data/n_number_starting_with_dot.json @@ -0,0 +1 @@ +[.123] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_with_alpha.json b/json/src/test/resources/data/n_number_with_alpha.json new file mode 100644 index 0000000..1e42d81 --- /dev/null +++ b/json/src/test/resources/data/n_number_with_alpha.json @@ -0,0 +1 @@ +[1.2a-3] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_with_alpha_char.json b/json/src/test/resources/data/n_number_with_alpha_char.json new file mode 100644 index 0000000..b79dacc --- /dev/null +++ b/json/src/test/resources/data/n_number_with_alpha_char.json @@ -0,0 +1 @@ +[1.8011670033376514H-308] \ No newline at end of file diff --git a/json/src/test/resources/data/n_number_with_leading_zero.json b/json/src/test/resources/data/n_number_with_leading_zero.json new file mode 100644 index 0000000..7106da1 --- /dev/null +++ b/json/src/test/resources/data/n_number_with_leading_zero.json @@ -0,0 +1 @@ +[012] \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_bad_value.json b/json/src/test/resources/data/n_object_bad_value.json new file mode 100644 index 0000000..a03a8c0 --- /dev/null +++ b/json/src/test/resources/data/n_object_bad_value.json @@ -0,0 +1 @@ +["x", truth] \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_bracket_key.json b/json/src/test/resources/data/n_object_bracket_key.json new file mode 100644 index 0000000..cc443b4 --- /dev/null +++ b/json/src/test/resources/data/n_object_bracket_key.json @@ -0,0 +1 @@ +{[: "x"} diff --git a/json/src/test/resources/data/n_object_comma_instead_of_colon.json b/json/src/test/resources/data/n_object_comma_instead_of_colon.json new file mode 100644 index 0000000..8d56377 --- /dev/null +++ b/json/src/test/resources/data/n_object_comma_instead_of_colon.json @@ -0,0 +1 @@ +{"x", null} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_double_colon.json b/json/src/test/resources/data/n_object_double_colon.json new file mode 100644 index 0000000..80e8c7b --- /dev/null +++ b/json/src/test/resources/data/n_object_double_colon.json @@ -0,0 +1 @@ +{"x"::"b"} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_emoji.json b/json/src/test/resources/data/n_object_emoji.json new file mode 100644 index 0000000..1a95232 --- /dev/null +++ b/json/src/test/resources/data/n_object_emoji.json @@ -0,0 +1 @@ +{🇨🇭} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_garbage_at_end.json b/json/src/test/resources/data/n_object_garbage_at_end.json new file mode 100644 index 0000000..80c42cb --- /dev/null +++ b/json/src/test/resources/data/n_object_garbage_at_end.json @@ -0,0 +1 @@ +{"a":"a" 123} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_key_with_single_quotes.json b/json/src/test/resources/data/n_object_key_with_single_quotes.json new file mode 100644 index 0000000..77c3275 --- /dev/null +++ b/json/src/test/resources/data/n_object_key_with_single_quotes.json @@ -0,0 +1 @@ +{key: 'value'} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_lone_continuation_byte_in_key_and_trailing_comma.json b/json/src/test/resources/data/n_object_lone_continuation_byte_in_key_and_trailing_comma.json new file mode 100644 index 0000000..1c7e4bc --- /dev/null +++ b/json/src/test/resources/data/n_object_lone_continuation_byte_in_key_and_trailing_comma.json @@ -0,0 +1 @@ +{"ยน":"0",} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_missing_colon.json b/json/src/test/resources/data/n_object_missing_colon.json new file mode 100644 index 0000000..b98eff6 --- /dev/null +++ b/json/src/test/resources/data/n_object_missing_colon.json @@ -0,0 +1 @@ +{"a" b} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_missing_key.json b/json/src/test/resources/data/n_object_missing_key.json new file mode 100644 index 0000000..b4fb0f5 --- /dev/null +++ b/json/src/test/resources/data/n_object_missing_key.json @@ -0,0 +1 @@ +{:"b"} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_missing_semicolon.json b/json/src/test/resources/data/n_object_missing_semicolon.json new file mode 100644 index 0000000..e345138 --- /dev/null +++ b/json/src/test/resources/data/n_object_missing_semicolon.json @@ -0,0 +1 @@ +{"a" "b"} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_missing_value.json b/json/src/test/resources/data/n_object_missing_value.json new file mode 100644 index 0000000..3ef538a --- /dev/null +++ b/json/src/test/resources/data/n_object_missing_value.json @@ -0,0 +1 @@ +{"a": \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_no-colon.json b/json/src/test/resources/data/n_object_no-colon.json new file mode 100644 index 0000000..f3797b3 --- /dev/null +++ b/json/src/test/resources/data/n_object_no-colon.json @@ -0,0 +1 @@ +{"a" \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_non_string_key.json b/json/src/test/resources/data/n_object_non_string_key.json new file mode 100644 index 0000000..b9945b3 --- /dev/null +++ b/json/src/test/resources/data/n_object_non_string_key.json @@ -0,0 +1 @@ +{1:1} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_non_string_key_but_huge_number_instead.json b/json/src/test/resources/data/n_object_non_string_key_but_huge_number_instead.json new file mode 100644 index 0000000..b37fa86 --- /dev/null +++ b/json/src/test/resources/data/n_object_non_string_key_but_huge_number_instead.json @@ -0,0 +1 @@ +{9999E9999:1} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_repeated_null_null.json b/json/src/test/resources/data/n_object_repeated_null_null.json new file mode 100644 index 0000000..f7d2959 --- /dev/null +++ b/json/src/test/resources/data/n_object_repeated_null_null.json @@ -0,0 +1 @@ +{null:null,null:null} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_several_trailing_commas.json b/json/src/test/resources/data/n_object_several_trailing_commas.json new file mode 100644 index 0000000..3c9afe8 --- /dev/null +++ b/json/src/test/resources/data/n_object_several_trailing_commas.json @@ -0,0 +1 @@ +{"id":0,,,,,} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_single_quote.json b/json/src/test/resources/data/n_object_single_quote.json new file mode 100644 index 0000000..e5cdf97 --- /dev/null +++ b/json/src/test/resources/data/n_object_single_quote.json @@ -0,0 +1 @@ +{'a':0} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_trailing_comma.json b/json/src/test/resources/data/n_object_trailing_comma.json new file mode 100644 index 0000000..a4b0250 --- /dev/null +++ b/json/src/test/resources/data/n_object_trailing_comma.json @@ -0,0 +1 @@ +{"id":0,} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_trailing_comment.json b/json/src/test/resources/data/n_object_trailing_comment.json new file mode 100644 index 0000000..a372c65 --- /dev/null +++ b/json/src/test/resources/data/n_object_trailing_comment.json @@ -0,0 +1 @@ +{"a":"b"}/**/ \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_trailing_comment_open.json b/json/src/test/resources/data/n_object_trailing_comment_open.json new file mode 100644 index 0000000..d557f41 --- /dev/null +++ b/json/src/test/resources/data/n_object_trailing_comment_open.json @@ -0,0 +1 @@ +{"a":"b"}/**// \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_trailing_comment_slash_open.json b/json/src/test/resources/data/n_object_trailing_comment_slash_open.json new file mode 100644 index 0000000..e335136 --- /dev/null +++ b/json/src/test/resources/data/n_object_trailing_comment_slash_open.json @@ -0,0 +1 @@ +{"a":"b"}// \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_trailing_comment_slash_open_incomplete.json b/json/src/test/resources/data/n_object_trailing_comment_slash_open_incomplete.json new file mode 100644 index 0000000..d892e49 --- /dev/null +++ b/json/src/test/resources/data/n_object_trailing_comment_slash_open_incomplete.json @@ -0,0 +1 @@ +{"a":"b"}/ \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_two_commas_in_a_row.json b/json/src/test/resources/data/n_object_two_commas_in_a_row.json new file mode 100644 index 0000000..7c639ae --- /dev/null +++ b/json/src/test/resources/data/n_object_two_commas_in_a_row.json @@ -0,0 +1 @@ +{"a":"b",,"c":"d"} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_unquoted_key.json b/json/src/test/resources/data/n_object_unquoted_key.json new file mode 100644 index 0000000..8ba1372 --- /dev/null +++ b/json/src/test/resources/data/n_object_unquoted_key.json @@ -0,0 +1 @@ +{a: "b"} \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_unterminated-value.json b/json/src/test/resources/data/n_object_unterminated-value.json new file mode 100644 index 0000000..7fe699a --- /dev/null +++ b/json/src/test/resources/data/n_object_unterminated-value.json @@ -0,0 +1 @@ +{"a":"a \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_with_single_string.json b/json/src/test/resources/data/n_object_with_single_string.json new file mode 100644 index 0000000..d63f7fb --- /dev/null +++ b/json/src/test/resources/data/n_object_with_single_string.json @@ -0,0 +1 @@ +{ "foo" : "bar", "a" } \ No newline at end of file diff --git a/json/src/test/resources/data/n_object_with_trailing_garbage.json b/json/src/test/resources/data/n_object_with_trailing_garbage.json new file mode 100644 index 0000000..787c8f0 --- /dev/null +++ b/json/src/test/resources/data/n_object_with_trailing_garbage.json @@ -0,0 +1 @@ +{"a":"b"}# \ No newline at end of file diff --git a/json/src/test/resources/data/n_single_space.json b/json/src/test/resources/data/n_single_space.json new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/json/src/test/resources/data/n_single_space.json @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_1_surrogate_then_escape.json b/json/src/test/resources/data/n_string_1_surrogate_then_escape.json new file mode 100644 index 0000000..acec66d --- /dev/null +++ b/json/src/test/resources/data/n_string_1_surrogate_then_escape.json @@ -0,0 +1 @@ +["\uD800\"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_1_surrogate_then_escape_u.json b/json/src/test/resources/data/n_string_1_surrogate_then_escape_u.json new file mode 100644 index 0000000..e834b05 --- /dev/null +++ b/json/src/test/resources/data/n_string_1_surrogate_then_escape_u.json @@ -0,0 +1 @@ +["\uD800\u"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_1_surrogate_then_escape_u1.json b/json/src/test/resources/data/n_string_1_surrogate_then_escape_u1.json new file mode 100644 index 0000000..a04cd34 --- /dev/null +++ b/json/src/test/resources/data/n_string_1_surrogate_then_escape_u1.json @@ -0,0 +1 @@ +["\uD800\u1"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_1_surrogate_then_escape_u1x.json b/json/src/test/resources/data/n_string_1_surrogate_then_escape_u1x.json new file mode 100644 index 0000000..bfbd234 --- /dev/null +++ b/json/src/test/resources/data/n_string_1_surrogate_then_escape_u1x.json @@ -0,0 +1 @@ +["\uD800\u1x"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_accentuated_char_no_quotes.json b/json/src/test/resources/data/n_string_accentuated_char_no_quotes.json new file mode 100644 index 0000000..fd68956 --- /dev/null +++ b/json/src/test/resources/data/n_string_accentuated_char_no_quotes.json @@ -0,0 +1 @@ +[é] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_backslash_00.json b/json/src/test/resources/data/n_string_backslash_00.json new file mode 100644 index 0000000000000000000000000000000000000000..b5bf267b5d4ee922d20cec1543b66d1530ff76cf GIT binary patch literal 6 Ncma!6ieXTS1pox&0a*Y5 literal 0 HcmV?d00001 diff --git a/json/src/test/resources/data/n_string_escape_x.json b/json/src/test/resources/data/n_string_escape_x.json new file mode 100644 index 0000000..fae2919 --- /dev/null +++ b/json/src/test/resources/data/n_string_escape_x.json @@ -0,0 +1 @@ +["\x00"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_escaped_backslash_bad.json b/json/src/test/resources/data/n_string_escaped_backslash_bad.json new file mode 100644 index 0000000..016fcb4 --- /dev/null +++ b/json/src/test/resources/data/n_string_escaped_backslash_bad.json @@ -0,0 +1 @@ +["\\\"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_escaped_ctrl_char_tab.json b/json/src/test/resources/data/n_string_escaped_ctrl_char_tab.json new file mode 100644 index 0000000..f35ea38 --- /dev/null +++ b/json/src/test/resources/data/n_string_escaped_ctrl_char_tab.json @@ -0,0 +1 @@ +["\ "] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_escaped_emoji.json b/json/src/test/resources/data/n_string_escaped_emoji.json new file mode 100644 index 0000000..c00a66a --- /dev/null +++ b/json/src/test/resources/data/n_string_escaped_emoji.json @@ -0,0 +1 @@ +["\🌀"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_incomplete_escape.json b/json/src/test/resources/data/n_string_incomplete_escape.json new file mode 100644 index 0000000..3415c33 --- /dev/null +++ b/json/src/test/resources/data/n_string_incomplete_escape.json @@ -0,0 +1 @@ +["\"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_incomplete_escaped_character.json b/json/src/test/resources/data/n_string_incomplete_escaped_character.json new file mode 100644 index 0000000..0f2197e --- /dev/null +++ b/json/src/test/resources/data/n_string_incomplete_escaped_character.json @@ -0,0 +1 @@ +["\u00A"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_incomplete_surrogate.json b/json/src/test/resources/data/n_string_incomplete_surrogate.json new file mode 100644 index 0000000..75504a6 --- /dev/null +++ b/json/src/test/resources/data/n_string_incomplete_surrogate.json @@ -0,0 +1 @@ +["\uD834\uDd"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_incomplete_surrogate_escape_invalid.json b/json/src/test/resources/data/n_string_incomplete_surrogate_escape_invalid.json new file mode 100644 index 0000000..bd96560 --- /dev/null +++ b/json/src/test/resources/data/n_string_incomplete_surrogate_escape_invalid.json @@ -0,0 +1 @@ +["\uD800\uD800\x"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_invalid-utf-8-in-escape.json b/json/src/test/resources/data/n_string_invalid-utf-8-in-escape.json new file mode 100644 index 0000000..786740d --- /dev/null +++ b/json/src/test/resources/data/n_string_invalid-utf-8-in-escape.json @@ -0,0 +1 @@ +["\uċ"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_invalid_backslash_esc.json b/json/src/test/resources/data/n_string_invalid_backslash_esc.json new file mode 100644 index 0000000..d1eb609 --- /dev/null +++ b/json/src/test/resources/data/n_string_invalid_backslash_esc.json @@ -0,0 +1 @@ +["\a"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_invalid_unicode_escape.json b/json/src/test/resources/data/n_string_invalid_unicode_escape.json new file mode 100644 index 0000000..7608cb6 --- /dev/null +++ b/json/src/test/resources/data/n_string_invalid_unicode_escape.json @@ -0,0 +1 @@ +["\uqqqq"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_invalid_utf8_after_escape.json b/json/src/test/resources/data/n_string_invalid_utf8_after_escape.json new file mode 100644 index 0000000..65efb4a --- /dev/null +++ b/json/src/test/resources/data/n_string_invalid_utf8_after_escape.json @@ -0,0 +1 @@ +["\å"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_leading_uescaped_thinspace.json b/json/src/test/resources/data/n_string_leading_uescaped_thinspace.json new file mode 100644 index 0000000..7b297c6 --- /dev/null +++ b/json/src/test/resources/data/n_string_leading_uescaped_thinspace.json @@ -0,0 +1 @@ +[\u0020"asd"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_no_quotes_with_bad_escape.json b/json/src/test/resources/data/n_string_no_quotes_with_bad_escape.json new file mode 100644 index 0000000..01bc70a --- /dev/null +++ b/json/src/test/resources/data/n_string_no_quotes_with_bad_escape.json @@ -0,0 +1 @@ +[\n] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_single_doublequote.json b/json/src/test/resources/data/n_string_single_doublequote.json new file mode 100644 index 0000000..9d68933 --- /dev/null +++ b/json/src/test/resources/data/n_string_single_doublequote.json @@ -0,0 +1 @@ +" \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_single_quote.json b/json/src/test/resources/data/n_string_single_quote.json new file mode 100644 index 0000000..caff239 --- /dev/null +++ b/json/src/test/resources/data/n_string_single_quote.json @@ -0,0 +1 @@ +['single quote'] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_single_string_no_double_quotes.json b/json/src/test/resources/data/n_string_single_string_no_double_quotes.json new file mode 100644 index 0000000..f2ba8f8 --- /dev/null +++ b/json/src/test/resources/data/n_string_single_string_no_double_quotes.json @@ -0,0 +1 @@ +abc \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_start_escape_unclosed.json b/json/src/test/resources/data/n_string_start_escape_unclosed.json new file mode 100644 index 0000000..db62a46 --- /dev/null +++ b/json/src/test/resources/data/n_string_start_escape_unclosed.json @@ -0,0 +1 @@ +["\ \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_unescaped_ctrl_char.json b/json/src/test/resources/data/n_string_unescaped_ctrl_char.json new file mode 100644 index 0000000000000000000000000000000000000000..9f21348071d3d736bdd469f159cea674c09237af GIT binary patch literal 7 Ocma!6N@Pe>iUj}$`2oKG literal 0 HcmV?d00001 diff --git a/json/src/test/resources/data/n_string_unescaped_newline.json b/json/src/test/resources/data/n_string_unescaped_newline.json new file mode 100644 index 0000000..700d360 --- /dev/null +++ b/json/src/test/resources/data/n_string_unescaped_newline.json @@ -0,0 +1,2 @@ +["new +line"] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_unescaped_tab.json b/json/src/test/resources/data/n_string_unescaped_tab.json new file mode 100644 index 0000000..160264a --- /dev/null +++ b/json/src/test/resources/data/n_string_unescaped_tab.json @@ -0,0 +1 @@ +[" "] \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_unicode_CapitalU.json b/json/src/test/resources/data/n_string_unicode_CapitalU.json new file mode 100644 index 0000000..17332bb --- /dev/null +++ b/json/src/test/resources/data/n_string_unicode_CapitalU.json @@ -0,0 +1 @@ +"\UA66D" \ No newline at end of file diff --git a/json/src/test/resources/data/n_string_with_trailing_garbage.json b/json/src/test/resources/data/n_string_with_trailing_garbage.json new file mode 100644 index 0000000..efe3bd2 --- /dev/null +++ b/json/src/test/resources/data/n_string_with_trailing_garbage.json @@ -0,0 +1 @@ +""x \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_100000_opening_arrays.json b/json/src/test/resources/data/n_structure_100000_opening_arrays.json new file mode 100644 index 0000000..a4823ee --- /dev/null +++ b/json/src/test/resources/data/n_structure_100000_opening_arrays.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_U+2060_word_joined.json b/json/src/test/resources/data/n_structure_U+2060_word_joined.json new file mode 100644 index 0000000..81156a6 --- /dev/null +++ b/json/src/test/resources/data/n_structure_U+2060_word_joined.json @@ -0,0 +1 @@ +[⁠] \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_UTF8_BOM_no_data.json b/json/src/test/resources/data/n_structure_UTF8_BOM_no_data.json new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/json/src/test/resources/data/n_structure_UTF8_BOM_no_data.json @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_angle_bracket_..json b/json/src/test/resources/data/n_structure_angle_bracket_..json new file mode 100644 index 0000000..a56fef0 --- /dev/null +++ b/json/src/test/resources/data/n_structure_angle_bracket_..json @@ -0,0 +1 @@ +<.> \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_angle_bracket_null.json b/json/src/test/resources/data/n_structure_angle_bracket_null.json new file mode 100644 index 0000000..617f262 --- /dev/null +++ b/json/src/test/resources/data/n_structure_angle_bracket_null.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_array_trailing_garbage.json b/json/src/test/resources/data/n_structure_array_trailing_garbage.json new file mode 100644 index 0000000..5a745e6 --- /dev/null +++ b/json/src/test/resources/data/n_structure_array_trailing_garbage.json @@ -0,0 +1 @@ +[1]x \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_array_with_extra_array_close.json b/json/src/test/resources/data/n_structure_array_with_extra_array_close.json new file mode 100644 index 0000000..6cfb139 --- /dev/null +++ b/json/src/test/resources/data/n_structure_array_with_extra_array_close.json @@ -0,0 +1 @@ +[1]] \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_array_with_unclosed_string.json b/json/src/test/resources/data/n_structure_array_with_unclosed_string.json new file mode 100644 index 0000000..ba6b178 --- /dev/null +++ b/json/src/test/resources/data/n_structure_array_with_unclosed_string.json @@ -0,0 +1 @@ +["asd] \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_ascii-unicode-identifier.json b/json/src/test/resources/data/n_structure_ascii-unicode-identifier.json new file mode 100644 index 0000000..b89fc55 --- /dev/null +++ b/json/src/test/resources/data/n_structure_ascii-unicode-identifier.json @@ -0,0 +1 @@ +aĆ„ \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_capitalized_True.json b/json/src/test/resources/data/n_structure_capitalized_True.json new file mode 100644 index 0000000..7cd8846 --- /dev/null +++ b/json/src/test/resources/data/n_structure_capitalized_True.json @@ -0,0 +1 @@ +[True] \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_close_unopened_array.json b/json/src/test/resources/data/n_structure_close_unopened_array.json new file mode 100644 index 0000000..d2af0c6 --- /dev/null +++ b/json/src/test/resources/data/n_structure_close_unopened_array.json @@ -0,0 +1 @@ +1] \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_comma_instead_of_closing_brace.json b/json/src/test/resources/data/n_structure_comma_instead_of_closing_brace.json new file mode 100644 index 0000000..ac61b82 --- /dev/null +++ b/json/src/test/resources/data/n_structure_comma_instead_of_closing_brace.json @@ -0,0 +1 @@ +{"x": true, \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_double_array.json b/json/src/test/resources/data/n_structure_double_array.json new file mode 100644 index 0000000..058d162 --- /dev/null +++ b/json/src/test/resources/data/n_structure_double_array.json @@ -0,0 +1 @@ +[][] \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_end_array.json b/json/src/test/resources/data/n_structure_end_array.json new file mode 100644 index 0000000..54caf60 --- /dev/null +++ b/json/src/test/resources/data/n_structure_end_array.json @@ -0,0 +1 @@ +] \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_incomplete_UTF8_BOM.json b/json/src/test/resources/data/n_structure_incomplete_UTF8_BOM.json new file mode 100644 index 0000000..2034807 --- /dev/null +++ b/json/src/test/resources/data/n_structure_incomplete_UTF8_BOM.json @@ -0,0 +1 @@ +ï»{} \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_lone-invalid-utf-8.json b/json/src/test/resources/data/n_structure_lone-invalid-utf-8.json new file mode 100644 index 0000000..7284aea --- /dev/null +++ b/json/src/test/resources/data/n_structure_lone-invalid-utf-8.json @@ -0,0 +1 @@ +å \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_lone-open-bracket.json b/json/src/test/resources/data/n_structure_lone-open-bracket.json new file mode 100644 index 0000000..8e2f0be --- /dev/null +++ b/json/src/test/resources/data/n_structure_lone-open-bracket.json @@ -0,0 +1 @@ +[ \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_no_data.json b/json/src/test/resources/data/n_structure_no_data.json new file mode 100644 index 0000000..e69de29 diff --git a/json/src/test/resources/data/n_structure_null-byte-outside-string.json b/json/src/test/resources/data/n_structure_null-byte-outside-string.json new file mode 100644 index 0000000000000000000000000000000000000000..326db14422a756e9bd39221edf37b844cb8471c7 GIT binary patch literal 3 Kcma!Mhy?%vaR9jh literal 0 HcmV?d00001 diff --git a/json/src/test/resources/data/n_structure_number_with_trailing_garbage.json b/json/src/test/resources/data/n_structure_number_with_trailing_garbage.json new file mode 100644 index 0000000..0746539 --- /dev/null +++ b/json/src/test/resources/data/n_structure_number_with_trailing_garbage.json @@ -0,0 +1 @@ +2@ \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_object_followed_by_closing_object.json b/json/src/test/resources/data/n_structure_object_followed_by_closing_object.json new file mode 100644 index 0000000..aa9ebae --- /dev/null +++ b/json/src/test/resources/data/n_structure_object_followed_by_closing_object.json @@ -0,0 +1 @@ +{}} \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_object_unclosed_no_value.json b/json/src/test/resources/data/n_structure_object_unclosed_no_value.json new file mode 100644 index 0000000..17d0451 --- /dev/null +++ b/json/src/test/resources/data/n_structure_object_unclosed_no_value.json @@ -0,0 +1 @@ +{"": \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_object_with_comment.json b/json/src/test/resources/data/n_structure_object_with_comment.json new file mode 100644 index 0000000..ed1b569 --- /dev/null +++ b/json/src/test/resources/data/n_structure_object_with_comment.json @@ -0,0 +1 @@ +{"a":/*comment*/"b"} \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_object_with_trailing_garbage.json b/json/src/test/resources/data/n_structure_object_with_trailing_garbage.json new file mode 100644 index 0000000..9ca2336 --- /dev/null +++ b/json/src/test/resources/data/n_structure_object_with_trailing_garbage.json @@ -0,0 +1 @@ +{"a": true} "x" \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_open_array_apostrophe.json b/json/src/test/resources/data/n_structure_open_array_apostrophe.json new file mode 100644 index 0000000..8bebe3a --- /dev/null +++ b/json/src/test/resources/data/n_structure_open_array_apostrophe.json @@ -0,0 +1 @@ +[' \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_open_array_comma.json b/json/src/test/resources/data/n_structure_open_array_comma.json new file mode 100644 index 0000000..6295fdc --- /dev/null +++ b/json/src/test/resources/data/n_structure_open_array_comma.json @@ -0,0 +1 @@ +[, \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_open_array_object.json b/json/src/test/resources/data/n_structure_open_array_object.json new file mode 100644 index 0000000..e870445 --- /dev/null +++ b/json/src/test/resources/data/n_structure_open_array_object.json @@ -0,0 +1 @@ +[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"": diff --git a/json/src/test/resources/data/n_structure_open_array_open_object.json b/json/src/test/resources/data/n_structure_open_array_open_object.json new file mode 100644 index 0000000..7a63c8c --- /dev/null +++ b/json/src/test/resources/data/n_structure_open_array_open_object.json @@ -0,0 +1 @@ +[{ \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_open_array_open_string.json b/json/src/test/resources/data/n_structure_open_array_open_string.json new file mode 100644 index 0000000..9822a6b --- /dev/null +++ b/json/src/test/resources/data/n_structure_open_array_open_string.json @@ -0,0 +1 @@ +["a \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_open_array_string.json b/json/src/test/resources/data/n_structure_open_array_string.json new file mode 100644 index 0000000..42a6193 --- /dev/null +++ b/json/src/test/resources/data/n_structure_open_array_string.json @@ -0,0 +1 @@ +["a" \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_open_object.json b/json/src/test/resources/data/n_structure_open_object.json new file mode 100644 index 0000000..81750b9 --- /dev/null +++ b/json/src/test/resources/data/n_structure_open_object.json @@ -0,0 +1 @@ +{ \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_open_object_close_array.json b/json/src/test/resources/data/n_structure_open_object_close_array.json new file mode 100644 index 0000000..eebc700 --- /dev/null +++ b/json/src/test/resources/data/n_structure_open_object_close_array.json @@ -0,0 +1 @@ +{] \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_open_object_comma.json b/json/src/test/resources/data/n_structure_open_object_comma.json new file mode 100644 index 0000000..47bc910 --- /dev/null +++ b/json/src/test/resources/data/n_structure_open_object_comma.json @@ -0,0 +1 @@ +{, \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_open_object_open_array.json b/json/src/test/resources/data/n_structure_open_object_open_array.json new file mode 100644 index 0000000..381ede5 --- /dev/null +++ b/json/src/test/resources/data/n_structure_open_object_open_array.json @@ -0,0 +1 @@ +{[ \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_open_object_open_string.json b/json/src/test/resources/data/n_structure_open_object_open_string.json new file mode 100644 index 0000000..328c30c --- /dev/null +++ b/json/src/test/resources/data/n_structure_open_object_open_string.json @@ -0,0 +1 @@ +{"a \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_open_object_string_with_apostrophes.json b/json/src/test/resources/data/n_structure_open_object_string_with_apostrophes.json new file mode 100644 index 0000000..9dba170 --- /dev/null +++ b/json/src/test/resources/data/n_structure_open_object_string_with_apostrophes.json @@ -0,0 +1 @@ +{'a' \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_open_open.json b/json/src/test/resources/data/n_structure_open_open.json new file mode 100644 index 0000000..841fd5f --- /dev/null +++ b/json/src/test/resources/data/n_structure_open_open.json @@ -0,0 +1 @@ +["\{["\{["\{["\{ \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_single_eacute.json b/json/src/test/resources/data/n_structure_single_eacute.json new file mode 100644 index 0000000..4b04fff --- /dev/null +++ b/json/src/test/resources/data/n_structure_single_eacute.json @@ -0,0 +1 @@ +é \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_single_star.json b/json/src/test/resources/data/n_structure_single_star.json new file mode 100644 index 0000000..f59ec20 --- /dev/null +++ b/json/src/test/resources/data/n_structure_single_star.json @@ -0,0 +1 @@ +* \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_trailing_#.json b/json/src/test/resources/data/n_structure_trailing_#.json new file mode 100644 index 0000000..8986110 --- /dev/null +++ b/json/src/test/resources/data/n_structure_trailing_#.json @@ -0,0 +1 @@ +{"a":"b"}#{} \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_uescaped_LF_before_string.json b/json/src/test/resources/data/n_structure_uescaped_LF_before_string.json new file mode 100644 index 0000000..df2f0f2 --- /dev/null +++ b/json/src/test/resources/data/n_structure_uescaped_LF_before_string.json @@ -0,0 +1 @@ +[\u000A""] \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_unclosed_array.json b/json/src/test/resources/data/n_structure_unclosed_array.json new file mode 100644 index 0000000..1120951 --- /dev/null +++ b/json/src/test/resources/data/n_structure_unclosed_array.json @@ -0,0 +1 @@ +[1 \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_unclosed_array_partial_null.json b/json/src/test/resources/data/n_structure_unclosed_array_partial_null.json new file mode 100644 index 0000000..0d59176 --- /dev/null +++ b/json/src/test/resources/data/n_structure_unclosed_array_partial_null.json @@ -0,0 +1 @@ +[ false, nul \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_unclosed_array_unfinished_false.json b/json/src/test/resources/data/n_structure_unclosed_array_unfinished_false.json new file mode 100644 index 0000000..a2ff850 --- /dev/null +++ b/json/src/test/resources/data/n_structure_unclosed_array_unfinished_false.json @@ -0,0 +1 @@ +[ true, fals \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_unclosed_array_unfinished_true.json b/json/src/test/resources/data/n_structure_unclosed_array_unfinished_true.json new file mode 100644 index 0000000..3149e8f --- /dev/null +++ b/json/src/test/resources/data/n_structure_unclosed_array_unfinished_true.json @@ -0,0 +1 @@ +[ false, tru \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_unclosed_object.json b/json/src/test/resources/data/n_structure_unclosed_object.json new file mode 100644 index 0000000..694d69d --- /dev/null +++ b/json/src/test/resources/data/n_structure_unclosed_object.json @@ -0,0 +1 @@ +{"asd":"asd" \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_unicode-identifier.json b/json/src/test/resources/data/n_structure_unicode-identifier.json new file mode 100644 index 0000000..7284aea --- /dev/null +++ b/json/src/test/resources/data/n_structure_unicode-identifier.json @@ -0,0 +1 @@ +å \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_whitespace_U+2060_word_joiner.json b/json/src/test/resources/data/n_structure_whitespace_U+2060_word_joiner.json new file mode 100644 index 0000000..81156a6 --- /dev/null +++ b/json/src/test/resources/data/n_structure_whitespace_U+2060_word_joiner.json @@ -0,0 +1 @@ +[⁠] \ No newline at end of file diff --git a/json/src/test/resources/data/n_structure_whitespace_formfeed.json b/json/src/test/resources/data/n_structure_whitespace_formfeed.json new file mode 100644 index 0000000..a9ea535 --- /dev/null +++ b/json/src/test/resources/data/n_structure_whitespace_formfeed.json @@ -0,0 +1 @@ +[ ] \ No newline at end of file diff --git a/json/src/test/resources/data/y_array_arraysWithSpaces.json b/json/src/test/resources/data/y_array_arraysWithSpaces.json new file mode 100644 index 0000000..5822907 --- /dev/null +++ b/json/src/test/resources/data/y_array_arraysWithSpaces.json @@ -0,0 +1 @@ +[[] ] \ No newline at end of file diff --git a/json/src/test/resources/data/y_array_empty-string.json b/json/src/test/resources/data/y_array_empty-string.json new file mode 100644 index 0000000..93b6be2 --- /dev/null +++ b/json/src/test/resources/data/y_array_empty-string.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/json/src/test/resources/data/y_array_empty.json b/json/src/test/resources/data/y_array_empty.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/json/src/test/resources/data/y_array_empty.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/json/src/test/resources/data/y_array_ending_with_newline.json b/json/src/test/resources/data/y_array_ending_with_newline.json new file mode 100644 index 0000000..eac5f7b --- /dev/null +++ b/json/src/test/resources/data/y_array_ending_with_newline.json @@ -0,0 +1 @@ +["a"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_array_false.json b/json/src/test/resources/data/y_array_false.json new file mode 100644 index 0000000..67b2f07 --- /dev/null +++ b/json/src/test/resources/data/y_array_false.json @@ -0,0 +1 @@ +[false] \ No newline at end of file diff --git a/json/src/test/resources/data/y_array_heterogeneous.json b/json/src/test/resources/data/y_array_heterogeneous.json new file mode 100644 index 0000000..d3c1e26 --- /dev/null +++ b/json/src/test/resources/data/y_array_heterogeneous.json @@ -0,0 +1 @@ +[null, 1, "1", {}] \ No newline at end of file diff --git a/json/src/test/resources/data/y_array_null.json b/json/src/test/resources/data/y_array_null.json new file mode 100644 index 0000000..500db4a --- /dev/null +++ b/json/src/test/resources/data/y_array_null.json @@ -0,0 +1 @@ +[null] \ No newline at end of file diff --git a/json/src/test/resources/data/y_array_with_1_and_newline.json b/json/src/test/resources/data/y_array_with_1_and_newline.json new file mode 100644 index 0000000..9948255 --- /dev/null +++ b/json/src/test/resources/data/y_array_with_1_and_newline.json @@ -0,0 +1,2 @@ +[1 +] \ No newline at end of file diff --git a/json/src/test/resources/data/y_array_with_leading_space.json b/json/src/test/resources/data/y_array_with_leading_space.json new file mode 100644 index 0000000..18bfe64 --- /dev/null +++ b/json/src/test/resources/data/y_array_with_leading_space.json @@ -0,0 +1 @@ + [1] \ No newline at end of file diff --git a/json/src/test/resources/data/y_array_with_several_null.json b/json/src/test/resources/data/y_array_with_several_null.json new file mode 100644 index 0000000..99f6c5d --- /dev/null +++ b/json/src/test/resources/data/y_array_with_several_null.json @@ -0,0 +1 @@ +[1,null,null,null,2] \ No newline at end of file diff --git a/json/src/test/resources/data/y_array_with_trailing_space.json b/json/src/test/resources/data/y_array_with_trailing_space.json new file mode 100644 index 0000000..de9e7a9 --- /dev/null +++ b/json/src/test/resources/data/y_array_with_trailing_space.json @@ -0,0 +1 @@ +[2] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number.json b/json/src/test/resources/data/y_number.json new file mode 100644 index 0000000..e5f5cc3 --- /dev/null +++ b/json/src/test/resources/data/y_number.json @@ -0,0 +1 @@ +[123e65] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_0e+1.json b/json/src/test/resources/data/y_number_0e+1.json new file mode 100644 index 0000000..d1d3967 --- /dev/null +++ b/json/src/test/resources/data/y_number_0e+1.json @@ -0,0 +1 @@ +[0e+1] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_0e1.json b/json/src/test/resources/data/y_number_0e1.json new file mode 100644 index 0000000..3283a79 --- /dev/null +++ b/json/src/test/resources/data/y_number_0e1.json @@ -0,0 +1 @@ +[0e1] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_after_space.json b/json/src/test/resources/data/y_number_after_space.json new file mode 100644 index 0000000..623570d --- /dev/null +++ b/json/src/test/resources/data/y_number_after_space.json @@ -0,0 +1 @@ +[ 4] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_double_close_to_zero.json b/json/src/test/resources/data/y_number_double_close_to_zero.json new file mode 100644 index 0000000..96555ff --- /dev/null +++ b/json/src/test/resources/data/y_number_double_close_to_zero.json @@ -0,0 +1 @@ +[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001] diff --git a/json/src/test/resources/data/y_number_int_with_exp.json b/json/src/test/resources/data/y_number_int_with_exp.json new file mode 100644 index 0000000..a4ca9e7 --- /dev/null +++ b/json/src/test/resources/data/y_number_int_with_exp.json @@ -0,0 +1 @@ +[20e1] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_minus_zero.json b/json/src/test/resources/data/y_number_minus_zero.json new file mode 100644 index 0000000..37af131 --- /dev/null +++ b/json/src/test/resources/data/y_number_minus_zero.json @@ -0,0 +1 @@ +[-0] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_negative_int.json b/json/src/test/resources/data/y_number_negative_int.json new file mode 100644 index 0000000..8e30f8b --- /dev/null +++ b/json/src/test/resources/data/y_number_negative_int.json @@ -0,0 +1 @@ +[-123] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_negative_one.json b/json/src/test/resources/data/y_number_negative_one.json new file mode 100644 index 0000000..99d21a2 --- /dev/null +++ b/json/src/test/resources/data/y_number_negative_one.json @@ -0,0 +1 @@ +[-1] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_negative_zero.json b/json/src/test/resources/data/y_number_negative_zero.json new file mode 100644 index 0000000..37af131 --- /dev/null +++ b/json/src/test/resources/data/y_number_negative_zero.json @@ -0,0 +1 @@ +[-0] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_real_capital_e.json b/json/src/test/resources/data/y_number_real_capital_e.json new file mode 100644 index 0000000..6edbdfc --- /dev/null +++ b/json/src/test/resources/data/y_number_real_capital_e.json @@ -0,0 +1 @@ +[1E22] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_real_capital_e_neg_exp.json b/json/src/test/resources/data/y_number_real_capital_e_neg_exp.json new file mode 100644 index 0000000..0a01bd3 --- /dev/null +++ b/json/src/test/resources/data/y_number_real_capital_e_neg_exp.json @@ -0,0 +1 @@ +[1E-2] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_real_capital_e_pos_exp.json b/json/src/test/resources/data/y_number_real_capital_e_pos_exp.json new file mode 100644 index 0000000..5a8fc09 --- /dev/null +++ b/json/src/test/resources/data/y_number_real_capital_e_pos_exp.json @@ -0,0 +1 @@ +[1E+2] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_real_exponent.json b/json/src/test/resources/data/y_number_real_exponent.json new file mode 100644 index 0000000..da2522d --- /dev/null +++ b/json/src/test/resources/data/y_number_real_exponent.json @@ -0,0 +1 @@ +[123e45] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_real_fraction_exponent.json b/json/src/test/resources/data/y_number_real_fraction_exponent.json new file mode 100644 index 0000000..3944a7a --- /dev/null +++ b/json/src/test/resources/data/y_number_real_fraction_exponent.json @@ -0,0 +1 @@ +[123.456e78] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_real_neg_exp.json b/json/src/test/resources/data/y_number_real_neg_exp.json new file mode 100644 index 0000000..ca40d3c --- /dev/null +++ b/json/src/test/resources/data/y_number_real_neg_exp.json @@ -0,0 +1 @@ +[1e-2] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_real_pos_exponent.json b/json/src/test/resources/data/y_number_real_pos_exponent.json new file mode 100644 index 0000000..343601d --- /dev/null +++ b/json/src/test/resources/data/y_number_real_pos_exponent.json @@ -0,0 +1 @@ +[1e+2] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_simple_int.json b/json/src/test/resources/data/y_number_simple_int.json new file mode 100644 index 0000000..e47f69a --- /dev/null +++ b/json/src/test/resources/data/y_number_simple_int.json @@ -0,0 +1 @@ +[123] \ No newline at end of file diff --git a/json/src/test/resources/data/y_number_simple_real.json b/json/src/test/resources/data/y_number_simple_real.json new file mode 100644 index 0000000..b02878e --- /dev/null +++ b/json/src/test/resources/data/y_number_simple_real.json @@ -0,0 +1 @@ +[123.456789] \ No newline at end of file diff --git a/json/src/test/resources/data/y_object.json b/json/src/test/resources/data/y_object.json new file mode 100644 index 0000000..78262ed --- /dev/null +++ b/json/src/test/resources/data/y_object.json @@ -0,0 +1 @@ +{"asd":"sdf", "dfg":"fgh"} \ No newline at end of file diff --git a/json/src/test/resources/data/y_object_basic.json b/json/src/test/resources/data/y_object_basic.json new file mode 100644 index 0000000..646bbe7 --- /dev/null +++ b/json/src/test/resources/data/y_object_basic.json @@ -0,0 +1 @@ +{"asd":"sdf"} \ No newline at end of file diff --git a/json/src/test/resources/data/y_object_duplicated_key.json b/json/src/test/resources/data/y_object_duplicated_key.json new file mode 100644 index 0000000..bbc2e1c --- /dev/null +++ b/json/src/test/resources/data/y_object_duplicated_key.json @@ -0,0 +1 @@ +{"a":"b","a":"c"} \ No newline at end of file diff --git a/json/src/test/resources/data/y_object_duplicated_key_and_value.json b/json/src/test/resources/data/y_object_duplicated_key_and_value.json new file mode 100644 index 0000000..211581c --- /dev/null +++ b/json/src/test/resources/data/y_object_duplicated_key_and_value.json @@ -0,0 +1 @@ +{"a":"b","a":"b"} \ No newline at end of file diff --git a/json/src/test/resources/data/y_object_empty.json b/json/src/test/resources/data/y_object_empty.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/json/src/test/resources/data/y_object_empty.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/json/src/test/resources/data/y_object_empty_key.json b/json/src/test/resources/data/y_object_empty_key.json new file mode 100644 index 0000000..c0013d3 --- /dev/null +++ b/json/src/test/resources/data/y_object_empty_key.json @@ -0,0 +1 @@ +{"":0} \ No newline at end of file diff --git a/json/src/test/resources/data/y_object_escaped_null_in_key.json b/json/src/test/resources/data/y_object_escaped_null_in_key.json new file mode 100644 index 0000000..593f0f6 --- /dev/null +++ b/json/src/test/resources/data/y_object_escaped_null_in_key.json @@ -0,0 +1 @@ +{"foo\u0000bar": 42} \ No newline at end of file diff --git a/json/src/test/resources/data/y_object_extreme_numbers.json b/json/src/test/resources/data/y_object_extreme_numbers.json new file mode 100644 index 0000000..a0d3531 --- /dev/null +++ b/json/src/test/resources/data/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/json/src/test/resources/data/y_object_long_strings.json b/json/src/test/resources/data/y_object_long_strings.json new file mode 100644 index 0000000..bdc4a08 --- /dev/null +++ b/json/src/test/resources/data/y_object_long_strings.json @@ -0,0 +1 @@ +{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"} \ No newline at end of file diff --git a/json/src/test/resources/data/y_object_simple.json b/json/src/test/resources/data/y_object_simple.json new file mode 100644 index 0000000..dacac91 --- /dev/null +++ b/json/src/test/resources/data/y_object_simple.json @@ -0,0 +1 @@ +{"a":[]} \ No newline at end of file diff --git a/json/src/test/resources/data/y_object_string_unicode.json b/json/src/test/resources/data/y_object_string_unicode.json new file mode 100644 index 0000000..8effdb2 --- /dev/null +++ b/json/src/test/resources/data/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/json/src/test/resources/data/y_object_with_newlines.json b/json/src/test/resources/data/y_object_with_newlines.json new file mode 100644 index 0000000..246ec6b --- /dev/null +++ b/json/src/test/resources/data/y_object_with_newlines.json @@ -0,0 +1,3 @@ +{ +"a": "b" +} \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_1_2_3_bytes_UTF-8_sequences.json b/json/src/test/resources/data/y_string_1_2_3_bytes_UTF-8_sequences.json new file mode 100644 index 0000000..9967dde --- /dev/null +++ b/json/src/test/resources/data/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/json/src/test/resources/data/y_string_accepted_surrogate_pair.json b/json/src/test/resources/data/y_string_accepted_surrogate_pair.json new file mode 100644 index 0000000..996875c --- /dev/null +++ b/json/src/test/resources/data/y_string_accepted_surrogate_pair.json @@ -0,0 +1 @@ +["\uD801\udc37"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_accepted_surrogate_pairs.json b/json/src/test/resources/data/y_string_accepted_surrogate_pairs.json new file mode 100644 index 0000000..3401021 --- /dev/null +++ b/json/src/test/resources/data/y_string_accepted_surrogate_pairs.json @@ -0,0 +1 @@ +["\ud83d\ude39\ud83d\udc8d"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_allowed_escapes.json b/json/src/test/resources/data/y_string_allowed_escapes.json new file mode 100644 index 0000000..7f49553 --- /dev/null +++ b/json/src/test/resources/data/y_string_allowed_escapes.json @@ -0,0 +1 @@ +["\"\\\/\b\f\n\r\t"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_backslash_and_u_escaped_zero.json b/json/src/test/resources/data/y_string_backslash_and_u_escaped_zero.json new file mode 100644 index 0000000..d4439ed --- /dev/null +++ b/json/src/test/resources/data/y_string_backslash_and_u_escaped_zero.json @@ -0,0 +1 @@ +["\\u0000"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_backslash_doublequotes.json b/json/src/test/resources/data/y_string_backslash_doublequotes.json new file mode 100644 index 0000000..ae03243 --- /dev/null +++ b/json/src/test/resources/data/y_string_backslash_doublequotes.json @@ -0,0 +1 @@ +["\""] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_comments.json b/json/src/test/resources/data/y_string_comments.json new file mode 100644 index 0000000..2260c20 --- /dev/null +++ b/json/src/test/resources/data/y_string_comments.json @@ -0,0 +1 @@ +["a/*b*/c/*d//e"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_double_escape_a.json b/json/src/test/resources/data/y_string_double_escape_a.json new file mode 100644 index 0000000..6715d6f --- /dev/null +++ b/json/src/test/resources/data/y_string_double_escape_a.json @@ -0,0 +1 @@ +["\\a"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_double_escape_n.json b/json/src/test/resources/data/y_string_double_escape_n.json new file mode 100644 index 0000000..44ca56c --- /dev/null +++ b/json/src/test/resources/data/y_string_double_escape_n.json @@ -0,0 +1 @@ +["\\n"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_escaped_control_character.json b/json/src/test/resources/data/y_string_escaped_control_character.json new file mode 100644 index 0000000..5b014a9 --- /dev/null +++ b/json/src/test/resources/data/y_string_escaped_control_character.json @@ -0,0 +1 @@ +["\u0012"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_escaped_noncharacter.json b/json/src/test/resources/data/y_string_escaped_noncharacter.json new file mode 100644 index 0000000..2ff52e2 --- /dev/null +++ b/json/src/test/resources/data/y_string_escaped_noncharacter.json @@ -0,0 +1 @@ +["\uFFFF"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_in_array.json b/json/src/test/resources/data/y_string_in_array.json new file mode 100644 index 0000000..21d7ae4 --- /dev/null +++ b/json/src/test/resources/data/y_string_in_array.json @@ -0,0 +1 @@ +["asd"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_in_array_with_leading_space.json b/json/src/test/resources/data/y_string_in_array_with_leading_space.json new file mode 100644 index 0000000..9e1887c --- /dev/null +++ b/json/src/test/resources/data/y_string_in_array_with_leading_space.json @@ -0,0 +1 @@ +[ "asd"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_last_surrogates_1_and_2.json b/json/src/test/resources/data/y_string_last_surrogates_1_and_2.json new file mode 100644 index 0000000..3919cef --- /dev/null +++ b/json/src/test/resources/data/y_string_last_surrogates_1_and_2.json @@ -0,0 +1 @@ +["\uDBFF\uDFFF"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_nbsp_uescaped.json b/json/src/test/resources/data/y_string_nbsp_uescaped.json new file mode 100644 index 0000000..2085ab1 --- /dev/null +++ b/json/src/test/resources/data/y_string_nbsp_uescaped.json @@ -0,0 +1 @@ +["new\u00A0line"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_nonCharacterInUTF-8_U+10FFFF.json b/json/src/test/resources/data/y_string_nonCharacterInUTF-8_U+10FFFF.json new file mode 100644 index 0000000..059e4d9 --- /dev/null +++ b/json/src/test/resources/data/y_string_nonCharacterInUTF-8_U+10FFFF.json @@ -0,0 +1 @@ +["􏿿"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_nonCharacterInUTF-8_U+FFFF.json b/json/src/test/resources/data/y_string_nonCharacterInUTF-8_U+FFFF.json new file mode 100644 index 0000000..4c913bd --- /dev/null +++ b/json/src/test/resources/data/y_string_nonCharacterInUTF-8_U+FFFF.json @@ -0,0 +1 @@ +["￿"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_null_escape.json b/json/src/test/resources/data/y_string_null_escape.json new file mode 100644 index 0000000..c1ad844 --- /dev/null +++ b/json/src/test/resources/data/y_string_null_escape.json @@ -0,0 +1 @@ +["\u0000"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_one-byte-utf-8.json b/json/src/test/resources/data/y_string_one-byte-utf-8.json new file mode 100644 index 0000000..1571859 --- /dev/null +++ b/json/src/test/resources/data/y_string_one-byte-utf-8.json @@ -0,0 +1 @@ +["\u002c"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_pi.json b/json/src/test/resources/data/y_string_pi.json new file mode 100644 index 0000000..9df11ae --- /dev/null +++ b/json/src/test/resources/data/y_string_pi.json @@ -0,0 +1 @@ +["π"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_reservedCharacterInUTF-8_U+1BFFF.json b/json/src/test/resources/data/y_string_reservedCharacterInUTF-8_U+1BFFF.json new file mode 100644 index 0000000..12d2253 --- /dev/null +++ b/json/src/test/resources/data/y_string_reservedCharacterInUTF-8_U+1BFFF.json @@ -0,0 +1 @@ +["𛿿"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_simple_ascii.json b/json/src/test/resources/data/y_string_simple_ascii.json new file mode 100644 index 0000000..8cadf7d --- /dev/null +++ b/json/src/test/resources/data/y_string_simple_ascii.json @@ -0,0 +1 @@ +["asd "] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_space.json b/json/src/test/resources/data/y_string_space.json new file mode 100644 index 0000000..efd782c --- /dev/null +++ b/json/src/test/resources/data/y_string_space.json @@ -0,0 +1 @@ +" " \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json b/json/src/test/resources/data/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json new file mode 100644 index 0000000..7620b66 --- /dev/null +++ b/json/src/test/resources/data/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json @@ -0,0 +1 @@ +["\uD834\uDd1e"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_three-byte-utf-8.json b/json/src/test/resources/data/y_string_three-byte-utf-8.json new file mode 100644 index 0000000..108f1d6 --- /dev/null +++ b/json/src/test/resources/data/y_string_three-byte-utf-8.json @@ -0,0 +1 @@ +["\u0821"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_two-byte-utf-8.json b/json/src/test/resources/data/y_string_two-byte-utf-8.json new file mode 100644 index 0000000..461503c --- /dev/null +++ b/json/src/test/resources/data/y_string_two-byte-utf-8.json @@ -0,0 +1 @@ +["\u0123"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_u+2028_line_sep.json b/json/src/test/resources/data/y_string_u+2028_line_sep.json new file mode 100644 index 0000000..897b602 --- /dev/null +++ b/json/src/test/resources/data/y_string_u+2028_line_sep.json @@ -0,0 +1 @@ +["
"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_u+2029_par_sep.json b/json/src/test/resources/data/y_string_u+2029_par_sep.json new file mode 100644 index 0000000..8cd998c --- /dev/null +++ b/json/src/test/resources/data/y_string_u+2029_par_sep.json @@ -0,0 +1 @@ +["
"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_uEscape.json b/json/src/test/resources/data/y_string_uEscape.json new file mode 100644 index 0000000..f7b41a0 --- /dev/null +++ b/json/src/test/resources/data/y_string_uEscape.json @@ -0,0 +1 @@ +["\u0061\u30af\u30EA\u30b9"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_uescaped_newline.json b/json/src/test/resources/data/y_string_uescaped_newline.json new file mode 100644 index 0000000..3a5a220 --- /dev/null +++ b/json/src/test/resources/data/y_string_uescaped_newline.json @@ -0,0 +1 @@ +["new\u000Aline"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_unescaped_char_delete.json b/json/src/test/resources/data/y_string_unescaped_char_delete.json new file mode 100644 index 0000000..7d064f4 --- /dev/null +++ b/json/src/test/resources/data/y_string_unescaped_char_delete.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_unicode.json b/json/src/test/resources/data/y_string_unicode.json new file mode 100644 index 0000000..3598095 --- /dev/null +++ b/json/src/test/resources/data/y_string_unicode.json @@ -0,0 +1 @@ +["\uA66D"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_unicodeEscapedBackslash.json b/json/src/test/resources/data/y_string_unicodeEscapedBackslash.json new file mode 100644 index 0000000..0bb3b51 --- /dev/null +++ b/json/src/test/resources/data/y_string_unicodeEscapedBackslash.json @@ -0,0 +1 @@ +["\u005C"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_unicode_2.json b/json/src/test/resources/data/y_string_unicode_2.json new file mode 100644 index 0000000..a7dcb97 --- /dev/null +++ b/json/src/test/resources/data/y_string_unicode_2.json @@ -0,0 +1 @@ +["⍂㈴⍂"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_unicode_U+10FFFE_nonchar.json b/json/src/test/resources/data/y_string_unicode_U+10FFFE_nonchar.json new file mode 100644 index 0000000..9a8370b --- /dev/null +++ b/json/src/test/resources/data/y_string_unicode_U+10FFFE_nonchar.json @@ -0,0 +1 @@ +["\uDBFF\uDFFE"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_unicode_U+1FFFE_nonchar.json b/json/src/test/resources/data/y_string_unicode_U+1FFFE_nonchar.json new file mode 100644 index 0000000..c51f8ae --- /dev/null +++ b/json/src/test/resources/data/y_string_unicode_U+1FFFE_nonchar.json @@ -0,0 +1 @@ +["\uD83F\uDFFE"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json b/json/src/test/resources/data/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json new file mode 100644 index 0000000..626d5f8 --- /dev/null +++ b/json/src/test/resources/data/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json @@ -0,0 +1 @@ +["\u200B"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_unicode_U+2064_invisible_plus.json b/json/src/test/resources/data/y_string_unicode_U+2064_invisible_plus.json new file mode 100644 index 0000000..1e23972 --- /dev/null +++ b/json/src/test/resources/data/y_string_unicode_U+2064_invisible_plus.json @@ -0,0 +1 @@ +["\u2064"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_unicode_U+FDD0_nonchar.json b/json/src/test/resources/data/y_string_unicode_U+FDD0_nonchar.json new file mode 100644 index 0000000..18ef151 --- /dev/null +++ b/json/src/test/resources/data/y_string_unicode_U+FDD0_nonchar.json @@ -0,0 +1 @@ +["\uFDD0"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_unicode_U+FFFE_nonchar.json b/json/src/test/resources/data/y_string_unicode_U+FFFE_nonchar.json new file mode 100644 index 0000000..13d261f --- /dev/null +++ b/json/src/test/resources/data/y_string_unicode_U+FFFE_nonchar.json @@ -0,0 +1 @@ +["\uFFFE"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_unicode_escaped_double_quote.json b/json/src/test/resources/data/y_string_unicode_escaped_double_quote.json new file mode 100644 index 0000000..4e62578 --- /dev/null +++ b/json/src/test/resources/data/y_string_unicode_escaped_double_quote.json @@ -0,0 +1 @@ +["\u0022"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_utf8.json b/json/src/test/resources/data/y_string_utf8.json new file mode 100644 index 0000000..4087843 --- /dev/null +++ b/json/src/test/resources/data/y_string_utf8.json @@ -0,0 +1 @@ +["€𝄞"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_string_with_del_character.json b/json/src/test/resources/data/y_string_with_del_character.json new file mode 100644 index 0000000..8bd2490 --- /dev/null +++ b/json/src/test/resources/data/y_string_with_del_character.json @@ -0,0 +1 @@ +["aa"] \ No newline at end of file diff --git a/json/src/test/resources/data/y_structure_lonely_false.json b/json/src/test/resources/data/y_structure_lonely_false.json new file mode 100644 index 0000000..02e4a84 --- /dev/null +++ b/json/src/test/resources/data/y_structure_lonely_false.json @@ -0,0 +1 @@ +false \ No newline at end of file diff --git a/json/src/test/resources/data/y_structure_lonely_int.json b/json/src/test/resources/data/y_structure_lonely_int.json new file mode 100644 index 0000000..f70d7bb --- /dev/null +++ b/json/src/test/resources/data/y_structure_lonely_int.json @@ -0,0 +1 @@ +42 \ No newline at end of file diff --git a/json/src/test/resources/data/y_structure_lonely_negative_real.json b/json/src/test/resources/data/y_structure_lonely_negative_real.json new file mode 100644 index 0000000..b5135a2 --- /dev/null +++ b/json/src/test/resources/data/y_structure_lonely_negative_real.json @@ -0,0 +1 @@ +-0.1 \ No newline at end of file diff --git a/json/src/test/resources/data/y_structure_lonely_null.json b/json/src/test/resources/data/y_structure_lonely_null.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/json/src/test/resources/data/y_structure_lonely_null.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/json/src/test/resources/data/y_structure_lonely_string.json b/json/src/test/resources/data/y_structure_lonely_string.json new file mode 100644 index 0000000..b6e982c --- /dev/null +++ b/json/src/test/resources/data/y_structure_lonely_string.json @@ -0,0 +1 @@ +"asd" \ No newline at end of file diff --git a/json/src/test/resources/data/y_structure_lonely_true.json b/json/src/test/resources/data/y_structure_lonely_true.json new file mode 100644 index 0000000..f32a580 --- /dev/null +++ b/json/src/test/resources/data/y_structure_lonely_true.json @@ -0,0 +1 @@ +true \ No newline at end of file diff --git a/json/src/test/resources/data/y_structure_string_empty.json b/json/src/test/resources/data/y_structure_string_empty.json new file mode 100644 index 0000000..3cc762b --- /dev/null +++ b/json/src/test/resources/data/y_structure_string_empty.json @@ -0,0 +1 @@ +"" \ No newline at end of file diff --git a/json/src/test/resources/data/y_structure_trailing_newline.json b/json/src/test/resources/data/y_structure_trailing_newline.json new file mode 100644 index 0000000..0c3426d --- /dev/null +++ b/json/src/test/resources/data/y_structure_trailing_newline.json @@ -0,0 +1 @@ +["a"] diff --git a/json/src/test/resources/data/y_structure_true_in_array.json b/json/src/test/resources/data/y_structure_true_in_array.json new file mode 100644 index 0000000..de601e3 --- /dev/null +++ b/json/src/test/resources/data/y_structure_true_in_array.json @@ -0,0 +1 @@ +[true] \ No newline at end of file diff --git a/json/src/test/resources/data/y_structure_whitespace_array.json b/json/src/test/resources/data/y_structure_whitespace_array.json new file mode 100644 index 0000000..2bedf7f --- /dev/null +++ b/json/src/test/resources/data/y_structure_whitespace_array.json @@ -0,0 +1 @@ + [] \ No newline at end of file From 58d21d8a0a3040fb42007ca9f146b397751d20bd Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Fri, 18 Apr 2025 00:34:57 -0600 Subject: [PATCH 11/28] add json codec --- json/src/main/java/alpine/json/JsonCodec.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 json/src/main/java/alpine/json/JsonCodec.java diff --git a/json/src/main/java/alpine/json/JsonCodec.java b/json/src/main/java/alpine/json/JsonCodec.java new file mode 100644 index 0000000..daffcdc --- /dev/null +++ b/json/src/main/java/alpine/json/JsonCodec.java @@ -0,0 +1,37 @@ +package alpine.json; + +import alpine.json.Element; + +import java.util.function.Function; + +public interface JsonCodec { + T decode(E element); + + E encode(T value); + + static JsonCodec of(Function decoder, Function encoder) { + return new JsonCodec<>() { + @Override + public T decode(E element) { + return decoder.apply(element); + } + + @Override + public E encode(T value) { + return encoder.apply(value); + } + }; + } + + static JsonCodec decode(Function decoder) { + return of(decoder, value -> { + throw new UnsupportedOperationException("This JSON codec does not support encoding!"); + }); + } + + static JsonCodec encode(Function encoder) { + return of(value -> { + throw new UnsupportedOperationException("This JSON codec does not support encoding!"); + }, encoder); + } +} From 22205e7900939ea93a69e79e1f038d3f519eb0ea Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Sat, 19 Apr 2025 18:12:00 -0600 Subject: [PATCH 12/28] add built-in json codecs --- json/src/main/java/alpine/json/JsonCodec.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/json/src/main/java/alpine/json/JsonCodec.java b/json/src/main/java/alpine/json/JsonCodec.java index daffcdc..5130fcf 100644 --- a/json/src/main/java/alpine/json/JsonCodec.java +++ b/json/src/main/java/alpine/json/JsonCodec.java @@ -1,14 +1,30 @@ package alpine.json; -import alpine.json.Element; - import java.util.function.Function; public interface JsonCodec { + JsonCodec BOOLEAN = of(BooleanElement::value, Element::bool); + JsonCodec NUMBER = of(NumberElement::value, Element::number); + JsonCodec STRING = of(StringElement::value, Element::string); + T decode(E element); E encode(T value); + default JsonCodec map(Function to, Function from) { + return new JsonCodec<>() { + @Override + public U decode(E element) { + return to.apply(JsonCodec.this.decode(element)); + } + + @Override + public E encode(U value) { + return JsonCodec.this.encode(from.apply(value)); + } + }; + } + static JsonCodec of(Function decoder, Function encoder) { return new JsonCodec<>() { @Override @@ -34,4 +50,8 @@ static JsonCodec encode(Function encoder) { throw new UnsupportedOperationException("This JSON codec does not support encoding!"); }, encoder); } + + static > JsonCodec name(Class clazz) { + return STRING.map(name -> Enum.valueOf(clazz, name), Enum::name); + } } From 4a5ced5dda1be4e41e514a20deffcb49c180561e Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Wed, 23 Apr 2025 00:02:55 -0600 Subject: [PATCH 13/28] add file shorthands --- json/src/main/java/alpine/json/Json.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/json/src/main/java/alpine/json/Json.java b/json/src/main/java/alpine/json/Json.java index 8692be7..230f3bb 100644 --- a/json/src/main/java/alpine/json/Json.java +++ b/json/src/main/java/alpine/json/Json.java @@ -1,6 +1,6 @@ package alpine.json; -import java.io.IOException; +import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; @@ -73,6 +73,10 @@ public static Element read(Path path) throws ParsingException { } } + public static Element read(File file) throws ParsingException { + return read(file.toPath()); + } + public static String write(Element element, Formatting formatting) { return WRITER.write(element, formatting); } @@ -85,6 +89,10 @@ public static void write(Path path, Element element, Formatting formatting) { } } + public static void write(File file, Element element, Formatting formatting) { + write(file.toPath(), element, formatting); + } + static boolean isControl(char character) { return character <= 0x1F; } @@ -99,13 +107,13 @@ static boolean isWhitespace(char character) { public record Formatting(String indentation, String newLine, String comma, String colon) { public static final Formatting COMPACT = new Formatting( "", - String.valueOf(LINE_FEED), + System.lineSeparator(), String.valueOf(COMMA), String.valueOf(COLON)); public static final Formatting PRETTY = new Formatting( String.valueOf(SPACE).repeat(4), - String.valueOf(LINE_FEED), + System.lineSeparator(), COMPACT.comma + SPACE, COMPACT.colon + SPACE); } From 8f102a4ef1960823c70df2be0782cdd29fe5f77d Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Wed, 23 Apr 2025 23:05:41 -0600 Subject: [PATCH 14/28] thanks nopox --- binary/src/main/java/alpine/binary/MapBinaryCodec.java | 2 ++ json/src/main/java/alpine/json/Element.java | 4 ++++ json/src/main/java/alpine/json/JsonReader.java | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/binary/src/main/java/alpine/binary/MapBinaryCodec.java b/binary/src/main/java/alpine/binary/MapBinaryCodec.java index 424129d..879c0c7 100644 --- a/binary/src/main/java/alpine/binary/MapBinaryCodec.java +++ b/binary/src/main/java/alpine/binary/MapBinaryCodec.java @@ -28,6 +28,8 @@ public Map read(ByteBuf buffer) { @Override public void write(ByteBuf buffer, Map value) { + VARINT.write(buffer, value.size()); + for (var entry : value.entrySet()) { this.keyCodec.write(buffer, entry.getKey()); this.valueCodec.write(buffer, entry.getValue()); diff --git a/json/src/main/java/alpine/json/Element.java b/json/src/main/java/alpine/json/Element.java index d831ecb..31719e1 100644 --- a/json/src/main/java/alpine/json/Element.java +++ b/json/src/main/java/alpine/json/Element.java @@ -12,6 +12,10 @@ static BooleanElement bool(boolean value) { } static NumberElement number(double value) { + if (Double.isNaN(value) && Double.isInfinite(value)) { + throw new IllegalArgumentException("NaN and infinite numbers are not allowed!"); + } + return new NumberElement(value); } diff --git a/json/src/main/java/alpine/json/JsonReader.java b/json/src/main/java/alpine/json/JsonReader.java index 9e94f38..89cfb3b 100644 --- a/json/src/main/java/alpine/json/JsonReader.java +++ b/json/src/main/java/alpine/json/JsonReader.java @@ -12,7 +12,7 @@ final class JsonReader { private int position; Element read(String input) throws ParsingException { - this.input = input.trim(); + this.input = input; this.position = 0; this.skipWhitespace(); return this.readElement(); From bb6a35d2c9a89a6ee26fe1b2da8aa7ff7b66d820 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 25 Apr 2025 14:08:24 +0000 Subject: [PATCH 15/28] Update dependency gradle to v8.14 --- gradle/wrapper/gradle-wrapper.jar | Bin 43705 -> 43764 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 4 ++-- gradlew.bat | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 9bbc975c742b298b441bfb90dbc124400a3751b9..1b33c55baabb587c669f562ae36f953de2481846 100644 GIT binary patch delta 642 zcmdmamFde>rVZJA^}0Q$xegf!xPEW^+5YDM%iT2bEgct9o+jH~+sJas#HZ=szO|** z=Pj=X_vx?W&DSwKck|WWn~hffsvnQ+42*W$b7b0$SCcOoZ`{W{^$^pk;4>8-A*-)$ z?n(Po`1$6Jn_u?t-L+tsPyZ2#X}8T6OS8pAU;kdgd+_Hw4z4TW0p9E!T+=f7-c&O% zFic^X{7^$?^Ho04eona9n#mGMxKhA=~8B%JN`M zMhm5wc-2v)$``sY$!Q`9xiU@DhI73ZxiGEKg>yIPs)NmWwMdF-ngLXpZSqV5ez36n zVkxF2rjrjWR+_xr6e6@_u@s~2uv{9vi*1pj2)BjFD+-%@&pRVP1f{O1glxTOp2-62Ph;v z`N1+vCd)9ea)af*Ol1*JCfnp$%Uu}%OuoN7g2}3C@`L5FlP#(sA=|h@iixuZC?qp^ z=L$=v$ZoI}|87Wh=&h7udff{aieKr*l+zDp?pf)_bbRvUf>kn;HCDMXNlgbbo!QRK I1x7am0No)LiU0rr delta 584 zcmexzm1*ZyrVZJAexH5Moc8h7)w{^+t*dqJ%=yhh23L$9JpFV=_k`zJ-?Q4DI*eSe z+ES)HSrVnWLtJ&)lO%hRkV9zl5qqWRt0e;bb zPPo`)y?HTAyZI&u&X<|2$FDHCf4;!v8}p=?Tm`^F0`u(|1ttf~&t$qP3KUSD>@TJQ zRwJ}Pim6NzEc8KA6)e;S6gs8=7IIL8sQL*MYEuRYO;Uj<%3UbMbV&^&!Zvx+LKmjT z8Zch6rYP7Tw?$Hn(UTJwWiS=$f{lB(C=e*%usDV})0AQIK~sat=ND@+Gg*Pyij!rR z*fa02W|%BsV++>4W{DKDGSIUEHd2$P+8ct!RF+CHDowUuTEZOZ%rJSQv*qOXOSPDN zT|sP-$p*_3ncsWB*qoD7JQcyZ9xan%cJP6Tb4-?AZpr*F6v98hoNaPJm@HV`yya5N z))6pqFXn@}P(3T0nEzM8*c_9KtE9o|_pFd&K35GBXP^9Kg(b6GH-z8S4GDzIl~T+b zdLd#meKKHu$5u))8cu$=GKINkGDPOUD)!0$C(BH(U!}!-e;Q0ok8Sc?V1zRO04>ts AA^-pY diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 37f853b..ca025c8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index faf9300..23d15a9 100755 --- a/gradlew +++ b/gradlew @@ -114,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -213,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 9b42019..5eed7ee 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell From 5a590f29a0d4af03360a4162ffdc80dcdae235f3 Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Tue, 29 Apr 2025 16:53:57 -0600 Subject: [PATCH 16/28] add more json javadocs --- .../main/java/alpine/binary/BinaryCodec.java | 2 +- .../src/main/java/alpine/binary/Either.java | 5 ++ .../java/alpine/binary/EitherBinaryCodec.java | 12 ++- .../main/java/alpine/json/ArrayElement.java | 1 + .../main/java/alpine/json/BooleanElement.java | 5 ++ json/src/main/java/alpine/json/Element.java | 14 ++++ json/src/main/java/alpine/json/Json.java | 79 +++++-------------- json/src/main/java/alpine/json/JsonCodec.java | 27 +++++++ .../src/main/java/alpine/json/JsonReader.java | 26 +++--- .../main/java/alpine/json/JsonUtility.java | 79 +++++++++++++++++++ .../src/main/java/alpine/json/JsonWriter.java | 13 +-- .../main/java/alpine/json/NullElement.java | 7 ++ .../main/java/alpine/json/NumberElement.java | 5 ++ .../main/java/alpine/json/ObjectElement.java | 5 ++ .../java/alpine/json/ParsingException.java | 4 + .../main/java/alpine/json/StringElement.java | 5 ++ 16 files changed, 205 insertions(+), 84 deletions(-) create mode 100644 json/src/main/java/alpine/json/JsonUtility.java diff --git a/binary/src/main/java/alpine/binary/BinaryCodec.java b/binary/src/main/java/alpine/binary/BinaryCodec.java index de4b802..a86e8ba 100644 --- a/binary/src/main/java/alpine/binary/BinaryCodec.java +++ b/binary/src/main/java/alpine/binary/BinaryCodec.java @@ -12,7 +12,7 @@ import java.util.function.Supplier; /** - * Represents something that can encode and decode a value. + * Represents something that can encode and decode a value to a byte buffer. * @param The value type. * @author mudkip */ diff --git a/binary/src/main/java/alpine/binary/Either.java b/binary/src/main/java/alpine/binary/Either.java index cc095cf..7d7465c 100644 --- a/binary/src/main/java/alpine/binary/Either.java +++ b/binary/src/main/java/alpine/binary/Either.java @@ -9,6 +9,7 @@ * Something that can be represented as one of two types. * @param The left type. * @param The right type. + * @author mudkip */ public final class Either { enum Type { @@ -89,6 +90,10 @@ public void consume(Consumer leftConsumer, Consumer rightConsumer) { this.ifRight(rightConsumer); } + public Either swap() { + return this.isLeft() ? right(this.left) : left(this.right); + } + public boolean isLeft() { return this.type == Type.LEFT; } diff --git a/binary/src/main/java/alpine/binary/EitherBinaryCodec.java b/binary/src/main/java/alpine/binary/EitherBinaryCodec.java index 31683d5..30a692b 100644 --- a/binary/src/main/java/alpine/binary/EitherBinaryCodec.java +++ b/binary/src/main/java/alpine/binary/EitherBinaryCodec.java @@ -9,6 +9,7 @@ * @param The left value type. * @param The right value type. * @see Either + * @author mudkip */ record EitherBinaryCodec(BinaryCodec leftCodec, BinaryCodec rightCodec) implements BinaryCodec> { @Override @@ -22,12 +23,9 @@ public Either read(ByteBuf buffer) { @Override public void write(ByteBuf buffer, Either value) { - if (value.isLeft()) { - BOOLEAN.write(buffer, false); - this.leftCodec.write(buffer, value.expectLeft()); - } else { - BOOLEAN.write(buffer, true); - this.rightCodec.write(buffer, value.expectRight()); - } + BOOLEAN.write(buffer, value.isRight()); + value.consume( + left -> this.leftCodec.write(buffer, left), + right -> this.rightCodec.write(buffer, right)); } } diff --git a/json/src/main/java/alpine/json/ArrayElement.java b/json/src/main/java/alpine/json/ArrayElement.java index b7fb977..ff7bb5b 100644 --- a/json/src/main/java/alpine/json/ArrayElement.java +++ b/json/src/main/java/alpine/json/ArrayElement.java @@ -12,6 +12,7 @@ /** * A JSON element which in itself stores an ordered sequence of elements. + * @see RFC 8259 * @author mudkip */ public final class ArrayElement implements Element, Iterable { diff --git a/json/src/main/java/alpine/json/BooleanElement.java b/json/src/main/java/alpine/json/BooleanElement.java index 051a608..b2905f7 100644 --- a/json/src/main/java/alpine/json/BooleanElement.java +++ b/json/src/main/java/alpine/json/BooleanElement.java @@ -1,5 +1,10 @@ package alpine.json; +/** + * A JSON element which can represent a {@code true} or {@code false} value. + * @see RFC 8259 + * @author mudkip + */ public final class BooleanElement implements Element { private final boolean value; diff --git a/json/src/main/java/alpine/json/Element.java b/json/src/main/java/alpine/json/Element.java index 31719e1..1366b10 100644 --- a/json/src/main/java/alpine/json/Element.java +++ b/json/src/main/java/alpine/json/Element.java @@ -2,6 +2,20 @@ import java.util.*; +/** + * The base class for a JSON element. + *

+ * A JSON element can be one of the following types: + *

    + *
  • {@code null} — represented by {@link NullElement}
  • + *
  • {@code boolean} — represented by {@link BooleanElement}
  • + *
  • {@code number} — represented by {@link NumberElement}
  • + *
  • {@code string} — represented by {@link StringElement}
  • + *
  • {@code array} — represented by {@link ArrayElement}
  • + *
  • {@code object} — represented by {@link ObjectElement}
  • + *
+ * @author mudkip + */ public sealed interface Element permits ArrayElement, BooleanElement, NullElement, NumberElement, ObjectElement, StringElement { static NullElement nil() { return NullElement.INSTANCE; diff --git a/json/src/main/java/alpine/json/Json.java b/json/src/main/java/alpine/json/Json.java index 230f3bb..8e5374f 100644 --- a/json/src/main/java/alpine/json/Json.java +++ b/json/src/main/java/alpine/json/Json.java @@ -3,60 +3,17 @@ import java.io.*; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Map; +import static alpine.json.JsonUtility.*; + +/** + * A helper class for reading and writing JSON data. + * @author mudkip + */ public final class Json { private static final JsonReader READER = new JsonReader(); private static final JsonWriter WRITER = new JsonWriter(); - // Structural - static final char BEGIN_OBJECT = '{'; - static final char END_OBJECT = '}'; - static final char BEGIN_ARRAY = '['; - static final char END_ARRAY = ']'; - static final char COMMA = ','; - static final char COLON = ':'; - - // Strings - static final char QUOTE = '"'; - static final char BACKSLASH = '\\'; - static final char SLASH = '/'; - - // Whitespace - static final char SPACE = ' '; - static final char TAB = '\t'; - static final char LINE_FEED = '\n'; - static final char CARRIAGE_RETURN = '\r'; - - // Literals - static final String NULL = "null"; - static final String TRUE = "true"; - static final String FALSE = "false"; - - // Other - static final char BACKSPACE = '\b'; - static final char FORM_FEED = '\f'; - - // Escaping - static final Map CHARACTER_TO_ESCAPE = Map.of( - QUOTE, QUOTE, - BACKSLASH, BACKSLASH, - BACKSPACE, 'b', - FORM_FEED, 'f', - LINE_FEED, 'n', - CARRIAGE_RETURN, 'r', - TAB, 't'); - - static final Map ESCAPE_TO_CHARACTER = Map.of( - 'b', BACKSPACE, - 'f', FORM_FEED, - 'n', LINE_FEED, - 'r', CARRIAGE_RETURN, - 't', TAB, - QUOTE, QUOTE, - BACKSLASH, BACKSLASH, - SLASH, SLASH); - private Json() { } @@ -93,24 +50,26 @@ public static void write(File file, Element element, Formatting formatting) { write(file.toPath(), element, formatting); } - static boolean isControl(char character) { - return character <= 0x1F; - } - - static boolean isWhitespace(char character) { - return character == SPACE - || character == TAB - || character == LINE_FEED - || character == CARRIAGE_RETURN; - } - + /** + * Defines rules for customizing the formatting when writing JSON data. + * @param indentation The string to use when indenting. Typically empty, a tab character ({@code \t}), or multiple spaces. + * @param newLine The string to use to terminate a line. Typically empty, a Unix line ending ({@code \n}) or a Windows line ending ({@code \r\n}). + * @param comma The string to use between values of an object or array. Typically {@code ,} followed by a space. + * @param colon The string to use between key-value pairs of an object. Typically {@code :} followed by a space. + */ public record Formatting(String indentation, String newLine, String comma, String colon) { + /** + * Represents a minified format ideal for exchanging data over the network. + */ public static final Formatting COMPACT = new Formatting( "", System.lineSeparator(), String.valueOf(COMMA), String.valueOf(COLON)); + /** + * Represents a beautified format ideal for human readability. + */ public static final Formatting PRETTY = new Formatting( String.valueOf(SPACE).repeat(4), System.lineSeparator(), diff --git a/json/src/main/java/alpine/json/JsonCodec.java b/json/src/main/java/alpine/json/JsonCodec.java index 5130fcf..2ed0f37 100644 --- a/json/src/main/java/alpine/json/JsonCodec.java +++ b/json/src/main/java/alpine/json/JsonCodec.java @@ -2,13 +2,40 @@ import java.util.function.Function; +/** + * Represents something that can encode and decode a value to a JSON element. + * @param The value type. + * @param The type of the element the codec will be writing to. + * @author mudkip + */ public interface JsonCodec { + /** + * A JSON codec which serializes a boolean as a {@code true} or {@code false} value. + */ JsonCodec BOOLEAN = of(BooleanElement::value, Element::bool); + + /** + * A JSON codec which serializes an integer or a fractional number. + */ JsonCodec NUMBER = of(NumberElement::value, Element::number); + + /** + * A JSON codec which serializes a sequence of characters. + */ JsonCodec STRING = of(StringElement::value, Element::string); + /** + * Decodes the value from the element. + * @param element The element + * @return The decoded value. + */ T decode(E element); + /** + * Encodes a value to an element. + * @param value The + * @return The JSON element. + */ E encode(T value); default JsonCodec map(Function to, Function from) { diff --git a/json/src/main/java/alpine/json/JsonReader.java b/json/src/main/java/alpine/json/JsonReader.java index 89cfb3b..55092c8 100644 --- a/json/src/main/java/alpine/json/JsonReader.java +++ b/json/src/main/java/alpine/json/JsonReader.java @@ -1,12 +1,15 @@ package alpine.json; +import org.jetbrains.annotations.ApiStatus; + import java.util.ArrayList; import java.util.LinkedHashMap; import static alpine.json.Element.*; -import static alpine.json.Json.*; +import static alpine.json.JsonUtility.*; import static java.lang.Character.isDigit; +@ApiStatus.Internal final class JsonReader { private String input; private int position; @@ -21,9 +24,9 @@ Element read(String input) throws ParsingException { private Element readElement() throws ParsingException { var character = this.peek(); - if (character == '"') { + if (character == QUOTE) { return this.parseString(); - } else if (isDigit(character) || character == '-') { + } else if (isDigit(character) || character == MINUS) { return this.parseNumber(); } else if (character == TRUE.charAt(0) || character == FALSE.charAt(0)) { return this.parseBoolean(); @@ -48,10 +51,10 @@ private NullElement parseNull() throws ParsingException { } private BooleanElement parseBoolean() throws ParsingException { - if (this.input.startsWith("true", this.position)) { + if (this.input.startsWith(TRUE, this.position)) { this.position += TRUE.length(); return bool(true); - } else if (this.input.startsWith("false", this.position)) { + } else if (this.input.startsWith(FALSE, this.position)) { this.position += FALSE.length(); return bool(false); } @@ -64,7 +67,7 @@ private NumberElement parseNumber() throws ParsingException { var length = this.input.length(); // negative sign - if (this.peek() == '-') { + if (this.peek() == MINUS) { this.position++; } @@ -80,7 +83,7 @@ private NumberElement parseNumber() throws ParsingException { } // fraction part - if (this.position < length && this.input.charAt(this.position) == '.') { + if (this.position < length && this.input.charAt(this.position) == BEGIN_DECIMAL) { this.position++; if (this.position >= length || !isDigit(this.input.charAt(this.position))) { throw new ParsingException(this.input, "Expected digit(s) after the decimal point!", this.position); @@ -94,7 +97,7 @@ private NumberElement parseNumber() throws ParsingException { // exponent part if (this.position < length && this.isExponent(this.input.charAt(this.position))) { this.position++; - if (this.position < length && (this.input.charAt(this.position) == '+' || this.input.charAt(this.position) == '-')) { + if (this.position < length && (this.input.charAt(this.position) == PLUS || this.input.charAt(this.position) == MINUS)) { this.position++; } @@ -146,7 +149,7 @@ private StringElement parseString() throws ParsingException { var escapeCharacter = this.input.charAt(this.position++); - if (escapeCharacter == 'u') { + if (escapeCharacter == UNICODE_ESCAPE) { if (this.position + 4 > this.input.length()) { throw new ParsingException(this.input, "Invalid unicode escape", this.position); } @@ -222,7 +225,7 @@ private ObjectElement parseObject() throws ParsingException { while (true) { this.skipWhitespace(); - if (this.peek() != '"') { + if (this.peek() != QUOTE) { throw new ParsingException(this.input, "Expected string for object key!", this.position); } @@ -247,7 +250,8 @@ private ObjectElement parseObject() throws ParsingException { } private boolean isExponent(char character) { - return character == 'e' || character == 'E'; + return character == Character.toLowerCase(EXPONENT) + || character == Character.toUpperCase(EXPONENT); } private char peek() throws ParsingException { diff --git a/json/src/main/java/alpine/json/JsonUtility.java b/json/src/main/java/alpine/json/JsonUtility.java new file mode 100644 index 0000000..3ab926a --- /dev/null +++ b/json/src/main/java/alpine/json/JsonUtility.java @@ -0,0 +1,79 @@ +package alpine.json; + +import org.jetbrains.annotations.ApiStatus; + +import java.util.Map; + +/** + * Represents constants internal to the JSON parser. + *

+ * Includes things like which characters to escape within a string. + */ +@ApiStatus.Internal +interface JsonUtility { + static boolean isControl(char character) { + return character <= 0x1F; + } + + static boolean isWhitespace(char character) { + return character == SPACE + || character == TAB + || character == LINE_FEED + || character == CARRIAGE_RETURN; + } + + // Structural + char BEGIN_OBJECT = '{'; + char END_OBJECT = '}'; + char BEGIN_ARRAY = '['; + char END_ARRAY = ']'; + char COMMA = ','; + char COLON = ':'; + + // Strings + char QUOTE = '"'; + char BACKSLASH = '\\'; + char SLASH = '/'; + char UNICODE_ESCAPE = 'u'; + + // Numbers + char PLUS = '+'; + char MINUS = '-'; + char EXPONENT = 'e'; + char BEGIN_DECIMAL = '.'; + + // Whitespace + char SPACE = ' '; + char TAB = '\t'; + char LINE_FEED = '\n'; + char CARRIAGE_RETURN = '\r'; + + // Literals + String NULL = "null"; + String TRUE = "true"; + String FALSE = "false"; + + // Other + char BACKSPACE = '\b'; + char FORM_FEED = '\f'; + + // Escaping + Map CHARACTER_TO_ESCAPE = Map.of( + QUOTE, QUOTE, + BACKSLASH, BACKSLASH, + BACKSPACE, 'b', + FORM_FEED, 'f', + LINE_FEED, 'n', + CARRIAGE_RETURN, 'r', + TAB, 't'); + + Map ESCAPE_TO_CHARACTER = Map.of( + 'b', BACKSPACE, + 'f', FORM_FEED, + 'n', LINE_FEED, + 'r', CARRIAGE_RETURN, + 't', TAB, + QUOTE, QUOTE, + BACKSLASH, BACKSLASH, + SLASH, SLASH); +} diff --git a/json/src/main/java/alpine/json/JsonWriter.java b/json/src/main/java/alpine/json/JsonWriter.java index a4e6856..dec5712 100644 --- a/json/src/main/java/alpine/json/JsonWriter.java +++ b/json/src/main/java/alpine/json/JsonWriter.java @@ -1,16 +1,19 @@ package alpine.json; +import org.jetbrains.annotations.ApiStatus; + import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; -import static alpine.json.Json.*; +import static alpine.json.JsonUtility.*; +@ApiStatus.Internal final class JsonWriter { private static final String ESCAPED = "" + QUOTE + BACKSLASH + BACKSPACE + FORM_FEED + LINE_FEED + CARRIAGE_RETURN + TAB; - String write(Element value, Formatting formatting) { + String write(Element value, Json.Formatting formatting) { var builder = new StringBuilder(); switch (value) { @@ -44,7 +47,7 @@ private void writeString(StringBuilder builder, String string) { if (CHARACTER_TO_ESCAPE.containsKey(character)) { builder.append(BACKSLASH).append(CHARACTER_TO_ESCAPE.get(character)); } else if (Character.isISOControl(character)) { - builder.append(String.format("\\u%04X", (int) character)); + builder.append(String.format("\\%c%04X", UNICODE_ESCAPE, (int) character)); } else { builder.append(character); } @@ -53,7 +56,7 @@ private void writeString(StringBuilder builder, String string) { builder.append(QUOTE); } - private void writeArray(StringBuilder builder, ArrayElement element, Formatting formatting) { + private void writeArray(StringBuilder builder, ArrayElement element, Json.Formatting formatting) { builder .append(BEGIN_ARRAY) .append(element.stream() @@ -62,7 +65,7 @@ private void writeArray(StringBuilder builder, ArrayElement element, Formatting .append(END_ARRAY); } - private void writeObject(StringBuilder builder, ObjectElement element, Formatting formatting) { + private void writeObject(StringBuilder builder, ObjectElement element, Json.Formatting formatting) { var firstElement = new AtomicBoolean(true); builder.append(BEGIN_OBJECT); diff --git a/json/src/main/java/alpine/json/NullElement.java b/json/src/main/java/alpine/json/NullElement.java index c83c08c..7ba683e 100644 --- a/json/src/main/java/alpine/json/NullElement.java +++ b/json/src/main/java/alpine/json/NullElement.java @@ -1,5 +1,12 @@ package alpine.json; +/** + * A JSON element which represents the absence of a value. + *

+ * This element can only be represented as {@code null} in encoded form. + * @see RFC 8259 + * @author mudkip + */ public final class NullElement implements Element { static final NullElement INSTANCE = new NullElement(); diff --git a/json/src/main/java/alpine/json/NumberElement.java b/json/src/main/java/alpine/json/NumberElement.java index 3a271de..163a99e 100644 --- a/json/src/main/java/alpine/json/NumberElement.java +++ b/json/src/main/java/alpine/json/NumberElement.java @@ -1,5 +1,10 @@ package alpine.json; +/** + * A JSON element which can represent both integers and fractional numbers. + * @see RFC 8259 + * @author mudkip + */ public final class NumberElement implements Element { private final double value; diff --git a/json/src/main/java/alpine/json/ObjectElement.java b/json/src/main/java/alpine/json/ObjectElement.java index 3c11ef9..57fe3c9 100644 --- a/json/src/main/java/alpine/json/ObjectElement.java +++ b/json/src/main/java/alpine/json/ObjectElement.java @@ -10,6 +10,11 @@ import java.util.function.Consumer; import java.util.stream.Stream; +/** + * A JSON element which stores a collection of key-value pairs where the keys are strings. + * @see RFC 8259 + * @author mudkip + */ public final class ObjectElement implements Element { private final Map elements; diff --git a/json/src/main/java/alpine/json/ParsingException.java b/json/src/main/java/alpine/json/ParsingException.java index 3492cd1..e021078 100644 --- a/json/src/main/java/alpine/json/ParsingException.java +++ b/json/src/main/java/alpine/json/ParsingException.java @@ -1,5 +1,9 @@ package alpine.json; +/** + * An exception thrown when the JSON parser encounters malformed input. + * @author mudkip + */ public final class ParsingException extends Exception { private final String input; private final int position; diff --git a/json/src/main/java/alpine/json/StringElement.java b/json/src/main/java/alpine/json/StringElement.java index 0a383d8..3ac0636 100644 --- a/json/src/main/java/alpine/json/StringElement.java +++ b/json/src/main/java/alpine/json/StringElement.java @@ -2,6 +2,11 @@ import java.util.Objects; +/** + * A JSON element which can store a sequence of Unicode characters. + * @see RFC 8259 + * @author mudkip + */ public final class StringElement implements Element { private final String value; From be4f3e78a91fbbc8aa8be4eed467cea3a69e1c94 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 16:05:44 +0000 Subject: [PATCH 17/28] Update dependency io.netty:netty-buffer to v4.2.1.Final --- binary/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/binary/build.gradle.kts b/binary/build.gradle.kts index 85802cf..957acb1 100644 --- a/binary/build.gradle.kts +++ b/binary/build.gradle.kts @@ -1,6 +1,6 @@ description = "A binary serialization library for Java." dependencies { - compileOnly("io.netty:netty-buffer:4.2.0.Final") - testImplementation("io.netty:netty-buffer:4.2.0.Final") + compileOnly("io.netty:netty-buffer:4.2.1.Final") + testImplementation("io.netty:netty-buffer:4.2.1.Final") } \ No newline at end of file From 643c111f5b9611cea9d637a1420587dd642ebf70 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 May 2025 19:08:06 +0000 Subject: [PATCH 18/28] Update plugin com.vanniktech.maven.publish to v0.32.0 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index a235e09..ae63fc2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ import com.vanniktech.maven.publish.SonatypeHost plugins { java signing - id("com.vanniktech.maven.publish") version "0.31.0" + id("com.vanniktech.maven.publish") version "0.32.0" } subprojects { From 16d503d7215338d38b324da4268c92bc0133e95b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 May 2025 20:27:19 +0000 Subject: [PATCH 19/28] Update dependency gradle to v8.14.1 --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ca025c8..002b867 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 1cdc478034712ffd5b51df7080f63a51e629f76a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 30 May 2025 11:33:23 +0000 Subject: [PATCH 20/28] Update junit5 monorepo --- build.gradle.kts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index ae63fc2..bd1e658 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,10 +21,10 @@ subprojects { dependencies { compileOnly("org.jetbrains:annotations:26.0.2") - testImplementation("org.junit.jupiter:junit-jupiter-api:5.12.2") - testImplementation("org.junit.jupiter:junit-jupiter-params:5.12.2") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.12.2") - testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.12.2") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.13.0") + testImplementation("org.junit.jupiter:junit-jupiter-params:5.13.0") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.13.0") + testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.13.0") } tasks.test { From 5f9df06dc9b68069656ff4f3b939d3acc1b37fad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Jun 2025 08:41:30 +0000 Subject: [PATCH 21/28] Update dependency io.netty:netty-buffer to v4.2.2.Final --- binary/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/binary/build.gradle.kts b/binary/build.gradle.kts index 957acb1..bca9466 100644 --- a/binary/build.gradle.kts +++ b/binary/build.gradle.kts @@ -1,6 +1,6 @@ description = "A binary serialization library for Java." dependencies { - compileOnly("io.netty:netty-buffer:4.2.1.Final") - testImplementation("io.netty:netty-buffer:4.2.1.Final") + compileOnly("io.netty:netty-buffer:4.2.2.Final") + testImplementation("io.netty:netty-buffer:4.2.2.Final") } \ No newline at end of file From 80fa6937fdc6dd4a1618031a3e45bf3fdc277a2b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Jun 2025 21:34:29 +0000 Subject: [PATCH 22/28] Update dependency gradle to v8.14.2 --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 002b867..ff23a68 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 4c8149df712496c0e2e988af9e2a3f54629d322b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 7 Jun 2025 09:13:55 +0000 Subject: [PATCH 23/28] Update junit5 monorepo --- build.gradle.kts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index bd1e658..0895cd1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,10 +21,10 @@ subprojects { dependencies { compileOnly("org.jetbrains:annotations:26.0.2") - testImplementation("org.junit.jupiter:junit-jupiter-api:5.13.0") - testImplementation("org.junit.jupiter:junit-jupiter-params:5.13.0") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.13.0") - testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.13.0") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.13.1") + testImplementation("org.junit.jupiter:junit-jupiter-params:5.13.1") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.13.1") + testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.13.1") } tasks.test { From e745e4c64509f0958e2a2142a1755c6d3b2fa376 Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Thu, 12 Jun 2025 15:04:15 -0600 Subject: [PATCH 24/28] add decode/encode only codecs --- binary/src/main/java/alpine/binary/BinaryCodec.java | 12 ++++++++++++ json/src/main/java/alpine/json/JsonCodec.java | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/binary/src/main/java/alpine/binary/BinaryCodec.java b/binary/src/main/java/alpine/binary/BinaryCodec.java index a86e8ba..f6bac6f 100644 --- a/binary/src/main/java/alpine/binary/BinaryCodec.java +++ b/binary/src/main/java/alpine/binary/BinaryCodec.java @@ -83,6 +83,18 @@ public void write(ByteBuf buffer, T value) { }; } + static BinaryCodec decodeOnly(Function reader) { + return of(reader, (buffer, value) -> { + throw new UnsupportedOperationException("This binary codec does not support encoding!"); + }); + } + + static BinaryCodec encodeOnly(BiConsumer writer) { + return of(buffer -> { + throw new UnsupportedOperationException("This binary codec does not support decoding!"); + }, writer); + } + static BinaryCodec unit(Supplier supplier) { return of(buffer -> supplier.get(), (buffer, value) -> {}); } diff --git a/json/src/main/java/alpine/json/JsonCodec.java b/json/src/main/java/alpine/json/JsonCodec.java index 2ed0f37..8839160 100644 --- a/json/src/main/java/alpine/json/JsonCodec.java +++ b/json/src/main/java/alpine/json/JsonCodec.java @@ -66,13 +66,13 @@ public E encode(T value) { }; } - static JsonCodec decode(Function decoder) { + static JsonCodec decodeOnly(Function decoder) { return of(decoder, value -> { throw new UnsupportedOperationException("This JSON codec does not support encoding!"); }); } - static JsonCodec encode(Function encoder) { + static JsonCodec encodeOnly(Function encoder) { return of(value -> { throw new UnsupportedOperationException("This JSON codec does not support encoding!"); }, encoder); From c5ba2c4bc53b2bde0785ce66aee424ad4a3eb4bc Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Tue, 17 Jun 2025 15:44:56 -0600 Subject: [PATCH 25/28] temp benchmark code --- benchmark/build.gradle.kts | 16 ++++++ .../jmh/java/alpine/json/JsonBenchmark.java | 46 +++++++++++++++++ build.gradle.kts | 51 +++++++++++-------- settings.gradle.kts | 3 +- 4 files changed, 92 insertions(+), 24 deletions(-) create mode 100644 benchmark/build.gradle.kts create mode 100644 benchmark/src/jmh/java/alpine/json/JsonBenchmark.java diff --git a/benchmark/build.gradle.kts b/benchmark/build.gradle.kts new file mode 100644 index 0000000..8d8b0c3 --- /dev/null +++ b/benchmark/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + id("me.champeau.jmh") version "0.7.3" +} + +dependencies { + jmhImplementation(project(":json")) + jmhImplementation("org.openjdk.jmh:jmh-core:1.37") + jmhImplementation("org.openjdk.jmh:jmh-generator-annprocess:1.37") + jmhImplementation("com.google.code.gson:gson:2.13.1") +} + +jmh { + warmupIterations.set(3) + iterations.set(5) + fork.set(1) +} \ No newline at end of file diff --git a/benchmark/src/jmh/java/alpine/json/JsonBenchmark.java b/benchmark/src/jmh/java/alpine/json/JsonBenchmark.java new file mode 100644 index 0000000..211c610 --- /dev/null +++ b/benchmark/src/jmh/java/alpine/json/JsonBenchmark.java @@ -0,0 +1,46 @@ +package alpine.json; + +import com.google.gson.JsonParser; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +@State(Scope.Thread) +public class JsonBenchmark { + private static final String COMPLEX_JSON = """ + { + "name": "Mudkip", + "type": "Water", + "stats": { + "hp": 50, + "attack": 70, + "defense": 50, + "speed": 40, + "abilities": ["Torrent", "Damp"] + }, + "evolution": { + "level": 16, + "next": "Marshtomp" + }, + "moves": [ + {"name": "Water Gun", "power": 40}, + {"name": "Tackle", "power": 35}, + {"name": "Mud-Slap", "power": 20} + ], + "metadata": { + "origin": "Hoenn", + "isLegendary": false + } + } + """; + + @Benchmark + public void alpine() throws ParsingException { + Json.read(COMPLEX_JSON); + } + + @Benchmark + public void gson() { + JsonParser.parseString(COMPLEX_JSON); + } +} diff --git a/build.gradle.kts b/build.gradle.kts index 6915cbe..451593b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,31 +6,10 @@ plugins { id("com.vanniktech.maven.publish") version "0.32.0" } -subprojects { - apply(plugin = "java") +fun Project.applyPublishingSettings() { apply(plugin = "signing") apply(plugin = "com.vanniktech.maven.publish") - group = "dev.mudkip" - version = "0.2.0" - java.toolchain.languageVersion = JavaLanguageVersion.of(21) - - repositories { - mavenCentral() - } - - dependencies { - compileOnly("org.jetbrains:annotations:26.0.2") - testImplementation("org.junit.jupiter:junit-jupiter-api:5.13.1") - testImplementation("org.junit.jupiter:junit-jupiter-params:5.13.1") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.13.1") - testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.13.1") - } - - tasks.test { - useJUnitPlatform() - } - mavenPublishing { coordinates(group.toString(), "${rootProject.name}-${project.name}", version.toString()) publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) @@ -64,4 +43,32 @@ subprojects { } } } +} + +subprojects { + apply(plugin = "java") + + group = "dev.mudkip" + version = "0.2.0" + java.toolchain.languageVersion = JavaLanguageVersion.of(21) + + repositories { + mavenCentral() + } + + dependencies { + compileOnly("org.jetbrains:annotations:26.0.2") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.13.1") + testImplementation("org.junit.jupiter:junit-jupiter-params:5.13.1") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.13.1") + testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.13.1") + } + + tasks.test { + useJUnitPlatform() + } + + if (name in setOf("binary", "json")) { + applyPublishingSettings() + } } \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 00cc400..116212c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,3 +1,2 @@ rootProject.name = "alpine" -include("binary") -include("json") \ No newline at end of file +include("binary", "json", "benchmark") \ No newline at end of file From 5219dcd78d62232a889de9bed5df93d0cc7c027a Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Wed, 18 Feb 2026 20:33:34 -0700 Subject: [PATCH 26/28] update to java 25, update gradle, add write benchmark, add jackson and fastjson2 to benchmarks, speed up reading, speed up writing, fix StringElement hashCode bug, add proper json codecs, add codec builders --- benchmark/build.gradle.kts | 6 +- .../jmh/java/alpine/json/JsonBenchmark.java | 46 - .../java/alpine/json/JsonReadBenchmark.java | 66 ++ .../java/alpine/json/JsonWriteBenchmark.java | 83 ++ .../main/java/alpine/binary/BinaryCodec.java | 8 + build.gradle.kts | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 43764 -> 46175 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 5 +- gradlew.bat | 3 +- json/src/main/java/alpine/json/Element.java | 2 +- json/src/main/java/alpine/json/JsonCodec.java | 84 -- .../src/main/java/alpine/json/JsonReader.java | 185 ++- .../src/main/java/alpine/json/JsonWriter.java | 101 +- .../main/java/alpine/json/ObjectElement.java | 114 +- .../main/java/alpine/json/StringElement.java | 2 +- .../main/java/alpine/json/codec/Codec.java | 11 + .../java/alpine/json/codec/CodecBuilder.java | 1052 +++++++++++++++++ .../alpine/json/codec/DecodingException.java | 7 + .../alpine/json/codec/JsonTranscoder.java | 74 ++ .../alpine/json/codec/PrimitiveCodecs.java | 51 + .../java/alpine/json/codec/Transcoder.java | 27 + .../java/alpine/json/CodecBuilderTest.java | 24 + json/src/test/java/alpine/json/JsonTest.java | 12 +- .../src/test/java/alpine/json/ObjectTest.java | 6 +- 25 files changed, 1719 insertions(+), 254 deletions(-) delete mode 100644 benchmark/src/jmh/java/alpine/json/JsonBenchmark.java create mode 100644 benchmark/src/jmh/java/alpine/json/JsonReadBenchmark.java create mode 100644 benchmark/src/jmh/java/alpine/json/JsonWriteBenchmark.java delete mode 100644 json/src/main/java/alpine/json/JsonCodec.java create mode 100644 json/src/main/java/alpine/json/codec/Codec.java create mode 100644 json/src/main/java/alpine/json/codec/CodecBuilder.java create mode 100644 json/src/main/java/alpine/json/codec/DecodingException.java create mode 100644 json/src/main/java/alpine/json/codec/JsonTranscoder.java create mode 100644 json/src/main/java/alpine/json/codec/PrimitiveCodecs.java create mode 100644 json/src/main/java/alpine/json/codec/Transcoder.java create mode 100644 json/src/test/java/alpine/json/CodecBuilderTest.java diff --git a/benchmark/build.gradle.kts b/benchmark/build.gradle.kts index 8d8b0c3..9af6248 100644 --- a/benchmark/build.gradle.kts +++ b/benchmark/build.gradle.kts @@ -6,11 +6,13 @@ dependencies { jmhImplementation(project(":json")) jmhImplementation("org.openjdk.jmh:jmh-core:1.37") jmhImplementation("org.openjdk.jmh:jmh-generator-annprocess:1.37") - jmhImplementation("com.google.code.gson:gson:2.13.1") + jmhImplementation("com.google.code.gson:gson:2.13.2") + jmhImplementation("tools.jackson.core:jackson-databind:3.0.4") + jmhImplementation("com.alibaba.fastjson2:fastjson2:2.0.60") } jmh { - warmupIterations.set(3) + warmupIterations.set(5) iterations.set(5) fork.set(1) } \ No newline at end of file diff --git a/benchmark/src/jmh/java/alpine/json/JsonBenchmark.java b/benchmark/src/jmh/java/alpine/json/JsonBenchmark.java deleted file mode 100644 index 211c610..0000000 --- a/benchmark/src/jmh/java/alpine/json/JsonBenchmark.java +++ /dev/null @@ -1,46 +0,0 @@ -package alpine.json; - -import com.google.gson.JsonParser; -import org.openjdk.jmh.annotations.Benchmark; -import org.openjdk.jmh.annotations.Scope; -import org.openjdk.jmh.annotations.State; - -@State(Scope.Thread) -public class JsonBenchmark { - private static final String COMPLEX_JSON = """ - { - "name": "Mudkip", - "type": "Water", - "stats": { - "hp": 50, - "attack": 70, - "defense": 50, - "speed": 40, - "abilities": ["Torrent", "Damp"] - }, - "evolution": { - "level": 16, - "next": "Marshtomp" - }, - "moves": [ - {"name": "Water Gun", "power": 40}, - {"name": "Tackle", "power": 35}, - {"name": "Mud-Slap", "power": 20} - ], - "metadata": { - "origin": "Hoenn", - "isLegendary": false - } - } - """; - - @Benchmark - public void alpine() throws ParsingException { - Json.read(COMPLEX_JSON); - } - - @Benchmark - public void gson() { - JsonParser.parseString(COMPLEX_JSON); - } -} diff --git a/benchmark/src/jmh/java/alpine/json/JsonReadBenchmark.java b/benchmark/src/jmh/java/alpine/json/JsonReadBenchmark.java new file mode 100644 index 0000000..752ac7d --- /dev/null +++ b/benchmark/src/jmh/java/alpine/json/JsonReadBenchmark.java @@ -0,0 +1,66 @@ +package alpine.json; + +import com.alibaba.fastjson2.JSON; +import com.google.gson.JsonParser; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; +import tools.jackson.databind.ObjectMapper; + +import java.util.concurrent.TimeUnit; + +@State(Scope.Thread) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +public class JsonReadBenchmark { + private static final ObjectMapper JACKSON = new ObjectMapper(); + + // non-static, non-final to prevent the JVM from constant-folding the input + String complexJson = """ + { + "name": "Mudkip", + "type": "Water", + "stats": { + "hp": 50, + "attack": 70, + "defense": 50, + "speed": 40, + "abilities": ["Torrent", "Damp"] + }, + "evolution": { + "level": 16, + "next": "Marshtomp" + }, + "moves": [ + {"name": "Water Gun", "power": 40}, + {"name": "Tackle", "power": 35}, + {"name": "Mud-Slap", "power": 20} + ], + "metadata": { + "origin": "Hoenn", + "isLegendary": false + } + } + """; + + @Benchmark + public void alpine(Blackhole blackhole) throws Exception { + blackhole.consume(Json.read(this.complexJson)); + } + + @Benchmark + public void gson(Blackhole blackhole) throws Exception { + blackhole.consume(JsonParser.parseString(this.complexJson)); + } + + @Benchmark + public void jackson(Blackhole blackhole) throws Exception { + blackhole.consume(JACKSON.readTree(this.complexJson)); + } + + @Benchmark + public void fastjson(Blackhole blackhole) throws Exception { + blackhole.consume(JSON.parseObject(this.complexJson)); + } +} diff --git a/benchmark/src/jmh/java/alpine/json/JsonWriteBenchmark.java b/benchmark/src/jmh/java/alpine/json/JsonWriteBenchmark.java new file mode 100644 index 0000000..409e465 --- /dev/null +++ b/benchmark/src/jmh/java/alpine/json/JsonWriteBenchmark.java @@ -0,0 +1,83 @@ +package alpine.json; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; + +import java.util.concurrent.TimeUnit; + +@State(Scope.Thread) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +public class JsonWriteBenchmark { + private static final ObjectMapper JACKSON = new ObjectMapper(); + private static final Gson GSON = new Gson(); + + private static final String COMPLEX_JSON = """ + { + "name": "Mudkip", + "type": "Water", + "stats": { + "hp": 50, + "attack": 70, + "defense": 50, + "speed": 40, + "abilities": ["Torrent", "Damp"] + }, + "evolution": { + "level": 16, + "next": "Marshtomp" + }, + "moves": [ + {"name": "Water Gun", "power": 40}, + {"name": "Tackle", "power": 35}, + {"name": "Mud-Slap", "power": 20} + ], + "metadata": { + "origin": "Hoenn", + "isLegendary": false + } + } + """; + + private Element alpineElement; + private JsonElement gsonElement; + private JsonNode jacksonNode; + private JSONObject fastjsonObject; + + @Setup(Level.Trial) + public void setup() throws Exception { + this.alpineElement = Json.read(COMPLEX_JSON); + this.gsonElement = JsonParser.parseString(COMPLEX_JSON); + this.jacksonNode = JACKSON.readTree(COMPLEX_JSON); + this.fastjsonObject = JSON.parseObject(COMPLEX_JSON); + } + + @Benchmark + public void alpine(Blackhole blackhole) throws Exception { + blackhole.consume(Json.write(this.alpineElement, Json.Formatting.COMPACT)); + } + + @Benchmark + public void gson(Blackhole blackhole) throws Exception { + blackhole.consume(GSON.toJson(this.gsonElement)); + } + + @Benchmark + public void jackson(Blackhole blackhole) throws Exception { + blackhole.consume(JACKSON.writeValueAsString(this.jacksonNode)); + } + + @Benchmark + public void fastjson(Blackhole blackhole) throws Exception { + blackhole.consume(JSON.toJSONString(this.fastjsonObject)); + } +} diff --git a/binary/src/main/java/alpine/binary/BinaryCodec.java b/binary/src/main/java/alpine/binary/BinaryCodec.java index f6bac6f..2113922 100644 --- a/binary/src/main/java/alpine/binary/BinaryCodec.java +++ b/binary/src/main/java/alpine/binary/BinaryCodec.java @@ -83,6 +83,14 @@ public void write(ByteBuf buffer, T value) { }; } + static BinaryCodec unsupported() { + return of(buffer -> { + throw new UnsupportedOperationException("This binary codec is not implemented!"); + }, (buffer, value) -> { + throw new UnsupportedOperationException("This binary codec is not implemented!"); + }); + } + static BinaryCodec decodeOnly(Function reader) { return of(reader, (buffer, value) -> { throw new UnsupportedOperationException("This binary codec does not support encoding!"); diff --git a/build.gradle.kts b/build.gradle.kts index 451593b..18e4cf1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -50,7 +50,7 @@ subprojects { group = "dev.mudkip" version = "0.2.0" - java.toolchain.languageVersion = JavaLanguageVersion.of(21) + java.toolchain.languageVersion = JavaLanguageVersion.of(25) repositories { mavenCentral() diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 1b33c55baabb587c669f562ae36f953de2481846..61285a659d17295f1de7c53e24fdf13ad755c379 100644 GIT binary patch delta 37988 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 xt3G?g z4&W%tBqXPbR`Dfgu>2G0TRV&4bOw6_Oz;EyI?i0{oODJ_4RFbbY2RF|&r|=*#sMY0 z^C#;!#u8O8tq#gKuO^NKL!6Empu_>FK3#2qJJ>Gg2Xel_lYOijF0X4d*)|59)BO|T zbURajp;K0G60wrdr5zug$aA=!F{BTlUpz*+?~5|qnzM^2-)J~`dY|bTblUUB2E0zZ zTVU9xOlwKgGs`C~SzmLe70MsFd5R%^#gG5Fe3Ew+Y@7c|KK8HV)<8aT1VdaD@53hs zK3VM$cX*5nGAbswuZ9B6S5JK1%{5s~{ABm!0TL{o--m-y_e#*5;Gks<%U4#kR=7EL zfdL<|duXWGB1Xo2BtemLawd&4`z5*w2gbEEKX_nZG}cRNIdHbz1`hQ=nDsa0xI&=n84=S@gGA2DHTxQF0jjouQnFsD*`p#;*Xg)EAP?cklFQb>(sA} zqNk`Su_t$9u&Lr6nlrh_xaFqd&PVrLKB?HbeLk9Nmy1i)h$6BN$+5&R?!ns!q3|_` zIU3m-`iV13Iwu;dUqV*uj0CvF&z5e_ryG5NqxHN$QUepAY&@Sf0-)FUqLKGPE?Tuybs0 zflp2+u!wi|uhII!bB}KtElo6FEaxecon!{PqX04^gX-k2woe$JhG1$>RKotzO>vVX zf~U5Pf+n937U@14ClFNVgE3AL>-48h;3<)wwUITF_%(1WH zt`@dMMY1U6RpwZhRTz1f@oPD?J~KglvhXauZl_U5!YyO@N!e(v>YEx#ue9$_$}Klc zs*8wd-HSapLJ!kDq;u0txcz@oOi2^~qFdeV`n?vl9v&LL=}oqoP8OqVAI@`b-wuJV z#+?@iA-7*ULLx$N1cjJ#h|QcqZoFJLn_I{uu?x*pMmvmx_kgMF0znV&_ztnBr@!8p zUC?2~#v)1@;PrS~$vt15qCoU8teD&L%Pq%N$EZFxAGBC8hc`FVXvTO(Jo_M1oy+eA z^_7k=J!_a^M?dmq@x)*>Kzt@6Y;3xou%6JGW&y8B> z%%tcqpf79fPUvikJUbYLNldGFu*~+sGnDd&gPW10*$Bj5mAH|82V>xVA~7jHbf_8) zkrU#%C=m-jZC@4f5pIxXQAfE2o*puTv=@LPB{+ngnBZA~wL)Sn@ezgnuokGZkd2Xp+j2&bAixl>UdhtWT=nGFR8N_Zz(q8aI!vtcZ;N^| z_PMlgO?9N@79w`#!HdJ_Bwwt`%JX-w>Wr?i5{#LOhtl6{jm^1C9Oaw(Ts4^QQJGmt z?>sWdDdptyT>&Adp*tjGx)@ko6sv(%+W1Jaia(KUfv12MZ&K9|@NE-I_&1qmt`**Am7|)DZk7<}0lEb(bp|OCIpv*7ETM(?Lz-@t>PU0~)D1BEIs_YYB&Z7Oh6Mb&2M1vC4_z5qw(S9VpM z(nw04WrEHJBmi=6!AM5Kz2u>-^?$<^=|x*Z=SbD^Quu;#a7yW-gd-TEj7IIvbGYQY zQ8Vby5K2EmJ!6U^gGiQ|bZ3v_9_J&t&?p*X@#E{>6R_(qR}F=yq_Ior>zBGeUfW8H~Sw?Z6`>8E+J9iP_v1=!S{< z7cL7;5UE+f;AR)G+fPuRb7yyAU!d8}<3ABR2{@VN{c~_q!3x1*kqkaMK6X6r?3z1<@E1h5xo+)q%j zQeUw}SQ(M@cv>Ykax~-it9ui1yu#%7$Qpo;opj*sy1)IXM>x}9{$ZmYTBW#%;qVqi zhZibvl2%4P>LkNfDwL&iLfuZ3WSr5XiNO嵍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 delta 35498 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 The value type. - * @param The type of the element the codec will be writing to. - * @author mudkip - */ -public interface JsonCodec { - /** - * A JSON codec which serializes a boolean as a {@code true} or {@code false} value. - */ - JsonCodec BOOLEAN = of(BooleanElement::value, Element::bool); - - /** - * A JSON codec which serializes an integer or a fractional number. - */ - JsonCodec NUMBER = of(NumberElement::value, Element::number); - - /** - * A JSON codec which serializes a sequence of characters. - */ - JsonCodec STRING = of(StringElement::value, Element::string); - - /** - * Decodes the value from the element. - * @param element The element - * @return The decoded value. - */ - T decode(E element); - - /** - * Encodes a value to an element. - * @param value The - * @return The JSON element. - */ - E encode(T value); - - default JsonCodec map(Function to, Function from) { - return new JsonCodec<>() { - @Override - public U decode(E element) { - return to.apply(JsonCodec.this.decode(element)); - } - - @Override - public E encode(U value) { - return JsonCodec.this.encode(from.apply(value)); - } - }; - } - - static JsonCodec of(Function decoder, Function encoder) { - return new JsonCodec<>() { - @Override - public T decode(E element) { - return decoder.apply(element); - } - - @Override - public E encode(T value) { - return encoder.apply(value); - } - }; - } - - static JsonCodec decodeOnly(Function decoder) { - return of(decoder, value -> { - throw new UnsupportedOperationException("This JSON codec does not support encoding!"); - }); - } - - static JsonCodec encodeOnly(Function encoder) { - return of(value -> { - throw new UnsupportedOperationException("This JSON codec does not support encoding!"); - }, encoder); - } - - static > JsonCodec name(Class clazz) { - return STRING.map(name -> Enum.valueOf(clazz, name), Enum::name); - } -} diff --git a/json/src/main/java/alpine/json/JsonReader.java b/json/src/main/java/alpine/json/JsonReader.java index 55092c8..82a9322 100644 --- a/json/src/main/java/alpine/json/JsonReader.java +++ b/json/src/main/java/alpine/json/JsonReader.java @@ -12,10 +12,12 @@ @ApiStatus.Internal final class JsonReader { private String input; + private char[] characters; private int position; Element read(String input) throws ParsingException { this.input = input; + this.characters = input.toCharArray(); this.position = 0; this.skipWhitespace(); return this.readElement(); @@ -42,8 +44,14 @@ private Element readElement() throws ParsingException { } private NullElement parseNull() throws ParsingException { - if (this.input.startsWith(NULL, this.position)) { - this.position += NULL.length(); + var length = this.characters.length; + + if (this.position + 4 <= length + && this.characters[this.position + 0] == 'n' + && this.characters[this.position + 1] == 'u' + && this.characters[this.position + 2] == 'l' + && this.characters[this.position + 3] == 'l') { + this.position += 4; return nil(); } @@ -51,11 +59,24 @@ private NullElement parseNull() throws ParsingException { } private BooleanElement parseBoolean() throws ParsingException { - if (this.input.startsWith(TRUE, this.position)) { - this.position += TRUE.length(); + var length = this.characters.length; + + if (this.position + 4 <= length + && this.characters[this.position + 0] == 't' + && this.characters[this.position + 1] == 'r' + && this.characters[this.position + 2] == 'u' + && this.characters[this.position + 3] == 'e') { + this.position += 4; return bool(true); - } else if (this.input.startsWith(FALSE, this.position)) { - this.position += FALSE.length(); + } + + if (this.position + 5 <= length + && this.characters[this.position + 0] == 'f' + && this.characters[this.position + 1] == 'a' + && this.characters[this.position + 2] == 'l' + && this.characters[this.position + 3] == 's' + && this.characters[this.position + 4] == 'e') { + this.position += 5; return bool(false); } @@ -64,7 +85,7 @@ private BooleanElement parseBoolean() throws ParsingException { private NumberElement parseNumber() throws ParsingException { var start = this.position; - var length = this.input.length(); + var length = this.characters.length; // negative sign if (this.peek() == MINUS) { @@ -75,7 +96,7 @@ private NumberElement parseNumber() throws ParsingException { if (this.peek() == '0') { this.position++; } else if (this.peek() >= '1' && this.peek() <= '9') { - while (this.position < length && isDigit(this.input.charAt(this.position))) { + while (this.position < length && isDigit(this.characters[this.position])) { this.position++; } } else { @@ -83,97 +104,141 @@ private NumberElement parseNumber() throws ParsingException { } // fraction part - if (this.position < length && this.input.charAt(this.position) == BEGIN_DECIMAL) { + if (this.position < length && this.characters[this.position] == BEGIN_DECIMAL) { this.position++; - if (this.position >= length || !isDigit(this.input.charAt(this.position))) { + if (this.position >= length || !isDigit(this.characters[this.position])) { throw new ParsingException(this.input, "Expected digit(s) after the decimal point!", this.position); } - while (this.position < length && isDigit(this.input.charAt(this.position))) { + while (this.position < length && isDigit(this.characters[this.position])) { this.position++; } } // exponent part - if (this.position < length && this.isExponent(this.input.charAt(this.position))) { - this.position++; - if (this.position < length && (this.input.charAt(this.position) == PLUS || this.input.charAt(this.position) == MINUS)) { + if (this.position < length) { + var character = this.characters[this.position]; + + if (character == 'e' || character == 'E') { this.position++; - } - if (this.position >= length || !isDigit(this.input.charAt(this.position))) { - throw new ParsingException(this.input, "Expected digit(s) in exponent!", this.position); - } + if (this.position < length && (this.characters[this.position] == PLUS || this.characters[this.position] == MINUS)) { + this.position++; + } - while (this.position < length && isDigit(this.input.charAt(this.position))) { - this.position++; + if (this.position >= length || !isDigit(this.characters[this.position])) { + throw new ParsingException(this.input, "Expected digit(s) in exponent!", this.position); + } + + while (this.position < length && isDigit(this.characters[this.position])) { + this.position++; + } } } - if ( - this.position < length - && !isWhitespace(this.input.charAt(this.position)) - && ",}]".indexOf(this.input.charAt(this.position)) < 0) { - throw new ParsingException(this.input, "Invalid character after number!", this.position); + if (this.position < length) { + var character = this.characters[this.position]; + + if (!isWhitespace(character) && character != COMMA && character != END_OBJECT && character != END_ARRAY) { + throw new ParsingException(this.input, "Invalid character after number!", this.position); + } } - var text = this.input.substring(start, this.position); + var text = new String(this.characters, start, this.position - start); try { - return number(Double.parseDouble(text)); + var value = Double.parseDouble(text); + + if (Double.isInfinite(value) || Double.isNaN(value)) { + throw new ParsingException(this.input, "Number out of range: " + text, start); + } + + return number(value); } catch (NumberFormatException exception) { throw new ParsingException(this.input, "Invalid number \"" + text + "\"!", start); } } - private StringElement parseString() throws ParsingException { - var builder = new StringBuilder(); + return string(this.parseRawString()); + } + + private String parseRawString() throws ParsingException { this.expect(QUOTE); + var start = this.position; + var length = this.characters.length; + + // fast path: scan for closing quote with no escape sequences + while (this.position < length) { + var character = this.characters[this.position]; + + if (character == QUOTE) { + return new String(this.characters, start, this.position++ - start); + } + + if (character == BACKSLASH) { + break; // fall through + } + + if (isControl(character)) { + throw new ParsingException(this.input, "Unescaped control character in string!", this.position); + } + + this.position++; + } + + if (this.position >= length) { + throw new ParsingException(this.input, "Unterminated string!", this.position); + } + + var builder = new StringBuilder(); + builder.append(this.characters, start, this.position - start); while (true) { - if (this.position >= this.input.length()) { + if (this.position >= length) { throw new ParsingException(this.input, "Unterminated string!", this.position); } - var character = this.input.charAt(this.position++); + var character = this.characters[this.position++]; if (character == QUOTE) { break; } if (character == BACKSLASH) { - if (this.position >= this.input.length()) { + if (this.position >= length) { throw new ParsingException(this.input, "Unterminated escape sequence!", this.position); } - var escapeCharacter = this.input.charAt(this.position++); + var escapeCharacter = this.characters[this.position++]; if (escapeCharacter == UNICODE_ESCAPE) { - if (this.position + 4 > this.input.length()) { + if (this.position + 4 > length) { throw new ParsingException(this.input, "Invalid unicode escape", this.position); } - var hex = this.input.substring(this.position, this.position + 4); + var hex = new String(this.characters, this.position, 4); try { - var codePoint = Integer.parseInt(hex, 16); - builder.append((char) codePoint); + builder.append((char) Integer.parseInt(hex, 16)); } catch (NumberFormatException e) { throw new ParsingException(this.input, "Invalid unicode escape: \\u" + hex, this.position); } this.position += 4; } else { - var decoded = ESCAPE_TO_CHARACTER.get(escapeCharacter); - - if (decoded == null) { - throw new ParsingException(this.input, "Invalid escape character: \\" + escapeCharacter, this.position); - } - - builder.append(decoded); + builder.append(switch (escapeCharacter) { + case '"' -> '"'; + case '\\' -> '\\'; + case '/' -> '/'; + case 'b' -> '\b'; + case 'f' -> '\f'; + case 'n' -> '\n'; + case 'r' -> '\r'; + case 't' -> '\t'; + default -> throw new ParsingException(this.input, "Invalid escape character: \\" + escapeCharacter, this.position); + }); } - } else if (isControl(character)) { throw new ParsingException(this.input, "Unescaped control character in string!", this.position); } else { @@ -181,10 +246,9 @@ private StringElement parseString() throws ParsingException { } } - return string(builder.toString()); + return builder.toString(); } - private ArrayElement parseArray() throws ParsingException { var elements = new ArrayList(); this.expect(BEGIN_ARRAY); @@ -197,8 +261,7 @@ private ArrayElement parseArray() throws ParsingException { while (true) { this.skipWhitespace(); - var element = this.readElement(); - elements.add(element); + elements.add(this.readElement()); this.skipWhitespace(); if (this.peek() == END_ARRAY) { @@ -209,7 +272,7 @@ private ArrayElement parseArray() throws ParsingException { this.expect(COMMA); } - return array(elements); + return new ArrayElement(elements); } private ObjectElement parseObject() throws ParsingException { @@ -229,13 +292,12 @@ private ObjectElement parseObject() throws ParsingException { throw new ParsingException(this.input, "Expected string for object key!", this.position); } - var key = this.parseString().value(); + var key = this.parseRawString(); this.skipWhitespace(); this.expect(COLON); this.skipWhitespace(); - var value = this.readElement(); - map.put(key, value); + map.put(key, this.readElement()); this.skipWhitespace(); if (this.peek() == END_OBJECT) { @@ -249,29 +311,26 @@ private ObjectElement parseObject() throws ParsingException { return new ObjectElement(map); } - private boolean isExponent(char character) { - return character == Character.toLowerCase(EXPONENT) - || character == Character.toUpperCase(EXPONENT); - } - private char peek() throws ParsingException { - if (this.position >= this.input.length()) { + if (this.position >= this.characters.length) { throw new ParsingException(this.input, "Unexpected end of input!", this.position); } - return this.input.charAt(this.position); + return this.characters[this.position]; } private void expect(char character) throws ParsingException { - if (this.peek() != character) { - throw new ParsingException(this.input, "Expected '" + character + "', got '" + this.peek() + "'!", this.position); + var actualCharacter = this.peek(); + + if (actualCharacter != character) { + throw new ParsingException(this.input, "Expected '" + character + "', got '" + actualCharacter + "'!", this.position); } this.position++; } private void skipWhitespace() { - while (this.position < this.input.length() && isWhitespace(this.input.charAt(this.position))) { + while (this.position < this.characters.length && isWhitespace(this.characters[this.position])) { this.position++; } } diff --git a/json/src/main/java/alpine/json/JsonWriter.java b/json/src/main/java/alpine/json/JsonWriter.java index dec5712..9e4f407 100644 --- a/json/src/main/java/alpine/json/JsonWriter.java +++ b/json/src/main/java/alpine/json/JsonWriter.java @@ -2,30 +2,33 @@ import org.jetbrains.annotations.ApiStatus; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.stream.Collectors; - import static alpine.json.JsonUtility.*; @ApiStatus.Internal final class JsonWriter { - private static final String ESCAPED = "" - + QUOTE + BACKSLASH + BACKSPACE + FORM_FEED - + LINE_FEED + CARRIAGE_RETURN + TAB; + private static final char[] HEX_CHARACTERS = "0123456789ABCDEF".toCharArray(); String write(Element value, Json.Formatting formatting) { - var builder = new StringBuilder(); + // pre-size string builder for performance + var builder = new StringBuilder(switch (value) { + case ObjectElement element -> 64 * element.length(); + case ArrayElement element -> 16 * element.length(); + default -> 32; + }); + this.write(builder, value, formatting); + return builder.toString(); + } + + private void write(StringBuilder builder, Element value, Json.Formatting formatting) { switch (value) { - case NullElement ignored -> builder.append(NULL); + case NullElement _ -> builder.append(NULL); case BooleanElement element -> builder.append(element.value() ? TRUE : FALSE); case NumberElement element -> this.writeNumber(builder, element.value()); case StringElement element -> this.writeString(builder, element.value()); case ArrayElement element -> this.writeArray(builder, element, formatting); case ObjectElement element -> this.writeObject(builder, element, formatting); - }; - - return builder.toString(); + } } private void writeNumber(StringBuilder builder, double value) { @@ -43,37 +46,79 @@ private void writeNumber(StringBuilder builder, double value) { private void writeString(StringBuilder builder, String string) { builder.append(QUOTE); - for (var character : string.toCharArray()) { - if (CHARACTER_TO_ESCAPE.containsKey(character)) { - builder.append(BACKSLASH).append(CHARACTER_TO_ESCAPE.get(character)); - } else if (Character.isISOControl(character)) { - builder.append(String.format("\\%c%04X", UNICODE_ESCAPE, (int) character)); - } else { - builder.append(character); + var start = 0; + var length = string.length(); + + for (var index = 0; index < length; index++) { + var character = string.charAt(i); + + // fast path: safe character + if (character != '"' && character != '\\' && !Character.isISOControl(character)) { + continue; + } + + if (index > start) { + builder.append(string, start, i); } + + switch (character) { + case '"' -> builder.append("\\\""); + case '\\' -> builder.append("\\\\"); + case '\b' -> builder.append("\\b"); + case '\f' -> builder.append("\\f"); + case '\n' -> builder.append("\\n"); + case '\r' -> builder.append("\\r"); + case '\t' -> builder.append("\\t"); + + default -> { + builder.append("\\u"); + builder.append(HEX_CHARACTERS[(character >> 12) & 0xF]); + builder.append(HEX_CHARACTERS[(character >> 8) & 0xF]); + builder.append(HEX_CHARACTERS[(character >> 4) & 0xF]); + builder.append(HEX_CHARACTERS[character & 0xF]); + } + } + + start = index + 1; + } + + if (start < length) { + builder.append(string, start, length); } builder.append(QUOTE); } private void writeArray(StringBuilder builder, ArrayElement element, Json.Formatting formatting) { - builder - .append(BEGIN_ARRAY) - .append(element.stream() - .map(value -> this.write(value, formatting)) - .collect(Collectors.joining(formatting.comma()))) - .append(END_ARRAY); + builder.append(BEGIN_ARRAY); + var firstElement = true; + + for (var value : element) { + if (!firstElement) { + builder.append(formatting.comma()); + } + + this.write(builder, value, formatting); + firstElement = false; + } + + builder.append(END_ARRAY); } private void writeObject(StringBuilder builder, ObjectElement element, Json.Formatting formatting) { - var firstElement = new AtomicBoolean(true); builder.append(BEGIN_OBJECT); + var firstElement = new boolean[] { true }; element.each((key, value) -> { - builder.append(firstElement.get() ? "" : formatting.comma()); + if (firstElement[0]) { + firstElement[0] = false; + } else { + builder.append(formatting.comma()); + } + this.writeString(builder, key); - firstElement.set(false); - builder.append(formatting.colon()).append(this.write(value, formatting)); + builder.append(formatting.colon()); + this.write(builder, value, formatting); }); builder.append(END_OBJECT); diff --git a/json/src/main/java/alpine/json/ObjectElement.java b/json/src/main/java/alpine/json/ObjectElement.java index 57fe3c9..ff67062 100644 --- a/json/src/main/java/alpine/json/ObjectElement.java +++ b/json/src/main/java/alpine/json/ObjectElement.java @@ -2,7 +2,6 @@ import org.jetbrains.annotations.Nullable; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; @@ -58,10 +57,103 @@ public int length() { return this.elements.get(key); } + public @Nullable String getString(String key) { + return this.getString(key, null); + } + + public @Nullable Number getNumber(String key) { + return this.getNumber(key, null); + } + + public byte getByte(String key) { + return (byte) this.getNumber(key, 0); + } + + public short getShort(String key) { + return (short) this.getNumber(key, 0); + } + + public int getInteger(String key) { + return (int) this.getNumber(key, 0); + } + + public long getLong(String key) { + return (long) this.getNumber(key, 0); + } + + public float getFloat(String key) { + return (float) this.getNumber(key, 0.0F); + } + + public double getDouble(String key) { + return (double) this.getNumber(key, 0.0D); + } + + public @Nullable Boolean getBoolean(String key) { + return this.elements.get(key) instanceof BooleanElement element + ? element.value() : null; + } + public @Nullable Element get(String key, Element fallback) { return this.elements.getOrDefault(key, fallback); } + public String getString(String key, String fallback) { + return this.elements.get(key) instanceof StringElement element + ? element.value() : fallback; + } + + public Number getNumber(String key, Number fallback) { + return this.elements.get(key) instanceof NumberElement element + ? element.value() : fallback; + } + + public byte getByte(String key, byte fallback) { + return this.elements.get(key) instanceof NumberElement element + ? (byte) element.value() : fallback; + } + + public short getShort(String key, short fallback) { + return this.elements.get(key) instanceof NumberElement element + ? (short) element.value() : fallback; + } + + public int getInteger(String key, int fallback) { + return this.elements.get(key) instanceof NumberElement element + ? (int) element.value() : fallback; + } + + public long getLong(String key, long fallback) { + return this.elements.get(key) instanceof NumberElement element + ? (long) element.value() : fallback; + } + + public float getFloat(String key, float fallback) { + return this.elements.get(key) instanceof NumberElement element + ? (float) element.value() : fallback; + } + + public double getDouble(String key, double fallback) { + return this.elements.get(key) instanceof NumberElement element + ? element.value() : fallback; + } + + public boolean getBoolean(String key, boolean fallback) { + return this.elements.get(key) instanceof BooleanElement element + ? element.value() : fallback; + } + + @SuppressWarnings("unchecked") + public T get(String key, Class clazz, T fallback) { + var element = this.elements.get(key); + + if (clazz.isInstance(element)) { + return (T) element; + } else { + return fallback; + } + } + @SuppressWarnings("unchecked") public T expect(String key, Class clazz) { var element = this.elements.get(key); @@ -73,22 +165,26 @@ public T expect(String key, Class clazz) { } else return (T) element; } - public boolean has(String key) { + public boolean hasKey(String key) { if (key == null) throw new IllegalArgumentException("Key cannot be null!"); return this.elements.containsKey(key); } - public boolean has(Element value) { + public boolean hasValue(Element value) { if (value == null) throw new IllegalArgumentException("Value cannot be null!"); return this.elements.containsValue(value); } - public boolean has(Boolean value) { - return this.has(Element.bool(value)); + public boolean hasString(String value) { + return this.hasValue(Element.string(value)); + } + + public boolean hasValue(Number value) { + return this.hasValue(Element.number(value)); } - public boolean has(Number value) { - return this.has(Element.number(value)); + public boolean hasValue(Boolean value) { + return this.hasValue(Element.bool(value)); } public void each(BiConsumer consumer) { @@ -122,7 +218,7 @@ public ObjectElement set(String key, String value) { } public ObjectElement remove(String key) { - if (!this.has(key)) { + if (!this.hasKey(key)) { throw new IllegalStateException("Key \"" + key + "\" is not present!"); } @@ -135,7 +231,7 @@ public ObjectElement clear() { public ObjectElement copy(Consumer> mutator) { if (mutator == null) throw new IllegalArgumentException("Mutator cannot be null!"); - var map = new HashMap<>(this.elements); + var map = new LinkedHashMap<>(this.elements); mutator.accept(map); return new ObjectElement(map); } diff --git a/json/src/main/java/alpine/json/StringElement.java b/json/src/main/java/alpine/json/StringElement.java index 3ac0636..cc5602f 100644 --- a/json/src/main/java/alpine/json/StringElement.java +++ b/json/src/main/java/alpine/json/StringElement.java @@ -20,7 +20,7 @@ public final class StringElement implements Element { @Override public int hashCode() { - return super.hashCode(); + return this.value.hashCode(); } @Override diff --git a/json/src/main/java/alpine/json/codec/Codec.java b/json/src/main/java/alpine/json/codec/Codec.java new file mode 100644 index 0000000..9b84ee9 --- /dev/null +++ b/json/src/main/java/alpine/json/codec/Codec.java @@ -0,0 +1,11 @@ +package alpine.json.codec; + +public interface Codec extends PrimitiveCodecs { + T decode(Transcoder transcoder, R value); + + R encode(Transcoder transcoder, T value); + + static CodecBuilder._0 builder() { + return new CodecBuilder._0<>(); + } +} diff --git a/json/src/main/java/alpine/json/codec/CodecBuilder.java b/json/src/main/java/alpine/json/codec/CodecBuilder.java new file mode 100644 index 0000000..05c3a5a --- /dev/null +++ b/json/src/main/java/alpine/json/codec/CodecBuilder.java @@ -0,0 +1,1052 @@ +package alpine.json.codec; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.Function; + +@SuppressWarnings("unused") +public final class CodecBuilder { + private CodecBuilder() { + + } + + public record Field(String key, Codec codec, Function getter) { + + } + + public static _0 builder() { + return new _0<>(); + } + + public interface Constructor0 { + R construct(); + } + + public interface Constructor1 { + R construct(F1 f1); + } + + public interface Constructor2 { + R construct(F1 f1, F2 f2); + } + + public interface Constructor3 { + R construct(F1 f1, F2 f2, F3 f3); + } + + public interface Constructor4 { + R construct(F1 f1, F2 f2, F3 f3, F4 f4); + } + + public interface Constructor5 { + R construct(F1 f1, F2 f2, F3 f3, F4 f4, F5 f5); + } + + public interface Constructor6 { + R construct(F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6); + } + + public interface Constructor7 { + R construct(F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7); + } + + public interface Constructor8 { + R construct(F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8); + } + + public interface Constructor9 { + R construct(F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8, F9 f9); + } + + public interface Constructor10 { + R construct(F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8, F9 f9, F10 f10); + } + + public interface Constructor11 { + R construct(F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8, F9 f9, F10 f10, F11 f11); + } + + public interface Constructor12 { + R construct(F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8, F9 f9, F10 f10, F11 f11, F12 f12); + } + + public interface Constructor13 { + R construct(F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8, F9 f9, F10 f10, F11 f11, F12 f12, F13 f13); + } + + public interface Constructor14 { + R construct(F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8, F9 f9, F10 f10, F11 f11, F12 f12, F13 f13, F14 f14); + } + + public interface Constructor15 { + R construct(F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8, F9 f9, F10 f10, F11 f11, F12 f12, F13 f13, F14 f14, F15 f15); + } + + public interface Constructor16 { + R construct(F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8, F9 f9, F10 f10, F11 f11, F12 f12, F13 f13, F14 f14, F15 f15, F16 f16); + } + + public static final class _0 { + _0() { + + } + + public Codec build(Constructor0 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + return constructor.construct(); + } + + @Override + public R encode(Transcoder transcoder, T value) { + return transcoder.encodeObject(Map.of()); + } + }; + } + + public _1 with(String key, Codec codec, Function getter) { + return new _1<>(new Field<>(key, codec, getter)); + } + } + + public static final class _1 { + private final Field field1; + + _1(Field field1) { + this.field1 = field1; + } + + public Codec build(Constructor1 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _1.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _1.this.field1.key())); + return constructor.construct(f1); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_1.this.field1.key(), _1.this.field1.codec().encode(transcoder, _1.this.field1.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _2 with(String key, Codec codec, Function getter) { + return new _2<>(this.field1, new Field<>(key, codec, getter)); + } + } + + public static final class _2 { + private final Field field1; + private final Field field2; + + _2(Field field1, Field field2) { + this.field1 = field1; + this.field2 = field2; + } + + public Codec build(Constructor2 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _2.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _2.this.field1.key())); + F2 f2 = _2.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _2.this.field2.key())); + return constructor.construct(f1, f2); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_2.this.field1.key(), _2.this.field1.codec().encode(transcoder, _2.this.field1.getter().apply(value))); + fields.put(_2.this.field2.key(), _2.this.field2.codec().encode(transcoder, _2.this.field2.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _3 with(String key, Codec codec, Function getter) { + return new _3<>(this.field1, this.field2, new Field<>(key, codec, getter)); + } + } + + public static final class _3 { + private final Field field1; + private final Field field2; + private final Field field3; + + _3(Field field1, Field field2, Field field3) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + } + + public Codec build(Constructor3 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _3.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _3.this.field1.key())); + F2 f2 = _3.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _3.this.field2.key())); + F3 f3 = _3.this.field3.codec().decode(transcoder, transcoder.decodeObjectField(value, _3.this.field3.key())); + return constructor.construct(f1, f2, f3); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_3.this.field1.key(), _3.this.field1.codec().encode(transcoder, _3.this.field1.getter().apply(value))); + fields.put(_3.this.field2.key(), _3.this.field2.codec().encode(transcoder, _3.this.field2.getter().apply(value))); + fields.put(_3.this.field3.key(), _3.this.field3.codec().encode(transcoder, _3.this.field3.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _4 with(String key, Codec codec, Function getter) { + return new _4<>(this.field1, this.field2, this.field3, new Field<>(key, codec, getter)); + } + } + + public static final class _4 { + private final Field field1; + private final Field field2; + private final Field field3; + private final Field field4; + + _4(Field field1, Field field2, Field field3, Field field4) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + this.field4 = field4; + } + + public Codec build(Constructor4 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _4.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _4.this.field1.key())); + F2 f2 = _4.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _4.this.field2.key())); + F3 f3 = _4.this.field3.codec().decode(transcoder, transcoder.decodeObjectField(value, _4.this.field3.key())); + F4 f4 = _4.this.field4.codec().decode(transcoder, transcoder.decodeObjectField(value, _4.this.field4.key())); + return constructor.construct(f1, f2, f3, f4); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_4.this.field1.key(), _4.this.field1.codec().encode(transcoder, _4.this.field1.getter().apply(value))); + fields.put(_4.this.field2.key(), _4.this.field2.codec().encode(transcoder, _4.this.field2.getter().apply(value))); + fields.put(_4.this.field3.key(), _4.this.field3.codec().encode(transcoder, _4.this.field3.getter().apply(value))); + fields.put(_4.this.field4.key(), _4.this.field4.codec().encode(transcoder, _4.this.field4.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _5 with(String key, Codec codec, Function getter) { + return new _5<>(this.field1, this.field2, this.field3, this.field4, new Field<>(key, codec, getter)); + } + } + + public static final class _5 { + private final Field field1; + private final Field field2; + private final Field field3; + private final Field field4; + private final Field field5; + + _5(Field field1, Field field2, Field field3, Field field4, Field field5) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + this.field4 = field4; + this.field5 = field5; + } + + public Codec build(Constructor5 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _5.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _5.this.field1.key())); + F2 f2 = _5.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _5.this.field2.key())); + F3 f3 = _5.this.field3.codec().decode(transcoder, transcoder.decodeObjectField(value, _5.this.field3.key())); + F4 f4 = _5.this.field4.codec().decode(transcoder, transcoder.decodeObjectField(value, _5.this.field4.key())); + F5 f5 = _5.this.field5.codec().decode(transcoder, transcoder.decodeObjectField(value, _5.this.field5.key())); + return constructor.construct(f1, f2, f3, f4, f5); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_5.this.field1.key(), _5.this.field1.codec().encode(transcoder, _5.this.field1.getter().apply(value))); + fields.put(_5.this.field2.key(), _5.this.field2.codec().encode(transcoder, _5.this.field2.getter().apply(value))); + fields.put(_5.this.field3.key(), _5.this.field3.codec().encode(transcoder, _5.this.field3.getter().apply(value))); + fields.put(_5.this.field4.key(), _5.this.field4.codec().encode(transcoder, _5.this.field4.getter().apply(value))); + fields.put(_5.this.field5.key(), _5.this.field5.codec().encode(transcoder, _5.this.field5.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _6 with(String key, Codec codec, Function getter) { + return new _6<>(this.field1, this.field2, this.field3, this.field4, this.field5, new Field<>(key, codec, getter)); + } + } + + public static final class _6 { + private final Field field1; + private final Field field2; + private final Field field3; + private final Field field4; + private final Field field5; + private final Field field6; + + _6(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + this.field4 = field4; + this.field5 = field5; + this.field6 = field6; + } + + public Codec build(Constructor6 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _6.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _6.this.field1.key())); + F2 f2 = _6.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _6.this.field2.key())); + F3 f3 = _6.this.field3.codec().decode(transcoder, transcoder.decodeObjectField(value, _6.this.field3.key())); + F4 f4 = _6.this.field4.codec().decode(transcoder, transcoder.decodeObjectField(value, _6.this.field4.key())); + F5 f5 = _6.this.field5.codec().decode(transcoder, transcoder.decodeObjectField(value, _6.this.field5.key())); + F6 f6 = _6.this.field6.codec().decode(transcoder, transcoder.decodeObjectField(value, _6.this.field6.key())); + return constructor.construct(f1, f2, f3, f4, f5, f6); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_6.this.field1.key(), _6.this.field1.codec().encode(transcoder, _6.this.field1.getter().apply(value))); + fields.put(_6.this.field2.key(), _6.this.field2.codec().encode(transcoder, _6.this.field2.getter().apply(value))); + fields.put(_6.this.field3.key(), _6.this.field3.codec().encode(transcoder, _6.this.field3.getter().apply(value))); + fields.put(_6.this.field4.key(), _6.this.field4.codec().encode(transcoder, _6.this.field4.getter().apply(value))); + fields.put(_6.this.field5.key(), _6.this.field5.codec().encode(transcoder, _6.this.field5.getter().apply(value))); + fields.put(_6.this.field6.key(), _6.this.field6.codec().encode(transcoder, _6.this.field6.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _7 with(String key, Codec codec, Function getter) { + return new _7<>(this.field1, this.field2, this.field3, this.field4, this.field5, this.field6, new Field<>(key, codec, getter)); + } + } + + public static final class _7 { + private final Field field1; + private final Field field2; + private final Field field3; + private final Field field4; + private final Field field5; + private final Field field6; + private final Field field7; + + _7(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + this.field4 = field4; + this.field5 = field5; + this.field6 = field6; + this.field7 = field7; + } + + public Codec build(Constructor7 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _7.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _7.this.field1.key())); + F2 f2 = _7.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _7.this.field2.key())); + F3 f3 = _7.this.field3.codec().decode(transcoder, transcoder.decodeObjectField(value, _7.this.field3.key())); + F4 f4 = _7.this.field4.codec().decode(transcoder, transcoder.decodeObjectField(value, _7.this.field4.key())); + F5 f5 = _7.this.field5.codec().decode(transcoder, transcoder.decodeObjectField(value, _7.this.field5.key())); + F6 f6 = _7.this.field6.codec().decode(transcoder, transcoder.decodeObjectField(value, _7.this.field6.key())); + F7 f7 = _7.this.field7.codec().decode(transcoder, transcoder.decodeObjectField(value, _7.this.field7.key())); + return constructor.construct(f1, f2, f3, f4, f5, f6, f7); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_7.this.field1.key(), _7.this.field1.codec().encode(transcoder, _7.this.field1.getter().apply(value))); + fields.put(_7.this.field2.key(), _7.this.field2.codec().encode(transcoder, _7.this.field2.getter().apply(value))); + fields.put(_7.this.field3.key(), _7.this.field3.codec().encode(transcoder, _7.this.field3.getter().apply(value))); + fields.put(_7.this.field4.key(), _7.this.field4.codec().encode(transcoder, _7.this.field4.getter().apply(value))); + fields.put(_7.this.field5.key(), _7.this.field5.codec().encode(transcoder, _7.this.field5.getter().apply(value))); + fields.put(_7.this.field6.key(), _7.this.field6.codec().encode(transcoder, _7.this.field6.getter().apply(value))); + fields.put(_7.this.field7.key(), _7.this.field7.codec().encode(transcoder, _7.this.field7.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _8 with(String key, Codec codec, Function getter) { + return new _8<>(this.field1, this.field2, this.field3, this.field4, this.field5, this.field6, this.field7, new Field<>(key, codec, getter)); + } + } + + public static final class _8 { + private final Field field1; + private final Field field2; + private final Field field3; + private final Field field4; + private final Field field5; + private final Field field6; + private final Field field7; + private final Field field8; + + _8(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + this.field4 = field4; + this.field5 = field5; + this.field6 = field6; + this.field7 = field7; + this.field8 = field8; + } + + public Codec build(Constructor8 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _8.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _8.this.field1.key())); + F2 f2 = _8.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _8.this.field2.key())); + F3 f3 = _8.this.field3.codec().decode(transcoder, transcoder.decodeObjectField(value, _8.this.field3.key())); + F4 f4 = _8.this.field4.codec().decode(transcoder, transcoder.decodeObjectField(value, _8.this.field4.key())); + F5 f5 = _8.this.field5.codec().decode(transcoder, transcoder.decodeObjectField(value, _8.this.field5.key())); + F6 f6 = _8.this.field6.codec().decode(transcoder, transcoder.decodeObjectField(value, _8.this.field6.key())); + F7 f7 = _8.this.field7.codec().decode(transcoder, transcoder.decodeObjectField(value, _8.this.field7.key())); + F8 f8 = _8.this.field8.codec().decode(transcoder, transcoder.decodeObjectField(value, _8.this.field8.key())); + return constructor.construct(f1, f2, f3, f4, f5, f6, f7, f8); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_8.this.field1.key(), _8.this.field1.codec().encode(transcoder, _8.this.field1.getter().apply(value))); + fields.put(_8.this.field2.key(), _8.this.field2.codec().encode(transcoder, _8.this.field2.getter().apply(value))); + fields.put(_8.this.field3.key(), _8.this.field3.codec().encode(transcoder, _8.this.field3.getter().apply(value))); + fields.put(_8.this.field4.key(), _8.this.field4.codec().encode(transcoder, _8.this.field4.getter().apply(value))); + fields.put(_8.this.field5.key(), _8.this.field5.codec().encode(transcoder, _8.this.field5.getter().apply(value))); + fields.put(_8.this.field6.key(), _8.this.field6.codec().encode(transcoder, _8.this.field6.getter().apply(value))); + fields.put(_8.this.field7.key(), _8.this.field7.codec().encode(transcoder, _8.this.field7.getter().apply(value))); + fields.put(_8.this.field8.key(), _8.this.field8.codec().encode(transcoder, _8.this.field8.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _9 with(String key, Codec codec, Function getter) { + return new _9<>(this.field1, this.field2, this.field3, this.field4, this.field5, this.field6, this.field7, this.field8, new Field<>(key, codec, getter)); + } + } + + public static final class _9 { + private final Field field1; + private final Field field2; + private final Field field3; + private final Field field4; + private final Field field5; + private final Field field6; + private final Field field7; + private final Field field8; + private final Field field9; + + _9(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + this.field4 = field4; + this.field5 = field5; + this.field6 = field6; + this.field7 = field7; + this.field8 = field8; + this.field9 = field9; + } + + public Codec build(Constructor9 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _9.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _9.this.field1.key())); + F2 f2 = _9.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _9.this.field2.key())); + F3 f3 = _9.this.field3.codec().decode(transcoder, transcoder.decodeObjectField(value, _9.this.field3.key())); + F4 f4 = _9.this.field4.codec().decode(transcoder, transcoder.decodeObjectField(value, _9.this.field4.key())); + F5 f5 = _9.this.field5.codec().decode(transcoder, transcoder.decodeObjectField(value, _9.this.field5.key())); + F6 f6 = _9.this.field6.codec().decode(transcoder, transcoder.decodeObjectField(value, _9.this.field6.key())); + F7 f7 = _9.this.field7.codec().decode(transcoder, transcoder.decodeObjectField(value, _9.this.field7.key())); + F8 f8 = _9.this.field8.codec().decode(transcoder, transcoder.decodeObjectField(value, _9.this.field8.key())); + F9 f9 = _9.this.field9.codec().decode(transcoder, transcoder.decodeObjectField(value, _9.this.field9.key())); + return constructor.construct(f1, f2, f3, f4, f5, f6, f7, f8, f9); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_9.this.field1.key(), _9.this.field1.codec().encode(transcoder, _9.this.field1.getter().apply(value))); + fields.put(_9.this.field2.key(), _9.this.field2.codec().encode(transcoder, _9.this.field2.getter().apply(value))); + fields.put(_9.this.field3.key(), _9.this.field3.codec().encode(transcoder, _9.this.field3.getter().apply(value))); + fields.put(_9.this.field4.key(), _9.this.field4.codec().encode(transcoder, _9.this.field4.getter().apply(value))); + fields.put(_9.this.field5.key(), _9.this.field5.codec().encode(transcoder, _9.this.field5.getter().apply(value))); + fields.put(_9.this.field6.key(), _9.this.field6.codec().encode(transcoder, _9.this.field6.getter().apply(value))); + fields.put(_9.this.field7.key(), _9.this.field7.codec().encode(transcoder, _9.this.field7.getter().apply(value))); + fields.put(_9.this.field8.key(), _9.this.field8.codec().encode(transcoder, _9.this.field8.getter().apply(value))); + fields.put(_9.this.field9.key(), _9.this.field9.codec().encode(transcoder, _9.this.field9.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _10 with(String key, Codec codec, Function getter) { + return new _10<>(this.field1, this.field2, this.field3, this.field4, this.field5, this.field6, this.field7, this.field8, this.field9, new Field<>(key, codec, getter)); + } + } + + public static final class _10 { + private final Field field1; + private final Field field2; + private final Field field3; + private final Field field4; + private final Field field5; + private final Field field6; + private final Field field7; + private final Field field8; + private final Field field9; + private final Field field10; + + _10(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + this.field4 = field4; + this.field5 = field5; + this.field6 = field6; + this.field7 = field7; + this.field8 = field8; + this.field9 = field9; + this.field10 = field10; + } + + public Codec build(Constructor10 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _10.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _10.this.field1.key())); + F2 f2 = _10.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _10.this.field2.key())); + F3 f3 = _10.this.field3.codec().decode(transcoder, transcoder.decodeObjectField(value, _10.this.field3.key())); + F4 f4 = _10.this.field4.codec().decode(transcoder, transcoder.decodeObjectField(value, _10.this.field4.key())); + F5 f5 = _10.this.field5.codec().decode(transcoder, transcoder.decodeObjectField(value, _10.this.field5.key())); + F6 f6 = _10.this.field6.codec().decode(transcoder, transcoder.decodeObjectField(value, _10.this.field6.key())); + F7 f7 = _10.this.field7.codec().decode(transcoder, transcoder.decodeObjectField(value, _10.this.field7.key())); + F8 f8 = _10.this.field8.codec().decode(transcoder, transcoder.decodeObjectField(value, _10.this.field8.key())); + F9 f9 = _10.this.field9.codec().decode(transcoder, transcoder.decodeObjectField(value, _10.this.field9.key())); + F10 f10 = _10.this.field10.codec().decode(transcoder, transcoder.decodeObjectField(value, _10.this.field10.key())); + return constructor.construct(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_10.this.field1.key(), _10.this.field1.codec().encode(transcoder, _10.this.field1.getter().apply(value))); + fields.put(_10.this.field2.key(), _10.this.field2.codec().encode(transcoder, _10.this.field2.getter().apply(value))); + fields.put(_10.this.field3.key(), _10.this.field3.codec().encode(transcoder, _10.this.field3.getter().apply(value))); + fields.put(_10.this.field4.key(), _10.this.field4.codec().encode(transcoder, _10.this.field4.getter().apply(value))); + fields.put(_10.this.field5.key(), _10.this.field5.codec().encode(transcoder, _10.this.field5.getter().apply(value))); + fields.put(_10.this.field6.key(), _10.this.field6.codec().encode(transcoder, _10.this.field6.getter().apply(value))); + fields.put(_10.this.field7.key(), _10.this.field7.codec().encode(transcoder, _10.this.field7.getter().apply(value))); + fields.put(_10.this.field8.key(), _10.this.field8.codec().encode(transcoder, _10.this.field8.getter().apply(value))); + fields.put(_10.this.field9.key(), _10.this.field9.codec().encode(transcoder, _10.this.field9.getter().apply(value))); + fields.put(_10.this.field10.key(), _10.this.field10.codec().encode(transcoder, _10.this.field10.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _11 with(String key, Codec codec, Function getter) { + return new _11<>(this.field1, this.field2, this.field3, this.field4, this.field5, this.field6, this.field7, this.field8, this.field9, this.field10, new Field<>(key, codec, getter)); + } + } + + public static final class _11 { + private final Field field1; + private final Field field2; + private final Field field3; + private final Field field4; + private final Field field5; + private final Field field6; + private final Field field7; + private final Field field8; + private final Field field9; + private final Field field10; + private final Field field11; + + _11(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + this.field4 = field4; + this.field5 = field5; + this.field6 = field6; + this.field7 = field7; + this.field8 = field8; + this.field9 = field9; + this.field10 = field10; + this.field11 = field11; + } + + public Codec build(Constructor11 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _11.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _11.this.field1.key())); + F2 f2 = _11.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _11.this.field2.key())); + F3 f3 = _11.this.field3.codec().decode(transcoder, transcoder.decodeObjectField(value, _11.this.field3.key())); + F4 f4 = _11.this.field4.codec().decode(transcoder, transcoder.decodeObjectField(value, _11.this.field4.key())); + F5 f5 = _11.this.field5.codec().decode(transcoder, transcoder.decodeObjectField(value, _11.this.field5.key())); + F6 f6 = _11.this.field6.codec().decode(transcoder, transcoder.decodeObjectField(value, _11.this.field6.key())); + F7 f7 = _11.this.field7.codec().decode(transcoder, transcoder.decodeObjectField(value, _11.this.field7.key())); + F8 f8 = _11.this.field8.codec().decode(transcoder, transcoder.decodeObjectField(value, _11.this.field8.key())); + F9 f9 = _11.this.field9.codec().decode(transcoder, transcoder.decodeObjectField(value, _11.this.field9.key())); + F10 f10 = _11.this.field10.codec().decode(transcoder, transcoder.decodeObjectField(value, _11.this.field10.key())); + F11 f11 = _11.this.field11.codec().decode(transcoder, transcoder.decodeObjectField(value, _11.this.field11.key())); + return constructor.construct(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_11.this.field1.key(), _11.this.field1.codec().encode(transcoder, _11.this.field1.getter().apply(value))); + fields.put(_11.this.field2.key(), _11.this.field2.codec().encode(transcoder, _11.this.field2.getter().apply(value))); + fields.put(_11.this.field3.key(), _11.this.field3.codec().encode(transcoder, _11.this.field3.getter().apply(value))); + fields.put(_11.this.field4.key(), _11.this.field4.codec().encode(transcoder, _11.this.field4.getter().apply(value))); + fields.put(_11.this.field5.key(), _11.this.field5.codec().encode(transcoder, _11.this.field5.getter().apply(value))); + fields.put(_11.this.field6.key(), _11.this.field6.codec().encode(transcoder, _11.this.field6.getter().apply(value))); + fields.put(_11.this.field7.key(), _11.this.field7.codec().encode(transcoder, _11.this.field7.getter().apply(value))); + fields.put(_11.this.field8.key(), _11.this.field8.codec().encode(transcoder, _11.this.field8.getter().apply(value))); + fields.put(_11.this.field9.key(), _11.this.field9.codec().encode(transcoder, _11.this.field9.getter().apply(value))); + fields.put(_11.this.field10.key(), _11.this.field10.codec().encode(transcoder, _11.this.field10.getter().apply(value))); + fields.put(_11.this.field11.key(), _11.this.field11.codec().encode(transcoder, _11.this.field11.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _12 with(String key, Codec codec, Function getter) { + return new _12<>(this.field1, this.field2, this.field3, this.field4, this.field5, this.field6, this.field7, this.field8, this.field9, this.field10, this.field11, new Field<>(key, codec, getter)); + } + } + + public static final class _12 { + private final Field field1; + private final Field field2; + private final Field field3; + private final Field field4; + private final Field field5; + private final Field field6; + private final Field field7; + private final Field field8; + private final Field field9; + private final Field field10; + private final Field field11; + private final Field field12; + + _12(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + this.field4 = field4; + this.field5 = field5; + this.field6 = field6; + this.field7 = field7; + this.field8 = field8; + this.field9 = field9; + this.field10 = field10; + this.field11 = field11; + this.field12 = field12; + } + + public Codec build(Constructor12 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _12.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _12.this.field1.key())); + F2 f2 = _12.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _12.this.field2.key())); + F3 f3 = _12.this.field3.codec().decode(transcoder, transcoder.decodeObjectField(value, _12.this.field3.key())); + F4 f4 = _12.this.field4.codec().decode(transcoder, transcoder.decodeObjectField(value, _12.this.field4.key())); + F5 f5 = _12.this.field5.codec().decode(transcoder, transcoder.decodeObjectField(value, _12.this.field5.key())); + F6 f6 = _12.this.field6.codec().decode(transcoder, transcoder.decodeObjectField(value, _12.this.field6.key())); + F7 f7 = _12.this.field7.codec().decode(transcoder, transcoder.decodeObjectField(value, _12.this.field7.key())); + F8 f8 = _12.this.field8.codec().decode(transcoder, transcoder.decodeObjectField(value, _12.this.field8.key())); + F9 f9 = _12.this.field9.codec().decode(transcoder, transcoder.decodeObjectField(value, _12.this.field9.key())); + F10 f10 = _12.this.field10.codec().decode(transcoder, transcoder.decodeObjectField(value, _12.this.field10.key())); + F11 f11 = _12.this.field11.codec().decode(transcoder, transcoder.decodeObjectField(value, _12.this.field11.key())); + F12 f12 = _12.this.field12.codec().decode(transcoder, transcoder.decodeObjectField(value, _12.this.field12.key())); + return constructor.construct(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_12.this.field1.key(), _12.this.field1.codec().encode(transcoder, _12.this.field1.getter().apply(value))); + fields.put(_12.this.field2.key(), _12.this.field2.codec().encode(transcoder, _12.this.field2.getter().apply(value))); + fields.put(_12.this.field3.key(), _12.this.field3.codec().encode(transcoder, _12.this.field3.getter().apply(value))); + fields.put(_12.this.field4.key(), _12.this.field4.codec().encode(transcoder, _12.this.field4.getter().apply(value))); + fields.put(_12.this.field5.key(), _12.this.field5.codec().encode(transcoder, _12.this.field5.getter().apply(value))); + fields.put(_12.this.field6.key(), _12.this.field6.codec().encode(transcoder, _12.this.field6.getter().apply(value))); + fields.put(_12.this.field7.key(), _12.this.field7.codec().encode(transcoder, _12.this.field7.getter().apply(value))); + fields.put(_12.this.field8.key(), _12.this.field8.codec().encode(transcoder, _12.this.field8.getter().apply(value))); + fields.put(_12.this.field9.key(), _12.this.field9.codec().encode(transcoder, _12.this.field9.getter().apply(value))); + fields.put(_12.this.field10.key(), _12.this.field10.codec().encode(transcoder, _12.this.field10.getter().apply(value))); + fields.put(_12.this.field11.key(), _12.this.field11.codec().encode(transcoder, _12.this.field11.getter().apply(value))); + fields.put(_12.this.field12.key(), _12.this.field12.codec().encode(transcoder, _12.this.field12.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _13 with(String key, Codec codec, Function getter) { + return new _13<>(this.field1, this.field2, this.field3, this.field4, this.field5, this.field6, this.field7, this.field8, this.field9, this.field10, this.field11, this.field12, new Field<>(key, codec, getter)); + } + } + + public static final class _13 { + private final Field field1; + private final Field field2; + private final Field field3; + private final Field field4; + private final Field field5; + private final Field field6; + private final Field field7; + private final Field field8; + private final Field field9; + private final Field field10; + private final Field field11; + private final Field field12; + private final Field field13; + + _13(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + this.field4 = field4; + this.field5 = field5; + this.field6 = field6; + this.field7 = field7; + this.field8 = field8; + this.field9 = field9; + this.field10 = field10; + this.field11 = field11; + this.field12 = field12; + this.field13 = field13; + } + + public Codec build(Constructor13 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _13.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _13.this.field1.key())); + F2 f2 = _13.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _13.this.field2.key())); + F3 f3 = _13.this.field3.codec().decode(transcoder, transcoder.decodeObjectField(value, _13.this.field3.key())); + F4 f4 = _13.this.field4.codec().decode(transcoder, transcoder.decodeObjectField(value, _13.this.field4.key())); + F5 f5 = _13.this.field5.codec().decode(transcoder, transcoder.decodeObjectField(value, _13.this.field5.key())); + F6 f6 = _13.this.field6.codec().decode(transcoder, transcoder.decodeObjectField(value, _13.this.field6.key())); + F7 f7 = _13.this.field7.codec().decode(transcoder, transcoder.decodeObjectField(value, _13.this.field7.key())); + F8 f8 = _13.this.field8.codec().decode(transcoder, transcoder.decodeObjectField(value, _13.this.field8.key())); + F9 f9 = _13.this.field9.codec().decode(transcoder, transcoder.decodeObjectField(value, _13.this.field9.key())); + F10 f10 = _13.this.field10.codec().decode(transcoder, transcoder.decodeObjectField(value, _13.this.field10.key())); + F11 f11 = _13.this.field11.codec().decode(transcoder, transcoder.decodeObjectField(value, _13.this.field11.key())); + F12 f12 = _13.this.field12.codec().decode(transcoder, transcoder.decodeObjectField(value, _13.this.field12.key())); + F13 f13 = _13.this.field13.codec().decode(transcoder, transcoder.decodeObjectField(value, _13.this.field13.key())); + return constructor.construct(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_13.this.field1.key(), _13.this.field1.codec().encode(transcoder, _13.this.field1.getter().apply(value))); + fields.put(_13.this.field2.key(), _13.this.field2.codec().encode(transcoder, _13.this.field2.getter().apply(value))); + fields.put(_13.this.field3.key(), _13.this.field3.codec().encode(transcoder, _13.this.field3.getter().apply(value))); + fields.put(_13.this.field4.key(), _13.this.field4.codec().encode(transcoder, _13.this.field4.getter().apply(value))); + fields.put(_13.this.field5.key(), _13.this.field5.codec().encode(transcoder, _13.this.field5.getter().apply(value))); + fields.put(_13.this.field6.key(), _13.this.field6.codec().encode(transcoder, _13.this.field6.getter().apply(value))); + fields.put(_13.this.field7.key(), _13.this.field7.codec().encode(transcoder, _13.this.field7.getter().apply(value))); + fields.put(_13.this.field8.key(), _13.this.field8.codec().encode(transcoder, _13.this.field8.getter().apply(value))); + fields.put(_13.this.field9.key(), _13.this.field9.codec().encode(transcoder, _13.this.field9.getter().apply(value))); + fields.put(_13.this.field10.key(), _13.this.field10.codec().encode(transcoder, _13.this.field10.getter().apply(value))); + fields.put(_13.this.field11.key(), _13.this.field11.codec().encode(transcoder, _13.this.field11.getter().apply(value))); + fields.put(_13.this.field12.key(), _13.this.field12.codec().encode(transcoder, _13.this.field12.getter().apply(value))); + fields.put(_13.this.field13.key(), _13.this.field13.codec().encode(transcoder, _13.this.field13.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _14 with(String key, Codec codec, Function getter) { + return new _14<>(this.field1, this.field2, this.field3, this.field4, this.field5, this.field6, this.field7, this.field8, this.field9, this.field10, this.field11, this.field12, this.field13, new Field<>(key, codec, getter)); + } + } + + public static final class _14 { + private final Field field1; + private final Field field2; + private final Field field3; + private final Field field4; + private final Field field5; + private final Field field6; + private final Field field7; + private final Field field8; + private final Field field9; + private final Field field10; + private final Field field11; + private final Field field12; + private final Field field13; + private final Field field14; + + _14(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + this.field4 = field4; + this.field5 = field5; + this.field6 = field6; + this.field7 = field7; + this.field8 = field8; + this.field9 = field9; + this.field10 = field10; + this.field11 = field11; + this.field12 = field12; + this.field13 = field13; + this.field14 = field14; + } + + public Codec build(Constructor14 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _14.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _14.this.field1.key())); + F2 f2 = _14.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _14.this.field2.key())); + F3 f3 = _14.this.field3.codec().decode(transcoder, transcoder.decodeObjectField(value, _14.this.field3.key())); + F4 f4 = _14.this.field4.codec().decode(transcoder, transcoder.decodeObjectField(value, _14.this.field4.key())); + F5 f5 = _14.this.field5.codec().decode(transcoder, transcoder.decodeObjectField(value, _14.this.field5.key())); + F6 f6 = _14.this.field6.codec().decode(transcoder, transcoder.decodeObjectField(value, _14.this.field6.key())); + F7 f7 = _14.this.field7.codec().decode(transcoder, transcoder.decodeObjectField(value, _14.this.field7.key())); + F8 f8 = _14.this.field8.codec().decode(transcoder, transcoder.decodeObjectField(value, _14.this.field8.key())); + F9 f9 = _14.this.field9.codec().decode(transcoder, transcoder.decodeObjectField(value, _14.this.field9.key())); + F10 f10 = _14.this.field10.codec().decode(transcoder, transcoder.decodeObjectField(value, _14.this.field10.key())); + F11 f11 = _14.this.field11.codec().decode(transcoder, transcoder.decodeObjectField(value, _14.this.field11.key())); + F12 f12 = _14.this.field12.codec().decode(transcoder, transcoder.decodeObjectField(value, _14.this.field12.key())); + F13 f13 = _14.this.field13.codec().decode(transcoder, transcoder.decodeObjectField(value, _14.this.field13.key())); + F14 f14 = _14.this.field14.codec().decode(transcoder, transcoder.decodeObjectField(value, _14.this.field14.key())); + return constructor.construct(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_14.this.field1.key(), _14.this.field1.codec().encode(transcoder, _14.this.field1.getter().apply(value))); + fields.put(_14.this.field2.key(), _14.this.field2.codec().encode(transcoder, _14.this.field2.getter().apply(value))); + fields.put(_14.this.field3.key(), _14.this.field3.codec().encode(transcoder, _14.this.field3.getter().apply(value))); + fields.put(_14.this.field4.key(), _14.this.field4.codec().encode(transcoder, _14.this.field4.getter().apply(value))); + fields.put(_14.this.field5.key(), _14.this.field5.codec().encode(transcoder, _14.this.field5.getter().apply(value))); + fields.put(_14.this.field6.key(), _14.this.field6.codec().encode(transcoder, _14.this.field6.getter().apply(value))); + fields.put(_14.this.field7.key(), _14.this.field7.codec().encode(transcoder, _14.this.field7.getter().apply(value))); + fields.put(_14.this.field8.key(), _14.this.field8.codec().encode(transcoder, _14.this.field8.getter().apply(value))); + fields.put(_14.this.field9.key(), _14.this.field9.codec().encode(transcoder, _14.this.field9.getter().apply(value))); + fields.put(_14.this.field10.key(), _14.this.field10.codec().encode(transcoder, _14.this.field10.getter().apply(value))); + fields.put(_14.this.field11.key(), _14.this.field11.codec().encode(transcoder, _14.this.field11.getter().apply(value))); + fields.put(_14.this.field12.key(), _14.this.field12.codec().encode(transcoder, _14.this.field12.getter().apply(value))); + fields.put(_14.this.field13.key(), _14.this.field13.codec().encode(transcoder, _14.this.field13.getter().apply(value))); + fields.put(_14.this.field14.key(), _14.this.field14.codec().encode(transcoder, _14.this.field14.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _15 with(String key, Codec codec, Function getter) { + return new _15<>(this.field1, this.field2, this.field3, this.field4, this.field5, this.field6, this.field7, this.field8, this.field9, this.field10, this.field11, this.field12, this.field13, this.field14, new Field<>(key, codec, getter)); + } + } + + public static final class _15 { + private final Field field1; + private final Field field2; + private final Field field3; + private final Field field4; + private final Field field5; + private final Field field6; + private final Field field7; + private final Field field8; + private final Field field9; + private final Field field10; + private final Field field11; + private final Field field12; + private final Field field13; + private final Field field14; + private final Field field15; + + _15(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + this.field4 = field4; + this.field5 = field5; + this.field6 = field6; + this.field7 = field7; + this.field8 = field8; + this.field9 = field9; + this.field10 = field10; + this.field11 = field11; + this.field12 = field12; + this.field13 = field13; + this.field14 = field14; + this.field15 = field15; + } + + public Codec build(Constructor15 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _15.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field1.key())); + F2 f2 = _15.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field2.key())); + F3 f3 = _15.this.field3.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field3.key())); + F4 f4 = _15.this.field4.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field4.key())); + F5 f5 = _15.this.field5.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field5.key())); + F6 f6 = _15.this.field6.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field6.key())); + F7 f7 = _15.this.field7.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field7.key())); + F8 f8 = _15.this.field8.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field8.key())); + F9 f9 = _15.this.field9.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field9.key())); + F10 f10 = _15.this.field10.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field10.key())); + F11 f11 = _15.this.field11.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field11.key())); + F12 f12 = _15.this.field12.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field12.key())); + F13 f13 = _15.this.field13.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field13.key())); + F14 f14 = _15.this.field14.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field14.key())); + F15 f15 = _15.this.field15.codec().decode(transcoder, transcoder.decodeObjectField(value, _15.this.field15.key())); + return constructor.construct(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_15.this.field1.key(), _15.this.field1.codec().encode(transcoder, _15.this.field1.getter().apply(value))); + fields.put(_15.this.field2.key(), _15.this.field2.codec().encode(transcoder, _15.this.field2.getter().apply(value))); + fields.put(_15.this.field3.key(), _15.this.field3.codec().encode(transcoder, _15.this.field3.getter().apply(value))); + fields.put(_15.this.field4.key(), _15.this.field4.codec().encode(transcoder, _15.this.field4.getter().apply(value))); + fields.put(_15.this.field5.key(), _15.this.field5.codec().encode(transcoder, _15.this.field5.getter().apply(value))); + fields.put(_15.this.field6.key(), _15.this.field6.codec().encode(transcoder, _15.this.field6.getter().apply(value))); + fields.put(_15.this.field7.key(), _15.this.field7.codec().encode(transcoder, _15.this.field7.getter().apply(value))); + fields.put(_15.this.field8.key(), _15.this.field8.codec().encode(transcoder, _15.this.field8.getter().apply(value))); + fields.put(_15.this.field9.key(), _15.this.field9.codec().encode(transcoder, _15.this.field9.getter().apply(value))); + fields.put(_15.this.field10.key(), _15.this.field10.codec().encode(transcoder, _15.this.field10.getter().apply(value))); + fields.put(_15.this.field11.key(), _15.this.field11.codec().encode(transcoder, _15.this.field11.getter().apply(value))); + fields.put(_15.this.field12.key(), _15.this.field12.codec().encode(transcoder, _15.this.field12.getter().apply(value))); + fields.put(_15.this.field13.key(), _15.this.field13.codec().encode(transcoder, _15.this.field13.getter().apply(value))); + fields.put(_15.this.field14.key(), _15.this.field14.codec().encode(transcoder, _15.this.field14.getter().apply(value))); + fields.put(_15.this.field15.key(), _15.this.field15.codec().encode(transcoder, _15.this.field15.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + + public _16 with(String key, Codec codec, Function getter) { + return new _16<>(this.field1, this.field2, this.field3, this.field4, this.field5, this.field6, this.field7, this.field8, this.field9, this.field10, this.field11, this.field12, this.field13, this.field14, this.field15, new Field<>(key, codec, getter)); + } + } + + public static final class _16 { + private final Field field1; + private final Field field2; + private final Field field3; + private final Field field4; + private final Field field5; + private final Field field6; + private final Field field7; + private final Field field8; + private final Field field9; + private final Field field10; + private final Field field11; + private final Field field12; + private final Field field13; + private final Field field14; + private final Field field15; + private final Field field16; + + _16(Field field1, Field field2, Field field3, Field field4, Field field5, Field field6, Field field7, Field field8, Field field9, Field field10, Field field11, Field field12, Field field13, Field field14, Field field15, Field field16) { + this.field1 = field1; + this.field2 = field2; + this.field3 = field3; + this.field4 = field4; + this.field5 = field5; + this.field6 = field6; + this.field7 = field7; + this.field8 = field8; + this.field9 = field9; + this.field10 = field10; + this.field11 = field11; + this.field12 = field12; + this.field13 = field13; + this.field14 = field14; + this.field15 = field15; + this.field16 = field16; + } + + public Codec build(Constructor16 constructor) { + return new Codec<>() { + @Override + public T decode(Transcoder transcoder, R value) { + F1 f1 = _16.this.field1.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field1.key())); + F2 f2 = _16.this.field2.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field2.key())); + F3 f3 = _16.this.field3.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field3.key())); + F4 f4 = _16.this.field4.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field4.key())); + F5 f5 = _16.this.field5.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field5.key())); + F6 f6 = _16.this.field6.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field6.key())); + F7 f7 = _16.this.field7.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field7.key())); + F8 f8 = _16.this.field8.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field8.key())); + F9 f9 = _16.this.field9.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field9.key())); + F10 f10 = _16.this.field10.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field10.key())); + F11 f11 = _16.this.field11.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field11.key())); + F12 f12 = _16.this.field12.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field12.key())); + F13 f13 = _16.this.field13.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field13.key())); + F14 f14 = _16.this.field14.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field14.key())); + F15 f15 = _16.this.field15.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field15.key())); + F16 f16 = _16.this.field16.codec().decode(transcoder, transcoder.decodeObjectField(value, _16.this.field16.key())); + return constructor.construct(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16); + } + + @Override + public R encode(Transcoder transcoder, T value) { + var fields = new LinkedHashMap(); + fields.put(_16.this.field1.key(), _16.this.field1.codec().encode(transcoder, _16.this.field1.getter().apply(value))); + fields.put(_16.this.field2.key(), _16.this.field2.codec().encode(transcoder, _16.this.field2.getter().apply(value))); + fields.put(_16.this.field3.key(), _16.this.field3.codec().encode(transcoder, _16.this.field3.getter().apply(value))); + fields.put(_16.this.field4.key(), _16.this.field4.codec().encode(transcoder, _16.this.field4.getter().apply(value))); + fields.put(_16.this.field5.key(), _16.this.field5.codec().encode(transcoder, _16.this.field5.getter().apply(value))); + fields.put(_16.this.field6.key(), _16.this.field6.codec().encode(transcoder, _16.this.field6.getter().apply(value))); + fields.put(_16.this.field7.key(), _16.this.field7.codec().encode(transcoder, _16.this.field7.getter().apply(value))); + fields.put(_16.this.field8.key(), _16.this.field8.codec().encode(transcoder, _16.this.field8.getter().apply(value))); + fields.put(_16.this.field9.key(), _16.this.field9.codec().encode(transcoder, _16.this.field9.getter().apply(value))); + fields.put(_16.this.field10.key(), _16.this.field10.codec().encode(transcoder, _16.this.field10.getter().apply(value))); + fields.put(_16.this.field11.key(), _16.this.field11.codec().encode(transcoder, _16.this.field11.getter().apply(value))); + fields.put(_16.this.field12.key(), _16.this.field12.codec().encode(transcoder, _16.this.field12.getter().apply(value))); + fields.put(_16.this.field13.key(), _16.this.field13.codec().encode(transcoder, _16.this.field13.getter().apply(value))); + fields.put(_16.this.field14.key(), _16.this.field14.codec().encode(transcoder, _16.this.field14.getter().apply(value))); + fields.put(_16.this.field15.key(), _16.this.field15.codec().encode(transcoder, _16.this.field15.getter().apply(value))); + fields.put(_16.this.field16.key(), _16.this.field16.codec().encode(transcoder, _16.this.field16.getter().apply(value))); + return transcoder.encodeObject(fields); + } + }; + } + } +} diff --git a/json/src/main/java/alpine/json/codec/DecodingException.java b/json/src/main/java/alpine/json/codec/DecodingException.java new file mode 100644 index 0000000..440f99c --- /dev/null +++ b/json/src/main/java/alpine/json/codec/DecodingException.java @@ -0,0 +1,7 @@ +package alpine.json.codec; + +public final class DecodingException extends RuntimeException { + public DecodingException(String message) { + super(message); + } +} diff --git a/json/src/main/java/alpine/json/codec/JsonTranscoder.java b/json/src/main/java/alpine/json/codec/JsonTranscoder.java new file mode 100644 index 0000000..0571795 --- /dev/null +++ b/json/src/main/java/alpine/json/codec/JsonTranscoder.java @@ -0,0 +1,74 @@ +package alpine.json.codec; + +import alpine.json.BooleanElement; +import alpine.json.Element; +import alpine.json.NumberElement; +import alpine.json.ObjectElement; +import alpine.json.StringElement; + +import java.util.Map; + +import static alpine.json.Element.*; + +final class JsonTranscoder implements Transcoder { + @Override + public Element encodeNull() { + return nil(); + } + + @Override + public boolean decodeBoolean(Element value) { + if (value instanceof BooleanElement element) { + return element.value(); + } else { + throw new DecodingException("Expected a boolean!"); + } + } + + @Override + public Element encodeBoolean(boolean value) { + return bool(value); + } + + @Override + public double decodeNumber(Element value) { + if (value instanceof NumberElement element) { + return element.value(); + } else { + throw new DecodingException("Expected a number!"); + } + } + + @Override + public Element encodeNumber(double value) { + return number(value); + } + + @Override + public String decodeString(Element value) { + if (value instanceof StringElement element) { + return element.value(); + } else { + throw new DecodingException("Expected a string!"); + } + } + + @Override + public Element encodeString(String value) { + return string(value); + } + + @Override + public Element decodeObjectField(Element object, String key) { + if (object instanceof ObjectElement element) { + return element.get(key); + } else { + throw new DecodingException("Expected an object!"); + } + } + + @Override + public Element encodeObject(Map fields) { + return object(fields); + } +} diff --git a/json/src/main/java/alpine/json/codec/PrimitiveCodecs.java b/json/src/main/java/alpine/json/codec/PrimitiveCodecs.java new file mode 100644 index 0000000..a90347a --- /dev/null +++ b/json/src/main/java/alpine/json/codec/PrimitiveCodecs.java @@ -0,0 +1,51 @@ +package alpine.json.codec; + +interface PrimitiveCodecs { + Codec BOOLEAN = new Codec<>() { + @Override + public Boolean decode(Transcoder transcoder, R value) { + return transcoder.decodeBoolean(value); + } + + @Override + public R encode(Transcoder transcoder, Boolean value) { + return transcoder.encodeBoolean(value); + } + }; + + Codec NUMBER = new Codec<>() { + @Override + public Double decode(Transcoder transcoder, R value) { + return transcoder.decodeNumber(value); + } + + @Override + public R encode(Transcoder transcoder, Double value) { + return transcoder.encodeNumber(value); + } + }; + + Codec INTEGER = new Codec<>() { + @Override + public Integer decode(Transcoder transcoder, R value) { + return (int) transcoder.decodeNumber(value); + } + + @Override + public R encode(Transcoder transcoder, Integer value) { + return transcoder.encodeNumber(value); + } + }; + + Codec STRING = new Codec<>() { + @Override + public String decode(Transcoder transcoder, R value) { + return transcoder.decodeString(value); + } + + @Override + public R encode(Transcoder transcoder, String value) { + return transcoder.encodeString(value); + } + }; +} diff --git a/json/src/main/java/alpine/json/codec/Transcoder.java b/json/src/main/java/alpine/json/codec/Transcoder.java new file mode 100644 index 0000000..964afad --- /dev/null +++ b/json/src/main/java/alpine/json/codec/Transcoder.java @@ -0,0 +1,27 @@ +package alpine.json.codec; + +import alpine.json.Element; + +import java.util.Map; + +public interface Transcoder { + Transcoder JSON = new JsonTranscoder(); + + T encodeNull(); + + boolean decodeBoolean(T value); + + T encodeBoolean(boolean value); + + double decodeNumber(T value); + + T encodeNumber(double value); + + String decodeString(T value); + + T encodeString(String value); + + T decodeObjectField(T object, String key); + + T encodeObject(Map fields); +} diff --git a/json/src/test/java/alpine/json/CodecBuilderTest.java b/json/src/test/java/alpine/json/CodecBuilderTest.java new file mode 100644 index 0000000..deca321 --- /dev/null +++ b/json/src/test/java/alpine/json/CodecBuilderTest.java @@ -0,0 +1,24 @@ +package alpine.json; + +import alpine.json.codec.Codec; +import alpine.json.codec.Transcoder; +import org.junit.jupiter.api.Test; + +import static alpine.json.Element.object; +import static org.junit.jupiter.api.Assertions.assertEquals; + +final class CodecBuilderTest { + record User(String name, int age) { + static final Codec CODEC = Codec.builder() + .with("name", Codec.STRING, User::name) + .with("age", Codec.INTEGER, User::age) + .build(User::new); + } + + @Test + void testUser() { + var actual = User.CODEC.encode(Transcoder.JSON, new User("Steve", 67)); + var expected = object().set("name", "Steve").set("age", 67); + assertEquals(actual, expected); + } +} diff --git a/json/src/test/java/alpine/json/JsonTest.java b/json/src/test/java/alpine/json/JsonTest.java index bead0bb..d881b5a 100644 --- a/json/src/test/java/alpine/json/JsonTest.java +++ b/json/src/test/java/alpine/json/JsonTest.java @@ -85,19 +85,13 @@ private static int traverseRecursively(Element element, int currentDepth) { return switch (element) { case ArrayElement array -> { var depth = new AtomicInteger(currentDepth); - - array.forEach(child -> depth.set(Math.max(depth.get(), - traverseRecursively(child, currentDepth + 1)))); - + array.forEach(child -> depth.set(Math.max(depth.get(), traverseRecursively(child, currentDepth + 1)))); yield depth.get(); } case ObjectElement object -> { - AtomicInteger depth = new AtomicInteger(currentDepth); - - object.each((key, value) -> depth.set(Math.max(depth.get(), - traverseRecursively(value, currentDepth + 1)))); - + var depth = new AtomicInteger(currentDepth); + object.each((key, value) -> depth.set(Math.max(depth.get(), traverseRecursively(value, currentDepth + 1)))); yield depth.get(); } diff --git a/json/src/test/java/alpine/json/ObjectTest.java b/json/src/test/java/alpine/json/ObjectTest.java index 7d5ffed..29a650e 100644 --- a/json/src/test/java/alpine/json/ObjectTest.java +++ b/json/src/test/java/alpine/json/ObjectTest.java @@ -20,9 +20,9 @@ void testSetting() { @Test void testContains() { - assert !object().has("key"); - assert !object().has(false); - assert object().set("key", "value").has("key"); + assert !object().hasKey("key"); + assert !object().hasValue(false); + assert object().set("key", "value").hasKey("key"); } @Test From 9b0e355ae412f54b40fded3d31fc4f358013cf12 Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Wed, 18 Feb 2026 20:53:06 -0700 Subject: [PATCH 27/28] pick random json strings for benchmark --- .../java/alpine/json/JsonReadBenchmark.java | 66 ++++++++------- .../java/alpine/json/JsonWriteBenchmark.java | 84 ++++++++++--------- .../src/main/java/alpine/json/JsonWriter.java | 4 +- 3 files changed, 83 insertions(+), 71 deletions(-) diff --git a/benchmark/src/jmh/java/alpine/json/JsonReadBenchmark.java b/benchmark/src/jmh/java/alpine/json/JsonReadBenchmark.java index 752ac7d..1c70a49 100644 --- a/benchmark/src/jmh/java/alpine/json/JsonReadBenchmark.java +++ b/benchmark/src/jmh/java/alpine/json/JsonReadBenchmark.java @@ -16,51 +16,55 @@ public class JsonReadBenchmark { private static final ObjectMapper JACKSON = new ObjectMapper(); - // non-static, non-final to prevent the JVM from constant-folding the input - String complexJson = """ - { - "name": "Mudkip", - "type": "Water", - "stats": { - "hp": 50, - "attack": 70, - "defense": 50, - "speed": 40, - "abilities": ["Torrent", "Damp"] - }, - "evolution": { - "level": 16, - "next": "Marshtomp" - }, - "moves": [ - {"name": "Water Gun", "power": 40}, - {"name": "Tackle", "power": 35}, - {"name": "Mud-Slap", "power": 20} - ], - "metadata": { - "origin": "Hoenn", - "isLegendary": false - } - } - """; + // Pool of 8 varied inputs (power of 2 for cheap index masking). + // Different string lengths, number values, array sizes and nesting depth + // prevent the branch predictor from memorizing a single character sequence. + private static final String[] INPUTS = { + """ + {"name":"Mudkip","type":"Water","stats":{"hp":50,"attack":70,"defense":50,"speed":40,"abilities":["Torrent","Damp"]},"evolution":{"level":16,"next":"Marshtomp"},"moves":[{"name":"Water Gun","power":40},{"name":"Tackle","power":35},{"name":"Mud-Slap","power":20}],"metadata":{"origin":"Hoenn","isLegendary":false}} + """, + """ + {"name":"Charizard","type":"Fire","stats":{"hp":78,"attack":84,"defense":78,"speed":100,"abilities":["Blaze","Solar Power"]},"evolution":{"level":36,"next":null},"moves":[{"name":"Flamethrower","power":90},{"name":"Dragon Claw","power":80},{"name":"Air Slash","power":75},{"name":"Fire Blast","power":110}],"metadata":{"origin":"Kanto","isLegendary":false}} + """, + """ + {"name":"Pikachu","type":"Electric","stats":{"hp":35,"attack":55,"defense":40,"speed":90,"abilities":["Static","Lightning Rod"]},"evolution":{"level":null,"next":"Raichu"},"moves":[{"name":"Thunderbolt","power":90},{"name":"Quick Attack","power":40}],"metadata":{"origin":"Kanto","isLegendary":false}} + """, + """ + {"name":"Mewtwo","type":"Psychic","stats":{"hp":106,"attack":110,"defense":90,"speed":130,"abilities":["Pressure","Unnerve"]},"evolution":{"level":null,"next":null},"moves":[{"name":"Psystrike","power":100},{"name":"Shadow Ball","power":80},{"name":"Aura Sphere","power":80},{"name":"Ice Beam","power":90},{"name":"Recover","power":0}],"metadata":{"origin":"Kanto","isLegendary":true}} + """, + """ + {"name":"Bulbasaur","type":"Grass","stats":{"hp":45,"attack":49,"defense":49,"speed":45,"abilities":["Overgrow","Chlorophyll"]},"evolution":{"level":16,"next":"Ivysaur"},"moves":[{"name":"Vine Whip","power":45},{"name":"Razor Leaf","power":55},{"name":"Tackle","power":35}],"metadata":{"origin":"Kanto","isLegendary":false}} + """, + """ + {"name":"Snorlax","type":"Normal","stats":{"hp":160,"attack":110,"defense":65,"speed":30,"abilities":["Immunity","Thick Fat","Gluttony"]},"evolution":{"level":null,"next":null},"moves":[{"name":"Body Slam","power":85},{"name":"Crunch","power":80},{"name":"Rest","power":0},{"name":"Snore","power":50}],"metadata":{"origin":"Kanto","isLegendary":false}} + """, + """ + {"name":"Gengar","type":"Ghost","stats":{"hp":60,"attack":65,"defense":60,"speed":110,"abilities":["Cursed Body"]},"evolution":{"level":null,"next":"Mega Gengar"},"moves":[{"name":"Shadow Ball","power":80},{"name":"Sludge Bomb","power":90},{"name":"Dazzling Gleam","power":80},{"name":"Thunderbolt","power":90}],"metadata":{"origin":"Kanto","isLegendary":false}} + """, + """ + {"name":"Eevee","type":"Normal","stats":{"hp":55,"attack":55,"defense":50,"speed":55,"abilities":["Run Away","Adaptability","Anticipation"]},"evolution":{"level":null,"next":null},"moves":[{"name":"Swift","power":60},{"name":"Bite","power":60},{"name":"Covet","power":60}],"metadata":{"origin":"Kanto","isLegendary":false}} + """ + }; + + private int index = 0; @Benchmark public void alpine(Blackhole blackhole) throws Exception { - blackhole.consume(Json.read(this.complexJson)); + blackhole.consume(Json.read(INPUTS[this.index++ % INPUTS.length])); } @Benchmark public void gson(Blackhole blackhole) throws Exception { - blackhole.consume(JsonParser.parseString(this.complexJson)); + blackhole.consume(JsonParser.parseString(INPUTS[this.index++ % INPUTS.length])); } @Benchmark public void jackson(Blackhole blackhole) throws Exception { - blackhole.consume(JACKSON.readTree(this.complexJson)); + blackhole.consume(JACKSON.readTree(INPUTS[this.index++ % INPUTS.length])); } @Benchmark public void fastjson(Blackhole blackhole) throws Exception { - blackhole.consume(JSON.parseObject(this.complexJson)); + blackhole.consume(JSON.parseObject(INPUTS[this.index++ % INPUTS.length])); } } diff --git a/benchmark/src/jmh/java/alpine/json/JsonWriteBenchmark.java b/benchmark/src/jmh/java/alpine/json/JsonWriteBenchmark.java index 409e465..30808e5 100644 --- a/benchmark/src/jmh/java/alpine/json/JsonWriteBenchmark.java +++ b/benchmark/src/jmh/java/alpine/json/JsonWriteBenchmark.java @@ -21,63 +21,71 @@ public class JsonWriteBenchmark { private static final ObjectMapper JACKSON = new ObjectMapper(); private static final Gson GSON = new Gson(); - private static final String COMPLEX_JSON = """ - { - "name": "Mudkip", - "type": "Water", - "stats": { - "hp": 50, - "attack": 70, - "defense": 50, - "speed": 40, - "abilities": ["Torrent", "Damp"] - }, - "evolution": { - "level": 16, - "next": "Marshtomp" - }, - "moves": [ - {"name": "Water Gun", "power": 40}, - {"name": "Tackle", "power": 35}, - {"name": "Mud-Slap", "power": 20} - ], - "metadata": { - "origin": "Hoenn", - "isLegendary": false - } - } - """; + private static final String[] INPUTS = { + """ + {"name":"Mudkip","type":"Water","stats":{"hp":50,"attack":70,"defense":50,"speed":40,"abilities":["Torrent","Damp"]},"evolution":{"level":16,"next":"Marshtomp"},"moves":[{"name":"Water Gun","power":40},{"name":"Tackle","power":35},{"name":"Mud-Slap","power":20}],"metadata":{"origin":"Hoenn","isLegendary":false}} + """, + """ + {"name":"Charizard","type":"Fire","stats":{"hp":78,"attack":84,"defense":78,"speed":100,"abilities":["Blaze","Solar Power"]},"evolution":{"level":36,"next":null},"moves":[{"name":"Flamethrower","power":90},{"name":"Dragon Claw","power":80},{"name":"Air Slash","power":75},{"name":"Fire Blast","power":110}],"metadata":{"origin":"Kanto","isLegendary":false}} + """, + """ + {"name":"Pikachu","type":"Electric","stats":{"hp":35,"attack":55,"defense":40,"speed":90,"abilities":["Static","Lightning Rod"]},"evolution":{"level":null,"next":"Raichu"},"moves":[{"name":"Thunderbolt","power":90},{"name":"Quick Attack","power":40}],"metadata":{"origin":"Kanto","isLegendary":false}} + """, + """ + {"name":"Mewtwo","type":"Psychic","stats":{"hp":106,"attack":110,"defense":90,"speed":130,"abilities":["Pressure","Unnerve"]},"evolution":{"level":null,"next":null},"moves":[{"name":"Psystrike","power":100},{"name":"Shadow Ball","power":80},{"name":"Aura Sphere","power":80},{"name":"Ice Beam","power":90},{"name":"Recover","power":0}],"metadata":{"origin":"Kanto","isLegendary":true}} + """, + """ + {"name":"Bulbasaur","type":"Grass","stats":{"hp":45,"attack":49,"defense":49,"speed":45,"abilities":["Overgrow","Chlorophyll"]},"evolution":{"level":16,"next":"Ivysaur"},"moves":[{"name":"Vine Whip","power":45},{"name":"Razor Leaf","power":55},{"name":"Tackle","power":35}],"metadata":{"origin":"Kanto","isLegendary":false}} + """, + """ + {"name":"Snorlax","type":"Normal","stats":{"hp":160,"attack":110,"defense":65,"speed":30,"abilities":["Immunity","Thick Fat","Gluttony"]},"evolution":{"level":null,"next":null},"moves":[{"name":"Body Slam","power":85},{"name":"Crunch","power":80},{"name":"Rest","power":0},{"name":"Snore","power":50}],"metadata":{"origin":"Kanto","isLegendary":false}} + """, + """ + {"name":"Gengar","type":"Ghost","stats":{"hp":60,"attack":65,"defense":60,"speed":110,"abilities":["Cursed Body"]},"evolution":{"level":null,"next":"Mega Gengar"},"moves":[{"name":"Shadow Ball","power":80},{"name":"Sludge Bomb","power":90},{"name":"Dazzling Gleam","power":80},{"name":"Thunderbolt","power":90}],"metadata":{"origin":"Kanto","isLegendary":false}} + """, + """ + {"name":"Eevee","type":"Normal","stats":{"hp":55,"attack":55,"defense":50,"speed":55,"abilities":["Run Away","Adaptability","Anticipation"]},"evolution":{"level":null,"next":null},"moves":[{"name":"Swift","power":60},{"name":"Bite","power":60},{"name":"Covet","power":60}],"metadata":{"origin":"Kanto","isLegendary":false}} + """ + }; - private Element alpineElement; - private JsonElement gsonElement; - private JsonNode jacksonNode; - private JSONObject fastjsonObject; + private Element[] alpineArray; + private JsonElement[] gsonArray; + private JsonNode[] jacksonArray; + private JSONObject[] fastjsonArray; + private int index; @Setup(Level.Trial) public void setup() throws Exception { - this.alpineElement = Json.read(COMPLEX_JSON); - this.gsonElement = JsonParser.parseString(COMPLEX_JSON); - this.jacksonNode = JACKSON.readTree(COMPLEX_JSON); - this.fastjsonObject = JSON.parseObject(COMPLEX_JSON); + this.alpineArray = new Element[INPUTS.length]; + this.gsonArray = new JsonElement[INPUTS.length]; + this.jacksonArray = new JsonNode[INPUTS.length]; + this.fastjsonArray = new JSONObject[INPUTS.length]; + + for (var index = 0; index < INPUTS.length; index++) { + this.alpineArray[index] = Json.read(INPUTS[index]); + this.gsonArray[index] = JsonParser.parseString(INPUTS[index]); + this.jacksonArray[index] = JACKSON.readTree(INPUTS[index]); + this.fastjsonArray[index] = JSON.parseObject(INPUTS[index]); + } } @Benchmark public void alpine(Blackhole blackhole) throws Exception { - blackhole.consume(Json.write(this.alpineElement, Json.Formatting.COMPACT)); + blackhole.consume(Json.write(this.alpineArray[this.index++ % INPUTS.length], Json.Formatting.COMPACT)); } @Benchmark public void gson(Blackhole blackhole) throws Exception { - blackhole.consume(GSON.toJson(this.gsonElement)); + blackhole.consume(GSON.toJson(this.gsonArray[this.index++ % INPUTS.length])); } @Benchmark public void jackson(Blackhole blackhole) throws Exception { - blackhole.consume(JACKSON.writeValueAsString(this.jacksonNode)); + blackhole.consume(JACKSON.writeValueAsString(this.jacksonArray[this.index++ % INPUTS.length])); } @Benchmark public void fastjson(Blackhole blackhole) throws Exception { - blackhole.consume(JSON.toJSONString(this.fastjsonObject)); + blackhole.consume(JSON.toJSONString(this.fastjsonArray[this.index++ % INPUTS.length])); } } diff --git a/json/src/main/java/alpine/json/JsonWriter.java b/json/src/main/java/alpine/json/JsonWriter.java index 9e4f407..ef04d26 100644 --- a/json/src/main/java/alpine/json/JsonWriter.java +++ b/json/src/main/java/alpine/json/JsonWriter.java @@ -50,7 +50,7 @@ private void writeString(StringBuilder builder, String string) { var length = string.length(); for (var index = 0; index < length; index++) { - var character = string.charAt(i); + var character = string.charAt(index); // fast path: safe character if (character != '"' && character != '\\' && !Character.isISOControl(character)) { @@ -58,7 +58,7 @@ private void writeString(StringBuilder builder, String string) { } if (index > start) { - builder.append(string, start, i); + builder.append(string, start, index); } switch (character) { From c14c1a73e38ef90b650e03d037b9c5c91f14eadd Mon Sep 17 00:00:00 2001 From: mudkipdev Date: Wed, 18 Feb 2026 20:57:13 -0700 Subject: [PATCH 28/28] add warning to readme --- .github/README.md | 9 ++++++--- .github/renovate.json | 10 ---------- binary/build.gradle.kts | 4 ++-- 3 files changed, 8 insertions(+), 15 deletions(-) delete mode 100644 .github/renovate.json diff --git a/.github/README.md b/.github/README.md index fcfb914..2b42f0a 100644 --- a/.github/README.md +++ b/.github/README.md @@ -4,6 +4,9 @@ A binary and JSON serialization library for Java. ![](https://wakatime.com/badge/github/mudkipdev/alpine.svg) ## Installation +> [!WARNING] +> I'm in the process of setting up the Maven publishing again. JSON is currently not published, and for binary you should use the `0.1.1` version instead of `0.2.0`. This notice is temporary. + ### Binary

@@ -13,7 +16,7 @@ A binary and JSON serialization library for Java. ```kts dependencies { implementation("dev.mudkip:alpine-binary:0.2.0") - implementation("io.netty:netty-buffer:4.2.0.Final") + implementation("io.netty:netty-buffer:4.2.10.Final") } ``` @@ -26,7 +29,7 @@ dependencies { ```groovy dependencies { implementation 'dev.mudkip:alpine-binary:0.2.0' - implementation 'io.netty:netty-buffer:4.2.0.Final' + implementation 'io.netty:netty-buffer:4.2.10.Final' } ``` @@ -46,7 +49,7 @@ dependencies { io.netty netty-buffer - 4.2.0.Final + 4.2.10.Final ``` diff --git a/.github/renovate.json b/.github/renovate.json deleted file mode 100644 index 90cd5f4..0000000 --- a/.github/renovate.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ], - "rangeStrategy": "bump", - "assignees": [ - "mudkipdev" - ] -} \ No newline at end of file diff --git a/binary/build.gradle.kts b/binary/build.gradle.kts index bca9466..459d401 100644 --- a/binary/build.gradle.kts +++ b/binary/build.gradle.kts @@ -1,6 +1,6 @@ description = "A binary serialization library for Java." dependencies { - compileOnly("io.netty:netty-buffer:4.2.2.Final") - testImplementation("io.netty:netty-buffer:4.2.2.Final") + compileOnly("io.netty:netty-buffer:4.2.10.Final") + testImplementation("io.netty:netty-buffer:4.2.10.Final") } \ No newline at end of file