@drawtonomy/sdk 0.6.0 → 0.7.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.ja.md +36 -0
- package/README.md +16 -2
- package/dist/exporter/index.d.ts +3 -0
- package/dist/exporter/index.d.ts.map +1 -1
- package/dist/exporter/index.js +8 -3
- package/dist/exporter/index.js.map +1 -1
- package/dist/exporter/lanelet2.d.ts +26 -0
- package/dist/exporter/lanelet2.d.ts.map +1 -0
- package/dist/exporter/lanelet2.js +261 -0
- package/dist/exporter/lanelet2.js.map +1 -0
- package/dist/exporter/osmParser.d.ts +54 -0
- package/dist/exporter/osmParser.d.ts.map +1 -0
- package/dist/exporter/osmParser.js +247 -0
- package/dist/exporter/osmParser.js.map +1 -0
- package/dist/exporter/osmToShapes.d.ts +107 -0
- package/dist/exporter/osmToShapes.d.ts.map +1 -0
- package/dist/exporter/osmToShapes.js +370 -0
- package/dist/exporter/osmToShapes.js.map +1 -0
- package/package.json +7 -6
- package/LICENSE +0 -190
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
// Lanelet2 OSM (.osm XML) parser.
|
|
2
|
+
//
|
|
3
|
+
// The Lanelet2 format reuses OpenStreetMap's `<node>` / `<way>` / `<relation>`
|
|
4
|
+
// tag structure but with traffic-domain semantics:
|
|
5
|
+
// - <node> : a 2D point in lat/lon (optionally with `ele` tag for height)
|
|
6
|
+
// - <way> : an ordered list of node refs forming a polyline
|
|
7
|
+
// (used for lane boundaries, stop lines, etc.)
|
|
8
|
+
// - <relation> : a typed grouping of ways/nodes
|
|
9
|
+
// (`type=lanelet` joins a left + right way as a lane;
|
|
10
|
+
// `type=regulatory_element` etc. are kept untouched)
|
|
11
|
+
//
|
|
12
|
+
// drawtonomy-emitted files additionally embed `drawtonomy_origin_lat` and
|
|
13
|
+
// `drawtonomy_origin_lon` attributes on the root `<osm>` element so that the
|
|
14
|
+
// canvas page coordinates can be reconstructed exactly on round-trip. Standard
|
|
15
|
+
// OSM consumers ignore unknown attributes, keeping the file compatible.
|
|
16
|
+
//
|
|
17
|
+
// The parser is intentionally hand-written so it works in a plain Node runtime
|
|
18
|
+
// without a DOM. When a global `DOMParser` is available (e.g. in a browser or
|
|
19
|
+
// when jsdom is installed), it is used for robustness; otherwise a regex-based
|
|
20
|
+
// fallback parses the same subset of OSM XML used by Lanelet2.
|
|
21
|
+
function getDomParser() {
|
|
22
|
+
const g = globalThis;
|
|
23
|
+
return typeof g.DOMParser === 'function' ? g.DOMParser : null;
|
|
24
|
+
}
|
|
25
|
+
function parseOsmXmlWithDom(xmlString, DOMParserImpl) {
|
|
26
|
+
const parser = new DOMParserImpl();
|
|
27
|
+
const doc = parser.parseFromString(xmlString, 'text/xml');
|
|
28
|
+
const nodes = new Map();
|
|
29
|
+
const ways = new Map();
|
|
30
|
+
const relations = [];
|
|
31
|
+
let drawtonomyOrigin;
|
|
32
|
+
const osmEl = doc.querySelector('osm');
|
|
33
|
+
if (osmEl) {
|
|
34
|
+
const oLat = parseFloat(osmEl.getAttribute('drawtonomy_origin_lat') || '');
|
|
35
|
+
const oLon = parseFloat(osmEl.getAttribute('drawtonomy_origin_lon') || '');
|
|
36
|
+
if (Number.isFinite(oLat) && Number.isFinite(oLon)) {
|
|
37
|
+
drawtonomyOrigin = { lat: oLat, lon: oLon };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const collectTags = (el) => {
|
|
41
|
+
const tags = {};
|
|
42
|
+
el.querySelectorAll(':scope > tag').forEach(tagEl => {
|
|
43
|
+
const k = tagEl.getAttribute('k') || '';
|
|
44
|
+
const v = tagEl.getAttribute('v') || '';
|
|
45
|
+
if (k)
|
|
46
|
+
tags[k] = v;
|
|
47
|
+
});
|
|
48
|
+
return tags;
|
|
49
|
+
};
|
|
50
|
+
doc.querySelectorAll('node').forEach(nodeEl => {
|
|
51
|
+
const id = nodeEl.getAttribute('id') || '';
|
|
52
|
+
const lat = parseFloat(nodeEl.getAttribute('lat') || '0');
|
|
53
|
+
const lon = parseFloat(nodeEl.getAttribute('lon') || '0');
|
|
54
|
+
const tags = collectTags(nodeEl);
|
|
55
|
+
nodes.set(id, {
|
|
56
|
+
id,
|
|
57
|
+
lat,
|
|
58
|
+
lon,
|
|
59
|
+
ele: tags.ele !== undefined ? parseFloat(tags.ele) : undefined,
|
|
60
|
+
tags,
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
doc.querySelectorAll('way').forEach(wayEl => {
|
|
64
|
+
const id = wayEl.getAttribute('id') || '';
|
|
65
|
+
const nodeRefs = [];
|
|
66
|
+
wayEl.querySelectorAll(':scope > nd').forEach(ndEl => {
|
|
67
|
+
const ref = ndEl.getAttribute('ref') || '';
|
|
68
|
+
if (ref)
|
|
69
|
+
nodeRefs.push(ref);
|
|
70
|
+
});
|
|
71
|
+
ways.set(id, { id, nodeRefs, tags: collectTags(wayEl) });
|
|
72
|
+
});
|
|
73
|
+
doc.querySelectorAll('relation').forEach(relEl => {
|
|
74
|
+
const id = relEl.getAttribute('id') || '';
|
|
75
|
+
const members = [];
|
|
76
|
+
relEl.querySelectorAll(':scope > member').forEach(memEl => {
|
|
77
|
+
members.push({
|
|
78
|
+
type: memEl.getAttribute('type') || '',
|
|
79
|
+
ref: memEl.getAttribute('ref') || '',
|
|
80
|
+
role: memEl.getAttribute('role') || '',
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
// Keep all relations (regulatory_element etc.) so they survive a
|
|
84
|
+
// round-trip; consumers can filter by tag type.
|
|
85
|
+
relations.push({ id, members, tags: collectTags(relEl) });
|
|
86
|
+
});
|
|
87
|
+
return { nodes, ways, relations, drawtonomyOrigin };
|
|
88
|
+
}
|
|
89
|
+
// ---------- Hand-rolled fallback parser (no DOM dependency) ----------
|
|
90
|
+
const ATTR_RE = /([a-zA-Z_][\w:.-]*)\s*=\s*(?:"([^"]*)"|'([^']*)')/g;
|
|
91
|
+
function parseAttributes(attrString) {
|
|
92
|
+
const attrs = {};
|
|
93
|
+
ATTR_RE.lastIndex = 0;
|
|
94
|
+
let m;
|
|
95
|
+
while ((m = ATTR_RE.exec(attrString)) !== null) {
|
|
96
|
+
const value = m[2] !== undefined ? m[2] : m[3];
|
|
97
|
+
attrs[m[1]] = decodeXmlEntities(value);
|
|
98
|
+
}
|
|
99
|
+
return attrs;
|
|
100
|
+
}
|
|
101
|
+
function decodeXmlEntities(s) {
|
|
102
|
+
return s
|
|
103
|
+
.replace(/</g, '<')
|
|
104
|
+
.replace(/>/g, '>')
|
|
105
|
+
.replace(/"/g, '"')
|
|
106
|
+
.replace(/'/g, "'")
|
|
107
|
+
.replace(/&#(\d+);/g, (_, code) => String.fromCharCode(parseInt(code, 10)))
|
|
108
|
+
.replace(/&#x([0-9a-fA-F]+);/g, (_, code) => String.fromCharCode(parseInt(code, 16)))
|
|
109
|
+
.replace(/&/g, '&');
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Minimal XML parser supporting the subset used by Lanelet2 OSM files:
|
|
113
|
+
* elements, attributes, self-closing tags, and nested elements. XML comments
|
|
114
|
+
* and CDATA blocks are stripped first. Sufficient for `<node>`/`<way>`/
|
|
115
|
+
* `<relation>`/`<tag>`/`<nd>`/`<member>`.
|
|
116
|
+
*/
|
|
117
|
+
function parseXmlSubset(xml) {
|
|
118
|
+
// Strip XML declaration, comments, processing instructions, and CDATA.
|
|
119
|
+
let src = xml
|
|
120
|
+
.replace(/<\?[\s\S]*?\?>/g, '')
|
|
121
|
+
.replace(/<!--[\s\S]*?-->/g, '')
|
|
122
|
+
.replace(/<!\[CDATA\[[\s\S]*?\]\]>/g, '')
|
|
123
|
+
.replace(/<!DOCTYPE[\s\S]*?>/g, '');
|
|
124
|
+
const tagRe = /<\/?\s*([a-zA-Z_][\w:.-]*)((?:[^<>"']|"[^"]*"|'[^']*')*)\/?\s*>/g;
|
|
125
|
+
const stack = [];
|
|
126
|
+
let root = null;
|
|
127
|
+
let m;
|
|
128
|
+
while ((m = tagRe.exec(src)) !== null) {
|
|
129
|
+
const fullTag = m[0];
|
|
130
|
+
const name = m[1];
|
|
131
|
+
const rest = m[2];
|
|
132
|
+
const isClosing = fullTag.startsWith('</');
|
|
133
|
+
const isSelfClosing = fullTag.endsWith('/>');
|
|
134
|
+
if (isClosing) {
|
|
135
|
+
// Pop matching element.
|
|
136
|
+
const top = stack.pop();
|
|
137
|
+
if (!top || top.name !== name) {
|
|
138
|
+
// Tolerate slight mismatches by ignoring stray closers.
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
const el = { name, attrs: parseAttributes(rest), children: [] };
|
|
144
|
+
const parent = stack[stack.length - 1];
|
|
145
|
+
if (parent)
|
|
146
|
+
parent.children.push(el);
|
|
147
|
+
else
|
|
148
|
+
root = el;
|
|
149
|
+
if (!isSelfClosing)
|
|
150
|
+
stack.push(el);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return root;
|
|
154
|
+
}
|
|
155
|
+
function findChildren(el, name) {
|
|
156
|
+
return el.children.filter(c => c.name === name);
|
|
157
|
+
}
|
|
158
|
+
function collectTagsFromChildren(el) {
|
|
159
|
+
const tags = {};
|
|
160
|
+
for (const c of findChildren(el, 'tag')) {
|
|
161
|
+
const k = c.attrs.k;
|
|
162
|
+
const v = c.attrs.v ?? '';
|
|
163
|
+
if (k)
|
|
164
|
+
tags[k] = v;
|
|
165
|
+
}
|
|
166
|
+
return tags;
|
|
167
|
+
}
|
|
168
|
+
function parseOsmXmlFallback(xmlString) {
|
|
169
|
+
const root = parseXmlSubset(xmlString);
|
|
170
|
+
const nodes = new Map();
|
|
171
|
+
const ways = new Map();
|
|
172
|
+
const relations = [];
|
|
173
|
+
let drawtonomyOrigin;
|
|
174
|
+
if (!root)
|
|
175
|
+
return { nodes, ways, relations };
|
|
176
|
+
const osmRoot = root.name === 'osm' ? root : findChildren(root, 'osm')[0];
|
|
177
|
+
if (!osmRoot)
|
|
178
|
+
return { nodes, ways, relations };
|
|
179
|
+
const oLat = parseFloat(osmRoot.attrs.drawtonomy_origin_lat ?? '');
|
|
180
|
+
const oLon = parseFloat(osmRoot.attrs.drawtonomy_origin_lon ?? '');
|
|
181
|
+
if (Number.isFinite(oLat) && Number.isFinite(oLon)) {
|
|
182
|
+
drawtonomyOrigin = { lat: oLat, lon: oLon };
|
|
183
|
+
}
|
|
184
|
+
for (const child of osmRoot.children) {
|
|
185
|
+
if (child.name === 'node') {
|
|
186
|
+
const id = child.attrs.id ?? '';
|
|
187
|
+
const lat = parseFloat(child.attrs.lat ?? '0');
|
|
188
|
+
const lon = parseFloat(child.attrs.lon ?? '0');
|
|
189
|
+
const tags = collectTagsFromChildren(child);
|
|
190
|
+
nodes.set(id, {
|
|
191
|
+
id,
|
|
192
|
+
lat,
|
|
193
|
+
lon,
|
|
194
|
+
ele: tags.ele !== undefined ? parseFloat(tags.ele) : undefined,
|
|
195
|
+
tags,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
else if (child.name === 'way') {
|
|
199
|
+
const id = child.attrs.id ?? '';
|
|
200
|
+
const nodeRefs = findChildren(child, 'nd').map(c => c.attrs.ref ?? '').filter(r => r.length > 0);
|
|
201
|
+
ways.set(id, { id, nodeRefs, tags: collectTagsFromChildren(child) });
|
|
202
|
+
}
|
|
203
|
+
else if (child.name === 'relation') {
|
|
204
|
+
const id = child.attrs.id ?? '';
|
|
205
|
+
const members = findChildren(child, 'member').map(c => ({
|
|
206
|
+
type: c.attrs.type ?? '',
|
|
207
|
+
ref: c.attrs.ref ?? '',
|
|
208
|
+
role: c.attrs.role ?? '',
|
|
209
|
+
}));
|
|
210
|
+
relations.push({ id, members, tags: collectTagsFromChildren(child) });
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return { nodes, ways, relations, drawtonomyOrigin };
|
|
214
|
+
}
|
|
215
|
+
/** Parse a Lanelet2 OSM XML string into structured data. */
|
|
216
|
+
export function parseOsmXml(xmlString) {
|
|
217
|
+
const DOMParserImpl = getDomParser();
|
|
218
|
+
if (DOMParserImpl) {
|
|
219
|
+
try {
|
|
220
|
+
return parseOsmXmlWithDom(xmlString, DOMParserImpl);
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// Fall through to the hand-rolled parser.
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return parseOsmXmlFallback(xmlString);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Project lat/lon onto canvas (page) coordinates using a simple
|
|
230
|
+
* equirectangular projection centered at (centerLat, centerLon).
|
|
231
|
+
*
|
|
232
|
+
* The default scale matches drawtonomy's visual sizing convention: a 3 m wide
|
|
233
|
+
* lane renders as 50 px (16.67 px/m), so `scale = 16.67 * 111320 ≈ 1,855,000`.
|
|
234
|
+
*/
|
|
235
|
+
export function latLonToCanvas(lat, lon, centerLat, centerLon, scale = 1855000) {
|
|
236
|
+
const x = (lon - centerLon) * scale * Math.cos((centerLat * Math.PI) / 180);
|
|
237
|
+
// Page Y axis points down, latitude grows northward (= up), so flip.
|
|
238
|
+
const y = -(lat - centerLat) * scale;
|
|
239
|
+
return { x, y };
|
|
240
|
+
}
|
|
241
|
+
/** Inverse of `latLonToCanvas`: page coordinates back to lat/lon. */
|
|
242
|
+
export function canvasToLatLon(x, y, centerLat, centerLon, scale = 1855000) {
|
|
243
|
+
const lat = centerLat - y / scale;
|
|
244
|
+
const lon = centerLon + x / (scale * Math.cos((centerLat * Math.PI) / 180));
|
|
245
|
+
return { lat, lon };
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=osmParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osmParser.js","sourceRoot":"","sources":["../../src/exporter/osmParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { ShapeId } from '../types';
|
|
2
|
+
import { type OsmData } from './osmParser';
|
|
3
|
+
/**
|
|
4
|
+
* ID allocator interface. The default implementation produces predictable
|
|
5
|
+
* `shape:<kind>_<n>` ids starting from 0; callers (e.g. the editor) can pass
|
|
6
|
+
* a custom allocator to coordinate IDs with their own counters.
|
|
7
|
+
*/
|
|
8
|
+
export interface ShapeIdAllocator {
|
|
9
|
+
next(kind: 'point' | 'linestring' | 'lane'): ShapeId;
|
|
10
|
+
}
|
|
11
|
+
/** Default allocator: monotonic counter per shape kind. */
|
|
12
|
+
export declare function createShapeIdAllocator(): ShapeIdAllocator;
|
|
13
|
+
export interface ImportedPoint {
|
|
14
|
+
id: ShapeId;
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
osmId: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ImportedLinestring {
|
|
20
|
+
id: ShapeId;
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
pointIds: string[];
|
|
24
|
+
osmId: string;
|
|
25
|
+
attributes: Record<string, string>;
|
|
26
|
+
}
|
|
27
|
+
export interface ImportedLane {
|
|
28
|
+
id: ShapeId;
|
|
29
|
+
x: number;
|
|
30
|
+
y: number;
|
|
31
|
+
leftBoundaryId: string;
|
|
32
|
+
rightBoundaryId: string;
|
|
33
|
+
/**
|
|
34
|
+
* Whether the boundary's node order should be reversed when interpreted by
|
|
35
|
+
* the editor. Lanelet2 encodes lane direction via the left boundary's node
|
|
36
|
+
* order, but a sibling lane in the opposite direction may share the same
|
|
37
|
+
* boundary read backwards.
|
|
38
|
+
*/
|
|
39
|
+
invertLeft: boolean;
|
|
40
|
+
invertRight: boolean;
|
|
41
|
+
osmId: string;
|
|
42
|
+
attributes: Record<string, string>;
|
|
43
|
+
next: string[];
|
|
44
|
+
prev: string[];
|
|
45
|
+
}
|
|
46
|
+
export interface ImportBounds {
|
|
47
|
+
minX: number;
|
|
48
|
+
maxX: number;
|
|
49
|
+
minY: number;
|
|
50
|
+
maxY: number;
|
|
51
|
+
centerX: number;
|
|
52
|
+
centerY: number;
|
|
53
|
+
width: number;
|
|
54
|
+
height: number;
|
|
55
|
+
}
|
|
56
|
+
export interface ImportedShapes {
|
|
57
|
+
points: ImportedPoint[];
|
|
58
|
+
linestrings: ImportedLinestring[];
|
|
59
|
+
lanes: ImportedLane[];
|
|
60
|
+
bounds: ImportBounds;
|
|
61
|
+
/**
|
|
62
|
+
* Geographic center used as the canvas origin during projection. The host
|
|
63
|
+
* app should call `setMapOrigin(originLatLon)` so that the map background
|
|
64
|
+
* lines up with the imported lanes at page (0, 0).
|
|
65
|
+
*/
|
|
66
|
+
originLatLon?: {
|
|
67
|
+
lat: number;
|
|
68
|
+
lon: number;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export interface OsmToShapesOptions {
|
|
72
|
+
/** Custom id allocator. A fresh `createShapeIdAllocator()` is used when omitted. */
|
|
73
|
+
idAllocator?: ShapeIdAllocator;
|
|
74
|
+
/**
|
|
75
|
+
* Restrict conversion to the given lanelet relation IDs. When omitted, all
|
|
76
|
+
* `type=lanelet` relations are converted (regulatory_element etc. are
|
|
77
|
+
* always skipped here; they are preserved separately via the OSM sidecar).
|
|
78
|
+
*/
|
|
79
|
+
selectedLaneIds?: readonly string[];
|
|
80
|
+
}
|
|
81
|
+
interface Point2d {
|
|
82
|
+
x: number;
|
|
83
|
+
y: number;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Decide whether to reverse the left and/or right boundary so the lane is
|
|
87
|
+
* interpreted consistently by the editor.
|
|
88
|
+
*
|
|
89
|
+
* In Lanelet2, the way's node order defines the lane direction (the left
|
|
90
|
+
* boundary's direction is the lane's direction). This routine preserves that
|
|
91
|
+
* direction whenever possible, only flipping a boundary when needed to keep
|
|
92
|
+
* the right-of-left invariant.
|
|
93
|
+
*/
|
|
94
|
+
export declare function alignBoundaries(leftPoints: Point2d[], rightPoints: Point2d[]): {
|
|
95
|
+
invertLeft: boolean;
|
|
96
|
+
invertRight: boolean;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Convert parsed OSM data into editor-ready point/linestring/lane records.
|
|
100
|
+
*
|
|
101
|
+
* Pass `selectedLaneIds` to restrict to a subset of lanelet relations
|
|
102
|
+
* (selective import); leave it `undefined` to import every `type=lanelet`
|
|
103
|
+
* relation.
|
|
104
|
+
*/
|
|
105
|
+
export declare function osmToShapes(osmData: OsmData, options?: OsmToShapesOptions): ImportedShapes;
|
|
106
|
+
export {};
|
|
107
|
+
//# sourceMappingURL=osmToShapes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osmToShapes.d.ts","sourceRoot":"","sources":["../../src/exporter/osmToShapes.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1D;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,GAAG,MAAM,GAAG,OAAO,CAAA;CACrD;AAED,2DAA2D;AAC3D,wBAAgB,sBAAsB,IAAI,gBAAgB,CASzD;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAA;IACX,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,OAAO,CAAA;IACX,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAA;IACX,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,cAAc,EAAE,MAAM,CAAA;IACtB,eAAe,EAAE,MAAM,CAAA;IACvB;;;;;OAKG;IACH,UAAU,EAAE,OAAO,CAAA;IACnB,WAAW,EAAE,OAAO,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,IAAI,EAAE,MAAM,EAAE,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,aAAa,EAAE,CAAA;IACvB,WAAW,EAAE,kBAAkB,EAAE,CAAA;IACjC,KAAK,EAAE,YAAY,EAAE,CAAA;IACrB,MAAM,EAAE,YAAY,CAAA;IACpB;;;;OAIG;IACH,YAAY,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5C;AAED,MAAM,WAAW,kBAAkB;IACjC,oFAAoF;IACpF,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC9B;;;;OAIG;IACH,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACpC;AAED,UAAU,OAAO;IACf,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AAcD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,OAAO,EAAE,EACrB,WAAW,EAAE,OAAO,EAAE,GACrB;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CA4E/C;AAmFD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,GAAE,kBAAuB,GAAG,cAAc,CAmM9F"}
|