UNPKG

72.7 kBJavaScriptView Raw
1import { __assign, __decorate, __metadata, __awaiter, __generator, __values } from 'tslib';
2import { forwardRef, Injectable, InjectionToken, Component, NgModule } from '@angular/core';
3import { Type, plainToClass } from 'class-transformer';
4import { Router, ActivatedRoute, RouterModule } from '@angular/router';
5import { Storage, UbudStorageModule } from '@ubud/storage';
6import { forkJoin, Observable, of } from 'rxjs';
7import { fromPromise } from 'rxjs/internal/observable/fromPromise';
8import { catchError, map, switchMap, tap, first } from 'rxjs/internal/operators';
9import { HttpClient } from '@angular/common/http';
10import { Location } from '@angular/common';
11import { ErrorObservable } from 'rxjs-compat/observable/ErrorObservable';
12
13/**
14 * @fileoverview added by tsickle
15 * @suppress {checkTypes} checked by tsc
16 */
17var Config = /** @class */ (function () {
18 function Config(data) {
19 this.endpoint = 'https://account.kemnaker.go.id';
20 Object.assign(this, data);
21 }
22 return Config;
23}());
24
25/**
26 * @fileoverview added by tsickle
27 * @suppress {checkTypes} checked by tsc
28 */
29var User = /** @class */ (function () {
30 function User() {
31 }
32 __decorate([
33 Type(/** @type {?} */ (forwardRef(function () { return Date; }))),
34 __metadata("design:type", Date)
35 ], User.prototype, "updatedAt", void 0);
36 return User;
37}());
38
39/**
40 * @fileoverview added by tsickle
41 * @suppress {checkTypes} checked by tsc
42 */
43var NacoService = /** @class */ (function () {
44 function NacoService(config, router, storage, http, location) {
45 this.config = config;
46 this.router = router;
47 this.storage = storage;
48 this.http = http;
49 this.location = location;
50 this.VERSION = 'v1';
51 this.signature = null;
52 this.user = null;
53 this.refreshToken = null;
54 this.clientSecret = null;
55 }
56 /**
57 * @param {?} user
58 * @return {?}
59 */
60 NacoService.prototype.setUser = /**
61 * @param {?} user
62 * @return {?}
63 */
64 function (user) {
65 this.user = user;
66 this.storage.set('user', user);
67 };
68 /**
69 * @return {?}
70 */
71 NacoService.prototype.getUser = /**
72 * @return {?}
73 */
74 function () {
75 var _this = this;
76 if (null !== this.user) {
77 return of(this.user);
78 }
79 return fromPromise(this.storage.get('user')).pipe(switchMap(function (user) {
80 if (user) {
81 return of(user);
82 }
83 var /** @type {?} */ uri = _this.getUri('/users/me');
84 return fromPromise(_this.getSignature()).pipe(switchMap(function (signature) {
85 if (null === signature) {
86 return _this.refreshUser();
87 }
88 var /** @type {?} */ options = {
89 headers: {
90 Authorization: signature.type + " " + signature.token,
91 },
92 };
93 return _this.http.get(uri, options).pipe(map(function (res) {
94 if (res.data) {
95 return res.data;
96 }
97 throw new Error('There are no body to be transformed');
98 }), map(function (data) {
99 var /** @type {?} */ authUser = plainToClass(User, data);
100 _this.setUser(authUser);
101 return authUser;
102 }), catchError(function (e) {
103 if (401 === e.status) {
104 return _this.refreshUser().pipe(switchMap(function (refreshUser) {
105 if (refreshUser) {
106 return of(refreshUser);
107 }
108 return ErrorObservable.create(e);
109 }));
110 }
111 return ErrorObservable.create(e);
112 }));
113 }));
114 }));
115 };
116 /**
117 * @return {?}
118 */
119 NacoService.prototype.getSignature = /**
120 * @return {?}
121 */
122 function () {
123 if (this.signature) {
124 return Promise.resolve(this.signature);
125 }
126 return this.storage.get('signature');
127 };
128 /**
129 * @param {?} signature
130 * @return {?}
131 */
132 NacoService.prototype.setSignature = /**
133 * @param {?} signature
134 * @return {?}
135 */
136 function (signature) {
137 this.signature = signature;
138 this.storage.set('signature', signature);
139 };
140 /**
141 * @param {?} secret
142 * @return {?}
143 */
144 NacoService.prototype.setClientSecret = /**
145 * @param {?} secret
146 * @return {?}
147 */
148 function (secret) {
149 this.clientSecret = secret;
150 this.storage.set('client_secret', secret);
151 };
152 /**
153 * @param {?} refreshToken
154 * @return {?}
155 */
156 NacoService.prototype.setRefreshToken = /**
157 * @param {?} refreshToken
158 * @return {?}
159 */
160 function (refreshToken) {
161 this.refreshToken = refreshToken;
162 this.storage.set('refresh_token', refreshToken);
163 };
164 /**
165 * @param {?=} scopes
166 * @return {?}
167 */
168 NacoService.prototype.refreshUser = /**
169 * @param {?=} scopes
170 * @return {?}
171 */
172 function (scopes) {
173 var _this = this;
174 this.setUser(null);
175 this.setSignature(null);
176 return forkJoin(this.getRefreshToken(), this.getClientSecret()).pipe(switchMap(function (results) {
177 var /** @type {?} */ refreshToken = results[0];
178 var /** @type {?} */ clientSecret = results[1];
179 if (refreshToken && clientSecret) {
180 return _this.refreshWithRefreshToken(clientSecret, refreshToken.token, scopes);
181 }
182 return _this.refreshWithSilentAuth();
183 }));
184 };
185 /**
186 * @param {?} clientSecret
187 * @param {?} refreshToken
188 * @param {?=} scopes
189 * @return {?}
190 */
191 NacoService.prototype.refreshWithRefreshToken = /**
192 * @param {?} clientSecret
193 * @param {?} refreshToken
194 * @param {?=} scopes
195 * @return {?}
196 */
197 function (clientSecret, refreshToken, scopes) {
198 var _this = this;
199 var /** @type {?} */ request = this.http.post(this.getUri('/tokens'), {
200 grant_type: 'refresh_token',
201 scopes: scopes || 'basic email',
202 client_id: this.config.clientId,
203 client_secret: clientSecret,
204 refresh_token: refreshToken,
205 });
206 return request.pipe(tap(function (tokens) {
207 if (tokens && tokens.data) {
208 _this.setSignature({
209 expiresIn: tokens.data.expires_in,
210 type: tokens.data.token_type,
211 token: tokens.data.access_token,
212 });
213 _this.setRefreshToken({
214 type: tokens.data.token_type,
215 token: tokens.data.refresh_token,
216 });
217 }
218 }), map(function (tokens) { return tokens && tokens.data; }), switchMap(function (hasToken) {
219 if (hasToken) {
220 return _this.getUser();
221 }
222 return of(null);
223 }));
224 };
225 /**
226 * @return {?}
227 */
228 NacoService.prototype.refreshWithSilentAuth = /**
229 * @return {?}
230 */
231 function () {
232 var _this = this;
233 return new Observable(function (observer) {
234 var /** @type {?} */ redirectUri = _this.getCurrentOrigin('auth/silent');
235 var /** @type {?} */ uri = _this.login('basic email', redirectUri, false);
236 var /** @type {?} */ iframe = document.createElement('iframe');
237 iframe.setAttribute('src', uri);
238 iframe.style.display = 'none';
239 iframe.addEventListener('load', function () { return __awaiter(_this, void 0, void 0, function () {
240 var e_1, _a, queryString, queryParts, params, queryParts_1, queryParts_1_1, item, itemParts, user, e_2;
241 return __generator(this, function (_b) {
242 switch (_b.label) {
243 case 0:
244 _b.trys.push([0, 5, , 6]);
245 queryString = iframe.contentWindow.location.search.substring(1);
246 iframe.parentNode.removeChild(iframe);
247 if (!queryString) return [3 /*break*/, 4];
248 queryParts = queryString.split('&');
249 params = {};
250 try {
251 for (queryParts_1 = __values(queryParts), queryParts_1_1 = queryParts_1.next(); !queryParts_1_1.done; queryParts_1_1 = queryParts_1.next()) {
252 item = queryParts_1_1.value;
253 itemParts = item.split('=');
254 params[itemParts[0]] = itemParts[1];
255 }
256 }
257 catch (e_1_1) { e_1 = { error: e_1_1 }; }
258 finally {
259 try {
260 if (queryParts_1_1 && !queryParts_1_1.done && (_a = queryParts_1.return)) _a.call(queryParts_1);
261 }
262 finally { if (e_1) throw e_1.error; }
263 }
264 if (!params.hasOwnProperty('access_token')) return [3 /*break*/, 2];
265 this.setSignature({
266 token: params['access_token'],
267 type: params['token_type'],
268 expiresIn: params['ttl'],
269 });
270 return [4 /*yield*/, this.getUser().toPromise()];
271 case 1:
272 user = _b.sent();
273 if (user) {
274 this.setUser(user);
275 }
276 observer.next(user);
277 return [3 /*break*/, 3];
278 case 2:
279 observer.next(null);
280 _b.label = 3;
281 case 3: return [2 /*return*/];
282 case 4:
283 observer.next(null);
284 return [3 /*break*/, 6];
285 case 5:
286 e_2 = _b.sent();
287 observer.next(null);
288 return [3 /*break*/, 6];
289 case 6: return [2 /*return*/];
290 }
291 });
292 }); }, false);
293 document.body.appendChild(iframe);
294 });
295 };
296 /**
297 * @param {?} scopes
298 * @param {?=} redirectUri
299 * @param {?=} needState
300 * @return {?}
301 */
302 NacoService.prototype.login = /**
303 * @param {?} scopes
304 * @param {?=} redirectUri
305 * @param {?=} needState
306 * @return {?}
307 */
308 function (scopes, redirectUri, needState) {
309 if (needState === void 0) { needState = true; }
310 if (!redirectUri) {
311 redirectUri = this.router.url;
312 }
313 var /** @type {?} */ params = {
314 'response_type': 'token',
315 'scopes': scopes,
316 'client': this.config.clientId,
317 'silent': true,
318 'continue': encodeURIComponent(redirectUri),
319 };
320 if (needState) {
321 var /** @type {?} */ state = this.generateState();
322 this.storage.set('state', state);
323 params.state = state;
324 }
325 var /** @type {?} */ query = this.buildQueryString(params);
326 return this.config.endpoint + '/auth?' + query;
327 };
328 /**
329 * @param {?=} redirectUri
330 * @return {?}
331 */
332 NacoService.prototype.logout = /**
333 * @param {?=} redirectUri
334 * @return {?}
335 */
336 function (redirectUri) {
337 var _this = this;
338 this.signature = null;
339 this.user = null;
340 return new Promise(function (resolve) {
341 Promise.all([
342 _this.storage.remove('signature'),
343 _this.storage.remove('user'),
344 ]).then(function () {
345 var /** @type {?} */ endpoint = _this.config.endpoint + '/auth/logout';
346 if (redirectUri) {
347 endpoint += '?continue=' + encodeURIComponent(redirectUri);
348 }
349 resolve(endpoint);
350 });
351 });
352 };
353 /**
354 * @return {?}
355 */
356 NacoService.prototype.getState = /**
357 * @return {?}
358 */
359 function () {
360 return this.storage.get('state');
361 };
362 /**
363 * @param {?} route
364 * @return {?}
365 */
366 NacoService.prototype.buildNestedUri = /**
367 * @param {?} route
368 * @return {?}
369 */
370 function (route) {
371 var _this = this;
372 var /** @type {?} */ uri = '';
373 if (route.routeConfig && route.routeConfig.path) {
374 var /** @type {?} */ routePath = route.routeConfig.path;
375 for (var /** @type {?} */ key in route.params) {
376 if (key) {
377 var /** @type {?} */ re = new RegExp('\:' + key);
378 routePath = routePath.replace(re, route.params[key]);
379 }
380 }
381 uri += '/' + routePath;
382 }
383 if (route.children) {
384 route.children.forEach(function (item) {
385 uri += _this.buildNestedUri(item);
386 });
387 }
388 return uri;
389 };
390 /**
391 * @return {?}
392 */
393 NacoService.prototype.getRefreshToken = /**
394 * @return {?}
395 */
396 function () {
397 if (null !== this.refreshToken) {
398 return Promise.resolve(this.refreshToken);
399 }
400 return this.storage.get('refresh_token');
401 };
402 /**
403 * @return {?}
404 */
405 NacoService.prototype.getClientSecret = /**
406 * @return {?}
407 */
408 function () {
409 if (null !== this.clientSecret) {
410 return Promise.resolve(this.clientSecret);
411 }
412 return this.storage.get('client_secret');
413 };
414 /**
415 * @param {?} path
416 * @return {?}
417 */
418 NacoService.prototype.getUri = /**
419 * @param {?} path
420 * @return {?}
421 */
422 function (path) {
423 return this.config.endpoint + '/api/' + this.VERSION + path;
424 };
425 /**
426 * @param {?=} path
427 * @return {?}
428 */
429 NacoService.prototype.getCurrentOrigin = /**
430 * @param {?=} path
431 * @return {?}
432 */
433 function (path) {
434 return window.location.origin + this.location.prepareExternalUrl(path || '');
435 };
436 /**
437 * @return {?}
438 */
439 NacoService.prototype.generateState = /**
440 * @return {?}
441 */
442 function () {
443 var /** @type {?} */ possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
444 var /** @type {?} */ text = '';
445 for (var /** @type {?} */ i = 0; i < 5; i++) {
446 text += possible.charAt(Math.floor(Math.random() * possible.length));
447 }
448 return text;
449 };
450 /**
451 * @param {?} params
452 * @return {?}
453 */
454 NacoService.prototype.buildQueryString = /**
455 * @param {?} params
456 * @return {?}
457 */
458 function (params) {
459 var /** @type {?} */ queryParams = Object.keys(params).map(function (key) {
460 return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
461 });
462 return queryParams.join('&');
463 };
464 NacoService.decorators = [
465 { type: Injectable },
466 ];
467 /** @nocollapse */
468 NacoService.ctorParameters = function () { return [
469 { type: Config },
470 { type: Router },
471 { type: Storage },
472 { type: HttpClient },
473 { type: Location }
474 ]; };
475 return NacoService;
476}());
477
478/**
479 * @fileoverview added by tsickle
480 * @suppress {checkTypes} checked by tsc
481 */
482var Signature = /** @class */ (function () {
483 function Signature() {
484 }
485 return Signature;
486}());
487
488/**
489 * @fileoverview added by tsickle
490 * @suppress {checkTypes} checked by tsc
491 */
492var AuthenticatedGuard = /** @class */ (function () {
493 function AuthenticatedGuard(naco, storage) {
494 this.naco = naco;
495 this.storage = storage;
496 }
497 /**
498 * @param {?} route
499 * @return {?}
500 */
501 AuthenticatedGuard.prototype.canActivate = /**
502 * @param {?} route
503 * @return {?}
504 */
505 function (route) {
506 var _this = this;
507 return this.naco.getUser().pipe(first(), map(function (user) {
508 if (null === user) {
509 var /** @type {?} */ uri = _this.naco.buildNestedUri(route.root);
510 var /** @type {?} */ next = _this.naco.getCurrentOrigin('/' + _this.ltrim(uri));
511 _this.storage.set('naco_intended_url', next).then(function () {
512 window.location.href = _this.naco.login('basic email', _this.naco.getCurrentOrigin('/auth'));
513 });
514 }
515 return !!user;
516 }));
517 };
518 /**
519 * @param {?} route
520 * @return {?}
521 */
522 AuthenticatedGuard.prototype.canActivateChild = /**
523 * @param {?} route
524 * @return {?}
525 */
526 function (route) {
527 return this.canActivate(route);
528 };
529 /**
530 * @param {?} text
531 * @return {?}
532 */
533 AuthenticatedGuard.prototype.ltrim = /**
534 * @param {?} text
535 * @return {?}
536 */
537 function (text) {
538 return text.replace(/^\/+/, '');
539 };
540 /**
541 * @param {?} text
542 * @return {?}
543 */
544 AuthenticatedGuard.prototype.rtrim = /**
545 * @param {?} text
546 * @return {?}
547 */
548 function (text) {
549 return text.replace(/\/+$/, '');
550 };
551 AuthenticatedGuard.decorators = [
552 { type: Injectable },
553 ];
554 /** @nocollapse */
555 AuthenticatedGuard.ctorParameters = function () { return [
556 { type: NacoService },
557 { type: Storage }
558 ]; };
559 return AuthenticatedGuard;
560}());
561
562/**
563 * @fileoverview added by tsickle
564 * @suppress {checkTypes} checked by tsc
565 */
566var AuthInterceptor = /** @class */ (function () {
567 function AuthInterceptor(naco) {
568 this.naco = naco;
569 }
570 /**
571 * @param {?} req
572 * @param {?} next
573 * @return {?}
574 */
575 AuthInterceptor.prototype.intercept = /**
576 * @param {?} req
577 * @param {?} next
578 * @return {?}
579 */
580 function (req, next) {
581 var _this = this;
582 return fromPromise(this.naco.getSignature()).pipe(switchMap(function (signature) {
583 if (!signature) {
584 return next.handle(req);
585 }
586 return next
587 .handle(req.clone({
588 setHeaders: {
589 Authorization: signature.type + " " + signature.token,
590 },
591 }))
592 .pipe(catchError(function (error) {
593 if (error.status === 401) {
594 return _this.naco.refreshUser().pipe(switchMap(function (user) {
595 if (user) {
596 return fromPromise(_this.naco.getSignature()).pipe(switchMap(function (newSignature) {
597 return next.handle(req.clone({
598 setHeaders: {
599 Authorization: newSignature.type + " " + newSignature.token,
600 },
601 }));
602 }));
603 }
604 return ErrorObservable.create(error);
605 }));
606 }
607 return ErrorObservable.create(error);
608 }));
609 }));
610 };
611 AuthInterceptor.decorators = [
612 { type: Injectable },
613 ];
614 /** @nocollapse */
615 AuthInterceptor.ctorParameters = function () { return [
616 { type: NacoService }
617 ]; };
618 return AuthInterceptor;
619}());
620
621/**
622 * @fileoverview added by tsickle
623 * @suppress {checkTypes} checked by tsc
624 */
625/**
626 * @param {?} config
627 * @param {?} router
628 * @param {?} storage
629 * @param {?} http
630 * @param {?} location
631 * @return {?}
632 */
633function nacoFactory(config, router, storage, http, location) {
634 return new NacoService(new Config(__assign({}, config)), router, storage, http, location);
635}
636var /** @type {?} */ NACO_CONFIG = new InjectionToken('NACO_CONFIG');
637
638/**
639 * @fileoverview added by tsickle
640 * @suppress {checkTypes} checked by tsc
641 */
642var AuthPage = /** @class */ (function () {
643 function AuthPage(route, naco, storage) {
644 var _this = this;
645 this.route = route;
646 this.naco = naco;
647 this.storage = storage;
648 this.message = 'Authenticating...';
649 this.route.queryParams.subscribe(function (params) { return _this.handle(params); });
650 }
651 /**
652 * @param {?} params
653 * @return {?}
654 */
655 AuthPage.prototype.handle = /**
656 * @param {?} params
657 * @return {?}
658 */
659 function (params) {
660 var _this = this;
661 if (params["state"]) {
662 this.naco.getState().then(function (state) {
663 if (state !== params["state"]) {
664 _this.message = 'Invalid CSRF';
665 return;
666 }
667 _this.authenticate(params);
668 });
669 }
670 else {
671 this.authenticate(params);
672 }
673 };
674 /**
675 * @param {?} params
676 * @return {?}
677 */
678 AuthPage.prototype.authenticate = /**
679 * @param {?} params
680 * @return {?}
681 */
682 function (params) {
683 var _this = this;
684 var /** @type {?} */ signature = {
685 expiresIn: params["expires_in"],
686 type: params["token_type"],
687 token: params["access_token"],
688 };
689 this.naco.setUser(null);
690 this.naco.setSignature(signature);
691 this.naco.getUser().subscribe(function (user) {
692 if (null !== user) {
693 _this.storage.get('naco_intended_url').then(function (url) {
694 _this.storage.remove('naco_intended_url').then(function () {
695 window.location.href = url ? url : '/';
696 });
697 });
698 return;
699 }
700 _this.message = 'Unauthenticated!';
701 });
702 };
703 AuthPage.decorators = [
704 { type: Component, args: [{
705 selector: 'naker-auth-page',
706 template: '{{ message }}',
707 },] },
708 ];
709 /** @nocollapse */
710 AuthPage.ctorParameters = function () { return [
711 { type: ActivatedRoute },
712 { type: NacoService },
713 { type: Storage }
714 ]; };
715 return AuthPage;
716}());
717
718/**
719 * @fileoverview added by tsickle
720 * @suppress {checkTypes} checked by tsc
721 */
722var AuthSilentPage = /** @class */ (function () {
723 function AuthSilentPage() {
724 }
725 AuthSilentPage.decorators = [
726 { type: Component, args: [{
727 selector: 'naker-auth-silent',
728 template: 'Processing silent auth...',
729 },] },
730 ];
731 return AuthSilentPage;
732}());
733
734/**
735 * @fileoverview added by tsickle
736 * @suppress {checkTypes} checked by tsc
737 */
738var /** @type {?} */ routes = [
739 {
740 path: 'auth',
741 component: AuthPage
742 },
743 {
744 path: 'auth/silent',
745 component: AuthSilentPage
746 },
747];
748var /** @type {?} */ AUTH_ROUTING = RouterModule.forChild(routes);
749
750/**
751 * @fileoverview added by tsickle
752 * @suppress {checkTypes} checked by tsc
753 */
754var NacoViewModule = /** @class */ (function () {
755 function NacoViewModule() {
756 }
757 NacoViewModule.decorators = [
758 { type: NgModule, args: [{
759 imports: [
760 AUTH_ROUTING,
761 ],
762 declarations: [
763 AuthPage,
764 AuthSilentPage,
765 ],
766 },] },
767 ];
768 return NacoViewModule;
769}());
770
771/**
772 * @fileoverview added by tsickle
773 * @suppress {checkTypes} checked by tsc
774 */
775var NacoModule = /** @class */ (function () {
776 function NacoModule() {
777 }
778 /**
779 * @param {?} config
780 * @return {?}
781 */
782 NacoModule.forRoot = /**
783 * @param {?} config
784 * @return {?}
785 */
786 function (config) {
787 return {
788 ngModule: NacoModule,
789 providers: [
790 {
791 provide: NACO_CONFIG,
792 useValue: config,
793 },
794 {
795 provide: NacoService,
796 useFactory: nacoFactory,
797 deps: [NACO_CONFIG, Router, Storage, HttpClient, Location],
798 },
799 AuthenticatedGuard,
800 ],
801 };
802 };
803 NacoModule.decorators = [
804 { type: NgModule, args: [{
805 imports: [
806 UbudStorageModule,
807 NacoViewModule,
808 ],
809 },] },
810 ];
811 return NacoModule;
812}());
813
814/**
815 * @fileoverview added by tsickle
816 * @suppress {checkTypes} checked by tsc
817 */
818
819/**
820 * @fileoverview added by tsickle
821 * @suppress {checkTypes} checked by tsc
822 */
823
824export { NacoService, User, Signature, Config, AuthenticatedGuard, AuthInterceptor, NacoModule, NACO_CONFIG as ɵf, nacoFactory as ɵe, NacoViewModule as ɵa, AuthSilentPage as ɵd, AuthPage as ɵc, AUTH_ROUTING as ɵb };
825
826//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFrZXItbmFjby5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vQG5ha2VyL25hY28vZG9tYWlucy92YWx1ZXMvY29uZmlnLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9kb21haW5zL21vZGVscy91c2VyLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9kb21haW5zL3NlcnZpY2VzL25hY28uc2VydmljZS50cyIsIm5nOi8vQG5ha2VyL25hY28vZG9tYWlucy92YWx1ZXMvc2lnbmF0dXJlLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9ndWFyZHMvYXV0aGVudGljYXRlZC5ndWFyZC50cyIsIm5nOi8vQG5ha2VyL25hY28vaW50ZXJjZXB0b3JzL2F1dGguaW50ZXJjZXB0b3IudHMiLCJuZzovL0BuYWtlci9uYWNvL2ZhY3Rvcmllcy9uYWNvLWZhY3RvcnkudHMiLCJuZzovL0BuYWtlci9uYWNvL3ZpZXdzL3BhZ2VzL2F1dGgucGFnZS50cyIsIm5nOi8vQG5ha2VyL25hY28vdmlld3MvcGFnZXMvYXV0aC1zaWxlbnQucGFnZS50cyIsIm5nOi8vQG5ha2VyL25hY28vdmlld3Mvcm91dGVzLnRzIiwibmc6Ly9AbmFrZXIvbmFjby92aWV3cy9tb2R1bGUudHMiLCJuZzovL0BuYWtlci9uYWNvL25hY28ubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjbGFzcyBDb25maWcge1xuICAgIHB1YmxpYyBlbmRwb2ludDogc3RyaW5nID0gJ2h0dHBzOi8vYWNjb3VudC5rZW1uYWtlci5nby5pZCc7XG4gICAgcHVibGljIGNsaWVudElkOiBzdHJpbmc7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoZGF0YT86IFBhcnRpYWw8Q29uZmlnPikge1xuICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMsIGRhdGEpO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IGZvcndhcmRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFR5cGUgfSBmcm9tICdjbGFzcy10cmFuc2Zvcm1lcic7XG5cbmV4cG9ydCBjbGFzcyBVc2VyIHtcbiAgICBwdWJsaWMgaWQ6IHN0cmluZztcbiAgICBwdWJsaWMgdXNlcm5hbWU6IHN0cmluZztcbiAgICBwdWJsaWMgZW1haWw/OiBzdHJpbmc7XG4gICAgcHVibGljIG5hbWU6IHN0cmluZztcbiAgICBwdWJsaWMgc3RhdHVzOiBudW1iZXI7XG5cbiAgICBAVHlwZShmb3J3YXJkUmVmKCgpID0+IERhdGUpIGFzIGFueSlcbiAgICBwdWJsaWMgdXBkYXRlZEF0OiBEYXRlO1xufVxuIiwiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGVTbmFwc2hvdCwgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFN0b3JhZ2UgfSBmcm9tICdAdWJ1ZC9zdG9yYWdlJztcbmltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4uL3ZhbHVlcy9jb25maWcnO1xuaW1wb3J0IHsgVXNlciB9IGZyb20gJy4uL21vZGVscy91c2VyJztcbmltcG9ydCB7IGZvcmtKb2luLCBPYnNlcnZhYmxlLCBPYnNlcnZlciwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFNpZ25hdHVyZSB9IGZyb20gJy4uL3ZhbHVlcy9zaWduYXR1cmUnO1xuaW1wb3J0IHsgZnJvbVByb21pc2UgfSBmcm9tICdyeGpzL2ludGVybmFsL29ic2VydmFibGUvZnJvbVByb21pc2UnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgbWFwLCBzd2l0Y2hNYXAsIHRhcCB9IGZyb20gJ3J4anMvaW50ZXJuYWwvb3BlcmF0b3JzJztcbmltcG9ydCB7IHBsYWluVG9DbGFzcyB9IGZyb20gJ2NsYXNzLXRyYW5zZm9ybWVyJztcbmltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBFcnJvclJlc3BvbnNlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgTG9jYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRXJyb3JPYnNlcnZhYmxlIH0gZnJvbSAncnhqcy1jb21wYXQvb2JzZXJ2YWJsZS9FcnJvck9ic2VydmFibGUnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTmFjb1NlcnZpY2Uge1xuICAgIHB1YmxpYyByZWFkb25seSBWRVJTSU9OID0gJ3YxJztcblxuICAgIHByaXZhdGUgc2lnbmF0dXJlOiBTaWduYXR1cmUgfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIHVzZXI6IFVzZXIgfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIHJlZnJlc2hUb2tlbjogU2lnbmF0dXJlIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSBjbGllbnRTZWNyZXQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgY29uZmlnOiBDb25maWcsIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsIHByaXZhdGUgc3RvcmFnZTogU3RvcmFnZSwgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LCBwcml2YXRlIGxvY2F0aW9uOiBMb2NhdGlvbikge1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRVc2VyKHVzZXI6IFVzZXIgfCBudWxsKTogdm9pZCB7XG4gICAgICAgIHRoaXMudXNlciA9IHVzZXI7XG4gICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ3VzZXInLCB1c2VyKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0VXNlcigpOiBPYnNlcnZhYmxlPFVzZXIgfCBudWxsPiB7XG4gICAgICAgIGlmIChudWxsICE9PSB0aGlzLnVzZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBvZih0aGlzLnVzZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZyb21Qcm9taXNlKHRoaXMuc3RvcmFnZS5nZXQoJ3VzZXInKSkucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcCgodXNlcjogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHVzZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9mKHVzZXIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHVyaSA9IHRoaXMuZ2V0VXJpKCcvdXNlcnMvbWUnKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBmcm9tUHJvbWlzZSh0aGlzLmdldFNpZ25hdHVyZSgpKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKHNpZ25hdHVyZTogU2lnbmF0dXJlIHwgbnVsbCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG51bGwgPT09IHNpZ25hdHVyZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnJlZnJlc2hVc2VyKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdXRob3JpemF0aW9uOiBgJHtzaWduYXR1cmUudHlwZX0gJHtzaWduYXR1cmUudG9rZW59YCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8YW55Pih1cmksIG9wdGlvbnMpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwKChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzLmRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXMuZGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlcmUgYXJlIG5vIGJvZHkgdG8gYmUgdHJhbnNmb3JtZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXAoKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhdXRoVXNlcjogYW55ID0gcGxhaW5Ub0NsYXNzKFVzZXIsIGRhdGEpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0VXNlcihhdXRoVXNlcik7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF1dGhVc2VyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoRXJyb3IoKGU6IEh0dHBFcnJvclJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICg0MDEgPT09IGUuc3RhdHVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZWZyZXNoVXNlcigpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoTWFwKChyZWZyZXNoVXNlcjogVXNlciB8IG51bGwpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlZnJlc2hVc2VyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YocmVmcmVzaFVzZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVycm9yT2JzZXJ2YWJsZS5jcmVhdGUoZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEVycm9yT2JzZXJ2YWJsZS5jcmVhdGUoZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldFNpZ25hdHVyZSgpOiBQcm9taXNlPFNpZ25hdHVyZSB8IG51bGw+IHtcbiAgICAgICAgaWYgKHRoaXMuc2lnbmF0dXJlKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuc2lnbmF0dXJlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZ2V0KCdzaWduYXR1cmUnKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0U2lnbmF0dXJlKHNpZ25hdHVyZTogU2lnbmF0dXJlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2lnbmF0dXJlID0gc2lnbmF0dXJlO1xuICAgICAgICB0aGlzLnN0b3JhZ2Uuc2V0KCdzaWduYXR1cmUnLCBzaWduYXR1cmUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRDbGllbnRTZWNyZXQoc2VjcmV0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jbGllbnRTZWNyZXQgPSBzZWNyZXQ7XG4gICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ2NsaWVudF9zZWNyZXQnLCBzZWNyZXQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRSZWZyZXNoVG9rZW4ocmVmcmVzaFRva2VuOiBTaWduYXR1cmUpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5yZWZyZXNoVG9rZW4gPSByZWZyZXNoVG9rZW47XG4gICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ3JlZnJlc2hfdG9rZW4nLCByZWZyZXNoVG9rZW4pO1xuICAgIH1cblxuICAgIHB1YmxpYyByZWZyZXNoVXNlcihzY29wZXM/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPFVzZXIgfCBudWxsPiB7XG4gICAgICAgIHRoaXMuc2V0VXNlcihudWxsKTtcbiAgICAgICAgdGhpcy5zZXRTaWduYXR1cmUobnVsbCk7XG5cbiAgICAgICAgcmV0dXJuIGZvcmtKb2luKHRoaXMuZ2V0UmVmcmVzaFRva2VuKCksIHRoaXMuZ2V0Q2xpZW50U2VjcmV0KCkpLnBpcGUoXG4gICAgICAgICAgICBzd2l0Y2hNYXAoKHJlc3VsdHM6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlZnJlc2hUb2tlbjogU2lnbmF0dXJlID0gcmVzdWx0c1swXTtcbiAgICAgICAgICAgICAgICBjb25zdCBjbGllbnRTZWNyZXQ6IHN0cmluZyA9IHJlc3VsdHNbMV07XG5cbiAgICAgICAgICAgICAgICBpZiAocmVmcmVzaFRva2VuICYmIGNsaWVudFNlY3JldCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZWZyZXNoV2l0aFJlZnJlc2hUb2tlbihjbGllbnRTZWNyZXQsIHJlZnJlc2hUb2tlbi50b2tlbiwgc2NvcGVzKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZWZyZXNoV2l0aFNpbGVudEF1dGgoKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyByZWZyZXNoV2l0aFJlZnJlc2hUb2tlbihjbGllbnRTZWNyZXQ6IHN0cmluZywgcmVmcmVzaFRva2VuOiBzdHJpbmcsIHNjb3Blcz86IHN0cmluZyk6IE9ic2VydmFibGU8VXNlciB8IG51bGw+IHtcbiAgICAgICAgY29uc3QgcmVxdWVzdCA9IHRoaXMuaHR0cC5wb3N0KHRoaXMuZ2V0VXJpKCcvdG9rZW5zJyksIHtcbiAgICAgICAgICAgIGdyYW50X3R5cGU6ICdyZWZyZXNoX3Rva2VuJyxcbiAgICAgICAgICAgIHNjb3Blczogc2NvcGVzIHx8ICdiYXNpYyBlbWFpbCcsXG4gICAgICAgICAgICBjbGllbnRfaWQ6IHRoaXMuY29uZmlnLmNsaWVudElkLFxuICAgICAgICAgICAgY2xpZW50X3NlY3JldDogY2xpZW50U2VjcmV0LFxuICAgICAgICAgICAgcmVmcmVzaF90b2tlbjogcmVmcmVzaFRva2VuLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcmVxdWVzdC5waXBlKFxuICAgICAgICAgICAgdGFwKCh0b2tlbnM6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0b2tlbnMgJiYgdG9rZW5zLmRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRTaWduYXR1cmUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZXhwaXJlc0luOiB0b2tlbnMuZGF0YS5leHBpcmVzX2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogdG9rZW5zLmRhdGEudG9rZW5fdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuOiB0b2tlbnMuZGF0YS5hY2Nlc3NfdG9rZW4sXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0UmVmcmVzaFRva2VuKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IHRva2Vucy5kYXRhLnRva2VuX3R5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogdG9rZW5zLmRhdGEucmVmcmVzaF90b2tlbixcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBtYXAoKHRva2VuczogYW55KSA9PiB0b2tlbnMgJiYgdG9rZW5zLmRhdGEpLFxuICAgICAgICAgICAgc3dpdGNoTWFwKChoYXNUb2tlbjogYm9vbGVhbikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChoYXNUb2tlbikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRVc2VyKCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9mKG51bGwpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlZnJlc2hXaXRoU2lsZW50QXV0aCgpOiBPYnNlcnZhYmxlPFVzZXIgfCBudWxsPiB7XG4gICAgICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZTxVc2VyIHwgbnVsbD4oKG9ic2VydmVyOiBPYnNlcnZlcjxVc2VyIHwgbnVsbD4pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlZGlyZWN0VXJpID0gdGhpcy5nZXRDdXJyZW50T3JpZ2luKCdhdXRoL3NpbGVudCcpO1xuICAgICAgICAgICAgY29uc3QgdXJpID0gdGhpcy5sb2dpbignYmFzaWMgZW1haWwnLCByZWRpcmVjdFVyaSwgZmFsc2UpO1xuXG4gICAgICAgICAgICBjb25zdCBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICAgICAgICAgIGlmcmFtZS5zZXRBdHRyaWJ1dGUoJ3NyYycsIHVyaSk7XG4gICAgICAgICAgICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcblxuICAgICAgICAgICAgaWZyYW1lLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVlcnlTdHJpbmcgPSBpZnJhbWUuY29udGVudFdpbmRvdy5sb2NhdGlvbi5zZWFyY2guc3Vic3RyaW5nKDEpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmcmFtZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGlmcmFtZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHF1ZXJ5U3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBxdWVyeVBhcnRzID0gcXVlcnlTdHJpbmcuc3BsaXQoJyYnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgcXVlcnlQYXJ0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW1QYXJ0cyA9IGl0ZW0uc3BsaXQoJz0nKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtc1tpdGVtUGFydHNbMF1dID0gaXRlbVBhcnRzWzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyYW1zLmhhc093blByb3BlcnR5KCdhY2Nlc3NfdG9rZW4nKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U2lnbmF0dXJlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW46IHBhcmFtc1snYWNjZXNzX3Rva2VuJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IHBhcmFtc1sndG9rZW5fdHlwZSddLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBpcmVzSW46IHBhcmFtc1sndHRsJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1c2VyID0gYXdhaXQgdGhpcy5nZXRVc2VyKCkudG9Qcm9taXNlKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFVzZXIodXNlcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dCh1c2VyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChudWxsKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm5leHQobnVsbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgZmFsc2UpO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGlmcmFtZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBsb2dpbihzY29wZXM6IHN0cmluZywgcmVkaXJlY3RVcmk/OiBzdHJpbmcsIG5lZWRTdGF0ZTogYm9vbGVhbiA9IHRydWUpOiBzdHJpbmcge1xuICAgICAgICBpZiAoIXJlZGlyZWN0VXJpKSB7XG4gICAgICAgICAgICByZWRpcmVjdFVyaSA9IHRoaXMucm91dGVyLnVybDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBhcmFtczogYW55ID0ge1xuICAgICAgICAgICAgJ3Jlc3BvbnNlX3R5cGUnOiAndG9rZW4nLFxuICAgICAgICAgICAgJ3Njb3Blcyc6IHNjb3BlcyxcbiAgICAgICAgICAgICdjbGllbnQnOiB0aGlzLmNvbmZpZy5jbGllbnRJZCxcbiAgICAgICAgICAgICdzaWxlbnQnOiB0cnVlLFxuICAgICAgICAgICAgJ2NvbnRpbnVlJzogZW5jb2RlVVJJQ29tcG9uZW50KHJlZGlyZWN0VXJpKSxcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAobmVlZFN0YXRlKSB7XG4gICAgICAgICAgICBjb25zdCBzdGF0ZSA9IHRoaXMuZ2VuZXJhdGVTdGF0ZSgpO1xuXG4gICAgICAgICAgICB0aGlzLnN0b3JhZ2Uuc2V0KCdzdGF0ZScsIHN0YXRlKTtcbiAgICAgICAgICAgIHBhcmFtcy5zdGF0ZSA9IHN0YXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcXVlcnk6IHN0cmluZyA9IHRoaXMuYnVpbGRRdWVyeVN0cmluZyhwYXJhbXMpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5lbmRwb2ludCArICcvYXV0aD8nICsgcXVlcnk7XG4gICAgfVxuXG4gICAgcHVibGljIGxvZ291dChyZWRpcmVjdFVyaT86IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHRoaXMuc2lnbmF0dXJlID0gbnVsbDtcbiAgICAgICAgdGhpcy51c2VyID0gbnVsbDtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlLnJlbW92ZSgnc2lnbmF0dXJlJyksXG4gICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlLnJlbW92ZSgndXNlcicpLFxuICAgICAgICAgICAgXSkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IGVuZHBvaW50ID0gdGhpcy5jb25maWcuZW5kcG9pbnQgKyAnL2F1dGgvbG9nb3V0JztcblxuICAgICAgICAgICAgICAgIGlmIChyZWRpcmVjdFVyaSkge1xuICAgICAgICAgICAgICAgICAgICBlbmRwb2ludCArPSAnP2NvbnRpbnVlPScgKyBlbmNvZGVVUklDb21wb25lbnQocmVkaXJlY3RVcmkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJlc29sdmUoZW5kcG9pbnQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRTdGF0ZSgpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZS5nZXQoJ3N0YXRlJyk7XG4gICAgfVxuXG4gICAgcHVibGljIGJ1aWxkTmVzdGVkVXJpKHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90KTogc3RyaW5nIHtcbiAgICAgICAgbGV0IHVyaSA9ICcnO1xuXG4gICAgICAgIGlmIChyb3V0ZS5yb3V0ZUNvbmZpZyAmJiByb3V0ZS5yb3V0ZUNvbmZpZy5wYXRoKSB7XG4gICAgICAgICAgICBsZXQgcm91dGVQYXRoID0gcm91dGUucm91dGVDb25maWcucGF0aDtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gcm91dGUucGFyYW1zKSB7XG4gICAgICAgICAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZSA9IG5ldyBSZWdFeHAoJ1xcOicgKyBrZXkpO1xuXG4gICAgICAgICAgICAgICAgICAgIHJvdXRlUGF0aCA9IHJvdXRlUGF0aC5yZXBsYWNlKHJlLCByb3V0ZS5wYXJhbXNba2V5XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB1cmkgKz0gJy8nICsgcm91dGVQYXRoO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJvdXRlLmNoaWxkcmVuKSB7XG4gICAgICAgICAgICByb3V0ZS5jaGlsZHJlbi5mb3JFYWNoKChpdGVtOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90KSA9PiB7XG4gICAgICAgICAgICAgICAgdXJpICs9IHRoaXMuYnVpbGROZXN0ZWRVcmkoaXRlbSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB1cmk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSZWZyZXNoVG9rZW4oKTogUHJvbWlzZTxTaWduYXR1cmUgfCBudWxsPiB7XG4gICAgICAgIGlmIChudWxsICE9PSB0aGlzLnJlZnJlc2hUb2tlbikge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLnJlZnJlc2hUb2tlbik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5zdG9yYWdlLmdldCgncmVmcmVzaF90b2tlbicpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q2xpZW50U2VjcmV0KCk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgICAgICBpZiAobnVsbCAhPT0gdGhpcy5jbGllbnRTZWNyZXQpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5jbGllbnRTZWNyZXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZS5nZXQoJ2NsaWVudF9zZWNyZXQnKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFVyaShwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuZW5kcG9pbnQgKyAnL2FwaS8nICsgdGhpcy5WRVJTSU9OICsgcGF0aDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0Q3VycmVudE9yaWdpbihwYXRoPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5sb2NhdGlvbi5vcmlnaW4gKyB0aGlzLmxvY2F0aW9uLnByZXBhcmVFeHRlcm5hbFVybChwYXRoIHx8ICcnKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdlbmVyYXRlU3RhdGUoKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgcG9zc2libGUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODknO1xuICAgICAgICBsZXQgdGV4dCA9ICcnO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNTsgaSsrKSB7XG4gICAgICAgICAgICB0ZXh0ICs9IHBvc3NpYmxlLmNoYXJBdChNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBwb3NzaWJsZS5sZW5ndGgpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cblxuICAgIHByaXZhdGUgYnVpbGRRdWVyeVN0cmluZyhwYXJhbXM6IG9iamVjdCk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5UGFyYW1zID0gT2JqZWN0LmtleXMocGFyYW1zKS5tYXAoKGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KGtleSkgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQocGFyYW1zW2tleV0pO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcXVlcnlQYXJhbXMuam9pbignJicpO1xuICAgIH1cbn1cbiIsImV4cG9ydCBjbGFzcyBTaWduYXR1cmUge1xuICAgIHB1YmxpYyBleHBpcmVzSW4/OiBudW1iZXI7XG4gICAgcHVibGljIHRva2VuOiBzdHJpbmc7XG4gICAgcHVibGljIHR5cGU6IHN0cmluZztcbn1cbiIsImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENhbkFjdGl2YXRlLCBDYW5BY3RpdmF0ZUNoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IE5hY29TZXJ2aWNlIH0gZnJvbSAnLi4vZG9tYWlucy9zZXJ2aWNlcy9uYWNvLnNlcnZpY2UnO1xuaW1wb3J0IHsgZmlyc3QsIG1hcCB9IGZyb20gJ3J4anMvaW50ZXJuYWwvb3BlcmF0b3JzJztcbmltcG9ydCB7IFVzZXIgfSBmcm9tICcuLi9kb21haW5zL21vZGVscy91c2VyJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFN0b3JhZ2UgfSBmcm9tICdAdWJ1ZC9zdG9yYWdlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlU25hcHNob3QgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXIvc3JjL3JvdXRlcl9zdGF0ZSc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBBdXRoZW50aWNhdGVkR3VhcmQgaW1wbGVtZW50cyBDYW5BY3RpdmF0ZSwgQ2FuQWN0aXZhdGVDaGlsZCB7XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgbmFjbzogTmFjb1NlcnZpY2UsIHByaXZhdGUgc3RvcmFnZTogU3RvcmFnZSkge1xuICAgIH1cblxuICAgIHB1YmxpYyBjYW5BY3RpdmF0ZShyb3V0ZTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5uYWNvLmdldFVzZXIoKS5waXBlKFxuICAgICAgICAgICAgZmlyc3QoKSxcbiAgICAgICAgICAgIG1hcCgodXNlcjogVXNlciB8IG51bGwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobnVsbCA9PT0gdXNlcikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB1cmkgPSB0aGlzLm5hY28uYnVpbGROZXN0ZWRVcmkocm91dGUucm9vdCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5leHQgPSB0aGlzLm5hY28uZ2V0Q3VycmVudE9yaWdpbignLycgKyB0aGlzLmx0cmltKHVyaSkpO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ25hY29faW50ZW5kZWRfdXJsJywgbmV4dCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHRoaXMubmFjby5sb2dpbihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYmFzaWMgZW1haWwnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmFjby5nZXRDdXJyZW50T3JpZ2luKCcvYXV0aCcpLFxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuICEhdXNlcjtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBjYW5BY3RpdmF0ZUNoaWxkKHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90KTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhbkFjdGl2YXRlKHJvdXRlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGx0cmltKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0ZXh0LnJlcGxhY2UoL15cXC8rLywnJyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBydHJpbSh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGV4dC5yZXBsYWNlKC9cXC8rJC8sJycpO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IEh0dHBFcnJvclJlc3BvbnNlLCBIdHRwRXZlbnQsIEh0dHBIYW5kbGVyLCBIdHRwSW50ZXJjZXB0b3IsIEh0dHBSZXF1ZXN0IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgTmFjb1NlcnZpY2UgfSBmcm9tICcuLi9kb21haW5zL3NlcnZpY2VzL25hY28uc2VydmljZSc7XG5pbXBvcnQgeyBmcm9tUHJvbWlzZSB9IGZyb20gJ3J4anMvaW50ZXJuYWwvb2JzZXJ2YWJsZS9mcm9tUHJvbWlzZSc7XG5pbXBvcnQgeyBTaWduYXR1cmUgfSBmcm9tICcuLi9kb21haW5zL3ZhbHVlcy9zaWduYXR1cmUnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9pbnRlcm5hbC9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgRXJyb3JPYnNlcnZhYmxlIH0gZnJvbSAncnhqcy1jb21wYXQvb2JzZXJ2YWJsZS9FcnJvck9ic2VydmFibGUnO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQXV0aEludGVyY2VwdG9yIGltcGxlbWVudHMgSHR0cEludGVyY2VwdG9yIHtcbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJpdmF0ZSBuYWNvOiBOYWNvU2VydmljZSkge1xuICAgIH1cblxuICAgIHB1YmxpYyBpbnRlcmNlcHQocmVxOiBIdHRwUmVxdWVzdDxhbnk+LCBuZXh0OiBIdHRwSGFuZGxlcik6IE9ic2VydmFibGU8SHR0cEV2ZW50PGFueT4+IHtcbiAgICAgICAgcmV0dXJuIGZyb21Qcm9taXNlKHRoaXMubmFjby5nZXRTaWduYXR1cmUoKSkucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcCgoc2lnbmF0dXJlOiBTaWduYXR1cmUgfCBudWxsKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFzaWduYXR1cmUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5leHQuaGFuZGxlKHJlcSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5leHRcbiAgICAgICAgICAgICAgICAgICAgLmhhbmRsZShcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcS5jbG9uZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0SGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdXRob3JpemF0aW9uOiBgJHtzaWduYXR1cmUudHlwZX0gJHtzaWduYXR1cmUudG9rZW59YCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXRjaEVycm9yKChlcnJvcjogSHR0cEVycm9yUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3Iuc3RhdHVzID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmFjby5yZWZyZXNoVXNlcigpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKHVzZXI6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1c2VyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmcm9tUHJvbWlzZSh0aGlzLm5hY28uZ2V0U2lnbmF0dXJlKCkpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKG5ld1NpZ25hdHVyZTogU2lnbmF0dXJlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5leHQuaGFuZGxlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXEuY2xvbmUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0SGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1dGhvcml6YXRpb246IGAke25ld1NpZ25hdHVyZS50eXBlfSAke25ld1NpZ25hdHVyZS50b2tlbn1gLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBFcnJvck9ic2VydmFibGUuY3JlYXRlKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBFcnJvck9ic2VydmFibGUuY3JlYXRlKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgTmFjb1NlcnZpY2UgfSBmcm9tICcuLi9kb21haW5zL3NlcnZpY2VzL25hY28uc2VydmljZSc7XG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuLi9kb21haW5zL3ZhbHVlcy9jb25maWcnO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFN0b3JhZ2UgfSBmcm9tICdAdWJ1ZC9zdG9yYWdlJztcbmltcG9ydCB7IEluamVjdGlvblRva2VuIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgTG9jYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuXG5leHBvcnQgZnVuY3Rpb24gbmFjb0ZhY3RvcnkoY29uZmlnOiBvYmplY3QsIHJvdXRlcjogUm91dGVyLCBzdG9yYWdlOiBTdG9yYWdlLCBodHRwOiBIdHRwQ2xpZW50LCBsb2NhdGlvbjogTG9jYXRpb24pIHtcbiAgICByZXR1cm4gbmV3IE5hY29TZXJ2aWNlKFxuICAgICAgICBuZXcgQ29uZmlnKHsgLi4uY29uZmlnIH0pLFxuICAgICAgICByb3V0ZXIsXG4gICAgICAgIHN0b3JhZ2UsXG4gICAgICAgIGh0dHAsXG4gICAgICAgIGxvY2F0aW9uXG4gICAgKTtcbn1cblxuZXhwb3J0IGNvbnN0IE5BQ09fQ09ORklHID0gbmV3IEluamVjdGlvblRva2VuPG9iamVjdD4oJ05BQ09fQ09ORklHJyk7XG4iLCJpbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBQYXJhbXMgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgTmFjb1NlcnZpY2UgfSBmcm9tICcuLi8uLi9kb21haW5zL3NlcnZpY2VzL25hY28uc2VydmljZSc7XG5pbXBvcnQgeyBTaWduYXR1cmUgfSBmcm9tICcuLi8uLi9kb21haW5zL3ZhbHVlcy9zaWduYXR1cmUnO1xuaW1wb3J0IHsgVXNlciB9IGZyb20gJy4uLy4uL2RvbWFpbnMvbW9kZWxzL3VzZXInO1xuaW1wb3J0IHsgU3RvcmFnZSB9IGZyb20gJ0B1YnVkL3N0b3JhZ2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ25ha2VyLWF1dGgtcGFnZScsXG4gICAgdGVtcGxhdGU6ICd7eyBtZXNzYWdlIH19Jyxcbn0pXG5leHBvcnQgY2xhc3MgQXV0aFBhZ2Uge1xuICAgIHB1YmxpYyBtZXNzYWdlOiBzdHJpbmcgPSAnQXV0aGVudGljYXRpbmcuLi4nO1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgcm91dGU6IEFjdGl2YXRlZFJvdXRlLCBwcml2YXRlIG5hY286IE5hY29TZXJ2aWNlLCBwcml2YXRlIHN0b3JhZ2U6IFN0b3JhZ2UpIHtcbiAgICAgICAgdGhpcy5yb3V0ZS5xdWVyeVBhcmFtcy5zdWJzY3JpYmUoKHBhcmFtczogUGFyYW1zKSA9PiB0aGlzLmhhbmRsZShwYXJhbXMpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaGFuZGxlKHBhcmFtczogUGFyYW1zKTogdm9pZCB7XG4gICAgICAgIGlmIChwYXJhbXMuc3RhdGUpIHtcbiAgICAgICAgICAgIHRoaXMubmFjby5nZXRTdGF0ZSgpLnRoZW4oKHN0YXRlOiBzdHJpbmcgfCBudWxsKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlICE9PSBwYXJhbXMuc3RhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlID0gJ0ludmFsaWQgQ1NSRic7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuYXV0aGVudGljYXRlKHBhcmFtcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYXV0aGVudGljYXRlKHBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGF1dGhlbnRpY2F0ZShwYXJhbXM6IFBhcmFtcyk6IHZvaWQge1xuICAgICAgICBjb25zdCBzaWduYXR1cmU6IFNpZ25hdHVyZSA9IHtcbiAgICAgICAgICAgIGV4cGlyZXNJbjogcGFyYW1zLmV4cGlyZXNfaW4sXG4gICAgICAgICAgICB0eXBlOiBwYXJhbXMudG9rZW5fdHlwZSxcbiAgICAgICAgICAgIHRva2VuOiBwYXJhbXMuYWNjZXNzX3Rva2VuLFxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMubmFjby5zZXRVc2VyKG51bGwpO1xuICAgICAgICB0aGlzLm5hY28uc2V0U2lnbmF0dXJlKHNpZ25hdHVyZSk7XG5cbiAgICAgICAgdGhpcy5uYWNvLmdldFVzZXIoKS5zdWJzY3JpYmUoKHVzZXI6IFVzZXIgfCBudWxsKSA9PiB7XG4gICAgICAgICAgICBpZiAobnVsbCAhPT0gdXNlcikge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5nZXQoJ25hY29faW50ZW5kZWRfdXJsJykudGhlbigodXJsOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlLnJlbW92ZSgnbmFjb19pbnRlbmRlZF91cmwnKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gdXJsID8gdXJsIDogJy8nO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlID0gJ1VuYXV0aGVudGljYXRlZCEnO1xuICAgICAgICB9KTtcbiAgICB9XG59XG5cbiIsImltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ25ha2VyLWF1dGgtc2lsZW50JyxcbiAgICB0ZW1wbGF0ZTogJ1Byb2Nlc3Npbmcgc2lsZW50IGF1dGguLi4nLFxufSlcbmV4cG9ydCBjbGFzcyBBdXRoU2lsZW50UGFnZSB7XG59XG4iLCJpbXBvcnQgeyBNb2R1bGVXaXRoUHJvdmlkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSb3V0ZXJNb2R1bGUsIFJvdXRlcyB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBBdXRoUGFnZSB9IGZyb20gJy4vcGFnZXMvYXV0aC5wYWdlJztcbmltcG9ydCB7IEF1dGhTaWxlbnRQYWdlIH0gZnJvbSAnLi9wYWdlcy9hdXRoLXNpbGVudC5wYWdlJztcblxuY29uc3Qgcm91dGVzOiBSb3V0ZXMgPSBbXG4gICAge1xuICAgICAgICBwYXRoOiAnYXV0aCcsXG4gICAgICAgIGNvbXBvbmVudDogQXV0aFBhZ2VcbiAgICB9LFxuICAgIHtcbiAgICAgICAgcGF0aDogJ2F1dGgvc2lsZW50JyxcbiAgICAgICAgY29tcG9uZW50OiBBdXRoU2lsZW50UGFnZVxuICAgIH0sXG5dO1xuXG5leHBvcnQgY29uc3QgQVVUSF9ST1VUSU5HOiBNb2R1bGVXaXRoUHJvdmlkZXJzID0gUm91dGVyTW9kdWxlLmZvckNoaWxkKHJvdXRlcyk7XG4iLCJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQVVUSF9ST1VUSU5HIH0gZnJvbSAnLi9yb3V0ZXMnO1xuaW1wb3J0IHsgQXV0aFBhZ2UgfSBmcm9tICcuL3BhZ2VzL2F1dGgucGFnZSc7XG5pbXBvcnQgeyBBdXRoU2lsZW50UGFnZSB9IGZyb20gJy4vcGFnZXMvYXV0aC1zaWxlbnQucGFnZSc7XG5cbkBOZ01vZHVsZSh7XG4gICAgaW1wb3J0czogW1xuICAgICAgICBBVVRIX1JPVVRJTkcsXG4gICAgXSxcbiAgICBkZWNsYXJhdGlvbnM6IFtcbiAgICAgICAgQXV0aFBhZ2UsXG4gICAgICAgIEF1dGhTaWxlbnRQYWdlLFxuICAgIF0sXG59KVxuZXhwb3J0IGNsYXNzIE5hY29WaWV3TW9kdWxlIHtcbn1cbiIsImltcG9ydCB7IE1vZHVsZVdpdGhQcm92aWRlcnMsIE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4vZG9tYWlucy9zZXJ2aWNlcy9uYWNvLnNlcnZpY2UnO1xuaW1wb3J0IHsgQXV0aGVudGljYXRlZEd1YXJkIH0gZnJvbSAnLi9ndWFyZHMvYXV0aGVudGljYXRlZC5ndWFyZCc7XG5pbXBvcnQgeyBOQUNPX0NPTkZJRywgbmFjb0ZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYWNvLWZhY3RvcnknO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFN0b3JhZ2UsIFVidWRTdG9yYWdlTW9kdWxlIH0gZnJvbSAnQHVidWQvc3RvcmFnZSc7XG5pbXBvcnQgeyBOYWNvVmlld01vZHVsZSB9IGZyb20gJy4vdmlld3MvbW9kdWxlJztcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBMb2NhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbkBOZ01vZHVsZSh7XG4gICAgaW1wb3J0czogW1xuICAgICAgICBVYnVkU3RvcmFnZU1vZHVsZSxcbiAgICAgICAgTmFjb1ZpZXdNb2R1bGUsXG4gICAgXSxcbn0pXG5leHBvcnQgY2xhc3MgTmFjb01vZHVsZSB7XG4gICAgcHVibGljIHN0YXRpYyBmb3JSb290KGNvbmZpZzogeyBjbGllbnRJZDogc3RyaW5nLCBlbmRwb2ludD86IHN0cmluZyB9KTogTW9kdWxlV2l0aFByb3ZpZGVycyB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBuZ01vZHVsZTogTmFjb01vZHVsZSxcbiAgICAgICAgICAgIHByb3ZpZGVyczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvdmlkZTogTkFDT19DT05GSUcsXG4gICAgICAgICAgICAgICAgICAgIHVzZVZhbHVlOiBjb25maWcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGU6IE5hY29TZXJ2aWNlLFxuICAgICAgICAgICAgICAgICAgICB1c2VGYWN0b3J5OiBuYWNvRmFjdG9yeSxcbiAgICAgICAgICAgICAgICAgICAgZGVwczogW05BQ09fQ09ORklHLCBSb3V0ZXIsIFN0b3JhZ2UsIEh0dHBDbGllbnQsIExvY2F0aW9uXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIEF1dGhlbnRpY2F0ZWRHdWFyZCxcbiAgICAgICAgICAgIF0sXG4gICAgICAgIH07XG4gICAgfVxufVxu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
\No newline at end of file