ng-http-caching 18.0.2 → 20.0.1
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 +26 -46
- package/fesm2022/ng-http-caching.mjs +57 -36
- package/fesm2022/ng-http-caching.mjs.map +1 -1
- package/index.d.ts +320 -5
- package/package.json +1 -3
- package/esm2022/lib/ng-http-caching-interceptor.service.mjs +0 -65
- package/esm2022/lib/ng-http-caching.module.mjs +0 -44
- package/esm2022/lib/ng-http-caching.service.mjs +0 -424
- package/esm2022/lib/storage/ng-http-caching-browser-storage.mjs +0 -155
- package/esm2022/lib/storage/ng-http-caching-local-storage.mjs +0 -7
- package/esm2022/lib/storage/ng-http-caching-memory-storage.mjs +0 -3
- package/esm2022/lib/storage/ng-http-caching-session-storage.mjs +0 -7
- package/esm2022/lib/storage/ng-http-caching-storage.interface.mjs +0 -2
- package/esm2022/ng-http-caching.mjs +0 -5
- package/esm2022/public-api.mjs +0 -12
- package/lib/ng-http-caching-interceptor.service.d.ts +0 -15
- package/lib/ng-http-caching.module.d.ts +0 -9
- package/lib/ng-http-caching.service.d.ts +0 -227
- package/lib/storage/ng-http-caching-browser-storage.d.ts +0 -27
- package/lib/storage/ng-http-caching-local-storage.d.ts +0 -4
- package/lib/storage/ng-http-caching-memory-storage.d.ts +0 -4
- package/lib/storage/ng-http-caching-session-storage.d.ts +0 -4
- package/lib/storage/ng-http-caching-storage.interface.d.ts +0 -31
- package/public-api.d.ts +0 -8
|
@@ -1,424 +0,0 @@
|
|
|
1
|
-
import { Injectable, InjectionToken, Inject, Optional, VERSION, isDevMode } from '@angular/core';
|
|
2
|
-
import { HttpContextToken, HttpContext } from '@angular/common/http';
|
|
3
|
-
import { NgHttpCachingMemoryStorage } from './storage/ng-http-caching-memory-storage';
|
|
4
|
-
import * as i0 from "@angular/core";
|
|
5
|
-
export const NG_HTTP_CACHING_CONTEXT = new HttpContextToken(() => ({}));
|
|
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
|
-
};
|
|
32
|
-
export const NG_HTTP_CACHING_CONFIG = new InjectionToken('ng-http-caching.config');
|
|
33
|
-
export var NgHttpCachingStrategy;
|
|
34
|
-
(function (NgHttpCachingStrategy) {
|
|
35
|
-
/**
|
|
36
|
-
* All request are cacheable if HTTP method is into `allowedMethod`
|
|
37
|
-
*/
|
|
38
|
-
NgHttpCachingStrategy["ALLOW_ALL"] = "ALLOW_ALL";
|
|
39
|
-
/**
|
|
40
|
-
* Only the request with `X-NG-HTTP-CACHING-ALLOW-CACHE` header are cacheable if HTTP method is into `allowedMethod`
|
|
41
|
-
*/
|
|
42
|
-
NgHttpCachingStrategy["DISALLOW_ALL"] = "DISALLOW_ALL";
|
|
43
|
-
})(NgHttpCachingStrategy || (NgHttpCachingStrategy = {}));
|
|
44
|
-
export var NgHttpCachingHeaders;
|
|
45
|
-
(function (NgHttpCachingHeaders) {
|
|
46
|
-
/**
|
|
47
|
-
* Request is cacheable if HTTP method is into `allowedMethod`
|
|
48
|
-
*/
|
|
49
|
-
NgHttpCachingHeaders["ALLOW_CACHE"] = "X-NG-HTTP-CACHING-ALLOW-CACHE";
|
|
50
|
-
/**
|
|
51
|
-
* Request isn't cacheable
|
|
52
|
-
*/
|
|
53
|
-
NgHttpCachingHeaders["DISALLOW_CACHE"] = "X-NG-HTTP-CACHING-DISALLOW-CACHE";
|
|
54
|
-
/**
|
|
55
|
-
* Specific cache lifetime for the request
|
|
56
|
-
*/
|
|
57
|
-
NgHttpCachingHeaders["LIFETIME"] = "X-NG-HTTP-CACHING-LIFETIME";
|
|
58
|
-
/**
|
|
59
|
-
* You can tag multiple request by adding this header with the same tag and
|
|
60
|
-
* using `NgHttpCachingService.clearCacheByTag(tag: string)` for delete all the tagged request
|
|
61
|
-
*/
|
|
62
|
-
NgHttpCachingHeaders["TAG"] = "X-NG-HTTP-CACHING-TAG";
|
|
63
|
-
})(NgHttpCachingHeaders || (NgHttpCachingHeaders = {}));
|
|
64
|
-
export const NgHttpCachingHeadersList = Object.values(NgHttpCachingHeaders);
|
|
65
|
-
export const NG_HTTP_CACHING_SECOND_IN_MS = 1000;
|
|
66
|
-
export const NG_HTTP_CACHING_MINUTE_IN_MS = NG_HTTP_CACHING_SECOND_IN_MS * 60;
|
|
67
|
-
export const NG_HTTP_CACHING_HOUR_IN_MS = NG_HTTP_CACHING_MINUTE_IN_MS * 60;
|
|
68
|
-
export const NG_HTTP_CACHING_DAY_IN_MS = NG_HTTP_CACHING_HOUR_IN_MS * 24;
|
|
69
|
-
export const NG_HTTP_CACHING_WEEK_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 7;
|
|
70
|
-
export const NG_HTTP_CACHING_MONTH_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 30;
|
|
71
|
-
export const NG_HTTP_CACHING_YEAR_IN_MS = NG_HTTP_CACHING_DAY_IN_MS * 365;
|
|
72
|
-
export const NgHttpCachingConfigDefault = {
|
|
73
|
-
store: new NgHttpCachingMemoryStorage(),
|
|
74
|
-
lifetime: NG_HTTP_CACHING_HOUR_IN_MS,
|
|
75
|
-
version: VERSION.major,
|
|
76
|
-
allowedMethod: ['GET', 'HEAD'],
|
|
77
|
-
cacheStrategy: NgHttpCachingStrategy.ALLOW_ALL,
|
|
78
|
-
checkResponseHeaders: false
|
|
79
|
-
};
|
|
80
|
-
export class NgHttpCachingService {
|
|
81
|
-
constructor(config) {
|
|
82
|
-
this.queue = new Map();
|
|
83
|
-
this.gcLock = false;
|
|
84
|
-
this.devMode = isDevMode();
|
|
85
|
-
if (config) {
|
|
86
|
-
this.config = { ...NgHttpCachingConfigDefault, ...config };
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
this.config = { ...NgHttpCachingConfigDefault };
|
|
90
|
-
}
|
|
91
|
-
// start cache clean
|
|
92
|
-
this.runGc();
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Return the config
|
|
96
|
-
*/
|
|
97
|
-
getConfig() {
|
|
98
|
-
return this.config;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Return the queue map
|
|
102
|
-
*/
|
|
103
|
-
getQueue() {
|
|
104
|
-
return this.queue;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Return the cache store
|
|
108
|
-
*/
|
|
109
|
-
getStore() {
|
|
110
|
-
return this.config.store;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Return response from cache
|
|
114
|
-
*/
|
|
115
|
-
getFromCache(req) {
|
|
116
|
-
const key = this.getKey(req);
|
|
117
|
-
const cached = this.config.store.get(key);
|
|
118
|
-
if (!cached) {
|
|
119
|
-
return undefined;
|
|
120
|
-
}
|
|
121
|
-
if (this.isExpired(cached)) {
|
|
122
|
-
this.clearCacheByKey(key);
|
|
123
|
-
return undefined;
|
|
124
|
-
}
|
|
125
|
-
return this.deepFreeze(cached.response);
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Add response to cache
|
|
129
|
-
*/
|
|
130
|
-
addToCache(req, res) {
|
|
131
|
-
const entry = {
|
|
132
|
-
url: req.urlWithParams,
|
|
133
|
-
response: res,
|
|
134
|
-
request: req,
|
|
135
|
-
addedTime: Date.now(),
|
|
136
|
-
version: this.config.version,
|
|
137
|
-
};
|
|
138
|
-
if (this.isValid(entry)) {
|
|
139
|
-
const key = this.getKey(req);
|
|
140
|
-
this.config.store.set(key, entry);
|
|
141
|
-
return true;
|
|
142
|
-
}
|
|
143
|
-
return false;
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Delete response from cache
|
|
147
|
-
*/
|
|
148
|
-
deleteFromCache(req) {
|
|
149
|
-
const key = this.getKey(req);
|
|
150
|
-
return this.clearCacheByKey(key);
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Clear the cache
|
|
154
|
-
*/
|
|
155
|
-
clearCache() {
|
|
156
|
-
this.config.store.clear();
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Clear the cache by key
|
|
160
|
-
*/
|
|
161
|
-
clearCacheByKey(key) {
|
|
162
|
-
return this.config.store.delete(key);
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Clear the cache by keys
|
|
166
|
-
*/
|
|
167
|
-
clearCacheByKeys(keys) {
|
|
168
|
-
let counter = 0;
|
|
169
|
-
if (keys) {
|
|
170
|
-
for (const key of keys) {
|
|
171
|
-
if (this.clearCacheByKey(key)) {
|
|
172
|
-
counter++;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
return counter;
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Clear the cache by regex
|
|
180
|
-
*/
|
|
181
|
-
clearCacheByRegex(regex) {
|
|
182
|
-
const keys = [];
|
|
183
|
-
this.config.store.forEach((_, key) => {
|
|
184
|
-
if (regex.test(key)) {
|
|
185
|
-
keys.push(key);
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
return this.clearCacheByKeys(keys);
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Clear the cache by TAG
|
|
192
|
-
*/
|
|
193
|
-
clearCacheByTag(tag) {
|
|
194
|
-
const keys = [];
|
|
195
|
-
this.config.store.forEach((entry, key) => {
|
|
196
|
-
const tagHeader = entry.request.headers.get(NgHttpCachingHeaders.TAG);
|
|
197
|
-
if (tagHeader && tagHeader.split(',').includes(tag)) {
|
|
198
|
-
keys.push(key);
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
return this.clearCacheByKeys(keys);
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Run garbage collector (delete expired cache entry)
|
|
205
|
-
*/
|
|
206
|
-
runGc() {
|
|
207
|
-
if (this.gcLock) {
|
|
208
|
-
return false;
|
|
209
|
-
}
|
|
210
|
-
this.gcLock = true;
|
|
211
|
-
const keys = [];
|
|
212
|
-
this.config.store.forEach((entry, key) => {
|
|
213
|
-
if (this.isExpired(entry)) {
|
|
214
|
-
keys.push(key);
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
this.clearCacheByKeys(keys);
|
|
218
|
-
this.gcLock = false;
|
|
219
|
-
return true;
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Return true if cache entry is expired
|
|
223
|
-
*/
|
|
224
|
-
isExpired(entry) {
|
|
225
|
-
// if user provide custom method, use it
|
|
226
|
-
const context = entry.request.context.get(NG_HTTP_CACHING_CONTEXT);
|
|
227
|
-
if (typeof context?.isExpired === 'function') {
|
|
228
|
-
const result = context.isExpired(entry);
|
|
229
|
-
// if result is undefined, normal behaviour is provided
|
|
230
|
-
if (result !== undefined) {
|
|
231
|
-
return result;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
// if user provide custom method, use it
|
|
235
|
-
if (typeof this.config.isExpired === 'function') {
|
|
236
|
-
const result = this.config.isExpired(entry);
|
|
237
|
-
// if result is undefined, normal behaviour is provided
|
|
238
|
-
if (result !== undefined) {
|
|
239
|
-
return result;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
// if version change, always expire
|
|
243
|
-
if (this.config.version !== entry.version) {
|
|
244
|
-
return true;
|
|
245
|
-
}
|
|
246
|
-
// config/default lifetime
|
|
247
|
-
let lifetime = this.config.lifetime;
|
|
248
|
-
// request has own lifetime
|
|
249
|
-
const headerLifetime = entry.request.headers.get(NgHttpCachingHeaders.LIFETIME);
|
|
250
|
-
if (headerLifetime) {
|
|
251
|
-
lifetime = +headerLifetime;
|
|
252
|
-
}
|
|
253
|
-
// never expire if 0
|
|
254
|
-
if (lifetime === 0) {
|
|
255
|
-
return false;
|
|
256
|
-
}
|
|
257
|
-
// wrong lifetime
|
|
258
|
-
if (lifetime < 0 || isNaN(lifetime)) {
|
|
259
|
-
throw new Error('lifetime must be greater than or equal 0');
|
|
260
|
-
}
|
|
261
|
-
return entry.addedTime + lifetime < Date.now();
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* Return true if cache entry is valid for store in the cache
|
|
265
|
-
* Default behaviour is whether the status code falls in the 2xx range and response headers cache-control and expires allow cache.
|
|
266
|
-
*/
|
|
267
|
-
isValid(entry) {
|
|
268
|
-
const context = entry.request.context.get(NG_HTTP_CACHING_CONTEXT);
|
|
269
|
-
// if user provide custom method, use it
|
|
270
|
-
if (typeof context.isValid === 'function') {
|
|
271
|
-
const result = context.isValid(entry);
|
|
272
|
-
// if result is undefined, normal behaviour is provided
|
|
273
|
-
if (result !== undefined) {
|
|
274
|
-
return result;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
// if user provide custom method, use it
|
|
278
|
-
if (typeof this.config.isValid === 'function') {
|
|
279
|
-
const result = this.config.isValid(entry);
|
|
280
|
-
// if result is undefined, normal behaviour is provided
|
|
281
|
-
if (result !== undefined) {
|
|
282
|
-
return result;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
// different version
|
|
286
|
-
if (this.config.version !== entry.version) {
|
|
287
|
-
return false;
|
|
288
|
-
}
|
|
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;
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
* Return true if the request is cacheable
|
|
298
|
-
*/
|
|
299
|
-
isCacheable(req) {
|
|
300
|
-
const context = req.context.get(NG_HTTP_CACHING_CONTEXT);
|
|
301
|
-
// if user provide custom method, use it
|
|
302
|
-
if (typeof context?.isCacheable === 'function') {
|
|
303
|
-
const result = context.isCacheable(req);
|
|
304
|
-
// if result is undefined, normal behaviour is provided
|
|
305
|
-
if (result !== undefined) {
|
|
306
|
-
return result;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
// if user provide custom method, use it
|
|
310
|
-
if (typeof this.config.isCacheable === 'function') {
|
|
311
|
-
const result = this.config.isCacheable(req);
|
|
312
|
-
// if result is undefined, normal behaviour is provided
|
|
313
|
-
if (result !== undefined) {
|
|
314
|
-
return result;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
// request has disallow cache header
|
|
318
|
-
if (req.headers.has(NgHttpCachingHeaders.DISALLOW_CACHE)) {
|
|
319
|
-
return false;
|
|
320
|
-
}
|
|
321
|
-
// strategy is disallow all...
|
|
322
|
-
if (this.config.cacheStrategy === NgHttpCachingStrategy.DISALLOW_ALL) {
|
|
323
|
-
// request isn't allowed if come without allow header
|
|
324
|
-
if (!req.headers.has(NgHttpCachingHeaders.ALLOW_CACHE)) {
|
|
325
|
-
return false;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
// if allowed method is only ALL, allow all http methods
|
|
329
|
-
if (this.config.allowedMethod.length === 1) {
|
|
330
|
-
if (this.config.allowedMethod[0] === 'ALL') {
|
|
331
|
-
return true;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
// request is allowed if method is in allowedMethod
|
|
335
|
-
return this.config.allowedMethod.indexOf(req.method) !== -1;
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Return the cache key.
|
|
339
|
-
* Default key is http method plus url with query parameters, eg.:
|
|
340
|
-
* `GET@https://github.com/nigrosimone/ng-http-caching`
|
|
341
|
-
*/
|
|
342
|
-
getKey(req) {
|
|
343
|
-
// if user provide custom method, use it
|
|
344
|
-
const context = req.context.get(NG_HTTP_CACHING_CONTEXT);
|
|
345
|
-
if (typeof context.getKey === 'function') {
|
|
346
|
-
const result = context.getKey(req);
|
|
347
|
-
// if result is undefined, normal behaviour is provided
|
|
348
|
-
if (result !== undefined) {
|
|
349
|
-
return result;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
// if user provide custom method, use it
|
|
353
|
-
if (typeof this.config.getKey === 'function') {
|
|
354
|
-
const result = this.config.getKey(req);
|
|
355
|
-
// if result is undefined, normal behaviour is provided
|
|
356
|
-
if (result !== undefined) {
|
|
357
|
-
return result;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
// default key is req.method plus url with query parameters
|
|
361
|
-
return req.method + '@' + req.urlWithParams;
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Return observable from cache
|
|
365
|
-
*/
|
|
366
|
-
getFromQueue(req) {
|
|
367
|
-
const key = this.getKey(req);
|
|
368
|
-
const cached = this.queue.get(key);
|
|
369
|
-
if (!cached) {
|
|
370
|
-
return undefined;
|
|
371
|
-
}
|
|
372
|
-
return cached;
|
|
373
|
-
}
|
|
374
|
-
/**
|
|
375
|
-
* Add observable to cache
|
|
376
|
-
*/
|
|
377
|
-
addToQueue(req, obs) {
|
|
378
|
-
const key = this.getKey(req);
|
|
379
|
-
this.queue.set(key, obs);
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* Delete observable from cache
|
|
383
|
-
*/
|
|
384
|
-
deleteFromQueue(req) {
|
|
385
|
-
const key = this.getKey(req);
|
|
386
|
-
return this.queue.delete(key);
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* Recursively Object.freeze simple Javascript structures consisting of plain objects, arrays, and primitives.
|
|
390
|
-
* Make the data immutable.
|
|
391
|
-
* @returns immutable object
|
|
392
|
-
*/
|
|
393
|
-
deepFreeze(object) {
|
|
394
|
-
// No freezing in production (for better performance).
|
|
395
|
-
if (!this.devMode || !object || typeof object !== 'object') {
|
|
396
|
-
return object;
|
|
397
|
-
}
|
|
398
|
-
// When already frozen, we assume its children are frozen (for better performance).
|
|
399
|
-
// This should be true if you always use `deepFreeze` to freeze objects.
|
|
400
|
-
//
|
|
401
|
-
// Note that Object.isFrozen will also return `true` for primitives (numbers,
|
|
402
|
-
// strings, booleans, undefined, null), so there is no need to check for
|
|
403
|
-
// those explicitly.
|
|
404
|
-
if (Object.isFrozen(object)) {
|
|
405
|
-
return object;
|
|
406
|
-
}
|
|
407
|
-
// At this point we know that we're dealing with either an array or plain object, so
|
|
408
|
-
// just freeze it and recurse on its values.
|
|
409
|
-
Object.freeze(object);
|
|
410
|
-
Object.keys(object).forEach(key => this.deepFreeze(object[key]));
|
|
411
|
-
return object;
|
|
412
|
-
}
|
|
413
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: NgHttpCachingService, deps: [{ token: NG_HTTP_CACHING_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
414
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: NgHttpCachingService }); }
|
|
415
|
-
}
|
|
416
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: NgHttpCachingService, decorators: [{
|
|
417
|
-
type: Injectable
|
|
418
|
-
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
419
|
-
type: Inject,
|
|
420
|
-
args: [NG_HTTP_CACHING_CONFIG]
|
|
421
|
-
}, {
|
|
422
|
-
type: Optional
|
|
423
|
-
}] }] });
|
|
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==
|