UNPKG

121 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('class-transformer'), require('@angular/router'), require('@ubud/storage'), require('rxjs'), require('rxjs/operators'), require('@angular/common/http'), require('@angular/common'), require('rxjs-compat/observable/fromPromise'), require('@nguniversal/express-engine/tokens'), require('rxjs/internal/operators')) :
3 typeof define === 'function' && define.amd ? define('@naker/naco', ['exports', '@angular/core', 'class-transformer', '@angular/router', '@ubud/storage', 'rxjs', 'rxjs/operators', '@angular/common/http', '@angular/common', 'rxjs-compat/observable/fromPromise', '@nguniversal/express-engine/tokens', 'rxjs/internal/operators'], factory) :
4 (factory((global.naker = global.naker || {}, global.naker.naco = {}),global.ng.core,null,global.ng.router,null,global.rxjs,global.rxjs.operators,global.ng.common.http,global.ng.common,null,null,global.rxjs['internal/operators']));
5}(this, (function (exports,core,classTransformer,router,storage,rxjs,operators,http,common,fromPromise,tokens,operators$1) { 'use strict';
6
7 /*! *****************************************************************************
8 Copyright (c) Microsoft Corporation. All rights reserved.
9 Licensed under the Apache License, Version 2.0 (the "License"); you may not use
10 this file except in compliance with the License. You may obtain a copy of the
11 License at http://www.apache.org/licenses/LICENSE-2.0
12
13 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
15 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
16 MERCHANTABLITY OR NON-INFRINGEMENT.
17
18 See the Apache Version 2.0 License for specific language governing permissions
19 and limitations under the License.
20 ***************************************************************************** */
21 /* global Reflect, Promise */
22 var extendStatics = function (d, b) {
23 extendStatics = Object.setPrototypeOf ||
24 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
25 function (d, b) { for (var p in b)
26 if (b.hasOwnProperty(p))
27 d[p] = b[p]; };
28 return extendStatics(d, b);
29 };
30 function __extends(d, b) {
31 extendStatics(d, b);
32 function __() { this.constructor = d; }
33 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
34 }
35 function __decorate(decorators, target, key, desc) {
36 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
37 if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
38 r = Reflect.decorate(decorators, target, key, desc);
39 else
40 for (var i = decorators.length - 1; i >= 0; i--)
41 if (d = decorators[i])
42 r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
43 return c > 3 && r && Object.defineProperty(target, key, r), r;
44 }
45 function __metadata(metadataKey, metadataValue) {
46 if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
47 return Reflect.metadata(metadataKey, metadataValue);
48 }
49 function __awaiter(thisArg, _arguments, P, generator) {
50 return new (P || (P = Promise))(function (resolve, reject) {
51 function fulfilled(value) { try {
52 step(generator.next(value));
53 }
54 catch (e) {
55 reject(e);
56 } }
57 function rejected(value) { try {
58 step(generator["throw"](value));
59 }
60 catch (e) {
61 reject(e);
62 } }
63 function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
64 step((generator = generator.apply(thisArg, _arguments || [])).next());
65 });
66 }
67 function __generator(thisArg, body) {
68 var _ = { label: 0, sent: function () { if (t[0] & 1)
69 throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
70 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g;
71 function verb(n) { return function (v) { return step([n, v]); }; }
72 function step(op) {
73 if (f)
74 throw new TypeError("Generator is already executing.");
75 while (_)
76 try {
77 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
78 return t;
79 if (y = 0, t)
80 op = [op[0] & 2, t.value];
81 switch (op[0]) {
82 case 0:
83 case 1:
84 t = op;
85 break;
86 case 4:
87 _.label++;
88 return { value: op[1], done: false };
89 case 5:
90 _.label++;
91 y = op[1];
92 op = [0];
93 continue;
94 case 7:
95 op = _.ops.pop();
96 _.trys.pop();
97 continue;
98 default:
99 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
100 _ = 0;
101 continue;
102 }
103 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
104 _.label = op[1];
105 break;
106 }
107 if (op[0] === 6 && _.label < t[1]) {
108 _.label = t[1];
109 t = op;
110 break;
111 }
112 if (t && _.label < t[2]) {
113 _.label = t[2];
114 _.ops.push(op);
115 break;
116 }
117 if (t[2])
118 _.ops.pop();
119 _.trys.pop();
120 continue;
121 }
122 op = body.call(thisArg, _);
123 }
124 catch (e) {
125 op = [6, e];
126 y = 0;
127 }
128 finally {
129 f = t = 0;
130 }
131 if (op[0] & 5)
132 throw op[1];
133 return { value: op[0] ? op[1] : void 0, done: true };
134 }
135 }
136 function __values(o) {
137 var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
138 if (m)
139 return m.call(o);
140 return {
141 next: function () {
142 if (o && i >= o.length)
143 o = void 0;
144 return { value: o && o[i++], done: !o };
145 }
146 };
147 }
148
149 /**
150 * @fileoverview added by tsickle
151 * @suppress {checkTypes} checked by tsc
152 */
153 var Config = /** @class */ (function () {
154 function Config(data) {
155 this.endpoint = 'https://account.kemnaker.go.id';
156 this.scopes = 'basic email';
157 this.responseType = 'token';
158 Object.assign(this, data);
159 }
160 return Config;
161 }());
162
163 /**
164 * @fileoverview added by tsickle
165 * @suppress {checkTypes} checked by tsc
166 */
167 var User = /** @class */ (function () {
168 function User() {
169 }
170 __decorate([
171 classTransformer.Type(/** @type {?} */ (core.forwardRef(function () { return Date; }))),
172 __metadata("design:type", Date)
173 ], User.prototype, "updatedAt", void 0);
174 return User;
175 }());
176
177 /**
178 * @fileoverview added by tsickle
179 * @suppress {checkTypes} checked by tsc
180 */
181 var NacoService = /** @class */ (function () {
182 function NacoService(config, router$$1, storage$$1, http$$1, location) {
183 this.config = config;
184 this.router = router$$1;
185 this.storage = storage$$1;
186 this.http = http$$1;
187 this.location = location;
188 this.VERSION = 'v1';
189 this.signature = null;
190 this.user = null;
191 this.refreshToken = null;
192 this.clientSecret = null;
193 if (this.config.clientSecret) {
194 this.setClientSecret(this.config.clientSecret);
195 }
196 }
197 /**
198 * @param {?} user
199 * @return {?}
200 */
201 NacoService.prototype.setUser = /**
202 * @param {?} user
203 * @return {?}
204 */
205 function (user) {
206 this.user = user;
207 };
208 /**
209 * @return {?}
210 */
211 NacoService.prototype.getUser = /**
212 * @return {?}
213 */
214 function () {
215 var _this = this;
216 if (null !== this.user) {
217 return rxjs.of(this.user);
218 }
219 var /** @type {?} */ uri = this.getUri('/users/me');
220 return rxjs.from(this.getSignature()).pipe(operators.switchMap(function (signature) {
221 if (!signature) {
222 return _this.refreshUser(_this.config.scopes);
223 }
224 var /** @type {?} */ options = {
225 headers: {
226 Authorization: signature.type + " " + signature.token,
227 },
228 };
229 return _this.http.get(uri, options).pipe(operators.map(function (res) {
230 if (res.data) {
231 return res.data;
232 }
233 throw new Error('There are no body to be transformed');
234 }), operators.map(function (data) {
235 var /** @type {?} */ authUser = classTransformer.plainToClass(User, data);
236 _this.setUser(authUser);
237 return authUser;
238 }), operators.catchError(function (e) {
239 if (401 === e.status) {
240 return _this.refreshUser(signature.scopes);
241 }
242 return rxjs.of(null);
243 }));
244 }));
245 };
246 /**
247 * @param {?} user
248 * @return {?}
249 */
250 NacoService.prototype.getProfilePicture = /**
251 * @param {?} user
252 * @return {?}
253 */
254 function (user) {
255 return this.config.endpoint + '/users/' + user + '/picture';
256 };
257 /**
258 * @return {?}
259 */
260 NacoService.prototype.getSignature = /**
261 * @return {?}
262 */
263 function () {
264 if (this.signature) {
265 return Promise.resolve(this.signature);
266 }
267 return this.storage.get('signature');
268 };
269 /**
270 * @param {?} signature
271 * @return {?}
272 */
273 NacoService.prototype.setSignature = /**
274 * @param {?} signature
275 * @return {?}
276 */
277 function (signature) {
278 this.signature = signature;
279 this.storage.set('signature', signature);
280 };
281 /**
282 * @param {?} secret
283 * @return {?}
284 */
285 NacoService.prototype.setClientSecret = /**
286 * @param {?} secret
287 * @return {?}
288 */
289 function (secret) {
290 this.clientSecret = secret;
291 };
292 /**
293 * @param {?} refreshToken
294 * @return {?}
295 */
296 NacoService.prototype.setRefreshToken = /**
297 * @param {?} refreshToken
298 * @return {?}
299 */
300 function (refreshToken) {
301 this.refreshToken = refreshToken;
302 this.storage.set('refresh_token', refreshToken);
303 };
304 /**
305 * @param {?=} scopes
306 * @return {?}
307 */
308 NacoService.prototype.refreshUser = /**
309 * @param {?=} scopes
310 * @return {?}
311 */
312 function (scopes) {
313 var _this = this;
314 this.setUser(null);
315 this.setSignature(null);
316 return rxjs.forkJoin(this.getRefreshToken(), this.getClientSecret()).pipe(operators.switchMap(function (results) {
317 var /** @type {?} */ refreshToken = results[0];
318 var /** @type {?} */ clientSecret = results[1];
319 if (refreshToken && clientSecret) {
320 return _this.refreshWithRefreshToken(clientSecret, refreshToken.token, scopes);
321 }
322 return _this.refreshWithSilentAuth(scopes);
323 }));
324 };
325 /**
326 * @param {?} clientSecret
327 * @param {?} refreshToken
328 * @param {?=} scopes
329 * @return {?}
330 */
331 NacoService.prototype.refreshWithRefreshToken = /**
332 * @param {?} clientSecret
333 * @param {?} refreshToken
334 * @param {?=} scopes
335 * @return {?}
336 */
337 function (clientSecret, refreshToken, scopes) {
338 var _this = this;
339 var /** @type {?} */ request = this.http.post(this.getUri('/tokens'), {
340 grant_type: 'refresh_token',
341 scopes: scopes || this.config.scopes,
342 client_id: this.config.clientId,
343 client_secret: clientSecret,
344 refresh_token: refreshToken,
345 });
346 return request.pipe(operators.tap(function (tokens$$1) {
347 if (tokens$$1 && tokens$$1.data) {
348 _this.setSignature({
349 expiresIn: tokens$$1.data.expires_in || tokens$$1.data.expiresIn,
350 type: tokens$$1.data.token_type || tokens$$1.data.tokenType,
351 token: tokens$$1.data.access_token || tokens$$1.data.accessToken,
352 scopes: decodeURIComponent(tokens$$1.data.scopes || _this.config.scopes),
353 });
354 _this.setRefreshToken({
355 type: tokens$$1.data.token_type || tokens$$1.data.tokenType,
356 token: tokens$$1.data.refresh_token || tokens$$1.data.refreshToken,
357 });
358 }
359 }), operators.map(function (tokens$$1) { return tokens$$1 && tokens$$1.data; }), operators.switchMap(function (hasToken) {
360 if (hasToken) {
361 return _this.getUser();
362 }
363 return rxjs.of(null);
364 }));
365 };
366 /**
367 * @param {?=} scopes
368 * @return {?}
369 */
370 NacoService.prototype.refreshWithSilentAuth = /**
371 * @param {?=} scopes
372 * @return {?}
373 */
374 function (scopes) {
375 var _this = this;
376 return new rxjs.Observable(function (observer) {
377 var /** @type {?} */ redirectUri = _this.getCurrentOrigin('auth/silent');
378 var /** @type {?} */ uri = _this.login(scopes || _this.config.scopes, redirectUri, true, 'token', false);
379 var /** @type {?} */ iframe = document.createElement('iframe');
380 iframe.setAttribute('src', uri);
381 iframe.style.display = 'none';
382 iframe.addEventListener('load', function () {
383 return __awaiter(_this, void 0, void 0, function () {
384 var e_1, _a, queryString, queryParts, params, queryParts_1, queryParts_1_1, item, itemParts, user, e_2;
385 return __generator(this, function (_b) {
386 switch (_b.label) {
387 case 0:
388 _b.trys.push([0, 5, , 6]);
389 queryString = iframe.contentWindow.location.search.substring(1);
390 iframe.parentNode.removeChild(iframe);
391 if (!queryString)
392 return [3 /*break*/, 4];
393 queryParts = queryString.split('&');
394 params = {};
395 try {
396 for (queryParts_1 = __values(queryParts), queryParts_1_1 = queryParts_1.next(); !queryParts_1_1.done; queryParts_1_1 = queryParts_1.next()) {
397 item = queryParts_1_1.value;
398 itemParts = item.split('=');
399 params[itemParts[0]] = itemParts[1];
400 }
401 }
402 catch (e_1_1) {
403 e_1 = { error: e_1_1 };
404 }
405 finally {
406 try {
407 if (queryParts_1_1 && !queryParts_1_1.done && (_a = queryParts_1.return))
408 _a.call(queryParts_1);
409 }
410 finally {
411 if (e_1)
412 throw e_1.error;
413 }
414 }
415 if (!params.hasOwnProperty('access_token'))
416 return [3 /*break*/, 2];
417 this.setSignature({
418 token: params['access_token'],
419 type: params['token_type'],
420 expiresIn: params['expires_in'],
421 scopes: decodeURIComponent(params['scopes'] || this.config.scopes),
422 });
423 return [4 /*yield*/, this.getUser().toPromise()];
424 case 1:
425 user = _b.sent();
426 if (user) {
427 this.setUser(user);
428 }
429 observer.next(user);
430 return [3 /*break*/, 3];
431 case 2:
432 observer.next(null);
433 _b.label = 3;
434 case 3: return [2 /*return*/];
435 case 4:
436 observer.next(null);
437 return [3 /*break*/, 6];
438 case 5:
439 e_2 = _b.sent();
440 observer.next(null);
441 return [3 /*break*/, 6];
442 case 6: return [2 /*return*/];
443 }
444 });
445 });
446 }, false);
447 document.body.appendChild(iframe);
448 });
449 };
450 /**
451 * @param {?} code
452 * @param {?} redirectUri
453 * @param {?=} scopes
454 * @return {?}
455 */
456 NacoService.prototype.getAccessTokenFromAuthCode = /**
457 * @param {?} code
458 * @param {?} redirectUri
459 * @param {?=} scopes
460 * @return {?}
461 */
462 function (code, redirectUri, scopes) {
463 var _this = this;
464 return fromPromise.fromPromise(this.getState()).pipe(operators.switchMap(function (state) {
465 var /** @type {?} */ params = {
466 code: code,
467 grant_type: 'authorization_code',
468 scopes: scopes || _this.config.scopes,
469 client_id: _this.config.clientId,
470 client_secret: _this.config.clientSecret,
471 redirect_uri: redirectUri,
472 };
473 if (state) {
474 params["state"] = state;
475 }
476 return _this.http.post(_this.getUri('/tokens'), params);
477 }), operators.map(function (res) {
478 if (res.data) {
479 return res.data;
480 }
481 throw new Error('There are no body to be transformed');
482 }));
483 };
484 /**
485 * @param {?} scopes
486 * @param {?=} redirectUri
487 * @param {?=} silent
488 * @param {?=} responseType
489 * @param {?=} needState
490 * @return {?}
491 */
492 NacoService.prototype.login = /**
493 * @param {?} scopes
494 * @param {?=} redirectUri
495 * @param {?=} silent
496 * @param {?=} responseType
497 * @param {?=} needState
498 * @return {?}
499 */
500 function (scopes, redirectUri, silent, responseType, needState) {
501 if (silent === void 0) {
502 silent = false;
503 }
504 if (responseType === void 0) {
505 responseType = 'token';
506 }
507 if (needState === void 0) {
508 needState = true;
509 }
510 if (!redirectUri) {
511 redirectUri = this.router.url;
512 }
513 var /** @type {?} */ params = {
514 response_type: responseType,
515 scopes: scopes,
516 client: this.config.clientId,
517 silent: silent,
518 continue: encodeURIComponent(redirectUri),
519 };
520 if (needState) {
521 var /** @type {?} */ state = this.generateState();
522 this.storage.set('state', state);
523 params.state = state;
524 }
525 var /** @type {?} */ query = this.buildQueryString(params);
526 return this.config.endpoint + '/auth?' + query;
527 };
528 /**
529 * @param {?=} redirectUri
530 * @return {?}
531 */
532 NacoService.prototype.logout = /**
533 * @param {?=} redirectUri
534 * @return {?}
535 */
536 function (redirectUri) {
537 var _this = this;
538 this.signature = null;
539 this.user = null;
540 this.refreshToken = null;
541 return new Promise(function (resolve) {
542 var /** @type {?} */ clear = [_this.storage.remove('signature'), _this.storage.remove('user'), _this.storage.remove('refresh_token')];
543 Promise.all(clear).then(function () {
544 var /** @type {?} */ endpoint = _this.config.endpoint + '/auth/logout';
545 if (redirectUri) {
546 endpoint += '?continue=' + encodeURIComponent(redirectUri);
547 }
548 resolve(endpoint);
549 });
550 });
551 };
552 /**
553 * @return {?}
554 */
555 NacoService.prototype.getState = /**
556 * @return {?}
557 */
558 function () {
559 return this.storage.get('state');
560 };
561 /**
562 * @param {?} route
563 * @return {?}
564 */
565 NacoService.prototype.buildNestedUri = /**
566 * @param {?} route
567 * @return {?}
568 */
569 function (route) {
570 var _this = this;
571 var /** @type {?} */ uri = '';
572 if (route.routeConfig && route.routeConfig.path) {
573 var /** @type {?} */ routePath = route.routeConfig.path;
574 for (var /** @type {?} */ key in route.params) {
575 if (key) {
576 var /** @type {?} */ re = new RegExp(':' + key);
577 routePath = routePath.replace(re, route.params[key]);
578 }
579 }
580 uri += '/' + routePath;
581 }
582 if (route.children) {
583 route.children.forEach(function (item) {
584 uri += _this.buildNestedUri(item);
585 });
586 }
587 return uri;
588 };
589 /**
590 * @return {?}
591 */
592 NacoService.prototype.getRefreshToken = /**
593 * @return {?}
594 */
595 function () {
596 if (null !== this.refreshToken) {
597 return Promise.resolve(this.refreshToken);
598 }
599 return this.storage.get('refresh_token');
600 };
601 /**
602 * @return {?}
603 */
604 NacoService.prototype.getClientSecret = /**
605 * @return {?}
606 */
607 function () {
608 if (null !== this.clientSecret) {
609 return Promise.resolve(this.clientSecret);
610 }
611 return this.storage.get('client_secret');
612 };
613 /**
614 * @param {?} path
615 * @return {?}
616 */
617 NacoService.prototype.getUri = /**
618 * @param {?} path
619 * @return {?}
620 */
621 function (path) {
622 return this.config.endpoint + '/api/' + this.VERSION + path;
623 };
624 /**
625 * @param {?=} path
626 * @return {?}
627 */
628 NacoService.prototype.getCurrentOrigin = /**
629 * @param {?=} path
630 * @return {?}
631 */
632 function (path) {
633 return window.location.origin + this.location.prepareExternalUrl(path || '');
634 };
635 /**
636 * @return {?}
637 */
638 NacoService.prototype.generateState = /**
639 * @return {?}
640 */
641 function () {
642 var /** @type {?} */ possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
643 var /** @type {?} */ text = '';
644 for (var /** @type {?} */ i = 0; i < 5; i++) {
645 text += possible.charAt(Math.floor(Math.random() * possible.length));
646 }
647 return text;
648 };
649 /**
650 * @param {?} params
651 * @return {?}
652 */
653 NacoService.prototype.buildQueryString = /**
654 * @param {?} params
655 * @return {?}
656 */
657 function (params) {
658 var /** @type {?} */ queryParams = Object.keys(params).map(function (key) {
659 return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
660 });
661 return queryParams.join('&');
662 };
663 /**
664 * @param {?} route
665 * @param {?=} responseType
666 * @return {?}
667 */
668 NacoService.prototype.goToAccountEndpoint = /**
669 * @param {?} route
670 * @param {?=} responseType
671 * @return {?}
672 */
673 function (route, responseType) {
674 var _this = this;
675 var /** @type {?} */ ltrim = function (text) { return text.replace(/^\/+/, ''); };
676 var /** @type {?} */ next = this.getCurrentOrigin('/' + ltrim(this.buildNestedUri(route.root)));
677 this.storage.set('naco_intended_url', next).then(function () {
678 _this.redirect(_this.login(_this.config.scopes, _this.getCurrentOrigin('/auth'), false, responseType || _this.config.responseType, true));
679 });
680 };
681 /**
682 * @return {?}
683 */
684 NacoService.prototype.goToIntendedUrl = /**
685 * @return {?}
686 */
687 function () {
688 var _this = this;
689 this.storage.get('naco_intended_url').then(function (url) {
690 _this.storage.remove('naco_intended_url');
691 _this.redirect(url || '/');
692 });
693 };
694 /**
695 * @param {?} url
696 * @return {?}
697 */
698 NacoService.prototype.redirect = /**
699 * @param {?} url
700 * @return {?}
701 */
702 function (url) {
703 window.location.href = url;
704 };
705 NacoService.decorators = [
706 { type: core.Injectable },
707 ];
708 /** @nocollapse */
709 NacoService.ctorParameters = function () {
710 return [
711 { type: Config },
712 { type: router.Router },
713 { type: storage.Storage },
714 { type: http.HttpClient },
715 { type: common.Location }
716 ];
717 };
718 return NacoService;
719 }());
720
721 /**
722 * @fileoverview added by tsickle
723 * @suppress {checkTypes} checked by tsc
724 */
725 var NacoExpressService = /** @class */ (function (_super) {
726 __extends(NacoExpressService, _super);
727 function NacoExpressService(config, router$$1, storage$$1, http$$1, location, request, response) {
728 var _this = _super.call(this, config, router$$1, storage$$1, http$$1, location) || this;
729 _this.request = request;
730 _this.response = response;
731 return _this;
732 }
733 /**
734 * @return {?}
735 */
736 NacoExpressService.prototype.refreshWithSilentAuth = /**
737 * @return {?}
738 */
739 function () {
740 return rxjs.of(null);
741 };
742 /**
743 * @param {?=} path
744 * @return {?}
745 */
746 NacoExpressService.prototype.getCurrentOrigin = /**
747 * @param {?=} path
748 * @return {?}
749 */
750 function (path) {
751 if (path === void 0) {
752 path = '';
753 }
754 return this.request.protocol + "://" + this.request.headers.host + this.location.prepareExternalUrl(path || '');
755 };
756 /**
757 * @param {?} url
758 * @return {?}
759 */
760 NacoExpressService.prototype.redirect = /**
761 * @param {?} url
762 * @return {?}
763 */
764 function (url) {
765 this.response.redirect(302, url);
766 this.response.end();
767 };
768 NacoExpressService.decorators = [
769 { type: core.Injectable },
770 ];
771 /** @nocollapse */
772 NacoExpressService.ctorParameters = function () {
773 return [
774 { type: Config },
775 { type: router.Router },
776 { type: storage.Storage },
777 { type: http.HttpClient },
778 { type: common.Location },
779 { type: undefined, decorators: [{ type: core.Inject, args: [tokens.REQUEST,] }] },
780 { type: undefined, decorators: [{ type: core.Inject, args: [tokens.RESPONSE,] }] }
781 ];
782 };
783 return NacoExpressService;
784 }(NacoService));
785
786 /**
787 * @fileoverview added by tsickle
788 * @suppress {checkTypes} checked by tsc
789 */
790 var Signature = /** @class */ (function () {
791 function Signature() {
792 }
793 return Signature;
794 }());
795
796 /**
797 * @fileoverview added by tsickle
798 * @suppress {checkTypes} checked by tsc
799 */
800 var AuthenticatedGuard = /** @class */ (function () {
801 function AuthenticatedGuard(naco, storage$$1, location) {
802 this.naco = naco;
803 this.storage = storage$$1;
804 this.location = location;
805 }
806 /**
807 * @param {?} route
808 * @return {?}
809 */
810 AuthenticatedGuard.prototype.canActivate = /**
811 * @param {?} route
812 * @return {?}
813 */
814 function (route) {
815 var _this = this;
816 return this.naco.getUser().pipe(operators$1.first(), operators$1.map(function (user) {
817 if (null === user) {
818 _this.naco.goToAccountEndpoint(route.root);
819 }
820 return !!user;
821 }));
822 };
823 /**
824 * @param {?} route
825 * @return {?}
826 */
827 AuthenticatedGuard.prototype.canActivateChild = /**
828 * @param {?} route
829 * @return {?}
830 */
831 function (route) {
832 return this.canActivate(route);
833 };
834 AuthenticatedGuard.decorators = [
835 { type: core.Injectable },
836 ];
837 /** @nocollapse */
838 AuthenticatedGuard.ctorParameters = function () {
839 return [
840 { type: NacoService },
841 { type: storage.Storage },
842 { type: common.Location }
843 ];
844 };
845 return AuthenticatedGuard;
846 }());
847
848 /**
849 * @fileoverview added by tsickle
850 * @suppress {checkTypes} checked by tsc
851 */
852 var AuthInterceptor = /** @class */ (function () {
853 function AuthInterceptor(naco) {
854 this.naco = naco;
855 }
856 /**
857 * @param {?} req
858 * @param {?} next
859 * @return {?}
860 */
861 AuthInterceptor.prototype.intercept = /**
862 * @param {?} req
863 * @param {?} next
864 * @return {?}
865 */
866 function (req, next) {
867 var _this = this;
868 var /** @type {?} */ needRetry = true;
869 return rxjs.from(this.naco.getSignature()).pipe(operators.switchMap(function (signature) {
870 if (!signature) {
871 needRetry = false;
872 return next.handle(req);
873 }
874 return next.handle(req.clone({
875 setHeaders: {
876 Authorization: signature.type + " " + signature.token,
877 },
878 }));
879 }), operators.retryWhen(function (error) {
880 return error.pipe(operators.switchMap(function (error) {
881 if (error.status !== 401 || !needRetry) {
882 return rxjs.throwError(error);
883 }
884 needRetry = false;
885 return _this.naco.refreshUser().pipe(operators.switchMap(function (user) {
886 if (!user) {
887 return rxjs.of(null);
888 }
889 return rxjs.throwError(error);
890 }));
891 }));
892 }));
893 };
894 AuthInterceptor.decorators = [
895 { type: core.Injectable },
896 ];
897 /** @nocollapse */
898 AuthInterceptor.ctorParameters = function () {
899 return [
900 { type: NacoService }
901 ];
902 };
903 return AuthInterceptor;
904 }());
905
906 /**
907 * @fileoverview added by tsickle
908 * @suppress {checkTypes} checked by tsc
909 */
910 var AuthPage = /** @class */ (function () {
911 function AuthPage(route, naco, storage$$1, location) {
912 this.route = route;
913 this.naco = naco;
914 this.storage = storage$$1;
915 this.location = location;
916 this.message$ = rxjs.concat(rxjs.of('Authenticating...'), this.handle());
917 }
918 /**
919 * @return {?}
920 */
921 AuthPage.prototype.handle = /**
922 * @return {?}
923 */
924 function () {
925 var _this = this;
926 return rxjs.from(this.naco.getState()).pipe(operators.switchMap(function (state) {
927 return _this.route.queryParams.pipe(operators.switchMap(function (params) {
928 if (state && params["state"] !== state) {
929 return rxjs.throwError('Invalid CSRF Token');
930 }
931 return rxjs.of(params);
932 }));
933 }), operators.switchMap(function (params) {
934 _this.naco.setUser(null);
935 if (params["access_token"]) {
936 _this.naco.setSignature({
937 expiresIn: params["expires_in"],
938 type: params["token_type"],
939 token: params["access_token"],
940 scopes: decodeURIComponent(params["scopes"]),
941 });
942 return _this.naco.getUser();
943 }
944 if (params["code"]) {
945 return _this.naco.getAccessTokenFromAuthCode(params["code"], _this.naco.getCurrentOrigin('/auth')).pipe(operators.tap(function (tokens$$1) {
946 _this.naco.setSignature({
947 expiresIn: tokens$$1.expires_in || tokens$$1.expiresIn,
948 type: tokens$$1.token_type || tokens$$1.tokenType,
949 token: tokens$$1.access_token || tokens$$1.accessToken,
950 scopes: decodeURIComponent(tokens$$1.scopes),
951 });
952 _this.naco.setRefreshToken({
953 expiresIn: tokens$$1.expires_in || tokens$$1.expiresIn,
954 type: tokens$$1.token_type || tokens$$1.tokenType,
955 token: tokens$$1.refresh_token || tokens$$1.refreshToken,
956 scopes: decodeURIComponent(tokens$$1.scopes),
957 });
958 }), operators.switchMap(function () { return _this.naco.getUser(); }));
959 }
960 return rxjs.of(null);
961 }), operators.switchMap(function (user) {
962 if (null === user) {
963 return rxjs.throwError(new Error('Unauthenticated!'));
964 }
965 _this.naco.goToIntendedUrl();
966 return rxjs.of('Success, please wait for redirecting...');
967 }), operators.catchError(function (e) {
968 return rxjs.of(e.message);
969 }));
970 };
971 AuthPage.decorators = [
972 { type: core.Component, args: [{
973 selector: 'naker-auth-page',
974 template: '{{ message$ | async }}',
975 },] },
976 ];
977 /** @nocollapse */
978 AuthPage.ctorParameters = function () {
979 return [
980 { type: router.ActivatedRoute },
981 { type: NacoService },
982 { type: storage.Storage },
983 { type: common.Location }
984 ];
985 };
986 return AuthPage;
987 }());
988
989 /**
990 * @fileoverview added by tsickle
991 * @suppress {checkTypes} checked by tsc
992 */
993 var AuthSilentPage = /** @class */ (function () {
994 function AuthSilentPage(naco) {
995 this.naco = naco;
996 }
997 /**
998 * @return {?}
999 */
1000 AuthSilentPage.prototype.ngOnInit = /**
1001 * @return {?}
1002 */
1003 function () {
1004 var _this = this;
1005 var /** @type {?} */ timeout = setTimeout(function () {
1006 clearTimeout(timeout);
1007 _this.naco.redirect('/');
1008 }, 2000);
1009 };
1010 AuthSilentPage.decorators = [
1011 { type: core.Component, args: [{
1012 selector: 'naker-auth-silent',
1013 template: 'Please wait...',
1014 },] },
1015 ];
1016 /** @nocollapse */
1017 AuthSilentPage.ctorParameters = function () {
1018 return [
1019 { type: NacoService }
1020 ];
1021 };
1022 return AuthSilentPage;
1023 }());
1024
1025 /**
1026 * @fileoverview added by tsickle
1027 * @suppress {checkTypes} checked by tsc
1028 */
1029 var /** @type {?} */ routes = [
1030 {
1031 path: 'auth',
1032 component: AuthPage
1033 },
1034 {
1035 path: 'auth/silent',
1036 component: AuthSilentPage
1037 },
1038 ];
1039 var /** @type {?} */ AUTH_ROUTING = router.RouterModule.forChild(routes);
1040
1041 /**
1042 * @fileoverview added by tsickle
1043 * @suppress {checkTypes} checked by tsc
1044 */
1045 var NacoViewModule = /** @class */ (function () {
1046 function NacoViewModule() {
1047 }
1048 NacoViewModule.decorators = [
1049 { type: core.NgModule, args: [{
1050 imports: [common.CommonModule, AUTH_ROUTING],
1051 declarations: [AuthPage, AuthSilentPage],
1052 },] },
1053 ];
1054 return NacoViewModule;
1055 }());
1056
1057 /**
1058 * @fileoverview added by tsickle
1059 * @suppress {checkTypes} checked by tsc
1060 */
1061 var /** @type {?} */ NACO_ROOT_CONFIG = new core.InjectionToken('NACO_ROOT_CONFIG');
1062 /**
1063 * @param {?} config
1064 * @return {?}
1065 */
1066 function nacoConfigFactory(config) {
1067 return new Config(config);
1068 }
1069 var NacoModule = /** @class */ (function () {
1070 function NacoModule() {
1071 }
1072 /**
1073 * @param {?} config
1074 * @return {?}
1075 */
1076 NacoModule.forRoot = /**
1077 * @param {?} config
1078 * @return {?}
1079 */
1080 function (config) {
1081 return {
1082 ngModule: NacoModule,
1083 providers: [
1084 {
1085 provide: NACO_ROOT_CONFIG,
1086 useValue: config,
1087 },
1088 {
1089 provide: Config,
1090 useFactory: nacoConfigFactory,
1091 deps: [NACO_ROOT_CONFIG],
1092 },
1093 NacoService,
1094 AuthenticatedGuard,
1095 ],
1096 };
1097 };
1098 NacoModule.decorators = [
1099 { type: core.NgModule, args: [{
1100 imports: [NacoViewModule],
1101 },] },
1102 ];
1103 return NacoModule;
1104 }());
1105
1106 /**
1107 * @fileoverview added by tsickle
1108 * @suppress {checkTypes} checked by tsc
1109 */
1110
1111 /**
1112 * @fileoverview added by tsickle
1113 * @suppress {checkTypes} checked by tsc
1114 */
1115
1116 exports.NacoService = NacoService;
1117 exports.NacoExpressService = NacoExpressService;
1118 exports.User = User;
1119 exports.Signature = Signature;
1120 exports.Config = Config;
1121 exports.AuthenticatedGuard = AuthenticatedGuard;
1122 exports.AuthInterceptor = AuthInterceptor;
1123 exports.nacoConfigFactory = nacoConfigFactory;
1124 exports.NacoModule = NacoModule;
1125 exports.ɵa = NacoViewModule;
1126 exports.ɵd = AuthSilentPage;
1127 exports.ɵc = AuthPage;
1128 exports.ɵb = AUTH_ROUTING;
1129
1130 Object.defineProperty(exports, '__esModule', { value: true });
1131
1132})));
1133
1134//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFrZXItbmFjby51bWQuanMubWFwIiwic291cmNlcyI6W251bGwsIm5nOi8vQG5ha2VyL25hY28vZG9tYWlucy92YWx1ZXMvY29uZmlnLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9kb21haW5zL21vZGVscy91c2VyLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9kb21haW5zL3NlcnZpY2VzL25hY28uc2VydmljZS50cyIsIm5nOi8vQG5ha2VyL25hY28vZG9tYWlucy9zZXJ2aWNlcy9uYWNvLmV4cHJlc3Muc2VydmljZS50cyIsIm5nOi8vQG5ha2VyL25hY28vZG9tYWlucy92YWx1ZXMvc2lnbmF0dXJlLnRzIiwibmc6Ly9AbmFrZXIvbmFjby9ndWFyZHMvYXV0aGVudGljYXRlZC5ndWFyZC50cyIsIm5nOi8vQG5ha2VyL25hY28vaW50ZXJjZXB0b3JzL2F1dGguaW50ZXJjZXB0b3IudHMiLCJuZzovL0BuYWtlci9uYWNvL3ZpZXdzL3BhZ2VzL2F1dGgucGFnZS50cyIsIm5nOi8vQG5ha2VyL25hY28vdmlld3MvcGFnZXMvYXV0aC1zaWxlbnQucGFnZS50cyIsIm5nOi8vQG5ha2VyL25hY28vdmlld3Mvcm91dGVzLnRzIiwibmc6Ly9AbmFrZXIvbmFjby92aWV3cy9tb2R1bGUudHMiLCJuZzovL0BuYWtlci9uYWNvL25hY28ubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlXHJcbnRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlXHJcbkxpY2Vuc2UgYXQgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcblxyXG5USElTIENPREUgSVMgUFJPVklERUQgT04gQU4gKkFTIElTKiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbktJTkQsIEVJVEhFUiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04gQU5ZIElNUExJRURcclxuV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIFRJVExFLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSxcclxuTUVSQ0hBTlRBQkxJVFkgT1IgTk9OLUlORlJJTkdFTUVOVC5cclxuXHJcblNlZSB0aGUgQXBhY2hlIFZlcnNpb24gMi4wIExpY2Vuc2UgZm9yIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9uc1xyXG5hbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4dGVuZHMoZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMClcclxuICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZShyZXN1bHQudmFsdWUpOyB9KS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2dlbmVyYXRvcih0aGlzQXJnLCBib2R5KSB7XHJcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnO1xyXG4gICAgcmV0dXJuIGcgPSB7IG5leHQ6IHZlcmIoMCksIFwidGhyb3dcIjogdmVyYigxKSwgXCJyZXR1cm5cIjogdmVyYigyKSB9LCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKF8pIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcclxuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBleHBvcnRzKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmICghZXhwb3J0cy5oYXNPd25Qcm9wZXJ0eShwKSkgZXhwb3J0c1twXSA9IG1bcF07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl0sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgZmluYWxseSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0KHYpIHtcclxuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0dlbmVyYXRvcih0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlmIChnW25dKSBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiByZXN1bWUobiwgdikgeyB0cnkgeyBzdGVwKGdbbl0odikpOyB9IGNhdGNoIChlKSB7IHNldHRsZShxWzBdWzNdLCBlKTsgfSB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKHIpIHsgci52YWx1ZSBpbnN0YW5jZW9mIF9fYXdhaXQgPyBQcm9taXNlLnJlc29sdmUoci52YWx1ZS52KS50aGVuKGZ1bGZpbGwsIHJlamVjdCkgOiBzZXR0bGUocVswXVsyXSwgcik7IH1cclxuICAgIGZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHsgcmVzdW1lKFwibmV4dFwiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHJlamVjdCh2YWx1ZSkgeyByZXN1bWUoXCJ0aHJvd1wiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShmLCB2KSB7IGlmIChmKHYpLCBxLnNoaWZ0KCksIHEubGVuZ3RoKSByZXN1bWUocVswXVswXSwgcVswXVsxXSk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNEZWxlZ2F0b3Iobykge1xyXG4gICAgdmFyIGksIHA7XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIsIGZ1bmN0aW9uIChlKSB7IHRocm93IGU7IH0pLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuLCBmKSB7IGlbbl0gPSBvW25dID8gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIChwID0gIXApID8geyB2YWx1ZTogX19hd2FpdChvW25dKHYpKSwgZG9uZTogbiA9PT0gXCJyZXR1cm5cIiB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcclxuICAgIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XHJcbiAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxyXG4gICAgcmV0dXJuIGNvb2tlZDtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIHJlc3VsdFtrXSA9IG1vZFtrXTtcclxuICAgIHJlc3VsdC5kZWZhdWx0ID0gbW9kO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuIiwiZXhwb3J0IGNsYXNzIENvbmZpZyB7XG4gICAgcHVibGljIGVuZHBvaW50Pzogc3RyaW5nID0gJ2h0dHBzOi8vYWNjb3VudC5rZW1uYWtlci5nby5pZCc7XG4gICAgcHVibGljIGNsaWVudElkPzogc3RyaW5nO1xuICAgIHB1YmxpYyBjbGllbnRTZWNyZXQ/OiBzdHJpbmc7XG4gICAgcHVibGljIHNjb3Blcz86IHN0cmluZyA9ICdiYXNpYyBlbWFpbCc7XG4gICAgcHVibGljIHJlc3BvbnNlVHlwZT86ICd0b2tlbicgfCAnY29kZScgPSAndG9rZW4nO1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKGRhdGE/OiBQYXJ0aWFsPENvbmZpZz4pIHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLCBkYXRhKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBmb3J3YXJkUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBUeXBlIH0gZnJvbSAnY2xhc3MtdHJhbnNmb3JtZXInO1xuXG5leHBvcnQgY2xhc3MgVXNlciB7XG4gICAgcHVibGljIGlkOiBzdHJpbmc7XG4gICAgcHVibGljIHVzZXJuYW1lOiBzdHJpbmc7XG4gICAgcHVibGljIGVtYWlsPzogc3RyaW5nO1xuICAgIHB1YmxpYyBuYW1lOiBzdHJpbmc7XG4gICAgcHVibGljIHN0YXR1czogbnVtYmVyO1xuXG4gICAgQFR5cGUoZm9yd2FyZFJlZigoKSA9PiBEYXRlKSBhcyBhbnkpXG4gICAgcHVibGljIHVwZGF0ZWRBdDogRGF0ZTtcbn1cbiIsImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlU25hcHNob3QsIFBhcmFtcywgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFN0b3JhZ2UgfSBmcm9tICdAdWJ1ZC9zdG9yYWdlJztcbmltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4uL3ZhbHVlcy9jb25maWcnO1xuaW1wb3J0IHsgVXNlciB9IGZyb20gJy4uL21vZGVscy91c2VyJztcbmltcG9ydCB7IGZvcmtKb2luLCBmcm9tLCBPYnNlcnZhYmxlLCBPYnNlcnZlciwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFNpZ25hdHVyZSB9IGZyb20gJy4uL3ZhbHVlcy9zaWduYXR1cmUnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgbWFwLCBzd2l0Y2hNYXAsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IHBsYWluVG9DbGFzcyB9IGZyb20gJ2NsYXNzLXRyYW5zZm9ybWVyJztcbmltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBFcnJvclJlc3BvbnNlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgTG9jYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgZnJvbVByb21pc2UgfSBmcm9tICdyeGpzLWNvbXBhdC9vYnNlcnZhYmxlL2Zyb21Qcm9taXNlJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5hY29TZXJ2aWNlIHtcbiAgICBwdWJsaWMgcmVhZG9ubHkgVkVSU0lPTiA9ICd2MSc7XG5cbiAgICBwcml2YXRlIHNpZ25hdHVyZTogU2lnbmF0dXJlIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSB1c2VyOiBVc2VyIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSByZWZyZXNoVG9rZW46IFNpZ25hdHVyZSB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgY2xpZW50U2VjcmV0OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJvdGVjdGVkIGNvbmZpZzogQ29uZmlnLFxuICAgICAgICBwcm90ZWN0ZWQgcm91dGVyOiBSb3V0ZXIsXG4gICAgICAgIHByb3RlY3RlZCBzdG9yYWdlOiBTdG9yYWdlLFxuICAgICAgICBwcm90ZWN0ZWQgaHR0cDogSHR0cENsaWVudCxcbiAgICAgICAgcHJvdGVjdGVkIGxvY2F0aW9uOiBMb2NhdGlvbixcbiAgICApIHtcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLmNsaWVudFNlY3JldCkge1xuICAgICAgICAgICAgdGhpcy5zZXRDbGllbnRTZWNyZXQodGhpcy5jb25maWcuY2xpZW50U2VjcmV0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzZXRVc2VyKHVzZXI6IFVzZXIgfCBudWxsKTogdm9pZCB7XG4gICAgICAgIHRoaXMudXNlciA9IHVzZXI7XG4gICAgfVxuXG4gICAgcHVibGljIGdldFVzZXIoKTogT2JzZXJ2YWJsZTxVc2VyIHwgbnVsbD4ge1xuICAgICAgICBpZiAobnVsbCAhPT0gdGhpcy51c2VyKSB7XG4gICAgICAgICAgICByZXR1cm4gb2YodGhpcy51c2VyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHVyaSA9IHRoaXMuZ2V0VXJpKCcvdXNlcnMvbWUnKTtcblxuICAgICAgICByZXR1cm4gZnJvbSh0aGlzLmdldFNpZ25hdHVyZSgpKS5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKChzaWduYXR1cmU6IFNpZ25hdHVyZSB8IG51bGwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXNpZ25hdHVyZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZWZyZXNoVXNlcih0aGlzLmNvbmZpZy5zY29wZXMpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEF1dGhvcml6YXRpb246IGAke3NpZ25hdHVyZS50eXBlfSAke3NpZ25hdHVyZS50b2tlbn1gLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5odHRwLmdldDxhbnk+KHVyaSwgb3B0aW9ucykucGlwZShcbiAgICAgICAgICAgICAgICAgICAgbWFwKChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcy5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5kYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZXJlIGFyZSBubyBib2R5IHRvIGJlIHRyYW5zZm9ybWVkJyk7XG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICBtYXAoKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXV0aFVzZXI6IGFueSA9IHBsYWluVG9DbGFzcyhVc2VyLCBkYXRhKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRVc2VyKGF1dGhVc2VyKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF1dGhVc2VyO1xuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgY2F0Y2hFcnJvcigoZTogSHR0cEVycm9yUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICg0MDEgPT09IGUuc3RhdHVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaFVzZXIoc2lnbmF0dXJlLnNjb3Blcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRQcm9maWxlUGljdHVyZSh1c2VyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuZW5kcG9pbnQgKyAnL3VzZXJzLycgKyB1c2VyICsgJy9waWN0dXJlJztcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0U2lnbmF0dXJlKCk6IFByb21pc2U8U2lnbmF0dXJlIHwgbnVsbD4ge1xuICAgICAgICBpZiAodGhpcy5zaWduYXR1cmUpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5zaWduYXR1cmUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZS5nZXQoJ3NpZ25hdHVyZScpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRTaWduYXR1cmUoc2lnbmF0dXJlOiBTaWduYXR1cmUgfCBudWxsKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2lnbmF0dXJlID0gc2lnbmF0dXJlO1xuXG4gICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ3NpZ25hdHVyZScsIHNpZ25hdHVyZSk7XG4gICAgfVxuXG4gICAgcHVibGljIHNldENsaWVudFNlY3JldChzZWNyZXQ6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0aGlzLmNsaWVudFNlY3JldCA9IHNlY3JldDtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0UmVmcmVzaFRva2VuKHJlZnJlc2hUb2tlbjogU2lnbmF0dXJlKTogdm9pZCB7XG4gICAgICAgIHRoaXMucmVmcmVzaFRva2VuID0gcmVmcmVzaFRva2VuO1xuICAgICAgICB0aGlzLnN0b3JhZ2Uuc2V0KCdyZWZyZXNoX3Rva2VuJywgcmVmcmVzaFRva2VuKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVmcmVzaFVzZXIoc2NvcGVzPzogc3RyaW5nKTogT2JzZXJ2YWJsZTxVc2VyIHwgbnVsbD4ge1xuICAgICAgICB0aGlzLnNldFVzZXIobnVsbCk7XG4gICAgICAgIHRoaXMuc2V0U2lnbmF0dXJlKG51bGwpO1xuXG4gICAgICAgIHJldHVybiBmb3JrSm9pbih0aGlzLmdldFJlZnJlc2hUb2tlbigpLCB0aGlzLmdldENsaWVudFNlY3JldCgpKS5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKChyZXN1bHRzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByZWZyZXNoVG9rZW46IFNpZ25hdHVyZSA9IHJlc3VsdHNbMF07XG4gICAgICAgICAgICAgICAgY29uc3QgY2xpZW50U2VjcmV0OiBzdHJpbmcgPSByZXN1bHRzWzFdO1xuXG4gICAgICAgICAgICAgICAgaWYgKHJlZnJlc2hUb2tlbiAmJiBjbGllbnRTZWNyZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaFdpdGhSZWZyZXNoVG9rZW4oY2xpZW50U2VjcmV0LCByZWZyZXNoVG9rZW4udG9rZW4sIHNjb3Blcyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaFdpdGhTaWxlbnRBdXRoKHNjb3Blcyk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVmcmVzaFdpdGhSZWZyZXNoVG9rZW4oY2xpZW50U2VjcmV0OiBzdHJpbmcsIHJlZnJlc2hUb2tlbjogc3RyaW5nLCBzY29wZXM/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPFVzZXIgfCBudWxsPiB7XG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSB0aGlzLmh0dHAucG9zdCh0aGlzLmdldFVyaSgnL3Rva2VucycpLCB7XG4gICAgICAgICAgICBncmFudF90eXBlOiAncmVmcmVzaF90b2tlbicsXG4gICAgICAgICAgICBzY29wZXM6IHNjb3BlcyB8fCB0aGlzLmNvbmZpZy5zY29wZXMsXG4gICAgICAgICAgICBjbGllbnRfaWQ6IHRoaXMuY29uZmlnLmNsaWVudElkLFxuICAgICAgICAgICAgY2xpZW50X3NlY3JldDogY2xpZW50U2VjcmV0LFxuICAgICAgICAgICAgcmVmcmVzaF90b2tlbjogcmVmcmVzaFRva2VuLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcmVxdWVzdC5waXBlKFxuICAgICAgICAgICAgdGFwKCh0b2tlbnM6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0b2tlbnMgJiYgdG9rZW5zLmRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRTaWduYXR1cmUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgZXhwaXJlc0luOiB0b2tlbnMuZGF0YS5leHBpcmVzX2luIHx8IHRva2Vucy5kYXRhLmV4cGlyZXNJbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IHRva2Vucy5kYXRhLnRva2VuX3R5cGUgfHwgdG9rZW5zLmRhdGEudG9rZW5UeXBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW46IHRva2Vucy5kYXRhLmFjY2Vzc190b2tlbiB8fCB0b2tlbnMuZGF0YS5hY2Nlc3NUb2tlbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjb3BlczogZGVjb2RlVVJJQ29tcG9uZW50KHRva2Vucy5kYXRhLnNjb3BlcyB8fCB0aGlzLmNvbmZpZy5zY29wZXMpLFxuICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFJlZnJlc2hUb2tlbih7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiB0b2tlbnMuZGF0YS50b2tlbl90eXBlIHx8IHRva2Vucy5kYXRhLnRva2VuVHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuOiB0b2tlbnMuZGF0YS5yZWZyZXNoX3Rva2VuIHx8IHRva2Vucy5kYXRhLnJlZnJlc2hUb2tlbixcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBtYXAoKHRva2VuczogYW55KSA9PiB0b2tlbnMgJiYgdG9rZW5zLmRhdGEpLFxuICAgICAgICAgICAgc3dpdGNoTWFwKChoYXNUb2tlbjogYm9vbGVhbikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChoYXNUb2tlbikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRVc2VyKCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9mKG51bGwpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlZnJlc2hXaXRoU2lsZW50QXV0aChzY29wZXM/OiBzdHJpbmcpOiBPYnNlcnZhYmxlPFVzZXIgfCBudWxsPiB7XG4gICAgICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZTxVc2VyIHwgbnVsbD4oKG9ic2VydmVyOiBPYnNlcnZlcjxVc2VyIHwgbnVsbD4pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlZGlyZWN0VXJpID0gdGhpcy5nZXRDdXJyZW50T3JpZ2luKCdhdXRoL3NpbGVudCcpO1xuICAgICAgICAgICAgY29uc3QgdXJpID0gdGhpcy5sb2dpbihzY29wZXMgfHwgdGhpcy5jb25maWcuc2NvcGVzLCByZWRpcmVjdFVyaSwgdHJ1ZSwgJ3Rva2VuJywgZmFsc2UpO1xuXG4gICAgICAgICAgICBjb25zdCBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICAgICAgICAgIGlmcmFtZS5zZXRBdHRyaWJ1dGUoJ3NyYycsIHVyaSk7XG4gICAgICAgICAgICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcblxuICAgICAgICAgICAgaWZyYW1lLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgJ2xvYWQnLFxuICAgICAgICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHF1ZXJ5U3RyaW5nID0gaWZyYW1lLmNvbnRlbnRXaW5kb3cubG9jYXRpb24uc2VhcmNoLnN1YnN0cmluZygxKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWZyYW1lLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHF1ZXJ5U3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJ0cyA9IHF1ZXJ5U3RyaW5nLnNwbGl0KCcmJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFyYW1zID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgcXVlcnlQYXJ0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpdGVtUGFydHMgPSBpdGVtLnNwbGl0KCc9Jyk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zW2l0ZW1QYXJ0c1swXV0gPSBpdGVtUGFydHNbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmFtcy5oYXNPd25Qcm9wZXJ0eSgnYWNjZXNzX3Rva2VuJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRTaWduYXR1cmUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW46IHBhcmFtc1snYWNjZXNzX3Rva2VuJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBwYXJhbXNbJ3Rva2VuX3R5cGUnXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGlyZXNJbjogcGFyYW1zWydleHBpcmVzX2luJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY29wZXM6IGRlY29kZVVSSUNvbXBvbmVudChwYXJhbXNbJ3Njb3BlcyddIHx8IHRoaXMuY29uZmlnLnNjb3BlcyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLmdldFVzZXIoKS50b1Byb21pc2UoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRVc2VyKHVzZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dCh1c2VyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KG51bGwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGlmcmFtZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRBY2Nlc3NUb2tlbkZyb21BdXRoQ29kZShjb2RlOiBzdHJpbmcsIHJlZGlyZWN0VXJpOiBzdHJpbmcsIHNjb3Blcz86IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgICAgIHJldHVybiBmcm9tUHJvbWlzZSh0aGlzLmdldFN0YXRlKCkpLnBpcGUoXG4gICAgICAgICAgICBzd2l0Y2hNYXAoKHN0YXRlPzogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyYW1zOiBQYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNvZGUsXG4gICAgICAgICAgICAgICAgICAgIGdyYW50X3R5cGU6ICdhdXRob3JpemF0aW9uX2NvZGUnLFxuICAgICAgICAgICAgICAgICAgICBzY29wZXM6IHNjb3BlcyB8fCB0aGlzLmNvbmZpZy5zY29wZXMsXG4gICAgICAgICAgICAgICAgICAgIGNsaWVudF9pZDogdGhpcy5jb25maWcuY2xpZW50SWQsXG4gICAgICAgICAgICAgICAgICAgIGNsaWVudF9zZWNyZXQ6IHRoaXMuY29uZmlnLmNsaWVudFNlY3JldCxcbiAgICAgICAgICAgICAgICAgICAgcmVkaXJlY3RfdXJpOiByZWRpcmVjdFVyaSxcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmFtcy5zdGF0ZSA9IHN0YXRlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmh0dHAucG9zdCh0aGlzLmdldFVyaSgnL3Rva2VucycpLCBwYXJhbXMpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBtYXAoKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHJlcy5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXMuZGF0YTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZXJlIGFyZSBubyBib2R5IHRvIGJlIHRyYW5zZm9ybWVkJyk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbG9naW4oXG4gICAgICAgIHNjb3Blczogc3RyaW5nLFxuICAgICAgICByZWRpcmVjdFVyaT86IHN0cmluZyxcbiAgICAgICAgc2lsZW50OiBib29sZWFuID0gZmFsc2UsXG4gICAgICAgIHJlc3BvbnNlVHlwZTogJ3Rva2VuJyB8ICdjb2RlJyA9ICd0b2tlbicsXG4gICAgICAgIG5lZWRTdGF0ZTogYm9vbGVhbiA9IHRydWUsXG4gICAgKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKCFyZWRpcmVjdFVyaSkge1xuICAgICAgICAgICAgcmVkaXJlY3RVcmkgPSB0aGlzLnJvdXRlci51cmw7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYXJhbXM6IGFueSA9IHtcbiAgICAgICAgICAgIHJlc3BvbnNlX3R5cGU6IHJlc3BvbnNlVHlwZSxcbiAgICAgICAgICAgIHNjb3Blczogc2NvcGVzLFxuICAgICAgICAgICAgY2xpZW50OiB0aGlzLmNvbmZpZy5jbGllbnRJZCxcbiAgICAgICAgICAgIHNpbGVudDogc2lsZW50LFxuICAgICAgICAgICAgY29udGludWU6IGVuY29kZVVSSUNvbXBvbmVudChyZWRpcmVjdFVyaSksXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG5lZWRTdGF0ZSkge1xuICAgICAgICAgICAgY29uc3Qgc3RhdGUgPSB0aGlzLmdlbmVyYXRlU3RhdGUoKTtcblxuICAgICAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgnc3RhdGUnLCBzdGF0ZSk7XG4gICAgICAgICAgICBwYXJhbXMuc3RhdGUgPSBzdGF0ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHF1ZXJ5OiBzdHJpbmcgPSB0aGlzLmJ1aWxkUXVlcnlTdHJpbmcocGFyYW1zKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuZW5kcG9pbnQgKyAnL2F1dGg/JyArIHF1ZXJ5O1xuICAgIH1cblxuICAgIHB1YmxpYyBsb2dvdXQocmVkaXJlY3RVcmk/OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICB0aGlzLnNpZ25hdHVyZSA9IG51bGw7XG4gICAgICAgIHRoaXMudXNlciA9IG51bGw7XG4gICAgICAgIHRoaXMucmVmcmVzaFRva2VuID0gbnVsbDtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjbGVhciA9IFt0aGlzLnN0b3JhZ2UucmVtb3ZlKCdzaWduYXR1cmUnKSwgdGhpcy5zdG9yYWdlLnJlbW92ZSgndXNlcicpLCB0aGlzLnN0b3JhZ2UucmVtb3ZlKCdyZWZyZXNoX3Rva2VuJyldO1xuXG4gICAgICAgICAgICBQcm9taXNlLmFsbChjbGVhcikudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IGVuZHBvaW50ID0gdGhpcy5jb25maWcuZW5kcG9pbnQgKyAnL2F1dGgvbG9nb3V0JztcblxuICAgICAgICAgICAgICAgIGlmIChyZWRpcmVjdFVyaSkge1xuICAgICAgICAgICAgICAgICAgICBlbmRwb2ludCArPSAnP2NvbnRpbnVlPScgKyBlbmNvZGVVUklDb21wb25lbnQocmVkaXJlY3RVcmkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJlc29sdmUoZW5kcG9pbnQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRTdGF0ZSgpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZS5nZXQoJ3N0YXRlJyk7XG4gICAgfVxuXG4gICAgcHVibGljIGJ1aWxkTmVzdGVkVXJpKHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90KTogc3RyaW5nIHtcbiAgICAgICAgbGV0IHVyaSA9ICcnO1xuXG4gICAgICAgIGlmIChyb3V0ZS5yb3V0ZUNvbmZpZyAmJiByb3V0ZS5yb3V0ZUNvbmZpZy5wYXRoKSB7XG4gICAgICAgICAgICBsZXQgcm91dGVQYXRoID0gcm91dGUucm91dGVDb25maWcucGF0aDtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gcm91dGUucGFyYW1zKSB7XG4gICAgICAgICAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZSA9IG5ldyBSZWdFeHAoJzonICsga2V5KTtcblxuICAgICAgICAgICAgICAgICAgICByb3V0ZVBhdGggPSByb3V0ZVBhdGgucmVwbGFjZShyZSwgcm91dGUucGFyYW1zW2tleV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdXJpICs9ICcvJyArIHJvdXRlUGF0aDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyb3V0ZS5jaGlsZHJlbikge1xuICAgICAgICAgICAgcm91dGUuY2hpbGRyZW4uZm9yRWFjaCgoaXRlbTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCkgPT4ge1xuICAgICAgICAgICAgICAgIHVyaSArPSB0aGlzLmJ1aWxkTmVzdGVkVXJpKGl0ZW0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdXJpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0UmVmcmVzaFRva2VuKCk6IFByb21pc2U8U2lnbmF0dXJlIHwgbnVsbD4ge1xuICAgICAgICBpZiAobnVsbCAhPT0gdGhpcy5yZWZyZXNoVG9rZW4pIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5yZWZyZXNoVG9rZW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmFnZS5nZXQoJ3JlZnJlc2hfdG9rZW4nKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENsaWVudFNlY3JldCgpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICAgICAgaWYgKG51bGwgIT09IHRoaXMuY2xpZW50U2VjcmV0KSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuY2xpZW50U2VjcmV0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZ2V0KCdjbGllbnRfc2VjcmV0Jyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRVcmkocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmVuZHBvaW50ICsgJy9hcGkvJyArIHRoaXMuVkVSU0lPTiArIHBhdGg7XG4gICAgfVxuXG4gICAgcHVibGljIGdldEN1cnJlbnRPcmlnaW4ocGF0aD86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB3aW5kb3cubG9jYXRpb24ub3JpZ2luICsgdGhpcy5sb2NhdGlvbi5wcmVwYXJlRXh0ZXJuYWxVcmwocGF0aCB8fCAnJyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZW5lcmF0ZVN0YXRlKCk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IHBvc3NpYmxlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5JztcbiAgICAgICAgbGV0IHRleHQgPSAnJztcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDU7IGkrKykge1xuICAgICAgICAgICAgdGV4dCArPSBwb3NzaWJsZS5jaGFyQXQoTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogcG9zc2libGUubGVuZ3RoKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGV4dDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGJ1aWxkUXVlcnlTdHJpbmcocGFyYW1zOiBvYmplY3QpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBxdWVyeVBhcmFtcyA9IE9iamVjdC5rZXlzKHBhcmFtcykubWFwKChrZXk6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChrZXkpICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHBhcmFtc1trZXldKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHF1ZXJ5UGFyYW1zLmpvaW4oJyYnKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ29Ub0FjY291bnRFbmRwb2ludChyb3V0ZTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCwgcmVzcG9uc2VUeXBlPzogJ3Rva2VuJyB8ICdjb2RlJyk6IHZvaWQge1xuICAgICAgICBjb25zdCBsdHJpbSA9IHRleHQgPT4gdGV4dC5yZXBsYWNlKC9eXFwvKy8sICcnKTtcblxuICAgICAgICBjb25zdCBuZXh0ID0gdGhpcy5nZXRDdXJyZW50T3JpZ2luKCcvJyArIGx0cmltKHRoaXMuYnVpbGROZXN0ZWRVcmkocm91dGUucm9vdCkpKTtcblxuICAgICAgICB0aGlzLnN0b3JhZ2Uuc2V0KCduYWNvX2ludGVuZGVkX3VybCcsIG5leHQpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZWRpcmVjdChcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2luKHRoaXMuY29uZmlnLnNjb3BlcywgdGhpcy5nZXRDdXJyZW50T3JpZ2luKCcvYXV0aCcpLCBmYWxzZSwgcmVzcG9uc2VUeXBlIHx8IHRoaXMuY29uZmlnLnJlc3BvbnNlVHlwZSwgdHJ1ZSksXG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ29Ub0ludGVuZGVkVXJsKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnN0b3JhZ2UuZ2V0PHN0cmluZz4oJ25hY29faW50ZW5kZWRfdXJsJykudGhlbih1cmwgPT4ge1xuICAgICAgICAgICAgdGhpcy5zdG9yYWdlLnJlbW92ZSgnbmFjb19pbnRlbmRlZF91cmwnKTtcbiAgICAgICAgICAgIHRoaXMucmVkaXJlY3QodXJsIHx8ICcvJyk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyByZWRpcmVjdCh1cmw6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHVybDtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBTdG9yYWdlIH0gZnJvbSAnQHVidWQvc3RvcmFnZSc7XG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuLi92YWx1ZXMvY29uZmlnJztcbmltcG9ydCB7IFVzZXIgfSBmcm9tICcuLi9tb2RlbHMvdXNlcic7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IExvY2F0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IFJFUVVFU1QsIFJFU1BPTlNFIH0gZnJvbSAnQG5ndW5pdmVyc2FsL2V4cHJlc3MtZW5naW5lL3Rva2Vucyc7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4vbmFjby5zZXJ2aWNlJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5hY29FeHByZXNzU2VydmljZSBleHRlbmRzIE5hY29TZXJ2aWNlIHtcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgICAgIGNvbmZpZzogQ29uZmlnLFxuICAgICAgICByb3V0ZXI6IFJvdXRlcixcbiAgICAgICAgc3RvcmFnZTogU3RvcmFnZSxcbiAgICAgICAgaHR0cDogSHR0cENsaWVudCxcbiAgICAgICAgbG9jYXRpb246IExvY2F0aW9uLFxuICAgICAgICBASW5qZWN0KFJFUVVFU1QpIHByaXZhdGUgcmVxdWVzdDogYW55LFxuICAgICAgICBASW5qZWN0KFJFU1BPTlNFKSBwcml2YXRlIHJlc3BvbnNlOiBhbnksXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGNvbmZpZywgcm91dGVyLCBzdG9yYWdlLCBodHRwLCBsb2NhdGlvbik7XG4gICAgfVxuXG4gICAgcHVibGljIHJlZnJlc2hXaXRoU2lsZW50QXV0aCgpOiBPYnNlcnZhYmxlPFVzZXIgfCBudWxsPiB7XG4gICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0Q3VycmVudE9yaWdpbihwYXRoOiBzdHJpbmcgPSAnJyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBgJHt0aGlzLnJlcXVlc3QucHJvdG9jb2x9Oi8vJHt0aGlzLnJlcXVlc3QuaGVhZGVycy5ob3N0fSR7dGhpcy5sb2NhdGlvbi5wcmVwYXJlRXh0ZXJuYWxVcmwocGF0aCB8fCAnJyl9YDtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVkaXJlY3QodXJsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5yZXNwb25zZS5yZWRpcmVjdCgzMDIsIHVybCk7XG4gICAgICAgIHRoaXMucmVzcG9uc2UuZW5kKCk7XG4gICAgfVxufVxuIiwiZXhwb3J0IGNsYXNzIFNpZ25hdHVyZSB7XG4gICAgcHVibGljIGV4cGlyZXNJbj86IG51bWJlcjtcbiAgICBwdWJsaWMgdG9rZW46IHN0cmluZztcbiAgICBwdWJsaWMgdHlwZTogc3RyaW5nO1xuICAgIHB1YmxpYyBzY29wZXM/OiBzdHJpbmc7XG59XG4iLCJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90LCBDYW5BY3RpdmF0ZSwgQ2FuQWN0aXZhdGVDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4uL2RvbWFpbnMvc2VydmljZXMvbmFjby5zZXJ2aWNlJztcbmltcG9ydCB7IGZpcnN0LCBtYXAgfSBmcm9tICdyeGpzL2ludGVybmFsL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBVc2VyIH0gZnJvbSAnLi4vZG9tYWlucy9tb2RlbHMvdXNlcic7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBTdG9yYWdlIH0gZnJvbSAnQHVidWQvc3RvcmFnZSc7XG5pbXBvcnQgeyBMb2NhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBBdXRoZW50aWNhdGVkR3VhcmQgaW1wbGVtZW50cyBDYW5BY3RpdmF0ZSwgQ2FuQWN0aXZhdGVDaGlsZCB7XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgbmFjbzogTmFjb1NlcnZpY2UsIHByaXZhdGUgc3RvcmFnZTogU3RvcmFnZSwgcHJpdmF0ZSBsb2NhdGlvbjogTG9jYXRpb24pIHt9XG5cbiAgICBwdWJsaWMgY2FuQWN0aXZhdGUocm91dGU6IEFjdGl2YXRlZFJvdXRlU25hcHNob3QpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMubmFjby5nZXRVc2VyKCkucGlwZShcbiAgICAgICAgICAgIGZpcnN0KCksXG4gICAgICAgICAgICBtYXAoKHVzZXI6IFVzZXIgfCBudWxsKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG51bGwgPT09IHVzZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5uYWNvLmdvVG9BY2NvdW50RW5kcG9pbnQocm91dGUucm9vdCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuICEhdXNlcjtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBjYW5BY3RpdmF0ZUNoaWxkKHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90KTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhbkFjdGl2YXRlKHJvdXRlKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBIdHRwRXJyb3JSZXNwb25zZSwgSHR0cEV2ZW50LCBIdHRwSGFuZGxlciwgSHR0cEludGVyY2VwdG9yLCBIdHRwUmVxdWVzdCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IGZyb20sIE9ic2VydmFibGUsIG9mLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBOYWNvU2VydmljZSB9IGZyb20gJy4uL2RvbWFpbnMvc2VydmljZXMvbmFjby5zZXJ2aWNlJztcbmltcG9ydCB7IFNpZ25hdHVyZSB9IGZyb20gJy4uL2RvbWFpbnMvdmFsdWVzL3NpZ25hdHVyZSc7XG5pbXBvcnQgeyByZXRyeVdoZW4sIHN3aXRjaE1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEF1dGhJbnRlcmNlcHRvciBpbXBsZW1lbnRzIEh0dHBJbnRlcmNlcHRvciB7XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgbmFjbzogTmFjb1NlcnZpY2UpIHt9XG5cbiAgICBwdWJsaWMgaW50ZXJjZXB0KHJlcTogSHR0cFJlcXVlc3Q8YW55PiwgbmV4dDogSHR0cEhhbmRsZXIpOiBPYnNlcnZhYmxlPEh0dHBFdmVudDxhbnk+PiB7XG4gICAgICAgIGxldCBuZWVkUmV0cnk6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgICAgIHJldHVybiBmcm9tKHRoaXMubmFjby5nZXRTaWduYXR1cmUoKSkucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcCgoc2lnbmF0dXJlOiBTaWduYXR1cmUgfCBudWxsKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFzaWduYXR1cmUpIHtcbiAgICAgICAgICAgICAgICAgICAgbmVlZFJldHJ5ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXh0LmhhbmRsZShyZXEpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBuZXh0LmhhbmRsZShcbiAgICAgICAgICAgICAgICAgICAgcmVxLmNsb25lKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldEhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdXRob3JpemF0aW9uOiBgJHtzaWduYXR1cmUudHlwZX0gJHtzaWduYXR1cmUudG9rZW59YCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHJldHJ5V2hlbigoZXJyb3I6IE9ic2VydmFibGU8SHR0cEVycm9yUmVzcG9uc2U+KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoZXJyb3I6IEh0dHBFcnJvclJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3Iuc3RhdHVzICE9PSA0MDEgfHwgIW5lZWRSZXRyeSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgbmVlZFJldHJ5ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uYWNvLnJlZnJlc2hVc2VyKCkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2hNYXAoKHVzZXI6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXVzZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBQYXJhbXMgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgTmFjb1NlcnZpY2UgfSBmcm9tICcuLi8uLi9kb21haW5zL3NlcnZpY2VzL25hY28uc2VydmljZSc7XG5pbXBvcnQgeyBTdG9yYWdlIH0gZnJvbSAnQHVidWQvc3RvcmFnZSc7XG5pbXBvcnQgeyBjb25jYXQsIGZyb20sIE9ic2VydmFibGUsIG9mLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBzd2l0Y2hNYXAsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IExvY2F0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICduYWtlci1hdXRoLXBhZ2UnLFxuICAgIHRlbXBsYXRlOiAne3sgbWVzc2FnZSQgfCBhc3luYyB9fScsXG59KVxuZXhwb3J0IGNsYXNzIEF1dGhQYWdlIHtcbiAgICBwdWJsaWMgbWVzc2FnZSQ6IE9ic2VydmFibGU8c3RyaW5nPjtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSwgcHJpdmF0ZSBuYWNvOiBOYWNvU2VydmljZSwgcHJpdmF0ZSBzdG9yYWdlOiBTdG9yYWdlLCBwcml2YXRlIGxvY2F0aW9uOiBMb2NhdGlvbikge1xuICAgICAgICB0aGlzLm1lc3NhZ2UkID0gY29uY2F0KG9mKCdBdXRoZW50aWNhdGluZy4uLicpLCB0aGlzLmhhbmRsZSgpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaGFuZGxlKCk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBmcm9tKHRoaXMubmFjby5nZXRTdGF0ZSgpKS5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKHN0YXRlID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yb3V0ZS5xdWVyeVBhcmFtcy5waXBlKFxuICAgICAgICAgICAgICAgICAgICBzd2l0Y2hNYXAocGFyYW1zID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0ZSAmJiBwYXJhbXMuc3RhdGUgIT09IHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoJ0ludmFsaWQgQ1NSRiBUb2tlbicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YocGFyYW1zKTtcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgc3dpdGNoTWFwKChwYXJhbXM6IFBhcmFtcykgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubmFjby5zZXRVc2VyKG51bGwpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBhcmFtcy5hY2Nlc3NfdG9rZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5uYWNvLnNldFNpZ25hdHVyZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHBpcmVzSW46IHBhcmFtcy5leHBpcmVzX2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogcGFyYW1zLnRva2VuX3R5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICB0b2tlbjogcGFyYW1zLmFjY2Vzc190b2tlbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjb3BlczogZGVjb2RlVVJJQ29tcG9uZW50KHBhcmFtcy5zY29wZXMpLFxuICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uYWNvLmdldFVzZXIoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAocGFyYW1zLmNvZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmFjby5nZXRBY2Nlc3NUb2tlbkZyb21BdXRoQ29kZShwYXJhbXMuY29kZSwgdGhpcy5uYWNvLmdldEN1cnJlbnRPcmlnaW4oJy9hdXRoJykpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXAoKHRva2VuczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5uYWNvLnNldFNpZ25hdHVyZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGlyZXNJbjogdG9rZW5zLmV4cGlyZXNfaW4gfHwgdG9rZW5zLmV4cGlyZXNJbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogdG9rZW5zLnRva2VuX3R5cGUgfHwgdG9rZW5zLnRva2VuVHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW46IHRva2Vucy5hY2Nlc3NfdG9rZW4gfHwgdG9rZW5zLmFjY2Vzc1Rva2VuLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY29wZXM6IGRlY29kZVVSSUNvbXBvbmVudCh0b2tlbnMuc2NvcGVzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmFjby5zZXRSZWZyZXNoVG9rZW4oe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBpcmVzSW46IHRva2Vucy5leHBpcmVzX2luIHx8IHRva2Vucy5leHBpcmVzSW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IHRva2Vucy50b2tlbl90eXBlIHx8IHRva2Vucy50b2tlblR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuOiB0b2tlbnMucmVmcmVzaF90b2tlbiB8fCB0b2tlbnMucmVmcmVzaFRva2VuLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY29wZXM6IGRlY29kZVVSSUNvbXBvbmVudCh0b2tlbnMuc2NvcGVzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMubmFjby5nZXRVc2VyKCkpLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgc3dpdGNoTWFwKHVzZXIgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChudWxsID09PSB1c2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKG5ldyBFcnJvcignVW5hdXRoZW50aWNhdGVkIScpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLm5hY28uZ29Ub0ludGVuZGVkVXJsKCk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gb2YoJ1N1Y2Nlc3MsIHBsZWFzZSB3YWl0IGZvciByZWRpcmVjdGluZy4uLicpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBjYXRjaEVycm9yKGUgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBvZihlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5hY29TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vZG9tYWlucy9zZXJ2aWNlcy9uYWNvLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ25ha2VyLWF1dGgtc2lsZW50JyxcbiAgICB0ZW1wbGF0ZTogJ1BsZWFzZSB3YWl0Li4uJyxcbn0pXG5leHBvcnQgY2xhc3MgQXV0aFNpbGVudFBhZ2UgaW1wbGVtZW50cyBPbkluaXQge1xuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIG5hY286IE5hY29TZXJ2aWNlKSB7fVxuXG4gICAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICBjb25zdCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgICAgICB0aGlzLm5hY28ucmVkaXJlY3QoJy8nKTtcbiAgICAgICAgfSwgMjAwMCk7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgTW9kdWxlV2l0aFByb3ZpZGVycyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUm91dGVyTW9kdWxlLCBSb3V0ZXMgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgQXV0aFBhZ2UgfSBmcm9tICcuL3BhZ2VzL2F1dGgucGFnZSc7XG5pbXBvcnQgeyBBdXRoU2lsZW50UGFnZSB9IGZyb20gJy4vcGFnZXMvYXV0aC1zaWxlbnQucGFnZSc7XG5cbmNvbnN0IHJvdXRlczogUm91dGVzID0gW1xuICAgIHtcbiAgICAgICAgcGF0aDogJ2F1dGgnLFxuICAgICAgICBjb21wb25lbnQ6IEF1dGhQYWdlXG4gICAgfSxcbiAgICB7XG4gICAgICAgIHBhdGg6ICdhdXRoL3NpbGVudCcsXG4gICAgICAgIGNvbXBvbmVudDogQXV0aFNpbGVudFBhZ2VcbiAgICB9LFxuXTtcblxuZXhwb3J0IGNvbnN0IEFVVEhfUk9VVElORzogTW9kdWxlV2l0aFByb3ZpZGVycyA9IFJvdXRlck1vZHVsZS5mb3JDaGlsZChyb3V0ZXMpO1xuIiwiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFVVEhfUk9VVElORyB9IGZyb20gJy4vcm91dGVzJztcbmltcG9ydCB7IEF1dGhQYWdlIH0gZnJvbSAnLi9wYWdlcy9hdXRoLnBhZ2UnO1xuaW1wb3J0IHsgQXV0aFNpbGVudFBhZ2UgfSBmcm9tICcuL3BhZ2VzL2F1dGgtc2lsZW50LnBhZ2UnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuQE5nTW9kdWxlKHtcbiAgICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBBVVRIX1JPVVRJTkddLFxuICAgIGRlY2xhcmF0aW9uczogW0F1dGhQYWdlLCBBdXRoU2lsZW50UGFnZV0sXG59KVxuZXhwb3J0IGNsYXNzIE5hY29WaWV3TW9kdWxlIHt9XG4iLCJpbXBvcnQgeyBJbmplY3Rpb25Ub2tlbiwgTW9kdWxlV2l0aFByb3ZpZGVycywgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5hY29TZXJ2aWNlIH0gZnJvbSAnLi9kb21haW5zL3NlcnZpY2VzL25hY28uc2VydmljZSc7XG5pbXBvcnQgeyBBdXRoZW50aWNhdGVkR3VhcmQgfSBmcm9tICcuL2d1YXJkcy9hdXRoZW50aWNhdGVkLmd1YXJkJztcbmltcG9ydCB7IE5hY29WaWV3TW9kdWxlIH0gZnJvbSAnLi92aWV3cy9tb2R1bGUnO1xuaW1wb3J0IHsgQ29uZmlnIH0gZnJvbSAnLi9kb21haW5zL3ZhbHVlcy9jb25maWcnO1xuXG5jb25zdCBOQUNPX1JPT1RfQ09ORklHID0gbmV3IEluamVjdGlvblRva2VuKCdOQUNPX1JPT1RfQ09ORklHJyk7XG5cbmV4cG9ydCBmdW5jdGlvbiBuYWNvQ29uZmlnRmFjdG9yeShjb25maWc6IENvbmZpZykge1xuICAgIHJldHVybiBuZXcgQ29uZmlnKGNvbmZpZyk7XG59XG5cbkBOZ01vZHVsZSh7XG4gICAgaW1wb3J0czogW05hY29WaWV3TW9kdWxlXSxcbn0pXG5leHBvcnQgY2xhc3MgTmFjb01vZHVsZSB7XG4gICAgcHVibGljIHN0YXRpYyBmb3JSb290KGNvbmZpZzogQ29uZmlnKTogTW9kdWxlV2l0aFByb3ZpZGVycyB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBuZ01vZHVsZTogTmFjb01vZHVsZSxcbiAgICAgICAgICAgIHByb3ZpZGVyczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvdmlkZTogTkFDT19ST09UX0NPTkZJRyxcbiAgICAgICAgICAgICAgICAgICAgdXNlVmFsdWU6IGNvbmZpZyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvdmlkZTogQ29uZmlnLFxuICAgICAgICAgICAgICAgICAgICB1c2VGYWN0b3J5OiBuYWNvQ29uZmlnRmFjdG9yeSxcbiAgICAgICAgICAgICAgICAgICAgZGVwczogW05BQ09fUk9PVF9DT05GSUddLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgTmFjb1NlcnZpY2UsXG4gICAgICAgICAgICAgICAgQXV0aGVudGljYXRlZEd1YXJkLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICB9XG59XG4iXSwibmFtZXMiOlsiVHlwZSIsImZvcndhcmRSZWYiLCJyb3V0ZXIiLCJzdG9yYWdlIiwiaHR0cCIsIm9mIiwiZnJvbSIsInN3aXRjaE1hcCIsIm1hcCIsInBsYWluVG9DbGFzcyIsImNhdGNoRXJyb3IiLCJmb3JrSm9pbiIsInRhcCIsInRva2VucyIsIk9ic2VydmFibGUiLCJ0c2xpYl8xLl9fdmFsdWVzIiwiZnJvbVByb21pc2UiLCJJbmplY3RhYmxlIiwiUm91dGVyIiwiU3RvcmFnZSIsIkh0dHBDbGllbnQiLCJMb2NhdGlvbiIsInRzbGliXzEuX19leHRlbmRzIiwiSW5qZWN0IiwiUkVRVUVTVCIsIlJFU1BPTlNFIiwiZmlyc3QiLCJyZXRyeVdoZW4iLCJ0aHJvd0Vycm9yIiwiY29uY2F0IiwiQ29tcG9uZW50IiwiQWN0aXZhdGVkUm91dGUiLCJSb3V0ZXJNb2R1bGUiLCJOZ01vZHVsZSIsIkNvbW1vbk1vZHVsZSIsIkluamVjdGlvblRva2VuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7SUFBQTs7Ozs7Ozs7Ozs7Ozs7SUFjQTtJQUVBLElBQUksYUFBYSxHQUFHLFVBQVMsQ0FBQyxFQUFFLENBQUM7UUFDN0IsYUFBYSxHQUFHLE1BQU0sQ0FBQyxjQUFjO2FBQ2hDLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxZQUFZLEtBQUssSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzVFLFVBQVUsQ0FBQyxFQUFFLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQUUsSUFBSSxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztvQkFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUMvRSxPQUFPLGFBQWEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDL0IsQ0FBQyxDQUFDO0FBRUYsdUJBQTBCLENBQUMsRUFBRSxDQUFDO1FBQzFCLGFBQWEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDcEIsZ0JBQWdCLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLEVBQUU7UUFDdkMsQ0FBQyxDQUFDLFNBQVMsR0FBRyxDQUFDLEtBQUssSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFD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QUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUk7d0JBQUUsT0FBTyxDQUFDLENBQUM7b0JBQzdKLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO3dCQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUN4QyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7d0JBQ1QsS0FBSyxDQUFDLENBQUM7d0JBQUMsS0FBSyxDQUFDOzRCQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7NEJBQUMsTUFBTTt3QkFDOUIsS0FBSyxDQUFDOzRCQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQzs0QkFBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUM7d0JBQ3hELEtBQUssQ0FBQzs0QkFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7NEJBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFBQyxTQUFTO3dCQUNqRCxLQUFLLENBQUM7NEJBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7NEJBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQzs0QkFBQyxTQUFTO3dCQUNqRDs0QkFDSSxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7Z0NBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQ0FBQyxTQUFTOzZCQUFFOzRCQUM1RyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQ0FBRSxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQ0FBQyxNQUFNOzZCQUFFOzRCQUN0RixJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0NBQUUsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0NBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQ0FBQyxNQUFNOzZCQUFFOzRCQUNyRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQ0FBRSxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztnQ0FBQyxNQUFNOzZCQUFFOzRCQUNuRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0NBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQzs0QkFDdEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQzs0QkFBQyxTQUFTO3FCQUM5Qjtv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
\No newline at end of file