@objectstack/cli 10.0.0 → 10.2.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.
Files changed (53) hide show
  1. package/dist/commands/compile.js +2 -2
  2. package/dist/commands/compile.js.map +1 -1
  3. package/dist/commands/doctor.js +1 -1
  4. package/dist/commands/doctor.js.map +1 -1
  5. package/dist/commands/lint.js +1 -1
  6. package/dist/commands/lint.js.map +1 -1
  7. package/dist/commands/migrate/apply.d.ts +19 -0
  8. package/dist/commands/migrate/apply.d.ts.map +1 -0
  9. package/dist/commands/migrate/apply.js +155 -0
  10. package/dist/commands/migrate/apply.js.map +1 -0
  11. package/dist/commands/migrate/index.d.ts +9 -0
  12. package/dist/commands/migrate/index.d.ts.map +1 -0
  13. package/dist/commands/migrate/index.js +10 -0
  14. package/dist/commands/migrate/index.js.map +1 -0
  15. package/dist/commands/migrate/plan.d.ts +16 -0
  16. package/dist/commands/migrate/plan.d.ts.map +1 -0
  17. package/dist/commands/migrate/plan.js +93 -0
  18. package/dist/commands/migrate/plan.js.map +1 -0
  19. package/dist/commands/serve.d.ts.map +1 -1
  20. package/dist/commands/serve.js +6 -0
  21. package/dist/commands/serve.js.map +1 -1
  22. package/dist/commands/validate.d.ts.map +1 -1
  23. package/dist/commands/validate.js +37 -3
  24. package/dist/commands/validate.js.map +1 -1
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +4 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/utils/schema-migrate.d.ts +26 -0
  30. package/dist/utils/schema-migrate.d.ts.map +1 -0
  31. package/dist/utils/schema-migrate.integration.test.d.ts +2 -0
  32. package/dist/utils/schema-migrate.integration.test.d.ts.map +1 -0
  33. package/dist/utils/schema-migrate.integration.test.js +83 -0
  34. package/dist/utils/schema-migrate.integration.test.js.map +1 -0
  35. package/dist/utils/schema-migrate.js +123 -0
  36. package/dist/utils/schema-migrate.js.map +1 -0
  37. package/package.json +48 -47
  38. package/dist/utils/validate-expressions.d.ts +0 -19
  39. package/dist/utils/validate-expressions.d.ts.map +0 -1
  40. package/dist/utils/validate-expressions.js +0 -201
  41. package/dist/utils/validate-expressions.js.map +0 -1
  42. package/dist/utils/validate-expressions.test.d.ts +0 -2
  43. package/dist/utils/validate-expressions.test.d.ts.map +0 -1
  44. package/dist/utils/validate-expressions.test.js +0 -320
  45. package/dist/utils/validate-expressions.test.js.map +0 -1
  46. package/dist/utils/validate-widget-bindings.d.ts +0 -74
  47. package/dist/utils/validate-widget-bindings.d.ts.map +0 -1
  48. package/dist/utils/validate-widget-bindings.js +0 -304
  49. package/dist/utils/validate-widget-bindings.js.map +0 -1
  50. package/dist/utils/validate-widget-bindings.test.d.ts +0 -2
  51. package/dist/utils/validate-widget-bindings.test.d.ts.map +0 -1
  52. package/dist/utils/validate-widget-bindings.test.js +0 -285
  53. package/dist/utils/validate-widget-bindings.test.js.map +0 -1
@@ -1,320 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { validateStackExpressions } from './validate-expressions.js';
3
- describe('validateStackExpressions (ADR-0032 build-time)', () => {
4
- const objects = [
5
- { name: 'crm_lead', fields: { rating: { type: 'number' }, status: { type: 'text' } } },
6
- ];
7
- it('passes a clean stack', () => {
8
- const issues = validateStackExpressions({
9
- objects,
10
- flows: [{
11
- name: 'lead_flow',
12
- nodes: [
13
- { id: 'start', type: 'start', config: { objectName: 'crm_lead' } },
14
- { id: 'check', type: 'decision', config: { condition: 'record.rating >= 4' } },
15
- ],
16
- edges: [{ id: 'e1', source: 'check', target: 'end', condition: 'record.rating < 4' }],
17
- }],
18
- });
19
- expect(issues).toHaveLength(0);
20
- });
21
- it('flags a brace-in-CEL condition with location + corrective message', () => {
22
- const issues = validateStackExpressions({
23
- objects,
24
- flows: [{
25
- name: 'lead_flow',
26
- nodes: [
27
- { id: 'start', type: 'start', config: { objectName: 'crm_lead' } },
28
- { id: 'check', type: 'decision', config: { condition: '{record.rating} >= 4' } },
29
- ],
30
- edges: [],
31
- }],
32
- });
33
- expect(issues).toHaveLength(1);
34
- expect(issues[0].where).toContain("flow 'lead_flow'");
35
- expect(issues[0].where).toContain("node 'check'");
36
- expect(issues[0].message).toMatch(/map literal|bare reference/);
37
- expect(issues[0].source).toBe('{record.rating} >= 4');
38
- });
39
- it('flags an unknown record field against the resolved schema (did-you-mean)', () => {
40
- const issues = validateStackExpressions({
41
- objects,
42
- flows: [{
43
- name: 'lead_flow',
44
- nodes: [
45
- { id: 'start', type: 'start', config: { objectName: 'crm_lead' } },
46
- { id: 'check', type: 'decision', config: { condition: 'record.raitng >= 4' } },
47
- ],
48
- edges: [],
49
- }],
50
- });
51
- expect(issues).toHaveLength(1);
52
- expect(issues[0].message).toMatch(/unknown field `raitng`/);
53
- expect(issues[0].message).toMatch(/did you mean `rating`/);
54
- });
55
- it('validates object validation-rule predicates too', () => {
56
- const issues = validateStackExpressions({
57
- objects: [
58
- { name: 'crm_lead', fields: { rating: {} }, validations: [{ name: 'r1', expression: '{record.rating} > 0' }] },
59
- ],
60
- });
61
- expect(issues).toHaveLength(1);
62
- expect(issues[0].where).toContain("validation 'r1'");
63
- });
64
- // #1870 — a `script` node that names no callable is a silent no-op.
65
- it('flags a script node that declares neither actionType nor function (#1870)', () => {
66
- const issues = validateStackExpressions({
67
- flows: [{
68
- name: 'helpdesk_flow',
69
- nodes: [
70
- { id: 'start', type: 'start', config: {} },
71
- { id: 'triage', type: 'script', config: { actionType: undefined } },
72
- ],
73
- edges: [],
74
- }],
75
- });
76
- expect(issues).toHaveLength(1);
77
- expect(issues[0].where).toContain("node 'triage' (script) callable");
78
- expect(issues[0].message).toMatch(/neither .*actionType.* nor .*function/);
79
- });
80
- it('accepts a script node that names a built-in action or a function (#1870)', () => {
81
- const issues = validateStackExpressions({
82
- flows: [{
83
- name: 'helpdesk_flow',
84
- nodes: [
85
- { id: 'start', type: 'start', config: {} },
86
- { id: 'mail', type: 'script', config: { actionType: 'email' } },
87
- { id: 'triage', type: 'script', config: { function: 'helpdesk.aiTriageStub' } },
88
- { id: 'inline', type: 'script', config: { script: 'variables.x = 1;' } },
89
- ],
90
- edges: [],
91
- }],
92
- });
93
- expect(issues).toHaveLength(0);
94
- });
95
- // #1870 DX — `functionName` is an accepted alias for `function`.
96
- it('accepts a script node that names a callable via the functionName alias', () => {
97
- const issues = validateStackExpressions({
98
- flows: [{
99
- name: 'helpdesk_flow',
100
- nodes: [
101
- { id: 'start', type: 'start', config: {} },
102
- { id: 'triage', type: 'script', config: { actionType: 'invoke_function', functionName: 'helpdesk.aiTriageStub' } },
103
- ],
104
- edges: [],
105
- }],
106
- });
107
- expect(issues).toHaveLength(0);
108
- });
109
- it('flags actionType invoke_function with no function/functionName', () => {
110
- const issues = validateStackExpressions({
111
- flows: [{
112
- name: 'helpdesk_flow',
113
- nodes: [
114
- { id: 'start', type: 'start', config: {} },
115
- { id: 'triage', type: 'script', config: { actionType: 'invoke_function', inputs: { x: 1 } } },
116
- ],
117
- edges: [],
118
- }],
119
- });
120
- expect(issues).toHaveLength(1);
121
- expect(issues[0].message).toMatch(/invoke_function.*no .*function/i);
122
- });
123
- // #1928 — bare field references are silently null in `record`-scoped sites
124
- // (field formulas + validation predicates) but correct in flattened flow
125
- // conditions. The validator wires the scope per site.
126
- describe('bare-reference detection by site scope (#1928)', () => {
127
- it('flags a bare reference in a field formula', () => {
128
- const issues = validateStackExpressions({
129
- objects: [{
130
- name: 'crm_opportunity',
131
- fields: {
132
- amount: { type: 'currency' },
133
- probability: { type: 'percent' },
134
- expected_revenue: { type: 'formula', name: 'expected_revenue', formula: 'amount * probability / 100' },
135
- },
136
- }],
137
- });
138
- expect(issues).toHaveLength(1);
139
- expect(issues[0].where).toContain("field 'expected_revenue' formula");
140
- expect(issues[0].message).toMatch(/bare reference `(amount|probability)`/);
141
- });
142
- it('flags a bare reference in a validation predicate', () => {
143
- const issues = validateStackExpressions({
144
- objects: [{
145
- name: 'crm_lead',
146
- fields: { lead_score: { type: 'number' } },
147
- validations: [{ name: 'lead_score_range', expression: 'lead_score != null && lead_score > 100' }],
148
- }],
149
- });
150
- expect(issues).toHaveLength(1);
151
- expect(issues[0].where).toContain("validation 'lead_score_range'");
152
- expect(issues[0].message).toMatch(/bare reference `lead_score`/);
153
- });
154
- it('accepts the record-qualified forms', () => {
155
- const issues = validateStackExpressions({
156
- objects: [{
157
- name: 'crm_opportunity',
158
- fields: {
159
- amount: { type: 'currency' },
160
- probability: { type: 'percent' },
161
- expected_revenue: { type: 'formula', name: 'expected_revenue', formula: 'record.amount * record.probability / 100' },
162
- },
163
- validations: [{ name: 'amt', expression: 'record.amount != null && record.amount >= 0' }],
164
- }],
165
- });
166
- expect(issues).toHaveLength(0);
167
- });
168
- it('does NOT flag bare references in a flow condition (flattened scope)', () => {
169
- const issues = validateStackExpressions({
170
- objects: [{ name: 'crm_opportunity', fields: { stage: { type: 'select' }, amount: { type: 'currency' } } }],
171
- flows: [{
172
- name: 'high_value_deal',
173
- nodes: [
174
- { id: 'start', type: 'start', config: { objectName: 'crm_opportunity', condition: 'amount > 100000 && previous.amount <= 100000' } },
175
- ],
176
- edges: [{ id: 'e1', source: 'start', target: 'end', condition: 'stage != "closed_won"' }],
177
- }],
178
- });
179
- expect(issues).toHaveLength(0);
180
- });
181
- // #1928 tier 3 — a likely field typo in a flow condition is a non-blocking warning.
182
- it('warns (severity=warning) on a likely field typo in a flow condition', () => {
183
- const issues = validateStackExpressions({
184
- objects: [{ name: 'crm_opportunity', fields: { stage: { type: 'select' }, amount: { type: 'currency' } } }],
185
- flows: [{
186
- name: 'opp_won',
187
- nodes: [
188
- { id: 'start', type: 'start', config: { objectName: 'crm_opportunity', condition: 'stagee == "closed_won"' } },
189
- ],
190
- edges: [],
191
- }],
192
- });
193
- expect(issues).toHaveLength(1);
194
- expect(issues[0].severity).toBe('warning');
195
- expect(issues[0].message).toMatch(/did you mean `stage`/);
196
- });
197
- it('does not warn when the bare ref is far from any field (likely a flow variable)', () => {
198
- const issues = validateStackExpressions({
199
- objects: [{ name: 'crm_opportunity', fields: { stage: { type: 'select' } } }],
200
- flows: [{
201
- name: 'renewal',
202
- nodes: [{ id: 'start', type: 'start', config: { objectName: 'crm_opportunity' } }],
203
- edges: [{ id: 'e1', source: 'start', target: 'end', condition: 'expiring_deals.length > 0' }],
204
- }],
205
- });
206
- expect(issues).toHaveLength(0);
207
- });
208
- it('tags record-scoped bare-ref issues as errors', () => {
209
- const issues = validateStackExpressions({
210
- objects: [{
211
- name: 'crm_lead',
212
- fields: { lead_score: { type: 'number' } },
213
- validations: [{ name: 'r', expression: 'lead_score > 100' }],
214
- }],
215
- });
216
- expect(issues).toHaveLength(1);
217
- expect(issues[0].severity).toBe('error');
218
- });
219
- });
220
- describe('action visible/disabled predicates (record-scoped) — #2183 class', () => {
221
- it('flags a bare-field `visible` on a stack action (the trap that hid Mark Done)', () => {
222
- const issues = validateStackExpressions({
223
- objects: [{ name: 'showcase_task', fields: { done: { type: 'boolean' }, status: { type: 'select' } } }],
224
- actions: [{ name: 'mark_done', objectName: 'showcase_task', type: 'script', locations: ['record_header'], visible: '!done' }],
225
- });
226
- const v = issues.filter(i => i.where.includes("action 'mark_done' visible"));
227
- expect(v).toHaveLength(1);
228
- expect(v[0].severity).toBe('error');
229
- expect(v[0].message).toMatch(/bare reference `done`/);
230
- });
231
- it('accepts the record-qualified form', () => {
232
- const issues = validateStackExpressions({
233
- objects: [{ name: 'showcase_task', fields: { done: { type: 'boolean' } } }],
234
- actions: [{ name: 'mark_done', objectName: 'showcase_task', type: 'script', visible: '!record.done' }],
235
- });
236
- expect(issues).toHaveLength(0);
237
- });
238
- it('accepts ambient globals (ctx / features / user) used by platform actions', () => {
239
- const issues = validateStackExpressions({
240
- objects: [{ name: 'sys_user', fields: { id: { type: 'text' }, email_verified: { type: 'boolean' } } }],
241
- actions: [{ name: 'verify_email', objectName: 'sys_user', visible: 'record.id == ctx.user.id && record.email_verified == false && features.x != true' }],
242
- });
243
- expect(issues).toHaveLength(0);
244
- });
245
- it('flags a bare-field `disabled` predicate but ignores a boolean `disabled`', () => {
246
- const bad = validateStackExpressions({
247
- objects: [{ name: 'crm_lead', fields: { status: { type: 'select' } } }],
248
- actions: [{ name: 'park', objectName: 'crm_lead', disabled: 'status == "converted"' }],
249
- });
250
- expect(bad.filter(i => i.where.includes("action 'park' disabled"))).toHaveLength(1);
251
- const ok = validateStackExpressions({
252
- objects: [{ name: 'crm_lead', fields: { status: { type: 'select' } } }],
253
- actions: [{ name: 'park', objectName: 'crm_lead', disabled: true }],
254
- });
255
- expect(ok).toHaveLength(0);
256
- });
257
- it('validates an action attached to an object (record scope = parent object)', () => {
258
- const issues = validateStackExpressions({
259
- objects: [{
260
- name: 'showcase_task',
261
- fields: { done: { type: 'boolean' } },
262
- actions: [{ name: 'mark_done', type: 'script', visible: '!done' }],
263
- }],
264
- });
265
- expect(issues.filter(i => i.where.includes("action 'mark_done' visible"))).toHaveLength(1);
266
- });
267
- });
268
- describe('record-scoped coverage extensions (field rules / sharing / hooks / nested when)', () => {
269
- it('flags a bare-field `readonlyWhen`/`requiredWhen` on a field', () => {
270
- const issues = validateStackExpressions({
271
- objects: [{
272
- name: 'showcase_task',
273
- fields: {
274
- done: { type: 'boolean', readonlyWhen: 'done == true' },
275
- title: { type: 'text', requiredWhen: 'status == "x"' },
276
- },
277
- }],
278
- });
279
- expect(issues.some(i => i.where.includes('readonlyWhen') && /bare reference `done`/.test(i.message))).toBe(true);
280
- expect(issues.some(i => i.where.includes('requiredWhen') && /bare reference `status`/.test(i.message))).toBe(true);
281
- });
282
- it('accepts record-qualified field rules and the master-detail `parent` namespace', () => {
283
- const issues = validateStackExpressions({
284
- objects: [{
285
- name: 'inv_line',
286
- fields: {
287
- qty: { type: 'number', readonlyWhen: "parent.status == 'paid'" },
288
- note: { type: 'text', requiredWhen: 'record.qty >= 100' },
289
- },
290
- }],
291
- });
292
- expect(issues).toHaveLength(0);
293
- });
294
- it('flags a bare-field sharing-rule condition', () => {
295
- const issues = validateStackExpressions({
296
- objects: [{ name: 'crm_account', fields: { region: { type: 'text' } } }],
297
- sharingRules: [{ name: 'sales_region', object: 'crm_account', condition: 'region == "EMEA"' }],
298
- });
299
- expect(issues.some(i => i.where.includes("sharingRule 'sales_region'") && /bare reference `region`/.test(i.message))).toBe(true);
300
- });
301
- it('flags a bare-field hook condition', () => {
302
- const issues = validateStackExpressions({
303
- objects: [{ name: 'crm_lead', fields: { status: { type: 'select' } } }],
304
- hooks: [{ name: 'on_close', object: 'crm_lead', condition: 'status == "closed"' }],
305
- });
306
- expect(issues.some(i => i.where.includes("hook 'on_close'") && /bare reference `status`/.test(i.message))).toBe(true);
307
- });
308
- it('flags a bare-field nested `when` on a conditional validation rule', () => {
309
- const issues = validateStackExpressions({
310
- objects: [{
311
- name: 'crm_account',
312
- fields: { tier: { type: 'select' } },
313
- validations: [{ name: 'cond', type: 'conditional', when: 'tier == "gold"', then: { type: 'required' } }],
314
- }],
315
- });
316
- expect(issues.some(i => i.where.includes('when') && /bare reference `tier`/.test(i.message))).toBe(true);
317
- });
318
- });
319
- });
320
- //# sourceMappingURL=validate-expressions.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validate-expressions.test.js","sourceRoot":"","sources":["../../src/utils/validate-expressions.test.ts"],"names":[],"mappings":"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"}
@@ -1,74 +0,0 @@
1
- /**
2
- * Build-time dashboard widget binding diagnostics (issues #1719, #1721).
3
- *
4
- * Runs at `objectstack validate`/`compile`/`build` AFTER the stack has been
5
- * schema-parsed, so every widget's `dataset` reference can be linked to its
6
- * `defineDataset` and each entry in `dimensions`/`values` resolved to a
7
- * declared dimension/measure. This is the semantic/cross-reference phase —
8
- * the rules here cannot run during plain Zod parsing of the raw widget
9
- * literal (the dataset may even live in another package of the stack).
10
- *
11
- * Reference-integrity rules (#1721) — severity `error`, the page is broken:
12
- *
13
- * - `widget-dataset-unknown` — `dataset` does not resolve to a declared
14
- * `Dataset`.
15
- * - `widget-dimension-unknown` — a `dimensions[]` entry is not a dimension
16
- * name on the bound dataset.
17
- * - `widget-measure-unknown` — a `values[]` entry is not a measure name on
18
- * the bound dataset.
19
- * - `chart-field-unknown` — a `chartConfig` binding names a field the query
20
- * result will not contain: `xAxis.field` must be one of the widget's
21
- * dimensions (or a dataset dimension), and each `yAxis[].field` /
22
- * `series[].name` must be one of the widget's selected measures
23
- * (`values`). Post-cutover (ADR-0021) the result rows are keyed by
24
- * measure NAME (e.g. `sum_amount`), not the base column (`amount`) — a
25
- * stale base-column reference renders the axis but an empty series.
26
- *
27
- * Advisory rules — severity `warning`, build stays green:
28
- *
29
- * - `chart-config-missing` — a chart-type widget (bar/line/pie/…) has no
30
- * `chartConfig`, so the renderer cannot tell which measure to plot.
31
- * - `table-count-only` (#1719) — a `table`/`pivot` widget whose selected
32
- * measures are ALL `aggregate: 'count'` and which declares no
33
- * `dimensions` asks the analytics service for a single summary row. That
34
- * is the shape a `metric` widget wants — for a table it almost always
35
- * means the author wanted a per-record listing, which is not an
36
- * analytics dataset at all (model it as an object-bound ListView,
37
- * ADR-0017). Evaluated on the WIDGET's binding, not the dataset.
38
- *
39
- * Warnings can be deliberately suppressed per widget via
40
- * `suppressWarnings: ['<rule-id>']`; errors cannot — they describe a
41
- * binding the analytics service cannot satisfy.
42
- */
43
- export declare const WIDGET_DATASET_UNKNOWN = "widget-dataset-unknown";
44
- export declare const WIDGET_DIMENSION_UNKNOWN = "widget-dimension-unknown";
45
- export declare const WIDGET_MEASURE_UNKNOWN = "widget-measure-unknown";
46
- export declare const CHART_FIELD_UNKNOWN = "chart-field-unknown";
47
- export declare const CHART_CONFIG_MISSING = "chart-config-missing";
48
- export declare const TABLE_COUNT_ONLY = "table-count-only";
49
- export type WidgetBindingSeverity = 'error' | 'warning';
50
- export interface WidgetBindingFinding {
51
- /** `error` = unresolvable binding (broken page); `warning` = advisory. */
52
- severity: WidgetBindingSeverity;
53
- /** Diagnostic rule id (registry entry), e.g. `widget-measure-unknown`. */
54
- rule: string;
55
- /** Human-readable location, e.g. `dashboard "x" › widget "y"`. */
56
- where: string;
57
- /** Config path, e.g. `dashboards[0].widgets[3]`. */
58
- path: string;
59
- /** What is wrong. */
60
- message: string;
61
- /** How to fix (or deliberately suppress) it. */
62
- hint: string;
63
- }
64
- type AnyRec = Record<string, unknown>;
65
- /**
66
- * Validate every dashboard widget's dataset binding. Returns the list of
67
- * findings (empty = clean). Caller decides how to surface them: `error`
68
- * findings describe bindings the analytics service cannot satisfy and
69
- * should fail validate/build; `warning` findings are advisory and must
70
- * never fail the build on their own.
71
- */
72
- export declare function validateWidgetBindings(stack: AnyRec): WidgetBindingFinding[];
73
- export {};
74
- //# sourceMappingURL=validate-widget-bindings.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validate-widget-bindings.d.ts","sourceRoot":"","sources":["../../src/utils/validate-widget-bindings.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AACnE,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AACzD,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAC3D,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAEnD,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,SAAS,CAAC;AAExD,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,QAAQ,EAAE,qBAAqB,CAAC;IAChC,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA6EtC;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,EAAE,CA2L5E"}