rtoon 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +12 -18
- data/README.md +76 -231
- metadata +1 -2
- data/TOON_SPEC.md +0 -61
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 43281cede188669647dacb5c6bbe76988310a356fed392e00a6e43eb6c7fb237
|
|
4
|
+
data.tar.gz: b6bf197adc646d47cec17a09a4962fe90a884c9910ccbe261df9e90c210589e6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ae5b46894a99b025b3884b644e632b901621500f6ea6c9fde203756cf557fe6a33e67882771f8999d35a158690671b158c6c436f0decc11160a0c522a589f9ad
|
|
7
|
+
data.tar.gz: 7f98aa510a5b9585d9b8b381cd42b97b675a328ac4435117a66b77ca1e3111dccf6d12cfc67d29553839ab87e0a298fc9b3c9524cf6e2cfee26f929425b3fb3d
|
data/LICENSE.txt
CHANGED
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
Copyright 2025 Zoobean Inc.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
|
4
|
+
and associated documentation files (the “Software”), to deal in the Software without restriction,
|
|
5
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
|
6
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
|
7
|
+
is furnished to do so, subject to the following conditions:
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
9
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
11
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
|
12
|
+
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
13
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
14
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
15
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
|
@@ -1,87 +1,81 @@
|
|
|
1
|
-
#
|
|
1
|
+
# RTOON - Token Object Oriented Notation Parser
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/zoobean/rtoon/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.ruby-lang.org/)
|
|
5
|
+
[](LICENSE.txt)
|
|
6
|
+
[](https://badge.fury.io/rb/rtoon)
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
A Ruby gem for parsing and encoding **Token Object Oriented Notation (TOON)** — a human-readable data format combining tabular structure with JSON-like flexibility.'
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
- **Schema declarations** with field definitions
|
|
9
|
-
- **Tabular data** for compact representation
|
|
10
|
-
- **Indentation-based nesting** for hierarchy
|
|
11
|
-
- **Array size hints** for structure clarity
|
|
10
|
+
Inspired by [toon-format/toon](https://github.com/toon-format/toon) which is written in TypeScript and for TypeScript projects.
|
|
12
11
|
|
|
13
|
-
### Example
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
items[1]{users,status}:
|
|
17
|
-
users[2]{id,name}:
|
|
18
|
-
1,Ada
|
|
19
|
-
2,Bob
|
|
20
|
-
status: active
|
|
21
|
-
```
|
|
13
|
+
## What is TOON?
|
|
22
14
|
|
|
23
|
-
|
|
15
|
+
TOON is a data serialization format with schema declarations, tabular rows, and indentation-based nesting.
|
|
24
16
|
|
|
25
|
-
|
|
26
|
-
{
|
|
27
|
-
"items" => [
|
|
28
|
-
{
|
|
29
|
-
"users" => [
|
|
30
|
-
{ "id" => "1", "name" => "Ada" },
|
|
31
|
-
{ "id" => "2", "name" => "Bob" }
|
|
32
|
-
],
|
|
33
|
-
"status" => "active"
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
}
|
|
37
|
-
```
|
|
17
|
+
From the original project description:
|
|
38
18
|
|
|
39
|
-
|
|
19
|
+
> Token-Oriented Object Notation is a compact, human-readable serialization format designed for passing structured data to Large Language Models with significantly reduced token usage. It's intended for LLM input as a lossless, drop-in representation of JSON data.
|
|
20
|
+
|
|
21
|
+
> TOON's sweet spot is uniform arrays of objects – multiple fields per row, same structure across items. It borrows YAML's indentation-based structure for nested objects and CSV's tabular format for uniform data rows, then optimizes both for token efficiency in LLM contexts. For deeply nested or non-uniform data, JSON may be more efficient.
|
|
22
|
+
|
|
23
|
+
> TOON achieves CSV-like compactness while adding explicit structure that helps LLMs parse and validate data reliably.
|
|
40
24
|
|
|
41
|
-
|
|
25
|
+
**Example:**
|
|
26
|
+
```toon
|
|
27
|
+
users[2]{id,name}:
|
|
28
|
+
1,Ada
|
|
29
|
+
2,Bob
|
|
30
|
+
```
|
|
42
31
|
|
|
32
|
+
**Parses to:**
|
|
43
33
|
```ruby
|
|
44
|
-
|
|
34
|
+
{"users" => [{"id" => "1", "name" => "Ada"}, {"id" => "2", "name" => "Bob"}]}
|
|
45
35
|
```
|
|
46
36
|
|
|
47
|
-
|
|
37
|
+
## Installation
|
|
48
38
|
|
|
49
39
|
```bash
|
|
50
40
|
gem install rtoon
|
|
51
41
|
```
|
|
52
42
|
|
|
53
|
-
|
|
43
|
+
Or add to `Gemfile`:
|
|
44
|
+
```ruby
|
|
45
|
+
gem 'rtoon'
|
|
46
|
+
```
|
|
54
47
|
|
|
55
|
-
|
|
48
|
+
## Quick Start
|
|
56
49
|
|
|
57
50
|
```ruby
|
|
58
51
|
require 'rtoon'
|
|
59
52
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
2,Bob
|
|
64
|
-
TOON
|
|
53
|
+
# Parse TOON → Ruby
|
|
54
|
+
result = Rtoon.parse("users[1]{id,name}:\n 1,Ada\n")
|
|
55
|
+
# => {"users" => [{"id" => "1", "name" => "Ada"}]}
|
|
65
56
|
|
|
66
|
-
|
|
67
|
-
|
|
57
|
+
# Encode Ruby → TOON
|
|
58
|
+
data = {"users" => [{"id" => "1", "name" => "Ada"}]}
|
|
59
|
+
toon = Rtoon.encode(data)
|
|
60
|
+
# => "users[1]{id,name}:\n 1,Ada\n"
|
|
68
61
|
```
|
|
69
62
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
Define data structures with schemas:
|
|
63
|
+
## Syntax
|
|
73
64
|
|
|
65
|
+
**Schema Declaration:**
|
|
74
66
|
```toon
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
3,Gizmo,300
|
|
67
|
+
identifier[size]{field1,field2}:
|
|
68
|
+
value1,value2
|
|
69
|
+
value3,value4
|
|
79
70
|
```
|
|
80
71
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
72
|
+
**Field Assignment:**
|
|
73
|
+
```toon
|
|
74
|
+
name: John
|
|
75
|
+
age: 30
|
|
76
|
+
```
|
|
84
77
|
|
|
78
|
+
**Nested Structure:**
|
|
85
79
|
```toon
|
|
86
80
|
company[1]{depts,location}:
|
|
87
81
|
depts[2]{name,size}:
|
|
@@ -90,209 +84,60 @@ company[1]{depts,location}:
|
|
|
90
84
|
location: NYC
|
|
91
85
|
```
|
|
92
86
|
|
|
93
|
-
|
|
87
|
+
## API
|
|
94
88
|
|
|
95
|
-
|
|
89
|
+
### `Rtoon.parse(string)` / `Rtoon.decode(string)`
|
|
90
|
+
Parses TOON-formatted string to Ruby Hash/Array.
|
|
96
91
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
age: 30
|
|
100
|
-
active: true
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
## TOON Syntax
|
|
104
|
-
|
|
105
|
-
### Schema Declaration
|
|
106
|
-
|
|
107
|
-
```
|
|
108
|
-
identifier[size]{field1,field2,...}:
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
- **identifier**: Name of the data structure
|
|
112
|
-
- **[size]**: Optional array size hint (can be any number)
|
|
113
|
-
- **{fields}**: Comma-separated list of field names
|
|
114
|
-
- **:** Indicates content follows on indented lines
|
|
115
|
-
|
|
116
|
-
### Data Rows
|
|
117
|
-
|
|
118
|
-
```
|
|
119
|
-
value1,value2,value3
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Comma-separated values matching the schema fields in order.
|
|
123
|
-
|
|
124
|
-
### Indentation
|
|
125
|
-
|
|
126
|
-
- Use **2 spaces** for each nesting level
|
|
127
|
-
- Indentation defines the structure hierarchy
|
|
128
|
-
- Empty lines are ignored
|
|
129
|
-
|
|
130
|
-
### Complete Example
|
|
131
|
-
|
|
132
|
-
```toon
|
|
133
|
-
database[1]{tables,version}:
|
|
134
|
-
tables[3]{name,records,indexed}:
|
|
135
|
-
users,1000,yes
|
|
136
|
-
posts,5000,yes
|
|
137
|
-
comments,20000,no
|
|
138
|
-
version: 3
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
Parses to:
|
|
92
|
+
### `Rtoon.encode(hash, indent_level = 0)`
|
|
93
|
+
Converts Ruby data structure to TOON format.
|
|
142
94
|
|
|
95
|
+
### Error Handling
|
|
143
96
|
```ruby
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
{ "name" => "posts", "records" => "5000", "indexed" => "yes" },
|
|
150
|
-
{ "name" => "comments", "records" => "20000", "indexed" => "no" }
|
|
151
|
-
],
|
|
152
|
-
"version" => "3"
|
|
153
|
-
}
|
|
154
|
-
]
|
|
155
|
-
}
|
|
97
|
+
begin
|
|
98
|
+
result = Rtoon.parse(invalid_toon)
|
|
99
|
+
rescue Rtoon::Parser::ParseError => e
|
|
100
|
+
puts "Parse error: #{e.message}"
|
|
101
|
+
end
|
|
156
102
|
```
|
|
157
103
|
|
|
158
|
-
## API Reference
|
|
159
|
-
|
|
160
|
-
### `Rtoon.parse(string)`
|
|
161
|
-
|
|
162
|
-
Parses a TOON string and returns a Ruby hash/array structure.
|
|
163
|
-
|
|
164
|
-
**Parameters:**
|
|
165
|
-
- `string` (String): TOON formatted string
|
|
166
|
-
|
|
167
|
-
**Returns:**
|
|
168
|
-
- Hash or Array with parsed data
|
|
169
|
-
|
|
170
|
-
**Raises:**
|
|
171
|
-
- `RtoonParser::ParseError`: If the string contains invalid TOON syntax
|
|
172
|
-
|
|
173
|
-
### `Rtoon.decode(string)`
|
|
174
|
-
|
|
175
|
-
Alias for `Rtoon.parse(string)`.
|
|
176
|
-
|
|
177
|
-
## Features
|
|
178
|
-
|
|
179
|
-
✅ Schema-based declarations
|
|
180
|
-
✅ Tabular data rows
|
|
181
|
-
✅ Indentation-based nesting
|
|
182
|
-
✅ Array size hints
|
|
183
|
-
✅ Field assignments
|
|
184
|
-
✅ Multi-level nesting
|
|
185
|
-
✅ Empty line handling
|
|
186
|
-
|
|
187
|
-
## Grammar
|
|
188
|
-
|
|
189
|
-
TOON uses a context-free grammar parsed with Racc (Ruby parser generator):
|
|
190
|
-
|
|
191
|
-
- **Statements**: Schema blocks or field assignments
|
|
192
|
-
- **Schema Block**: Header + indented content
|
|
193
|
-
- **Schema Header**: `name[size]{fields}:`
|
|
194
|
-
- **Data Rows**: Comma-separated values
|
|
195
|
-
- **Field Assignment**: `name: value`
|
|
196
|
-
- **Indentation**: INDENT/DEDENT tokens (2 spaces)
|
|
197
|
-
|
|
198
104
|
## Development
|
|
199
105
|
|
|
200
|
-
### Prerequisites
|
|
201
|
-
|
|
202
|
-
```bash
|
|
203
|
-
# Ruby 2.7 or higher
|
|
204
|
-
ruby --version
|
|
205
|
-
|
|
206
|
-
# Racc (included with Ruby)
|
|
207
|
-
ruby -e "require 'racc/parser'; puts 'Racc available'"
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### Building from Source
|
|
211
|
-
|
|
212
106
|
```bash
|
|
213
|
-
# Clone
|
|
107
|
+
# Clone and setup
|
|
108
|
+
git clone https://github.com/zoobean/rtoon.git
|
|
214
109
|
cd rtoon
|
|
215
|
-
|
|
216
|
-
# Compile grammar
|
|
217
|
-
racc -o lib/rtoon.tab.rb lib/rtoon.y
|
|
110
|
+
bundle install
|
|
218
111
|
|
|
219
112
|
# Run tests
|
|
220
113
|
ruby test/toon_test.rb
|
|
221
114
|
|
|
222
|
-
#
|
|
223
|
-
|
|
115
|
+
# Compile grammar (if modified)
|
|
116
|
+
racc -o lib/rtoon/parser.tab.rb lib/rtoon/parser.y
|
|
224
117
|
```
|
|
225
118
|
|
|
226
|
-
### Running Tests
|
|
227
|
-
|
|
228
|
-
```bash
|
|
229
|
-
ruby test/toon_test.rb
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
Expected output:
|
|
233
|
-
```
|
|
234
|
-
11 runs, 39 assertions, 0 failures, 0 errors, 0 skips
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
## Architecture
|
|
238
|
-
|
|
239
|
-
```
|
|
240
|
-
TOON String
|
|
241
|
-
↓
|
|
242
|
-
RtoonLexer (tokenization + indentation tracking)
|
|
243
|
-
↓
|
|
244
|
-
RtoonParser (Racc-generated parser)
|
|
245
|
-
↓
|
|
246
|
-
Ruby Hash/Array
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
### Components
|
|
250
|
-
|
|
251
|
-
- **lib/rtoon/lexer.rb**: Indentation-aware lexer
|
|
252
|
-
- **lib/rtoon/parser.y**: Racc grammar definition
|
|
253
|
-
- **lib/rtoon/parser.tab.rb**: Generated parser (don't edit!)
|
|
254
|
-
- **lib/rtoon/encoder.rb**: TOON encoder (Ruby → TOON)
|
|
255
|
-
- **lib/rtoon.rb**: Main interface
|
|
256
|
-
|
|
257
|
-
## Use Cases
|
|
258
|
-
|
|
259
|
-
TOON is ideal for:
|
|
260
|
-
|
|
261
|
-
- **Configuration files** with tabular data
|
|
262
|
-
- **Database seeds** with schemas and rows
|
|
263
|
-
- **API responses** with structured tables
|
|
264
|
-
- **Data exports** in readable format
|
|
265
|
-
- **Test fixtures** with clear structure
|
|
266
|
-
|
|
267
119
|
## Limitations
|
|
268
120
|
|
|
269
|
-
- Values
|
|
270
|
-
- No support for nested arrays in data rows
|
|
121
|
+
- Values returned as strings (no automatic type conversion)
|
|
271
122
|
- No string escaping (commas in values not supported)
|
|
272
|
-
-
|
|
273
|
-
|
|
274
|
-
## Future Enhancements
|
|
275
|
-
|
|
276
|
-
- Type inference/conversion (numbers, booleans)
|
|
277
|
-
- String literals with quotes
|
|
278
|
-
- Escape sequences for commas in values
|
|
279
|
-
- Comments support
|
|
280
|
-
- Encoder (Ruby → TOON)
|
|
123
|
+
- Fixed 2-space indentation
|
|
124
|
+
- No comment syntax
|
|
281
125
|
|
|
282
126
|
## Contributing
|
|
283
127
|
|
|
284
128
|
1. Fork the repository
|
|
285
|
-
2. Create
|
|
286
|
-
3. Add tests for
|
|
287
|
-
4.
|
|
288
|
-
|
|
129
|
+
2. Create a feature branch
|
|
130
|
+
3. Add tests for new features
|
|
131
|
+
4. Submit a Pull Request
|
|
132
|
+
|
|
133
|
+
See [ARCHITECTURE.md](ARCHITECTURE.md) for implementation details.
|
|
289
134
|
|
|
290
135
|
## License
|
|
291
136
|
|
|
292
|
-
MIT License - See LICENSE.txt
|
|
137
|
+
MIT License - See [LICENSE.txt](LICENSE.txt)
|
|
138
|
+
|
|
139
|
+
## Author
|
|
293
140
|
|
|
294
|
-
|
|
141
|
+
**Antonio Chavez** - [Zoobean](https://github.com/zoobean)
|
|
295
142
|
|
|
296
|
-
|
|
297
|
-
- Parser theory: https://en.wikipedia.org/wiki/Parsing
|
|
298
|
-
- Indentation-based parsing: https://en.wikipedia.org/wiki/Off-side_rule
|
|
143
|
+
Report bugs: [GitHub Issues](https://github.com/zoobean/rtoon/issues)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rtoon
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Antonio Chavez
|
|
@@ -61,7 +61,6 @@ extra_rdoc_files: []
|
|
|
61
61
|
files:
|
|
62
62
|
- LICENSE.txt
|
|
63
63
|
- README.md
|
|
64
|
-
- TOON_SPEC.md
|
|
65
64
|
- lib/rtoon.rb
|
|
66
65
|
- lib/rtoon/encoder.rb
|
|
67
66
|
- lib/rtoon/lexer.rb
|
data/TOON_SPEC.md
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
# TOON Format Specification
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
Token Object Oriented Notation (TOON) is a tabular, schema-based data format with indentation-based structure.
|
|
5
|
-
|
|
6
|
-
## Syntax Elements
|
|
7
|
-
|
|
8
|
-
### Schema Declaration
|
|
9
|
-
```
|
|
10
|
-
identifier[size]{field1,field2,...}:
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
- **identifier**: Name of the data structure
|
|
14
|
-
- **[size]**: Optional array size hint
|
|
15
|
-
- **{fields}**: Comma-separated list of field names
|
|
16
|
-
- **:** Indicates content follows
|
|
17
|
-
|
|
18
|
-
### Data Rows
|
|
19
|
-
```
|
|
20
|
-
value1,value2,value3
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
Comma-separated values corresponding to the schema fields.
|
|
24
|
-
|
|
25
|
-
### Nesting
|
|
26
|
-
Uses indentation (2 spaces) to indicate nested structures.
|
|
27
|
-
|
|
28
|
-
### Example
|
|
29
|
-
```
|
|
30
|
-
items[1]{users,status}:
|
|
31
|
-
users[2]{id,name}:
|
|
32
|
-
1,Ada
|
|
33
|
-
2,Bob
|
|
34
|
-
status: active
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Parsed Structure
|
|
38
|
-
The above should parse to:
|
|
39
|
-
```ruby
|
|
40
|
-
{
|
|
41
|
-
"items" => [
|
|
42
|
-
{
|
|
43
|
-
"users" => [
|
|
44
|
-
{ "id" => "1", "name" => "Ada" },
|
|
45
|
-
{ "id" => "2", "name" => "Bob" }
|
|
46
|
-
],
|
|
47
|
-
"status" => "active"
|
|
48
|
-
}
|
|
49
|
-
]
|
|
50
|
-
}
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Grammar Rules
|
|
54
|
-
|
|
55
|
-
1. **Top-level**: Schema declaration or field assignment
|
|
56
|
-
2. **Schema**: `name[size]{fields}:` followed by indented content
|
|
57
|
-
3. **Field**: `name: value` (simple assignment)
|
|
58
|
-
4. **Data rows**: Comma-separated values matching schema fields
|
|
59
|
-
5. **Indentation**: 2 spaces per level
|
|
60
|
-
6. **Arrays**: Created from schema declarations with size hint
|
|
61
|
-
7. **Objects**: Created from schema fields
|