@oneteme/jquery-table 0.0.14 → 0.0.16

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
@@ -24,7 +24,7 @@ Bibliothèque Angular qui encapsule Angular Material Table avec une API orienté
24
24
  - Pagination standard et pagination par groupe
25
25
  - **Group by** : regroupement des lignes par colonne, groupes pliables/dépliables, pagination indépendante par groupe
26
26
  - **Slice panel** : filtres catégoriels latéraux, statiques (prédéfinis) ou dynamiques (colonne valeurs uniques), multi-sélection configurable
27
- - **Chargement paresseux** (lazy) de cellules via Observable par colonne
27
+ - **Chargement paresseux** (lazy) de colonnes : `lazy: true` + `lazyLoader` dans la config (la colonne n'est demandée qu'à son activation)
28
28
  - Rendus de cellule personnalisés via directive `jqtCellDef`
29
29
  - État de chargement (`isLoading`) et état vide configurable
30
30
  - Événement de clic sur ligne (`rowSelected`)
@@ -119,6 +119,7 @@ Le `config` complet reste disponible pour activer les fonctionnalités avancées
119
119
  | `columnsConfig` | `TableColumnProvider<T>[]` | Configuration des colonnes (remplace `config.columns`) |
120
120
  | `columnLabels` | `Record<string, string>` | Labels des colonnes pour le mode allégé |
121
121
  | `isLoading` | `boolean` | Affiche l'état de chargement (défaut : `false`) |
122
+ | `lazyError` | `boolean` | `true` quand la requête relancée après `lazyColumnsRequested` échoue : les colonnes lazy en attente affichent « Réessayer » (voir colonnes lazy) |
122
123
  | `view` | `TableViewConfig` | Surcharge `config.view` si défini (mode HTML) |
123
124
 
124
125
  ### Outputs
@@ -131,6 +132,7 @@ Le `config` complet reste disponible pour activer les fonctionnalités avancées
131
132
  | `searchChange` | `string` | Frappe dans la barre de recherche |
132
133
  | `groupByChange` | `string \| null` | Group by activé (clé) ou désactivé (`null`) |
133
134
  | `columnsChange` | `string[]` | Colonnes visibles modifiées (clés dans l'ordre d'affichage) |
135
+ | `lazyColumnsRequested` | `string[]` | Clés cumulées des colonnes `lazy` demandées, émises à l'activation d'une nouvelle colonne (voir colonnes lazy) |
134
136
  | `columnAdded` | `TableColumnProvider<T>` | Colonne ajoutée aux colonnes actives |
135
137
  | `columnRemoved` | `TableColumnProvider<T>` | Colonne retirée des colonnes actives |
136
138
  | `categorySelected` | `string` | Catégorie de slice sélectionnée |
@@ -153,6 +155,7 @@ interface TableProvider<T = any> {
153
155
  view?: TableViewConfig;
154
156
  labels?: TableLabelsConfig;
155
157
  export?: TableExportConfig<T>;
158
+ lazyLoader?: (lazyColumns: string[]) => Observable<T[]>; // Charge les colonnes lazy (lignes complètes)
156
159
  preferences?: TablePreferencesConfig; // Sauvegarde dans localStorage
157
160
 
158
161
  defaultSort?: { active: string; direction: 'asc' | 'desc' };
@@ -180,16 +183,14 @@ interface TableColumnProvider<T = any> {
180
183
  width?: string; // Largeur CSS en px uniquement pour le calcul min-width (ex: '120px')
181
184
  // Les unités %, em, rem sont ignorées dans le calcul de tableMinWidth
182
185
 
183
- optional?: boolean; // Colonne masquée par défaut, ajoutables via View menu
186
+ optional?: boolean; // Colonne masquée par défaut, ajoutables via View menu (implicite pour une colonne lazy)
184
187
  removable?: boolean; // Peut être retirée manuellement
185
188
 
186
189
  groupable?: boolean; // Disponible comme critère de regroupement dans View menu
187
190
  sliceable?: boolean; // Disponible comme slice dynamique dans View menu
188
191
  searchValue?: DataProvider<string>; // Valeur utilisée par la recherche texte (si différente de value)
189
192
 
190
- lazy?: {
191
- fetchFn: () => Observable<any[]>; // Retourne un tableau dans le même ordre que les lignes
192
- };
193
+ lazy?: true; // Absente de la requête de base, forcément optionnelle : demandée à sa première activation
193
194
  }
194
195
  ```
195
196
 
@@ -398,19 +399,70 @@ interface SliceCategory<T = any> {
398
399
 
399
400
  ## Fonctionnalité — lazy columns
400
401
 
402
+ Une colonne `lazy: true` est absente de la requête de base : elle réduit la réponse du premier rendu et n'est demandée que si l'utilisateur l'affiche. Elle est donc **forcément optionnelle** : `optional: true` est implicite (inutile de l'écrire) et `optional: false` lève une erreur explicite, car la colonne serait demandée dès le premier rendu, soit une requête de plus pour rien. Le type refuse aussi cette combinaison à la compilation.
403
+
404
+ ### Avec `lazyLoader` (le plus simple)
405
+
406
+ `[data]` reste la requête de base de l'application. Le chargeur de la config est appelé à l'activation d'une colonne lazy et retourne les **lignes complètes** (colonnes de base + colonnes lazy demandées) :
407
+
401
408
  ```ts
402
- columns: [
403
- {
404
- key: 'details',
405
- header: 'Détails',
406
- lazy: {
407
- fetchFn: () => this.api.getDetails(),
408
- },
409
- },
410
- ],
409
+ config: TableProvider<Country> = {
410
+ columns: [
411
+ col('code', 'Code'),
412
+ col('name', 'Pays'),
413
+ col('capital', 'Capitale', { lazy: true }),
414
+ col('currency', 'Devise', { lazy: true }),
415
+ ],
416
+ // colonnes lazy demandées (cumul) : ['capital'], puis ['capital', 'currency']
417
+ lazyLoader: columns => this.api.fetchCountries(columns), // Observable<Country[]>
418
+ };
411
419
  ```
412
420
 
413
- Le composant gère l'état `idle | loading | loaded | error` par colonne, avec possibilité de relancer la requête en cas d'erreur.
421
+ ```html
422
+ <jquery-table [config]="config" [data]="countries"></jquery-table>
423
+ ```
424
+
425
+ La table appelle `lazyLoader`, affiche le skeleton, remplace ses lignes par la réponse, gère l'erreur et le bouton « Réessayer » (sans `[lazyError]`), et annule l'appel en cours si une nouvelle demande arrive.
426
+
427
+ - Un nouveau `[data]` (rafraîchissement de l'application) l'emporte sur les lignes du chargeur : si des colonnes lazy ont déjà été demandées, la table rappelle `lazyLoader` avec ce cumul (le skeleton réapparaît le temps de la requête). Pour une page rafraîchie en continu, préférer le mode événement ci-dessous afin d'éviter cette seconde requête.
428
+ - Rien n'est appelé tant que le tableau n'a aucune ligne.
429
+
430
+ ### Avec l'événement `lazyColumnsRequested` (l'application garde la main)
431
+
432
+ Sans `lazyLoader`, la table émet `(lazyColumnsRequested)` ; l'application **relance sa requête complète en incluant ces colonnes** et repasse les nouvelles `data`. Tant qu'elles ne sont pas arrivées, la colonne affiche un skeleton ; à leur arrivée, elles remplacent les anciennes lignes.
433
+
434
+ ```ts
435
+ config: TableProvider<Session> = {
436
+ columns: [
437
+ col('name', 'Nom'),
438
+ col('address', 'Adresse', { lazy: true }),
439
+ col('status', 'Statut', { lazy: true }),
440
+ ],
441
+ };
442
+ ```
443
+
444
+ ```html
445
+ <jquery-table [config]="config" [data]="rows" [lazyError]="lazyFailed" (lazyColumnsRequested)="onLazyColumns($event)"></jquery-table>
446
+ ```
447
+
448
+ ```ts
449
+ onLazyColumns(columns: string[]) { // ex. ['address'], puis ['address', 'status']
450
+ this.lazyFailed = false;
451
+ this.api.fetchRows(columns).subscribe({ // même requête que la base + ces colonnes
452
+ next: rows => this.rows = rows,
453
+ error: () => this.lazyFailed = true,
454
+ });
455
+ }
456
+ ```
457
+
458
+ - `lazyColumnsRequested` émet **toutes** les colonnes lazy demandées depuis le début (cumul) : la requête complète peut être reconstruite à partir de cette seule liste, y compris lors d'un rafraîchissement périodique.
459
+ - Les colonnes `lazy: true` apparaissent dans Organizer > Champs sans être demandées ; l'événement part à l'activation (ou si la colonne sert de Group by / Slice by, y compris `defaultGroupBy`, une préférence restaurée ou un snapshot). Plusieurs colonnes activées dans le même tick partent dans un seul événement.
460
+ - Rien n'est émis tant que le tableau n'a aucune ligne : la première réponse de l'application ne doit pas être prise pour celle qui contient les colonnes.
461
+ - Les nouvelles `data` (changement de `[data]` ou `[dataSource]`) marquent toutes les colonnes demandées comme prêtes. Les données fournies ensuite (rafraîchissement, changement de `config`) doivent donc déjà contenir les colonnes demandées : la table ne les redemande pas.
462
+ - Pour garder le tableau visible pendant la requête, ne pas passer `isLoading` à `true` : seul le skeleton de la colonne apparaît. Annuler la requête précédente (`switchMap`) évite qu'une réponse périmée soit prise pour la bonne.
463
+ - En cas d'échec, passer `[lazyError]` à `true` : les colonnes en attente affichent « Réessayer » (cellule, ou en-tête de groupe si la colonne sert de Group by). Le clic réémet `lazyColumnsRequested` ; repasser `lazyError` à `false` au nouvel essai.
464
+ - Sans `lazyLoader` ni écouteur, une colonne lazy activée resterait en skeleton : en développement, la table l'indique par un avertissement dans la console.
465
+ - Une fois reçue, la colonne se comporte comme une colonne ordinaire : tri, recherche, Group by, Slice by, `value`, `sortValue`, `searchValue`, `jqtCellDef` et export CSV. L'export n'écrit jamais d'état de chargement ou d'erreur (cellule vide).
414
466
 
415
467
  ---
416
468
 
@@ -433,6 +485,7 @@ Le composant gère l'état `idle | loading | loaded | error` par colonne, avec p
433
485
  Contexte du template :
434
486
  - `$implicit` la ligne brute (`T`)
435
487
  - `index` index global de la ligne
488
+ - `value` valeur affichée de la cellule ; seul moyen de lire la valeur d'une colonne `lazy`, absente de la ligne brute (`let-value="value"`). Pour une colonne lazy, le template n'est rendu qu'une fois la valeur chargée : le skeleton et le bouton d'erreur sont gérés par le tableau.
436
489
 
437
490
  ---
438
491
 
@@ -473,8 +526,7 @@ config: TableProvider<Row> = {
473
526
  | `sliceConfigs` | `SliceConfig<T>[]` | Configurations des slices |
474
527
  | `columns` | `SliceColumnDef<T>[]` | Définitions des colonnes pour la résolution des valeurs |
475
528
  | `data` | `T[]` | Données source |
476
- | `lazyData` | `Map<string, Map<any,any>>` | Valeurs lazy chargées |
477
- | `lazyStatus` | `Map<string, 'idle'\|'loading'\|'loaded'\|'error'>` | État par colonne lazy |
529
+ | `lazyStatus` | `Map<string, 'idle'\|'loading'\|'loaded'\|'error'>` | État par colonne lazy (leurs valeurs sont lues dans les lignes de `data`) |
478
530
  | `showToggle` | `boolean` | Affiche le bouton collapse du panel (défaut : `true`) |
479
531
  | `showCounts` | `boolean` | Affiche le nombre de lignes par catégorie (défaut : `true`) |
480
532
  | `collapsedByDefault` | `boolean` | Les slices démarrent repliés (défaut : `false`) |
@@ -596,7 +648,7 @@ import { normalizeCellValue, humanizeKey, getFrenchPaginatorIntl } from '@onetem
596
648
 
597
649
  Ajoute un sous-menu **Préférences** dans le menu View permettant :
598
650
  - **Mode édition** : redimensionner et réordonner les colonnes à la souris
599
- - **Enregistrer** : persiste la configuration dans le `localStorage` (colonnes visibles, ordre, largeurs, tri, group by, filtres slice)
651
+ - **Enregistrer** : persiste la configuration dans le `localStorage` (colonnes visibles, ordre, largeurs, tri, group by, filtres slice, nombre de lignes par page et par groupe)
600
652
  - **Effacer** : supprime la configuration sauvegardée
601
653
 
602
654
  ```ts
@@ -620,6 +672,8 @@ interface TablePreferencesConfig {
620
672
 
621
673
  La configuration est persistée sous la clé `jqt_prefs_<tableId>` et restaurée automatiquement au chargement suivant.
622
674
 
675
+ Le nombre de lignes (`pageSize` en mode normal, `groupPageSize` en mode Group by, `0` = tout afficher) est restauré uniquement s'il figure encore dans `pagination.pageSizeOptions` / `pageSizeOptionsGroupBy` ; sinon la valeur de la config est conservée. L'index de page n'est pas sauvegardé.
676
+
623
677
  ---
624
678
 
625
679
  ## Build
@@ -17,7 +17,8 @@ export class ExportManager {
17
17
  return;
18
18
  const rows = this.getRows();
19
19
  const columns = this.getColumns();
20
- const filename = (cfg.filename || 'export') + '.csv';
20
+ const baseName = cfg.filename || 'export';
21
+ const filename = baseName.toLowerCase().endsWith('.csv') ? baseName : baseName + '.csv';
21
22
  const header = columns.map(c => this._csvEscape(c.header || c.key)).join(',');
22
23
  const lines = rows.map((row, idx) => {
23
24
  if (cfg.transform) {
@@ -31,7 +32,7 @@ export class ExportManager {
31
32
  const url = URL.createObjectURL(blob);
32
33
  const a = document.createElement('a');
33
34
  a.href = url;
34
- a.download = filename.endsWith('.csv') ? filename : filename + '.csv';
35
+ a.download = filename;
35
36
  a.click();
36
37
  URL.revokeObjectURL(url);
37
38
  }
@@ -42,4 +43,4 @@ export class ExportManager {
42
43
  return value;
43
44
  }
44
45
  }
45
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwb3J0Lm1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vbmV0ZW1lL2pxdWVyeS10YWJsZS9zcmMvbGliL2NvbXBvbmVudC9leHBvcnQubWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyxhQUFhO0lBQ3hCLFlBQ21CLE9BQWtCLEVBQ2xCLFVBQTBDLEVBQzFDLFNBQWlELEVBQ2pELGdCQUE2RTtRQUg3RSxZQUFPLEdBQVAsT0FBTyxDQUFXO1FBQ2xCLGVBQVUsR0FBVixVQUFVLENBQWdDO1FBQzFDLGNBQVMsR0FBVCxTQUFTLENBQXdDO1FBQ2pELHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBNkQ7SUFDN0YsQ0FBQztJQUVKLE1BQU07UUFDSixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLEdBQUcsRUFBRSxPQUFPO1lBQUUsT0FBTztRQUMxQixNQUFNLElBQUksR0FBTSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDL0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sUUFBUSxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsR0FBRyxNQUFNLENBQUM7UUFFckQsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUUsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtZQUNsQyxJQUFJLEdBQUcsQ0FBQyxTQUFTLEVBQUU7Z0JBQ2pCLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzdCLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUM1RTtZQUNELE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkcsQ0FBQyxDQUFDLENBQUM7UUFFSCxtREFBbUQ7UUFDbkQsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSx3QkFBd0IsRUFBRSxDQUFDLENBQUM7UUFDdEcsTUFBTSxHQUFHLEdBQUksR0FBRyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2QyxNQUFNLENBQUMsR0FBTSxRQUFRLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDO1FBQ2IsQ0FBQyxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUM7UUFDdEUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1YsR0FBRyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRU8sVUFBVSxDQUFDLEtBQWE7UUFDOUIsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQzlGLE9BQU8sR0FBRyxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQztTQUNoRDtRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVGFibGVDb2x1bW5Qcm92aWRlciwgVGFibGVFeHBvcnRDb25maWcgfSBmcm9tICcuLi9qcXVlcnktdGFibGUubW9kZWwnO1xuXG4vKipcbiAqIEV4cG9ydE1hbmFnZXJcbiAqXG4gKiBFbmNhcHN1bGUgbCdleHBvcnQgQ1NWIDogY29uc3RydWN0aW9uIGR1IGZpY2hpZXIgQk9NL1VURi04LCDDqWNoYXBwZW1lbnQgZXQgZMOpY2xlbmNoZW1lbnQgZHUgdMOpbMOpY2hhcmdlbWVudC5cbiAqIEF1Y3VuZSBkw6lwZW5kYW5jZSBBbmd1bGFyIOKAlCBpbmTDqXBlbmRhbnQgZHUgY3ljbGUgZGUgdmllIGR1IGNvbXBvc2FudC5cbiAqL1xuZXhwb3J0IGNsYXNzIEV4cG9ydE1hbmFnZXI8VD4ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGdldFJvd3M6ICgpID0+IFRbXSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGdldENvbHVtbnM6ICgpID0+IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD5bXSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGdldENvbmZpZzogKCkgPT4gVGFibGVFeHBvcnRDb25maWc8VD4gfCB1bmRlZmluZWQsXG4gICAgcHJpdmF0ZSByZWFkb25seSByZXNvbHZlQ2VsbFZhbHVlOiAoY29sOiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+LCByb3c6IFQsIGluZGV4OiBudW1iZXIpID0+IGFueSxcbiAgKSB7fVxuXG4gIGV4cG9ydCgpOiB2b2lkIHtcbiAgICBjb25zdCBjZmcgPSB0aGlzLmdldENvbmZpZygpO1xuICAgIGlmICghY2ZnPy5lbmFibGVkKSByZXR1cm47XG4gICAgY29uc3Qgcm93cyAgICA9IHRoaXMuZ2V0Um93cygpO1xuICAgIGNvbnN0IGNvbHVtbnMgPSB0aGlzLmdldENvbHVtbnMoKTtcbiAgICBjb25zdCBmaWxlbmFtZSA9IChjZmcuZmlsZW5hbWUgfHwgJ2V4cG9ydCcpICsgJy5jc3YnO1xuXG4gICAgY29uc3QgaGVhZGVyID0gY29sdW1ucy5tYXAoYyA9PiB0aGlzLl9jc3ZFc2NhcGUoYy5oZWFkZXIgfHwgYy5rZXkpKS5qb2luKCcsJyk7XG4gICAgY29uc3QgbGluZXMgPSByb3dzLm1hcCgocm93LCBpZHgpID0+IHtcbiAgICAgIGlmIChjZmcudHJhbnNmb3JtKSB7XG4gICAgICAgIGNvbnN0IHQgPSBjZmcudHJhbnNmb3JtKHJvdyk7XG4gICAgICAgIHJldHVybiBjb2x1bW5zLm1hcChjID0+IHRoaXMuX2NzdkVzY2FwZShTdHJpbmcodFtjLmtleV0gPz8gJycpKSkuam9pbignLCcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNvbHVtbnMubWFwKGMgPT4gdGhpcy5fY3N2RXNjYXBlKFN0cmluZyh0aGlzLnJlc29sdmVDZWxsVmFsdWUoYywgcm93LCBpZHgpID8/ICcnKSkpLmpvaW4oJywnKTtcbiAgICB9KTtcblxuICAgIC8vIEJPTSBVVEYtOCBwb3VyIHVuZSBvdXZlcnR1cmUgY29ycmVjdGUgc291cyBFeGNlbFxuICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbJ1xcdUZFRkYnICsgW2hlYWRlciwgLi4ubGluZXNdLmpvaW4oJ1xcbicpXSwgeyB0eXBlOiAndGV4dC9jc3Y7Y2hhcnNldD11dGYtOCcgfSk7XG4gICAgY29uc3QgdXJsICA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgY29uc3QgYSAgICA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICBhLmhyZWYgPSB1cmw7XG4gICAgYS5kb3dubG9hZCA9IGZpbGVuYW1lLmVuZHNXaXRoKCcuY3N2JykgPyBmaWxlbmFtZSA6IGZpbGVuYW1lICsgJy5jc3YnO1xuICAgIGEuY2xpY2soKTtcbiAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gIH1cblxuICBwcml2YXRlIF9jc3ZFc2NhcGUodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKHZhbHVlLmluY2x1ZGVzKCcsJykgfHwgdmFsdWUuaW5jbHVkZXMoJ1wiJykgfHwgdmFsdWUuaW5jbHVkZXMoJ1xcbicpIHx8IHZhbHVlLmluY2x1ZGVzKCdcXHInKSkge1xuICAgICAgcmV0dXJuICdcIicgKyB2YWx1ZS5yZXBsYWNlQWxsKCdcIicsICdcIlwiJykgKyAnXCInO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cbiJdfQ==
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwb3J0Lm1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vbmV0ZW1lL2pxdWVyeS10YWJsZS9zcmMvbGliL2NvbXBvbmVudC9leHBvcnQubWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyxhQUFhO0lBQ3hCLFlBQ21CLE9BQWtCLEVBQ2xCLFVBQTBDLEVBQzFDLFNBQWlELEVBQ2pELGdCQUE2RTtRQUg3RSxZQUFPLEdBQVAsT0FBTyxDQUFXO1FBQ2xCLGVBQVUsR0FBVixVQUFVLENBQWdDO1FBQzFDLGNBQVMsR0FBVCxTQUFTLENBQXdDO1FBQ2pELHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBNkQ7SUFDN0YsQ0FBQztJQUVKLE1BQU07UUFDSixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLEdBQUcsRUFBRSxPQUFPO1lBQUUsT0FBTztRQUMxQixNQUFNLElBQUksR0FBTSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDL0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQyxRQUFRLElBQUksUUFBUSxDQUFDO1FBQzFDLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQztRQUV4RixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM5RSxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFO1lBQ2xDLElBQUksR0FBRyxDQUFDLFNBQVMsRUFBRTtnQkFDakIsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDN0IsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQzVFO1lBQ0QsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN2RyxDQUFDLENBQUMsQ0FBQztRQUVILG1EQUFtRDtRQUNuRCxNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLFFBQVEsR0FBRyxDQUFDLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLHdCQUF3QixFQUFFLENBQUMsQ0FBQztRQUN0RyxNQUFNLEdBQUcsR0FBSSxHQUFHLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sQ0FBQyxHQUFNLFFBQVEsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDekMsQ0FBQyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUM7UUFDYixDQUFDLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN0QixDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDVixHQUFHLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFFTyxVQUFVLENBQUMsS0FBYTtRQUM5QixJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDOUYsT0FBTyxHQUFHLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDO1NBQ2hEO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUYWJsZUNvbHVtblByb3ZpZGVyLCBUYWJsZUV4cG9ydENvbmZpZyB9IGZyb20gJy4uL2pxdWVyeS10YWJsZS5tb2RlbCc7XG5cbi8qKlxuICogRXhwb3J0TWFuYWdlclxuICpcbiAqIEVuY2Fwc3VsZSBsJ2V4cG9ydCBDU1YgOiBjb25zdHJ1Y3Rpb24gZHUgZmljaGllciBCT00vVVRGLTgsIMOpY2hhcHBlbWVudCBldCBkw6ljbGVuY2hlbWVudCBkdSB0w6lsw6ljaGFyZ2VtZW50LlxuICogQXVjdW5lIGTDqXBlbmRhbmNlIEFuZ3VsYXIg4oCUIGluZMOpcGVuZGFudCBkdSBjeWNsZSBkZSB2aWUgZHUgY29tcG9zYW50LlxuICovXG5leHBvcnQgY2xhc3MgRXhwb3J0TWFuYWdlcjxUPiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZ2V0Um93czogKCkgPT4gVFtdLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZ2V0Q29sdW1uczogKCkgPT4gVGFibGVDb2x1bW5Qcm92aWRlcjxUPltdLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZ2V0Q29uZmlnOiAoKSA9PiBUYWJsZUV4cG9ydENvbmZpZzxUPiB8IHVuZGVmaW5lZCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlc29sdmVDZWxsVmFsdWU6IChjb2w6IFRhYmxlQ29sdW1uUHJvdmlkZXI8VD4sIHJvdzogVCwgaW5kZXg6IG51bWJlcikgPT4gYW55LFxuICApIHt9XG5cbiAgZXhwb3J0KCk6IHZvaWQge1xuICAgIGNvbnN0IGNmZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XG4gICAgaWYgKCFjZmc/LmVuYWJsZWQpIHJldHVybjtcbiAgICBjb25zdCByb3dzICAgID0gdGhpcy5nZXRSb3dzKCk7XG4gICAgY29uc3QgY29sdW1ucyA9IHRoaXMuZ2V0Q29sdW1ucygpO1xuICAgIGNvbnN0IGJhc2VOYW1lID0gY2ZnLmZpbGVuYW1lIHx8ICdleHBvcnQnO1xuICAgIGNvbnN0IGZpbGVuYW1lID0gYmFzZU5hbWUudG9Mb3dlckNhc2UoKS5lbmRzV2l0aCgnLmNzdicpID8gYmFzZU5hbWUgOiBiYXNlTmFtZSArICcuY3N2JztcblxuICAgIGNvbnN0IGhlYWRlciA9IGNvbHVtbnMubWFwKGMgPT4gdGhpcy5fY3N2RXNjYXBlKGMuaGVhZGVyIHx8IGMua2V5KSkuam9pbignLCcpO1xuICAgIGNvbnN0IGxpbmVzID0gcm93cy5tYXAoKHJvdywgaWR4KSA9PiB7XG4gICAgICBpZiAoY2ZnLnRyYW5zZm9ybSkge1xuICAgICAgICBjb25zdCB0ID0gY2ZnLnRyYW5zZm9ybShyb3cpO1xuICAgICAgICByZXR1cm4gY29sdW1ucy5tYXAoYyA9PiB0aGlzLl9jc3ZFc2NhcGUoU3RyaW5nKHRbYy5rZXldID8/ICcnKSkpLmpvaW4oJywnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb2x1bW5zLm1hcChjID0+IHRoaXMuX2NzdkVzY2FwZShTdHJpbmcodGhpcy5yZXNvbHZlQ2VsbFZhbHVlKGMsIHJvdywgaWR4KSA/PyAnJykpKS5qb2luKCcsJyk7XG4gICAgfSk7XG5cbiAgICAvLyBCT00gVVRGLTggcG91ciB1bmUgb3V2ZXJ0dXJlIGNvcnJlY3RlIHNvdXMgRXhjZWxcbiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoWydcXHVGRUZGJyArIFtoZWFkZXIsIC4uLmxpbmVzXS5qb2luKCdcXG4nKV0sIHsgdHlwZTogJ3RleHQvY3N2O2NoYXJzZXQ9dXRmLTgnIH0pO1xuICAgIGNvbnN0IHVybCAgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgIGNvbnN0IGEgICAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgYS5ocmVmID0gdXJsO1xuICAgIGEuZG93bmxvYWQgPSBmaWxlbmFtZTtcbiAgICBhLmNsaWNrKCk7XG4gICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICB9XG5cbiAgcHJpdmF0ZSBfY3N2RXNjYXBlKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICh2YWx1ZS5pbmNsdWRlcygnLCcpIHx8IHZhbHVlLmluY2x1ZGVzKCdcIicpIHx8IHZhbHVlLmluY2x1ZGVzKCdcXG4nKSB8fCB2YWx1ZS5pbmNsdWRlcygnXFxyJykpIHtcbiAgICAgIHJldHVybiAnXCInICsgdmFsdWUucmVwbGFjZUFsbCgnXCInLCAnXCJcIicpICsgJ1wiJztcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG59XG4iXX0=
@@ -28,11 +28,21 @@ export class TablePreferencesManager {
28
28
  }
29
29
  /** Supprime la configuration sauvegardée. */
30
30
  clear() {
31
- localStorage.removeItem(this.key);
31
+ try {
32
+ localStorage.removeItem(this.key);
33
+ }
34
+ catch {
35
+ // stockage indisponible : rien à effacer
36
+ }
32
37
  }
33
38
  /** Indique si une configuration est actuellement sauvegardée. */
34
39
  hasSaved() {
35
- return localStorage.getItem(this.key) !== null;
40
+ try {
41
+ return localStorage.getItem(this.key) !== null;
42
+ }
43
+ catch {
44
+ return false;
45
+ }
36
46
  }
37
47
  }
38
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtcHJlZmVyZW5jZXMubWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29uZXRlbWUvanF1ZXJ5LXRhYmxlL3NyYy9saWIvY29tcG9uZW50L3RhYmxlLXByZWZlcmVuY2VzLm1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxjQUFjLEdBQUcsWUFBWSxDQUFDO0FBRXBDOzs7R0FHRztBQUNILE1BQU0sT0FBTyx1QkFBdUI7SUFHbEMsWUFBWSxPQUFlO1FBQ3pCLElBQUksQ0FBQyxHQUFHLEdBQUcsY0FBYyxHQUFHLE9BQU8sQ0FBQztJQUN0QyxDQUFDO0lBRUQsK0VBQStFO0lBQy9FLElBQUk7UUFDRixJQUFJO1lBQ0YsTUFBTSxHQUFHLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDM0MsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFzQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7U0FDM0Q7UUFBQyxNQUFNO1lBQ04sT0FBTyxJQUFJLENBQUM7U0FDYjtJQUNILENBQUM7SUFFRCxzREFBc0Q7SUFDdEQsSUFBSSxDQUFDLE1BQXdCO1FBQzNCLElBQUk7WUFDRixZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1NBQ3hEO1FBQUMsTUFBTTtZQUNOLDBFQUEwRTtTQUMzRTtJQUNILENBQUM7SUFFRCw2Q0FBNkM7SUFDN0MsS0FBSztRQUNILFlBQVksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxpRUFBaUU7SUFDakUsUUFBUTtRQUNOLE9BQU8sWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssSUFBSSxDQUFDO0lBQ2pELENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNhdmVkVGFibGVDb25maWcgfSBmcm9tICcuLi9qcXVlcnktdGFibGUubW9kZWwnO1xuXG5jb25zdCBTVE9SQUdFX1BSRUZJWCA9ICdqcXRfcHJlZnNfJztcblxuLyoqXG4gKiBHw6hyZSBsYSBwZXJzaXN0YW5jZSBkZSBsYSBjb25maWd1cmF0aW9uIGQndW4gdGFibGVhdSBkYW5zIGxlIGxvY2FsU3RvcmFnZS5cbiAqIElkZW50aWZpZSBjaGFxdWUgdGFibGVhdSBwYXIgdW4gYHRhYmxlSWRgIHVuaXF1ZSBmb3VybmkgcGFyIGwndXRpbGlzYXRldXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBUYWJsZVByZWZlcmVuY2VzTWFuYWdlciB7XG4gIHJlYWRvbmx5IGtleTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHRhYmxlSWQ6IHN0cmluZykge1xuICAgIHRoaXMua2V5ID0gU1RPUkFHRV9QUkVGSVggKyB0YWJsZUlkO1xuICB9XG5cbiAgLyoqIFJldG91cm5lIGxhIGNvbmZpZ3VyYXRpb24gc2F1dmVnYXJkw6llLCBvdSBgbnVsbGAgc2kgYWJzZW50ZSAvIGNvcnJvbXB1ZS4gKi9cbiAgbG9hZCgpOiBTYXZlZFRhYmxlQ29uZmlnIHwgbnVsbCB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJhdyA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMua2V5KTtcbiAgICAgIHJldHVybiByYXcgPyAoSlNPTi5wYXJzZShyYXcpIGFzIFNhdmVkVGFibGVDb25maWcpIDogbnVsbDtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBQZXJzaXN0ZSBsYSBjb25maWd1cmF0aW9uIGRhbnMgbGUgbG9jYWxTdG9yYWdlLiAqL1xuICBzYXZlKGNvbmZpZzogU2F2ZWRUYWJsZUNvbmZpZyk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSh0aGlzLmtleSwgSlNPTi5zdHJpbmdpZnkoY29uZmlnKSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBsb2NhbFN0b3JhZ2UgcGV1dCDDqnRyZSBpbmRpc3BvbmlibGUgKG1vZGUgcHJpdsOpIHN0cmljdCwgcXVvdGEgZMOpcGFzc8Op4oCmKVxuICAgIH1cbiAgfVxuXG4gIC8qKiBTdXBwcmltZSBsYSBjb25maWd1cmF0aW9uIHNhdXZlZ2FyZMOpZS4gKi9cbiAgY2xlYXIoKTogdm9pZCB7XG4gICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0odGhpcy5rZXkpO1xuICB9XG5cbiAgLyoqIEluZGlxdWUgc2kgdW5lIGNvbmZpZ3VyYXRpb24gZXN0IGFjdHVlbGxlbWVudCBzYXV2ZWdhcmTDqWUuICovXG4gIGhhc1NhdmVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLmtleSkgIT09IG51bGw7XG4gIH1cbn1cbiJdfQ==
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtcHJlZmVyZW5jZXMubWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29uZXRlbWUvanF1ZXJ5LXRhYmxlL3NyYy9saWIvY29tcG9uZW50L3RhYmxlLXByZWZlcmVuY2VzLm1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxjQUFjLEdBQUcsWUFBWSxDQUFDO0FBRXBDOzs7R0FHRztBQUNILE1BQU0sT0FBTyx1QkFBdUI7SUFHbEMsWUFBWSxPQUFlO1FBQ3pCLElBQUksQ0FBQyxHQUFHLEdBQUcsY0FBYyxHQUFHLE9BQU8sQ0FBQztJQUN0QyxDQUFDO0lBRUQsK0VBQStFO0lBQy9FLElBQUk7UUFDRixJQUFJO1lBQ0YsTUFBTSxHQUFHLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDM0MsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFzQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7U0FDM0Q7UUFBQyxNQUFNO1lBQ04sT0FBTyxJQUFJLENBQUM7U0FDYjtJQUNILENBQUM7SUFFRCxzREFBc0Q7SUFDdEQsSUFBSSxDQUFDLE1BQXdCO1FBQzNCLElBQUk7WUFDRixZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1NBQ3hEO1FBQUMsTUFBTTtZQUNOLDBFQUEwRTtTQUMzRTtJQUNILENBQUM7SUFFRCw2Q0FBNkM7SUFDN0MsS0FBSztRQUNILElBQUk7WUFDRixZQUFZLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUNuQztRQUFDLE1BQU07WUFDTix5Q0FBeUM7U0FDMUM7SUFDSCxDQUFDO0lBRUQsaUVBQWlFO0lBQ2pFLFFBQVE7UUFDTixJQUFJO1lBQ0YsT0FBTyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxJQUFJLENBQUM7U0FDaEQ7UUFBQyxNQUFNO1lBQ04sT0FBTyxLQUFLLENBQUM7U0FDZDtJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNhdmVkVGFibGVDb25maWcgfSBmcm9tICcuLi9qcXVlcnktdGFibGUubW9kZWwnO1xuXG5jb25zdCBTVE9SQUdFX1BSRUZJWCA9ICdqcXRfcHJlZnNfJztcblxuLyoqXG4gKiBHw6hyZSBsYSBwZXJzaXN0YW5jZSBkZSBsYSBjb25maWd1cmF0aW9uIGQndW4gdGFibGVhdSBkYW5zIGxlIGxvY2FsU3RvcmFnZS5cbiAqIElkZW50aWZpZSBjaGFxdWUgdGFibGVhdSBwYXIgdW4gYHRhYmxlSWRgIHVuaXF1ZSBmb3VybmkgcGFyIGwndXRpbGlzYXRldXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBUYWJsZVByZWZlcmVuY2VzTWFuYWdlciB7XG4gIHJlYWRvbmx5IGtleTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHRhYmxlSWQ6IHN0cmluZykge1xuICAgIHRoaXMua2V5ID0gU1RPUkFHRV9QUkVGSVggKyB0YWJsZUlkO1xuICB9XG5cbiAgLyoqIFJldG91cm5lIGxhIGNvbmZpZ3VyYXRpb24gc2F1dmVnYXJkw6llLCBvdSBgbnVsbGAgc2kgYWJzZW50ZSAvIGNvcnJvbXB1ZS4gKi9cbiAgbG9hZCgpOiBTYXZlZFRhYmxlQ29uZmlnIHwgbnVsbCB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJhdyA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMua2V5KTtcbiAgICAgIHJldHVybiByYXcgPyAoSlNPTi5wYXJzZShyYXcpIGFzIFNhdmVkVGFibGVDb25maWcpIDogbnVsbDtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBQZXJzaXN0ZSBsYSBjb25maWd1cmF0aW9uIGRhbnMgbGUgbG9jYWxTdG9yYWdlLiAqL1xuICBzYXZlKGNvbmZpZzogU2F2ZWRUYWJsZUNvbmZpZyk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSh0aGlzLmtleSwgSlNPTi5zdHJpbmdpZnkoY29uZmlnKSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBsb2NhbFN0b3JhZ2UgcGV1dCDDqnRyZSBpbmRpc3BvbmlibGUgKG1vZGUgcHJpdsOpIHN0cmljdCwgcXVvdGEgZMOpcGFzc8Op4oCmKVxuICAgIH1cbiAgfVxuXG4gIC8qKiBTdXBwcmltZSBsYSBjb25maWd1cmF0aW9uIHNhdXZlZ2FyZMOpZS4gKi9cbiAgY2xlYXIoKTogdm9pZCB7XG4gICAgdHJ5IHtcbiAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKHRoaXMua2V5KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIHN0b2NrYWdlIGluZGlzcG9uaWJsZSA6IHJpZW4gw6AgZWZmYWNlclxuICAgIH1cbiAgfVxuXG4gIC8qKiBJbmRpcXVlIHNpIHVuZSBjb25maWd1cmF0aW9uIGVzdCBhY3R1ZWxsZW1lbnQgc2F1dmVnYXJkw6llLiAqL1xuICBoYXNTYXZlZCgpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMua2V5KSAhPT0gbnVsbDtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==