@webda/ql 4.0.0-beta.5 → 4.0.0-beta.7
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 +72 -31
- package/lib/WebdaQLLexer.d.ts +44 -30
- package/lib/WebdaQLLexer.d.ts.map +1 -1
- package/lib/WebdaQLLexer.js +257 -152
- package/lib/WebdaQLLexer.js.map +1 -1
- package/lib/WebdaQLParserLexer.d.ts +44 -30
- package/lib/WebdaQLParserLexer.d.ts.map +1 -1
- package/lib/WebdaQLParserLexer.js +257 -152
- package/lib/WebdaQLParserLexer.js.map +1 -1
- package/lib/WebdaQLParserListener.d.ts +203 -30
- package/lib/WebdaQLParserListener.d.ts.map +1 -1
- package/lib/WebdaQLParserParser.d.ts +242 -44
- package/lib/WebdaQLParserParser.d.ts.map +1 -1
- package/lib/WebdaQLParserParser.js +2054 -715
- package/lib/WebdaQLParserParser.js.map +1 -1
- package/lib/WebdaQLParserVisitor.d.ts +126 -17
- package/lib/WebdaQLParserVisitor.d.ts.map +1 -1
- package/lib/aggregation-query.d.ts +95 -0
- package/lib/aggregation-query.d.ts.map +1 -0
- package/lib/aggregation-query.js +104 -0
- package/lib/aggregation-query.js.map +1 -0
- package/lib/aggregation-select.spec.d.ts +2 -0
- package/lib/aggregation-select.spec.d.ts.map +1 -0
- package/lib/aggregation-select.spec.js +165 -0
- package/lib/aggregation-select.spec.js.map +1 -0
- package/lib/aggregation.d.ts +97 -0
- package/lib/aggregation.d.ts.map +1 -0
- package/lib/aggregation.js +241 -0
- package/lib/aggregation.js.map +1 -0
- package/lib/aggregation.spec.d.ts +2 -0
- package/lib/aggregation.spec.d.ts.map +1 -0
- package/lib/aggregation.spec.js +360 -0
- package/lib/aggregation.spec.js.map +1 -0
- package/lib/bind.d.ts.map +1 -1
- package/lib/bind.js +29 -0
- package/lib/bind.js.map +1 -1
- package/lib/filter.d.ts +54 -0
- package/lib/filter.d.ts.map +1 -0
- package/lib/filter.js +135 -0
- package/lib/filter.js.map +1 -0
- package/lib/filter.spec.d.ts +2 -0
- package/lib/filter.spec.d.ts.map +1 -0
- package/lib/filter.spec.js +124 -0
- package/lib/filter.spec.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/query.d.ts +173 -12
- package/lib/query.d.ts.map +1 -1
- package/lib/query.js +529 -64
- package/lib/query.js.map +1 -1
- package/lib/query.spec.js +7 -4
- package/lib/query.spec.js.map +1 -1
- package/lib/statements.spec.d.ts +2 -0
- package/lib/statements.spec.d.ts.map +1 -0
- package/lib/statements.spec.js +423 -0
- package/lib/statements.spec.js.map +1 -0
- package/lib/webdaql-string.d.ts +9 -0
- package/lib/webdaql-string.d.ts.map +1 -1
- package/lib/webdaql-string.js +9 -8
- package/lib/webdaql-string.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This module is part of Webda Application Framework that allows you to quickly develop applications with all modern prerequisites: Security, Extensibility, GraphQL, REST, CloudNative [https://webda.io](https://webda.io)
|
|
4
4
|
|
|
5
|
-
<img src="https://webda.io/
|
|
5
|
+
<img src="https://webda.io/img/webda.svg" width="128" />
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|
|
|
@@ -23,14 +23,10 @@ You need WQL when you call `store.query()` or a relation's `.query()` method. Ev
|
|
|
23
23
|
|
|
24
24
|
```typescript
|
|
25
25
|
// Query the User repository
|
|
26
|
-
const { results } = await User.getRepository().query(
|
|
27
|
-
`email = 'alice@example.com' LIMIT 1`
|
|
28
|
-
);
|
|
26
|
+
const { results } = await User.getRepository().query(`email = 'alice@example.com' LIMIT 1`);
|
|
29
27
|
|
|
30
28
|
// Query a relation
|
|
31
|
-
const { results: posts } = await user.posts.query(
|
|
32
|
-
`status = 'published' ORDER BY createdAt DESC LIMIT 10`
|
|
33
|
-
);
|
|
29
|
+
const { results: posts } = await user.posts.query(`status = 'published' ORDER BY createdAt DESC LIMIT 10`);
|
|
34
30
|
```
|
|
35
31
|
|
|
36
32
|
### Install
|
|
@@ -44,10 +40,19 @@ npm install @webda/ql
|
|
|
44
40
|
### Syntax overview
|
|
45
41
|
|
|
46
42
|
```
|
|
47
|
-
expression? orderExpression? limitExpression? offsetExpression?
|
|
43
|
+
expression? orderExpression? limitExpression? offsetExpression? -- a filter query (implicit SELECT)
|
|
44
|
+
SELECT f1, f2 [WHERE expression] [ORDER BY ...] [LIMIT n] [OFFSET t]
|
|
45
|
+
SELECT g, COUNT(*) AS n, SUM(f) AS s [WHERE expression] [GROUP BY g] [ORDER BY ...] [LIMIT n]
|
|
46
|
+
DELETE [WHERE expression] [LIMIT n]
|
|
47
|
+
UPDATE SET a = v, b.c = v [WHERE expression] [LIMIT n]
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
Keywords are uppercase only: `select`, `delete`, `set`, `where`... in lowercase are field names. Since the
|
|
51
|
+
aggregation syntax, uppercase `COUNT`, `SUM`, `AVG`, `MIN`, `MAX`, `AS`, `DISTINCT` and `GROUP BY` are reserved too
|
|
52
|
+
(breaking for attributes with those uppercase names).
|
|
53
|
+
|
|
50
54
|
**Filter expressions** support:
|
|
55
|
+
|
|
51
56
|
- Comparison: `field = value`, `field != value`, `field > value`, `field >= value`, `field < value`, `field <= value`
|
|
52
57
|
- Pattern match: `field LIKE "pattern"` (`_` = single char, `%` = any chars)
|
|
53
58
|
- Set membership: `field IN [value, value, ...]`
|
|
@@ -56,6 +61,7 @@ expression? orderExpression? limitExpression? offsetExpression?
|
|
|
56
61
|
- Logic: `AND`, `OR`, `( ... )`
|
|
57
62
|
|
|
58
63
|
**Pagination / ordering:**
|
|
64
|
+
|
|
59
65
|
- `ORDER BY field [ASC|DESC], ...`
|
|
60
66
|
- `LIMIT <integer>`
|
|
61
67
|
- `OFFSET "<continuationToken>"`
|
|
@@ -66,17 +72,12 @@ expression? orderExpression? limitExpression? offsetExpression?
|
|
|
66
72
|
import * as WebdaQL from "@webda/ql";
|
|
67
73
|
|
|
68
74
|
// Parse and evaluate against an in-memory object
|
|
69
|
-
const validator = new WebdaQL.QueryValidator(
|
|
70
|
-
`status = 'published' AND viewCount >= 100`
|
|
71
|
-
);
|
|
75
|
+
const validator = new WebdaQL.QueryValidator(`status = 'published' AND viewCount >= 100`);
|
|
72
76
|
const post = { status: "published", viewCount: 150 };
|
|
73
77
|
console.log(validator.eval(post)); // true
|
|
74
78
|
|
|
75
79
|
// Prepend a mandatory condition to a user-supplied query
|
|
76
|
-
const merged = WebdaQL.PrependCondition(
|
|
77
|
-
`status = 'published' ORDER BY title LIMIT 10`,
|
|
78
|
-
`authorId = 'u-123'`
|
|
79
|
-
);
|
|
80
|
+
const merged = WebdaQL.PrependCondition(`status = 'published' ORDER BY title LIMIT 10`, `authorId = 'u-123'`);
|
|
80
81
|
// => 'status = "published" AND authorId = "u-123" ORDER BY title ASC LIMIT 10'
|
|
81
82
|
```
|
|
82
83
|
|
|
@@ -93,30 +94,70 @@ WebdaQL.bind("priority >= ? LIMIT ?", [2, 10]); // priority >= 2 LIMIT 10
|
|
|
93
94
|
|
|
94
95
|
Placeholders are only allowed where a value is expected, values are escaped by type, and `= ?` / `!= ?` with `null` become `IS NULL` / `IS NOT NULL`. Template literals passed straight to a query method are escaped the same way at compile time by `webdac`. See [Parameters](../../docs/pages/Modules/ql/Parameters.md).
|
|
95
96
|
|
|
97
|
+
### Statements: SELECT, DELETE, UPDATE
|
|
98
|
+
|
|
99
|
+
WebdaQL parses `SELECT`, `DELETE` and `UPDATE` statements; the parsed `Query` carries `type` (`"SELECT"` for a plain filter), `fields` (SELECT) and `assignments` (UPDATE), and `toString()` round-trips them.
|
|
100
|
+
|
|
101
|
+
- **Field lists are parse-level only**: the Query operations (REST, gRPC, MCP, GraphQL) refuse a `SELECT` field list with a 400, and repositories refuse it in `query()`.
|
|
102
|
+
- **DELETE and UPDATE are repository-level operations**: `useRepository(Model).deleteMany("DELETE WHERE ...")` and `updateMany("UPDATE SET ... WHERE ...")` run them in bulk and return the affected count. They **bypass events, hooks, validation and `canAct`**. The Query operations refuse them with a 400, and `query()` / `iterate()` refuse them.
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
const q = WebdaQL.parse("UPDATE SET status = 'archived' WHERE owner = 'bob' LIMIT 10");
|
|
106
|
+
q.type; // "UPDATE"
|
|
107
|
+
q.assignments; // [{ field: "status", value: "archived" }]
|
|
108
|
+
await useRepository(Task).updateMany("UPDATE SET status = ? WHERE owner = ?", ["archived", "bob"]); // count
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
See [Statements](../../docs/pages/Modules/ql/Statements.md).
|
|
112
|
+
|
|
113
|
+
### Aggregations
|
|
114
|
+
|
|
115
|
+
A `SELECT` with aggregate functions or `GROUP BY` parses into an `AggregationQuery` (`parse(q).aggregation`), the
|
|
116
|
+
same AST `toAggregationQuery()` builds from the object form used by `Model.aggregate()`. Stores translate it
|
|
117
|
+
natively, or stream objects through the in-memory `Aggregator`.
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
const q = WebdaQL.parse("SELECT status, COUNT(*) AS n, SUM(points) AS total GROUP BY status ORDER BY total DESC");
|
|
121
|
+
q.aggregation.metrics; // { n: { fn: "COUNT" }, total: { fn: "SUM", field: "points" } }
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
See [Statements](../../docs/pages/Modules/ql/Statements.md#aggregation-select--group-by) and
|
|
125
|
+
[Repositories](../../docs/pages/Concepts/Stores/Repositories.md#aggregation).
|
|
126
|
+
|
|
96
127
|
### API reference
|
|
97
128
|
|
|
98
|
-
| Export
|
|
99
|
-
|
|
100
|
-
| `QueryValidator`
|
|
101
|
-
| `bind(query, params)`
|
|
102
|
-
| `escape(parts, values)`
|
|
103
|
-
| `validateSyntax(query)`
|
|
104
|
-
| `PrependCondition(query, condition)`
|
|
105
|
-
| `ExpressionBuilder`
|
|
106
|
-
| `AndExpression`
|
|
107
|
-
| `OrExpression`
|
|
108
|
-
| `ComparisonExpression`
|
|
109
|
-
| `
|
|
110
|
-
| `
|
|
129
|
+
| Export | Description |
|
|
130
|
+
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
131
|
+
| `QueryValidator` | Parses a WQL string; `eval(obj)` evaluates it, `toString()` normalizes it |
|
|
132
|
+
| `bind(query, params)` | Binds `?` / `:name` placeholders to escaped values |
|
|
133
|
+
| `escape(parts, values)` | Escapes template literal values (used by the compile-time rewrite) |
|
|
134
|
+
| `validateSyntax(query)` | Checks a query against the grammar without evaluating it; placeholders allowed |
|
|
135
|
+
| `PrependCondition(query, condition)` | Merges a condition in front of an existing query, preserving ORDER BY / LIMIT / OFFSET |
|
|
136
|
+
| `ExpressionBuilder` | ANTLR visitor that builds the optimized expression AST |
|
|
137
|
+
| `AndExpression` | Logic AND node |
|
|
138
|
+
| `OrExpression` | Logic OR node |
|
|
139
|
+
| `ComparisonExpression` | Comparison leaf node |
|
|
140
|
+
| `parse(query, allowedFields?)` | Parses a filter or statement; `allowedFields` checks SELECT fields and SET targets |
|
|
141
|
+
| `validateQueryFields(query, allowed)` | Checks SELECT fields and SET targets against a field list |
|
|
142
|
+
| `assertFilterQuery(query)` | Refuses DELETE, UPDATE, SELECT field lists and aggregations |
|
|
143
|
+
| `toAggregationQuery(input, params?)` | Converts the object form of an aggregation to a validated `AggregationQuery` |
|
|
144
|
+
| `validateAggregation(query)` | Validates an `AggregationQuery` (paths, aliases, functions, ORDER BY, LIMIT) |
|
|
145
|
+
| `Aggregator` | In-memory aggregation engine: `add(item)` then `rows()` |
|
|
146
|
+
| `compareValues(a, b)` | The cross-backend ordering of aggregated values (null < numbers < strings) |
|
|
147
|
+
| `AggregationError` | Runtime aggregation error with a `code` (`AGGREGATION_NOT_NATIVE`, `AGGREGATION_TOO_MANY_GROUPS`) |
|
|
148
|
+
| `Query` | Parsed query result: `{ type, filter, fields?, assignments?, aggregation?, orderBy?, limit?, continuationToken? }` |
|
|
149
|
+
| `OrderBy` | `{ field: string; direction: "ASC" \| "DESC" }` |
|
|
111
150
|
|
|
112
151
|
### See also
|
|
113
152
|
|
|
114
153
|
- [WQL Syntax reference](../../docs/pages/Modules/ql/Syntax.md)
|
|
115
154
|
- [Operators](../../docs/pages/Modules/ql/Operators.md)
|
|
116
155
|
- [Parameters](../../docs/pages/Modules/ql/Parameters.md) — binding values safely
|
|
156
|
+
- [Statements](../../docs/pages/Modules/ql/Statements.md) — SELECT, DELETE, UPDATE and repository bulk operations
|
|
117
157
|
- [Store Translators](../../docs/pages/Modules/ql/Translators.md) — how each Store backend converts WQL
|
|
118
158
|
|
|
119
159
|
<!-- README_FOOTER -->
|
|
160
|
+
|
|
120
161
|
## Sponsors
|
|
121
162
|
|
|
122
163
|
<!--
|
|
@@ -125,12 +166,12 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
|
|
|
125
166
|
|
|
126
167
|
Arize AI is a machine learning observability and model monitoring platform. It helps you visualize, monitor, and explain your machine learning models. [Learn more](https://arize.com)
|
|
127
168
|
|
|
128
|
-
[<img src="https://
|
|
169
|
+
[<img src="https://webda.io/img/sponsors/arize.svg" width="200">](https://arize.com)
|
|
129
170
|
|
|
130
171
|
Loopingz is a software development company that provides consulting and development services. [Learn more](https://loopingz.com)
|
|
131
172
|
|
|
132
|
-
[<img src="https://
|
|
173
|
+
[<img src="https://webda.io/img/sponsors/loopingz.png" width="200">](https://loopingz.com)
|
|
133
174
|
|
|
134
175
|
Tellae is an innovative consulting firm specialized in cities transportation issues. We provide our clients, both public and private, with solutions to support your strategic and operational decisions. [Learn more](https://tellae.fr)
|
|
135
176
|
|
|
136
|
-
[<img src="https://tellae.
|
|
177
|
+
[<img src="https://webda.io/img/sponsors/tellae.svg" width="200">](https://tellae.fr)
|
package/lib/WebdaQLLexer.d.ts
CHANGED
|
@@ -11,36 +11,50 @@ export declare class WebdaQLLexer extends Lexer {
|
|
|
11
11
|
static readonly DOUBLE_QUOTE_SYMB = 6;
|
|
12
12
|
static readonly LR_SQ_BRACKET = 7;
|
|
13
13
|
static readonly RR_SQ_BRACKET = 8;
|
|
14
|
-
static readonly
|
|
15
|
-
static readonly
|
|
16
|
-
static readonly
|
|
17
|
-
static readonly
|
|
18
|
-
static readonly
|
|
19
|
-
static readonly
|
|
20
|
-
static readonly
|
|
21
|
-
static readonly
|
|
22
|
-
static readonly
|
|
23
|
-
static readonly
|
|
24
|
-
static readonly
|
|
25
|
-
static readonly
|
|
26
|
-
static readonly
|
|
27
|
-
static readonly
|
|
28
|
-
static readonly
|
|
29
|
-
static readonly
|
|
30
|
-
static readonly
|
|
31
|
-
static readonly
|
|
32
|
-
static readonly
|
|
33
|
-
static readonly
|
|
34
|
-
static readonly
|
|
35
|
-
static readonly
|
|
36
|
-
static readonly
|
|
37
|
-
static readonly
|
|
38
|
-
static readonly
|
|
39
|
-
static readonly
|
|
40
|
-
static readonly
|
|
41
|
-
static readonly
|
|
42
|
-
static readonly
|
|
43
|
-
static readonly
|
|
14
|
+
static readonly DELETE = 9;
|
|
15
|
+
static readonly UPDATE = 10;
|
|
16
|
+
static readonly SELECT = 11;
|
|
17
|
+
static readonly SET = 12;
|
|
18
|
+
static readonly WHERE = 13;
|
|
19
|
+
static readonly AND = 14;
|
|
20
|
+
static readonly OR = 15;
|
|
21
|
+
static readonly EQUAL = 16;
|
|
22
|
+
static readonly NOT_EQUAL = 17;
|
|
23
|
+
static readonly GREATER = 18;
|
|
24
|
+
static readonly GREATER_OR_EQUAL = 19;
|
|
25
|
+
static readonly LESS = 20;
|
|
26
|
+
static readonly LESS_OR_EQUAL = 21;
|
|
27
|
+
static readonly LIKE = 22;
|
|
28
|
+
static readonly IN = 23;
|
|
29
|
+
static readonly CONTAINS = 24;
|
|
30
|
+
static readonly IS = 25;
|
|
31
|
+
static readonly NOT = 26;
|
|
32
|
+
static readonly NULL = 27;
|
|
33
|
+
static readonly TRUE = 28;
|
|
34
|
+
static readonly FALSE = 29;
|
|
35
|
+
static readonly LIMIT = 30;
|
|
36
|
+
static readonly OFFSET = 31;
|
|
37
|
+
static readonly ORDER_BY = 32;
|
|
38
|
+
static readonly ASC = 33;
|
|
39
|
+
static readonly DESC = 34;
|
|
40
|
+
static readonly GROUP_BY = 35;
|
|
41
|
+
static readonly AS = 36;
|
|
42
|
+
static readonly DISTINCT = 37;
|
|
43
|
+
static readonly COUNT = 38;
|
|
44
|
+
static readonly SUM = 39;
|
|
45
|
+
static readonly AVG = 40;
|
|
46
|
+
static readonly MIN = 41;
|
|
47
|
+
static readonly MAX = 42;
|
|
48
|
+
static readonly STAR = 43;
|
|
49
|
+
static readonly DQUOTED_STRING_LITERAL = 44;
|
|
50
|
+
static readonly SQUOTED_STRING_LITERAL = 45;
|
|
51
|
+
static readonly INTEGER_LITERAL = 46;
|
|
52
|
+
static readonly NUMBER_LITERAL = 47;
|
|
53
|
+
static readonly POSITIONAL_PARAMETER = 48;
|
|
54
|
+
static readonly NAMED_PARAMETER = 49;
|
|
55
|
+
static readonly IDENTIFIER = 50;
|
|
56
|
+
static readonly IDENTIFIER_WITH_NUMBER = 51;
|
|
57
|
+
static readonly FUNCTION_IDENTIFIER_WITH_UNDERSCORE = 52;
|
|
44
58
|
static readonly channelNames: string[];
|
|
45
59
|
static readonly modeNames: string[];
|
|
46
60
|
static readonly ruleNames: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebdaQLLexer.d.ts","sourceRoot":"","sources":["../src/WebdaQLLexer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAK1C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKpD,qBAAa,YAAa,SAAQ,KAAK;IACrC,gBAAuB,KAAK,KAAK;IACjC,gBAAuB,UAAU,KAAK;IACtC,gBAAuB,UAAU,KAAK;IACtC,gBAAuB,KAAK,KAAK;IACjC,gBAAuB,iBAAiB,KAAK;IAC7C,gBAAuB,iBAAiB,KAAK;IAC7C,gBAAuB,aAAa,KAAK;IACzC,gBAAuB,aAAa,KAAK;IACzC,gBAAuB,GAAG,KAAK;
|
|
1
|
+
{"version":3,"file":"WebdaQLLexer.d.ts","sourceRoot":"","sources":["../src/WebdaQLLexer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAK1C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKpD,qBAAa,YAAa,SAAQ,KAAK;IACrC,gBAAuB,KAAK,KAAK;IACjC,gBAAuB,UAAU,KAAK;IACtC,gBAAuB,UAAU,KAAK;IACtC,gBAAuB,KAAK,KAAK;IACjC,gBAAuB,iBAAiB,KAAK;IAC7C,gBAAuB,iBAAiB,KAAK;IAC7C,gBAAuB,aAAa,KAAK;IACzC,gBAAuB,aAAa,KAAK;IACzC,gBAAuB,MAAM,KAAK;IAClC,gBAAuB,MAAM,MAAM;IACnC,gBAAuB,MAAM,MAAM;IACnC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,KAAK,MAAM;IAClC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,EAAE,MAAM;IAC/B,gBAAuB,KAAK,MAAM;IAClC,gBAAuB,SAAS,MAAM;IACtC,gBAAuB,OAAO,MAAM;IACpC,gBAAuB,gBAAgB,MAAM;IAC7C,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,aAAa,MAAM;IAC1C,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,EAAE,MAAM;IAC/B,gBAAuB,QAAQ,MAAM;IACrC,gBAAuB,EAAE,MAAM;IAC/B,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,KAAK,MAAM;IAClC,gBAAuB,KAAK,MAAM;IAClC,gBAAuB,MAAM,MAAM;IACnC,gBAAuB,QAAQ,MAAM;IACrC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,QAAQ,MAAM;IACrC,gBAAuB,EAAE,MAAM;IAC/B,gBAAuB,QAAQ,MAAM;IACrC,gBAAuB,KAAK,MAAM;IAClC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,sBAAsB,MAAM;IACnD,gBAAuB,sBAAsB,MAAM;IACnD,gBAAuB,eAAe,MAAM;IAC5C,gBAAuB,cAAc,MAAM;IAC3C,gBAAuB,oBAAoB,MAAM;IACjD,gBAAuB,eAAe,MAAM;IAC5C,gBAAuB,UAAU,MAAM;IACvC,gBAAuB,sBAAsB,MAAM;IACnD,gBAAuB,mCAAmC,MAAM;IAGhE,gBAAuB,YAAY,EAAE,MAAM,EAAE,CAAuC;IAGpF,gBAAuB,SAAS,EAAE,MAAM,EAAE,CAAoB;IAE9D,gBAAuB,SAAS,EAAE,MAAM,EAAE,CA2DxC;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAkDpC;IACF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAsDrC;IACF,gBAAuB,UAAU,EAAE,UAAU,CAI3C;IAIF,IAAW,UAAU,IAAI,UAAU,CAElC;IAGD,YAAY,KAAK,EAAE,UAAU,EAG5B;IAGD,IAAW,eAAe,IAAI,MAAM,CAEnC;IAGD,IAAW,SAAS,IAAI,MAAM,EAAE,CAE/B;IAGD,IAAW,aAAa,IAAI,MAAM,CAEjC;IAGD,IAAW,YAAY,IAAI,MAAM,EAAE,CAElC;IAGD,IAAW,SAAS,IAAI,MAAM,EAAE,CAE/B;IAED,gBAAuB,cAAc,EAAE,MAAM,CAwL4B;IACzE,OAAc,KAAK,EAAE,GAAG,CAAC;IACzB,WAAkB,IAAI,IAAI,GAAG,CAM5B;CACF"}
|