@infra-blocks/zod-utils 0.3.0-alpha.0 → 0.4.0-alpha.0
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 +150 -10
- package/lib/cjs/geojson/base.d.ts +8 -0
- package/lib/cjs/geojson/base.js +9 -0
- package/lib/cjs/geojson/base.js.map +1 -0
- package/lib/cjs/geojson/bounding-box.d.ts +5 -0
- package/lib/cjs/geojson/bounding-box.js +27 -0
- package/lib/cjs/geojson/bounding-box.js.map +1 -0
- package/lib/cjs/geojson/coordinate.d.ts +5 -0
- package/lib/cjs/geojson/coordinate.js +16 -0
- package/lib/cjs/geojson/coordinate.js.map +1 -0
- package/lib/cjs/geojson/feature-collection.d.ts +657 -0
- package/lib/cjs/geojson/feature-collection.js +15 -0
- package/lib/cjs/geojson/feature-collection.js.map +1 -0
- package/lib/cjs/geojson/feature.d.ts +397 -0
- package/lib/cjs/geojson/feature.js +18 -0
- package/lib/cjs/geojson/feature.js.map +1 -0
- package/lib/cjs/geojson/geojson.d.ts +1193 -0
- package/lib/cjs/geojson/geojson.js +13 -0
- package/lib/cjs/geojson/geojson.js.map +1 -0
- package/lib/cjs/geojson/geometry.d.ts +155 -0
- package/lib/cjs/geojson/geometry.js +33 -0
- package/lib/cjs/geojson/geometry.js.map +1 -0
- package/lib/cjs/geojson/index.d.ts +622 -0
- package/lib/cjs/geojson/index.js +34 -0
- package/lib/cjs/geojson/index.js.map +1 -0
- package/lib/cjs/geojson/line-string.d.ts +29 -0
- package/lib/cjs/geojson/line-string.js +15 -0
- package/lib/cjs/geojson/line-string.js.map +1 -0
- package/lib/cjs/geojson/multi-line-string.d.ts +29 -0
- package/lib/cjs/geojson/multi-line-string.js +15 -0
- package/lib/cjs/geojson/multi-line-string.js.map +1 -0
- package/lib/cjs/geojson/multi-point.d.ts +29 -0
- package/lib/cjs/geojson/multi-point.js +15 -0
- package/lib/cjs/geojson/multi-point.js.map +1 -0
- package/lib/cjs/geojson/multi-polygon.d.ts +29 -0
- package/lib/cjs/geojson/multi-polygon.js +15 -0
- package/lib/cjs/geojson/multi-polygon.js.map +1 -0
- package/lib/cjs/geojson/point.d.ts +29 -0
- package/lib/cjs/geojson/point.js +15 -0
- package/lib/cjs/geojson/point.js.map +1 -0
- package/lib/cjs/geojson/polygon.d.ts +29 -0
- package/lib/cjs/geojson/polygon.js +15 -0
- package/lib/cjs/geojson/polygon.js.map +1 -0
- package/lib/cjs/geojson/types.d.ts +12 -0
- package/lib/cjs/geojson/types.js +3 -0
- package/lib/cjs/geojson/types.js.map +1 -0
- package/lib/cjs/index.d.ts +608 -0
- package/lib/cjs/index.js +2 -0
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/geojson/base.d.ts +8 -0
- package/lib/esm/geojson/base.js +6 -0
- package/lib/esm/geojson/base.js.map +1 -0
- package/lib/esm/geojson/bounding-box.d.ts +5 -0
- package/lib/esm/geojson/bounding-box.js +23 -0
- package/lib/esm/geojson/bounding-box.js.map +1 -0
- package/lib/esm/geojson/coordinate.d.ts +5 -0
- package/lib/esm/geojson/coordinate.js +12 -0
- package/lib/esm/geojson/coordinate.js.map +1 -0
- package/lib/esm/geojson/feature-collection.d.ts +657 -0
- package/lib/esm/geojson/feature-collection.js +11 -0
- package/lib/esm/geojson/feature-collection.js.map +1 -0
- package/lib/esm/geojson/feature.d.ts +397 -0
- package/lib/esm/geojson/feature.js +14 -0
- package/lib/esm/geojson/feature.js.map +1 -0
- package/lib/esm/geojson/geojson.d.ts +1193 -0
- package/lib/esm/geojson/geojson.js +9 -0
- package/lib/esm/geojson/geojson.js.map +1 -0
- package/lib/esm/geojson/geometry.d.ts +155 -0
- package/lib/esm/geojson/geometry.js +28 -0
- package/lib/esm/geojson/geometry.js.map +1 -0
- package/lib/esm/geojson/index.d.ts +622 -0
- package/lib/esm/geojson/index.js +31 -0
- package/lib/esm/geojson/index.js.map +1 -0
- package/lib/esm/geojson/line-string.d.ts +29 -0
- package/lib/esm/geojson/line-string.js +11 -0
- package/lib/esm/geojson/line-string.js.map +1 -0
- package/lib/esm/geojson/multi-line-string.d.ts +29 -0
- package/lib/esm/geojson/multi-line-string.js +11 -0
- package/lib/esm/geojson/multi-line-string.js.map +1 -0
- package/lib/esm/geojson/multi-point.d.ts +29 -0
- package/lib/esm/geojson/multi-point.js +11 -0
- package/lib/esm/geojson/multi-point.js.map +1 -0
- package/lib/esm/geojson/multi-polygon.d.ts +29 -0
- package/lib/esm/geojson/multi-polygon.js +11 -0
- package/lib/esm/geojson/multi-polygon.js.map +1 -0
- package/lib/esm/geojson/point.d.ts +29 -0
- package/lib/esm/geojson/point.js +11 -0
- package/lib/esm/geojson/point.js.map +1 -0
- package/lib/esm/geojson/polygon.d.ts +29 -0
- package/lib/esm/geojson/polygon.js +11 -0
- package/lib/esm/geojson/polygon.js.map +1 -0
- package/lib/esm/geojson/types.d.ts +12 -0
- package/lib/esm/geojson/types.js +2 -0
- package/lib/esm/geojson/types.js.map +1 -0
- package/lib/esm/index.d.ts +608 -0
- package/lib/esm/index.js +2 -0
- package/lib/esm/index.js.map +1 -1
- package/package.json +8 -1
package/README.md
CHANGED
|
@@ -8,8 +8,156 @@ This package exposes various utilities extending the [zod](https://www.npmjs.com
|
|
|
8
8
|
|
|
9
9
|
## API
|
|
10
10
|
|
|
11
|
+
- [geojson](#geojson)
|
|
11
12
|
- [json](#json)
|
|
12
13
|
|
|
14
|
+
### GeoJson
|
|
15
|
+
|
|
16
|
+
The `geojson` module contains utilities to validate GeoJSON objects.
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { zu } from "@infra-blocks/zod-utils";
|
|
20
|
+
|
|
21
|
+
// Supports all GeoJSON types.
|
|
22
|
+
// All geometries are supported.
|
|
23
|
+
zu.geojson().parse({
|
|
24
|
+
type: "Point",
|
|
25
|
+
coordinates: [1, 2]
|
|
26
|
+
});
|
|
27
|
+
// Features
|
|
28
|
+
zu.geojson().parse({
|
|
29
|
+
type: "Feature",
|
|
30
|
+
geometry: {
|
|
31
|
+
type: "LineString",
|
|
32
|
+
// Works with 3d coordinates too.
|
|
33
|
+
coordinates: [[1, 2, 3], [4, 4, 6]]
|
|
34
|
+
},
|
|
35
|
+
// Either null or a JSON object.
|
|
36
|
+
properties: {
|
|
37
|
+
name: "BigFeature"
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
// Feature collections
|
|
41
|
+
zu.geojson().parse({
|
|
42
|
+
type: "FeatureCollection",
|
|
43
|
+
features: [
|
|
44
|
+
{
|
|
45
|
+
type: "Feature",
|
|
46
|
+
geometry: {
|
|
47
|
+
type: "Polygon",
|
|
48
|
+
coordinates: [[[1, 2], [2, 2], [2, 1], [1, 1]]]
|
|
49
|
+
},
|
|
50
|
+
properties: {
|
|
51
|
+
name: "BroSquare"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
#### Sub schemas & Types
|
|
59
|
+
|
|
60
|
+
For convenience, the module also exports sub schemas and types. This way, a user can pick and choose which schemas
|
|
61
|
+
they specifically need in their context, or which ones they'd like to extend and customize.
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import {zu} from "@infra-blocks/zod-utils";
|
|
65
|
+
import {
|
|
66
|
+
GeoJson,
|
|
67
|
+
GeoJsonBoundingBox,
|
|
68
|
+
GeoJsonFeature,
|
|
69
|
+
GeoJsonFeatureCollection,
|
|
70
|
+
GeoJsonGeometryCollection,
|
|
71
|
+
GeoJsonLineString,
|
|
72
|
+
GeoJsonMultiLineString,
|
|
73
|
+
GeoJsonMultiPoint,
|
|
74
|
+
GeoJsonMultiPolygon,
|
|
75
|
+
GeoJsonPoint,
|
|
76
|
+
GeoJsonPolygon,
|
|
77
|
+
GeoJsonCoordinate
|
|
78
|
+
} from "@infra-blocks/zod-utils/geojson";
|
|
79
|
+
|
|
80
|
+
const boundingBoxSchema = zu.geojson.boundingBox();
|
|
81
|
+
const boundingBox: GeoJsonBoundingBox = boundingBoxSchema.parse({...});
|
|
82
|
+
|
|
83
|
+
const featureSchema = zu.geojson.feature();
|
|
84
|
+
const feature: GeoJsonFeature = featureSchema.parse({...});
|
|
85
|
+
|
|
86
|
+
const featureCollectionSchema = zu.geojson.featureCollection();
|
|
87
|
+
const featureCollection: GeoJsonFeatureCollection = featureCollectionSchema.parse({...});
|
|
88
|
+
|
|
89
|
+
const geometryCollectionSchema = zu.geojson.geometryCollection();
|
|
90
|
+
const geometryCollection: GeoJsonGeometryCollection = geometryCollectionSchema.parse({...});
|
|
91
|
+
|
|
92
|
+
const lineStringSchema = zu.geojson.lineString();
|
|
93
|
+
const lineString: GeoJsonLineString = lineStringSchema.parse({...});
|
|
94
|
+
|
|
95
|
+
const multiLineStringSchema = zu.geojson.multiLineString();
|
|
96
|
+
const multiLineString: GeoJsonMultiLineString = multiLineStringSchema.parse({...});
|
|
97
|
+
|
|
98
|
+
const multiPointSchema = zu.geojson.multiPoint();
|
|
99
|
+
const multiPoint: GeoJsonMultiPoint = multiPointSchema.parse({...});
|
|
100
|
+
|
|
101
|
+
const multiPolygonSchema = zu.geojson.multiPolygon();
|
|
102
|
+
const multiPolygon: GeoJsonMultiPolygon = multiPolygonSchema.parse({...});
|
|
103
|
+
|
|
104
|
+
const pointSchema = zu.geojson.point();
|
|
105
|
+
const point: GeoJsonPoint = pointSchema.parse({...});
|
|
106
|
+
|
|
107
|
+
const polygonSchema = zu.geojson.polygon();
|
|
108
|
+
const polygon: GeoJsonPolygon = polygonSchema.parse({...});
|
|
109
|
+
|
|
110
|
+
const coordinateSchema = zu.geojson.coordinate();
|
|
111
|
+
const coordinate: GeoJsonCoordinate = coordinateSchema.parse([1, 2]);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### Design considerations
|
|
115
|
+
|
|
116
|
+
##### Empty coordinates arrays
|
|
117
|
+
|
|
118
|
+
The module follows the [spec](https://datatracker.ietf.org/doc/html/rfc7946). Note that the spec states the
|
|
119
|
+
following:
|
|
120
|
+
|
|
121
|
+
> GeoJSON processors MAY interpret Geometry objects with
|
|
122
|
+
empty "coordinates" arrays as null objects.
|
|
123
|
+
|
|
124
|
+
This module tolerates empty coordinates arrays where the spec doesn't explicitly state that it must not be empty.
|
|
125
|
+
For example, the following won't throw:
|
|
126
|
+
```typescript
|
|
127
|
+
zu.geojson().parse({
|
|
128
|
+
type: "MultiLineString",
|
|
129
|
+
coordinates: []
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
However, the following will throw because the spec explicitly states the coordinates must contain at least two
|
|
134
|
+
positions:
|
|
135
|
+
```typescript
|
|
136
|
+
zu.geojson().parse({
|
|
137
|
+
type: "LineString",
|
|
138
|
+
coordinates: []
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
This behaviour could become configurable in a future version with a stricter default approach.
|
|
143
|
+
|
|
144
|
+
##### Properties
|
|
145
|
+
|
|
146
|
+
GeoJSON features must have properties. Those properties are either null or a JSON object. This module uses
|
|
147
|
+
the `json` module to validate the properties. This means that the following will throw:
|
|
148
|
+
```typescript
|
|
149
|
+
zu.geojson().parse({
|
|
150
|
+
type: "Feature",
|
|
151
|
+
geometry: {
|
|
152
|
+
type: "Point",
|
|
153
|
+
coordinates: [1, 2]
|
|
154
|
+
},
|
|
155
|
+
properties: {
|
|
156
|
+
notJson: new Map()
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
13
161
|
### JSON
|
|
14
162
|
|
|
15
163
|
The `json` module contains utilities to validate JSON objects and stringified JSON objects.
|
|
@@ -44,21 +192,13 @@ zu.json().parse(new Set()); // Boom.
|
|
|
44
192
|
zu.json.stringified().parse("5"); // Returns the number 5.
|
|
45
193
|
zu.json.stringified().parse('"JSON string"'); // Returns "JSON string". Note the quotes were removed.
|
|
46
194
|
zu.json.stringified().parse(JSON.strinfify({ field: "value" })); // Returns {field: "value"}.
|
|
47
|
-
|
|
48
|
-
// Inferred types are exported for convenience.
|
|
49
|
-
import { Json } from "@infra-blocks/zod-utils/json";
|
|
50
|
-
|
|
51
|
-
// Compiles.
|
|
52
|
-
const myJson: Json = { hello: "world" };
|
|
53
|
-
// Doesn't compile: undefined is not valid JSON.
|
|
54
|
-
const boom: Json = { nope: undefined };
|
|
55
195
|
````
|
|
56
196
|
|
|
57
|
-
|
|
197
|
+
#### Sub schemas & Types
|
|
58
198
|
|
|
59
199
|
```typescript
|
|
60
200
|
import { zu } from "@infra-blocks/zod-utils";
|
|
61
|
-
import { JsonArray, JsonObject, JsonPrimitive } from "@infra-blocks/zod-utils/json";
|
|
201
|
+
import { Json, JsonArray, JsonObject, JsonPrimitive } from "@infra-blocks/zod-utils/json";
|
|
62
202
|
|
|
63
203
|
// The type hints are used just to showcase their usage. They aren't necessary when parsing.
|
|
64
204
|
// Want to parse a JSON primitive?
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const schemaWithBoundingBox: z.ZodObject<{
|
|
3
|
+
bbox: z.ZodOptional<z.ZodUnion<[z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>, z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>]>>;
|
|
4
|
+
}, "strict", z.ZodTypeAny, {
|
|
5
|
+
bbox?: [number, number, number, number] | [number, number, number, number, number, number] | undefined;
|
|
6
|
+
}, {
|
|
7
|
+
bbox?: [number, number, number, number] | [number, number, number, number, number, number] | undefined;
|
|
8
|
+
}>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.schemaWithBoundingBox = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const bounding_box_js_1 = require("./bounding-box.js");
|
|
6
|
+
exports.schemaWithBoundingBox = zod_1.z.strictObject({
|
|
7
|
+
bbox: (0, bounding_box_js_1.boundingBox)().optional(),
|
|
8
|
+
});
|
|
9
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/geojson/base.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AACxB,uDAAgD;AAEnC,QAAA,qBAAqB,GAAG,OAAC,CAAC,YAAY,CAAC;IAClD,IAAI,EAAE,IAAA,6BAAW,GAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
declare const boundingBoxSchema: z.ZodUnion<[z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>, z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>]>;
|
|
3
|
+
export type GeoJsonBoundingBox = z.infer<typeof boundingBoxSchema>;
|
|
4
|
+
export declare function boundingBox(): z.ZodUnion<[z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>, z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>]>;
|
|
5
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.boundingBox = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const twoDimensionalBoundingBox = zod_1.z.tuple([
|
|
6
|
+
zod_1.z.number(),
|
|
7
|
+
zod_1.z.number(),
|
|
8
|
+
zod_1.z.number(),
|
|
9
|
+
zod_1.z.number(),
|
|
10
|
+
]);
|
|
11
|
+
const threeDimensionalBoundingBox = zod_1.z.tuple([
|
|
12
|
+
zod_1.z.number(),
|
|
13
|
+
zod_1.z.number(),
|
|
14
|
+
zod_1.z.number(),
|
|
15
|
+
zod_1.z.number(),
|
|
16
|
+
zod_1.z.number(),
|
|
17
|
+
zod_1.z.number(),
|
|
18
|
+
]);
|
|
19
|
+
const boundingBoxSchema = zod_1.z.union([
|
|
20
|
+
twoDimensionalBoundingBox,
|
|
21
|
+
threeDimensionalBoundingBox,
|
|
22
|
+
]);
|
|
23
|
+
function boundingBox() {
|
|
24
|
+
return boundingBoxSchema;
|
|
25
|
+
}
|
|
26
|
+
exports.boundingBox = boundingBox;
|
|
27
|
+
//# sourceMappingURL=bounding-box.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounding-box.js","sourceRoot":"","sources":["../../../src/geojson/bounding-box.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB,MAAM,yBAAyB,GAAG,OAAC,CAAC,KAAK,CAAC;IACxC,OAAC,CAAC,MAAM,EAAE;IACV,OAAC,CAAC,MAAM,EAAE;IACV,OAAC,CAAC,MAAM,EAAE;IACV,OAAC,CAAC,MAAM,EAAE;CACX,CAAC,CAAC;AAEH,MAAM,2BAA2B,GAAG,OAAC,CAAC,KAAK,CAAC;IAC1C,OAAC,CAAC,MAAM,EAAE;IACV,OAAC,CAAC,MAAM,EAAE;IACV,OAAC,CAAC,MAAM,EAAE;IACV,OAAC,CAAC,MAAM,EAAE;IACV,OAAC,CAAC,MAAM,EAAE;IACV,OAAC,CAAC,MAAM,EAAE;CACX,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,OAAC,CAAC,KAAK,CAAC;IAChC,yBAAyB;IACzB,2BAA2B;CAC5B,CAAC,CAAC;AAIH,SAAgB,WAAW;IACzB,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAFD,kCAEC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
declare const schema: z.ZodUnion<[z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>, z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>]>;
|
|
3
|
+
export type GeoJsonCoordinate = z.infer<typeof schema>;
|
|
4
|
+
export declare function coordinate(): z.ZodUnion<[z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>, z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>]>;
|
|
5
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.coordinate = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const twoDimensionalCoordinate = zod_1.z.tuple([zod_1.z.number(), zod_1.z.number()]);
|
|
6
|
+
const threeDimensionalCoordinate = zod_1.z.tuple([
|
|
7
|
+
zod_1.z.number(),
|
|
8
|
+
zod_1.z.number(),
|
|
9
|
+
zod_1.z.number(),
|
|
10
|
+
]);
|
|
11
|
+
const schema = zod_1.z.union([twoDimensionalCoordinate, threeDimensionalCoordinate]);
|
|
12
|
+
function coordinate() {
|
|
13
|
+
return schema;
|
|
14
|
+
}
|
|
15
|
+
exports.coordinate = coordinate;
|
|
16
|
+
//# sourceMappingURL=coordinate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinate.js","sourceRoot":"","sources":["../../../src/geojson/coordinate.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB,MAAM,wBAAwB,GAAG,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AACnE,MAAM,0BAA0B,GAAG,OAAC,CAAC,KAAK,CAAC;IACzC,OAAC,CAAC,MAAM,EAAE;IACV,OAAC,CAAC,MAAM,EAAE;IACV,OAAC,CAAC,MAAM,EAAE;CACX,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,OAAC,CAAC,KAAK,CAAC,CAAC,wBAAwB,EAAE,0BAA0B,CAAC,CAAC,CAAC;AAI/E,SAAgB,UAAU;IACxB,OAAO,MAAM,CAAC;AAChB,CAAC;AAFD,gCAEC"}
|