colregs 0.3.1 → 0.3.3
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.
- package/README.md +22 -14
- package/data/applicability.json +295 -276
- package/data/facts.json +19 -19
- package/data/i18n/en.json +73 -7
- package/data/i18n/fi.json +5 -5
- package/data/lights.json +10 -20
- package/data/version.json +1 -1
- package/docs/adr/0010-text-withheld-jurisdictions.md +2 -0
- package/docs/adr/0011-api-shape.md +7 -7
- package/docs/adr/0012-trace-and-rule2-departure-api.md +2 -2
- package/docs/adr/0016-encounter-roles-are-pooled-across-frames.md +82 -0
- package/docs/adr/0017-closed-vocabularies-are-prefixed-identifiers.md +105 -0
- package/docs/adr/0018-jurisdiction-delta-is-a-merge-patch.md +102 -0
- package/docs/adr/0019-relation-reach-and-import-reads.md +106 -0
- package/docs/budgets.json +6 -1
- package/docs/decisions.md +8 -0
- package/docs/identifiers.md +77 -60
- package/docs/part-b-invariants.md +41 -38
- package/docs/requirements.md +137 -137
- package/fixtures/applicability-fixtures.json +42 -0
- package/fixtures/situation-fixtures.json +600 -329
- package/package.json +4 -1
- package/schema/applicability.schema.json +74 -59
- package/schema/conduct-evaluation.schema.json +1 -1
- package/schema/encounter-evaluation.schema.json +6 -6
- package/schema/evaluation.schema.json +2 -2
- package/schema/facts.schema.json +4 -4
- package/schema/i18n-catalog.schema.json +26 -5
- package/schema/lights.schema.json +2 -3
- package/schema/situation-fixtures.schema.json +39 -0
- package/schema/situation.schema.json +3 -3
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "colregs",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "COLREGS 72 and its national amalgamations as language-neutral JSON — rule text, light definitions, and applicability predicates — with cross-implementation fixtures",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
|
+
"colregs": {
|
|
7
|
+
"referenceLanguage": "en"
|
|
8
|
+
},
|
|
6
9
|
"repository": {
|
|
7
10
|
"type": "git",
|
|
8
11
|
"url": "git+https://github.com/mark-brannan/colregs.git"
|
|
@@ -10,21 +10,21 @@
|
|
|
10
10
|
"ruleCategory": {
|
|
11
11
|
"type": "string",
|
|
12
12
|
"enum": [
|
|
13
|
-
"definition",
|
|
14
|
-
"standard",
|
|
15
|
-
"scope",
|
|
16
|
-
"display",
|
|
17
|
-
"classification",
|
|
18
|
-
"precedence",
|
|
19
|
-
"conduct",
|
|
20
|
-
"care",
|
|
21
|
-
"meta"
|
|
13
|
+
"category:definition",
|
|
14
|
+
"category:standard",
|
|
15
|
+
"category:scope",
|
|
16
|
+
"category:display",
|
|
17
|
+
"category:classification",
|
|
18
|
+
"category:precedence",
|
|
19
|
+
"category:conduct",
|
|
20
|
+
"category:care",
|
|
21
|
+
"category:meta"
|
|
22
22
|
]
|
|
23
23
|
},
|
|
24
24
|
"ruleId": { "type": "string", "pattern": "^rule:[0-9]+[a-z]?(_[ivx]+)*(:[a-z][a-z0-9_]*)?$" },
|
|
25
25
|
"modality": {
|
|
26
26
|
"type": "string",
|
|
27
|
-
"enum": ["shall", "may", "shall-if-practicable", "conditional", "exempt", "shall-not", "shall-not-impede"]
|
|
27
|
+
"enum": ["modality:shall", "modality:may", "modality:shall-if-practicable", "modality:conditional", "modality:exempt", "modality:shall-not", "modality:shall-not-impede"]
|
|
28
28
|
},
|
|
29
29
|
"predicateValue": {
|
|
30
30
|
"oneOf": [
|
|
@@ -95,13 +95,13 @@
|
|
|
95
95
|
},
|
|
96
96
|
"patternProperties": {
|
|
97
97
|
"^fact:[a-z0-9_]+$": { "$ref": "#/$defs/predicateValue" },
|
|
98
|
-
"^(
|
|
98
|
+
"^(self|other):(fact|kin|geo|hist):[a-z0-9_]+$": { "$ref": "#/$defs/predicateValue" },
|
|
99
99
|
"^pair:(geo|env):[a-z0-9_]+$": { "$ref": "#/$defs/predicateValue" }
|
|
100
100
|
}
|
|
101
101
|
},
|
|
102
102
|
"effectRole": {
|
|
103
103
|
"type": "string",
|
|
104
|
-
"enum": ["give-way", "stand-on", "shall-not-impede", "keep-clear", "none"]
|
|
104
|
+
"enum": ["role:give-way", "role:stand-on", "role:shall-not-impede", "role:keep-clear", "role:none"]
|
|
105
105
|
},
|
|
106
106
|
"effect": {
|
|
107
107
|
"oneOf": [
|
|
@@ -122,9 +122,9 @@
|
|
|
122
122
|
{
|
|
123
123
|
"type": "object",
|
|
124
124
|
"additionalProperties": false,
|
|
125
|
-
"required": ["
|
|
125
|
+
"required": ["self", "other"],
|
|
126
126
|
"properties": {
|
|
127
|
-
"
|
|
127
|
+
"self": { "$ref": "#/$defs/effectRole" },
|
|
128
128
|
"other": { "$ref": "#/$defs/effectRole" }
|
|
129
129
|
}
|
|
130
130
|
},
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
"properties": {
|
|
136
136
|
"encounter": {
|
|
137
137
|
"type": "string",
|
|
138
|
-
"enum": ["head-on", "crossing", "overtaking", "none"]
|
|
138
|
+
"enum": ["encounter:head-on", "encounter:crossing", "encounter:overtaking", "encounter:none"]
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
},
|
|
@@ -230,48 +230,48 @@
|
|
|
230
230
|
"type": "object",
|
|
231
231
|
"additionalProperties": false,
|
|
232
232
|
"required": [
|
|
233
|
-
"shall",
|
|
234
|
-
"may",
|
|
235
|
-
"shall-if-practicable",
|
|
236
|
-
"conditional",
|
|
237
|
-
"exempt",
|
|
238
|
-
"shall-not",
|
|
239
|
-
"shall-not-impede"
|
|
233
|
+
"modality:shall",
|
|
234
|
+
"modality:may",
|
|
235
|
+
"modality:shall-if-practicable",
|
|
236
|
+
"modality:conditional",
|
|
237
|
+
"modality:exempt",
|
|
238
|
+
"modality:shall-not",
|
|
239
|
+
"modality:shall-not-impede"
|
|
240
240
|
],
|
|
241
241
|
"properties": {
|
|
242
|
-
"shall": { "type": "string" },
|
|
243
|
-
"may": { "type": "string" },
|
|
244
|
-
"shall-if-practicable": { "type": "string" },
|
|
245
|
-
"conditional": { "type": "string" },
|
|
246
|
-
"exempt": { "type": "string" },
|
|
247
|
-
"shall-not": { "type": "string" },
|
|
248
|
-
"shall-not-impede": { "type": "string" }
|
|
242
|
+
"modality:shall": { "type": "string" },
|
|
243
|
+
"modality:may": { "type": "string" },
|
|
244
|
+
"modality:shall-if-practicable": { "type": "string" },
|
|
245
|
+
"modality:conditional": { "type": "string" },
|
|
246
|
+
"modality:exempt": { "type": "string" },
|
|
247
|
+
"modality:shall-not": { "type": "string" },
|
|
248
|
+
"modality:shall-not-impede": { "type": "string" }
|
|
249
249
|
}
|
|
250
250
|
},
|
|
251
251
|
"categories": {
|
|
252
252
|
"type": "object",
|
|
253
253
|
"additionalProperties": false,
|
|
254
254
|
"required": [
|
|
255
|
-
"definition",
|
|
256
|
-
"standard",
|
|
257
|
-
"scope",
|
|
258
|
-
"display",
|
|
259
|
-
"classification",
|
|
260
|
-
"precedence",
|
|
261
|
-
"conduct",
|
|
262
|
-
"care",
|
|
263
|
-
"meta"
|
|
255
|
+
"category:definition",
|
|
256
|
+
"category:standard",
|
|
257
|
+
"category:scope",
|
|
258
|
+
"category:display",
|
|
259
|
+
"category:classification",
|
|
260
|
+
"category:precedence",
|
|
261
|
+
"category:conduct",
|
|
262
|
+
"category:care",
|
|
263
|
+
"category:meta"
|
|
264
264
|
],
|
|
265
265
|
"properties": {
|
|
266
|
-
"definition": { "type": "string" },
|
|
267
|
-
"standard": { "type": "string" },
|
|
268
|
-
"scope": { "type": "string" },
|
|
269
|
-
"display": { "type": "string" },
|
|
270
|
-
"classification": { "type": "string" },
|
|
271
|
-
"precedence": { "type": "string" },
|
|
272
|
-
"conduct": { "type": "string" },
|
|
273
|
-
"care": { "type": "string" },
|
|
274
|
-
"meta": { "type": "string" }
|
|
266
|
+
"category:definition": { "type": "string" },
|
|
267
|
+
"category:standard": { "type": "string" },
|
|
268
|
+
"category:scope": { "type": "string" },
|
|
269
|
+
"category:display": { "type": "string" },
|
|
270
|
+
"category:classification": { "type": "string" },
|
|
271
|
+
"category:precedence": { "type": "string" },
|
|
272
|
+
"category:conduct": { "type": "string" },
|
|
273
|
+
"category:care": { "type": "string" },
|
|
274
|
+
"category:meta": { "type": "string" }
|
|
275
275
|
}
|
|
276
276
|
},
|
|
277
277
|
"effects": {
|
|
@@ -283,29 +283,44 @@
|
|
|
283
283
|
"roles": {
|
|
284
284
|
"type": "object",
|
|
285
285
|
"additionalProperties": false,
|
|
286
|
-
"required": ["give-way", "stand-on", "shall-not-impede", "keep-clear", "none"],
|
|
286
|
+
"required": ["role:give-way", "role:stand-on", "role:shall-not-impede", "role:keep-clear", "role:none"],
|
|
287
287
|
"properties": {
|
|
288
|
-
"give-way": { "type": "string" },
|
|
289
|
-
"stand-on": { "type": "string" },
|
|
290
|
-
"shall-not-impede": { "type": "string" },
|
|
291
|
-
"keep-clear": { "type": "string" },
|
|
292
|
-
"none": { "type": "string" }
|
|
288
|
+
"role:give-way": { "type": "string" },
|
|
289
|
+
"role:stand-on": { "type": "string" },
|
|
290
|
+
"role:shall-not-impede": { "type": "string" },
|
|
291
|
+
"role:keep-clear": { "type": "string" },
|
|
292
|
+
"role:none": { "type": "string" }
|
|
293
293
|
}
|
|
294
294
|
},
|
|
295
295
|
"encounters": {
|
|
296
296
|
"type": "object",
|
|
297
297
|
"additionalProperties": false,
|
|
298
|
-
"required": ["head-on", "crossing", "overtaking", "none"],
|
|
298
|
+
"required": ["encounter:head-on", "encounter:crossing", "encounter:overtaking", "encounter:none"],
|
|
299
299
|
"properties": {
|
|
300
|
-
"head-on": { "type": "string" },
|
|
301
|
-
"crossing": { "type": "string" },
|
|
302
|
-
"overtaking": { "type": "string" },
|
|
303
|
-
"none": { "type": "string" }
|
|
300
|
+
"encounter:head-on": { "type": "string" },
|
|
301
|
+
"encounter:crossing": { "type": "string" },
|
|
302
|
+
"encounter:overtaking": { "type": "string" },
|
|
303
|
+
"encounter:none": { "type": "string" }
|
|
304
304
|
}
|
|
305
305
|
},
|
|
306
306
|
"classification_shape": { "type": "string" }
|
|
307
307
|
}
|
|
308
308
|
},
|
|
309
|
+
"suppressions": {
|
|
310
|
+
"$comment": "Tombstones (REQ-SCOPE-3, ADR 0018): a jurisdiction deliberately lacks an inherited intl entry, as distinct from not-yet-transcribed. With the jurisdiction's own entries these form its RFC 7396 merge patch over intl; suppresses is the key that patch sets to null.",
|
|
311
|
+
"type": "array",
|
|
312
|
+
"items": {
|
|
313
|
+
"type": "object",
|
|
314
|
+
"additionalProperties": false,
|
|
315
|
+
"required": ["jurisdiction", "suppresses", "cite", "why"],
|
|
316
|
+
"properties": {
|
|
317
|
+
"jurisdiction": { "type": "string", "pattern": "^[a-z]+(/[a-z]+)+$" },
|
|
318
|
+
"suppresses": { "$ref": "#/$defs/ruleId" },
|
|
319
|
+
"cite": { "type": "string", "minLength": 1 },
|
|
320
|
+
"why": { "type": "string", "minLength": 1 }
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
},
|
|
309
324
|
"known_omissions": {
|
|
310
325
|
"type": "array",
|
|
311
326
|
"items": {
|
|
@@ -329,7 +344,7 @@
|
|
|
329
344
|
"id": { "$ref": "#/$defs/ruleId" },
|
|
330
345
|
"jurisdiction": { "type": "string", "pattern": "^[a-z]+(/[a-z]+)*$" },
|
|
331
346
|
"cite": { "type": "string", "minLength": 1 },
|
|
332
|
-
"category": { "type": "string", "enum": ["care", "meta"] },
|
|
347
|
+
"category": { "type": "string", "enum": ["category:care", "category:meta"] },
|
|
333
348
|
"note": { "type": "string", "minLength": 1 }
|
|
334
349
|
}
|
|
335
350
|
}
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"$comment": "Absent when no classification entry fired: cannot say, not none (Q-43).",
|
|
31
31
|
"type": "string",
|
|
32
32
|
"enum": [
|
|
33
|
-
"head-on",
|
|
34
|
-
"crossing",
|
|
35
|
-
"overtaking",
|
|
36
|
-
"none"
|
|
33
|
+
"encounter:head-on",
|
|
34
|
+
"encounter:crossing",
|
|
35
|
+
"encounter:overtaking",
|
|
36
|
+
"encounter:none"
|
|
37
37
|
]
|
|
38
38
|
},
|
|
39
39
|
"risk_of_collision": {
|
|
@@ -56,11 +56,11 @@
|
|
|
56
56
|
"type": "object",
|
|
57
57
|
"additionalProperties": false,
|
|
58
58
|
"required": [
|
|
59
|
-
"
|
|
59
|
+
"self",
|
|
60
60
|
"other"
|
|
61
61
|
],
|
|
62
62
|
"properties": {
|
|
63
|
-
"
|
|
63
|
+
"self": {
|
|
64
64
|
"$ref": "#/$defs/subjectRoles"
|
|
65
65
|
},
|
|
66
66
|
"other": {
|
package/schema/facts.schema.json
CHANGED
|
@@ -578,12 +578,12 @@
|
|
|
578
578
|
"type": "object",
|
|
579
579
|
"additionalProperties": false,
|
|
580
580
|
"required": [
|
|
581
|
-
"
|
|
581
|
+
"self",
|
|
582
582
|
"other",
|
|
583
583
|
"pair"
|
|
584
584
|
],
|
|
585
585
|
"properties": {
|
|
586
|
-
"
|
|
586
|
+
"self": {
|
|
587
587
|
"type": "string"
|
|
588
588
|
},
|
|
589
589
|
"other": {
|
|
@@ -716,12 +716,12 @@
|
|
|
716
716
|
"type": "object",
|
|
717
717
|
"additionalProperties": false,
|
|
718
718
|
"required": [
|
|
719
|
-
"
|
|
719
|
+
"self",
|
|
720
720
|
"other",
|
|
721
721
|
"pair"
|
|
722
722
|
],
|
|
723
723
|
"properties": {
|
|
724
|
-
"
|
|
724
|
+
"self": {
|
|
725
725
|
"type": "object",
|
|
726
726
|
"additionalProperties": false,
|
|
727
727
|
"properties": {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://github.com/mark-brannan/colregs/schema/i18n-catalog.schema.json",
|
|
4
4
|
"title": "data/i18n/*.json",
|
|
5
|
-
"description": "Display catalog for one BCP 47 language: UI strings for
|
|
5
|
+
"description": "Display catalog for one BCP 47 language: UI strings for the closed vocabularies the package emits (lights, modalities, roles, encounters, jurisdictions, closed-list fact values), not legal text -- see docs/adr/0003-language-as-a-dimension.md 'Display catalogs' and REQ-LANG-6.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
8
|
"required": ["language", "provenance", "strings"],
|
|
@@ -25,17 +25,38 @@
|
|
|
25
25
|
},
|
|
26
26
|
"strings": {
|
|
27
27
|
"type": "object",
|
|
28
|
-
"description": "One section per vocabulary
|
|
28
|
+
"description": "One section per vocabulary (REQ-LANG-6, REQ-LANG-9's ruling docs/adr/0017). Every section is keyed by the identifier itself, as documented in docs/identifiers.md -- light, modality, role and encounter identifiers carry a type prefix; jurisdiction and closed-list fact values are keyed by their own bare or fact-prefixed form. Values are static strings: no interpolation, no plurals -- the consumer's i18n system owns composition.",
|
|
29
29
|
"additionalProperties": false,
|
|
30
30
|
"properties": {
|
|
31
|
-
"
|
|
31
|
+
"lights": {
|
|
32
32
|
"type": "object",
|
|
33
33
|
"propertyNames": { "pattern": "^light:[a-z_]+$" },
|
|
34
34
|
"additionalProperties": { "$ref": "#/$defs/label" }
|
|
35
35
|
},
|
|
36
|
-
"
|
|
36
|
+
"modalities": {
|
|
37
37
|
"type": "object",
|
|
38
|
-
"propertyNames": { "pattern": "^[a-z]+(-[a-z]+)*$" },
|
|
38
|
+
"propertyNames": { "pattern": "^modality:[a-z]+(-[a-z]+)*$" },
|
|
39
|
+
"additionalProperties": { "$ref": "#/$defs/label" }
|
|
40
|
+
},
|
|
41
|
+
"roles": {
|
|
42
|
+
"type": "object",
|
|
43
|
+
"propertyNames": { "pattern": "^role:[a-z]+(-[a-z]+)*$" },
|
|
44
|
+
"additionalProperties": { "$ref": "#/$defs/label" }
|
|
45
|
+
},
|
|
46
|
+
"encounters": {
|
|
47
|
+
"type": "object",
|
|
48
|
+
"propertyNames": { "pattern": "^encounter:[a-z]+(-[a-z]+)*$" },
|
|
49
|
+
"additionalProperties": { "$ref": "#/$defs/label" }
|
|
50
|
+
},
|
|
51
|
+
"jurisdictions": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"propertyNames": { "pattern": "^[a-z]+(/[a-z]+)*$" },
|
|
54
|
+
"additionalProperties": { "$ref": "#/$defs/label" }
|
|
55
|
+
},
|
|
56
|
+
"facts": {
|
|
57
|
+
"type": "object",
|
|
58
|
+
"description": "Closed-list fact-value labels only (Tier A): propulsion, activity, position, rule18_class, dynamics, obstruction_side, wind_side. Field names (fact:length_m, geo:tcpa_s, ...) have no closed list behind them and are never catalogued here -- form-label text and unit/number formatting are the consumer's.",
|
|
59
|
+
"propertyNames": { "pattern": "^[a-z][a-z0-9_]*:[a-z][a-z0-9_]*$" },
|
|
39
60
|
"additionalProperties": { "$ref": "#/$defs/label" }
|
|
40
61
|
}
|
|
41
62
|
}
|
|
@@ -53,10 +53,9 @@
|
|
|
53
53
|
"^light:[a-z_]+$": {
|
|
54
54
|
"type": "object",
|
|
55
55
|
"additionalProperties": false,
|
|
56
|
-
"required": ["
|
|
56
|
+
"required": ["term", "cite", "character", "rule21"],
|
|
57
57
|
"properties": {
|
|
58
|
-
"
|
|
59
|
-
"colregs_term": { "type": "string", "minLength": 1 },
|
|
58
|
+
"term": { "type": "string", "minLength": 1 },
|
|
60
59
|
"cite": { "type": "string", "minLength": 1 },
|
|
61
60
|
"color": { "type": ["string", "null"] },
|
|
62
61
|
"color_note": { "type": "string" },
|
|
@@ -40,6 +40,22 @@
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
]
|
|
43
|
+
},
|
|
44
|
+
"subjectRole": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"additionalProperties": false,
|
|
47
|
+
"required": [
|
|
48
|
+
"role",
|
|
49
|
+
"by"
|
|
50
|
+
],
|
|
51
|
+
"properties": {
|
|
52
|
+
"role": {
|
|
53
|
+
"$ref": "applicability.schema.json#/$defs/effectRole"
|
|
54
|
+
},
|
|
55
|
+
"by": {
|
|
56
|
+
"$ref": "#/$defs/ruleId"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
43
59
|
}
|
|
44
60
|
},
|
|
45
61
|
"properties": {
|
|
@@ -175,6 +191,29 @@
|
|
|
175
191
|
"situation": {
|
|
176
192
|
"$comment": "A Situation (schema/situation.schema.json, ADR 0014).",
|
|
177
193
|
"$ref": "situation.schema.json"
|
|
194
|
+
},
|
|
195
|
+
"roles": {
|
|
196
|
+
"$comment": "The pooled, resolved roles of both subjects (ADR 0016). `expect` stays the self-frame entry ids.",
|
|
197
|
+
"type": "object",
|
|
198
|
+
"additionalProperties": false,
|
|
199
|
+
"required": [
|
|
200
|
+
"self",
|
|
201
|
+
"other"
|
|
202
|
+
],
|
|
203
|
+
"properties": {
|
|
204
|
+
"self": {
|
|
205
|
+
"type": "array",
|
|
206
|
+
"items": {
|
|
207
|
+
"$ref": "#/$defs/subjectRole"
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
"other": {
|
|
211
|
+
"type": "array",
|
|
212
|
+
"items": {
|
|
213
|
+
"$ref": "#/$defs/subjectRole"
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
178
217
|
}
|
|
179
218
|
}
|
|
180
219
|
}
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
"$id": "https://github.com/mark-brannan/colregs/schema/situation.schema.json",
|
|
4
4
|
"title": "Situation",
|
|
5
5
|
"description": "Two vessels and the encounter at one instant: the input evaluateEncounter reads, nested by subject and class (ADR 0005 §2, ADR 0011 §3, ADR 0014). Structure only -- every kin:/geo:/hist:/env: key must be declared in data/facts.json §situation, checked in the tests.",
|
|
6
|
-
"$comment": "The same shape as a case's `situation` in schema/situation-fixtures.schema.json, stated once here so an operation can name it; `
|
|
6
|
+
"$comment": "The same shape as a case's `situation` in schema/situation-fixtures.schema.json, stated once here so an operation can name it; `self` required, `other` optional (Rule 19's single-vessel scope), every class and key optional -- absent is absent.",
|
|
7
7
|
"type": "object",
|
|
8
8
|
"additionalProperties": false,
|
|
9
|
-
"required": ["
|
|
9
|
+
"required": ["self"],
|
|
10
10
|
"properties": {
|
|
11
|
-
"
|
|
11
|
+
"self": { "$ref": "#/$defs/subject" },
|
|
12
12
|
"other": { "$ref": "#/$defs/subject" },
|
|
13
13
|
"pair": {
|
|
14
14
|
"type": "object",
|