@sumaris-net/ngx-components 2.4.57 → 2.4.59

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.
Files changed (52) hide show
  1. package/doc/changelog.md +8 -0
  2. package/esm2020/public_api.mjs +11 -3
  3. package/esm2020/src/app/core/graphql/graphql.service.mjs +2 -2
  4. package/esm2020/src/app/core/graphql/graphql.utils.mjs +1 -1
  5. package/esm2020/src/app/core/services/network.service.mjs +17 -4
  6. package/esm2020/src/app/core/services/platform.service.mjs +24 -5
  7. package/esm2020/src/app/core/services/storage/entities-storage.service.mjs +2 -2
  8. package/esm2020/src/app/core/services/storage/entity-store.class.mjs +1 -1
  9. package/esm2020/src/app/core/table/table.class.mjs +1 -1
  10. package/esm2020/src/app/shared/debug/debug-service.class.mjs +3 -0
  11. package/esm2020/src/app/shared/file/json.utils.mjs +4 -4
  12. package/esm2020/src/app/shared/logging/log-level.model.mjs +48 -0
  13. package/esm2020/src/app/shared/logging/logger.model.mjs +47 -0
  14. package/esm2020/src/app/shared/logging/logging-service.class.mjs +121 -0
  15. package/esm2020/src/app/shared/logging/logging-service.config.mjs +2 -0
  16. package/esm2020/src/app/shared/logging/logging-service.module.mjs +30 -0
  17. package/esm2020/src/app/shared/shared.module.mjs +3 -3
  18. package/esm2020/src/app/shared/shared.testing.module.mjs +16 -8
  19. package/esm2020/src/app/shared/storage/storage-explorer.component.mjs +262 -0
  20. package/esm2020/src/app/shared/storage/storage-explorer.module.mjs +60 -0
  21. package/esm2020/src/app/shared/storage/storage.service.mjs +132 -0
  22. package/esm2020/src/app/shared/storage/storage.utils.mjs +13 -0
  23. package/esm2020/src/app/social/user-event/testing/user-event.testing.service.mjs +1 -1
  24. package/esm2020/src/environments/environment.class.mjs +1 -1
  25. package/esm2020/src/environments/environment.mjs +7 -2
  26. package/fesm2015/sumaris-net.ngx-components.mjs +965 -376
  27. package/fesm2015/sumaris-net.ngx-components.mjs.map +1 -1
  28. package/fesm2020/sumaris-net.ngx-components.mjs +941 -383
  29. package/fesm2020/sumaris-net.ngx-components.mjs.map +1 -1
  30. package/package.json +1 -1
  31. package/public_api.d.ts +10 -2
  32. package/src/app/core/graphql/graphql.service.d.ts +1 -1
  33. package/src/app/core/graphql/graphql.utils.d.ts +1 -1
  34. package/src/app/core/services/network.service.d.ts +5 -2
  35. package/src/app/core/services/platform.service.d.ts +6 -3
  36. package/src/app/core/services/storage/entities-storage.service.d.ts +1 -1
  37. package/src/app/core/services/storage/entity-store.class.d.ts +1 -1
  38. package/src/app/shared/debug/debug-service.class.d.ts +5 -0
  39. package/src/app/shared/logging/log-level.model.d.ts +38 -0
  40. package/src/app/shared/logging/logger.model.d.ts +68 -0
  41. package/src/app/shared/logging/logging-service.class.d.ts +39 -0
  42. package/src/app/shared/logging/logging-service.config.d.ts +25 -0
  43. package/src/app/shared/logging/logging-service.module.d.ts +9 -0
  44. package/src/app/shared/shared.testing.module.d.ts +2 -1
  45. package/src/app/shared/storage/storage-explorer.component.d.ts +58 -0
  46. package/src/app/shared/storage/storage-explorer.module.d.ts +16 -0
  47. package/src/app/shared/{services/storage → storage}/storage.service.d.ts +2 -2
  48. package/src/assets/i18n/fr.json +3 -0
  49. package/src/environments/environment.class.d.ts +2 -0
  50. package/esm2020/src/app/shared/services/storage/storage.service.mjs +0 -132
  51. package/esm2020/src/app/shared/services/storage/storage.utils.mjs +0 -13
  52. /package/src/app/shared/{services/storage → storage}/storage.utils.d.ts +0 -0
@@ -0,0 +1,262 @@
1
+ import { ChangeDetectionStrategy, Component, Inject, InjectionToken, Input, Optional, ViewChild } from '@angular/core';
2
+ import { BehaviorSubject } from 'rxjs';
3
+ import { isNotNilOrBlank, removeDuplicatesFromArray, sleep, toBoolean } from '../functions';
4
+ import { APP_STORAGE } from './storage.utils';
5
+ import { APP_DEBUG_DATA_SERVICE } from '../debug/debug-service.class';
6
+ import { Toasts } from '../toast/toasts';
7
+ import { JsonUtils } from '../file/json.utils';
8
+ import { Clipboard } from '@capacitor/clipboard';
9
+ import { ENVIRONMENT } from '../../../environments/environment.class';
10
+ import { LogUtils } from '../logging/logger.model';
11
+ import { DATE_ISO_PATTERN } from '../constants';
12
+ import { LogLevel } from '../logging/log-level.model';
13
+ import { DateUtils } from '../dates';
14
+ import { Alerts } from '../alerts';
15
+ import * as i0 from "@angular/core";
16
+ import * as i1 from "@ionic/angular";
17
+ import * as i2 from "@ngx-translate/core";
18
+ import * as i3 from "@angular/material-moment-adapter";
19
+ import * as i4 from "@angular/common";
20
+ import * as i5 from "@rx-angular/template/for";
21
+ import * as i6 from "@angular/material/icon";
22
+ import * as i7 from "@angular/material/button";
23
+ import * as i8 from "../pipes/date-format.pipe";
24
+ import * as i9 from "../pipes/arrays.pipe";
25
+ import * as i10 from "../../../environments/environment.class";
26
+ export const APP_STORAGE_EXPLORER_PROTECTED_KEYS = new InjectionToken('StorageExplorerProtectedKeys');
27
+ export class StorageExplorerComponent {
28
+ constructor(platform, toastController, alertCtrl, translate, dateAdapter, cd, storage, environment, debugDataService, _protectedKeys) {
29
+ this.platform = platform;
30
+ this.toastController = toastController;
31
+ this.alertCtrl = alertCtrl;
32
+ this.translate = translate;
33
+ this.dateAdapter = dateAdapter;
34
+ this.cd = cd;
35
+ this.storage = storage;
36
+ this.environment = environment;
37
+ this.debugDataService = debugDataService;
38
+ this._protectedKeys = _protectedKeys;
39
+ this._logPrefix = '[storage-explorer] ';
40
+ this.$loading = new BehaviorSubject(true);
41
+ this.$items = new BehaviorSubject([]);
42
+ this.levelToString = LogUtils.levelToString;
43
+ this._protectedKeys = removeDuplicatesFromArray([...(this._protectedKeys || []), 'seckey', 'token']);
44
+ this._logKey = environment.logging?.localStorageAppender?.localStorageKey || 'log';
45
+ }
46
+ ngOnInit() {
47
+ this.showSendButton = toBoolean(this.showSendButton, true) && !!this.debugDataService;
48
+ this.mobile = toBoolean(this.mobile, this.platform.is('mobile'));
49
+ this.storage.ready()
50
+ .then(() => this.start());
51
+ }
52
+ async sendDataClick(event, key) {
53
+ if (!this.debugDataService) {
54
+ console.warn(`${this._logPrefix}Cannot send debug data: missing provider for 'APP_DEBUG_DATA_SERVICE'`);
55
+ return;
56
+ }
57
+ this.sendDataModal.present();
58
+ const { data, role } = await this.sendDataModal.onDidDismiss();
59
+ if (role === 'send') {
60
+ this.sendData(key);
61
+ }
62
+ }
63
+ async viewDataClick(event, key) {
64
+ if (!key)
65
+ return; // skip
66
+ try {
67
+ this.key = key;
68
+ const data = await this.storage.get(key);
69
+ if (this._logKey === key) {
70
+ const logs = Array.isArray(data) ? data : JSON.parse(data);
71
+ this.logs = LogUtils.fromObjects(logs);
72
+ }
73
+ else {
74
+ this.data = this.toString(key, data);
75
+ }
76
+ this.viewDataModal.present();
77
+ await this.viewDataModal.onWillDismiss();
78
+ }
79
+ finally {
80
+ // Forget the data
81
+ this.data = null;
82
+ this.logs = null;
83
+ this.key = null;
84
+ }
85
+ }
86
+ async sendData(key) {
87
+ if (!key || !this.debugDataService)
88
+ return; // Skip
89
+ const rawValue = await this.storage.get(key);
90
+ try {
91
+ await this.debugDataService.sendDebugData(rawValue);
92
+ }
93
+ catch (e) {
94
+ await Toasts.show(this.toastController, this.translate, {
95
+ type: 'error',
96
+ message: e.message
97
+ });
98
+ return;
99
+ }
100
+ // Confirm message was sent
101
+ await Toasts.show(this.toastController, this.translate, {
102
+ type: 'info',
103
+ message: this.translate.instant('SOCIAL.INFO.MESSAGE_SENT')
104
+ });
105
+ }
106
+ async downloadAsJson(key) {
107
+ if (!key)
108
+ return; // skip
109
+ const data = await this.storage.get(key);
110
+ const content = this.toString(key, data);
111
+ JsonUtils.exportToFile(content, { filename: `${key}.json` });
112
+ }
113
+ async copyToClipboard(key) {
114
+ if (!key)
115
+ return; // skip
116
+ const data = await this.storage.get(key);
117
+ try {
118
+ const text = this.toString(key, data);
119
+ await Clipboard.write({
120
+ string: text,
121
+ });
122
+ await Toasts.show(this.toastController, this.translate, {
123
+ type: 'info', message: 'INFO.COPY_SUCCEED'
124
+ });
125
+ }
126
+ catch (error) {
127
+ console.error('Error copying text to clipboard', error);
128
+ }
129
+ }
130
+ async start() {
131
+ const items = [];
132
+ this.storage.forEach((value, key) => {
133
+ if (this._protectedKeys.includes(key))
134
+ return; // Skip protected keys
135
+ if (Array.isArray(value)) {
136
+ items.push({
137
+ key,
138
+ type: 'array',
139
+ total: value.length
140
+ });
141
+ }
142
+ else if (typeof value === 'object') {
143
+ let total;
144
+ if (value?.type && value?.type == 'object') {
145
+ const nestedValue = JSON.parse(value.value);
146
+ total = (Array.isArray(nestedValue)) ? nestedValue.length : (Object.keys(nestedValue).length > 0 ? 1 : 0);
147
+ }
148
+ else {
149
+ total = Object.keys(value).length > 0 ? 1 : 0;
150
+ }
151
+ items.push({
152
+ key,
153
+ type: 'object',
154
+ total
155
+ });
156
+ }
157
+ else {
158
+ const type = (typeof value === 'number') ? 'number' : 'string';
159
+ items.push({
160
+ key,
161
+ type,
162
+ total: isNotNilOrBlank(value) ? 1 : 0
163
+ });
164
+ }
165
+ this.$items.next(items);
166
+ });
167
+ this.$loading.next(false);
168
+ }
169
+ async refresh() {
170
+ if (this.$loading.value)
171
+ return; // SKip if loading
172
+ this.$loading.next(true);
173
+ await this.start();
174
+ }
175
+ toString(key, data, html) {
176
+ if (key === this._logKey) {
177
+ let dateTimePattern = this.translate.instant('COMMON.DATE_TIME_SECONDS_PATTERN');
178
+ if (dateTimePattern === 'COMMON.DATE_TIME_SECONDS_PATTERN') {
179
+ dateTimePattern = DATE_ISO_PATTERN;
180
+ }
181
+ const logs = Array.isArray(data) ? data : JSON.parse(data);
182
+ return this.toLogs(data).map(log => [
183
+ this.dateAdapter.format(log.date, dateTimePattern),
184
+ LogUtils.levelToString(log.level),
185
+ log.loggerName + '\t',
186
+ log.message
187
+ ].join('\t')).join('\n');
188
+ }
189
+ // Force settings to be indent
190
+ if (key === 'settings') {
191
+ data = (typeof data === 'object') ? data : JSON.parse(data);
192
+ }
193
+ // Default case
194
+ return (typeof data === 'string') ? data : JSON.stringify(data, null, 2);
195
+ }
196
+ toLogs(data) {
197
+ try {
198
+ const logs = Array.isArray(data) ? data
199
+ : (data ? JSON.parse(data) : []);
200
+ return LogUtils.fromObjects(logs);
201
+ }
202
+ catch (err) {
203
+ console.error(err);
204
+ return [{
205
+ loggerName: 'storage-explorer',
206
+ level: LogLevel.FATAL,
207
+ message: err?.message || JSON.stringify(err),
208
+ date: DateUtils.moment()
209
+ }];
210
+ }
211
+ }
212
+ async clear(key) {
213
+ const confirmed = await Alerts.askActionConfirmation(this.alertCtrl, this.translate, true);
214
+ if (!confirmed)
215
+ return;
216
+ this.logs = [];
217
+ this.cd.markForCheck();
218
+ await sleep(650);
219
+ await this.storage.remove(key);
220
+ this.viewDataModal.dismiss();
221
+ this.refresh();
222
+ }
223
+ trackByFn(index, item) {
224
+ return item.key;
225
+ }
226
+ levelToColor(level) {
227
+ return `var(--ion-color-${LogUtils.levelToColor(level)})`;
228
+ }
229
+ }
230
+ StorageExplorerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: StorageExplorerComponent, deps: [{ token: i1.Platform }, { token: i1.ToastController }, { token: i1.AlertController }, { token: i2.TranslateService }, { token: i3.MomentDateAdapter }, { token: i0.ChangeDetectorRef }, { token: APP_STORAGE }, { token: ENVIRONMENT }, { token: APP_DEBUG_DATA_SERVICE, optional: true }, { token: APP_STORAGE_EXPLORER_PROTECTED_KEYS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
231
+ StorageExplorerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: StorageExplorerComponent, selector: "app-storage-explorer", inputs: { mobile: "mobile", showSendButton: "showSendButton" }, viewQueries: [{ propertyName: "sendDataModal", first: true, predicate: ["sendDataModal"], descendants: true }, { propertyName: "viewDataModal", first: true, predicate: ["viewDataModal"], descendants: true }], ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"primary\">\n <ion-title>Storage Explorer</ion-title>\n\n <ion-buttons slot=\"end\">\n <!-- Refresh -->\n <button mat-icon-button\n [title]=\"'COMMON.BTN_REFRESH'|translate\"\n (click)=\"refresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-no-padding\">\n\n\n <ion-grid class=\"ion-padding list-istorage\">\n <ion-row>\n <ion-col size=\"12\" size-lg=\"6\" class=\"mat-header-cell\">\n <ion-label translate>REFERENTIAL.LABEL</ion-label>\n </ion-col>\n <ion-col class=\"mat-header-cell\">\n <ion-label translate>REFERENTIAL.TYPE</ion-label>\n </ion-col>\n <ion-col class=\"mat-header-cell ion-text-start\">\n <ion-label>Nb</ion-label>\n </ion-col>\n <ion-col class=\"mat-header-cell\" size=\"auto\" >\n </ion-col>\n </ion-row>\n\n\n <ion-row class=\"mat-row\" *rxFor=\"let item of $items; trackBy: trackByFn; odd as odd;\"\n [class.odd]=\"odd\" >\n <ion-col size=\"12\" size-lg=\"6\">\n <ion-label class=\"ion-text-wrap mat-cell\"><b>{{ item.key }}</b></ion-label>\n </ion-col>\n <ion-col class=\" mat-cell\">\n <ion-label>{{ item.type }}</ion-label>\n </ion-col>\n <ion-col class=\" mat-cell\">\n <ion-label>{{ item.total }}</ion-label>\n </ion-col>\n <ion-col size=\"auto mat-cell\">\n <ion-buttons>\n\n <ion-button color=\"primary\" (click)=\"viewDataClick($event, item.key)\"\n [title]=\"'COMMON.BTN_PREVIEW'|translate\">\n <mat-icon slot=\"icon-only\" [attr.aria-label]=\"'COMMON.BTN_PREVIEW'|translate\">remove_red_eye</mat-icon>\n </ion-button>\n <ion-button *ngIf=\"showSendButton\"\n color=\"primary\"\n (click)=\"sendDataClick($event, item.key)\"\n [title]=\"'COMMON.BTN_SEND'|translate\">\n <mat-icon slot=\"icon-only\" [attr.aria-label]=\"'COMMON.BTN_SEND'|translate\">send</mat-icon>\n </ion-button>\n </ion-buttons>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n\n <ng-container *ngIf=\"$loading|async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"$items|async|isEmptyArray\">\n <ion-text color=\"danger\"\n class=\"text-italic\"\n [innerHTML]=\"'COMMON.NO_RESULT' | translate\">\n </ion-text>\n </ion-item>\n </ng-template>\n\n</ion-content>\n\n\n<ion-modal #sendDataModal>\n <ng-template>\n <ion-content class=\"ion-padding\">\n <ion-item lines=\"none\" translate>CONFIRM.SEND_DEBUG_DATA</ion-item>\n </ion-content>\n <ion-footer>\n <ion-toolbar>\n\n <ion-row class=\"ion-no-padding\" nowrap>\n <ion-col></ion-col>\n\n <!-- buttons -->\n <ion-col size=\"auto\">\n <ion-button fill=\"clear\" color=\"dark\" (click)=\"sendDataModal.dismiss()\">\n <ion-label translate>COMMON.BTN_CANCEL</ion-label>\n </ion-button>\n\n <ion-button fill=\"solid\" (click)=\"sendDataModal.dismiss(null, 'send')\" color=\"tertiary\">\n <ion-label translate>COMMON.BTN_VALIDATE</ion-label>\n </ion-button>\n </ion-col>\n </ion-row>\n </ion-toolbar>\n </ion-footer>\n </ng-template>\n</ion-modal>\n\n<ion-modal #viewDataModal class=\"modal-large view-modal\">\n <ng-template>\n <ion-content class=\"ion-no-padding\" scroll-y=\"true\">\n <!-- display logs-->\n <ng-container *ngIf=\"logs; else otherKey\">\n <ion-grid>\n <ion-row *ngFor=\"let log of logs\"\n [style.color]=\"levelToColor(log.level)\">\n <ion-col size=\"2\" class=\"ion-text-start\">\n {{log.date|dateFormat: {time: true} }}\n </ion-col>\n <ion-col size=\"1\" class=\"ion-text-start\">\n {{levelToString(log.level)}}\n </ion-col>\n <ion-col size=\"2\" class=\"ion-text-start\">\n {{log.loggerName}}\n </ion-col>\n <ion-col class=\"ion-text-wrap\">\n {{ log.message }}\n </ion-col>\n </ion-row>\n </ion-grid>\n </ng-container>\n <ng-template #otherKey>\n <div class=\"ion-padding\">\n <pre>{{data}}</pre>\n </div>\n </ng-template>\n </ion-content>\n\n <ion-footer>\n <ion-toolbar>\n\n <ion-row class=\"ion-no-padding\" nowrap>\n <ion-col></ion-col>\n\n <!-- buttons -->\n <ion-col size=\"auto\">\n\n <ion-button fill=\"clear\" color=\"danger\"\n (click)=\"clear(key)\">\n <mat-icon slot=\"start\">delete</mat-icon>\n <ion-label translate>COMMON.BTN_CLEAR</ion-label>\n </ion-button>\n <ion-button fill=\"clear\"\n (click)=\"copyToClipboard(key)\">\n <mat-icon slot=\"start\">content_copy</mat-icon>\n <ion-label translate>COMMON.BTN_COPY</ion-label>\n </ion-button>\n\n <ion-button fill=\"clear\"\n *ngIf=\"!mobile\"\n (click)=\"downloadAsJson(key)\">\n <mat-icon slot=\"start\">download</mat-icon>\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n\n <ion-button fill=\"solid\" color=\"tertiary\" (click)=\"viewDataModal.dismiss()\">\n <ion-label translate>COMMON.BTN_CLOSE</ion-label>\n </ion-button>\n </ion-col>\n </ion-row>\n </ion-toolbar>\n </ion-footer>\n </ng-template>\n</ion-modal>\n", styles: ["ion-grid.list-istorage{--ion-grid-column-padding: 5px}ion-grid.list-istorage ion-row{align-items:center}ion-grid.list-istorage ion-row.mat-header-row{height:40px}ion-grid.list-istorage ion-row.mat-header-row ion-col{vertical-align:center}ion-grid.list-istorage ion-row.computed ion-col ion-label,ion-grid.list-istorage ion-row ion-label.computed{color:var(--ion-color-primary-tint)!important;font-style:italic!important}ion-grid.list-istorage ion-row.odd{background-color:var(--ion-color-light)}ion-grid.list-istorage ion-row ion-col{padding:var(--ion-grid-column-padding)}ion-grid.list-istorage ion-row ion-col ion-label{vertical-align:center}.view-modal pre{overflow-x:auto;white-space:pre-wrap;word-wrap:break-word}\n"], dependencies: [{ kind: "component", type: i1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i1.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i1.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i1.IonRow, selector: "ion-row" }, { kind: "component", type: i1.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: i1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i1.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: i1.IonModal, selector: "ion-modal", inputs: ["animated", "keepContentsMounted", "backdropBreakpoint", "backdropDismiss", "breakpoints", "canDismiss", "cssClass", "enterAnimation", "event", "handle", "handleBehavior", "initialBreakpoint", "isOpen", "keyboardClose", "leaveAnimation", "mode", "presentingElement", "showBackdrop", "swipeToClose", "translucent", "trigger"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i5.RxFor, selector: "[rxFor][rxForOf]", inputs: ["rxForOf", "rxForTemplate", "rxForStrategy", "rxForParent", "rxForPatchZone", "rxForTrackBy", "rxForRenderCallback"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i7.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "pipe", type: i8.DateFormatPipe, name: "dateFormat" }, { kind: "pipe", type: i9.EmptyArrayPipe, name: "isEmptyArray" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
232
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: StorageExplorerComponent, decorators: [{
233
+ type: Component,
234
+ args: [{ selector: 'app-storage-explorer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ion-header>\n <ion-toolbar color=\"primary\">\n <ion-title>Storage Explorer</ion-title>\n\n <ion-buttons slot=\"end\">\n <!-- Refresh -->\n <button mat-icon-button\n [title]=\"'COMMON.BTN_REFRESH'|translate\"\n (click)=\"refresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n\n<ion-content class=\"ion-no-padding\">\n\n\n <ion-grid class=\"ion-padding list-istorage\">\n <ion-row>\n <ion-col size=\"12\" size-lg=\"6\" class=\"mat-header-cell\">\n <ion-label translate>REFERENTIAL.LABEL</ion-label>\n </ion-col>\n <ion-col class=\"mat-header-cell\">\n <ion-label translate>REFERENTIAL.TYPE</ion-label>\n </ion-col>\n <ion-col class=\"mat-header-cell ion-text-start\">\n <ion-label>Nb</ion-label>\n </ion-col>\n <ion-col class=\"mat-header-cell\" size=\"auto\" >\n </ion-col>\n </ion-row>\n\n\n <ion-row class=\"mat-row\" *rxFor=\"let item of $items; trackBy: trackByFn; odd as odd;\"\n [class.odd]=\"odd\" >\n <ion-col size=\"12\" size-lg=\"6\">\n <ion-label class=\"ion-text-wrap mat-cell\"><b>{{ item.key }}</b></ion-label>\n </ion-col>\n <ion-col class=\" mat-cell\">\n <ion-label>{{ item.type }}</ion-label>\n </ion-col>\n <ion-col class=\" mat-cell\">\n <ion-label>{{ item.total }}</ion-label>\n </ion-col>\n <ion-col size=\"auto mat-cell\">\n <ion-buttons>\n\n <ion-button color=\"primary\" (click)=\"viewDataClick($event, item.key)\"\n [title]=\"'COMMON.BTN_PREVIEW'|translate\">\n <mat-icon slot=\"icon-only\" [attr.aria-label]=\"'COMMON.BTN_PREVIEW'|translate\">remove_red_eye</mat-icon>\n </ion-button>\n <ion-button *ngIf=\"showSendButton\"\n color=\"primary\"\n (click)=\"sendDataClick($event, item.key)\"\n [title]=\"'COMMON.BTN_SEND'|translate\">\n <mat-icon slot=\"icon-only\" [attr.aria-label]=\"'COMMON.BTN_SEND'|translate\">send</mat-icon>\n </ion-button>\n </ion-buttons>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n\n <ng-container *ngIf=\"$loading|async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"$items|async|isEmptyArray\">\n <ion-text color=\"danger\"\n class=\"text-italic\"\n [innerHTML]=\"'COMMON.NO_RESULT' | translate\">\n </ion-text>\n </ion-item>\n </ng-template>\n\n</ion-content>\n\n\n<ion-modal #sendDataModal>\n <ng-template>\n <ion-content class=\"ion-padding\">\n <ion-item lines=\"none\" translate>CONFIRM.SEND_DEBUG_DATA</ion-item>\n </ion-content>\n <ion-footer>\n <ion-toolbar>\n\n <ion-row class=\"ion-no-padding\" nowrap>\n <ion-col></ion-col>\n\n <!-- buttons -->\n <ion-col size=\"auto\">\n <ion-button fill=\"clear\" color=\"dark\" (click)=\"sendDataModal.dismiss()\">\n <ion-label translate>COMMON.BTN_CANCEL</ion-label>\n </ion-button>\n\n <ion-button fill=\"solid\" (click)=\"sendDataModal.dismiss(null, 'send')\" color=\"tertiary\">\n <ion-label translate>COMMON.BTN_VALIDATE</ion-label>\n </ion-button>\n </ion-col>\n </ion-row>\n </ion-toolbar>\n </ion-footer>\n </ng-template>\n</ion-modal>\n\n<ion-modal #viewDataModal class=\"modal-large view-modal\">\n <ng-template>\n <ion-content class=\"ion-no-padding\" scroll-y=\"true\">\n <!-- display logs-->\n <ng-container *ngIf=\"logs; else otherKey\">\n <ion-grid>\n <ion-row *ngFor=\"let log of logs\"\n [style.color]=\"levelToColor(log.level)\">\n <ion-col size=\"2\" class=\"ion-text-start\">\n {{log.date|dateFormat: {time: true} }}\n </ion-col>\n <ion-col size=\"1\" class=\"ion-text-start\">\n {{levelToString(log.level)}}\n </ion-col>\n <ion-col size=\"2\" class=\"ion-text-start\">\n {{log.loggerName}}\n </ion-col>\n <ion-col class=\"ion-text-wrap\">\n {{ log.message }}\n </ion-col>\n </ion-row>\n </ion-grid>\n </ng-container>\n <ng-template #otherKey>\n <div class=\"ion-padding\">\n <pre>{{data}}</pre>\n </div>\n </ng-template>\n </ion-content>\n\n <ion-footer>\n <ion-toolbar>\n\n <ion-row class=\"ion-no-padding\" nowrap>\n <ion-col></ion-col>\n\n <!-- buttons -->\n <ion-col size=\"auto\">\n\n <ion-button fill=\"clear\" color=\"danger\"\n (click)=\"clear(key)\">\n <mat-icon slot=\"start\">delete</mat-icon>\n <ion-label translate>COMMON.BTN_CLEAR</ion-label>\n </ion-button>\n <ion-button fill=\"clear\"\n (click)=\"copyToClipboard(key)\">\n <mat-icon slot=\"start\">content_copy</mat-icon>\n <ion-label translate>COMMON.BTN_COPY</ion-label>\n </ion-button>\n\n <ion-button fill=\"clear\"\n *ngIf=\"!mobile\"\n (click)=\"downloadAsJson(key)\">\n <mat-icon slot=\"start\">download</mat-icon>\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n\n <ion-button fill=\"solid\" color=\"tertiary\" (click)=\"viewDataModal.dismiss()\">\n <ion-label translate>COMMON.BTN_CLOSE</ion-label>\n </ion-button>\n </ion-col>\n </ion-row>\n </ion-toolbar>\n </ion-footer>\n </ng-template>\n</ion-modal>\n", styles: ["ion-grid.list-istorage{--ion-grid-column-padding: 5px}ion-grid.list-istorage ion-row{align-items:center}ion-grid.list-istorage ion-row.mat-header-row{height:40px}ion-grid.list-istorage ion-row.mat-header-row ion-col{vertical-align:center}ion-grid.list-istorage ion-row.computed ion-col ion-label,ion-grid.list-istorage ion-row ion-label.computed{color:var(--ion-color-primary-tint)!important;font-style:italic!important}ion-grid.list-istorage ion-row.odd{background-color:var(--ion-color-light)}ion-grid.list-istorage ion-row ion-col{padding:var(--ion-grid-column-padding)}ion-grid.list-istorage ion-row ion-col ion-label{vertical-align:center}.view-modal pre{overflow-x:auto;white-space:pre-wrap;word-wrap:break-word}\n"] }]
235
+ }], ctorParameters: function () { return [{ type: i1.Platform }, { type: i1.ToastController }, { type: i1.AlertController }, { type: i2.TranslateService }, { type: i3.MomentDateAdapter }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
236
+ type: Inject,
237
+ args: [APP_STORAGE]
238
+ }] }, { type: i10.Environment, decorators: [{
239
+ type: Inject,
240
+ args: [ENVIRONMENT]
241
+ }] }, { type: undefined, decorators: [{
242
+ type: Optional
243
+ }, {
244
+ type: Inject,
245
+ args: [APP_DEBUG_DATA_SERVICE]
246
+ }] }, { type: undefined, decorators: [{
247
+ type: Optional
248
+ }, {
249
+ type: Inject,
250
+ args: [APP_STORAGE_EXPLORER_PROTECTED_KEYS]
251
+ }] }]; }, propDecorators: { mobile: [{
252
+ type: Input
253
+ }], showSendButton: [{
254
+ type: Input
255
+ }], sendDataModal: [{
256
+ type: ViewChild,
257
+ args: ['sendDataModal']
258
+ }], viewDataModal: [{
259
+ type: ViewChild,
260
+ args: ['viewDataModal']
261
+ }] } });
262
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS1leHBsb3Jlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3NoYXJlZC9zdG9yYWdlL3N0b3JhZ2UtZXhwbG9yZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9zaGFyZWQvc3RvcmFnZS9zdG9yYWdlLWV4cGxvcmVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyx1QkFBdUIsRUFBcUIsU0FBUyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsS0FBSyxFQUFVLFFBQVEsRUFBRSxTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFFaEosT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUNyQyxPQUFPLEVBQUMsZUFBZSxFQUFFLHlCQUF5QixFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDMUYsT0FBTyxFQUFDLFdBQVcsRUFBVyxNQUFNLGlCQUFpQixDQUFDO0FBQ3RELE9BQU8sRUFBQyxzQkFBc0IsRUFBb0IsTUFBTSw4QkFBOEIsQ0FBQztBQUV2RixPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBQzdDLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUMvQyxPQUFPLEVBQWMsV0FBVyxFQUFDLE1BQU0seUNBQXlDLENBQUM7QUFDakYsT0FBTyxFQUFNLFFBQVEsRUFBQyxNQUFNLHlCQUF5QixDQUFDO0FBRXRELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUM5QyxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDcEQsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLFVBQVUsQ0FBQztB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QUFFLElBQXFCO1FBQ3RELE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQztJQUNsQixDQUFDO0lBRVMsWUFBWSxDQUFDLEtBQWU7UUFDcEMsT0FBTyxtQkFBbUIsUUFBUSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDO0lBQzVELENBQUM7O3NIQXhQVSx3QkFBd0IsME1BeUJ6QixXQUFXLGFBQ1gsV0FBVyxhQUNDLHNCQUFzQiw2QkFDdEIsbUNBQW1DOzBHQTVCOUMsd0JBQXdCLDZVQ2xDckMsbTBMQStLQTs0RkQ3SWEsd0JBQXdCO2tCQU5wQyxTQUFTOytCQUNFLHNCQUFzQixtQkFHZix1QkFBdUIsQ0FBQyxNQUFNOzswQkEyQjVDLE1BQU07MkJBQUMsV0FBVzs7MEJBQ2xCLE1BQU07MkJBQUMsV0FBVzs7MEJBQ2xCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsc0JBQXNCOzswQkFDekMsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxtQ0FBbUM7NENBakJoRCxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFFc0IsYUFBYTtzQkFBeEMsU0FBUzt1QkFBQyxlQUFlO2dCQUNFLGFBQWE7c0JBQXhDLFNBQVM7dUJBQUMsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEluamVjdCwgSW5qZWN0aW9uVG9rZW4sIElucHV0LCBPbkluaXQsIE9wdGlvbmFsLCBWaWV3Q2hpbGR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtBbGVydENvbnRyb2xsZXIsIElvbk1vZGFsLCBQbGF0Zm9ybSwgVG9hc3RDb250cm9sbGVyfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQge0JlaGF2aW9yU3ViamVjdH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge2lzTm90TmlsT3JCbGFuaywgcmVtb3ZlRHVwbGljYXRlc0Zyb21BcnJheSwgc2xlZXAsIHRvQm9vbGVhbn0gZnJvbSAnLi4vZnVuY3Rpb25zJztcbmltcG9ydCB7QVBQX1NUT1JBR0UsIElTdG9yYWdlfSBmcm9tICcuL3N0b3JhZ2UudXRpbHMnO1xuaW1wb3J0IHtBUFBfREVCVUdfREFUQV9TRVJWSUNFLCBJRGVidWdEYXRhU2VydmljZX0gZnJvbSAnLi4vZGVidWcvZGVidWctc2VydmljZS5jbGFzcyc7XG5pbXBvcnQge1RyYW5zbGF0ZVNlcnZpY2V9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtUb2FzdHN9IGZyb20gJy4uL3RvYXN0L3RvYXN0cyc7XG5pbXBvcnQge0pzb25VdGlsc30gZnJvbSAnLi4vZmlsZS9qc29uLnV0aWxzJztcbmltcG9ydCB7Q2xpcGJvYXJkfSBmcm9tICdAY2FwYWNpdG9yL2NsaXBib2FyZCc7XG5pbXBvcnQge0Vudmlyb25tZW50LCBFTlZJUk9OTUVOVH0gZnJvbSAnLi4vLi4vLi4vZW52aXJvbm1lbnRzL2Vudmlyb25tZW50LmNsYXNzJztcbmltcG9ydCB7TG9nLCBMb2dVdGlsc30gZnJvbSAnLi4vbG9nZ2luZy9sb2dnZXIubW9kZWwnO1xuaW1wb3J0IHtNb21lbnREYXRlQWRhcHRlcn0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwtbW9tZW50LWFkYXB0ZXInO1xuaW1wb3J0IHtEQVRFX0lTT19QQVRURVJOfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHtMb2dMZXZlbH0gZnJvbSAnLi4vbG9nZ2luZy9sb2ctbGV2ZWwubW9kZWwnO1xuaW1wb3J0IHtEYXRlVXRpbHN9IGZyb20gJy4uL2RhdGVzJztcbmltcG9ydCB7QWxlcnRzfSBmcm9tICcuLi9hbGVydHMnO1xuXG50eXBlIFN0b3JhZ2VJdGVtSW5mbyA9IHtcbiAga2V5OiBzdHJpbmc7XG4gIHR5cGU6ICdhcnJheScgfCAnb2JqZWN0JyB8ICdzdHJpbmcnIHwgJ251bWJlcic7XG4gIHRvdGFsOiBudW1iZXI7XG59O1xuXG5cbmV4cG9ydCBjb25zdCBBUFBfU1RPUkFHRV9FWFBMT1JFUl9QUk9URUNURURfS0VZUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxzdHJpbmdbXT4oJ1N0b3JhZ2VFeHBsb3JlclByb3RlY3RlZEtleXMnKTtcblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtc3RvcmFnZS1leHBsb3JlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9zdG9yYWdlLWV4cGxvcmVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc3RvcmFnZS1leHBsb3Jlci5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBTdG9yYWdlRXhwbG9yZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIHByaXZhdGUgX2xvZ1ByZWZpeCA9ICdbc3RvcmFnZS1leHBsb3Jlcl0gJztcbiAgcHJvdGVjdGVkICRsb2FkaW5nID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPih0cnVlKTtcbiAgcHJvdGVjdGVkICRpdGVtcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8U3RvcmFnZUl0ZW1JbmZvW10+KFtdKTtcbiAgcHJvdGVjdGVkIF9sb2dLZXk6IHN0cmluZztcblxuICBwcm90ZWN0ZWQgZGF0YTogYW55O1xuICBwcm90ZWN0ZWQgbG9nczogTG9nW107XG4gIHByb3RlY3RlZCBrZXk6IHN0cmluZztcblxuICBASW5wdXQoKSBtb2JpbGU6IGJvb2xlYW47XG4gIEBJbnB1dCgpIHNob3dTZW5kQnV0dG9uOiBib29sZWFuO1xuXG4gIEBWaWV3Q2hpbGQoJ3NlbmREYXRhTW9kYWwnKSBzZW5kRGF0YU1vZGFsOiBJb25Nb2RhbDtcbiAgQFZpZXdDaGlsZCgndmlld0RhdGFNb2RhbCcpIHZpZXdEYXRhTW9kYWw6IElvbk1vZGFsO1xuXG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIHBsYXRmb3JtOiBQbGF0Zm9ybSxcbiAgICBwcm90ZWN0ZWQgdG9hc3RDb250cm9sbGVyOiBUb2FzdENvbnRyb2xsZXIsXG4gICAgcHJvdGVjdGVkIGFsZXJ0Q3RybDogQWxlcnRDb250cm9sbGVyLFxuICAgIHByb3RlY3RlZCB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIGRhdGVBZGFwdGVyOiBNb21lbnREYXRlQWRhcHRlcixcbiAgICBwcm90ZWN0ZWQgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIEBJbmplY3QoQVBQX1NUT1JBR0UpIHByb3RlY3RlZCByZWFkb25seSBzdG9yYWdlOiBJU3RvcmFnZSxcbiAgICBASW5qZWN0KEVOVklST05NRU5UKSBwcm90ZWN0ZWQgcmVhZG9ubHkgZW52aXJvbm1lbnQ6IEVudmlyb25tZW50LFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoQVBQX0RFQlVHX0RBVEFfU0VSVklDRSkgcHJvdGVjdGVkIHJlYWRvbmx5IGRlYnVnRGF0YVNlcnZpY2U6IElEZWJ1Z0RhdGFTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoQVBQX1NUT1JBR0VfRVhQTE9SRVJfUFJPVEVDVEVEX0tFWVMpIHByaXZhdGUgcmVhZG9ubHkgX3Byb3RlY3RlZEtleXM6IHN0cmluZ1tdXG4gICkge1xuICAgIHRoaXMuX3Byb3RlY3RlZEtleXMgPSByZW1vdmVEdXBsaWNhdGVzRnJvbUFycmF5KFsuLi4odGhpcy5fcHJvdGVjdGVkS2V5cyB8fCBbXSksICdzZWNrZXknLCAndG9rZW4nXSk7XG4gICAgdGhpcy5fbG9nS2V5ID0gZW52aXJvbm1lbnQubG9nZ2luZz8ubG9jYWxTdG9yYWdlQXBwZW5kZXI/LmxvY2FsU3RvcmFnZUtleSB8fCAnbG9nJztcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuc2hvd1NlbmRCdXR0b24gPSB0b0Jvb2xlYW4odGhpcy5zaG93U2VuZEJ1dHRvbiwgdHJ1ZSkgJiYgISF0aGlzLmRlYnVnRGF0YVNlcnZpY2U7XG4gICAgdGhpcy5tb2JpbGUgPSB0b0Jvb2xlYW4odGhpcy5tb2JpbGUsIHRoaXMucGxhdGZvcm0uaXMoJ21vYmlsZScpKTtcblxuICAgIHRoaXMuc3RvcmFnZS5yZWFkeSgpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLnN0YXJ0KCkpXG4gIH1cblxuICBhc3luYyBzZW5kRGF0YUNsaWNrKGV2ZW50OiBFdmVudCwga2V5OiBzdHJpbmcpIHtcbiAgICBpZiAoIXRoaXMuZGVidWdEYXRhU2VydmljZSkge1xuICAgICAgY29uc29sZS53YXJuKGAke3RoaXMuX2xvZ1ByZWZpeH1DYW5ub3Qgc2VuZCBkZWJ1ZyBkYXRhOiBtaXNzaW5nIHByb3ZpZGVyIGZvciAnQVBQX0RFQlVHX0RBVEFfU0VSVklDRSdgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zZW5kRGF0YU1vZGFsLnByZXNlbnQoKTtcblxuICAgIGNvbnN0IHtkYXRhLCByb2xlfSA9IGF3YWl0IHRoaXMuc2VuZERhdGFNb2RhbC5vbkRpZERpc21pc3MoKTtcbiAgICBpZiAocm9sZSA9PT0gJ3NlbmQnKSB7XG4gICAgICB0aGlzLnNlbmREYXRhKGtleSlcbiAgICB9XG4gIH1cblxuICBhc3luYyB2aWV3RGF0YUNsaWNrKGV2ZW50OiBFdmVudCwga2V5OnN0cmluZykge1xuICAgIGlmICgha2V5KSByZXR1cm47IC8vIHNraXBcblxuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMua2V5ID0ga2V5O1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuc3RvcmFnZS5nZXQoa2V5KTtcbiAgICAgIGlmICh0aGlzLl9sb2dLZXkgPT09IGtleSkge1xuICAgICAgICBjb25zdCBsb2dzID0gQXJyYXkuaXNBcnJheShkYXRhKSA/IGRhdGEgOiBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgICB0aGlzLmxvZ3MgPSBMb2dVdGlscy5mcm9tT2JqZWN0cyhsb2dzKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB0aGlzLmRhdGEgPSB0aGlzLnRvU3RyaW5nKGtleSwgZGF0YSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMudmlld0RhdGFNb2RhbC5wcmVzZW50KCk7XG5cbiAgICAgIGF3YWl0IHRoaXMudmlld0RhdGFNb2RhbC5vbldpbGxEaXNtaXNzKCk7XG5cbiAgICB9XG4gICAgZmluYWxseSB7XG4gICAgICAvLyBGb3JnZXQgdGhlIGRhdGFcbiAgICAgIHRoaXMuZGF0YSA9IG51bGw7XG4gICAgICB0aGlzLmxvZ3MgPSBudWxsO1xuICAgICAgdGhpcy5rZXkgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNlbmREYXRhKGtleTogc3RyaW5nKSB7XG4gICAgaWYgKCFrZXkgfHwgIXRoaXMuZGVidWdEYXRhU2VydmljZSkgcmV0dXJuOyAvLyBTa2lwXG5cbiAgICBjb25zdCByYXdWYWx1ZSA9IGF3YWl0IHRoaXMuc3RvcmFnZS5nZXQoa2V5KTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5kZWJ1Z0RhdGFTZXJ2aWNlLnNlbmREZWJ1Z0RhdGEocmF3VmFsdWUpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGF3YWl0IFRvYXN0cy5zaG93KHRoaXMudG9hc3RDb250cm9sbGVyLCB0aGlzLnRyYW5zbGF0ZSwge1xuICAgICAgICB0eXBlOiAnZXJyb3InLFxuICAgICAgICBtZXNzYWdlOiBlLm1lc3NhZ2VcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENvbmZpcm0gbWVzc2FnZSB3YXMgc2VudFxuICAgIGF3YWl0IFRvYXN0cy5zaG93KHRoaXMudG9hc3RDb250cm9sbGVyLCB0aGlzLnRyYW5zbGF0ZSwge1xuICAgICAgdHlwZTogJ2luZm8nLFxuICAgICAgbWVzc2FnZTogdGhpcy50cmFuc2xhdGUuaW5zdGFudCgnU09DSUFMLklORk8uTUVTU0FHRV9TRU5UJylcbiAgICB9KTtcbiAgfVxuXG5cbiAgYXN5bmMgZG93bmxvYWRBc0pzb24oa2V5OiBzdHJpbmcpIHtcbiAgICBpZiAoIWtleSkgcmV0dXJuOyAvLyBza2lwXG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuc3RvcmFnZS5nZXQoa2V5KTtcbiAgICBjb25zdCBjb250ZW50ID0gdGhpcy50b1N0cmluZyhrZXksIGRhdGEpO1xuXG4gICAgSnNvblV0aWxzLmV4cG9ydFRvRmlsZShjb250ZW50LCB7ZmlsZW5hbWU6IGAke2tleX0uanNvbmB9KTtcbiAgfVxuXG4gIGFzeW5jIGNvcHlUb0NsaXBib2FyZChrZXk6IHN0cmluZykge1xuICAgIGlmICgha2V5KSByZXR1cm47IC8vIHNraXBcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgdGhpcy5zdG9yYWdlLmdldChrZXkpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRleHQgPSB0aGlzLnRvU3RyaW5nKGtleSwgZGF0YSk7XG5cbiAgICAgIGF3YWl0IENsaXBib2FyZC53cml0ZSh7XG4gICAgICAgIHN0cmluZzogdGV4dCxcbiAgICAgIH0pO1xuXG4gICAgICBhd2FpdCBUb2FzdHMuc2hvdyh0aGlzLnRvYXN0Q29udHJvbGxlciwgdGhpcy50cmFuc2xhdGUsIHtcbiAgICAgICAgdHlwZTogJ2luZm8nLCBtZXNzYWdlOiAnSU5GTy5DT1BZX1NVQ0NFRUQnXG4gICAgICB9KVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBjb3B5aW5nIHRleHQgdG8gY2xpcGJvYXJkJywgZXJyb3IpO1xuICAgIH1cbiAgfVxuXG5cbiAgcHJvdGVjdGVkIGFzeW5jIHN0YXJ0KCkge1xuICAgIGNvbnN0IGl0ZW1zID0gW107XG4gICAgdGhpcy5zdG9yYWdlLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcblxuICAgICAgaWYgKHRoaXMuX3Byb3RlY3RlZEtleXMuaW5jbHVkZXMoa2V5KSkgcmV0dXJuOyAvLyBTa2lwIHByb3RlY3RlZCBrZXlzXG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgICBrZXksXG4gICAgICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgICAgICB0b3RhbDogdmFsdWUubGVuZ3RoXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGxldCB0b3RhbDtcbiAgICAgICAgaWYgKHZhbHVlPy50eXBlICYmIHZhbHVlPy50eXBlID09ICdvYmplY3QnKSB7XG4gICAgICAgICAgY29uc3QgbmVzdGVkVmFsdWUgPSBKU09OLnBhcnNlKHZhbHVlLnZhbHVlKTtcbiAgICAgICAgICB0b3RhbCA9IChBcnJheS5pc0FycmF5KG5lc3RlZFZhbHVlKSkgPyBuZXN0ZWRWYWx1ZS5sZW5ndGggOiAoT2JqZWN0LmtleXMobmVzdGVkVmFsdWUpLmxlbmd0aCA+IDAgPyAxIDogMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdG90YWwgPSBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoID4gMCA/IDEgOiAwO1xuICAgICAgICB9XG4gICAgICAgIGl0ZW1zLnB1c2goe1xuICAgICAgICAgIGtleSxcbiAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICB0b3RhbFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHR5cGUgPSAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykgPyAnbnVtYmVyJyA6ICdzdHJpbmcnO1xuICAgICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgICBrZXksXG4gICAgICAgICAgdHlwZSxcbiAgICAgICAgICB0b3RhbDogaXNOb3ROaWxPckJsYW5rKHZhbHVlKSA/IDEgOiAwXG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIHRoaXMuJGl0ZW1zLm5leHQoaXRlbXMpO1xuICAgIH0pO1xuXG4gICAgdGhpcy4kbG9hZGluZy5uZXh0KGZhbHNlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyByZWZyZXNoKCkge1xuICAgIGlmICh0aGlzLiRsb2FkaW5nLnZhbHVlKSByZXR1cm47IC8vIFNLaXAgaWYgbG9hZGluZ1xuXG4gICAgdGhpcy4kbG9hZGluZy5uZXh0KHRydWUpO1xuICAgIGF3YWl0IHRoaXMuc3RhcnQoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB0b1N0cmluZyhrZXk6IHN0cmluZywgZGF0YTogYW55LCBodG1sPzogYm9vbGVhbik6IHN0cmluZyB7XG4gICAgaWYgKGtleT09PSB0aGlzLl9sb2dLZXkpIHtcbiAgICAgIGxldCBkYXRlVGltZVBhdHRlcm4gPSB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdDT01NT04uREFURV9USU1FX1NFQ09ORFNfUEFUVEVSTicpO1xuICAgICAgaWYgKGRhdGVUaW1lUGF0dGVybiA9PT0gJ0NPTU1PTi5EQVRFX1RJTUVfU0VDT05EU19QQVRURVJOJykge1xuICAgICAgICBkYXRlVGltZVBhdHRlcm4gPSBEQVRFX0lTT19QQVRURVJOO1xuICAgICAgfVxuICAgICAgY29uc3QgbG9ncyA9IEFycmF5LmlzQXJyYXkoZGF0YSkgPyBkYXRhIDogSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgIHJldHVybiB0aGlzLnRvTG9ncyhkYXRhKS5tYXAobG9nID0+XG4gICAgICAgIFtcbiAgICAgICAgICB0aGlzLmRhdGVBZGFwdGVyLmZvcm1hdChsb2cuZGF0ZSwgZGF0ZVRpbWVQYXR0ZXJuKSxcbiAgICAgICAgICBMb2dVdGlscy5sZXZlbFRvU3RyaW5nKGxvZy5sZXZlbCksXG4gICAgICAgICAgbG9nLmxvZ2dlck5hbWUgKyAnXFx0JyxcbiAgICAgICAgICBsb2cubWVzc2FnZVxuICAgICAgICBdLmpvaW4oJ1xcdCcpXG4gICAgICApLmpvaW4oJ1xcbicpO1xuICAgIH1cblxuICAgIC8vIEZvcmNlIHNldHRpbmdzIHRvIGJlIGluZGVudFxuICAgIGlmIChrZXkgPT09ICdzZXR0aW5ncycpIHtcbiAgICAgIGRhdGEgPSAodHlwZW9mIGRhdGEgPT09ICdvYmplY3QnKSA/IGRhdGEgOiBKU09OLnBhcnNlKGRhdGEpO1xuICAgIH1cblxuICAgIC8vIERlZmF1bHQgY2FzZVxuICAgIHJldHVybiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSA/IGRhdGEgOiBKU09OLnN0cmluZ2lmeShkYXRhLCBudWxsLCAyKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB0b0xvZ3MoZGF0YTogYW55KTogTG9nW10ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBsb2dzID0gQXJyYXkuaXNBcnJheShkYXRhKSA/IGRhdGFcbiAgICAgICAgOiAoZGF0YSA/IEpTT04ucGFyc2UoZGF0YSkgOiBbXSk7XG4gICAgICByZXR1cm4gTG9nVXRpbHMuZnJvbU9iamVjdHMobG9ncyk7XG4gICAgfVxuICAgIGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgIHJldHVybiBbe1xuICAgICAgICBsb2dnZXJOYW1lOiAnc3RvcmFnZS1leHBsb3JlcicsXG4gICAgICAgIGxldmVsOiBMb2dMZXZlbC5GQVRBTCxcbiAgICAgICAgbWVzc2FnZTogZXJyPy5tZXNzYWdlIHx8IEpTT04uc3RyaW5naWZ5KGVyciksXG4gICAgICAgIGRhdGU6IERhdGVVdGlscy5tb21lbnQoKVxuICAgICAgfV1cbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgY2xlYXIoa2V5OiBzdHJpbmcpIHtcblxuICAgIGNvbnN0IGNvbmZpcm1lZCA9IGF3YWl0IEFsZXJ0cy5hc2tBY3Rpb25Db25maXJtYXRpb24odGhpcy5hbGVydEN0cmwsIHRoaXMudHJhbnNsYXRlLCB0cnVlKTtcbiAgICBpZiAoIWNvbmZpcm1lZCkgcmV0dXJuO1xuXG4gICAgdGhpcy5sb2dzID0gW107XG4gICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcblxuICAgIGF3YWl0IHNsZWVwKDY1MCk7XG5cbiAgICBhd2FpdCB0aGlzLnN0b3JhZ2UucmVtb3ZlKGtleSk7XG5cbiAgICB0aGlzLnZpZXdEYXRhTW9kYWwuZGlzbWlzcygpO1xuXG4gICAgdGhpcy5yZWZyZXNoKCk7XG5cbiAgfVxuXG5cbiAgcHJvdGVjdGVkIHRyYWNrQnlGbihpbmRleDogbnVtYmVyLCBpdGVtOiBTdG9yYWdlSXRlbUluZm8pOiBhbnkge1xuICAgIHJldHVybiBpdGVtLmtleTtcbiAgfVxuXG4gIHByb3RlY3RlZCBsZXZlbFRvQ29sb3IobGV2ZWw6IExvZ0xldmVsKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYHZhcigtLWlvbi1jb2xvci0ke0xvZ1V0aWxzLmxldmVsVG9Db2xvcihsZXZlbCl9KWA7XG4gIH1cbiAgcHJvdGVjdGVkIGxldmVsVG9TdHJpbmcgPSBMb2dVdGlscy5sZXZlbFRvU3RyaW5nO1xufVxuIiwiPGlvbi1oZWFkZXI+XG4gIDxpb24tdG9vbGJhciBjb2xvcj1cInByaW1hcnlcIj5cbiAgICA8aW9uLXRpdGxlPlN0b3JhZ2UgRXhwbG9yZXI8L2lvbi10aXRsZT5cblxuICAgIDxpb24tYnV0dG9ucyBzbG90PVwiZW5kXCI+XG4gICAgICA8IS0tIFJlZnJlc2ggLS0+XG4gICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgICAgICBbdGl0bGVdPVwiJ0NPTU1PTi5CVE5fUkVGUkVTSCd8dHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInJlZnJlc2goKVwiPlxuICAgICAgICA8bWF0LWljb24+cmVmcmVzaDwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2lvbi1idXR0b25zPlxuICA8L2lvbi10b29sYmFyPlxuPC9pb24taGVhZGVyPlxuXG48aW9uLWNvbnRlbnQgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuXG5cbiAgPGlvbi1ncmlkIGNsYXNzPVwiaW9uLXBhZGRpbmcgbGlzdC1pc3RvcmFnZVwiPlxuICAgIDxpb24tcm93PlxuICAgICAgPGlvbi1jb2wgc2l6ZT1cIjEyXCIgc2l6ZS1sZz1cIjZcIiBjbGFzcz1cIm1hdC1oZWFkZXItY2VsbFwiPlxuICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5SRUZFUkVOVElBTC5MQUJFTDwvaW9uLWxhYmVsPlxuICAgICAgPC9pb24tY29sPlxuICAgICAgPGlvbi1jb2wgY2xhc3M9XCJtYXQtaGVhZGVyLWNlbGxcIj5cbiAgICAgICAgPGlvbi1sYWJlbCB0cmFuc2xhdGU+UkVGRVJFTlRJQUwuVFlQRTwvaW9uLWxhYmVsPlxuICAgICAgPC9pb24tY29sPlxuICAgICAgPGlvbi1jb2wgY2xhc3M9XCJtYXQtaGVhZGVyLWNlbGwgaW9uLXRleHQtc3RhcnRcIj5cbiAgICAgICAgPGlvbi1sYWJlbD5OYjwvaW9uLWxhYmVsPlxuICAgICAgPC9pb24tY29sPlxuICAgICAgPGlvbi1jb2wgY2xhc3M9XCJtYXQtaGVhZGVyLWNlbGxcIiBzaXplPVwiYXV0b1wiID5cbiAgICAgIDwvaW9uLWNvbD5cbiAgICA8L2lvbi1yb3c+XG5cblxuICAgIDxpb24tcm93IGNsYXNzPVwibWF0LXJvd1wiICpyeEZvcj1cImxldCBpdGVtIG9mICRpdGVtczsgdHJhY2tCeTogdHJhY2tCeUZuOyBvZGQgYXMgb2RkO1wiXG4gICAgICAgICAgICAgW2NsYXNzLm9kZF09XCJvZGRcIiA+XG4gICAgICA8aW9uLWNvbCBzaXplPVwiMTJcIiBzaXplLWxnPVwiNlwiPlxuICAgICAgICA8aW9uLWxhYmVsIGNsYXNzPVwiaW9uLXRleHQtd3JhcCBtYXQtY2VsbFwiPjxiPnt7IGl0ZW0ua2V5IH19PC9iPjwvaW9uLWxhYmVsPlxuICAgICAgPC9pb24tY29sPlxuICAgICAgPGlvbi1jb2wgY2xhc3M9XCIgbWF0LWNlbGxcIj5cbiAgICAgICAgPGlvbi1sYWJlbD57eyBpdGVtLnR5cGUgfX08L2lvbi1sYWJlbD5cbiAgICAgIDwvaW9uLWNvbD5cbiAgICAgIDxpb24tY29sIGNsYXNzPVwiIG1hdC1jZWxsXCI+XG4gICAgICAgIDxpb24tbGFiZWw+e3sgaXRlbS50b3RhbCB9fTwvaW9uLWxhYmVsPlxuICAgICAgPC9pb24tY29sPlxuICAgICAgPGlvbi1jb2wgc2l6ZT1cImF1dG8gbWF0LWNlbGxcIj5cbiAgICAgICAgPGlvbi1idXR0b25zPlxuXG4gICAgICAgICAgPGlvbi1idXR0b24gY29sb3I9XCJwcmltYXJ5XCIgKGNsaWNrKT1cInZpZXdEYXRhQ2xpY2soJGV2ZW50LCBpdGVtLmtleSlcIlxuICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCInQ09NTU9OLkJUTl9QUkVWSUVXJ3x0cmFuc2xhdGVcIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbiBzbG90PVwiaWNvbi1vbmx5XCIgW2F0dHIuYXJpYS1sYWJlbF09XCInQ09NTU9OLkJUTl9QUkVWSUVXJ3x0cmFuc2xhdGVcIj5yZW1vdmVfcmVkX2V5ZTwvbWF0LWljb24+XG4gICAgICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgICAgIDxpb24tYnV0dG9uICpuZ0lmPVwic2hvd1NlbmRCdXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiXG4gICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbmREYXRhQ2xpY2soJGV2ZW50LCBpdGVtLmtleSlcIlxuICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCInQ09NTU9OLkJUTl9TRU5EJ3x0cmFuc2xhdGVcIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbiBzbG90PVwiaWNvbi1vbmx5XCIgW2F0dHIuYXJpYS1sYWJlbF09XCInQ09NTU9OLkJUTl9TRU5EJ3x0cmFuc2xhdGVcIj5zZW5kPC9tYXQtaWNvbj5cbiAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgIDwvaW9uLWJ1dHRvbnM+XG4gICAgICA8L2lvbi1jb2w+XG4gICAgPC9pb24tcm93PlxuICA8L2lvbi1ncmlkPlxuXG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiRsb2FkaW5nfGFzeW5jOyBlbHNlIG5vUmVzdWx0XCI+XG4gICAgPGlvbi1pdGVtPlxuICAgICAgPGlvbi1za2VsZXRvbi10ZXh0IGFuaW1hdGVkPjwvaW9uLXNrZWxldG9uLXRleHQ+XG4gICAgPC9pb24taXRlbT5cbiAgPC9uZy1jb250YWluZXI+XG5cbiAgPG5nLXRlbXBsYXRlICNub1Jlc3VsdD5cbiAgICA8aW9uLWl0ZW0gKm5nSWY9XCIkaXRlbXN8YXN5bmN8aXNFbXB0eUFycmF5XCI+XG4gICAgICA8aW9uLXRleHQgY29sb3I9XCJkYW5nZXJcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwidGV4dC1pdGFsaWNcIlxuICAgICAgICAgICAgICAgIFtpbm5lckhUTUxdPVwiJ0NPTU1PTi5OT19SRVNVTFQnIHwgdHJhbnNsYXRlXCI+XG4gICAgICA8L2lvbi10ZXh0PlxuICAgIDwvaW9uLWl0ZW0+XG4gIDwvbmctdGVtcGxhdGU+XG5cbjwvaW9uLWNvbnRlbnQ+XG5cblxuPGlvbi1tb2RhbCAjc2VuZERhdGFNb2RhbD5cbiAgPG5nLXRlbXBsYXRlPlxuICAgIDxpb24tY29udGVudCBjbGFzcz1cImlvbi1wYWRkaW5nXCI+XG4gICAgICA8aW9uLWl0ZW0gbGluZXM9XCJub25lXCIgdHJhbnNsYXRlPkNPTkZJUk0uU0VORF9ERUJVR19EQVRBPC9pb24taXRlbT5cbiAgICA8L2lvbi1jb250ZW50PlxuICAgIDxpb24tZm9vdGVyPlxuICAgICAgPGlvbi10b29sYmFyPlxuXG4gICAgICAgIDxpb24tcm93IGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIiBub3dyYXA+XG4gICAgICAgICAgPGlvbi1jb2w+PC9pb24tY29sPlxuXG4gICAgICAgICAgPCEtLSBidXR0b25zIC0tPlxuICAgICAgICAgIDxpb24tY29sIHNpemU9XCJhdXRvXCI+XG4gICAgICAgICAgICA8aW9uLWJ1dHRvbiBmaWxsPVwiY2xlYXJcIiBjb2xvcj1cImRhcmtcIiAoY2xpY2spPVwic2VuZERhdGFNb2RhbC5kaXNtaXNzKClcIj5cbiAgICAgICAgICAgICAgPGlvbi1sYWJlbCB0cmFuc2xhdGU+Q09NTU9OLkJUTl9DQU5DRUw8L2lvbi1sYWJlbD5cbiAgICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cblxuICAgICAgICAgICAgPGlvbi1idXR0b24gZmlsbD1cInNvbGlkXCIgKGNsaWNrKT1cInNlbmREYXRhTW9kYWwuZGlzbWlzcyhudWxsLCAnc2VuZCcpXCIgY29sb3I9XCJ0ZXJ0aWFyeVwiPlxuICAgICAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5DT01NT04uQlROX1ZBTElEQVRFPC9pb24tbGFiZWw+XG4gICAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICA8L2lvbi1yb3c+XG4gICAgICA8L2lvbi10b29sYmFyPlxuICAgIDwvaW9uLWZvb3Rlcj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvaW9uLW1vZGFsPlxuXG48aW9uLW1vZGFsICN2aWV3RGF0YU1vZGFsIGNsYXNzPVwibW9kYWwtbGFyZ2Ugdmlldy1tb2RhbFwiPlxuICA8bmctdGVtcGxhdGU+XG4gICAgPGlvbi1jb250ZW50IGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIiBzY3JvbGwteT1cInRydWVcIj5cbiAgICAgIDwhLS0gZGlzcGxheSBsb2dzLS0+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibG9nczsgZWxzZSBvdGhlcktleVwiPlxuICAgICAgICA8aW9uLWdyaWQ+XG4gICAgICAgICAgPGlvbi1yb3cgKm5nRm9yPVwibGV0IGxvZyBvZiBsb2dzXCJcbiAgICAgICAgICAgICAgICAgICBbc3R5bGUuY29sb3JdPVwibGV2ZWxUb0NvbG9yKGxvZy5sZXZlbClcIj5cbiAgICAgICAgICAgIDxpb24tY29sIHNpemU9XCIyXCIgY2xhc3M9XCJpb24tdGV4dC1zdGFydFwiPlxuICAgICAgICAgICAgICB7e2xvZy5kYXRlfGRhdGVGb3JtYXQ6IHt0aW1lOiB0cnVlfSB9fVxuICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgPGlvbi1jb2wgc2l6ZT1cIjFcIiBjbGFzcz1cImlvbi10ZXh0LXN0YXJ0XCI+XG4gICAgICAgICAgICAgIHt7bGV2ZWxUb1N0cmluZyhsb2cubGV2ZWwpfX1cbiAgICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICAgIDxpb24tY29sIHNpemU9XCIyXCIgY2xhc3M9XCJpb24tdGV4dC1zdGFydFwiPlxuICAgICAgICAgICAgICB7e2xvZy5sb2dnZXJOYW1lfX1cbiAgICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICAgIDxpb24tY29sIGNsYXNzPVwiaW9uLXRleHQtd3JhcFwiPlxuICAgICAgICAgICAgICB7eyBsb2cubWVzc2FnZSB9fVxuICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgIDwvaW9uLXJvdz5cbiAgICAgICAgPC9pb24tZ3JpZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPG5nLXRlbXBsYXRlICNvdGhlcktleT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImlvbi1wYWRkaW5nXCI+XG4gICAgICAgICAgPHByZT57e2RhdGF9fTwvcHJlPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9pb24tY29udGVudD5cblxuICAgIDxpb24tZm9vdGVyPlxuICAgICAgPGlvbi10b29sYmFyPlxuXG4gICAgICAgIDxpb24tcm93IGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIiBub3dyYXA+XG4gICAgICAgICAgPGlvbi1jb2w+PC9pb24tY29sPlxuXG4gICAgICAgICAgPCEtLSBidXR0b25zIC0tPlxuICAgICAgICAgIDxpb24tY29sIHNpemU9XCJhdXRvXCI+XG5cbiAgICAgICAgICAgIDxpb24tYnV0dG9uIGZpbGw9XCJjbGVhclwiIGNvbG9yPVwiZGFuZ2VyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjbGVhcihrZXkpXCI+XG4gICAgICAgICAgICAgIDxtYXQtaWNvbiBzbG90PVwic3RhcnRcIj5kZWxldGU8L21hdC1pY29uPlxuICAgICAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5DT01NT04uQlROX0NMRUFSPC9pb24tbGFiZWw+XG4gICAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgICAgICA8aW9uLWJ1dHRvbiBmaWxsPVwiY2xlYXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvcHlUb0NsaXBib2FyZChrZXkpXCI+XG4gICAgICAgICAgICAgIDxtYXQtaWNvbiBzbG90PVwic3RhcnRcIj5jb250ZW50X2NvcHk8L21hdC1pY29uPlxuICAgICAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5DT01NT04uQlROX0NPUFk8L2lvbi1sYWJlbD5cbiAgICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cblxuICAgICAgICAgICAgPGlvbi1idXR0b24gZmlsbD1cImNsZWFyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIW1vYmlsZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZG93bmxvYWRBc0pzb24oa2V5KVwiPlxuICAgICAgICAgICAgICA8bWF0LWljb24gc2xvdD1cInN0YXJ0XCI+ZG93bmxvYWQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5DT01NT04uQlROX0RPV05MT0FEPC9pb24tbGFiZWw+XG4gICAgICAgICAgICA8L2lvbi1idXR0b24+XG5cbiAgICAgICAgICAgIDxpb24tYnV0dG9uIGZpbGw9XCJzb2xpZFwiIGNvbG9yPVwidGVydGlhcnlcIiAoY2xpY2spPVwidmlld0RhdGFNb2RhbC5kaXNtaXNzKClcIj5cbiAgICAgICAgICAgICAgPGlvbi1sYWJlbCB0cmFuc2xhdGU+Q09NTU9OLkJUTl9DTE9TRTwvaW9uLWxhYmVsPlxuICAgICAgICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgPC9pb24tcm93PlxuICAgICAgPC9pb24tdG9vbGJhcj5cbiAgICA8L2lvbi1mb290ZXI+XG4gIDwvbmctdGVtcGxhdGU+XG48L2lvbi1tb2RhbD5cbiJdfQ==
@@ -0,0 +1,60 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { StorageExplorerComponent } from './storage-explorer.component';
4
+ import { RouterModule } from '@angular/router';
5
+ import { TranslateModule } from '@ngx-translate/core';
6
+ import { ForModule } from '@rx-angular/template/for';
7
+ import { IonicModule } from '@ionic/angular';
8
+ import { SharedPipesModule } from '../pipes/pipes.module';
9
+ import { SharedMaterialModule } from '../material/material.module';
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "@ngx-translate/core";
12
+ import * as i2 from "@angular/router";
13
+ export const SHARED_STORAGE_TESTING_PAGES = [
14
+ { label: 'Storage explorer', page: '/testing/shared/storage' }
15
+ ];
16
+ const routes = [
17
+ {
18
+ path: 'storage',
19
+ pathMatch: 'full',
20
+ component: StorageExplorerComponent,
21
+ }
22
+ ];
23
+ export class StorageExplorerModule {
24
+ }
25
+ StorageExplorerModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: StorageExplorerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
26
+ StorageExplorerModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: StorageExplorerModule, declarations: [StorageExplorerComponent], imports: [IonicModule,
27
+ CommonModule, i1.TranslateModule, i2.RouterModule, ForModule,
28
+ // Other shared modules
29
+ SharedPipesModule,
30
+ SharedMaterialModule], exports: [StorageExplorerComponent] });
31
+ StorageExplorerModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: StorageExplorerModule, imports: [IonicModule,
32
+ CommonModule,
33
+ TranslateModule.forChild(),
34
+ RouterModule.forChild(routes),
35
+ ForModule,
36
+ // Other shared modules
37
+ SharedPipesModule,
38
+ SharedMaterialModule] });
39
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: StorageExplorerModule, decorators: [{
40
+ type: NgModule,
41
+ args: [{
42
+ imports: [
43
+ IonicModule,
44
+ CommonModule,
45
+ TranslateModule.forChild(),
46
+ RouterModule.forChild(routes),
47
+ ForModule,
48
+ // Other shared modules
49
+ SharedPipesModule,
50
+ SharedMaterialModule
51
+ ],
52
+ declarations: [
53
+ StorageExplorerComponent,
54
+ ],
55
+ exports: [
56
+ StorageExplorerComponent,
57
+ ]
58
+ }]
59
+ }] });
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS1leHBsb3Jlci5tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3NoYXJlZC9zdG9yYWdlL3N0b3JhZ2UtZXhwbG9yZXIubW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDdkMsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQzdDLE9BQU8sRUFBQyx3QkFBd0IsRUFBQyxNQUFNLDhCQUE4QixDQUFDO0FBQ3RFLE9BQU8sRUFBQyxZQUFZLEVBQVMsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRCxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBQ25ELE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUV4RCxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSw2QkFBNkIsQ0FBQzs7OztBQUVqRSxNQUFNLENBQUMsTUFBTSw0QkFBNEIsR0FBa0I7SUFDekQsRUFBQyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsSUFBSSxFQUFFLHlCQUF5QixFQUFDO0NBQzdELENBQUM7QUFFRixNQUFNLE1BQU0sR0FBVztJQUNyQjtRQUNFLElBQUksRUFBRSxTQUFTO1FBQ2YsU0FBUyxFQUFFLE1BQU07UUFDakIsU0FBUyxFQUFFLHdCQUF3QjtLQUNwQztDQUNGLENBQUM7QUFzQkYsTUFBTSxPQUFPLHFCQUFxQjs7bUhBQXJCLHFCQUFxQjtvSEFBckIscUJBQXFCLGlCQU45Qix3QkFBd0IsYUFYeEIsV0FBVztRQUNYLFlBQVksdUNBR1osU0FBUztRQUVULHVCQUF1QjtRQUN2QixpQkFBaUI7UUFDakIsb0JBQW9CLGFBTXBCLHdCQUF3QjtvSEFHZixxQkFBcUIsWUFqQjlCLFdBQVc7UUFDWCxZQUFZO1FBQ1osZUFBZSxDQUFDLFFBQVEsRUFBRTtRQUMxQixZQUFZLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztRQUM3QixTQUFTO1FBRVQsdUJBQXVCO1FBQ3ZCLGlCQUFpQjtRQUNqQixvQkFBb0I7NEZBU1gscUJBQXFCO2tCQW5CakMsUUFBUTttQkFBQztvQkFDUixPQUFPLEVBQUU7d0JBQ1AsV0FBVzt3QkFDWCxZQUFZO3dCQUNaLGVBQWUsQ0FBQyxRQUFRLEVBQUU7d0JBQzFCLFlBQVksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO3dCQUM3QixTQUFTO3dCQUVULHVCQUF1Qjt3QkFDdkIsaUJBQWlCO3dCQUNqQixvQkFBb0I7cUJBQ3JCO29CQUNELFlBQVksRUFBRTt3QkFDWix3QkFBd0I7cUJBQ3pCO29CQUNELE9BQU8sRUFBRTt3QkFDUCx3QkFBd0I7cUJBQ3pCO2lCQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtOZ01vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0NvbW1vbk1vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7U3RvcmFnZUV4cGxvcmVyQ29tcG9uZW50fSBmcm9tICcuL3N0b3JhZ2UtZXhwbG9yZXIuY29tcG9uZW50JztcbmltcG9ydCB7Um91dGVyTW9kdWxlLCBSb3V0ZXN9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge1RyYW5zbGF0ZU1vZHVsZX0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQge0Zvck1vZHVsZX0gZnJvbSAnQHJ4LWFuZ3VsYXIvdGVtcGxhdGUvZm9yJztcbmltcG9ydCB7SW9uaWNNb2R1bGV9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7U2hhcmVkUGlwZXNNb2R1bGV9IGZyb20gJy4uL3BpcGVzL3BpcGVzLm1vZHVsZSc7XG5pbXBvcnQge1Rlc3RpbmdQYWdlfSBmcm9tICcuLi90ZXN0aW5nL3Rlc3RzLnBhZ2UnO1xuaW1wb3J0IHtTaGFyZWRNYXRlcmlhbE1vZHVsZX0gZnJvbSAnLi4vbWF0ZXJpYWwvbWF0ZXJpYWwubW9kdWxlJztcblxuZXhwb3J0IGNvbnN0IFNIQVJFRF9TVE9SQUdFX1RFU1RJTkdfUEFHRVM6IFRlc3RpbmdQYWdlW10gPSBbXG4gIHtsYWJlbDogJ1N0b3JhZ2UgZXhwbG9yZXInLCBwYWdlOiAnL3Rlc3Rpbmcvc2hhcmVkL3N0b3JhZ2UnfVxuXTtcblxuY29uc3Qgcm91dGVzOiBSb3V0ZXMgPSBbXG4gIHtcbiAgICBwYXRoOiAnc3RvcmFnZScsXG4gICAgcGF0aE1hdGNoOiAnZnVsbCcsXG4gICAgY29tcG9uZW50OiBTdG9yYWdlRXhwbG9yZXJDb21wb25lbnQsXG4gIH1cbl07XG5cblxuQE5nTW9kdWxlKHtcbiAgaW1wb3J0czogW1xuICAgIElvbmljTW9kdWxlLFxuICAgIENvbW1vbk1vZHVsZSxcbiAgICBUcmFuc2xhdGVNb2R1bGUuZm9yQ2hpbGQoKSxcbiAgICBSb3V0ZXJNb2R1bGUuZm9yQ2hpbGQocm91dGVzKSxcbiAgICBGb3JNb2R1bGUsXG5cbiAgICAvLyBPdGhlciBzaGFyZWQgbW9kdWxlc1xuICAgIFNoYXJlZFBpcGVzTW9kdWxlLFxuICAgIFNoYXJlZE1hdGVyaWFsTW9kdWxlXG4gIF0sXG4gIGRlY2xhcmF0aW9uczogW1xuICAgIFN0b3JhZ2VFeHBsb3JlckNvbXBvbmVudCxcbiAgXSxcbiAgZXhwb3J0czogW1xuICAgIFN0b3JhZ2VFeHBsb3JlckNvbXBvbmVudCxcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBTdG9yYWdlRXhwbG9yZXJNb2R1bGUgeyB9XG4iXX0=
@@ -0,0 +1,132 @@
1
+ import { Inject, Injectable } from '@angular/core';
2
+ import { StorageDrivers } from './storage.utils';
3
+ import { StartableService } from '../services/startable-service.class';
4
+ import { environment } from '../../../environments/environment';
5
+ import { ENVIRONMENT } from '../../../environments/environment.class';
6
+ import * as cordovaSQLiteDriver from 'localforage-cordovasqlitedriver';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "@ionic/angular";
9
+ import * as i2 from "@ionic/storage-angular";
10
+ import * as i3 from "../../../environments/environment.class";
11
+ export class StorageService extends StartableService {
12
+ constructor(platform, storage, environment) {
13
+ super(platform);
14
+ this.platform = platform;
15
+ this.storage = storage;
16
+ this.environment = environment;
17
+ this._debug = !environment.production;
18
+ this.start();
19
+ }
20
+ get driver() {
21
+ return this._data?.driver;
22
+ }
23
+ async ngOnStart() {
24
+ try {
25
+ console.debug(`[storage] Starting... {driverOrder: ${environment.storage?.driverOrder}}`);
26
+ // Define Cordova SQLLite driver
27
+ await this.storage.defineDriver(cordovaSQLiteDriver);
28
+ // Create the storage instance
29
+ const storage = await this.storage.create();
30
+ // Migrate from old storage
31
+ await this.migrate(storage);
32
+ console.info(`[storage] Started using driver: ${storage?.driver}`);
33
+ return storage;
34
+ }
35
+ catch (err) {
36
+ console.error('[storage] Cannot create storage: ' + (err?.message || err), err);
37
+ }
38
+ }
39
+ async migrate(storage) {
40
+ const canMigrate = storage?.driver === StorageDrivers.SQLLite;
41
+ if (!canMigrate)
42
+ return; // Skip
43
+ //
44
+ // const oldForage = storage.createInstance({
45
+ // name: storage.config().name,
46
+ // storeName: storage.config().storeName,
47
+ // driver: [storage.INDEXEDDB, storage.WEBSQL]
48
+ // });
49
+ //
50
+ // const keys = await oldForage.keys();
51
+ //
52
+ // // No data in the odl storage: skip migration
53
+ // if (isEmptyArray(keys)) {
54
+ // // Drop the old instance (not need anymore)
55
+ // console.debug(`[platform] Old storage is empty: dropping unused instance {name: '${storage.config().name}', driver: '${oldForage.driver()}'}`);
56
+ // await oldForage.dropInstance();
57
+ // }
58
+ // // IF some data stored in the OLD storage: start migration
59
+ // else {
60
+ //
61
+ // const now = Date.now();
62
+ // console.info(`[platform] Starting storage migration...`);
63
+ //
64
+ // const toast = await this.showToast({message: 'INFO.DATA_MIGRATION_STARTED', type: 'info', duration: 30000});
65
+ // try {
66
+ // await StorageUtils.copy(oldForage, storage, {keys, deleteAfterCopy: false});
67
+ //
68
+ // const duration = Date.now() - now;
69
+ // setTimeout(() => toast.dismiss(), Math.max(2000 - duration, 0));
70
+ // await this.showToast({message: 'INFO.DATA_MIGRATION_SUCCEED',
71
+ // type: 'info',
72
+ // showCloseButton: true
73
+ // });
74
+ // console.info('[platform] Starting storage migration [OK]');
75
+ //
76
+ // // Drop the old instance
77
+ // console.info(`[platform] Drop old storage {name: '${storage.config().name}', driver: '${oldForage.driver()}'}`);
78
+ // await oldForage.dropInstance();
79
+ // }
80
+ // catch (err) {
81
+ // console.error(err && err.message || err, err);
82
+ // await toast.dismiss();
83
+ // await this.showToast({message: 'ERROR.DATA_MIGRATION_FAILED',
84
+ // type: 'error',
85
+ // showCloseButton: true
86
+ // });
87
+ // }
88
+ //}
89
+ }
90
+ async set(key, value) {
91
+ if (!this.started)
92
+ await this.ready();
93
+ return this._data.set(key, value);
94
+ }
95
+ async get(key) {
96
+ if (!this.started)
97
+ await this.ready();
98
+ return this._data.get(key);
99
+ }
100
+ async remove(key) {
101
+ if (!this.started)
102
+ await this.ready();
103
+ return this._data.remove(key);
104
+ }
105
+ async keys() {
106
+ if (!this.started)
107
+ await this.ready();
108
+ return this._data.keys();
109
+ }
110
+ async clear() {
111
+ if (!this.started)
112
+ await this.ready();
113
+ await this._data.clear();
114
+ }
115
+ async forEach(iteratorCallback) {
116
+ if (!this.started)
117
+ await this.ready();
118
+ return this._data.forEach(iteratorCallback);
119
+ }
120
+ }
121
+ StorageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: StorageService, deps: [{ token: i1.Platform }, { token: i2.Storage }, { token: ENVIRONMENT }], target: i0.ɵɵFactoryTarget.Injectable });
122
+ StorageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: StorageService, providedIn: 'root' });
123
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: StorageService, decorators: [{
124
+ type: Injectable,
125
+ args: [{
126
+ providedIn: 'root', deps: [ENVIRONMENT]
127
+ }]
128
+ }], ctorParameters: function () { return [{ type: i1.Platform }, { type: i2.Storage }, { type: i3.Environment, decorators: [{
129
+ type: Inject,
130
+ args: [ENVIRONMENT]
131
+ }] }]; } });
132
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9zaGFyZWQvc3RvcmFnZS9zdG9yYWdlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFFakQsT0FBTyxFQUFXLGNBQWMsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLHFDQUFxQyxDQUFDO0FBRXJFLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxtQ0FBbUMsQ0FBQztBQUM5RCxPQUFPLEVBQUMsV0FBVyxFQUFjLE1BQU0seUNBQXlDLENBQUM7QUFDakYsT0FBTyxLQUFLLG1CQUFtQixNQUFNLGlDQUFpQyxDQUFDOzs7OztBQUt2RSxNQUFNLE9BQU8sY0FBZSxTQUFRLGdCQUF5QjtJQU8zRCxZQUFvQixRQUFrQixFQUNsQixPQUFnQixFQUNLLFdBQXdCO1FBRS9ELEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUpFLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDbEIsWUFBTyxHQUFQLE9BQU8sQ0FBUztRQUNLLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBRy9ELElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNmLENBQUM7SUFYRCxJQUFJLE1BQU07UUFDUixPQUFPLElBQUksQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDO0lBQzVCLENBQUM7SUFXUyxLQUFLLENBQUMsU0FBUztRQUN2QixJQUFJO1lBQ0YsT0FBTyxDQUFDLEtBQUssQ0FBQyx1Q0FBdUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxXQUFXLEdBQUcsQ0FBQyxDQUFDO1lBRTFGLGdDQUFnQztZQUNoQyxNQUFNLElBQUksQ0FBQyxP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QyxLQUFLLEVBQUUsQ0FBQztRQUN0QyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVELEtBQUssQ0FBQyxPQUFPLENBQUMsZ0JBQTJFO1FBQ3ZGLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUFFLE1BQU0sSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3RDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUM5QyxDQUFDOzs0R0F2SFUsY0FBYyxpRUFTTCxXQUFXO2dIQVRwQixjQUFjLGNBRmIsTUFBTTs0RkFFUCxjQUFjO2tCQUgxQixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsV0FBVyxDQUFDO2lCQUN4Qzs7MEJBVWMsTUFBTTsyQkFBQyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtJbmplY3QsIEluamVjdGFibGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtTdG9yYWdlfSBmcm9tICdAaW9uaWMvc3RvcmFnZS1hbmd1bGFyJztcbmltcG9ydCB7SVN0b3JhZ2UsIFN0b3JhZ2VEcml2ZXJzfSBmcm9tICcuL3N0b3JhZ2UudXRpbHMnO1xuaW1wb3J0IHtTdGFydGFibGVTZXJ2aWNlfSBmcm9tICcuLi9zZXJ2aWNlcy9zdGFydGFibGUtc2VydmljZS5jbGFzcyc7XG5pbXBvcnQge1BsYXRmb3JtfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQge2Vudmlyb25tZW50fSBmcm9tICcuLi8uLi8uLi9lbnZpcm9ubWVudHMvZW52aXJvbm1lbnQnO1xuaW1wb3J0IHtFTlZJUk9OTUVOVCwgRW52aXJvbm1lbnR9IGZyb20gJy4uLy4uLy4uL2Vudmlyb25tZW50cy9lbnZpcm9ubWVudC5jbGFzcyc7XG5pbXBvcnQgKiBhcyBjb3Jkb3ZhU1FMaXRlRHJpdmVyIGZyb20gJ2xvY2FsZm9yYWdlLWNvcmRvdmFzcWxpdGVkcml2ZXInO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290JywgZGVwczogW0VOVklST05NRU5UXVxufSlcbmV4cG9ydCBjbGFzcyBTdG9yYWdlU2VydmljZSBleHRlbmRzIFN0YXJ0YWJsZVNlcnZpY2U8U3RvcmFnZT5cbiAgaW1wbGVtZW50cyBJU3RvcmFnZTxTdG9yYWdlPiB7XG5cbiAgZ2V0IGRyaXZlcigpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9kYXRhPy5kcml2ZXI7XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHBsYXRmb3JtOiBQbGF0Zm9ybSxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBzdG9yYWdlOiBTdG9yYWdlLFxuICAgICAgICAgICAgICBASW5qZWN0KEVOVklST05NRU5UKSBwcml2YXRlIGVudmlyb25tZW50OiBFbnZpcm9ubWVudCxcbiAgICAgICAgICAgICAgKSB7XG4gICAgc3VwZXIocGxhdGZvcm0pO1xuICAgIHRoaXMuX2RlYnVnID0gIWVudmlyb25tZW50LnByb2R1Y3Rpb247XG4gICAgdGhpcy5zdGFydCgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIG5nT25TdGFydCgpOiBQcm9taXNlPFN0b3JhZ2U+IHtcbiAgICB0cnkge1xuICAgICAgY29uc29sZS5kZWJ1ZyhgW3N0b3JhZ2VdIFN0YXJ0aW5nLi4uIHtkcml2ZXJPcmRlcjogJHtlbnZpcm9ubWVudC5zdG9yYWdlPy5kcml2ZXJPcmRlcn19YCk7XG5cbiAgICAgIC8vIERlZmluZSBDb3Jkb3ZhIFNRTExpdGUgZHJpdmVyXG4gICAgICBhd2FpdCB0aGlzLnN0b3JhZ2UuZGVmaW5lRHJpdmVyKGNvcmRvdmFTUUxpdGVEcml2ZXIpO1xuXG5cbiAgICAgIC8vIENyZWF0ZSB0aGUgc3RvcmFnZSBpbnN0YW5jZVxuICAgICAgY29uc3Qgc3RvcmFnZSA9IGF3YWl0IHRoaXMuc3RvcmFnZS5jcmVhdGUoKTtcblxuICAgICAgLy8gTWlncmF0ZSBmcm9tIG9sZCBzdG9yYWdlXG4gICAgICBhd2FpdCB0aGlzLm1pZ3JhdGUoc3RvcmFnZSk7XG5cbiAgICAgIGNvbnNvbGUuaW5mbyhgW3N0b3JhZ2VdIFN0YXJ0ZWQgdXNpbmcgZHJpdmVyOiAke3N0b3JhZ2U/LmRyaXZlcn1gKTtcbiAgICAgIHJldHVybiBzdG9yYWdlO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdbc3RvcmFnZV0gQ2Fubm90IGNyZWF0ZSBzdG9yYWdlOiAnICsgKGVycj8ubWVzc2FnZSB8fCBlcnIpLCBlcnIpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBtaWdyYXRlKHN0b3JhZ2U6IFN0b3JhZ2UpIHtcbiAgICBjb25zdCBjYW5NaWdyYXRlID0gc3RvcmFnZT8uZHJpdmVyID09PSBTdG9yYWdlRHJpdmVycy5TUUxMaXRlO1xuXG4gICAgaWYgKCFjYW5NaWdyYXRlKSByZXR1cm47IC8vIFNraXBcblxuICAgIC8vXG4gICAgLy8gY29uc3Qgb2xkRm9yYWdlID0gc3RvcmFnZS5jcmVhdGVJbnN0YW5jZSh7XG4gICAgLy8gICBuYW1lOiBzdG9yYWdlLmNvbmZpZygpLm5hbWUsXG4gICAgLy8gICBzdG9yZU5hbWU6IHN0b3JhZ2UuY29uZmlnKCkuc3RvcmVOYW1lLFxuICAgIC8vICAgZHJpdmVyOiBbc3RvcmFnZS5JTkRFWEVEREIsIHN0b3JhZ2UuV0VCU1FMXVxuICAgIC8vIH0pO1xuICAgIC8vXG4gICAgLy8gY29uc3Qga2V5cyA9IGF3YWl0IG9sZEZvcmFnZS5rZXlzKCk7XG4gICAgLy9cbiAgICAvLyAvLyBObyBkYXRhIGluIHRoZSBvZGwgc3RvcmFnZTogc2tpcCBtaWdyYXRpb25cbiAgICAvLyBpZiAoaXNFbXB0eUFycmF5KGtleXMpKSB7XG4gICAgLy8gICAvLyBEcm9wIHRoZSBvbGQgaW5zdGFuY2UgKG5vdCBuZWVkIGFueW1vcmUpXG4gICAgLy8gICBjb25zb2xlLmRlYnVnKGBbcGxhdGZvcm1dIE9sZCBzdG9yYWdlIGlzIGVtcHR5OiBkcm9wcGluZyB1bnVzZWQgaW5zdGFuY2Uge25hbWU6ICcke3N0b3JhZ2UuY29uZmlnKCkubmFtZX0nLCBkcml2ZXI6ICcke29sZEZvcmFnZS5kcml2ZXIoKX0nfWApO1xuICAgIC8vICAgYXdhaXQgb2xkRm9yYWdlLmRyb3BJbnN0YW5jZSgpO1xuICAgIC8vIH1cbiAgICAvLyAvLyBJRiBzb21lIGRhdGEgc3RvcmVkIGluIHRoZSBPTEQgc3RvcmFnZTogc3RhcnQgbWlncmF0aW9uXG4gICAgLy8gZWxzZSB7XG4gICAgLy9cbiAgICAvLyAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgLy8gICBjb25zb2xlLmluZm8oYFtwbGF0Zm9ybV0gU3RhcnRpbmcgc3RvcmFnZSBtaWdyYXRpb24uLi5gKTtcbiAgICAvL1xuICAgIC8vICAgY29uc3QgdG9hc3QgPSBhd2FpdCB0aGlzLnNob3dUb2FzdCh7bWVzc2FnZTogJ0lORk8uREFUQV9NSUdSQVRJT05fU1RBUlRFRCcsIHR5cGU6ICdpbmZvJywgZHVyYXRpb246IDMwMDAwfSk7XG4gICAgLy8gICB0cnkge1xuICAgIC8vICAgICBhd2FpdCBTdG9yYWdlVXRpbHMuY29weShvbGRGb3JhZ2UsIHN0b3JhZ2UsIHtrZXlzLCBkZWxldGVBZnRlckNvcHk6IGZhbHNlfSk7XG4gICAgLy9cbiAgICAvLyAgICAgY29uc3QgZHVyYXRpb24gPSBEYXRlLm5vdygpIC0gbm93O1xuICAgIC8vICAgICBzZXRUaW1lb3V0KCgpID0+IHRvYXN0LmRpc21pc3MoKSwgIE1hdGgubWF4KDIwMDAgLSBkdXJhdGlvbiwgMCkpO1xuICAgIC8vICAgICBhd2FpdCB0aGlzLnNob3dUb2FzdCh7bWVzc2FnZTogJ0lORk8uREFUQV9NSUdSQVRJT05fU1VDQ0VFRCcsXG4gICAgLy8gICAgICAgdHlwZTogJ2luZm8nLFxuICAgIC8vICAgICAgIHNob3dDbG9zZUJ1dHRvbjogdHJ1ZVxuICAgIC8vICAgICB9KTtcbiAgICAvLyAgICAgY29uc29sZS5pbmZvKCdbcGxhdGZvcm1dIFN0YXJ0aW5nIHN0b3JhZ2UgbWlncmF0aW9uIFtPS10nKTtcbiAgICAvL1xuICAgIC8vICAgICAvLyBEcm9wIHRoZSBvbGQgaW5zdGFuY2VcbiAgICAvLyAgICAgY29uc29sZS5pbmZvKGBbcGxhdGZvcm1dIERyb3Agb2xkIHN0b3JhZ2Uge25hbWU6ICcke3N0b3JhZ2UuY29uZmlnKCkubmFtZX0nLCBkcml2ZXI6ICcke29sZEZvcmFnZS5kcml2ZXIoKX0nfWApO1xuICAgIC8vICAgICBhd2FpdCBvbGRGb3JhZ2UuZHJvcEluc3RhbmNlKCk7XG4gICAgLy8gICB9XG4gICAgLy8gICBjYXRjaCAoZXJyKSB7XG4gICAgLy8gICAgIGNvbnNvbGUuZXJyb3IoZXJyICYmIGVyci5tZXNzYWdlIHx8IGVyciwgZXJyKTtcbiAgICAvLyAgICAgYXdhaXQgdG9hc3QuZGlzbWlzcygpO1xuICAgIC8vICAgICBhd2FpdCB0aGlzLnNob3dUb2FzdCh7bWVzc2FnZTogJ0VSUk9SLkRBVEFfTUlHUkFUSU9OX0ZBSUxFRCcsXG4gICAgLy8gICAgICAgdHlwZTogJ2Vycm9yJyxcbiAgICAvLyAgICAgICBzaG93Q2xvc2VCdXR0b246IHRydWVcbiAgICAvLyAgICAgfSk7XG4gICAgLy8gICB9XG4gICAgLy99XG4gIH1cblxuICBhc3luYyBzZXQoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpIHtcbiAgICBpZiAoIXRoaXMuc3RhcnRlZCkgYXdhaXQgdGhpcy5yZWFkeSgpO1xuICAgIHJldHVybiB0aGlzLl9kYXRhLnNldChrZXksIHZhbHVlKTtcbiAgfVxuXG4gIGFzeW5jIGdldChrZXk6IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKCF0aGlzLnN0YXJ0ZWQpIGF3YWl0IHRoaXMucmVhZHkoKTtcbiAgICByZXR1cm4gdGhpcy5fZGF0YS5nZXQoa2V5KTtcbiAgfVxuXG4gIGFzeW5jIHJlbW92ZShrZXk6IHN0cmluZykge1xuICAgIGlmICghdGhpcy5zdGFydGVkKSBhd2FpdCB0aGlzLnJlYWR5KCk7XG4gICAgcmV0dXJuIHRoaXMuX2RhdGEucmVtb3ZlKGtleSk7XG4gIH1cblxuICBhc3luYyBrZXlzKCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBpZiAoIXRoaXMuc3RhcnRlZCkgYXdhaXQgdGhpcy5yZWFkeSgpO1xuICAgIHJldHVybiB0aGlzLl9kYXRhLmtleXMoKTtcbiAgfVxuXG4gIGFzeW5jIGNsZWFyKCkge1xuICAgIGlmICghdGhpcy5zdGFydGVkKSBhd2FpdCB0aGlzLnJlYWR5KCk7XG4gICAgYXdhaXQgdGhpcy5fZGF0YS5jbGVhcigpO1xuICB9XG5cbiAgYXN5bmMgZm9yRWFjaChpdGVyYXRvckNhbGxiYWNrOiAodmFsdWU6IGFueSwga2V5OiBzdHJpbmcsIGl0ZXJhdGlvbk51bWJlcjogTnVtYmVyKSA9PiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuc3RhcnRlZCkgYXdhaXQgdGhpcy5yZWFkeSgpO1xuICAgIHJldHVybiB0aGlzLl9kYXRhLmZvckVhY2goaXRlcmF0b3JDYWxsYmFjayk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,13 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ import { Drivers } from '@ionic/storage';
3
+ import * as LocalForage from 'localforage';
4
+ import * as CordovaSQLiteDriver from 'localforage-cordovasqlitedriver';
5
+ export const StorageDrivers = {
6
+ SQLLite: CordovaSQLiteDriver._driver,
7
+ SecureStorage: Drivers.SecureStorage,
8
+ WebSQL: LocalForage.WEBSQL,
9
+ IndexedDB: Drivers.IndexedDB,
10
+ LocalStorage: Drivers.LocalStorage
11
+ };
12
+ export const APP_STORAGE = new InjectionToken('Storage');
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS51dGlscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL3N0b3JhZ2Uvc3RvcmFnZS51dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQzdDLE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN2QyxPQUFPLEtBQUssV0FBVyxNQUFNLGFBQWEsQ0FBQztBQUMzQyxPQUFPLEtBQUssbUJBQW1CLE1BQU0saUNBQWlDLENBQUM7QUFhdkUsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHO0lBQzVCLE9BQU8sRUFBRSxtQkFBbUIsQ0FBQyxPQUFPO0lBQ3BDLGFBQWEsRUFBRSxPQUFPLENBQUMsYUFBYTtJQUNwQyxNQUFNLEVBQUUsV0FBVyxDQUFDLE1BQU07SUFDMUIsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO0lBQzVCLFlBQVksRUFBRSxPQUFPLENBQUMsWUFBWTtDQUNuQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLElBQUksY0FBYyxDQUFXLFNBQVMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtJbmplY3Rpb25Ub2tlbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0RyaXZlcnN9IGZyb20gJ0Bpb25pYy9zdG9yYWdlJztcbmltcG9ydCAqIGFzIExvY2FsRm9yYWdlIGZyb20gJ2xvY2FsZm9yYWdlJztcbmltcG9ydCAqIGFzIENvcmRvdmFTUUxpdGVEcml2ZXIgZnJvbSAnbG9jYWxmb3JhZ2UtY29yZG92YXNxbGl0ZWRyaXZlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVN0b3JhZ2U8VCA9IGFueT4ge1xuICByZWFkb25seSBkcml2ZXI6IHN0cmluZztcbiAgcmVhZHkoKTogUHJvbWlzZTxUPlxuICBzZXQoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpOiBQcm9taXNlPHZvaWQ+O1xuICBnZXQoa2V5OiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gIHJlbW92ZShrZXk6IHN0cmluZyk6IFByb21pc2U8dm9pZD5cbiAga2V5cygpOiBQcm9taXNlPHN0cmluZ1tdPjtcbiAgY2xlYXIoKTogUHJvbWlzZTx2b2lkPjtcbiAgZm9yRWFjaChpdGVyYXRvckNhbGxiYWNrOiAodmFsdWU6IGFueSwga2V5OiBzdHJpbmcsIGl0ZXJhdGlvbk51bWJlcjogTnVtYmVyKSA9PiBhbnkpOiBQcm9taXNlPHZvaWQ+O1xufVxuXG5leHBvcnQgY29uc3QgU3RvcmFnZURyaXZlcnMgPSB7XG4gIFNRTExpdGU6IENvcmRvdmFTUUxpdGVEcml2ZXIuX2RyaXZlcixcbiAgU2VjdXJlU3RvcmFnZTogRHJpdmVycy5TZWN1cmVTdG9yYWdlLFxuICBXZWJTUUw6IExvY2FsRm9yYWdlLldFQlNRTCxcbiAgSW5kZXhlZERCOiBEcml2ZXJzLkluZGV4ZWREQixcbiAgTG9jYWxTdG9yYWdlOiBEcml2ZXJzLkxvY2FsU3RvcmFnZVxufTtcblxuZXhwb3J0IGNvbnN0IEFQUF9TVE9SQUdFID0gbmV3IEluamVjdGlvblRva2VuPElTdG9yYWdlPignU3RvcmFnZScpO1xuIl19