Skip to content

Commit f4129ac

Browse files
authored
Don't create a whole category for "enum" data types (#844)
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent c9743d0 commit f4129ac

File tree

14 files changed

+705
-739
lines changed

14 files changed

+705
-739
lines changed

src/runtime/decoder_common.cc

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,19 @@ auto Decoder::read(const Encoding &encoding) -> sourcemeta::jsontoolkit::JSON {
2323
HANDLE_DECODING(6, LARGE_CHOICE_INDEX)
2424
HANDLE_DECODING(7, TOP_LEVEL_BYTE_CHOICE_INDEX)
2525
HANDLE_DECODING(8, CONST_NONE)
26-
HANDLE_DECODING(9, UTF8_STRING_NO_LENGTH)
27-
HANDLE_DECODING(10, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED)
28-
HANDLE_DECODING(11, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED)
29-
HANDLE_DECODING(12, BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED)
30-
HANDLE_DECODING(13, RFC3339_DATE_INTEGER_TRIPLET)
31-
HANDLE_DECODING(14, PREFIX_VARINT_LENGTH_STRING_SHARED)
32-
HANDLE_DECODING(15, FIXED_TYPED_ARRAY)
33-
HANDLE_DECODING(16, BOUNDED_8BITS_TYPED_ARRAY)
34-
HANDLE_DECODING(17, FLOOR_TYPED_ARRAY)
35-
HANDLE_DECODING(18, ROOF_TYPED_ARRAY)
36-
HANDLE_DECODING(19, FIXED_TYPED_ARBITRARY_OBJECT)
37-
HANDLE_DECODING(20, VARINT_TYPED_ARBITRARY_OBJECT)
38-
HANDLE_DECODING(21, ANY_PACKED_TYPE_TAG_BYTE_PREFIX)
26+
HANDLE_DECODING(9, ANY_PACKED_TYPE_TAG_BYTE_PREFIX)
27+
HANDLE_DECODING(10, UTF8_STRING_NO_LENGTH)
28+
HANDLE_DECODING(11, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED)
29+
HANDLE_DECODING(12, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED)
30+
HANDLE_DECODING(13, BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED)
31+
HANDLE_DECODING(14, RFC3339_DATE_INTEGER_TRIPLET)
32+
HANDLE_DECODING(15, PREFIX_VARINT_LENGTH_STRING_SHARED)
33+
HANDLE_DECODING(16, FIXED_TYPED_ARRAY)
34+
HANDLE_DECODING(17, BOUNDED_8BITS_TYPED_ARRAY)
35+
HANDLE_DECODING(18, FLOOR_TYPED_ARRAY)
36+
HANDLE_DECODING(19, ROOF_TYPED_ARRAY)
37+
HANDLE_DECODING(20, FIXED_TYPED_ARBITRARY_OBJECT)
38+
HANDLE_DECODING(21, VARINT_TYPED_ARBITRARY_OBJECT)
3939
#undef HANDLE_DECODING
4040
}
4141

src/runtime/encoder_common.cc

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,19 @@ auto Encoder::write(const sourcemeta::jsontoolkit::JSON &document,
2525
HANDLE_ENCODING(6, LARGE_CHOICE_INDEX)
2626
HANDLE_ENCODING(7, TOP_LEVEL_BYTE_CHOICE_INDEX)
2727
HANDLE_ENCODING(8, CONST_NONE)
28-
HANDLE_ENCODING(9, UTF8_STRING_NO_LENGTH)
29-
HANDLE_ENCODING(10, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED)
30-
HANDLE_ENCODING(11, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED)
31-
HANDLE_ENCODING(12, BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED)
32-
HANDLE_ENCODING(13, RFC3339_DATE_INTEGER_TRIPLET)
33-
HANDLE_ENCODING(14, PREFIX_VARINT_LENGTH_STRING_SHARED)
34-
HANDLE_ENCODING(15, FIXED_TYPED_ARRAY)
35-
HANDLE_ENCODING(16, BOUNDED_8BITS_TYPED_ARRAY)
36-
HANDLE_ENCODING(17, FLOOR_TYPED_ARRAY)
37-
HANDLE_ENCODING(18, ROOF_TYPED_ARRAY)
38-
HANDLE_ENCODING(19, FIXED_TYPED_ARBITRARY_OBJECT)
39-
HANDLE_ENCODING(20, VARINT_TYPED_ARBITRARY_OBJECT)
40-
HANDLE_ENCODING(21, ANY_PACKED_TYPE_TAG_BYTE_PREFIX)
28+
HANDLE_ENCODING(9, ANY_PACKED_TYPE_TAG_BYTE_PREFIX)
29+
HANDLE_ENCODING(10, UTF8_STRING_NO_LENGTH)
30+
HANDLE_ENCODING(11, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED)
31+
HANDLE_ENCODING(12, ROOF_VARINT_PREFIX_UTF8_STRING_SHARED)
32+
HANDLE_ENCODING(13, BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED)
33+
HANDLE_ENCODING(14, RFC3339_DATE_INTEGER_TRIPLET)
34+
HANDLE_ENCODING(15, PREFIX_VARINT_LENGTH_STRING_SHARED)
35+
HANDLE_ENCODING(16, FIXED_TYPED_ARRAY)
36+
HANDLE_ENCODING(17, BOUNDED_8BITS_TYPED_ARRAY)
37+
HANDLE_ENCODING(18, FLOOR_TYPED_ARRAY)
38+
HANDLE_ENCODING(19, ROOF_TYPED_ARRAY)
39+
HANDLE_ENCODING(20, FIXED_TYPED_ARBITRARY_OBJECT)
40+
HANDLE_ENCODING(21, VARINT_TYPED_ARBITRARY_OBJECT)
4141
#undef HANDLE_ENCODING
4242
}
4343

src/runtime/include/sourcemeta/jsonbinpack/runtime_encoding.h

Lines changed: 58 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct BYTE_CHOICE_INDEX;
2424
struct LARGE_CHOICE_INDEX;
2525
struct TOP_LEVEL_BYTE_CHOICE_INDEX;
2626
struct CONST_NONE;
27+
struct ANY_PACKED_TYPE_TAG_BYTE_PREFIX;
2728
struct UTF8_STRING_NO_LENGTH;
2829
struct FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED;
2930
struct ROOF_VARINT_PREFIX_UTF8_STRING_SHARED;
@@ -36,7 +37,6 @@ struct FLOOR_TYPED_ARRAY;
3637
struct ROOF_TYPED_ARRAY;
3738
struct FIXED_TYPED_ARBITRARY_OBJECT;
3839
struct VARINT_TYPED_ARBITRARY_OBJECT;
39-
struct ANY_PACKED_TYPE_TAG_BYTE_PREFIX;
4040
#endif
4141

4242
/// @ingroup runtime
@@ -45,14 +45,13 @@ using Encoding = std::variant<
4545
BOUNDED_MULTIPLE_8BITS_ENUM_FIXED, FLOOR_MULTIPLE_ENUM_VARINT,
4646
ROOF_MULTIPLE_MIRROR_ENUM_VARINT, ARBITRARY_MULTIPLE_ZIGZAG_VARINT,
4747
DOUBLE_VARINT_TUPLE, BYTE_CHOICE_INDEX, LARGE_CHOICE_INDEX,
48-
TOP_LEVEL_BYTE_CHOICE_INDEX, CONST_NONE, UTF8_STRING_NO_LENGTH,
49-
FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED,
48+
TOP_LEVEL_BYTE_CHOICE_INDEX, CONST_NONE, ANY_PACKED_TYPE_TAG_BYTE_PREFIX,
49+
UTF8_STRING_NO_LENGTH, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED,
5050
ROOF_VARINT_PREFIX_UTF8_STRING_SHARED,
5151
BOUNDED_8BIT_PREFIX_UTF8_STRING_SHARED, RFC3339_DATE_INTEGER_TRIPLET,
5252
PREFIX_VARINT_LENGTH_STRING_SHARED, FIXED_TYPED_ARRAY,
5353
BOUNDED_8BITS_TYPED_ARRAY, FLOOR_TYPED_ARRAY, ROOF_TYPED_ARRAY,
54-
FIXED_TYPED_ARBITRARY_OBJECT, VARINT_TYPED_ARBITRARY_OBJECT,
55-
ANY_PACKED_TYPE_TAG_BYTE_PREFIX>;
54+
FIXED_TYPED_ARBITRARY_OBJECT, VARINT_TYPED_ARBITRARY_OBJECT>;
5655

5756
/// @ingroup runtime
5857
/// @defgroup encoding_integer Integer Encodings
@@ -260,7 +259,7 @@ struct DOUBLE_VARINT_TUPLE {};
260259
/// @}
261260

262261
/// @ingroup runtime
263-
/// @defgroup encoding_enum Enumeration Encodings
262+
/// @defgroup encoding_any Any Encodings
264263
/// @{
265264

266265
// clang-format off
@@ -401,6 +400,59 @@ struct CONST_NONE {
401400
const sourcemeta::jsontoolkit::JSON value;
402401
};
403402

403+
// TODO: Write brief description
404+
struct ANY_PACKED_TYPE_TAG_BYTE_PREFIX {};
405+
#ifndef DOXYGEN
406+
namespace internal::ANY_PACKED_TYPE_TAG_BYTE_PREFIX {
407+
constexpr auto type_size = 3;
408+
constexpr std::uint8_t TYPE_SHARED_STRING = 0b00000000;
409+
constexpr std::uint8_t TYPE_STRING = 0b00000001;
410+
constexpr std::uint8_t TYPE_LONG_STRING = 0b00000010;
411+
constexpr std::uint8_t TYPE_OBJECT = 0b00000011;
412+
constexpr std::uint8_t TYPE_ARRAY = 0b00000100;
413+
constexpr std::uint8_t TYPE_POSITIVE_INTEGER_BYTE = 0b00000101;
414+
constexpr std::uint8_t TYPE_NEGATIVE_INTEGER_BYTE = 0b00000110;
415+
constexpr std::uint8_t TYPE_OTHER = 0b00000111;
416+
static_assert(TYPE_SHARED_STRING <= uint_max<type_size>);
417+
static_assert(TYPE_STRING <= uint_max<type_size>);
418+
static_assert(TYPE_LONG_STRING <= uint_max<type_size>);
419+
static_assert(TYPE_OBJECT <= uint_max<type_size>);
420+
static_assert(TYPE_ARRAY <= uint_max<type_size>);
421+
static_assert(TYPE_POSITIVE_INTEGER_BYTE <= uint_max<type_size>);
422+
static_assert(TYPE_NEGATIVE_INTEGER_BYTE <= uint_max<type_size>);
423+
static_assert(TYPE_OTHER <= uint_max<type_size>);
424+
425+
constexpr auto subtype_size = 5;
426+
constexpr std::uint8_t SUBTYPE_FALSE = 0b00000000;
427+
constexpr std::uint8_t SUBTYPE_TRUE = 0b00000001;
428+
constexpr std::uint8_t SUBTYPE_NULL = 0b00000010;
429+
constexpr std::uint8_t SUBTYPE_POSITIVE_INTEGER = 0b00000011;
430+
constexpr std::uint8_t SUBTYPE_NEGATIVE_INTEGER = 0b00000100;
431+
constexpr std::uint8_t SUBTYPE_NUMBER = 0b00000101;
432+
constexpr std::uint8_t SUBTYPE_LONG_STRING_BASE_EXPONENT_7 = 0b00000111;
433+
constexpr std::uint8_t SUBTYPE_LONG_STRING_BASE_EXPONENT_8 = 0b00001000;
434+
constexpr std::uint8_t SUBTYPE_LONG_STRING_BASE_EXPONENT_9 = 0b00001001;
435+
constexpr std::uint8_t SUBTYPE_LONG_STRING_BASE_EXPONENT_10 = 0b00001010;
436+
437+
static_assert(SUBTYPE_FALSE <= uint_max<subtype_size>);
438+
static_assert(SUBTYPE_TRUE <= uint_max<subtype_size>);
439+
static_assert(SUBTYPE_NULL <= uint_max<subtype_size>);
440+
static_assert(SUBTYPE_POSITIVE_INTEGER <= uint_max<subtype_size>);
441+
static_assert(SUBTYPE_NEGATIVE_INTEGER <= uint_max<subtype_size>);
442+
static_assert(SUBTYPE_NUMBER <= uint_max<subtype_size>);
443+
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_7 <= uint_max<subtype_size>);
444+
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_8 <= uint_max<subtype_size>);
445+
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_9 <= uint_max<subtype_size>);
446+
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_10 <= uint_max<subtype_size>);
447+
448+
// Note that the binary values actually match the declared exponents
449+
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_7 == 7);
450+
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_8 == 8);
451+
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_9 == 9);
452+
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_10 == 10);
453+
} // namespace internal::ANY_PACKED_TYPE_TAG_BYTE_PREFIX
454+
#endif
455+
404456
/// @}
405457

406458
/// @ingroup runtime
@@ -987,66 +1039,6 @@ struct VARINT_TYPED_ARBITRARY_OBJECT {
9871039

9881040
/// @}
9891041

990-
/// @ingroup runtime
991-
/// @defgroup encoding_any Any Encodings
992-
/// @{
993-
994-
// TODO: Write brief description
995-
struct ANY_PACKED_TYPE_TAG_BYTE_PREFIX {};
996-
#ifndef DOXYGEN
997-
namespace internal::ANY_PACKED_TYPE_TAG_BYTE_PREFIX {
998-
constexpr auto type_size = 3;
999-
constexpr std::uint8_t TYPE_SHARED_STRING = 0b00000000;
1000-
constexpr std::uint8_t TYPE_STRING = 0b00000001;
1001-
constexpr std::uint8_t TYPE_LONG_STRING = 0b00000010;
1002-
constexpr std::uint8_t TYPE_OBJECT = 0b00000011;
1003-
constexpr std::uint8_t TYPE_ARRAY = 0b00000100;
1004-
constexpr std::uint8_t TYPE_POSITIVE_INTEGER_BYTE = 0b00000101;
1005-
constexpr std::uint8_t TYPE_NEGATIVE_INTEGER_BYTE = 0b00000110;
1006-
constexpr std::uint8_t TYPE_OTHER = 0b00000111;
1007-
static_assert(TYPE_SHARED_STRING <= uint_max<type_size>);
1008-
static_assert(TYPE_STRING <= uint_max<type_size>);
1009-
static_assert(TYPE_LONG_STRING <= uint_max<type_size>);
1010-
static_assert(TYPE_OBJECT <= uint_max<type_size>);
1011-
static_assert(TYPE_ARRAY <= uint_max<type_size>);
1012-
static_assert(TYPE_POSITIVE_INTEGER_BYTE <= uint_max<type_size>);
1013-
static_assert(TYPE_NEGATIVE_INTEGER_BYTE <= uint_max<type_size>);
1014-
static_assert(TYPE_OTHER <= uint_max<type_size>);
1015-
1016-
constexpr auto subtype_size = 5;
1017-
constexpr std::uint8_t SUBTYPE_FALSE = 0b00000000;
1018-
constexpr std::uint8_t SUBTYPE_TRUE = 0b00000001;
1019-
constexpr std::uint8_t SUBTYPE_NULL = 0b00000010;
1020-
constexpr std::uint8_t SUBTYPE_POSITIVE_INTEGER = 0b00000011;
1021-
constexpr std::uint8_t SUBTYPE_NEGATIVE_INTEGER = 0b00000100;
1022-
constexpr std::uint8_t SUBTYPE_NUMBER = 0b00000101;
1023-
constexpr std::uint8_t SUBTYPE_LONG_STRING_BASE_EXPONENT_7 = 0b00000111;
1024-
constexpr std::uint8_t SUBTYPE_LONG_STRING_BASE_EXPONENT_8 = 0b00001000;
1025-
constexpr std::uint8_t SUBTYPE_LONG_STRING_BASE_EXPONENT_9 = 0b00001001;
1026-
constexpr std::uint8_t SUBTYPE_LONG_STRING_BASE_EXPONENT_10 = 0b00001010;
1027-
1028-
static_assert(SUBTYPE_FALSE <= uint_max<subtype_size>);
1029-
static_assert(SUBTYPE_TRUE <= uint_max<subtype_size>);
1030-
static_assert(SUBTYPE_NULL <= uint_max<subtype_size>);
1031-
static_assert(SUBTYPE_POSITIVE_INTEGER <= uint_max<subtype_size>);
1032-
static_assert(SUBTYPE_NEGATIVE_INTEGER <= uint_max<subtype_size>);
1033-
static_assert(SUBTYPE_NUMBER <= uint_max<subtype_size>);
1034-
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_7 <= uint_max<subtype_size>);
1035-
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_8 <= uint_max<subtype_size>);
1036-
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_9 <= uint_max<subtype_size>);
1037-
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_10 <= uint_max<subtype_size>);
1038-
1039-
// Note that the binary values actually match the declared exponents
1040-
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_7 == 7);
1041-
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_8 == 8);
1042-
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_9 == 9);
1043-
static_assert(SUBTYPE_LONG_STRING_BASE_EXPONENT_10 == 10);
1044-
} // namespace internal::ANY_PACKED_TYPE_TAG_BYTE_PREFIX
1045-
#endif
1046-
1047-
/// @}
1048-
// clang-format on
1049-
10501042
} // namespace sourcemeta::jsonbinpack
10511043

10521044
#endif

src/runtime/loader.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@ auto load(const sourcemeta::jsontoolkit::JSON &input) -> Encoding {
2929
PARSE_ENCODING(v1, ARBITRARY_MULTIPLE_ZIGZAG_VARINT)
3030
// Numbers
3131
PARSE_ENCODING(v1, DOUBLE_VARINT_TUPLE)
32-
// Enumerations
32+
// Any
3333
PARSE_ENCODING(v1, BYTE_CHOICE_INDEX)
3434
PARSE_ENCODING(v1, LARGE_CHOICE_INDEX)
3535
PARSE_ENCODING(v1, TOP_LEVEL_BYTE_CHOICE_INDEX)
3636
PARSE_ENCODING(v1, CONST_NONE)
37+
PARSE_ENCODING(v1, ANY_PACKED_TYPE_TAG_BYTE_PREFIX)
3738
// Strings
3839
PARSE_ENCODING(v1, UTF8_STRING_NO_LENGTH)
3940
PARSE_ENCODING(v1, FLOOR_VARINT_PREFIX_UTF8_STRING_SHARED)
@@ -46,9 +47,8 @@ auto load(const sourcemeta::jsontoolkit::JSON &input) -> Encoding {
4647
PARSE_ENCODING(v1, BOUNDED_8BITS_TYPED_ARRAY)
4748
PARSE_ENCODING(v1, FLOOR_TYPED_ARRAY)
4849
PARSE_ENCODING(v1, ROOF_TYPED_ARRAY)
50+
4951
// TODO: Handle object encodings
50-
// Any
51-
PARSE_ENCODING(v1, ANY_PACKED_TYPE_TAG_BYTE_PREFIX)
5252

5353
#undef PARSE_ENCODING
5454

test/compiler/2020_12_compiler_any_test.cc

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,69 @@
33
#include <sourcemeta/jsonbinpack/compiler.h>
44
#include <sourcemeta/jsontoolkit/json.h>
55

6+
TEST(JSONBinPack_Compiler_Any_2020_12, enum_singleton) {
7+
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
8+
"$schema": "https://json-schema.org/draft/2020-12/schema",
9+
"enum": [ 2 ]
10+
})JSON");
11+
12+
sourcemeta::jsonbinpack::compile(
13+
schema, sourcemeta::jsontoolkit::default_schema_walker,
14+
sourcemeta::jsontoolkit::official_resolver);
15+
16+
const auto expected = sourcemeta::jsontoolkit::parse(R"JSON({
17+
"$schema": "tag:sourcemeta.com,2024:jsonbinpack/encoding/v1",
18+
"binpackEncoding": "CONST_NONE",
19+
"binpackOptions": {
20+
"value": 2
21+
}
22+
})JSON");
23+
24+
EXPECT_EQ(schema, expected);
25+
}
26+
27+
TEST(JSONBinPack_Compiler_Any_2020_12, const_scalar) {
28+
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
29+
"$schema": "https://json-schema.org/draft/2020-12/schema",
30+
"const": 2
31+
})JSON");
32+
33+
sourcemeta::jsonbinpack::compile(
34+
schema, sourcemeta::jsontoolkit::default_schema_walker,
35+
sourcemeta::jsontoolkit::official_resolver);
36+
37+
const auto expected = sourcemeta::jsontoolkit::parse(R"JSON({
38+
"$schema": "tag:sourcemeta.com,2024:jsonbinpack/encoding/v1",
39+
"binpackEncoding": "CONST_NONE",
40+
"binpackOptions": {
41+
"value": 2
42+
}
43+
})JSON");
44+
45+
EXPECT_EQ(schema, expected);
46+
}
47+
48+
TEST(JSONBinPack_Compiler_Any_2020_12, enum_small_top_level) {
49+
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
50+
"$schema": "https://json-schema.org/draft/2020-12/schema",
51+
"enum": [ 1, 2, 3 ]
52+
})JSON");
53+
54+
sourcemeta::jsonbinpack::compile(
55+
schema, sourcemeta::jsontoolkit::default_schema_walker,
56+
sourcemeta::jsontoolkit::official_resolver);
57+
58+
const auto expected = sourcemeta::jsontoolkit::parse(R"JSON({
59+
"$schema": "tag:sourcemeta.com,2024:jsonbinpack/encoding/v1",
60+
"binpackEncoding": "TOP_LEVEL_BYTE_CHOICE_INDEX",
61+
"binpackOptions": {
62+
"choices": [ 1, 2, 3 ]
63+
}
64+
})JSON");
65+
66+
EXPECT_EQ(schema, expected);
67+
}
68+
669
TEST(JSONBinPack_Compiler_Any_2020_12, only_metaschema) {
770
auto schema = sourcemeta::jsontoolkit::parse(R"JSON({
871
"$schema": "https://json-schema.org/draft/2020-12/schema"

test/compiler/2020_12_compiler_enum_test.cc

Lines changed: 0 additions & 67 deletions
This file was deleted.

0 commit comments

Comments
 (0)