@starterlib/ui 0.1.1 → 0.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.
package/README.md CHANGED
@@ -14,6 +14,55 @@ des dependances de pair : c'est l'application qui les installe, et elles doivent
14
14
  etre **identiques dans l'hote et dans chaque remote**. Deux versions du socle
15
15
  dans le meme navigateur, ce sont deux jeux de jetons d'injection.
16
16
 
17
+ ## Deux points d'entree
18
+
19
+ Decoupes par **dependance**, jamais par famille : un composant sort du tronc
20
+ quand il traine un pair lourd, et seulement alors.
21
+
22
+ | Point d'entree | Contenu | Ce qu'il traine |
23
+ | ------------------------- | ----------------------------------- | ------------------------------------------------- |
24
+ | `@starterlib/ui` | 22 composants | rien de lourd |
25
+ | `@starterlib/ui/surfaces` | ce qui se pose AU-DESSUS de la page | `@angular/cdk` overlay et portal, `@angular/aria` |
26
+
27
+ ```ts
28
+ import { StButton, StIcon } from '@starterlib/ui';
29
+ import { StMenu, StMenuItem, StMenuTrigger } from '@starterlib/ui/surfaces';
30
+ ```
31
+
32
+ ⚠️ Un paquet partage en federation **ne s'elague pas** : declare singleton, il
33
+ est charge en entier des qu'un remote le reference. La separation n'a donc pas
34
+ pour but le poids — 16,8 Ko gzippes pour le tronc — mais le **train de
35
+ singletons** : une application qui n'affiche ni menu ni dialogue ne charge pas
36
+ le CDK, et n'a pas a se redeployer quand celui-ci monte de version.
37
+
38
+ `@angular/cdk` reste declare en pair du paquet, mais n'est importe que par
39
+ `ui/surfaces`. Voir `docs/adr/0003-points-d-entree-decoupes-par-dependance.md`.
40
+
41
+ ## Configuration — une fois, dans l'hote
42
+
43
+ ```ts
44
+ import { provideStarterUi, LIBELLES_FR } from '@starterlib/ui';
45
+
46
+ export const appConfig: ApplicationConfig = {
47
+ providers: [
48
+ provideStarterUi({
49
+ cheminDuSprite: '/ui/socle/assets/icones/sprite.svg',
50
+ locale, // Signal<string> : les formats suivent la langue a chaud
51
+ libelles, // Signal<LibellesUi> : LIBELLES_FR, LIBELLES_EN, ou le votre
52
+ fuseau: 'Europe/Paris',
53
+ }),
54
+ ],
55
+ };
56
+ ```
57
+
58
+ ⚠️ **Dans l'hote uniquement.** Un remote qui la rappellerait poserait un second
59
+ jeu de valeurs dans son injecteur de route : deux locales, deux dictionnaires,
60
+ et la moitie de l'ecran resterait dans l'ancienne langue apres une bascule.
61
+
62
+ Sans configuration, les composants prennent `LOCALE_ID` et le francais. C'est un
63
+ depannage, pas une i18n : une application bilingue doit fournir des signaux,
64
+ sinon la bascule de langue ne touche pas les composants du socle.
65
+
17
66
  ## Sprite d'icones — a cabler avant le premier rendu
18
67
 
19
68
  `st-icon` lit un sprite SVG servi **en meme origine**. Le paquet livre l'actif,
@@ -0,0 +1,244 @@
1
+ import { Overlay } from '@angular/cdk/overlay';
2
+ import { DomPortal } from '@angular/cdk/portal';
3
+ import * as i0 from '@angular/core';
4
+ import { inject, ElementRef, input, signal, DestroyRef, ChangeDetectionStrategy, Component, Directive } from '@angular/core';
5
+ import * as i1 from '@angular/aria/menu';
6
+ import { Menu, MenuItem } from '@angular/aria/menu';
7
+ import { StIcon } from '@starterlib/ui';
8
+
9
+ const POSITIONS = {
10
+ debut: [
11
+ { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
12
+ { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
13
+ ],
14
+ fin: [
15
+ { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },
16
+ { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },
17
+ ],
18
+ };
19
+ /**
20
+ * Menu d'actions. Le declencheur le designe, comme chez Material :
21
+ *
22
+ * ```html
23
+ * <button stMenuTrigger [menu]="compte" stButton>Actions</button>
24
+ *
25
+ * <st-menu #compte etiquette="Compte" (selection)="agir($event)">
26
+ * <button stMenuItem valeur="profil">Mon profil</button>
27
+ * <button stMenuItem valeur="quitter" ton="destructeur">Se deconnecter</button>
28
+ * </st-menu>
29
+ * ```
30
+ *
31
+ * ⚠️ Pourquoi le declencheur est DEHORS et les elements DEDANS. La primitive
32
+ * `Menu` d'`@angular/aria` relie ses elements au menu par injection, et un
33
+ * contenu projete garde l'injecteur de l'endroit ou il est ECRIT — jamais celui
34
+ * qui le rend. Les elements doivent donc etre ecrits a l'interieur de l'element
35
+ * qui porte le menu, sans quoi ils ne s'y enregistrent pas : le clavier ne
36
+ * bouge plus, et rien ne le signale. Le declencheur, lui, n'a rien a faire dans
37
+ * un `role="menu"`, qui ne contient que des elements de menu.
38
+ *
39
+ * Le clavier vient d'Aria, le placement du CDK. Le socle n'ecrit ni l'un ni
40
+ * l'autre : deux motifs longs, que l'on croit finis avant de les avoir
41
+ * eprouves au lecteur d'ecran ou au bord de l'ecran.
42
+ *
43
+ * ⚠️ A l'ouverture, l'element est DEPLACE dans la couche d'overlay
44
+ * (`DomPortal`), il n'est pas recree : ses liaisons, son etat et son injecteur
45
+ * survivent au passage, ce qu'un gabarit reconstruit perdrait.
46
+ */
47
+ class StMenu {
48
+ element = inject(ElementRef);
49
+ overlay = inject(Overlay);
50
+ aria = inject(Menu);
51
+ /** Nom du menu pour les technologies d'assistance. */
52
+ etiquette = input.required(/* @ts-ignore */
53
+ ...(ngDevMode ? [{ debugName: "etiquette" }] : /* istanbul ignore next */ []));
54
+ alignement = input('debut', /* @ts-ignore */
55
+ ...(ngDevMode ? [{ debugName: "alignement" }] : /* istanbul ignore next */ []));
56
+ ouvertInterne = signal(false, /* @ts-ignore */
57
+ ...(ngDevMode ? [{ debugName: "ouvertInterne" }] : /* istanbul ignore next */ []));
58
+ ouvert = this.ouvertInterne.asReadonly();
59
+ couche = null;
60
+ declencheur = null;
61
+ constructor() {
62
+ // La primitive detecte la selection ; elle ne connait rien de la couche
63
+ // d'overlay, donc c'est ici que le menu se referme.
64
+ this.aria.itemSelected.subscribe(() => {
65
+ this.fermer();
66
+ });
67
+ inject(DestroyRef).onDestroy(() => {
68
+ this.detruireLaCouche();
69
+ });
70
+ }
71
+ ouvrirDepuis(declencheur) {
72
+ if (this.ouvertInterne())
73
+ return;
74
+ this.declencheur = declencheur;
75
+ this.couche = this.overlay.create({
76
+ positionStrategy: this.overlay
77
+ .position()
78
+ .flexibleConnectedTo(declencheur)
79
+ .withPositions(POSITIONS[this.alignement()])
80
+ .withPush(true),
81
+ // Le menu suit son declencheur au defilement : le figer le laisserait
82
+ // seul au milieu de l'ecran, sans lien visible avec ce qu'il commande.
83
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
84
+ });
85
+ this.couche.attach(new DomPortal(this.element));
86
+ this.ouvertInterne.set(true);
87
+ this.couche.outsidePointerEvents().subscribe(() => {
88
+ this.fermer({ rendreLeFocus: false });
89
+ });
90
+ // Le panneau prend le focus : la primitive y tient l'indice de tabulation
91
+ // glissant, donc c'est elle qui decide de l'element actif.
92
+ this.element.nativeElement.focus();
93
+ }
94
+ /**
95
+ * Ferme, et rend le focus au declencheur : sans cela, le focus retombe sur le
96
+ * corps du document, et la navigation clavier reprend en haut de page.
97
+ */
98
+ fermer(options = {}) {
99
+ if (!this.ouvertInterne())
100
+ return;
101
+ this.ouvertInterne.set(false);
102
+ this.detruireLaCouche();
103
+ const declencheur = this.declencheur;
104
+ this.declencheur = null;
105
+ if (options.rendreLeFocus !== false)
106
+ declencheur?.focus();
107
+ }
108
+ basculerDepuis(declencheur) {
109
+ if (this.ouvertInterne())
110
+ this.fermer();
111
+ else
112
+ this.ouvrirDepuis(declencheur);
113
+ }
114
+ auClavier(evenement) {
115
+ if (evenement.key !== 'Escape')
116
+ return;
117
+ evenement.preventDefault();
118
+ this.fermer();
119
+ }
120
+ detruireLaCouche() {
121
+ // `detach` avant `dispose` : le portail rend l'element a sa place d'origine,
122
+ // et le composant reste utilisable pour une reouverture.
123
+ this.couche?.detach();
124
+ this.couche?.dispose();
125
+ this.couche = null;
126
+ }
127
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
128
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: StMenu, isStandalone: true, selector: "st-menu", inputs: { etiquette: { classPropertyName: "etiquette", publicName: "etiquette", isSignal: true, isRequired: true, transformFunction: null }, alignement: { classPropertyName: "alignement", publicName: "alignement", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "keydown": "auClavier($event)" }, properties: { "attr.aria-label": "etiquette()", "attr.data-ouvert": "ouvert() ? \"\" : null" }, classAttribute: "st-menu" }, hostDirectives: [{ directive: i1.Menu, inputs: ["wrap", "wrap", "typeaheadDelay", "typeaheadDelay", "disabled", "disabled"], outputs: ["itemSelected", "selection"] }], ngImport: i0, template: "<ng-content />\n", styles: [":host{display:none}:host([data-ouvert]){display:flex;flex-direction:column;gap:2px;min-inline-size:12rem;max-block-size:80vh;padding:var(--st-espacement-1);overflow-y:auto;background:var(--st-couleur-surface-elevee);border:1px solid var(--st-couleur-bordure);border-radius:var(--st-rayon-md);box-shadow:var(--st-ombre-2)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
129
+ }
130
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StMenu, decorators: [{
131
+ type: Component,
132
+ args: [{ selector: 'st-menu', changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [
133
+ {
134
+ directive: Menu,
135
+ inputs: ['wrap', 'typeaheadDelay', 'disabled'],
136
+ outputs: ['itemSelected: selection'],
137
+ },
138
+ ], host: {
139
+ class: 'st-menu',
140
+ '[attr.aria-label]': 'etiquette()',
141
+ '[attr.data-ouvert]': 'ouvert() ? "" : null',
142
+ '(keydown)': 'auClavier($event)',
143
+ }, template: "<ng-content />\n", styles: [":host{display:none}:host([data-ouvert]){display:flex;flex-direction:column;gap:2px;min-inline-size:12rem;max-block-size:80vh;padding:var(--st-espacement-1);overflow-y:auto;background:var(--st-couleur-surface-elevee);border:1px solid var(--st-couleur-bordure);border-radius:var(--st-rayon-md);box-shadow:var(--st-ombre-2)}\n"] }]
144
+ }], ctorParameters: () => [], propDecorators: { etiquette: [{ type: i0.Input, args: [{ isSignal: true, alias: "etiquette", required: true }] }], alignement: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignement", required: false }] }] } });
145
+
146
+ /**
147
+ * Element de menu, pose en ATTRIBUT sur un `<button>` natif — meme raison que
148
+ * `st-button` : une enveloppe casserait le comportement natif du bouton.
149
+ *
150
+ * Le clavier (fleches, Debut, Fin, saisie au vol, indice de tabulation
151
+ * glissant) vient de la primitive `MenuItem` d'`@angular/aria`, composee en
152
+ * directive d'hote. Le socle n'en reecrit aucune part : ces motifs sont longs a
153
+ * ecrire, faciles a croire finis, et c'est la ou l'accessibilite se perd.
154
+ *
155
+ * ⚠️ `valeur` est OBLIGATOIRE parce que la primitive l'exige, et c'est un bon
156
+ * defaut : c'est elle que `st-menu` emet a la selection. Un menu dont les
157
+ * elements n'ont pas d'identite stable oblige l'appelant a distinguer ses
158
+ * actions par leur libelle, donc par leur traduction.
159
+ */
160
+ class StMenuItem {
161
+ icone = input(null, /* @ts-ignore */
162
+ ...(ngDevMode ? [{ debugName: "icone" }] : /* istanbul ignore next */ []));
163
+ ton = input('neutre', /* @ts-ignore */
164
+ ...(ngDevMode ? [{ debugName: "ton" }] : /* istanbul ignore next */ []));
165
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StMenuItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
166
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: StMenuItem, isStandalone: true, selector: "button[stMenuItem]", inputs: { icone: { classPropertyName: "icone", publicName: "icone", isSignal: true, isRequired: false, transformFunction: null }, ton: { classPropertyName: "ton", publicName: "ton", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "button" }, properties: { "attr.data-ton": "ton()" }, classAttribute: "st-menu-item" }, hostDirectives: [{ directive: i1.MenuItem, inputs: ["value", "valeur", "disabled", "desactive", "role", "role"] }], ngImport: i0, template: "@if (icone(); as nom) {\n <st-icon [nom]=\"nom\" taille=\"sm\" />\n}\n\n<span class=\"st-menu-item__libelle\"><ng-content /></span>\n", styles: [".st-vh{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}:host{display:flex;gap:var(--st-espacement-2);align-items:center;inline-size:100%;min-block-size:2.25rem;padding-block:var(--st-espacement-2);padding-inline:var(--st-espacement-3);font-family:var(--st-police-base);font-size:var(--st-taille-sm);color:var(--st-couleur-texte);text-align:start;cursor:pointer;background:transparent;border:0;border-radius:var(--st-rayon-sm)}:host:focus-visible{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:-2px}:host:hover:not([aria-disabled=true]){background:var(--st-couleur-surface-survol)}:host[data-active=true]{background:var(--st-couleur-surface-survol)}:host[aria-disabled=true]{color:var(--st-couleur-texte-desactive);cursor:not-allowed}@media(any-pointer:coarse){:host{min-block-size:var(--st-cible-tactile-min)}}:host([data-ton=danger]){color:var(--st-couleur-danger)}:host([data-ton=danger]):hover:not([aria-disabled=true]),:host([data-ton=danger])[data-active=true]{background:var(--st-couleur-danger-discret)}.st-menu-item__libelle{flex:1}\n"], dependencies: [{ kind: "component", type: StIcon, selector: "st-icon", inputs: ["nom", "taille", "ton", "etiquette"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
167
+ }
168
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StMenuItem, decorators: [{
169
+ type: Component,
170
+ args: [{ selector: 'button[stMenuItem]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [StIcon], hostDirectives: [
171
+ { directive: MenuItem, inputs: ['value: valeur', 'disabled: desactive', 'role'] },
172
+ ], host: {
173
+ class: 'st-menu-item',
174
+ type: 'button',
175
+ '[attr.data-ton]': 'ton()',
176
+ }, template: "@if (icone(); as nom) {\n <st-icon [nom]=\"nom\" taille=\"sm\" />\n}\n\n<span class=\"st-menu-item__libelle\"><ng-content /></span>\n", styles: [".st-vh{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}:host{display:flex;gap:var(--st-espacement-2);align-items:center;inline-size:100%;min-block-size:2.25rem;padding-block:var(--st-espacement-2);padding-inline:var(--st-espacement-3);font-family:var(--st-police-base);font-size:var(--st-taille-sm);color:var(--st-couleur-texte);text-align:start;cursor:pointer;background:transparent;border:0;border-radius:var(--st-rayon-sm)}:host:focus-visible{outline:2px solid var(--st-couleur-anneau-focus);outline-offset:-2px}:host:hover:not([aria-disabled=true]){background:var(--st-couleur-surface-survol)}:host[data-active=true]{background:var(--st-couleur-surface-survol)}:host[aria-disabled=true]{color:var(--st-couleur-texte-desactive);cursor:not-allowed}@media(any-pointer:coarse){:host{min-block-size:var(--st-cible-tactile-min)}}:host([data-ton=danger]){color:var(--st-couleur-danger)}:host([data-ton=danger]):hover:not([aria-disabled=true]),:host([data-ton=danger])[data-active=true]{background:var(--st-couleur-danger-discret)}.st-menu-item__libelle{flex:1}\n"] }]
177
+ }], propDecorators: { icone: [{ type: i0.Input, args: [{ isSignal: true, alias: "icone", required: false }] }], ton: [{ type: i0.Input, args: [{ isSignal: true, alias: "ton", required: false }] }] } });
178
+
179
+ /**
180
+ * Controle qui ouvre un menu. Il le DESIGNE, il ne le contient pas :
181
+ *
182
+ * ```html
183
+ * <button stMenuTrigger [menu]="compte" stButton>Actions</button>
184
+ * <st-menu #compte etiquette="Compte">…</st-menu>
185
+ * ```
186
+ *
187
+ * ⚠️ Le type de `menu` est importe en TYPE seulement : `st-menu` n'a pas besoin
188
+ * de cette directive, et l'importer dans les deux sens formerait un cycle.
189
+ */
190
+ class StMenuTrigger {
191
+ element = inject(ElementRef).nativeElement;
192
+ menu = input.required(/* @ts-ignore */
193
+ ...(ngDevMode ? [{ debugName: "menu" }] : /* istanbul ignore next */ []));
194
+ basculer() {
195
+ this.menu().basculerDepuis(this.element);
196
+ }
197
+ auClavier(evenement) {
198
+ // La fleche bas ouvre sans activer : convention des menus, et elle evite
199
+ // d'ouvrir a chaque frappe sur un controle qui porte deja une action.
200
+ if (evenement.key !== 'ArrowDown' || this.menu().ouvert())
201
+ return;
202
+ evenement.preventDefault();
203
+ this.menu().ouvrirDepuis(this.element);
204
+ }
205
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StMenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
206
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: StMenuTrigger, isStandalone: true, selector: "[stMenuTrigger]", inputs: { menu: { classPropertyName: "menu", publicName: "menu", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "aria-haspopup": "menu" }, listeners: { "click": "basculer()", "keydown": "auClavier($event)" }, properties: { "attr.aria-expanded": "menu().ouvert()", "attr.data-ouvert": "menu().ouvert() ? \"\" : null" } }, ngImport: i0 });
207
+ }
208
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: StMenuTrigger, decorators: [{
209
+ type: Directive,
210
+ args: [{
211
+ selector: '[stMenuTrigger]',
212
+ host: {
213
+ 'aria-haspopup': 'menu',
214
+ '[attr.aria-expanded]': 'menu().ouvert()',
215
+ '[attr.data-ouvert]': 'menu().ouvert() ? "" : null',
216
+ '(click)': 'basculer()',
217
+ '(keydown)': 'auClavier($event)',
218
+ },
219
+ }]
220
+ }], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "menu", required: true }] }] } });
221
+
222
+ /**
223
+ * @starterlib/ui/surfaces — ce qui se pose AU-DESSUS de la page.
224
+ *
225
+ * ⚠️ Un point d'entree separe pour une raison de dependance, et non de rangement :
226
+ * tout ce qui vit ici traine `@angular/cdk/overlay` et `@angular/cdk/portal`.
227
+ * Laisse dans le tronc, le CDK entrerait dans le train de singletons de CHAQUE
228
+ * application federee, y compris celles qui n'affichent ni menu ni dialogue.
229
+ *
230
+ * Le decoupage suit donc les pairs lourds, pas les familles de composants : un
231
+ * decoupage par famille multiplierait les points d'entree a tenir sans rien
232
+ * retirer de plus au chargement.
233
+ *
234
+ * ```ts
235
+ * import { StMenu, StMenuItem, StMenuTrigger } from '@starterlib/ui/surfaces';
236
+ * ```
237
+ */
238
+
239
+ /**
240
+ * Generated bundle index. Do not edit.
241
+ */
242
+
243
+ export { StMenu, StMenuItem, StMenuTrigger };
244
+ //# sourceMappingURL=starterlib-ui-surfaces.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"starterlib-ui-surfaces.mjs","sources":["../../../../packages/ui/surfaces/src/lib/menu/st-menu.ts","../../../../packages/ui/surfaces/src/lib/menu/st-menu.html","../../../../packages/ui/surfaces/src/lib/menu/st-menu-item.ts","../../../../packages/ui/surfaces/src/lib/menu/st-menu-item.html","../../../../packages/ui/surfaces/src/lib/menu/st-menu-trigger.ts","../../../../packages/ui/surfaces/src/public-api.ts","../../../../packages/ui/surfaces/src/starterlib-ui-surfaces.ts"],"names":[],"mappings":";;;;;;;;AAgBA,MAAM,SAAS,GAA4D;AACzE,IAAA,KAAK,EAAE;AACL,QAAA,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE;QACvF,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE;AACzF,KAAA;AACD,IAAA,GAAG,EAAE;AACH,QAAA,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE;QACnF,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE;AACrF,KAAA;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;MAoBU,MAAM,CAAA;AACA,IAAA,OAAO,GAAG,MAAM,CAA0B,UAAU,CAAC;AACrD,IAAA,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;AACzB,IAAA,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;;IAG3B,SAAS,GAAG,KAAK,CAAC,QAAQ;kFAAU;IAEpC,UAAU,GAAG,KAAK,CAAmB,OAAO;mFAAC;IAErC,aAAa,GAAG,MAAM,CAAC,KAAK;sFAAC;AACrC,IAAA,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE;IAEzC,MAAM,GAAsB,IAAI;IAChC,WAAW,GAAuB,IAAI;AAE9C,IAAA,WAAA,GAAA;;;QAGE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAK;YACpC,IAAI,CAAC,MAAM,EAAE;AACf,QAAA,CAAC,CAAC;AAEF,QAAA,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,MAAK;YAChC,IAAI,CAAC,gBAAgB,EAAE;AACzB,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,YAAY,CAAC,WAAwB,EAAA;QACnC,IAAI,IAAI,CAAC,aAAa,EAAE;YAAE;AAC1B,QAAA,IAAI,CAAC,WAAW,GAAG,WAAW;QAE9B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YAChC,gBAAgB,EAAE,IAAI,CAAC;AACpB,iBAAA,QAAQ;iBACR,mBAAmB,CAAC,WAAW;iBAC/B,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;iBAC1C,QAAQ,CAAC,IAAI,CAAC;;;YAGjB,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,UAAU,EAAE;AAC3D,SAAA,CAAC;AAEF,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC/C,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;QAE5B,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC,SAAS,CAAC,MAAK;YAChD,IAAI,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;AACvC,QAAA,CAAC,CAAC;;;AAIF,QAAA,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE;IACpC;AAEA;;;AAGG;IACH,MAAM,CAAC,UAAgD,EAAE,EAAA;AACvD,QAAA,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;YAAE;AAC3B,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;QAC7B,IAAI,CAAC,gBAAgB,EAAE;AAEvB,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW;AACpC,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI;AACvB,QAAA,IAAI,OAAO,CAAC,aAAa,KAAK,KAAK;YAAE,WAAW,EAAE,KAAK,EAAE;IAC3D;AAEA,IAAA,cAAc,CAAC,WAAwB,EAAA;QACrC,IAAI,IAAI,CAAC,aAAa,EAAE;YAAE,IAAI,CAAC,MAAM,EAAE;;AAClC,YAAA,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC;IACrC;AAEU,IAAA,SAAS,CAAC,SAAwB,EAAA;AAC1C,QAAA,IAAI,SAAS,CAAC,GAAG,KAAK,QAAQ;YAAE;QAChC,SAAS,CAAC,cAAc,EAAE;QAC1B,IAAI,CAAC,MAAM,EAAE;IACf;IAEQ,gBAAgB,GAAA;;;AAGtB,QAAA,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE;AACrB,QAAA,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE;AACtB,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI;IACpB;uGAtFW,MAAM,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAN,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAM,qrBC1EnB,kBACA,EAAA,MAAA,EAAA,CAAA,qUAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FDyEa,MAAM,EAAA,UAAA,EAAA,CAAA;kBAnBlB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,SAAS,EAAA,eAAA,EAGF,uBAAuB,CAAC,MAAM,EAAA,cAAA,EAC/B;AACd,wBAAA;AACE,4BAAA,SAAS,EAAE,IAAI;AACf,4BAAA,MAAM,EAAE,CAAC,MAAM,EAAE,gBAAgB,EAAE,UAAU,CAAC;4BAC9C,OAAO,EAAE,CAAC,yBAAyB,CAAC;AACrC,yBAAA;qBACF,EAAA,IAAA,EACK;AACJ,wBAAA,KAAK,EAAE,SAAS;AAChB,wBAAA,mBAAmB,EAAE,aAAa;AAClC,wBAAA,oBAAoB,EAAE,sBAAsB;AAC5C,wBAAA,WAAW,EAAE,mBAAmB;AACjC,qBAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,qUAAA,CAAA,EAAA;;;AE7DH;;;;;;;;;;;;;AAaG;MAgBU,UAAU,CAAA;IACZ,KAAK,GAAG,KAAK,CAAmB,IAAI;8EAAC;IACrC,GAAG,GAAG,KAAK,CAAoB,QAAQ;4EAAC;uGAFtC,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAV,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,UAAA,EAAA,EAAA,eAAA,EAAA,OAAA,EAAA,EAAA,cAAA,EAAA,cAAA,EAAA,EAAA,cAAA,EAAA,CAAA,EAAA,SAAA,EAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,WAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECxCvB,wIAKA,EAAA,MAAA,EAAA,CAAA,mnCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDyBY,MAAM,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,KAAA,EAAA,QAAA,EAAA,KAAA,EAAA,WAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAUL,UAAU,EAAA,UAAA,EAAA,CAAA;kBAftB,SAAS;+BACE,oBAAoB,EAAA,eAAA,EAGb,uBAAuB,CAAC,MAAM,WACtC,CAAC,MAAM,CAAC,EAAA,cAAA,EACD;AACd,wBAAA,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,eAAe,EAAE,qBAAqB,EAAE,MAAM,CAAC,EAAE;qBAClF,EAAA,IAAA,EACK;AACJ,wBAAA,KAAK,EAAE,cAAc;AACrB,wBAAA,IAAI,EAAE,QAAQ;AACd,wBAAA,iBAAiB,EAAE,OAAO;AAC3B,qBAAA,EAAA,QAAA,EAAA,wIAAA,EAAA,MAAA,EAAA,CAAA,mnCAAA,CAAA,EAAA;;;AEnCH;;;;;;;;;;AAUG;MAWU,aAAa,CAAA;AACP,IAAA,OAAO,GAAG,MAAM,CAA0B,UAAU,CAAC,CAAC,aAAa;IAE3E,IAAI,GAAG,KAAK,CAAC,QAAQ;6EAAU;IAE9B,QAAQ,GAAA;QAChB,IAAI,CAAC,IAAI,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC;IAC1C;AAEU,IAAA,SAAS,CAAC,SAAwB,EAAA;;;AAG1C,QAAA,IAAI,SAAS,CAAC,GAAG,KAAK,WAAW,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE;YAAE;QAC3D,SAAS,CAAC,cAAc,EAAE;QAC1B,IAAI,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;IACxC;uGAfW,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAb,aAAa,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,eAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,YAAA,EAAA,SAAA,EAAA,mBAAA,EAAA,EAAA,UAAA,EAAA,EAAA,oBAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,+BAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAb,aAAa,EAAA,UAAA,EAAA,CAAA;kBAVzB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,iBAAiB;AAC3B,oBAAA,IAAI,EAAE;AACJ,wBAAA,eAAe,EAAE,MAAM;AACvB,wBAAA,sBAAsB,EAAE,iBAAiB;AACzC,wBAAA,oBAAoB,EAAE,6BAA6B;AACnD,wBAAA,SAAS,EAAE,YAAY;AACvB,wBAAA,WAAW,EAAE,mBAAmB;AACjC,qBAAA;AACF,iBAAA;;;ACvBD;;;;;;;;;;;;;;;AAeG;;ACfH;;AAEG;;"}