@oneteme/jquery-table 0.0.13 → 0.0.15

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
@@ -2,6 +2,18 @@
2
2
 
3
3
  Bibliothèque Angular qui encapsule Angular Material Table avec une API orientée configuration runtime.
4
4
 
5
+ > **Documentation et démonstrations** : [ouvrir l'application de documentation](https://oneteme.github.io/jquery-charts/)
6
+ >
7
+ > La documentation interactive présente les colonnes configurables, la recherche, le Group by, les slices, les préférences et l'intégration avec l'Organizer.
8
+
9
+ ## Nouveautés intégrées
10
+
11
+ - préférences persistantes par tableau via `TablePreferencesConfig` et `localStorage` ;
12
+ - export CSV limité aux lignes filtrées et aux colonnes visibles, avec transformation personnalisable ;
13
+ - Group by avec pagination indépendante et slices dynamiques depuis le menu View ;
14
+ - colonnes lazy avec états `idle`, `loading`, `loaded` et `error` ;
15
+ - snapshots de configuration pour conserver les colonnes visibles, l'ordre, les largeurs, le tri, le regroupement et les filtres.
16
+
5
17
  ## Features
6
18
 
7
19
  - Configuration déclarative du tableau via `TableProvider`
@@ -12,7 +24,7 @@ Bibliothèque Angular qui encapsule Angular Material Table avec une API orienté
12
24
  - Pagination standard et pagination par groupe
13
25
  - **Group by** : regroupement des lignes par colonne, groupes pliables/dépliables, pagination indépendante par groupe
14
26
  - **Slice panel** : filtres catégoriels latéraux, statiques (prédéfinis) ou dynamiques (colonne valeurs uniques), multi-sélection configurable
15
- - **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)
16
28
  - Rendus de cellule personnalisés via directive `jqtCellDef`
17
29
  - État de chargement (`isLoading`) et état vide configurable
18
30
  - Événement de clic sur ligne (`rowSelected`)
@@ -107,6 +119,7 @@ Le `config` complet reste disponible pour activer les fonctionnalités avancées
107
119
  | `columnsConfig` | `TableColumnProvider<T>[]` | Configuration des colonnes (remplace `config.columns`) |
108
120
  | `columnLabels` | `Record<string, string>` | Labels des colonnes pour le mode allégé |
109
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) |
110
123
  | `view` | `TableViewConfig` | Surcharge `config.view` si défini (mode HTML) |
111
124
 
112
125
  ### Outputs
@@ -119,6 +132,7 @@ Le `config` complet reste disponible pour activer les fonctionnalités avancées
119
132
  | `searchChange` | `string` | Frappe dans la barre de recherche |
120
133
  | `groupByChange` | `string \| null` | Group by activé (clé) ou désactivé (`null`) |
121
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) |
122
136
  | `columnAdded` | `TableColumnProvider<T>` | Colonne ajoutée aux colonnes actives |
123
137
  | `columnRemoved` | `TableColumnProvider<T>` | Colonne retirée des colonnes actives |
124
138
  | `categorySelected` | `string` | Catégorie de slice sélectionnée |
@@ -141,6 +155,7 @@ interface TableProvider<T = any> {
141
155
  view?: TableViewConfig;
142
156
  labels?: TableLabelsConfig;
143
157
  export?: TableExportConfig<T>;
158
+ lazyLoader?: (lazyColumns: string[]) => Observable<T[]>; // Charge les colonnes lazy (lignes complètes)
144
159
  preferences?: TablePreferencesConfig; // Sauvegarde dans localStorage
145
160
 
146
161
  defaultSort?: { active: string; direction: 'asc' | 'desc' };
@@ -168,16 +183,14 @@ interface TableColumnProvider<T = any> {
168
183
  width?: string; // Largeur CSS en px uniquement pour le calcul min-width (ex: '120px')
169
184
  // Les unités %, em, rem sont ignorées dans le calcul de tableMinWidth
170
185
 
171
- 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)
172
187
  removable?: boolean; // Peut être retirée manuellement
173
188
 
174
189
  groupable?: boolean; // Disponible comme critère de regroupement dans View menu
175
190
  sliceable?: boolean; // Disponible comme slice dynamique dans View menu
176
191
  searchValue?: DataProvider<string>; // Valeur utilisée par la recherche texte (si différente de value)
177
192
 
178
- lazy?: {
179
- fetchFn: () => Observable<any[]>; // Retourne un tableau dans le même ordre que les lignes
180
- };
193
+ lazy?: true; // Absente de la requête de base, forcément optionnelle : demandée à sa première activation
181
194
  }
182
195
  ```
183
196
 
@@ -288,13 +301,13 @@ Seuls les champs fournis écrasent les défauts français. Voir `JqtI18n` pour l
288
301
 
289
302
  ## Fonctionnalité — Group by
290
303
 
291
- Le regroupement s'active en ajoutant `groupable: true` sur une ou plusieurs colonnes. L'utilisateur choisit ensuite la colonne de regroupement depuis le menu View.
304
+ Le regroupement est disponible par défaut pour les colonnes qui possèdent un `header`. Utilisez `groupable: false` pour retirer une colonne du menu Group by ; `groupable: true` reste utile pour une colonne sans `header`.
292
305
 
293
306
  ```ts
294
307
  columns: [
295
- { key: 'team', header: 'Équipe', groupable: true },
296
- { key: 'status', header: 'Statut', groupable: true },
297
- { key: 'name', header: 'Nom' },
308
+ { key: 'team', header: 'Équipe' },
309
+ { key: 'status', header: 'Statut' },
310
+ { key: 'name', header: 'Nom', groupable: false },
298
311
  ],
299
312
  view: { enabled: true },
300
313
  pagination: {
@@ -339,11 +352,12 @@ slices: [
339
352
 
340
353
  ### Slices dynamiques (depuis le menu View)
341
354
 
342
- Une colonne avec `sliceable: true` peut être ajoutée dynamiquement comme slice depuis le menu View.
355
+ Les colonnes qui possèdent un `header` sont disponibles par défaut comme slices dynamiques depuis le menu View. Utilisez `sliceable: false` pour retirer une colonne ; `sliceable: true` reste utile pour une colonne sans `header`.
343
356
 
344
357
  ```ts
345
358
  columns: [
346
- { key: 'team', header: 'Équipe', sliceable: true },
359
+ { key: 'team', header: 'Équipe' },
360
+ { key: 'reference', header: 'Référence', sliceable: false },
347
361
  ],
348
362
  view: { enabled: true },
349
363
  ```
@@ -385,19 +399,70 @@ interface SliceCategory<T = any> {
385
399
 
386
400
  ## Fonctionnalité — lazy columns
387
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
+
388
408
  ```ts
389
- columns: [
390
- {
391
- key: 'details',
392
- header: 'Détails',
393
- lazy: {
394
- fetchFn: () => this.api.getDetails(),
395
- },
396
- },
397
- ],
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
+ };
419
+ ```
420
+
421
+ ```html
422
+ <jquery-table [config]="config" [data]="countries"></jquery-table>
398
423
  ```
399
424
 
400
- Le composant gère l'état `idle | loading | loaded | error` par colonne, avec possibilité de relancer la requête en cas d'erreur.
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).
401
466
 
402
467
  ---
403
468
 
@@ -420,6 +485,7 @@ Le composant gère l'état `idle | loading | loaded | error` par colonne, avec p
420
485
  Contexte du template :
421
486
  - `$implicit` la ligne brute (`T`)
422
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.
423
489
 
424
490
  ---
425
491
 
@@ -460,8 +526,7 @@ config: TableProvider<Row> = {
460
526
  | `sliceConfigs` | `SliceConfig<T>[]` | Configurations des slices |
461
527
  | `columns` | `SliceColumnDef<T>[]` | Définitions des colonnes pour la résolution des valeurs |
462
528
  | `data` | `T[]` | Données source |
463
- | `lazyData` | `Map<string, Map<any,any>>` | Valeurs lazy chargées |
464
- | `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`) |
465
530
  | `showToggle` | `boolean` | Affiche le bouton collapse du panel (défaut : `true`) |
466
531
  | `showCounts` | `boolean` | Affiche le nombre de lignes par catégorie (défaut : `true`) |
467
532
  | `collapsedByDefault` | `boolean` | Les slices démarrent repliés (défaut : `false`) |
@@ -505,9 +570,59 @@ jquery-table {
505
570
  /* Accent & danger */
506
571
  --jqt-primary-color: #1d4ed8;
507
572
  --jqt-danger-color: #dc2626;
573
+
574
+ /* Header / footer */
575
+ --jqt-header-bg: #f5f5f5;
576
+ --jqt-header-text-color: #374151;
577
+ --jqt-header-height: 56px;
578
+ --jqt-header-cell-padding-y: 0px;
579
+ --jqt-footer-bg: #f5f5f5;
580
+ --jqt-footer-text-color: #374151;
581
+ --jqt-footer-icon-color: #374151;
582
+ --jqt-footer-height: 56px;
583
+
584
+ /* Contrôles de la toolbar */
585
+ --jqt-toolbar-control-height: 34px;
586
+
587
+ /* Panneau de slices */
588
+ --jqt-slice-panel-min-width: 155px;
589
+ --jqt-slice-panel-max-width: 190px;
590
+ --jqt-slice-header-height: 34px;
591
+ --jqt-slice-header-margin-bottom: 8px;
592
+ --jqt-slice-body-padding: 4px 10px 10px;
593
+ --jqt-slice-section-title-font-size: 14px;
594
+ --jqt-slice-item-font-size: 13px;
595
+ --jqt-slice-item-min-height: 30px;
596
+ --jqt-slice-item-padding: 5px 10px 5px 16px;
597
+
598
+ /* Bouton Organizer */
599
+ --jqt-organizer-button-height: 34px;
600
+ --jqt-organizer-button-width: 34px;
601
+ --jqt-organizer-button-min-width: 34px;
602
+ --jqt-organizer-button-radius: 8px;
603
+ --jqt-organizer-button-border-color: #e0e0e0;
604
+ --jqt-organizer-button-background: #ffffff;
605
+ --jqt-organizer-button-hover-border-color: #9e9e9e;
606
+ --jqt-organizer-button-hover-background: #ffffff;
607
+ --jqt-organizer-button-icon-color: #000000;
508
608
  }
509
609
  ```
510
610
 
611
+ Le bouton Organizer intégré peut aussi être configuré via `TableProvider` :
612
+
613
+ ```ts
614
+ const table: TableProvider<Row> = {
615
+ organizer: {
616
+ buttonLabel: 'Vue',
617
+ buttonIcon: 'tune',
618
+ showButtonIcon: true,
619
+ hideMenuValues: false,
620
+ },
621
+ };
622
+ ```
623
+
624
+ Les variables CSS sont héritées par le tableau, son panneau de slices et son Organizer. Elles permettent notamment de réduire le header/footer, d'ajuster la largeur et la densité des filtres, et de modifier le bouton sans cibler les classes internes Angular Material.
625
+
511
626
  ---
512
627
 
513
628
  ## Utilitaires exportés
@@ -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,15 +32,15 @@ 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
  }
38
39
  _csvEscape(value) {
39
- if (value.includes(',') || value.includes('"') || value.includes('\n')) {
40
- return '"' + value.replace(/"/g, '""') + '"';
40
+ if (value.includes(',') || value.includes('"') || value.includes('\n') || value.includes('\r')) {
41
+ return '"' + value.replaceAll('"', '""') + '"';
41
42
  }
42
43
  return value;
43
44
  }
44
45
  }
45
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwb3J0Lm1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vbmV0ZW1lL2pxdWVyeS10YWJsZS9zcmMvbGliL2NvbXBvbmVudC9leHBvcnQubWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyxhQUFhO0lBQ3hCLFlBQ21CLE9BQWtCLEVBQ2xCLFVBQTBDLEVBQzFDLFNBQWlELEVBQ2pELGdCQUE2RTtRQUg3RSxZQUFPLEdBQVAsT0FBTyxDQUFXO1FBQ2xCLGVBQVUsR0FBVixVQUFVLENBQWdDO1FBQzFDLGNBQVMsR0FBVCxTQUFTLENBQXdDO1FBQ2pELHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBNkQ7SUFDN0YsQ0FBQztJQUVKLE1BQU07UUFDSixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLEdBQUcsRUFBRSxPQUFPO1lBQUUsT0FBTztRQUMxQixNQUFNLElBQUksR0FBTSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDL0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sUUFBUSxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsR0FBRyxNQUFNLENBQUM7UUFFckQsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUUsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtZQUNsQyxJQUFJLEdBQUcsQ0FBQyxTQUFTLEVBQUU7Z0JBQ2pCLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzdCLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUM1RTtZQUNELE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkcsQ0FBQyxDQUFDLENBQUM7UUFFSCxtREFBbUQ7UUFDbkQsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSx3QkFBd0IsRUFBRSxDQUFDLENBQUM7UUFDdEcsTUFBTSxHQUFHLEdBQUksR0FBRyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2QyxNQUFNLENBQUMsR0FBTSxRQUFRLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDO1FBQ2IsQ0FBQyxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUM7UUFDdEUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1YsR0FBRyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRU8sVUFBVSxDQUFDLEtBQWE7UUFDOUIsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUN0RSxPQUFPLEdBQUcsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUM7U0FDOUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRhYmxlQ29sdW1uUHJvdmlkZXIsIFRhYmxlRXhwb3J0Q29uZmlnIH0gZnJvbSAnLi4vanF1ZXJ5LXRhYmxlLm1vZGVsJztcblxuLyoqXG4gKiBFeHBvcnRNYW5hZ2VyXG4gKlxuICogRW5jYXBzdWxlIGwnZXhwb3J0IENTViA6IGNvbnN0cnVjdGlvbiBkdSBmaWNoaWVyIEJPTS9VVEYtOCwgw6ljaGFwcGVtZW50IGV0IGTDqWNsZW5jaGVtZW50IGR1IHTDqWzDqWNoYXJnZW1lbnQuXG4gKiBBdWN1bmUgZMOpcGVuZGFuY2UgQW5ndWxhciDigJQgaW5kw6lwZW5kYW50IGR1IGN5Y2xlIGRlIHZpZSBkdSBjb21wb3NhbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBFeHBvcnRNYW5hZ2VyPFQ+IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBnZXRSb3dzOiAoKSA9PiBUW10sXG4gICAgcHJpdmF0ZSByZWFkb25seSBnZXRDb2x1bW5zOiAoKSA9PiBUYWJsZUNvbHVtblByb3ZpZGVyPFQ+W10sXG4gICAgcHJpdmF0ZSByZWFkb25seSBnZXRDb25maWc6ICgpID0+IFRhYmxlRXhwb3J0Q29uZmlnPFQ+IHwgdW5kZWZpbmVkLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVzb2x2ZUNlbGxWYWx1ZTogKGNvbDogVGFibGVDb2x1bW5Qcm92aWRlcjxUPiwgcm93OiBULCBpbmRleDogbnVtYmVyKSA9PiBhbnksXG4gICkge31cblxuICBleHBvcnQoKTogdm9pZCB7XG4gICAgY29uc3QgY2ZnID0gdGhpcy5nZXRDb25maWcoKTtcbiAgICBpZiAoIWNmZz8uZW5hYmxlZCkgcmV0dXJuO1xuICAgIGNvbnN0IHJvd3MgICAgPSB0aGlzLmdldFJvd3MoKTtcbiAgICBjb25zdCBjb2x1bW5zID0gdGhpcy5nZXRDb2x1bW5zKCk7XG4gICAgY29uc3QgZmlsZW5hbWUgPSAoY2ZnLmZpbGVuYW1lIHx8ICdleHBvcnQnKSArICcuY3N2JztcblxuICAgIGNvbnN0IGhlYWRlciA9IGNvbHVtbnMubWFwKGMgPT4gdGhpcy5fY3N2RXNjYXBlKGMuaGVhZGVyIHx8IGMua2V5KSkuam9pbignLCcpO1xuICAgIGNvbnN0IGxpbmVzID0gcm93cy5tYXAoKHJvdywgaWR4KSA9PiB7XG4gICAgICBpZiAoY2ZnLnRyYW5zZm9ybSkge1xuICAgICAgICBjb25zdCB0ID0gY2ZnLnRyYW5zZm9ybShyb3cpO1xuICAgICAgICByZXR1cm4gY29sdW1ucy5tYXAoYyA9PiB0aGlzLl9jc3ZFc2NhcGUoU3RyaW5nKHRbYy5rZXldID8/ICcnKSkpLmpvaW4oJywnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb2x1bW5zLm1hcChjID0+IHRoaXMuX2NzdkVzY2FwZShTdHJpbmcodGhpcy5yZXNvbHZlQ2VsbFZhbHVlKGMsIHJvdywgaWR4KSA/PyAnJykpKS5qb2luKCcsJyk7XG4gICAgfSk7XG5cbiAgICAvLyBCT00gVVRGLTggcG91ciB1bmUgb3V2ZXJ0dXJlIGNvcnJlY3RlIHNvdXMgRXhjZWxcbiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoWydcXHVGRUZGJyArIFtoZWFkZXIsIC4uLmxpbmVzXS5qb2luKCdcXG4nKV0sIHsgdHlwZTogJ3RleHQvY3N2O2NoYXJzZXQ9dXRmLTgnIH0pO1xuICAgIGNvbnN0IHVybCAgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgIGNvbnN0IGEgICAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgYS5ocmVmID0gdXJsO1xuICAgIGEuZG93bmxvYWQgPSBmaWxlbmFtZS5lbmRzV2l0aCgnLmNzdicpID8gZmlsZW5hbWUgOiBmaWxlbmFtZSArICcuY3N2JztcbiAgICBhLmNsaWNrKCk7XG4gICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICB9XG5cbiAgcHJpdmF0ZSBfY3N2RXNjYXBlKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICh2YWx1ZS5pbmNsdWRlcygnLCcpIHx8IHZhbHVlLmluY2x1ZGVzKCdcIicpIHx8IHZhbHVlLmluY2x1ZGVzKCdcXG4nKSkge1xuICAgICAgcmV0dXJuICdcIicgKyB2YWx1ZS5yZXBsYWNlKC9cIi9nLCAnXCJcIicpICsgJ1wiJztcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG59XG4iXX0=
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==