@stackbit/cms-core 1.0.2-develop.1 → 1.0.2-develop.2

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 (64) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/content-store.d.ts +6 -1
  3. package/dist/content-store.d.ts.map +1 -1
  4. package/dist/content-store.js +37 -6
  5. package/dist/content-store.js.map +1 -1
  6. package/dist/types/content-store-api-document-fields.d.ts +3 -33
  7. package/dist/types/content-store-api-document-fields.d.ts.map +1 -1
  8. package/dist/types/content-store-document-fields.d.ts +1 -106
  9. package/dist/types/content-store-document-fields.d.ts.map +1 -1
  10. package/dist/types/content-store-documents.d.ts +4 -2
  11. package/dist/types/content-store-documents.d.ts.map +1 -1
  12. package/dist/types/custom-actions.d.ts +2 -3
  13. package/dist/types/custom-actions.d.ts.map +1 -1
  14. package/dist/types/index.d.ts +1 -0
  15. package/dist/types/index.d.ts.map +1 -1
  16. package/dist/types/index.js +1 -0
  17. package/dist/types/index.js.map +1 -1
  18. package/dist/utils/csi-to-api-docs-converter.d.ts +3 -9
  19. package/dist/utils/csi-to-api-docs-converter.d.ts.map +1 -1
  20. package/dist/utils/csi-to-api-docs-converter.js +23 -27
  21. package/dist/utils/csi-to-api-docs-converter.js.map +1 -1
  22. package/dist/utils/csi-to-store-docs-converter.d.ts.map +1 -1
  23. package/dist/utils/csi-to-store-docs-converter.js +0 -38
  24. package/dist/utils/csi-to-store-docs-converter.js.map +1 -1
  25. package/dist/utils/custom-actions.d.ts +2 -41
  26. package/dist/utils/custom-actions.d.ts.map +1 -1
  27. package/dist/utils/custom-actions.js +3 -198
  28. package/dist/utils/custom-actions.js.map +1 -1
  29. package/dist/utils/custom-search-filters.d.ts +12 -0
  30. package/dist/utils/custom-search-filters.d.ts.map +1 -0
  31. package/dist/utils/custom-search-filters.js +46 -0
  32. package/dist/utils/custom-search-filters.js.map +1 -0
  33. package/dist/utils/field-path-utils.d.ts +1 -1
  34. package/dist/utils/field-path-utils.d.ts.map +1 -1
  35. package/dist/utils/field-path-utils.js +4 -0
  36. package/dist/utils/field-path-utils.js.map +1 -1
  37. package/dist/utils/model-utils.d.ts.map +1 -1
  38. package/dist/utils/model-utils.js +21 -0
  39. package/dist/utils/model-utils.js.map +1 -1
  40. package/dist/utils/store-to-api-docs-converter.d.ts.map +1 -1
  41. package/dist/utils/store-to-api-docs-converter.js +26 -74
  42. package/dist/utils/store-to-api-docs-converter.js.map +1 -1
  43. package/dist/utils/store-to-api-v2-docs-converter.d.ts +2 -3
  44. package/dist/utils/store-to-api-v2-docs-converter.d.ts.map +1 -1
  45. package/dist/utils/store-to-api-v2-docs-converter.js +91 -148
  46. package/dist/utils/store-to-api-v2-docs-converter.js.map +1 -1
  47. package/package.json +5 -5
  48. package/src/content-store.ts +53 -8
  49. package/src/types/content-store-api-document-fields.ts +471 -0
  50. package/src/types/content-store-document-fields.ts +1 -50
  51. package/src/types/content-store-documents.ts +4 -2
  52. package/src/types/custom-actions.ts +2 -3
  53. package/src/types/index.ts +1 -0
  54. package/src/utils/csi-to-api-docs-converter.ts +27 -42
  55. package/src/utils/csi-to-store-docs-converter.ts +1 -42
  56. package/src/utils/custom-actions.ts +4 -277
  57. package/src/utils/field-path-utils.ts +6 -2
  58. package/src/utils/model-utils.ts +20 -2
  59. package/src/utils/store-to-api-docs-converter.ts +26 -79
  60. package/src/utils/store-to-api-v2-docs-converter.ts +441 -0
  61. package/dist/utils/file-cache.d.ts +0 -13
  62. package/dist/utils/file-cache.d.ts.map +0 -1
  63. package/dist/utils/file-cache.js +0 -69
  64. package/dist/utils/file-cache.js.map +0 -1
@@ -0,0 +1,441 @@
1
+ import _ from 'lodash';
2
+ import { omitByUndefined } from '@stackbit/utils';
3
+ import * as CSITypes from '@stackbit/types';
4
+ import * as ContentStoreTypes from '../types';
5
+ import { getContentSourceId, getDocumentFieldForLocale } from '../content-store-utils';
6
+
7
+ export function mapDocumentsToApiDocuments({
8
+ documents,
9
+ allowedLocales,
10
+ contentSourceDataById,
11
+ delegate
12
+ }: {
13
+ documents: ContentStoreTypes.Document[];
14
+ allowedLocales?: string[];
15
+ contentSourceDataById: Record<string, ContentStoreTypes.ContentSourceData>;
16
+ delegate: CSITypes.ConfigDelegate;
17
+ }): ContentStoreTypes.APIDocument[] {
18
+ return documents.map((document) =>
19
+ documentToApiV2Object({
20
+ document,
21
+ allowedLocales,
22
+ contentSourceDataById,
23
+ delegate
24
+ })
25
+ );
26
+ }
27
+
28
+ function documentToApiV2Object({
29
+ document,
30
+ allowedLocales,
31
+ contentSourceDataById,
32
+ delegate
33
+ }: {
34
+ document: ContentStoreTypes.Document;
35
+ allowedLocales?: string[];
36
+ contentSourceDataById: Record<string, ContentStoreTypes.ContentSourceData>;
37
+ delegate: CSITypes.ConfigDelegate;
38
+ }): ContentStoreTypes.APIDocument {
39
+ const { fields, getPreview, ...rest } = document;
40
+ return omitByUndefined({
41
+ ..._.omit(rest),
42
+ srcObjectLabel: getPreview({ delegate /*, locale*/ }).previewTitle,
43
+ fields: toAPIV2Fields({
44
+ docFields: fields,
45
+ delegate,
46
+ allowedLocales,
47
+ contentSourceDataById,
48
+ contentSourceId: getContentSourceId(document.srcType, document.srcProjectId)
49
+ })
50
+ });
51
+ }
52
+
53
+ function toAPIV2Fields({
54
+ docFields,
55
+ delegate,
56
+ contentSourceDataById,
57
+ contentSourceId,
58
+ allowedLocales
59
+ }: {
60
+ docFields: Record<string, ContentStoreTypes.DocumentField>;
61
+ delegate: CSITypes.ConfigDelegate;
62
+ contentSourceDataById: Record<string, ContentStoreTypes.ContentSourceData>;
63
+ contentSourceId: string;
64
+ allowedLocales?: string[];
65
+ }): Record<string, ContentStoreTypes.DocumentFieldAPIV2> {
66
+ return _.mapValues(docFields, (docField) => {
67
+ return omitByUndefined(
68
+ toAPIV2Field({
69
+ docField,
70
+ delegate,
71
+ contentSourceDataById,
72
+ contentSourceId,
73
+ allowedLocales
74
+ })
75
+ );
76
+ });
77
+ }
78
+
79
+ function toAPIV2Field({
80
+ docField,
81
+ delegate,
82
+ contentSourceDataById,
83
+ contentSourceId,
84
+ allowedLocales,
85
+ isListItem = false
86
+ }: {
87
+ docField: ContentStoreTypes.DocumentField;
88
+ delegate: CSITypes.ConfigDelegate;
89
+ allowedLocales?: string[];
90
+ contentSourceDataById: Record<string, ContentStoreTypes.ContentSourceData>;
91
+ contentSourceId: string;
92
+ isListItem?: boolean;
93
+ }): ContentStoreTypes.DocumentFieldAPIV2 {
94
+ // TODO: reduce over allowedLocales rather then existing locales - use isUnset, and add fieldActions even for missing locales
95
+ switch (docField.type) {
96
+ case 'string':
97
+ case 'text':
98
+ case 'url':
99
+ case 'slug':
100
+ case 'html':
101
+ case 'number':
102
+ case 'boolean':
103
+ case 'enum':
104
+ case 'date':
105
+ case 'datetime':
106
+ case 'color':
107
+ case 'style':
108
+ case 'json':
109
+ case 'file':
110
+ case 'markdown':
111
+ case 'richText': {
112
+ if (docField.localized) {
113
+ const locales = _.reduce(
114
+ docField.locales,
115
+ (acc, cur, locale) => {
116
+ acc[locale] = cur;
117
+ return acc;
118
+ },
119
+ {} as ContentStoreTypes.DocumentFieldLocalizedAPIV2['locales']
120
+ );
121
+
122
+ return {
123
+ ...docField,
124
+ locales
125
+ } as ContentStoreTypes.DocumentFieldLocalizedAPIV2;
126
+ }
127
+
128
+ return docField;
129
+ }
130
+ case 'image': {
131
+ if (docField.localized) {
132
+ const locales = _.reduce(
133
+ docField.locales,
134
+ (acc, cur, locale) => {
135
+ acc[locale] = {
136
+ ...cur,
137
+ fields: toAPIV2Fields({
138
+ docFields: cur.fields,
139
+ delegate,
140
+ contentSourceDataById,
141
+ contentSourceId,
142
+ allowedLocales
143
+ }) as ContentStoreTypes.ImageFieldsAPIV2
144
+ };
145
+ return acc;
146
+ },
147
+ {} as ContentStoreTypes.DocumentImageFieldLocalizedAPIV2['locales']
148
+ );
149
+
150
+ return {
151
+ ...docField,
152
+ locales
153
+ } as ContentStoreTypes.DocumentFieldLocalizedAPIV2;
154
+ }
155
+
156
+ if (docField.isUnset) {
157
+ return docField;
158
+ }
159
+
160
+ return {
161
+ ...docField,
162
+ fields: toAPIV2Fields({
163
+ docFields: docField.fields,
164
+ delegate,
165
+ contentSourceDataById,
166
+ contentSourceId,
167
+ allowedLocales
168
+ }) as ContentStoreTypes.ImageFieldsAPIV2
169
+ };
170
+ }
171
+ case 'object': {
172
+ if (docField.localized) {
173
+ const locales = _.reduce(
174
+ docField.locales,
175
+ (acc, cur) => {
176
+ const { fields, getPreview, locale } = cur;
177
+ acc[locale] = {
178
+ ...cur,
179
+ srcObjectLabel:
180
+ getPreview({
181
+ delegate,
182
+ locale
183
+ }).previewTitle ?? (isListItem ? 'Item' : 'Object'),
184
+ fields: toAPIV2Fields({
185
+ docFields: fields,
186
+ delegate,
187
+ contentSourceDataById,
188
+ contentSourceId,
189
+ allowedLocales
190
+ })
191
+ };
192
+ return acc;
193
+ },
194
+ {} as ContentStoreTypes.DocumentObjectFieldLocalizedAPIV2['locales']
195
+ );
196
+
197
+ return {
198
+ ...docField,
199
+ locales
200
+ };
201
+ }
202
+
203
+ // TODO: what about unset locales? what if there is an action that generates content for an empty object?
204
+ if (docField.isUnset) {
205
+ return docField;
206
+ }
207
+
208
+ const { fields, getPreview, ...rest } = docField;
209
+ return {
210
+ ...rest,
211
+ srcObjectLabel: getPreview({ delegate }).previewTitle ?? (isListItem ? 'Item' : 'Object'),
212
+ fields: toAPIV2Fields({
213
+ docFields: fields,
214
+ delegate,
215
+ contentSourceDataById,
216
+ contentSourceId,
217
+ allowedLocales
218
+ })
219
+ };
220
+ }
221
+ case 'model': {
222
+ // TODO: merge with object
223
+ if (docField.localized) {
224
+ const locales = _.reduce(
225
+ docField.locales,
226
+ (acc, cur) => {
227
+ const { fields, getPreview, locale } = cur;
228
+ acc[locale] = {
229
+ ...cur,
230
+ srcObjectLabel: getPreview({
231
+ delegate,
232
+ locale
233
+ }).previewTitle,
234
+ fields: toAPIV2Fields({
235
+ docFields: fields,
236
+ delegate,
237
+ contentSourceDataById,
238
+ contentSourceId,
239
+ allowedLocales
240
+ })
241
+ };
242
+ return acc;
243
+ },
244
+ {} as ContentStoreTypes.DocumentModelFieldLocalizedAPIV2['locales']
245
+ );
246
+
247
+ return {
248
+ ...docField,
249
+ locales
250
+ };
251
+ }
252
+
253
+ // TODO: what about unset locales? what if there is an action that generates content for an empty object?
254
+ if (docField.isUnset) {
255
+ return docField;
256
+ }
257
+
258
+ const { fields, getPreview, ...rest } = docField;
259
+ return {
260
+ ...rest,
261
+ srcObjectLabel: getPreview({ delegate }).previewTitle,
262
+ fields: toAPIV2Fields({
263
+ docFields: fields,
264
+ delegate,
265
+ contentSourceDataById,
266
+ contentSourceId,
267
+ allowedLocales
268
+ })
269
+ };
270
+ }
271
+ case 'reference': {
272
+ if (docField.localized) {
273
+ const refField = docField;
274
+ const locales = _.reduce(
275
+ docField.locales,
276
+ (acc, cur, locale) => {
277
+ acc[locale] = {
278
+ ...cur,
279
+ ...populateReferenceLabels({
280
+ docField: refField,
281
+ contentSourceDataById,
282
+ contentSourceId,
283
+ locale: locale,
284
+ delegate
285
+ })
286
+ };
287
+ return acc;
288
+ },
289
+ {} as ContentStoreTypes.DocumentReferenceFieldLocalizedAPIV2['locales']
290
+ );
291
+
292
+ return {
293
+ ...docField,
294
+ locales
295
+ };
296
+ }
297
+
298
+ return {
299
+ ...docField,
300
+ ...populateReferenceLabels({ docField, contentSourceDataById, contentSourceId, delegate })
301
+ };
302
+ }
303
+ case 'cross-reference': {
304
+ // todo: unify with reference using helper methods
305
+ if (docField.localized) {
306
+ const refField = docField;
307
+ const locales = _.reduce(
308
+ docField.locales,
309
+ (acc, cur, locale) => {
310
+ acc[locale] = {
311
+ ...cur,
312
+ ...populateReferenceLabels({
313
+ docField: refField,
314
+ contentSourceDataById,
315
+ contentSourceId,
316
+ locale: locale,
317
+ delegate
318
+ })
319
+ };
320
+ return acc;
321
+ },
322
+ {} as ContentStoreTypes.DocumentCrossReferenceFieldLocalizedAPIV2['locales']
323
+ );
324
+
325
+ return {
326
+ ...docField,
327
+ locales
328
+ };
329
+ }
330
+
331
+ return {
332
+ ...docField,
333
+ ...populateReferenceLabels({ docField, contentSourceDataById, contentSourceId, delegate })
334
+ };
335
+ }
336
+ case 'list': {
337
+ if (docField.localized) {
338
+ const locales = _.reduce(
339
+ docField.locales,
340
+ (acc, cur, locale) => {
341
+ acc[locale] = {
342
+ ...cur,
343
+ items: (cur.items ?? []).map(
344
+ (field) =>
345
+ toAPIV2Field({
346
+ docField: field,
347
+ contentSourceDataById,
348
+ contentSourceId,
349
+ delegate,
350
+ allowedLocales,
351
+ isListItem: true
352
+ }) as ContentStoreTypes.DocumentListFieldItemsAPIV2
353
+ )
354
+ };
355
+ return acc;
356
+ },
357
+ {} as ContentStoreTypes.DocumentListFieldLocalizedAPIV2['locales']
358
+ );
359
+
360
+ return {
361
+ ...docField,
362
+ locales
363
+ };
364
+ }
365
+
366
+ const { items, ...rest } = docField;
367
+ return {
368
+ ...rest,
369
+ items: items.map(
370
+ (field) =>
371
+ toAPIV2Field({
372
+ docField: field,
373
+ delegate,
374
+ contentSourceDataById,
375
+ contentSourceId,
376
+ allowedLocales,
377
+ isListItem: true
378
+ }) as ContentStoreTypes.DocumentListFieldItemsAPIV2
379
+ )
380
+ };
381
+ }
382
+ default: {
383
+ const _exhaustiveCheck: never = docField;
384
+ console.error(`toLocalizedAPIField _exhaustiveCheck failed, docField.type: ${docField['type']}`);
385
+ return _exhaustiveCheck;
386
+ }
387
+ }
388
+ }
389
+
390
+ function populateReferenceLabels({
391
+ docField,
392
+ locale,
393
+ contentSourceDataById,
394
+ contentSourceId,
395
+ delegate
396
+ }: {
397
+ docField: ContentStoreTypes.DocumentReferenceField | ContentStoreTypes.DocumentCrossReferenceField;
398
+ locale?: string;
399
+ contentSourceDataById: Record<string, ContentStoreTypes.ContentSourceData>;
400
+ contentSourceId: string;
401
+ delegate: CSITypes.ConfigDelegate;
402
+ }) {
403
+ const refField = getDocumentFieldForLocale(docField, locale);
404
+ if (!refField || refField?.isUnset) {
405
+ return {};
406
+ }
407
+
408
+ if (refField.type === 'reference') {
409
+ if (refField.refType === 'document') {
410
+ const document = contentSourceDataById[contentSourceId]?.documentMap[refField.refId];
411
+ if (document) {
412
+ return { srcObjectLabel: document?.getPreview({ delegate }).previewTitle, srcModelLabel: document?.srcModelLabel, isMissing: false };
413
+ }
414
+ } else if (refField.refType === 'asset') {
415
+ const asset = contentSourceDataById[contentSourceId]?.assetMap[refField.refId];
416
+ if (asset) {
417
+ return { srcObjectLabel: asset.srcObjectLabel, srcModelLabel: asset.srcModelLabel, isMissing: false };
418
+ }
419
+ }
420
+ } else if (refField?.type === 'cross-reference') {
421
+ const srcId = getContentSourceId(refField.refSrcType, refField.refProjectId);
422
+ if (refField.refType === 'document') {
423
+ const document = contentSourceDataById[srcId]?.documentMap[refField.refId];
424
+ if (document) {
425
+ return {
426
+ refObjectLabel: document?.getPreview({ delegate }).previewTitle,
427
+ refModelLabel: document?.srcModelLabel,
428
+ refModelName: document?.srcModelName,
429
+ isMissing: false
430
+ };
431
+ }
432
+ } else if (refField.refType === 'asset') {
433
+ const asset = contentSourceDataById[srcId]?.assetMap[refField.refId];
434
+ if (asset) {
435
+ return { refObjectLabel: asset.srcObjectLabel, refModelLabel: asset.srcModelLabel, refModelName: asset?.srcModelName, isMissing: false };
436
+ }
437
+ }
438
+ }
439
+
440
+ return { isMissing: true };
441
+ }
@@ -1,13 +0,0 @@
1
- export declare class FileCache {
2
- private readonly dirPath;
3
- private readonly keyPrefix;
4
- constructor({ dirPath, keyPrefix }: {
5
- dirPath: string;
6
- keyPrefix?: string;
7
- });
8
- get(key: string): Promise<unknown>;
9
- set(key: string, value: unknown): Promise<void>;
10
- remove(key: string): Promise<void>;
11
- private filePathKey;
12
- }
13
- //# sourceMappingURL=file-cache.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"file-cache.d.ts","sourceRoot":"","sources":["../../src/utils/file-cache.ts"],"names":[],"mappings":"AAGA,qBAAa,SAAS;IAClB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBACvB,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;IAIrE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYlC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxC,OAAO,CAAC,WAAW;CAGtB"}
@@ -1,69 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
- Object.defineProperty(o, "default", { enumerable: true, value: v });
11
- }) : function(o, v) {
12
- o["default"] = v;
13
- });
14
- var __importStar = (this && this.__importStar) || function (mod) {
15
- if (mod && mod.__esModule) return mod;
16
- var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
- __setModuleDefault(result, mod);
19
- return result;
20
- };
21
- var __importDefault = (this && this.__importDefault) || function (mod) {
22
- return (mod && mod.__esModule) ? mod : { "default": mod };
23
- };
24
- Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.FileCache = void 0;
26
- const path_1 = __importDefault(require("path"));
27
- const fse = __importStar(require("fs-extra"));
28
- class FileCache {
29
- constructor({ dirPath, keyPrefix }) {
30
- this.dirPath = dirPath;
31
- this.keyPrefix = keyPrefix !== null && keyPrefix !== void 0 ? keyPrefix : '';
32
- }
33
- async get(key) {
34
- const fileName = this.filePathKey(key);
35
- try {
36
- const exists = await fse.pathExists(fileName);
37
- if (!exists) {
38
- return;
39
- }
40
- return fse.readJson(fileName);
41
- }
42
- catch (error) {
43
- return;
44
- }
45
- }
46
- async set(key, value) {
47
- const fileName = this.filePathKey(key);
48
- try {
49
- return fse.outputJson(fileName, value);
50
- }
51
- catch (error) {
52
- return;
53
- }
54
- }
55
- async remove(key) {
56
- const fileName = this.filePathKey(key);
57
- try {
58
- return await fse.remove(fileName);
59
- }
60
- catch (error) {
61
- return;
62
- }
63
- }
64
- filePathKey(key) {
65
- return path_1.default.join(this.dirPath, '.stackbit/cache', `${this.keyPrefix}${key}.json`);
66
- }
67
- }
68
- exports.FileCache = FileCache;
69
- //# sourceMappingURL=file-cache.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"file-cache.js","sourceRoot":"","sources":["../../src/utils/file-cache.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAAwB;AACxB,8CAAgC;AAEhC,MAAa,SAAS;IAGlB,YAAY,EAAE,OAAO,EAAE,SAAS,EAA2C;QACvE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,EAAE,CAAC;IACrC,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,GAAW;QACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI;YACA,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC9C,IAAI,CAAC,MAAM,EAAE;gBACT,OAAO;aACV;YACD,OAAO,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;SACjC;QAAC,OAAO,KAAK,EAAE;YACZ,OAAO;SACV;IACL,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAc;QACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI;YACA,OAAO,GAAG,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;SAC1C;QAAC,OAAO,KAAK,EAAE;YACZ,OAAO;SACV;IACL,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,GAAW;QACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI;YACA,OAAO,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;SACrC;QAAC,OAAO,KAAK,EAAE;YACZ,OAAO;SACV;IACL,CAAC;IAEO,WAAW,CAAC,GAAW;QAC3B,OAAO,cAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,SAAS,GAAG,GAAG,OAAO,CAAC,CAAC;IACtF,CAAC;CACJ;AAvCD,8BAuCC"}