@loaders.gl/graphs 5.0.0-alpha.9 → 5.0.0-beta.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.
Files changed (78) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +121 -4
  3. package/THIRD-PARTY-NOTICES.md +17 -0
  4. package/dist/dot-loader-types.d.ts +25 -8
  5. package/dist/dot-loader-types.d.ts.map +1 -1
  6. package/dist/dot-loader-types.js +2 -2
  7. package/dist/dot-loader-types.js.map +1 -1
  8. package/dist/dot-loader.cjs +638 -47
  9. package/dist/dot-loader.cjs.map +3 -3
  10. package/dist/dot-loader.d.ts +10 -6
  11. package/dist/dot-loader.d.ts.map +1 -1
  12. package/dist/dot-loader.js +3 -3
  13. package/dist/dot-loader.js.map +1 -1
  14. package/dist/dot-types.d.ts +6 -1
  15. package/dist/dot-types.d.ts.map +1 -1
  16. package/dist/gexf-loader-types.d.ts +53 -0
  17. package/dist/gexf-loader-types.d.ts.map +1 -0
  18. package/dist/gexf-loader-types.js +26 -0
  19. package/dist/gexf-loader-types.js.map +1 -0
  20. package/dist/gexf-loader.cjs +1304 -0
  21. package/dist/gexf-loader.cjs.map +6 -0
  22. package/dist/gexf-loader.d.ts +24 -0
  23. package/dist/gexf-loader.d.ts.map +1 -0
  24. package/dist/gexf-loader.js +13 -0
  25. package/dist/gexf-loader.js.map +1 -0
  26. package/dist/gexf-types.d.ts +16 -0
  27. package/dist/gexf-types.d.ts.map +1 -0
  28. package/dist/gexf-types.js +5 -0
  29. package/dist/gexf-types.js.map +1 -0
  30. package/dist/graph-types.d.ts +28 -0
  31. package/dist/graph-types.d.ts.map +1 -1
  32. package/dist/graphml-loader-types.d.ts +24 -8
  33. package/dist/graphml-loader-types.d.ts.map +1 -1
  34. package/dist/graphml-loader-types.js +2 -2
  35. package/dist/graphml-loader-types.js.map +1 -1
  36. package/dist/graphml-loader.cjs +670 -60
  37. package/dist/graphml-loader.cjs.map +3 -3
  38. package/dist/graphml-loader.d.ts +10 -6
  39. package/dist/graphml-loader.d.ts.map +1 -1
  40. package/dist/graphml-loader.js +3 -3
  41. package/dist/graphml-loader.js.map +1 -1
  42. package/dist/index.cjs +927 -59
  43. package/dist/index.cjs.map +3 -3
  44. package/dist/index.d.ts +7 -0
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +1 -0
  47. package/dist/index.js.map +1 -1
  48. package/dist/lib/build-graph-tables.d.ts +4 -0
  49. package/dist/lib/build-graph-tables.d.ts.map +1 -0
  50. package/dist/lib/build-graph-tables.js +143 -0
  51. package/dist/lib/build-graph-tables.js.map +1 -0
  52. package/dist/lib/parse-dot.d.ts +3 -1
  53. package/dist/lib/parse-dot.d.ts.map +1 -1
  54. package/dist/lib/parse-dot.js +38 -21
  55. package/dist/lib/parse-dot.js.map +1 -1
  56. package/dist/lib/parse-gexf.d.ts +5 -0
  57. package/dist/lib/parse-gexf.d.ts.map +1 -0
  58. package/dist/lib/parse-gexf.js +380 -0
  59. package/dist/lib/parse-gexf.js.map +1 -0
  60. package/dist/lib/parse-graphml.d.ts +2 -1
  61. package/dist/lib/parse-graphml.d.ts.map +1 -1
  62. package/dist/lib/parse-graphml.js +50 -27
  63. package/dist/lib/parse-graphml.js.map +1 -1
  64. package/package.json +13 -5
  65. package/src/dot-loader-types.ts +15 -5
  66. package/src/dot-loader.ts +7 -4
  67. package/src/dot-types.ts +7 -1
  68. package/src/gexf-loader-types.ts +41 -0
  69. package/src/gexf-loader.ts +17 -0
  70. package/src/gexf-types.ts +21 -0
  71. package/src/graph-types.ts +35 -0
  72. package/src/graphml-loader-types.ts +14 -5
  73. package/src/graphml-loader.ts +7 -4
  74. package/src/index.ts +9 -0
  75. package/src/lib/build-graph-tables.ts +208 -0
  76. package/src/lib/parse-dot.ts +44 -21
  77. package/src/lib/parse-gexf.ts +388 -0
  78. package/src/lib/parse-graphml.ts +86 -34
package/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ loaders.gl is licensed under the MIT license
2
+
3
+ Copyright (c) vis.gl contributors
4
+ Copyright (c) 2015 Uber Technologies, Inc.
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
23
+
24
+ For adapted portions, see THIRD-PARTY-NOTICES.md and the applicable upstream terms.
package/README.md CHANGED
@@ -1,6 +1,65 @@
1
1
  # @loaders.gl/graphs
2
2
 
3
- Framework-independent loaders for GraphML and Graphviz DOT documents.
3
+ Framework-independent loaders for GraphML, Graphviz DOT, and GEXF documents.
4
+
5
+ ## Graph output shapes
6
+
7
+ Graph loaders default to `graphml.shape: 'arrow-table'`, `dot.shape: 'arrow-table'`,
8
+ or `gexf.shape: 'arrow-table'`.
9
+ The result uses the standard table collection shape:
10
+
11
+ ```typescript
12
+ {
13
+ shape: 'tables',
14
+ tables: [
15
+ {name: 'nodes', table: {shape: 'arrow-table', schema, data: nodes}},
16
+ {name: 'edges', table: {shape: 'arrow-table', schema, data: edges}}
17
+ ]
18
+ }
19
+ ```
20
+
21
+ Each `data` is an Apache Arrow `Table`; each `schema` is a loaders.gl schema.
22
+ The node table has `id`, nullable `label`, and nullable `attributes` columns.
23
+ The edge table additionally has `sourceId`, `targetId`, and `directed`.
24
+ Structural identifiers are strings, including numeric DOT edge IDs. Row order follows
25
+ document order after DOT strict-edge coalescing. Edges may reference undeclared nodes;
26
+ the loaders preserve their endpoints without inventing GraphML nodes.
27
+
28
+ Application attributes live in a typed `attributes` struct, so keys such as `id` cannot
29
+ replace structural columns. GraphML declarations determine Boolean, Int32, Int64,
30
+ Float32, Float64, and Utf8 fields, including unused declarations on empty graphs.
31
+ GraphML `long` values are parsed as exact integers and read as `bigint`.
32
+ Invalid or out-of-range integer values make the affected attribute column Utf8,
33
+ preserving values as strings. DOT scalar types are inferred across the whole column;
34
+ numbers use Float64, booleans use Bool, and mixed scalar types use Utf8. Nested DOT
35
+ subgraph membership uses List and Struct columns. Missing values become Arrow nulls.
36
+ Empty undeclared attributes have a Struct with no child fields.
37
+
38
+ ```typescript
39
+ const graph = await load('network.graphml', GraphMLLoader);
40
+ if (graph.shape === 'tables' && graph.tables[0].table.shape === 'arrow-table') {
41
+ const nodes = graph.tables[0].table.data;
42
+ console.log(nodes.getChild('id')?.get(0));
43
+ }
44
+ ```
45
+
46
+ Select `'object-row-table'` for the same named table collection with object arrays in
47
+ `table.data`. This mode also preserves GraphML long values as `bigint`; it retains original
48
+ application attribute values rather than applying Arrow column normalization.
49
+
50
+ For compatibility with existing graph-layer consumers, request plain graph records:
51
+
52
+ ```typescript
53
+ const graph = await load('network.graphml', GraphMLLoader, {
54
+ graphml: {shape: 'plain-graph-data'}
55
+ });
56
+ // DOT: {dot: {shape: 'plain-graph-data'}}
57
+ ```
58
+
59
+ Plain output retains `shape: 'plain-graph-data'`, `nodes`, and `edges`, with original
60
+ DOT edge ID types. GraphML long values in this compatibility mode remain JavaScript
61
+ numbers and can lose precision outside the safe integer range.
62
+ DOT graph metadata is available as `graph.metadata` in every output shape.
4
63
 
5
64
  ## GraphML loader
6
65
 
@@ -17,7 +76,7 @@ For synchronous parsing, import `GraphMLLoaderWithParser` from
17
76
  `@loaders.gl/graphs/graphml-loader` and pass it to `parseSync` from `@loaders.gl/core`.
18
77
  The package root exports metadata only; asynchronous core APIs preload the implementation.
19
78
 
20
- The result is `GraphData` with `shape: 'plain-graph-data'`, `nodes`, and `edges`.
79
+ The explicit plain compatibility result is `GraphData` with `shape: 'plain-graph-data'`, `nodes`, and `edges`.
21
80
  Nodes have `id`, optional `label`, and optional `attributes`. Edges additionally have
22
81
  `sourceId`, `targetId`, and `directed`. This shape is compatible with
23
82
  `createGraphFromData` in `@deck.gl-community/graph-layers`.
@@ -25,7 +84,7 @@ Nodes have `id`, optional `label`, and optional `attributes`. Edges additionally
25
84
  Supported constructs include node and edge identifiers, generated IDs for unnamed edges,
26
85
  `edgedefault` and per-edge direction overrides, node/edge/all keys, typed data and defaults,
27
86
  unknown data keys, and namespace-prefixed elements. Numeric and boolean keys become JavaScript
28
- values; other values remain strings. Nested XML data becomes a JSON string.
87
+ values; string values preserve their whitespace. Nested XML data becomes a JSON string.
29
88
 
30
89
  Only the first graph is returned. Nested graphs, hyperedges, ports, and graph-level data are
31
90
  ignored. Nodes without IDs and edges without endpoints are skipped. This is a permissive
@@ -45,8 +104,10 @@ const graph = await load('network.dot', DOTLoader);
45
104
  Use `DOTLoaderWithParser` from `@loaders.gl/graphs/dot-loader` with `parseSync`
46
105
  for synchronous text or UTF-8 `ArrayBuffer` parsing. `DOTLoader` recognizes `.dot` and `.gv` files.
47
106
 
48
- The loader returns the same plain `GraphData` node/edge shape as GraphML, plus typed
107
+ The loader returns the same named node/edge table collection as GraphML, plus typed
49
108
  DOT metadata: graph ID, direction, strictness, graph attributes, and subgraph descriptors.
109
+ Unknown backslash sequences are preserved for downstream attribute interpretation.
110
+ Backslashes followed by physical line endings join quoted identifiers and labels across lines.
50
111
  Identifiers remain strings, including numeric-looking IDs. Unquoted numeric attributes
51
112
  become numbers; quoted attributes remain strings. Node and edge `label` attributes are
52
113
  also exposed as record labels.
@@ -64,3 +125,59 @@ This is a parser for the supported DOT subset, not a Graphviz renderer. Node por
64
125
  subgraph endpoints in edge statements, and concatenated quoted strings are unsupported.
65
126
  Port syntax is rejected; identifiers containing colons must be quoted. Truncated input,
66
127
  trailing content, and edge operators inconsistent with the graph declaration are rejected.
128
+
129
+ ## GEXF loader
130
+
131
+ `GEXFLoader` reads static GEXF 1.2 (including `1.2draft`) and 1.3 documents.
132
+
133
+ ```typescript
134
+ import {load} from '@loaders.gl/core';
135
+ import {GEXFLoader} from '@loaders.gl/graphs';
136
+
137
+ const graph = await load('network.gexf', GEXFLoader);
138
+ // Optional: {gexf: {shape: 'object-row-table'}} or {gexf: {shape: 'plain-graph-data'}}
139
+ ```
140
+
141
+ For synchronous parsing, use `GEXFLoaderWithParser` from
142
+ `@loaders.gl/graphs/gexf-loader` with `parseSync`. The package root exports metadata
143
+ only; asynchronous core APIs preload the parser. Text and UTF-8 binary inputs are supported.
144
+ The loader recognizes `.gexf` and `application/gexf+xml`.
145
+
146
+ The default result contains named Arrow node and edge tables in the standard `tables`
147
+ collection. Application attributes use declaration titles inside the `attributes` struct;
148
+ node and edge declarations are scoped separately. Boolean, integer, long, float, double,
149
+ and string declarations retain their Arrow types, even for empty graphs. Byte and short
150
+ attributes use Int32. `anyURI`, date, char, bigdecimal, and biginteger values retain their text
151
+ as Utf8. Long integers remain exact `bigint` values in every output shape, including
152
+ plain records. Invalid or out-of-range scalar values promote the affected Arrow field
153
+ to Utf8, preserving the original text.
154
+
155
+ List attributes become typed Arrow Lists, including unused declarations. Both bracketed
156
+ comma-separated lists and legacy pipe/comma/semicolon-separated values are accepted.
157
+ Single and double quotes preserve embedded delimiters and whitespace; malformed
158
+ list quoting is rejected. An empty value becomes an empty list. Defaults apply before explicit values; absent
159
+ attributes without defaults become Arrow nulls. String values and labels preserve whitespace.
160
+
161
+ Native edge weight and kind properties are retained under `attributes.gexf.weight` and
162
+ `attributes.gexf.kind`. Namespaced color, position, size, shape, and thickness elements
163
+ are retained as nested structs under `attributes.gexf.viz`, with numeric coordinates,
164
+ color components, sizes, and thicknesses. Shape names, image URIs, and hex colors remain
165
+ strings. The application attribute title `gexf` is reserved to prevent collisions.
166
+
167
+ `graph.metadata` contains the document version, default direction, and an `attributes`
168
+ object with creator, description, keywords, and lastmodifieddate when supplied.
169
+ Directed and undirected edges, per-edge direction overrides, self-loops, and parallel
170
+ edges are preserved in document order. IDs remain strings; missing edge IDs receive
171
+ stable `edge-<index>` identifiers that avoid collisions with supplied IDs.
172
+
173
+ This is a static graph parser, not a complete GEXF schema validator. Dynamic graphs,
174
+ slice graphs, temporal values/spells, hierarchical/parent structures, mutual edges,
175
+ unsupported attribute types, and document type declarations are rejected explicitly.
176
+ Duplicate IDs or attribute declarations, undeclared application attributes, missing
177
+ required record attributes, and endpoints referencing undeclared nodes are rejected.
178
+ Foreign namespace extensions are ignored. See the [GEXF specification](https://gexf.net/schema.html).
179
+
180
+ ## Sources and credits
181
+
182
+ See [THIRD-PARTY-NOTICES.md](./THIRD-PARTY-NOTICES.md) for implementation lineage
183
+ and applicable notices, and the project-wide [References and credits](https://loaders.gl/docs/references-and-credits).
@@ -0,0 +1,17 @@
1
+ # @loaders.gl/graphs: sources and credits
2
+
3
+ Graph loaders are developed by vis.gl contributors against DOT, GEXF and GraphML format definitions. Separately installed fast-xml-parser supplies XML parsing; Apache Arrow supplies columnar tables.
4
+
5
+ ## Scope and maintenance
6
+
7
+ Original loaders.gl contributions are covered by [LICENSE](./LICENSE). The upstream
8
+ notices above apply to their respective portions and do not change those terms.
9
+ Source adaptations, separately installed libraries, format definitions and test
10
+ data are different contributions. This index is not a transitive dependency
11
+ bill of materials. Runtime dependencies can bring additional notices.
12
+
13
+ Version information is recorded where the repository preserves it. Unpinned
14
+ historical ports are identified by retained source and Git history; no upstream
15
+ version is inferred from a current dependency. Keep copyright headers, full
16
+ terms, source/version information and material modification notes when updating.
17
+ Retain this file and the applicable licenses when redistributing bundles or workers.
@@ -1,9 +1,18 @@
1
- import type { DOTGraphData } from "./dot-types.js";
1
+ import type { DOTOutput } from "./dot-types.js";
2
+ import type { GraphShape } from "./graph-types.js";
3
+ /** Options for selecting the DOT graph output representation. */
4
+ export type DOTLoaderOptions = {
5
+ /** Format-specific graph options. */
6
+ dot?: {
7
+ /** Representation of each named table; defaults to Arrow. */
8
+ shape?: GraphShape;
9
+ };
10
+ };
2
11
  /** Preloads the DOT parser implementation. */
3
12
  declare function preload(): Promise<{
4
- parse: (data: ArrayBuffer) => Promise<DOTGraphData>;
5
- parseSync: (data: ArrayBuffer) => DOTGraphData;
6
- parseTextSync: typeof import("./lib/parse-dot").parseDOT;
13
+ parse: (data: ArrayBuffer, options?: DOTLoaderOptions) => Promise<DOTOutput>;
14
+ parseSync: (data: ArrayBuffer, options?: DOTLoaderOptions) => DOTOutput;
15
+ parseTextSync: (data: string, options?: DOTLoaderOptions) => DOTOutput;
7
16
  name: "DOT";
8
17
  id: "dot";
9
18
  module: "graphs";
@@ -12,9 +21,13 @@ declare function preload(): Promise<{
12
21
  mimeTypes: ["text/vnd.graphviz", "text/x-graphviz", "application/vnd.graphviz"];
13
22
  text: true;
14
23
  worker: false;
15
- dataType: DOTGraphData;
24
+ dataType: DOTOutput;
16
25
  batchType: never;
17
- options: {};
26
+ options: {
27
+ readonly dot: {
28
+ readonly shape: "arrow-table";
29
+ };
30
+ };
18
31
  preload: typeof preload;
19
32
  }>;
20
33
  /** Metadata-only loader for Graphviz DOT documents. */
@@ -27,9 +40,13 @@ export declare const DOTLoader: {
27
40
  readonly mimeTypes: ["text/vnd.graphviz", "text/x-graphviz", "application/vnd.graphviz"];
28
41
  readonly text: true;
29
42
  readonly worker: false;
30
- readonly dataType: DOTGraphData;
43
+ readonly dataType: DOTOutput;
31
44
  readonly batchType: never;
32
- readonly options: {};
45
+ readonly options: {
46
+ readonly dot: {
47
+ readonly shape: "arrow-table";
48
+ };
49
+ };
33
50
  readonly preload: typeof preload;
34
51
  };
35
52
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"dot-loader-types.d.ts","sourceRoot":"","sources":["../src/dot-loader-types.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,YAAY,EAAC,uBAAoB;AAK9C,8CAA8C;AAC9C,iBAAe,OAAO;;;;;;;;;;;;cAeS,YAAY;eACtB,KAAK;;;GAbzB;AAED,uDAAuD;AACvD,eAAO,MAAM,SAAS;;;;;;;;;uBASS,YAAY;wBACtB,KAAK;;;CAGsB,CAAC"}
1
+ {"version":3,"file":"dot-loader-types.d.ts","sourceRoot":"","sources":["../src/dot-loader-types.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,SAAS,EAAC,uBAAoB;AAC3C,OAAO,KAAK,EAAC,UAAU,EAAC,yBAAsB;AAE9C,iEAAiE;AACjE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qCAAqC;IACrC,GAAG,CAAC,EAAE;QACJ,6DAA6D;QAC7D,KAAK,CAAC,EAAE,UAAU,CAAC;KACpB,CAAC;CACH,CAAC;AAKF,8CAA8C;AAC9C,iBAAe,OAAO;;;;;;;;;;;;cAeS,SAAS;eACnB,KAAK;;;;;;;GAbzB;AAED,uDAAuD;AACvD,eAAO,MAAM,SAAS;;;;;;;;;uBASS,SAAS;wBACnB,KAAK;;;;;;;CAGqC,CAAC"}
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
  // @ts-ignore __VERSION__ is injected by the build.
5
- const VERSION = typeof "5.0.0-alpha.9" !== 'undefined' ? "5.0.0-alpha.9" : 'latest';
5
+ const VERSION = typeof "5.0.0-beta.1" !== 'undefined' ? "5.0.0-beta.1" : 'latest';
6
6
  /** Preloads the DOT parser implementation. */
7
7
  async function preload() {
8
8
  const { DOTLoaderWithParser } = await import('@loaders.gl/graphs/dot-loader');
@@ -20,7 +20,7 @@ export const DOTLoader = {
20
20
  worker: false,
21
21
  dataType: null,
22
22
  batchType: null,
23
- options: {},
23
+ options: { dot: { shape: 'arrow-table' } },
24
24
  preload
25
25
  };
26
26
  //# sourceMappingURL=dot-loader-types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dot-loader-types.js","sourceRoot":"","sources":["../src/dot-loader-types.ts"],"names":[],"mappings":"AAAA,aAAa;AACb,+BAA+B;AAC/B,oCAAoC;AAKpC,mDAAmD;AACnD,MAAM,OAAO,GAAG,sBAAkB,KAAK,WAAW,CAAC,CAAC,iBAAa,CAAC,CAAC,QAAQ,CAAC;AAE5E,8CAA8C;AAC9C,KAAK,UAAU,OAAO;IACpB,MAAM,EAAC,mBAAmB,EAAC,GAAG,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC;IAC5E,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED,uDAAuD;AACvD,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,KAAK;IACX,EAAE,EAAE,KAAK;IACT,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC;IACzB,SAAS,EAAE,CAAC,mBAAmB,EAAE,iBAAiB,EAAE,0BAA0B,CAAC;IAC/E,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,KAAK;IACb,QAAQ,EAAE,IAA+B;IACzC,SAAS,EAAE,IAAa;IACxB,OAAO,EAAE,EAAE;IACX,OAAO;CACuC,CAAC"}
1
+ {"version":3,"file":"dot-loader-types.js","sourceRoot":"","sources":["../src/dot-loader-types.ts"],"names":[],"mappings":"AAAA,aAAa;AACb,+BAA+B;AAC/B,oCAAoC;AAepC,mDAAmD;AACnD,MAAM,OAAO,GAAG,qBAAkB,KAAK,WAAW,CAAC,CAAC,gBAAa,CAAC,CAAC,QAAQ,CAAC;AAE5E,8CAA8C;AAC9C,KAAK,UAAU,OAAO;IACpB,MAAM,EAAC,mBAAmB,EAAC,GAAG,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC;IAC5E,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED,uDAAuD;AACvD,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,KAAK;IACX,EAAE,EAAE,KAAK;IACT,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC;IACzB,SAAS,EAAE,CAAC,mBAAmB,EAAE,iBAAiB,EAAE,0BAA0B,CAAC;IAC/E,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,KAAK;IACb,QAAQ,EAAE,IAA4B;IACtC,SAAS,EAAE,IAAa;IACxB,OAAO,EAAE,EAAC,GAAG,EAAE,EAAC,KAAK,EAAE,aAAa,EAAC,EAAC;IACtC,OAAO;CACsD,CAAC"}