@ngx-pwa/local-storage 18.0.0 → 20.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/fesm2022/ngx-pwa-local-storage.mjs +89 -63
- package/fesm2022/ngx-pwa-local-storage.mjs.map +1 -1
- package/index.d.ts +656 -3
- package/package.json +3 -5
- package/schematics/ng-add/index.js +9 -9
- package/schematics/ng-add/index.js.map +1 -1
- package/schematics/ng-update/index.js +14 -24
- package/schematics/ng-update/index.js.map +1 -1
- package/schematics/utility/config.js +24 -34
- package/schematics/utility/config.js.map +1 -1
- package/schematics/utility/module.js +3 -3
- package/schematics/utility/module.js.map +1 -1
- package/esm2022/lib/databases/exceptions.mjs +0 -28
- package/esm2022/lib/databases/indexeddb-database.mjs +0 -308
- package/esm2022/lib/databases/local-database.mjs +0 -66
- package/esm2022/lib/databases/localstorage-database.mjs +0 -158
- package/esm2022/lib/databases/memory-database.mjs +0 -84
- package/esm2022/lib/providers.mjs +0 -66
- package/esm2022/lib/storage.module.mjs +0 -34
- package/esm2022/lib/storages/exceptions.mjs +0 -15
- package/esm2022/lib/storages/storage-map.service.mjs +0 -340
- package/esm2022/lib/tokens.mjs +0 -59
- package/esm2022/lib/validation/json-schema.mjs +0 -5
- package/esm2022/lib/validation/json-validator.mjs +0 -244
- package/esm2022/ngx-pwa-local-storage.mjs +0 -5
- package/esm2022/public-api.mjs +0 -9
- package/lib/databases/exceptions.d.ts +0 -20
- package/lib/databases/indexeddb-database.d.ts +0 -107
- package/lib/databases/local-database.d.ts +0 -18
- package/lib/databases/localstorage-database.d.ts +0 -64
- package/lib/databases/memory-database.d.ts +0 -50
- package/lib/providers.d.ts +0 -56
- package/lib/storage.module.d.ts +0 -19
- package/lib/storages/exceptions.d.ts +0 -10
- package/lib/storages/storage-map.service.d.ts +0 -254
- package/lib/tokens.d.ts +0 -75
- package/lib/validation/json-schema.d.ts +0 -260
- package/lib/validation/json-validator.d.ts +0 -71
- package/public-api.d.ts +0 -7
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { Injectable } from "@angular/core";
|
|
2
|
-
import { Observable, from, of } from "rxjs";
|
|
3
|
-
import { LocalDatabase } from "./local-database";
|
|
4
|
-
import * as i0 from "@angular/core";
|
|
5
|
-
export class MemoryDatabase {
|
|
6
|
-
constructor() {
|
|
7
|
-
/**
|
|
8
|
-
* Memory storage
|
|
9
|
-
*/
|
|
10
|
-
this.memoryStorage = new Map();
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Number of items in memory
|
|
14
|
-
*/
|
|
15
|
-
get size() {
|
|
16
|
-
/* Wrap in a RxJS `Observable` to be consistent with other storages */
|
|
17
|
-
return of(this.memoryStorage.size);
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Gets an item value in memory
|
|
21
|
-
* @param key The item's key
|
|
22
|
-
* @returns The item's value if the key exists, `undefined` otherwise, wrapped in a RxJS `Observable`
|
|
23
|
-
*/
|
|
24
|
-
get(key) {
|
|
25
|
-
/* Wrap in a RxJS `Observable` to be consistent with other storages */
|
|
26
|
-
return of(this.memoryStorage.get(key));
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Sets an item in memory
|
|
30
|
-
* @param key The item's key
|
|
31
|
-
* @param data The item's value
|
|
32
|
-
* @returns A RxJS `Observable` to wait the end of the operation
|
|
33
|
-
*/
|
|
34
|
-
set(key, data) {
|
|
35
|
-
this.memoryStorage.set(key, data);
|
|
36
|
-
/* Wrap in a RxJS `Observable` to be consistent with other storages */
|
|
37
|
-
return of(undefined);
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Deletes an item in memory
|
|
41
|
-
* @param key The item's key
|
|
42
|
-
* @returns A RxJS `Observable` to wait the end of the operation
|
|
43
|
-
*/
|
|
44
|
-
delete(key) {
|
|
45
|
-
this.memoryStorage.delete(key);
|
|
46
|
-
/* Wrap in a RxJS `Observable` to be consistent with other storages */
|
|
47
|
-
return of(undefined);
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Deletes all items in memory
|
|
51
|
-
* @returns A RxJS `Observable` to wait the end of the operation
|
|
52
|
-
*/
|
|
53
|
-
clear() {
|
|
54
|
-
this.memoryStorage.clear();
|
|
55
|
-
/* Wrap in a RxJS `Observable` to be consistent with other storages */
|
|
56
|
-
return of(undefined);
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Get all keys in memory
|
|
60
|
-
* @returns A RxJS `Observable` iterating on keys
|
|
61
|
-
*/
|
|
62
|
-
keys() {
|
|
63
|
-
/* Create an `Observable` from keys */
|
|
64
|
-
return from(this.memoryStorage.keys());
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Check if a key exists in memory
|
|
68
|
-
* @param key Key name
|
|
69
|
-
* @returns a RxJS `Observable` telling if the key exists or not
|
|
70
|
-
*/
|
|
71
|
-
has(key) {
|
|
72
|
-
/* Wrap in a RxJS `Observable` to be consistent with other storages */
|
|
73
|
-
return of(this.memoryStorage.has(key));
|
|
74
|
-
}
|
|
75
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: MemoryDatabase, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
76
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: MemoryDatabase, providedIn: "root" }); }
|
|
77
|
-
}
|
|
78
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: MemoryDatabase, decorators: [{
|
|
79
|
-
type: Injectable,
|
|
80
|
-
args: [{
|
|
81
|
-
providedIn: "root"
|
|
82
|
-
}]
|
|
83
|
-
}] });
|
|
84
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LWRhdGFiYXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGliL3NyYy9saWIvZGF0YWJhc2VzL21lbW9yeS1kYXRhYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM1QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7O0FBS2pELE1BQU0sT0FBTyxjQUFjO0lBSDNCO1FBS0U7O1dBRUc7UUFDYyxrQkFBYSxHQUFHLElBQUksR0FBRyxFQUFtQixDQUFDO0tBeUY3RDtJQXZGQzs7T0FFRztJQUNILElBQUksSUFBSTtRQUVOLHNFQUFzRTtRQUN0RSxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRXJDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsR0FBRyxDQUFDLEdBQVc7UUFFYixzRUFBc0U7UUFDdEUsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUV6QyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxHQUFHLENBQUMsR0FBVyxFQUFFLElBQWE7UUFFNUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRWxDLHNFQUFzRTtRQUN0RSxPQUFPLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUV2QixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxHQUFXO1FBRWhCLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRS9CLHNFQUFzRTtRQUN0RSxPQUFPLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUV2QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSztRQUVILElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFM0Isc0VBQXNFO1FBQ3RFLE9BQU8sRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBRXZCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFJO1FBRUYsc0NBQXNDO1FBQ3RDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUV6QyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEdBQUcsQ0FBQyxHQUFXO1FBRWIsc0VBQXNFO1FBQ3RFLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFekMsQ0FBQzs4R0E1RlUsY0FBYztrSEFBZCxjQUFjLGNBRmIsTUFBTTs7MkZBRVAsY0FBYztrQkFIMUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IE9ic2VydmFibGUsIGZyb20sIG9mIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IExvY2FsRGF0YWJhc2UgfSBmcm9tIFwiLi9sb2NhbC1kYXRhYmFzZVwiO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46IFwicm9vdFwiXG59KVxuZXhwb3J0IGNsYXNzIE1lbW9yeURhdGFiYXNlIGltcGxlbWVudHMgTG9jYWxEYXRhYmFzZSB7XG5cbiAgLyoqXG4gICAqIE1lbW9yeSBzdG9yYWdlXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IG1lbW9yeVN0b3JhZ2UgPSBuZXcgTWFwPHN0cmluZywgdW5rbm93bj4oKTtcblxuICAvKipcbiAgICogTnVtYmVyIG9mIGl0ZW1zIGluIG1lbW9yeVxuICAgKi9cbiAgZ2V0IHNpemUoKTogT2JzZXJ2YWJsZTxudW1iZXI+IHtcblxuICAgIC8qIFdyYXAgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYCB0byBiZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgc3RvcmFnZXMgKi9cbiAgICByZXR1cm4gb2YodGhpcy5tZW1vcnlTdG9yYWdlLnNpemUpO1xuXG4gIH1cblxuICAvKipcbiAgICogR2V0cyBhbiBpdGVtIHZhbHVlIGluIG1lbW9yeVxuICAgKiBAcGFyYW0ga2V5IFRoZSBpdGVtJ3Mga2V5XG4gICAqIEByZXR1cm5zIFRoZSBpdGVtJ3MgdmFsdWUgaWYgdGhlIGtleSBleGlzdHMsIGB1bmRlZmluZWRgIG90aGVyd2lzZSwgd3JhcHBlZCBpbiBhIFJ4SlMgYE9ic2VydmFibGVgXG4gICAqL1xuICBnZXQoa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPHVua25vd24+IHtcblxuICAgIC8qIFdyYXAgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYCB0byBiZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgc3RvcmFnZXMgKi9cbiAgICByZXR1cm4gb2YodGhpcy5tZW1vcnlTdG9yYWdlLmdldChrZXkpKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgYW4gaXRlbSBpbiBtZW1vcnlcbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcGFyYW0gZGF0YSBUaGUgaXRlbSdzIHZhbHVlXG4gICAqIEByZXR1cm5zIEEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICovXG4gIHNldChrZXk6IHN0cmluZywgZGF0YTogdW5rbm93bik6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICB0aGlzLm1lbW9yeVN0b3JhZ2Uuc2V0KGtleSwgZGF0YSk7XG5cbiAgICAvKiBXcmFwIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gYmUgY29uc2lzdGVudCB3aXRoIG90aGVyIHN0b3JhZ2VzICovXG4gICAgcmV0dXJuIG9mKHVuZGVmaW5lZCk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGFuIGl0ZW0gaW4gbWVtb3J5XG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgQSBSeEpTIGBPYnNlcnZhYmxlYCB0byB3YWl0IHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgZGVsZXRlKGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTx1bmRlZmluZWQ+IHtcblxuICAgIHRoaXMubWVtb3J5U3RvcmFnZS5kZWxldGUoa2V5KTtcblxuICAgIC8qIFdyYXAgaW4gYSBSeEpTIGBPYnNlcnZhYmxlYCB0byBiZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgc3RvcmFnZXMgKi9cbiAgICByZXR1cm4gb2YodW5kZWZpbmVkKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgYWxsIGl0ZW1zIGluIG1lbW9yeVxuICAgKiBAcmV0dXJucyBBIFJ4SlMgYE9ic2VydmFibGVgIHRvIHdhaXQgdGhlIGVuZCBvZiB0aGUgb3BlcmF0aW9uXG4gICAqL1xuICBjbGVhcigpOiBPYnNlcnZhYmxlPHVuZGVmaW5lZD4ge1xuXG4gICAgdGhpcy5tZW1vcnlTdG9yYWdlLmNsZWFyKCk7XG5cbiAgICAvKiBXcmFwIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gYmUgY29uc2lzdGVudCB3aXRoIG90aGVyIHN0b3JhZ2VzICovXG4gICAgcmV0dXJuIG9mKHVuZGVmaW5lZCk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIGtleXMgaW4gbWVtb3J5XG4gICAqIEByZXR1cm5zIEEgUnhKUyBgT2JzZXJ2YWJsZWAgaXRlcmF0aW5nIG9uIGtleXNcbiAgICovXG4gIGtleXMoKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcblxuICAgIC8qIENyZWF0ZSBhbiBgT2JzZXJ2YWJsZWAgZnJvbSBrZXlzICovXG4gICAgcmV0dXJuIGZyb20odGhpcy5tZW1vcnlTdG9yYWdlLmtleXMoKSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIGtleSBleGlzdHMgaW4gbWVtb3J5XG4gICAqIEBwYXJhbSBrZXkgS2V5IG5hbWVcbiAgICogQHJldHVybnMgYSBSeEpTIGBPYnNlcnZhYmxlYCB0ZWxsaW5nIGlmIHRoZSBrZXkgZXhpc3RzIG9yIG5vdFxuICAgKi9cbiAgaGFzKGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG5cbiAgICAvKiBXcmFwIGluIGEgUnhKUyBgT2JzZXJ2YWJsZWAgdG8gYmUgY29uc2lzdGVudCB3aXRoIG90aGVyIHN0b3JhZ2VzICovXG4gICAgcmV0dXJuIG9mKHRoaXMubWVtb3J5U3RvcmFnZS5oYXMoa2V5KSk7XG5cbiAgfVxuXG59XG4iXX0=
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { makeEnvironmentProviders } from "@angular/core";
|
|
2
|
-
import { IDB_DB_NAME, IDB_DB_VERSION, IDB_STORE_NAME, LS_PREFIX } from "./tokens";
|
|
3
|
-
/**
|
|
4
|
-
* Allows to add a prefix before `localStorage` keys.
|
|
5
|
-
*
|
|
6
|
-
* *Use only* for interoperability with other APIs or to avoid collision for multiple applications on the same subdomain.
|
|
7
|
-
*
|
|
8
|
-
* **WARNING: do not change this option in an application already deployed in production, as previously stored data would be lost.**
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* export const appConfig: ApplicationConfig = {
|
|
12
|
-
* providers: [provideLocalStoragePrefix('custom_')]
|
|
13
|
-
* };
|
|
14
|
-
*/
|
|
15
|
-
export function provideLocalStoragePrefix(prefix) {
|
|
16
|
-
return makeEnvironmentProviders([{ provide: LS_PREFIX, useValue: prefix }]);
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Allows to change the name used for `indexedDB` database.
|
|
20
|
-
*
|
|
21
|
-
* *Use only* for interoperability with other APIs or to avoid collision for multiple applications on the same subdomain.
|
|
22
|
-
*
|
|
23
|
-
* **WARNING: do not change this option in an application already deployed in production, as previously stored data would be lost.**
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* export const appConfig: ApplicationConfig = {
|
|
27
|
-
* providers: [provideIndexedDBDataBaseName('custom')]
|
|
28
|
-
* };
|
|
29
|
-
*/
|
|
30
|
-
export function provideIndexedDBDataBaseName(name) {
|
|
31
|
-
return makeEnvironmentProviders([{ provide: IDB_DB_NAME, useValue: name }]);
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Allows to change the database version used for `indexedDB` database.
|
|
35
|
-
* Must be an unsigned **integer**.
|
|
36
|
-
*
|
|
37
|
-
* **Use with caution as the creation of the store depends on the version.**
|
|
38
|
-
*
|
|
39
|
-
* *Use only* for interoperability with other APIs or to avoid collision for multiple applications on the same subdomain.
|
|
40
|
-
*
|
|
41
|
-
* **WARNING: do not change this option in an applicattion already deployed in production, as previously stored data would be lost.**
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* export const appConfig: ApplicationConfig = {
|
|
45
|
-
* providers: [provideIndexedDBDataBaseVersion(2)]
|
|
46
|
-
* };
|
|
47
|
-
*/
|
|
48
|
-
export function provideIndexedDBDataBaseVersion(version) {
|
|
49
|
-
return makeEnvironmentProviders([{ provide: IDB_DB_VERSION, useValue: version }]);
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Allows to change the name used for `indexedDB` object store.
|
|
53
|
-
*
|
|
54
|
-
* *Use only* for interoperability with other APIs.
|
|
55
|
-
*
|
|
56
|
-
* **WARNING: do not change this option in an application already deployed in production, as previously stored data would be lost.**
|
|
57
|
-
*
|
|
58
|
-
* @example
|
|
59
|
-
* export const appConfig: ApplicationConfig = {
|
|
60
|
-
* providers: [provideIndexedDBStoreName('custom')]
|
|
61
|
-
* };
|
|
62
|
-
*/
|
|
63
|
-
export function provideIndexedDBStoreName(name) {
|
|
64
|
-
return makeEnvironmentProviders([{ provide: IDB_STORE_NAME, useValue: name }]);
|
|
65
|
-
}
|
|
66
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vbGliL3NyYy9saWIvcHJvdmlkZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx3QkFBd0IsRUFBNkIsTUFBTSxlQUFlLENBQUM7QUFDcEYsT0FBTyxFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUUsY0FBYyxFQUFFLFNBQVMsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUVsRjs7Ozs7Ozs7Ozs7R0FXRztBQUNILE1BQU0sVUFBVSx5QkFBeUIsQ0FBQyxNQUFjO0lBRXRELE9BQU8sd0JBQXdCLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztBQUU5RSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLFVBQVUsNEJBQTRCLENBQUMsSUFBWTtJQUV2RCxPQUFPLHdCQUF3QixDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFFOUUsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsTUFBTSxVQUFVLCtCQUErQixDQUFDLE9BQWU7SUFFN0QsT0FBTyx3QkFBd0IsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBRXBGLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7R0FXRztBQUNILE1BQU0sVUFBVSx5QkFBeUIsQ0FBQyxJQUFZO0lBRXBELE9BQU8sd0JBQXdCLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztBQUVqRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbWFrZUVudmlyb25tZW50UHJvdmlkZXJzLCB0eXBlIEVudmlyb25tZW50UHJvdmlkZXJzIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IElEQl9EQl9OQU1FLCBJREJfREJfVkVSU0lPTiwgSURCX1NUT1JFX05BTUUsIExTX1BSRUZJWCB9IGZyb20gXCIuL3Rva2Vuc1wiO1xuXG4vKipcbiAqIEFsbG93cyB0byBhZGQgYSBwcmVmaXggYmVmb3JlIGBsb2NhbFN0b3JhZ2VgIGtleXMuXG4gKiBcbiAqICpVc2Ugb25seSogZm9yIGludGVyb3BlcmFiaWxpdHkgd2l0aCBvdGhlciBBUElzIG9yIHRvIGF2b2lkIGNvbGxpc2lvbiBmb3IgbXVsdGlwbGUgYXBwbGljYXRpb25zIG9uIHRoZSBzYW1lIHN1YmRvbWFpbi5cbiAqIFxuICogKipXQVJOSU5HOiBkbyBub3QgY2hhbmdlIHRoaXMgb3B0aW9uIGluIGFuIGFwcGxpY2F0aW9uIGFscmVhZHkgZGVwbG95ZWQgaW4gcHJvZHVjdGlvbiwgYXMgcHJldmlvdXNseSBzdG9yZWQgZGF0YSB3b3VsZCBiZSBsb3N0LioqXG4gKlxuICogQGV4YW1wbGVcbiAqIGV4cG9ydCBjb25zdCBhcHBDb25maWc6IEFwcGxpY2F0aW9uQ29uZmlnID0ge1xuICogICBwcm92aWRlcnM6IFtwcm92aWRlTG9jYWxTdG9yYWdlUHJlZml4KCdjdXN0b21fJyldXG4gKiB9O1xuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZUxvY2FsU3RvcmFnZVByZWZpeChwcmVmaXg6IHN0cmluZyk6IEVudmlyb25tZW50UHJvdmlkZXJzIHtcblxuICByZXR1cm4gbWFrZUVudmlyb25tZW50UHJvdmlkZXJzKFt7IHByb3ZpZGU6IExTX1BSRUZJWCwgdXNlVmFsdWU6IHByZWZpeCB9XSk7XG5cbn1cblxuLyoqXG4gKiBBbGxvd3MgdG8gY2hhbmdlIHRoZSBuYW1lIHVzZWQgZm9yIGBpbmRleGVkREJgIGRhdGFiYXNlLlxuICogXG4gKiAqVXNlIG9ubHkqIGZvciBpbnRlcm9wZXJhYmlsaXR5IHdpdGggb3RoZXIgQVBJcyBvciB0byBhdm9pZCBjb2xsaXNpb24gZm9yIG11bHRpcGxlIGFwcGxpY2F0aW9ucyBvbiB0aGUgc2FtZSBzdWJkb21haW4uXG4gKiBcbiAqICoqV0FSTklORzogZG8gbm90IGNoYW5nZSB0aGlzIG9wdGlvbiBpbiBhbiBhcHBsaWNhdGlvbiBhbHJlYWR5IGRlcGxveWVkIGluIHByb2R1Y3Rpb24sIGFzIHByZXZpb3VzbHkgc3RvcmVkIGRhdGEgd291bGQgYmUgbG9zdC4qKlxuICpcbiAqIEBleGFtcGxlXG4gKiBleHBvcnQgY29uc3QgYXBwQ29uZmlnOiBBcHBsaWNhdGlvbkNvbmZpZyA9IHtcbiAqICAgcHJvdmlkZXJzOiBbcHJvdmlkZUluZGV4ZWREQkRhdGFCYXNlTmFtZSgnY3VzdG9tJyldXG4gKiB9O1xuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZUluZGV4ZWREQkRhdGFCYXNlTmFtZShuYW1lOiBzdHJpbmcpOiBFbnZpcm9ubWVudFByb3ZpZGVycyB7XG5cbiAgcmV0dXJuIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyhbeyBwcm92aWRlOiBJREJfREJfTkFNRSwgdXNlVmFsdWU6IG5hbWUgfV0pO1xuXG59XG5cbi8qKlxuICogQWxsb3dzIHRvIGNoYW5nZSB0aGUgZGF0YWJhc2UgdmVyc2lvbiB1c2VkIGZvciBgaW5kZXhlZERCYCBkYXRhYmFzZS5cbiAqIE11c3QgYmUgYW4gdW5zaWduZWQgKippbnRlZ2VyKiouXG4gKiBcbiAqICoqVXNlIHdpdGggY2F1dGlvbiBhcyB0aGUgY3JlYXRpb24gb2YgdGhlIHN0b3JlIGRlcGVuZHMgb24gdGhlIHZlcnNpb24uKipcbiAqIFxuICogKlVzZSBvbmx5KiBmb3IgaW50ZXJvcGVyYWJpbGl0eSB3aXRoIG90aGVyIEFQSXMgb3IgdG8gYXZvaWQgY29sbGlzaW9uIGZvciBtdWx0aXBsZSBhcHBsaWNhdGlvbnMgb24gdGhlIHNhbWUgc3ViZG9tYWluLlxuICogXG4gKiAqKldBUk5JTkc6IGRvIG5vdCBjaGFuZ2UgdGhpcyBvcHRpb24gaW4gYW4gYXBwbGljYXR0aW9uIGFscmVhZHkgZGVwbG95ZWQgaW4gcHJvZHVjdGlvbiwgYXMgcHJldmlvdXNseSBzdG9yZWQgZGF0YSB3b3VsZCBiZSBsb3N0LioqXG4gKlxuICogQGV4YW1wbGVcbiAqIGV4cG9ydCBjb25zdCBhcHBDb25maWc6IEFwcGxpY2F0aW9uQ29uZmlnID0ge1xuICogICBwcm92aWRlcnM6IFtwcm92aWRlSW5kZXhlZERCRGF0YUJhc2VWZXJzaW9uKDIpXVxuICogfTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByb3ZpZGVJbmRleGVkREJEYXRhQmFzZVZlcnNpb24odmVyc2lvbjogbnVtYmVyKTogRW52aXJvbm1lbnRQcm92aWRlcnMge1xuXG4gIHJldHVybiBtYWtlRW52aXJvbm1lbnRQcm92aWRlcnMoW3sgcHJvdmlkZTogSURCX0RCX1ZFUlNJT04sIHVzZVZhbHVlOiB2ZXJzaW9uIH1dKTtcblxufVxuXG4vKipcbiAqIEFsbG93cyB0byBjaGFuZ2UgdGhlIG5hbWUgdXNlZCBmb3IgYGluZGV4ZWREQmAgb2JqZWN0IHN0b3JlLlxuICogXG4gKiAqVXNlIG9ubHkqIGZvciBpbnRlcm9wZXJhYmlsaXR5IHdpdGggb3RoZXIgQVBJcy5cbiAqIFxuICogKipXQVJOSU5HOiBkbyBub3QgY2hhbmdlIHRoaXMgb3B0aW9uIGluIGFuIGFwcGxpY2F0aW9uIGFscmVhZHkgZGVwbG95ZWQgaW4gcHJvZHVjdGlvbiwgYXMgcHJldmlvdXNseSBzdG9yZWQgZGF0YSB3b3VsZCBiZSBsb3N0LioqXG4gKlxuICogQGV4YW1wbGVcbiAqIGV4cG9ydCBjb25zdCBhcHBDb25maWc6IEFwcGxpY2F0aW9uQ29uZmlnID0ge1xuICogICBwcm92aWRlcnM6IFtwcm92aWRlSW5kZXhlZERCU3RvcmVOYW1lKCdjdXN0b20nKV1cbiAqIH07XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm92aWRlSW5kZXhlZERCU3RvcmVOYW1lKG5hbWU6IHN0cmluZyk6IEVudmlyb25tZW50UHJvdmlkZXJzIHtcblxuICByZXR1cm4gbWFrZUVudmlyb25tZW50UHJvdmlkZXJzKFt7IHByb3ZpZGU6IElEQl9TVE9SRV9OQU1FLCB1c2VWYWx1ZTogbmFtZSB9XSk7XG5cbn1cbiJdfQ==
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { NgModule } from "@angular/core";
|
|
2
|
-
import { IDB_DB_NAME, IDB_DB_VERSION, IDB_NO_WRAP, IDB_STORE_NAME, LS_PREFIX } from "./tokens";
|
|
3
|
-
import * as i0 from "@angular/core";
|
|
4
|
-
/**
|
|
5
|
-
* This module is only here for backward compatibility, **do not add it by yourself**
|
|
6
|
-
*
|
|
7
|
-
* @ignore
|
|
8
|
-
*/
|
|
9
|
-
export class StorageModule {
|
|
10
|
-
/**
|
|
11
|
-
* Only useful to provide options, otherwise it does nothing.
|
|
12
|
-
*
|
|
13
|
-
* **Must be used at initialization, ie. in `AppModule`, and must not be loaded again in another module.**
|
|
14
|
-
*/
|
|
15
|
-
static forRoot(config) {
|
|
16
|
-
return {
|
|
17
|
-
ngModule: StorageModule,
|
|
18
|
-
providers: [
|
|
19
|
-
config.LSPrefix ? { provide: LS_PREFIX, useValue: config.LSPrefix } : [],
|
|
20
|
-
config.IDBDBName ? { provide: IDB_DB_NAME, useValue: config.IDBDBName } : [],
|
|
21
|
-
config.IDBStoreName ? { provide: IDB_STORE_NAME, useValue: config.IDBStoreName } : [],
|
|
22
|
-
config.IDBDBVersion ? { provide: IDB_DB_VERSION, useValue: config.IDBDBVersion } : [],
|
|
23
|
-
(config.IDBNoWrap === false) ? { provide: IDB_NO_WRAP, useValue: config.IDBNoWrap } : [],
|
|
24
|
-
],
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: StorageModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
28
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.0.0", ngImport: i0, type: StorageModule }); }
|
|
29
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: StorageModule }); }
|
|
30
|
-
}
|
|
31
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: StorageModule, decorators: [{
|
|
32
|
-
type: NgModule
|
|
33
|
-
}] });
|
|
34
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS5tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWIvc3JjL2xpYi9zdG9yYWdlLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUE0QixNQUFNLGVBQWUsQ0FBQztBQUNuRSxPQUFPLEVBQUUsV0FBVyxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLFNBQVMsRUFBc0IsTUFBTSxVQUFVLENBQUM7O0FBRW5IOzs7O0dBSUc7QUFFSCxNQUFNLE9BQU8sYUFBYTtJQUV4Qjs7OztPQUlHO0lBQ0gsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFxQjtRQUNsQyxPQUFPO1lBQ0wsUUFBUSxFQUFFLGFBQWE7WUFDdkIsU0FBUyxFQUFFO2dCQUNULE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUN4RSxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDNUUsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3JGLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNyRixDQUFDLE1BQU0sQ0FBQyxTQUFTLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFO2FBQ3pGO1NBQ0YsQ0FBQztJQUNKLENBQUM7OEdBbEJVLGFBQWE7K0dBQWIsYUFBYTsrR0FBYixhQUFhOzsyRkFBYixhQUFhO2tCQUR6QixRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdNb2R1bGUsIHR5cGUgTW9kdWxlV2l0aFByb3ZpZGVycyB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBJREJfREJfTkFNRSwgSURCX0RCX1ZFUlNJT04sIElEQl9OT19XUkFQLCBJREJfU1RPUkVfTkFNRSwgTFNfUFJFRklYLCB0eXBlIFN0b3JhZ2VDb25maWcgfSBmcm9tIFwiLi90b2tlbnNcIjtcblxuLyoqXG4gKiBUaGlzIG1vZHVsZSBpcyBvbmx5IGhlcmUgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksICoqZG8gbm90IGFkZCBpdCBieSB5b3Vyc2VsZioqXG4gKiBcbiAqIEBpZ25vcmVcbiAqL1xuQE5nTW9kdWxlKClcbmV4cG9ydCBjbGFzcyBTdG9yYWdlTW9kdWxlIHtcblxuICAvKipcbiAgICogT25seSB1c2VmdWwgdG8gcHJvdmlkZSBvcHRpb25zLCBvdGhlcndpc2UgaXQgZG9lcyBub3RoaW5nLlxuICAgKiBcbiAgICogKipNdXN0IGJlIHVzZWQgYXQgaW5pdGlhbGl6YXRpb24sIGllLiBpbiBgQXBwTW9kdWxlYCwgYW5kIG11c3Qgbm90IGJlIGxvYWRlZCBhZ2FpbiBpbiBhbm90aGVyIG1vZHVsZS4qKlxuICAgKi9cbiAgc3RhdGljIGZvclJvb3QoY29uZmlnOiBTdG9yYWdlQ29uZmlnKTogTW9kdWxlV2l0aFByb3ZpZGVyczxTdG9yYWdlTW9kdWxlPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5nTW9kdWxlOiBTdG9yYWdlTW9kdWxlLFxuICAgICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIGNvbmZpZy5MU1ByZWZpeCA/IHsgcHJvdmlkZTogTFNfUFJFRklYLCB1c2VWYWx1ZTogY29uZmlnLkxTUHJlZml4IH0gOiBbXSxcbiAgICAgICAgY29uZmlnLklEQkRCTmFtZSA/IHsgcHJvdmlkZTogSURCX0RCX05BTUUsIHVzZVZhbHVlOiBjb25maWcuSURCREJOYW1lIH0gOiBbXSxcbiAgICAgICAgY29uZmlnLklEQlN0b3JlTmFtZSA/IHsgcHJvdmlkZTogSURCX1NUT1JFX05BTUUsIHVzZVZhbHVlOiBjb25maWcuSURCU3RvcmVOYW1lIH0gOiBbXSxcbiAgICAgICAgY29uZmlnLklEQkRCVmVyc2lvbiA/IHsgcHJvdmlkZTogSURCX0RCX1ZFUlNJT04sIHVzZVZhbHVlOiBjb25maWcuSURCREJWZXJzaW9uIH0gOiBbXSxcbiAgICAgICAgKGNvbmZpZy5JREJOb1dyYXAgPT09IGZhbHNlKSA/IHsgcHJvdmlkZTogSURCX05PX1dSQVAsIHVzZVZhbHVlOiBjb25maWcuSURCTm9XcmFwIH0gOiBbXSxcbiAgICAgIF0sXG4gICAgfTtcbiAgfVxuXG59XG4iXX0=
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Exception message when a value is not valid against the JSON schema
|
|
3
|
-
*/
|
|
4
|
-
export const VALIDATION_ERROR = `Data stored is not valid against the provided JSON schema.
|
|
5
|
-
Check your JSON schema, otherwise it means data has been corrupted.`;
|
|
6
|
-
/**
|
|
7
|
-
* Exception throwned when a value is not valid against the JSON schema
|
|
8
|
-
*/
|
|
9
|
-
export class ValidationError extends Error {
|
|
10
|
-
constructor() {
|
|
11
|
-
super(...arguments);
|
|
12
|
-
this.message = VALIDATION_ERROR;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhjZXB0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYi9zcmMvbGliL3N0b3JhZ2VzL2V4Y2VwdGlvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRztvRUFDb0MsQ0FBQztBQUVyRTs7R0FFRztBQUNILE1BQU0sT0FBTyxlQUFnQixTQUFRLEtBQUs7SUFBMUM7O1FBQ1csWUFBTyxHQUFHLGdCQUFnQixDQUFDO0lBQ3RDLENBQUM7Q0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRXhjZXB0aW9uIG1lc3NhZ2Ugd2hlbiBhIHZhbHVlIGlzIG5vdCB2YWxpZCBhZ2FpbnN0IHRoZSBKU09OIHNjaGVtYVxuICovXG5leHBvcnQgY29uc3QgVkFMSURBVElPTl9FUlJPUiA9IGBEYXRhIHN0b3JlZCBpcyBub3QgdmFsaWQgYWdhaW5zdCB0aGUgcHJvdmlkZWQgSlNPTiBzY2hlbWEuXG5DaGVjayB5b3VyIEpTT04gc2NoZW1hLCBvdGhlcndpc2UgaXQgbWVhbnMgZGF0YSBoYXMgYmVlbiBjb3JydXB0ZWQuYDtcblxuLyoqXG4gKiBFeGNlcHRpb24gdGhyb3duZWQgd2hlbiBhIHZhbHVlIGlzIG5vdCB2YWxpZCBhZ2FpbnN0IHRoZSBKU09OIHNjaGVtYVxuICovXG5leHBvcnQgY2xhc3MgVmFsaWRhdGlvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBvdmVycmlkZSBtZXNzYWdlID0gVkFMSURBVElPTl9FUlJPUjtcbn1cbiJdfQ==
|
|
@@ -1,340 +0,0 @@
|
|
|
1
|
-
import { Injectable } from "@angular/core";
|
|
2
|
-
import { Observable, ReplaySubject, of, throwError } from "rxjs";
|
|
3
|
-
import { catchError, mergeMap, tap } from "rxjs/operators";
|
|
4
|
-
import { IDB_BROKEN_ERROR } from "../databases/exceptions";
|
|
5
|
-
import { IndexedDBDatabase } from "../databases/indexeddb-database";
|
|
6
|
-
import { LocalDatabase } from "../databases/local-database";
|
|
7
|
-
import { LocalStorageDatabase } from "../databases/localstorage-database";
|
|
8
|
-
import { MemoryDatabase } from "../databases/memory-database";
|
|
9
|
-
import { JSONValidator } from "../validation/json-validator";
|
|
10
|
-
import { ValidationError } from "./exceptions";
|
|
11
|
-
import * as i0 from "@angular/core";
|
|
12
|
-
import * as i1 from "../databases/local-database";
|
|
13
|
-
export class StorageMap {
|
|
14
|
-
#database;
|
|
15
|
-
#jsonValidator;
|
|
16
|
-
#notifiers = new Map();
|
|
17
|
-
/**
|
|
18
|
-
* Constructor params are provided by Angular (but can also be passed manually in tests)
|
|
19
|
-
* @param database Storage to use
|
|
20
|
-
*/
|
|
21
|
-
constructor(database) {
|
|
22
|
-
this.#database = database;
|
|
23
|
-
this.#jsonValidator = new JSONValidator();
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* **Number of items** in storage, wrapped in an Observable.
|
|
27
|
-
*
|
|
28
|
-
* Note you do *not* need to unsubscribe (it is a self-completing Observable).
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* this.storageMap.size.subscribe((size) => {
|
|
32
|
-
* console.log(size);
|
|
33
|
-
* });
|
|
34
|
-
*/
|
|
35
|
-
get size() {
|
|
36
|
-
return this.#database.size
|
|
37
|
-
/* Catch if `indexedDb` is broken */
|
|
38
|
-
.pipe(this.#catchIDBBroken(() => this.#database.size));
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Tells you which storage engine is used.
|
|
42
|
-
*
|
|
43
|
-
* *Only useful for interoperability.*
|
|
44
|
-
*
|
|
45
|
-
* Note that due to some browsers issues in some special contexts
|
|
46
|
-
* (like Safari cross-origin iframes),
|
|
47
|
-
* **this information may be wrong at initialization,**
|
|
48
|
-
* as the storage could fallback from `indexedDB` to `localStorage`
|
|
49
|
-
* only after a first read or write operation.
|
|
50
|
-
* @returns Storage engine used
|
|
51
|
-
*
|
|
52
|
-
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/main/docs/INTEROPERABILITY.md}
|
|
53
|
-
*
|
|
54
|
-
* @example
|
|
55
|
-
* if (this.storageMap.backingEngine === 'indexedDB') {}
|
|
56
|
-
*/
|
|
57
|
-
get backingEngine() {
|
|
58
|
-
if (this.#database instanceof IndexedDBDatabase) {
|
|
59
|
-
return "indexedDB";
|
|
60
|
-
}
|
|
61
|
-
else if (this.#database instanceof LocalStorageDatabase) {
|
|
62
|
-
return "localStorage";
|
|
63
|
-
}
|
|
64
|
-
else if (this.#database instanceof MemoryDatabase) {
|
|
65
|
-
return "memory";
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
return "unknown";
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Information about `indexedDB` database.
|
|
73
|
-
*
|
|
74
|
-
* *Only useful for interoperability.*
|
|
75
|
-
*
|
|
76
|
-
* @returns `indexedDB` database name, store name and database version.
|
|
77
|
-
* **Values will be empty if the storage is not `indexedDB`, so it should be used after an engine check**.
|
|
78
|
-
*
|
|
79
|
-
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/main/docs/INTEROPERABILITY.md}
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* if (this.storageMap.backingEngine === 'indexedDB') {
|
|
83
|
-
* const { database, store, version } = this.storageMap.backingStore;
|
|
84
|
-
* }
|
|
85
|
-
*/
|
|
86
|
-
get backingStore() {
|
|
87
|
-
return (this.#database instanceof IndexedDBDatabase) ?
|
|
88
|
-
this.#database.backingStore :
|
|
89
|
-
{ database: "", store: "", version: 0 };
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Information about `localStorage` fallback storage.
|
|
93
|
-
*
|
|
94
|
-
* *Only useful for interoperability.*
|
|
95
|
-
*
|
|
96
|
-
* @returns `localStorage` prefix.
|
|
97
|
-
* **Values will be empty if the storage is not `localStorage`, so it should be used after an engine check**.
|
|
98
|
-
*
|
|
99
|
-
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/main/docs/INTEROPERABILITY.md}
|
|
100
|
-
*
|
|
101
|
-
* @example
|
|
102
|
-
* if (this.storageMap.backingEngine === 'localStorage') {
|
|
103
|
-
* const { prefix } = this.storageMap.fallbackBackingStore;
|
|
104
|
-
* }
|
|
105
|
-
*/
|
|
106
|
-
get fallbackBackingStore() {
|
|
107
|
-
return (this.#database instanceof LocalStorageDatabase) ?
|
|
108
|
-
{ prefix: this.#database.prefix } :
|
|
109
|
-
{ prefix: "" };
|
|
110
|
-
}
|
|
111
|
-
get(key, schema) {
|
|
112
|
-
/* Get the data in storage */
|
|
113
|
-
return this.#database.get(key).pipe(
|
|
114
|
-
/* Check if `indexedDb` is broken */
|
|
115
|
-
this.#catchIDBBroken(() => this.#database.get(key)), mergeMap((data) => {
|
|
116
|
-
/* No need to validate if the data is empty */
|
|
117
|
-
if ((data === undefined) || (data === null)) {
|
|
118
|
-
return of(undefined);
|
|
119
|
-
}
|
|
120
|
-
else if (schema) {
|
|
121
|
-
/* Validate data against a JSON schema if provided */
|
|
122
|
-
if (!this.#jsonValidator.validate(data, schema)) {
|
|
123
|
-
return throwError(() => new ValidationError());
|
|
124
|
-
}
|
|
125
|
-
/* Data have been checked, so it's OK to cast */
|
|
126
|
-
return of(data);
|
|
127
|
-
}
|
|
128
|
-
/* Cast to unknown as the data wasn't checked */
|
|
129
|
-
return of(data);
|
|
130
|
-
}));
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Store an item in storage.
|
|
134
|
-
*
|
|
135
|
-
* Note that:
|
|
136
|
-
* * you *do* need to subscribe, even if you do not have something specific to do after writing in storage, otherwise nothing happens (because it is how RxJS Observables work),
|
|
137
|
-
* * but you do *not* need to unsubscribe (it is a self-completing Observable),
|
|
138
|
-
* * setting `null` or `undefined` will remove the item to avoid some browsers issues,
|
|
139
|
-
* * you should stick to serializable JSON data, meaning primitive types, arrays and literal objects. Date, Map, Set, Blob and other special structures can cause issues in some scenarios.
|
|
140
|
-
* @see {@link https://github.com/cyrilletuzi/angular-async-local-storage/blob/main/docs/SERIALIZATION.md}
|
|
141
|
-
*
|
|
142
|
-
* @param key The item's key
|
|
143
|
-
* @param data The item's value
|
|
144
|
-
* @param schema Optional JSON schema to validate the data
|
|
145
|
-
* @returns A RxJS Observable to wait the end of the operation
|
|
146
|
-
*
|
|
147
|
-
* @example
|
|
148
|
-
* this.storageMap.set('key', 'value').subscribe(() => {});
|
|
149
|
-
*/
|
|
150
|
-
set(key, data, schema) {
|
|
151
|
-
/* Storing `undefined` or `null` is useless and can cause issues in `indexedDb` in some browsers,
|
|
152
|
-
* so removing item instead for all storages to have a consistent API */
|
|
153
|
-
if ((data === undefined) || (data === null)) {
|
|
154
|
-
return this.delete(key);
|
|
155
|
-
}
|
|
156
|
-
/* Validate data against a JSON schema if provided */
|
|
157
|
-
if (schema && !this.#jsonValidator.validate(data, schema)) {
|
|
158
|
-
return throwError(() => new ValidationError());
|
|
159
|
-
}
|
|
160
|
-
return this.#database.set(key, data).pipe(
|
|
161
|
-
/* Catch if `indexedDb` is broken */
|
|
162
|
-
this.#catchIDBBroken(() => this.#database.set(key, data)),
|
|
163
|
-
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
|
|
164
|
-
tap(() => { this.#notify(key, data); }));
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Delete an item in storage.
|
|
168
|
-
*
|
|
169
|
-
* Note that:
|
|
170
|
-
* * you *do* need to subscribe, even if you do not have something specific to do after deleting, otherwise nothing happens (because it is how RxJS Observables work),
|
|
171
|
-
* * but you do *not* need to unsubscribe (it is a self-completing Observable).
|
|
172
|
-
*
|
|
173
|
-
* @param key The item's key
|
|
174
|
-
* @returns A RxJS Observable to wait the end of the operation
|
|
175
|
-
*
|
|
176
|
-
* @example
|
|
177
|
-
* this.storageMap.delete('key').subscribe(() => {});
|
|
178
|
-
*/
|
|
179
|
-
delete(key) {
|
|
180
|
-
return this.#database.delete(key).pipe(
|
|
181
|
-
/* Catch if `indexedDb` is broken */
|
|
182
|
-
this.#catchIDBBroken(() => this.#database.delete(key)),
|
|
183
|
-
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
|
|
184
|
-
tap(() => { this.#notify(key, undefined); }));
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Delete all items in storage.
|
|
188
|
-
*
|
|
189
|
-
* Note that:
|
|
190
|
-
* * you *do* need to subscribe, even if you do not have something specific to do after clearing, otherwise nothing happens (because it is how RxJS Observables work),
|
|
191
|
-
* * but you do *not* need to unsubscribe (it is a self-completing Observable).
|
|
192
|
-
*
|
|
193
|
-
* @returns A RxJS Observable to wait the end of the operation
|
|
194
|
-
*
|
|
195
|
-
* @example
|
|
196
|
-
* this.storageMap.clear().subscribe(() => {});
|
|
197
|
-
*/
|
|
198
|
-
clear() {
|
|
199
|
-
return this.#database.clear().pipe(
|
|
200
|
-
/* Catch if `indexedDb` is broken */
|
|
201
|
-
this.#catchIDBBroken(() => this.#database.clear()),
|
|
202
|
-
/* Notify watchers (must be last because it should only happen if the operation succeeds) */
|
|
203
|
-
tap(() => {
|
|
204
|
-
for (const key of this.#notifiers.keys()) {
|
|
205
|
-
this.#notify(key, undefined);
|
|
206
|
-
}
|
|
207
|
-
}));
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Get all keys stored in storage.
|
|
211
|
-
*
|
|
212
|
-
* Note **this is an *iterating* Observable**:
|
|
213
|
-
* * if there is no key, the `next` callback will not be invoked,
|
|
214
|
-
* * if you need to wait the whole operation to end, be sure to act in the `complete` callback,
|
|
215
|
-
* as this Observable can emit several values and so will invoke the `next` callback several times,
|
|
216
|
-
* * you do *not* need to unsubscribe (it is a self-completing Observable).
|
|
217
|
-
*
|
|
218
|
-
* @returns A list of the keys wrapped in a RxJS Observable
|
|
219
|
-
*
|
|
220
|
-
* @example
|
|
221
|
-
* this.storageMap.keys().subscribe({
|
|
222
|
-
* next: (key) => { console.log(key); },
|
|
223
|
-
* complete: () => { console.log('Done'); },
|
|
224
|
-
* });
|
|
225
|
-
*/
|
|
226
|
-
keys() {
|
|
227
|
-
return this.#database.keys()
|
|
228
|
-
/* Catch if `indexedDb` is broken */
|
|
229
|
-
.pipe(this.#catchIDBBroken(() => this.#database.keys()));
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Tells if a key exists in storage.
|
|
233
|
-
*
|
|
234
|
-
* Note you do *not* need to unsubscribe (it is a self-completing Observable).
|
|
235
|
-
*
|
|
236
|
-
* @returns A RxJS Observable telling if the key exists
|
|
237
|
-
*
|
|
238
|
-
* @example
|
|
239
|
-
* this.storageMap.has('key').subscribe((hasKey) => {
|
|
240
|
-
* if (hasKey) {}
|
|
241
|
-
* });
|
|
242
|
-
*/
|
|
243
|
-
has(key) {
|
|
244
|
-
return this.#database.has(key)
|
|
245
|
-
/* Catch if `indexedDb` is broken */
|
|
246
|
-
.pipe(this.#catchIDBBroken(() => this.#database.has(key)));
|
|
247
|
-
}
|
|
248
|
-
watch(key, schema) {
|
|
249
|
-
/* Check if there is already a notifier */
|
|
250
|
-
if (!this.#notifiers.has(key)) {
|
|
251
|
-
this.#notifiers.set(key, new ReplaySubject(1));
|
|
252
|
-
}
|
|
253
|
-
/* Non-null assertion is required because TypeScript doesn't narrow `.has()` yet */
|
|
254
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Ensured by the logic
|
|
255
|
-
const notifier = this.#notifiers.get(key);
|
|
256
|
-
/* Get the current item value */
|
|
257
|
-
(schema ? this.get(key, schema) : this.get(key)).subscribe({
|
|
258
|
-
next: (result) => {
|
|
259
|
-
notifier.next(result);
|
|
260
|
-
},
|
|
261
|
-
error: (error) => {
|
|
262
|
-
notifier.error(error);
|
|
263
|
-
},
|
|
264
|
-
});
|
|
265
|
-
/* Only the public API of the Observable should be returned */
|
|
266
|
-
return (schema ?
|
|
267
|
-
notifier.asObservable() :
|
|
268
|
-
notifier.asObservable());
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Notify when a value changes
|
|
272
|
-
* @param key The item's key
|
|
273
|
-
* @param data The new value
|
|
274
|
-
*/
|
|
275
|
-
#notify(key, value) {
|
|
276
|
-
const notifier = this.#notifiers.get(key);
|
|
277
|
-
if (notifier) {
|
|
278
|
-
notifier.next(value);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* RxJS operator to catch if `indexedDB` is broken
|
|
283
|
-
* @param operationCallback Callback with the operation to redo
|
|
284
|
-
*/
|
|
285
|
-
#catchIDBBroken(operationCallback) {
|
|
286
|
-
return catchError((error) => {
|
|
287
|
-
/* Check if `indexedDB` is broken based on error message (the specific error class seems to be lost in the process) */
|
|
288
|
-
if ((error !== undefined) && (error !== null)
|
|
289
|
-
&& (typeof error === "object") && ("message" in error)
|
|
290
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- Required because TypeScript narrowing is not working here
|
|
291
|
-
&& (error.message === IDB_BROKEN_ERROR)) {
|
|
292
|
-
/* When storage is fully disabled in browser (via the "Block all cookies" option),
|
|
293
|
-
* just trying to check `localStorage` variable causes a security exception.
|
|
294
|
-
* Prevents https://github.com/cyrilletuzi/angular-async-local-storage/issues/118
|
|
295
|
-
*/
|
|
296
|
-
try {
|
|
297
|
-
if ("getItem" in localStorage) {
|
|
298
|
-
/* Fallback to `localStorage` if available */
|
|
299
|
-
this.#database = new LocalStorageDatabase();
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
/* Fallback to memory storage otherwise */
|
|
303
|
-
this.#database = new MemoryDatabase();
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
catch {
|
|
307
|
-
/* Fallback to memory storage otherwise */
|
|
308
|
-
this.#database = new MemoryDatabase();
|
|
309
|
-
}
|
|
310
|
-
/* Redo the operation */
|
|
311
|
-
return operationCallback();
|
|
312
|
-
}
|
|
313
|
-
else {
|
|
314
|
-
/* Otherwise, rethrow the error */
|
|
315
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
316
|
-
return throwError(() => error);
|
|
317
|
-
}
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* THIS METHOD IS FOR INTERNAL PURPOSE ONLY AND MUST NOT BE USED,
|
|
322
|
-
* IT CAN BE REMOVED AT ANY TIME AND MESSING WITH IT CAN CAUSE ISSUES
|
|
323
|
-
* @private
|
|
324
|
-
* @ignore
|
|
325
|
-
*/
|
|
326
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment, @typescript-eslint/prefer-ts-expect-error -- Silence the not used error, it is used in tests
|
|
327
|
-
// @ts-ignore
|
|
328
|
-
ɵinternalGetDatabase() {
|
|
329
|
-
return this.#database;
|
|
330
|
-
}
|
|
331
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: StorageMap, deps: [{ token: i1.LocalDatabase }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
332
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: StorageMap, providedIn: "root" }); }
|
|
333
|
-
}
|
|
334
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: StorageMap, decorators: [{
|
|
335
|
-
type: Injectable,
|
|
336
|
-
args: [{
|
|
337
|
-
providedIn: "root"
|
|
338
|
-
}]
|
|
339
|
-
}], ctorParameters: () => [{ type: i1.LocalDatabase }] });
|
|
340
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS1tYXAuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYi9zcmMvbGliL3N0b3JhZ2VzL3N0b3JhZ2UtbWFwLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUF5QixNQUFNLE1BQU0sQ0FBQztBQUN4RixPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDNUQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDMUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBTzlELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sY0FBYyxDQUFDOzs7QUFLL0MsTUFBTSxPQUFPLFVBQVU7SUFFckIsU0FBUyxDQUFnQjtJQUNoQixjQUFjLENBQWdCO0lBQzlCLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBa0MsQ0FBQztJQUVoRTs7O09BR0c7SUFDSCxZQUNFLFFBQXVCO1FBRXZCLElBQUksQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDO1FBQzFCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxhQUFhLEVBQUUsQ0FBQztJQUM1QyxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0gsSUFBSSxJQUFJO1FBRU4sT0FBTyxJQUFJ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Y29yZVwiO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgUmVwbGF5U3ViamVjdCwgb2YsIHRocm93RXJyb3IsIHR5cGUgT3BlcmF0b3JGdW5jdGlvbiB9IGZyb20gXCJyeGpzXCI7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBtZXJnZU1hcCwgdGFwIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5pbXBvcnQgeyBJREJfQlJPS0VOX0VSUk9SIH0gZnJvbSBcIi4uL2RhdGFiYXNlcy9leGNlcHRpb25zXCI7XG5pbXBvcnQgeyBJbmRleGVkREJEYXRhYmFzZSB9IGZyb20gXCIuLi9kYXRhYmFzZXMvaW5kZXhlZGRiLWRhdGFiYXNlXCI7XG5pbXBvcnQgeyBMb2NhbERhdGFiYXNlIH0gZnJvbSBcIi4uL2RhdGFiYXNlcy9sb2NhbC1kYXRhYmFzZVwiO1xuaW1wb3J0IHsgTG9jYWxTdG9yYWdlRGF0YWJhc2UgfSBmcm9tIFwiLi4vZGF0YWJhc2VzL2xvY2Fsc3RvcmFnZS1kYXRhYmFzZVwiO1xuaW1wb3J0IHsgTWVtb3J5RGF0YWJhc2UgfSBmcm9tIFwiLi4vZGF0YWJhc2VzL21lbW9yeS1kYXRhYmFzZVwiO1xuaW1wb3J0IHR5cGUge1xuICBKU09OU2NoZW1hLFxuICBKU09OU2NoZW1hQXJyYXlPZixcbiAgSlNPTlNjaGVtYUJvb2xlYW4sIEpTT05TY2hlbWFJbnRlZ2VyLFxuICBKU09OU2NoZW1hTnVtYmVyLCBKU09OU2NoZW1hU3RyaW5nXG59IGZyb20gXCIuLi92YWxpZGF0aW9uL2pzb24tc2NoZW1hXCI7XG5pbXBvcnQgeyBKU09OVmFsaWRhdG9yIH0gZnJvbSBcIi4uL3ZhbGlkYXRpb24vanNvbi12YWxpZGF0b3JcIjtcbmltcG9ydCB7IFZhbGlkYXRpb25FcnJvciB9IGZyb20gXCIuL2V4Y2VwdGlvbnNcIjtcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiBcInJvb3RcIlxufSlcbmV4cG9ydCBjbGFzcyBTdG9yYWdlTWFwIHtcblxuICAjZGF0YWJhc2U6IExvY2FsRGF0YWJhc2U7XG4gIHJlYWRvbmx5ICNqc29uVmFsaWRhdG9yOiBKU09OVmFsaWRhdG9yO1xuICByZWFkb25seSAjbm90aWZpZXJzID0gbmV3IE1hcDxzdHJpbmcsIFJlcGxheVN1YmplY3Q8dW5rbm93bj4+KCk7XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdG9yIHBhcmFtcyBhcmUgcHJvdmlkZWQgYnkgQW5ndWxhciAoYnV0IGNhbiBhbHNvIGJlIHBhc3NlZCBtYW51YWxseSBpbiB0ZXN0cylcbiAgICogQHBhcmFtIGRhdGFiYXNlIFN0b3JhZ2UgdG8gdXNlXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBkYXRhYmFzZTogTG9jYWxEYXRhYmFzZSxcbiAgKSB7XG4gICAgdGhpcy4jZGF0YWJhc2UgPSBkYXRhYmFzZTtcbiAgICB0aGlzLiNqc29uVmFsaWRhdG9yID0gbmV3IEpTT05WYWxpZGF0b3IoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAqKk51bWJlciBvZiBpdGVtcyoqIGluIHN0b3JhZ2UsIHdyYXBwZWQgaW4gYW4gT2JzZXJ2YWJsZS5cbiAgICogXG4gICAqIE5vdGUgeW91IGRvICpub3QqIG5lZWQgdG8gdW5zdWJzY3JpYmUgKGl0IGlzIGEgc2VsZi1jb21wbGV0aW5nIE9ic2VydmFibGUpLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiB0aGlzLnN0b3JhZ2VNYXAuc2l6ZS5zdWJzY3JpYmUoKHNpemUpID0+IHtcbiAgICogICBjb25zb2xlLmxvZyhzaXplKTtcbiAgICogfSk7XG4gICAqL1xuICBnZXQgc2l6ZSgpOiBPYnNlcnZhYmxlPG51bWJlcj4ge1xuXG4gICAgcmV0dXJuIHRoaXMuI2RhdGFiYXNlLnNpemVcbiAgICAgIC8qIENhdGNoIGlmIGBpbmRleGVkRGJgIGlzIGJyb2tlbiAqL1xuICAgICAgLnBpcGUodGhpcy4jY2F0Y2hJREJCcm9rZW4oKCkgPT4gdGhpcy4jZGF0YWJhc2Uuc2l6ZSkpO1xuXG4gIH1cblxuICAvKipcbiAgICogVGVsbHMgeW91IHdoaWNoIHN0b3JhZ2UgZW5naW5lIGlzIHVzZWQuXG4gICAqIFxuICAgKiAqT25seSB1c2VmdWwgZm9yIGludGVyb3BlcmFiaWxpdHkuKlxuICAgKiBcbiAgICogTm90ZSB0aGF0IGR1ZSB0byBzb21lIGJyb3dzZXJzIGlzc3VlcyBpbiBzb21lIHNwZWNpYWwgY29udGV4dHNcbiAgICogKGxpa2UgU2FmYXJpIGNyb3NzLW9yaWdpbiBpZnJhbWVzKSxcbiAgICogKip0aGlzIGluZm9ybWF0aW9uIG1heSBiZSB3cm9uZyBhdCBpbml0aWFsaXphdGlvbiwqKlxuICAgKiBhcyB0aGUgc3RvcmFnZSBjb3VsZCBmYWxsYmFjayBmcm9tIGBpbmRleGVkREJgIHRvIGBsb2NhbFN0b3JhZ2VgXG4gICAqIG9ubHkgYWZ0ZXIgYSBmaXJzdCByZWFkIG9yIHdyaXRlIG9wZXJhdGlvbi5cbiAgICogQHJldHVybnMgU3RvcmFnZSBlbmdpbmUgdXNlZFxuICAgKlxuICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2Jsb2IvbWFpbi9kb2NzL0lOVEVST1BFUkFCSUxJVFkubWR9XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGlmICh0aGlzLnN0b3JhZ2VNYXAuYmFja2luZ0VuZ2luZSA9PT0gJ2luZGV4ZWREQicpIHt9XG4gICAqL1xuICBnZXQgYmFja2luZ0VuZ2luZSgpOiBcImluZGV4ZWREQlwiIHwgXCJsb2NhbFN0b3JhZ2VcIiB8IFwibWVtb3J5XCIgfCBcInVua25vd25cIiB7XG5cbiAgICBpZiAodGhpcy4jZGF0YWJhc2UgaW5zdGFuY2VvZiBJbmRleGVkREJEYXRhYmFzZSkge1xuXG4gICAgICByZXR1cm4gXCJpbmRleGVkREJcIjtcblxuICAgIH0gZWxzZSBpZiAodGhpcy4jZGF0YWJhc2UgaW5zdGFuY2VvZiBMb2NhbFN0b3JhZ2VEYXRhYmFzZSkge1xuXG4gICAgICByZXR1cm4gXCJsb2NhbFN0b3JhZ2VcIjtcblxuICAgIH0gZWxzZSBpZiAodGhpcy4jZGF0YWJhc2UgaW5zdGFuY2VvZiBNZW1vcnlEYXRhYmFzZSkge1xuXG4gICAgICByZXR1cm4gXCJtZW1vcnlcIjtcblxuICAgIH0gZWxzZSB7XG5cbiAgICAgIHJldHVybiBcInVua25vd25cIjtcblxuICAgIH1cblxuICB9XG5cbiAgLyoqXG4gICAqIEluZm9ybWF0aW9uIGFib3V0IGBpbmRleGVkREJgIGRhdGFiYXNlLlxuICAgKiBcbiAgICogKk9ubHkgdXNlZnVsIGZvciBpbnRlcm9wZXJhYmlsaXR5LipcbiAgICogXG4gICAqIEByZXR1cm5zIGBpbmRleGVkREJgIGRhdGFiYXNlIG5hbWUsIHN0b3JlIG5hbWUgYW5kIGRhdGFiYXNlIHZlcnNpb24uXG4gICAqICoqVmFsdWVzIHdpbGwgYmUgZW1wdHkgaWYgdGhlIHN0b3JhZ2UgaXMgbm90IGBpbmRleGVkREJgLCBzbyBpdCBzaG91bGQgYmUgdXNlZCBhZnRlciBhbiBlbmdpbmUgY2hlY2sqKi5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9ibG9iL21haW4vZG9jcy9JTlRFUk9QRVJBQklMSVRZLm1kfVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBpZiAodGhpcy5zdG9yYWdlTWFwLmJhY2tpbmdFbmdpbmUgPT09ICdpbmRleGVkREInKSB7XG4gICAqICAgY29uc3QgeyBkYXRhYmFzZSwgc3RvcmUsIHZlcnNpb24gfSA9IHRoaXMuc3RvcmFnZU1hcC5iYWNraW5nU3RvcmU7XG4gICAqIH1cbiAgICovXG4gIGdldCBiYWNraW5nU3RvcmUoKTogeyBkYXRhYmFzZTogc3RyaW5nLCBzdG9yZTogc3RyaW5nLCB2ZXJzaW9uOiBudW1iZXI7IH0ge1xuXG4gICAgcmV0dXJuICh0aGlzLiNkYXRhYmFzZSBpbnN0YW5jZW9mIEluZGV4ZWREQkRhdGFiYXNlKSA/XG4gICAgICB0aGlzLiNkYXRhYmFzZS5iYWNraW5nU3RvcmUgOlxuICAgICAgeyBkYXRhYmFzZTogXCJcIiwgc3RvcmU6IFwiXCIsIHZlcnNpb246IDAgfTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEluZm9ybWF0aW9uIGFib3V0IGBsb2NhbFN0b3JhZ2VgIGZhbGxiYWNrIHN0b3JhZ2UuXG4gICAqIFxuICAgKiAqT25seSB1c2VmdWwgZm9yIGludGVyb3BlcmFiaWxpdHkuKlxuICAgKiBcbiAgICogQHJldHVybnMgYGxvY2FsU3RvcmFnZWAgcHJlZml4LlxuICAgKiAqKlZhbHVlcyB3aWxsIGJlIGVtcHR5IGlmIHRoZSBzdG9yYWdlIGlzIG5vdCBgbG9jYWxTdG9yYWdlYCwgc28gaXQgc2hvdWxkIGJlIHVzZWQgYWZ0ZXIgYW4gZW5naW5lIGNoZWNrKiouXG4gICAqXG4gICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9jeXJpbGxldHV6aS9hbmd1bGFyLWFzeW5jLWxvY2FsLXN0b3JhZ2UvYmxvYi9tYWluL2RvY3MvSU5URVJPUEVSQUJJTElUWS5tZH1cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogaWYgKHRoaXMuc3RvcmFnZU1hcC5iYWNraW5nRW5naW5lID09PSAnbG9jYWxTdG9yYWdlJykge1xuICAgKiAgIGNvbnN0IHsgcHJlZml4IH0gPSB0aGlzLnN0b3JhZ2VNYXAuZmFsbGJhY2tCYWNraW5nU3RvcmU7XG4gICAqIH1cbiAgICovXG4gIGdldCBmYWxsYmFja0JhY2tpbmdTdG9yZSgpOiB7IHByZWZpeDogc3RyaW5nOyB9IHtcblxuICAgIHJldHVybiAodGhpcy4jZGF0YWJhc2UgaW5zdGFuY2VvZiBMb2NhbFN0b3JhZ2VEYXRhYmFzZSkgP1xuICAgICAgeyBwcmVmaXg6IHRoaXMuI2RhdGFiYXNlLnByZWZpeCB9IDpcbiAgICAgIHsgcHJlZml4OiBcIlwiIH07XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYW4gaXRlbSB2YWx1ZSBpbiBzdG9yYWdlLlxuICAgKiBcbiAgICogTm90ZSB0aGF0OlxuICAgKiAqIG5vdCBmaW5kaW5nIGFuIGl0ZW0gaXMgbm90IGFuIGVycm9yLCBpdCBzdWNjZWVkcyBidXQgcmV0dXJucyBgdW5kZWZpbmVkYCxcbiAgICogKiB5b3UgZG8gKm5vdCogbmVlZCB0byB1bnN1YnNjcmliZSAoaXQgaXMgYSBzZWxmLWNvbXBsZXRpbmcgT2JzZXJ2YWJsZSksXG4gICAqICogeW91IHdpbGwgb25seSBnZXQgKm9uZSogdmFsdWU6IHRoZSBPYnNlcnZhYmxlIGlzIGhlcmUgZm9yIGFzeW5jaHJvbnkgYnV0IGlzICpub3QqIG1lYW50IHRvIGVtaXQgYWdhaW4gd2hlbiB0aGUgc3RvcmVkIGRhdGEgaXMgY2hhbmdlZC4gSWYgeW91IG5lZWQgdG8gd2F0Y2ggdGhlIHZhbHVlLCBzZWUgdGhlIGB3YXRjaGAgbWV0aG9kLlxuICAgKiBcbiAgICogRG8gbm90IGZvcmdldCBpdCBpcyBjbGllbnQtc2lkZSBzdG9yYWdlOiAqKmFsd2F5cyBjaGVjayB0aGUgZGF0YSoqLCBhcyBpdCBjb3VsZCBoYXZlIGJlZW4gZm9yZ2VkLlxuICAgKiBAc2VlIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vY3lyaWxsZXR1emkvYW5ndWxhci1hc3luYy1sb2NhbC1zdG9yYWdlL2Jsb2IvbWFpbi9kb2NzL1ZBTElEQVRJT04ubWR9XG4gICAqIFxuICAgKiBAcGFyYW0ga2V5IFRoZSBpdGVtJ3Mga2V5XG4gICAqIEBwYXJhbSBzY2hlbWEgT3B0aW9uYWwgYnV0IHJlY29tbWVuZGVkIEpTT04gc2NoZW1hIHRvIHZhbGlkYXRlIHRoZSBkYXRhXG4gICAqIEByZXR1cm5zIFRoZSBpdGVtJ3MgdmFsdWUgaWYgdGhlIGtleSBleGlzdHMsIGB1bmRlZmluZWRgIG90aGVyd2lzZSwgd3JhcHBlZCBpbiBhIFJ4SlMgT2JzZXJ2YWJsZVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiB0aGlzLnN0b3JhZ2VNYXAuZ2V0KCdrZXknLCB7IHR5cGU6ICdzdHJpbmcnIH0pLnN1YnNjcmliZSgocmVzdWx0KSA9PiB7XG4gICAqICAgcmVzdWx0OyAvLyBzdHJpbmcgb3IgdW5kZWZpbmVkXG4gICAqIH0pO1xuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBpbnRlcmZhY2UgVXNlciB7XG4gICAqICAgZmlyc3ROYW1lOiBzdHJpbmc7XG4gICAqICAgbGFzdE5hbWU/OiBzdHJpbmc7XG4gICAqIH1cbiAgICpcbiAgICogY29uc3Qgc2NoZW1hID0ge1xuICAgKiAgIHR5cGU6ICdvYmplY3QnLFxuICAgKiAgIHByb3BlcnRpZXM6IHtcbiAgICogICAgIGZpcnN0TmFtZTogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgKiAgICAgbGFzdE5hbWU6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICogICB9LFxuICAgKiAgIHJlcXVpcmVkOiBbJ2ZpcnN0TmFtZSddLFxuICAgKiB9IHNhdGlzZmllcyBKU09OU2NoZW1hO1xuICAgKlxuICAgKiB0aGlzLnN0b3JhZ2VNYXAuZ2V0PFVzZXI+KCd1c2VyJywgc2NoZW1hKS5zdWJzY3JpYmUoKHVzZXIpID0+IHtcbiAgICogICBpZiAodXNlcikge1xuICAgKiAgICAgdXNlci5maXJzdE5hbWU7XG4gICAqICAgfVxuICAgKiB9KTtcbiAgICovXG4gIGdldChrZXk6IHN0cmluZyk6IE9ic2VydmFibGU8dW5rbm93bj47XG4gIGdldDxUIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hU3RyaW5nKTogT2JzZXJ2YWJsZTxUIHwgdW5kZWZpbmVkPjtcbiAgZ2V0PFQgZXh0ZW5kcyBudW1iZXIgPSBudW1iZXI+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFJbnRlZ2VyIHwgSlNPTlNjaGVtYU51bWJlcik6IE9ic2VydmFibGU8VCB8IHVuZGVmaW5lZD47XG4gIGdldDxUIGV4dGVuZHMgYm9vbGVhbiA9IGJvb2xlYW4+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFCb29sZWFuKTogT2JzZXJ2YWJsZTxUIHwgdW5kZWZpbmVkPjtcbiAgZ2V0PFQgZXh0ZW5kcyByZWFkb25seSBzdHJpbmdbXSA9IHN0cmluZ1tdPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQXJyYXlPZjxKU09OU2NoZW1hU3RyaW5nPik6IE9ic2VydmFibGU8VCB8IHVuZGVmaW5lZD47XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvdW5pZmllZC1zaWduYXR1cmVzIC0tIEJldHRlciBmb3IgZG9jdW1lbnRhdGlvblxuICBnZXQ8VCBleHRlbmRzIHJlYWRvbmx5IG51bWJlcltdID0gbnVtYmVyW10+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFBcnJheU9mPEpTT05TY2hlbWFJbnRlZ2VyIHwgSlNPTlNjaGVtYU51bWJlcj4pOiBPYnNlcnZhYmxlPFQgfCB1bmRlZmluZWQ+O1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3VuaWZpZWQtc2lnbmF0dXJlcyAtLSBCZXR0ZXIgZm9yIGRvY3VtZW50YXRpb25cbiAgZ2V0PFQgZXh0ZW5kcyByZWFkb25seSBib29sZWFuW10gPSBib29sZWFuW10+KGtleTogc3RyaW5nLCBzY2hlbWE6IEpTT05TY2hlbWFBcnJheU9mPEpTT05TY2hlbWFCb29sZWFuPik6IE9ic2VydmFibGU8VCB8IHVuZGVmaW5lZD47XG4gIGdldDxUPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hKTogT2JzZXJ2YWJsZTxUIHwgdW5kZWZpbmVkPjtcbiAgZ2V0PFQgPSB1bmtub3duPihrZXk6IHN0cmluZywgc2NoZW1hPzogSlNPTlNjaGVtYSk6IE9ic2VydmFibGU8dW5rbm93bj4ge1xuXG4gICAgLyogR2V0IHRoZSBkYXRhIGluIHN0b3JhZ2UgKi9cbiAgICByZXR1cm4gdGhpcy4jZGF0YWJhc2UuZ2V0KGtleSkucGlwZShcbiAgICAgIC8qIENoZWNrIGlmIGBpbmRleGVkRGJgIGlzIGJyb2tlbiAqL1xuICAgICAgdGhpcy4jY2F0Y2hJREJCcm9rZW4oKCkgPT4gdGhpcy4jZGF0YWJhc2UuZ2V0KGtleSkpLFxuICAgICAgbWVyZ2VNYXAoKGRhdGEpID0+IHtcblxuICAgICAgICAvKiBObyBuZWVkIHRvIHZhbGlkYXRlIGlmIHRoZSBkYXRhIGlzIGVtcHR5ICovXG4gICAgICAgIGlmICgoZGF0YSA9PT0gdW5kZWZpbmVkKSB8fCAoZGF0YSA9PT0gbnVsbCkpIHtcblxuICAgICAgICAgIHJldHVybiBvZih1bmRlZmluZWQpO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoc2NoZW1hKSB7XG5cbiAgICAgICAgICAvKiBWYWxpZGF0ZSBkYXRhIGFnYWluc3QgYSBKU09OIHNjaGVtYSBpZiBwcm92aWRlZCAqL1xuICAgICAgICAgIGlmICghdGhpcy4janNvblZhbGlkYXRvci52YWxpZGF0ZShkYXRhLCBzY2hlbWEpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgVmFsaWRhdGlvbkVycm9yKCkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8qIERhdGEgaGF2ZSBiZWVuIGNoZWNrZWQsIHNvIGl0J3MgT0sgdG8gY2FzdCAqL1xuICAgICAgICAgIHJldHVybiBvZihkYXRhIGFzIFQgfCB1bmRlZmluZWQpO1xuXG4gICAgICAgIH1cblxuICAgICAgICAvKiBDYXN0IHRvIHVua25vd24gYXMgdGhlIGRhdGEgd2Fzbid0IGNoZWNrZWQgKi9cbiAgICAgICAgcmV0dXJuIG9mKGRhdGEpO1xuXG4gICAgICB9KSxcbiAgICApO1xuXG4gIH1cblxuICAvKipcbiAgICogU3RvcmUgYW4gaXRlbSBpbiBzdG9yYWdlLlxuICAgKiBcbiAgICogTm90ZSB0aGF0OlxuICAgKiAqIHlvdSAqZG8qIG5lZWQgdG8gc3Vic2NyaWJlLCBldmVuIGlmIHlvdSBkbyBub3QgaGF2ZSBzb21ldGhpbmcgc3BlY2lmaWMgdG8gZG8gYWZ0ZXIgd3JpdGluZyBpbiBzdG9yYWdlLCBvdGhlcndpc2Ugbm90aGluZyBoYXBwZW5zIChiZWNhdXNlIGl0IGlzIGhvdyBSeEpTIE9ic2VydmFibGVzIHdvcmspLFxuICAgKiAqIGJ1dCB5b3UgZG8gKm5vdCogbmVlZCB0byB1bnN1YnNjcmliZSAoaXQgaXMgYSBzZWxmLWNvbXBsZXRpbmcgT2JzZXJ2YWJsZSksXG4gICAqICogc2V0dGluZyBgbnVsbGAgb3IgYHVuZGVmaW5lZGAgd2lsbCByZW1vdmUgdGhlIGl0ZW0gdG8gYXZvaWQgc29tZSBicm93c2VycyBpc3N1ZXMsXG4gICAqICogeW91IHNob3VsZCBzdGljayB0byBzZXJpYWxpemFibGUgSlNPTiBkYXRhLCBtZWFuaW5nIHByaW1pdGl2ZSB0eXBlcywgYXJyYXlzIGFuZCBsaXRlcmFsIG9iamVjdHMuIERhdGUsIE1hcCwgU2V0LCBCbG9iIGFuZCBvdGhlciBzcGVjaWFsIHN0cnVjdHVyZXMgY2FuIGNhdXNlIGlzc3VlcyBpbiBzb21lIHNjZW5hcmlvcy5cbiAgICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9ibG9iL21haW4vZG9jcy9TRVJJQUxJWkFUSU9OLm1kfVxuICAgKiBcbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcGFyYW0gZGF0YSBUaGUgaXRlbSdzIHZhbHVlXG4gICAqIEBwYXJhbSBzY2hlbWEgT3B0aW9uYWwgSlNPTiBzY2hlbWEgdG8gdmFsaWRhdGUgdGhlIGRhdGFcbiAgICogQHJldHVybnMgQSBSeEpTIE9ic2VydmFibGUgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGhpcy5zdG9yYWdlTWFwLnNldCgna2V5JywgJ3ZhbHVlJykuc3Vic2NyaWJlKCgpID0+IHt9KTtcbiAgICovXG4gIHNldChrZXk6IHN0cmluZywgZGF0YTogdW5rbm93biwgc2NoZW1hPzogSlNPTlNjaGVtYSk6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICAvKiBTdG9yaW5nIGB1bmRlZmluZWRgIG9yIGBudWxsYCBpcyB1c2VsZXNzIGFuZCBjYW4gY2F1c2UgaXNzdWVzIGluIGBpbmRleGVkRGJgIGluIHNvbWUgYnJvd3NlcnMsXG4gICAgICogc28gcmVtb3ZpbmcgaXRlbSBpbnN0ZWFkIGZvciBhbGwgc3RvcmFnZXMgdG8gaGF2ZSBhIGNvbnNpc3RlbnQgQVBJICovXG4gICAgaWYgKChkYXRhID09PSB1bmRlZmluZWQpIHx8IChkYXRhID09PSBudWxsKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVsZXRlKGtleSk7XG4gICAgfVxuXG4gICAgLyogVmFsaWRhdGUgZGF0YSBhZ2FpbnN0IGEgSlNPTiBzY2hlbWEgaWYgcHJvdmlkZWQgKi9cbiAgICBpZiAoc2NoZW1hICYmICF0aGlzLiNqc29uVmFsaWRhdG9yLnZhbGlkYXRlKGRhdGEsIHNjaGVtYSkpIHtcbiAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IG5ldyBWYWxpZGF0aW9uRXJyb3IoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuI2RhdGFiYXNlLnNldChrZXksIGRhdGEpLnBpcGUoXG4gICAgICAvKiBDYXRjaCBpZiBgaW5kZXhlZERiYCBpcyBicm9rZW4gKi9cbiAgICAgIHRoaXMuI2NhdGNoSURCQnJva2VuKCgpID0+IHRoaXMuI2RhdGFiYXNlLnNldChrZXksIGRhdGEpKSxcbiAgICAgIC8qIE5vdGlmeSB3YXRjaGVycyAobXVzdCBiZSBsYXN0IGJlY2F1c2UgaXQgc2hvdWxkIG9ubHkgaGFwcGVuIGlmIHRoZSBvcGVyYXRpb24gc3VjY2VlZHMpICovXG4gICAgICB0YXAoKCkgPT4geyB0aGlzLiNub3RpZnkoa2V5LCBkYXRhKTsgfSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgYW4gaXRlbSBpbiBzdG9yYWdlLlxuICAgKiBcbiAgICogTm90ZSB0aGF0OlxuICAgKiAqIHlvdSAqZG8qIG5lZWQgdG8gc3Vic2NyaWJlLCBldmVuIGlmIHlvdSBkbyBub3QgaGF2ZSBzb21ldGhpbmcgc3BlY2lmaWMgdG8gZG8gYWZ0ZXIgZGVsZXRpbmcsIG90aGVyd2lzZSBub3RoaW5nIGhhcHBlbnMgKGJlY2F1c2UgaXQgaXMgaG93IFJ4SlMgT2JzZXJ2YWJsZXMgd29yayksXG4gICAqICogYnV0IHlvdSBkbyAqbm90KiBuZWVkIHRvIHVuc3Vic2NyaWJlIChpdCBpcyBhIHNlbGYtY29tcGxldGluZyBPYnNlcnZhYmxlKS5cbiAgICogXG4gICAqIEBwYXJhbSBrZXkgVGhlIGl0ZW0ncyBrZXlcbiAgICogQHJldHVybnMgQSBSeEpTIE9ic2VydmFibGUgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGhpcy5zdG9yYWdlTWFwLmRlbGV0ZSgna2V5Jykuc3Vic2NyaWJlKCgpID0+IHt9KTtcbiAgICovXG4gIGRlbGV0ZShrZXk6IHN0cmluZyk6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICByZXR1cm4gdGhpcy4jZGF0YWJhc2UuZGVsZXRlKGtleSkucGlwZShcbiAgICAgIC8qIENhdGNoIGlmIGBpbmRleGVkRGJgIGlzIGJyb2tlbiAqL1xuICAgICAgdGhpcy4jY2F0Y2hJREJCcm9rZW4oKCkgPT4gdGhpcy4jZGF0YWJhc2UuZGVsZXRlKGtleSkpLFxuICAgICAgLyogTm90aWZ5IHdhdGNoZXJzIChtdXN0IGJlIGxhc3QgYmVjYXVzZSBpdCBzaG91bGQgb25seSBoYXBwZW4gaWYgdGhlIG9wZXJhdGlvbiBzdWNjZWVkcykgKi9cbiAgICAgIHRhcCgoKSA9PiB7IHRoaXMuI25vdGlmeShrZXksIHVuZGVmaW5lZCk7IH0pLFxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgYWxsIGl0ZW1zIGluIHN0b3JhZ2UuXG4gICAqIFxuICAgKiBOb3RlIHRoYXQ6XG4gICAqICogeW91ICpkbyogbmVlZCB0byBzdWJzY3JpYmUsIGV2ZW4gaWYgeW91IGRvIG5vdCBoYXZlIHNvbWV0aGluZyBzcGVjaWZpYyB0byBkbyBhZnRlciBjbGVhcmluZywgb3RoZXJ3aXNlIG5vdGhpbmcgaGFwcGVucyAoYmVjYXVzZSBpdCBpcyBob3cgUnhKUyBPYnNlcnZhYmxlcyB3b3JrKSxcbiAgICogKiBidXQgeW91IGRvICpub3QqIG5lZWQgdG8gdW5zdWJzY3JpYmUgKGl0IGlzIGEgc2VsZi1jb21wbGV0aW5nIE9ic2VydmFibGUpLlxuICAgKiBcbiAgICogQHJldHVybnMgQSBSeEpTIE9ic2VydmFibGUgdG8gd2FpdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGhpcy5zdG9yYWdlTWFwLmNsZWFyKCkuc3Vic2NyaWJlKCgpID0+IHt9KTtcbiAgICovXG4gIGNsZWFyKCk6IE9ic2VydmFibGU8dW5kZWZpbmVkPiB7XG5cbiAgICByZXR1cm4gdGhpcy4jZGF0YWJhc2UuY2xlYXIoKS5waXBlKFxuICAgICAgLyogQ2F0Y2ggaWYgYGluZGV4ZWREYmAgaXMgYnJva2VuICovXG4gICAgICB0aGlzLiNjYXRjaElEQkJyb2tlbigoKSA9PiB0aGlzLiNkYXRhYmFzZS5jbGVhcigpKSxcbiAgICAgIC8qIE5vdGlmeSB3YXRjaGVycyAobXVzdCBiZSBsYXN0IGJlY2F1c2UgaXQgc2hvdWxkIG9ubHkgaGFwcGVuIGlmIHRoZSBvcGVyYXRpb24gc3VjY2VlZHMpICovXG4gICAgICB0YXAoKCkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiB0aGlzLiNub3RpZmllcnMua2V5cygpKSB7XG4gICAgICAgICAgdGhpcy4jbm90aWZ5KGtleSwgdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwga2V5cyBzdG9yZWQgaW4gc3RvcmFnZS5cbiAgICogXG4gICAqIE5vdGUgKip0aGlzIGlzIGFuICppdGVyYXRpbmcqIE9ic2VydmFibGUqKjpcbiAgICogKiBpZiB0aGVyZSBpcyBubyBrZXksIHRoZSBgbmV4dGAgY2FsbGJhY2sgd2lsbCBub3QgYmUgaW52b2tlZCxcbiAgICogKiBpZiB5b3UgbmVlZCB0byB3YWl0IHRoZSB3aG9sZSBvcGVyYXRpb24gdG8gZW5kLCBiZSBzdXJlIHRvIGFjdCBpbiB0aGUgYGNvbXBsZXRlYCBjYWxsYmFjayxcbiAgICogYXMgdGhpcyBPYnNlcnZhYmxlIGNhbiBlbWl0IHNldmVyYWwgdmFsdWVzIGFuZCBzbyB3aWxsIGludm9rZSB0aGUgYG5leHRgIGNhbGxiYWNrIHNldmVyYWwgdGltZXMsXG4gICAqICogeW91IGRvICpub3QqIG5lZWQgdG8gdW5zdWJzY3JpYmUgKGl0IGlzIGEgc2VsZi1jb21wbGV0aW5nIE9ic2VydmFibGUpLlxuICAgKiBcbiAgICogQHJldHVybnMgQSBsaXN0IG9mIHRoZSBrZXlzIHdyYXBwZWQgaW4gYSBSeEpTIE9ic2VydmFibGVcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogdGhpcy5zdG9yYWdlTWFwLmtleXMoKS5zdWJzY3JpYmUoe1xuICAgKiAgIG5leHQ6IChrZXkpID0+IHsgY29uc29sZS5sb2coa2V5KTsgfSxcbiAgICogICBjb21wbGV0ZTogKCkgPT4geyBjb25zb2xlLmxvZygnRG9uZScpOyB9LFxuICAgKiB9KTtcbiAgICovXG4gIGtleXMoKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcblxuICAgIHJldHVybiB0aGlzLiNkYXRhYmFzZS5rZXlzKClcbiAgICAgIC8qIENhdGNoIGlmIGBpbmRleGVkRGJgIGlzIGJyb2tlbiAqL1xuICAgICAgLnBpcGUodGhpcy4jY2F0Y2hJREJCcm9rZW4oKCkgPT4gdGhpcy4jZGF0YWJhc2Uua2V5cygpKSk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBUZWxscyBpZiBhIGtleSBleGlzdHMgaW4gc3RvcmFnZS5cbiAgICogXG4gICAqIE5vdGUgeW91IGRvICpub3QqIG5lZWQgdG8gdW5zdWJzY3JpYmUgKGl0IGlzIGEgc2VsZi1jb21wbGV0aW5nIE9ic2VydmFibGUpLlxuICAgKiBcbiAgICogQHJldHVybnMgQSBSeEpTIE9ic2VydmFibGUgdGVsbGluZyBpZiB0aGUga2V5IGV4aXN0c1xuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiB0aGlzLnN0b3JhZ2VNYXAuaGFzKCdrZXknKS5zdWJzY3JpYmUoKGhhc0tleSkgPT4ge1xuICAgKiAgIGlmIChoYXNLZXkpIHt9XG4gICAqIH0pO1xuICAgKi9cbiAgaGFzKGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG5cbiAgICByZXR1cm4gdGhpcy4jZGF0YWJhc2UuaGFzKGtleSlcbiAgICAgIC8qIENhdGNoIGlmIGBpbmRleGVkRGJgIGlzIGJyb2tlbiAqL1xuICAgICAgLnBpcGUodGhpcy4jY2F0Y2hJREJCcm9rZW4oKCkgPT4gdGhpcy4jZGF0YWJhc2UuaGFzKGtleSkpKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIFdhdGNoIGFuIGl0ZW0gdmFsdWUgaW4gc3RvcmFnZS5cbiAgICogXG4gICAqIE5vdGUgdGhhdDpcbiAgICogKiBpdCBpcyBhbiBpbmZpbml0ZSBPYnNlcnZhYmxlLCBkbyBub3QgZm9yZ2V0IHRvIHVuc3Vic2NyaWJlLFxuICAgKiAqIG9ubHkgY2hhbmdlcyBkb25lIHZpYSB0aGlzIGxpYnJhcnkgd2lsbCBiZSB3YXRjaGVkLCBleHRlcm5hbCBjaGFuZ2VzIGluIHN0b3JhZ2UgY2Fubm90IGJlIGRldGVjdGVkLlxuICAgKiBcbiAgICogVGhlIHNpZ25hdHVyZSBoYXMgbWFueSBvdmVybG9hZHMgZHVlIHRvIHZhbGlkYXRpb24sICoqcGxlYXNlIHJlZmVyIHRvIHRoZSBkb2N1bWVudGF0aW9uLioqXG4gICAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9ibG9iL21haW4vZG9jcy9WQUxJREFUSU9OLm1kXG4gICAqIFxuICAgKiBAcGFyYW0ga2V5IFRoZSBpdGVtJ3Mga2V5IHRvIHdhdGNoXG4gICAqIEBwYXJhbSBzY2hlbWEgT3B0aW9uYWwgSlNPTiBzY2hlbWEgdG8gdmFsaWRhdGUgdGhlIGluaXRpYWwgdmFsdWVcbiAgICogQHJldHVybnMgQW4gaW5maW5pdGUgT2JzZXJ2YWJsZSBnaXZpbmcgdGhlIGN1cnJlbnQgdmFsdWVcbiAgICogXG4gICAqIEBleGFtcGxlXG4gICAqIENvbXBvbmVudCgpXG4gICAqIGV4cG9ydCBjbGFzcyBNeUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgICogXG4gICAqICAgcHJpdmF0ZSBzdG9yYWdlU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuICAgKiBcbiAgICogICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICogICAgIHRoaXMuc3RvcmFnZVN1YnNjcmlwdGlvbiA9IHRoaXMuc3RvcmFnZU1hcC53YXRjaCgna2V5JywgeyB0eXBlOiAnc3RyaW5nJyB9KS5zdWJzY3JpYmUoKHJlc3VsdCkgPT4ge1xuICAgKiAgICAgICByZXN1bHQ7IC8vIHN0cmluZyBvciB1bmRlZmluZWRcbiAgICogICAgIH0pO1xuICAgKiAgIH1cbiAgICogXG4gICAqICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAqICAgICB0aGlzLnN0b3JhZ2VTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAqICAgfVxuICAgKiBcbiAgICogfVxuICAgKi9cbiAgd2F0Y2goa2V5OiBzdHJpbmcpOiBPYnNlcnZhYmxlPHVua25vd24+O1xuICB3YXRjaDxUIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hU3RyaW5nKTogT2JzZXJ2YWJsZTxUIHwgdW5kZWZpbmVkPjtcbiAgd2F0Y2g8VCBleHRlbmRzIG51bWJlciA9IG51bWJlcj4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYUludGVnZXIgfCBKU09OU2NoZW1hTnVtYmVyKTogT2JzZXJ2YWJsZTxUIHwgdW5kZWZpbmVkPjtcbiAgd2F0Y2g8VCBleHRlbmRzIGJvb2xlYW4gPSBib29sZWFuPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQm9vbGVhbik6IE9ic2VydmFibGU8VCB8IHVuZGVmaW5lZD47XG4gIHdhdGNoPFQgZXh0ZW5kcyByZWFkb25seSBzdHJpbmdbXSA9IHN0cmluZ1tdPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQXJyYXlPZjxKU09OU2NoZW1hU3RyaW5nPik6IE9ic2VydmFibGU8VCB8IHVuZGVmaW5lZD47XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvdW5pZmllZC1zaWduYXR1cmVzIC0tIEJldHRlciBmb3IgZG9jdW1lbnRhdGlvblxuICB3YXRjaDxUIGV4dGVuZHMgcmVhZG9ubHkgbnVtYmVyW10gPSBudW1iZXJbXT4oa2V5OiBzdHJpbmcsIHNjaGVtYTogSlNPTlNjaGVtYUFycmF5T2Y8SlNPTlNjaGVtYUludGVnZXIgfCBKU09OU2NoZW1hTnVtYmVyPik6IE9ic2VydmFibGU8VCB8IHVuZGVmaW5lZD47XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvdW5pZmllZC1zaWduYXR1cmVzIC0tIEJldHRlciBmb3IgZG9jdW1lbnRhdGlvblxuICB3YXRjaDxUIGV4dGVuZHMgcmVhZG9ubHkgYm9vbGVhbltdID0gYm9vbGVhbltdPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hQXJyYXlPZjxKU09OU2NoZW1hQm9vbGVhbj4pOiBPYnNlcnZhYmxlPFQgfCB1bmRlZmluZWQ+O1xuICB3YXRjaDxUPihrZXk6IHN0cmluZywgc2NoZW1hOiBKU09OU2NoZW1hKTogT2JzZXJ2YWJsZTxUIHwgdW5kZWZpbmVkPjtcbiAgd2F0Y2g8VCA9IHVua25vd24+KGtleTogc3RyaW5nLCBzY2hlbWE/OiBKU09OU2NoZW1hKTogT2JzZXJ2YWJsZTx1bmtub3duPiB7XG5cbiAgICAvKiBDaGVjayBpZiB0aGVyZSBpcyBhbHJlYWR5IGEgbm90aWZpZXIgKi9cbiAgICBpZiAoIXRoaXMuI25vdGlmaWVycy5oYXMoa2V5KSkge1xuICAgICAgdGhpcy4jbm90aWZpZXJzLnNldChrZXksIG5ldyBSZXBsYXlTdWJqZWN0KDEpKTtcbiAgICB9XG5cbiAgICAvKiBOb24tbnVsbCBhc3NlcnRpb24gaXMgcmVxdWlyZWQgYmVjYXVzZSBUeXBlU2NyaXB0IGRvZXNuJ3QgbmFycm93IGAuaGFzKClgIHlldCAqL1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uIC0tIEVuc3VyZWQgYnkgdGhlIGxvZ2ljXG4gICAgY29uc3Qgbm90aWZpZXIgPSB0aGlzLiNub3RpZmllcnMuZ2V0KGtleSkhO1xuXG4gICAgLyogR2V0IHRoZSBjdXJyZW50IGl0ZW0gdmFsdWUgKi9cbiAgICAoc2NoZW1hID8gdGhpcy5nZXQ8VD4oa2V5LCBzY2hlbWEpIDogdGhpcy5nZXQoa2V5KSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXN1bHQpID0+IHtcbiAgICAgICAgbm90aWZpZXIubmV4dChyZXN1bHQpO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgbm90aWZpZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8qIE9ubHkgdGhlIHB1YmxpYyBBUEkgb2YgdGhlIE9ic2VydmFibGUgc2hvdWxkIGJlIHJldHVybmVkICovXG4gICAgcmV0dXJuIChzY2hlbWEgP1xuICAgICAgbm90aWZpZXIuYXNPYnNlcnZhYmxlKCkgYXMgT2JzZXJ2YWJsZTxUIHwgdW5kZWZpbmVkPiA6XG4gICAgICBub3RpZmllci5hc09ic2VydmFibGUoKVxuICAgICk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBOb3RpZnkgd2hlbiBhIHZhbHVlIGNoYW5nZXNcbiAgICogQHBhcmFtIGtleSBUaGUgaXRlbSdzIGtleVxuICAgKiBAcGFyYW0gZGF0YSBUaGUgbmV3IHZhbHVlXG4gICAqL1xuICAjbm90aWZ5KGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bik6IHZvaWQge1xuXG4gICAgY29uc3Qgbm90aWZpZXIgPSB0aGlzLiNub3RpZmllcnMuZ2V0KGtleSk7XG5cbiAgICBpZiAobm90aWZpZXIpIHtcbiAgICAgIG5vdGlmaWVyLm5leHQodmFsdWUpO1xuICAgIH1cblxuICB9XG5cbiAgLyoqXG4gICAqIFJ4SlMgb3BlcmF0b3IgdG8gY2F0Y2ggaWYgYGluZGV4ZWREQmAgaXMgYnJva2VuXG4gICAqIEBwYXJhbSBvcGVyYXRpb25DYWxsYmFjayBDYWxsYmFjayB3aXRoIHRoZSBvcGVyYXRpb24gdG8gcmVkb1xuICAgKi9cbiAgI2NhdGNoSURCQnJva2VuPFQ+KG9wZXJhdGlvbkNhbGxiYWNrOiAoKSA9PiBPYnNlcnZhYmxlPFQ+KTogT3BlcmF0b3JGdW5jdGlvbjxULCBUPiB7XG5cbiAgICByZXR1cm4gY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcblxuICAgICAgLyogQ2hlY2sgaWYgYGluZGV4ZWREQmAgaXMgYnJva2VuIGJhc2VkIG9uIGVycm9yIG1lc3NhZ2UgKHRoZSBzcGVjaWZpYyBlcnJvciBjbGFzcyBzZWVtcyB0byBiZSBsb3N0IGluIHRoZSBwcm9jZXNzKSAqL1xuICAgICAgaWYgKChlcnJvciAhPT0gdW5kZWZpbmVkKSAmJiAoZXJyb3IgIT09IG51bGwpXG4gICAgICAgICYmICh0eXBlb2YgZXJyb3IgPT09IFwib2JqZWN0XCIpICYmIChcIm1lc3NhZ2VcIiBpbiBlcnJvcilcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtbWVtYmVyLWFjY2VzcyAtLSBSZXF1aXJlZCBiZWNhdXNlIFR5cGVTY3JpcHQgbmFycm93aW5nIGlzIG5vdCB3b3JraW5nIGhlcmVcbiAgICAgICAgJiYgKGVycm9yLm1lc3NhZ2UgPT09IElEQl9CUk9LRU5fRVJST1IpKSB7XG5cbiAgICAgICAgLyogV2hlbiBzdG9yYWdlIGlzIGZ1bGx5IGRpc2FibGVkIGluIGJyb3dzZXIgKHZpYSB0aGUgXCJCbG9jayBhbGwgY29va2llc1wiIG9wdGlvbiksXG4gICAgICAgICAqIGp1c3QgdHJ5aW5nIHRvIGNoZWNrIGBsb2NhbFN0b3JhZ2VgIHZhcmlhYmxlIGNhdXNlcyBhIHNlY3VyaXR5IGV4Y2VwdGlvbi5cbiAgICAgICAgICogUHJldmVudHMgaHR0cHM6Ly9naXRodWIuY29tL2N5cmlsbGV0dXppL2FuZ3VsYXItYXN5bmMtbG9jYWwtc3RvcmFnZS9pc3N1ZXMvMTE4XG4gICAgICAgICAqL1xuICAgICAgICB0cnkge1xuXG4gICAgICAgICAgaWYgKFwiZ2V0SXRlbVwiIGluIGxvY2FsU3RvcmFnZSkge1xuXG4gICAgICAgICAgICAvKiBGYWxsYmFjayB0byBgbG9jYWxTdG9yYWdlYCBpZiBhdmFpbGFibGUgKi9cbiAgICAgICAgICAgIHRoaXMuI2RhdGFiYXNlID0gbmV3IExvY2FsU3RvcmFnZURhdGFiYXNlKCk7XG5cbiAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAvKiBGYWxsYmFjayB0byBtZW1vcnkgc3RvcmFnZSBvdGhlcndpc2UgKi9cbiAgICAgICAgICAgIHRoaXMuI2RhdGFiYXNlID0gbmV3IE1lbW9yeURhdGFiYXNlKCk7XG5cbiAgICAgICAgICB9XG5cbiAgICAgICAgfSBjYXRjaCB7XG5cbiAgICAgICAgICAvKiBGYWxsYmFjayB0byBtZW1vcnkgc3RvcmFnZSBvdGhlcndpc2UgKi9cbiAgICAgICAgICB0aGlzLiNkYXRhYmFzZSA9IG5ldyBNZW1vcnlEYXRhYmFzZSgpO1xuXG4gICAgICAgIH1cblxuICAgICAgICAvKiBSZWRvIHRoZSBvcGVyYXRpb24gKi9cbiAgICAgICAgcmV0dXJuIG9wZXJhdGlvbkNhbGxiYWNrKCk7XG5cbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgLyogT3RoZXJ3aXNlLCByZXRocm93IHRoZSBlcnJvciAqL1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1yZXR1cm5cbiAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xuXG4gICAgICB9XG5cbiAgICB9KTtcblxuICB9XG5cbiAgLyoqXG4gICAqIFRISVMgTUVUSE9EIElTIEZPUiBJTlRFUk5BTCBQVVJQT1NFIE9OTFkgQU5EIE1VU1QgTk9UIEJFIFVTRUQsXG4gICAqIElUIENBTiBCRSBSRU1PVkVEIEFUIEFOWSBUSU1FIEFORCBNRVNTSU5HIFdJVEggSVQgQ0FOIENBVVNFIElTU1VFU1xuICAgKiBAcHJpdmF0ZVxuICAgKiBAaWdub3JlXG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50LCBAdHlwZXNjcmlwdC1lc2xpbnQvcHJlZmVyLXRzLWV4cGVjdC1lcnJvciAtLSBTaWxlbmNlIHRoZSBub3QgdXNlZCBlcnJvciwgaXQgaXMgdXNlZCBpbiB0ZXN0c1xuICAvLyBAdHMtaWdub3JlXG4gIHByaXZhdGUgybVpbnRlcm5hbEdldERhdGFiYXNlKCk6IExvY2FsRGF0YWJhc2Uge1xuXG4gICAgcmV0dXJuIHRoaXMuI2RhdGFiYXNlO1xuXG4gIH1cblxufVxuIl19
|