ng-http-caching 18.0.1 → 18.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ See the [stackblitz demo](https://stackblitz.com/edit/demo-ng-http-caching?file=
|
|
|
15
15
|
✅ Automatic garbage collector of cache<br>
|
|
16
16
|
✅ More than 90% unit tested<br>
|
|
17
17
|
✅ LocalStorage, SessionStorage, MemoryStorage and custom cache storage<br>
|
|
18
|
+
✅ Check response headers cache-control and expires<br>
|
|
18
19
|
|
|
19
20
|
## Get Started
|
|
20
21
|
|
|
@@ -108,6 +109,9 @@ The default value is Angular major version (eg. 13), in this way, the cache is i
|
|
|
108
109
|
Number of millisecond that a response is stored in the cache.
|
|
109
110
|
You can set specific "lifetime" for each request by add the header `X-NG-HTTP-CACHING-LIFETIME` (see example below).
|
|
110
111
|
|
|
112
|
+
### checkResponseHeaders (boolean - default false);
|
|
113
|
+
If true response headers cache-control and expires are respected.
|
|
114
|
+
|
|
111
115
|
### allowedMethod (string[] - default: ['GET', 'HEAD'])
|
|
112
116
|
Array of allowed HTTP methods to cache.
|
|
113
117
|
You can allow multiple methods, eg.: `['GET', 'POST', 'PUT', 'DELETE', 'HEAD']` or
|
|
@@ -181,7 +185,7 @@ const ngHttpCachingConfig: NgHttpCachingConfig = {
|
|
|
181
185
|
### isValid (function - default see NgHttpCachingService.isValid());
|
|
182
186
|
If this function return `true` the cache entry is valid and can be stored, if return `false` isn't valid.
|
|
183
187
|
If the result is `undefined`, the normal behaviour is provided.
|
|
184
|
-
Default behaviour is whether the status code falls in the 2xx range.
|
|
188
|
+
Default behaviour is whether the status code falls in the 2xx range and response headers cache-control and expires allow cache.
|
|
185
189
|
Example of customization:
|
|
186
190
|
|
|
187
191
|
```ts
|
|
@@ -412,7 +416,7 @@ export class NgHttpCachingService {
|
|
|
412
416
|
|
|
413
417
|
/**
|
|
414
418
|
* Return true if cache entry is valid for store in the cache
|
|
415
|
-
* Default behaviour is whether the status code falls in the 2xx range.
|
|
419
|
+
* Default behaviour is whether the status code falls in the 2xx range and response headers cache-control and expires allow cache.
|
|
416
420
|
*/
|
|
417
421
|
isValid<K, T>(entry: NgHttpCachingEntry<K, T>): boolean;
|
|
418
422
|
|
|
@@ -4,6 +4,31 @@ import { NgHttpCachingMemoryStorage } from './storage/ng-http-caching-memory-sto
|
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
5
|
export const NG_HTTP_CACHING_CONTEXT = new HttpContextToken(() => ({}));
|
|
6
6
|
export const withNgHttpCachingContext = (value, context = new HttpContext()) => context.set(NG_HTTP_CACHING_CONTEXT, value);
|
|
7
|
+
export const checkCacheHeaders = (headers) => {
|
|
8
|
+
// check Cache-Control
|
|
9
|
+
const cacheControlHeader = headers.get('cache-control');
|
|
10
|
+
if (cacheControlHeader) {
|
|
11
|
+
const cacheControl = cacheControlHeader.toLowerCase();
|
|
12
|
+
if (cacheControl.includes('no-store')) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
else if (cacheControl.includes('no-cache')) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// check Expires header Expires if response is without Cache-Control
|
|
23
|
+
const expiresHeader = headers.get('expires');
|
|
24
|
+
if (expiresHeader) {
|
|
25
|
+
const expires = Date.parse(expiresHeader);
|
|
26
|
+
if (!isNaN(expires)) {
|
|
27
|
+
return expires > Date.now();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return true;
|
|
31
|
+
};
|
|
7
32
|
export const NG_HTTP_CACHING_CONFIG = new InjectionToken('ng-http-caching.config');
|
|
8
33
|
export var NgHttpCachingStrategy;
|
|
9
34
|
(function (NgHttpCachingStrategy) {
|
|
@@ -50,6 +75,7 @@ export const NgHttpCachingConfigDefault = {
|
|
|
50
75
|
version: VERSION.major,
|
|
51
76
|
allowedMethod: ['GET', 'HEAD'],
|
|
52
77
|
cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,
|
|
78
|
+
checkResponseHeaders: false
|
|
53
79
|
};
|
|
54
80
|
export class NgHttpCachingService {
|
|
55
81
|
constructor(config) {
|
|
@@ -236,7 +262,7 @@ export class NgHttpCachingService {
|
|
|
236
262
|
}
|
|
237
263
|
/**
|
|
238
264
|
* Return true if cache entry is valid for store in the cache
|
|
239
|
-
* Default behaviour is whether the status code falls in the 2xx range.
|
|
265
|
+
* Default behaviour is whether the status code falls in the 2xx range and response headers cache-control and expires allow cache.
|
|
240
266
|
*/
|
|
241
267
|
isValid(entry) {
|
|
242
268
|
const context = entry.request.context.get(NG_HTTP_CACHING_CONTEXT);
|
|
@@ -260,7 +286,12 @@ export class NgHttpCachingService {
|
|
|
260
286
|
if (this.config.version !== entry.version) {
|
|
261
287
|
return false;
|
|
262
288
|
}
|
|
263
|
-
|
|
289
|
+
let fromHeader = true;
|
|
290
|
+
if (this.config.checkResponseHeaders) {
|
|
291
|
+
// check if response headers allow cache
|
|
292
|
+
fromHeader = checkCacheHeaders(entry.response.headers);
|
|
293
|
+
}
|
|
294
|
+
return entry.response.ok && fromHeader;
|
|
264
295
|
}
|
|
265
296
|
/**
|
|
266
297
|
* Return true if the request is cacheable
|
|
@@ -390,4 +421,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.2", ngImpor
|
|
|
390
421
|
}, {
|
|
391
422
|
type: Optional
|
|
392
423
|
}] }] });
|
|
393
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctaHR0cC1jYWNoaW5nLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1odHRwLWNhY2hpbmcvc3JjL2xpYi9uZy1odHRwLWNhY2hpbmcuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakcsT0FBTyxFQUF3QyxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUczRyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQzs7QUFJdEYsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBdUIsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBRTlGLE1BQU0sQ0FBQyxNQUFNLHdCQUF3QixHQUFHLENBQUMsS0FBMkIsRUFBRSxVQUF1QixJQUFJLFdBQVcsRUFBRSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixFQUFFLEtBQUssQ0FBQyxDQUFBO0FBeUI5SixNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxJQUFJLGNBQWMsQ0FDdEQsd0JBQXdCLENBQ3pCLENBQUM7QUFFRixNQUFNLENBQU4sSUFBWSxxQkFTWDtBQVRELFdBQVkscUJBQXFCO0lBQy9COztPQUVHO0lBQ0gsZ0RBQXVCLENBQUE7SUFDdkI7O09BRUc7SUFDSCxzREFBNkIsQ0FBQTtBQUMvQixDQUFDLEVBVFcscUJBQXFCLEtBQXJCLHFCQUFxQixRQVNoQztBQUVELE1BQU0sQ0FBTixJQUFZLG9CQWtCWDtBQWxCRCxXQUFZLG9CQUFvQjtJQUM5Qjs7T0FFRztJQUNILHFFQUE2QyxDQUFBO0lBQzdDOztPQUVHO0lBQ0gsMkVBQW1ELENB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biwgSW5qZWN0LCBPcHRpb25hbCwgVkVSU0lPTiwgaXNEZXZNb2RlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEh0dHBSZXF1ZXN0LCBIdHRwUmVzcG9uc2UsIEh0dHBFdmVudCwgSHR0cENvbnRleHRUb2tlbiwgSHR0cENvbnRleHQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzL2ludGVybmFsL09ic2VydmFibGUnO1xyXG5pbXBvcnQgeyBOZ0h0dHBDYWNoaW5nU3RvcmFnZUludGVyZmFjZSB9IGZyb20gJy4vc3RvcmFnZS9uZy1odHRwLWNhY2hpbmctc3RvcmFnZS5pbnRlcmZhY2UnO1xyXG5pbXBvcnQgeyBOZ0h0dHBDYWNoaW5nTWVtb3J5U3RvcmFnZSB9IGZyb20gJy4vc3RvcmFnZS9uZy1odHRwLWNhY2hpbmctbWVtb3J5LXN0b3JhZ2UnO1xyXG5cclxuZXhwb3J0IHR5cGUgTmdIdHRwQ2FjaGluZ0NvbnRleHQgPSBQaWNrPE5nSHR0cENhY2hpbmdDb25maWcsICdnZXRLZXknIHwgJ2lzQ2FjaGVhYmxlJyB8ICdpc0V4cGlyZWQnIHwgJ2lzVmFsaWQnPjtcclxuXHJcbmV4cG9ydCBjb25zdCBOR19IVFRQX0NBQ0hJTkdfQ09OVEVYVCA9IG5ldyBIdHRwQ29udGV4dFRva2VuPE5nSHR0cENhY2hpbmdDb250ZXh0PigoKSA9PiAoe30pKTtcclxuXHJcbmV4cG9ydCBjb25zdCB3aXRoTmdIdHRwQ2FjaGluZ0NvbnRleHQgPSAodmFsdWU6IE5nSHR0cENhY2hpbmdDb250ZXh0LCBjb250ZXh0OiBIdHRwQ29udGV4dCA9IG5ldyBIdHRwQ29udGV4dCgpKSA9PiBjb250ZXh0LnNldChOR19IVFRQX0NBQ0hJTkdfQ09OVEVYVCwgdmFsdWUpXHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIE5nSHR0cENhY2hpbmdFbnRyeTxLID0gYW55LCBUID0gYW55PiB7XHJcbiAgLyoqXHJcbiAgICogVVJMXHJcbiAgICovXHJcbiAgdXJsOiBzdHJpbmc7XHJcbiAgLyoqXHJcbiAgICogSHR0cFJlc3BvbnNlXHJcbiAgICovXHJcbiAgcmVzcG9uc2U6IEh0dHBSZXNwb25zZTxUPjtcclxuICAvKipcclxuICAgKiBIdHRwUmVxdWVzdFxyXG4gICAqL1xyXG4gIHJlcXVlc3Q6IEh0dHBSZXF1ZXN0PEs+O1xyXG4gIC8qKlxyXG4gICAqIFRpbWVzdGFtcCBvZiBhZGQgdG8gY2FjaGUgdGltZVxyXG4gICAqL1xyXG4gIGFkZGVkVGltZTogbnVtYmVyO1xyXG4gIC8qKlxyXG4gICAqIENhY2hlIHZlcnNpb25cclxuICAgKi9cclxuICB2ZXJzaW9uOiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBOR19IVFRQX0NBQ0hJTkdfQ09ORklHID0gbmV3IEluamVjdGlvblRva2VuPE5nSHR0cENhY2hpbmdDb250ZXh0PihcclxuICAnbmctaHR0cC1jYWNoaW5nLmNvbmZpZydcclxuKTtcclxuXHJcbmV4cG9ydCBlbnVtIE5nSHR0cENhY2hpbmdTdHJhdGVneSB7XHJcbiAgLyoqXHJcbiAgICogQWxsIHJlcXVlc3QgYXJlIGNhY2hlYWJsZSBpZiBIVFRQIG1ldGhvZCBpcyBpbnRvIGBhbGxvd2VkTWV0aG9kYFxyXG4gICAqL1xyXG4gIEFMTE9XX0FMTCA9ICdBTExPV19BTEwnLFxyXG4gIC8qKlxyXG4gICAqIE9ubHkgdGhlIHJlcXVlc3Qgd2l0aCBgWC1ORy1IVFRQLUNBQ0hJTkctQUxMT1ctQ0FDSEVgIGhlYWRlciBhcmUgY2FjaGVhYmxlIGlmIEhUVFAgbWV0aG9kIGlzIGludG8gYGFsbG93ZWRNZXRob2RgXHJcbiAgICovXHJcbiAgRElTQUxMT1dfQUxMID0gJ0RJU0FMTE9XX0FMTCdcclxufVxyXG5cclxuZXhwb3J0IGVudW0gTmdIdHRwQ2FjaGluZ0hlYWRlcnMge1xyXG4gIC8qKlxyXG4gICAqIFJlcXVlc3QgaXMgY2FjaGVhYmxlIGlmIEhUVFAgbWV0aG9kIGlzIGludG8gYGFsbG93ZWRNZXRob2RgXHJcbiAgICovXHJcbiAgQUxMT1dfQ0FDSEUgPSAnWC1ORy1IVFRQLUNBQ0hJTkctQUxMT1ctQ0FDSEUnLFxyXG4gIC8qKlxyXG4gICAqIFJlcXVlc3QgaXNuJ3QgY2FjaGVhYmxlXHJcbiAgICovXHJcbiAgRElTQUxMT1dfQ0FDSEUgPSAnWC1ORy1IVFRQLUNBQ0hJTkctRElTQUxMT1ctQ0FDSEUnLFxyXG4gIC8qKlxyXG4gICAqIFNwZWNpZmljIGNhY2hlIGxpZmV0aW1lIGZvciB0aGUgcmVxdWVzdFxyXG4gICAqL1xyXG4gIExJRkVUSU1FID0gJ1gtTkctSFRUUC1DQUNISU5HLUxJRkVUSU1FJyxcclxuICAvKipcclxuICAgKiBZb3UgY2FuIHRhZyBtdWx0aXBsZSByZXF1ZXN0IGJ5IGFkZGluZyB0aGlzIGhlYWRlciB3aXRoIHRoZSBzYW1lIHRhZyBhbmQgXHJcbiAgICogdXNpbmcgYE5nSHR0cENhY2hpbmdTZXJ2aWNlLmNsZWFyQ2FjaGVCeVRhZyh0YWc6IHN0cmluZylgIGZvciBkZWxldGUgYWxsIHRoZSB0YWdnZWQgcmVxdWVzdFxyXG4gICAqL1xyXG4gIFRBRyA9ICdYLU5HLUhUVFAtQ0FDSElORy1UQUcnXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBOZ0h0dHBDYWNoaW5nSGVhZGVyc0xpc3QgPSBPYmplY3QudmFsdWVzKE5nSHR0cENhY2hpbmdIZWFkZXJzKTtcclxuXHJcbmV4cG9ydCBjb25zdCBOR19IVFRQX0NBQ0hJTkdfU0VDT05EX0lOX01TID0gMTAwMDtcclxuZXhwb3J0IGNvbnN0IE5HX0hUVFBfQ0FDSElOR19NSU5VVEVfSU5fTVMgPSBOR19IVFRQX0NBQ0hJTkdfU0VDT05EX0lOX01TICogNjA7XHJcbmV4cG9ydCBjb25zdCBOR19IVFRQX0NBQ0hJTkdfSE9VUl9JTl9NUyA9IE5HX0hUVFBfQ0FDSElOR19NSU5VVEVfSU5fTVMgKiA2MDtcclxuZXhwb3J0IGNvbnN0IE5HX0hUVFBfQ0FDSElOR19EQVlfSU5fTVMgPSBOR19IVFRQX0NBQ0hJTkdfSE9VUl9JTl9NUyAqIDI0O1xyXG5leHBvcnQgY29uc3QgTkdfSFRUUF9DQUNISU5HX1dFRUtfSU5fTVMgPSBOR19IVFRQX0NBQ0hJTkdfREFZX0lOX01TICogNztcclxuZXhwb3J0IGNvbnN0IE5HX0hUVFBfQ0FDSElOR19NT05USF9JTl9NUyA9IE5HX0hUVFBfQ0FDSElOR19EQVlfSU5fTVMgKiAzMDtcclxuZXhwb3J0IGNvbnN0IE5HX0hUVFBfQ0FDSElOR19ZRUFSX0lOX01TID0gTkdfSFRUUF9DQUNISU5HX0RBWV9JTl9NUyAqIDM2NTtcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTmdIdHRwQ2FjaGluZ0NvbmZpZyB7XHJcbiAgLyoqXHJcbiAgICogU2V0IHRoZSBjYWNoZSBzdG9yZS4gWW91IGNhbiBpbXBsZW1lbnQgeW91ciBjdXN0b20gc3RvcmUgYnkgaW1wbGVtZW50IHRoZSBgTmdIdHRwQ2FjaGluZ1N0b3JhZ2VJbnRlcmZhY2VgIGludGVyZmFjZSwgZWcuOlxyXG4gICAqL1xyXG4gIHN0b3JlPzogTmdIdHRwQ2FjaGluZ1N0b3JhZ2VJbnRlcmZhY2U7XHJcbiAgLyoqXHJcbiAgICogTnVtYmVyIG9mIG1pbGxpc2Vjb25kIHRoYXQgYSByZXNwb25zZSBpcyBzdG9yZWQgaW4gdGhlIGNhY2hlLiBcclxuICAgKiBZb3UgY2FuIHNldCBzcGVjaWZpYyBcImxpZmV0aW1lXCIgZm9yIGVhY2ggcmVxdWVzdCBieSBhZGQgdGhlIGhlYWRlciBgWC1ORy1IVFRQLUNBQ0hJTkctTElGRVRJTUVgIChzZWUgZXhhbXBsZSBiZWxvdykuXHJcbiAgICovXHJcbiAgbGlmZXRpbWU/OiBudW1iZXI7XHJcbiAgLyoqXHJcbiAgICogQXJyYXkgb2YgYWxsb3dlZCBIVFRQIG1ldGhvZHMgdG8gY2FjaGUuIFxyXG4gICAqIFlvdSBjYW4gYWxsb3cgbXVsdGlwbGUgbWV0aG9kcywgZWcuOiBgWydHRVQnLCAnUE9TVCcsICdQVVQnLCAnREVMRVRFJywgJ0hFQUQnXWAgb3IgXHJcbiAgICogYWxsb3cgYWxsIG1ldGhvZHMgYnk6IGBbJ0FMTCddYC4gSWYgYGFsbG93ZWRNZXRob2RgIGlzIGFuIGVtcHR5IGFycmF5IChgW11gKSwgbm8gcmVzcG9uc2UgYXJlIGNhY2hlZC5cclxuICAgKiAqV2FybmluZyEqIGBOZ0h0dHBDYWNoaW5nYCB1c2UgdGhlIGZ1bGwgdXJsICh1cmwgd2l0aCBxdWVyeSBwYXJhbWV0ZXJzKSBhcyB1bmlxdWUga2V5IGZvciB0aGUgY2FjaGVkIHJlc3BvbnNlLFxyXG4gICAqIHRoaXMgaXMgY29ycmVjdCBmb3IgdGhlIGBHRVRgIHJlcXVlc3QgYnV0IGlzIF9wb3RlbnRpYWxseV8gd3JvbmcgZm9yIG90aGVyIHR5cGUgb2YgcmVxdWVzdCAoZWcuIGBQT1NUYCwgYFBVVGApLiBcclxuICAgKiBZb3UgY2FuIHNldCBhIGRpZmZlcmVudCBcImtleVwiIGJ5IGN1c3RvbWl6aW5nIHRoZSBgZ2V0S2V5YCBjb25maWcgbWV0aG9kIChzZWUgYGdldEtleWAgc2VjdGlvbikuXHJcbiAgICovXHJcbiAgYWxsb3dlZE1ldGhvZD86IHN0cmluZ1tdO1xyXG4gIC8qKlxyXG4gICAqIFNldCB0aGUgY2FjaGUgc3RyYXRlZ3ksIHBvc3NpYmxlIHN0cmF0ZWdpZXMgYXJlOlxyXG4gICAqIC0gYE5nSHR0cENhY2hpbmdTdHJhdGVneS5BTExPV19BTExgOiBBbGwgcmVxdWVzdCBhcmUgY2FjaGVhYmxlIGlmIEhUVFAgbWV0aG9kIGlzIGludG8gYGFsbG93ZWRNZXRob2RgO1xyXG4gICAqIC0gYE5nSHR0cENhY2hpbmdTdHJhdGVneS5ESVNBTExPV19BTExgOiBPbmx5IHRoZSByZXF1ZXN0IHdpdGggYFgtTkctSFRUUC1DQUNISU5HLUFMTE9XLUNBQ0hFYCBoZWFkZXIgYXJlIGNhY2hlYWJsZSBpZiBIVFRQIG1ldGhvZCBpcyBpbnRvIGBhbGxvd2VkTWV0aG9kYDtcclxuICAgKi9cclxuICBjYWNoZVN0cmF0ZWd5PzogTmdIdHRwQ2FjaGluZ1N0cmF0ZWd5O1xyXG4gIC8qKlxyXG4gICAqIENhY2hlIHZlcnNpb24uIFdoZW4geW91IGhhdmUgYSBicmVha2luZyBjaGFuZ2UsIGNoYW5nZSB0aGUgdmVyc2lvbiwgYW5kIGl0J2xsIGRlbGV0ZSB0aGUgY3VycmVudCBjYWNoZSBhdXRvbWF0aWNhbGx5LlxyXG4gICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIEFuZ3VsYXIgbWFqb3IgdmVyc2lvbiAoZWcuIDEzKSwgaW4gdGhpcyB3YXksIHRoZSBjYWNoZSBpcyBpbnZhbGlkYXRlZCBvbiBldmVyeSBBbmd1bGFyIHVwZ3JhZGUuXHJcbiAgICovXHJcbiAgdmVyc2lvbj86IHN0cmluZztcclxuICAvKipcclxuICAgKiBJZiB0aGlzIGZ1bmN0aW9uIHJldHVybiBgdHJ1ZWAgdGhlIHJlcXVlc3QgaXMgZXhwaXJlZCBhbmQgYSBuZXcgcmVxdWVzdCBpcyBzZW5kIHRvIGJhY2tlbmQsIGlmIHJldHVybiBgZmFsc2VgIGlzbid0IGV4cGlyZWQuIFxyXG4gICAqIElmIHRoZSByZXN1bHQgaXMgYHVuZGVmaW5lZGAsIHRoZSBub3JtYWwgYmVoYXZpb3VyIGlzIHByb3ZpZGVkLlxyXG4gICAqL1xyXG4gIGlzRXhwaXJlZD86IDxLLCBUPihlbnRyeTogTmdIdHRwQ2FjaGluZ0VudHJ5PEssIFQ+KSA9PiBib29sZWFuIHwgdW5kZWZpbmVkIHwgdm9pZDtcclxuICAvKipcclxuICAgKiBJZiB0aGlzIGZ1bmN0aW9uIHJldHVybiBgdHJ1ZWAgdGhlIHJlcXVlc3QgaXMgY2FjaGVhYmxlLCBpZiByZXR1cm4gYGZhbHNlYCBpc24ndCBjYWNoZWFibGUuIFxyXG4gICAqIElmIHRoZSByZXN1bHQgaXMgYHVuZGVmaW5lZGAsIHRoZSBub3JtYWwgYmVoYXZpb3VyIGlzIHByb3ZpZGVkLlxyXG4gICAqL1xyXG4gIGlzQ2FjaGVhYmxlPzogPEs+KHJlcTogSHR0cFJlcXVlc3Q8Sz4pID0+IGJvb2xlYW4gfCB1bmRlZmluZWQgfCB2b2lkO1xyXG4gIC8qKlxyXG4gICAqIFRoaXMgZnVuY3Rpb24gcmV0dXJuIHRoZSB1bmlxdWUga2V5IChgc3RyaW5nYCkgZm9yIHN0b3JlIHRoZSByZXNwb25zZSBpbnRvIHRoZSBjYWNoZS4gXHJcbiAgICogSWYgdGhlIHJlc3VsdCBpcyBgdW5kZWZpbmVkYCwgdGhlIG5vcm1hbCBiZWhhdmlvdXIgaXMgcHJvdmlkZWQuXHJcbiAgICovXHJcbiAgZ2V0S2V5PzogPEs+KHJlcTogSHR0cFJlcXVlc3Q8Sz4pID0+IHN0cmluZyB8IHVuZGVmaW5lZCB8IHZvaWQ7XHJcbiAgLyoqXHJcbiAgICogSWYgdGhpcyBmdW5jdGlvbiByZXR1cm4gYHRydWVgIHRoZSBjYWNoZSBlbnRyeSBpcyB2YWxpZCBhbmQgY2FuIGJlIHN0b3JlZCwgaWYgcmV0dXJuIGBmYWxzZWAgaXNuJ3QgdmFsaWQuIFxyXG4gICAqIElmIHRoZSByZXN1bHQgaXMgYHVuZGVmaW5lZGAsIHRoZSBub3JtYWwgYmVoYXZpb3VyIGlzIHByb3ZpZGVkLlxyXG4gICAqL1xyXG4gIGlzVmFsaWQ/OiA8SywgVD4oZW50cnk6IE5nSHR0cENhY2hpbmdFbnRyeTxLLCBUPikgPT4gYm9vbGVhbiB8IHVuZGVmaW5lZCB8IHZvaWQ7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTmdIdHRwQ2FjaGluZ0RlZmF1bHRDb25maWcgZXh0ZW5kcyBOZ0h0dHBDYWNoaW5nQ29uZmlnIHtcclxuICBzdG9yZTogTmdIdHRwQ2FjaGluZ1N0b3JhZ2VJbnRlcmZhY2U7XHJcbiAgbGlmZXRpbWU6IG51bWJlcjtcclxuICBhbGxvd2VkTWV0aG9kOiBzdHJpbmdbXTtcclxuICBjYWNoZVN0cmF0ZWd5OiBOZ0h0dHBDYWNoaW5nU3RyYXRlZ3k7XHJcbiAgdmVyc2lvbjogc3RyaW5nO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgTmdIdHRwQ2FjaGluZ0NvbmZpZ0RlZmF1bHQ6IFJlYWRvbmx5PE5nSHR0cENhY2hpbmdEZWZhdWx0Q29uZmlnPiA9IHtcclxuICBzdG9yZTogbmV3IE5nSHR0cENhY2hpbmdNZW1vcnlTdG9yYWdlKCksXHJcbiAgbGlmZXRpbWU6IE5HX0hUVFBfQ0FDSElOR19IT1VSX0lOX01TLFxyXG4gIHZlcnNpb246IFZFUlNJT04ubWFqb3IsXHJcbiAgYWxsb3dlZE1ldGhvZDogWydHRVQnLCAnSEVBRCddLFxyXG4gIGNhY2hlU3RyYXRlZ3k6IE5nSHR0cENhY2hpbmdTdHJhdGVneS5BTExPV19BTEwsXHJcbn07XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBOZ0h0dHBDYWNoaW5nU2VydmljZSB7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgcXVldWUgPSBuZXcgTWFwPHN0cmluZywgT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4+KCk7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgY29uZmlnOiBOZ0h0dHBDYWNoaW5nRGVmYXVsdENvbmZpZztcclxuXHJcbiAgcHJpdmF0ZSBnY0xvY2sgPSBmYWxzZTtcclxuXHJcbiAgcHJpdmF0ZSBkZXZNb2RlOiBib29sZWFuID0gaXNEZXZNb2RlKCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgQEluamVjdChOR19IVFRQX0NBQ0hJTkdfQ09ORklHKSBAT3B0aW9uYWwoKSBjb25maWc6IFJlYWRvbmx5PE5nSHR0cENhY2hpbmdDb25maWc+XHJcbiAgKSB7XHJcbiAgICBpZiAoY29uZmlnKSB7XHJcbiAgICAgIHRoaXMuY29uZmlnID0geyAuLi5OZ0h0dHBDYWNoaW5nQ29uZmlnRGVmYXVsdCwgLi4uY29uZmlnIH07XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmNvbmZpZyA9IHsgLi4uTmdIdHRwQ2FjaGluZ0NvbmZpZ0RlZmF1bHQgfTtcclxuICAgIH1cclxuICAgIC8vIHN0YXJ0IGNhY2hlIGNsZWFuXHJcbiAgICB0aGlzLnJ1bkdjKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gdGhlIGNvbmZpZ1xyXG4gICAqL1xyXG4gIGdldENvbmZpZygpOiBSZWFkb25seTxOZ0h0dHBDYWNoaW5nQ29uZmlnPiB7XHJcbiAgICByZXR1cm4gdGhpcy5jb25maWc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gdGhlIHF1ZXVlIG1hcFxyXG4gICAqL1xyXG4gIGdldFF1ZXVlKCk6IFJlYWRvbmx5PE1hcDxzdHJpbmcsIE9ic2VydmFibGU8SHR0cEV2ZW50PGFueT4+Pj4ge1xyXG4gICAgcmV0dXJuIHRoaXMucXVldWU7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gdGhlIGNhY2hlIHN0b3JlXHJcbiAgICovXHJcbiAgZ2V0U3RvcmUoKTogUmVhZG9ubHk8TmdIdHRwQ2FjaGluZ1N0b3JhZ2VJbnRlcmZhY2U+IHtcclxuICAgIHJldHVybiB0aGlzLmNvbmZpZy5zdG9yZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybiByZXNwb25zZSBmcm9tIGNhY2hlXHJcbiAgICovXHJcbiAgZ2V0RnJvbUNhY2hlPEssIFQ+KHJlcTogSHR0cFJlcXVlc3Q8Sz4pOiBSZWFkb25seTxIdHRwUmVzcG9uc2U8VD4+IHwgdW5kZWZpbmVkIHtcclxuICAgIGNvbnN0IGtleTogc3RyaW5nID0gdGhpcy5nZXRLZXkocmVxKTtcclxuICAgIGNvbnN0IGNhY2hlZDogTmdIdHRwQ2FjaGluZ0VudHJ5PEssIFQ+IHwgdW5kZWZpbmVkID0gdGhpcy5jb25maWcuc3RvcmUuZ2V0PEssIFQ+KGtleSk7XHJcblxyXG4gICAgaWYgKCFjYWNoZWQpIHtcclxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5pc0V4cGlyZWQoY2FjaGVkKSkge1xyXG4gICAgICB0aGlzLmNsZWFyQ2FjaGVCeUtleShrZXkpO1xyXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLmRlZXBGcmVlemUoY2FjaGVkLnJlc3BvbnNlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZCByZXNwb25zZSB0byBjYWNoZVxyXG4gICAqL1xyXG4gIGFkZFRvQ2FjaGU8SywgVD4ocmVxOiBIdHRwUmVxdWVzdDxLPiwgcmVzOiBIdHRwUmVzcG9uc2U8VD4pOiBib29sZWFuIHtcclxuICAgIGNvbnN0IGVudHJ5OiBOZ0h0dHBDYWNoaW5nRW50cnk8SywgVD4gPSB7XHJcbiAgICAgIHVybDogcmVxLnVybFdpdGhQYXJhbXMsXHJcbiAgICAgIHJlc3BvbnNlOiByZXMsXHJcbiAgICAgIHJlcXVlc3Q6IHJlcSxcclxuICAgICAgYWRkZWRUaW1lOiBEYXRlLm5vdygpLFxyXG4gICAgICB2ZXJzaW9uOiB0aGlzLmNvbmZpZy52ZXJzaW9uLFxyXG4gICAgfTtcclxuICAgIGlmICh0aGlzLmlzVmFsaWQoZW50cnkpKSB7XHJcbiAgICAgIGNvbnN0IGtleTogc3RyaW5nID0gdGhpcy5nZXRLZXkocmVxKTtcclxuICAgICAgdGhpcy5jb25maWcuc3RvcmUuc2V0KGtleSwgZW50cnkpO1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlbGV0ZSByZXNwb25zZSBmcm9tIGNhY2hlXHJcbiAgICovXHJcbiAgZGVsZXRlRnJvbUNhY2hlPEs+KHJlcTogSHR0cFJlcXVlc3Q8Sz4pOiBib29sZWFuIHtcclxuICAgIGNvbnN0IGtleTogc3RyaW5nID0gdGhpcy5nZXRLZXkocmVxKTtcclxuICAgIHJldHVybiB0aGlzLmNsZWFyQ2FjaGVCeUtleShrZXkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2xlYXIgdGhlIGNhY2hlXHJcbiAgICovXHJcbiAgY2xlYXJDYWNoZSgpOiB2b2lkIHtcclxuICAgIHRoaXMuY29uZmlnLnN0b3JlLmNsZWFyKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDbGVhciB0aGUgY2FjaGUgYnkga2V5XHJcbiAgICovXHJcbiAgY2xlYXJDYWNoZUJ5S2V5KGtleTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5jb25maWcuc3RvcmUuZGVsZXRlKGtleSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDbGVhciB0aGUgY2FjaGUgYnkga2V5c1xyXG4gICAqL1xyXG4gIGNsZWFyQ2FjaGVCeUtleXMoa2V5czogQXJyYXk8c3RyaW5nPik6IG51bWJlciB7XHJcbiAgICBsZXQgY291bnRlciA9IDA7XHJcbiAgICBpZiAoa2V5cykge1xyXG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY2xlYXJDYWNoZUJ5S2V5KGtleSkpIHtcclxuICAgICAgICAgIGNvdW50ZXIrKztcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBjb3VudGVyO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2xlYXIgdGhlIGNhY2hlIGJ5IHJlZ2V4XHJcbiAgICovXHJcbiAgY2xlYXJDYWNoZUJ5UmVnZXg8SywgVD4ocmVnZXg6IFJlZ0V4cCk6IG51bWJlciB7XHJcbiAgICBjb25zdCBrZXlzOiBBcnJheTxzdHJpbmc+ID0gW107XHJcbiAgICB0aGlzLmNvbmZpZy5zdG9yZS5mb3JFYWNoPEssIFQ+KChfOiBOZ0h0dHBDYWNoaW5nRW50cnk8SywgVD4sIGtleTogc3RyaW5nKSA9PiB7XHJcbiAgICAgIGlmIChyZWdleC50ZXN0KGtleSkpIHtcclxuICAgICAgICBrZXlzLnB1c2goa2V5KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdGhpcy5jbGVhckNhY2hlQnlLZXlzKGtleXMpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2xlYXIgdGhlIGNhY2hlIGJ5IFRBR1xyXG4gICAqL1xyXG4gIGNsZWFyQ2FjaGVCeVRhZzxLLCBUPih0YWc6IHN0cmluZyk6IG51bWJlciB7XHJcbiAgICBjb25zdCBrZXlzOiBBcnJheTxzdHJpbmc+ID0gW107XHJcbiAgICB0aGlzLmNvbmZpZy5zdG9yZS5mb3JFYWNoPEssIFQ+KChlbnRyeTogTmdIdHRwQ2FjaGluZ0VudHJ5PEssIFQ+LCBrZXk6IHN0cmluZykgPT4ge1xyXG4gICAgICBjb25zdCB0YWdIZWFkZXIgPSBlbnRyeS5yZXF1ZXN0LmhlYWRlcnMuZ2V0KE5nSHR0cENhY2hpbmdIZWFkZXJzLlRBRyk7XHJcbiAgICAgIGlmICh0YWdIZWFkZXIgJiYgdGFnSGVhZGVyLnNwbGl0KCcsJykuaW5jbHVkZXModGFnKSkge1xyXG4gICAgICAgIGtleXMucHVzaChrZXkpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIHJldHVybiB0aGlzLmNsZWFyQ2FjaGVCeUtleXMoa2V5cyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSdW4gZ2FyYmFnZSBjb2xsZWN0b3IgKGRlbGV0ZSBleHBpcmVkIGNhY2hlIGVudHJ5KVxyXG4gICAqL1xyXG4gIHJ1bkdjPEssIFQ+KCk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKHRoaXMuZ2NMb2NrKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIHRoaXMuZ2NMb2NrID0gdHJ1ZTtcclxuICAgIGNvbnN0IGtleXM6IEFycmF5PHN0cmluZz4gPSBbXTtcclxuICAgIHRoaXMuY29uZmlnLnN0b3JlLmZvckVhY2g8SywgVD4oKGVudHJ5OiBOZ0h0dHBDYWNoaW5nRW50cnk8SywgVD4sIGtleTogc3RyaW5nKSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLmlzRXhwaXJlZChlbnRyeSkpIHtcclxuICAgICAgICBrZXlzLnB1c2goa2V5KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICB0aGlzLmNsZWFyQ2FjaGVCeUtleXMoa2V5cyk7XHJcbiAgICB0aGlzLmdjTG9jayA9IGZhbHNlO1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gdHJ1ZSBpZiBjYWNoZSBlbnRyeSBpcyBleHBpcmVkXHJcbiAgICovXHJcbiAgaXNFeHBpcmVkPEssIFQ+KGVudHJ5OiBOZ0h0dHBDYWNoaW5nRW50cnk8SywgVD4pOiBib29sZWFuIHtcclxuICAgIC8vIGlmIHVzZXIgcHJvdmlkZSBjdXN0b20gbWV0aG9kLCB1c2UgaXRcclxuICAgIGNvbnN0IGNvbnRleHQgPSBlbnRyeS5yZXF1ZXN0LmNvbnRleHQuZ2V0KE5HX0hUVFBfQ0FDSElOR19DT05URVhUKTtcclxuICAgIGlmICh0eXBlb2YgY29udGV4dD8uaXNFeHBpcmVkID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnRleHQuaXNFeHBpcmVkKGVudHJ5KTtcclxuICAgICAgLy8gaWYgcmVzdWx0IGlzIHVuZGVmaW5lZCwgbm9ybWFsIGJlaGF2aW91ciBpcyBwcm92aWRlZFxyXG4gICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBpZiB1c2VyIHByb3ZpZGUgY3VzdG9tIG1ldGhvZCwgdXNlIGl0XHJcbiAgICBpZiAodHlwZW9mIHRoaXMuY29uZmlnLmlzRXhwaXJlZCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmNvbmZpZy5pc0V4cGlyZWQoZW50cnkpO1xyXG4gICAgICAvLyBpZiByZXN1bHQgaXMgdW5kZWZpbmVkLCBub3JtYWwgYmVoYXZpb3VyIGlzIHByb3ZpZGVkXHJcbiAgICAgIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIGlmIHZlcnNpb24gY2hhbmdlLCBhbHdheXMgZXhwaXJlXHJcbiAgICBpZiAodGhpcy5jb25maWcudmVyc2lvbiAhPT0gZW50cnkudmVyc2lvbikge1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuICAgIC8vIGNvbmZpZy9kZWZhdWx0IGxpZmV0aW1lXHJcbiAgICBsZXQgbGlmZXRpbWU6IG51bWJlciA9IHRoaXMuY29uZmlnLmxpZmV0aW1lO1xyXG4gICAgLy8gcmVxdWVzdCBoYXMgb3duIGxpZmV0aW1lXHJcbiAgICBjb25zdCBoZWFkZXJMaWZldGltZSA9IGVudHJ5LnJlcXVlc3QuaGVhZGVycy5nZXQoTmdIdHRwQ2FjaGluZ0hlYWRlcnMuTElGRVRJTUUpO1xyXG4gICAgaWYgKGhlYWRlckxpZmV0aW1lKSB7XHJcbiAgICAgIGxpZmV0aW1lID0gK2hlYWRlckxpZmV0aW1lO1xyXG4gICAgfVxyXG4gICAgLy8gbmV2ZXIgZXhwaXJlIGlmIDBcclxuICAgIGlmIChsaWZldGltZSA9PT0gMCkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICAvLyB3cm9uZyBsaWZldGltZVxyXG4gICAgaWYgKGxpZmV0aW1lIDwgMCB8fCBpc05hTihsaWZldGltZSkpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsaWZldGltZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCAwJyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZW50cnkuYWRkZWRUaW1lICsgbGlmZXRpbWUgPCBEYXRlLm5vdygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJuIHRydWUgaWYgY2FjaGUgZW50cnkgaXMgdmFsaWQgZm9yIHN0b3JlIGluIHRoZSBjYWNoZVxyXG4gICAqIERlZmF1bHQgYmVoYXZpb3VyIGlzIHdoZXRoZXIgdGhlIHN0YXR1cyBjb2RlIGZhbGxzIGluIHRoZSAyeHggcmFuZ2UuXHJcbiAgICovXHJcbiAgaXNWYWxpZDxLLCBUPihlbnRyeTogTmdIdHRwQ2FjaGluZ0VudHJ5PEssIFQ+KTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBjb250ZXh0ID0gZW50cnkucmVxdWVzdC5jb250ZXh0LmdldChOR19IVFRQX0NBQ0hJTkdfQ09OVEVYVCk7XHJcbiAgICAvLyBpZiB1c2VyIHByb3ZpZGUgY3VzdG9tIG1ldGhvZCwgdXNlIGl0XHJcbiAgICBpZiAodHlwZW9mIGNvbnRleHQuaXNWYWxpZCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICBjb25zdCByZXN1bHQgPSBjb250ZXh0LmlzVmFsaWQoZW50cnkpO1xyXG4gICAgICAvLyBpZiByZXN1bHQgaXMgdW5kZWZpbmVkLCBub3JtYWwgYmVoYXZpb3VyIGlzIHByb3ZpZGVkXHJcbiAgICAgIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIGlmIHVzZXIgcHJvdmlkZSBjdXN0b20gbWV0aG9kLCB1c2UgaXRcclxuICAgIGlmICh0eXBlb2YgdGhpcy5jb25maWcuaXNWYWxpZCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmNvbmZpZy5pc1ZhbGlkKGVudHJ5KTtcclxuICAgICAgLy8gaWYgcmVzdWx0IGlzIHVuZGVmaW5lZCwgbm9ybWFsIGJlaGF2aW91ciBpcyBwcm92aWRlZFxyXG4gICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBkaWZmZXJlbnQgdmVyc2lvblxyXG4gICAgaWYgKHRoaXMuY29uZmlnLnZlcnNpb24gIT09IGVudHJ5LnZlcnNpb24pIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGVudHJ5LnJlc3BvbnNlLm9rO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJuIHRydWUgaWYgdGhlIHJlcXVlc3QgaXMgY2FjaGVhYmxlXHJcbiAgICovXHJcbiAgaXNDYWNoZWFibGU8Sz4ocmVxOiBIdHRwUmVxdWVzdDxLPik6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgY29udGV4dCA9IHJlcS5jb250ZXh0LmdldChOR19IVFRQX0NBQ0hJTkdfQ09OVEVYVCk7XHJcbiAgICAvLyBpZiB1c2VyIHByb3ZpZGUgY3VzdG9tIG1ldGhvZCwgdXNlIGl0XHJcbiAgICBpZiAodHlwZW9mIGNvbnRleHQ/LmlzQ2FjaGVhYmxlID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnRleHQuaXNDYWNoZWFibGUocmVxKTtcclxuICAgICAgLy8gaWYgcmVzdWx0IGlzIHVuZGVmaW5lZCwgbm9ybWFsIGJlaGF2aW91ciBpcyBwcm92aWRlZFxyXG4gICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBpZiB1c2VyIHByb3ZpZGUgY3VzdG9tIG1ldGhvZCwgdXNlIGl0XHJcbiAgICBpZiAodHlwZW9mIHRoaXMuY29uZmlnLmlzQ2FjaGVhYmxlID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuY29uZmlnLmlzQ2FjaGVhYmxlKHJlcSk7XHJcbiAgICAgIC8vIGlmIHJlc3VsdCBpcyB1bmRlZmluZWQsIG5vcm1hbCBiZWhhdmlvdXIgaXMgcHJvdmlkZWRcclxuICAgICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gcmVxdWVzdCBoYXMgZGlzYWxsb3cgY2FjaGUgaGVhZGVyXHJcbiAgICBpZiAocmVxLmhlYWRlcnMuaGFzKE5nSHR0cENhY2hpbmdIZWFkZXJzLkRJU0FMTE9XX0NBQ0hFKSkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICAvLyBzdHJhdGVneSBpcyBkaXNhbGxvdyBhbGwuLi5cclxuICAgIGlmICh0aGlzLmNvbmZpZy5jYWNoZVN0cmF0ZWd5ID09PSBOZ0h0dHBDYWNoaW5nU3RyYXRlZ3kuRElTQUxMT1dfQUxMKSB7XHJcbiAgICAgIC8vIHJlcXVlc3QgaXNuJ3QgYWxsb3dlZCBpZiBjb21lIHdpdGhvdXQgYWxsb3cgaGVhZGVyXHJcbiAgICAgIGlmICghcmVxLmhlYWRlcnMuaGFzKE5nSHR0cENhY2hpbmdIZWFkZXJzLkFMTE9XX0NBQ0hFKSkge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gaWYgYWxsb3dlZCBtZXRob2QgaXMgb25seSBBTEwsIGFsbG93IGFsbCBodHRwIG1ldGhvZHNcclxuICAgIGlmICh0aGlzLmNvbmZpZy5hbGxvd2VkTWV0aG9kLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICBpZiAodGhpcy5jb25maWcuYWxsb3dlZE1ldGhvZFswXSA9PT0gJ0FMTCcpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gcmVxdWVzdCBpcyBhbGxvd2VkIGlmIG1ldGhvZCBpcyBpbiBhbGxvd2VkTWV0aG9kXHJcbiAgICByZXR1cm4gdGhpcy5jb25maWcuYWxsb3dlZE1ldGhvZC5pbmRleE9mKHJlcS5tZXRob2QpICE9PSAtMTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybiB0aGUgY2FjaGUga2V5LlxyXG4gICAqIERlZmF1bHQga2V5IGlzIGh0dHAgbWV0aG9kIHBsdXMgdXJsIHdpdGggcXVlcnkgcGFyYW1ldGVycywgZWcuOlxyXG4gICAqIGBHRVRAaHR0cHM6Ly9naXRodWIuY29tL25pZ3Jvc2ltb25lL25nLWh0dHAtY2FjaGluZ2BcclxuICAgKi9cclxuICBnZXRLZXk8Sz4ocmVxOiBIdHRwUmVxdWVzdDxLPik6IHN0cmluZyB7XHJcbiAgICAvLyBpZiB1c2VyIHByb3ZpZGUgY3VzdG9tIG1ldGhvZCwgdXNlIGl0XHJcbiAgICBjb25zdCBjb250ZXh0ID0gcmVxLmNvbnRleHQuZ2V0KE5HX0hUVFBfQ0FDSElOR19DT05URVhUKTtcclxuICAgIGlmICh0eXBlb2YgY29udGV4dC5nZXRLZXkgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgY29uc3QgcmVzdWx0ID0gY29udGV4dC5nZXRLZXkocmVxKTtcclxuICAgICAgLy8gaWYgcmVzdWx0IGlzIHVuZGVmaW5lZCwgbm9ybWFsIGJlaGF2aW91ciBpcyBwcm92aWRlZFxyXG4gICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBpZiB1c2VyIHByb3ZpZGUgY3VzdG9tIG1ldGhvZCwgdXNlIGl0XHJcbiAgICBpZiAodHlwZW9mIHRoaXMuY29uZmlnLmdldEtleSA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmNvbmZpZy5nZXRLZXkocmVxKTtcclxuICAgICAgLy8gaWYgcmVzdWx0IGlzIHVuZGVmaW5lZCwgbm9ybWFsIGJlaGF2aW91ciBpcyBwcm92aWRlZFxyXG4gICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBkZWZhdWx0IGtleSBpcyByZXEubWV0aG9kIHBsdXMgdXJsIHdpdGggcXVlcnkgcGFyYW1ldGVyc1xyXG4gICAgcmV0dXJuIHJlcS5tZXRob2QgKyAnQCcgKyByZXEudXJsV2l0aFBhcmFtcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybiBvYnNlcnZhYmxlIGZyb20gY2FjaGVcclxuICAgKi9cclxuICBnZXRGcm9tUXVldWU8SywgVD4ocmVxOiBIdHRwUmVxdWVzdDxLPik6IE9ic2VydmFibGU8SHR0cEV2ZW50PFQ+PiB8IHVuZGVmaW5lZCB7XHJcbiAgICBjb25zdCBrZXk6IHN0cmluZyA9IHRoaXMuZ2V0S2V5KHJlcSk7XHJcbiAgICBjb25zdCBjYWNoZWQ6IE9ic2VydmFibGU8SHR0cEV2ZW50PFQ+PiB8IHVuZGVmaW5lZCA9IHRoaXMucXVldWUuZ2V0KGtleSk7XHJcblxyXG4gICAgaWYgKCFjYWNoZWQpIHtcclxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gY2FjaGVkO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQWRkIG9ic2VydmFibGUgdG8gY2FjaGVcclxuICAgKi9cclxuICBhZGRUb1F1ZXVlPEssIFQ+KHJlcTogSHR0cFJlcXVlc3Q8Sz4sIG9iczogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8VD4+KTogdm9pZCB7XHJcbiAgICBjb25zdCBrZXk6IHN0cmluZyA9IHRoaXMuZ2V0S2V5KHJlcSk7XHJcbiAgICB0aGlzLnF1ZXVlLnNldChrZXksIG9icyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBEZWxldGUgb2JzZXJ2YWJsZSBmcm9tIGNhY2hlXHJcbiAgICovXHJcbiAgZGVsZXRlRnJvbVF1ZXVlPEs+KHJlcTogSHR0cFJlcXVlc3Q8Sz4pOiBib29sZWFuIHtcclxuICAgIGNvbnN0IGtleTogc3RyaW5nID0gdGhpcy5nZXRLZXkocmVxKTtcclxuICAgIHJldHVybiB0aGlzLnF1ZXVlLmRlbGV0ZShrZXkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVjdXJzaXZlbHkgT2JqZWN0LmZyZWV6ZSBzaW1wbGUgSmF2YXNjcmlwdCBzdHJ1Y3R1cmVzIGNvbnNpc3Rpbmcgb2YgcGxhaW4gb2JqZWN0cywgYXJyYXlzLCBhbmQgcHJpbWl0aXZlcy5cclxuICAgKiBNYWtlIHRoZSBkYXRhIGltbXV0YWJsZS5cclxuICAgKiBAcmV0dXJucyBpbW11dGFibGUgb2JqZWN0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBkZWVwRnJlZXplPFM+KG9iamVjdDogUyk6IFJlYWRvbmx5PFM+IHtcclxuICAgIC8vIE5vIGZyZWV6aW5nIGluIHByb2R1Y3Rpb24gKGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UpLlxyXG4gICAgaWYgKCF0aGlzLmRldk1vZGUgfHwgIW9iamVjdCB8fCB0eXBlb2Ygb2JqZWN0ICE9PSAnb2JqZWN0Jykge1xyXG4gICAgICByZXR1cm4gb2JqZWN0IGFzIFJlYWRvbmx5PFM+O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFdoZW4gYWxyZWFkeSBmcm96ZW4sIHdlIGFzc3VtZSBpdHMgY2hpbGRyZW4gYXJlIGZyb3plbiAoZm9yIGJldHRlciBwZXJmb3JtYW5jZSkuXHJcbiAgICAvLyBUaGlzIHNob3VsZCBiZSB0cnVlIGlmIHlvdSBhbHdheXMgdXNlIGBkZWVwRnJlZXplYCB0byBmcmVlemUgb2JqZWN0cy5cclxuICAgIC8vXHJcbiAgICAvLyBOb3RlIHRoYXQgT2JqZWN0LmlzRnJvemVuIHdpbGwgYWxzbyByZXR1cm4gYHRydWVgIGZvciBwcmltaXRpdmVzIChudW1iZXJzLFxyXG4gICAgLy8gc3RyaW5ncywgYm9vbGVhbnMsIHVuZGVmaW5lZCwgbnVsbCksIHNvIHRoZXJlIGlzIG5vIG5lZWQgdG8gY2hlY2sgZm9yXHJcbiAgICAvLyB0aG9zZSBleHBsaWNpdGx5LlxyXG4gICAgaWYgKE9iamVjdC5pc0Zyb3plbihvYmplY3QpKSB7XHJcbiAgICAgIHJldHVybiBvYmplY3QgYXMgUmVhZG9ubHk8Uz47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQXQgdGhpcyBwb2ludCB3ZSBrbm93IHRoYXQgd2UncmUgZGVhbGluZyB3aXRoIGVpdGhlciBhbiBhcnJheSBvciBwbGFpbiBvYmplY3QsIHNvXHJcbiAgICAvLyBqdXN0IGZyZWV6ZSBpdCBhbmQgcmVjdXJzZSBvbiBpdHMgdmFsdWVzLlxyXG4gICAgT2JqZWN0LmZyZWV6ZShvYmplY3QpO1xyXG4gICAgT2JqZWN0LmtleXMob2JqZWN0KS5mb3JFYWNoKGtleSA9PiB0aGlzLmRlZXBGcmVlemUoKG9iamVjdCBhcyBhbnkpW2tleV0pKTtcclxuXHJcbiAgICByZXR1cm4gb2JqZWN0IGFzIFJlYWRvbmx5PFM+O1xyXG4gIH1cclxufVxyXG4iXX0=
|
|
424
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctaHR0cC1jYWNoaW5nLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1odHRwLWNhY2hpbmcvc3JjL2xpYi9uZy1odHRwLWNhY2hpbmcuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakcsT0FBTyxFQUF3QyxnQkFBZ0IsRUFBRSxXQUFXLEVBQWUsTUFBTSxzQkFBc0IsQ0FBQztBQUd4SCxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQzs7QUFJdEYsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBdUIsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBRTlGLE1BQU0sQ0FBQyxNQUFNLHdCQUF3QixHQUFHLENBQUMsS0FBMkIsRUFBRSxVQUF1QixJQUFJLFdBQVcsRUFBRSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixFQUFFLEtBQUssQ0FBQyxDQUFBO0FBRTlKLE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLENBQUMsT0FBb0IsRUFBVyxFQUFFO0lBQ2pFLHNCQUFzQjtJQUN0QixNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDeEQsSUFBSSxrQkFBa0IsRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sWUFBWSxHQUFHLGtCQUFrQixDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3RELElBQUksWUFBWSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQ3RDLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQzthQUFNLElBQUksWUFBWSxDQUFDLFFBQVEsQ0FB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Y3Rpb25Ub2tlbiwgSW5qZWN0LCBPcHRpb25hbCwgVkVSU0lPTiwgaXNEZXZNb2RlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEh0dHBSZXF1ZXN0LCBIdHRwUmVzcG9uc2UsIEh0dHBFdmVudCwgSHR0cENvbnRleHRUb2tlbiwgSHR0cENvbnRleHQsIEh0dHBIZWFkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcy9pbnRlcm5hbC9PYnNlcnZhYmxlJztcclxuaW1wb3J0IHsgTmdIdHRwQ2FjaGluZ1N0b3JhZ2VJbnRlcmZhY2UgfSBmcm9tICcuL3N0b3JhZ2UvbmctaHR0cC1jYWNoaW5nLXN0b3JhZ2UuaW50ZXJmYWNlJztcclxuaW1wb3J0IHsgTmdIdHRwQ2FjaGluZ01lbW9yeVN0b3JhZ2UgfSBmcm9tICcuL3N0b3JhZ2UvbmctaHR0cC1jYWNoaW5nLW1lbW9yeS1zdG9yYWdlJztcclxuXHJcbmV4cG9ydCB0eXBlIE5nSHR0cENhY2hpbmdDb250ZXh0ID0gUGljazxOZ0h0dHBDYWNoaW5nQ29uZmlnLCAnZ2V0S2V5JyB8ICdpc0NhY2hlYWJsZScgfCAnaXNFeHBpcmVkJyB8ICdpc1ZhbGlkJz47XHJcblxyXG5leHBvcnQgY29uc3QgTkdfSFRUUF9DQUNISU5HX0NPTlRFWFQgPSBuZXcgSHR0cENvbnRleHRUb2tlbjxOZ0h0dHBDYWNoaW5nQ29udGV4dD4oKCkgPT4gKHt9KSk7XHJcblxyXG5leHBvcnQgY29uc3Qgd2l0aE5nSHR0cENhY2hpbmdDb250ZXh0ID0gKHZhbHVlOiBOZ0h0dHBDYWNoaW5nQ29udGV4dCwgY29udGV4dDogSHR0cENvbnRleHQgPSBuZXcgSHR0cENvbnRleHQoKSkgPT4gY29udGV4dC5zZXQoTkdfSFRUUF9DQUNISU5HX0NPTlRFWFQsIHZhbHVlKVxyXG5cclxuZXhwb3J0IGNvbnN0IGNoZWNrQ2FjaGVIZWFkZXJzID0gKGhlYWRlcnM6IEh0dHBIZWFkZXJzKTogYm9vbGVhbiA9PiB7XHJcbiAgLy8gY2hlY2sgQ2FjaGUtQ29udHJvbFxyXG4gIGNvbnN0IGNhY2hlQ29udHJvbEhlYWRlciA9IGhlYWRlcnMuZ2V0KCdjYWNoZS1jb250cm9sJyk7XHJcbiAgaWYgKGNhY2hlQ29udHJvbEhlYWRlcikge1xyXG4gICAgY29uc3QgY2FjaGVDb250cm9sID0gY2FjaGVDb250cm9sSGVhZGVyLnRvTG93ZXJDYXNlKCk7XHJcbiAgICBpZiAoY2FjaGVDb250cm9sLmluY2x1ZGVzKCduby1zdG9yZScpKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH0gZWxzZSBpZiAoY2FjaGVDb250cm9sLmluY2x1ZGVzKCduby1jYWNoZScpKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gY2hlY2sgRXhwaXJlcyBoZWFkZXIgRXhwaXJlcyBpZiByZXNwb25zZSBpcyB3aXRob3V0IENhY2hlLUNvbnRyb2xcclxuICBjb25zdCBleHBpcmVzSGVhZGVyID0gaGVhZGVycy5nZXQoJ2V4cGlyZXMnKTtcclxuICBpZiAoZXhwaXJlc0hlYWRlcikge1xyXG4gICAgY29uc3QgZXhwaXJlcyA9IERhdGUucGFyc2UoZXhwaXJlc0hlYWRlcik7XHJcbiAgICBpZiAoIWlzTmFOKGV4cGlyZXMpKSB7XHJcbiAgICAgIHJldHVybiBleHBpcmVzID4gRGF0ZS5ub3coKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiB0cnVlO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIE5nSHR0cENhY2hpbmdFbnRyeTxLID0gYW55LCBUID0gYW55PiB7XHJcbiAgLyoqXHJcbiAgICogVVJMXHJcbiAgICovXHJcbiAgdXJsOiBzdHJpbmc7XHJcbiAgLyoqXHJcbiAgICogSHR0cFJlc3BvbnNlXHJcbiAgICovXHJcbiAgcmVzcG9uc2U6IEh0dHBSZXNwb25zZTxUPjtcclxuICAvKipcclxuICAgKiBIdHRwUmVxdWVzdFxyXG4gICAqL1xyXG4gIHJlcXVlc3Q6IEh0dHBSZXF1ZXN0PEs+O1xyXG4gIC8qKlxyXG4gICAqIFRpbWVzdGFtcCBvZiBhZGQgdG8gY2FjaGUgdGltZVxyXG4gICAqL1xyXG4gIGFkZGVkVGltZTogbnVtYmVyO1xyXG4gIC8qKlxyXG4gICAqIENhY2hlIHZlcnNpb25cclxuICAgKi9cclxuICB2ZXJzaW9uOiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBOR19IVFRQX0NBQ0hJTkdfQ09ORklHID0gbmV3IEluamVjdGlvblRva2VuPE5nSHR0cENhY2hpbmdDb250ZXh0PihcclxuICAnbmctaHR0cC1jYWNoaW5nLmNvbmZpZydcclxuKTtcclxuXHJcbmV4cG9ydCBlbnVtIE5nSHR0cENhY2hpbmdTdHJhdGVneSB7XHJcbiAgLyoqXHJcbiAgICogQWxsIHJlcXVlc3QgYXJlIGNhY2hlYWJsZSBpZiBIVFRQIG1ldGhvZCBpcyBpbnRvIGBhbGxvd2VkTWV0aG9kYFxyXG4gICAqL1xyXG4gIEFMTE9XX0FMTCA9ICdBTExPV19BTEwnLFxyXG4gIC8qKlxyXG4gICAqIE9ubHkgdGhlIHJlcXVlc3Qgd2l0aCBgWC1ORy1IVFRQLUNBQ0hJTkctQUxMT1ctQ0FDSEVgIGhlYWRlciBhcmUgY2FjaGVhYmxlIGlmIEhUVFAgbWV0aG9kIGlzIGludG8gYGFsbG93ZWRNZXRob2RgXHJcbiAgICovXHJcbiAgRElTQUxMT1dfQUxMID0gJ0RJU0FMTE9XX0FMTCdcclxufVxyXG5cclxuZXhwb3J0IGVudW0gTmdIdHRwQ2FjaGluZ0hlYWRlcnMge1xyXG4gIC8qKlxyXG4gICAqIFJlcXVlc3QgaXMgY2FjaGVhYmxlIGlmIEhUVFAgbWV0aG9kIGlzIGludG8gYGFsbG93ZWRNZXRob2RgXHJcbiAgICovXHJcbiAgQUxMT1dfQ0FDSEUgPSAnWC1ORy1IVFRQLUNBQ0hJTkctQUxMT1ctQ0FDSEUnLFxyXG4gIC8qKlxyXG4gICAqIFJlcXVlc3QgaXNuJ3QgY2FjaGVhYmxlXHJcbiAgICovXHJcbiAgRElTQUxMT1dfQ0FDSEUgPSAnWC1ORy1IVFRQLUNBQ0hJTkctRElTQUxMT1ctQ0FDSEUnLFxyXG4gIC8qKlxyXG4gICAqIFNwZWNpZmljIGNhY2hlIGxpZmV0aW1lIGZvciB0aGUgcmVxdWVzdFxyXG4gICAqL1xyXG4gIExJRkVUSU1FID0gJ1gtTkctSFRUUC1DQUNISU5HLUxJRkVUSU1FJyxcclxuICAvKipcclxuICAgKiBZb3UgY2FuIHRhZyBtdWx0aXBsZSByZXF1ZXN0IGJ5IGFkZGluZyB0aGlzIGhlYWRlciB3aXRoIHRoZSBzYW1lIHRhZyBhbmQgXHJcbiAgICogdXNpbmcgYE5nSHR0cENhY2hpbmdTZXJ2aWNlLmNsZWFyQ2FjaGVCeVRhZyh0YWc6IHN0cmluZylgIGZvciBkZWxldGUgYWxsIHRoZSB0YWdnZWQgcmVxdWVzdFxyXG4gICAqL1xyXG4gIFRBRyA9ICdYLU5HLUhUVFAtQ0FDSElORy1UQUcnXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBOZ0h0dHBDYWNoaW5nSGVhZGVyc0xpc3QgPSBPYmplY3QudmFsdWVzKE5nSHR0cENhY2hpbmdIZWFkZXJzKTtcclxuXHJcbmV4cG9ydCBjb25zdCBOR19IVFRQX0NBQ0hJTkdfU0VDT05EX0lOX01TID0gMTAwMDtcclxuZXhwb3J0IGNvbnN0IE5HX0hUVFBfQ0FDSElOR19NSU5VVEVfSU5fTVMgPSBOR19IVFRQX0NBQ0hJTkdfU0VDT05EX0lOX01TICogNjA7XHJcbmV4cG9ydCBjb25zdCBOR19IVFRQX0NBQ0hJTkdfSE9VUl9JTl9NUyA9IE5HX0hUVFBfQ0FDSElOR19NSU5VVEVfSU5fTVMgKiA2MDtcclxuZXhwb3J0IGNvbnN0IE5HX0hUVFBfQ0FDSElOR19EQVlfSU5fTVMgPSBOR19IVFRQX0NBQ0hJTkdfSE9VUl9JTl9NUyAqIDI0O1xyXG5leHBvcnQgY29uc3QgTkdfSFRUUF9DQUNISU5HX1dFRUtfSU5fTVMgPSBOR19IVFRQX0NBQ0hJTkdfREFZX0lOX01TICogNztcclxuZXhwb3J0IGNvbnN0IE5HX0hUVFBfQ0FDSElOR19NT05USF9JTl9NUyA9IE5HX0hUVFBfQ0FDSElOR19EQVlfSU5fTVMgKiAzMDtcclxuZXhwb3J0IGNvbnN0IE5HX0hUVFBfQ0FDSElOR19ZRUFSX0lOX01TID0gTkdfSFRUUF9DQUNISU5HX0RBWV9JTl9NUyAqIDM2NTtcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTmdIdHRwQ2FjaGluZ0NvbmZpZyB7XHJcbiAgLyoqXHJcbiAgICogU2V0IHRoZSBjYWNoZSBzdG9yZS4gWW91IGNhbiBpbXBsZW1lbnQgeW91ciBjdXN0b20gc3RvcmUgYnkgaW1wbGVtZW50IHRoZSBgTmdIdHRwQ2FjaGluZ1N0b3JhZ2VJbnRlcmZhY2VgIGludGVyZmFjZSwgZWcuOlxyXG4gICAqL1xyXG4gIHN0b3JlPzogTmdIdHRwQ2FjaGluZ1N0b3JhZ2VJbnRlcmZhY2U7XHJcbiAgLyoqXHJcbiAgICogTnVtYmVyIG9mIG1pbGxpc2Vjb25kIHRoYXQgYSByZXNwb25zZSBpcyBzdG9yZWQgaW4gdGhlIGNhY2hlLiBcclxuICAgKiBZb3UgY2FuIHNldCBzcGVjaWZpYyBcImxpZmV0aW1lXCIgZm9yIGVhY2ggcmVxdWVzdCBieSBhZGQgdGhlIGhlYWRlciBgWC1ORy1IVFRQLUNBQ0hJTkctTElGRVRJTUVgIChzZWUgZXhhbXBsZSBiZWxvdykuXHJcbiAgICovXHJcbiAgbGlmZXRpbWU/OiBudW1iZXI7XHJcbiAgLyoqXHJcbiAgICogQXJyYXkgb2YgYWxsb3dlZCBIVFRQIG1ldGhvZHMgdG8gY2FjaGUuIFxyXG4gICAqIFlvdSBjYW4gYWxsb3cgbXVsdGlwbGUgbWV0aG9kcywgZWcuOiBgWydHRVQnLCAnUE9TVCcsICdQVVQnLCAnREVMRVRFJywgJ0hFQUQnXWAgb3IgXHJcbiAgICogYWxsb3cgYWxsIG1ldGhvZHMgYnk6IGBbJ0FMTCddYC4gSWYgYGFsbG93ZWRNZXRob2RgIGlzIGFuIGVtcHR5IGFycmF5IChgW11gKSwgbm8gcmVzcG9uc2UgYXJlIGNhY2hlZC5cclxuICAgKiAqV2FybmluZyEqIGBOZ0h0dHBDYWNoaW5nYCB1c2UgdGhlIGZ1bGwgdXJsICh1cmwgd2l0aCBxdWVyeSBwYXJhbWV0ZXJzKSBhcyB1bmlxdWUga2V5IGZvciB0aGUgY2FjaGVkIHJlc3BvbnNlLFxyXG4gICAqIHRoaXMgaXMgY29ycmVjdCBmb3IgdGhlIGBHRVRgIHJlcXVlc3QgYnV0IGlzIF9wb3RlbnRpYWxseV8gd3JvbmcgZm9yIG90aGVyIHR5cGUgb2YgcmVxdWVzdCAoZWcuIGBQT1NUYCwgYFBVVGApLiBcclxuICAgKiBZb3UgY2FuIHNldCBhIGRpZmZlcmVudCBcImtleVwiIGJ5IGN1c3RvbWl6aW5nIHRoZSBgZ2V0S2V5YCBjb25maWcgbWV0aG9kIChzZWUgYGdldEtleWAgc2VjdGlvbikuXHJcbiAgICovXHJcbiAgYWxsb3dlZE1ldGhvZD86IHN0cmluZ1tdO1xyXG4gIC8qKlxyXG4gICAqIFNldCB0aGUgY2FjaGUgc3RyYXRlZ3ksIHBvc3NpYmxlIHN0cmF0ZWdpZXMgYXJlOlxyXG4gICAqIC0gYE5nSHR0cENhY2hpbmdTdHJhdGVneS5BTExPV19BTExgOiBBbGwgcmVxdWVzdCBhcmUgY2FjaGVhYmxlIGlmIEhUVFAgbWV0aG9kIGlzIGludG8gYGFsbG93ZWRNZXRob2RgO1xyXG4gICAqIC0gYE5nSHR0cENhY2hpbmdTdHJhdGVneS5ESVNBTExPV19BTExgOiBPbmx5IHRoZSByZXF1ZXN0IHdpdGggYFgtTkctSFRUUC1DQUNISU5HLUFMTE9XLUNBQ0hFYCBoZWFkZXIgYXJlIGNhY2hlYWJsZSBpZiBIVFRQIG1ldGhvZCBpcyBpbnRvIGBhbGxvd2VkTWV0aG9kYDtcclxuICAgKi9cclxuICBjYWNoZVN0cmF0ZWd5PzogTmdIdHRwQ2FjaGluZ1N0cmF0ZWd5O1xyXG4gIC8qKlxyXG4gICAqIENhY2hlIHZlcnNpb24uIFdoZW4geW91IGhhdmUgYSBicmVha2luZyBjaGFuZ2UsIGNoYW5nZSB0aGUgdmVyc2lvbiwgYW5kIGl0J2xsIGRlbGV0ZSB0aGUgY3VycmVudCBjYWNoZSBhdXRvbWF0aWNhbGx5LlxyXG4gICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIEFuZ3VsYXIgbWFqb3IgdmVyc2lvbiAoZWcuIDEzKSwgaW4gdGhpcyB3YXksIHRoZSBjYWNoZSBpcyBpbnZhbGlkYXRlZCBvbiBldmVyeSBBbmd1bGFyIHVwZ3JhZGUuXHJcbiAgICovXHJcbiAgdmVyc2lvbj86IHN0cmluZztcclxuICAvKipcclxuICAgKiBJZiB0cnVlIHJlc3BvbnNlIGhlYWRlcnMgY2FjaGUtY29udHJvbCBhbmQgZXhwaXJlcyBhcmUgcmVzcGVjdGVkLlxyXG4gICAqL1xyXG4gIGNoZWNrUmVzcG9uc2VIZWFkZXJzPzogYm9vbGVhbjtcclxuICAvKipcclxuICAgKiBJZiB0aGlzIGZ1bmN0aW9uIHJldHVybiBgdHJ1ZWAgdGhlIHJlcXVlc3QgaXMgZXhwaXJlZCBhbmQgYSBuZXcgcmVxdWVzdCBpcyBzZW5kIHRvIGJhY2tlbmQsIGlmIHJldHVybiBgZmFsc2VgIGlzbid0IGV4cGlyZWQuIFxyXG4gICAqIElmIHRoZSByZXN1bHQgaXMgYHVuZGVmaW5lZGAsIHRoZSBub3JtYWwgYmVoYXZpb3VyIGlzIHByb3ZpZGVkLlxyXG4gICAqL1xyXG4gIGlzRXhwaXJlZD86IDxLLCBUPihlbnRyeTogTmdIdHRwQ2FjaGluZ0VudHJ5PEssIFQ+KSA9PiBib29sZWFuIHwgdW5kZWZpbmVkIHwgdm9pZDtcclxuICAvKipcclxuICAgKiBJZiB0aGlzIGZ1bmN0aW9uIHJldHVybiBgdHJ1ZWAgdGhlIHJlcXVlc3QgaXMgY2FjaGVhYmxlLCBpZiByZXR1cm4gYGZhbHNlYCBpc24ndCBjYWNoZWFibGUuIFxyXG4gICAqIElmIHRoZSByZXN1bHQgaXMgYHVuZGVmaW5lZGAsIHRoZSBub3JtYWwgYmVoYXZpb3VyIGlzIHByb3ZpZGVkLlxyXG4gICAqL1xyXG4gIGlzQ2FjaGVhYmxlPzogPEs+KHJlcTogSHR0cFJlcXVlc3Q8Sz4pID0+IGJvb2xlYW4gfCB1bmRlZmluZWQgfCB2b2lkO1xyXG4gIC8qKlxyXG4gICAqIFRoaXMgZnVuY3Rpb24gcmV0dXJuIHRoZSB1bmlxdWUga2V5IChgc3RyaW5nYCkgZm9yIHN0b3JlIHRoZSByZXNwb25zZSBpbnRvIHRoZSBjYWNoZS4gXHJcbiAgICogSWYgdGhlIHJlc3VsdCBpcyBgdW5kZWZpbmVkYCwgdGhlIG5vcm1hbCBiZWhhdmlvdXIgaXMgcHJvdmlkZWQuXHJcbiAgICovXHJcbiAgZ2V0S2V5PzogPEs+KHJlcTogSHR0cFJlcXVlc3Q8Sz4pID0+IHN0cmluZyB8IHVuZGVmaW5lZCB8IHZvaWQ7XHJcbiAgLyoqXHJcbiAgICogSWYgdGhpcyBmdW5jdGlvbiByZXR1cm4gYHRydWVgIHRoZSBjYWNoZSBlbnRyeSBpcyB2YWxpZCBhbmQgY2FuIGJlIHN0b3JlZCwgaWYgcmV0dXJuIGBmYWxzZWAgaXNuJ3QgdmFsaWQuIFxyXG4gICAqIElmIHRoZSByZXN1bHQgaXMgYHVuZGVmaW5lZGAsIHRoZSBub3JtYWwgYmVoYXZpb3VyIGlzIHByb3ZpZGVkLlxyXG4gICAqL1xyXG4gIGlzVmFsaWQ/OiA8SywgVD4oZW50cnk6IE5nSHR0cENhY2hpbmdFbnRyeTxLLCBUPikgPT4gYm9vbGVhbiB8IHVuZGVmaW5lZCB8IHZvaWQ7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTmdIdHRwQ2FjaGluZ0RlZmF1bHRDb25maWcgZXh0ZW5kcyBOZ0h0dHBDYWNoaW5nQ29uZmlnIHtcclxuICBzdG9yZTogTmdIdHRwQ2FjaGluZ1N0b3JhZ2VJbnRlcmZhY2U7XHJcbiAgbGlmZXRpbWU6IG51bWJlcjtcclxuICBhbGxvd2VkTWV0aG9kOiBzdHJpbmdbXTtcclxuICBjYWNoZVN0cmF0ZWd5OiBOZ0h0dHBDYWNoaW5nU3RyYXRlZ3k7XHJcbiAgdmVyc2lvbjogc3RyaW5nO1xyXG4gIGNoZWNrUmVzcG9uc2VIZWFkZXJzOiBib29sZWFuO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgTmdIdHRwQ2FjaGluZ0NvbmZpZ0RlZmF1bHQ6IFJlYWRvbmx5PE5nSHR0cENhY2hpbmdEZWZhdWx0Q29uZmlnPiA9IHtcclxuICBzdG9yZTogbmV3IE5nSHR0cENhY2hpbmdNZW1vcnlTdG9yYWdlKCksXHJcbiAgbGlmZXRpbWU6IE5HX0hUVFBfQ0FDSElOR19IT1VSX0lOX01TLFxyXG4gIHZlcnNpb246IFZFUlNJT04ubWFqb3IsXHJcbiAgYWxsb3dlZE1ldGhvZDogWydHRVQnLCAnSEVBRCddLFxyXG4gIGNhY2hlU3RyYXRlZ3k6IE5nSHR0cENhY2hpbmdTdHJhdGVneS5BTExPV19BTEwsXHJcbiAgY2hlY2tSZXNwb25zZUhlYWRlcnM6IGZhbHNlXHJcbn07XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBOZ0h0dHBDYWNoaW5nU2VydmljZSB7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgcXVldWUgPSBuZXcgTWFwPHN0cmluZywgT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4+KCk7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgY29uZmlnOiBOZ0h0dHBDYWNoaW5nRGVmYXVsdENvbmZpZztcclxuXHJcbiAgcHJpdmF0ZSBnY0xvY2sgPSBmYWxzZTtcclxuXHJcbiAgcHJpdmF0ZSBkZXZNb2RlOiBib29sZWFuID0gaXNEZXZNb2RlKCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgQEluamVjdChOR19IVFRQX0NBQ0hJTkdfQ09ORklHKSBAT3B0aW9uYWwoKSBjb25maWc6IFJlYWRvbmx5PE5nSHR0cENhY2hpbmdDb25maWc+XHJcbiAgKSB7XHJcbiAgICBpZiAoY29uZmlnKSB7XHJcbiAgICAgIHRoaXMuY29uZmlnID0geyAuLi5OZ0h0dHBDYWNoaW5nQ29uZmlnRGVmYXVsdCwgLi4uY29uZmlnIH07XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmNvbmZpZyA9IHsgLi4uTmdIdHRwQ2FjaGluZ0NvbmZpZ0RlZmF1bHQgfTtcclxuICAgIH1cclxuICAgIC8vIHN0YXJ0IGNhY2hlIGNsZWFuXHJcbiAgICB0aGlzLnJ1bkdjKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gdGhlIGNvbmZpZ1xyXG4gICAqL1xyXG4gIGdldENvbmZpZygpOiBSZWFkb25seTxOZ0h0dHBDYWNoaW5nQ29uZmlnPiB7XHJcbiAgICByZXR1cm4gdGhpcy5jb25maWc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gdGhlIHF1ZXVlIG1hcFxyXG4gICAqL1xyXG4gIGdldFF1ZXVlKCk6IFJlYWRvbmx5PE1hcDxzdHJpbmcsIE9ic2VydmFibGU8SHR0cEV2ZW50PGFueT4+Pj4ge1xyXG4gICAgcmV0dXJuIHRoaXMucXVldWU7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gdGhlIGNhY2hlIHN0b3JlXHJcbiAgICovXHJcbiAgZ2V0U3RvcmUoKTogUmVhZG9ubHk8TmdIdHRwQ2FjaGluZ1N0b3JhZ2VJbnRlcmZhY2U+IHtcclxuICAgIHJldHVybiB0aGlzLmNvbmZpZy5zdG9yZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybiByZXNwb25zZSBmcm9tIGNhY2hlXHJcbiAgICovXHJcbiAgZ2V0RnJvbUNhY2hlPEssIFQ+KHJlcTogSHR0cFJlcXVlc3Q8Sz4pOiBSZWFkb25seTxIdHRwUmVzcG9uc2U8VD4+IHwgdW5kZWZpbmVkIHtcclxuICAgIGNvbnN0IGtleTogc3RyaW5nID0gdGhpcy5nZXRLZXkocmVxKTtcclxuICAgIGNvbnN0IGNhY2hlZDogTmdIdHRwQ2FjaGluZ0VudHJ5PEssIFQ+IHwgdW5kZWZpbmVkID0gdGhpcy5jb25maWcuc3RvcmUuZ2V0PEssIFQ+KGtleSk7XHJcblxyXG4gICAgaWYgKCFjYWNoZWQpIHtcclxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5pc0V4cGlyZWQoY2FjaGVkKSkge1xyXG4gICAgICB0aGlzLmNsZWFyQ2FjaGVCeUtleShrZXkpO1xyXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLmRlZXBGcmVlemUoY2FjaGVkLnJlc3BvbnNlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZCByZXNwb25zZSB0byBjYWNoZVxyXG4gICAqL1xyXG4gIGFkZFRvQ2FjaGU8SywgVD4ocmVxOiBIdHRwUmVxdWVzdDxLPiwgcmVzOiBIdHRwUmVzcG9uc2U8VD4pOiBib29sZWFuIHtcclxuICAgIGNvbnN0IGVudHJ5OiBOZ0h0dHBDYWNoaW5nRW50cnk8SywgVD4gPSB7XHJcbiAgICAgIHVybDogcmVxLnVybFdpdGhQYXJhbXMsXHJcbiAgICAgIHJlc3BvbnNlOiByZXMsXHJcbiAgICAgIHJlcXVlc3Q6IHJlcSxcclxuICAgICAgYWRkZWRUaW1lOiBEYXRlLm5vdygpLFxyXG4gICAgICB2ZXJzaW9uOiB0aGlzLmNvbmZpZy52ZXJzaW9uLFxyXG4gICAgfTtcclxuICAgIGlmICh0aGlzLmlzVmFsaWQoZW50cnkpKSB7XHJcbiAgICAgIGNvbnN0IGtleTogc3RyaW5nID0gdGhpcy5nZXRLZXkocmVxKTtcclxuICAgICAgdGhpcy5jb25maWcuc3RvcmUuc2V0KGtleSwgZW50cnkpO1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlbGV0ZSByZXNwb25zZSBmcm9tIGNhY2hlXHJcbiAgICovXHJcbiAgZGVsZXRlRnJvbUNhY2hlPEs+KHJlcTogSHR0cFJlcXVlc3Q8Sz4pOiBib29sZWFuIHtcclxuICAgIGNvbnN0IGtleTogc3RyaW5nID0gdGhpcy5nZXRLZXkocmVxKTtcclxuICAgIHJldHVybiB0aGlzLmNsZWFyQ2FjaGVCeUtleShrZXkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2xlYXIgdGhlIGNhY2hlXHJcbiAgICovXHJcbiAgY2xlYXJDYWNoZSgpOiB2b2lkIHtcclxuICAgIHRoaXMuY29uZmlnLnN0b3JlLmNsZWFyKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDbGVhciB0aGUgY2FjaGUgYnkga2V5XHJcbiAgICovXHJcbiAgY2xlYXJDYWNoZUJ5S2V5KGtleTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5jb25maWcuc3RvcmUuZGVsZXRlKGtleSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDbGVhciB0aGUgY2FjaGUgYnkga2V5c1xyXG4gICAqL1xyXG4gIGNsZWFyQ2FjaGVCeUtleXMoa2V5czogQXJyYXk8c3RyaW5nPik6IG51bWJlciB7XHJcbiAgICBsZXQgY291bnRlciA9IDA7XHJcbiAgICBpZiAoa2V5cykge1xyXG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY2xlYXJDYWNoZUJ5S2V5KGtleSkpIHtcclxuICAgICAgICAgIGNvdW50ZXIrKztcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBjb3VudGVyO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2xlYXIgdGhlIGNhY2hlIGJ5IHJlZ2V4XHJcbiAgICovXHJcbiAgY2xlYXJDYWNoZUJ5UmVnZXg8SywgVD4ocmVnZXg6IFJlZ0V4cCk6IG51bWJlciB7XHJcbiAgICBjb25zdCBrZXlzOiBBcnJheTxzdHJpbmc+ID0gW107XHJcbiAgICB0aGlzLmNvbmZpZy5zdG9yZS5mb3JFYWNoPEssIFQ+KChfOiBOZ0h0dHBDYWNoaW5nRW50cnk8SywgVD4sIGtleTogc3RyaW5nKSA9PiB7XHJcbiAgICAgIGlmIChyZWdleC50ZXN0KGtleSkpIHtcclxuICAgICAgICBrZXlzLnB1c2goa2V5KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdGhpcy5jbGVhckNhY2hlQnlLZXlzKGtleXMpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2xlYXIgdGhlIGNhY2hlIGJ5IFRBR1xyXG4gICAqL1xyXG4gIGNsZWFyQ2FjaGVCeVRhZzxLLCBUPih0YWc6IHN0cmluZyk6IG51bWJlciB7XHJcbiAgICBjb25zdCBrZXlzOiBBcnJheTxzdHJpbmc+ID0gW107XHJcbiAgICB0aGlzLmNvbmZpZy5zdG9yZS5mb3JFYWNoPEssIFQ+KChlbnRyeTogTmdIdHRwQ2FjaGluZ0VudHJ5PEssIFQ+LCBrZXk6IHN0cmluZykgPT4ge1xyXG4gICAgICBjb25zdCB0YWdIZWFkZXIgPSBlbnRyeS5yZXF1ZXN0LmhlYWRlcnMuZ2V0KE5nSHR0cENhY2hpbmdIZWFkZXJzLlRBRyk7XHJcbiAgICAgIGlmICh0YWdIZWFkZXIgJiYgdGFnSGVhZGVyLnNwbGl0KCcsJykuaW5jbHVkZXModGFnKSkge1xyXG4gICAgICAgIGtleXMucHVzaChrZXkpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIHJldHVybiB0aGlzLmNsZWFyQ2FjaGVCeUtleXMoa2V5cyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSdW4gZ2FyYmFnZSBjb2xsZWN0b3IgKGRlbGV0ZSBleHBpcmVkIGNhY2hlIGVudHJ5KVxyXG4gICAqL1xyXG4gIHJ1bkdjPEssIFQ+KCk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKHRoaXMuZ2NMb2NrKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIHRoaXMuZ2NMb2NrID0gdHJ1ZTtcclxuICAgIGNvbnN0IGtleXM6IEFycmF5PHN0cmluZz4gPSBbXTtcclxuICAgIHRoaXMuY29uZmlnLnN0b3JlLmZvckVhY2g8SywgVD4oKGVudHJ5OiBOZ0h0dHBDYWNoaW5nRW50cnk8SywgVD4sIGtleTogc3RyaW5nKSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLmlzRXhwaXJlZChlbnRyeSkpIHtcclxuICAgICAgICBrZXlzLnB1c2goa2V5KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICB0aGlzLmNsZWFyQ2FjaGVCeUtleXMoa2V5cyk7XHJcbiAgICB0aGlzLmdjTG9jayA9IGZhbHNlO1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gdHJ1ZSBpZiBjYWNoZSBlbnRyeSBpcyBleHBpcmVkXHJcbiAgICovXHJcbiAgaXNFeHBpcmVkPEssIFQ+KGVudHJ5OiBOZ0h0dHBDYWNoaW5nRW50cnk8SywgVD4pOiBib29sZWFuIHtcclxuICAgIC8vIGlmIHVzZXIgcHJvdmlkZSBjdXN0b20gbWV0aG9kLCB1c2UgaXRcclxuICAgIGNvbnN0IGNvbnRleHQgPSBlbnRyeS5yZXF1ZXN0LmNvbnRleHQuZ2V0KE5HX0hUVFBfQ0FDSElOR19DT05URVhUKTtcclxuICAgIGlmICh0eXBlb2YgY29udGV4dD8uaXNFeHBpcmVkID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnRleHQuaXNFeHBpcmVkKGVudHJ5KTtcclxuICAgICAgLy8gaWYgcmVzdWx0IGlzIHVuZGVmaW5lZCwgbm9ybWFsIGJlaGF2aW91ciBpcyBwcm92aWRlZFxyXG4gICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBpZiB1c2VyIHByb3ZpZGUgY3VzdG9tIG1ldGhvZCwgdXNlIGl0XHJcbiAgICBpZiAodHlwZW9mIHRoaXMuY29uZmlnLmlzRXhwaXJlZCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmNvbmZpZy5pc0V4cGlyZWQoZW50cnkpO1xyXG4gICAgICAvLyBpZiByZXN1bHQgaXMgdW5kZWZpbmVkLCBub3JtYWwgYmVoYXZpb3VyIGlzIHByb3ZpZGVkXHJcbiAgICAgIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIGlmIHZlcnNpb24gY2hhbmdlLCBhbHdheXMgZXhwaXJlXHJcbiAgICBpZiAodGhpcy5jb25maWcudmVyc2lvbiAhPT0gZW50cnkudmVyc2lvbikge1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuICAgIC8vIGNvbmZpZy9kZWZhdWx0IGxpZmV0aW1lXHJcbiAgICBsZXQgbGlmZXRpbWU6IG51bWJlciA9IHRoaXMuY29uZmlnLmxpZmV0aW1lO1xyXG4gICAgLy8gcmVxdWVzdCBoYXMgb3duIGxpZmV0aW1lXHJcbiAgICBjb25zdCBoZWFkZXJMaWZldGltZSA9IGVudHJ5LnJlcXVlc3QuaGVhZGVycy5nZXQoTmdIdHRwQ2FjaGluZ0hlYWRlcnMuTElGRVRJTUUpO1xyXG4gICAgaWYgKGhlYWRlckxpZmV0aW1lKSB7XHJcbiAgICAgIGxpZmV0aW1lID0gK2hlYWRlckxpZmV0aW1lO1xyXG4gICAgfVxyXG4gICAgLy8gbmV2ZXIgZXhwaXJlIGlmIDBcclxuICAgIGlmIChsaWZldGltZSA9PT0gMCkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICAvLyB3cm9uZyBsaWZldGltZVxyXG4gICAgaWYgKGxpZmV0aW1lIDwgMCB8fCBpc05hTihsaWZldGltZSkpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsaWZldGltZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCAwJyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZW50cnkuYWRkZWRUaW1lICsgbGlmZXRpbWUgPCBEYXRlLm5vdygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJuIHRydWUgaWYgY2FjaGUgZW50cnkgaXMgdmFsaWQgZm9yIHN0b3JlIGluIHRoZSBjYWNoZVxyXG4gICAqIERlZmF1bHQgYmVoYXZpb3VyIGlzIHdoZXRoZXIgdGhlIHN0YXR1cyBjb2RlIGZhbGxzIGluIHRoZSAyeHggcmFuZ2UgYW5kIHJlc3BvbnNlIGhlYWRlcnMgY2FjaGUtY29udHJvbCBhbmQgZXhwaXJlcyBhbGxvdyBjYWNoZS5cclxuICAgKi9cclxuICBpc1ZhbGlkPEssIFQ+KGVudHJ5OiBOZ0h0dHBDYWNoaW5nRW50cnk8SywgVD4pOiBib29sZWFuIHtcclxuICAgIGNvbnN0IGNvbnRleHQgPSBlbnRyeS5yZXF1ZXN0LmNvbnRleHQuZ2V0KE5HX0hUVFBfQ0FDSElOR19DT05URVhUKTtcclxuICAgIC8vIGlmIHVzZXIgcHJvdmlkZSBjdXN0b20gbWV0aG9kLCB1c2UgaXRcclxuICAgIGlmICh0eXBlb2YgY29udGV4dC5pc1ZhbGlkID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnRleHQuaXNWYWxpZChlbnRyeSk7XHJcbiAgICAgIC8vIGlmIHJlc3VsdCBpcyB1bmRlZmluZWQsIG5vcm1hbCBiZWhhdmlvdXIgaXMgcHJvdmlkZWRcclxuICAgICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gaWYgdXNlciBwcm92aWRlIGN1c3RvbSBtZXRob2QsIHVzZSBpdFxyXG4gICAgaWYgKHR5cGVvZiB0aGlzLmNvbmZpZy5pc1ZhbGlkID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuY29uZmlnLmlzVmFsaWQoZW50cnkpO1xyXG4gICAgICAvLyBpZiByZXN1bHQgaXMgdW5kZWZpbmVkLCBub3JtYWwgYmVoYXZpb3VyIGlzIHByb3ZpZGVkXHJcbiAgICAgIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIGRpZmZlcmVudCB2ZXJzaW9uXHJcbiAgICBpZiAodGhpcy5jb25maWcudmVyc2lvbiAhPT0gZW50cnkudmVyc2lvbikge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IGZyb21IZWFkZXIgPSB0cnVlO1xyXG4gICAgaWYgKHRoaXMuY29uZmlnLmNoZWNrUmVzcG9uc2VIZWFkZXJzKSB7XHJcbiAgICAgIC8vIGNoZWNrIGlmIHJlc3BvbnNlIGhlYWRlcnMgYWxsb3cgY2FjaGVcclxuICAgICAgZnJvbUhlYWRlciA9IGNoZWNrQ2FjaGVIZWFkZXJzKGVudHJ5LnJlc3BvbnNlLmhlYWRlcnMpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGVudHJ5LnJlc3BvbnNlLm9rICYmIGZyb21IZWFkZXI7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gdHJ1ZSBpZiB0aGUgcmVxdWVzdCBpcyBjYWNoZWFibGVcclxuICAgKi9cclxuICBpc0NhY2hlYWJsZTxLPihyZXE6IEh0dHBSZXF1ZXN0PEs+KTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBjb250ZXh0ID0gcmVxLmNvbnRleHQuZ2V0KE5HX0hUVFBfQ0FDSElOR19DT05URVhUKTtcclxuICAgIC8vIGlmIHVzZXIgcHJvdmlkZSBjdXN0b20gbWV0aG9kLCB1c2UgaXRcclxuICAgIGlmICh0eXBlb2YgY29udGV4dD8uaXNDYWNoZWFibGUgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgY29uc3QgcmVzdWx0ID0gY29udGV4dC5pc0NhY2hlYWJsZShyZXEpO1xyXG4gICAgICAvLyBpZiByZXN1bHQgaXMgdW5kZWZpbmVkLCBub3JtYWwgYmVoYXZpb3VyIGlzIHByb3ZpZGVkXHJcbiAgICAgIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIGlmIHVzZXIgcHJvdmlkZSBjdXN0b20gbWV0aG9kLCB1c2UgaXRcclxuICAgIGlmICh0eXBlb2YgdGhpcy5jb25maWcuaXNDYWNoZWFibGUgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5jb25maWcuaXNDYWNoZWFibGUocmVxKTtcclxuICAgICAgLy8gaWYgcmVzdWx0IGlzIHVuZGVmaW5lZCwgbm9ybWFsIGJlaGF2aW91ciBpcyBwcm92aWRlZFxyXG4gICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyByZXF1ZXN0IGhhcyBkaXNhbGxvdyBjYWNoZSBoZWFkZXJcclxuICAgIGlmIChyZXEuaGVhZGVycy5oYXMoTmdIdHRwQ2FjaGluZ0hlYWRlcnMuRElTQUxMT1dfQ0FDSEUpKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIC8vIHN0cmF0ZWd5IGlzIGRpc2FsbG93IGFsbC4uLlxyXG4gICAgaWYgKHRoaXMuY29uZmlnLmNhY2hlU3RyYXRlZ3kgPT09IE5nSHR0cENhY2hpbmdTdHJhdGVneS5ESVNBTExPV19BTEwpIHtcclxuICAgICAgLy8gcmVxdWVzdCBpc24ndCBhbGxvd2VkIGlmIGNvbWUgd2l0aG91dCBhbGxvdyBoZWFkZXJcclxuICAgICAgaWYgKCFyZXEuaGVhZGVycy5oYXMoTmdIdHRwQ2FjaGluZ0hlYWRlcnMuQUxMT1dfQ0FDSEUpKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBpZiBhbGxvd2VkIG1ldGhvZCBpcyBvbmx5IEFMTCwgYWxsb3cgYWxsIGh0dHAgbWV0aG9kc1xyXG4gICAgaWYgKHRoaXMuY29uZmlnLmFsbG93ZWRNZXRob2QubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgIGlmICh0aGlzLmNvbmZpZy5hbGxvd2VkTWV0aG9kWzBdID09PSAnQUxMJykge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyByZXF1ZXN0IGlzIGFsbG93ZWQgaWYgbWV0aG9kIGlzIGluIGFsbG93ZWRNZXRob2RcclxuICAgIHJldHVybiB0aGlzLmNvbmZpZy5hbGxvd2VkTWV0aG9kLmluZGV4T2YocmVxLm1ldGhvZCkgIT09IC0xO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJuIHRoZSBjYWNoZSBrZXkuXHJcbiAgICogRGVmYXVsdCBrZXkgaXMgaHR0cCBtZXRob2QgcGx1cyB1cmwgd2l0aCBxdWVyeSBwYXJhbWV0ZXJzLCBlZy46XHJcbiAgICogYEdFVEBodHRwczovL2dpdGh1Yi5jb20vbmlncm9zaW1vbmUvbmctaHR0cC1jYWNoaW5nYFxyXG4gICAqL1xyXG4gIGdldEtleTxLPihyZXE6IEh0dHBSZXF1ZXN0PEs+KTogc3RyaW5nIHtcclxuICAgIC8vIGlmIHVzZXIgcHJvdmlkZSBjdXN0b20gbWV0aG9kLCB1c2UgaXRcclxuICAgIGNvbnN0IGNvbnRleHQgPSByZXEuY29udGV4dC5nZXQoTkdfSFRUUF9DQUNISU5HX0NPTlRFWFQpO1xyXG4gICAgaWYgKHR5cGVvZiBjb250ZXh0LmdldEtleSA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICBjb25zdCByZXN1bHQgPSBjb250ZXh0LmdldEtleShyZXEpO1xyXG4gICAgICAvLyBpZiByZXN1bHQgaXMgdW5kZWZpbmVkLCBub3JtYWwgYmVoYXZpb3VyIGlzIHByb3ZpZGVkXHJcbiAgICAgIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIGlmIHVzZXIgcHJvdmlkZSBjdXN0b20gbWV0aG9kLCB1c2UgaXRcclxuICAgIGlmICh0eXBlb2YgdGhpcy5jb25maWcuZ2V0S2V5ID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuY29uZmlnLmdldEtleShyZXEpO1xyXG4gICAgICAvLyBpZiByZXN1bHQgaXMgdW5kZWZpbmVkLCBub3JtYWwgYmVoYXZpb3VyIGlzIHByb3ZpZGVkXHJcbiAgICAgIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIGRlZmF1bHQga2V5IGlzIHJlcS5tZXRob2QgcGx1cyB1cmwgd2l0aCBxdWVyeSBwYXJhbWV0ZXJzXHJcbiAgICByZXR1cm4gcmVxLm1ldGhvZCArICdAJyArIHJlcS51cmxXaXRoUGFyYW1zO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJuIG9ic2VydmFibGUgZnJvbSBjYWNoZVxyXG4gICAqL1xyXG4gIGdldEZyb21RdWV1ZTxLLCBUPihyZXE6IEh0dHBSZXF1ZXN0PEs+KTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8VD4+IHwgdW5kZWZpbmVkIHtcclxuICAgIGNvbnN0IGtleTogc3RyaW5nID0gdGhpcy5nZXRLZXkocmVxKTtcclxuICAgIGNvbnN0IGNhY2hlZDogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8VD4+IHwgdW5kZWZpbmVkID0gdGhpcy5xdWV1ZS5nZXQoa2V5KTtcclxuXHJcbiAgICBpZiAoIWNhY2hlZCkge1xyXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBjYWNoZWQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBZGQgb2JzZXJ2YWJsZSB0byBjYWNoZVxyXG4gICAqL1xyXG4gIGFkZFRvUXVldWU8SywgVD4ocmVxOiBIdHRwUmVxdWVzdDxLPiwgb2JzOiBPYnNlcnZhYmxlPEh0dHBFdmVudDxUPj4pOiB2b2lkIHtcclxuICAgIGNvbnN0IGtleTogc3RyaW5nID0gdGhpcy5nZXRLZXkocmVxKTtcclxuICAgIHRoaXMucXVldWUuc2V0KGtleSwgb2JzKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlbGV0ZSBvYnNlcnZhYmxlIGZyb20gY2FjaGVcclxuICAgKi9cclxuICBkZWxldGVGcm9tUXVldWU8Sz4ocmVxOiBIdHRwUmVxdWVzdDxLPik6IGJvb2xlYW4ge1xyXG4gICAgY29uc3Qga2V5OiBzdHJpbmcgPSB0aGlzLmdldEtleShyZXEpO1xyXG4gICAgcmV0dXJuIHRoaXMucXVldWUuZGVsZXRlKGtleSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWN1cnNpdmVseSBPYmplY3QuZnJlZXplIHNpbXBsZSBKYXZhc2NyaXB0IHN0cnVjdHVyZXMgY29uc2lzdGluZyBvZiBwbGFpbiBvYmplY3RzLCBhcnJheXMsIGFuZCBwcmltaXRpdmVzLlxyXG4gICAqIE1ha2UgdGhlIGRhdGEgaW1tdXRhYmxlLlxyXG4gICAqIEByZXR1cm5zIGltbXV0YWJsZSBvYmplY3RcclxuICAgKi9cclxuICBwcml2YXRlIGRlZXBGcmVlemU8Uz4ob2JqZWN0OiBTKTogUmVhZG9ubHk8Uz4ge1xyXG4gICAgLy8gTm8gZnJlZXppbmcgaW4gcHJvZHVjdGlvbiAoZm9yIGJldHRlciBwZXJmb3JtYW5jZSkuXHJcbiAgICBpZiAoIXRoaXMuZGV2TW9kZSB8fCAhb2JqZWN0IHx8IHR5cGVvZiBvYmplY3QgIT09ICdvYmplY3QnKSB7XHJcbiAgICAgIHJldHVybiBvYmplY3QgYXMgUmVhZG9ubHk8Uz47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gV2hlbiBhbHJlYWR5IGZyb3plbiwgd2UgYXNzdW1lIGl0cyBjaGlsZHJlbiBhcmUgZnJvemVuIChmb3IgYmV0dGVyIHBlcmZvcm1hbmNlKS5cclxuICAgIC8vIFRoaXMgc2hvdWxkIGJlIHRydWUgaWYgeW91IGFsd2F5cyB1c2UgYGRlZXBGcmVlemVgIHRvIGZyZWV6ZSBvYmplY3RzLlxyXG4gICAgLy9cclxuICAgIC8vIE5vdGUgdGhhdCBPYmplY3QuaXNGcm96ZW4gd2lsbCBhbHNvIHJldHVybiBgdHJ1ZWAgZm9yIHByaW1pdGl2ZXMgKG51bWJlcnMsXHJcbiAgICAvLyBzdHJpbmdzLCBib29sZWFucywgdW5kZWZpbmVkLCBudWxsKSwgc28gdGhlcmUgaXMgbm8gbmVlZCB0byBjaGVjayBmb3JcclxuICAgIC8vIHRob3NlIGV4cGxpY2l0bHkuXHJcbiAgICBpZiAoT2JqZWN0LmlzRnJvemVuKG9iamVjdCkpIHtcclxuICAgICAgcmV0dXJuIG9iamVjdCBhcyBSZWFkb25seTxTPjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBBdCB0aGlzIHBvaW50IHdlIGtub3cgdGhhdCB3ZSdyZSBkZWFsaW5nIHdpdGggZWl0aGVyIGFuIGFycmF5IG9yIHBsYWluIG9iamVjdCwgc29cclxuICAgIC8vIGp1c3QgZnJlZXplIGl0IGFuZCByZWN1cnNlIG9uIGl0cyB2YWx1ZXMuXHJcbiAgICBPYmplY3QuZnJlZXplKG9iamVjdCk7XHJcbiAgICBPYmplY3Qua2V5cyhvYmplY3QpLmZvckVhY2goa2V5ID0+IHRoaXMuZGVlcEZyZWV6ZSgob2JqZWN0IGFzIGFueSlba2V5XSkpO1xyXG5cclxuICAgIHJldHVybiBvYmplY3QgYXMgUmVhZG9ubHk8Uz47XHJcbiAgfVxyXG59XHJcbiJdfQ==
|
|
@@ -9,6 +9,31 @@ class NgHttpCachingMemoryStorage extends Map {
|
|
|
9
9
|
|
|
10
10
|
const NG_HTTP_CACHING_CONTEXT = new HttpContextToken(() => ({}));
|
|
11
11
|
const withNgHttpCachingContext = (value, context = new HttpContext()) => context.set(NG_HTTP_CACHING_CONTEXT, value);
|
|
12
|
+
const checkCacheHeaders = (headers) => {
|
|
13
|
+
// check Cache-Control
|
|
14
|
+
const cacheControlHeader = headers.get('cache-control');
|
|
15
|
+
if (cacheControlHeader) {
|
|
16
|
+
const cacheControl = cacheControlHeader.toLowerCase();
|
|
17
|
+
if (cacheControl.includes('no-store')) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
else if (cacheControl.includes('no-cache')) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// check Expires header Expires if response is without Cache-Control
|
|
28
|
+
const expiresHeader = headers.get('expires');
|
|
29
|
+
if (expiresHeader) {
|
|
30
|
+
const expires = Date.parse(expiresHeader);
|
|
31
|
+
if (!isNaN(expires)) {
|
|
32
|
+
return expires > Date.now();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
};
|
|
12
37
|
const NG_HTTP_CACHING_CONFIG = new InjectionToken('ng-http-caching.config');
|
|
13
38
|
var NgHttpCachingStrategy;
|
|
14
39
|
(function (NgHttpCachingStrategy) {
|
|
@@ -55,6 +80,7 @@ const NgHttpCachingConfigDefault = {
|
|
|
55
80
|
version: VERSION.major,
|
|
56
81
|
allowedMethod: ['GET', 'HEAD'],
|
|
57
82
|
cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,
|
|
83
|
+
checkResponseHeaders: false
|
|
58
84
|
};
|
|
59
85
|
class NgHttpCachingService {
|
|
60
86
|
constructor(config) {
|
|
@@ -241,7 +267,7 @@ class NgHttpCachingService {
|
|
|
241
267
|
}
|
|
242
268
|
/**
|
|
243
269
|
* Return true if cache entry is valid for store in the cache
|
|
244
|
-
* Default behaviour is whether the status code falls in the 2xx range.
|
|
270
|
+
* Default behaviour is whether the status code falls in the 2xx range and response headers cache-control and expires allow cache.
|
|
245
271
|
*/
|
|
246
272
|
isValid(entry) {
|
|
247
273
|
const context = entry.request.context.get(NG_HTTP_CACHING_CONTEXT);
|
|
@@ -265,7 +291,12 @@ class NgHttpCachingService {
|
|
|
265
291
|
if (this.config.version !== entry.version) {
|
|
266
292
|
return false;
|
|
267
293
|
}
|
|
268
|
-
|
|
294
|
+
let fromHeader = true;
|
|
295
|
+
if (this.config.checkResponseHeaders) {
|
|
296
|
+
// check if response headers allow cache
|
|
297
|
+
fromHeader = checkCacheHeaders(entry.response.headers);
|
|
298
|
+
}
|
|
299
|
+
return entry.response.ok && fromHeader;
|
|
269
300
|
}
|
|
270
301
|
/**
|
|
271
302
|
* Return true if the request is cacheable
|
|
@@ -667,5 +698,5 @@ class NgHttpCachingSessionStorage extends NgHttpCachingBrowserStorage {
|
|
|
667
698
|
* Generated bundle index. Do not edit.
|
|
668
699
|
*/
|
|
669
700
|
|
|
670
|
-
export { NG_HTTP_CACHING_CONFIG, NG_HTTP_CACHING_CONTEXT, NG_HTTP_CACHING_DAY_IN_MS, NG_HTTP_CACHING_HOUR_IN_MS, NG_HTTP_CACHING_MINUTE_IN_MS, NG_HTTP_CACHING_MONTH_IN_MS, NG_HTTP_CACHING_SECOND_IN_MS, NG_HTTP_CACHING_WEEK_IN_MS, NG_HTTP_CACHING_YEAR_IN_MS, NgHttpCachingBrowserStorage, NgHttpCachingConfigDefault, NgHttpCachingHeaders, NgHttpCachingHeadersList, NgHttpCachingInterceptorService, NgHttpCachingLocalStorage, NgHttpCachingMemoryStorage, NgHttpCachingModule, NgHttpCachingService, NgHttpCachingSessionStorage, NgHttpCachingStrategy, deserializeRequest, deserializeResponse, serializeRequest, serializeResponse, withNgHttpCachingContext };
|
|
701
|
+
export { NG_HTTP_CACHING_CONFIG, NG_HTTP_CACHING_CONTEXT, NG_HTTP_CACHING_DAY_IN_MS, NG_HTTP_CACHING_HOUR_IN_MS, NG_HTTP_CACHING_MINUTE_IN_MS, NG_HTTP_CACHING_MONTH_IN_MS, NG_HTTP_CACHING_SECOND_IN_MS, NG_HTTP_CACHING_WEEK_IN_MS, NG_HTTP_CACHING_YEAR_IN_MS, NgHttpCachingBrowserStorage, NgHttpCachingConfigDefault, NgHttpCachingHeaders, NgHttpCachingHeadersList, NgHttpCachingInterceptorService, NgHttpCachingLocalStorage, NgHttpCachingMemoryStorage, NgHttpCachingModule, NgHttpCachingService, NgHttpCachingSessionStorage, NgHttpCachingStrategy, checkCacheHeaders, deserializeRequest, deserializeResponse, serializeRequest, serializeResponse, withNgHttpCachingContext };
|
|
671
702
|
//# sourceMappingURL=ng-http-caching.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-http-caching.mjs","sources":["../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-memory-storage.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching.service.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching-interceptor.service.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching.module.ts","../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-browser-storage.ts","../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-local-storage.ts","../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-session-storage.ts","../../../projects/ng-http-caching/src/public-api.ts","../../../projects/ng-http-caching/src/ng-http-caching.ts"],"sourcesContent":["import { NgHttpCachingStorageInterface } from './ng-http-caching-storage.interface';\r\nimport { NgHttpCachingEntry } from '../ng-http-caching.service';\r\n\r\nexport class NgHttpCachingMemoryStorage extends Map<string, NgHttpCachingEntry<any, any>> implements NgHttpCachingStorageInterface { }\r\n","import { Injectable, InjectionToken, Inject, Optional, VERSION, isDevMode } from '@angular/core';\r\nimport { HttpRequest, HttpResponse, HttpEvent, HttpContextToken, HttpContext } from '@angular/common/http';\r\nimport { Observable } from 'rxjs/internal/Observable';\r\nimport { NgHttpCachingStorageInterface } from './storage/ng-http-caching-storage.interface';\r\nimport { NgHttpCachingMemoryStorage } from './storage/ng-http-caching-memory-storage';\r\n\r\nexport type NgHttpCachingContext = Pick<NgHttpCachingConfig, 'getKey' | 'isCacheable' | 'isExpired' | 'isValid'>;\r\n\r\nexport const NG_HTTP_CACHING_CONTEXT = new HttpContextToken<NgHttpCachingContext>(() => ({}));\r\n\r\nexport const withNgHttpCachingContext = (value: NgHttpCachingContext, context: HttpContext = new HttpContext()) => context.set(NG_HTTP_CACHING_CONTEXT, value)\r\n\r\nexport interface NgHttpCachingEntry<K = any, T = any> {\r\n /**\r\n * URL\r\n */\r\n url: string;\r\n /**\r\n * HttpResponse\r\n */\r\n response: HttpResponse<T>;\r\n /**\r\n * HttpRequest\r\n */\r\n request: HttpRequest<K>;\r\n /**\r\n * Timestamp of add to cache time\r\n */\r\n addedTime: number;\r\n /**\r\n * Cache version\r\n */\r\n version: string;\r\n}\r\n\r\nexport const NG_HTTP_CACHING_CONFIG = new InjectionToken<NgHttpCachingContext>(\r\n 'ng-http-caching.config'\r\n);\r\n\r\nexport enum NgHttpCachingStrategy {\r\n /**\r\n * All request are cacheable if HTTP method is into `allowedMethod`\r\n */\r\n ALLOW_ALL = 'ALLOW_ALL',\r\n /**\r\n * Only the request with `X-NG-HTTP-CACHING-ALLOW-CACHE` header are cacheable if HTTP method is into `allowedMethod`\r\n */\r\n DISALLOW_ALL = 'DISALLOW_ALL'\r\n}\r\n\r\nexport enum NgHttpCachingHeaders {\r\n /**\r\n * Request is cacheable if HTTP method is into `allowedMethod`\r\n */\r\n ALLOW_CACHE = 'X-NG-HTTP-CACHING-ALLOW-CACHE',\r\n /**\r\n * Request isn't cacheable\r\n */\r\n DISALLOW_CACHE = 'X-NG-HTTP-CACHING-DISALLOW-CACHE',\r\n /**\r\n * Specific cache lifetime for the request\r\n */\r\n LIFETIME = 'X-NG-HTTP-CACHING-LIFETIME',\r\n /**\r\n * You can tag multiple request by adding this header with the same tag and \r\n * using `NgHttpCachingService.clearCacheByTag(tag: string)` for delete all the tagged request\r\n */\r\n TAG = 'X-NG-HTTP-CACHING-TAG'\r\n}\r\n\r\nexport const NgHttpCachingHeadersList = Object.values(NgHttpCachingHeaders);\r\n\r\nexport const NG_HTTP_CACHING_SECOND_IN_MS = 1000;\r\nexport const NG_HTTP_CACHING_MINUTE_IN_MS = NG_HTTP_CACHING_SECOND_IN_MS * 60;\r\nexport const NG_HTTP_CACHING_HOUR_IN_MS = NG_HTTP_CACHING_MINUTE_IN_MS * 60;\r\nexport const NG_HTTP_CACHING_DAY_IN_MS = NG_HTTP_CACHING_HOUR_IN_MS * 24;\r\nexport const NG_HTTP_CACHING_WEEK_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 7;\r\nexport const NG_HTTP_CACHING_MONTH_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 30;\r\nexport const NG_HTTP_CACHING_YEAR_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 365;\r\n\r\nexport interface NgHttpCachingConfig {\r\n /**\r\n * Set the cache store. You can implement your custom store by implement the `NgHttpCachingStorageInterface` interface, eg.:\r\n */\r\n store?: NgHttpCachingStorageInterface;\r\n /**\r\n * Number of millisecond that a response is stored in the cache. \r\n * You can set specific \"lifetime\" for each request by add the header `X-NG-HTTP-CACHING-LIFETIME` (see example below).\r\n */\r\n lifetime?: number;\r\n /**\r\n * Array of allowed HTTP methods to cache. \r\n * You can allow multiple methods, eg.: `['GET', 'POST', 'PUT', 'DELETE', 'HEAD']` or \r\n * allow all methods by: `['ALL']`. If `allowedMethod` is an empty array (`[]`), no response are cached.\r\n * *Warning!* `NgHttpCaching` use the full url (url with query parameters) as unique key for the cached response,\r\n * this is correct for the `GET` request but is _potentially_ wrong for other type of request (eg. `POST`, `PUT`). \r\n * You can set a different \"key\" by customizing the `getKey` config method (see `getKey` section).\r\n */\r\n allowedMethod?: string[];\r\n /**\r\n * Set the cache strategy, possible strategies are:\r\n * - `NgHttpCachingStrategy.ALLOW_ALL`: All request are cacheable if HTTP method is into `allowedMethod`;\r\n * - `NgHttpCachingStrategy.DISALLOW_ALL`: Only the request with `X-NG-HTTP-CACHING-ALLOW-CACHE` header are cacheable if HTTP method is into `allowedMethod`;\r\n */\r\n cacheStrategy?: NgHttpCachingStrategy;\r\n /**\r\n * Cache version. When you have a breaking change, change the version, and it'll delete the current cache automatically.\r\n * The default value is Angular major version (eg. 13), in this way, the cache is invalidated on every Angular upgrade.\r\n */\r\n version?: string;\r\n /**\r\n * If this function return `true` the request is expired and a new request is send to backend, if return `false` isn't expired. \r\n * If the result is `undefined`, the normal behaviour is provided.\r\n */\r\n isExpired?: <K, T>(entry: NgHttpCachingEntry<K, T>) => boolean | undefined | void;\r\n /**\r\n * If this function return `true` the request is cacheable, if return `false` isn't cacheable. \r\n * If the result is `undefined`, the normal behaviour is provided.\r\n */\r\n isCacheable?: <K>(req: HttpRequest<K>) => boolean | undefined | void;\r\n /**\r\n * This function return the unique key (`string`) for store the response into the cache. \r\n * If the result is `undefined`, the normal behaviour is provided.\r\n */\r\n getKey?: <K>(req: HttpRequest<K>) => string | undefined | void;\r\n /**\r\n * If this function return `true` the cache entry is valid and can be stored, if return `false` isn't valid. \r\n * If the result is `undefined`, the normal behaviour is provided.\r\n */\r\n isValid?: <K, T>(entry: NgHttpCachingEntry<K, T>) => boolean | undefined | void;\r\n}\r\n\r\nexport interface NgHttpCachingDefaultConfig extends NgHttpCachingConfig {\r\n store: NgHttpCachingStorageInterface;\r\n lifetime: number;\r\n allowedMethod: string[];\r\n cacheStrategy: NgHttpCachingStrategy;\r\n version: string;\r\n}\r\n\r\nexport const NgHttpCachingConfigDefault: Readonly<NgHttpCachingDefaultConfig> = {\r\n store: new NgHttpCachingMemoryStorage(),\r\n lifetime: NG_HTTP_CACHING_HOUR_IN_MS,\r\n version: VERSION.major,\r\n allowedMethod: ['GET', 'HEAD'],\r\n cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,\r\n};\r\n\r\n@Injectable()\r\nexport class NgHttpCachingService {\r\n\r\n private readonly queue = new Map<string, Observable<HttpEvent<any>>>();\r\n\r\n private readonly config: NgHttpCachingDefaultConfig;\r\n\r\n private gcLock = false;\r\n\r\n private devMode: boolean = isDevMode();\r\n\r\n constructor(\r\n @Inject(NG_HTTP_CACHING_CONFIG) @Optional() config: Readonly<NgHttpCachingConfig>\r\n ) {\r\n if (config) {\r\n this.config = { ...NgHttpCachingConfigDefault, ...config };\r\n } else {\r\n this.config = { ...NgHttpCachingConfigDefault };\r\n }\r\n // start cache clean\r\n this.runGc();\r\n }\r\n\r\n /**\r\n * Return the config\r\n */\r\n getConfig(): Readonly<NgHttpCachingConfig> {\r\n return this.config;\r\n }\r\n\r\n /**\r\n * Return the queue map\r\n */\r\n getQueue(): Readonly<Map<string, Observable<HttpEvent<any>>>> {\r\n return this.queue;\r\n }\r\n\r\n /**\r\n * Return the cache store\r\n */\r\n getStore(): Readonly<NgHttpCachingStorageInterface> {\r\n return this.config.store;\r\n }\r\n\r\n /**\r\n * Return response from cache\r\n */\r\n getFromCache<K, T>(req: HttpRequest<K>): Readonly<HttpResponse<T>> | undefined {\r\n const key: string = this.getKey(req);\r\n const cached: NgHttpCachingEntry<K, T> | undefined = this.config.store.get<K, T>(key);\r\n\r\n if (!cached) {\r\n return undefined;\r\n }\r\n\r\n if (this.isExpired(cached)) {\r\n this.clearCacheByKey(key);\r\n return undefined;\r\n }\r\n\r\n return this.deepFreeze(cached.response);\r\n }\r\n\r\n /**\r\n * Add response to cache\r\n */\r\n addToCache<K, T>(req: HttpRequest<K>, res: HttpResponse<T>): boolean {\r\n const entry: NgHttpCachingEntry<K, T> = {\r\n url: req.urlWithParams,\r\n response: res,\r\n request: req,\r\n addedTime: Date.now(),\r\n version: this.config.version,\r\n };\r\n if (this.isValid(entry)) {\r\n const key: string = this.getKey(req);\r\n this.config.store.set(key, entry);\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Delete response from cache\r\n */\r\n deleteFromCache<K>(req: HttpRequest<K>): boolean {\r\n const key: string = this.getKey(req);\r\n return this.clearCacheByKey(key);\r\n }\r\n\r\n /**\r\n * Clear the cache\r\n */\r\n clearCache(): void {\r\n this.config.store.clear();\r\n }\r\n\r\n /**\r\n * Clear the cache by key\r\n */\r\n clearCacheByKey(key: string): boolean {\r\n return this.config.store.delete(key);\r\n }\r\n\r\n /**\r\n * Clear the cache by keys\r\n */\r\n clearCacheByKeys(keys: Array<string>): number {\r\n let counter = 0;\r\n if (keys) {\r\n for (const key of keys) {\r\n if (this.clearCacheByKey(key)) {\r\n counter++;\r\n }\r\n }\r\n }\r\n return counter;\r\n }\r\n\r\n /**\r\n * Clear the cache by regex\r\n */\r\n clearCacheByRegex<K, T>(regex: RegExp): number {\r\n const keys: Array<string> = [];\r\n this.config.store.forEach<K, T>((_: NgHttpCachingEntry<K, T>, key: string) => {\r\n if (regex.test(key)) {\r\n keys.push(key);\r\n }\r\n });\r\n return this.clearCacheByKeys(keys);\r\n }\r\n\r\n /**\r\n * Clear the cache by TAG\r\n */\r\n clearCacheByTag<K, T>(tag: string): number {\r\n const keys: Array<string> = [];\r\n this.config.store.forEach<K, T>((entry: NgHttpCachingEntry<K, T>, key: string) => {\r\n const tagHeader = entry.request.headers.get(NgHttpCachingHeaders.TAG);\r\n if (tagHeader && tagHeader.split(',').includes(tag)) {\r\n keys.push(key);\r\n }\r\n });\r\n return this.clearCacheByKeys(keys);\r\n }\r\n\r\n /**\r\n * Run garbage collector (delete expired cache entry)\r\n */\r\n runGc<K, T>(): boolean {\r\n if (this.gcLock) {\r\n return false;\r\n }\r\n this.gcLock = true;\r\n const keys: Array<string> = [];\r\n this.config.store.forEach<K, T>((entry: NgHttpCachingEntry<K, T>, key: string) => {\r\n if (this.isExpired(entry)) {\r\n keys.push(key);\r\n }\r\n });\r\n this.clearCacheByKeys(keys);\r\n this.gcLock = false;\r\n return true;\r\n }\r\n\r\n /**\r\n * Return true if cache entry is expired\r\n */\r\n isExpired<K, T>(entry: NgHttpCachingEntry<K, T>): boolean {\r\n // if user provide custom method, use it\r\n const context = entry.request.context.get(NG_HTTP_CACHING_CONTEXT);\r\n if (typeof context?.isExpired === 'function') {\r\n const result = context.isExpired(entry);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // if user provide custom method, use it\r\n if (typeof this.config.isExpired === 'function') {\r\n const result = this.config.isExpired(entry);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // if version change, always expire\r\n if (this.config.version !== entry.version) {\r\n return true;\r\n }\r\n // config/default lifetime\r\n let lifetime: number = this.config.lifetime;\r\n // request has own lifetime\r\n const headerLifetime = entry.request.headers.get(NgHttpCachingHeaders.LIFETIME);\r\n if (headerLifetime) {\r\n lifetime = +headerLifetime;\r\n }\r\n // never expire if 0\r\n if (lifetime === 0) {\r\n return false;\r\n }\r\n // wrong lifetime\r\n if (lifetime < 0 || isNaN(lifetime)) {\r\n throw new Error('lifetime must be greater than or equal 0');\r\n }\r\n return entry.addedTime + lifetime < Date.now();\r\n }\r\n\r\n /**\r\n * Return true if cache entry is valid for store in the cache\r\n * Default behaviour is whether the status code falls in the 2xx range.\r\n */\r\n isValid<K, T>(entry: NgHttpCachingEntry<K, T>): boolean {\r\n const context = entry.request.context.get(NG_HTTP_CACHING_CONTEXT);\r\n // if user provide custom method, use it\r\n if (typeof context.isValid === 'function') {\r\n const result = context.isValid(entry);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // if user provide custom method, use it\r\n if (typeof this.config.isValid === 'function') {\r\n const result = this.config.isValid(entry);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // different version\r\n if (this.config.version !== entry.version) {\r\n return false;\r\n }\r\n return entry.response.ok;\r\n }\r\n\r\n /**\r\n * Return true if the request is cacheable\r\n */\r\n isCacheable<K>(req: HttpRequest<K>): boolean {\r\n const context = req.context.get(NG_HTTP_CACHING_CONTEXT);\r\n // if user provide custom method, use it\r\n if (typeof context?.isCacheable === 'function') {\r\n const result = context.isCacheable(req);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // if user provide custom method, use it\r\n if (typeof this.config.isCacheable === 'function') {\r\n const result = this.config.isCacheable(req);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // request has disallow cache header\r\n if (req.headers.has(NgHttpCachingHeaders.DISALLOW_CACHE)) {\r\n return false;\r\n }\r\n // strategy is disallow all...\r\n if (this.config.cacheStrategy === NgHttpCachingStrategy.DISALLOW_ALL) {\r\n // request isn't allowed if come without allow header\r\n if (!req.headers.has(NgHttpCachingHeaders.ALLOW_CACHE)) {\r\n return false;\r\n }\r\n }\r\n // if allowed method is only ALL, allow all http methods\r\n if (this.config.allowedMethod.length === 1) {\r\n if (this.config.allowedMethod[0] === 'ALL') {\r\n return true;\r\n }\r\n }\r\n // request is allowed if method is in allowedMethod\r\n return this.config.allowedMethod.indexOf(req.method) !== -1;\r\n }\r\n\r\n /**\r\n * Return the cache key.\r\n * Default key is http method plus url with query parameters, eg.:\r\n * `GET@https://github.com/nigrosimone/ng-http-caching`\r\n */\r\n getKey<K>(req: HttpRequest<K>): string {\r\n // if user provide custom method, use it\r\n const context = req.context.get(NG_HTTP_CACHING_CONTEXT);\r\n if (typeof context.getKey === 'function') {\r\n const result = context.getKey(req);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // if user provide custom method, use it\r\n if (typeof this.config.getKey === 'function') {\r\n const result = this.config.getKey(req);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // default key is req.method plus url with query parameters\r\n return req.method + '@' + req.urlWithParams;\r\n }\r\n\r\n /**\r\n * Return observable from cache\r\n */\r\n getFromQueue<K, T>(req: HttpRequest<K>): Observable<HttpEvent<T>> | undefined {\r\n const key: string = this.getKey(req);\r\n const cached: Observable<HttpEvent<T>> | undefined = this.queue.get(key);\r\n\r\n if (!cached) {\r\n return undefined;\r\n }\r\n\r\n return cached;\r\n }\r\n\r\n /**\r\n * Add observable to cache\r\n */\r\n addToQueue<K, T>(req: HttpRequest<K>, obs: Observable<HttpEvent<T>>): void {\r\n const key: string = this.getKey(req);\r\n this.queue.set(key, obs);\r\n }\r\n\r\n /**\r\n * Delete observable from cache\r\n */\r\n deleteFromQueue<K>(req: HttpRequest<K>): boolean {\r\n const key: string = this.getKey(req);\r\n return this.queue.delete(key);\r\n }\r\n\r\n /**\r\n * Recursively Object.freeze simple Javascript structures consisting of plain objects, arrays, and primitives.\r\n * Make the data immutable.\r\n * @returns immutable object\r\n */\r\n private deepFreeze<S>(object: S): Readonly<S> {\r\n // No freezing in production (for better performance).\r\n if (!this.devMode || !object || typeof object !== 'object') {\r\n return object as Readonly<S>;\r\n }\r\n\r\n // When already frozen, we assume its children are frozen (for better performance).\r\n // This should be true if you always use `deepFreeze` to freeze objects.\r\n //\r\n // Note that Object.isFrozen will also return `true` for primitives (numbers,\r\n // strings, booleans, undefined, null), so there is no need to check for\r\n // those explicitly.\r\n if (Object.isFrozen(object)) {\r\n return object as Readonly<S>;\r\n }\r\n\r\n // At this point we know that we're dealing with either an array or plain object, so\r\n // just freeze it and recurse on its values.\r\n Object.freeze(object);\r\n Object.keys(object).forEach(key => this.deepFreeze((object as any)[key]));\r\n\r\n return object as Readonly<S>;\r\n }\r\n}\r\n","import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { asyncScheduler, Observable, of, scheduled } from 'rxjs';\r\nimport { tap, finalize, shareReplay } from 'rxjs/operators';\r\nimport { NgHttpCachingService, NgHttpCachingHeadersList } from './ng-http-caching.service';\r\n\r\n@Injectable()\r\nexport class NgHttpCachingInterceptorService implements HttpInterceptor {\r\n\r\n constructor(private readonly cacheService: NgHttpCachingService) { }\r\n\r\n intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\r\n // run garbage collector\r\n this.cacheService.runGc();\r\n\r\n // Don't cache if it's not cacheable\r\n if (!this.cacheService.isCacheable(req)) {\r\n return this.sendRequest(req, next);\r\n }\r\n\r\n // Checked if there is pending response for this request\r\n const cachedObservable: Observable<HttpEvent<any>> | undefined = this.cacheService.getFromQueue(req);\r\n if (cachedObservable) {\r\n // console.log('cachedObservable',cachedObservable);\r\n return cachedObservable;\r\n }\r\n\r\n // Checked if there is cached response for this request\r\n const cachedResponse: HttpResponse<any> | undefined = this.cacheService.getFromCache(req);\r\n if (cachedResponse) {\r\n // console.log('cachedResponse');\r\n return scheduled(of(cachedResponse.clone()), asyncScheduler);\r\n }\r\n\r\n // If the request of going through for first time\r\n // then let the request proceed and cache the response\r\n // console.log('sendRequest', req);\r\n const shared = this.sendRequest(req, next).pipe(\r\n tap(event => {\r\n if (event instanceof HttpResponse) {\r\n this.cacheService.addToCache(req, event.clone());\r\n }\r\n }),\r\n finalize(() => {\r\n // delete pending request\r\n this.cacheService.deleteFromQueue(req);\r\n }),\r\n shareReplay()\r\n );\r\n\r\n // add pending request to queue for cache parallel request\r\n this.cacheService.addToQueue(req, shared);\r\n\r\n return shared;\r\n }\r\n\r\n /**\r\n * Send http request (next handler)\r\n */\r\n sendRequest(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\r\n let cloned: HttpRequest<any> = req.clone();\r\n // trim custom headers before send request\r\n NgHttpCachingHeadersList.forEach(ngHttpCachingHeaders => {\r\n if (cloned.headers.has(ngHttpCachingHeaders)) {\r\n cloned = cloned.clone({ headers: cloned.headers.delete(ngHttpCachingHeaders) });\r\n }\r\n });\r\n return next.handle(cloned);\r\n }\r\n}\r\n","import { NgModule, ModuleWithProviders } from '@angular/core';\r\nimport { HTTP_INTERCEPTORS } from '@angular/common/http';\r\nimport {\r\n NG_HTTP_CACHING_CONFIG,\r\n NgHttpCachingConfig,\r\n NgHttpCachingService,\r\n} from './ng-http-caching.service';\r\nimport { NgHttpCachingInterceptorService } from './ng-http-caching-interceptor.service';\r\n\r\n@NgModule({\r\n providers: [\r\n NgHttpCachingService,\r\n NgHttpCachingInterceptorService,\r\n {\r\n provide: HTTP_INTERCEPTORS,\r\n useClass: NgHttpCachingInterceptorService,\r\n multi: true,\r\n },\r\n ]\r\n})\r\nexport class NgHttpCachingModule {\r\n static forRoot(\r\n ngHttpCachingConfig?: NgHttpCachingConfig\r\n ): ModuleWithProviders<NgHttpCachingModule> {\r\n return {\r\n ngModule: NgHttpCachingModule,\r\n providers: [\r\n {\r\n provide: NG_HTTP_CACHING_CONFIG,\r\n useValue: ngHttpCachingConfig,\r\n },\r\n ],\r\n };\r\n }\r\n}\r\n","import { NgHttpCachingStorageInterface } from './ng-http-caching-storage.interface';\r\nimport { NgHttpCachingEntry } from '../ng-http-caching.service';\r\nimport { HttpHeaders, HttpParams, HttpRequest, HttpResponse } from '@angular/common/http';\r\n\r\nconst KEY_PREFIX = 'NgHttpCaching::';\r\n\r\nexport interface NgHttpCachingStorageEntry {\r\n url: string;\r\n response: string;\r\n request: string;\r\n addedTime: number;\r\n version: string;\r\n}\r\n\r\nexport const serializeRequest = (req: HttpRequest<any>): string => {\r\n const request = req.clone(); // Make a clone, useful for doing destructive things\r\n return JSON.stringify({\r\n headers: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n request.headers.keys().map( // Get all of the headers\r\n (key: string) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n )\r\n ),\r\n method: request.method, // The Request Method, e.g. GET, POST, DELETE\r\n url: request.url, // The URL\r\n params: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n request.headers.keys().map( // Get all of the headers\r\n (key: string) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n )\r\n ), // The request parameters\r\n withCredentials: request.withCredentials, // Whether credentials are being sent\r\n responseType: request.responseType, // The response type\r\n body: request.serializeBody() // Serialize the body, all well and good since we are working on a clone\r\n });\r\n}\r\n\r\nexport const serializeResponse = (res: HttpResponse<any>): string => {\r\n const response = res.clone();\r\n return JSON.stringify({\r\n headers: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n response.headers.keys().map( // Get all of the headers\r\n (key: string) => [key, response.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n )\r\n ),\r\n status: response.status,\r\n statusText: response.statusText,\r\n url: response.url,\r\n body: response.body // Serialize the body, all well and good since we are working on a clone\r\n });\r\n}\r\n\r\nexport const deserializeRequest = <T = any>(req: string): HttpRequest<T> => {\r\n const request = JSON.parse(req);\r\n const headers = new HttpHeaders(request.headers);\r\n const params = new HttpParams(); // Probably some way to make this a one-liner, but alas, there are no good docs\r\n for (const parameter in request.params) {\r\n request.params[parameter].forEach((paramValue: string) => params.append(parameter, paramValue));\r\n }\r\n return new HttpRequest(request.method, request.url, request.body, {\r\n headers,\r\n params,\r\n responseType: request.responseType,\r\n withCredentials: request.withCredentials\r\n });\r\n}\r\n\r\nexport const deserializeResponse = <T = any>(res: string): HttpResponse<T> => {\r\n const response = JSON.parse(res);\r\n return new HttpResponse<T>({\r\n url: response.url,\r\n headers: new HttpHeaders(response.headers),\r\n body: response.body,\r\n status: response.status,\r\n statusText: response.statusText,\r\n });\r\n}\r\n\r\nexport class NgHttpCachingBrowserStorage implements NgHttpCachingStorageInterface {\r\n\r\n constructor(private storage: Storage) { }\r\n\r\n get size(): number {\r\n let count = 0;\r\n for (let i = 0, e = this.storage.length; i < e; i++) {\r\n const key = this.storage.key(i);\r\n if (key && key.startsWith(KEY_PREFIX)) {\r\n count++;\r\n }\r\n }\r\n return count;\r\n }\r\n\r\n clear(): void {\r\n for (let i = this.storage.length; i >= 0; i--) {\r\n const key = this.storage.key(i);\r\n if (key && key.startsWith(KEY_PREFIX)) {\r\n this.storage.removeItem(key);\r\n }\r\n }\r\n }\r\n\r\n delete(key: string): boolean {\r\n if (!key) {\r\n return false;\r\n }\r\n if (!key.startsWith(KEY_PREFIX)) {\r\n key = KEY_PREFIX + key;\r\n }\r\n this.storage.removeItem(key);\r\n return true;\r\n }\r\n\r\n forEach(callbackfn: (value: NgHttpCachingEntry, key: string) => void): void {\r\n // iterate this.storage\r\n for (let i = 0, e = this.storage.length; i < e; i++) {\r\n const keyWithPrefix = this.storage.key(i);\r\n if (keyWithPrefix && keyWithPrefix.startsWith(KEY_PREFIX)) {\r\n const value = this.get(keyWithPrefix);\r\n if (value) {\r\n const keyWithoutPrefix = keyWithPrefix.substring(KEY_PREFIX.length);\r\n callbackfn(value, keyWithoutPrefix);\r\n }\r\n }\r\n }\r\n }\r\n\r\n get(key: string): Readonly<NgHttpCachingEntry> | undefined {\r\n if (!key) {\r\n return undefined;\r\n }\r\n if (!key.startsWith(KEY_PREFIX)) {\r\n key = KEY_PREFIX + key;\r\n }\r\n const item = this.storage.getItem(key);\r\n if (item) {\r\n const parsedItem: NgHttpCachingStorageEntry = JSON.parse(item);\r\n return this.deserialize(parsedItem);\r\n }\r\n return undefined;\r\n }\r\n\r\n has(key: string): boolean {\r\n if (!key) {\r\n return false;\r\n }\r\n if (!key.startsWith(KEY_PREFIX)) {\r\n key = KEY_PREFIX + key;\r\n }\r\n return !!this.storage.getItem(key);\r\n }\r\n\r\n set(key: string, value: NgHttpCachingEntry): void {\r\n if (!key) {\r\n return;\r\n }\r\n if (!key.startsWith(KEY_PREFIX)) {\r\n key = KEY_PREFIX + key;\r\n }\r\n const unParsedItem: NgHttpCachingStorageEntry = this.serialize(value);\r\n this.storage.setItem(key, JSON.stringify(unParsedItem));\r\n }\r\n\r\n protected serialize(value: NgHttpCachingEntry): NgHttpCachingStorageEntry {\r\n return {\r\n url: value.url,\r\n response: serializeResponse(value.response),\r\n request: serializeRequest(value.request),\r\n addedTime: value.addedTime,\r\n version: value.version\r\n };\r\n }\r\n\r\n protected deserialize(value: NgHttpCachingStorageEntry): NgHttpCachingEntry {\r\n return {\r\n url: value.url,\r\n response: deserializeResponse(value.response),\r\n request: deserializeRequest(value.request),\r\n addedTime: value.addedTime,\r\n version: value.version\r\n };\r\n }\r\n}\r\n\r\n","import { NgHttpCachingBrowserStorage } from './ng-http-caching-browser-storage';\r\n\r\nexport class NgHttpCachingLocalStorage extends NgHttpCachingBrowserStorage {\r\n\r\n constructor() {\r\n super(localStorage);\r\n }\r\n}\r\n","import { NgHttpCachingBrowserStorage } from './ng-http-caching-browser-storage';\r\n\r\nexport class NgHttpCachingSessionStorage extends NgHttpCachingBrowserStorage {\r\n\r\n constructor() {\r\n super(sessionStorage);\r\n }\r\n}\r\n","/*\r\n * Public API Surface of ng-http-caching\r\n */\r\n\r\nexport * from './lib/ng-http-caching-interceptor.service';\r\nexport * from './lib/ng-http-caching.service';\r\nexport * from './lib/ng-http-caching.module';\r\nexport * from './lib/storage/ng-http-caching-storage.interface';\r\nexport * from './lib/storage/ng-http-caching-memory-storage';\r\nexport * from './lib/storage/ng-http-caching-local-storage';\r\nexport * from './lib/storage/ng-http-caching-session-storage';\r\nexport * from './lib/storage/ng-http-caching-browser-storage';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.NgHttpCachingService"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ng-http-caching.mjs","sources":["../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-memory-storage.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching.service.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching-interceptor.service.ts","../../../projects/ng-http-caching/src/lib/ng-http-caching.module.ts","../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-browser-storage.ts","../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-local-storage.ts","../../../projects/ng-http-caching/src/lib/storage/ng-http-caching-session-storage.ts","../../../projects/ng-http-caching/src/public-api.ts","../../../projects/ng-http-caching/src/ng-http-caching.ts"],"sourcesContent":["import { NgHttpCachingStorageInterface } from './ng-http-caching-storage.interface';\r\nimport { NgHttpCachingEntry } from '../ng-http-caching.service';\r\n\r\nexport class NgHttpCachingMemoryStorage extends Map<string, NgHttpCachingEntry<any, any>> implements NgHttpCachingStorageInterface { }\r\n","import { Injectable, InjectionToken, Inject, Optional, VERSION, isDevMode } from '@angular/core';\r\nimport { HttpRequest, HttpResponse, HttpEvent, HttpContextToken, HttpContext, HttpHeaders } from '@angular/common/http';\r\nimport { Observable } from 'rxjs/internal/Observable';\r\nimport { NgHttpCachingStorageInterface } from './storage/ng-http-caching-storage.interface';\r\nimport { NgHttpCachingMemoryStorage } from './storage/ng-http-caching-memory-storage';\r\n\r\nexport type NgHttpCachingContext = Pick<NgHttpCachingConfig, 'getKey' | 'isCacheable' | 'isExpired' | 'isValid'>;\r\n\r\nexport const NG_HTTP_CACHING_CONTEXT = new HttpContextToken<NgHttpCachingContext>(() => ({}));\r\n\r\nexport const withNgHttpCachingContext = (value: NgHttpCachingContext, context: HttpContext = new HttpContext()) => context.set(NG_HTTP_CACHING_CONTEXT, value)\r\n\r\nexport const checkCacheHeaders = (headers: HttpHeaders): boolean => {\r\n // check Cache-Control\r\n const cacheControlHeader = headers.get('cache-control');\r\n if (cacheControlHeader) {\r\n const cacheControl = cacheControlHeader.toLowerCase();\r\n if (cacheControl.includes('no-store')) {\r\n return false;\r\n } else if (cacheControl.includes('no-cache')) {\r\n return false;\r\n } else {\r\n return true;\r\n }\r\n }\r\n\r\n // check Expires header Expires if response is without Cache-Control\r\n const expiresHeader = headers.get('expires');\r\n if (expiresHeader) {\r\n const expires = Date.parse(expiresHeader);\r\n if (!isNaN(expires)) {\r\n return expires > Date.now();\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\nexport interface NgHttpCachingEntry<K = any, T = any> {\r\n /**\r\n * URL\r\n */\r\n url: string;\r\n /**\r\n * HttpResponse\r\n */\r\n response: HttpResponse<T>;\r\n /**\r\n * HttpRequest\r\n */\r\n request: HttpRequest<K>;\r\n /**\r\n * Timestamp of add to cache time\r\n */\r\n addedTime: number;\r\n /**\r\n * Cache version\r\n */\r\n version: string;\r\n}\r\n\r\nexport const NG_HTTP_CACHING_CONFIG = new InjectionToken<NgHttpCachingContext>(\r\n 'ng-http-caching.config'\r\n);\r\n\r\nexport enum NgHttpCachingStrategy {\r\n /**\r\n * All request are cacheable if HTTP method is into `allowedMethod`\r\n */\r\n ALLOW_ALL = 'ALLOW_ALL',\r\n /**\r\n * Only the request with `X-NG-HTTP-CACHING-ALLOW-CACHE` header are cacheable if HTTP method is into `allowedMethod`\r\n */\r\n DISALLOW_ALL = 'DISALLOW_ALL'\r\n}\r\n\r\nexport enum NgHttpCachingHeaders {\r\n /**\r\n * Request is cacheable if HTTP method is into `allowedMethod`\r\n */\r\n ALLOW_CACHE = 'X-NG-HTTP-CACHING-ALLOW-CACHE',\r\n /**\r\n * Request isn't cacheable\r\n */\r\n DISALLOW_CACHE = 'X-NG-HTTP-CACHING-DISALLOW-CACHE',\r\n /**\r\n * Specific cache lifetime for the request\r\n */\r\n LIFETIME = 'X-NG-HTTP-CACHING-LIFETIME',\r\n /**\r\n * You can tag multiple request by adding this header with the same tag and \r\n * using `NgHttpCachingService.clearCacheByTag(tag: string)` for delete all the tagged request\r\n */\r\n TAG = 'X-NG-HTTP-CACHING-TAG'\r\n}\r\n\r\nexport const NgHttpCachingHeadersList = Object.values(NgHttpCachingHeaders);\r\n\r\nexport const NG_HTTP_CACHING_SECOND_IN_MS = 1000;\r\nexport const NG_HTTP_CACHING_MINUTE_IN_MS = NG_HTTP_CACHING_SECOND_IN_MS * 60;\r\nexport const NG_HTTP_CACHING_HOUR_IN_MS = NG_HTTP_CACHING_MINUTE_IN_MS * 60;\r\nexport const NG_HTTP_CACHING_DAY_IN_MS = NG_HTTP_CACHING_HOUR_IN_MS * 24;\r\nexport const NG_HTTP_CACHING_WEEK_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 7;\r\nexport const NG_HTTP_CACHING_MONTH_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 30;\r\nexport const NG_HTTP_CACHING_YEAR_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 365;\r\n\r\nexport interface NgHttpCachingConfig {\r\n /**\r\n * Set the cache store. You can implement your custom store by implement the `NgHttpCachingStorageInterface` interface, eg.:\r\n */\r\n store?: NgHttpCachingStorageInterface;\r\n /**\r\n * Number of millisecond that a response is stored in the cache. \r\n * You can set specific \"lifetime\" for each request by add the header `X-NG-HTTP-CACHING-LIFETIME` (see example below).\r\n */\r\n lifetime?: number;\r\n /**\r\n * Array of allowed HTTP methods to cache. \r\n * You can allow multiple methods, eg.: `['GET', 'POST', 'PUT', 'DELETE', 'HEAD']` or \r\n * allow all methods by: `['ALL']`. If `allowedMethod` is an empty array (`[]`), no response are cached.\r\n * *Warning!* `NgHttpCaching` use the full url (url with query parameters) as unique key for the cached response,\r\n * this is correct for the `GET` request but is _potentially_ wrong for other type of request (eg. `POST`, `PUT`). \r\n * You can set a different \"key\" by customizing the `getKey` config method (see `getKey` section).\r\n */\r\n allowedMethod?: string[];\r\n /**\r\n * Set the cache strategy, possible strategies are:\r\n * - `NgHttpCachingStrategy.ALLOW_ALL`: All request are cacheable if HTTP method is into `allowedMethod`;\r\n * - `NgHttpCachingStrategy.DISALLOW_ALL`: Only the request with `X-NG-HTTP-CACHING-ALLOW-CACHE` header are cacheable if HTTP method is into `allowedMethod`;\r\n */\r\n cacheStrategy?: NgHttpCachingStrategy;\r\n /**\r\n * Cache version. When you have a breaking change, change the version, and it'll delete the current cache automatically.\r\n * The default value is Angular major version (eg. 13), in this way, the cache is invalidated on every Angular upgrade.\r\n */\r\n version?: string;\r\n /**\r\n * If true response headers cache-control and expires are respected.\r\n */\r\n checkResponseHeaders?: boolean;\r\n /**\r\n * If this function return `true` the request is expired and a new request is send to backend, if return `false` isn't expired. \r\n * If the result is `undefined`, the normal behaviour is provided.\r\n */\r\n isExpired?: <K, T>(entry: NgHttpCachingEntry<K, T>) => boolean | undefined | void;\r\n /**\r\n * If this function return `true` the request is cacheable, if return `false` isn't cacheable. \r\n * If the result is `undefined`, the normal behaviour is provided.\r\n */\r\n isCacheable?: <K>(req: HttpRequest<K>) => boolean | undefined | void;\r\n /**\r\n * This function return the unique key (`string`) for store the response into the cache. \r\n * If the result is `undefined`, the normal behaviour is provided.\r\n */\r\n getKey?: <K>(req: HttpRequest<K>) => string | undefined | void;\r\n /**\r\n * If this function return `true` the cache entry is valid and can be stored, if return `false` isn't valid. \r\n * If the result is `undefined`, the normal behaviour is provided.\r\n */\r\n isValid?: <K, T>(entry: NgHttpCachingEntry<K, T>) => boolean | undefined | void;\r\n}\r\n\r\nexport interface NgHttpCachingDefaultConfig extends NgHttpCachingConfig {\r\n store: NgHttpCachingStorageInterface;\r\n lifetime: number;\r\n allowedMethod: string[];\r\n cacheStrategy: NgHttpCachingStrategy;\r\n version: string;\r\n checkResponseHeaders: boolean;\r\n}\r\n\r\nexport const NgHttpCachingConfigDefault: Readonly<NgHttpCachingDefaultConfig> = {\r\n store: new NgHttpCachingMemoryStorage(),\r\n lifetime: NG_HTTP_CACHING_HOUR_IN_MS,\r\n version: VERSION.major,\r\n allowedMethod: ['GET', 'HEAD'],\r\n cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,\r\n checkResponseHeaders: false\r\n};\r\n\r\n@Injectable()\r\nexport class NgHttpCachingService {\r\n\r\n private readonly queue = new Map<string, Observable<HttpEvent<any>>>();\r\n\r\n private readonly config: NgHttpCachingDefaultConfig;\r\n\r\n private gcLock = false;\r\n\r\n private devMode: boolean = isDevMode();\r\n\r\n constructor(\r\n @Inject(NG_HTTP_CACHING_CONFIG) @Optional() config: Readonly<NgHttpCachingConfig>\r\n ) {\r\n if (config) {\r\n this.config = { ...NgHttpCachingConfigDefault, ...config };\r\n } else {\r\n this.config = { ...NgHttpCachingConfigDefault };\r\n }\r\n // start cache clean\r\n this.runGc();\r\n }\r\n\r\n /**\r\n * Return the config\r\n */\r\n getConfig(): Readonly<NgHttpCachingConfig> {\r\n return this.config;\r\n }\r\n\r\n /**\r\n * Return the queue map\r\n */\r\n getQueue(): Readonly<Map<string, Observable<HttpEvent<any>>>> {\r\n return this.queue;\r\n }\r\n\r\n /**\r\n * Return the cache store\r\n */\r\n getStore(): Readonly<NgHttpCachingStorageInterface> {\r\n return this.config.store;\r\n }\r\n\r\n /**\r\n * Return response from cache\r\n */\r\n getFromCache<K, T>(req: HttpRequest<K>): Readonly<HttpResponse<T>> | undefined {\r\n const key: string = this.getKey(req);\r\n const cached: NgHttpCachingEntry<K, T> | undefined = this.config.store.get<K, T>(key);\r\n\r\n if (!cached) {\r\n return undefined;\r\n }\r\n\r\n if (this.isExpired(cached)) {\r\n this.clearCacheByKey(key);\r\n return undefined;\r\n }\r\n\r\n return this.deepFreeze(cached.response);\r\n }\r\n\r\n /**\r\n * Add response to cache\r\n */\r\n addToCache<K, T>(req: HttpRequest<K>, res: HttpResponse<T>): boolean {\r\n const entry: NgHttpCachingEntry<K, T> = {\r\n url: req.urlWithParams,\r\n response: res,\r\n request: req,\r\n addedTime: Date.now(),\r\n version: this.config.version,\r\n };\r\n if (this.isValid(entry)) {\r\n const key: string = this.getKey(req);\r\n this.config.store.set(key, entry);\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Delete response from cache\r\n */\r\n deleteFromCache<K>(req: HttpRequest<K>): boolean {\r\n const key: string = this.getKey(req);\r\n return this.clearCacheByKey(key);\r\n }\r\n\r\n /**\r\n * Clear the cache\r\n */\r\n clearCache(): void {\r\n this.config.store.clear();\r\n }\r\n\r\n /**\r\n * Clear the cache by key\r\n */\r\n clearCacheByKey(key: string): boolean {\r\n return this.config.store.delete(key);\r\n }\r\n\r\n /**\r\n * Clear the cache by keys\r\n */\r\n clearCacheByKeys(keys: Array<string>): number {\r\n let counter = 0;\r\n if (keys) {\r\n for (const key of keys) {\r\n if (this.clearCacheByKey(key)) {\r\n counter++;\r\n }\r\n }\r\n }\r\n return counter;\r\n }\r\n\r\n /**\r\n * Clear the cache by regex\r\n */\r\n clearCacheByRegex<K, T>(regex: RegExp): number {\r\n const keys: Array<string> = [];\r\n this.config.store.forEach<K, T>((_: NgHttpCachingEntry<K, T>, key: string) => {\r\n if (regex.test(key)) {\r\n keys.push(key);\r\n }\r\n });\r\n return this.clearCacheByKeys(keys);\r\n }\r\n\r\n /**\r\n * Clear the cache by TAG\r\n */\r\n clearCacheByTag<K, T>(tag: string): number {\r\n const keys: Array<string> = [];\r\n this.config.store.forEach<K, T>((entry: NgHttpCachingEntry<K, T>, key: string) => {\r\n const tagHeader = entry.request.headers.get(NgHttpCachingHeaders.TAG);\r\n if (tagHeader && tagHeader.split(',').includes(tag)) {\r\n keys.push(key);\r\n }\r\n });\r\n return this.clearCacheByKeys(keys);\r\n }\r\n\r\n /**\r\n * Run garbage collector (delete expired cache entry)\r\n */\r\n runGc<K, T>(): boolean {\r\n if (this.gcLock) {\r\n return false;\r\n }\r\n this.gcLock = true;\r\n const keys: Array<string> = [];\r\n this.config.store.forEach<K, T>((entry: NgHttpCachingEntry<K, T>, key: string) => {\r\n if (this.isExpired(entry)) {\r\n keys.push(key);\r\n }\r\n });\r\n this.clearCacheByKeys(keys);\r\n this.gcLock = false;\r\n return true;\r\n }\r\n\r\n /**\r\n * Return true if cache entry is expired\r\n */\r\n isExpired<K, T>(entry: NgHttpCachingEntry<K, T>): boolean {\r\n // if user provide custom method, use it\r\n const context = entry.request.context.get(NG_HTTP_CACHING_CONTEXT);\r\n if (typeof context?.isExpired === 'function') {\r\n const result = context.isExpired(entry);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // if user provide custom method, use it\r\n if (typeof this.config.isExpired === 'function') {\r\n const result = this.config.isExpired(entry);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // if version change, always expire\r\n if (this.config.version !== entry.version) {\r\n return true;\r\n }\r\n // config/default lifetime\r\n let lifetime: number = this.config.lifetime;\r\n // request has own lifetime\r\n const headerLifetime = entry.request.headers.get(NgHttpCachingHeaders.LIFETIME);\r\n if (headerLifetime) {\r\n lifetime = +headerLifetime;\r\n }\r\n // never expire if 0\r\n if (lifetime === 0) {\r\n return false;\r\n }\r\n // wrong lifetime\r\n if (lifetime < 0 || isNaN(lifetime)) {\r\n throw new Error('lifetime must be greater than or equal 0');\r\n }\r\n return entry.addedTime + lifetime < Date.now();\r\n }\r\n\r\n /**\r\n * Return true if cache entry is valid for store in the cache\r\n * Default behaviour is whether the status code falls in the 2xx range and response headers cache-control and expires allow cache.\r\n */\r\n isValid<K, T>(entry: NgHttpCachingEntry<K, T>): boolean {\r\n const context = entry.request.context.get(NG_HTTP_CACHING_CONTEXT);\r\n // if user provide custom method, use it\r\n if (typeof context.isValid === 'function') {\r\n const result = context.isValid(entry);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // if user provide custom method, use it\r\n if (typeof this.config.isValid === 'function') {\r\n const result = this.config.isValid(entry);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // different version\r\n if (this.config.version !== entry.version) {\r\n return false;\r\n }\r\n\r\n let fromHeader = true;\r\n if (this.config.checkResponseHeaders) {\r\n // check if response headers allow cache\r\n fromHeader = checkCacheHeaders(entry.response.headers);\r\n }\r\n return entry.response.ok && fromHeader;\r\n }\r\n\r\n /**\r\n * Return true if the request is cacheable\r\n */\r\n isCacheable<K>(req: HttpRequest<K>): boolean {\r\n const context = req.context.get(NG_HTTP_CACHING_CONTEXT);\r\n // if user provide custom method, use it\r\n if (typeof context?.isCacheable === 'function') {\r\n const result = context.isCacheable(req);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // if user provide custom method, use it\r\n if (typeof this.config.isCacheable === 'function') {\r\n const result = this.config.isCacheable(req);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // request has disallow cache header\r\n if (req.headers.has(NgHttpCachingHeaders.DISALLOW_CACHE)) {\r\n return false;\r\n }\r\n // strategy is disallow all...\r\n if (this.config.cacheStrategy === NgHttpCachingStrategy.DISALLOW_ALL) {\r\n // request isn't allowed if come without allow header\r\n if (!req.headers.has(NgHttpCachingHeaders.ALLOW_CACHE)) {\r\n return false;\r\n }\r\n }\r\n // if allowed method is only ALL, allow all http methods\r\n if (this.config.allowedMethod.length === 1) {\r\n if (this.config.allowedMethod[0] === 'ALL') {\r\n return true;\r\n }\r\n }\r\n // request is allowed if method is in allowedMethod\r\n return this.config.allowedMethod.indexOf(req.method) !== -1;\r\n }\r\n\r\n /**\r\n * Return the cache key.\r\n * Default key is http method plus url with query parameters, eg.:\r\n * `GET@https://github.com/nigrosimone/ng-http-caching`\r\n */\r\n getKey<K>(req: HttpRequest<K>): string {\r\n // if user provide custom method, use it\r\n const context = req.context.get(NG_HTTP_CACHING_CONTEXT);\r\n if (typeof context.getKey === 'function') {\r\n const result = context.getKey(req);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // if user provide custom method, use it\r\n if (typeof this.config.getKey === 'function') {\r\n const result = this.config.getKey(req);\r\n // if result is undefined, normal behaviour is provided\r\n if (result !== undefined) {\r\n return result;\r\n }\r\n }\r\n // default key is req.method plus url with query parameters\r\n return req.method + '@' + req.urlWithParams;\r\n }\r\n\r\n /**\r\n * Return observable from cache\r\n */\r\n getFromQueue<K, T>(req: HttpRequest<K>): Observable<HttpEvent<T>> | undefined {\r\n const key: string = this.getKey(req);\r\n const cached: Observable<HttpEvent<T>> | undefined = this.queue.get(key);\r\n\r\n if (!cached) {\r\n return undefined;\r\n }\r\n\r\n return cached;\r\n }\r\n\r\n /**\r\n * Add observable to cache\r\n */\r\n addToQueue<K, T>(req: HttpRequest<K>, obs: Observable<HttpEvent<T>>): void {\r\n const key: string = this.getKey(req);\r\n this.queue.set(key, obs);\r\n }\r\n\r\n /**\r\n * Delete observable from cache\r\n */\r\n deleteFromQueue<K>(req: HttpRequest<K>): boolean {\r\n const key: string = this.getKey(req);\r\n return this.queue.delete(key);\r\n }\r\n\r\n /**\r\n * Recursively Object.freeze simple Javascript structures consisting of plain objects, arrays, and primitives.\r\n * Make the data immutable.\r\n * @returns immutable object\r\n */\r\n private deepFreeze<S>(object: S): Readonly<S> {\r\n // No freezing in production (for better performance).\r\n if (!this.devMode || !object || typeof object !== 'object') {\r\n return object as Readonly<S>;\r\n }\r\n\r\n // When already frozen, we assume its children are frozen (for better performance).\r\n // This should be true if you always use `deepFreeze` to freeze objects.\r\n //\r\n // Note that Object.isFrozen will also return `true` for primitives (numbers,\r\n // strings, booleans, undefined, null), so there is no need to check for\r\n // those explicitly.\r\n if (Object.isFrozen(object)) {\r\n return object as Readonly<S>;\r\n }\r\n\r\n // At this point we know that we're dealing with either an array or plain object, so\r\n // just freeze it and recurse on its values.\r\n Object.freeze(object);\r\n Object.keys(object).forEach(key => this.deepFreeze((object as any)[key]));\r\n\r\n return object as Readonly<S>;\r\n }\r\n}\r\n","import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { asyncScheduler, Observable, of, scheduled } from 'rxjs';\r\nimport { tap, finalize, shareReplay } from 'rxjs/operators';\r\nimport { NgHttpCachingService, NgHttpCachingHeadersList } from './ng-http-caching.service';\r\n\r\n@Injectable()\r\nexport class NgHttpCachingInterceptorService implements HttpInterceptor {\r\n\r\n constructor(private readonly cacheService: NgHttpCachingService) { }\r\n\r\n intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\r\n // run garbage collector\r\n this.cacheService.runGc();\r\n\r\n // Don't cache if it's not cacheable\r\n if (!this.cacheService.isCacheable(req)) {\r\n return this.sendRequest(req, next);\r\n }\r\n\r\n // Checked if there is pending response for this request\r\n const cachedObservable: Observable<HttpEvent<any>> | undefined = this.cacheService.getFromQueue(req);\r\n if (cachedObservable) {\r\n // console.log('cachedObservable',cachedObservable);\r\n return cachedObservable;\r\n }\r\n\r\n // Checked if there is cached response for this request\r\n const cachedResponse: HttpResponse<any> | undefined = this.cacheService.getFromCache(req);\r\n if (cachedResponse) {\r\n // console.log('cachedResponse');\r\n return scheduled(of(cachedResponse.clone()), asyncScheduler);\r\n }\r\n\r\n // If the request of going through for first time\r\n // then let the request proceed and cache the response\r\n // console.log('sendRequest', req);\r\n const shared = this.sendRequest(req, next).pipe(\r\n tap(event => {\r\n if (event instanceof HttpResponse) {\r\n this.cacheService.addToCache(req, event.clone());\r\n }\r\n }),\r\n finalize(() => {\r\n // delete pending request\r\n this.cacheService.deleteFromQueue(req);\r\n }),\r\n shareReplay()\r\n );\r\n\r\n // add pending request to queue for cache parallel request\r\n this.cacheService.addToQueue(req, shared);\r\n\r\n return shared;\r\n }\r\n\r\n /**\r\n * Send http request (next handler)\r\n */\r\n sendRequest(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\r\n let cloned: HttpRequest<any> = req.clone();\r\n // trim custom headers before send request\r\n NgHttpCachingHeadersList.forEach(ngHttpCachingHeaders => {\r\n if (cloned.headers.has(ngHttpCachingHeaders)) {\r\n cloned = cloned.clone({ headers: cloned.headers.delete(ngHttpCachingHeaders) });\r\n }\r\n });\r\n return next.handle(cloned);\r\n }\r\n}\r\n","import { NgModule, ModuleWithProviders } from '@angular/core';\r\nimport { HTTP_INTERCEPTORS } from '@angular/common/http';\r\nimport {\r\n NG_HTTP_CACHING_CONFIG,\r\n NgHttpCachingConfig,\r\n NgHttpCachingService,\r\n} from './ng-http-caching.service';\r\nimport { NgHttpCachingInterceptorService } from './ng-http-caching-interceptor.service';\r\n\r\n@NgModule({\r\n providers: [\r\n NgHttpCachingService,\r\n NgHttpCachingInterceptorService,\r\n {\r\n provide: HTTP_INTERCEPTORS,\r\n useClass: NgHttpCachingInterceptorService,\r\n multi: true,\r\n },\r\n ]\r\n})\r\nexport class NgHttpCachingModule {\r\n static forRoot(\r\n ngHttpCachingConfig?: NgHttpCachingConfig\r\n ): ModuleWithProviders<NgHttpCachingModule> {\r\n return {\r\n ngModule: NgHttpCachingModule,\r\n providers: [\r\n {\r\n provide: NG_HTTP_CACHING_CONFIG,\r\n useValue: ngHttpCachingConfig,\r\n },\r\n ],\r\n };\r\n }\r\n}\r\n","import { NgHttpCachingStorageInterface } from './ng-http-caching-storage.interface';\r\nimport { NgHttpCachingEntry } from '../ng-http-caching.service';\r\nimport { HttpHeaders, HttpParams, HttpRequest, HttpResponse } from '@angular/common/http';\r\n\r\nconst KEY_PREFIX = 'NgHttpCaching::';\r\n\r\nexport interface NgHttpCachingStorageEntry {\r\n url: string;\r\n response: string;\r\n request: string;\r\n addedTime: number;\r\n version: string;\r\n}\r\n\r\nexport const serializeRequest = (req: HttpRequest<any>): string => {\r\n const request = req.clone(); // Make a clone, useful for doing destructive things\r\n return JSON.stringify({\r\n headers: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n request.headers.keys().map( // Get all of the headers\r\n (key: string) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n )\r\n ),\r\n method: request.method, // The Request Method, e.g. GET, POST, DELETE\r\n url: request.url, // The URL\r\n params: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n request.headers.keys().map( // Get all of the headers\r\n (key: string) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n )\r\n ), // The request parameters\r\n withCredentials: request.withCredentials, // Whether credentials are being sent\r\n responseType: request.responseType, // The response type\r\n body: request.serializeBody() // Serialize the body, all well and good since we are working on a clone\r\n });\r\n}\r\n\r\nexport const serializeResponse = (res: HttpResponse<any>): string => {\r\n const response = res.clone();\r\n return JSON.stringify({\r\n headers: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer\r\n response.headers.keys().map( // Get all of the headers\r\n (key: string) => [key, response.headers.getAll(key)] // Get all of the corresponding values for the headers\r\n )\r\n ),\r\n status: response.status,\r\n statusText: response.statusText,\r\n url: response.url,\r\n body: response.body // Serialize the body, all well and good since we are working on a clone\r\n });\r\n}\r\n\r\nexport const deserializeRequest = <T = any>(req: string): HttpRequest<T> => {\r\n const request = JSON.parse(req);\r\n const headers = new HttpHeaders(request.headers);\r\n const params = new HttpParams(); // Probably some way to make this a one-liner, but alas, there are no good docs\r\n for (const parameter in request.params) {\r\n request.params[parameter].forEach((paramValue: string) => params.append(parameter, paramValue));\r\n }\r\n return new HttpRequest(request.method, request.url, request.body, {\r\n headers,\r\n params,\r\n responseType: request.responseType,\r\n withCredentials: request.withCredentials\r\n });\r\n}\r\n\r\nexport const deserializeResponse = <T = any>(res: string): HttpResponse<T> => {\r\n const response = JSON.parse(res);\r\n return new HttpResponse<T>({\r\n url: response.url,\r\n headers: new HttpHeaders(response.headers),\r\n body: response.body,\r\n status: response.status,\r\n statusText: response.statusText,\r\n });\r\n}\r\n\r\nexport class NgHttpCachingBrowserStorage implements NgHttpCachingStorageInterface {\r\n\r\n constructor(private storage: Storage) { }\r\n\r\n get size(): number {\r\n let count = 0;\r\n for (let i = 0, e = this.storage.length; i < e; i++) {\r\n const key = this.storage.key(i);\r\n if (key && key.startsWith(KEY_PREFIX)) {\r\n count++;\r\n }\r\n }\r\n return count;\r\n }\r\n\r\n clear(): void {\r\n for (let i = this.storage.length; i >= 0; i--) {\r\n const key = this.storage.key(i);\r\n if (key && key.startsWith(KEY_PREFIX)) {\r\n this.storage.removeItem(key);\r\n }\r\n }\r\n }\r\n\r\n delete(key: string): boolean {\r\n if (!key) {\r\n return false;\r\n }\r\n if (!key.startsWith(KEY_PREFIX)) {\r\n key = KEY_PREFIX + key;\r\n }\r\n this.storage.removeItem(key);\r\n return true;\r\n }\r\n\r\n forEach(callbackfn: (value: NgHttpCachingEntry, key: string) => void): void {\r\n // iterate this.storage\r\n for (let i = 0, e = this.storage.length; i < e; i++) {\r\n const keyWithPrefix = this.storage.key(i);\r\n if (keyWithPrefix && keyWithPrefix.startsWith(KEY_PREFIX)) {\r\n const value = this.get(keyWithPrefix);\r\n if (value) {\r\n const keyWithoutPrefix = keyWithPrefix.substring(KEY_PREFIX.length);\r\n callbackfn(value, keyWithoutPrefix);\r\n }\r\n }\r\n }\r\n }\r\n\r\n get(key: string): Readonly<NgHttpCachingEntry> | undefined {\r\n if (!key) {\r\n return undefined;\r\n }\r\n if (!key.startsWith(KEY_PREFIX)) {\r\n key = KEY_PREFIX + key;\r\n }\r\n const item = this.storage.getItem(key);\r\n if (item) {\r\n const parsedItem: NgHttpCachingStorageEntry = JSON.parse(item);\r\n return this.deserialize(parsedItem);\r\n }\r\n return undefined;\r\n }\r\n\r\n has(key: string): boolean {\r\n if (!key) {\r\n return false;\r\n }\r\n if (!key.startsWith(KEY_PREFIX)) {\r\n key = KEY_PREFIX + key;\r\n }\r\n return !!this.storage.getItem(key);\r\n }\r\n\r\n set(key: string, value: NgHttpCachingEntry): void {\r\n if (!key) {\r\n return;\r\n }\r\n if (!key.startsWith(KEY_PREFIX)) {\r\n key = KEY_PREFIX + key;\r\n }\r\n const unParsedItem: NgHttpCachingStorageEntry = this.serialize(value);\r\n this.storage.setItem(key, JSON.stringify(unParsedItem));\r\n }\r\n\r\n protected serialize(value: NgHttpCachingEntry): NgHttpCachingStorageEntry {\r\n return {\r\n url: value.url,\r\n response: serializeResponse(value.response),\r\n request: serializeRequest(value.request),\r\n addedTime: value.addedTime,\r\n version: value.version\r\n };\r\n }\r\n\r\n protected deserialize(value: NgHttpCachingStorageEntry): NgHttpCachingEntry {\r\n return {\r\n url: value.url,\r\n response: deserializeResponse(value.response),\r\n request: deserializeRequest(value.request),\r\n addedTime: value.addedTime,\r\n version: value.version\r\n };\r\n }\r\n}\r\n\r\n","import { NgHttpCachingBrowserStorage } from './ng-http-caching-browser-storage';\r\n\r\nexport class NgHttpCachingLocalStorage extends NgHttpCachingBrowserStorage {\r\n\r\n constructor() {\r\n super(localStorage);\r\n }\r\n}\r\n","import { NgHttpCachingBrowserStorage } from './ng-http-caching-browser-storage';\r\n\r\nexport class NgHttpCachingSessionStorage extends NgHttpCachingBrowserStorage {\r\n\r\n constructor() {\r\n super(sessionStorage);\r\n }\r\n}\r\n","/*\r\n * Public API Surface of ng-http-caching\r\n */\r\n\r\nexport * from './lib/ng-http-caching-interceptor.service';\r\nexport * from './lib/ng-http-caching.service';\r\nexport * from './lib/ng-http-caching.module';\r\nexport * from './lib/storage/ng-http-caching-storage.interface';\r\nexport * from './lib/storage/ng-http-caching-memory-storage';\r\nexport * from './lib/storage/ng-http-caching-local-storage';\r\nexport * from './lib/storage/ng-http-caching-session-storage';\r\nexport * from './lib/storage/ng-http-caching-browser-storage';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.NgHttpCachingService"],"mappings":"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"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { InjectionToken } from '@angular/core';
|
|
2
|
-
import { HttpRequest, HttpResponse, HttpEvent, HttpContextToken, HttpContext } from '@angular/common/http';
|
|
2
|
+
import { HttpRequest, HttpResponse, HttpEvent, HttpContextToken, HttpContext, HttpHeaders } from '@angular/common/http';
|
|
3
3
|
import { Observable } from 'rxjs/internal/Observable';
|
|
4
4
|
import { NgHttpCachingStorageInterface } from './storage/ng-http-caching-storage.interface';
|
|
5
5
|
import * as i0 from "@angular/core";
|
|
6
6
|
export type NgHttpCachingContext = Pick<NgHttpCachingConfig, 'getKey' | 'isCacheable' | 'isExpired' | 'isValid'>;
|
|
7
7
|
export declare const NG_HTTP_CACHING_CONTEXT: HttpContextToken<NgHttpCachingContext>;
|
|
8
8
|
export declare const withNgHttpCachingContext: (value: NgHttpCachingContext, context?: HttpContext) => HttpContext;
|
|
9
|
+
export declare const checkCacheHeaders: (headers: HttpHeaders) => boolean;
|
|
9
10
|
export interface NgHttpCachingEntry<K = any, T = any> {
|
|
10
11
|
/**
|
|
11
12
|
* URL
|
|
@@ -96,6 +97,10 @@ export interface NgHttpCachingConfig {
|
|
|
96
97
|
* The default value is Angular major version (eg. 13), in this way, the cache is invalidated on every Angular upgrade.
|
|
97
98
|
*/
|
|
98
99
|
version?: string;
|
|
100
|
+
/**
|
|
101
|
+
* If true response headers cache-control and expires are respected.
|
|
102
|
+
*/
|
|
103
|
+
checkResponseHeaders?: boolean;
|
|
99
104
|
/**
|
|
100
105
|
* If this function return `true` the request is expired and a new request is send to backend, if return `false` isn't expired.
|
|
101
106
|
* If the result is `undefined`, the normal behaviour is provided.
|
|
@@ -123,6 +128,7 @@ export interface NgHttpCachingDefaultConfig extends NgHttpCachingConfig {
|
|
|
123
128
|
allowedMethod: string[];
|
|
124
129
|
cacheStrategy: NgHttpCachingStrategy;
|
|
125
130
|
version: string;
|
|
131
|
+
checkResponseHeaders: boolean;
|
|
126
132
|
}
|
|
127
133
|
export declare const NgHttpCachingConfigDefault: Readonly<NgHttpCachingDefaultConfig>;
|
|
128
134
|
export declare class NgHttpCachingService {
|
|
@@ -185,7 +191,7 @@ export declare class NgHttpCachingService {
|
|
|
185
191
|
isExpired<K, T>(entry: NgHttpCachingEntry<K, T>): boolean;
|
|
186
192
|
/**
|
|
187
193
|
* Return true if cache entry is valid for store in the cache
|
|
188
|
-
* Default behaviour is whether the status code falls in the 2xx range.
|
|
194
|
+
* Default behaviour is whether the status code falls in the 2xx range and response headers cache-control and expires allow cache.
|
|
189
195
|
*/
|
|
190
196
|
isValid<K, T>(entry: NgHttpCachingEntry<K, T>): boolean;
|
|
191
197
|
/**
|