@tryghost/metafield-types 0.2.0 → 0.4.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.
@@ -0,0 +1,185 @@
1
+ /**
2
+ * The rules every field of a shape follows, whatever its type and settings, and the rules a field
3
+ * adds from its settings when a held value is read.
4
+ *
5
+ * A shape's rules look only at structure: they know a list is a list of strings, but not which
6
+ * strings a field offers. They also say what a write does to a held value, which is part of the
7
+ * API's contract rather than storage's choice: a client works out a write against the value its
8
+ * form loaded, and Ghost applies it to whatever is stored when it lands, which another writer may
9
+ * have changed in between. The two only agree because both read the rules here.
10
+ *
11
+ * Each table is keyed by shape, so a shape added to the catalog fails to compile here until it has
12
+ * an entry. Each translator of a shape into another domain's terms, such as the storage translator
13
+ * into rows or the CSV translator into cells, keeps its own table of the same form, which `shaped`
14
+ * lets it index without a cast.
15
+ *
16
+ * Zod-free, like `./structure`, so Portal can use it. The strict rule a write must meet is built
17
+ * from zod and lives in `./index` as `accept`.
18
+ */
19
+ import { type FieldOfShape, type FieldShape, type FieldType, type FieldTypeOfShape, type Leaf, type LeafKind, type LeafValues, type TypedSettings, type ValueOf, type WriteOf } from './structure.js';
20
+ /** A leaf's value of any kind. */
21
+ export type AnyLeafValue = LeafValues[LeafKind];
22
+ /**
23
+ * What a value of each JSON kind is. Primitives only: the shape rules compare two leaf values with
24
+ * `===`, which a kind holding objects would break.
25
+ */
26
+ interface KindValues {
27
+ string: string;
28
+ number: number;
29
+ boolean: boolean;
30
+ }
31
+ /** The JSON kind a value comes in. */
32
+ type KindOf<V> = {
33
+ [K in keyof KindValues]: V extends KindValues[K] ? K : never;
34
+ }[keyof KindValues];
35
+ /**
36
+ * The JSON kinds the catalog's leaves' values come in, which is all that tells two leaves' values
37
+ * apart without their field: how storage picks a value's column, and a filter what to compare it
38
+ * in. Read from the leaves, so a leaf kind whose value is a new JSON kind widens it.
39
+ */
40
+ export type ValueKind = KindOf<AnyLeafValue>;
41
+ /** The leaf values of one JSON kind. */
42
+ export type ValueOfKind<K extends ValueKind> = Extract<AnyLeafValue, KindValues[K]>;
43
+ /**
44
+ * What the domain knows about each kind of leaf beyond its rule, which needs zod and is
45
+ * `LEAF_RULES` in `./index`. Keyed by kind, so a kind added to the catalog fails to compile here
46
+ * until it says each.
47
+ */
48
+ interface LeafKindRules<K extends LeafKind> {
49
+ /** The JSON kind its value comes in. */
50
+ readonly kind: KindOf<LeafValues[K]>;
51
+ /** A raw value read as this leaf's value, or undefined when it holds none. */
52
+ read(raw: unknown): LeafValues[K] | undefined;
53
+ /**
54
+ * Text, as a form's input or a CSV cell holds it, read as this leaf's value, or the text itself
55
+ * where it holds none, so the leaf's rule refuses it rather than it being dropped. Writing a
56
+ * value as text is `String` for every kind.
57
+ */
58
+ fromText(text: string): LeafValues[K] | string;
59
+ }
60
+ /**
61
+ * What a value of each shape holds: whatever a type of that shape holds, read from the catalog, so a
62
+ * type's parts and leaves are typed the same way here. A value always holds something: a field
63
+ * holding nothing has no value at all, rather than an empty one, so `0` and an answer left blank are
64
+ * never confused. A record holds at least one part, and a set at least one option.
65
+ */
66
+ export type ShapeValue = {
67
+ [S in FieldShape]: ValueOf<FieldTypeOfShape<S>>;
68
+ };
69
+ /** What a write to a field of each shape gives, from the catalog in the same way; see `WriteOf`. */
70
+ export type ShapeWrite = {
71
+ [S in FieldShape]: WriteOf<FieldTypeOfShape<S>>;
72
+ };
73
+ export interface ShapeRules<S extends FieldShape> {
74
+ /**
75
+ * What `raw` holds as a value of `type`, or undefined when it holds nothing of it. Lenient: a part
76
+ * the type doesn't declare, or one of another kind than its leaf, is left out.
77
+ */
78
+ parse(type: FieldTypeOfShape<S>, raw: unknown): ShapeValue[S] | undefined;
79
+ /** Whether two values hold the same, which a write that changes nothing leaves alone. */
80
+ same(a: ShapeValue[S], b: ShapeValue[S]): boolean;
81
+ /** What a write does to what is held, which is nothing when a record's write clears every part. */
82
+ apply(held: ShapeValue[S] | undefined, write: ShapeWrite[S]): ShapeValue[S] | undefined;
83
+ /**
84
+ * The smallest write that turns `held` into `next`: `null` when `next` holds nothing, and
85
+ * undefined when the two hold the same.
86
+ */
87
+ diff(held: ShapeValue[S] | undefined, next: ShapeValue[S] | undefined): ShapeWrite[S] | null | undefined;
88
+ }
89
+ export declare const LEAVES: {
90
+ readonly [K in LeafKind]: LeafKindRules<K>;
91
+ };
92
+ /** Each shape's rules. A shape added to the catalog without rules doesn't compile. */
93
+ export declare const SHAPES: {
94
+ readonly [S in FieldShape]: ShapeRules<S>;
95
+ };
96
+ /**
97
+ * A field together with its shape, as one of a union with a member per shape. Indexing a table
98
+ * keyed by shape with `shape` gives the entry for the same shape that `field` has, so a translator
99
+ * such as the storage translator can call its entry for a field without a cast or a branch per
100
+ * shape.
101
+ */
102
+ export type ShapedField<F extends TypedSettings = TypedSettings, S extends FieldShape = FieldShape> = {
103
+ [K in S]: {
104
+ readonly shape: K;
105
+ readonly field: FieldOfShape<K, F>;
106
+ };
107
+ }[S];
108
+ /** A field paired with its shape: the one place a field's union is branched on by shape. */
109
+ export declare function shaped<F extends TypedSettings>(field: F): ShapedField<F>;
110
+ /**
111
+ * A type together with its shape, for a translator that knows a field's type but not its settings,
112
+ * as the CSV translator does.
113
+ */
114
+ export type ShapedType<S extends FieldShape = FieldShape> = {
115
+ [K in S]: {
116
+ readonly shape: K;
117
+ readonly type: FieldTypeOfShape<K>;
118
+ };
119
+ }[S];
120
+ /** A type paired with its shape. */
121
+ export declare function shapedType(type: FieldType): ShapedType;
122
+ /** How a field of each shape reads a held value, using its type and settings. */
123
+ export interface FieldReading<S extends FieldShape> {
124
+ /**
125
+ * Lenient: what a field holds, read as the field gives it meaning. Keeps answers to options
126
+ * since removed, and parts saved under an older, looser rule, so tightening a rule never hides
127
+ * what members hold. Puts a list's answers in the field's order, then the removed ones.
128
+ */
129
+ held(field: FieldOfShape<S>, value: ShapeValue[S]): ShapeValue[S] | undefined;
130
+ /**
131
+ * What a form can show of a held value. A save that writes what the form shows drops an answer
132
+ * the form can't show.
133
+ */
134
+ editable(field: FieldOfShape<S>, held: ShapeValue[S]): ShapeValue[S] | undefined;
135
+ }
136
+ export declare const FIELD_READING: {
137
+ readonly [S in FieldShape]: FieldReading<S>;
138
+ };
139
+ /**
140
+ * What a held raw value reads as for its field: its structure checked, then read as the field
141
+ * gives it meaning. Undefined when the value isn't the field's structure.
142
+ */
143
+ export declare function heldValue<S extends FieldShape>({ shape, field }: ShapedField<TypedSettings, S>, raw: unknown): ShapeValue[S] | undefined;
144
+ /** What a form can show of a held raw value, or undefined when it shows nothing. */
145
+ export declare function editableValue<S extends FieldShape>(of: ShapedField<TypedSettings, S>, raw: unknown): ShapeValue[S] | undefined;
146
+ /** A leaf's value as text gives it, or undefined for blank text, which holds nothing. */
147
+ export declare const leafFromText: (leaf: Leaf, text: string) => AnyLeafValue | undefined;
148
+ /**
149
+ * What a value given as text holds, such as a form's inputs or a row's cells: each leaf read from
150
+ * its text, then parsed as a value of its type, which drops blank text. Undefined when it holds
151
+ * nothing.
152
+ */
153
+ export declare function valueFromText<S extends FieldShape>({ shape, type }: ShapedType<S>, raw: unknown): ShapeValue[S] | undefined;
154
+ /** A value of each shape as a form's inputs hold it: each leaf as its text. */
155
+ export interface ShapeText {
156
+ scalar: string;
157
+ record: {
158
+ readonly [part: string]: string;
159
+ };
160
+ set: string[];
161
+ }
162
+ /** A value as a form's inputs hold it, which `valueFromText` reads back as the same value. */
163
+ export declare function textOfValue<S extends FieldShape>(shape: S, value: ShapeValue[S]): ShapeText[S];
164
+ /** What a field holds, each leaf as its text, as a field shown but not edited draws it. */
165
+ export declare function heldTextOf<S extends FieldShape>(of: ShapedField<TypedSettings, S>, held: unknown): ShapeText[S] | undefined;
166
+ /**
167
+ * What a form's inputs start from for a held raw value: what the form can show of it, each leaf as
168
+ * its text, or undefined when it shows nothing.
169
+ */
170
+ export declare function formTextOf<S extends FieldShape>(of: ShapedField<TypedSettings, S>, held: unknown): ShapeText[S] | undefined;
171
+ /**
172
+ * What a form's inputs show, read as the field reads a value: each leaf from its text, blank text
173
+ * holding nothing, and only what the form can show. Undefined when they show nothing.
174
+ */
175
+ export declare function formShows<S extends FieldShape>(of: ShapedField<TypedSettings, S>, inputs: unknown): ShapeValue[S] | undefined;
176
+ /**
177
+ * The write that turns what a field holds into what a form's inputs show: `null` when the inputs
178
+ * show nothing of a replacing shape, and undefined when they show what the field holds. The held
179
+ * value is read as the field reads it first, so a part the form doesn't draw is never written, and
180
+ * an answer the form can't show, such as one to an option the field no longer offers, is cleared
181
+ * by the write.
182
+ */
183
+ export declare function formWrite<S extends FieldShape>(of: ShapedField<TypedSettings, S>, inputs: unknown, held: unknown): ShapeWrite[S] | null | undefined;
184
+ export {};
185
+ //# sourceMappingURL=shapes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shapes.d.ts","sourceRoot":"","sources":["../src/shapes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,262 @@
1
+ /**
2
+ * The rules every field of a shape follows, whatever its type and settings, and the rules a field
3
+ * adds from its settings when a held value is read.
4
+ *
5
+ * A shape's rules look only at structure: they know a list is a list of strings, but not which
6
+ * strings a field offers. They also say what a write does to a held value, which is part of the
7
+ * API's contract rather than storage's choice: a client works out a write against the value its
8
+ * form loaded, and Ghost applies it to whatever is stored when it lands, which another writer may
9
+ * have changed in between. The two only agree because both read the rules here.
10
+ *
11
+ * Each table is keyed by shape, so a shape added to the catalog fails to compile here until it has
12
+ * an entry. Each translator of a shape into another domain's terms, such as the storage translator
13
+ * into rows or the CSV translator into cells, keeps its own table of the same form, which `shaped`
14
+ * lets it index without a cast.
15
+ *
16
+ * Zod-free, like `./structure`, so Portal can use it. The strict rule a write must meet is built
17
+ * from zod and lives in `./index` as `accept`.
18
+ */
19
+ import { FIELD_STRUCTURES, editableAnswers, isRecordValue, matchField, matchShape, keysOf, } from './structure.js';
20
+ /**
21
+ * A leaf's value, or undefined for text of nothing but spaces, which holds nothing: a form's input
22
+ * or a CSV cell left blank says no more than one left out.
23
+ */
24
+ const filled = (raw) => typeof raw === 'string' && raw.trim() === '' ? undefined : raw;
25
+ /** A value JSON carries as a string, without its padding, which every such leaf's rule trims too. */
26
+ const stringRules = {
27
+ kind: 'string',
28
+ read: (raw) => (typeof raw === 'string' ? filled(raw.trim()) : undefined),
29
+ fromText: (text) => text.trim(),
30
+ };
31
+ export const LEAVES = {
32
+ text: stringRules,
33
+ choice: stringRules,
34
+ };
35
+ /** A raw value read as its leaf's kind of value, typed by the leaf. */
36
+ const readLeaf = (leaf, raw) => LEAVES[leaf.leaf].read(raw);
37
+ /** A raw value read as a value of any kind of leaf, or undefined when no kind reads it. */
38
+ function readAnyLeaf(raw) {
39
+ for (const kind of keysOf(LEAVES)) {
40
+ const value = LEAVES[kind].read(raw);
41
+ if (value !== undefined) {
42
+ return value;
43
+ }
44
+ }
45
+ return undefined;
46
+ }
47
+ const isTextList = (raw) => Array.isArray(raw) && raw.every((entry) => typeof entry === 'string');
48
+ /**
49
+ * The diff of a shape whose write replaces what is held, from how it compares two values that both
50
+ * hold something: a value going is the write `null`, and a value arriving is the whole value.
51
+ */
52
+ const diffing = (change) => (held, next) => {
53
+ if (next === undefined) {
54
+ return held === undefined ? undefined : null;
55
+ }
56
+ return held === undefined ? next : change(held, next);
57
+ };
58
+ /** A record's parts that hold something, or undefined when none does: cleared parts are left out. */
59
+ const someParts = (parts) => {
60
+ const held = {};
61
+ for (const part of keysOf(parts)) {
62
+ const value = filled(parts[part] ?? undefined);
63
+ if (value !== undefined) {
64
+ held[part] = value;
65
+ }
66
+ }
67
+ return keysOf(held).length > 0 ? held : undefined;
68
+ };
69
+ /** A set's options, or undefined when it has none. */
70
+ const someOptions = (options) => options.length > 0 ? options : undefined;
71
+ const scalar = {
72
+ // Any leaf's value rather than only its own leaf's, so text that holds no value of the leaf is
73
+ // kept for the leaf's rule to refuse; its type decides which kind it must be.
74
+ parse: (_type, raw) => readAnyLeaf(raw),
75
+ same: (a, b) => a === b,
76
+ apply: (_held, write) => write,
77
+ diff: diffing((held, next) => (held === next ? undefined : next)),
78
+ };
79
+ const record = {
80
+ // Only the parts the type declares, each read as its leaf's kind of value.
81
+ parse: (type, raw) => {
82
+ if (!isRecordValue(raw)) {
83
+ return undefined;
84
+ }
85
+ const parts = FIELD_STRUCTURES[type].parts;
86
+ const value = {};
87
+ for (const part of keysOf(parts)) {
88
+ const held = readLeaf(parts[part], raw[part]);
89
+ if (held !== undefined) {
90
+ value[part] = held;
91
+ }
92
+ }
93
+ return keysOf(value).length > 0 ? value : undefined;
94
+ },
95
+ same: (a, b) => record.diff(a, b) === undefined,
96
+ // Merged, as JSON Merge Patch merges objects: a part the write names is set, `null` clears it,
97
+ // and a part it leaves out is left alone, so writes to different parts don't overwrite each
98
+ // other.
99
+ apply: (held, write) => {
100
+ const merged = { ...held };
101
+ for (const part of keysOf(write)) {
102
+ const value = write[part];
103
+ if (value !== undefined) {
104
+ merged[part] = value;
105
+ }
106
+ }
107
+ return someParts(merged);
108
+ },
109
+ // Never `null`, even when nothing is left: a merged write names only the parts its writer saw, so
110
+ // a writer clearing the city doesn't also clear a country someone else has just set.
111
+ diff: (held, next) => {
112
+ if (held === undefined) {
113
+ return next;
114
+ }
115
+ const now = next ?? {};
116
+ const write = {};
117
+ for (const part of keysOf({ ...held, ...now })) {
118
+ if (held[part] !== now[part]) {
119
+ write[part] = now[part] ?? null;
120
+ }
121
+ }
122
+ return keysOf(write).length > 0 ? write : undefined;
123
+ },
124
+ };
125
+ const set = {
126
+ parse: (_type, raw) => (isTextList(raw) ? someOptions(raw) : undefined),
127
+ same: (a, b) => {
128
+ const options = new Set(b);
129
+ return new Set(a).size === options.size && a.every((option) => options.has(option));
130
+ },
131
+ // Replaced, as JSON Merge Patch replaces arrays: a write states the whole answer.
132
+ apply: (_held, write) => write,
133
+ diff: diffing((held, next) => (set.same(held, next) ? undefined : next)),
134
+ };
135
+ /** Each shape's rules. A shape added to the catalog without rules doesn't compile. */
136
+ export const SHAPES = { scalar, record, set };
137
+ /** A field paired with its shape: the one place a field's union is branched on by shape. */
138
+ export function shaped(field) {
139
+ return matchField(field, {
140
+ scalar: (of) => ({ shape: 'scalar', field: of }),
141
+ record: (of) => ({ shape: 'record', field: of }),
142
+ set: (of) => ({ shape: 'set', field: of }),
143
+ });
144
+ }
145
+ /** A type paired with its shape. */
146
+ export function shapedType(type) {
147
+ return matchShape(type, {
148
+ scalar: (_structure, of) => ({ shape: 'scalar', type: of }),
149
+ record: (_structure, of) => ({ shape: 'record', type: of }),
150
+ set: (_structure, of) => ({ shape: 'set', type: of }),
151
+ });
152
+ }
153
+ /** A form shows everything the field holds: true of every shape but a set. */
154
+ const showsWhatItHolds = () => ({
155
+ editable: (_field, held) => held,
156
+ });
157
+ export const FIELD_READING = {
158
+ scalar: { held: (_field, value) => value, ...showsWhatItHolds() },
159
+ // Parsing already kept only the parts the type declares, which are all a client can draw.
160
+ record: { held: (_field, value) => value, ...showsWhatItHolds() },
161
+ set: {
162
+ held: ({ settings }, value) => {
163
+ const rank = (text) => {
164
+ const index = settings.options.indexOf(text);
165
+ return index === -1 ? settings.options.length : index;
166
+ };
167
+ return [...value].sort((a, b) => rank(a) - rank(b) || (a < b ? -1 : a > b ? 1 : 0));
168
+ },
169
+ editable: ({ settings }, held) => someOptions(editableAnswers(settings, held)),
170
+ },
171
+ };
172
+ /**
173
+ * What a held raw value reads as for its field: its structure checked, then read as the field
174
+ * gives it meaning. Undefined when the value isn't the field's structure.
175
+ */
176
+ export function heldValue({ shape, field }, raw) {
177
+ const value = SHAPES[shape].parse(field.type, raw);
178
+ return value === undefined ? undefined : FIELD_READING[shape].held(field, value);
179
+ }
180
+ /** What a form can show of a held raw value, or undefined when it shows nothing. */
181
+ export function editableValue(of, raw) {
182
+ const held = heldValue(of, raw);
183
+ return held === undefined ? undefined : FIELD_READING[of.shape].editable(of.field, held);
184
+ }
185
+ /** A leaf's value as text gives it, or undefined for blank text, which holds nothing. */
186
+ export const leafFromText = (leaf, text) => {
187
+ const value = filled(text);
188
+ return value === undefined ? undefined : LEAVES[leaf.leaf].fromText(text);
189
+ };
190
+ /** A leaf read from its text, where it is text; blank text is kept, for parsing to drop. */
191
+ const leafOf = (leaf, raw) => typeof raw === 'string' ? (leafFromText(leaf, raw) ?? raw) : raw;
192
+ const SHAPE_TEXT = {
193
+ scalar: { fromText: (type, raw) => leafOf(FIELD_STRUCTURES[type].leaf, raw) },
194
+ record: {
195
+ fromText: (type, raw) => {
196
+ if (!isRecordValue(raw)) {
197
+ return raw;
198
+ }
199
+ const leaves = FIELD_STRUCTURES[type].parts;
200
+ return Object.fromEntries(Object.entries(raw).map(([part, held]) => {
201
+ const leaf = Object.prototype.hasOwnProperty.call(leaves, part)
202
+ ? leaves[part]
203
+ : undefined;
204
+ return [part, leaf ? leafOf(leaf, held) : held];
205
+ }));
206
+ },
207
+ },
208
+ set: { fromText: (_type, raw) => raw },
209
+ };
210
+ /**
211
+ * What a value given as text holds, such as a form's inputs or a row's cells: each leaf read from
212
+ * its text, then parsed as a value of its type, which drops blank text. Undefined when it holds
213
+ * nothing.
214
+ */
215
+ export function valueFromText({ shape, type }, raw) {
216
+ return SHAPES[shape].parse(type, SHAPE_TEXT[shape].fromText(type, raw));
217
+ }
218
+ /** How a value of each shape is held by a form's inputs, each leaf as `String` writes it. */
219
+ const VALUE_TEXT = {
220
+ scalar: (value) => String(value),
221
+ record: (value) => Object.fromEntries(keysOf(value).flatMap((part) => {
222
+ const held = value[part];
223
+ return held === undefined ? [] : [[part, String(held)]];
224
+ })),
225
+ set: (value) => value,
226
+ };
227
+ /** A value as a form's inputs hold it, which `valueFromText` reads back as the same value. */
228
+ export function textOfValue(shape, value) {
229
+ return VALUE_TEXT[shape](value);
230
+ }
231
+ /** What a field holds, each leaf as its text, as a field shown but not edited draws it. */
232
+ export function heldTextOf(of, held) {
233
+ const value = heldValue(of, held);
234
+ return value === undefined ? undefined : textOfValue(of.shape, value);
235
+ }
236
+ /**
237
+ * What a form's inputs start from for a held raw value: what the form can show of it, each leaf as
238
+ * its text, or undefined when it shows nothing.
239
+ */
240
+ export function formTextOf(of, held) {
241
+ const value = editableValue(of, held);
242
+ return value === undefined ? undefined : textOfValue(of.shape, value);
243
+ }
244
+ /**
245
+ * What a form's inputs show, read as the field reads a value: each leaf from its text, blank text
246
+ * holding nothing, and only what the form can show. Undefined when they show nothing.
247
+ */
248
+ export function formShows(of, inputs) {
249
+ const typed = valueFromText({ shape: of.shape, type: of.field.type }, inputs);
250
+ return typed === undefined ? undefined : editableValue(of, typed);
251
+ }
252
+ /**
253
+ * The write that turns what a field holds into what a form's inputs show: `null` when the inputs
254
+ * show nothing of a replacing shape, and undefined when they show what the field holds. The held
255
+ * value is read as the field reads it first, so a part the form doesn't draw is never written, and
256
+ * an answer the form can't show, such as one to an option the field no longer offers, is cleared
257
+ * by the write.
258
+ */
259
+ export function formWrite(of, inputs, held) {
260
+ return SHAPES[of.shape].diff(heldValue(of, held), formShows(of, inputs));
261
+ }
262
+ //# sourceMappingURL=shapes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shapes.js","sourceRoot":"","sources":["../src/shapes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,UAAU,EACV,UAAU,EAWV,MAAM,GACP,MAAM,gBAAgB,CAAC;AA6ExB;;;GAGG;AACH,MAAM,MAAM,GAAG,CAAyB,GAAkB,EAAiB,EAAE,CAC3E,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;AAEjE,qGAAqG;AACrG,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,CAAC,GAAY,EAAE,EAAE,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClF,QAAQ,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE;CAC/B,CAAC;AAEX,MAAM,CAAC,MAAM,MAAM,GAAmD;IACpE,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,WAAW;CACpB,CAAC;AAEF,uEAAuE;AACvE,MAAM,QAAQ,GAAG,CAAqB,IAA0B,EAAE,GAAY,EAAE,EAAE,CAChF,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE9B,2FAA2F;AAC3F,SAAS,WAAW,CAAC,GAAY;IAC/B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAKD,MAAM,UAAU,GAAG,CAAC,GAAY,EAAmB,EAAE,CACnD,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC;AAExE;;;GAGG;AACH,MAAM,OAAO,GACX,CAAO,MAA2C,EAAE,EAAE,CACtD,CAAC,IAAmB,EAAE,IAAmB,EAA4B,EAAE;IACrE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/C,CAAC;IACD,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACxD,CAAC,CAAC;AAEJ,qGAAqG;AACrG,MAAM,SAAS,GAAG,CAAC,KAA2B,EAAoC,EAAE;IAClF,MAAM,IAAI,GAAmC,EAAE,CAAC;IAChD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,CAAC;QAC/C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC,CAAC;AAEF,sDAAsD;AACtD,MAAM,WAAW,GAAG,CAAC,OAA0B,EAAiC,EAAE,CAChF,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAE3C,MAAM,MAAM,GAAyB;IACnC,+FAA+F;IAC/F,8EAA8E;IAC9E,KAAK,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC;IACvB,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK;IAC9B,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;CAClE,CAAC;AAEF,MAAM,MAAM,GAAyB;IACnC,2EAA2E;IAC3E,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACnB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;QAC3C,MAAM,KAAK,GAAmC,EAAE,CAAC;QACjD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;YACrB,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,CAAC;IACD,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,SAAS;IAC/C,+FAA+F;IAC/F,4FAA4F;IAC5F,SAAS;IACT,KAAK,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACrB,MAAM,MAAM,GAAmC,EAAE,GAAG,IAAI,EAAE,CAAC;QAC3D,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;YACvB,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IACD,kGAAkG;IAClG,qFAAqF;IACrF,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;QACnB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,GAAG,GAAyB,IAAI,IAAI,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAmC,EAAE,CAAC;QACjD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC;YAC/C,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;YAClC,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,CAAC;CACF,CAAC;AAEF,MAAM,GAAG,GAAsB;IAC7B,KAAK,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACb,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3B,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACtF,CAAC;IACD,kFAAkF;IAClF,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK;IAC9B,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;CACzE,CAAC;AAEF,sFAAsF;AACtF,MAAM,CAAC,MAAM,MAAM,GAAkD,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAe7F,4FAA4F;AAC5F,MAAM,UAAU,MAAM,CAA0B,KAAQ;IACtD,OAAO,UAAU,CAAoB,KAAK,EAAE;QAC1C,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAChD,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAChD,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;KAC3C,CAAC,CAAC;AACL,CAAC;AAUD,oCAAoC;AACpC,MAAM,UAAU,UAAU,CAAC,IAAe;IACxC,OAAO,UAAU,CAAa,IAAI,EAAE;QAClC,MAAM,EAAE,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAC3D,MAAM,EAAE,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAC3D,GAAG,EAAE,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;KACtD,CAAC,CAAC;AACL,CAAC;AAiBD,8EAA8E;AAC9E,MAAM,gBAAgB,GAAG,GAA4D,EAAE,CAAC,CAAC;IACvF,QAAQ,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI;CACjC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAoD;IAC5E,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,gBAAgB,EAAY,EAAE;IAC3E,0FAA0F;IAC1F,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,gBAAgB,EAAY,EAAE;IAC3E,GAAG,EAAE;QACH,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE;YAC5B,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE;gBAC5B,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBAC7C,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;YACxD,CAAC,CAAC;YACF,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtF,CAAC;QACD,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;KAC/E;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,SAAS,CACvB,EAAE,KAAK,EAAE,KAAK,EAAiC,EAC/C,GAAY;IAEZ,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACnD,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACnF,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,aAAa,CAC3B,EAAiC,EACjC,GAAY;IAEZ,MAAM,IAAI,GAAG,SAAS,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAChC,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAC3F,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAU,EAAE,IAAY,EAA4B,EAAE;IACjF,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC5E,CAAC,CAAC;AAUF,4FAA4F;AAC5F,MAAM,MAAM,GAAG,CAAC,IAAU,EAAE,GAAY,EAAW,EAAE,CACnD,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAEnE,MAAM,UAAU,GAAoD;IAClE,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE;IAC7E,MAAM,EAAE;QACN,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YACtB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,OAAO,GAAG,CAAC;YACb,CAAC;YACD,MAAM,MAAM,GAA+C,gBAAgB,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;YACxF,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvC,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;oBAC7D,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;oBACd,CAAC,CAAC,SAAS,CAAC;gBACd,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAClD,CAAC,CAAC,CACH,CAAC;QACJ,CAAC;KACF;IACD,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE;CACvC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,EAAE,KAAK,EAAE,IAAI,EAAiB,EAC9B,GAAY;IAEZ,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;AAC1E,CAAC;AASD,6FAA6F;AAC7F,MAAM,UAAU,GAA2E;IACzF,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;IAChC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAChB,MAAM,CAAC,WAAW,CAChB,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACzB,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC,CACH;IACH,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;CACtB,CAAC;AAEF,8FAA8F;AAC9F,MAAM,UAAU,WAAW,CAAuB,KAAQ,EAAE,KAAoB;IAC9E,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,UAAU,CACxB,EAAiC,EACjC,IAAa;IAEb,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAClC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACxE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,EAAiC,EACjC,IAAa;IAEb,MAAM,KAAK,GAAG,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACtC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACxE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CACvB,EAAiC,EACjC,MAAe;IAEf,MAAM,KAAK,GAAG,aAAa,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;IAC9E,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AACpE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACvB,EAAiC,EACjC,MAAe,EACf,IAAa;IAEb,OAAO,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;AAC3E,CAAC"}