12 Commits
Author SHA1 Message Date
weaselbot 34fc22a7c2 Handle null parser in WeaselJsonParser_reset and _destroy
WeaselJsonParser_create can return nullptr when allocation fails or the
requested stack size is too small. Previously, passing that nullptr to
WeaselJsonParser_reset or WeaselJsonParser_destroy dereferenced it before
doing any work, causing immediate undefined behavior.

Add an early null check to both functions so they behave like free(nullptr)
(i.e., are a safe no-op). Also add a doctest case covering both a null
returned from create and a literal nullptr.

Closes #41
2026-06-29 13:53:31 -04:00
andrew 08b864d31b Reject invalid UTF-16 surrogate pairs and lone low surrogates for clarity
The string unescape logic treated any code unit in the surrogate range

(0xD800-0xDFFF) as the start of a surrogate pair. The concrete example

from issue #39 (\uDC00\uDC00) was already rejected by the existing

0x10FFFF bounds check, but the check was misleading and would accept a

lone low surrogate as a regular BMP code point if the second surrogate

happened to be in a narrower range. Clean this up so the intent is

obvious.

Changes in src/parser3.h:

- Fast path (n_string2): only treat high surrogates (0xD800-0xDBFF) as

the start of a surrogate pair, and explicitly reject lone low surrogates

(0xDC00-0xDFFF).

- Slow path (t_hex2): same high-surrogate check, with explicit rejection

of lone low surrogates.

The t_hex3 path already validates that the second code unit is a low

surrogate (0xDC00-0xDFFF), so no change is needed there.

Also commit the current fuzzer corpus.

Closes #39
2026-06-29 13:37:58 -04:00
andrew 4ce2002663 Merge pull request 'schemagen: reject scalar root values when root schema is object/array' (#32) from weaselbot/weaseljson:weaselbot/issue-16 into main
Reviewed-on: weaselab/weaseljson#32
2026-06-24 19:34:06 +00:00
weaselbot df693ef4c9 schemagen: reject scalar root values when root schema is object/array
The generated RootBuilder crashed (undefined behavior on std::vector::back())
when a JSON document's root value was a scalar or null while the schema
declared a non-nullable object or array root. The stack starts empty for
object/array roots, but cbStringData, cbNumberData, and cbBool called
stack_.back() without checking for an empty stack.

Add an empty-stack guard to the three scalar callbacks so they reject
instead of crashing. cbNull already handles the empty-stack case.

Regression tests added for:
- non-nullable object root rejecting null, boolean, number, and string roots
- nullable object root rejecting scalar roots
- nullable array root rejecting scalar roots

Closes #16
2026-06-24 14:30:36 -04:00
andrew e5cbaac401 Merge pull request 'schemagen: cache non-object $defs entries to avoid duplicate types' (#31) from weaselbot/weaseljson:weaselbot/issue-17 into main
Reviewed-on: weaselab/weaseljson#31
2026-06-24 17:02:38 +00:00
weaselbot e155e0bbf4 schemagen: restore nullable tuple return for object schemas
The previous change to cache object definitions started returning the
bare TObj from build_type for object schemas, discarding the nullable
flag. This caused nullable root objects to be emitted as plain structs
instead of std::optional<RootInner>, breaking the nullable root tests.

Return the (TObj, nullable) tuple so callers (including the root
emitter) see the correct nullability again.
2026-06-24 09:51:19 -04:00
weaselbot 717f30099f schemagen: cache non-object $defs entries to avoid duplicate types
Extend the existing per-definition cache (`self._building`) to enum,
array, and scalar $defs, not just object definitions. This ensures
that multiple $refs to the same non-object definition reuse the same
C++ type instead of generating Role, Role2, Role3, etc.

- Cache the built (type, nullable) tuple under defname for enum,
  scalar, and array definitions.
- Pre-register array definitions before recursing into items so $ref
  cycles resolve to the same TArr instance.
- Store object definitions as (TObj, nullable) tuples so nullable object
  $defs also preserve their nullability when referenced.

Add a regression test for issue #17 covering reused enum and array-of-enum
$defs.
2026-06-23 22:16:34 -04:00
andrew 1404ebdfbd Merge pull request 'fix schemagen integer parsing boundary bugs' (#30) from weaselbot/weaseljson:weaselbot/issue-19 into main
Reviewed-on: weaselab/weaseljson#30
2026-06-24 00:40:09 +00:00
weaselbot 38079cc278 schemagen: parse integer fallback exactly for decimal/exponent forms
Replace the double-based fallback in generated integer slots with a
string-to-int64 parser that handles decimal points and exponents
without losing precision near the int64 boundaries.

The old path used std::from_chars<double> and compared against
±9223372036854775808.0, which rounds the int64 max and min so that
valid values are rejected and out-of-range negatives are accepted.

The new helper:
- Parses sign, integer part, optional fraction, and optional exponent.
- Strips trailing zeros to cancel fractional places.
- Rejects non-integral values and overflow using exact uint64_t
  arithmetic.

Adds regression tests covering root integer and object-field integer
boundary values, including the cases from issue #19.
2026-06-23 18:36:53 -04:00
andrew ceb4bc1041 Merge pull request 'schemagen: drop support for additionalProperties: true' (#28) from weaselbot/weaseljson:weaselbot/issue-20 into main
Reviewed-on: weaselab/weaseljson#28
2026-06-23 20:56:58 +00:00
weaselbot 16f13c241c schemagen: drop support for additionalProperties: true
Following review feedback, the generator no longer supports permissive
objects. Changes:

- Reject `additionalProperties: true` at generation time.
- Treat an absent `additionalProperties` as `false`, so every object is
  strict by default and unknown keys are rejected during parsing.
- Remove the now-dead permissive-object infrastructure: `Kind::Skip`,
  `Cat::Skip`, `kSkip`, the per-frame `unknown` key set, and `isStrict()`.
- Update the README feature/rejection tables accordingly.
- Remove the permissive "loose" object from example.schema.json and the
  associated tests from test_gen.cpp.
- Add Python unit tests verifying the new `additionalProperties` behavior.

All tests pass (`ctest --output-on-failure`).
2026-06-23 15:11:48 -04:00
weaselbot ab95fefb09 schemagen: reject duplicate unknown keys in non-strict objects
Track unknown keys in a per-object unordered_set so that permissive
objects (additionalProperties absent/true) still reject duplicate keys,
matching the README guarantee.

- Add std::unordered_set<std::string> to Frame.
- Insert unknown keys in cbKeyData and reject duplicates before skipping.
- Add a permissive "loose" subobject to example.schema.json.
- Test single unknown key accepted and duplicate unknown/known keys rejected.
2026-06-23 15:08:48 -04:00
34 changed files with 1405 additions and 79 deletions
+5 -5
View File
@@ -45,7 +45,7 @@ into the result, so it is non-movable.
| `$ref` to `$defs`/`definitions` | the referenced named struct | | `$ref` to `$defs`/`definitions` | the referenced named struct |
| recursive `$ref` | `std::unique_ptr<T>` (cycle broken) | | recursive `$ref` | `std::unique_ptr<T>` (cycle broken) |
| `additionalProperties: false` | unknown keys rejected | | `additionalProperties: false` | unknown keys rejected |
| `additionalProperties` absent / `true` | unknown keys' values skipped | | `additionalProperties` absent / `true` | not supported (rejected at generation) |
## Schema violations (rejected at parse time) ## Schema violations (rejected at parse time)
@@ -55,15 +55,15 @@ into the result, so it is non-movable.
- value not in a string `enum` - value not in a string `enum`
- a number not representable in the target type (e.g. `1.5` for an `integer`) - a number not representable in the target type (e.g. `1.5` for an `integer`)
- duplicate object keys - duplicate object keys
- unknown key under `additionalProperties: false` - unknown key in any object
## Not supported (rejected at generation time, no fallback) ## Not supported (rejected at generation time, no fallback)
`oneOf` / `anyOf` / `allOf` / `not` / `if`-`then`-`else`, `oneOf` / `anyOf` / `allOf` / `not` / `if`-`then`-`else`,
`patternProperties`, `additionalProperties` with a schema (typed map), `patternProperties`, `additionalProperties` with a schema (typed map),
`prefixItems` (tuples), `const`, `dependentSchemas`/`dependentRequired`, `additionalProperties: true`, `prefixItems` (tuples), `const`,
union `type` lists other than `["T", "null"]`, non-string enums, and remote `dependentSchemas`/`dependentRequired`, union `type` lists other than
(`$ref` to other documents). `["T", "null"]`, non-string enums, and remote (`$ref` to other documents).
## Notes ## Notes
+4
View File
@@ -184,6 +184,10 @@ int main() {
expectReject(R"({"name":"x","age":1,"address":{"zip":5}})", expectReject(R"({"name":"x","age":1,"address":{"zip":5}})",
"missing required nested 'city'"); "missing required nested 'city'");
expectReject(R"([1,2,3])", "array where object expected (root)"); expectReject(R"([1,2,3])", "array where object expected (root)");
expectReject("null", "null where object expected (root)");
expectReject("true", "boolean where object expected (root)");
expectReject("123", "number where object expected (root)");
expectReject(R"("hi")", "string where object expected (root)");
expectReject(R"({"name":"x","age":1,)", "truncated / invalid json"); expectReject(R"({"name":"x","age":1,)", "truncated / invalid json");
if (failures == 0) { if (failures == 0) {
+40
View File
@@ -61,6 +61,18 @@ static void expectReject(nullable_object::RootBuilder &b, std::string in,
} }
} }
static void expectReject(nullable_array::RootBuilder &b, std::string in,
const char *what) {
WeaselJsonStatus s = parseStrided(b, in);
if (s == WeaselJson_REJECT) {
printf("ok reject: %s\n", what);
} else {
printf("FAIL expected reject (%s) got status %d for: %s\n", what, s,
in.c_str());
++failures;
}
}
int main() { int main() {
// ---- nullable root object: valid document ---- // ---- nullable root object: valid document ----
{ {
@@ -149,6 +161,34 @@ int main() {
} }
} }
// ---- nullable root object: scalar values rejected ----
{
nullable_object::RootBuilder b;
expectReject(b, "true", "boolean where nullable object expected (root)");
}
{
nullable_object::RootBuilder b;
expectReject(b, "123", "number where nullable object expected (root)");
}
{
nullable_object::RootBuilder b;
expectReject(b, R"("hi")", "string where nullable object expected (root)");
}
// ---- nullable root array: scalar values rejected ----
{
nullable_array::RootBuilder b;
expectReject(b, "true", "boolean where nullable array expected (root)");
}
{
nullable_array::RootBuilder b;
expectReject(b, "123", "number where nullable array expected (root)");
}
{
nullable_array::RootBuilder b;
expectReject(b, R"("hi")", "string where nullable array expected (root)");
}
if (failures == 0) { if (failures == 0) {
printf("\nALL TESTS PASSED\n"); printf("\nALL TESTS PASSED\n");
return 0; return 0;
+278 -3
View File
@@ -8,6 +8,7 @@ import shutil
import subprocess import subprocess
import sys import sys
import tempfile import tempfile
import textwrap
import unittest import unittest
SCRIPT = os.path.join(os.path.dirname(__file__), "weaseljson_schemagen.py") SCRIPT = os.path.join(os.path.dirname(__file__), "weaseljson_schemagen.py")
@@ -178,21 +179,295 @@ class SchemagenCollisionTest(unittest.TestCase):
self.assertIn("Arr1", enumerators) self.assertIn("Arr1", enumerators)
self.assertEqual(len(enumerators), len(set(enumerators))) self.assertEqual(len(enumerators), len(set(enumerators)))
def test_skip_is_reserved(self): def test_skip_user_type_is_allowed(self):
schema = { schema = {
"type": "array", "type": "array",
"items": {"$ref": "#/$defs/Skip"}, "items": {"$ref": "#/$defs/Skip"},
"$defs": {"Skip": {"type": "object", "properties": {}}}, "$defs": {"Skip": {"type": "object", "properties": {}}},
} }
out = self.generate_and_compile(schema) out = self.generate_and_compile(schema)
self.assertIn("struct Skip1", out) self.assertIn("struct Skip", out)
self.assertNotIn("struct Skip1", out)
m = re.search(r"enum class Kind : uint8_t \{([^}]+)\}", out) m = re.search(r"enum class Kind : uint8_t \{([^}]+)\}", out)
self.assertIsNotNone(m) self.assertIsNotNone(m)
enumerators = [e.strip() for e in m.group(1).split(",")] enumerators = [e.strip() for e in m.group(1).split(",")]
self.assertIn("Skip", enumerators) self.assertIn("Skip", enumerators)
self.assertIn("Skip1", enumerators) self.assertIn("Arr0", enumerators)
self.assertEqual(len(enumerators), len(set(enumerators))) self.assertEqual(len(enumerators), len(set(enumerators)))
def test_non_object_defs_reused_across_refs(self):
"""Regression test for issue #17: enum and array $defs must be reused."""
schema = {
"type": "object",
"properties": {
"role1": {"$ref": "#/$defs/Role"},
"role2": {"$ref": "#/$defs/Role"},
"roles1": {"$ref": "#/$defs/Roles"},
"roles2": {"$ref": "#/$defs/Roles"},
},
"$defs": {
"Role": {"enum": ["admin", "user"]},
"Roles": {"type": "array", "items": {"$ref": "#/$defs/Role"}},
},
}
out = self.generate_and_compile(schema)
# Exactly one Role enum is generated.
self.assertIn("enum class Role : int { admin, user };", out)
self.assertNotIn("enum class Role1 : int", out)
self.assertNotIn("enum class Role2 : int", out)
# The array of enum is represented by a single kind.
m = re.search(r"enum class Kind : uint8_t \{([^}]+)\}", out)
self.assertIsNotNone(m)
enumerators = [e.strip() for e in m.group(1).split(",")]
self.assertEqual(enumerators.count("Arr0"), 1)
# All four fields use the same C++ types.
self.assertIn("std::optional<Role> role1;", out)
self.assertIn("std::optional<Role> role2;", out)
self.assertIn("std::optional<std::vector<Role>> roles1;", out)
self.assertIn("std::optional<std::vector<Role>> roles2;", out)
class SchemagenAdditionalPropertiesTest(unittest.TestCase):
def run_schemagen(self, schema, args=None):
"""Run schemagen on a schema dict. Returns (returncode, stdout, stderr)."""
with tempfile.NamedTemporaryFile("w", suffix=".json", delete=False) as fp:
json.dump(schema, fp)
schema_path = fp.name
try:
cmd = [sys.executable, SCRIPT, schema_path]
if args:
cmd.extend(args)
result = subprocess.run(cmd, capture_output=True, text=True, check=False)
return result.returncode, result.stdout, result.stderr
finally:
os.unlink(schema_path)
def test_additional_properties_true_rejected(self):
schema = {
"type": "object",
"additionalProperties": True,
"properties": {"name": {"type": "string"}},
}
rc, stdout, stderr = self.run_schemagen(schema)
self.assertNotEqual(rc, 0)
self.assertIn("additionalProperties: true is not supported", stderr)
def test_additional_properties_absent_defaults_to_strict(self):
schema = {
"type": "object",
"properties": {"name": {"type": "string"}},
}
rc, stdout, stderr = self.run_schemagen(schema)
self.assertEqual(rc, 0, msg=stderr)
# The generated parser should reject unknown keys. Verify the key-matching
# helper returns -1 for an unknown key and cbKeyData rejects it.
self.assertIn("int matchKey(Kind k, std::string_view key) const {", stdout)
self.assertNotIn("bool isStrict(Kind k) const", stdout)
def test_additional_properties_false_accepted(self):
schema = {
"type": "object",
"additionalProperties": False,
"properties": {"name": {"type": "string"}},
}
rc, stdout, stderr = self.run_schemagen(schema)
self.assertEqual(rc, 0, msg=stderr)
class SchemagenIntegerBoundaryTest(unittest.TestCase):
"""Regression tests for issue #19: integer slot parsing near int64 boundaries."""
def setUp(self):
self.repo_root = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
)
self.include_dir = os.path.join(self.repo_root, "include")
self.lib_src = os.path.join(self.repo_root, "src", "lib.cpp")
self.compiler = shutil.which("c++")
def _compile_harness(self, tmpdir, schema, harness):
schema_path = os.path.join(tmpdir, "schema.json")
with open(schema_path, "w") as fp:
json.dump(schema, fp)
header_path = os.path.join(tmpdir, "gen.h")
result = subprocess.run(
[
sys.executable,
SCRIPT,
schema_path,
"-o",
header_path,
"--namespace",
"test_schema",
],
capture_output=True,
text=True,
check=False,
)
self.assertEqual(result.returncode, 0, msg=result.stderr)
lib_obj = os.path.join(tmpdir, "lib.o")
comp_lib = subprocess.run(
[
self.compiler,
"-std=c++20",
"-I",
self.include_dir,
"-I",
os.path.join(self.repo_root, "third_party", "include"),
"-I",
os.path.join(self.repo_root, "third_party", "valgrind"),
"-c",
self.lib_src,
"-o",
lib_obj,
],
capture_output=True,
text=True,
check=False,
)
self.assertEqual(comp_lib.returncode, 0, msg=comp_lib.stderr)
cpp_path = os.path.join(tmpdir, "test.cpp")
with open(cpp_path, "w") as fp:
fp.write(harness)
exe_path = os.path.join(tmpdir, "test")
comp = subprocess.run(
[
self.compiler,
"-std=c++20",
"-I",
self.include_dir,
"-I",
tmpdir,
lib_obj,
cpp_path,
"-o",
exe_path,
],
capture_output=True,
text=True,
check=False,
)
self.assertEqual(comp.returncode, 0, msg=comp.stderr)
run = subprocess.run([exe_path], capture_output=True, text=True, check=False)
self.assertEqual(run.returncode, 0, msg=run.stdout + run.stderr)
def _build_cases_array(self, name, entries):
lines = [
f" struct {name}Case {{ const char *s; WeaselJsonStatus expected; long long v; }};"
]
lines.append(f" {name}Case {name}_cases[] = {{")
for s, exp, v in entries:
val = f"{v}LL" if isinstance(v, int) else v
lines.append(f' {{ R"({s})", {exp}, {val} }},')
lines.append(" };")
return "\n".join(lines)
def test_integer_boundary_root(self):
if not self.compiler:
self.skipTest("C++ compiler not available")
cases = [
("9223372036854775807.0", "WeaselJson_OK", 9223372036854775807),
("9223372036854775807", "WeaselJson_OK", 9223372036854775807),
("9223372036854775806.0", "WeaselJson_OK", 9223372036854775806),
("9223372036854775808", "WeaselJson_REJECT", 0),
("-9223372036854775808", "WeaselJson_OK", "-9223372036854775807LL - 1"),
("-9223372036854775808.0", "WeaselJson_OK", "-9223372036854775807LL - 1"),
("-9223372036854775809", "WeaselJson_REJECT", 0),
("1e3", "WeaselJson_OK", 1000),
("2.0", "WeaselJson_OK", 2),
("0.001", "WeaselJson_REJECT", 0),
("1e-3", "WeaselJson_REJECT", 0),
("1000e-3", "WeaselJson_OK", 1),
("100.0e-2", "WeaselJson_OK", 1),
("123.0", "WeaselJson_OK", 123),
("9e18", "WeaselJson_OK", 9000000000000000000),
("10e18", "WeaselJson_REJECT", 0),
]
cases_src = self._build_cases_array("root", cases)
harness = textwrap.dedent(
f"""
#include "gen.h"
#include <cstdio>
#include <cstring>
{cases_src}
int main() {{
for (const auto \u0026c : root_cases) {{
test_schema::RootBuilder b;
char buf[512];
std::strncpy(buf, c.s, sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\\0';
WeaselJsonStatus st = b.feed(buf, std::strlen(buf));
st = b.finish();
if (st != c.expected) {{
std::printf("root case %s expected %d got %d\\n", c.s, c.expected, st);
return 1;
}}
if (st == WeaselJson_OK \u0026\u0026 b.take() != c.v) {{
std::printf("root case %s value mismatch\\n", c.s);
return 2;
}}
}}
return 0;
}}
"""
)
with tempfile.TemporaryDirectory() as tmpdir:
self._compile_harness(tmpdir, {"type": "integer"}, harness)
def test_integer_boundary_object_field(self):
if not self.compiler:
self.skipTest("C++ compiler not available")
cases = [
('{"age":9223372036854775807.0}', "WeaselJson_OK", 9223372036854775807),
('{"age":-9223372036854775809}', "WeaselJson_REJECT", 0),
('{"age":1e3}', "WeaselJson_OK", 1000),
('{"age":2.0}', "WeaselJson_OK", 2),
('{"age":0.001}', "WeaselJson_REJECT", 0),
(
'{"age":-9223372036854775808.0}',
"WeaselJson_OK",
"-9223372036854775807LL - 1",
),
]
cases_src = self._build_cases_array("object", cases)
harness = textwrap.dedent(
f"""
#include "gen.h"
#include <cstdio>
#include <cstring>
{cases_src}
int main() {{
for (const auto \u0026c : object_cases) {{
test_schema::RootBuilder b;
char buf[512];
std::strncpy(buf, c.s, sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\\0';
WeaselJsonStatus st = b.feed(buf, std::strlen(buf));
st = b.finish();
if (st != c.expected) {{
std::printf("object case %s expected %d got %d\\n", c.s, c.expected, st);
return 3;
}}
if (st == WeaselJson_OK \u0026\u0026 b.take().age != c.v) {{
std::printf("object case %s value mismatch\\n", c.s);
return 4;
}}
}}
return 0;
}}
"""
)
schema = {
"type": "object",
"properties": {"age": {"type": "integer"}},
"required": ["age"],
}
with tempfile.TemporaryDirectory() as tmpdir:
self._compile_harness(tmpdir, schema, harness)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
+127 -69
View File
@@ -60,7 +60,6 @@ class ObjectType:
def __init__(self, name): def __init__(self, name):
self.name = name self.name = name
self.fields = [] # list[Field] self.fields = [] # list[Field]
self.strict = False # additionalProperties: false
class EnumType: class EnumType:
@@ -234,7 +233,7 @@ class Builder:
@staticmethod @staticmethod
def _is_reserved(name): def _is_reserved(name):
"""Names generated internally that must not collide with user types.""" """Names generated internally that must not collide with user types."""
return name in ("Root", "Skip", "RootScalar") return name in ("Root", "RootScalar")
def ref_name(self, ref): def ref_name(self, ref):
if not ref.startswith("#/"): if not ref.startswith("#/"):
@@ -251,7 +250,6 @@ class Builder:
if defname not in self.defs: if defname not in self.defs:
raise GenError(f"$ref to unknown def: {defname}") raise GenError(f"$ref to unknown def: {defname}")
node = self.defs[defname] node = self.defs[defname]
# For objects we must register the name before recursing into fields.
return self.build_type(node, defname, defname=defname) return self.build_type(node, defname, defname=defname)
def build_type(self, node, hint, defname=None): def build_type(self, node, hint, defname=None):
@@ -280,6 +278,10 @@ class Builder:
if "$ref" in node: if "$ref" in node:
return self.build_def(self.ref_name(node["$ref"])) return self.build_def(self.ref_name(node["$ref"]))
# Non-object $defs entries must reuse the same type for every $ref.
if defname is not None and defname in self._building:
return self._building[defname]
# nullability via type lists: ["string", "null"] # nullability via type lists: ["string", "null"]
nullable = False nullable = False
typ = node.get("type") typ = node.get("type")
@@ -298,18 +300,29 @@ class Builder:
raise GenError("only non-empty string enums are supported") raise GenError("only non-empty string enums are supported")
name = defname and self.unique_name(defname) or self.unique_name(hint) name = defname and self.unique_name(defname) or self.unique_name(hint)
self.enums[name] = EnumType(name, list(vals)) self.enums[name] = EnumType(name, list(vals))
return (TEnum(name), nullable) result = (TEnum(name), nullable)
if defname is not None:
self._building[defname] = result
return result
if typ == "object" or (typ is None and "properties" in node): if typ == "object" or (typ is None and "properties" in node):
return (self._build_object(node, hint, defname), nullable) return (self._build_object(node, hint, defname, nullable), nullable)
if typ == "array": if typ == "array":
if "items" not in node or not isinstance(node["items"], dict): if "items" not in node or not isinstance(node["items"], dict):
raise GenError("arrays require a single 'items' schema") raise GenError("arrays require a single 'items' schema")
# Register the array before building its items so $ref cycles back
# to this definition resolve to the same TArr instance.
t = TArr(None, False)
result = (t, nullable)
if defname is not None:
self._building[defname] = result
elem, elem_nullable = self._unpack( elem, elem_nullable = self._unpack(
self.build_type(node["items"], hint + "Item") self.build_type(node["items"], hint + "Item")
) )
return (TArr(elem, elem_nullable), nullable) t.elem = elem
t.elem_nullable = elem_nullable
return result
scalar = { scalar = {
"string": "str", "string": "str",
@@ -318,7 +331,10 @@ class Builder:
"boolean": "bool", "boolean": "bool",
}.get(typ) }.get(typ)
if scalar: if scalar:
return (TScalar(scalar), nullable) result = (TScalar(scalar), nullable)
if defname is not None:
self._building[defname] = result
return result
if typ == "null": if typ == "null":
raise GenError("'null'-only types are not supported") raise GenError("'null'-only types are not supported")
@@ -332,19 +348,21 @@ class Builder:
return result return result
return (result, False) return (result, False)
def _build_object(self, node, hint, defname): def _build_object(self, node, hint, defname, nullable=False):
name = self.unique_name(defname or hint) name = self.unique_name(defname or hint)
obj = ObjectType(name) obj = ObjectType(name)
self.objects[name] = obj self.objects[name] = obj
# register for $ref cycles before building fields # register for $ref cycles before building fields
tobj = TObj(name)
if defname is not None: if defname is not None:
self._building[defname] = TObj(name) self._building[defname] = (tobj, nullable)
ap = node.get("additionalProperties", True) ap = node.get("additionalProperties", False)
if ap is True:
raise GenError("additionalProperties: true is not supported")
if isinstance(ap, dict): if isinstance(ap, dict):
raise GenError( raise GenError(
"additionalProperties with a schema (typed map) is not " "supported yet" "additionalProperties with a schema (typed map) is not " "supported yet"
) )
obj.strict = ap is False
required = set(node.get("required", [])) required = set(node.get("required", []))
props = node.get("properties", {}) props = node.get("properties", {})
seen_cpp = set() seen_cpp = set()
@@ -358,7 +376,7 @@ class Builder:
cpp = f"{base}{i}" cpp = f"{base}{i}"
seen_cpp.add(cpp) seen_cpp.add(cpp)
obj.fields.append(Field(key, cpp, ty, key in required, nullable)) obj.fields.append(Field(key, cpp, ty, key in required, nullable))
return TObj(name) return tobj
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -620,7 +638,6 @@ namespace {ns} {{"""
root_is_container = isinstance(self.root_ty, (TObj, TArr)) root_is_container = isinstance(self.root_ty, (TObj, TArr))
if not root_is_container: if not root_is_container:
kinds.append("RootScalar") kinds.append("RootScalar")
kinds.append("Skip")
self.kind_order = kinds self.kind_order = kinds
return " enum class Kind : uint8_t { " + ", ".join(kinds) + " };" return " enum class Kind : uint8_t { " + ", ".join(kinds) + " };"
@@ -809,17 +826,6 @@ namespace {ns} {{"""
lines.append(" }") lines.append(" }")
return "\n".join(lines) return "\n".join(lines)
def _is_strict(self):
strict = [n for n, o in self.b.objects.items() if o.strict]
if not strict:
return " bool isStrict(Kind) const { return false; }"
cases = " ".join(f"case Kind::{n}:" for n in strict)
return (
" bool isStrict(Kind k) const {\n"
f" switch (k) {{ {cases} return true; default: return false; }}\n"
" }"
)
def _enum_name_arrays(self): def _enum_name_arrays(self):
out = [] out = []
for e in self.b.enums.values(): for e in self.b.enums.values():
@@ -861,13 +867,7 @@ namespace {ns} {{"""
else: else:
lines.append(" if (stack_.empty()) { reject(); return; }") lines.append(" if (stack_.empty()) { reject(); return; }")
lines.append(" Frame &f = stack_.back();") lines.append(" Frame &f = stack_.back();")
lines.append(
" if (f.kind == Kind::Skip) { stack_.push_back(Frame{Kind::Skip, nullptr}); return; }"
)
lines.append(" SlotInfo si = slotInfoG(f);") lines.append(" SlotInfo si = slotInfoG(f);")
lines.append(
" if (si.cat == Cat::Skip) { stack_.push_back(Frame{Kind::Skip, nullptr}); return; }"
)
lines.append(f" if (si.cat != Cat::{event_cat}) {{ reject(); return; }}") lines.append(f" if (si.cat != Cat::{event_cat}) {{ reject(); return; }}")
lines.append(" void *p = engage(f, true);") lines.append(" void *p = engage(f, true);")
lines.append(" stack_.push_back(Frame{si.child, p});") lines.append(" stack_.push_back(Frame{si.child, p});")
@@ -918,7 +918,7 @@ public:
private: private:
{kind_enum} {kind_enum}
enum class Cat {{ Reject, Str, Int, Dbl, Bool, Enum, Obj, Arr, Skip }}; enum class Cat {{ Reject, Str, Int, Dbl, Bool, Enum, Obj, Arr }};
struct SlotInfo {{ struct SlotInfo {{
Cat cat; Cat cat;
Kind child{{}}; Kind child{{}};
@@ -929,11 +929,10 @@ private:
struct Frame {{ struct Frame {{
Kind kind; Kind kind;
void *dest; void *dest;
int field = -1; // object: selected field (-1 want key, -2 skip) int field = -1; // object: selected field (-1 means waiting for key)
std::vector<uint64_t> seen; // populated field bitset (object frames) std::vector<uint64_t> seen; // populated field bitset (object frames)
}}; }};
static constexpr int kWantKey = -1; static constexpr int kWantKey = -1;
static constexpr int kSkip = -2;
{self._enum_name_arrays()} {self._enum_name_arrays()}
@@ -948,10 +947,93 @@ private:
void reject() {{ error_ = true; }} void reject() {{ error_ = true; }}
// Wrap the generated slotInfo() with the generic key/skip states. // Parse a JSON number text as int64_t. Accepts optional decimal point and
// exponent only when the mathematical value is an integer that fits in a
// signed 64-bit range.
static bool parseJsonInt64(const char *b, const char *e, int64_t &out) {{
const char *p = b;
bool neg = false;
if (p < e) {{
if (*p == '-') {{ neg = true; ++p; }}
else if (*p == '+') return false;
}}
const char *intStart = p;
while (p < e && *p >= '0' && *p <= '9') ++p;
const char *intEnd = p;
int fracDigits = 0;
const char *fracStart = p;
if (p < e && *p == '.') {{
++p;
fracStart = p;
while (p < e && *p >= '0' && *p <= '9') {{ ++p; ++fracDigits; }}
if (fracStart == p) return false;
}}
int64_t exp = 0;
bool expNeg = false;
if (p < e && (*p == 'e' || *p == 'E')) {{
++p;
if (p < e && (*p == '-' || *p == '+')) {{ expNeg = (*p == '-'); ++p; }}
if (p == e || *p < '0' || *p > '9') return false;
while (p < e && *p >= '0' && *p <= '9') {{
int digit = *p - '0';
if (exp <= (INT64_MAX - digit) / 10) exp = exp * 10 + digit;
else exp = INT64_MAX;
++p;
}}
if (expNeg) exp = -exp;
}}
if (p != e) return false;
if (intStart == intEnd) return false;
std::string digits;
digits.reserve((intEnd - intStart) + fracDigits);
for (const char *q = intStart; q < intEnd; ++q) digits.push_back(*q);
for (int i = 0; i < fracDigits; ++i) digits.push_back(fracStart[i]);
int64_t trim = 0;
while (!digits.empty() && digits.back() == '0') {{
digits.pop_back();
++trim;
}}
int64_t finalExp = exp - fracDigits + trim;
if (finalExp < 0) return false;
while (!digits.empty() && digits.front() == '0') digits.erase(digits.begin());
if (digits.empty()) {{ out = 0; return true; }}
constexpr uint64_t kMaxNeg = 9223372036854775808ULL;
constexpr uint64_t kMaxPos = 9223372036854775807ULL;
const uint64_t limit = neg ? kMaxNeg : kMaxPos;
if (finalExp > 19) return false;
int64_t maxSig = 19 - finalExp;
uint64_t mag = 0;
int64_t sigDigits = 0;
for (char ch : digits) {{
uint64_t d = static_cast<uint64_t>(ch - '0');
if (sigDigits >= maxSig) return false;
if (mag > (limit - d) / 10) return false;
mag = mag * 10 + d;
++sigDigits;
}}
for (int64_t i = 0; i < finalExp; ++i) {{
if (mag > limit / 10) return false;
mag *= 10;
}}
if (mag > limit) return false;
if (neg) {{
if (mag == kMaxNeg) {{
out = INT64_MIN;
}} else {{
out = -static_cast<int64_t>(mag);
}}
}} else {{
out = static_cast<int64_t>(mag);
}}
return true;
}}
// Wrap the generated slotInfo() with the generic key state.
SlotInfo slotInfoG(const Frame &f) {{ SlotInfo slotInfoG(const Frame &f) {{
if (isObjectKind(f.kind)) {{ if (isObjectKind(f.kind)) {{
if (f.field == kSkip) return SlotInfo{{Cat::Skip}};
if (f.field < 0) return SlotInfo{{Cat::Reject}}; if (f.field < 0) return SlotInfo{{Cat::Reject}};
}} }}
return slotInfo(f); return slotInfo(f);
@@ -976,11 +1058,6 @@ private:
void cbEndObject() {{ void cbEndObject() {{
if (error_) return; if (error_) return;
Frame &f = stack_.back(); Frame &f = stack_.back();
if (f.kind == Kind::Skip) {{
stack_.pop_back();
if (stack_.empty() || stack_.back().kind != Kind::Skip) valueComplete();
return;
}}
if (isObjectKind(f.kind)) {{ if (isObjectKind(f.kind)) {{
const auto &req = requiredMask(f.kind); const auto &req = requiredMask(f.kind);
bool missing = false; bool missing = false;
@@ -998,11 +1075,6 @@ private:
void cbEndArray() {{ void cbEndArray() {{
if (error_) return; if (error_) return;
Frame f = stack_.back(); Frame f = stack_.back();
if (f.kind == Kind::Skip) {{
stack_.pop_back();
if (stack_.empty() || stack_.back().kind != Kind::Skip) valueComplete();
return;
}}
stack_.pop_back(); stack_.pop_back();
valueComplete(); valueComplete();
}} }}
@@ -1014,12 +1086,10 @@ private:
scratch_.append(buf, len); scratch_.append(buf, len);
if (!done) return; if (!done) return;
int idx = matchKey(f.kind, scratch_); int idx = matchKey(f.kind, scratch_);
scratch_.clear();
if (idx < 0) {{ if (idx < 0) {{
if (isStrict(f.kind)) {{ reject(); return; }} reject(); return; // unknown key
f.field = kSkip;
return;
}} }}
scratch_.clear();
if (f.seen[idx >> 6] & (1ull << (idx & 63))) {{ if (f.seen[idx >> 6] & (1ull << (idx & 63))) {{
reject(); return; // duplicate key reject(); return; // duplicate key
}} }}
@@ -1028,10 +1098,9 @@ private:
void cbStringData(const char *buf, int len, int done) {{ void cbStringData(const char *buf, int len, int done) {{
if (error_) return; if (error_) return;
if (stack_.empty()) {{ reject(); return; }}
Frame &f = stack_.back(); Frame &f = stack_.back();
if (f.kind == Kind::Skip) return;
SlotInfo si = slotInfoG(f); SlotInfo si = slotInfoG(f);
if (si.cat == Cat::Skip) {{ if (done) valueComplete(); return; }}
if (si.cat == Cat::Str) {{ if (si.cat == Cat::Str) {{
auto *s = (std::string *)engage(f, !started_); auto *s = (std::string *)engage(f, !started_);
s->append(buf, len); s->append(buf, len);
@@ -1056,10 +1125,9 @@ private:
void cbNumberData(const char *buf, int len, int done) {{ void cbNumberData(const char *buf, int len, int done) {{
if (error_) return; if (error_) return;
if (stack_.empty()) {{ reject(); return; }}
Frame &f = stack_.back(); Frame &f = stack_.back();
if (f.kind == Kind::Skip) return;
SlotInfo si = slotInfoG(f); SlotInfo si = slotInfoG(f);
if (si.cat == Cat::Skip) {{ if (done) valueComplete(); return; }}
if (si.cat != Cat::Int && si.cat != Cat::Dbl) {{ reject(); return; }} if (si.cat != Cat::Int && si.cat != Cat::Dbl) {{ reject(); return; }}
scratch_.append(buf, len); scratch_.append(buf, len);
started_ = true; started_ = true;
@@ -1074,16 +1142,11 @@ private:
*(int64_t *)p = v; // plain integer literal: parsed exactly *(int64_t *)p = v; // plain integer literal: parsed exactly
}} else {{ }} else {{
// JSON Schema "integer" accepts any number with no fractional part, // JSON Schema "integer" accepts any number with no fractional part,
// including exponent/decimal forms like 1e3 or 2.0. Parse those as a // including exponent/decimal forms like 1e3 or 2.0. Parse those
// double and require an integral value within int64 range. // exactly as int64 when the value is integral and in range.
double d = 0; int64_t v2 = 0;
auto rd = std::from_chars(b, e, d); if (!parseJsonInt64(b, e, v2)) {{ reject(); return; }}
if (rd.ec != std::errc() || rd.ptr != e || d != std::trunc(d) || *(int64_t *)p = v2;
d < -9223372036854775808.0 || d >= 9223372036854775808.0) {{
reject();
return;
}}
*(int64_t *)p = (int64_t)d;
}} }}
}} else {{ }} else {{
double v = 0; double v = 0;
@@ -1096,10 +1159,9 @@ private:
void cbBool(bool value) {{ void cbBool(bool value) {{
if (error_) return; if (error_) return;
if (stack_.empty()) {{ reject(); return; }}
Frame &f = stack_.back(); Frame &f = stack_.back();
if (f.kind == Kind::Skip) return;
SlotInfo si = slotInfoG(f); SlotInfo si = slotInfoG(f);
if (si.cat == Cat::Skip) {{ valueComplete(); return; }}
if (si.cat != Cat::Bool) {{ reject(); return; }} if (si.cat != Cat::Bool) {{ reject(); return; }}
*(bool *)engage(f, true) = value; *(bool *)engage(f, true) = value;
valueComplete(); valueComplete();
@@ -1115,9 +1177,7 @@ private:
{null_at_root} {null_at_root}
}} }}
Frame &f = stack_.back(); Frame &f = stack_.back();
if (f.kind == Kind::Skip) return;
SlotInfo si = slotInfoG(f); SlotInfo si = slotInfoG(f);
if (si.cat == Cat::Skip) {{ valueComplete(); return; }}
if (!si.nullable) {{ reject(); return; }} if (!si.nullable) {{ reject(); return; }}
if (isArrayKind(f.kind)) appendNull(f); // keep null array elements if (isArrayKind(f.kind)) appendNull(f); // keep null array elements
valueComplete(); // leave optional empty / pointer null valueComplete(); // leave optional empty / pointer null
@@ -1155,8 +1215,6 @@ private:
{self._reqmask()} {self._reqmask()}
{self._is_object_kind()} {self._is_object_kind()}
{self._is_strict()}
}}; }};
""" """
@@ -0,0 +1 @@
"d\ud82d\udd9c8\ud8ed
@@ -0,0 +1,43 @@
[4,[5,[5,[4,[6,[5,[5,55,5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[5,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[5,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[[[[5,5,[5,[5,[[null,[461,[[5,[5,[415,4,5,[[5,5,[5,[5,[[null,5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[␍[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-41,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[[[[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-.41.8,[8,[7,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[5,[5,[[null,5,[1.0e+9, ""[[{},{}:0 -1.0e028 },[[false, [[false, [[[{},8,
@@ -0,0 +1 @@
[[[{ "min":-6.8, "in":-6.8, "in": -6, "Umin": -6.8, "m":-6.4, "max": 1, "mij": -6.8," ": -6.8, "UUaxax": 1, "mij": -6.8," ": -6.8, "UUax":-6.8, "Tin":-6.8, "mUUUax":-6.8, "maxn":-6.8, "in": -6, "Umin": -6.8, "m":-6.4, "max": 1, "mij": -6.8," ": -6.8, "UUax":-6.8, "Tin":-6.8, "mUUUax":-6.8, "max": -6.8, "min":-6.8, "mUax":-6.8, "man": -6, "mUmin": -6.8, "mi": -6, "Umx":-6.8, "Tin":-6.8, "mUUUax":-6.8, "maxn":-6.8, "in": -6, "Umin": -6.8, "m":-6.4, "max": 1, "mij": -6.8," ": -6.8, "UUax":-6.8, "Tin":-6.8, "mUUUax":-6.8, "max": -6.8, "min":-6.8, "mUax":-6.8, "man": -6, "mUmin": -6.8, "mi": -6, "Umin": -6.8, "m":-6.4, "max": 1, "mij": -6.8," ": -6.8, "UUaxin": -6, "Umin": -6.8, "m":-6.4, 1,334en":-5e556.8, "n": -6
@@ -0,0 +1 @@
["\uDA9D\uDDDDux\uDA9D\uDDDdDux\uDA9D\uDDDduxux\uDA9D\uDDDdDDDux\uDA9D\uDDDeu|\uDA9D\uDDDDDDux\uDA9D\uDDDdDDADDDux\uDA9D\uDDDduxux\uDA9D\uDDDdD\uDA9D\uDDDduuDDA9D\uDA9D\uDDDDD-ux\uDA9D\uDDDdDDAuDDDDDDDux\uDA9D\uDDDduxux\uDA9D\uDDDdDux\uDA0D\uDDDdu|DDux\uDA9D\uDDDddDDDDDux\uDA9D\uDDDduxux\uDA9D\uDDDdDux\uDA9D\uDDDdu|DDux\uDA9D\uDDDddDDux\uDA9D\uDDDdu|\uDA4D\uDDA9D\u³D\uDA9D\uDDDDDDDDD\uDA9D\uDDDduxu\uDA9D\uDDDd:DEux\uDA9D\uDDDdDux\uDA9DDDDux\uDA9D\uDDD­du|\uDA8D\uDDDDDDDDux\uDA9D\uDDDddDDDx\uDA9D\uDDDd\uDA4D\uDDA0DDDux\uDA9D\uDDDdDDA0
@@ -0,0 +1,27 @@
[15,4,5,[[5,5,[4,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[5,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,4,[5,[5,[4,[6,[5,[54,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,-418,[8,[[[
[[-41.8,␍␍[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,28,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[[5,2,[5,[5,[[null,[413,[[5,[5,[415,4,5,[[5,5,[5,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[5,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[ "\
@@ -0,0 +1,56 @@
[[[{},{}, [[[{},{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},3,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[7,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, 8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[8,[8,[8,
[[-41.8,[-41.8,{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[7,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[ [-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-20,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-417.777E-8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ { "$i": 9, "max": 8, "x": 2.0e+28,[[false, [[false, "8[[-418,[8,[4,[5,[5,[4,[6 8, "man": -3.8, "max": 8, "max": 8, "man": ,[ššššššššššš5,5, 5,[5,max
@@ -0,0 +1,54 @@
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{},{}, [[[{},{},[[[[{},{}, [[[{},{},[5,[[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,5,4,[5,[5,[4,[6,[5,[5,55,5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[4,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[{"x":[{"id": "xx"}],"x":[{"d":"x"}],""J:"xx"}],,[5,[[5,[4,5[[,5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[462,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,4,[5,[5,[5,ž,[5,[5,[[5,[5,[415,[4,[5,[5,[[5,(((((((((((((((((((((((((((((((((((((((((((((((((((((([[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[4,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[[55,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[4,[5,[[null,5,[5,[5,[[5,[5,[415,[4,
[[[[[false, [[f[
4
"p{ },,[5[
[
[{ },[[[6[
]ue,true,[ true,[[-41,[-,[5[[[[[[true,t[,[5rue,[ true,true, true,[[[[[[[[[[ true,true,[[ true,true,[41,,[ true,pr]]]
@@ -0,0 +1,54 @@
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,4,[5,[5,[4,[6,[5,[5,55,5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[4,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,4,[5,[5,[4,[6,[5,[5,55,5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[4,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[{"x":[{"id": {";;" : -8,"8[-5,[-5,5,[-5,5,[-" : 8,"" : -8,"" : -8,"8" : -8,"8;" : -8,"8" : 8,"" : -8,"8[-5,[-5,5,[-5,5,[-" : 8,"" : -8,"" : -8,"8" : -8,"8;" : -8,"8" : 8,"" : -8,"8" :-8,"8" : 8,"" : -8,"" : "" :",5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,4,[5,[5,[5,ž,[5,[5,[[5,[5,[415,[4,[5,[5,[[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[5,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,4,[5,[5,[4,[6,[5,[5,55,5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[4,[5,[[null,5,[5,[5,[[5,[5,[415,[4,
[[[[[false, [[f[
4
"p{ },,[5[
[
[{ },[[[6[
][-41,[-,[5[,[5,[41,
@@ -0,0 +1 @@
"\uDBFF\zFEFF
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -0,0 +1,55 @@
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{},{}, [[[{},{},[[[[{},{}, [[[{},{},[5,[[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[{"x":[{"id": "xx"}],"x":[{"d":"x"}],"":"xx"}],,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,4,[5,[5,[5,ž,[5,[5,[[5,[5,[415,[4,[5,[5,[[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5[[[[[[[[[[[
[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[5,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,4,[5,[5,[4,[6,[5,[5,55,5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[4,[5,[[null,5,[5,[5,[[5,[5,[415,[4,
[[[[[false, [[f[
4
"p{ },,[5[
[
[{ },[[[6[
][-41,[-,[5[,[5,[41,
@@ -0,0 +1 @@
{"title":"\u041e\ud41d41d\ud82d\udd29\4d9cu0430 \u;a 4 \u03
@@ -0,0 +1,71 @@
[[[{},{}, [[[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,8,[[1.8,[3,[8,[[[[ [[[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ 8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-417,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[0.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[["\uDA9D\uDDDDux\uDA9D^uDDDdux\uDA9D\uDDA9D\uDA9D\DDDD[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[[
[[-418,[8,[[[
[[-41,[[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1Dux9D\uDA9D\uDDDDDD*x¤Ý¤Ò-ËŠ\u18,DA9D\uDDdDDA0
@@ -0,0 +1,160 @@
[[[{},{}, [[[{},{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222241.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[7,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[0,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,8,[8,[8,[[[[[-41.8,[7E-5,7E-5,3E8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[0,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,8,[8,[8,[[[[[-41.8,[7E-5,7E-5,3E8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222241.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[7,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[0,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,8,[8,[8,[[[[[-41.8,[7E-5,7E-5,3E8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[0,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,8,[8,[8,[[[[[-41.8,[7E-5,7E-5,3E8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{
}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-20.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[
-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[ [[[ [[-41.8,[3,[8,[[,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222241.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[7,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{
}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-20.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[
-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418[[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false,"\@d83d\u34e55,335223334e55,33e5,334e55,3e5,39990.099999de55,e3339\ud
@@ -0,0 +1,54 @@
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{},{}, [[[{},{},[[[[{},{}, [[[{},{},[5,[[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[95,[5,[4,5,[5,5,[[[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[5,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[[[[[[[[[[[[[[[[[[[[[[[[[[{"a0.000000+0000000000000000000000000sd":"s1f", "dfg0000000000000d":"s1f", "d0g00000000000000sd":"s1f", "dff[[[[[[[[[[[[[[[[[0sd":"s1f", "dff[[[[[000000000000000sd":"G1f", "dfg00000000040000sd":"s1f", "d]]]null,[415,[4,[5,[5,[4,5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,4,[5,[5,[4,[6,[5,[5,55,5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[4,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,[5,[5]]]]]]]]]]]]]]]]]]]]]]]](]]]]]]]]]]]]]]]]]]]]0]]]]]]000sd":"s1f", "dfg00000000000000sd":,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5"sÌ™,[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5415,[4,[5,[[5,[4,[5,[5,4,[5,[5,[4,[6,[5,[5,55,5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[ÝÓ5,[3,[5,5,[5,[5,[[n "0ÿ"fg"]]ull,[415,[[5,[5,[415,4,5,[[5,5,[4,[5,[[null,5,[5,[5,[[5,[5,[415,[4,
[[[[[false, [[f[
4
"p{ },,[5[
[
[{ },[[[6[
][-41,[-,[5[,[5,[41",:]
@@ -0,0 +1,62 @@
{";N" :[[[{},{}, [[[{},{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[3,[8,[[[ 8, [ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[faf
@@ -0,0 +1 @@
"\uDA8D\tD]{DDD
@@ -0,0 +1,42 @@
[4,[5,[5,[4,[6,[5,[5,55,5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[5,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[5,[5,[[null,5,[5,[5,[[5,[5,[415,[4,[5,[5,[3,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[413,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[[5,[4,[5,[5,[5,5,[5,[5,[[5,[5,[415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[[[[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,5,[5,[5,[[null,5,[5,[5,5,[5,[5,[[5,[5,[3415,[4,[5,[5,[4,[5,[5,[5,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[5,5,[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[␍[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-41,5,[[5,[4,[5,[[5,5,[5,[5,[[null,[415,[4,[5,[5,[4,5,[[[[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[4,[5,[5,[4,5,[[[[5,5,[5,[5,[[null,[415,[[5,[5,[415,4,5,[[5,[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [{ "min":1.0e+9, ""[[{},{}:0 -1.0e020 },[[false, [[false, [[[{},8,
File diff suppressed because one or more lines are too long
@@ -0,0 +1,71 @@
[[[{},{}, [[[{},{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,8,[[1.8,[3,[8,[[[[ [[[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ 8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{},[[[{},8,[[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[8,
[[-41.8,[-41.8,[8,[8,8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[-418,[8,[[[
[[-41.8,[8,[8,␍9777E-1,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[83,6663,66666666,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[[[[[[-41.8,[83,666377777777777, 777728273720, 1, "1", 77777777, 1, "1", 77, 677777777777777777777777777777777777, 1, "1", 7738888888888, 1, "1", 67731, "1-", 7777777777777, 1,7777777777777777777, 1, "1", 7777777, "1", 77, 677777777777777777777777777777777777, 1, 77777777777, 1, "1", 7738888888888, 1, "1",7777777, 7777777777, 777728273720, 1, "1", 777777777777777, ,66666666,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[[
[[-418,[8,[[[
[[-41,[[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
["[-Ò418,
@@ -0,0 +1 @@
{"":"_________..............................._____________@@@@ffa\udafa\udffa2fa[-401.
@@ -0,0 +1,101 @@
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[[[
{"":
5
,[8,
[[-41.8,[-41.8,[8,[8,
[[[[[false, [[f[
4
"p{ },[
[
[{ },[[[6[
][-41,[-[
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
"de39\ud83dLudœ8
@@ -0,0 +1,62 @@
[[[{},{}, [[[{},{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[7,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[-418,[8,[[[
[[-41.8,[8,[8,␍9777E-1,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},2,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[8,[8,[[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[7,[[[[41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,[[[[[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-20.8,[8,[8,[[1.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41,{},[[false, [[false, [[[{},8,[-41.8,[8,[8,[[[[[-41.8,[8,[8,[[[[ [[[ [[-41.8,[3,[8,[[[[ [[[
[[-418,[8,[[[
[[-41.8,[8,[8,
[[-41.8,[-41.8,[8,[8,1.8,[-41.8,[8,[
[[-418,[8,[[[[[[-41.8,[8,[8,[[[[ [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, [[[{},8,[-41.8,[8,[8.8,[8,[[[{},{}, [[[{},{},[[false, [[false, [[[{},8, [[[
[[-41,{},[[[[{},{}, [[[{},{},[[false, [[false, "ffa2ffa\udafa\udffad@faa\udff41.8,[8,[8,[[[
[8{},[-[
+6
View File
@@ -29,11 +29,17 @@ WeaselJsonParser_create(int stackSize, const WeaselJsonCallbacks *callbacks,
__attribute__((visibility("default"))) void __attribute__((visibility("default"))) void
WeaselJsonParser_reset(WeaselJsonParser *parser) { WeaselJsonParser_reset(WeaselJsonParser *parser) {
if (parser == nullptr) {
return;
}
((Parser3 *)parser)->reset(); ((Parser3 *)parser)->reset();
} }
__attribute__((visibility("default"))) void __attribute__((visibility("default"))) void
WeaselJsonParser_destroy(WeaselJsonParser *parser) { WeaselJsonParser_destroy(WeaselJsonParser *parser) {
if (parser == nullptr) {
return;
}
((Parser3 *)parser)->~Parser3(); ((Parser3 *)parser)->~Parser3();
free(parser); free(parser);
} }
+8 -2
View File
@@ -625,7 +625,7 @@ inline PRESERVE_NONE ContinuationStatus n_string2(Parser3 *self, char *buf,
return WeaselJson_REJECT; return WeaselJson_REJECT;
} }
buf += 4; buf += 4;
if (0xd800 <= codepoint && codepoint <= 0xdfff) { if (0xd800 <= codepoint && codepoint <= 0xdbff) {
// utf-16 surrogate // utf-16 surrogate
int32_t codepoint2 = read4_hex(buf + 2); int32_t codepoint2 = read4_hex(buf + 2);
if (!(buf[0] == '\\' && buf[1] == 'u' && 0xdc00 <= codepoint2 && if (!(buf[0] == '\\' && buf[1] == 'u' && 0xdc00 <= codepoint2 &&
@@ -650,6 +650,8 @@ inline PRESERVE_NONE ContinuationStatus n_string2(Parser3 *self, char *buf,
self->writeBuf[0] = (0b00000111 & codepoint) | 0b11110000; self->writeBuf[0] = (0b00000111 & codepoint) | 0b11110000;
self->writeBuf += 4; self->writeBuf += 4;
} }
} else if (0xdc00 <= codepoint && codepoint <= 0xdfff) {
return WeaselJson_REJECT;
} else { } else {
if (!(self->flags & WeaselJsonRaw)) { if (!(self->flags & WeaselJsonRaw)) {
if (codepoint < 0x80) { if (codepoint < 0x80) {
@@ -793,7 +795,7 @@ inline PRESERVE_NONE ContinuationStatus t_hex2(Parser3 *self, char *buf,
} }
} else { } else {
assert(self->utf8Codepoint < 0x10000); assert(self->utf8Codepoint < 0x10000);
if (0xd800 <= self->utf8Codepoint && self->utf8Codepoint <= 0xdfff) { if (0xd800 <= self->utf8Codepoint && self->utf8Codepoint <= 0xdbff) {
// utf-16 surrogate // utf-16 surrogate
self->utf16Surrogate = self->utf8Codepoint; self->utf16Surrogate = self->utf8Codepoint;
self->utf8Codepoint = 0; self->utf8Codepoint = 0;
@@ -808,6 +810,10 @@ inline PRESERVE_NONE ContinuationStatus t_hex2(Parser3 *self, char *buf,
} }
MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd);
} }
if (0xdc00 <= self->utf8Codepoint && self->utf8Codepoint <= 0xdfff)
[[unlikely]] {
return WeaselJson_REJECT;
}
if (!(self->flags & WeaselJsonRaw)) { if (!(self->flags & WeaselJsonRaw)) {
bool useTmp = buf - self->writeBuf < 3; bool useTmp = buf - self->writeBuf < 3;
char *p = tmp; char *p = tmp;
+14
View File
@@ -246,6 +246,20 @@ TEST_CASE("create rejects too-small stack") {
WeaselJsonParser_destroy(parser); WeaselJsonParser_destroy(parser);
} }
TEST_CASE("reset and destroy accept null parser") {
// Creation can legitimately fail and return null. The cleanup functions must
// tolerate a null pointer the same way free(nullptr) is a no-op.
auto c = noopCallbacks();
WeaselJsonParser *parser = WeaselJsonParser_create(-1, &c, nullptr, 0);
REQUIRE(parser == nullptr);
WeaselJsonParser_reset(parser); // must not crash
WeaselJsonParser_destroy(parser); // must not crash
// Calling reset/destroy on literal nullptr directly must also be safe.
WeaselJsonParser_reset(nullptr);
WeaselJsonParser_destroy(nullptr);
}
TEST_CASE("parse rejects negative length") { TEST_CASE("parse rejects negative length") {
auto c = noopCallbacks(); auto c = noopCallbacks();
auto *parser = WeaselJsonParser_create(1024, &c, nullptr, 0); auto *parser = WeaselJsonParser_create(1024, &c, nullptr, 0);