@loaders.gl/ply 3.4.0-alpha.2 → 3.4.0-alpha.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.
Files changed (49) hide show
  1. package/dist/dist.min.js +142 -70
  2. package/dist/es5/index.js +17 -13
  3. package/dist/es5/index.js.map +1 -1
  4. package/dist/es5/lib/get-ply-schema.js +0 -1
  5. package/dist/es5/lib/get-ply-schema.js.map +1 -1
  6. package/dist/es5/lib/normalize-ply.js +47 -25
  7. package/dist/es5/lib/normalize-ply.js.map +1 -1
  8. package/dist/es5/lib/parse-ply-in-batches.js +162 -172
  9. package/dist/es5/lib/parse-ply-in-batches.js.map +1 -1
  10. package/dist/es5/lib/parse-ply.js +114 -54
  11. package/dist/es5/lib/parse-ply.js.map +1 -1
  12. package/dist/es5/lib/ply-types.js.map +1 -1
  13. package/dist/es5/ply-loader.js +1 -3
  14. package/dist/es5/ply-loader.js.map +1 -1
  15. package/dist/es5/workers/ply-worker.js.map +1 -1
  16. package/dist/esm/bundle.js +0 -1
  17. package/dist/esm/bundle.js.map +1 -1
  18. package/dist/esm/index.js +6 -8
  19. package/dist/esm/index.js.map +1 -1
  20. package/dist/esm/lib/get-ply-schema.js +0 -1
  21. package/dist/esm/lib/get-ply-schema.js.map +1 -1
  22. package/dist/esm/lib/normalize-ply.js +46 -26
  23. package/dist/esm/lib/normalize-ply.js.map +1 -1
  24. package/dist/esm/lib/parse-ply-in-batches.js +18 -27
  25. package/dist/esm/lib/parse-ply-in-batches.js.map +1 -1
  26. package/dist/esm/lib/parse-ply.js +92 -56
  27. package/dist/esm/lib/parse-ply.js.map +1 -1
  28. package/dist/esm/lib/ply-types.js.map +1 -1
  29. package/dist/esm/ply-loader.js +1 -4
  30. package/dist/esm/ply-loader.js.map +1 -1
  31. package/dist/index.d.ts +3 -5
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +6 -9
  34. package/dist/lib/normalize-ply.js +33 -11
  35. package/dist/lib/parse-ply-in-batches.d.ts +1 -1
  36. package/dist/lib/parse-ply-in-batches.d.ts.map +1 -1
  37. package/dist/lib/parse-ply-in-batches.js +19 -18
  38. package/dist/lib/parse-ply.d.ts +4 -1
  39. package/dist/lib/parse-ply.d.ts.map +1 -1
  40. package/dist/lib/parse-ply.js +103 -47
  41. package/dist/lib/ply-types.d.ts +19 -11
  42. package/dist/lib/ply-types.d.ts.map +1 -1
  43. package/dist/ply-worker.js +143 -71
  44. package/package.json +4 -4
  45. package/src/index.ts +6 -6
  46. package/src/lib/normalize-ply.ts +34 -12
  47. package/src/lib/parse-ply-in-batches.ts +20 -22
  48. package/src/lib/parse-ply.ts +114 -55
  49. package/src/lib/ply-types.ts +21 -12
@@ -40,19 +40,41 @@ exports.default = normalizePLY;
40
40
  * @param attributes
41
41
  * @returns accessors []
42
42
  */
43
+ // eslint-disable-next-line complexity
43
44
  function getMeshAttributes(attributes) {
44
45
  const accessors = {};
45
- accessors.POSITION = { value: new Float32Array(attributes.vertices), size: 3 };
46
- // optional attributes data
47
- if (attributes.normals.length > 0) {
48
- accessors.NORMAL = { value: new Float32Array(attributes.normals), size: 3 };
49
- }
50
- if (attributes.uvs.length > 0) {
51
- accessors.TEXCOORD_0 = { value: new Float32Array(attributes.uvs), size: 2 };
52
- }
53
- if (attributes.colors.length > 0) {
54
- // TODO - normalized shoud be based on `uchar` flag in source data?
55
- accessors.COLOR_0 = { value: new Uint8Array(attributes.colors), size: 3, normalized: true };
46
+ for (const attributeName of Object.keys(attributes)) {
47
+ switch (attributeName) {
48
+ case 'vertices':
49
+ if (attributes.vertices.length > 0) {
50
+ accessors.POSITION = { value: new Float32Array(attributes.vertices), size: 3 };
51
+ }
52
+ break;
53
+ // optional attributes data
54
+ case 'normals':
55
+ if (attributes.normals.length > 0) {
56
+ accessors.NORMAL = { value: new Float32Array(attributes.normals), size: 3 };
57
+ }
58
+ break;
59
+ case 'uvs':
60
+ if (attributes.uvs.length > 0) {
61
+ accessors.TEXCOORD_0 = { value: new Float32Array(attributes.uvs), size: 2 };
62
+ }
63
+ break;
64
+ case 'colors':
65
+ if (attributes.colors.length > 0) {
66
+ // TODO - normalized shoud be based on `uchar` flag in source data?
67
+ accessors.COLOR_0 = { value: new Uint8Array(attributes.colors), size: 3, normalized: true };
68
+ }
69
+ break;
70
+ case 'indices':
71
+ break;
72
+ default:
73
+ if (attributes[attributeName].length > 0) {
74
+ accessors[attributeName] = { value: new Float32Array(attributes[attributeName]), size: 1 };
75
+ }
76
+ break;
77
+ }
56
78
  }
57
79
  return accessors;
58
80
  }
@@ -4,5 +4,5 @@ import { PLYMesh } from './ply-types';
4
4
  * @param iterator
5
5
  * @param options
6
6
  */
7
- export default function parsePLYInBatches(iterator: AsyncIterable<ArrayBuffer> | Iterable<ArrayBuffer>, options: any): AsyncIterable<PLYMesh>;
7
+ export declare function parsePLYInBatches(iterator: AsyncIterable<ArrayBuffer> | Iterable<ArrayBuffer>, options: any): AsyncIterable<PLYMesh>;
8
8
  //# sourceMappingURL=parse-ply-in-batches.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse-ply-in-batches.d.ts","sourceRoot":"","sources":["../../src/lib/parse-ply-in-batches.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAC,OAAO,EAAyC,MAAM,aAAa,CAAC;AAI5E;;;;GAIG;AACH,wBAA+B,iBAAiB,CAC9C,QAAQ,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,EAC5D,OAAO,EAAE,GAAG,GACX,aAAa,CAAC,OAAO,CAAC,CAexB"}
1
+ {"version":3,"file":"parse-ply-in-batches.d.ts","sourceRoot":"","sources":["../../src/lib/parse-ply-in-batches.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAC,OAAO,EAAoD,MAAM,aAAa,CAAC;AAIvF;;;;GAIG;AACH,wBAAuB,iBAAiB,CACtC,QAAQ,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,EAC5D,OAAO,EAAE,GAAG,GACX,aAAa,CAAC,OAAO,CAAC,CAexB"}
@@ -25,6 +25,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
25
25
  return (mod && mod.__esModule) ? mod : { "default": mod };
26
26
  };
27
27
  Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.parsePLYInBatches = void 0;
28
29
  const loader_utils_1 = require("@loaders.gl/loader-utils");
29
30
  const normalize_ply_1 = __importDefault(require("./normalize-ply"));
30
31
  let currentElement;
@@ -47,7 +48,7 @@ async function* parsePLYInBatches(iterator, options) {
47
48
  }
48
49
  yield (0, normalize_ply_1.default)(header, attributes, options);
49
50
  }
50
- exports.default = parsePLYInBatches;
51
+ exports.parsePLYInBatches = parsePLYInBatches;
51
52
  /**
52
53
  * Parses header
53
54
  * @param lineIterator
@@ -112,22 +113,22 @@ async function parsePLYHeader(lineIterator, options) {
112
113
  }
113
114
  return header;
114
115
  }
115
- function makePLYElementProperty(propertValues, propertyNameMapping) {
116
- const property = {
117
- type: propertValues[0]
118
- };
119
- if (property.type === 'list') {
120
- property.name = propertValues[3];
121
- property.countType = propertValues[1];
122
- property.itemType = propertValues[2];
123
- }
124
- else {
125
- property.name = propertValues[1];
126
- }
127
- if (propertyNameMapping && property.name in propertyNameMapping) {
128
- property.name = propertyNameMapping[property.name];
116
+ function makePLYElementProperty(propertyValues, propertyNameMapping) {
117
+ const type = propertyValues[0];
118
+ switch (type) {
119
+ case 'list':
120
+ return {
121
+ type,
122
+ name: propertyValues[3],
123
+ countType: propertyValues[1],
124
+ itemType: propertyValues[2]
125
+ };
126
+ default:
127
+ return {
128
+ type,
129
+ name: propertyValues[1]
130
+ };
129
131
  }
130
- return property;
131
132
  }
132
133
  // ASCII PARSING
133
134
  /**
@@ -153,7 +154,7 @@ async function parseASCII(lineIterator, header) {
153
154
  currentElement++;
154
155
  currentElementCount = 0;
155
156
  }
156
- const element = parseASCIIElement(header.elements[currentElement].properties, line);
157
+ const element = parsePLYElement(header.elements[currentElement].properties, line);
157
158
  handleElement(attributes, header.elements[currentElement].name, element);
158
159
  currentElementCount++;
159
160
  }
@@ -197,7 +198,7 @@ function parseASCIINumber(n, type) {
197
198
  * @param line
198
199
  * @returns element
199
200
  */
200
- function parseASCIIElement(properties, line) {
201
+ function parsePLYElement(properties, line) {
201
202
  const values = line.split(/\s+/);
202
203
  const element = {};
203
204
  for (let i = 0; i < properties.length; i++) {
@@ -1,8 +1,11 @@
1
1
  import type { PLYMesh } from './ply-types';
2
+ export type ParsePLYOptions = {
3
+ propertyNameMapping?: Record<string, string>;
4
+ };
2
5
  /**
3
6
  * @param data
4
7
  * @param options
5
8
  * @returns
6
9
  */
7
- export default function parsePLY(data: ArrayBuffer | string, options?: {}): PLYMesh;
10
+ export declare function parsePLY(data: ArrayBuffer | string, options?: ParsePLYOptions): PLYMesh;
8
11
  //# sourceMappingURL=parse-ply.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse-ply.d.ts","sourceRoot":"","sources":["../../src/lib/parse-ply.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EACV,OAAO,EAMR,MAAM,aAAa,CAAC;AAGrB;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,EAAE,OAAO,KAAK,GAAG,OAAO,CAclF"}
1
+ {"version":3,"file":"parse-ply.d.ts","sourceRoot":"","sources":["../../src/lib/parse-ply.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EACV,OAAO,EAMR,MAAM,aAAa,CAAC;AAGrB,MAAM,MAAM,eAAe,GAAG;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAc3F"}
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.parsePLY = void 0;
6
7
  const normalize_ply_1 = __importDefault(require("./normalize-ply"));
7
8
  /**
8
9
  * @param data
@@ -23,7 +24,7 @@ function parsePLY(data, options = {}) {
23
24
  }
24
25
  return (0, normalize_ply_1.default)(header, attributes);
25
26
  }
26
- exports.default = parsePLY;
27
+ exports.parsePLY = parsePLY;
27
28
  /**
28
29
  * @param data
29
30
  * @param options
@@ -48,6 +49,7 @@ function parseHeader(data, options) {
48
49
  * @param options
49
50
  * @returns header
50
51
  */
52
+ // eslint-disable-next-line complexity
51
53
  function parseHeaderLines(lines, headerLength, options) {
52
54
  const header = {
53
55
  comments: [],
@@ -76,6 +78,7 @@ function parseHeaderLines(lines, headerLength, options) {
76
78
  header.comments.push(line);
77
79
  break;
78
80
  case 'element':
81
+ // Start new element, store previous element
79
82
  if (currentElement) {
80
83
  header.elements.push(currentElement);
81
84
  }
@@ -86,42 +89,82 @@ function parseHeaderLines(lines, headerLength, options) {
86
89
  };
87
90
  break;
88
91
  case 'property':
89
- if (!currentElement) {
90
- break;
92
+ if (currentElement) {
93
+ const property = makePLYElementProperty(lineValues);
94
+ if (options?.propertyNameMapping && property.name in options?.propertyNameMapping) {
95
+ property.name = options?.propertyNameMapping[property.name];
96
+ }
97
+ currentElement.properties.push(property);
91
98
  }
92
- currentElement.properties.push(makePLYElementProperty(lineValues, options.propertyNameMapping));
93
99
  break;
94
100
  default:
95
101
  // eslint-disable-next-line
96
102
  console.log('unhandled', lineType, lineValues);
97
103
  }
98
104
  }
99
- if (currentElement !== undefined) {
105
+ // Store in-progress element
106
+ if (currentElement) {
100
107
  header.elements.push(currentElement);
101
108
  }
102
109
  return header;
103
110
  }
111
+ /** Generate attributes arrays from the header */
112
+ // eslint-disable-next-line complexity
113
+ function getPLYAttributes(header) {
114
+ // TODO Generate only the attribute arrays actually in the header
115
+ const attributes = {
116
+ indices: [],
117
+ vertices: [],
118
+ normals: [],
119
+ uvs: [],
120
+ colors: []
121
+ };
122
+ for (const element of header.elements) {
123
+ if (element.name === 'vertex') {
124
+ for (const property of element.properties) {
125
+ switch (property.name) {
126
+ case 'x':
127
+ case 'y':
128
+ case 'z':
129
+ case 'nx':
130
+ case 'ny':
131
+ case 'nz':
132
+ case 's':
133
+ case 't':
134
+ case 'red':
135
+ case 'green':
136
+ case 'blue':
137
+ break;
138
+ default:
139
+ // Add any non-geometry attributes
140
+ attributes[property.name] = [];
141
+ break;
142
+ }
143
+ }
144
+ }
145
+ }
146
+ return attributes;
147
+ }
104
148
  /**
105
- * @param propertValues
106
- * @param propertyNameMapping
149
+ * @param propertyValues
107
150
  * @returns property of ply element
108
151
  */
109
- function makePLYElementProperty(propertValues, propertyNameMapping) {
110
- const property = {
111
- type: propertValues[0]
112
- };
113
- if (property.type === 'list') {
114
- property.name = propertValues[3];
115
- property.countType = propertValues[1];
116
- property.itemType = propertValues[2];
117
- }
118
- else {
119
- property.name = propertValues[1];
120
- }
121
- if (propertyNameMapping && property.name in propertyNameMapping) {
122
- property.name = propertyNameMapping[property.name];
152
+ function makePLYElementProperty(propertyValues) {
153
+ const type = propertyValues[0];
154
+ switch (type) {
155
+ case 'list':
156
+ return {
157
+ type,
158
+ name: propertyValues[3],
159
+ countType: propertyValues[1],
160
+ itemType: propertyValues[2]
161
+ };
162
+ default:
163
+ return {
164
+ type,
165
+ name: propertyValues[1]
166
+ };
123
167
  }
124
- return property;
125
168
  }
126
169
  /**
127
170
  * Parses ASCII number
@@ -159,7 +202,7 @@ function parseASCIINumber(n, type) {
159
202
  * @param line
160
203
  * @returns ASCII element
161
204
  */
162
- function parseASCIIElement(properties, line) {
205
+ function parsePLYElement(properties, line) {
163
206
  const values = line.split(/\s+/);
164
207
  const element = {};
165
208
  for (let i = 0; i < properties.length; i++) {
@@ -184,13 +227,7 @@ function parseASCIIElement(properties, line) {
184
227
  */
185
228
  function parseASCII(data, header) {
186
229
  // PLY ascii format specification, as per http://en.wikipedia.org/wiki/PLY_(file_format)
187
- const attributes = {
188
- indices: [],
189
- vertices: [],
190
- normals: [],
191
- uvs: [],
192
- colors: []
193
- };
230
+ const attributes = getPLYAttributes(header);
194
231
  let result;
195
232
  const patternBody = /end_header\s([\s\S]*)$/;
196
233
  let body = '';
@@ -208,7 +245,7 @@ function parseASCII(data, header) {
208
245
  currentElement++;
209
246
  currentElementCount = 0;
210
247
  }
211
- const element = parseASCIIElement(header.elements[currentElement].properties, line);
248
+ const element = parsePLYElement(header.elements[currentElement].properties, line);
212
249
  handleElement(attributes, header.elements[currentElement].name, element);
213
250
  currentElementCount++;
214
251
  }
@@ -223,15 +260,40 @@ function parseASCII(data, header) {
223
260
  // eslint-disable-next-line complexity
224
261
  function handleElement(buffer, elementName, element = {}) {
225
262
  if (elementName === 'vertex') {
226
- buffer.vertices.push(element.x, element.y, element.z);
227
- if ('nx' in element && 'ny' in element && 'nz' in element) {
228
- buffer.normals.push(element.nx, element.ny, element.nz);
229
- }
230
- if ('s' in element && 't' in element) {
231
- buffer.uvs.push(element.s, element.t);
232
- }
233
- if ('red' in element && 'green' in element && 'blue' in element) {
234
- buffer.colors.push(element.red, element.green, element.blue);
263
+ for (const propertyName of Object.keys(element)) {
264
+ switch (propertyName) {
265
+ case 'x':
266
+ buffer.vertices.push(element.x, element.y, element.z);
267
+ break;
268
+ case 'y':
269
+ case 'z':
270
+ break;
271
+ case 'nx':
272
+ if ('nx' in element && 'ny' in element && 'nz' in element) {
273
+ buffer.normals.push(element.nx, element.ny, element.nz);
274
+ }
275
+ break;
276
+ case 'ny':
277
+ case 'nz':
278
+ break;
279
+ case 's':
280
+ if ('s' in element && 't' in element) {
281
+ buffer.uvs.push(element.s, element.t);
282
+ }
283
+ break;
284
+ case 't':
285
+ break;
286
+ case 'red':
287
+ if ('red' in element && 'green' in element && 'blue' in element) {
288
+ buffer.colors.push(element.red, element.green, element.blue);
289
+ }
290
+ break;
291
+ case 'green':
292
+ case 'blue':
293
+ break;
294
+ default:
295
+ buffer[propertyName].push(element[propertyName]);
296
+ }
235
297
  }
236
298
  }
237
299
  else if (elementName === 'face') {
@@ -326,13 +388,7 @@ function binaryReadElement(dataview, at, properties, littleEndian) {
326
388
  * @returns [attributes] of data
327
389
  */
328
390
  function parseBinary(data, header) {
329
- const attributes = {
330
- indices: [],
331
- vertices: [],
332
- normals: [],
333
- uvs: [],
334
- colors: []
335
- };
391
+ const attributes = getPLYAttributes(header);
336
392
  const littleEndian = header.format === 'binary_little_endian';
337
393
  const body = new DataView(data, header.headerLength);
338
394
  let result;
@@ -1,29 +1,37 @@
1
1
  import type { Mesh } from '@loaders.gl/schema';
2
+ /** A parsed PLY mesh */
3
+ export type PLYMesh = Mesh & {
4
+ loader: 'ply';
5
+ loaderData: PLYHeader;
6
+ };
7
+ /** A PLY header */
2
8
  export type PLYHeader = {
3
9
  format?: string;
4
10
  comments: string[];
5
- elements: any[];
11
+ elements: PLYElement[];
6
12
  version?: string;
7
13
  headerLength?: number;
8
14
  };
9
- /** A parsed PLY mesh */
10
- export type PLYMesh = Mesh & {
11
- loader: 'ply';
12
- loaderData: PLYHeader;
13
- };
15
+ /** A general mesh header */
14
16
  export type MeshHeader = {
15
17
  vertexCount?: number;
16
18
  boundingBox?: [[number, number, number], [number, number, number]];
17
19
  };
20
+ /** The parsed columnar values */
18
21
  export type PLYAttributes = {
19
22
  [index: string]: number[];
20
23
  };
21
- export type PLYProperty = {
22
- [index: string]: string;
23
- };
24
- export type ASCIIElement = {
24
+ /** A top level PLY element (vertex, face, ...) */
25
+ export type PLYElement = {
25
26
  name: string;
26
27
  count: number;
27
- properties: any[];
28
+ properties: PLYProperty[];
29
+ };
30
+ /** One property in a top-level PLY element */
31
+ export type PLYProperty = {
32
+ name: string;
33
+ type: string;
34
+ countType?: string;
35
+ itemType?: string;
28
36
  };
29
37
  //# sourceMappingURL=ply-types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ply-types.d.ts","sourceRoot":"","sources":["../../src/lib/ply-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,oBAAoB,CAAC;AAE7C,MAAM,MAAM,SAAS,GAAG;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,wBAAwB;AACxB,MAAM,MAAM,OAAO,GAAG,IAAI,GAAG;IAC3B,MAAM,EAAE,KAAK,CAAC;IACd,UAAU,EAAE,SAAS,CAAC;CACvB,CAAC;AAIF,MAAM,MAAM,UAAU,GAAG;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACpE,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,GAAG,EAAE,CAAC;CACnB,CAAC"}
1
+ {"version":3,"file":"ply-types.d.ts","sourceRoot":"","sources":["../../src/lib/ply-types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,oBAAoB,CAAC;AAE7C,wBAAwB;AACxB,MAAM,MAAM,OAAO,GAAG,IAAI,GAAG;IAC3B,MAAM,EAAE,KAAK,CAAC;IACd,UAAU,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,mBAAmB;AACnB,MAAM,MAAM,SAAS,GAAG;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAIF,4BAA4B;AAC5B,MAAM,MAAM,UAAU,GAAG;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACpE,CAAC;AAEF,iCAAiC;AACjC,MAAM,MAAM,aAAa,GAAG;IAC1B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,mDAAmD;AACnD,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,WAAW,EAAE,CAAC;CAC3B,CAAC;AAEF,8CAA8C;AAC9C,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC"}