@sentropic/design-system-svelte 0.11.0 → 0.12.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,130 @@
1
+ <script lang="ts">
2
+ import { ChevronDown } from "@lucide/svelte";
3
+ import type { Snippet } from "svelte";
4
+ import type { HTMLAttributes } from "svelte/elements";
5
+
6
+ type CollapsibleProps = Omit<HTMLAttributes<HTMLDivElement>, "class" | "title"> & {
7
+ /** État ouvert (bindable). */
8
+ open?: boolean;
9
+ title: string;
10
+ disabled?: boolean;
11
+ onToggle?: (open: boolean) => void;
12
+ class?: string;
13
+ children?: Snippet;
14
+ };
15
+
16
+ let {
17
+ open = $bindable(false),
18
+ title,
19
+ disabled = false,
20
+ onToggle,
21
+ class: className,
22
+ children,
23
+ ...rest
24
+ }: CollapsibleProps = $props();
25
+
26
+ const uid = `st-collapsible-${Math.random().toString(36).slice(2, 9)}`;
27
+
28
+ const classes = $derived(
29
+ ["st-collapsible", open ? "st-collapsible--open" : null, className].filter(Boolean).join(" ")
30
+ );
31
+
32
+ function toggle() {
33
+ if (disabled) return;
34
+ open = !open;
35
+ onToggle?.(open);
36
+ }
37
+ </script>
38
+
39
+ <div {...rest} class={classes}>
40
+ <button
41
+ type="button"
42
+ class="st-collapsible__trigger"
43
+ aria-expanded={open ? "true" : "false"}
44
+ aria-controls={`${uid}-region`}
45
+ id={`${uid}-trigger`}
46
+ {disabled}
47
+ onclick={toggle}
48
+ >
49
+ <span class="st-collapsible__title">{title}</span>
50
+ <span class="st-collapsible__icon" aria-hidden="true">
51
+ <ChevronDown size={18} strokeWidth={2.25} />
52
+ </span>
53
+ </button>
54
+ {#if open}
55
+ <div
56
+ class="st-collapsible__region"
57
+ role="region"
58
+ id={`${uid}-region`}
59
+ aria-labelledby={`${uid}-trigger`}
60
+ >
61
+ {@render children?.()}
62
+ </div>
63
+ {/if}
64
+ </div>
65
+
66
+ <style>
67
+ .st-collapsible {
68
+ color: var(--st-semantic-text-primary);
69
+ width: 100%;
70
+ }
71
+
72
+ .st-collapsible__trigger {
73
+ align-items: center;
74
+ background: transparent;
75
+ border: 0;
76
+ color: var(--st-component-accordion-text, inherit);
77
+ cursor: pointer;
78
+ display: flex;
79
+ font: inherit;
80
+ font-size: var(--st-component-accordion-fontSize, 0.9375rem);
81
+ font-weight: var(--st-component-accordion-fontWeight, 650);
82
+ gap: 0.75rem;
83
+ justify-content: space-between;
84
+ line-height: var(--st-component-accordion-lineHeight, 1.3);
85
+ padding: var(--st-component-accordion-paddingBlock, 0.625rem)
86
+ var(--st-component-accordion-paddingInline, 0.25rem);
87
+ text-align: start;
88
+ transition: background-color var(--st-motion-fast, 120ms) var(--st-motion-easing, ease);
89
+ width: 100%;
90
+ }
91
+
92
+ .st-collapsible__trigger:hover:not(:disabled) {
93
+ background: var(--st-component-control-hoverBackground, var(--st-semantic-surface-subtle));
94
+ }
95
+
96
+ .st-collapsible__trigger:focus-visible {
97
+ outline: 2px solid var(--st-component-control-focusRing, var(--st-semantic-border-interactive));
98
+ outline-offset: -2px;
99
+ }
100
+
101
+ .st-collapsible__trigger:disabled {
102
+ color: var(--st-semantic-text-muted);
103
+ cursor: not-allowed;
104
+ }
105
+
106
+ .st-collapsible__title {
107
+ flex: 1 1 auto;
108
+ }
109
+
110
+ .st-collapsible__icon {
111
+ align-items: center;
112
+ color: var(--st-semantic-text-secondary);
113
+ display: inline-flex;
114
+ flex: 0 0 auto;
115
+ height: 1.25rem;
116
+ justify-content: center;
117
+ transition: transform var(--st-motion-fast, 120ms) var(--st-motion-easing, ease);
118
+ width: 1.25rem;
119
+ }
120
+
121
+ .st-collapsible--open .st-collapsible__icon {
122
+ transform: rotate(180deg);
123
+ }
124
+
125
+ .st-collapsible__region {
126
+ color: var(--st-semantic-text-secondary);
127
+ line-height: 1.5;
128
+ padding: 0 0.25rem 0.625rem;
129
+ }
130
+ </style>
@@ -0,0 +1,15 @@
1
+ import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ type CollapsibleProps = Omit<HTMLAttributes<HTMLDivElement>, "class" | "title"> & {
4
+ /** État ouvert (bindable). */
5
+ open?: boolean;
6
+ title: string;
7
+ disabled?: boolean;
8
+ onToggle?: (open: boolean) => void;
9
+ class?: string;
10
+ children?: Snippet;
11
+ };
12
+ declare const Collapsible: import("svelte").Component<CollapsibleProps, {}, "open">;
13
+ type Collapsible = ReturnType<typeof Collapsible>;
14
+ export default Collapsible;
15
+ //# sourceMappingURL=Collapsible.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Collapsible.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Collapsible.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG;IAChF,8BAA8B;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAgDJ,QAAA,MAAM,WAAW,0DAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -0,0 +1,111 @@
1
+ <script lang="ts" module>
2
+ export interface RadioGroupOption {
3
+ label: string;
4
+ value: string;
5
+ disabled?: boolean;
6
+ helperText?: string;
7
+ }
8
+ </script>
9
+
10
+ <script lang="ts">
11
+ import type { Snippet } from "svelte";
12
+ import type { HTMLAttributes } from "svelte/elements";
13
+ import Radio from "./Radio.svelte";
14
+
15
+ type RadioGroupProps = Omit<HTMLAttributes<HTMLFieldSetElement>, "class" | "onchange"> & {
16
+ legend: string;
17
+ /** Valeur sélectionnée (contrôlée). */
18
+ value?: string;
19
+ onchange?: (value: string) => void;
20
+ orientation?: "vertical" | "horizontal";
21
+ /** Nom partagé garantissant l'exclusivité radio. Requis. */
22
+ name: string;
23
+ options?: RadioGroupOption[];
24
+ helperText?: string;
25
+ disabled?: boolean;
26
+ class?: string;
27
+ children?: Snippet;
28
+ };
29
+
30
+ let {
31
+ legend,
32
+ value,
33
+ onchange,
34
+ orientation = "vertical",
35
+ name,
36
+ options = [],
37
+ helperText,
38
+ disabled = false,
39
+ class: className,
40
+ children,
41
+ ...rest
42
+ }: RadioGroupProps = $props();
43
+
44
+ const classes = $derived(
45
+ ["st-radioGroup", `st-radioGroup--${orientation}`, className].filter(Boolean).join(" ")
46
+ );
47
+
48
+ function select(optionValue: string) {
49
+ if (optionValue === value) return;
50
+ onchange?.(optionValue);
51
+ }
52
+ </script>
53
+
54
+ <fieldset {...rest} class={classes} {disabled}>
55
+ <legend class="st-radioGroup__legend">{legend}</legend>
56
+ {#if helperText}
57
+ <p class="st-radioGroup__help">{helperText}</p>
58
+ {/if}
59
+ <div class="st-radioGroup__options">
60
+ {#each options as option (option.value)}
61
+ <Radio
62
+ label={option.label}
63
+ helperText={option.helperText}
64
+ {name}
65
+ value={option.value}
66
+ checked={value === option.value}
67
+ disabled={option.disabled}
68
+ onchange={() => select(option.value)}
69
+ />
70
+ {/each}
71
+ {@render children?.()}
72
+ </div>
73
+ </fieldset>
74
+
75
+ <style>
76
+ .st-radioGroup {
77
+ border: 0;
78
+ margin: 0;
79
+ min-width: 0;
80
+ padding: 0;
81
+ }
82
+
83
+ .st-radioGroup__legend {
84
+ color: var(--st-component-field-labelText, var(--st-semantic-text-primary));
85
+ font-size: 0.9375rem;
86
+ font-weight: 650;
87
+ line-height: 1.3;
88
+ padding: 0;
89
+ }
90
+
91
+ .st-radioGroup__help {
92
+ color: var(--st-component-field-helpText, var(--st-semantic-text-secondary));
93
+ font-size: 0.8125rem;
94
+ margin: 0.25rem 0 0;
95
+ }
96
+
97
+ .st-radioGroup__options {
98
+ display: flex;
99
+ gap: var(--st-spacing-3, 0.75rem);
100
+ margin-top: var(--st-spacing-2, 0.5rem);
101
+ }
102
+
103
+ .st-radioGroup--vertical .st-radioGroup__options {
104
+ flex-direction: column;
105
+ }
106
+
107
+ .st-radioGroup--horizontal .st-radioGroup__options {
108
+ flex-direction: row;
109
+ flex-wrap: wrap;
110
+ }
111
+ </style>
@@ -0,0 +1,26 @@
1
+ export interface RadioGroupOption {
2
+ label: string;
3
+ value: string;
4
+ disabled?: boolean;
5
+ helperText?: string;
6
+ }
7
+ import type { Snippet } from "svelte";
8
+ import type { HTMLAttributes } from "svelte/elements";
9
+ type RadioGroupProps = Omit<HTMLAttributes<HTMLFieldSetElement>, "class" | "onchange"> & {
10
+ legend: string;
11
+ /** Valeur sélectionnée (contrôlée). */
12
+ value?: string;
13
+ onchange?: (value: string) => void;
14
+ orientation?: "vertical" | "horizontal";
15
+ /** Nom partagé garantissant l'exclusivité radio. Requis. */
16
+ name: string;
17
+ options?: RadioGroupOption[];
18
+ helperText?: string;
19
+ disabled?: boolean;
20
+ class?: string;
21
+ children?: Snippet;
22
+ };
23
+ declare const RadioGroup: import("svelte").Component<RadioGroupProps, {}, "">;
24
+ type RadioGroup = ReturnType<typeof RadioGroup>;
25
+ export default RadioGroup;
26
+ //# sourceMappingURL=RadioGroup.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RadioGroup.svelte.d.ts","sourceRoot":"","sources":["../src/lib/RadioGroup.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIpD,KAAK,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC,GAAG;IACvF,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACxC,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAkDJ,QAAA,MAAM,UAAU,qDAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -0,0 +1,257 @@
1
+ <script lang="ts" module>
2
+ export interface StepperStep {
3
+ label: string;
4
+ description?: string;
5
+ }
6
+
7
+ export type StepperOrientation = "horizontal" | "vertical";
8
+ </script>
9
+
10
+ <script lang="ts">
11
+ import { Check } from "@lucide/svelte";
12
+ import type { HTMLAttributes } from "svelte/elements";
13
+
14
+ type StepperProps = Omit<HTMLAttributes<HTMLOListElement>, "class"> & {
15
+ steps: StepperStep[];
16
+ /** Index de l'étape courante (0-based). */
17
+ current?: number;
18
+ orientation?: StepperOrientation;
19
+ /** Autorise la navigation au clic sur les étapes. */
20
+ clickable?: boolean;
21
+ onStepClick?: (index: number) => void;
22
+ /** Étiquette a11y de la liste d'étapes. */
23
+ label?: string;
24
+ class?: string;
25
+ };
26
+
27
+ let {
28
+ steps,
29
+ current = 0,
30
+ orientation = "horizontal",
31
+ clickable = false,
32
+ onStepClick,
33
+ label = "Progression",
34
+ class: className,
35
+ ...rest
36
+ }: StepperProps = $props();
37
+
38
+ const classes = $derived(
39
+ ["st-stepper", `st-stepper--${orientation}`, className].filter(Boolean).join(" ")
40
+ );
41
+
42
+ function stateOf(index: number): "complete" | "current" | "upcoming" {
43
+ if (index < current) return "complete";
44
+ if (index === current) return "current";
45
+ return "upcoming";
46
+ }
47
+
48
+ function handleClick(index: number) {
49
+ if (!clickable) return;
50
+ onStepClick?.(index);
51
+ }
52
+ </script>
53
+
54
+ <ol {...rest} class={classes} aria-label={label}>
55
+ {#each steps as step, index (index)}
56
+ {@const state = stateOf(index)}
57
+ {@const isLast = index === steps.length - 1}
58
+ <li
59
+ class={["st-stepper__step", `st-stepper__step--${state}`].join(" ")}
60
+ aria-current={state === "current" ? "step" : undefined}
61
+ >
62
+ <span class="st-stepper__indicator">
63
+ {#if clickable}
64
+ <button
65
+ type="button"
66
+ class="st-stepper__circle st-stepper__circle--button"
67
+ onclick={() => handleClick(index)}
68
+ aria-label={step.label}
69
+ >
70
+ {#if state === "complete"}
71
+ <Check size={14} strokeWidth={2.5} aria-hidden="true" />
72
+ {:else}
73
+ <span class="st-stepper__index">{index + 1}</span>
74
+ {/if}
75
+ </button>
76
+ {:else}
77
+ <span class="st-stepper__circle">
78
+ {#if state === "complete"}
79
+ <Check size={14} strokeWidth={2.5} aria-hidden="true" />
80
+ {:else}
81
+ <span class="st-stepper__index">{index + 1}</span>
82
+ {/if}
83
+ </span>
84
+ {/if}
85
+ {#if !isLast}
86
+ <span class="st-stepper__connector"></span>
87
+ {/if}
88
+ </span>
89
+ <span class="st-stepper__text">
90
+ <span class="st-stepper__label">{step.label}</span>
91
+ {#if step.description}
92
+ <span class="st-stepper__description">{step.description}</span>
93
+ {/if}
94
+ </span>
95
+ </li>
96
+ {/each}
97
+ </ol>
98
+
99
+ <style>
100
+ .st-stepper {
101
+ color: var(--st-semantic-text-primary);
102
+ display: flex;
103
+ list-style: none;
104
+ margin: 0;
105
+ padding: 0;
106
+ }
107
+
108
+ .st-stepper--horizontal {
109
+ align-items: flex-start;
110
+ flex-direction: row;
111
+ }
112
+
113
+ .st-stepper--vertical {
114
+ flex-direction: column;
115
+ }
116
+
117
+ .st-stepper__step {
118
+ display: flex;
119
+ flex: 1 1 0;
120
+ gap: var(--st-spacing-2, 0.5rem);
121
+ min-width: 0;
122
+ position: relative;
123
+ }
124
+
125
+ .st-stepper--horizontal .st-stepper__step {
126
+ align-items: flex-start;
127
+ flex-direction: column;
128
+ }
129
+
130
+ .st-stepper--vertical .st-stepper__step {
131
+ align-items: flex-start;
132
+ flex: 0 0 auto;
133
+ flex-direction: row;
134
+ }
135
+
136
+ .st-stepper__indicator {
137
+ align-items: center;
138
+ display: flex;
139
+ flex: 0 0 auto;
140
+ justify-content: center;
141
+ position: relative;
142
+ }
143
+
144
+ .st-stepper--horizontal .st-stepper__indicator {
145
+ flex-direction: row;
146
+ width: 100%;
147
+ }
148
+
149
+ .st-stepper--vertical .st-stepper__indicator {
150
+ flex-direction: column;
151
+ min-height: 3rem;
152
+ }
153
+
154
+ .st-stepper__circle {
155
+ align-items: center;
156
+ background: var(--st-semantic-surface-default);
157
+ border: 1.5px solid var(--st-semantic-border-strong);
158
+ border-radius: 50%;
159
+ color: var(--st-semantic-text-secondary);
160
+ display: inline-flex;
161
+ flex: 0 0 auto;
162
+ font-size: 0.75rem;
163
+ font-weight: 600;
164
+ height: 1.5rem;
165
+ justify-content: center;
166
+ line-height: 1;
167
+ width: 1.5rem;
168
+ z-index: 1;
169
+ }
170
+
171
+ .st-stepper__circle--button {
172
+ cursor: pointer;
173
+ font: inherit;
174
+ font-size: 0.75rem;
175
+ font-weight: 600;
176
+ padding: 0;
177
+ transition:
178
+ background var(--st-motion-fast, 120ms) var(--st-motion-easing, ease),
179
+ border-color var(--st-motion-fast, 120ms) var(--st-motion-easing, ease);
180
+ }
181
+
182
+ .st-stepper__circle--button:hover {
183
+ border-color: var(--st-semantic-action-primary);
184
+ }
185
+
186
+ .st-stepper__circle--button:focus-visible {
187
+ outline: 2px solid var(--st-semantic-border-interactive, var(--st-semantic-action-primary));
188
+ outline-offset: 2px;
189
+ }
190
+
191
+ .st-stepper__index {
192
+ line-height: 1;
193
+ }
194
+
195
+ .st-stepper__connector {
196
+ background: var(--st-semantic-border-subtle);
197
+ flex: 1 1 auto;
198
+ }
199
+
200
+ .st-stepper--horizontal .st-stepper__connector {
201
+ height: 2px;
202
+ margin-top: calc(0.75rem - 1px);
203
+ }
204
+
205
+ .st-stepper--vertical .st-stepper__connector {
206
+ margin-left: calc(0.75rem - 1px);
207
+ min-height: 1.5rem;
208
+ width: 2px;
209
+ }
210
+
211
+ .st-stepper__text {
212
+ display: grid;
213
+ gap: 0.125rem;
214
+ min-width: 0;
215
+ }
216
+
217
+ .st-stepper--horizontal .st-stepper__text {
218
+ padding-right: var(--st-spacing-3, 0.75rem);
219
+ padding-top: var(--st-spacing-2, 0.5rem);
220
+ }
221
+
222
+ .st-stepper--vertical .st-stepper__text {
223
+ padding-bottom: var(--st-spacing-3, 0.75rem);
224
+ }
225
+
226
+ .st-stepper__label {
227
+ color: var(--st-semantic-text-primary);
228
+ font-size: 0.875rem;
229
+ font-weight: 600;
230
+ }
231
+
232
+ .st-stepper__description {
233
+ color: var(--st-semantic-text-secondary);
234
+ font-size: 0.8125rem;
235
+ }
236
+
237
+ /* State: complete */
238
+ .st-stepper__step--complete .st-stepper__circle {
239
+ background: var(--st-semantic-action-primary);
240
+ border-color: var(--st-semantic-action-primary);
241
+ color: var(--st-semantic-action-primaryText);
242
+ }
243
+
244
+ .st-stepper__step--complete .st-stepper__connector {
245
+ background: var(--st-semantic-action-primary);
246
+ }
247
+
248
+ /* State: current */
249
+ .st-stepper__step--current .st-stepper__circle {
250
+ border-color: var(--st-semantic-action-primary);
251
+ color: var(--st-semantic-action-primary);
252
+ }
253
+
254
+ .st-stepper__step--current .st-stepper__label {
255
+ color: var(--st-semantic-action-primary);
256
+ }
257
+ </style>
@@ -0,0 +1,22 @@
1
+ export interface StepperStep {
2
+ label: string;
3
+ description?: string;
4
+ }
5
+ export type StepperOrientation = "horizontal" | "vertical";
6
+ import type { HTMLAttributes } from "svelte/elements";
7
+ type StepperProps = Omit<HTMLAttributes<HTMLOListElement>, "class"> & {
8
+ steps: StepperStep[];
9
+ /** Index de l'étape courante (0-based). */
10
+ current?: number;
11
+ orientation?: StepperOrientation;
12
+ /** Autorise la navigation au clic sur les étapes. */
13
+ clickable?: boolean;
14
+ onStepClick?: (index: number) => void;
15
+ /** Étiquette a11y de la liste d'étapes. */
16
+ label?: string;
17
+ class?: string;
18
+ };
19
+ declare const Stepper: import("svelte").Component<StepperProps, {}, "">;
20
+ type Stepper = ReturnType<typeof Stepper>;
21
+ export default Stepper;
22
+ //# sourceMappingURL=Stepper.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stepper.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Stepper.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,UAAU,CAAC;AAI7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC,GAAG;IACpE,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,qDAAqD;IACrD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA4EJ,QAAA,MAAM,OAAO,kDAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}